Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
71b9ef6
feat: add rust-packages pipeline and rust/base action
ob-aion Jun 2, 2026
48b65f3
refactor: align rust pipeline with npm-packages; drop redundant suppl…
ob-aion Jun 2, 2026
bdf3134
feat: restore cargo-deny supply-chain + --locked; document the model
ob-aion Jun 2, 2026
faca699
feat: firewall the npm fetch with Socket Firewall; document cooldown …
ob-aion Jun 2, 2026
3dbbc83
docs: tighten the Security firewall note (straight ellipsis, shorter …
ob-aion Jun 2, 2026
a375106
fix(release): drop misplaced rolling tag; share the commit-back step
ob-aion Jun 2, 2026
ff97adf
refactor(security): extract scanners to composites; manifest-gate osv
ob-aion Jun 2, 2026
69139aa
feat(rust): OIDC publish, verify build, and supply-chain gate
ob-aion Jun 2, 2026
fda5b2c
fix(javascript-npm-packages): gate publish on osv supply-chain scan
ob-aion Jun 2, 2026
651df7c
feat(release): move v0 rolling tag on coroboros/ci's own release
ob-aion Jun 2, 2026
a4410b1
docs: brand-voice README, CHANGELOG, CLAUDE; bump to 0.2.0
ob-aion Jun 2, 2026
958a678
fix(security): drop unscannable bun.lockb from osv gate [skip ci]
ob-aion Jun 2, 2026
b47a595
docs(security): note osv-scanner.toml exceptions [skip ci]
ob-aion Jun 2, 2026
66444ef
feat(security): gate publish on gitleaks via a secrets job [skip ci]
ob-aion Jun 2, 2026
96f3e74
style(security): trim what-clause from secrets comment [skip ci]
ob-aion Jun 2, 2026
d95f3e3
docs(security): note self-CI in the osv-scanner composable row
ob-aion Jun 2, 2026
5cfe545
feat(rust): add cargo-dist binary-distribution layer to rust-packages
ob-aion Jun 3, 2026
547d594
refactor(rust): factor the Cargo version pin into a shared composite
ob-aion Jun 3, 2026
2581fcf
ci(rust): pin cargo-edit by version in the rust/pin-version composite
ob-aion Jun 3, 2026
29da8cc
fix(security): impose the canonical cargo-deny ruleset
ob-aion Jun 3, 2026
3230292
docs(security): reconcile the README with the imposed cargo-deny ruleset
ob-aion Jun 3, 2026
236bf36
style(ci): drop what-comments, keep only non-obvious why
ob-aion Jun 3, 2026
103e064
refactor(ci): inline cargo-dist setup, gh-native logs, trim comments
ob-aion Jun 3, 2026
9b81a32
chore(release): fold the binary work into the unreleased 0.2.0
ob-aion Jun 3, 2026
9bf4723
feat(ci): prebuilt dist install, composite self-tests, Renovate tool …
ob-aion Jun 6, 2026
fc47bb3
fix(ci): drive self-actions against the real checkout, not env overrides
ob-aion Jun 6, 2026
0e8308e
fix(ci): pre-create main on the bare remote in the commit-artifacts s…
ob-aion Jun 6, 2026
713cb5e
fix(ci): isolate the commit-artifacts smoke in a non-shallow fixture …
ob-aion Jun 6, 2026
3b7396e
feat(ci): self-hosted Renovate with same-PR SHA-256 resync
ob-aion Jun 6, 2026
49df5a9
feat(ci): host native/C++ CLIs in the rust pipeline
ob-aion Jun 6, 2026
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
5 changes: 3 additions & 2 deletions .github/actions/check-docs/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,17 @@ runs:
- name: Log run context
shell: bash
run: |
echo "Run context:"
echo "::group::Run context"
echo " GITHUB_REF_NAME | ${GITHUB_REF_NAME}"
echo " GITHUB_REF_SLUG | $(echo "${GITHUB_REF_NAME}" | tr '[:upper:]' '[:lower:]' | tr -c 'a-z0-9-' '-' | head -c 63 | sed 's/-$//')"
echo " GITHUB_REF_TYPE | ${GITHUB_REF_TYPE}"
echo " GITHUB_REPOSITORY | ${GITHUB_REPOSITORY}"
echo " GITHUB_SERVER_URL | ${GITHUB_SERVER_URL}"
echo " GITHUB_REPOSITORY_URL | ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}"
echo "::endgroup::"

- name: README check
shell: bash
run: |
[ -f README.md ] || (echo "::error::A README.md file must be present at project root" && exit 1)
echo "README.md present"
echo "::notice::README.md present"
11 changes: 8 additions & 3 deletions .github/actions/javascript/base/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ runs:
exit 1
fi
node_version="$(tr -d '[:space:]v' < .node-version)"
echo "Resolved Node.js version: ${node_version} (from .node-version)"
echo "::notice::Resolved Node.js version: ${node_version} (from .node-version)"
echo "node-version=${node_version}" >> "${GITHUB_OUTPUT}"

- name: Setup Node.js
Expand All @@ -33,6 +33,10 @@ runs:
corepack enable
pnpm --version

- name: Install Socket Firewall
shell: bash
run: npm install -g sfw

- name: Setup pnpm cache
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4
with:
Expand All @@ -55,7 +59,8 @@ runs:

- name: Install dependencies
shell: bash
run: pnpm install --frozen-lockfile --ignore-scripts
# Fail-closed: no sfw, no install.
run: sfw pnpm install --frozen-lockfile --ignore-scripts

- name: Lint
shell: bash
Expand All @@ -67,7 +72,7 @@ runs:
if [ "$(jq .scripts.build package.json)" != "null" ]; then
pnpm run build
else
echo "Non required script 'build' skipped"
echo "::notice::Non required script 'build' skipped"
fi

- name: Test
Expand Down
28 changes: 28 additions & 0 deletions .github/actions/release/commit-artifacts/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Release Commit Artifacts Action Composite
name: release-commit-artifacts
description: Commit release artifacts back to main after a tagged publish.

inputs:
files:
description: Space-separated artifact paths to stage and commit.
required: true

runs:
using: composite
steps:
- name: Commit release artifacts back to main
shell: bash
env:
FILES: ${{ inputs.files }}
# [skip ci] keeps the bot's main push from re-triggering the pipeline.
run: |
read -ra paths <<< "${FILES}"
git add "${paths[@]}"
if git diff --staged --quiet; then
echo "::notice::No release artifacts to commit (nothing changed)"
else
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git commit -m "chore: release ${GITHUB_REF_NAME} [skip ci]"
git push origin HEAD:main
fi
4 changes: 2 additions & 2 deletions .github/actions/release/generate-changelog/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,10 @@ runs:
' CHANGELOG.md 2>/dev/null || true)"

if [ -n "${existing}" ]; then
echo "Using existing CHANGELOG section for ${tag}"
echo "::notice::Using existing CHANGELOG section for ${tag}"
body="${existing}"
else
echo "Auto-generating CHANGELOG section for ${tag}"
echo "::notice::Auto-generating CHANGELOG section for ${tag}"
prev_tag="$(git describe --tags --abbrev=0 HEAD^ 2>/dev/null || true)"
commits_range="${prev_tag:+${prev_tag}..}HEAD"

Expand Down
12 changes: 11 additions & 1 deletion .github/actions/release/github-release/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ inputs:
body:
description: Release notes body.
required: true
draft:
description: Create the release as a draft. Binary repos undraft after assets upload; library repos leave it false.
required: false
default: "false"

runs:
using: composite
Expand All @@ -15,10 +19,16 @@ runs:
env:
GH_TOKEN: ${{ github.token }}
BODY: ${{ inputs.body }}
DRAFT: ${{ inputs.draft }}
run: |
notes="$(mktemp)"
printf '%s' "${BODY}" > "${notes}"
draft_flag=()
if [ "${DRAFT}" = "true" ]; then
draft_flag=(--draft)
fi
gh release create "${GITHUB_REF_NAME}" \
--title "${GITHUB_REF_NAME}" \
--notes-file "${notes}"
--notes-file "${notes}" \
"${draft_flag[@]}"
rm -f "${notes}"
15 changes: 15 additions & 0 deletions .github/actions/release/verify-tag/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Release Verify Tag Action Composite
name: release-verify-tag
description: Fail unless the checked-out main HEAD matches the tag SHA that triggered the run.

runs:
using: composite
steps:
- name: Verify tag points to main HEAD
shell: bash
run: |
if [ "$(git rev-parse HEAD)" != "${GITHUB_SHA}" ]; then
echo "::error::main has moved since the tag was pushed — tag ${GITHUB_SHA}, main HEAD $(git rev-parse HEAD). Resolve manually."
exit 1
fi
echo "::notice::main HEAD matches tag SHA (${GITHUB_SHA})"
44 changes: 44 additions & 0 deletions .github/actions/rust/base/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Rust Base Action Composite
name: rust-base
description: Base setup for a Rust pipeline job.

runs:
using: composite
steps:
- name: Install Rust toolchain
shell: bash
run: |
if [ ! -f rust-toolchain.toml ]; then
echo "::error::rust-toolchain.toml is required at the repo root"
exit 1
fi
channel="$(grep -E '^[[:space:]]*channel[[:space:]]*=' rust-toolchain.toml | head -1 | sed -E 's/.*"([^"]+)".*/\1/')"
if [ -z "${channel}" ]; then
echo "::error::no channel found in rust-toolchain.toml"
exit 1
fi
echo "::notice::Installing Rust toolchain: ${channel} (from rust-toolchain.toml)"
rustup toolchain install "${channel}" --profile minimal --component rustfmt --component clippy --no-self-update

- name: Cache cargo + target
uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1
with:
save-if: ${{ github.ref == format('refs/heads/{0}', github.event.repository.default_branch) }}

- name: Native build dependencies
uses: coroboros/ci/.github/actions/rust/native-deps@v0

- name: Format
shell: bash
run: cargo fmt --check

- name: Lint
shell: bash
run: cargo clippy --all-targets --locked -- -D warnings

- name: Test dependencies
uses: coroboros/ci/.github/actions/rust/test-deps@v0

- name: Test
shell: bash
run: cargo test --locked
46 changes: 46 additions & 0 deletions .github/actions/rust/install-dist/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Rust install-dist Action Composite
name: rust-install-dist
description: Install cargo-dist's `dist` binary (prebuilt, SHA-256 verified) onto PATH. Linux, macOS, Windows.

runs:
using: composite
steps:
- name: Install dist
shell: bash
env:
CARGO_DIST_VERSION: "0.32.0"
# https://github.com/axodotdev/cargo-dist/releases/download/v0.32.0/sha256.sum
SHA256_X86_64_LINUX: "eb52f9fae0d0506774e9f1801c1168f87fa2c87a45e2d64d3ae7c89401929946"
SHA256_AARCH64_LINUX: "d29bcffeb3f8b0c517b4ce0dd2470926ed5cb0bb29d78c6bdd5f88d76ee14a6a"
SHA256_X86_64_DARWIN: "6243464a8389e006b9256ee548bc795638f1a17113c1b6669c0e05ce89fd05c5"
SHA256_AARCH64_DARWIN: "aa343b2ff78ec2981f17a65140250c5ad6062c74072163f68c5c2686d94763a7"
SHA256_X86_64_WINDOWS: "26e845cabff12a92911ce960af73a86c8f9b2b2d9072b01dfe5b662acf044fa3"
run: |
set -euo pipefail
case "$(uname -s)-$(uname -m)" in
Linux-x86_64) target="x86_64-unknown-linux-gnu"; sha="${SHA256_X86_64_LINUX}"; ext="tar.xz"; exe="" ;;
Linux-aarch64|Linux-arm64) target="aarch64-unknown-linux-gnu"; sha="${SHA256_AARCH64_LINUX}"; ext="tar.xz"; exe="" ;;
Darwin-x86_64) target="x86_64-apple-darwin"; sha="${SHA256_X86_64_DARWIN}"; ext="tar.xz"; exe="" ;;
Darwin-arm64) target="aarch64-apple-darwin"; sha="${SHA256_AARCH64_DARWIN}"; ext="tar.xz"; exe="" ;;
MINGW*-x86_64|MSYS*-x86_64|CYGWIN*-x86_64) target="x86_64-pc-windows-msvc"; sha="${SHA256_X86_64_WINDOWS}"; ext="zip"; exe=".exe" ;;
*) echo "::error::unsupported runner $(uname -s)-$(uname -m) for dist install"; exit 1 ;;
esac
asset="cargo-dist-${target}.${ext}"
tmp="$(mktemp -d)"
curl -fsSL "https://github.com/axodotdev/cargo-dist/releases/download/v${CARGO_DIST_VERSION}/${asset}" -o "${tmp}/${asset}"
# macOS runners ship `shasum`, not `sha256sum`; the dist-build matrix spans both.
if command -v sha256sum >/dev/null 2>&1; then
echo "${sha} ${tmp}/${asset}" | sha256sum -c -
else
echo "${sha} ${tmp}/${asset}" | shasum -a 256 -c -
fi
dest="${HOME}/.cargo/bin"
mkdir -p "${dest}"
if [ "${ext}" = "zip" ]; then
unzip -j -o "${tmp}/${asset}" "dist${exe}" -d "${dest}"
else
tar -xJf "${tmp}/${asset}" -C "${dest}" --strip-components=1 "cargo-dist-${target}/dist"
fi
rm -rf "${tmp}"
echo "${dest}" >> "${GITHUB_PATH}"
"${dest}/dist${exe}" --version
15 changes: 15 additions & 0 deletions .github/actions/rust/native-deps/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Rust Native Dependencies Action Composite
name: rust-native-deps
description: Run the optional ci/setup.sh native build-dependency hook.

