Jobs and steps
Understand how the split into jobs affects shared files, parallel work, runner placement, and results.
A job is the unit that Shipfox places on a runner. A step is one ordered action inside that job. A step is a run step, an agent step, or a tool step.
The main design choice is where one job ends and the next begins. That choice decides which steps share a checkout, what can run at the same time, and which results must pass from one job to another.
Three kinds of step
Each kind of step performs a different kind of work.
| Step | Performs | Runs on |
|---|---|---|
| Run step | A shell command in the job's checkout. | The runner. |
| Agent step | A goal that an agent pursues in the checkout. | The runner. |
| Tool step | One integration operation with inputs the workflow supplies. | The Shipfox API, through an integration connection. |
A tool step has no working tree. It can't read files, set env, or use
secrets. Its inputs come from run data, and its result becomes step outputs
for later steps. Shipfox makes the call, so the provider credential never
reaches the runner.
The job still holds its runner while a tool step runs. The runner waits for the call to finish and then continues with the next step. A job made only of tool steps still needs a runner. Integrations, integration connections, and tools explains when a tool step fits better than an agent with tools.
When to keep steps in one job
Steps in one job run in order and use the same checkout. A later step can read files that an earlier step changed. It can also use packages that an earlier step installed.
Steps don't share one long-lived shell process. A shell variable set in one run step doesn't reach the next. Save a file in the checkout when the next step needs it. Publish an output when the value must become workflow data.
One job is usually the right choice when steps must:
- Edit and check the same files.
- Reuse an expensive local setup.
- Repeat together in a feedback loop.
- Use the same runner capabilities and repository permission.
The tradeoff is less parallelism. One slow step holds the job's runner and delays every later step.
When to split work into jobs
Each job gets a fresh checkout. It can use a different runner or repository permission. Jobs without dependencies can start at the same time when capacity is free.
Separate jobs fit work that must:
- Run in parallel.
- Fail or skip on its own.
- Use a different execution environment.
- Expose a small, named result to later work.
The cost is extra setup. Two jobs that both need Node.js packages each install them again. Their files, process environment, and logs stay separate.
This complete workflow shows the split:
# yaml-language-server: $schema=https://www.shipfox.io/docs/workflow.schema.json
name: Check and review a change
runner: shipfox
triggers:
manual:
source: manual
jobs:
lint:
steps:
- run: npm ci && npm run lint
test:
steps:
- run: npm ci && npm test
review:
needs: [lint, test]
steps:
- prompt: Review the repository for likely bugs and missing tests.lint and test can run in parallel. Each installs its own dependencies.
review waits for both, but receives neither job's files nor logs. It reviews
its own fresh checkout.
The shipfox label selects the default hosted runner. The Runner labels
reference lists the other hosted sizes.
The parallel CI recipe applies this shape to a GitHub push. The job fields reference defines the dependency syntax.
How results move between jobs
A job output passes a small value to later jobs. It fits a version, a decision, an identifier, or a URL.
An artifact is a file or a directory. One job's checkout isn't available to another job. Put large reports and build products in an external store. Pass only their location as an output.
This explicit hand-off means a later job can't depend on a file that another job left behind by accident. It also makes reruns and runner placement easier to predict.
A named agent session is a third way to pass context. It gives one agent's conversation to a later agent step in the same run. It doesn't pass files either.
A job also chooses its runner and its access
A job selects its runner labels as a whole. Split work when one part needs a private network, special hardware, or another operating system. Keep it together when every step needs the same environment.
Repository checkout permission also applies to the whole job. Each agent step selects its own integration tools, and each tool step names one operation. Both are separate from Git access. This matters when an agent reads code but only one later step must write to an external system.
Runners and execution environments explains placement. Agent access shows the separate repository and integration controls. Call an integration tool shows a tool step.
Retries and later events stay inside the job
A feedback loop repeats steps inside one job execution, so the repeated work keeps the same checkout. A listening job creates a new job execution for each later event or event batch. It can run its steps several times in one run.
Choose the job boundary before you add either kind of repetition. A job that mixes unrelated writes makes retries and later events harder to handle safely.