Skip to content

ci: harden PR pipeline (audit, MSRV, beta matrix, release + docker smoke)#57

Merged
kevincodex1 merged 6 commits into
mainfrom
ci/harden-pipeline
Jun 22, 2026
Merged

ci: harden PR pipeline (audit, MSRV, beta matrix, release + docker smoke)#57
kevincodex1 merged 6 commits into
mainfrom
ci/harden-pipeline

Conversation

@beardthelion

@beardthelion beardthelion commented Jun 18, 2026

Copy link
Copy Markdown
Collaborator

Splits the single stable-only fmt + clippy + test job in pr-checks.yml into focused jobs and adds the coverage the pipeline was missing.

What runs on every PR now:

  • fmt + clippy (stable): cargo fmt --all -- --check, cargo clippy --workspace --all-targets -- -D warnings
  • test: matrix on stable and beta, cargo test --workspace. Beta is continue-on-error so an upstream beta regression warns instead of blocking merges; stable stays required.
  • build --release: cargo build --release --workspace, so PRs get a release-profile signal (previously only the release workflow built release artifacts, and only on tags).
  • cargo audit: installs cargo-audit with --locked and runs it against the committed Cargo.lock.
  • MSRV (Rust 1.91): pins the 1.91 toolchain and runs cargo check --workspace --all-targets. Backed by a real rust-version = "1.91" in [workspace.package], inherited by all five crates, so the README/Dockerfile's stated minimum is now enforced instead of aspirational.
  • Docker build smoke test: docker build plus a --version run, mirroring the release workflow's entrypoint, so a Dockerfile regression can't reach main and break docker compose up.

Also added a concurrency group that cancels superseded PR runs (never cancels main) and per-job timeouts. New actions follow the existing SHA-pinned convention.

Heads up on branch protection: the required status check changes from fmt + clippy + test to the new job names (fmt + clippy, test (stable), build --release, cargo audit, MSRV (Rust 1.91), Docker build smoke test). The required-checks list will need updating or PRs will wait on a check that no longer reports. test (beta) is intentionally non-blocking.


Accepted advisories (cargo audit)

The cargo audit gate is green, but two reachable advisories ship suppressed because no upstream fix exists yet. Noting them so a green check is not read as advisory-clean:

  • RUSTSEC-2026-0118 / RUSTSEC-2026-0119 (hickory-proto 0.25.2, via libp2p-dns 0.44): reachable DoS through the node's system DNS resolver (crates/gitlawb-node/src/p2p/mod.rs:238). No fix until libp2p-dns ships hickory 0.26. Tracked in Drop hickory advisory ignores once libp2p-dns ships hickory 0.26 #76.
  • RUSTSEC-2023-0071 (rsa 0.9.10): present in the lockfile via sqlx's unconditional sqlx-mysql, but not linked into the binary (sqlx is postgres-only), so there is no RSA oracle to attack; no upstream fix regardless.

rustls-webpki was bumped to 0.103.13 to clear its three advisories rather than ignore them. Suppressions live in .cargo/audit.toml with inline rationale; the audit job echoes the active ignores to its summary, and the weekly scheduled job re-checks without the ignores and fails on hickory drift.

Summary by CodeRabbit

Release Notes

  • Chores
    • Set an explicit minimum supported Rust version (1.91) across the workspace and crates.
    • Improved CI reliability and coverage with PR run concurrency control, a dedicated test matrix, release builds, MSRV checks, Docker build + version smoke testing, and automated security audits.
    • Added a scheduled weekly audit that detects advisory drift to help keep the security posture current.

…er smoke)

Restructure the single stable-only fmt+clippy+test job into separate jobs:
fmt+clippy (stable), a test matrix on stable+beta (beta non-blocking),
build --release, cargo audit, an MSRV check pinned to Rust 1.91, and a
Docker build smoke test mirroring the release workflow. Add concurrency
cancellation for superseded PR runs and per-job timeouts.

Declare rust-version = "1.91" in [workspace.package] and inherit it in
every member crate so the stated MSRV is a real, CI-enforced contract.
@coderabbitai

