Search code examples
azuregithubyamlgithub-actions

Environment variables not always being expanded in GitHub Actions workflow file


I have a GitHub Actions workflow file where environment variables are not always being expanded.

As per the comments, the usage of the environment variable works correctly until the last usage of it in the name: deploy section where it does not expand and literally becomes the string rg-blue-$***GITHUB_REF#refs/heads/*** instead of the correctly expanded string it is in the previous sections: rg-blue-my-branch-name.

This results in the Azure ARM error: Error: Resource Group rg-blue-$***GITHUB_REF#refs/heads/*** could not be found.

Why does variable expansion work correctly everywhere except the last step? How do I fix it?

on: [push]
name: Azure ARM
jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    env:
      resourceGroupName: rg-blue-${GITHUB_REF#refs/heads/}
      resourceGroupLocation: 'uksouth'

    - name: Use the custom ENV variable
      run: |
        echo "${{ env.resourceGroupName}}"
        echo ${{ env.resourceGroupName}}
      // these two work perfectly fine and prints "rg-blue-my-branch-name" etc

    - uses: actions/checkout@master

    - uses: azure/login@v1
      with:
        creds: ${{ secrets.AZURE_CREDENTIALS }}

    - uses: azure/CLI@v1
      with:
        inlineScript: |
          #!/bin/bash
          
    // works perfectly fine here too
          if $(az group exists --name ${{ env.resourceGroupName }}) ; then
            echo "Azure resource group ${{ env.resourceGroupName }} already exists, skipping creation..."
          else
            az group create --name ${{ env.resourceGroupName }} --location ${{ env.resourceGroupLocation }}
            echo "Azure resource group ${{ env.resourceGroupName }} created"
          fi

      # Deploy Bicep file
    - name: deploy
      uses: azure/arm-deploy@v1
      with:
        subscriptionId: ${{ secrets.AZURE_SUBSCRIPTION }}     <- this one works fine!
        resourceGroupName: "${{ env.resourceGroupName }}"     <- Error: Resource Group rg-blue-$***GITHUB_REF#refs/heads/*** could not be found.
        template: infrastructure/blue.bicep
        parameters: storagePrefix=mystore
        failOnStdErr: false

Solution

  • Shell parameter expansion doesn't happen when you assign a value in YAML. In other words, after this

        env:
          resourceGroupName: rg-blue-${GITHUB_REF#refs/heads/}
    

    the value of resourceGroupName is the literal string rg-blue-${GITHUB_REF#refs/heads/}. It seems to work because when you use

    echo "${{ env.resourceGroupName}}"
    

    this is replaced with

    echo "rg-blue-${GITHUB_REF#refs/heads/}"
    

    and then the shell does the expansion. You can test this by using

    echo '${{ env.resourceGroupName}}'
    

    instead to suppress shell parameter expansion.

    To fix, you could use a separate step to set the environment variable correctly:

        - name: Set env variable
          run: |
            echo "resourceGroupName=${GITHUB_REF#refs/heads/}" >> "$GITHUB_ENV"
    

    and not set it in the env beforehand.

    Alternatively, you could use github.ref_name, which is the already shortened Git ref:

        env:
          resourceGroupName: rg-blue-${{ github.ref_name }}
    

    This is also available in the environment as $GITHUB_REF_NAME.