Reusable GitHub Actions workflows for projects generated by
scaffold. Every generated project's own
.github/workflows/ holds five thin call sites; the actual jobs live here so
one fix reaches every project instead of drifting per project (see
docs/decisions/0005-share-ci-through-reusable-workflows.md in the scaffold
toolbox repo for why).
| File | Called from | Inputs |
|---|---|---|
app-ci.yml |
ci.yml |
roots — mise config roots to run ci-unit for, as a JSON array |
app-security.yml |
security.yml |
none |
app-build.yml |
build.yml |
images — JSON array of {image, context, dockerfile}, one per application |
app-release.yml |
release.yml |
images, same shape |
app-docs.yml |
docs.yml |
none |
app-targets.yml |
the two above | not called by a project directly |
app-build.yml and app-release.yml also still accept the singular
image/context/dockerfile they took before images existed, so a project
generated earlier keeps working at v1 unchanged. Give one shape or the
other, not both; app-targets.yml resolves whichever was given into the
matrix both workflows build from, so the two cannot disagree about what a
project publishes.
app-build.yml publishes main and sha-<commit> on every merge to main.
app-release.yml cuts a versioned release (via Release Please) and publishes
semver + latest tags when its pull request merges. The two never block each
other (see docs/decisions/0015-continuous-builds-separate-from-cut-releases.md).
app-release.yml's deploy job is a seam, not a feature: it is gated on
vars.DEPLOY_TARGET, which no project sets today, so it never runs (see
docs/decisions/0014-deployment-deferred-with-seams.md in the scaffold
toolbox repo).
Projects call these workflows at the moving tag v1
(you/.github/.github/workflows/app-ci.yml@v1). A change here reaches every
project once v1 is moved to point at it. Move v1 only after the smoke
suite has run green against the new commit on main; roll back by moving
v1 back to the previous release tag.
git tag v1.0.0
git tag -f v1
git push --tags -f origin v1Every workflow starts permissions: {} and grants the minimum a job needs.
Every action is pinned by commit SHA with the tag kept as a trailing
comment. Every actions/checkout sets persist-credentials: false. There
is no GitHub App token flow here (see
docs/decisions/0010-github-token-over-a-github-app.md in the scaffold
toolbox repo for why) — every job uses the built-in GITHUB_TOKEN.