ci: make crate publish re-runnable and fix cargo-sbom install on persistent cache#41
Conversation
…istent cache
Two coupled problems surfaced publishing 0.2.1 from the self-hosted runner:
1. `cargo install cargo-sbom --locked` exits 101 ("binary already exists")
because the runner's CARGO_HOME (/cache/cargo) is a persistent volume —
the binary survives across runs. Plain install is not idempotent there.
Fix: add --force so it reinstalls the --locked pinned version each time.
2. When the publish job fails after release-please has already tagged the
release, there was no way to re-publish: the job is gated on
`release_created`, which is only true on the release-PR merge, and
re-running the original run is pinned to the old workflow file.
Fix: add a `workflow_dispatch` trigger and allow the publish job to run
on it, so a tagged-but-unpublished version can be published via CI
(preserving build-provenance + SBOM attestation) instead of by hand.
|
Looking for one thing? Review this PR in Change Stack to search files, summaries, diffs, and code without losing your place. No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (1)
WalkthroughAdds ChangesRelease Workflow Manual Dispatch and Tooling
Possibly related PRs
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
.github/workflows/release.yml (1)
1-16:⚠️ Potential issue | 🟠 Major | ⚡ Quick winAdd concurrency guard to serialise release/publish executions
There is no workflow/job
concurrencycontrol, so overlapping runs (e.g. push + manual dispatch) can race into duplicate publish attempts against crates.io. Add a concurrency group (workflow-level orpublishjob-level) withcancel-in-progress: false.Suggested fix
name: Release +concurrency: + group: release-${{ github.ref }} + cancel-in-progress: falseAlso applies to: 34-43
🤖 Prompt for 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. In @.github/workflows/release.yml around lines 1 - 16, Add a concurrency guard to the Release workflow to prevent overlapping publish runs by adding a concurrency block (either workflow-level or inside the publish job) with a stable group name (e.g. "release-${{ github.ref }}" or "publish") and cancel-in-progress: false; update the existing workflow YAML (the top-level workflow "Release" or the "publish" job definition) to include concurrency: with group and cancel-in-progress: false so manual dispatches and pushes are serialized.Source: Linters/SAST tools
🤖 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/release.yml:
- Line 37: The publish gate is unsafe because
needs.release-please.outputs.release_created is a string and workflow_dispatch
can target arbitrary refs; update the `if:` to perform an explicit string
comparison on needs.release-please.outputs.release_created (e.g., compare to
'true') and additionally require the ref for manual dispatch to be the main
branch by checking github.ref (or github.event.ref) equals 'refs/heads/main'
when github.event_name == 'workflow_dispatch'; locate the condition line
referencing needs.release-please.outputs.release_created and github.event_name
and replace it with an explicit boolean expression that enforces both the string
comparison and the main-branch check before allowing cargo publish.
---
Outside diff comments:
In @.github/workflows/release.yml:
- Around line 1-16: Add a concurrency guard to the Release workflow to prevent
overlapping publish runs by adding a concurrency block (either workflow-level or
inside the publish job) with a stable group name (e.g. "release-${{ github.ref
}}" or "publish") and cancel-in-progress: false; update the existing workflow
YAML (the top-level workflow "Release" or the "publish" job definition) to
include concurrency: with group and cancel-in-progress: false so manual
dispatches and pushes are serialized.
🪄 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: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 578c7a0e-7386-434c-be62-d231fd391537
📒 Files selected for processing (1)
.github/workflows/release.yml
…y dispatch Addresses CodeRabbit review on #41: - Add workflow-level concurrency (group: release-<ref>, cancel-in-progress: false) so a push and a manual dispatch can't race into two concurrent cargo publish attempts. - Restrict the publish job's manual-dispatch path to refs/heads/main so a workflow_dispatch fired from a feature branch can't publish that branch's Cargo.toml version. Also make the release_created check an explicit == 'true' comparison rather than relying on string coercion.
|
@coderabbitai Both addressed in 852727f:
Please re-review. |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
cat .github/workflows/release.ymlLength of output: 3496
Concurrency (
Gate safety ( if: ${{ needs.release-please.outputs.release_created == 'true'
|| (github.event_name == 'workflow_dispatch' && github.ref == 'refs/heads/main') }}
The rest of the workflow ( (✿◠‿◠)🐰 ✏️ Learnings added
|
What
Makes the crate publish job both robust and re-runnable:
cargo install cargo-sbom --locked --force— the self-hosted runner'sCARGO_HOME(/cache/cargo) is a persistent volume, so the binary survives between runs and a plain install exits 101 (binary cargo-sbom already exists).--forcereinstalls the--lockedpinned version idempotently.workflow_dispatchtrigger + publish gate widened torelease_created || workflow_dispatch— lets a tagged-but-unpublished version be published via CI (with full build-provenance + SBOM attestation) instead of by hand.Why
0.2.1 was tagged by release-please but its publish job failed twice — first a transient Sigstore/Fulcio cert error, then deterministically on the cargo-sbom step above. The release was gated such that there was no CI path to re-publish an already-tagged version (re-running the failed run is pinned to the old workflow file). This fixes both the immediate bug and the structural gap.
After merge
gh workflow run release.yml(or the Actions UI Run workflow button) publishes the currentmainversion (0.2.1) through the full attest → SBOM → publish pipeline.ci:type — non-releasing.Summary by CodeRabbit