variables:
branches: $[ or(eq(variables['Build.SourceBranch'], 'refs/heads/branch/ayush'), contains(variables['Build.SourceBranch'], 'refs/heads/releases/'))]
This ${{ if eq(variables.branches, 'true') }} condition is not being executed and so the value of var is not being set. However if i set branches to true, it works.
I do not understand what the issue is. What data type does branches have?boolean or string.
According to your description, this problem is related to the expression syntax.
When you are using the runtime expression "$[]", it works in runtime of the pipeline and "${{}}" is compile time syntax, it works before the runtime. So, the condition "${{if...}}" cannot get the value of the "branches" variable.
As a workaround, you can try to use specific condition to set the variable.
variables:
branches: $[ or(eq(variables['Build.SourceBranch'], 'refs/heads/branch/ayush'), contains(variables['Build.SourceBranch'], 'refs/heads/releases/'))]
stages:
- stage: A
jobs:
- job: A1
steps:
- script: echo Hello Stage A!
- stage: B
condition: and(succeeded(), eq(variables.branches, 'true'))
jobs:
- job: B1
steps:
- script: echo Hello Stage B!
- powershell: |
Write-Host "##vso[task.setvariable variable=var;]value"
Related
I have build a yaml pipeline which has multiple stages in them.
To ensure all the stages are using the same git tag, I am trying to display the git tag in the displayName of each stage.
I have a job within the stage which goes and finds the git tag
stages:
- stage : stageA
jobs:
- job: Tag
steps:
- bash: |
tag=`git describe --tags --abbrev=0` && echo "##vso[task.setvariable variable=version_tag;isOutput=true]$tag"
echo "$tag"
name: setTag
How can I use the $tag under displayName in the next stage of the pipeline?
How can I use the $tag under displayName in the next stage of the
pipeline?
No, runtime variables are absolutely impossible to get in compile time. The values of display name are captured before any of the stage actually run, unless you pass a compile-time expression, otherwise anything will be handled as 'string'.
Take a look of this:
https://learn.microsoft.com/en-us/azure/devops/pipelines/process/variables?view=azure-devops&tabs=yaml%2Cbatch#understand-variable-syntax
Only this situation can work:
trigger:
- none
pool:
vmImage: ubuntu-latest
stages:
- stage: A
jobs:
- job: A1
steps:
- bash: |
tag="testtag"
echo "##vso[task.setvariable variable=myStageVal;isOutput=true]$tag"
name: MyOutputVar
- stage: B
dependsOn: A
jobs:
- job: B1
variables:
myStageAVar: $[stageDependencies.A.A1.outputs['MyOutputVar.myStageVal']]
steps:
- bash: echo $(myStageAVar)
I use the following azure pipeline (it is simplified for testing):
parameters:
- name: BUILD_QUALITY
displayName: What is the build quality?
type: string
default: "alpha"
values:
- alpha
- beta
- preview
- release
trigger: none
variables:
solution: "**/*.sln"
buildPlatform: 'Any CPU'
buildConfiguration: "Release"
patch: $[counter(variables['CustomVersion'], 1)]
versionNumber: $(Year:yyyy).$(Month).$(DayOfMonth)
${{ if eq( parameters['BUILD_QUALITY'], 'release') }}:
VERSION_NUMBER: ${{ variables.versionNumber }}.$(patch)
${{ else }}:
VERSION_NUMBER: ${{ variables.versionNumber }}.$(patch)-${{parameters['BUILD_QUALITY']}}
name: Test_${{ variables.versionNumber }}.$(patch)
pool:
vmImage: "windows-latest"
stages:
- stage: buildCliTool
jobs:
- job: cliTool
steps:
- script: echo "versionNumber is ${{ variables.versionNumber }}"
- script: echo "Build name is $(Build.BuildNumber)"
- stage: buildNuget
jobs:
- job: nuget
steps:
- script: echo "versionNumber is $(versionNumber)"
- script: echo "versionNumber is $(VERSION_NUMBER)"
Script steps are used to check, whether variables values are correct.
But, they print correct value just for expression - script: echo "Build name is $(Build.BuildNumber)"
In all other cases, output is not value, but expression itself.
I'd like to use versionNumber in my stages, but now it does not have proper value.
Could someone suggest please, how should I use that variable to obtain value, and not expression body?
The problem is with the tokens you're using in this variable:
versionNumber: $(Year:yyyy).$(Month).$(DayOfMonth)
Those year, month and dayofmonth tokens – you can't use them in normal variables, only when defining a build number:
You can use these tokens only to define a run number; they don't work anywhere else in your pipeline.
I know that it is possible to conditionally set a variable in azure pipelines yml.
See https://learn.microsoft.com/en-us/azure/devops/pipelines/process/expressions?view=azure-devops#conditional-insertion
Is it also somehow possible to conditionally use a variable group?
Let's say if a pipeline run variable is set or has a certain value then the pipeline shall use a variable group. If not then the group shall not be used.
Thank you
Is it possible like here for instance:
trigger: none
pr: none
variables:
isProd: true
stages:
- stage: Test
displayName: Build and restore
variables:
- ${{ if eq(variables['isProd'], 'false') }}:
- group: QA
- ${{ if eq(variables['isProd'], 'true') }}:
- group: PROD
jobs:
- job: A
steps:
- bash: echo $(name)
I have a pipeline.yaml that looks like this
pool:
vmImage: image
stages:
-stage: A
jobs:
-job: a
steps:
- script: |
echo "This is stage build"
echo "##vso[task.setvariable variable=doThing;isOutput=true]Yes"
name: BuildStageRun
-stage: B
jobs:
-job: b
steps: #do something in steps
-job: c
dependsOn: a
condition: eq(dependencies.build.outputs['BuildStageRun.doThing'], 'Yes')
steps:
- script: echo "I am scripting"
So, there are 2 stages, A with one job a, and B with 2 jobs b and c. I would like to have job c executed only when job a has executed. I tried to do so by setting the variable doThing in job a to Yes and then check this variable in job c.
But I get an error:
Stage plan job c depends on unknown job a.
The varible definition and the definition of condition was taken from Azure documentation
Do you have any suggestion on how to get this working?
While Shayki is correct that it is not supported - there is a workaround that I am currently using. That I used with the help of this blog https://medium.com/microsoftazure/how-to-pass-variables-in-azure-pipelines-yaml-tasks-5c81c5d31763
Basically you create your output as normal, and then publish the variables as pipeline artifacts. In the next stage, you read the artifact in the first job, and use that to construct your conditionals e.g.
stages:
- stage: firststage
jobs:
- job: setup_variables
pool:
vmImage: 'Ubuntu-16.04'
steps:
- powershell: |
$ShouldBuildThing1 = $true
# Write to normal output for other jobs in this stage
Write-Output "##vso[task.setvariable variable=BuildThing1;isOutput=true]$ShouldBuildThing1"
# Write to file to publish later
mkdir -p $(PipelineWorkspace)/variables
Write-Output "$ShouldBuildThing1" > $PipelineWorkspace/variables/BuildThing1
name: variablesStep
# Publish the folder as pipeline artifact
- publish: $(Pipeline.Workspace)/variables
artifact: VariablesArtifact
- job: build_something
pool:
vmImage: 'Ubuntu-16.04'
dependsOn: setup_variables
condition: eq(dependencies.setup_variables.outputs['variablesStep.BuildThing1'], 'true')
variables:
BuildThing1: $[dependencies.setup_variables.outputs['variablesStep.BuildThing1']]
steps:
- powershell: |
Write-Host "Look at me I can Read $env:BuildThing1"
- somethingElse:
someInputArgs: $(BuildThing1)
- stage: secondstage
jobs:
- job: read_variables
pool:
vmImage: 'Ubuntu-16.04'
steps:
# If you download all artifacts then foldername will be same as artifact name under $(Pipeline.Workspace). Artifacts are also auto downloaded on deployment jobs.
- task: DownloadPipelineArtifact#2
inputs:
artifact: "VariablesArtifact"
path: $(Pipeline.Workspace)/VariablesArtifact
- powershell: |
$ShouldBuildThing1 = $(Get-Content $(Pipeline.Workspace)/VariablesArtifact/BuildThing1)
Write-Output "##vso[task.setvariable variable=BuildThing1;isOutput=true]$ShouldBuildThing1"
name: variablesStep
- job: secondjob
pool:
vmImage: 'Ubuntu-16.04'
dependsOn: read_variables
condition: eq(dependencies.read_variables.outputs['variablesStep.BuildThing1'], 'true')
variables:
BuildThing1: $[dependencies.setup_variables.outputs['variablesStep.BuildThing1']]
steps:
- powershell: |
Write-Host "Look at me I can Read $env:BuildThing1"
- somethingElse:
someInputArgs: $(BuildThing1)
Looks like a few options available from Microsoft now.
First is job-to-job dependencies across stages
From Microsoft:
In this example, job B1 will run whether job A1 is successful or skipped. Job B2 will check the value of the output variable from job A1 to determine whether it should run.
trigger: none
pool:
vmImage: 'ubuntu-latest'
stages:
- stage: A
jobs:
- job: A1
steps:
- bash: echo "##vso[task.setvariable variable=shouldrun;isOutput=true]true"
# or on Windows:
# - script: echo ##vso[task.setvariable variable=shouldrun;isOutput=true]true
name: printvar
- stage: B
dependsOn: A
jobs:
- job: B1
condition: in(stageDependencies.A.A1.result, 'Succeeded', 'SucceededWithIssues', 'Skipped')
steps:
- script: echo hello from Job B1
- job: B2
condition: eq(stageDependencies.A.A1.outputs['printvar.shouldrun'], 'true')
steps:
- script: echo hello from Job B2
Also, there's another option where you could consume output variables across stages.
From Microsoft site:
Stages can also use output variables from another stage. In this example, Stage B depends on a variable in Stage A.
stages:
- stage: A
jobs:
- job: A1
steps:
- bash: echo "##vso[task.setvariable variable=shouldrun;isOutput=true]true"
# or on Windows:
# - script: echo ##vso[task.setvariable variable=shouldrun;isOutput=true]true
name: printvar
- stage: B
condition: and(succeeded(), eq(dependencies.A.outputs['A1.printvar.shouldrun'], 'true'))
dependsOn: A
jobs:
- job: B1
steps:
- script: echo hello from Stage B
It's because you can't depend on a job from another stage, you can depend stage B on stage A or job c on job b.
You can't achieve your goal with YAML conditions because you want to use a variable that you declared it in the first stage, the second stage doesn't know this variable, Azure DevOps don't support it yet:
You cannot currently specify that a stage run based on the value of an
output variable set in a previous stage.
You can depend stage B on A, so if in stage A there is only one job you depend stage B on stage A:
- stage: B
dependsOn: A
Let's say I'm starting with this configuration that works:
jobs:
- job: ARelease
pool:
vmImage: 'Ubuntu-16.04'
steps:
- script: |
echo "##vso[task.setvariable variable=ReleaseVar;isOutput=true]1"
name: JobResult
- job: C
pool:
vmImage: 'Ubuntu-16.04'
dependsOn: ARelease
variables:
AVar: $[ dependencies.A.outputs['JobResult.ReleaseVar'] ]
steps:
- script: |
echo $(AVar)
As expected job C outputs 1.
Now let's say that I have to add a new job ADebug, which is almost identical to ARelease, so I use a strategy:
jobs:
- job: A
strategy:
matrix:
Release:
BUILD_TYPE: Release
Debug:
BUILD_TYPE: Debug
pool:
vmImage: 'Ubuntu-16.04'
steps:
- script: |
echo "##vso[task.setvariable variable=$(BUILD_TYPE)Var;isOutput=true]1"
name: JobResult
- job: C
pool:
vmImage: 'Ubuntu-16.04'
dependsOn: A
variables:
AReleaseVar: $[ dependencies.A.outputs['JobResult.ReleaseVar'] ]
ADebugVar: $[ dependencies.A.outputs['JobResult.DebugVar'] ]
steps:
- script: |
echo $(AReleaseVar)
echo $(ADebugVar)
I would expect that everything works and that I can see the outputs.. but the output is empty.
Queuing the job with diagnostics it seems that $[ dependencies.A.outputs['JobResult.ReleaseVar'] ] and $[ dependencies.A.outputs['JobResult.DebugVar'] ] evaluate to Null.
I've tried different variations to access those variables, but it always evaluates to Null.
Any idea what is the correct way?
https://learn.microsoft.com/en-us/azure/devops/pipelines/process/variables?view=azure-devops&tabs=yaml%2Cbatch#set-a-multi-job-output-variable
If you're setting a variable from a matrix or slice, then to reference
the variable, you have to include the name of the job as well as the
step when you access it from a downstream job.
The format is as follows: dependencies.{job}.outputs['{matrix/slice key}.{step name}.{variable name}']
In your scenario, you have Job A run with a matrix strategy (Release, Debug), and you respectively set the variable names to be ReleaseVar and DebugVar. The way to accurately access these variables is:
dependencies.A.outputs['Release.JobResult.ReleaseVar']
dependencies.A.outputs['Debug.JobResult.DebugVar']
On a side note, perhaps just use the same variable name since it you are already able to distinguish between the values based on the matrix name.