Getting an error like unexpected value "name" on azure pipelines - azure

I have the below yaml file. I am trying to solve the issue where two deployment files set up in two different pipelines exist in a single folder and a case where one file change does not trigger other pipelines based on file changes.
For the above purpose, I have made the below change but getting an error in the pipeline unexpected value "name",
and the code is below
.....
trigger:
paths:
include:
- '.devops/**'
variables:
deploymentFile: 'test-hub-deploy-dev.yml'
stages:
- stage: Get the deployment file name
jobs:
- job: Get deployment file
displayName: 'Get deployment file'
steps:
- name: Get the deployment file name // getting error at here
script: |
if [[ $Build.SourcesDirectory == *"deployment-folder"* ]]; then
echo "##[set-output name=deploymentFile;]$(basename $Build.SourcesDirectory)"
fi
displayName: Get deployment file name
env:
SYSTEM_DEFAULTWORKINGDIRECTORY: $(System.DefaultWorkingDirectory)
BUILD_SOURCESDIRECTORY: $(Build.SourcesDirectory)
outputs:
deploymentFile: '$(deploymentFile)'
- name: Deploy to test-dev
condition: and(succeeded(), eq(variables['deploymentFile'], 'test-hub-deploy-dev.yml'))
script: echo "Deploying using test-hub-deploy-dev.yml"
displayName: Deploy to test-dev
- stage: Build
jobs:
....
I don't know where I am doing wrong with the above yaml code. Please point me in the right direction.

1 - In triggers section 'include' and - '.devops/**' should be on the same identation level
https://learn.microsoft.com/en-us/azure/devops/pipelines/yaml-schema/trigger?view=azure-pipelines#examples-2
trigger:
paths:
include:
- '.devops/**'
2 - Same for 'stages' and '- stage: abc'
https://learn.microsoft.com/en-us/azure/devops/pipelines/yaml-schema/stages-stage?view=azure-pipelines
stages:
- stage: abc
3 - The same for 'jobs' and '- job'
https://learn.microsoft.com/en-us/azure/devops/pipelines/yaml-schema/jobs?view=azure-pipelines#examples
4 - And for 'steps'
https://learn.microsoft.com/en-us/azure/devops/pipelines/yaml-schema/steps?view=azure-pipelines
First declare your step(script/pwsh/other) then you can assign name for it.
'script' needs to have dash in front of it.
https://learn.microsoft.com/en-us/azure/devops/pipelines/yaml-schema/steps-script?view=azure-pipelines#examples
5 - Outputting variable is used when you want to get this variable from next jobs, here you have second step using variable from step one within same job.
6 - Where did you find this 'set-output'? Why not use ##vso + task.setvariable. This whole line cannot work.
https://learn.microsoft.com/en-us/azure/devops/pipelines/process/set-variables-scripts?view=azure-devops&tabs=bash#set-an-output-variable-for-use-in-the-same-job
7 - $(basename $Build.SourcesDirectory)
I suppose that 'basename' is variable, not constant string but you did not provide this infromation.
This will never work, to access variable you need to use syntax $(VariableName)
If you want to concat variables, put them next to each other
"$(basename)$(Build.SourcesDirectory)
8 - I do not guarantee it will fully work because there was plenty of mistakes that I could miss something.
The 'steps' section of yaml should be similar to this one
steps:
- script: |
if [[ $Build.SourcesDirectory == *"deployment-folder"* ]]; then
echo "##vso[task.setvariable variable=deploymentFile;]$(basename)$(Build.SourcesDirectory)"
fi
name: Get the deployment file name
displayName: Get deployment file name
env:
SYSTEM_DEFAULTWORKINGDIRECTORY: $(System.DefaultWorkingDirectory)
BUILD_SOURCESDIRECTORY: $(Build.SourcesDirectory)
- script: echo "Deploying using test-hub-deploy-dev.yml"
displayName: Deploy to test-dev
name: Deploy to test-dev
condition: and(succeeded(), eq(variables['deploymentFile'], 'test-hub-deploy-dev.yml'))

Related

Azure Devops Pipelines - Add multiple/batch variables

