Pass Values Between Jobs
Publish a value from a step and read it in a later job.
Use an output to send a small value from one job to a later job. Typical values are a version, a commit SHA, a URL, or a decision. Jobs don't share files, so an output is the way to move a value between them.
The example below sends a short text message. To send another value, keep the same structure and change the names, the type, and the command.
Publish a value and read it in a later job
This is a complete workflow:
# yaml-language-server: $schema=https://www.shipfox.io/docs/workflow.schema.json
name: Pass output between jobs
runner: shipfox
triggers:
manual:
source: manual
jobs:
prepare:
steps:
- key: create_message
run: echo "message=Hello from the prepare job" >> "$SHIPFOX_OUTPUT"
outputs:
message: string
export: true
consume:
needs: prepare
steps:
- env:
MESSAGE: ${{ jobs.prepare.outputs.message }}
run: echo "$MESSAGE"To send any value between jobs, you need three things:
- Create the value in a step. Give the step a
key. Declare the output name and type underoutputs. In the command, writename=valueto the file$SHIPFOX_OUTPUT. - Export the value from the step. Add
export: trueto publish every declared output of the step as a job output with the same name. To publish only some outputs, list their names, as inexport: [message]. - Read the value in a later job. Add the first job to
needsin the later job. Read the value withjobs.<job>.outputs.<name>.
In your own workflow, change the output names, the type, and the command that produces the value. Keep everything else.
Set a default for a step that may not produce the value
A skipped step has no value for its outputs. A failed step has a value only
for the outputs it wrote before it failed. An exported output without a value
is left out of the job outputs, and a later job that reads it fails. Add a default to the output when later work always reads it.
- key: changes
run: git diff --quiet || echo "changed=true" >> "$SHIPFOX_OUTPUT"
outputs:
changed:
type: boolean
default: false
export: trueLater steps and jobs read the default of each output that the step has no value for. That covers a skipped step, and a failed or cancelled step that didn't write the output. It also covers a run step that succeeds without writing the output, as the example does when nothing changed.
Two step types behave differently:
-
Agent steps. An agent step that finishes must still set every declared output. Its defaults apply only when the step is skipped, fails, or is cancelled.
-
Tool steps. A tool step output can't have a default, because it is an expression and not a declaration. Don't export an output that later work always reads. Publish it from the job
outputsmap and check the step status there:outputs: pr_url: '${{ steps.open_pr.status == "succeeded" ? steps.open_pr.outputs.pr_url : "" }}'
Fill an output from standard output or a file
A run step can fill an output without writing to $SHIPFOX_OUTPUT. Use
from_stdout when the command prints the value. Use from_file when the
command writes the value to a file.
- key: revision
run: git rev-parse HEAD
outputs:
commit:
type: string
from_stdout: true
export: true
- key: notes
run: git log -5 --format=%s > notes.txt
outputs:
notes:
type: string
from_file: notes.txt
export: trueShipfox removes one trailing newline from the value. A step can have one
from_stdout output. A file path is relative to the working directory of the
step. Step outputs lists the rules
and the size limits.
Pass a list or a map to a command
Put the value in env. Shipfox writes a list or a map as JSON text, so the
command can parse it. You don't need toJson().
- key: plan
run: echo 'targets=["api","web"]' >> "$SHIPFOX_OUTPUT"
outputs:
targets: json
- env:
TARGETS: ${{ steps.plan.outputs.targets }}
run: printf '%s' "$TARGETS" | jq -r '.[]'Adapt it to your workflow
| To... | Change this |
|---|---|
| Read the value in a later step of the same job | You don't need export or needs. Read steps.<key>.outputs.<name> in the later step. |
| Rename a value, or build it from several steps | Remove export. Add an outputs map to the job and set each name to an expression. Job fields describes the map. |
| Pass a number, a boolean, or structured data | Declare another output type. Step outputs lists the types and their encoding. |
| Read a nested field in a later job | Declare a json output and export it. Later jobs can then read nested fields. See How jobs share data. |
| Run a later step only for some values | Read the output in the if condition of that step. |
| Publish a value from an agent step | Declare the outputs on the agent step and add export. See Get typed agent outputs. |
| Pass a file or a build product | Outputs are for small values. Upload the file to your own storage and pass its URL or path as the output. |
To use an output in a shell command, put it in env and read the environment
variable, as the example does. The shell then treats the value as text and
doesn't run it as part of the command.
To give later steps of the same job an environment variable or a PATH
directory, see Set environment variables for later
steps.
Verify the output
Start the workflow
Select Run, then open the new run.
Compare the output
Open the job that publishes the value. Confirm that its outputs include the name you declared. Open the job that reads the value. Confirm that it received the same value.
In the example, the prepare job lists message. The log of the consume
job contains Hello from the prepare job.
See Job outputs for size limits.