coderabbitai Bot commented Jun 18, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@beardthelion, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 32 minutes and 46 seconds. Learn how PR review limits work.

To continue reviewing without waiting, enable usage-based billing in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits.

🚦 How do rate limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan refill rate.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, the refill rate gradually slows as usage increases. The highest same-day bursts are limited more strictly.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 6298cbcf-62c1-46d0-bb22-b8f16596e67b

📥 Commits

Reviewing files that changed from the base of the PR and between 248441c and a06fef5.

📒 Files selected for processing (2)
  • .cargo/audit.toml
  • .github/workflows/audit-schedule.yml
📝 Walkthrough

Walkthrough

Rust 1.91 is declared as the workspace MSRV in the root Cargo.toml and propagated via rust-version.workspace = true to all five crate manifests. Cargo-audit configuration is established with a suppression allowlist for three specific RustSec advisories. A new scheduled audit workflow runs weekly to generate unsuppressed audit reports and validate advisory drift. The PR checks workflow gains concurrency cancellation, a test matrix job over stable/beta toolchains, and four new validation jobs: build-release, audit, msrv (Rust 1.91), and docker-build.

Changes

MSRV Declaration, Audit Configuration, and CI Expansion

Layer / File(s) Summary
Workspace and crate MSRV declarations
Cargo.toml, crates/git-remote-gitlawb/Cargo.toml, crates/gitlawb-attest/Cargo.toml, crates/gitlawb-core/Cargo.toml, crates/gitlawb-node/Cargo.toml, crates/gl/Cargo.toml
Sets rust-version = "1.91" in [workspace.package] and adds rust-version.workspace = true to each crate's [package] section.
Cargo audit configuration and allowlist
.cargo/audit.toml
Adds advisory suppression configuration for three RustSec IDs (hickory QUIC/DNS and RSA timing sidechannel) with documented rationale and drift removal notes.
Scheduled audit workflow and drift guard
.github/workflows/audit-schedule.yml
Introduces weekly scheduled audit workflow that generates full unsuppressed audit reports, appends them to the step summary, and includes a drift guard to validate hickory-proto version pinning against remaining advisory suppressions.
PR checks workflow restructure: concurrency, test matrix, and new jobs
.github/workflows/pr-checks.yml
Adds PR-scoped concurrency cancellation, splits cargo test into a dedicated matrix job over stable/beta toolchains with beta configured as non-blocking, and introduces build-release (release build), audit (cargo-audit with summary), msrv (pinned Rust 1.91 cargo check), and docker-build (image build plus smoke test) jobs.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested reviewers

  • kevincodex1

Poem

🐇 With whiskers twitched and toolchain blessed,
Rust one-nine-one passes every test!
Audits scheduled, suppressions clear,
Docker builds and checks run year after year.
CI jobs in parallel play—
Every crate validated every day! 🌿

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main changes: hardening the PR pipeline with new jobs (audit, MSRV, beta matrix, release, docker smoke test).
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description check ✅ Passed PR description is comprehensive and well-structured, covering all key template sections including summary, motivation, kind of change, what changed, verification steps, and protocol/signing impact.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ci/harden-pipeline

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/pr-checks.yml:
- Around line 27-28: The actions/checkout action in this workflow defaults to
persisting GitHub credentials in the git config, which creates a security risk
since untrusted PR code runs via cargo and docker build commands. Add a with
block containing persist-credentials: false to each of the six checkout steps in
the workflow (each uses
actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683) to prevent the GitHub
token from being stored in the local git configuration and exposed to executing
code.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: ce913bf5-8799-4665-9528-4c69c514e9d4

📥 Commits

Reviewing files that changed from the base of the PR and between 8680d0f and 9127834.

📒 Files selected for processing (7)
  • .github/workflows/pr-checks.yml
  • Cargo.toml
  • crates/git-remote-gitlawb/Cargo.toml
  • crates/gitlawb-attest/Cargo.toml
  • crates/gitlawb-core/Cargo.toml
  • crates/gitlawb-node/Cargo.toml
  • crates/gl/Cargo.toml