I'm using the below azure-pipeline.yml file to build docker image, push to Azure docker registry & restart the Azure docker app servicer.
This yaml file uses variable set in azure pipeline, screenshot attached.
My issue is, I need to create 2-3 pipelines every-week for different projects I need to add every variable manually for each project and copy paste from my config. Is there a way I can import a .env file or add multiple variables all at once while creating the pipeline.
Objectively I need to cut down the single variable copy paste time & avoid errors that might occurr
1.You could use variable group to reuse variables.
trigger:
- none
pool:
vmImage: ubuntu-latest
variables:
- group: forTest
steps:
- script: |
echo $(test1)
echo $(test2)
displayName: 'Run a multi-line script'
2.You could use variable template.
trigger:
- none
pool:
vmImage: ubuntu-latest
variables:
- template: vars.yml
steps:
- script: |
echo $(test1)
echo $(test2)
displayName: 'Run a multi-line script'

Unable to add tag to Azure pipeline during build

I want to tag my pipeline build during the build process itself. For which based on the official document I tried echo ##vso[build.addbuildtag]testing in the pipeline yaml. There was no error but the build was not tagged either.
I'm able to add tags from portal successfully.
My pipleine yaml below.
pool:
vmImage: ubuntu-latest
jobs:
- job: addingtag
displayName: addingtag
steps:
- script: |
echo ##vso[build.addbuildtag]testing
displayName: addingtag
Below are other combinations I tried and still failed.
echo ##vso[build.addbuildtag] testing
echo ##vso[build.addbuildtag]Tag_testing
You may need to add double quotes, I could successfully add tag by using YAML script like below.
- script: |
echo "##vso[build.addbuildtag]testing"
displayName: addingtag

Azure Pipeline: Update variables according to parameter

I have some very simple variables, which I would like to change according to the environment.
I have written the code below in very different ways (including indentation) but none was fruitful. Alternatives I see are
Use variable groups (trying to avoid to have too many of them)
Write a bash script which updates the variables (will work but I
think its not a super neat solution)
variables:
- group : secrets
- name: hello
value: world
${{ if eq(parameters.environment, 'dev') }}:
- name: RabbitMQ_replicaCount
value: 3
${{ if eq(parameters.environment, 'test') }}:
RabbitMQ_replicaCount: '1'
Any other ideas will be appriciated :)
I would rather go by a PS script/Bash script for this task. Why ? The logic part of build where manipulation is needed like setting or overriding var based on branch or env can be done in a better way in script rather than the build yaml itself. Also this part un-necessary elongates the yaml.
Step 1 : Define a var in the build pipe with default env name
and may be another var whose value you want to set based on condition
Step 2 : Add a yml file(lets name it BuildEnv.yml) in your repo which actually contains your PowerShell/Bash code:
steps:
- powershell: |
if($BuildEnv -ne "Test"){
Write-Host "##vso[task.setvariable variable=BuildEnv]Dev"
Write-Host "##vso[task.setvariable variable=RabbitMQ_replicaCount]11"
}
displayName: 'Override Build Env'
# MORE CODE HERE
Step 3: Plug your yml in the build pipe as a template-
trigger:
branches:
include:
- master
name: $(date:yyyy-MM-dd_HH.mm)_$(rev:.r)
stages:
- stage: Build_Stage
displayName: Build_Stage
jobs:
- job: Build_Job
pool:
name: ABC
steps:
- template: ..\BuildEnv.yml
#REST CODE
That's it. You are done.
Reference : Template usage in Azure DevOps build - https://learn.microsoft.com/en-us/azure/devops/pipelines/process/templates?view=azure-devops

How can I use variable created inside of pipeline (from gradle.properties file) within an template as a task

