I can firmly say that I am well experienced in Continuous Integration / Continuous Deployment (CI/CD) pipelines, and in general simple is always better dan complex. If you need something complex, there is a different place for your process: CICD should be nothing more than:

  • BUILD
  • TEST
  • RELEASE
  • DEPLOY

For a client I am working on Azure Devops Pipelines and so far my initial experiences have left me somewhat skeptical, as I find that it often imposes a level of abstraction that veers away from my preference for simplicity.

The basics

Run time vs Compile time variables

..

Iteration

Have a job that runs over every fruit in fruitList, with the strategy approach you can manage how many jobs will run in parallel.

- job: Fruit
  dependsOn: Setup
  strategy:
    maxParallel: ${{ parameters.maxParallel }}
    matrix: # https://learn.microsoft.com/en-us/azure/devops/pipelines/yaml-schema/jobs-job-strategy
      ${{ each fruitName in split(parameters.fruitList, ',') }}:
        ${{ fruitName }}:
          fruitName: ${{ fruitName }}
    steps:
      - checkout: self
        submodules: true
      - task: AzureCLI@2
        displayName: "echo"
        inputs:
          scriptType: bash
          scriptLocation: inlineScript
          addSpnToEnvironment: true
          inlineScript: |
            set -xe    
            set -o nounset    
            echo "RUNNING FOR FRUIT: $(fruitName)"            

Trigger another pipeline

This task triggers another pipeline with id 12345 and some parameters.

- task: AzureCLI@2
  name: CallAnotherPipeline
  displayName: CallAnotherPipeline
  env:
    AZURE_DEVOPS_EXT_PAT: $(System.AccessToken)
  inputs:
    scriptType: bash
    azureSubscription: ${{ environment.ServiceConnection }}
    scriptLocation: inlineScript
    addSpnToEnvironment: true
    inlineScript: |
      set -xe    
      set -o nounset
      # https://learn.microsoft.com/en-us/cli/azure/pipelines?view=azure-cli-latest#az-pipelines-run
      az config set extension.use_dynamic_install=yes_without_prompt
      az pipelines run --id 12345 \
        --branch $(Build.SourceBranch) \
        --parameters "EnvironmentName=sandbox" \
                      "fruitList=$(fruitList)" \
                      "AgentPool=${{ environment.AgentPool }}" \
                      "ServiceConnection=${{ environment.ServiceConnection }}" \
        --verbose
        ```