Equivalent for TeamCity's system.build.start.date in Azure Pipelines - azure-devops

Is there an equivalent for the TeamCity variable system.build.start.date in Azure Pipelines? I couldn't find it in the predefined variables (https://learn.microsoft.com/en-us/azure/devops/pipelines/build/variables?view=vsts)

It doesn't appear like there is. It is available on the Get Builds API though. You could add a custom PowerShell task as the first step and use it to set a variable for future tasks to reference within the same Agent phase.
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes((":{0}" -f $env:SYSTEM_ACCESSTOKEN)))
$uri = "https://dev.azure.com/{oraganization}/{project}/_apis/build/builds/$($env:BUILD_BUILDID)?api-version=5.0"
$buildStartTime = Invoke-RestMethod -Uri $uri -Method Get -Headers #{Authorization=("Basic {0}" -f $base64AuthInfo)} |
Select-Object -ExpandProperty startTime
Write-Host "##vso[task.setvariable variable=BuildStartTime;]$buildStartTime"

Related

Azure DevOps Server - pause/resume all pipelines during maintenance window

We have an Azure DevOps Server (on prem) and different build/release pipelines.
A build/release is depending to other systems. Now if we plan to do maintenance work on this other systems, no Azure build/release pipeline should be run during this time because of the dependency of this systems.
We can go to every pipeline and set the pipeline to "pause". This is working well for a small numbers of build/release pipelines, but if we have a lot of pipelines this would be time-consuming to enabled-disable all pipelines.
Is there any way to pause/resume all Azure Pipelines at the same time? (e.g. TeamCity has a simple flag to pause/resume the whole queue).
I checked the API, but there is also no way to disable the queue itself (change setting on the build/release pipeline). It this would be possible, we could loop through every pipeline definition and pause/resume the queue.
You can disable the agents to prevent the pipeline from running.
Go the Agent Pools under Pipelines in Project settings-->Select the agent pool -->Go to Agents tab-->Disable all the agents.
You can also use rest api to pause the build pipeline mentioned in the comments. See below example in powershell scripts: See here to get a personal access token.
$PAT="Personal Access Token"
$base64AuthInfo= [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($PAT)"))
#list build definiations api
$url = "https://dev.azure.com/org/proj/_apis/build/definitions?api-version=6.1-preview.7"
#list all build definitions
$AllDefinitons = Invoke-RestMethod -Uri $url1 -Headers #{Authorization = ("Bearer {0}" -f $base64AuthInfo)} -Method get
#get all the definition ids
$Ids = $AllDefinitons.value | select id
foreach($id in $Ids){
$definitionUrl="https://dev.azure.com/org/proj/_apis/build/definitions/$($id.id)?api-version=6.1-preview.7"
#get the definition of each build pipeline
$definiton = Invoke-RestMethod -Uri $definitionUrl-Headers #{Authorization = ("Bearer {0}" -f $base64AuthInfo)} -Method get
#set queueStatus to paused
$definiton.queueStatus= "paused"
#update the definition
Invoke-RestMethod -Uri $definitionUrl-Headers #{Authorization = ("Basic {0}" -f $base64AuthInfo)} -Method put -Body (ConvertTo-Json $definiton-Depth 100) -ContentType "application/json"
}

Azure DevOps pipelines: Cancel multiple pending jobs in queue

In Azure DevOps pipelines, How do I cancel all pending jobs for a job pool. I've got lots queued and couldn't see where I can cancel all the jobs I have waiting.
Azure devops doesnot yet have this feature to cancel all the pending jobs in batch from the UI partal.
You can write scripts to call rest api to cancel all the pending jobs as walkaround. Check out below steps:
First, use list build rest api to get all the pending jobs.
https://dev.azure.com/{organization}/{project}/_apis/build/builds?statusFilter=notStarted&api-version=5.1
Then, use update build api to cancel the pending jobs:
PATCH https://dev.azure.com/{organization}/{project}/_apis/build/builds/{buildId}?api-version=5.1
See below powershell scripts for reference:
Check here to get a Personal access token that will be used in below scripts.
$url= "https://dev.azure.com/{organization}/{project}/_apis/build/builds?statusFilter=notStarted&api-version=5.1"
$pat="Personal Access Token"
$base64AuthInfo= [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($pat)"))
$pendingJobs=Invoke-RestMethod -Uri $url-Headers #{Authorization = ("Basic {0}" -f $base64AuthInfo)} -Method get -ContentType "application/json"
$jobsToCancel = $pendingJobs.value
#Pending jobs donot consume the job agents in the agent pool. To filter the definition name to cancel pending jobs for a particular pipeline, you can use below filter criteria.
#$jobsToCancel = $pendingJobs.value | where {$_.definition.Name -eq "{Name of your pipeline }"}
#call update api to cancel each job.
ForEach($build in $jobsToCancel)
{
$build.status = "Cancelling"
$body = $build | ConvertTo-Json -Depth 10
$urlToCancel = "https://dev.azure.com/{organization}/{project}/_apis/build/builds/$($build.id)?api-version=5.1"
Invoke-RestMethod -Uri $urlToCancel -Method Patch -ContentType application/json -Body $body -Header #{Authorization = ("Basic {0}" -f $base64AuthInfo)}
}
You can also submit a new feature request(Click Suggest a feature and choose azure devops) to Microsoft development team for supporting cancelling pending jobs in batch. Hopefully they will consider adding this feature in the future sprint.
I find that using v6 of the api works, but instead of PATCH use DELETE.
(Reusing some of the code from #Levi Lu-MSFT)
$url= "https://dev.azure.com/{organization}/{project}/_apis/build/builds?statusFilter=notStarted&api-version=6.0-preview"
$pendingJobs=Invoke-RestMethod -Method GET -UseDefaultCredentials -Uri $url -ContentType "application/json"
$jobsToCancel = $pendingJobs.value
#$jobsToCancel = $pendingJobs.value | Where {$_.definition.Name -eq "{Name of your pipeline }"}
ForEach($build in $jobsToCancel)
{
$urlToCancel = "https://dev.azure.com/{organization}/{project}/_apis/build/builds/$($build.id)?api-version=6.0-preview"
Invoke-RestMethod -Uri $urlToCancel -Method DELETE -UseDefaultCredentials -ContentType application/json -Body $body
}

Is it possible to get a release pipeline creation date on Azure Devops/TFS?

I was wondering if it is possible to find the exact creation date as a predefined variable for a Release in Azure Devops. In release pipelines it can be seen as an actual column labeled "Created" (along with "Releases" and "Stages" to the left and right of "Created" respectively) - so I know that the data is stored somewhere.
The only variable I have been able to find is Release.Deployment.StartTime - which is the time the release deployment begins, which can be hours or even days after Release Creation, so not quite what I want.
Is there a way to do this? I attached a screenshot to show what I am trying to get.
What about $(SYSTEM_PIPELINESTARTTIME) ?
I like this task which dumps all the variables for you. I have it at the start of all my dev pipelines: https://marketplace.visualstudio.com/items?itemName=dutchworkz.DisplayAllVariables
You can also do it with powershell if you don't have access to install extensions:
Get-ChildItem Env: | Format-Table -Wrap -AutoSize
If none of the variable work you can also publish your own variable with a Powershell task. It will be about 5-10 seconds later than the real stage execution time:
$DateTime = (Get-Date).ToString("yyyyMMdd_HHmm")
Write-Host "##vso[task.setvariable variable=DateTime;]$DateTime"
You always can run a rest api call to see release details. Here is the example of a stage step with powershell:
$user = ""
$token = "$(System.AccessToken)"
$teamProject = "$(System.TeamProject)"
$releaseId = "$(Release.ReleaseId)"
$orgUrl = "$(System.CollectionUri)"
$orgUrlrel = $orgUrl -replace "dev", "vsrm.dev"
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $user,$token)))
$uriGetRelease = "$orgUrlrel/$teamProject/_apis/release/releases/$releaseId"+"?api-version=5.1"
$resultStatus = Invoke-RestMethod -Uri $uriGetRelease -Method Get -ContentType "application/json" -Headers #{Authorization=("Basic {0}" -f $base64AuthInfo)}
Write-Host "Created date:" $resultStatus.createdOn
Additionally, you have to enable access to the token:

