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.

How interpolation works

Interpolation reads a value from context and inserts it into a workflow field. Wrap the expression in ${{ }}. For example, Hello ${{ inputs.name }} adds the name input after Hello.

Use interpolation to add data to text or settings. It does not decide whether work runs.

A predicate is a yes-or-no check. For example, step.exit_code == 0 passes a gate when the command succeeds. Filters, conditions, gates, and job success rules use predicates.

The Expressions reference defines the exact syntax and available fields.

When data becomes available

A workflow gains data as the run progresses:

  • Run details, trigger data, inputs, and variables are available from the start.
  • Step outputs become available after the step finishes.
  • Job outputs become available after an upstream job finishes.
  • Restart feedback becomes available when a gate repeats steps.

The Contexts reference lists the exact availability of these values, tool results, listening events, and secrets.

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