From within a run of Azure Pipeline build, is there any way to get the URL of the build that is running?
Something like:
https://dev.azure.com/{organization}/{project}/_build/results?buildId={build_number}
I would have assumed that it would have been available as one of the environment variables, but it doesn't seem to be.
This one will work using all predefined variables
$buildUrl="$(System.TeamFoundationCollectionUri)$(System.TeamProject)/_build/results?buildId=$(Build.BuildId)"
Write-Host $buildUrl
There is no pre-defined variable of the build URL, but you can get it easily because you have a variable for the build id:
steps:
- powershell: |
$buildUrl = "https://dev.azure.com/$(System.TeamFoundationCollectionUri)$(System.TeamProject)/_build/results?buildId=$(Build.BuildId)"
Write-Host "##vso[task.setvariable variable=buildUrl;]$buildUrl"
displayName: 'Set build url variable'
In the next step I print the $(buildUrl) variable:
Here is alternative using System.CollectionUri variable which name is more generic, not specific to TFS. There is no equivalent with project name, so System.TeamProject has to be used, which will also work for GitHub repository.
The composed URL can be cached in Azure Pipelines variable in pipeline or job scope:
variables:
MyResultsUrl: '$(System.CollectionUri)$(System.TeamProject)/_build/results?buildId=$(Build.BuildId)'
Adding query parameter ?view=logs you can make the URL jump straights to the logs.
Related
In Azure DevOps, I created a Build. In that Build I created a ProjectBuildNumber Pipeline variable that is Settable at queue time. That variable is then used under Options -> Build number format to set my build number displayed in Azure.
However, I am trying to make that ProjectBuildNumber variable settable in the code I am building/deploying. Is there a way I can have a Task in my Build to update that ProjectBuildNumber and update the Build number in Azure DevOps?
Is there a way I can have a Task in my Build to update that ProjectBuildNumber and update the Build number in Azure DevOps?
The answer is yes.
You could add a Inline Power-Shell task in your build definition to update the value of ProjectBuildNumber and then update the build number base on the it:
Write-Host "##vso[task.setvariable variable=ProjectBuildNumber;]YourUpdateValue"
Write-Host "##vso[build.updatebuildnumber]xxx.$(ProjectBuildNumber).xxx.xxx"
Check the Logging Command during the build for some more details:
Besides, if you want to update the value of a Pipeline Variable on the UI/web portal, you need the REST API (Definitions - Update) to update the value of the build pipeline definition variable from a build task.
There is a very similar thread, you can check the answer for the details:
How to modify Azure DevOps release definition variable from a release task?
Note:Change the API to the build definitions:
PUT https://dev.azure.com/{organization}/{project}/_apis/build/definitions/{definitionId}?api-version=5.0
Hope this helps.
We can update Build Number in Azure Devops via two ways .
One from Option Section/Tab and 2nd Via PowerShell Scripts.
To update the build number from Power shell Script.. We need to add following script..
Write-Host "##vso[build.updatebuildnumber]$(VersionNumber).$(VersionRevision)"
Here we have used 2 variables : VersionNumber and VersionRevision.
We need to add 2 variables in PipeLine Configurations..
VersionNumber will be the desired number and VersionRevision is the counter number that will be updated every time, when ever we will create a new build.
Please check the complete demonstration from You tube video
https://youtu.be/WBmFTmzopiQ
Have created power shell task for that
# replace existing Build.BuildNumber with
# NAME_2.1.2.54_20211220.16_345
- task: PowerShell#2
displayName: 'Update Version Number'
inputs:
targetType: 'inline'
script: |
$lines = Get-ChildItem ".\Project\My Project\AssemblyInfo.vb"
$match = $lines | Select-String -Pattern "\<Assembly\:\s+AssemblyVersion\(""(\d+\.\d+\.\d+\.\d+)""\)\>"
$version = $match.Matches[0].Groups[1].Value
[Version]::Parse($version) # validate
$tag = "NAME_$($version)_$(Build.BuildNumber)_$(Build.BuildId)"
Write-Host "##vso[build.updatebuildnumber]$tag"
Check out the Microsoft documentation on this: Variables
Depending on your operating system you can add a Powershell/Batch/Bash Task and change the variable.
Edit: After some research it appears that the change of the variable will show up in the following task. Take a look at this issue Update environment variables using task.setvariable in a bash script does not work
I have an Azure Devops release pipeline (using the Classic Editor rather than yaml) and am having trouble setting a variable in an inline powershell script. The relevant part of the script is this:
Write-Host "Web is $web"
Write-Host "App is $app"
Write-Host "##vso[task.setvariable variable=MyWebEnv;]$web"
Write-Host "Set Web to $($MyWebEnv)"
Write-Host "##vso[task.setvariable variable=MyAppEnv;]$app"
Write-Host "Set App to $(MyAppEnv)"
The log files indicate that my $web and $app variables hold the correct values, however the setting is not working.
I've tried writing out the value in both the $($env:MyWebEnv) and $(MyWebEnv) formats and both formats indicate that the ADO variable has not been set correctly.
My variable is defined in the variables tab on the pipeline. It is set to Settable at queue time. I have tried with no value set in the definition and an initial value and I can see that the initial value does not get overwritten.
I've tried running this on both a self-hosted agent and an Azure Pipelines Hosted agent - same results. I have another release pipeline that does something similar without issues.
I'm trying to use the variable in a subsequent Stage.
I don't want to write the variable to a file or anything as I want to use the variable to control whether the stage even runs.
Edit:
Based on Levi's comment I tried adding isOutput=true and inspecting the variable in a subsequent step in the same stage - it's not visible even within a subsequent step:
=========================================================================
Edit 2:
I must have had a non visible character somewhere. I was composing the powershell in an external editor (just so I had more space) and pasting into the inline textbox in ADO - when I typed in the exact same thing I had into the editor it started working - sort of.
I can set the variable now and it's appearing in the task below, but what I really want is to use it in the next stages - in the IIS deployment group to control that IIS server A runs, but IIS server B doesn't. I'm attempting to do this in the Additional Options Run Expression.
I've tried
and(succeeded(), eq(variables['MyWebEnv'], 'myvalue')
or (where MyOutput. is the name given to my output reference when setting the variable)
and(succeeded(), eq(variables['MyOutpub.MyWebEnv'], 'myvalue')
or
and(succeeded(), eq(variables['MyOutpub_MyWebEnv'], 'myvalue')
To clarify, I'm doing this on the IIS Deployment Group itself, and not on any of the tasks within that group.
I keep seeing that the deployment is skipped due to:
Evaluating: eq(variables['MyOutput,MyWebEnv'], 'myvalue') Expanded: eq(Null, 'myvalue') Result: False
The variable you were trying to set in the powershell task will only take effect in the following tasks, which means if you echo out the variable in its own powershell task, it will not output the overriden value. See here.
To set a variable from a script, you use the task.setvariable logging command. This doesn't update the environment variables, but it does make the new variable available to downstream steps within the same job.
So you can only refer to it in the downstream tasks by wrapping it around $(). See below:
steps:
- powershell: |
Write-Host "##vso[task.setvariable variable=MyWebEnv]$web"
- powershell: |
Write-Host "Set Web to $(MyWebEnv)"
If you want to use it in a subsequent stage. You will have to make the variable to be an output variable by using isOutput=true. See here
- powershell: |
Write-Host "##vso[task.setvariable variable=MyWebEnv;isOutput=true]$web"
name: MyVariable
- powershell: echo "$(MyVariable.MyWebEnv)"
You should also give this powershell task a name in order to refer to it in the following stages. See here to learn how to refer to multiple stage output variables.
variables:
web: $[stageDependencies.stageName.jobName.outputs['stepName.variableName']]
You also need add dependency on this stage for the following stages.
See below example:
stages:
- stage: VariableStage
jobs:
- job: VariableJob
steps:
- powershell: |
$web = "---"
Write-Host "##vso[task.setvariable variable=MyWebEnv;isOutput=true]$web"
name: MyVariable
- stage:
dependsOn: VariableStage
variables:
web: $[stageDependencies.VariableStage.VariableJob.outputs['MyVariable.MyWebEnv']]
jobs:
- job:
steps:
- powershell: echo "$(web)"
As Levi Lu mentioned you can access pipeline variables in the next step. So if you set variables like this here:
$web ="some-web"
$app ="some-app"
Write-Host "##vso[task.setvariable variable=MyWebEnv;]$web"
Write-Host "##vso[task.setvariable variable=MyAppEnv;]$app"
then you can read them in this way:
Write-Host "Set Web to $(MyWebEnv)"
Write-Host "Set App to $(MyAppEnv)"
And if you want to access them via env variables you should use this syntax:
Write-Host "Set Web to $($env:MYWEBENV)"
Write-Host "Set App to $($env:MYAPPENV)"
Answer for EDIT 2:
What you actually need is output cross stage variables which is supported in YAML but not in classic pipelines. Please check this topics. You can overcome this but it requires an extra effort as it shown here. However, please remember that you can't publish an artifact from release pipeline.
Here you have docs for cross stage variables but as above, it works on YAML.
I have a pipeline in Azure DevOps somewhat like this:
parameters:
- name: Scenario
displayName: Scenario suite
type: string
default: 'Default'
variables:
Scenario: ${{ parameters.Scenario }}
...
steps:
- script: echo Scenario is $(Scenario)
And I'm executing the pipeline via the VSTS CLI like this:
vsts build queue ... --variables Scenario=Test
When I run my pipeline, it seems that the parameter default value overwrites my cmd line specified variable value and I get the step output Scenario is Default. I tried something like Scenario: $[coalesce(variables['Scenario'], ${{ parameters.Scenario }})] but I think I got the syntax wrong because that caused a parsing issue.
What would be the best way to only use the parameter value if the Scenario variable has not already been set?
What would be the best way to only use the parameter value if the
Scenario variable has not already been set?
Sorry but as I know your scenario is not supported by design. The Note here has stated that:
When you set a variable in the YAML file, don't define it in the web editor as settable at queue time. You can't currently change variables that are set in the YAML file at queue time. If you need a variable to be settable at queue time, don't set it in the YAML file.
The --variables switch in command can only be used to overwrite the variables which are marked as Settable at queue time. Since yaml pipeline doesn't support Settable variables by design, your --variables Scenario=Test won't actually be passed when queuing the yaml pipeline.
Here're my several tests to prove that:
1.Yaml pipeline which doesn't support Settable variable at Queue time:
pool:
vmImage: 'windows-latest'
variables:
Scenario: Test
steps:
- script: echo Scenario is $(Scenario)
I ran the command vsts build queue ... --variables Scenario=Test123, the pipeline run started but the output log would always be Scenario is Test instead of expected Scenario is Test123. It proves that it's not Pipeline parameter overwrites variable value, instead the --variables Scenario=xxx doesn't get passed cause yaml pipeline doesn't support Settable variables.
2.Create Classic UI build pipeline with pipeline variable Scenario:
Queuing it via command az pipelines build queue ... --variables Scenario=Test12345(It has the same function like vsts build queue ... --variables Scenario=Test) only gives this error:
Could not queue the build because there were validation errors or warnings.
3.Then enable the Settable at queue time option of this variable:
Run the same command again and now it works to queue the build. Also it succeeds to overwrite the original pipeline variable with the new value set in command-line.
You can do similar tests like what I did to figure out the cause of the behavior you met.
In addition:
VSTS CLI has been deprecated and replaced by Azure CLI with the Azure DevOps extension for a long time. So now it's more recommend to use az pipelines build queue
instead.
Lance had a great suggestion, but here is how I ended up solving it:
- name: Scenario
displayName: Scenario suite
type: string
default: 'Default'
variables:
ScenarioFinal: $[coalesce(variables['Scenario'], '${{ parameters.Scenario }}')]
...
steps:
- script: echo Scenario is $(ScenarioFinal)
In this case we use the coalesce expression to assign the value of a new variable, ScenarioFinal. This way we can still use --variables Scenario=Test via the CLI or use the parameter via the pipeline UI. coalesce will take the first non-null value and effectively "reorder" the precedence Lance linked to here: https://learn.microsoft.com/en-us/azure/devops/pipelines/process/variables?view=azure-devops&tabs=yaml%2Cbatch#expansion-of-variables
(Note that there need to be single quotes around the parameter reference '${{}}' because the ${{}} is simply converted to to the value, but then the coalesce expression doesn't know how to interpret the raw value unless it has the single quotes around it to denote it as a string)
Note that the ability to set parameters via the CLI is a current feature suggestion here: https://github.com/Azure/azure-devops-cli-extension/issues/972
I have an Azure DevOps online and want to set Buildnumber as ImageTag variable, to use it later as Image tag for docker image. To do so, I created empty variable ImageTag on the variables tab:
And add PS script:
Write-Host "Buildnumber is $(Build.BuildNumber)"
$ImageTagVar = "$(Build.BuildNumber)"
Write-Host "##vso[task.setvariable variable=ImageTag;]$ImageTagVar"
Write-Host "Set environment variable to $env:ImageTag"
Write-Host "Set environment variable1 to $ImageTag"
The problem is that content from $(Build.BuildNumber) does not pass to variable ImageTag:
Can anyone hint me, what am I doing wrong in Azure DevOps?
You will see it on next steps of your build pipeline:
Steps in build definition:
Step 1
Step 2
Build results
Step 1
Step 2
If you just want to tag the docker image with buildNumber, you do not need to define the ImageTag variable. You can directly use $(Build.BuildNumber) in the docker build task.
If you have to define the ImageTag variable, you can directly assign $(Build.BuildNumber) to it.
I am trying to include the 7-digit git hash in the artifact name built by my Azure Devops build pipeline. In my build agent job I have an inline powershell script with the following lines:
$commitId = "$(Build.SourceVersion)"
$shortCommitId = ("$commitId").SubString(0,7)
In the options for the Powershell script under "Output variables" I add a reference name: ps.
Then in the Publish Artifact step right after my Powershell step I set the artifact name as:
$(ApplicationName)_Rel_$(ps.shortCommitId)_$(build.buildnumber)
The actual result after the pipeline has finished running is:
MyApplication_Rel_$(ps.shortCommitId)_20190918.1
How do I pass the variable shortCommitId between steps so that it will be part of the artifact name? MyApplication_Rel_04f53f_20190918.18.
Just add another line that create a variable to the next steps:
Write-Host "##vso[task.setvariable variable=shortCommitId;]$shortCommitId"
In the Publish Artifacts task use the varaible $(shortCommitId):
$(ApplicationName)_Rel_$(shortCommitId)_$(build.buildnumber)
Another option, if you want to use it as an output varaible, is to add isOutput=true:
Write-Host "##vso[task.setvariable variable=shortCommitId;isOutput=true]$shortCommitId"
And now you can use the $(ps.shortCommitId).