runs:
using: composite
steps:
- name: Native build dependencies
shell: bash
run: |
if [ -f ci/setup.sh ]; then
bash ci/setup.sh
else
echo "::notice::No ci/setup.sh — pure-Rust package"
fi
14 changes: 14 additions & 0 deletions .github/actions/rust/pin-version/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Rust Pin Version Action Composite
name: rust-pin-version
description: Install cargo-set-version (version-pinned via CARGO_EDIT_VERSION) and stamp Cargo.toml to the release tag.

runs:
using: composite
steps:
- name: Pin Cargo.toml to tag
shell: bash
env:
CARGO_EDIT_VERSION: "0.13.11"
run: |
cargo install cargo-edit --bin cargo-set-version --version "${CARGO_EDIT_VERSION}" --locked
cargo set-version "${GITHUB_REF_NAME}"
21 changes: 21 additions & 0 deletions .github/actions/rust/test-deps/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Rust Test Dependencies Action Composite
name: rust-test-deps
description: Load the optional ci/test.env into the job environment and run the optional ci/test-setup.sh test-fixture hook.

runs:
using: composite
steps:
- name: Test environment and fixtures
shell: bash
run: |
if [ -f ci/test.env ]; then
grep -E '^[A-Za-z_][A-Za-z0-9_]*=' ci/test.env >> "${GITHUB_ENV}" || true
echo "::notice::Loaded ci/test.env into the job environment"
else
echo "::notice::No ci/test.env — no test environment overrides"
fi
if [ -f ci/test-setup.sh ]; then
bash ci/test-setup.sh
else
echo "::notice::No ci/test-setup.sh — no test fixtures"
fi
33 changes: 33 additions & 0 deletions .github/actions/security/cargo-deny/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Security cargo-deny Action Composite
name: security-cargo-deny
description: Run cargo-deny against the canonical Coroboros ruleset (imposed, no consumer override).

