Azure Devops - How to pass environment variables into dotnet test? - azure-devops

I have a standard .NET Core (Ubuntu) pipeline on Azure Devops and within my Test project, I use environment variables. Within my pipeline, I have defined my group variables like so
variables:
- group: MyApiVariables
Whenever I run the tests for my project
- task: DotNetCoreCLI#2
displayName: "Testing Application"
inputs:
command: test
projects: '**/*Tests/*.csproj'
arguments: '--configuration $(buildConfiguration)'
The actual environment variables aren't passed in. They are blank.
What am I missing to get this running? I've even defined variables in the edit pipeline page too with no luck
- task: Bash#3
inputs:
targetType: 'inline'
script: echo $AppConfigEndpoint
env:
AppConfigEndpoint: $(AppConfigEndpoint)
ApiConfigSection: $(ApiConfigSection)
Thanks!

CASING Strikes again! MyVariableName was turned into MYVARIABLENAME on Azure Devops. I changed my variable names in my group to all caps and it worked. I spent way too much time on this.

Mike, I see that you use variable groups. I assume it may cause your issue. Take a look at variable passing example I made:
First I had to create new variable group in Library:
Here is a pipeline code that reference created variables:
# Set variables group reference
variables:
- group: SampleVariableGroup
steps:
- powershell: 'Write-Host "Config variable=$(configuration) Platform variable=$(platform)"'
displayName: 'Display Sample Variable'
I used PowerShell task to verify if variables were properly passed to the job.
As you can see both configuration & platform values were displayed correctly.
In fact you can't go wrong that way, unless you start to mix variable groups with variables defined in a yaml. In such scenario you'll have to use name/value syntax for the individual (non-grouped) variables.
Please see Microsoft Variable Groups documentation. Such example is well explained there. I also suggest to take closer look at general Variables Documentation.
In case of referencing variables in other tasks here is a great example from MS (it should work everywhere in same manner):
# Set variables once
variables:
configuration: debug
platform: x64
steps:
# Use them once
- task: MSBuild#1
inputs:
solution: solution1.sln
configuration: $(configuration) # Use the variable
platform: $(platform)
# Use them again
- task: MSBuild#1
inputs:
solution: solution2.sln
configuration: $(configuration) # Use the variable
platform: $(platform)
Good luck!

Related

Azure Pipelines - Output variable from python script file to pipeline variable

I've tried several articles and threads from Stackoverflow but can't seem to get anywhere. I am trying to take a variable from a .py file which is called in a YAML step and set that variable globally to be used.
In my .py file i have
print(f'##vso[task.setvariable variable=AMLPipelineId;isOutput=true]{pipelineId}')
Then in my YAML pipeline step i have
- task: AzurePowerShell#5
displayName: 'Run AML Pipeline'
inputs:
azureSubscription: '$(azureSubscription)'
ScriptType: 'InlineScript'
name: AmlPipeline
azurePowerShellVersion: 'LatestVersion'
pwsh: true
Inline: |
$username = "$(ARM_CLIENT_ID)"
$password = "$(ARM_CLIENT_SECRET)"
$tenantId = "$(ARM_TENANT_ID)"
python $(Pipeline.Workspace)/AML_Pipeline/build_aml_pipeline.py --wsName $(wsName) --resourceGroup $(ResourceGroupName) --subscriptionId $(subId)
$MLPipelineId = $AmlPipeline.AMLPipelineId
But it seems like this variable is empty. I know there are other ways of using the "set variable" but this is my latest attempt i.e. something like print('##vso[task.setvariable variable=version;]%s' % (version))
My current approach i followed: https://learn.microsoft.com/en-us/azure/devops/pipelines/process/variables?view=azure-devops&tabs=yaml%2Cbatch
You don't need isOutput=true - that's only needed for referencing variables between different jobs or stages.
"You cannot use the variable in the step that it is defined." - split that script into two steps: one that runs your .py file, second one that uses the newly defined variable.
I used print('##vso[task.setvariable variable=<Variable-in-Pipeline]+<output-variable>')
Variable-in-Pipeline // the given name should be used in Azure Devops pipeline and should be added to pipeline variables as an empty string
A very minimal example for everyone struggling with this. The documentation is kind of lacking on this for my taste. As #qbik said, dont set and use the variable in the same step, make it seperate steps.
set_variable.py
if __name__ == '__main__':
# set name of the variable
name = 'COLOR'
# set value of the variable
value = 'red'
# set variable
print(f'##vso[task.setvariable variable={name};]{value}')
azure-pipelines.yml
trigger:
- main
pool:
vmImage: ubuntu-latest
steps:
- task: UsePythonVersion#0
inputs:
versionSpec: '3.9'
displayName: 'Use Python 3.9'
# run the script to set the variable
- task: PythonScript#0
inputs:
scriptSource: filePath
scriptPath: set_variable.py
# now you can use the variable in the next step
- bash: echo my favorite color is: $(COLOR)
Now you can technically do all kinds of cool stuff in python, then set, and reference the variables in the following steps. In my case I have to extract specific package version numbers from a JSON/YAML file based on an id that is set earlier in the pipeline and parse the information as an args for a docker build. Hope that helps other people stumbling across this answer looking for a minimal working example :)

