cell-in
cell-in

Reputation: 789

How to use defined variables in the for loop in Azure DevOps pipeline?

I would like to publish all the packages recursively as universal packages that are in $(Build.ArtifactStagingDirectory) folder in the Azure DevOps pipeline. So, I loop over the user defined variable which is created as an output of the previous bash script. Then, I use UniversalPackages@0 task to publish a packages with the for loop.

           - bash: |
                #!/bin/bash

                get_all_files=$(ls -Rp '$(Build.ArtifactStagingDirectory)' | grep -v /)

                my_array=()

                for OUTPUT in $get_all_files
                do
                file_name="${OUTPUT##*/}"
                echo "File: $file_name"
                my_array[${#my_array[@]}]=$file_name
                done
                my_array=${my_array[@]}
                echo "##vso[task.setvariable variable=my_array;isOutput=true]$my_array"
            displayName: 'Get the list of packages'
            name: setVarStep

          - bash: echo $(setVarStep.my_array)
            displayName: 'List the packages'

          - ${{ each item in '$(setVarStep.my_array)' }}:
            - task: UniversalPackages@0
              displayName: Universal Publish
              inputs:
                command: publish
                publishDirectory: '$(Build.ArtifactStagingDirectory)'
                vstsFeedPublish: 'my-feed'
                vstsFeedPackagePublish: $(item)
                packagePublishDescription: 'Publish package'

The pipeline throws the error below.

Expected a sequence or mapping. Actual value '$(setVarStep.my_array)'

Looks like this is not the correct way of using the variable that are defined on run-time. How to use defined variables in the for loop in Azure DevOps pipeline?

Upvotes: 0

Views: 1468

Answers (1)

jessehouwing
jessehouwing

Reputation: 114641

The ${{ }} syntax is evaluated prior to template execution. So the value is effectively undefined at that point in time. You can't rely on runtime values during template expansion.

You can use the command line tools to publish directly to artifacts from your script block using the Azure DevOps CLI. It has a az artifacts universal publish command:

// If not installed by default in Azure CLI
az extension add --name azure-devops

export AZURE_DEVOPS_EXT_PAT=$(System.AccessToken)
az devops login --organization https://dev.azure.com/jessehouwing/
az artifacts universal publish --organization https://dev.azure.com/jessehouwing/ --feed feed-name --name my-first-package --version 0.0.1 --description "Welcome to Universal Packages" --path .

It requires Azure CLI and the Azure CLI DevOps plugin to be installed. On the hosted agent, I think this is the default.

I'm not 100% sure you could use the predefined SYSTEM_ACCESSTOKEN as a PAT.

- bash: echo This script could use $SYSTEM_ACCESSTOKEN
  env:
    SYSTEM_ACCESSTOKEN: $(System.AccessToken)

I'm guessing this should work in the end, it's this token that is used in the UniversalPackages task.

Upvotes: 2

Related Questions