Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/javascript-npm-packages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ jobs:
if: ${{ github.ref_type == 'branch' }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: coroboros/ci/.github/actions/check-docs@v0
- uses: coroboros/ci/.github/actions/javascript/base@v0

Expand All @@ -51,7 +51,7 @@ jobs:
contents: write # for GitHub Release creation + commit-back to main
id-token: write # for npm OIDC Trusted Publisher
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
ref: main
fetch-depth: 0
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/renovate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
renovate:
runs-on: ubuntu-latest
steps:
- uses: renovatebot/github-action@8217b3fc286df088d7c27f3255fe8414463bc0fd # v46.1.15
- uses: renovatebot/github-action@316d7cd859606d6039a2182b7d69199e9b036835 # v46.2.1
with:
token: ${{ secrets.RENOVATE_TOKEN }}
env:
Expand Down
20 changes: 10 additions & 10 deletions .github/workflows/rust-packages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ jobs:
os: [ubuntu-latest, macos-14, windows-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: coroboros/ci/.github/actions/check-docs@v0
- uses: coroboros/ci/.github/actions/rust/base@v0

Expand All @@ -40,7 +40,7 @@ jobs:
if: ${{ github.ref_type == 'branch' }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: coroboros/ci/.github/actions/rust/native-deps@v0
- name: Verify the published crate builds
shell: bash
Expand All @@ -54,7 +54,7 @@ jobs:
matrix: ${{ steps.plan.outputs.matrix }}
tap: ${{ steps.detect.outputs.tap }}
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
ref: ${{ github.sha }}

Expand Down Expand Up @@ -112,12 +112,12 @@ jobs:
env:
CARGO_DIST_TARGET: "${{ join(matrix.targets, ' ') }}"
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
ref: ${{ github.sha }}

- name: Cache cargo + target
uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1
uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2
with:
key: ${{ join(matrix.targets, '_') }}

Expand Down Expand Up @@ -155,7 +155,7 @@ jobs:
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
ref: main
fetch-depth: 0
Expand All @@ -173,7 +173,7 @@ jobs:
- name: Mint a short-lived crates.io token via OIDC
id: auth
if: ${{ env.CARGO_REGISTRY_TOKEN == '' }}
uses: rust-lang/crates-io-auth-action@bbd81622f20ce9e2dd9622e3218b975523e45bbe # v1.0.4
uses: rust-lang/crates-io-auth-action@c6f97d42243bad5fab37ca0427f495c86d5b1a18 # v1.0.5

- name: Publish to crates.io
shell: bash
Expand Down Expand Up @@ -208,7 +208,7 @@ jobs:
permissions:
contents: write # upload release assets + undraft the release publish created
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
ref: ${{ github.sha }}

Expand Down Expand Up @@ -324,7 +324,7 @@ jobs:

- name: Checkout Homebrew tap
if: ${{ env.HOMEBREW_TAP_TOKEN != '' && needs.dist-plan.outputs.tap != '' }}
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
repository: ${{ needs.dist-plan.outputs.tap }}
token: ${{ secrets.HOMEBREW_TAP_TOKEN }}
Expand Down Expand Up @@ -360,7 +360,7 @@ jobs:
done

- name: Setup Node
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: "24"
registry-url: "https://registry.npmjs.org"
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/security-gate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
scan-supply-chain:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

- id: detect
name: Route supply-chain scan by ecosystem
Expand All @@ -38,7 +38,7 @@ jobs:
scan-secrets:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
- uses: coroboros/ci/.github/actions/security/gitleaks@v0
4 changes: 2 additions & 2 deletions .github/workflows/security.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
runs-on: ubuntu-latest
continue-on-error: true
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: actions/dependency-review-action@a1d282b36b6f3519aa1f3fc636f609c47dddb294 # v4
with:
fail-on-severity: high
Expand All @@ -23,7 +23,7 @@ jobs:
runs-on: ubuntu-latest
continue-on-error: true
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- id: detect
name: Detect a Rust manifest
shell: bash
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/self-lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
check-actions:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

- name: Install actionlint
shell: bash
Expand All @@ -41,7 +41,7 @@ jobs:
check-yaml:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

- name: Install yamllint
shell: bash
Expand All @@ -54,7 +54,7 @@ jobs:
check-shell:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Run shellcheck on inline workflow scripts
uses: ludeeus/action-shellcheck@00cae500b08a931fb5698e11e79bfbd38e612a38 # v2.0.0
env:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/self-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
permissions:
contents: write # force-push the rolling major tag
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

- name: Move rolling major tag
shell: bash
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/self-security.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,15 @@ jobs:
scan-secrets:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
- uses: ./.github/actions/security/gitleaks

scan-deps:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: ./.github/actions/security/osv-scanner

security-gate:
Expand Down
18 changes: 9 additions & 9 deletions .github/workflows/self-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
test-verify-tag:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Pass — HEAD matches the run SHA
uses: ./.github/actions/release/verify-tag
- name: Move HEAD so it diverges from the run SHA
Expand All @@ -42,7 +42,7 @@ jobs:
test-generate-changelog:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: SemVer gate rejects a non-tag ref
id: gate
continue-on-error: true
Expand All @@ -57,7 +57,7 @@ jobs:
test-commit-artifacts:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
path: _src
- name: Build a fixture repo + local bare remote
Expand Down Expand Up @@ -105,7 +105,7 @@ jobs:
test-cargo-deny:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Plant a forbidden consumer override
shell: bash
run: |
Expand All @@ -131,7 +131,7 @@ jobs:
os: [ubuntu-latest, macos-latest, windows-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: ./.github/actions/rust/install-dist
- name: Assert dist is installed and runnable
shell: bash
Expand All @@ -143,7 +143,7 @@ jobs:
test-native-deps:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Plant a fixture ci/setup.sh that records CARGO_DIST_TARGET
shell: bash
run: |
Expand Down Expand Up @@ -177,7 +177,7 @@ jobs:
test-test-deps:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Absent hooks → no-op
uses: ./.github/actions/rust/test-deps
- name: Plant ci/test.env and ci/test-setup.sh
Expand Down Expand Up @@ -205,7 +205,7 @@ jobs:
env:
NPM_CONFIG_FILE: "registry=https://registry.npmjs.org/"
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
path: _src
- name: Stage the npm fixture at the workspace root
Expand All @@ -224,7 +224,7 @@ jobs:
test-rust-base:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
path: _src
- name: Stage the rust fixture at the workspace root
Expand Down
25 changes: 25 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# coroboros/ci

Reusable GitHub Actions workflows and composite actions for the Coroboros stack. `README.md` owns pipeline contracts, environment variables, security policy and consumer examples.

## Project constraints

- Reusable workflows impose shared defaults; add inputs or secrets only for legitimate variation. Declare only consumed secrets; prohibit `secrets: inherit`.
- Pin third-party actions by full commit SHA with a version comment, and tooling binaries by version plus verified SHA-256. Do not pipe remote scripts into a shell.
- Reusable workflows and consumers reference composites at `coroboros/ci/.github/actions/<name>@v0`. Local `./` refs resolve against the caller checkout; self-tests use them deliberately to exercise PR code.
- Security gates fail closed. `security/deny.toml` owns Cargo advisory, ban and source policy; consumer `deny.toml` is ignored and exception files are rejected. Propose justified transitive-advisory exceptions centrally. The separate advisory workflow owns non-blocking license/quality checks.
- Use the gitleaks CLI directly; the third-party action requires a paid organization licence. `security/.gitleaks.toml` is the canonical ruleset.
- Keep consumer-visible workflow job IDs stable: imperative kebab-case, with existing phase-call and cargo-dist names as exceptions. Quote environment values, declare them where consumed, and use GitHub log commands without ANSI escapes.
- Keep action/workflow files focused on implementation. Put rationale in the owning documentation or changelog; update affected README contracts and examples with behavior changes.

## Validation

- Workflow/composite changes: `actionlint -shellcheck=shellcheck`, `yamllint -c .yamllint .`, and the relevant self-tests.
- Check consumer impact when changing reusable contracts. Self-tests that reference `@v0` exercise the released composites; local-ref tests exercise the PR. Tag-only behavior needs evidence from an authorized release.
- Documentation changes: check claims against source, affected links and `git diff --check`.

## Release

- PR-only into `main`, then squash merge. Manually bump `package.json:version` and prepend the matching `CHANGELOG.md` entry before merge.
- After authorization, create an annotated SemVer tag without a `v` prefix on the reviewed merge commit, then a GitHub release using that version as its title and the changelog entry as notes.
- `self-release.yml` owns the rolling `v0` update. It does not bump manifests or create the GitHub release; do not move `v0` manually.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog

## v0.2.11 - 05/09/2026

### Fixes
- Update pinned GitHub Actions dependencies across reusable workflows and self-CI.
- Share concise project constraints and release ownership through `AGENTS.md`, imported by `CLAUDE.md`.

## v0.2.10 - 08/07/2026

### Fixes
Expand Down
50 changes: 1 addition & 49 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -1,49 +1 @@
# coroboros/ci

Reusable GitHub Actions workflows + composite actions for the Coroboros stack.

## Commands

- `actionlint -shellcheck=shellcheck` — workflows, `action.yml`, inline shell.
- `yamllint -c .yamllint .` — YAML lint.

## Important files

- `.github/workflows/javascript-npm-packages.yml` — bundled NPM pipeline (`preflight` / `security-gate` / `publish-package` / `security`).
- `.github/workflows/rust-packages.yml` — bundled Cargo pipeline (`preflight` matrix / `security-gate` / `verify-package` / `publish-package` / `security`) + opt-in cargo-dist binary layer (`dist-plan` / `dist-build` / `dist-host` / `dist-publish`, gated on `[package.metadata.dist]` or `[workspace.metadata.dist]`).
- `.github/workflows/security-gate.yml` — blocking gate `publish-package` `needs:`. `scan-supply-chain` (auto-routed: `Cargo.toml` → `security/rust/cargo-deny` advisories+bans+sources, else `security/osv-scanner`) + `scan-secrets` (gitleaks). A separate reusable workflow so the caller's `publish` can `needs:` the whole gate as one job, running each scan once. Imposed via the package workflows, importable standalone by a non-package repo.
- `.github/workflows/security.yml` — advisory layer, never blocks: `review-dependencies` (PR-only) + `check-licenses` (Rust, `security/rust/cargo-deny` `checks: licenses`). License/quality policy lives here, off the gate.
- `.github/workflows/{self-lint,self-test,self-security,self-release}.yml` — self-CI: lint, the security composites + `security-gate`/`security` workflows via local `./`, the `v0` rolling-tag move, and `self-test` smoke-testing every composite (plus `javascript/base`/`rust/base` on `test/fixtures/`) every PR. Workflow self-tests resolve their `@v0` composites against the released `v0`, so a brand-new composite is testable only once a release moves `v0` onto it.
- `.github/actions/{check-docs,javascript/base,rust/{base,native-deps,test-deps,install-dist,pin-version,harden-homebrew-formula},security/{gitleaks,osv-scanner,rust/cargo-deny},release/{verify-tag,generate-changelog,github-release,commit-artifacts}}/action.yml` — composites.
- `.github/dependabot.yml` — auto-PRs for pinned action SHAs. `renovate.json` + `.github/workflows/renovate.yml` — self-hosted Renovate (needs the `RENOVATE_TOKEN` PAT secret, scope `repo` + `workflow`) auto-bumps the version-pinned tooling; `.github/renovate/sync-tool-sha.sh` re-syncs each paired tarball SHA-256 in the same PR.
- `security/.gitleaks.toml` — canonical gitleaks ruleset.
- `security/deny.toml` — canonical cargo-deny ruleset, imposed via `--config` (consumer `deny.toml` ignored; `deny.exceptions.toml` rejected). An unfixable transitive advisory → PR a justified `ignore = ["RUSTSEC-…"]` (with `# why`) to this file, never a per-repo override.
- `README.md` — public documentation (single source for pipelines, composables, structure, flow, env, security, examples).

## Rules

- **Imposed, not proposed.** Zero `inputs:` / `secrets:` on reusable workflows unless variation is legitimate.
- **Pin third-party actions by commit SHA**, inline `# vX` comment. No `@main`, `@master`, `@vX`.
- **Pin tooling binaries by version.** SHA-256 verification on binary release tarballs. No `curl | bash`.
- **Composite refs**: `coroboros/ci/.github/actions/<name>@v0` from reusable workflows and consumers. Exception — `self-security.yml` uses local `./.github/actions/security/<name>` so a PR self-tests its own composites; a reusable workflow's `./` resolves to the caller's checkout, so `security.yml` must pin `@v0`.
- **`secrets:`** declares only what the job consumes. Never `secrets: inherit`.
- **`gitleaks` CLI direct**, not `gitleaks/gitleaks-action@v2` (paid org license).
- **House style**:
- Env values quoted: `KEY: "value"`.
- GH workflow log commands: `::error::`, `::warning::`, `::notice::`. No ANSI codes.
- Declare env keys only where consumed.
- Job ids: `verb-noun`, kebab-case (imperative verb + object), mirroring the GitLab CI pipelines — `verify-package`, `publish-package`, `generate-changelog`, `commit-artifacts`, `verify-tag`. Phase call-jobs that `uses:` another workflow may stay single-word (`preflight`, `security-gate`, `security`); the cargo-dist `dist-plan`/`dist-build`/`dist-host`/`dist-publish` jobs mirror its subcommands. Reusable-workflow job ids are consumer-visible — rename deliberately.
- **Action and workflow files = implementation only.** Rationale lives in `CLAUDE.md` or `CHANGELOG.md`.

## Adding a workflow or composite

1. Update `README.md` (Pipelines / Composables table + Examples + Environment).
2. `actionlint -shellcheck=shellcheck` must exit 0.

## Release flow

- PR-only; no direct commits to `main`.
- In the PR (before merge): bump `package.json:version` + prepend `CHANGELOG.md` section (`## vX.Y.Z - DD/MM/YYYY`).
- Squash-merge.
- `git tag X.Y.Z && git push origin X.Y.Z` (no `v` prefix). `self-release.yml` then moves the rolling `v0` tag — no manual `git tag -f v0`.
- `gh release create X.Y.Z --title X.Y.Z --notes-file <CHANGELOG section>`.
@AGENTS.md
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@coroboros/ci",
"version": "0.2.10",
"version": "0.2.11",
"private": true,
"description": "Reusable GitHub Actions CI for the Coroboros stack.",
"license": "SEE LICENSE IN LICENSE.md",
Expand Down
Loading