6

I have a pipeline.yaml that looks like this

pool:
  vmImage: image

stages:
  -stage: A
   jobs: 
     -job: a
      steps: 
     - script: |
          echo "This is stage build"
          echo "##vso[task.setvariable variable=doThing;isOutput=true]Yes"
        name: BuildStageRun
  -stage: B
   jobs:
      -job: b
       steps: #do something in steps

      -job: c
       dependsOn: a
       condition: eq(dependencies.build.outputs['BuildStageRun.doThing'], 'Yes')
       steps:
        - script: echo "I am scripting" 

So, there are 2 stages, A with one job a, and B with 2 jobs b and c. I would like to have job c executed only when job a has executed. I tried to do so by setting the variable doThing in job a to Yes and then check this variable in job c.

But I get an error:

Stage plan job c depends on unknown job a.

The varible definition and the definition of condition was taken from Azure documentation

Do you have any suggestion on how to get this working?

viajero cósmico
  • 75
  • 1
  • 1
  • 7

3 Answers3

8

While Shayki is correct that it is not supported - there is a workaround that I am currently using. That I used with the help of this blog https://medium.com/microsoftazure/how-to-pass-variables-in-azure-pipelines-yaml-tasks-5c81c5d31763

Basically you create your output as normal, and then publish the variables as pipeline artifacts. In the next stage, you read the artifact in the first job, and use that to construct your conditionals e.g.

stages:

  - stage: firststage
    jobs:

      - job: setup_variables
        pool:
          vmImage: 'Ubuntu-16.04'
        steps:

          - powershell: |
              $ShouldBuildThing1 = $true
              # Write to normal output for other jobs in this stage
              Write-Output "##vso[task.setvariable variable=BuildThing1;isOutput=true]$ShouldBuildThing1"
              # Write to file to publish later
              mkdir -p $(PipelineWorkspace)/variables
              Write-Output "$ShouldBuildThing1" > $PipelineWorkspace/variables/BuildThing1
            name: variablesStep

          # Publish the folder as pipeline artifact
          - publish: $(Pipeline.Workspace)/variables
            artifact: VariablesArtifact

       - job: build_something
         pool:
          vmImage: 'Ubuntu-16.04'
         dependsOn: setup_variables
         condition: eq(dependencies.setup_variables.outputs['variablesStep.BuildThing1'], 'true')
         variables:
           BuildThing1: $[dependencies.setup_variables.outputs['variablesStep.BuildThing1']]
         steps:
           - powershell: |
               Write-Host "Look at me I can Read $env:BuildThing1"

           - somethingElse:
               someInputArgs: $(BuildThing1)


  - stage: secondstage
    jobs:

      - job: read_variables
        pool:
          vmImage: 'Ubuntu-16.04'
        steps:
          # If you download all artifacts then foldername will be same as artifact name under $(Pipeline.Workspace). Artifacts are also auto downloaded on deployment jobs.
          - task: DownloadPipelineArtifact@2
            inputs:
              artifact: "VariablesArtifact"
              path: $(Pipeline.Workspace)/VariablesArtifact

          - powershell: |
              $ShouldBuildThing1 = $(Get-Content $(Pipeline.Workspace)/VariablesArtifact/BuildThing1)
              Write-Output "##vso[task.setvariable variable=BuildThing1;isOutput=true]$ShouldBuildThing1"
            name: variablesStep

      - job: secondjob
        pool:
          vmImage: 'Ubuntu-16.04'
        dependsOn: read_variables
        condition: eq(dependencies.read_variables.outputs['variablesStep.BuildThing1'], 'true')
        variables:
           BuildThing1: $[dependencies.setup_variables.outputs['variablesStep.BuildThing1']]
         steps:
           - powershell: |
               Write-Host "Look at me I can Read $env:BuildThing1"

           - somethingElse:
               someInputArgs: $(BuildThing1)

Moffmo
  • 188
  • 2
  • 9
6

Looks like a few options available from Microsoft now.

First is job-to-job dependencies across stages

From Microsoft:

In this example, job B1 will run whether job A1 is successful or skipped. Job B2 will check the value of the output variable from job A1 to determine whether it should run.

trigger: none

pool:
  vmImage: 'ubuntu-latest'

stages:
- stage: A
  jobs:
  - job: A1
    steps:
     - bash: echo "##vso[task.setvariable variable=shouldrun;isOutput=true]true"
     # or on Windows:
     # - script: echo ##vso[task.setvariable variable=shouldrun;isOutput=true]true
       name: printvar

- stage: B
  dependsOn: A
  jobs:
  - job: B1
    condition: in(stageDependencies.A.A1.result, 'Succeeded', 'SucceededWithIssues', 'Skipped')
    steps:
    - script: echo hello from Job B1
  - job: B2
    condition: eq(stageDependencies.A.A1.outputs['printvar.shouldrun'], 'true')
    steps:
     - script: echo hello from Job B2

Also, there's another option where you could consume output variables across stages.

From Microsoft site:

Stages can also use output variables from another stage. In this example, Stage B depends on a variable in Stage A.

stages:
- stage: A
  jobs:
  - job: A1
    steps:
     - bash: echo "##vso[task.setvariable variable=shouldrun;isOutput=true]true"
     # or on Windows:
     # - script: echo ##vso[task.setvariable variable=shouldrun;isOutput=true]true
       name: printvar

- stage: B
  condition: and(succeeded(), eq(dependencies.A.outputs['A1.printvar.shouldrun'], 'true'))
  dependsOn: A
  jobs:
  - job: B1
    steps:
    - script: echo hello from Stage B
Tyler Seader
  • 156
  • 1
  • 4
4

It's because you can't depend on a job from another stage, you can depend stage B on stage A or job c on job b.

You can't achieve your goal with YAML conditions because you want to use a variable that you declared it in the first stage, the second stage doesn't know this variable, Azure DevOps don't support it yet:

You cannot currently specify that a stage run based on the value of an output variable set in a previous stage.

You can depend stage B on A, so if in stage A there is only one job you depend stage B on stage A:

- stage: B
  dependsOn: A
Shayki Abramczyk
  • 36,824
  • 16
  • 89
  • 114
  • 1
    Ok, this is what I suspected. I will need to modify the logic in the pipeline to achieve the same functionality then. I'm curious though. Do you have any explanation why this is not allowed? – viajero cósmico Feb 13 '20 at 09:53
  • 1
    Is it still accurate? I can't find such statement in linked doc. – ravenwing Mar 23 '21 at 19:03
  • 1
    @ravenwing - found a solution and posted about it [here](https://stackoverflow.com/a/68581906/9632623) – Tyler Seader Jul 29 '21 at 19:39