No shims. Old filenames are deleted. Change every uses: in the same window. Pin CI and ops at @v2. Pin publish, release, and deploy at @v2.0.0.
| Old | New | with / secrets |
Caller permissions |
Required check-run |
|---|---|---|---|---|
ci-rust.yml@main |
ci-rust.yml@v2 |
Keep submodules: true where used. toolchain → rust-version. |
contents: read |
ci / build → ci / ci |
ci-bun.yml@main |
ci-bun.yml@v2 |
Default bun-version is 1.4. Do not pass latest. |
contents: read |
ci / build → ci / ci |
ci-foundry.yml@main |
ci-foundry.yml@v2 |
Required submodules: true when lib/ is a submodule. Add [profile.ci] or pass foundry-profile: default. |
contents: read |
ci / Foundry project → ci / ci |
ci-node.yml@main |
ci-node.yml@v2 |
package-manager default npm. Not auto-detected. |
contents: read |
ci / build → ci / ci |
python.yml@main |
ci-python.yml@v2 |
python-version: '3.13' still valid. |
contents: read |
call-ci / build → call-ci / ci |
publish-crates.yml@main |
publish-crates.yml@v2.0.0 |
packages / timeout-minutes kept. toolchain → rust-version. |
contents: read + CARGO_REGISTRY_TOKEN |
publish / Build, Test & Publish → publish / publish |
publish-npm.yml@main |
publish-npm.yml@v2.0.0 |
Workspace install at install-directory (default .). Package publish at working-directory. OIDC: id-token: write. |
OIDC: contents: read + id-token: write. Token: contents: read. |
publish / Build & Publish → publish / publish |
publish-npm-bun.yml@main |
publish-npm.yml@v2.0.0 |
package-manager: bun. bun-version default 'latest' → '1.4' (do not pass latest). |
OIDC: must add id-token: write. |
publish / Build & Publish → publish / publish |
python-publish.yml@main |
publish-pypi.yml@v2.0.0 |
Secret id PYPI_TOKEN (repo may dual-write the old secret). |
Token-only: contents: read. OIDC: add id-token + attestations. |
call-publish / Build & Publish → call-publish / publish |
publish-pypi.yml@main |
publish-pypi.yml@v2.0.0 |
PYPI_API_TOKEN → PYPI_TOKEN. |
Same as row above. | publish / Build & Publish → publish / publish |
docker.yml@main |
publish-container.yml@v2.0.0 |
Keep no-cache: true. Suggest platforms: linux/amd64. No OIDC → attest: false. |
contents: read + packages: write; attest also needs id-token + attestations. |
docker / build → docker / publish |
container-build.yml@main |
publish-container.yml@v2.0.0 |
Secrets registry-username / registry-password → REGISTRY_USERNAME / REGISTRY_PASSWORD. attest default true. |
Same as docker row. | build / build → {job} / publish (default push: true) |
release.yml@main |
release.yml@v2.0.0 |
None required. | contents: write |
release / release |
release-rust.yml@main |
release-rust.yml@v2.0.0 |
bin / package / cross-* kept. toolchain → rust-version. |
contents: write |
Matrix release / Build <target> unchanged. release / Publish GitHub Release → release / release |
deploy-pages.yml@main |
deploy-pages.yml@v2.0.0 |
bun-version default 1.4. |
contents: read + pages: write + id-token: write |
deploy / build and deploy / deploy |
deploy-mkdocs.yml@main |
deploy-mkdocs.yml@v2.0.0 |
None required. | contents: write |
deploy / deploy |
repo-stale.yml@main |
ops-stale.yml@v2 |
None required. Caller owns schedule. |
issues: write + pull-requests: write |
{caller-job} / stale |
stale.yml@main |
ops-stale.yml@v2 |
None required. openai-python caller job id is close-stale. |
Same as repo-stale. | close-stale / stale (openai-python); other repos: {caller-job} / stale |
repo-sync-folder.yml@main |
ops-sync.yml@v2 |
Secret token → SYNC_TOKEN (omit to use github.token). |
contents: write |
sync / sync |
gen-openapi-client.yml@main |
deleted | No replacement. No gen- prefix. |
— | — |
ci-cpp.yml@main |
deleted | No replacement. Historical c-cpp.yml is also gone. |
— | — |
ci-dart.yml@main |
deleted | No replacement. Historical dart.yml is also gone. |
— | — |
| Old | New |
|---|---|
toolchain |
rust-version (ci-rust, publish-crates, release-rust) |
PYPI_API_TOKEN |
PYPI_TOKEN |
token (repo-sync-folder) |
SYNC_TOKEN |
registry-username / registry-password |
REGISTRY_USERNAME / REGISTRY_PASSWORD |
publish-npm-bun.yml |
publish-npm.yml + package-manager: bun |
foundry-profile default default |
default ci |
Foundry implicit submodules: recursive |
submodules: false. Foundry lib/ callers must pass submodules: true. |
| Node package manager auto-detect | package-manager default 'npm' |
bun-version: latest |
default '1.4' |
docker.yml single-arch amd64 |
publish-container.yml default linux/amd64,linux/arm64, attest: true |
CI job id build / check |
ci |
Callee jobs.<id>.name display strings |
unset (check-run right half is the job id) |
python.yml, python-publish.yml, docker.yml, publish-npm-bun.yml, container-build.yml, gen-openapi-client.yml, ci-cpp.yml, ci-dart.yml, repo-sync-folder.yml, plus historical bun.yml, c-cpp.yml, foundry.yml, go.yml, node.js.yml, dart.yml, npm-publish.yml, bun-publish.yml, rust.yml, rust-publish.yml, rust-cd.yml, github-pages.yml, sync-repo-folder.yml.
stale.yml and repo-stale.yml exist again as workflow_call forwards to ops-stale.yml so unmigrated @main callers do not fail. They are not the public API. New callers still use ops-stale.yml@v2.
gh search code --owner qntx 'qntx/workflows/.github/workflows' --limit 200Must not reappear: python.yml@, docker.yml, publish-npm-bun.yml, container-build.yml, ci-cpp.yml, ci-dart.yml, repo-sync-folder.yml, gen-openapi.
- Drop
pull_request/pull_request_targetfromon:. - Add
scheduleif the caller only had a PR event. Daily:0 4 * * *(04:00 UTC). - Drop any
dependabot[bot]-only jobif:(schedule actor is not Dependabot; thatif:skips the sweep on current@v2). - Leftover PR runs skip and must not share the sweep concurrency group (
…-${{ github.event.pull_request.number || 'sweep' }}stays in the callee). - Add
checks: readandactions: readon the caller workflow andjobs.merge(GitHub intersects with the callee). Rollup 403 is fail until those scopes are granted.