Sections

Output variables can be powerful and frustrating at the same time. This simple how to, can save you ages of try and error.

What are output variables

Output variables are like return values of a step which can be used in all down streams like jobs, , reusable workflows and more. See GitHub Workflow Job Output Example Accessing these outputs can be pretty challenging as it depends on the context in which you are.

Creating an output

Creating an output is pretty simple made by an echo.
The output from a step will be later referenced by its id.

Syntax define step output: echo "<VariableName>=my variable value" >> $GITHUB_OUTPUT.

- name: "Example output creation"
  id: "my_step"
  run: |
    my_var="Hello World"
    echo "Output [$my_var]"
    echo "my_var=$my_var" >> $GITHUB_OUTPUT    

Get output values between steps

This is pretty simple just call

Syntax receive step output: ${{steps.<StepId>.outputs.<VariableName>}}

- name: "Example output call between steps"
  run: |
        echo "Output [${{steps.my_step.outputs.my_var}}]"

Get output values between jobs

Now the outputs needs to be defined also on the job level.
Plus the jobs needs to be connected by adding needs: my_job

Syntax define job output: ${{steps.<StepId>.outputs.<VariableName>}}
Syntax receive job output: ${{needs.<JobId>.outputs.<VariableName>}}

jobs:
  my_job:
    outputs:
      # Map the step outputs to job outputs
      my_var: ${{steps.my_step.outputs.my_var}}
    steps:
      - name: "Example output creation"
        id: "my_step"
        run: |
          my_var="Hello World"
          echo "Output [$my_var]"
          echo "my_var=$my_var" >> $GITHUB_OUTPUT          
  my_second_job:
    needs: my_job
    steps:
      - run: echo my_var [${{needs.my_job.outputs.my_var}}]

Get output variables between workflows

Yes this is another context….

Syntax define job output: ${{steps.<StepId>.outputs.<VariableName>}}
Syntax define workflow output: ${{jobs.<JobId>.outputs.<VariableName> }}
Syntax receive job output: ${{needs.<JobId>.outputs.<VariableName>}}


########## WORKFLOW 1 ##########

on:
  workflow_dispatch:

jobs:
  job1:
    name: "Call other workflow"
    uses: MY_OWNER/MY_REPO/.github/workflows/my_workflow.yml@main
  job2:
    needs: job1
    steps:
      - name: "Print my_var"
        run: echo my_var [${{needs.job1.outputs.my_var}}]

########## WORKFLOW 2 ##########

on:
  workflow_call:
    # Map the workflow outputs to job outputs
    outputs:
      my_var:
        description: "The first output string"
        value: ${{jobs.my_job.outputs.my_var}}
jobs:
  my_job:
    # Map the job outputs to step outputs
    outputs:
      my_var: ${{steps.my_step.outputs.my_var}}
    steps:
      - name: "Example output creation"
        id: "my_step"
        run: |
          my_var="Hello World"
          echo "Output [$my_var]"
          echo "my_var=$my_var" >> $GITHUB_OUTPUT          
  my_second_job:
    needs: my_job
    steps:
      - run: echo my_var [${{needs.my_job.outputs.my_var}}]