github-actions

What's the proper way to modify inputs before calling an external workflow?


I'm working with multiple repositories on the same domain that use Github Actions. I'm trying to update our deployment pipeline to run a test suite whenever changes to one of our APIs are deployed to one of our servers. The workflow for any given API, the workflow for the deployment and the workflow for the tests are in separate repositories.

In github.com/ourdomain/deploymentrepo/path/to/deployment.yml I have a setup like this:

on:
  workflow_call:
    inputs:
      runTests:
        description: 'Run tests'
        required: false
        default: false
        type: boolean
      testTags:
        description: 'Tags to run tests with'
        required: false
        type: string

jobs:
  deploy:
    runs-on: company-runner

      - name: Set test tags
        if: ${{ inputs.runTests }}
        run: |
          if [[ <dev env condition> ]]; then
           echo "testTags=@dev and ${{ inputs.testTags }}" >> $GITHUB_ENV
          elif [[ <qa env condition> ]]; then
            echo "testTags=@qa and ${{ inputs.testTags }}" >> $GITHUB_ENV
          elif [[ <prod condition> ]]; then
            echo "testTags=@prod and ${{ inputs.testTags }}" >> $GITHUB_ENV
          else
           echo "testTags=${{ inputs.testTags }}" >> $GITHUB_ENV
          fi
  
  functional-test:
    needs: deploy
    uses: ourdomain/testrepo/path/to/tests.yml@main
    if: ${{ inputs.runTests }}
    with:
      TAGS: ${{ env.testTags }}
    secrets: inherit

Then in github.com/ourdomain/testrepo/path/to/tests.yml I have:

on:
  workflow_call:
    inputs:
      TAGS:
        description: 'Tags to run test with'
        required: true
        default: ''
        type: string

The problem I'm having is that I can't find a good way to modify the tags input in deployment.yml and pass the modified input to tests.yml. env doesn't work because Actions won't let you pass envs to external workflows and I've tried various ways of using outputs and none of those worked either.

Way 1)

on:
  workflow_call:
    inputs:
      runTests:
        description: 'Run tests'
        required: false
        default: false
        type: boolean
      testTags:
        description: 'Tags to run tests with'
        required: false
        type: string

jobs:
  deploy:
    runs-on: company-runner

      - name: Set test tags
        if: ${{ inputs.runTests }}
        run: |
          if [[ <dev env condition> ]]; then
           echo "testTags=@dev and ${{ inputs.testTags }}" >> $GITHUB_OUTPUT
          elif [[ <qa env condition> ]]; then
            echo "testTags=@qa and ${{ inputs.testTags }}" >> $GITHUB_OUTPUT
          elif [[ <prod condition> ]]; then
            echo "testTags=@prod and ${{ inputs.testTags }}" >> $GITHUB_OUTPUT
          else
           echo "testTags=${{ inputs.testTags }}" >> $GITHUB_OUTPUT
          fi

  
  functional-test:
    needs: deploy
    uses: ourdomain/testrepo/path/to/tests.yml@main
    if: ${{ inputs.runTests }}
    with:
      TAGS: ${{ needs.deploy.outputs.testTags }}
    secrets: inherit

Way 2)

on:
  workflow_call:
    inputs:
      runTests:
        description: 'Run tests'
        required: false
        default: false
        type: boolean
      testTags:
        description: 'Tags to run tests with'
        required: false
        type: string

jobs:
  deploy:
    runs-on: company-runner

      - name: Set test tags
        if: ${{ inputs.runTests }}
        run: |
          if [[ <dev env condition> ]]; then
           echo "testTags=@dev and ${{ inputs.testTags }}" >> "$GITHUB_OUTPUT"
          elif [[ <qa env condition> ]]; then
            echo "testTags=@qa and ${{ inputs.testTags }}" >> "$GITHUB_OUTPUT"
          elif [[ <prod condition> ]]; then
            echo "testTags=@prod and ${{ inputs.testTags }}" >> "$GITHUB_OUTPUT"
          else
           echo "testTags=${{ inputs.testTags }}" >> "$GITHUB_OUTPUT"
          fi

  
  functional-test:
    needs: deploy
    uses: ourdomain/testrepo/path/to/tests.yml@main
    if: ${{ inputs.runTests }}
    with:
      TAGS: ${{ needs.deploy.outputs.testTags }}
    secrets: inherit

Way 3)

on:
  workflow_call:
    inputs:
      runTests:
        description: 'Run tests'
        required: false
        default: false
        type: boolean
      testTags:
        description: 'Tags to run tests with'
        required: false
        type: string

jobs:
  deploy:
    runs-on: company-runner

      - name: Set test tags
        if: ${{ inputs.runTests }}
        run: |
          if [[ <dev env condition> ]]; then
          echo "::set-output name=testTags::@dev and ${{ inputs.testTags }}"
          elif [[ <qa env condition> ]]; then
          echo "::set-output name=testTags::@qa and ${{ inputs.testTags }}"
          elif [[ <prod condition> ]]; then
            echo "::set-output name=testTags::@prod and ${{ inputs.testTags }}"
          else
            echo "::set-output name=testTags::${{ inputs.testTags }}"
          fi

  
  functional-test:
    needs: deploy
    uses: ourdomain/testrepo/path/to/tests.yml@main
    if: ${{ inputs.runTests }}
    with:
      TAGS: ${{ needs.deploy.outputs.testTags }}
    secrets: inherit

What's the proper way to modify an input and pass the modified value to an external workflow on the same domain?


Solution

  • You have to declare the output on a job level, and add an ID to the step producing the output.

    Your examples are all invalid as they're missing the steps: object, but I assume that's due to copy-pasting:

    jobs:
      deploy:
        runs-on: company-runner
        outputs:
          tags: ${{ steps.tags.outputs.tags }}
        steps:
          - name: Set test tags
            id: tags
            if: inputs.runTests
            env:
              test_tags: ${{ inputs.testTags }}
            run: |
              if [[ <dev env condition> ]]; then
               prefix='@dev and '
              elif [[ <qa env condition> ]]; then
                prefxix='@qa and '
              elif [[ <prod condition> ]]; then
                prefix='@prod and '
              fi
    
              echo "tags=$prefix$test_tags" >> "$GITHUB_OUTPUT"
      
      functional-test:
        needs: deploy
        uses: ourdomain/testrepo/.github/workflows/tests.yml@main
        with:
          TAGS: ${{ needs.deploy.outputs.tags }}
        secrets: inherit
    

    Some additional remarks: