Side Quest: Passing Data Between Steps with $GITHUB_OUTPUT
August 15, 2026 · View on GitHub
Optional: work through this deep-dive if you want to understand how data flows between steps, then return to Step 16.
GitHub Actions runs each step in its own shell process. That means a plain export MY_VAR=value in one step is invisible to the next step — the environment is thrown away when the step exits. $GITHUB_OUTPUT is the official mechanism for persisting data across steps.
Why export doesn't work across steps
# ❌ This looks reasonable but DOES NOT WORK
- name: Set a value
run: export RESULT="hello"
- name: Use the value
run: echo "$RESULT" # prints nothing — RESULT is gone
Each step is a separate child process. Environment variables set with export only survive for the duration of that step.
Single-line values
Append a key=value pair to the file path stored in the $GITHUB_OUTPUT environment variable:
# ✅ Write a single-line value
echo "status=healthy" >> $GITHUB_OUTPUT
To read it back in a later step, reference ${{ steps.<id>.outputs.status }} — but first you need to give the writing step an id.
Giving steps an id
A step id is how you refer to its outputs elsewhere in the workflow. Add id: at the same level as name: and run::
- name: Check health
id: health_check
run: |
echo "status=healthy" >> $GITHUB_OUTPUT
Now any later step (or the AI prompt) can reference:
${{ steps.health_check.outputs.status }}
Multi-line values with the <<EOF heredoc syntax
A single echo "key=value" won't work for multi-line content because the newlines would break the key=value format. Use a heredoc delimiter instead:
# ✅ Write a multi-line value
echo "commit_log<<EOF" >> $GITHUB_OUTPUT
echo "$COMMIT_LOG" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
The three lines together tell GitHub Actions:
commit_log<<EOF— start a multi-line value namedcommit_log, usingEOFas the end marker.$COMMIT_LOG— the actual content (can span many lines).EOF— close the block.
You can use any unique string as the delimiter — EOF is just a convention.
Injecting outputs into an AI prompt
Once your data is in $GITHUB_OUTPUT, you reference it directly inside the workflow Markdown body — which is the AI prompt in gh-aw. There is no separate step to invoke the AI; the body text is sent to the model after all step outputs have been resolved.
Frontmatter (data-preparation step):
---
steps:
- name: Fetch recent commits
id: recent
run: |
echo "commit_log<<EOF" >> $GITHUB_OUTPUT
git log --oneline -10 >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
---
Workflow body (the prompt):
Here are the recent commits:
${{ steps.recent.outputs.commit_log }}
Write a one-paragraph summary of this activity.
The ${{ ... }} expression is resolved by GitHub Actions before the body is sent to the model, so the AI receives the fully expanded text.
✅ Checkpoint
- You can explain why
exportdoes not pass values between steps - You can write a single-line value to
$GITHUB_OUTPUT - You know how to give a step an
idand reference its outputs - You can use the
<<EOFheredoc syntax for multi-line values - You can reference step outputs inside an AI prompt
Return to Connect a Live Data Source to Your Workflow.