So, devops documentation can be really rough. I spent a lot of time trying to figure out how to run a new pipeline with expected parameters. This is for multi-stage pipelines.
The pipeline yaml looked something like this:
parameters:
- name: service
type: string
variables:
- name: service
value: ''
trigger: none
resources:
repositories:
- repository: self
stages:
- template: child-template.yml
parameters:
service: ${{ parameters.service }}
child-template-parameter: 'parameter-value'
I tried multiple yaml tasks trying to trigger this yaml build, but kept getting the dreaded warning: The parameter 'service' is required.
Didn't matter what I sent into the 'parameters' property of the json for the build.
Finally, I pulled out fiddler and looked at what the devops website is sending itself and found a couple of important things.
1. They're not using the api endpoint _api/builds/builds or anything like it. Instead, they're using:
_apis/pipelines/$definitionId/runs?api-version=5.1-preview
2. The proper property to pass in is actually templateParameters!
So, the final json body looked like this:
{`"stagesToSkip`":[],`"resources`":{`"repositories`":{`"self`":{`"refName`":`"refs/heads/master`"}}},`"templateParameters`":{`"service`":`"$Service`"},`"variables`":{}}
Here's a snippet from the powershell script:
$baseUri = "$($OrganizationUrl)/$($AzureDevOpsProjectName)/";
$getUri = "_apis/build/definitions?name=$(${PipelineName})";
$buildUri = "$($baseUri)$($getUri)"
# Base64-encodes the Personal Access Token (PAT) appropriately
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("token:{0}" -f $DevOpsPAT)))
$DevOpsHeaders = @{Authorization = ("Basic {0}" -f $base64AuthInfo)};
$BuildDefinitions = Invoke-RestMethod -Uri $buildUri -Method Get -ContentType "application/json" -Headers $DevOpsHeaders;
Write-Host $buildOutput
if ($BuildDefinitions -and $BuildDefinitions.count -eq 1)
{
$specificUri = $BuildDefinitions.value[0].url
$Definition = Invoke-RestMethod -Uri $specificUri -Method Get -ContentType "application/json" -Headers $DevOpsHeaders;
if ($Definition)
{
$definitionId = $Definition.id
$runUri = "_apis/pipelines/$definitionId/runs?api-version=5.1-preview"
$fullRunUri = "$($baseUri)$($runUri)"
$jsonbody = "{`"stagesToSkip`":[],`"resources`":{`"repositories`":{`"self`":{`"refName`":`"refs/heads/master`"}}},`"templateParameters`":{`"service`":`"$Service`"},`"variables`":{}}"
Write-Host "Running $jsonbody at uri $fullRunUri"
try
{
$Result = Invoke-RestMethod -Uri $fullRunUri -Method Post -ContentType "application/json" -Headers $DevOpsHeaders -Body $jsonbody;
}