4
votes

I am new to the YAML build pipeline in Azure Devops and I am trying to wrap my head around the trigger functionality. What bothers me is that I want different triggers on different branches but I want to use the same pipeline.

Lets say I want

  1. Build on all checkins on master branch and this should be deployed to a server
  2. Every night I want to build and deploy the develop branch to another server

I am confused since the yaml file is checked into Git as well. I read that if you have scheduled trigger you cant have CI trigger as well.

Do I need to have two .yml files? One defining each? Seems not cool to repeat all the steps

Or should I have different version of the same file in each branch? Won´t this get merged at some point?

Bonus question: What if you push a build pipeline on Developemt branch with a trigger on master? (ugh im getting dizzy)

2
How about the issue? Does the answer below resolved your question, If not, would you please let me know the latest information about this issue?Leo Liu-MSFT
My bonus question was more like: Are you suppose to keep different version of your build pipeline in different branches? I mean if i want to build develop branch each time i push to develop can this trigger be defined in the master branch version of the yaml file?Jepzen
Any update for this issue? Have you resolved this issue? If not, would you please let me know the latest information about this issue?Leo Liu-MSFT

2 Answers

2
votes

Do I need to have two .yml files? One defining each? Seems not cool to repeat all the steps

After a period of research, I personally recommend you better use two .yml files with different build pipelines.

The most direct question is that the code on the master branch and development branch is not synchronized in real time. When the code on the two branches is different, the results of the build are different. If they are in the same pipeline, we need to manually check which branch the error came from when the build failed. This is a painful thing.

Another deep problem is that we could defined the CI trigger and Scheduled trigger in one yaml file, like:

trigger: 
 branches:
    include:
      - master


schedules:
- cron: "* 10 * * *"
  always: true
  displayName: Daily midnight build (UTC 22:00)
  branches:
    include:
     - Development

To achieve this, we need set this yaml on the Development branch. If we change any code in the master branch, it will trigger this pipeline. However, it only build the code on the Development branch, it does not include the changed code in the master. So this CI trigger will be meaningless.

should I have different version of the same file in each branch? Won´t this get merged at some point?

Personally recommend you better use different yaml files with different name. Just like you said, the same files are prone to unnecessary risks in later branch merge.

My bonus question was more like: Are you suppose to keep different version of your build pipeline in different branches? I mean if i want to build develop branch each time i push to develop can this trigger be defined in the master branch version of the yaml file?

The answer is yes. You could set the CI triggers with a simple syntax in the master branch version of the yaml file:

trigger: 
 branches:
    include:
      - master
      - Development

With this settings, every time you push to develop branch will trigger a build defined in the master branch version of the yaml file.

Note: For your bonus question, if we set above CI triggers, the pipeline will trigger a build due to continuous commits on the dev branch. Sometimes we just modify a readme file, we do not want such modification to trigger unnecessary builds, the best way to solve such problems is to use PR trigger.

Hope this helps.

1
votes

You are tellng that you can't have scheduled trigger and CI trigger but this is not true. Please check the documentation here.

If you want to run your pipeline by only using scheduled triggers, you must disable PR and continuous integration triggers by specifying pr: none and trigger: none in your YAML file. If you're using Azure Repos Git, PR builds are configured using branch policy and must be disabled there.

So you have two options here:

  1. Keep it all in one YAML file and check what branch or how build was triggers in condition to make deployment to a proper server
  2. You can have two builds but to avoid repeating yourself extract common stuff to template and reuse them in build definition (so in fact in this case you are going yo have 3 yaml files).

Few examples:

  • you wan to run a job only for master branch:
jobs:
- job: A
  steps:
  - script: echo hello

- job: B
  dependsOn: A
  condition: and(succeeded(), eq(variables['build.sourceBranch'], 'refs/heads/master'))
  steps:
  - script: echo this only runs for master
  • you want to extract common steps and reuse them in a build definition

Common steps:

# File: simple-param.yml
parameters:
- name: yesNo # name of the parameter; required
  type: boolean # data type of the parameter; required
  default: false

steps:
- script: echo ${{ parameters.yesNo }}

Build definition:

# File: azure-pipelines.yml
trigger:
- master

extends:
  template: simple-param.yml
  parameters:
      yesNo: false # set to a non-boolean value to have the build fail

You can read about templates in the documentation or check example on my blog post.

If you want to have classic release pipelines you need to define two release pipelines with trigger to specific branch.

Continous trigger for release pipeline

To sum up: you can do what you want and you have more than one way to achieve this. My person recomendation is to use separate pipelines with template as it makes build definition cleaner than condition to check for which branch or how build was triggered.

In this variable Build.Reason you can check how your branch was triggered:

  • Manual: A user manually queued the build.
  • IndividualCI: Continuous integration (CI) triggered by a Git push or a TFVC check-in.
  • BatchedCI: Continuous integration (CI) triggered by a Git push or a TFVC check-in, and the Batch changes was selected.
  • Schedule: Scheduled trigger. ValidateShelveset: A user manually queued the build of a specific TFVC shelveset.
  • CheckInShelveset: Gated check-in trigger.
  • PullRequest: The build was triggered by a Git branch policy that requires a build.
  • BuildCompletion: The build was triggered by another build.
  • ResourceTrigger: The build was triggered by a resource trigger.

You can use then this variable in condition. Fore more info please go here.

Closing this, please be aware that there is special kind of job called deployment for deployments. Please consider using this if you are going to deploy your application using yaml pipeline.

For your bonus question: you can override settings for you build. I meand you can have trigger for master and only master branch. But still you can run your build for other branches (like development branch) (for instance by manual run). What happen then? Build will run for newly defined branch. At the end this is build definition and trigger just control automatic build executions.