In Azure DevOps (ADO) classic pipelines, you can encapsulate steps into collections called Task Groups. These groups can then be easily reused in Builds or Releases to get common or standard steps shared across several pipelines.
The issue is, if you just use the GUI to import a version of an existing Task Group, it just makes a new one with slightly different name, typically appending ‘copy’ to the same name. You can revise a Task Group while editing it but there are aspects that that the GUI does not expose to editing.
As one example, there is a typical PowerShell technique to print variables: “$($_.Exception.Message)”. Inside the parentheses would be initial calculations or expressions that needed to be computed before printing the string. If you have this in a PowerShell step and save or revise, ADO will assume you want that as a variable to input to the task group. There is no way to remove ‘extra’ variables in the Task Group in the GUI.
So, I looked at the ADO REST API documentation and saving a version isn’t standard. A search of the internet found one article on how to do this- https://medium.com/@tejasparmar99/azure-devops-task-group-version-upgrade-using-rest-apis-8524478364db. Updating a task group with a new version is a multi-step process when you use the GUI. The author figured out how these steps are replicated in PowerShell:
- Create a draft version of the task group by setting the version isTest value to true.
- Set the ‘parentDefinitionID’ property in the JSON definition of the task group to the ID of the previously created task group.
- Use the REST APIs to update the task group with the new version.
This method allows you to update task groups to new versions while keeping the different versions intact.
I took what they wrote and wrapped it in a little more logic. My function reads a list of the company standard Task Group definitions from a JSON file. It connects to the ADO Server using a Personal Access Token and retrieves the existing task groups. It compares the task group definitions from the JSON file with the existing task groups in Azure DevOps Server. If a task group definition is new, it takes the standard JSON definition file and creates new Task Group. If the Task Group exists, it uses the steps from above to create an updated version of the Task Group with multiple REST API calls.
The article showed me the way when the official documentation failed me but also left implied details while updating versions:
- Creates a draft task group by adding missing properties to the new task group object, such as instanceNameFormat, definitionType, iconUrl, runsOn, and version.
- Posts the draft task group to ADO using a POST request.
- Publishes the draft task group as a preview using a PUT request.
- Publishes the preview as a new version of the task group using a PATCH request.
This may have come from my standard JSON files not including all fields. There are enough to add it new but more parameters are needed when making a draft Task Group. Then there are parameters that change state as you change from draft to preview to published.