28

I'm having problems triggering a pipeline from another Pipeline in Azure DevOps. I have a CI pipeline and I want to trigger a Deploy Pipeline whenever CI passes on a master branch. This seems to be technically possible, but the documentation is unclear.

I see the following:

# this is being defined in app-ci pipeline
resources:
  pipelines:
  - pipeline: securitylib
    source: security-lib-ci
    trigger: 
      branches:
      - releases/*
      - master

But it's unclear as to a) whether this goes in the triggering pipeline (in my case the CI pipeline) or the triggered pipeline (in my case, the deploy pipeline).

It's also unclear as to what the pipeline and source refer to, and how I find out these variables? Are they both the name of the pipeline? I've tried various different permutations and nothing seems to be working.

Pezholio
  • 2,439
  • 5
  • 27
  • 41
  • did my answer helped you? it does answer all your questions... If so, please accept it :) – ccoutinho Dec 01 '20 at 15:58
  • Would be really cool if you would make your contribution to the community @Pezholio and mark my solution as valid, since it clearly answers your query. SO is not only to ask questions and get answers in return.... – ccoutinho Jul 23 '21 at 11:31

4 Answers4

31

EDIT 2

Finally Microsoft has improved their documentation with regards to the pipeline triggers in YAML! Here's the link.

EDIT

After having written my answer, Microsoft has come up with another solution to solve this problem, by using a build completion trigger via a classic pipeline. Their solution can be found here.



If you're not publishing an artifact from the triggering pipeline, it won't trigger the triggered pipeline.

Also, there is a very big restriction on the use of these types of triggers. It is necessary to change the defaultBranch for manual and scheduled builds in the depends pipeline, to the working branch. Otherwise it won't kick in at the end of the source pipeline execution. So, let's say you're working on feature branch, and defaultBranch is set to feature. You commit your code, and everything will run as expected: the source pipeline kicks in, and at its end, the depends pipeline will be triggered. All good! But when you will merge into master, if you do not change the defaultBranch, the depends pipeline won't be triggered at the end of the source pipeline. I explain how to change the defaultBranch at the end of the answer.


How to setup a pipeline trigger

I managed to get this up and running on a minimalistic project. Here you can have the code and here the project on Azure DevOps. I will try to guide you through how I did it, and answer the questions you've asked in your post.

I will be calling the triggered pipeline as depends pipeline and the triggering pipeline as source pipeline.

On the source pipeline, there's no need to do anything except publishing an artifact. If you don't publish an artifact from the source pipeline, it won't work. Below you can find the code I am using for my dummy source pipeline. I want it to be triggered for master branch, and at the end I want to be sure to publish an artifact.

trigger:
  branches:
    include: # branch names which will trigger a build
    - master
pr: none

steps:
  # required to cause pipeline triggering downstream
  - task: CopyFiles@2
    inputs:
      contents: $(System.DefaultWorkingDirectory)/**/*.yml
      targetFolder: $(Build.ArtifactStagingDirectory)
  - task: PublishBuildArtifacts@1
    inputs:
      pathtoPublish: $(Build.ArtifactStagingDirectory)
      artifactName: dummy-$(Build.BuildId)

On the depends pipeline (code shown below), I have to disable CI and PR triggers, otherwise when I commit to this repo, this pipeline will be triggered by the CI trigger, and then by the end of the execution of the source pipeline. This is done by the two first lines of my code. Then I want that the pipeline named source (this is the source property in the YAML below), within the project named Pipelining (project property in the YAML) will trigger the current (depends) pipeline when this updates master branch.

trigger: none
pr: none
resources:
  pipelines:
    - pipeline: source
      project: Pipelining
      source: source
      trigger: 
        branches:
          include:
          - master
steps:
  - checkout: none
  - script: echo 'triggered depends'

Does it make sense? It is important for your project name on Azure DevOps to match the property in the YAML depends pipeline code.For me it is Pipelining

enter image description here

As well as the source property, again in the YAML depends pipeline code.

enter image description here


Change the default branch

In order to change the defaultBranch, because of the issue mentioned above, you should edit the pipeline (in this case, the depends pipeline), then on the three dots on the top right corner pick Triggers. Then choose the YAML tab, and you will get to the screen shown in the image below, where you can set the working branch.

enter image description here

ccoutinho
  • 3,308
  • 5
  • 39
  • 47
  • For me, it even worked without publishing artifacts – Markus Hartmair Aug 20 '20 at 04:47
  • When I had set this up, it was not working for me without that part @MarkusHartmair. Maybe Microsoft improved it :) – ccoutinho Aug 20 '20 at 07:43
  • When i was debugging a similar pipeline dependency trigger chain, i got very little output because the pipeline being triggered was on a different branch (default branch): `/azure-pipelines.yml (Line: ...): Unexpected value 'trigger'` and `/azure-pipelines.yml (Line: ...): Unexpected value 'variables'`. No logs no debug traces. Hope this helps others. – Lars Pellarin Oct 26 '20 at 21:07
  • @ccoutinho: Very helpful, thank you. Any idea on how to define all/multiple source pipelines in the depends yaml? Do we need to define them all or is there a way to define any pipeline? E.g. to have a java default pipeline which does some maven thing when any java project (repo) receives a merge. – MyName Jun 07 '21 at 13:02
  • 1
    @MyName I haven't done that before, but I assume you need to declare them all – ccoutinho Jun 07 '21 at 17:48
  • So if I understood correctly, the pipeline that triggers (source) does not specify any details of the pipeline to be triggered (depends)? What if I have a pipeline that does something generic and want it to be triggered by multiple pipelines, and based on its output, the triggering pipeline will continue executing or fail. Example (source) builds and unit tests (depends) runs E2E tests. Based on my (depends) results, I want (source) to go to the next stage or fail. If I have other pipelines like (sourc2, source3, source4) they could also use (depends) and its output. Is this possible? – Vergil C. Jul 12 '21 at 17:24
  • You can definitely have multiple pipelines bring triggered from a single source pipeline. But I am 99% sure you can't have a stage in source pipeline triggering a depends pipeline, and then depends pipeline triggering a second stage in the source pipeline : source pipeline will trigger depends pipeline on successful conclusion, hence what you are trying to achieve does not seem possible. And that setup seems not only overcomplicated, but also not ideal. You don't want to have A depending on B, and B depending on A. Or source depending on depends, and depends depending on source – ccoutinho Jul 13 '21 at 08:00
  • 1
    I forked your repo and made 2 pipelines one for source and one for depends using existing azure devops yaml file, and ensured the default branch is set to master. Then manually ran source pipeline, but it did not trigger depends. Would be useful if you can provide others with a recipe on how to reproduce this on their own. For me, this does not work without adding a build completion trigger (by going to Triggers, and not in the yaml file) – masih Jul 22 '21 at 10:49
  • Did you set the default branch in the depends pipeline? Were you able to see the published artifact after running the source pipeline? If yes, can you run it again, but without manually triggering? The build completion trigger feature you mentioned is a new thing, it was not available when I implemented my solution. I will add it to my answer, thank you for the feedback :) – ccoutinho Jul 23 '21 at 11:23
  • Yes, I set the default branch in the depends pipeline to the master as you suggested. I was also able to see the published artifacts after running the source pipeline. I ran the source pipeline both manually and by pushing some changes. But in all cases the depends was not triggered untilI added a build completion trigger as Microsoft suggest here: https://learn.microsoft.com/en-us/azure/devops/pipelines/process/pipeline-triggers-classic?view=azure-devops – masih Jul 27 '21 at 09:59
  • But could not get the depends to trigger on completion of source by only depending on yaml file, as described by Microsoft here: https://learn.microsoft.com/en-us/azure/devops/pipelines/process/pipeline-triggers?view=azure-devops Seems to me like this feature Microsoft has made is only useful for filtering incoming triggers (which in this case would be a build completion trigger set up in classic way, meaning through UI but not yaml file) – masih Jul 27 '21 at 10:02
  • Hi @masih! I thought that MS might have introduced a bug, so I gave it a try in my demo repository without any changes and everything worked like a charm. I would suggest you to redo everything from scratch, you might be missing something! Please have a look in the azure DevOps project for confirmation: https://dev.azure.com/Coutinhos/Pipelining Both manually triggering the source pipeline, and committing new changes to the master branch, triggered the depends pipeline – ccoutinho Jul 28 '21 at 12:03
  • Have you properly referenced the Azure DevOps project in which you have the code? – ccoutinho Jul 28 '21 at 12:05
2

Above yaml pipeline trigger should be defined in the triggered pipeline(deploy pipeline).

- pipeline: string the string here is identifier you give to this pipeline resource. It can any string.

source: string the string here is the definition name of the triggering pipeline(the name of your CI pipeline).

Below yaml is from the document pipeline resource.

resources:
  pipelines:
  - pipeline: string  # identifier for the pipeline resource
    project:  string # project for the build pipeline; optional input for current project
    source: string  # source pipeline definition name
    branch: string  # branch to pick the artifact, optional; defaults to all branches
    version: string # pipeline run number to pick artifact, optional; defaults to last successfully completed run
    trigger:     # optional; triggers are not enabled by default.
      branches:
        include: [string] # branches to consider the trigger events, optional; defaults to all branches.
        exclude: [string] # branches to discard the trigger events, optional; defaults to none.

Option: You can also set the pipeline triggers from Ui page. Go the edit page of the triggered yaml pipeline(Deploy pipeline), Click the 3dots and choose Triggers

enter image description here

Go to Triggers--> Build completion and click add--> Select your triggering pipeline(CI pipeline)

enter image description here

Update:

I saw the pipeline resource in azure-deploy.yml is defined as below.

resources:
  pipelines:
  - pipeline: 'Deploy to Development'
    source: 'DFE-Digital.dfe-teachers-payment-service'
  trigger:
    branches:
      include:
      - "master"
      - "release-stuff"

please try changing the indentation of trigger element the same as source element. Check below example:

    resources:
      pipelines:
      - pipeline: 'Deploy to Development'
        source: 'DFE-Digital.dfe-teachers-payment-service'
        trigger:
          branches:
            include:
            - "master"
            - "release-stuff"
Levi Lu-MSFT
  • 27,483
  • 2
  • 31
  • 43
  • 1
    Thanks, but this still isn't working for me (I'd rather not try the UI option as I'd rather keep everything documented through code). My CI pipeline is called `DFE-Digital.dfe-teachers-payment-service` and my deploy pipeline is called `Deploy to Development`, so I set the `pipeline` variable to `Deploy to Development` and the `source` variable to `DFE-Digital.dfe-teachers-payment-service`. I expect the deploy pipeline to kick off when the CI finishes, but nothing happens. – Pezholio Mar 12 '20 at 10:26
  • In desperation, I've also tried the UI option, and that doesn't work either – Pezholio Mar 12 '20 at 11:54
  • The repo is open, so you can see my YAML here https://github.com/DFE-Digital/dfe-teachers-payment-service/blob/release-stuff/azure-deploy.yml – Pezholio Mar 12 '20 at 12:08
  • I saw there is an indent error for trigger element in your azure-deploy.yml. Please check above update. – Levi Lu-MSFT Mar 13 '20 at 02:06
  • Did you create a pipeline in azure devops pipeline for yaml azure-deploy.yml. It needs to be added as a pipeline in azure devops pipeline. – Levi Lu-MSFT Mar 13 '20 at 08:38
  • I've created a pipeline, yep. Running the suggestion gives me the error `/azure-deploy.yml: (Line: 13, Col: 3, Idx: 127) - (Line: 13, Col: 3, Idx: 127): While parsing a block collection, did not find expected '-' indicator.` – Pezholio Mar 13 '20 at 11:38
  • I copied the contents in azure-deploy.yml and created a test pipeline. It didnot reproduce above error. Could you share the pipeline you created on azure devops. – Levi Lu-MSFT Mar 16 '20 at 06:16
  • It's a private pipeline, so I don't think I'll be able to, I'm afraid – Pezholio Mar 16 '20 at 10:58
2

I may assume you are not working on the master branch, right? I have the same issue previously. But after I read the section Default branch for triggers of MS's doc. I understand why. The trigger only examine master's branch's yaml file by default. This means the pipeline will only be triggered by the definition of triggers in master branch's yaml file.

Therefore, whatever branches you add in the trigger section of yaml file in other branches(not master), tirgger is not active. You need to change the pipeline to look the yaml file in your current branch, not master. Just follow the doc's instruction, change the default trigger branch. You will get it working.

Once you merge your work into master, you probably need to change the dedault trigger branch back to master.

Zzz
  • 21
  • 1
2

I found the following:

  • In source pipeline I didn't need to create an artifact

  • In depends pipeline if I wanted to build after any commit to the source branch I could get it to work with this:

    trigger: none
    pr: none
    resources:
          pipelines:
          - pipeline: 'depends'
            source: 'common-gulp-trigger'
            trigger: true
user1451104
  • 113
  • 1
  • 7