Skip to content

Pipeline file reference

.squidci/pipelines.yaml, read at each commit. The JSON Schema at squidci.com/schema/pipelines.json states the same rules for editors and agents; what it cannot check is marked below. A file SquidCI refuses runs nothing, and the run says why.

Every value is read as text. tag: 1.10 is the tag 1.10, not the number 1.1, and push: false is the word false. Write values as you mean them; quoting is never needed for that.

A map. Its keys are component names, and environments.

  • At least one component; at most 50 jobs in all, a deploy counting once per environment.
  • At most 256 KB.
  • No key twice, anywhere. YAML aliases (*name) are refused.
<name>:
base: <directory>
runner: {image, arch, vcpus, spot, lambda}
services: {<name>: {image, env, healthcheck}}
aws: {profile, profiles, region}
needs: [<component>, ...]
after: [<component>, ...]
paths: [<directory>, ...]
artifacts: [<path>, ...]
cache: true | false
check | test | build | publish | run | deploy: [<step>, ...]

A name is segments of letters, digits, ., _ and -, each starting with a letter or digit, joined by /; at most 64 characters. Any key not listed here is refused.

At least one section is required. Each is a list of 1 to 100 steps, and one job.

section waits for pull requests
check needs, after run
test needs, after run
build needs, after run
publish its component’s check, test and build; needs, after not run
run needs, after not run
deploy every check, test and build in the run; its component’s publish; earlier environments not run

The directory the component’s steps run in, relative to the repository’s root: ./web, infra/cdk. The root when left out. Letters, digits, ., _, - and /; not absolute, and never climbing out with ...

key value default
image an image reference: [registry/]name[:tag][@sha256:digest], lower case SquidCI’s runner
arch amd64 or arm64. Jobs run natively, on a worker group of that architecture amd64
vcpus what of an instance each job reserves, in halves: 0.5 to 192 1
spot false keeps the jobs off spot instances spot preferred
lambda nodejs26.x: run each step as code in a Lambda function —

At least one key. lambda cannot be given with image, vcpus or spot. A component with lambda:

  • has no checkout: no base, services or artifacts;
  • takes commands and script steps only — each run as an ES module of TypeScript or JavaScript, with the runtime’s AWS SDK clients importable — not pnpm or docker;
  • runs for at most 14½ minutes;
  • runs on a Lambda worker group of its runtime and arch.

A map of containers that run beside each job of the component, on its network, reached by their name. At most 10.

key value required
image an image reference yes
env a map of variables: names like A_B1, values at most 10,000 characters; at most 100 no
healthcheck a command run in the service until it succeeds; the job starts after no

A name is a DNS label: lower-case letters, digits and -, up to 63 characters, and not job. Without a healthcheck the job starts as soon as the service’s container has.

What the component’s jobs may reach in AWS. See AWS access for jobs.

key value
profile the target AWS account plain aws uses: set as AWS_PROFILE
profiles every target AWS account the jobs may use: 1 to 10, none twice
region the region the jobs work in: set as AWS_REGION and AWS_DEFAULT_REGION

profile or profiles is required; profile is always among those the jobs may use. A profile is the name of a target AWS account of one of your execution planes — lower-case letters, digits and -, starting with a letter, at most 32 characters, not default. A name no plane of yours has is refused (not checked by the schema). region is shaped like eu-west-2; the plane’s region when left out.

Pull requests ignore aws. A deploy uses its environment’s aws instead.

Lists of component names, each once, never the component itself. Both make every job of this component wait for every job of those — but a deploy waits only for their deploys to the same environment.

  • needs also brings their artifacts and values, and makes their files part of whether this component is unchanged.
  • after brings nothing.

A component in both is refused, as is one that is not in the file, and any circle of needs and after (not checked by the schema).

More directories, beside base, that the component uses: a change in one means its jobs run again rather than end unchanged. 1 to 10, as base is written, and not the whole repository.

Paths inside base that the component’s build leaves for the rest of the run. 1 to 10, not ., and nothing under .squidci. A path the build did not leave fails it. Restored before the component’s own publish, run and deploy at the same paths, and before every job of a component that needs it under .squidci/artifacts/<component>/<path>.

false turns the component’s build cache off. On when left out.

A step is a command, or a map with exactly one of the keys below.

A command: a string, run by bash. Not empty; at most 10,000 characters.

pnpm: <args>: runs pnpm <args>, on one line. Before the job’s first pnpm step, Node is installed as .nvmrc or .node-version pins it (looked for from base upwards) and pnpm install --frozen-lockfile is run.

script: <path>: a file of the repository, relative to base, run by its extension — .js, .mjs, .cjs, .ts, .mts, .cts with Node, .sh with bash, anything else by its shebang. Letters, digits, ., _, - and /; inside the repository. In a process of its own, so unlike a command it cannot cd or export for the steps after it. Under runner.lambda, the file is read at the run’s commit, at most 256 KB, and its relative imports do not resolve.

docker: {image, tag, push}:

key value default
image the repository, without a tag: public.ecr.aws/example/web —
tag the tag: latest, 1.2.0 —
push false builds without pushing true

Builds the Dockerfile in base. A push to ECR Public or a private ECR registry logs in first with the job’s AWS credentials, so the job needs aws with access to it. A push exports digest, mediaType, size and architecture.

A step appends name=value lines to the file $SQUIDCI_OUTPUT names. Names are letters, digits and _; values are one line, at most 1 KB; at most 50 a job. A job that needs the component gets each as SQUIDCI_<COMPONENT>_<NAME> — upper-cased, anything not a letter or digit made _ — and all of them as JSON, by component, in the file $SQUIDCI_INPUTS names. Two sections of one component exporting the same name leave the dependent job skipped rather than guessing. Values are shown with the job: never put secrets in them.

A map of environment names to settings; at least one when any component has a deploy. A name is lower-case letters, digits and -, starting with a letter, at most 32 characters. An environment may have no settings (dev:).

key value
aws as a component’s aws; replaces it, wholly, for deploys here
after an environment, or a list: each must have had the version deployed first
trigger every-version, or a schedule; without one, deployed only by hand

A schedule:

key value default
schedule a cron of five fields — minute, hour, day of month, month, day of week —
timezone an IANA time zone: Europe/London UTC
soaked {in: <environment>, hours: 1–744}: only versions that reached in at least that long ago —

after and soaked.in must name environments in the file, not this one, and after must not go round in a circle; a cron must be valid and a time zone real (none of these checked by the schema).

Older spellings are refused with what to write instead: environment: on a component is now aws:, artifact: is now artifacts:, and an environment’s approval: is gone — leave the trigger out instead.