0

On a previous post Azure pipeline: how to use an output variable in a condition, I was having issues to use variables from dependencies.

Now, I have a pipeline where I call a script that returns true or false. The return value sets what is the next stage to run but I now have two issues.

The condition on the variable works but the display of the variable shows nothing. The condition makes the workflow go to two branches but now I need it to move back to only one branch

Here is my Yaml:

stages:
  - stage: Init
    jobs:
    - job: RunScript
      steps:
        - task: PowerShell@2
          name: compareFiles
          inputs:
            targetType: filePath
            filePath: '***\compareFileContent.ps1'

  - stage: Display1
    dependsOn: Init
    variables:
      areFilesDifferent: $[ dependencies.Init.outputs['RunScript.compareFiles.areDifferent'] ]
    jobs:
    - job: RunScript
      steps:
        - task: CmdLine@2
          inputs:
            script: |
              echo areFilesDifferent: $(areFilesDifferent)

  - stage: DeploymentStageWithApproval
    dependsOn: Display1
    variables:
      areFilesDifferent: $[ dependencies.Init.outputs['RunScript.compareFiles.areDifferent'] ]
    condition: eq( variables.areFilesDifferent, 'false' )
    jobs:
    - deployment: DeploymentJob
      environment: 'STWithApproval'
      strategy:
        runOnce:
          deploy:
            steps:
              - task: CmdLine@2
                inputs:
                  script: |
                    echo DeploymentStageWithApproval: $(areFilesDifferent)


  - stage: DeploymentStageWithoutApproval
    dependsOn: Display1
    variables:
      areFilesDifferent: $[ dependencies.Init.outputs['RunScript.compareFiles.areDifferent'] ]
    condition: eq( variables.areFilesDifferent, 'true' )
    jobs:
    - deployment: DeploymentJob
      environment: 'ST'
      strategy:
        runOnce:
          deploy:
            steps:
              - task: CmdLine@2
                inputs:
                  script: |
                    echo DeploymentStageWithoutApproval: $(areFilesDifferent)

  - stage: Display2
    condition: or( eq(dependencies.DeploymentStageWithApproval.result, 'Succeeded'), eq(dependencies.DeploymentStageWithoutApproval.result, 'Succeeded') )
    variables:
      areFilesDifferent: $[ dependencies.Init.outputs['RunScript.compareFiles.areDifferent'] ]
    jobs:
    - job: RunScript
      steps:
        - checkout: none
        - task: CmdLine@2
          inputs:
            script: |
              echo areFilesDifferent: $[ variables.areFilesDifferent ]
              echo DeploymentStageWithApproval: $[ dependencies.DeploymentStageWithApproval.result ]
              echo DeploymentStageWithoutApproval: $[ dependencies.DeploymentStageWithoutApproval.result ]

Here is my Powershell: '***\compareFileContent.ps1'

$equal = $filetext1 -ceq $filetext2 # case sensitive comparison
$equalString = (&{If($equal) {"true"} Else {"false"}})
echo "##vso[task.setvariable variable=areDifferent;isOutput=true]$equalString"

All the scripts jobs are writing only the text, not the variables, I don't understand why.

If DeploymentStageWithApproval is run, approval is triggered but Display2 is never run.

If DeploymentStageWithoutApproval is run, Display2 is run

I have the feeling that is because if the approval but one once I approve, the task runs, why it doesn't go to "stage: Display2" ?

Thanks for any help, Claude

*************************** Update 1

Thank you, your comments did helped me a lot understanding the syntax. Still, in my last stage, the variable is not printed and I don't understand why.

Here is a smaller version of my YAML that demonstrate my issue:

stages:
  - stage: Init
    jobs:
    - job: RunScript
      steps:
        - checkout: none
        - task: PowerShell@2
          name: compareFiles
          inputs:
            targetType: filePath
            filePath: '***\compareFileContent.ps1'

  - stage: Display1
    dependsOn: Init
    variables:
      areFilesDifferent: $[ stageDependencies.Init.RunScript.outputs['compareFiles.areDifferent'] ]
    jobs:
    - job: DisplayVariables
      steps:
        - checkout: none
        - task: CmdLine@2
          inputs:
            script: |
              echo areFilesDifferent: $(areFilesDifferent)

Displays: areFilesDifferent: true

  - stage: WithoutApproval
    dependsOn: Display1
    condition: eq( dependencies.Init.outputs['RunScript.compareFiles.areDifferent'], 'true' )
    variables:
      areFilesDifferent: $[ stageDependencies.Init.RunScript.outputs['compareFiles.areDifferent'] ]
    jobs:
    - deployment: DeploymentJob
      environment: 'ST'
      strategy:
        runOnce:
          deploy:
            steps:
              - checkout: none
              - task: CmdLine@2
                inputs:
                  script: |
                    echo DeploymentStageWithoutApproval: $(areFilesDifferent)

Displays: DeploymentStageWithoutApproval:

I would assume it is linked to the deployment task but I don't see how I can get the value, I did try to move the variable assignment under the job with no success.

I probably won't need the variable in that place but for debugging, it would be useful to understand this problem.

Thanks and regards, Claude

ClaudeVernier
  • 427
  • 4
  • 20

1 Answers1

1

You are using wrong syntax (which is really confusing here).

For instance - it doesn't work

      areFilesDifferent: $[ dependencies.Init.outputs['RunScript.compareFiles.areDifferent'] ]

Becase you need to use stageDependencies here not dependencies.

So for condition on stage level you should use dependencies, but for variables set on stage level stageDependencies.

What else:

  • you can't do that
    variables:
      areFilesDifferent: $[ dependencies.Init.outputs['RunScript.compareFiles.areDifferent'] ]
    condition: eq( variables.areFilesDifferent, 'false' )
  • but this would work
    condition: eq( dependencies.Init.outputs['RunScript.compareFiles.areDifferent'], 'false' )

Please check this example:

stages:
- stage: StageA
  jobs:
  - job: A1
    steps:
      - pwsh: echo "##vso[task.setvariable variable=RunStageB;isOutput=true]true"
        name: setvarStep
      - bash: echo $(System.JobName)

- stage: StageB
  dependsOn: 
    - StageA
 
  # when referring to another stage, stage name is included in variable path
  condition: eq(dependencies.StageA.outputs['A1.setvarStep.RunStageB'], 'true')
  
  # Variables reference syntax differs slightly from inter-stage condition syntax
  variables:
    myOutputVar: $[stageDependencies.StageA.A1.outputs['setvarStep.RunStageB']]
  jobs:
  - deployment: B1
    pool:
      vmImage: 'ubuntu-16.04'
    environment: envB
    strategy:                  
      runOnce:
        deploy:
          steps:
          - bash: echo $(myOutputVar)

But if you use the same condition on job level as it is shown above you should use stageDependencies

Krzysztof Madej
  • 32,704
  • 10
  • 78
  • 107
  • Thanks a lot ! It did helped but I still have an issue with displaying the variable in the later stage, I explained it in Update 1 if you would have some time and wanted to look at it :-) I am still stuck with my branch-in problem but will write a new question and try to be clearer :) – ClaudeVernier Jun 21 '21 at 15:29
  • @ClaudeVernier cool I'm happy that it helped you. Could you also consider upvoting my reply if it was helpful for you? – Krzysztof Madej Jun 21 '21 at 20:23