6
votes

I'm trying to create an azure pipeline which triggers on changes in a specific branch but exclude other branches. The sample scenario is, I have multiple branches like dev, test, beta branches. So I have this sample configuration in my azure-pipelines.yml

trigger:
  branches: 
    include: 
      - dev
    exclude:
      - test
      - beta

It works fine, it triggers the CI build for dev in my azure devops. But the problem is, after I switched to other branch on my machine, let's say test and I updated the azure-pipelines.yml like this:

trigger:
  branches: 
    include: 
      - test
    exclude:
      - dev
      - beta

and pushed it to the origin, the CI for test and dev are trigger and their branch tag is in the test branch. Which is wrong because a CI for dev shouldn't be included or triggered.

I also made sure that every CI build is using the azure-pipelines.yml that designated to a specific branch. That's why I don't know why it doesn't work properly.

1

1 Answers

7
votes

I think that you should not use the same file for different branches. If you want to have multiple build definition per branch you should have separated files for them. To avoid repeating code you should use templates.

To show you how it may work:

build-and-test.yaml:

parameters:
- name: buildConfiguration # name of the parameter; required
  default: 'Release'

steps:

    - task: DotNetCoreCLI@2
      displayName: Restore nuget packages
      inputs:
        command: restore
        projects: '**/*.csproj'
        workingDirectory: $(Build.SourcesDirectory)
    
    - task: DotNetCoreCLI@2
      displayName: Build
      inputs:
        command: build
        projects: '$(Build.SourcesDirectory)/gated-checkin/GatedCheckin.sln'
        arguments: '--configuration ${{ parameters.buildConfiguration }}'
    
    # You just added coverlet.collector to use 'XPlat Code Coverage'
    - task: DotNetCoreCLI@2
      displayName: Test
      inputs:
        command: test
        projects: '**/*Tests/*.csproj'
        arguments: '--configuration ${{ parameters.buildConfiguration }} --collect:"XPlat Code Coverage" -- RunConfiguration.DisableAppDomain=true'
        workingDirectory: $(Build.SourcesDirectory)

and then if your pipeline want to use only these steps you should use extends keyword:

trigger:
  branches:
    include:
    - '*'
    exclude:
    - master

pr:
  branches:
    include:
    - master
  paths:
    include:
    - gated-checkin-with-template/*
    exclude:
    - gated-checkin-with-template/azure-pipelines.yml

variables:
  buildConfiguration: 'Release'

extends:
  template: build-and-test.yaml
  parameters:
      buildConfiguration: $(buildConfiguration)

or if you want to have additional steps, please use template keyword:

trigger:
  branches:
    include:
    - master
  paths:
    include:
    - gated-checkin-with-template/*
    exclude:
    - gated-checkin-with-template/azure-pipelines-gc.yml

pr: none

pool:
  vmImage: 'ubuntu-latest'

variables:
  buildConfiguration: 'Release'

steps:

- template: build-and-test.yaml
  parameters:
      buildConfiguration: $(buildConfiguration)

- script: echo Some steps to create artifacts!
  displayName: 'Run a one-line script'

As you noticed each build has it's own trigger option so you can customize for your needs. I have this described on my blog, but all above here explains mechanism well.

I understood that it may introduce more files, but I would try to look for some patterns depending on branch type. I may find a reason to have some different behaviors for dev, test and beta but I really doubt that each single feature branch will be different than another feature branch. Thus you should find groups and create definitions for those groups. Adding different build also help you to recognized what was build. Otherwise you must go into details and check what branch was build.

For your case if you want to follow your approach I would try to set this pr: none (you have the example in code above).