I am trying to set an environment variable to use it in another task but it doesn't work.
The first task should set the variable "versionTag" so I can use it in the next task as $(versionTag).
Can anyone help me with this?
- task: Bash#3
displayName: Create version tag
inputs:
targetType: 'inline'
script: |
versionTag=$(echo "$(Build.BuildNumber)" | tr '+' '-')
echo "versionTag: ${versionTag}"
echo "##vso[task.setvariable variable=versionTag]${versionTag}"
- task: Docker#2
displayName: Create runtime docker image
inputs:
containerRegistry: '$(dockerRegistryServiceConnection)'
repository: '$(imageRepository)'
command: 'build'
Dockerfile: '$(dockerfilePath)'
buildContext: '$(Build.SourcesDirectory)'
tags: |
$(tags)
$(versionTag)
There's a magic command string you can write to the log:
echo "##vso[task.prependpath]c:\my\directory\path"
The path will be updated for the scope of the Job. If your pipeline has multiple jobs, you need to issue the same command for future jobs as well.
The updated path will be available in the next step. Not in the step in which you issue the command.
Related
I have a build process where I need to use a token, received through the AWSCLI. So far I have connected aws to my azure pipelines but I am having trouble setting up my yaml.
I want to fetch the relevant token to use it later as a variable in my script.
As you can see in my yaml I am running a powershell script with codeartifact and I am saving the value to my myOutputVar. The powershell script does not throw an error.
However, later when I run the building script that variable is not present resulting in ECHO is off.
How can I ensure the value received in the task can be used later in the script/build part?
trigger:
- azure-pipelines
pool:
vmImage: windows-latest
steps:
- task: NodeTool#0
inputs:
versionSpec: '10.x'
displayName: 'Install Node.js'
- task: AWSPowerShellModuleScript#1
inputs:
awsCredentials: 'AWS Connection'
regionName: 'eu-central-1'
scriptType: 'inline'
inlineScript: '##vso[task.setvariable variable=myOutputVar;]aws codeartifact get-authorization-token --domain somedomain --domain-owner 444.... --query authorizationToken --output text; '
- script: |
echo %myOutputVar%
npm ci
npm run build
displayName: 'npm install and build'
Your inline script can be multiple lines, and since this is PowerShell you can do something like:
inlineScript: |
$authToken = aws codeartifact get-authorization-token `
--domain somedomain `
--domain-owner 444.... `
--query authorizationToken `
--output text
Write-Host "##vso[task.setvariable variable=myOutputVar;]$authToken"
I have a variable group that i'm using from a python script. Something like this:
- task: PythonScript#0
inputs:
scriptSource: 'inline'
script: |
print('variableInVariableGroup: $(variableInVariableGroup)')
I'd like to write my script so that I can iterate over the variable group without explicitly referencing individual variables. Is there a way to feed in the entire variable group to the script as a dictionary or something similar?
You could not do that directly, for the workaround is to get the vars via azure cli and set with task variable, then get them in the python script task.
Something like below:
# 'Allow scripts to access the OAuth token' was selected in pipeline. Add the following YAML to any steps requiring access:
# env:
# MY_ACCESS_TOKEN: $(System.AccessToken)
# Variable Group 'vargroup1' was defined in the Variables tab
resources:
repositories:
- repository: self
type: git
ref: refs/heads/testb2
jobs:
- job: Job_1
displayName: Agent job 1
pool:
vmImage: ubuntu-20.04
steps:
- checkout: self
persistCredentials: True
- task: PowerShell#2
name: TestRef
displayName: PowerShell Script
inputs:
targetType: inline
script: >-
echo $(System.AccessToken) | az devops login
$a=az pipelines variable-group variable list --org 'https://dev.azure.com/orgname/' --project testpro1 --group-id 3 --only-show-errors --output json
echo "$a"
echo "##vso[task.setvariable variable=allvars;isOutput=true]$a"
- task: PythonScript#0
displayName: Run a Python script
inputs:
scriptSource: inline
script: "b=$(TestRef.allvars)\nprint(b)\n\n "
...
In an Azure Pipeline, I want to set a variable in a Powershell script and then use that variable in a later build step. The variable doesn't print out a value.
In my Powrshell script I hardcode a value for testing purposes:
$packageFolder = 'dotnet/TestPackage/'
##vso[task.setvariable variable=changedPackage;isOutput=true]$packageFolder
Here is my YAML file:
steps:
- task: PowerShell#2
displayName: 'Detect Subfolder Changes'
name: setvarStep
inputs:
targetType: 'filePath'
filePath: $(System.DefaultWorkingDirectory)\detectchanges.ps1
failOnStderr: true
- script: echo "$(setvarStep.changedPackage)"
- task: DotNetCoreCLI#2
displayName: 'dotnet build'
condition: ne('$(setvarStep.changedPackage)', '')
inputs:
projects: '$(setvarStep.changedPackage)'
When the pipeline gets to the script step it just prints out this:
Script contents:
echo "$(setvarStep.changedPackage)"
I don't think the variable is actually set. When the pipeline gets to the dotnet build step it throws an error: ##[error]Project file(s) matching the specified pattern were not found.
While having debugging turned on I noticed this in the dotnet build step logs: ##[debug]findPath: 'C:\agents\librarywin-1\_work\2\s\$(setvarStep.changedPackage)'
I think my issue is the pipeline variable syntax is wrong even though I'm following the example on Microsoft's website. I can't figure it out.
You need double quote the logging command:
detectchanges.ps1:
$packageFolder = 'dotnet/TestPackage/'
"##vso[task.setvariable variable=changedPackage;isOutput=true]$packageFolder"
YAML:
steps:
- task: PowerShell#2
displayName: 'Detect Subfolder Changes'
name: setvarStep
inputs:
targetType: 'filePath'
filePath: $(System.DefaultWorkingDirectory)\detectchanges.ps1
failOnStderr: true
- script: echo "$(setvarStep.changedPackage)"
You should have Write-Host
$packageFolder = 'dotnet/TestPackage/'
Write-Host ##vso[task.setvariable variable=changedPackage;isOutput=true]$packageFolder
like here
I have a Stage that runs my Terraform Code, but I need to whitelist the agent IP on my Azure SQL server, so I have a PowerShell script that can handle this, however, the environment variables inside the script (for instance $env:company_name) are all showing as null I believe because its bash. Not sure....the part of YAML is shown below. Any ideas on how I can accomplish this? Thanks
******************** YAML from pipeline**************************
steps:
- checkout: self
- task: Bash#3
displayName: 'Install AZ Modules'
inputs:
targetType: 'inline'
script: |
sudo /usr/bin/pwsh -NoLogo -NoProfile -NonInteractive -ExecutionPolicy Unrestricted -File "$(Build.Repository.LocalPath)/STAGE2/Scripts/buildazmodule.ps1"
- task: PowerShell#2
displayName: 'Add Firewall Rules'
inputs:
targetType: filePath
filePath: './STAGE2/Scripts/firewallrules.ps1'
- task: ms-devlabs.custom-terraform-tasks.custom-terraform-installer-task.TerraformInstaller#0
inputs:
terraformVersion: '0.12.28'
- script: terraform version
displayName: 'Terraform Version'
- script: az cloud set --name $(cloud)
displayName: 'Set Cloud'
- script: az login --service-principal -u $(client_id) -p $(client_secret) --tenant $(tenant_id)
displayName: 'Log Into Azure'
- script: terraform init -backend-config=resource_group_name=$(sg_resource_group) -backend-config="storage_account_name=$(sg_name)" -backend-config="container_name=$(blob_storage)" -backend-config="access_key=$(sg_accesskey)" -backend-config="key=$(state_file)" -backend-config="environment=$(cloud_environment_name)"
displayName: 'Terraform Init'
workingDirectory: $(System.DefaultWorkingDirectory)/STAGE2
- script: terraform plan -var="client_id=$(client_id)" -var="client_secret=$(client_secret)" -var="tenant_id=$(tenant_id)" -var="subscription_id=$(subscription_id)" -var="environment=$(cloud_environment_name)" -var="company_name=$(company_name)" -var="cloudsitename=$(cloudsitename)" -var="envtype=$(envtype)" -var="builddate=$(builddate)" -var="is_public=$(is_public)" -var="region=$(region)" -var="os_image_skey=$(os_image_skey)" -var="is_osmanaged_ad=$(is_osmanaged_ad)" -var="remote_tenant=$(remote_tenant)" -var="is_fedramp=$(is_fedramp)" -var="level=$(level)" -var="onestream_version=$(onestream_version)" -out="out.plan"
displayName: 'Terraform Plan'
workingDirectory: $(System.DefaultWorkingDirectory)/STAGE2
- script: terraform apply out.plan
displayName: 'Terraform Apply'
workingDirectory: $(System.DefaultWorkingDirectory)/STAGE2
************************ Part of script code***********************
$envtype = $env:envtype
$CompanyName = $env:company_name
$CompanyNameTemp = $CompanyName.ToLower() #input production environment name e.g. the "tmfgroup" in rg"tmfgroup" ***PIPELINE VAR***
$CompanyName = ($CompanyNametemp.subString(0, [System.Math]::Min(8, $CompanyNametemp.Length))).Trim()
$sgname = "sg${CompanyName}"
$rgname = "rg${CompanyName}"
$kvName = "kv${CompanyName}"
$sqlName = "sql${CompanyName}${envtype}"
*************************** Error**********************
InvalidOperation: /home/vsts/work/1/s/STAGE2/Scripts/firewallrules.ps1:4
Line |
4 | $CompanyNameTemp = $CompanyName.ToLower() #input production environme …
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| You cannot call a method on a null-valued expression.
Agree with Krzysztof Madej.
As far as I know, linux system is case sensitive.
When you set the variable in azure devops, it will be converted to uppercase letters in environment variables.
For example:
So when you use the environment variable in Linux system, you need to change the format as
$env:COMPANY_NAME.
By the way, you could use the script to output all environment variables(e.g. env | sort).
Then you could check the environment variable format.
In the azure pipeline yaml files, the variable imgRepoName is trimmed from the gitRepoName. An bash echo for gitRepoName shown core/cqb-api; bash echo for imgRepoName shown cqb-api
variables:
vmImageName: 'ubuntu-18.04'
gitRepoName: $(Build.Repository.Name)
imgRepoName: $(basename $(gitRepoName))
- job: build_push_image
pool:
vmImage: $(vmImageName)
steps:
- task: Docker#2
displayName: Build and Push image
inputs:
repository: imgRepoName
command: buildAndPush
containerRegistry: "coreContainerRegistry"
tags: test2
Issues:
When I wrote repository: "cqb-api" as the input for the docker task it works just fine, while use the variable directly as shown above won't create any images in the container registry.
PS, I also tried repository: $(imgRepoName) it give out the following error
invalid argument "***/$(basenamecore/cqb-api):test2" for "-t, --tag" flag: invalid reference format
It looks that it is executed at runtime. So gitreponame is replaced but basename function is not recognized in this context. You can check this:
variables:
gitRepoName: $(Build.Repository.Name)
steps:
- task: PowerShell#2
inputs:
targetType: 'inline'
script: |
$name = $(basename $(gitRepoName))
Write-Host "##vso[task.setvariable variable=imgRepoName]$name"
- task: Docker#2
displayName: Build and Push
inputs:
repository: $(imgRepoName)
command: build
Dockerfile: docker-multiple-apps/Dockerfile
tags: |
build-on-agent
It works for me.