Shipfox
Understand

Context and templating

Understand when run data becomes available, how outputs move it between jobs, and how workflows use it safely.

Context is the data a workflow can read while it runs. It starts with the event or the manual inputs. It grows as jobs and steps produce results.

Timing matters. A workflow can't read a result before the work that creates it has finished. Shipfox resolves each value once enough context exists. A value that depends on later work waits for that work to finish.

When each kind of data becomes available

Context is a flow, not one global object. Data joins it at five points:

  1. Run creation adds the run identity, the trigger, the event, and the inputs.
  2. Job readiness adds the outputs of upstream jobs that have finished.
  3. Listening execution adds the event batch that started that execution.
  4. Step dispatch adds earlier step outputs and retry context.
  5. Runner execution resolves secret bindings for the command that needs them. The secret value never enters the run plan.

A tool step adds one short-lived value. Its provider response is readable as result only while that step maps its outputs, right after the call returns. Later steps read the stored value as steps.<key>.outputs.result.

Workspace variables and project settings hold long-lived configuration. Events and outputs describe this run. Secrets grant access and follow a stricter path.

The Contexts reference is the canonical table of which contexts each field can read.

Two kinds of expression: templates and predicates

A ${{ }} template puts a value into text or into a setting. It can put an issue title in a prompt. It can also bind a job output to an environment variable.

A predicate returns true or false. Filters, conditions, gates, and job success rules use predicates. They decide whether work starts, continues, or passes.

The two roles stay separate, which makes policy easier to inspect. A template never decides control flow. A predicate can't run a command or change outside state. The same saved context therefore always produces the same decision.

Use a template to move a known value. Use a predicate when the workflow needs a yes-or-no rule. The Expressions reference defines the exact syntax and the available fields.

How outputs move results between jobs

Steps in one job can share files, but files don't cross a job boundary. An output turns a result into named workflow data that later work can read.

This complete workflow moves a version between two isolated jobs:

.shipfox/workflows/pass-version-between-jobs.yml
# yaml-language-server: $schema=https://www.shipfox.io/docs/workflow.schema.json
name: Pass a version between jobs
runner: shipfox

triggers:
  manual:
    source: manual

jobs:
  package:
    outputs:
      version: ${{ steps.read_version.outputs.version }}
    steps:
      - key: read_version
        run: echo "version=$(git describe --tags --always)" >> "$SHIPFOX_OUTPUT"
        outputs:
          version: string

  publish:
    needs: package
    steps:
      - run: printf 'Publishing version %s\n' "${{ jobs.package.outputs.version }}"

The step creates version. The package job publishes it. The publish job declares the dependency and puts the value in its command.

When a step declares a JSON array or object, a job output that maps exactly one expression keeps that structure for later jobs. A later expression such as jobs.review.outputs.findings[0].severity can then read a nested field. A template that mixes text and expressions still produces a string.

Outputs fit small facts. Files and build products belong in external artifact storage, with an output that carries their location. Step outputs defines declaration types and encoding. Job outputs lists the limits for job outputs.

Treat outside data as text, not as instructions

Events, inputs, and step outputs carry data that the workflow didn't write. A shell step reads that data as text, so it can't run as a command. A few shell constructs read their own arguments again and break that protection.

Nothing protects a prompt or a job setting this way. An event can contain instructions for an agent. It can also choose the runner a job uses. Keep event data out of any choice you wouldn't let a stranger make.

Secrets and variables describes storage, masking, and binding. Integrations, integration connections, and tools explains the external credential boundary.

Was this page helpful?
Edit this page on GitHub

On this page