chore: streamline release workflow and scripts#25
Conversation
|
Warning Rate limit exceeded
You’ve run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (7)
📝 WalkthroughWalkthroughThis PR refactors the release and installer infrastructure by replacing a legacy GitHub-embedded installer script with a modern prebuilt-release-first installer served via CDN, updating Makefile platform targeting and packaging, enhancing the release workflow with changelog generation and GPG verification, and enabling CodeQL security scanning on pull requests. ChangesRelease Pipeline and Installer Refactor
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes The PR spans multiple infrastructure areas (CI/workflows, Makefile, installer script) with some heterogeneity: workflow YAML configuration, Makefile target refactoring with loop-based logic, and a new shell script with platform detection and multiple execution paths. The changes are cohesive (all parts work together for the new release+install flow) but require verification across CI triggers, build artifact structure, release automation, and installer correctness. Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches✨ Simplify code
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 |
There was a problem hiding this comment.
Actionable comments posted: 5
🧹 Nitpick comments (2)
Makefile (1)
10-10: ⚡ Quick winDeclare command-only targets as
.PHONY.Please add
.PHONY: all releases test cleanto avoid filename collisions changing target execution behavior.Also applies to: 64-68
🤖 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 `@Makefile` at line 10, Add a .PHONY declaration so command-only Makefile targets cannot be mistaken for files: add a line declaring .PHONY: all releases test clean (so targets like all, releases, test, clean are always executed as targets), and ensure any other non-file targets used for builds (e.g., platform-specific targets invoked by all/releases) are covered by .PHONY where appropriate..github/workflows/release.yml (1)
13-15: ⚡ Quick winDisable checkout credential persistence in release jobs.
Set
persist-credentials: falseunless required later in the job to reduce token exposure risk.🤖 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 13 - 15, Update the checkout step that currently uses "actions/checkout@v6" (the block with fetch-depth: 0) to explicitly set persist-credentials: false so the workflow does not retain the GITHUB_TOKEN for later steps; locate the "uses: actions/checkout@v6" step and add the "persist-credentials: false" key alongside existing keys (e.g., fetch-depth) to disable credential persistence.
🤖 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/codeql.yml:
- Line 15: Replace the mutable branch reference in the uses line ("uses:
c3b2a7/.github/.github/workflows/codeql-go.yaml@main") with a fixed full commit
SHA (e.g., @<full-commit-sha>) and append a short version comment for
maintainability (e.g., " # v1.x.y"); update the string in the workflow so the
reusable workflow is pinned to that immutable commit SHA instead of `@main`.
In @.github/workflows/release.yml:
- Around line 45-47: The workflow step currently interpolates ${{
github.event.release.tag_name }} directly in the shell run which is unsafe;
modify the step to pass the tag into the step's env (e.g., set an env variable
like RELEASE_TAG: ${{ github.event.release.tag_name }}) and then use that env
var inside the run commands (replace occurrences of echo "Verifying the tag: ${{
github.event.release.tag_name }}" and git verify-tag "${{
github.event.release.tag_name }}" with references to $RELEASE_TAG and git
verify-tag "$RELEASE_TAG") so the shell never directly expands the GH
expression.
- Around line 13-17: Replace all mutable action refs with their corresponding
full commit SHAs: update the uses entries for actions/checkout@v6 (both
occurrences), orhun/git-cliff-action@v4, actions/setup-go@v6,
softprops/action-gh-release@v2, actions/attest@v4, and
c3b2a7/.github/.github/workflows/release-install-script.yaml@main to their
pinned SHA commits; also add persist-credentials: false to both checkout steps
(the two actions/checkout blocks) so credentials are not passed to later steps.
Ensure each replacement preserves the existing keys and indentation and only
changes the tag to the exact commit SHA and adds the persist-credentials
property under the checkout step configuration.
In `@install.sh`:
- Around line 136-138: After resolving version with latest_tag into the variable
version, validate that version is non-empty and exit with a clear error if it is
empty; update the install.sh block that calls latest_tag (and any code that uses
the version variable) to check [ -z "$version" ] (or equivalent) after
assignment and call echo to stderr and exit 1 to avoid proceeding with an
invalid URL.
- Around line 35-39: The untar function prints success regardless of failures;
update untar (and the similar block at lines 186-189) to fail-fast by checking
the exit status of the tar (and any curl/download) command(s). Specifically,
after running tar (and after any curl/download), inspect the exit code and if
non-zero log an error and exit non‑zero rather than continuing to chmod/print
success; ensure you only print the "Extracting release..."/success message after
a successful extraction. Target the untar function name (and the other
extract/download block) when making the change.
---
Nitpick comments:
In @.github/workflows/release.yml:
- Around line 13-15: Update the checkout step that currently uses
"actions/checkout@v6" (the block with fetch-depth: 0) to explicitly set
persist-credentials: false so the workflow does not retain the GITHUB_TOKEN for
later steps; locate the "uses: actions/checkout@v6" step and add the
"persist-credentials: false" key alongside existing keys (e.g., fetch-depth) to
disable credential persistence.
In `@Makefile`:
- Line 10: Add a .PHONY declaration so command-only Makefile targets cannot be
mistaken for files: add a line declaring .PHONY: all releases test clean (so
targets like all, releases, test, clean are always executed as targets), and
ensure any other non-file targets used for builds (e.g., platform-specific
targets invoked by all/releases) are covered by .PHONY where appropriate.
🪄 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: 7f975a69-b0db-4164-a9ef-0ace6134d767
📒 Files selected for processing (7)
.github/workflows/build.yml.github/workflows/codeql.yml.github/workflows/release.ymlMakefileREADME.mdinstall.shscripts/get-sshtunnel.sh
💤 Files with no reviewable changes (1)
- scripts/get-sshtunnel.sh
|
|
||
| jobs: | ||
| analyze: | ||
| uses: c3b2a7/.github/.github/workflows/codeql-go.yaml@main |
There was a problem hiding this comment.
🧩 Analysis chain
🌐 Web query:
GitHub Actions security reusable workflow pinning commit SHA best practices
💡 Result:
Pinning GitHub Actions and reusable workflows to a full-length commit SHA is a critical supply chain security best practice [1][2][3][4]. Because version tags (e.g., @v1) and branches (e.g., @main) are mutable, they can be re-pointed by a malicious actor or a compromised maintainer account to inject malicious code into your workflow without warning [5][4][6]. Best Practices for Pinning: 1. Use Full-Length Commit SHAs: Always reference actions and reusable workflows using the full-length commit SHA (e.g., uses: actions/checkout@b4ffde6) [2][3][7]. This ensures the code executed is immutable and identical to what you verified [2][3]. 2. Include Version Comments: Since commit SHAs are difficult to read, always append a comment specifying the version tag or release name to improve maintainability [5][8]. Example: - uses: actions/checkout@b4ffde6 # v4.1.1 3. Enforce via Policy: Administrators can enforce SHA pinning at the organization or repository level by configuring the allowed actions policy [1][2]. When enabled, GitHub will block any workflow that attempts to use an action not pinned to a full commit SHA [1]. 4. Manage Updates with Automation: To avoid the maintenance burden of manual updates, use tools like Dependabot or Renovate to automatically open pull requests when new tagged versions of your pinned actions are released [5][8][3]. This allows you to review and verify the update before merging [4][7]. 5. Contextual Risk Assessment: While pinning all actions is a best practice, it is especially critical for high-trust release pipelines, workflows with access to sensitive secrets, or those utilizing OIDC credentials [3][4][9]. 6. Verify Sources: When pinning, ensure the commit SHA originates from the original, trusted action repository and not a fork [2]. By pinning to a specific commit SHA, you neutralize risks associated with tag hijacking, where an attacker moves tags to an "imposter commit" to silently compromise downstream users [6]. Organizations are strongly encouraged to audit existing workflows and replace all tag-based references with pinned SHAs [6].
Citations:
- 1: https://github.blog/changelog/2025-08-15-github-actions-policy-now-supports-blocking-and-sha-pinning-actions/
- 2: https://docs.github.com/en/actions/reference/security/secure-use
- 3: https://www.stepsecurity.io/blog/pinning-github-actions-for-enhanced-security-a-complete-guide
- 4: https://www.aikido.dev/blog/checklist-github-actions
- 5: Pin GitHub Actions to commit SHAs in release workflow github/gh-aw#10021
- 6: https://gbhackers.com/compromised-github-action/
- 7: https://dev.to/nkuziev-sec/why-fixed-container-image-versions-matter-lessons-from-the-trivy-supply-chain-attack-29ke
- 8: Pin all GitHub Actions to immutable SHA commits for supply chain security github/gh-aw#5691
- 9: https://dev.to/duriantaco/github-actions-security-and-gitlab-ci-security-static-analysis-for-cicd-g9h
🏁 Script executed:
# First, let's examine the specific workflow file
cat -n .github/workflows/codeql.yml | head -30Repository: c3b2a7/sshtunnel
Length of output: 419
🏁 Script executed:
# Check for other workflow files and their pinning patterns
fd -e yml -e yaml .github/workflows/ -x cat -n {} \; | head -100Repository: c3b2a7/sshtunnel
Length of output: 438
🏁 Script executed:
fd . '.github/workflows/' -e yml -e yamlRepository: c3b2a7/sshtunnel
Length of output: 147
🏁 Script executed:
# Let's examine other workflow files to see if they use pinning
find .github/workflows -type f \( -name "*.yml" -o -name "*.yaml" \) -exec cat {} \;Repository: c3b2a7/sshtunnel
Length of output: 3499
Pin reusable workflow to an immutable commit SHA.
Using @main is mutable and can silently change security behavior. Pin to a full commit SHA and update intentionally. Per GitHub's official security guidance, branch references are vulnerable to compromise by malicious actors or compromised maintainers. Additionally, include a version comment alongside the commit SHA for maintainability (e.g., @abc123def456 # v1.2.3).
🧰 Tools
🪛 zizmor (1.25.2)
[error] 15-15: 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/codeql.yml at line 15, Replace the mutable branch
reference in the uses line ("uses:
c3b2a7/.github/.github/workflows/codeql-go.yaml@main") with a fixed full commit
SHA (e.g., @<full-commit-sha>) and append a short version comment for
maintainability (e.g., " # v1.x.y"); update the string in the workflow so the
reusable workflow is pinned to that immutable commit SHA instead of `@main`.
| uses: actions/checkout@v6 | ||
| with: | ||
| fetch-depth: 0 | ||
| - name: Generate a changelog | ||
| uses: orhun/git-cliff-action@v4 |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
cat -n .github/workflows/release.ymlRepository: c3b2a7/sshtunnel
Length of output: 2899
🏁 Script executed:
# Check for any additional security considerations
# Look at the permissions and see the full context of how these actions are used
# Also verify the git verify-tag usage
grep -n "persist-credentials" .github/workflows/release.yml || echo "No persist-credentials found"
# Check if there are any other workflow files that might show a pattern
ls -la .github/workflows/ 2>/dev/null || echo "No workflows directory"Repository: c3b2a7/sshtunnel
Length of output: 381
Pin all GitHub Actions to full commit SHAs instead of mutable tags.
Mutable refs like @v6, @v4, @v2, and @main can be retagged by maintainers, creating supply-chain risk in a release workflow. Replace each uses: entry with its corresponding full commit SHA:
- Line 13:
actions/checkout@v6→ SHA - Line 17:
orhun/git-cliff-action@v4→ SHA - Line 34:
actions/checkout@v6→ SHA - Line 37:
actions/setup-go@v6→ SHA - Line 51:
softprops/action-gh-release@v2→ SHA - Line 60:
actions/attest@v4→ SHA - Line 68:
c3b2a7/.github/.github/workflows/release-install-script.yaml@main→ SHA
Additionally, set persist-credentials: false on checkout steps (lines 13–15 and 34–36) to avoid credential exposure to subsequent steps.
🧰 Tools
🪛 zizmor (1.25.2)
[error] 13-13: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
[error] 17-17: 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 around lines 13 - 17, Replace all mutable
action refs with their corresponding full commit SHAs: update the uses entries
for actions/checkout@v6 (both occurrences), orhun/git-cliff-action@v4,
actions/setup-go@v6, softprops/action-gh-release@v2, actions/attest@v4, and
c3b2a7/.github/.github/workflows/release-install-script.yaml@main to their
pinned SHA commits; also add persist-credentials: false to both checkout steps
(the two actions/checkout blocks) so credentials are not passed to later steps.
Ensure each replacement preserves the existing keys and indentation and only
changes the tag to the exact commit SHA and adds the persist-credentials
property under the checkout step configuration.
| echo "Verifying the tag: ${{ github.event.release.tag_name }}" | ||
| # Only accepted if signed by c3b2a7's key | ||
| git verify-tag "${{ github.event.release.tag_name }}" || exit 1 |
There was a problem hiding this comment.
Avoid direct expression interpolation inside shell commands.
Interpolating ${{ github.event.release.tag_name }} directly in run: can enable command substitution payloads if tag content is unsafe. Pass it via env and reference the env var.
Proposed fix
- name: Validate commits and tag signatures
+ env:
+ RELEASE_TAG: ${{ github.event.release.tag_name }}
run: |
# Import key
curl 'https://github.com/c3b2a7.gpg' | gpg --import
- echo "Verifying the tag: ${{ github.event.release.tag_name }}"
+ echo "Verifying the tag: $RELEASE_TAG"
# Only accepted if signed by c3b2a7's key
- git verify-tag "${{ github.event.release.tag_name }}" || exit 1
+ git verify-tag "$RELEASE_TAG" || exit 1📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| echo "Verifying the tag: ${{ github.event.release.tag_name }}" | |
| # Only accepted if signed by c3b2a7's key | |
| git verify-tag "${{ github.event.release.tag_name }}" || exit 1 | |
| - name: Validate commits and tag signatures | |
| env: | |
| RELEASE_TAG: ${{ github.event.release.tag_name }} | |
| run: | | |
| # Import key | |
| curl 'https://github.com/c3b2a7.gpg' | gpg --import | |
| echo "Verifying the tag: $RELEASE_TAG" | |
| # Only accepted if signed by c3b2a7's key | |
| git verify-tag "$RELEASE_TAG" || exit 1 |
🧰 Tools
🪛 zizmor (1.25.2)
[error] 45-45: code injection via template expansion (template-injection): may expand into attacker-controllable code
(template-injection)
[error] 47-47: code injection via template expansion (template-injection): may expand into attacker-controllable code
(template-injection)
🤖 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 45 - 47, The workflow step
currently interpolates ${{ github.event.release.tag_name }} directly in the
shell run which is unsafe; modify the step to pass the tag into the step's env
(e.g., set an env variable like RELEASE_TAG: ${{ github.event.release.tag_name
}}) and then use that env var inside the run commands (replace occurrences of
echo "Verifying the tag: ${{ github.event.release.tag_name }}" and git
verify-tag "${{ github.event.release.tag_name }}" with references to
$RELEASE_TAG and git verify-tag "$RELEASE_TAG") so the shell never directly
expands the GH expression.
| untar() { | ||
| print "Extracting release to $out_prefix/$binary" | ||
| sh -c "tar -xzO \"$binary\" > \"$out_prefix/$binary\"" | ||
| chmod +x "$out_prefix/$binary" | ||
| } |
There was a problem hiding this comment.
Handle tar download/extract failures explicitly.
The tar path can fail without aborting, then still print a success message. Fail fast on curl/tar errors.
Proposed fix
untar() {
print "Extracting release to $out_prefix/$binary"
- sh -c "tar -xzO \"$binary\" > \"$out_prefix/$binary\""
+ sh -c "tar -xzO \"$binary\" > \"$out_prefix/$binary\"" || err "Unable to extract $archive_name"
chmod +x "$out_prefix/$binary"
}
@@
- curl -L -s "$download_url/$version/$archive_name" | untar
+ curl -fL -s "$download_url/$version/$archive_name" | untar || err "Unable to download $archive_name"Also applies to: 186-189
🤖 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 `@install.sh` around lines 35 - 39, The untar function prints success
regardless of failures; update untar (and the similar block at lines 186-189) to
fail-fast by checking the exit status of the tar (and any curl/download)
command(s). Specifically, after running tar (and after any curl/download),
inspect the exit code and if non-zero log an error and exit non‑zero rather than
continuing to chmod/print success; ensure you only print the "Extracting
release..."/success message after a successful extraction. Target the untar
function name (and the other extract/download block) when making the change.
| if test -z "$version"; then | ||
| version="$(latest_tag)" | ||
| fi |
There was a problem hiding this comment.
Validate resolved release version before continuing.
If latest_tag returns empty (API failure/rate limit), the script proceeds with an invalid URL. Add a non-empty check and error out early.
🤖 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 `@install.sh` around lines 136 - 138, After resolving version with latest_tag
into the variable version, validate that version is non-empty and exit with a
clear error if it is empty; update the install.sh block that calls latest_tag
(and any code that uses the version variable) to check [ -z "$version" ] (or
equivalent) after assignment and call echo to stderr and exit 1 to avoid
proceeding with an invalid URL.
4303e9b to
7b9129a
Compare
No description provided.