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.
The file
Section titled “The file”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.
Components
Section titled “Components”<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 ...
runner
Section titled “runner”| 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,servicesorartifacts; - takes commands and
scriptsteps only — each run as an ES module of TypeScript or JavaScript, with the runtime’s AWS SDK clients importable — notpnpmordocker; - runs for at most 14½ minutes;
- runs on a Lambda worker group of its runtime and
arch.
services
Section titled “services”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.
needs and after
Section titled “needs and after”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.
needsalso brings their artifacts and values, and makes their files part of whether this component is unchanged.afterbrings 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.
artifacts
Section titled “artifacts”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.
Values
Section titled “Values”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.
environments
Section titled “environments”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).
Refused with a pointer
Section titled “Refused with a pointer”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.