ci: add release automation via git-cliff#34
Conversation
scripts/release.sh bumps CMakeLists.txt VERSION, regenerates CHANGELOG.md with git-cliff, then commits and tags. Pushing is left to the operator. .github/workflows/release.yml triggers on tag push, regenerates the per-tag release notes with git-cliff, and creates the GitHub Release.
|
Warning Review limit reached
More reviews will be available in 32 minutes and 4 seconds. Learn how PR review limits work. Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file). ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the 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. 📝 WalkthroughWalkthroughTwo new release automation artifacts are added: ChangesRelease Automation
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
|
@coderabbitai review |
✅ Action performedReview finished.
|
There was a problem hiding this comment.
Actionable comments posted: 5
🧹 Nitpick comments (1)
.github/workflows/release.yml (1)
17-20: 💤 Low valueConsider setting
persist-credentials: falseon checkout.While this workflow doesn't perform subsequent git operations (so it's not strictly necessary), setting
persist-credentials: falseis security best practice to prevent credential leakage:- name: Checkout uses: actions/checkout@v4 with: fetch-depth: 0 persist-credentials: false🤖 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 17 - 20, The checkout step in the release workflow uses actions/checkout@v4 but does not explicitly set persist-credentials to false. Add persist-credentials: false to the with section of the Checkout step alongside the existing fetch-depth: 0 configuration. This follows security best practices by preventing GitHub credentials from being persisted in the workflow environment, reducing the risk of credential leakage even though this particular workflow doesn't perform subsequent git operations.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 24: The orhun/git-cliff-action reference in the workflow file is using a
version tag `@v4` instead of being pinned to a specific commit SHA, which can lead
to inconsistent behavior and security concerns. Replace the `@v4` reference with
the full commit SHA (d4c7180c0bf301e4aefbd7d5e91e93a3bd64e38a) to ensure
reproducibility and security. Verify this commit SHA matches the latest v4
release of the action by checking the action's official repository, then update
the uses field to use the commit SHA format with a comment indicating the
version for maintainability.
- Line 30: The `softprops/action-gh-release` action reference uses a version tag
(v2) instead of being pinned to a specific commit hash, which poses a security
risk. Replace the action reference from `softprops/action-gh-release@v2` with
the full commit SHA
`softprops/action-gh-release@de2c0eb89ae2a093876385947365ecca42febe4d` and add a
comment `# v2` to maintain readability while ensuring the action is locked to a
specific, immutable commit.
- Line 18: The actions/checkout action reference on line 18 is using a version
tag (v4) instead of being pinned to an exact commit hash, which violates
security best practices. Replace the `uses: actions/checkout@v4` reference with
the full commit SHA for that version, following the format `uses:
actions/checkout@<commit-sha> # v4.x.x`, where the commit SHA should be
verified from the action's official release page or repository tags to ensure
you have the correct hash for the version you intend to use.
In `@scripts/release.sh`:
- Line 78: The sed -i -E command on line 78 that updates the CMAKE_FILE is not
portable to macOS, which requires a different syntax for the in-place edit flag.
Replace the sed -i -E invocation with a portable approach by either detecting
the sed variant (GNU vs BSD) and using the appropriate flag, or use a temp file
pattern that writes to a temporary file and then moves it back to CMAKE_FILE.
The temp file approach is more universally portable across different systems.
- Around line 47-55: The conditional logic at line 47 uses an AND operator to
check both git-cliff and git together, but this allows execution to proceed if
only git-cliff is found while git is missing, causing the subsequent git cliff
command at line 52 to fail with an uninformative error. Refactor by replacing
the compound AND conditional with two separate sequential checks: first verify
that the git command exists with a dedicated check and error message, then
separately verify that git-cliff is available with its own check and error
message. This ensures both required tools are validated before attempting to use
git cliff.
---
Nitpick comments:
In @.github/workflows/release.yml:
- Around line 17-20: The checkout step in the release workflow uses
actions/checkout@v4 but does not explicitly set persist-credentials to false.
Add persist-credentials: false to the with section of the Checkout step
alongside the existing fetch-depth: 0 configuration. This follows security best
practices by preventing GitHub credentials from being persisted in the workflow
environment, reducing the risk of credential leakage even though this particular
workflow doesn't perform subsequent git operations.
🪄 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: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 70f4a719-4c3d-4f7c-88cc-eac7df4ab6ba
📒 Files selected for processing (2)
.github/workflows/release.ymlscripts/release.sh
| contents: write | ||
| steps: | ||
| - name: Checkout | ||
| uses: actions/checkout@v4 |
There was a problem hiding this comment.
Action reference actions/checkout@v4 is not pinned to a commit hash.
GitHub Actions best practice and security policy (enforced by zizmor) requires pinning actions to exact commit SHAs, not version tags. Tags can be re-pointed or hijacked.
Recommendation: Pin to a known commit hash. Example (verify exact SHA matches your intended version):
- uses: actions/checkout@a5ac7e51b41094c7418c8a7c5f280f24ab337563 # v4.1.0You can find the correct SHA by:
- Visiting the action's release page and copying the commit hash from the tag, or
- Running:
git ls-remote --heads https://github.com/actions/checkout refs/tags/v4 | awk '{print $1}'
🧰 Tools
🪛 zizmor (1.25.2)
[error] 18-18: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
🤖 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 at line 18, The actions/checkout action
reference on line 18 is using a version tag (v4) instead of being pinned to an
exact commit hash, which violates security best practices. Replace the `uses:
actions/checkout@v4` reference with the full commit SHA for that version,
following the format `uses: actions/checkout@<commit-sha> # v4.x.x`, where the
commit SHA should be verified from the action's official release page or
repository tags to ensure you have the correct hash for the version you intend
to use.
Source: Linters/SAST tools
|
|
||
| - name: Generate release notes | ||
| id: cliff | ||
| uses: orhun/git-cliff-action@v4 |
There was a problem hiding this comment.
Action reference orhun/git-cliff-action@v4 is not pinned to a commit hash.
Pin this action to a commit SHA for reproducibility and security:
- uses: orhun/git-cliff-action@d4c7180c0bf301e4aefbd7d5e91e93a3bd64e38a # v4Verify the exact commit SHA from the action's latest v4 release.
🧰 Tools
🪛 zizmor (1.25.2)
[error] 24-24: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
🤖 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 at line 24, The orhun/git-cliff-action
reference in the workflow file is using a version tag `@v4` instead of being
pinned to a specific commit SHA, which can lead to inconsistent behavior and
security concerns. Replace the `@v4` reference with the full commit SHA
(d4c7180c0bf301e4aefbd7d5e91e93a3bd64e38a) to ensure reproducibility and
security. Verify this commit SHA matches the latest v4 release of the action by
checking the action's official repository, then update the uses field to use the
commit SHA format with a comment indicating the version for maintainability.
Source: Linters/SAST tools
| args: --latest --strip header --tag ${{ github.ref_name }} | ||
|
|
||
| - name: Create GitHub Release | ||
| uses: softprops/action-gh-release@v2 |
There was a problem hiding this comment.
Action reference softprops/action-gh-release@v2 is not pinned to a commit hash.
Pin this action to a commit SHA:
- uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365ecca42febe4d # v2Verify the exact commit SHA from the action's latest v2 release.
🧰 Tools
🪛 zizmor (1.25.2)
[error] 30-30: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
[info] 30-30: action functionality is already included by the runner (superfluous-actions): use gh release in a script step
(superfluous-actions)
🤖 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 at line 30, The `softprops/action-gh-release`
action reference uses a version tag (v2) instead of being pinned to a specific
commit hash, which poses a security risk. Replace the action reference from
`softprops/action-gh-release@v2` with the full commit SHA
`softprops/action-gh-release@de2c0eb89ae2a093876385947365ecca42febe4d` and add a
comment `# v2` to maintain readability while ensuring the action is locked to a
specific, immutable commit.
Source: Linters/SAST tools
| if ! command -v git-cliff >/dev/null 2>&1 && ! command -v git >/dev/null 2>&1; then | ||
| echo "error: git not found on PATH" >&2 | ||
| exit 69 | ||
| fi | ||
|
|
||
| if ! git cliff --version >/dev/null 2>&1; then | ||
| echo "error: 'git cliff' not available; install git-cliff (https://git-cliff.org/)" >&2 | ||
| exit 69 | ||
| fi |
There was a problem hiding this comment.
Logic error in tool availability check (line 47).
The conditional at line 47 evaluates to: "if (git-cliff NOT found) AND (git NOT found)", but then unconditionally attempts to use git cliff at line 52. If only git is missing, the first check passes (because git-cliff is present), but line 52 fails with an uninformative error.
Refactor to check git availability first (always required), then check git-cliff separately:
if ! command -v git >/dev/null 2>&1; then
echo "error: git not found on PATH" >&2
exit 69
fi
if ! git cliff --version >/dev/null 2>&1; then
echo "error: 'git cliff' not available; install git-cliff (https://git-cliff.org/)" >&2
exit 69
fi🤖 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 `@scripts/release.sh` around lines 47 - 55, The conditional logic at line 47
uses an AND operator to check both git-cliff and git together, but this allows
execution to proceed if only git-cliff is found while git is missing, causing
the subsequent git cliff command at line 52 to fail with an uninformative error.
Refactor by replacing the compound AND conditional with two separate sequential
checks: first verify that the git command exists with a dedicated check and
error message, then separately verify that git-cliff is available with its own
check and error message. This ensures both required tools are validated before
attempting to use git cliff.
| exit 70 | ||
| fi | ||
|
|
||
| sed -i -E "s/^([[:space:]]*VERSION[[:space:]]+)[0-9]+\.[0-9]+\.[0-9]+/\1${VERSION}/" "${CMAKE_FILE}" |
There was a problem hiding this comment.
sed -i is not portable to macOS.
Line 78 uses sed -i -E, which works on Linux but fails on macOS (requires a backup suffix like sed -i '' -E or sed -i .bak -E).
If this script must run on developer machines or CI systems that include macOS, use a portable pattern via sed with -i and a platform-agnostic fallback, or use perl if it's a safe dependency. Alternatively, document that Linux is required.
🔧 Option 1: Use GNU sed-style with fallback
# Detect sed variant and use appropriate flag
if sed --version >/dev/null 2>&1; then
# GNU sed
sed -i -E "s/^([[:space:]]*VERSION[[:space:]]+)[0-9]+\.[0-9]+\.[0-9]+/\1${VERSION}/" "${CMAKE_FILE}"
else
# BSD/macOS sed
sed -i '' -E "s/^([[:space:]]*VERSION[[:space:]]+)[0-9]+\.[0-9]+\.[0-9]+/\1${VERSION}/" "${CMAKE_FILE}"
fi🔧 Option 2: Use a temp file (most portable)
sed -E "s/^([[:space:]]*VERSION[[:space:]]+)[0-9]+\.[0-9]+\.[0-9]+/\1${VERSION}/" "${CMAKE_FILE}" > "${CMAKE_FILE}.tmp"
mv "${CMAKE_FILE}.tmp" "${CMAKE_FILE}"🤖 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 `@scripts/release.sh` at line 78, The sed -i -E command on line 78 that updates
the CMAKE_FILE is not portable to macOS, which requires a different syntax for
the in-place edit flag. Replace the sed -i -E invocation with a portable
approach by either detecting the sed variant (GNU vs BSD) and using the
appropriate flag, or use a temp file pattern that writes to a temporary file and
then moves it back to CMAKE_FILE. The temp file approach is more universally
portable across different systems.
The compound `! cliff && ! git` check only fired when both were missing — a missing git-cliff slipped through. Drop the block: git is implicitly required by the `git rev-parse` call above, and the `git cliff --version` check below already handles the missing-cliff case with a clear error.
Summary
scripts/release.shto cut a release locally: validates input, bumpsCMakeLists.txtVERSION, regeneratesCHANGELOG.mdviagit cliff --tag v<version> -o, creates the release commit and annotated tag. Pushing is left to the operator..github/workflows/release.ymltriggered onv*tag push: usesorhun/git-cliff-action@v4to extract the per-tag notes (--latest --strip header) andsoftprops/action-gh-release@v2to publish the GitHub Release.Together these turn the release procedure into:
./scripts/release.sh <version>→git push origin main v<version>→ workflow publishes the Release.Test plan
release.shrejects bad input: no args (exit 64), invalid semver (exit 64), pre-existing tag (exit 65), dirty working tree (exit 65).chore(release): v0.2.0commit (touching onlyCMakeLists.txt+CHANGELOG.md), an annotatedv0.2.0tag, and a regeneratedCHANGELOG.mdcovering all 37 commits sincev0.1.0grouped percliff.toml.v0.2.0and confirm the workflow creates a GitHub Release with the expected notes.Notes
chore(release): ...commit message is already filtered out bycliff.toml, so it won't appear in future changelogs.git cliffcurrently fails in clones using git'sreftableref storage (libgit2 limitation); run the script in a clone using the classicfilesref backend, or convert withgit refs migrate --ref-format=files. CI is unaffected.Summary by CodeRabbit