Search code examples
azure-pipelines-yaml

Recreate Gitlab CI before_script / extends functionality to avoid duplicate code


With Gitlab CI, you can use before_script to run a script before every script command of a yaml file (cf. example 1 below).

A similar functionality can be achieved with extends and a hidden job, making it possible to also reuse other parameters (e.g. image, cf. example 2).

In this way, duplicate code can be avoided by defining content once and referencing it multiple times in different sections of the yaml file.

How can this be replicated with Azure Pipelines yaml files? There seems to be no equivalent of before_script and extends does not feature the Gitlab CI yaml functionality.

Gitlab CI yaml file, example 1:

before_script:
    - echo "this runs before every script command"

stages:
    - test

test-code:
    stage: test
    # before_script will be run before this script command
    script:
        - echo "run script"

Gitlab CI yaml file, example 2:

.hidden_job
    image: python:3.12-bookworm
    - script:
        - echo "reference this to avoid duplicate yaml code"

stages:
    - test

test-code:
    stage: test
    extends: .hidden_job
    script:
        - echo "run script"

Solution

  • I'm afraid there is no equivalent features in Azure DevOps as before_script and extends feature in Gitlab CI.

    duplicate code can be avoided by defining content once and referencing it multiple times in different sections of the yaml file.

    In addition to the YAML template shared by the answer above, I would like to share another method.

    We can define YAML Parameters(type: Stage, job, step) as the template job/step/stage in the same YAML. Then we can re-use it multiple times.

    Here are examples:

    Stage type parameter:

    parameters:
    - name: PreDeployStage
      type: stage
      default: 
        stage: 
        jobs:
        - job: DoNothing
          pool: 
           vmimage: windows-latest
          steps:
          - powershell: Write-host "Doing nothing"
    
    stages:
    - ${{ parameters.PreDeployStage }}
    - stage: 'Deploy'
      jobs:
      - job: test
        steps: 
        - script: echo "1"
    

    Job type parameter:

    parameters:
    - name: PreDeployJob
      type: job
      default: 
          job: 
          pool: 
           vmimage: windows-latest
          steps:
          - powershell: Write-host "Doing nothing"
    
    stages:
    - stage: 'Deploy'
      jobs:
      - ${{ parameters.PreDeployJob }}
      - job: test
        steps: 
        - script: echo "1"
    

    Step type parameter:

    parameters:
    - name: PreDeployStep
      type: step
      default: 
          script: echo "Doing nothing"
          displayName: PreDeployStep  
    stages:
    - stage: 'Deploy'
      jobs:
      - job: test
        steps: 
        - ${{ parameters.PreDeployStep }}
        - ${{ parameters.PreDeployStep }}
        - script: echo "1"
    

    In this case, when running the Pipeline, we can modify the parameters value.

    For example:

    enter image description here

    Result:

    enter image description here