13

I'm not sure if it's possible, but I'm attempting to use outputs from one reusable workflow, in another, that's part of the same caller workflow. For reference, please see the configs below:

Caller Workflow:

jobs:
  call-workflow-calver:
    uses: ./.github/workflows/called-workflow1.yaml
    secrets: inherit

  call-workflow-echo:
    needs: call-workflow-calver
    uses: ./.github/workflows/called-workflow2.yaml
    secrets: inherit

Job for creating the CalVer tag (it outputs as $VERSION as part of the action)

Called Workflow 1:

...
jobs:
  calver:
    name: Create CalVer tag
...
    steps:
      - name: Calver tag
        uses: StephaneBour/actions-calver@1.4.4
        if: ${{ github.ref == 'refs/heads/main' }}
        id: calVer
        with:
          date_format: "%Y-%m-%d"
          release: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }}
...

Trying to use the CalVer $VERSION output from another caller workflow

Called Workflow 2:

...
- name: Echo
  run: |
    echo ${{needs.calver.outputs.VERSION}}
...

The basic concept is I'm trying to use outputs from one reusable workflow in another for setting CalVer versions in workflow 1, calling that in workflow 2 so I can set it as an image version. I will eventually use in a 3rd reusable workflow to deploy said image. If this is possible, that would be great!

Hopefully, this all makes a bit of sense, but if anything needs clarifying, please do let me know!

Many thanks in advance!

Kris
  • 141
  • 1
  • 4

1 Answers1

23

According to the official documentation, you can now declare outputs to reusable workflows.

These work just like job outputs and are available via needs.<reusable>.outputs.<output> format once you declare the output.

Example

1. Reusable workflow configuration:

name: Reusable workflow

on:
  workflow_call:
    # Map the workflow outputs to job outputs
    outputs:
      firstword:
        description: "The first output string"
        value: ${{ jobs.example_job.outputs.output1 }}
      secondword:
        description: "The second output string"
        value: ${{ jobs.example_job.outputs.output2 }}

jobs:
  example_job:
    name: Generate output
    runs-on: ubuntu-latest
    # Map the job outputs to step outputs
    outputs:
      output1: ${{ steps.step1.outputs.firstword }}
      output2: ${{ steps.step2.outputs.secondword }}
    steps:
      - id: step1
        run: echo "firstword=hello" >> $GITHUB_OUTPUT
      - id: step2
        run: echo "secondword=world" >> $GITHUB_OUTPUT

2. Workflow using the reusable:

name: Call a reusable workflow and use its outputs

on:
  workflow_dispatch:

jobs:
  job1:
    uses: octo-org/example-repo/.github/workflows/called-workflow.yml@v1

  job2:
    runs-on: ubuntu-latest
    needs: job1
    steps:
      - run: echo ${{ needs.job1.outputs.firstword }} ${{ needs.job1.outputs.secondword }}

Note that if a reusable workflow that sets an output is executed with a matrix strategy, the output will be the output set by the last successful completing reusable workflow of the matrix which actually sets a value. That means if the last successful completing reusable workflow sets an empty string for its output, and the second last successful completing reusable workflow sets an actual value for its output, the output will contain the value of the second last completing reusable workflow.

I used this workflow as example here if you want to check the logs of the workflow run.

GuiFalourd
  • 15,523
  • 8
  • 44
  • 71
  • 2
    Ah that's amazing! not sure how i missed this! my google-fu doesn't seem on point recently :D ill give it a try :) – Kris Sep 13 '22 at 12:04