stages showing Unexpected value in yaml - variables

I know there is a similar question here but it did not help. I can't seem to figure out what is wrong with my pipeline. I want to declare a variable set for all the jobs, so I am declaring them in the stage:
parameters:
- name: myBatches
type: object
stages:
- stage: A
variables:
myVar: ""
jobs:
- ${{ each object in parameters.myBatches }}:
- job:
...
It throws error on line 5 that "unexpected value 'stages'". How can I resolve it?
(Note - my purpose of doing stages is just to distribute the variables through all jobs)
Thanks so much!

Related

Programmatically get the $(rev:.r) variable in yaml scripts

This is a follow up of this question
I'd like to put the number of my build in the description (and in other tasks), when using BuildId it works without any problem.
But if I use $(rev:.r), this variable is not interpreted and I have an error saying that the number version is not correct (invalid characters such as $ and :).
Here's some code working with BuildId but not with Rev :
variables:
- group: NumVersion
- name: upperversion
${{ if eq(parameters.VersionBuild,'ReleaseProd') }}:
value: $(1-VersionMajeur).$(2-VersionMineure-ReleaseProd)
${{ if eq(parameters.VersionBuild,'Release') }}:
value: $(1-VersionMajeur).$(2-VersionMineure-Release)
${{ if eq(parameters.VersionBuild,'Develop') }}:
value: $(1-VersionMajeur).$(2-VersionMineure-Dev)
- name: lowerversion
${{ if eq(parameters.TypeBuild,'Feature') }}:
value: 99.$(Build.BuildId)
${{ if eq(parameters.TypeBuild,'Production') }}:
value: $(3-VersionCorrective-Release).$(rev:.r)
name: $(upperversion).$(lowerversion)
stages:
- stage: Build
jobs:
- job: Prerequisites
displayName: Prerequisites
steps:
- checkout: self
- script: |
echo '##vso[build.updatebuildnumber]$(upperversion).$(lowerversion)
Did somebody encounter this? Thanks in advance!
According to the docs you can’t use this variable other than in the build number / name field.
In Azure DevOps $(Rev:r) is a special variable format that only works in the build number field. When a build is completed, if nothing else in the build number has changed, the Rev integer value increases by one.
https://learn.microsoft.com/en-us/azure/devops/pipelines/process/run-number?view=azure-devops

DevOps Pipeline Variables cannot be compared

I have a question to DevOps Pipelines.
I have created a Pipeline and during this creation I add a variable with this values “ Name: RESIDENCE ; value: ISS“. So this Value is defined outside from any script.
Pipeline Variable
Inside the .yml file I use this code:
variables:
- name: shuttle
value: Columbia
- name: pipe_var
value: $(RESIDENCE)
- name: location
${{ if eq(variables.pipe_var, 'ISS') }}:
value: pretty_cool
${{ if eq(variables.pipe_var, 'MIR') }}:
value: not_possible
steps:
- script: |
echo space shuttle is: $(shuttle)
echo residence is: $(pipe_var)
echo place to be is: $(location)
But The Pipeline output is only showing:
space shuttel is: Columbia
resicende is: ISS
place to be is:
So as it can be seen in the line “resicende is: ISS “ the value from the outside variable “RESIDENCE” is shown correct. To show this value I use the detour over the variable “pipe_var”. But when I try to compare this variable value with the “if equal” lines then I get no results.
What I’m doing wrong? Is there a special way to compare string values in a pipeline?
It would be nice if someone could give me a hint.

Azure Devops YAML: Looping Jobs With Different Variables Passed

