4
votes

I have a situation where two commits were merged to master (e.g. FIRST and SECOND) very close together (seconds apart). Both triggered the build pipeline: FIRST triggered the pipeline first and SECOND triggered it second (the builds ran in parallel). For whatever reason, the build pipeline for commit SECOND finished first, and 30 seconds later the build for commit FIRST finished.

My automatic release pipeline is configured to always get the "latest" artifact from the build pipeline. The sequence of events described above caused the SECOND change to be deployed first, and then the FIRST change was deployed next (since its pipeline finished second) and stomped on the prior release, effectively deploying old bits to the service.

Is there any way to prevent this situation? Even if a build pipeline finishes second for intermittent reasons, I don't want a release to stomp over a more recent change that happened to finish earlier.

EDIT: Thank you to those who suggested/supported the idea of batching builds but that's not an option I'm looking to enable. I still want each commit to trigger its own build (to enable easier assignment of build break cause). I'm just looking for the releases to trigger in the order of commits, not the order of builds finishing.

Thanks!

2
@AuthInfant If you are running the pipeline in parallel, then I don't thin there's a built-in way to achieve that. By default, if you have set CI/CD, any completed build will trigger the release. So set batch to true is working for publish the real latest change. Alternatively run with single agent, thus all the builds will run in queue. In addition, if you consist on that, then the only way I can think of is that you can try writing a script to check if the triggered version is the latest version/commits, if it's the latest version then delay a time period to complete.Andy Li-MSFT
@Auth Infant did you tried Andy's suggestion? Any good news?Levi Lu-MSFT

2 Answers

2
votes

You may need to make the pipelines to run on the same agent. So that the newest queue will wait for the previous queue to complete.

You can follow below steps to confine your pipeline to one agent. 1, Add a custom capability to the agent you want to run the pipeline(project settings->agent pools(select an agent pool)->agents(select a agent)->capabilities) enter image description here

2,Add a demand to your pipeline : # this works for both microsoft-hosted agents and self-hosted agents

enter image description here

I tested and found microsoft-hosted agent pool doesnot support demands for custom capabilities in yaml pipeline.

Below yaml pipeline works only for self-hosted agent pool.

pool:
  name: Default
  demands: Tag -equals Agent1
4
votes

You can set batch to true in triggers, so the system waits until the build is completed. Set "Batch changes while a build is in progress" option to true in Triggers for Build Pipeline at Azure DevOps or in YAML:

trigger:
  batch: true

If you use Pull request, there should be no issues as new push should cancel in-progress run. Check autoCancel in PR triggers