Comment thread .github/workflows/pr-checks.yml
Set persist-credentials: false on all six actions/checkout steps. These
jobs run untrusted PR code via cargo and docker build, and checkout's
default leaves the GITHUB_TOKEN in the local git config where that code
could read it. None of the jobs push or otherwise need git credentials.
Clears three advisories flagged by the new cargo audit job: a reachable
panic in CRL parsing and two name-constraint bypasses (wildcard and URI).
Semver-compatible patch, lockfile only, no manifest or code change.

cargo also corrects a stale lockfile reference while rewriting Cargo.lock:
data-encoding-macro-internal 0.1.17 (a build-time macro crate) requires
syn 1.x, and its dependency entry is re-pinned from syn 2.0.117 to the
1.0.109 it actually resolves to. Unrelated to the bump, unavoidable when
cargo touches the lock, and the more-correct state.
The cargo audit job stays hard-fail. The remaining three advisories have
no available upstream fix, so they are suppressed in .cargo/audit.toml
(the location cargo-audit actually reads; a repo-root audit.toml is not
read), each with an inline rationale and removal condition:

- RUSTSEC-2026-0118/0119 (hickory-proto 0.25.2, via libp2p-dns 0.44):
  reachable, since the node wraps QUIC in the system DNS resolver. No fix
  until libp2p-dns ships hickory 0.26. Accepted, reachable risk.
- RUSTSEC-2023-0071 (rsa Marvin): in the lockfile via sqlx's unconditional
  sqlx-mysql, but not linked (sqlx is postgres-only), so no RSA oracle
  exists; no upstream fix regardless.

Two controls keep the suppression honest. The PR audit job echoes the
active ignore list to the job summary, so a green check is not read as
advisory-clean. A weekly scheduled job re-runs cargo audit without the
ignores for visibility and hard-fails if hickory-proto moves off 0.25.x
while the ignores remain, so the suppression cannot silently outlive the
upstream fix.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/audit-schedule.yml:
- Around line 66-71: The drift guard check for RUSTSEC-2026-011 ignores in
.cargo/audit.toml only fails when the hickory-proto version is present and
doesn't match 0.25.*, but it misses the case where the dependency has been
removed entirely from Cargo.lock (when version is empty). Add an additional
condition to also trigger an error when ignores_present is true AND version is
empty (using the -z test), ensuring the workflow fails both when the dependency
is downgraded and when it's removed completely while ignores remain in the
configuration.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: e8337dbd-1a24-4baf-baf5-a35be6c8afef

📥 Commits

Reviewing files that changed from the base of the PR and between 9127834 and 248441c.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (3)
  • .cargo/audit.toml
  • .github/workflows/audit-schedule.yml
  • .github/workflows/pr-checks.yml
✅ Files skipped from review due to trivial changes (1)
  • .cargo/audit.toml
🚧 Files skipped from review as they are similar to previous changes (1)
  • .github/workflows/pr-checks.yml

Comment thread .github/workflows/audit-schedule.yml Outdated
@beardthelion

Copy link
Copy Markdown
Collaborator Author

@kevincodex1 this is green and ready. The only thing holding it was its own new cargo audit job flagging six advisories in the dependency tree. Fixed: bumped rustls-webpki to clear three, and suppressed the three with no upstream fix in .cargo/audit.toml, each justified inline. Two of those (hickory, reachable via the DNS resolver) are accepted risk tracked in #76, with a weekly scheduled job that fails if they ever become fixable and the ignore lingers. Full matrix is green. Details in the updated description.

The scheduled drift guard only failed when hickory-proto was present and
off 0.25.x, so removing it from Cargo.lock entirely left the RUSTSEC-2026-0118
/0119 ignores in place with the guard still passing. Treat an absent version
as drift as well, so dead ignore entries are caught whether the dependency is
bumped past 0.25.x or removed.

@kevincodex1 kevincodex1 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great to me!

@kevincodex1 kevincodex1 merged commit 7533b74 into main Jun 22, 2026
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants