Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can i trigger by branch AND tag in azure pipeline?

I want to create a azure pipeline such that when I push to branch (develop) AND tag (test*), the pipeline will be triggered. However, with what I have the pipeline is triggered when I push to branch (develop) without the tag, indicating the trigger is executing when pushing to the (develop) branch OR the (test*) tag.

Example:

trigger:
  branches:
    include:
      - develop
      - refs/tags/{test*}

How can I get the trigger to fire only when pushes to (develop) branch also have a reference to (test*) tags?

like image 291
CDN Avatar asked Feb 10 '20 16:02

CDN


2 Answers

As per the documentation on Triggers

When you specify a trigger, it replaces the default implicit trigger, and only pushes to branches that are explicitly configured to be included will trigger a pipeline. Includes are processed first, and then excludes are removed from that list.

What I think is lacking (or just confusing) from the documentation is that items satisfying any 1 include in a given section (branches, path, tags) are listed for that section and are removed if they satisfy any 1 exclude clause for that section. Except if all three sections are used. Then the following note applies:

If you specify tags in combination with branch filters that include file paths, the trigger will fire if the branch filter is satisfied and either the tag or the path filter is satisfied.

Summary

The include: collection is created first and excludes are removed from that list.

Sections are ORed together (branches OR tags), (branches OR paths) unless ALL sections are used, then they are (branches AND (tags OR paths))

With this in mind:

If you want to keep using only the branches section, you will need to go with an option that removes all undesirable branches from the list and only explicitly includes the tag ref (treated like a branch).

Include the tag and exclude the undesirable branch patterns

trigger:
  branches:
    include:
    - refs/tags/test*
    exclude:
    # a list of the branches for which you don't want to trigger
    - master
    - features/*
    - bugs/*
    - hotfix/*

If you are not constrained to using only the branches section, then using all 3 sections will get you there by including the develop branch and the test* tag but excluding all paths.

Include the tag and desirable branch, but exclude all paths on that branch

trigger:
  branches:
    include:
      - develop
  tags:
    include:
      - test*
  paths:
    exclude:
      - /*

This second option is basically shouldFire = (branch == develop && (tag == test* || false)) which is equivalent to shouldFire = (branch == develop && tag == test*)

like image 120
Josh Gust Avatar answered Oct 08 '22 04:10

Josh Gust


The answer from Josh Gust above might have been correct at the time, but unfortunately it does not seem to be the case anymore.

A recent update to the Azure docs has completely changed how the include/exclude logic is supposed to work.

With this in mind, it seems to me that there is no way to entirely stop a pipeline from firing except for specific branch plus tag combinations. Which is very unfortunate.

The next best thing seems to be to abort the pipeline as early as possible. You could do the following:

  • Make sure the pipeline is set to only trigger when your desired tag is present. Achieve this using the standard tags include setting.
  • Alternative 1: As your first step, conditionally abort the build as "cancelled" if the branch name is not what you expect. This seems to be quite involved and you'll probably want to use a library like this.
  • Alternative 2: Add a condition like eq(variables['Build.SourceBranchName'], 'master') to every single step in your pipeline. This is tedious, but simple.

When determining what branch name to use in the YAML script, it is useful to keep in mind this caveat from the docs (provided you are using Git):

Build.SourceBranchName: The last path segment in the ref. For example, in refs/heads/master this value is master. In refs/heads/feature/tools this value is tools.

From your comment dated Feb 12, it would seem to me that Josh's suggestion was working for you at that point. It would be really appreciated if you could please confirm whether it is still working as expected. If it is still working, then the Azure docs update has to be mistaken and I would like to raise an issue with them over this.

like image 45
mkoro Avatar answered Oct 08 '22 05:10

mkoro