Reputation: 1831
I have a mono-repo containing multiple sub-projects (Node/TypeScript if it matters). I'm trying to set up what I feel is a relatively simple pull request setup in Azure DevOps that is meant to deploy a PR environment for testing. It consists of 2 pipelines that I want to trigger one after the other in the PR. If either fail the PR should fail as well. The code is hosted in Azure DevOps Git.
Here are the steps I'm trying to achieve:
solution-a
for merging from features/feature-x
to dev
branchsolution-a-pipeline
based on the tag solution-a
. A different pipeline should be triggered if the tag is different.solution-a-pipeline
triggers infrastructure-pipeline
and solution-a-build-pipeline
in context of features/feature-x
branch* in order.solution-a-pipeline
completes successfully (indirectly this means infrastructure-pipeline
and solution-a-build-pipeline
also completed successfully in order) the bulid is considered successful. Otherwise it fails and the PR cannot be completed.*By "in context" I mean that the actual yaml file used for each pipeline is the one from the feature branch. This is because I want it to test any changes to the pipelines as well as any steps within the pipeline.
Is there a way to achieve this? I've been trying for days now using different combinations of pipeline files, templates, resources and triggers and I cannot seem to wrap my head around it.
Upvotes: 1
Views: 1484
Reputation: 1831
I've managed to work around the problem. It involves several steps and some hard-coding, but I'm now able to tag a Pull Request with certain defined tags and have a Build Validation triggered pipeline
run only the relevant parts as a result.
My setup consists of one big pr-pipeline.yml
file that is triggered by the Build Validation of PRs to my dev
branch. The trigger is manual, but required which allows the person issuing the PR to tag it accordingly before it begins.
Once the pipeline runs the very first step uses the Azure DevOps REST API to determine which tags are present on the associated PR by calling this endpoint:
https://dev.azure.com/$(organizationName)/$(System.TeamProjectId)/_apis/git/repositories/$(Build.Repository.ID)/pullRequests/$(System.PullRequest.PullRequestId)/labels?api-version=5.1-preview.1
Every parameter required except the organization name is provided by the predefined variables for the pipeline.
To call the endpoint I'm using the Personal Access Token (PAT) provided to the agent by Azure DevOps in the predefined variable System.AccessToken
and a small PowerShell script:
$accessToken = "$(System.AccessToken)"
$basicAuth = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(":$accessToken"))
$headers = @{Authorization = "Basic $basicAuth"}
$url = $(url)
$data = Invoke-WebRequest -Method Get -Uri $url -Headers $headers
Write-Host "##vso[task.setvariable variable=prlabels]$data"
Once I have my tags I extract each of them as a separate variable using a small PowerShell snippet. The prlabels
variable is populated by :
$tagsJson = '$(prlabels)' | ConvertFrom-Json
$tags = $tagsJson.value | ForEach-Object { $_.name }
Write-Host "Tags: $($tags -join ";")"
$tags | ForEach-Object { Write-Host "##vso[task.setvariable variable=prlabel_$_;isOutput=true]true" }
If my pr is tagged with solution-a
and solution-c
this will result in the following output variables being defined:
prlabel_solution-a = true
prlabel_solution-c = true
Finally, I can use those output variables as conditions for triggering the relevant jobs that perform the actual build and deployments for the respective solutions. The job that fetches the tags is named PreReq
and the task that outputs individual variables is named prlabels
:
- job: DeploySolutionA
dependsOn: PreReq
condition: and(succeeded(), eq(dependencies.PreReq.outputs['prlabels.prlabel_solution-a'], 'true'))
# ...
All of this together enables me to deploy one or more specific solutions in a PR based on what the user defines. It still requires the user to know of these labels, but at least they don't have to manually start each pipeline on each run outside of the PR.
Upvotes: 2
Reputation: 76890
Azure DevOps Pipeline structure for PRs in mono-repo
I could understand your requests, but AFAI for Azure devops, I do not believe there is such a way to achieve your needs at this moment.
There are three challenges here:
We could not add a tag to a Pull Request, you could check this thread for details.
We could not trigger different build pipeline based on the tags. There is no such condition for the option build validation.
We could not set the order of the build validation. We could set multiple build pipeline in the build validation, but we could not set the order of them. If we add a build validation and use build completion to set the build order, but build validation will only verify the results of the build pipeline we added, not the results of other associated pipelines
In summary, I do not believe there is such a way to achieve your needs at this moment.
Hope this helps.
Upvotes: 0