Reusable GitHub Actions workflows for QuantX repositories.
The public contract is only .github/workflows/*.yml with on.workflow_call. The caller owns on: (push, pull_request, tags, schedule). actions/ is private implementation; do not uses: it from other repositories.
Pin CI and ops uses: at @v2. Pin publish, release, and deploy at @v2.0.0.
Hardening in every public workflow:
- Job-level permissions (union at workflow top-level).
- Third-party
uses:pinned toowner/repo@<40-char-sha> # vX.Y.Z. - Same-repository references use
$/with no@ref. actions/checkoutvia$/actions/hardened-checkoutwithpersist-credentials: falseunless the job pushes.- Explicit
timeout-minuteson every concrete job. - CI cancels in-flight runs; publish / release / deploy / ops do not.
See docs/CATALOGUE.md for name:, job ids, and inputs. Permissions: docs/CONSUMERS.md. Cutover: docs/MIGRATION.md. Copy-paste callers: examples/.
| Workflow | Purpose |
|---|---|
ci-bun.yml | Bun install / lint / typecheck / build / test. bun-version default 1.4, not latest. |
ci-foundry.yml | Forge fmt --check / build --sizes / test -vvv. Profile default ci. |
ci-go.yml | go mod tidy drift check, vet, optional golangci-lint, race tests. |
ci-node.yml | Matrix across Node versions. package-manager is npm / pnpm / yarn, not detected. |
ci-python.yml | uv install, ruff + pytest. pyproject.toml or requirements.txt. |
ci-rust.yml | fmt / clippy -D warnings / build / test. Optional apt and deny (cargo-deny). |
CI job id is ci. Version inputs are {tool}-version (rust-version, node-version, …). submodules defaults to false. Foundry repos with lib/ as a git submodule must pass submodules: true.
| Workflow | Purpose |
|---|---|
publish-npm.yml | npm / pnpm / yarn / bun. Workspace install at install-directory; publish one package at working-directory. |
publish-pypi.yml | Empty PYPI_TOKEN → OIDC + attestations. Token path never attestations. |
publish-crates.yml | cargo publish --locked, skip-if-exists, 429 retry. CARGO_REGISTRY_TOKEN required. |
publish-container.yml | Dual-arch OCI push, SBOM, provenance. attest default true. |
Publish job id is publish. publish-container.yml splits mutually exclusive build (push: false) and publish (push: true) jobs.
| Workflow | Purpose |
|---|---|
release.yml | Tag → GitHub Release with git-cliff. Optional asset glob / artifact download. |
release-rust.yml | Five-target binary matrix, then GitHub Release. jobs.build.name is Build ${{ matrix.target }}. |
| Workflow | Purpose |
|---|---|
deploy-pages.yml | Bun build + actions/deploy-pages. Pull requests run build only. |
deploy-mkdocs.yml | uv-installed MkDocs via mkdocs gh-deploy --force (pushes gh-pages). |
| Workflow | Purpose |
|---|---|
ops-stale.yml | actions/stale. workflow_call only; the caller owns schedule. |
ops-sync.yml | Mirror a folder from another repository. Secret SYNC_TOKEN. |
ops-dependabot.yml | Enable auto-merge on Dependabot PRs. No checkout. Does not approve. |
Do not uses: these from other repositories.
| Workflow | Purpose |
|---|---|
self-ci.yml | actionlint, zizmor, pinact, format, composite tests. |
self-release.yml | Annotated v*.*.* tags → release.yml. |
self-stale.yml | This repository's stale cron. |
self-dependabot.yml | Auto-merge this repository's Dependabot PRs. |
self-retag.yml | Force-move v<major> onto an existing immutable tag. |
Pin CI and ops at @v2. Pin publish, release, and deploy at @v2.0.0.
on:
push:
branches: [main]pull_request:
permissions:
contents: readjobs:
ci:
uses: qntx/workflows/.github/workflows/ci-node.yml@v2with:
node-versions: '["22", "24"]'package-manager: npmon:
push:
branches: [main]pull_request:
permissions:
contents: readjobs:
ci:
uses: qntx/workflows/.github/workflows/ci-foundry.yml@v2with:
submodules: true# foundry-profile defaults to ci; set default if foundry.toml has no [profile.ci].on:
push:
tags: ['v*.*.*']permissions:
contents: readid-token: writejobs:
publish:
uses: qntx/workflows/.github/workflows/publish-npm.yml@v2.0.0on:
push:
tags: ['v*.*.*']permissions:
contents: writejobs:
release:
uses: qntx/workflows/.github/workflows/release.yml@v2.0.0on:
push:
branches: [main]permissions:
contents: readpages: writeid-token: writejobs:
deploy:
uses: qntx/workflows/.github/workflows/deploy-pages.yml@v2.0.0with:
path: distCaller job permissions are intersected with the callee. Token-only npm/PyPI does not need id-token. OIDC publish and Pages deploy do. Exact blocks: docs/CONSUMERS.md.
This project is licensed under the MIT License.