Azure DevOps Pipeline Triggers

Sahan Ruwanga Gunathilaka
6 min readJun 30, 2022

Azure DevOps pipelines hold a top position in CICD world. There are various factors which lead to bring Azure DevOps pipelines to such a position. Out of many, simplicity through yaml definitions, vast number of services availability to be integrated, and re-usability of pipeline templates are the key benefits I like most. I’ll be sharing one of the most important aspects of pipelines here, which is TRIGGERS!

What is a trigger? 🤔

In simple terms, it is the initiative factor or the initiator of a pipeline execution. On the other hand, the starting point of an automated flow.

Even though it is not that much complex to decide a trigger for a pipeline, choosing the best possible trigger would make the pipeline more robust!

Available triggers in Azure DevOps Pipelines 👏

Out of many available triggers[1], I will be briefing following triggers that I have used most. I’m more into YAMLdefinitions for pipelines which are hosted in GitHub repositories. Therefore, providing details will be related yaml based definitions and GitHub.

  1. CI triggers
  2. PR triggers
  3. Comment triggers
  4. Scheduled triggers
  5. Pipeline triggers

Let’s go through one by one! 🙂

1. CI triggers ⚡️

This is the Continuous Integration (CI) trigger which is available to start/run a pipeline when a change has been pushed to a respective branch or a tag in GitHub. We can define set of files/paths to be included or excluded from the trigger when it is for branches and set of tags to be included or excluded from the trigger when it is for tags. Both support wildcards as well. yaml syntax will be as follows.

Sample snippet: 1.1

trigger:
branches:
include:
- main
paths:
include:
- test/*
exclude:
- test/pr-trigger.yaml

Sample snippet: 1.2

trigger:
tags:
include:
- v0.1
exclude:
- v0-1.*

See important points to know about CI triggers! 👇

  • When a change is pushed to a branch, YAML file in that particular branch will be evaluated to decide whether it needs a CI run or not.
  • Batching CI runs can be configured by enabling it as follow. It will make sure that pipeline will start with all the queued changes only after the current execution is completed. No parallel runs are there!

Sample snippet: 1.3

trigger:
batch: true
branches:
include:
- dev
  • If CI trigger is not specified, it will consider as the following CI trigger configuration.

Sample snippet: 1.4

trigger:
branches:
include:
- '*'
  • If CI trigger is not required, it should be turned off as follows.

Sample snippet: 1.5

trigger: none
  • We can inform pipeline not to run even we have configured CI triggers, by adding [skip ci] or [ci skip] to message/description of any commit which is a part of the commit. See [2] for all available variations.

2. PR triggers ⚡️

Pull Request (PR) triggers will start pipeline execution when there is a new PR opened against the configured branch (in trigger) or any update made to such a PR.

This is much more needed trigger when we need to validate PRs before merging. Since this applies the changes in the PR and run the pipeline, we can use this to come up with a non-broken and yet reliable CICD process.

YAML syntax is same as in the CI trigger and I’m not going to duplicate it here 🙂. Just replace trigger with pr and that’s it. But, check the following useful points related to PR triggers.

  • A PR trigger should be added properly or disabled at all with pr: none config. Otherwise, pipeline will be triggered for each and every PR unnecessarily.
  • Wildcards are not supported for path filters (not as in CI triggers).
  • Can enable auto cancel of runs when more changes are pushed to the same PR while a previous job is being executed against the PR. Following syntax can be used for that. autoCancel is true by default.

Sample snippet: 2.1

pr:
autoCancel: false
branches:
include:
- dev
  • Draft PRs can be skipped from triggering the pipeline with the following snippet.

Sample snippet: 2.2

pr:
drafts: false
branches:
include:
- main

3. Comment triggers⚡️

This is kind of an additional security add-on to the PR trigger. Where PRs will not trigger the pipelines directly. Instead, a collaborator of that particular repository can add comment to the PR and trigger the pipeline.

This is really important when we are using pipelines for public GitHub repositories and we don’t need to run pipelines for each and every PR that will be opened by external parties. We can have the power to trigger the pipeline just adding a simple comment in the PR itself.

In order to use comment triggers, a repository collaborator with at least write access should add the comment.

This trigger will be configured by altering the pipeline configurations with PR triggers. Check out [3] to see the required configurations for that.

Following commands can be commented in the PR to trigger a pipeline.

/AzurePipelines run
/AzurePipelines run <pipeline-name>

Or simply, we can use, /azp instead of /AzurePipelines. Thus, commands in short will be /azp run and /azp run <pipeline-name>.

4. Scheduled triggers⚡️

This let us to define required cron jobs to start pipelines. We can even have multiple cron jobs in a single pipeline. Following is the syntax for that.

Sample snippet: 4.1

schedules:
- cron: "0 0 * * *"
displayName: Daily midnight build
branches:
include:
- main
exclude:
- releases/ancient/*
- cron: "0 12 * * 0"
displayName: Weekly Sunday build
branches:
include:
- dev/*

Cron syntax can check in [4].

Even here, it allows us to trigger the pipeline only if/after a change is made to the respective branches/files. always property can used for that and it is false by default.

Sample snippet: 4.2

schedules:
- cron: "0 0 * * *"
displayName: Daily midnight build
branches:
include:
- main
always: true

5. Pipeline triggers ⚡️

This is also called pipeline completion trigger where completion of one pipeline can trigger another pipeline. Let’s assume we have two pipelines as A and B. If we need to trigger the pipeline B when pipeline A completes its tasks, we can use this trigger. In order to get it used, we just need to add a pipeline resource in pipeline B yaml definition. The basic format is as follow.

Sample snippet: 5.1

resources:
pipelines:
- pipeline: pipeline-A
source: A
trigger: true

This also allows branch filters too where pipeline B will be triggered only if the pipeline A was triggered from a change which matches the branching filter. Following is an example to a branching filter.

Sample snippet: 5.2

resources:
pipelines:
- pipeline: pipeline-A
source: A
trigger:
branches:
include:
- test/*
exclude:
- pr-trigger

Tags can also be mentioned under pipeline trigger as a trigger filter. Here, triggering pipeline(A) needs to match all the added tags to trigger the triggered pipeline(B).

Sample snippet: 5.3

resources:
pipelines:
- pipeline: pipeline-A
source: A
trigger:
tags:
- test
- build

Important: As its name sounds, this will work only upon pipeline completion. Hence, if there is a failure in the triggering pipeline, triggered pipeline will not be started. But we may face some situations where we need to trigger the second pipeline even if the first pipeline has a failed step. In order to cater that, we can use another filter under pipeline triggers which is Stage filter. In there, we can define set of stages and the second pipeline will be triggered after the mentioned stages are completed in the triggering pipeline. We have to properly design the triggering pipeline to get this worked in the required manner. Following is the example to the stage filter.

Sample snippet: 5.4

resources:
pipelines:
- pipeline: pipeline-A
source: A
trigger:
stages:
- stage-A
- stage-B

As one last fact about the pipeline trigger, we need to pay attention to the pipeline’s default branch. You may see more details on that via the official documentations [5].

Final Tip!

Make sure to disable all unwanted triggers specially against prominent deployment environment like prod. Since CI trigger and PR trigger have the default configuration to trigger pipeline upon each commit and pr, take actions to manage those two trigger. They can be disabled as mentioned above using the configs trigger: none and pr: none.

Good bye! 👏

[1] https://docs.microsoft.com/en-us/azure/devops/pipelines/build/triggers?view=azure-devops

[2]https://docs.microsoft.com/en-us/azure/devops/pipelines/repos/github?view=azure-devops&tabs=yaml#skipping-ci-for-individual-commits

[3] https://docs.microsoft.com/en-us/azure/devops/pipelines/repos/github?view=azure-devops&tabs=yaml#comment-triggers

[4] https://docs.microsoft.com/en-us/azure/devops/pipelines/process/scheduled-triggers?view=azure-devops&tabs=yaml#cron-syntax

[5] https://docs.microsoft.com/en-us/azure/devops/pipelines/process/pipeline-triggers?view=azure-devops#branch-considerations

--

--

Sahan Ruwanga Gunathilaka

Senior Software Engineer | Microsoft Certified: Azure Administrator Associate | CKAD | Blogger | Sportsmen | Happy Soul