I have an java project which have gradle.properties file. Im extracting variables defined in gradle.properties as
##vso[task.setvariable variable=myVariable;]`my script to extract it from gradle.properties`
Then im using template from another repository that needs that variable but I can't use it within task, but when I try use it within - script: echo $variable as a step instead of task it is working.
When i try to use it within task it sees variable as $variable not a value.
Maybe there is a better way to extract variables to azure pipeline instead of using this approach?
Check the error message:
We get the error before the pipeline run the bash task, Since it cannot create the variable parampass, we get the parameters value is $(parampass) instead of the variable value.
Check this doc:
In a pipeline, template expression variables ${{ variables.var }} get processed at compile time, before runtime starts. Macro syntax variables $(var) get processed during runtime before a task runs. Runtime expressions $[variables.var] also get processed during runtime but were designed for use with conditions and expressions.
As a workaround:
pipeline.yml
pool:
vmImage: ubuntu-20.04
resources:
repositories:
- repository: common
type: git
name: organisation/repo-name
variables:
- name: parampass
value: xxx
stages:
- stage: "Build"
jobs:
- job: "Build"
steps:
- template: templatename.yml#common
parameters:
par1: ${{ variables.parampass}}
Result:
Probably you do not provide variable to your template
Example execution of template with provided parameter
- template: my/path/to/myTemplate.yml#MyAnotherRepositoryResourceName
parameters:
projectsToBeTested: $(someVariable)
And example template accepting parameters
steps:
- task: DotNetCoreCLI#2
displayName: 'Just testing'
inputs:
command: test
projects: ${{ parameters.projectsToBeTested}}
Please provide more information if it does not help.
Code looks like this:
pipeline.yml
pool:
vmImage: ubuntu-20.04
resources:
repositories:
- repository: common
type: git
name: organisation/repo-name
stages:
- stage: "Build"
jobs:
- job: "Build"
steps:
- bash: |
echo "##vso[task.setvariable variable=parampass]anything"
- template: templatename.yml#common
parameters:
par1: $(parampass)
templatename.yml
parameters:
- name: par1
steps:
- task: SonarCloudPrepare#1
displayName: SonarCloud analysis prepare
inputs:
SonarCloud: ${{ parameters.par1}}
organization: 'orgname'
scannerMode: 'Other'
extraProperties: |
# Additional properties that will be passed to the scanner,
# Put one key=value per line, example:
# sonar.exclusions=**/*.bin
sonar.projectKey= # same param pass case
sonar.projectName= # same param pass case
Generally, it does not matter if i do have parameters passed or if I'm using the template as if it were part of the pipeline code within. Output is always $(parampass) could not be found or smth

Share variables across stages in Azure DevOps Pipelines

