skip to Main Content

I am using stages from different Repository as a template Stage in my DevOps Pipeline. But I am not able to use those stages as dependsOn in a subsequent Stage. I am not allowed to make changes inside the Template Stages (build_functionapp_testcase2, datafactory_testcase3)

This is my pipeline, in this, I want that the Stage Cleanup is run if any of the above stages fail and it should also get the $NEW_VERSION variable from the ‘ImageDeployment’ Stage. Please help me with this.:

  - stage: ImageDeployment
    jobs:
      - job: NewImageDeployment
        timeoutInMinutes: 180
        pool:
          vmImage: 'ubuntu-latest'
        steps:
          - task: AzureKeyVault@2
            displayName: 'Fetch Secrets'
            inputs:
              connectedServiceName: '$(GLOBAL_SERVICE_CONNECTION)'
              keyVaultName: $(GLOBAL_KV_NAME)
              secretsFilter: "Packer-Secret"
              runAsPreJob: false

          - task: AzureCLI@2
            displayName: 'Check image version'
            retryCountOnTaskFailure: 0
            inputs:
              azureSubscription: '$(GLOBAL_SERVICE_CONNECTION)'
              scriptType: 'bash'
              scriptLocation: 'inlineScript'
              inlineScript: |
                while IFS=$'t' read -a arr_image_versions; do
                  version=${arr_image_versions[0]}
                  date=${arr_image_versions[1]}
                  if [[ $date > $old_date ]]; then
                    last_version=$version
                  fi
                  old_date=$date
                done <<< "$(az sig image-version list --gallery-image-definition xxxxxxxxxxx --gallery-name xxxxxxx --resource-group xxxxxxxx --query "[].[name, publishingProfile.publishedDate]" -o tsv)"
                echo "Last image version: $last_version"
                echo "##vso[task.setvariable variable=last_version]$last_version"
            
          - task: Bash@3
            name: CheckImageVersion
            displayName: 'Increment image version'
            inputs:
              targetType: 'inline'
              script: |
                IFS='.' read -ra VERSION_PARTS <<< "$(last_version)"
                PATCH_VERSION=${VERSION_PARTS[2]}
                PATCH_VERSION=$((PATCH_VERSION + 1))
                NEW_VERSION="${VERSION_PARTS[0]}.${VERSION_PARTS[1]}.$PATCH_VERSION"
                echo "New image version: $NEW_VERSION"
                echo "##vso[task.setvariable variable=NEW_VERSION;isOutput=true]$NEW_VERSION"

  - template: tests/build_functionapp_testcase2.yaml@self

  - template: tests/datafactory_testcase3.yaml@self

  - stage: Cleanup
    dependsOn: ImageDeployment
    condition: failed()
    jobs:
      - job: DeleteImage
        pool:
          vmImage: 'ubuntu-latest'
        variables:
          NEW_VERSION: $[ stageDependencies.ImageDeployment.NewImageDeployment.outputs['CheckImageVersion.NEW_VERSION'] ]
        steps:
          - script: |
              echo "NEW_VERSION in Cleanup stage: $(NEW_VERSION)" ```

2

Answers


  1. Stage conditions

    I want that the Stage Cleanup is run if any of the above stages fail

    You can use a combination of or(..) and failed(STAGE_NAME) expressions such as:

    - stage: Cleanup
      condition: or(
          failed('ImageDeployment'),
          failed('testcase2_STAGE_NAME'),
          failed('testcase3_STAGE_NAME')
        )
      jobs:
      - job: DeleteImage
        steps:
        # ...
    

    Stage dependencies

    But I am not able to use those stages as dependsOn in a subsequent Stage.

    TL;DR ideally a parameter should be added to the stage templates; if that’s not an option, keep in mind that when you define multiple stages in a pipeline, by default, they run one after the other.

    Creating configurable/extensible templates

    Considering that it’s difficult to predict and understand all the scenarios in which a stage or job template will be used, in order to create configurable and extensible stages/jobs templates the template authors/maintainers should be add some parameters to these templates, in order to:

    • Set stage/job condition
    • Set stage/job dependencies
    • Set job timeout

    For example:

    # templates/my-stage.yaml
    
    parameters:  
      # other parameters here
    
      - name: dependsOn
        type: object
        displayName: 'Dependencies'
        default: []
    
      - name: condition
        type: string
        displayName: 'Condition'
        default: ''
    
    stages:
      - stage: my_stage
        displayName: My stage
        dependsOn: ${{ parameters.dependsOn }}
        ${{ if ne(parameters.condition, '') }}:
          condition: ${{ parameters.condition }}
        jobs:
          # ...
    
    Login or Signup to reply.
  2. On the "Cleanup" stage, you can directly provide a list of stage names to the "dependsOn" option.

    stages:
    - stage: ImageDeployment
    
    . . .
    # Some stages defined in templates.
    . . .
    
    - stage: Cleanup
      dependsOn:
        - ImageDeployment
        - <name of stage_1 defined in templates>
        - <name of stage_2 defined in templates>
        . . .
        - <name of stage_N defined in templates>
      condition: failed()
    

    With above configurations, when any of the listed stages is failed, the "Cleanup" stage will run, and it also can get the output variable from "ImageDeployment" stage.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search