CI and Automation
CI and publish workflow contracts that contributors should keep in sync with local commands.
CI jobs
The main CI workflow enforces:
- commit message policy via
commitizen - hygiene hooks via
pre-commit - formatting via
cargo fmt --all --check - lint via
cargo clippy --workspace --all-targets --locked -- -D warnings - advisory runtime dependency check via
cargo run -p tq-release --locked -- check-runtime-deps ...only on pull requests whenCargo.lockorCargo.tomlchange; reports whether the shipped CLI dependency graph changed without blocking the PR - docs sync via
cargo run -p tq-docsgen --locked -- generate allonly when docs contract inputs, generated reference outputs,crates/tq-docsgen/**,crates/tq-cli/**, orcrates/tq-rules/**change - docs site build via
mise run docs-buildonly when docs content, docs toolchain files, or docs generator inputs change - tests via
cargo test --workspace --locked - release-policy validation via
cargo run -p tq-release --locked -- verify-release-policy --repo-root . - build validation via
cargo build,cargo package --workspace --locked,uv build --sdist, a release-wheel matrix for Linux x86_64, macOS x86_64, macOS arm64, and Windows x86_64, artifact policy verification, built artifact entrypoint smoke checks, and Linux wheel plus sdist compatibility smoke checks across Python 3.11 to 3.14 - secret scanning via
gitleaksanddetect-secretson every push and pull request - Rust dependency security checks via
cargo auditandcargo denyonly when Rust dependency or Rust security-policy files change - docs dependency security checks via
npm audit --package-lock-onlyonly when docs dependency or docs-toolchain files change
Separate policy workflows enforce frozen automation refs:
- external GitHub Action refs must be pinned to full commit SHAs
- external pre-commit hook revs must be pinned to full commit SHAs
Separate scheduled workflows handle dependency drift and security review outside the main PR and push pipeline:
- weekly Rust advisory and policy scanning via
.github/workflows/rust-security-advisories.yml,cargo audit, andcargo deny check - weekly docs dependency auditing via
.github/workflows/docs-security.ymlandnpm audit --package-lock-only - direct workspace dependency drift via
cargo outdated --workspace --root-deps-only - centralized Rust maintenance tool pin drift in
.github/actions/setup-rust-maintenance-tools/action.ymlforcargo-outdated,cargo-audit, andcargo-deny - frozen GitHub Action and pre-commit pin drift via
.github/workflows/pinned-external-dependency-drift.yml
For manual rotation and drift response steps, see Pin maintenance.
Security toolchain policy
Security scanners are treated as CI tooling, not as part of the tq runtime contract.
The workspace uses the pinned MSRV from rust-toolchain.toml. CI installs cargo-audit and cargo-deny on stable through .github/actions/setup-rust-security-tools, which delegates version pinning to .github/actions/setup-rust-maintenance-tools/action.yml, so scanner installation can move independently of the product toolchain. Main CI reruns those scanners only when Rust dependency or Rust security-policy surfaces change; the scheduled Rust workflow covers advisory churn between repository changes.
The docs dependency audit uses npm audit --package-lock-only and only reruns in main CI when the Node or docs-toolchain surface changes. The scheduled docs security workflow covers advisory churn for the VitePress toolchain between repository changes. The docs sync and docs build jobs follow the same model: they are skipped unless docs content, docs generator inputs, generated reference outputs, or docs-toolchain files changed.
When you add a new dependency manifest, lockfile, security-policy file, or workflow/composite action that owns scanner behavior, update the change-scope path gates in .github/workflows/ci.yml. Ordinary source or docs files under already covered directories do not usually require gate changes.
The stale dependency workflow installs cargo-outdated separately from the product toolchain and checks only root workspace dependencies. This complements Dependabot and other policy checks: cargo audit catches published advisories, cargo deny enforces explicit bans plus license and source policy, npm audit --package-lock-only covers the docs lockfile, and cargo outdated surfaces ordinary version drift.
The maintenance-tool pin workflow covers the embedded versions in .github/actions/setup-rust-maintenance-tools/action.yml because those values are not lockfile entries or Dependabot-managed manifests. When drift is detected, the workflow writes a summary, opens or refreshes a tracking issue on scheduled runs, and fails so the review stays visible.
Publish workflow
On SemVer tag pushes, the unprivileged CI build jobs validate and upload release-candidate wheel and sdist artifacts, then a separate tag-only CI job downloads the full artifact set, generates provenance attestations, and uploads the final validated-dist artifact for promotion.
The publish workflow runs after that successful tag-triggered CI run, downloads the validated wheels and sdist from CI, verifies the CI-generated provenance attestations, rejects native linux_* wheel tags before upload, re-runs artifact content policy validation with tq-release, smoke-tests the Linux wheel and sdist on the publish runner, publishes to PyPI with uv publish, verifies the consumer-facing Linux wheel, and uploads the release assets and checksums to the GitHub release for the SemVer tag.