I am trying to figure out how to share custom variables across ADO pipelines in my script. Below is my script with 2 stages.
I am setting the curProjVersion as an output variable and trying to access it from a different stage. Am I doing it right?
stages:
- stage: Build
displayName: Build stage
jobs:
- job: VersionCheck
pool:
vmImage: 'ubuntu-latest'
displayName: Version Check
continueOnError: false
steps:
- script: |
echo "##vso[task.setvariable variable=curProjVersion;isOutput=true]1.4.5"
name: setCurProjVersion
displayName: "Collect Application Version ID"
- stage: Deploy
displayName: Deploy stage
dependsOn: Build
variables:
curProjVersion1: $[ dependencies.Build.VersionCheck.outputs['setCurProjVersion.curProjVersion'] ]
jobs:
- job:
steps:
- script: |
echo $(curProjVersion1)
Updated:
Share variables across stages feature has been released in Sprint 168 now.
Please use below format to access output variables from previous stage:
stageDependencies.{stageName}.{jobName}.outputs['{stepName}.{variableName}']
Original:
Share variables across stages in Azure DevOps Pipelines
I'm afraid to say that it does not supported to share the variable which defined in one stage and pass it into another stage.
This is the feature we are plan to add, but until now, it does not supported. You can follow this Github issue, many people has the same demand with you. You can follow track that.
Until now, we only support set a multi-job output variable, but this only support YAML. For Classic Editor, there's no any plan to add this feature in release.
For work around, you can predefined the variables before the stages. But one important thing is if you change its value in one stage. The new value could not be passed to the next stage. The lifetime of variable with new value only exists in stage.
What is important to mention stageDependencies is not available in condition at stage level. It is aviable in jobs, but not in stage directly (at least at the moment).
stages:
- stage: A
jobs:
- job: JA
steps:
- script: |
echo "This is job Foo."
echo "##vso[task.setvariable variable=doThing;isOutput=true]Yes" #The variable doThing is set to true
name: DetermineResult
- script: echo $(DetermineResult.doThing)
name: echovar
- job: JA_2
dependsOn: JA
condition: eq(dependencies.JA.outputs['DetermineResult.doThing'], 'Yes')
steps:
- script: |
echo "This is job Bar."
#stage B runs if DetermineResult task set doThing variable n stage A
- stage: B
dependsOn: A
jobs:
- job: JB
condition: eq(stageDependencies.A.JA.outputs['DetermineResult.doThing'], 'Yes') #map doThing and check if true
variables:
varFromStageA: $[ stageDependencies.A.JA.outputs['DetermineResult.doThing'] ]
steps:
- bash: echo "Hello world stage B first job"
- script: echo $(varFromStageA)
Jobs can now access variables from previous stages
Output variables are still produced by steps inside of jobs. Instead of referring to dependencies.jobName.outputs['stepName.variableName'], stages refer to stageDependencies.stageName.jobName.outputs['stepName.variableName'].
https://learn.microsoft.com/en-us/azure/devops/release-notes/2020/sprint-168-update#azure-pipelines-1
This is available as of May 4th 2020
Jobs can access output variables from previous stages:
Output variables may now be used across stages in a YAML-based pipeline. This helps you pass useful information, such as a go/no-go decision or the ID of a generated output, from one stage to the next. The result (status) of a previous stage and its jobs is also available.
Output variables are still produced by steps inside of jobs. Instead of referring to dependencies.jobName.outputs['stepName.variableName'], stages refer to stageDependencies.stageName.jobName.outputs['stepName.variableName'].
Note
By default, each stage in a pipeline depends on the one just before it in the YAML file. Therefore, each stage can use output variables from the prior stage. You can alter the dependency graph, which will also alter which output variables are available. For instance, if stage 3 needs a variable from stage 1, it will need to declare an explicit dependency on stage 1.
For stage conditions on Azure DevOps Version Dev17.M153.5 with Agent Version 2.153.1 the following works:
stages:
- stage: A
jobs:
- job: JA
steps:
- script: |
echo "This is job Foo."
echo "##vso[task.setvariable variable=doThing;isOutput=true]Yes" #The variable doThing is set to 'Yes'
name: DetermineResult
#stage B runs if DetermineResult task set doThing variable on stage A
- stage: B
dependsOn: A
condition: eq(dependencies.A.outputs['JA.DetermineResult.doThing'], 'Yes')
jobs:
- job: JB
steps:
- bash: echo "Hello world stage B first job"
Note: The layout of properties is different on stage compared to job:
dependencies.{stage name}.outputs['{job name}.{script name}.{variable name}']
Note: The expression with 'stageDependencies' failed with the following error message:
An error occurred while loading the YAML build pipeline. Unrecognized value: 'stageDependencies'. Located at position XX within expression: and(always(), eq(stageDependencies.A.outputs['JA.DetermineResult.doThing'], 'Yes')). For more help, refer to https://go.microsoft.com/fwlink/?linkid=842996
Bonus:
See the following documentation on how to access the status of the dependent stages: link
Corresponding documentations:
Use output variables from tasks
Stage to stage dependencies
To use the output from a different stage, you must use the syntax depending on whether you're at the stage or job level:
At the stage level, the format for referencing variables from a different stage is dependencies.STAGE.outputs['JOB.TASK.VARIABLE']. You can use these variables in conditions.
At the job level, the format for referencing variables from a different stage is stageDependencies.STAGE.JOB.outputs['TASK.VARIABLE']
Note: By default, each stage in a pipeline depends on the one just before it in the YAML file. If you need to refer to a stage that isn't immediately prior to the current one, you can override this automatic default by adding a dependsOn section to the stage.
Yes this is possible, you need stageDependencies like below:
stages:
- stage: Build
displayName: Build stage
jobs:
- job: VersionCheck
pool:
vmImage: 'ubuntu-latest'
displayName: Version Check
continueOnError: false
steps:
- script: |
echo "##vso[task.setvariable variable=curProjVersion;isOutput=true]1.4.5"
name: setCurProjVersion
displayName: "Collect Application Version ID"
- stage: Deploy
displayName: Deploy stage
dependsOn: Build
variables:
curProjVersion1: $[ stageDependencies.Build.VersionCheck.outputs['setCurProjVersion.curProjVersion'] ]
jobs:
- job:
steps:
- script: |
echo $(curProjVersion1)
Note that I have changed
$[ dependencies.Build.VersionCheck.outputs['setCurProjVersion.curProjVersion'] ]
TO
$[ stageDependencies.Build.VersionCheck.outputs['setCurProjVersion.curProjVersion'] ]
source: https://jimferrari.com/2023/01/05/pass-variables-across-jobs-and-stages-in-azure-devops-pipelines/
As an update for anyone seeing this question, it seems passing variables between stages has been implemented and should be released in the next couple of weeks.
You can define a global variable and use a Powershell to assign the value of the stage variable to the global variable.
Write-Output ("##vso[task.setvariable variable=globalVar;]$stageVar")
Global variables can either be defined in the yaml itself or in variable groups.
Initialise the var with an empty value.
E.g. yaml
variables:
globalVar: ''
You can define the variables just after you define the trigger and before you define the stages
trigger:
- master
variables:
VarA: aaaaa
VarB: bbbbb
stages:
- stage: Build
jobs:
- job: Build
pool:
vmImage: 'vs2017-win2016'

Resources