yq: Read a Value into $GITHUB_OUTPUT
A GitHub Actions step reads a value with yq and writes it to $GITHUB_OUTPUT so later steps can consume it.
Exposing a version or image tag from a YAML file as a step output is one of the most common yq uses in Actions. The mechanics of $GITHUB_OUTPUT, not yq itself, cause most of the trouble.
What it does
yq prints the value at a path; the workflow captures it in a shell variable and appends key=value to the file named by $GITHUB_OUTPUT. A later step reads it via steps.<id>.outputs.<key>. Go yq prints scalars raw, so no -r flag is needed.
Common usage
- id: ver
run: echo "version=$(yq '.version' chart.yaml)" >> "$GITHUB_OUTPUT"
- run: echo "Got ${{ steps.ver.outputs.version }}"
# image tag for a selected container
- run: |
TAG=$(yq '.spec.template.spec.containers[]|select(.name=="app")|.image' deploy.yaml)
echo "image=$TAG" >> "$GITHUB_OUTPUT"Patterns
| Need | Approach |
|---|---|
| Single scalar | echo "k=$(yq '.path' f)" >> "$GITHUB_OUTPUT" |
| Compact JSON value | yq -o=json -I=0 '.obj' f, then write it |
| Avoid float coercion | Read with yq; keep the string as printed |
| Multiline value | Use the GITHUB_OUTPUT heredoc delimiter syntax |
| No-match guard | yq -e '.path' to exit non-zero on null |
In CI
For a value that may contain newlines (a multiline block or JSON), the single-line key=value form breaks; use the heredoc form: { echo "cfg<<EOF"; yq -o=json '.cfg' f; echo EOF; } >> "$GITHUB_OUTPUT". For scalars, the simple echo form is enough.
Common errors in CI
An empty output usually means the path did not match; yq printed null or an empty line. Add yq -e so a missing value fails the step instead of silently writing nothing. A multiline yq result written with the plain key=value form corrupts $GITHUB_OUTPUT and downstream steps see truncated data; switch to the heredoc delimiter. "yq: command not found" here is the same install problem as everywhere.