How to modify Azure DevOps release definition variable from a release task?

What is the easiest way to get key rotation to work for azure storage accounts from a AzureDevOps relase task? The current plan is to re-generate the old key after release to invalidate it, and have a fresh key that can be used on next deployment. But to get that to work it seems like I at least need to store the name of the key to use in a release variable.
I had a look at he logging tasks (https://github.com/Microsoft/azure-pipelines-tasks/blob/master/docs/authoring/commands.md), but that only changes the value in the current release and does not modify the release definition.
You can use the REST API (Definitions - Update) to update the value of the release definition variable from a release task.
Go to the Agent Phase and select Allow Scripts to Access OAuth Token. See Use the OAuth token to access the REST API
Grant Project Collection Build Service (xxx) account the edit
release pipeline permission. (Select the release pipeline --> ... --> Security --> Edit release definition set to Allow)
Add a PowerShell task in your release pipeline
Run inline script: (Update the value of variable v1030 in below sample)
$url = "$($env:SYSTEM_TEAMFOUNDATIONSERVERURI)$env:SYSTEM_TEAMPROJECTID/_apis/Release/definitions/$($env:RELEASE_DEFINITIONID)?api-version=5.0-preview.3"
Write-Host "URL: $url"
$pipeline = Invoke-RestMethod -Uri $url -Headers #{
Authorization = "Bearer $env:SYSTEM_ACCESSTOKEN"
}
Write-Host "Pipeline = $($pipeline | ConvertTo-Json -Depth 100)"
# Update an existing variable named v1030 to its new value 1035
$pipeline.variables.v1030.value = "1035"
####****************** update the modified object **************************
$json = #($pipeline) | ConvertTo-Json -Depth 99
$updatedef = Invoke-RestMethod -Uri $url -Method Put -Body $json -ContentType "application/json" -Headers #{Authorization = "Bearer $env:SYSTEM_ACCESSTOKEN"}
write-host "=========================================================="
Write-host "The value of Varialbe 'v1030' is updated to" $updatedef.variables.v1030.value
write-host "=========================================================="
Here is a much cleaner and better solution that also allows for multiple builds being triggered simultaneously.
https://tsuyoshiushio.medium.com/how-to-pass-variables-with-pipeline-trigger-in-azure-pipeline-5771c5f18f91
Essentially your triggering build produces artifacts that your triggered build reads and turns into variables.
Still not at all great, but better than nothing and better than REST calls setting static global variable groups.
The other answer above talks about how to update Release pipelines.
If you would like to update a Build Pipeline's variables, here is how you do that:
Edit build pipeline
Go to the Agent Phase and select Allow Scripts to Access OAuth Token. See Use the OAuth token to access the REST API
Go to Manage Security -> Users -> Select Project Collection Build Service (YOUR TEAM NAME HERE)
Change "Edit Build Definitions" to Allow
Now add a powershell stage - 2.x - inline script called Update variables.
Script inline contents:
$api_version='5.0-preview.6'
$url = "$($env:SYSTEM_TEAMFOUNDATIONSERVERURI)$env:SYSTEM_TEAMPROJECTID/_apis/build/definitions/$(System.DefinitionId)?api-version=${api_version}"
Write-Host "URL: $url"
$pipeline = Invoke-RestMethod -Uri $url -Headers #{
Authorization = "Bearer $env:SYSTEM_ACCESSTOKEN"
}
Write-Host "Pipeline = $($pipeline | ConvertTo-Json -Depth 100)"
# Update variables as desired here:
$pipeline.variables.mavenBuildVersionPatch.value = "2401"
####****************** update the modified object **************************
$json = #($pipeline) | ConvertTo-Json -Depth 99
$updatedef = Invoke-RestMethod -Uri $url -Method Put -Body $json -ContentType "application/json" -Headers #{Authorization = "Bearer $env:SYSTEM_ACCESSTOKEN"}
write-host "=========================================================="
Write-host "The value of Variable mavenBuildVersionPatch is updated to" $updatedef.variables.mavenBuildVersionPatch.value
write-host "=========================================================="
Take note of the API version in this script is 5.0-preview.6.
If your version of Azure Devops is newer, you may need to update this in the future.
Save build pipeline.
Now when you run job, after the job completes this powershell stage, this variable will be set.
Important: If you want to update a variable then make the updated variable for other pipeline stages, then you do it with a powershell stage with the following inline script:
$mavenBuildVersionPatch = [int]"$(mavenBuildVersionPatch)"
$mavenBuildVersionPatch = $mavenBuildVersionPatch + 1
Write-Host "##vso[task.setvariable variable=mavenBuildVersionPatch;]$mavenBuildVersionPatch"
This example would take our existing patch number and increment it by 1.
This does not save the variable at the end of the job, you still need to do that with another powershell script if desired.

VSTS build history for a Build definition

I have a VSTS build definitions in our project, Can i get the build results (passed/failed) that ran using that definition (builds started running using the definition since last 6 months) ?
Currently i am only getting last 20 build information ran from that build definition.
You can get it through Build REST API with PowerShell: Get a list of builds.
For example:
param(
[string]$sinceDate,
[string]$token,
[string]$defId
)
$uri="https://[acccount.visualstudio.com/DefaultCollection/[project]/_apis/build/builds?definitions=$defId&deletedFilter=1&minFinishTime=$sinceDate"
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f "test",$token)))
$result= Invoke-RestMethod -Method Get -Uri $Uri -ContentType "application/json" -Headers #{Authorization=("Basic {0}" -f $base64AuthInfo)}
$statusResult=$result.value | select-object -Property id,buildNumber,result
Arguments:
-sinceDate "12/1/2017" -token "[personal access token]" -defId "94"