ADO gulp task - pass previous task's output variable as argument

I am trying this for quite sometime now & not able to figure out how to proceed further. My requirement is to dynamically calculate a variable in a bash task & then in next step use the same as a parameter to the gulp task. Below are my two tasks as part of the build pipeline (removed lines for simplicity)
- task: Bash#3
name: SetVariableValue
inputs:
targetType: inline
script: >
// removed
myvariableValue=$(do something & calculate here, assume value will be 'abc')
// Set to an output variable
echo "##vso[task.setvariable variable=myVar;isOutput=true]$myvariableValue"
- task: gulp#0
displayName: Publish front-end
inputs:
gulpFile: $(Build.SourcesDirectory)/../gulpfile.js
targets: publish
arguments: >-
--buildId $(Build.BuildId) --buildNumber $(Build.BuildNumber) --sourceBranch $(Build.SourceBranch) --var $(myVar)
gulpjs: >-
$(Build.SourcesDirectory)/../node_modules/gulp/bin/gulp.js
enableCodeCoverage: false
I am using linux machines to build angular packages and the gulp publish command is used to package our code depending on the said variable.
With above steps all the rest parameters like BuildId, BuildNumber, SourceBranch are getting passed correctly but the 'var' parameter is being passed as $(myVar) only, rather abc
Can you please help me on what am I missing here? I tried multiple things like --var $(Build.myVar), but not able to make it work.
Thanks
Sanjay
Oh man all I needed was to correct the name of the step & refer it without mistyping :(
--var $(SetVariableValue.myVar) did the trick. Thanks.

Azure build pipelines - using the 'DownloadSecureFile' task within a template

I have an Azure DevOps project with a couple of YAML build pipelines that share a common template for some of their tasks.
I now want to add a DownloadSecureFile task to that template, but I can't find a way to get it to work.
The following snippet results in an error when added to the template, but works fine in the parent pipeline definition (Assuming I also replace the ${{ xx }} syntax for the variable names with the $(xx) version):
- task: DownloadSecureFile#1
name: securezip
displayName: Download latest files
inputs:
secureFile: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
retryCount: 5
- task: ExtractFiles#1
displayName: Extract files
inputs:
archiveFilePatterns: ${{ variables.securezip.secureFilePath }}
destinationFolder: '${{ parameters.sourcesDir }}\secure\'
cleanDestinationFolder: true
The error occurs on the 'Extract File' step and is Input required: archiveFilePatterns, so it looks like it's just not finding the variable.
As a workaround, I could move the download task to the parent pipeline scripts and pass the file path as a parameter. However, that means duplicating the task, which seems like a bit of a hack.
Variables in dollar-double-curly-brackets are resolved at template expansion time. They are not the output of tasks.
Output variables from tasks are referenced by dollar-single-parentheses and they don't need to start with the word "variables."
So I believe the line you're looking for is like this, and it isn't affected by the template mechanism.
archiveFilePatterns: $(securezip.secureFilePath)

Azure DevOps pipeline cannot expand any of the environment variables at runtime

I'm having an issue with a new pipeline I'm setting up for a microservice on Azure DevOps where the pipeline seems to be unable to reference environment variables provided by the build environment.
I have a step in my pipeline that runs a Powershell script that prints out all the environment variables for debugging purposes and this allows me to confirm that the environment does indeed contain the variables I am trying to use.
These variables are BUILD_DEFINITIONNAME = my-microservice-repo and BUILD_BUILDNUMBER = 20200519.2. Essentially I want to combine these two variables to create another variable to name my docker container so I'd have a variable equal to $(BUILD_DEFINITIONNAME):$(BUILD_BUILDNUMBER) which should expand out into my-microservice-repo:20200519.2. We will call this variable imageName. I have defined it in my variables section on my .yml script as
variables:
- name: imageName
value: $(BUILD_DEFINITIONNAME):$(BUILD_BUILDNUMBER)
However, if I try to use this variable on my Docker steps:
- task: Docker#0
inputs:
dockerFile: Dockerfile
azureSubscriptionEndpoint: 'endpoint'
azureContainerRegistry: 'my container registry'
imageName: $(imageName)
action: 'Build an image'
- task: Docker#0
inputs:
azureSubscriptionEndpoint: 'endpoint'
azureContainerRegistry: 'my container registry'
action: 'Push an image'
imageName: $(imageName)
Then when the script runs, I get this error: ##[error]invalid argument "myazurecontainerregistry.azurecr.io/$(build_definitionname):$(build_buildnumber)" for "-t, --tag" flag: invalid reference format
So clearly it's concatenating the strings correctly since I get $(build_definitionname):$(build_buildnumber), however, they're not being expanded, despite the fact that they both exist within the printed variables as I mentioned earlier.
Is there something special I need to do to allow environment variables to be used within my script? We have other pipeline scripts that are working just fine that I copied this yml script from, but mine refuses to work and I can't figure out why, nor can my colleagues.
Any help would be greatly appreciated.
Figured it out. I was misnaming the variables I wanted to use.
$(BUILD_BUILDNUMBER) should have been $(Build.BuildNumber).

Is it possible to set an VSTS Build variable in a Build Step so that the value can be used in a subsequent Build Step?

I'm currently using Build in Visual Studio Team Services (was Visual Studio Online), and would like to be able to set a Build Variable in a Build Step so that the new value can be used in a subsequent Build Step.
Obviously you can set it before the Build starts but I'm looking to late bind the variable during a subsequent Build Step.
Is this possible?
When inside of a script you can update a variable by emitting the following in your ps1
"##vso[task.setvariable variable=testvar;]testvalue"
You can then pass the variable into the next script using $(testvar)
This doc from the API talks about what ##vso commands you can use.
Don't forget to set system.debug to true. It seems there is a bug that muted stdout and thus, all ##vso are not working.
https://github.com/Microsoft/vso-agent-tasks/blob/master/docs/authoring/commands.md
You can create a powershell script an reference it as a build task.
Then inside your powershell scripts add this:
"##vso[task.setvariable variable=key]value"
After that on all your tasks you can read the variable as $(key).
If you want to protect your variable, use:
"##vso[task.setvariable variable=secretVar;issecret=true]value"
And then use it as $(secretVar) in your next tasks.
I found this link helpful: https://learn.microsoft.com/en-us/azure/devops/pipelines/scripts/logging-commands?view=azure-devops&tabs=powershell
This has the complete options of what you can do: https://learn.microsoft.com/en-us/azure/devops/pipelines/process/variables?view=azure-devops&tabs=yaml%2Cbatch
You can reuse set variable from task to task, and also job to job. I couldn't find anything on stage to stage.
In summary:
jobs:
# Set an output variable from job A
- job: A
pool:
vmImage: 'vs2017-win2016'
steps:
- powershell: echo "##vso[task.setvariable variable=myOutputVar;isOutput=true]this is the value"
name: setvarStep
- script: echo $(setvarStep.myOutputVar)
name: echovar
# Map the variable into job B
- job: B
dependsOn: A
pool:
vmImage: 'ubuntu-16.04'
variables:
myVarFromJobA: $[ dependencies.A.outputs['setvarStep.myOutputVar'] ] # map in the variable
# remember, expressions require single quotes
steps:
- script: echo $(myVarFromJobA)
name: echovar