I am struggling to figure out how to execute an API test using a pipeline where the command used can be modified using a loop. For example:
TEMPLATE.yaml
parameters:
JobName: ''
TestDirectory: '.\tests\smoke\'
PositiveTest: ''
NegativeTest: ''
- name: environments
type: object
values:
- dev01
- dev02
- test01
- test02
jobs:
- job: ${{ parameters.JobName }}
pool:
name: pool
demands:
- Cmd
variables:
PosTest: ${{ parameters.PositiveTest }}
NegTest: ${{ parameters.NegativeTest }}
Directory: ${{ parameters.TestDirectory }}
- script: |
call .\venv\Scripts\activate.bat
cd $(Directory)
python $(PosTest)
displayName: 'Executing Positive Test Scenarios'
condition: and(succeeded(), ne('${{ variables.PosTest }}', ''))
- script: |
call .\venv\Scripts\activate.bat
cd $(Directory)
python $(NegTest)
displayName: 'Executing Negative Test Scenarios'
condition: and(succeeded(), ne('${{ variables.NegTest }}', ''))
TEST_FILE.yaml
...
jobs:
# Get this file: templates\TEMPLATE.yml from the `build` repository (imported above)
- template: templates\api-test-build.yml#build
- ${{ each env in parameters.environments }}:
parameters:
TestDirectory: '.\tests\smoke\job_class'
PositiveTest: 'python_test.py http://apient${{ env }}/arbitrary/api/path/name'
NegativeTest: ''
This of course doesn't work (the each directive returns an error like "the first property must be template". If I move it up a line it then says "the first property must be a job" and this cycle of errors just continues...).
The idea is just that I have a loop that iterates through environment strings (top of the TEMPLATE.yaml example). The yaml file that references the template passes the command python_test.py http://apient<whatever env string the current iteration is on>/arbitrary/api/path/name for each iterated string (bottom of TEST_FILE.yaml) and the template just executes each of those api tests. At the end of a run there should be 4 environments that have been tested on.
This is just an idea I have and I am still learned all the in's and out's of Azure Devops YAML. If anyone knows how I can get this to work, any improvements I can make to the idea itself or any other workarounds/solutions that would be highly appreciated. Thank you!
You can try using Multi-job configuration (matrix) in your pipeline.
When you want to run the same job with multi-configuration in a pipeline, the matrix strategy is a good choose.
For example, in your pipeline, you want to run the jobs that have the same steps and input parameters but different values of the input parameters. You can just set up one job with the matrix strategy in the pipeline.

How can I use variables passed between jobs in a condition?

I am building a YAML pipeline in Azure DevOps. I'm generating couple of variables in first job, which I'm passing to other job and want to use them to conditionally run some steps.
Here's how the code looks like:
stages:
- stage: ConditionalVars
jobs:
- job: outputVars
steps:
- pwsh: |
Write-Host "##vso[task.setvariable variable=varExample;isOutput=true]testVar"
name: setVars
- job: useVars
dependsOn: outputVars
variables:
varFromJob: $[ dependencies.outputVars.outputs['setVars.varExample']]
steps:
- ${{ if eq($(varFromJob), 'testVar')}}:
- pwsh: |
Write-Output "Conditionally run"
I am able to print $(varFromJob) variable in step in job useVars. But I'm not able to use it in this if (condition) example.
I was trying different approaches like variables.varFromJob and other taken from https://learn.microsoft.com/en-us/azure/devops/pipelines/process/conditions?view=azure-devops&tabs=yaml.
Have you guys been struggling with similar issue? How could I define it to make it work?
Thanks a lot!
Rafal
Try to use a condition for the step:
steps:
- pwsh: |
Write-Output "Conditionally run"
condition: eq(variables['varFromJob'], 'testVar')
${{ if eq... }} is a compile-time expression that is evaluated when the YAML file is compiled.

Way to use anchors/references in job.<spec>.script for DRYness

I'm fairly new to using gitlab-ci and as such, I've run into a problem where the following fails ci-lint because of my use of anchors/references:
image: docker:latest
services:
- docker:dind
variables:
DOCKER_DRIVER: overlay2
DOCKER_HOST: tcp://localhost:2375
.install_thing1: &install_thing1
- do things
- to install
- thing1
.install_thing2: &install_thing2
- do things to
- install thing2
.setup_thing1: &setup_things1
variables:
VAR: var
FOO: bar
script:
- all
- the
- things
before_script:
...
stages:
- deploy-test
- deploy-stage
- deploy-prod
test:
stage: deploy-test
variables:
RUN_ENV: "test"
...
only:
- tags
- branches
script:
- *install_thing1
- *install_thing2
- *setup_thing1
- other stuff
...
test:
stage: deploy-stage
variables:
RUN_ENV: "stage"
...
only:
- master
script:
- *install_thing1
- *install_thing2
- *setup_thing1
- other stuff
When I attempt to lint the gitlab-ci.yml, I get the following error:
Status: syntax is incorrect
Error: jobs:test:script config should be a string or an array of strings
The error eludes to just needing an array for the script piece, which I believe I have. Use of the <<: *anchor pragma causes an error as well.
So, how can one accomplish what I'm trying to do here where I don't have to repeat the code in every -block?
You can fix it and even make it more DRY, take a look at the Auto DevOps template Gitlab created.
It can fix your issue and even more improve your CI file, just have a template job like their auto_devops job, include it in a before_script and then you can combine and call multiple functions in a script block.
The anchors only give you limited flexibility.
(This concept made it possible for me to have one CI file for 20+ projects and a centralized functions file I wget and load in my before_script.)