Azure DevOps REST api - Run pipeline with variables
T

2

11

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

Timbal answered 13/2, 2021 at 13:4 Comment(0)
A
23

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"
}
Apple answered 13/2, 2021 at 16:21 Comment(4)
Option 1 works for me! Thank you. I needed to add resources to my request... Would have been nice if it would give you an error for that but hey, seems to work now, thanks againTimbal
It works without the resources block also, it will fall back to the default branch.Apple
whats the syntax for more than one variables?Tilsit
@LarsPellarin just add the additional variables to the serialized json array "parameters": "{\"HELLO_WORLD\": \"HelloWorldValue\", \"ANOTHER_KEY\": \"ANOTHER_VALUE\"}"Apple
L
5

Here's the way I solved it....

The REST call:

POST https://dev.azure.com/<myOrg>/<myProject>/_apis/pipelines/17/runs?api-version=6.0-preview.1

  The body of the request:

{
    "resources": {
        "repositories": {
            "self": {
                "refName": "refs/heads/main"
            }
        }
    },
    "templateParameters": {
        "A_Parameter": "And now for something completely different."
    }
}

Note: I added an authorization header with basic auth containing a username (any name will do) and password (your PAT token value). Also added a Content-Type application/json header.


  Here's the entire yaml pipeline I used:  

parameters:
- name: A_Parameter
  displayName: A parameter
  default: noValue
  type: string
 
trigger:
- none
 
pool:
  vmImage: ubuntu-latest
 
steps:
 
- script: |
    echo '1 - using dollar sign parens, p dot A_Parameter is now: ' $(parameters.A_Parameter)
    echo '2 - using dollar sign double curly braces, p dot A_Parameter is now::' ${{ parameters.A_Parameter }} '::'
    echo '3 - using dollar sign and only the var name: ' $(A_Parameter)
  displayName: 'Run a multi-line script'

    And here's the output from the pipeline log. Note that only the second way properly displayed the value.    

1 - using dollar sign parens, p dot A_Parameter is now: 
2 - using dollar sign double curly braces, p dot A_Parameter is now:: And now for something completely different. :: 
3 - using dollar sign and only the var name:
Logic answered 23/6, 2021 at 20:6 Comment(1)
Lol, blizzville, I find myself doing the same echo script, too. Can never remember which syntax is appropriate.Heteropterous

© 2022 - 2024 — McMap. All rights reserved.