Skip to content

ci(security): SHA-pin GitHub Actions in publish.yml (SEC-06) - #3

Merged
wisdommen merged 1 commit into
masterfrom
feature/sha-pin-publish-yml
Jun 11, 2026
Merged

ci(security): SHA-pin GitHub Actions in publish.yml (SEC-06)#3
wisdommen merged 1 commit into
masterfrom
feature/sha-pin-publish-yml

Conversation

@wisdommen

@wisdommen wisdommen commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Summary

SHA-pins the three actions/*@v4 GitHub Actions references in .github/workflows/publish.yml to immutable commit SHAs. This is a uses:-SHA-value-only change — no version bump (v4 stays v4), and no on:/trigger, if:, with:, env:, needs:, or job-logic change.

Mapped pins (26-02 §2c):

  • actions/checkout@v4actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 (v4.3.1)
  • actions/setup-java@v4actions/setup-java@c1e323688fd81a25caa38c78aa6df2d33d3e20d9 # v4 (v4.8.0)
  • actions/setup-node@v4actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 (v4.4.0)

No-release proof (C1–C6, Archetype C) — UltiRecipe

  • C1 — Diff is SHA-value-only (asserted invariant). The candidate diff MUST change only the SHA token on the three mapped uses: lines re-confirmed @v4 on origin/master this plan — L22 actions/checkout@v4, L27 actions/setup-java@v4, L94 actions/setup-node@v4 — plus an optional trailing # v4 (vX.Y.Z) comment, pasting the 26-02 §2c pin strings verbatim. It MUST add/remove/modify no on:/trigger, no if:, no with:, no env:, no needs:, and no step ordering or job logic. (Re-verified against git diff origin/master in Task 3, gated behind the Task 2 token.)
  • C2 — Trigger model (leg a). on: push: branches: [master] (with paths-ignore for **.md, .gitignore, LICENSE) + workflow_dispatch (optional version input). Neither event is produced by the pin edit itself: a SHA-pin commit on a feature branch targeting master via PR does not trigger the push: branches: [master] path until merge, and at merge the existing-version guard (C5) intercepts before any publish step. No pull_request trigger (26-01 §0). UltiRecipe's publish.yml is byte-identical to UltiMenu's (shared sha256), so the trigger block is the same.
  • C3 — Guard (leg b). Single job release-and-publish (contents: write). Step check (Check if release exists, ~L48–58) runs gh release view "v${VERSION}"EXISTS=true|false. Every subsequent publish step (Generate changelog, Set project version, Build, Create GitHub Release, Set up Node.js, Install UltiKits CLI, Publish to UltiCloud) is gated if: steps.check.outputs.EXISTS == 'false'.
  • C4 — Diff-reachability = unreachable-to-publish (leg c). Because C1 holds, the trigger (C2) and the EXISTS guard (C3/C5) are byte-identical pre/post pin. The set of conditions under which any publish step runs is therefore unchanged. The pin cannot alter pom.xml <version> nor the release state, so it cannot flip EXISTS.
  • C5 — Existing-version guard (Archetype C, D-04). Read-only evidence captured 2026-06-11:
    • ${VERSION} = 1.0.0 (from git show origin/master:pom.xml <version>, read-only — no Maven build).
    • gh release view "v1.0.0" --repo UltiKits/UltiRecipe → exit 0; payload {"createdAt":"2026-02-15T00:51:56Z","isDraft":false,"isPrerelease":false,"name":"v1.0.0","tagName":"v1.0.0"}.
    • EXISTS=true — release v1.0.0 is published (not draft, not prerelease). The EXISTS=true branch short-circuits every publish step unconditionally; a SHA-only pin on a feature branch cannot flip EXISTS.
  • C6 — Verdict. PASS — config-only pin, unreachable-to-publish. Master base ref 5ce6163e89bf7ad43d59079d543b083b21f3c2e1; publish.yml master sha256 36728f8498b903237d1fdb3ee4d84c5e8f0cd6c3e6a3254f0a743d70f0d85998 (pre == post).

Merge boundary

Do NOT merge until the maintainer supplies the per-PR merge token (approve 28-01-merge) with the proof recorded PASS and CI confirming no release/tag/publish fired. publish.yml triggers on push: branches: [master] + workflow_dispatch — neither fires on this feature-branch PR; the existing-version guard short-circuits at merge anyway.

Summary by CodeRabbit

  • Chores
    • Updated internal CI/CD workflow configurations for improved security and stability.

@coderabbitai

coderabbitai Bot commented Jun 11, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The publish workflow is updated to pin GitHub Actions setup steps to specific commit SHAs instead of version tags. actions/checkout and actions/setup-java are pinned in one step block, and actions/setup-node is pinned separately, with version annotations preserved in comments.

Changes

Workflow Action Pinning

Layer / File(s) Summary
Pin GitHub Actions to commit SHAs
.github/workflows/publish.yml
actions/checkout, actions/setup-java, and actions/setup-node are changed from tag-based @v4 references to commit-hash pinned versions, with v4 version notes retained in inline comments.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐰 A rabbit checked and java set,
No tags, just hashes—safety net!
Node pinned down with SHA so true,
Supply chain hardened, shiny new.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the main change: SHA-pinning GitHub Actions in the publish.yml workflow file for security purposes, with an issue reference.
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.

✏️ 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 feature/sha-pin-publish-yml

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/publish.yml:
- Around line 22-24: The checkout step currently uses actions/checkout and
leaves the workflow token persisted; update the checkout step (the
actions/checkout@... usage) to include persist-credentials: false to prevent the
workflow token from being written to local git config and reduce token exposure
in downstream steps/artifacts.
🪄 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

Run ID: 1833848c-c7de-4100-b337-9819be19a0f5

📥 Commits

Reviewing files that changed from the base of the PR and between a04d69f and 642593e.

📒 Files selected for processing (1)
  • .github/workflows/publish.yml

Comment on lines +22 to 24
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 (v4.3.1)
with:
fetch-depth: 0

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Disable credential persistence in checkout step.

actions/checkout persists the workflow token in local git config by default. Set persist-credentials: false to reduce token exposure risk in downstream steps/artifacts.

Suggested patch
       - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5  # v4 (v4.3.1)
         with:
           fetch-depth: 0
+          persist-credentials: false
📝 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.

Suggested change
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 (v4.3.1)
with:
fetch-depth: 0
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 (v4.3.1)
with:
fetch-depth: 0
persist-credentials: false
🧰 Tools
🪛 zizmor (1.25.2)

[warning] 22-24: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)

🤖 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/publish.yml around lines 22 - 24, The checkout step
currently uses actions/checkout and leaves the workflow token persisted; update
the checkout step (the actions/checkout@... usage) to include
persist-credentials: false to prevent the workflow token from being written to
local git config and reduce token exposure in downstream steps/artifacts.

Source: Linters/SAST tools

@wisdommen
wisdommen merged commit f53f11e into master Jun 11, 2026
7 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.

1 participant