4
votes

I have been trying to define a variable in a lifecycle hook within a deployment job, to then access that variable in a later lifecycle hook. The documentation on deployment jobs references the ability to do so, but offers no actual examples of this case (added emphasis):

Define output variables in a deployment job's lifecycle hooks and consume them in other downstream steps and jobs within the same stage.

The sample pipeline that I've been working with:

stages:
- stage: Pipeline
  jobs:
  - deployment: Deploy
    environment: 'testing'
    strategy:
      runOnce:
        preDeploy:
          steps:
          - bash: |
              echo "##vso[task.setvariable variable=myLocalVar;isOutput=false]local variable"
            name: setvarStep
          - bash: |
              echo "##vso[task.setvariable variable=myOutputVar;isOutput=true]output variable"
            name: outvarStep
          - bash: |
              echo 'Both $(myLocalVar) and $(outvarStep.myOutputVar) are available here'
              echo "Both $(myLocalVar) and $(outvarStep.myOutputVar) are available here"
        deploy:
          steps:
          - bash: |
              echo 'Neither $(myLocalVar) nor $(outvarStep.myOutputVar) are available here'
              echo "Neither $(myLocalVar) nor $(outvarStep.myOutputVar) are available here"

I have tried any number of options, but nothing I've done seems to allow this to actually work - the output of the bash task in the deploy lifecycle hook is:

Neither nor are available here

  • I've tried wiring in the variables to the bash task via the env: input, both using the macro syntax (eg $(myOutputVar) and the runtime expression syntax, hoping maybe there's a hidden dependency I could find (eg $[ dependencies.Deploy.outputs['preDeploy.outVarStep.myOutputVar'] ], and many, many other syntaxes)
  • I've tried defining the variables at the job level, hoping they'd be updated by the first preDeploy lifecycle hook and available to the deploy lifecycle hook.
  • I've tried echo-ing the variables via the runtime expression syntax
  • Many other combinations of syntax, hoping I'd stumble onto the actual answer

But all to no avail. I will likely resort to a hack of uploading the variable as an artifact and downloading it later, but would really like to find the solution to this issue. Has anyone been able to accomplish this? Many thanks in advance.

1

1 Answers

5
votes

Work around:

Firstly, share you the correct sample on this scenario you are looking for:

stages:
- stage: Pipeline
  jobs:
  - deployment: Deploy
    environment: 'testing'
    strategy:
      runOnce:
        preDeploy:
          steps:
          - bash: |
              echo "##vso[task.setvariable variable=myLocalVar;isOutput=false]local variable"
            name: setvarStep
          - bash: |
              echo "##vso[task.setvariable variable=myOutputVar;isOutput=true]output variable"
            name: outvarStep
          - bash: |
              echo 'Both $(myLocalVar) and $(outvarStep.myOutputVar) are available here'
              echo "Both $(myLocalVar) and $(outvarStep.myOutputVar) are available here"
              mkdir -p $(Pipeline.Workspace)/variables
              echo "$(myLocalVar)" > $(Pipeline.Workspace)/variables/myLocalVar
              echo "$(outvarStep.myOutputVar)" > $(Pipeline.Workspace)/variables/myOutputVar

          - publish: $(Pipeline.Workspace)/variables
            artifact: variables
        deploy:
          steps:
          - bash: |
              echo 'Neither $(myLocalVar) nor $(outvarStep.myOutputVar) are available here'
              echo "Neither $(myLocalVar) nor $(outvarStep.myOutputVar) are available here"
          - download: current
            artifact: variables
          - bash: |
              myLocalVar=$(cat $(Pipeline.Workspace)/variables/myLocalVar)
              myOutputVar=$(cat $(Pipeline.Workspace)/variables/myOutputVar)
              echo "##vso[task.setvariable variable=myLocalVar;isoutput=true]$myLocalVar"
              echo "##vso[task.setvariable variable=myOutputVar;isoutput=true]$myOutputVar"
            name: output
          - bash: |
              echo "$(output.myLocalVar)"
              echo "$(output.myOutputVar)"
            name: SucceedToGet

You will see that the output variables can succeed to printed in SucceedToGet task:

enter image description here


Explanation for why your previous attempts were keeping failed:

For our system, strategy represents one job before it start to running(compile time). It only expanded at running time.

Define output variables in a deployment job's lifecycle hooks and consume them in other downstream steps and jobs within the same stage.

Here other downstream steps and jobs means a independent job which independent at compile time. That's why we provide that sample YAML under this line.