I have over 100 YAML files within an existing Git repo, each defining their own build pipeline. I am trying to create a PowerShell script to create these build definitions so I don't have to spend hours using the web UI to manually add new build definitions and point to their respective YAML files.
I've come across similar questions and resources, but haven't been able to get this script to work.
- How to create Build Definitions through VSTS REST API
- Create Build Definition using Azure Devops API
- https://www.nebbiatech.com/2018/11/29/automating-build-pipeline-creation-using-azure-devops-services-rest-api/
I know the REST API documentation supports cloning, but does it support creating a build definition that links to a YAML file within the Git repo?
$organization = "my-company"
$project = "MyProject"
$projUrl = "https://dev.azure.com/$($organization)/$($project)/"
$patToken = "<PAT>"
$token = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($patToken)"))
$header = @{authorization = "Basic $token"}
$Url = "$($projUrl)_apis/build/definitions?api-version=5.1"
$json = @{
project = "$($project)";
name = "My.New.Definition.Linked.To.Existing.YAML.File";
repository = @{
url = "<the-https-link-to-my-Git-repo>";
};
# The script still fails with definition.Process cannot be null.
# process = 0;
path = "\A New Folder";
type = "build"
}
$body = ($json | ConvertTo-Json -Depth 3)
Invoke-RestMethod -Uri $Url -Headers $header -Body $body -Method Post -ContentType application/json;
I get the following error with the script above:
Invoke-RestMethod : {"$id":"1","innerException":null,"message":"Value cannot be null.\r\nParameter name:
definition.Process","typeName":"System.ArgumentNullException, mscorlib","typeKey":"ArgumentNullException","errorCode":0,"eventId":0}
At create_pipelines.ps1:22 char:1
+ Invoke-RestMethod -Uri $Url -Headers $header -Body $body -Method Post ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebException
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand
Is it possible to create a new build definition without cloning an existing one I have to manually create via the web UI?
I have the 100+ YAML files located in a folder /azure-pipeline-YAML/ inside the Git repo. I suspect I need to somehow include that in the JSON I send via the REST API, but where/how? I'm stuck at this definition.Process error.
Update
Thanks to @danielmann I ended up needing to get some additional info (i.e. repository.Id
and changing the repository.Type
). I put the following in the script to get an example of a temporary definition I created based on an existing YAML file.
$Url = "$($projUrl)_apis/build/definitions/13?api-version=5.1"
Invoke-RestMethod $Url -Headers $header -Method Get -ContentType application/json;
The working script ended up being:
$organization = "my-company"
$project = "MyProject"
$projUrl = "https://dev.azure.com/$($organization)/$($project)/"
$patToken = "<PAT>"
$token = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($patToken)"))
$header = @{authorization = "Basic $token"}
$Url = "$($projUrl)_apis/build/definitions?api-version=5.1"
$json = @{
project = "$($project)";
name = "My.New.Definition.Linked.To.Existing.YAML.File";
repository = @{
url = "<the-https-link-to-my-Git-repo>";
defaultBranch = "refs/heads/feature/my-new-feature-branch";
id = "<taken-from-the-GET-API-request>";
type = "TfsGit";
};
process = @{
yamlFilename = "azure-pipeline-YAML/my-pipeline.yml";
type = 2;
};
path = "\A New Folder";
type = "build";
}
$body = ($json | ConvertTo-Json -Depth 3)
Invoke-RestMethod -Uri $Url -Headers $header -Body $body -Method Post -ContentType application/json;