Search code examples
azure-devopsazure-devops-rest-apiazure-devops-extensionsazure-devops-pipelines

Azure DevOps REST api - Run pipeline with variables


I have a pipeline on Azure Devops that I'm trying to run programatically/headless using the REST api: https://learn.microsoft.com/en-us/rest/api/azure/devops/pipelines/runs/run%20pipeline?view=azure-devops-rest-6.0

So far so good, I can auth and start a run. I would like to pass data to this pipeline which the docs suggests is possible using variables in the request body. My request body:

{
    "variables": {
        "HELLO_WORLD": {
            "isSecret": false,
            "value": "HelloWorldValue"
        }
    }
}

My pipeline YAML looks like this:

trigger: none

pr: none

pool:
  vmImage: 'ubuntu-latest'

steps:
- task: Bash@3
  inputs:
    targetType: 'inline'
    script: |
      KEY=$(HELLO_WORLD)
      echo "Hello world key: " $KEY

This however gives me an error that "HELLO_WORLD: command not found".

I have tried adding a "HELLO_WORLD" variable to the pipeline and enabled the "Let users override this value when running this pipeline"-setting. This results in the HELLO_WORLD variable no longer being unknown, but instead its stuck on its initial value and not set when i trigger a run with the REST api

How do you pass variables to a pipeline using the REST api? It is important that the variable value is set only for a specific run/build

I found another API to run a build, but it seems like you cannot use Personal Access Token auth with it, like you can with the pipeline api - only OAuth2 - https://learn.microsoft.com/en-us/rest/api/azure/devops/build/builds/queue?view=azure-devops-rest-6.0


Solution

  • You can do it with both the Runs API and Build Queue API, both work with Personal Access Tokens. For which one is the better/preferred, see this question: Difference between Azure Devops Builds - Queue vs run pipeline REST APIs, but in short the Runs API will be the more future proof option

    Option 1: Runs API

    POST https://dev.azure.com/{{organization}}/{{project}}/_apis/pipelines/{{PipelineId}}/runs?api-version=6.0-preview.1
    

    Your body will be of type application/json (HTTP header Content-Type is set to application/json) and similar to the below, just replace resources.repositories.self.refName with the appropriate value

    {
        "resources": {
            "repositories": {
                "self": {
                    "refName": "refs/heads/main"
                }
            }
        },
        "variables": {
            "HELLO_WORLD": {
                "isSecret": false,
                "value": "HelloWorldValue"
            }
        }
    }
    

    Option 2: Build API

    POST https://dev.azure.com/{{organization}}/{{project}}/_apis/build/builds?api-version=6.0
    

    Your body will be of type application/json (HTTP header Content-Type is set to application/json), something similar to below, just replace definition.id and sourcebranch with appropriate values. Please also note the "stringified" content of the parameter section (it should be a string representation of a json map)

    {
        "parameters": "{\"HELLO_WORLD\":\"HelloWorldValue\"}",
        "definition": {
            "id": 1
        },
        "sourceBranch": "refs/heads/main"
    }