Azure Devops REST API Automation
, automation | azure
I have worked on a deployment solution by use of Azure Devops and wanted a generic way to automate start of Azure Devops pipelines from a production server. An Azure Devops deployment pipeline was setup to deliver the build artifact and a Windows Scheduled Task was setup on the production server. The execution time of the task was beyond the timeout of a Azure Devops pipeline and hence needed a way to decouple deployment from task execution in order to obtain information when the task was done.
The solution was two pipelines in Azure Devops. One pipeline for deployment and one pipeline for post trigger after the task execution was done. The deployment pipeline was either triggered manually or by build pipeline dependency. The post trigger pipeline was started by the following Python script using the Azure Devops REST API:
In short the script calls the REST API backend requesting a specific Azure Devops pipeline to be started. This is
possible if 'sourceVersion', 'branch', and 'pipeline_definition_id' are defined. The pipeline definition id can be found
in the Azure Devops Pipelines URL when an already created pipeline is selected. Additional a build token ( Azure
Devops PAT ) is required and must be placed in the home folder of the execution user.
At build time save the Azure Devops source version and branch to file and store the information in the build artifact:
At execution time call the Python script on the production server:
Adding this to the final step in task execution will trigger the specified Azure Devops pipeline which can do
whatever is needed such as cleanup, save files and/or report errors. I choose to add the 'sourceVersion', 'branch',
and 'pipeline_definition_id' to the build artifact as files allowing the script to be called from any deployment and still
have the correct artifact information. Change this with respect to your deployment needs and workflow. The script
has not been tested on a Linux distribution. Change accordingly if you want to use it on Linux.
The solution was two pipelines in Azure Devops. One pipeline for deployment and one pipeline for post trigger after the task execution was done. The deployment pipeline was either triggered manually or by build pipeline dependency. The post trigger pipeline was started by the following Python script using the Azure Devops REST API:
import os
import sys
import base64
from pathlib import Path
import requests
from requests.structures import CaseInsensitiveDict
sourceVersion = ""
if len( sys.argv ) > 1:
sourceVersion = sys.argv[1]
branch = "refs/heads/master"
if len( sys.argv ) > 2:
branch = sys.argv[2]
pipeline_definition_id = 74
if len( sys.argv ) > 3:
pipeline_definition_id = int( sys.argv[3] )
token_file = "build_token"
token_path = os.path.join( Path.home(), token_file )
with open( str( token_path ) ) as f:
token = f.readline().rstrip()
url = "https://dev.azure.com/{organization}/{project}/_apis/build/builds?api-version=6.0"
userpass = ':' + token
encoded_u = base64.b64encode(userpass.encode()).decode()
headers = CaseInsensitiveDict()
headers["Authorization"] = "Basic %s" % encoded_u
headers["Content-Type"] = "application/json"
headers["Content-Length"] = "0"
payload = '{ "definition": { "id": %d }, "sourceBranch": "%s", "sourceVersion": "%s", "reason": 1, "demands": [] }' % ( pipeline_definition_id, branch, sourceVersion )
resp = requests.post( url, headers=headers, data=payload )
print( payload )
print( resp.status_code )
At build time save the Azure Devops source version and branch to file and store the information in the build artifact:
Set-Content -Path git-fullhash -Value "$(Build.SourceVersion)"
Set-Content -Path git-branch -Value "$(Build.SourceBranch)"
$gitfullhash = Get-Content -Path "git-fullhash" -TotalCount 1
$gitbranch = Get-Content -Path "git-branch" -TotalCount 1
& python.exe post_trigger.py $gitfullhash $gitbranch $post_pipeline_id 2>&1 > post_trigger_log.txt