# The caller checks out the repo to scan before using this composite.
runs:
using: composite
steps:
- name: Checkout canonical deny config
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
repository: coroboros/ci
path: .coroboros-ci
sparse-checkout: |
security/deny.toml
sparse-checkout-cone-mode: false

- name: Reject consumer deny overrides
shell: bash
# `--config` ignores the consumer's deny.toml, but cargo-deny still merges a
# project-local deny.exceptions.toml into the licenses policy — block it.
run: |
if find . -path ./.coroboros-ci -prune -o -type f \
\( -name 'deny.exceptions.toml' -o -name '.deny.exceptions.toml' \) -print \
| grep -q .; then
echo "::error::deny.exceptions.toml is not permitted — the cargo-deny policy is imposed by coroboros/ci"
exit 1
fi

- uses: EmbarkStudios/cargo-deny-action@bb137d7af7e4fb67e5f82a49c4fce4fad40782fe # v2.0.20
with:
command: check
command-arguments: "--config .coroboros-ci/security/deny.toml"
70 changes: 70 additions & 0 deletions .github/actions/security/gitleaks/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# Security gitleaks Action Composite
name: security-gitleaks
description: Install gitleaks (SHA-256 verified) and scan with the canonical Coroboros ruleset. Emits SARIF.

# The caller checks out the repo to scan (fetch-depth: 0) before using this composite.
runs:
using: composite
steps:
- name: Checkout canonical gitleaks config
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
repository: coroboros/ci
path: .coroboros-ci
sparse-checkout: |
security/.gitleaks.toml
sparse-checkout-cone-mode: false

- name: Install gitleaks
shell: bash
env:
GITLEAKS_VERSION: "8.30.1"
GITLEAKS_SHA256: "551f6fc83ea457d62a0d98237cbad105af8d557003051f41f3e7ca7b3f2470eb"
run: |
tmp="$(mktemp -d)"
tarball="gitleaks_${GITLEAKS_VERSION}_linux_x64.tar.gz"
curl -fsSL \
"https://github.com/gitleaks/gitleaks/releases/download/v${GITLEAKS_VERSION}/${tarball}" \
-o "${tmp}/${tarball}"
echo "${GITLEAKS_SHA256} ${tmp}/${tarball}" | sha256sum -c -
tar -xzf "${tmp}/${tarball}" -C "${tmp}" gitleaks
sudo install -m 0755 "${tmp}/gitleaks" /usr/local/bin/gitleaks
rm -rf "${tmp}"
gitleaks version

- name: Run gitleaks
shell: bash
env:
GITLEAKS_CONFIG: ".coroboros-ci/security/.gitleaks.toml"
SCAN_MODE: "git"
run: |
set +e
gitleaks "${SCAN_MODE}" \
--config "${GITLEAKS_CONFIG}" \
--no-banner \
--redact \
--report-format sarif \
--report-path results.sarif \
--exit-code 2
rc=$?
set -e

echo "::notice::gitleaks exit code: ${rc}"
if [ "${rc}" = "0" ]; then
echo "::notice::gitleaks: no leaks found"
elif [ "${rc}" = "2" ]; then
echo "::error::gitleaks: leaks detected — see results.sarif artifact"
exit 1
else
echo "::error::gitleaks: scan failed with exit code ${rc}"
exit "${rc}"
fi

- name: Upload SARIF report
if: always()
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: gitleaks-report
path: results.sarif
if-no-files-found: ignore
retention-days: 30
Loading
Loading