chore: pin GitHub Actions to immutable commit SHAs (FEPLAT-5068) - #51
chore: pin GitHub Actions to immutable commit SHAs (FEPLAT-5068)#51casper-phantom[bot] wants to merge 1 commit into
Conversation
Every action reference in the active workflows resolved through a mutable tag, so a moved tag or a compromised upstream could change executable CI code without any change landing in this repository. Each reference is now pinned to the 40-character commit SHA the tag resolved to at the time of the change, with the version retained as a trailing comment. All pinned actions are JavaScript actions with no nested `uses:`, so the pinned closure is complete and no recursive pinning is required. Closes FEPLAT-5068 Co-authored-by: casper-phantom[bot] <208212958+casper-phantom[bot]@users.noreply.github.com>
📝 WalkthroughWalkthroughChangesWorkflow action pinning
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
There was a problem hiding this comment.
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/android-ci.yml:
- Line 31: Update the workflow step using gradle/gradle-build-action to
gradle/actions/setup-gradle, preserving gradle-version: wrapper and
build-root-directory: example/android. Remove the action’s arguments
configuration and add a separate run step that executes the existing Gradle
command.
🪄 Autofix
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: 2204d7bc-57d4-453b-9f54-8a839078b62c
📒 Files selected for processing (7)
.github/workflows/android-ci.yml.github/workflows/detox.yml.github/workflows/ios-ci.yml.github/workflows/macos-ci.yml.github/workflows/release.yml.github/workflows/stale.yml.github/workflows/windows-ci.yml
| shell: bash | ||
| - name: Build Android test app | ||
| uses: gradle/gradle-build-action@v2 | ||
| uses: gradle/gradle-build-action@a8f75513eafdebd8141bd1cd4e30fcd194af8dfa # v2.12.0 |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -eu
file=".github/workflows/android-ci.yml"
printf '%s\n' "--- workflow context ---"
sed -n '1,100p' "$file"
printf '%s\n' "--- Gradle action references ---"
rg -n -C 3 'gradle/(gradle-build-action|actions)|setup-gradle|build-action' .github
printf '%s\n' "--- repository metadata ---"
if command -v gh >/dev/null 2>&1; then
gh api repos/gradle/gradle-build-action --jq '{archived,disabled,default_branch,updated_at}'
gh api repos/gradle/actions --jq '{archived,disabled,default_branch,updated_at}'
else
curl -fsSL https://api.github.com/repos/gradle/gradle-build-action | jq '{archived,disabled,default_branch,updated_at}'
curl -fsSL https://api.github.com/repos/gradle/actions | jq '{archived,disabled,default_branch,updated_at}'
fiRepository: phantom/react-native-webview
Length of output: 2171
🌐 Web query:
Gradle Build Action archived replacement gradle/actions/setup-gradle migration existing inputs
💡 Result:
The gradle/gradle-build-action has been officially archived and superseded by gradle/actions/setup-gradle [1][2]. This change is part of an effort to standardize Gradle's GitHub Actions, aligning them with other common actions like setup-java or setup-node [3]. Key migration details: 1. Replacement: Replace any instance of uses: gradle/gradle-build-action@v3 (or earlier) in your GitHub Actions workflow files with uses: gradle/actions/setup-gradle@v6 (or the latest available version) [3][4][1]. 2. Functionality: The two actions are functionally equivalent, and existing workflows using v3 of the old action will transparently delegate to the new setup-gradle action [1][5]. 3. Arguments Parameter Deprecation: The arguments parameter, previously used to execute Gradle builds directly within the action, is deprecated [3]. You should migrate away from this pattern by splitting your workflow step into two parts: - Step 1: Call setup-gradle to configure the environment. - Step 2: Use a standard run step (e.g., run:./gradlew build) to execute your build [3]. 4. Wrapper Validation: The setup-gradle action now automatically validates the Gradle Wrapper [4][6]. If you were using the standalone wrapper-validation action previously, it is likely no longer necessary [6][7]. For detailed documentation and advanced configuration, refer to the official gradle/actions repository [3][8].
Citations:
- 1: https://github.com/gradle/gradle-build-action?tab=readme-ov-file
- 2: https://github.com/gradle/gradle-build-action/blob/main/README.md
- 3: https://github.com/gradle/actions/blob/main/docs/deprecation-upgrade-guide.md
- 4: https://docs.gradle.org/current/userguide/github-actions.html
- 5: https://github.com/gradle/gradle-build-action/releases/tag/v3.5.0
- 6: https://github.com/marketplace/actions/build-with-gradle
- 7: https://github.com/actions/gradle-build-tools-actions
- 8: https://github.com/gradle/actions
🏁 Script executed:
#!/bin/bash
set -eu
tmpdir="$(mktemp -d)"
trap 'rm -rf "$tmpdir"' EXIT
curl -fsSL https://raw.githubusercontent.com/gradle/gradle-build-action/v2.12.0/action.yml \
-o "$tmpdir/old.yml"
curl -fsSL https://raw.githubusercontent.com/gradle/actions/v6/action.yml \
-o "$tmpdir/new.yml"
curl -fsSL https://raw.githubusercontent.com/gradle/actions/main/docs/deprecation-upgrade-guide.md \
-o "$tmpdir/guide.md"
python3 - "$tmpdir/old.yml" "$tmpdir/new.yml" "$tmpdir/guide.md" <<'PY'
import re, sys
from pathlib import Path
old, new, guide = map(Path, sys.argv[1:])
old_text, new_text, guide_text = old.read_text(), new.read_text(), guide.read_text()
def inputs(text):
block = text.split("inputs:", 1)[1] if "inputs:" in text else ""
return re.findall(r"(?m)^ ([A-Za-z0-9_-]+):\s*$", block)
print("old action inputs:", inputs(old_text))
print("new action inputs:", inputs(new_text))
for name in ("gradle-version", "arguments", "build-root-directory"):
print(f"{name}: old={'yes' if re.search(rf'(?m)^ {re.escape(name)}:\\s*$', old_text) else 'no'} "
f"new={'yes' if re.search(rf'(?m)^ {re.escape(name)}:\\s*$', new_text) else 'no'}")
for term in ("arguments", "build-root-directory", "gradle-version", "setup-gradle"):
hits = [line.strip() for line in guide_text.splitlines() if term in line]
print(f"guide {term}:", hits[:8])
PYRepository: phantom/react-native-webview
Length of output: 435
🏁 Script executed:
#!/bin/bash
set -eu
tmpdir="$(mktemp -d)"
trap 'rm -rf "$tmpdir"' EXIT
curl -fsSL https://raw.githubusercontent.com/gradle/gradle-build-action/v2.12.0/action.yml \
-o "$tmpdir/old.yml"
curl -fsSL https://raw.githubusercontent.com/gradle/actions/v6/action.yml \
-o "$tmpdir/new.yml"
curl -fsSL https://raw.githubusercontent.com/gradle/actions/main/docs/deprecation-upgrade-guide.md \
-o "$tmpdir/guide.md"
python3 - "$tmpdir/old.yml" "$tmpdir/new.yml" "$tmpdir/guide.md" <<'PY'
import re, sys
from pathlib import Path
old, new, guide = map(Path, sys.argv[1:])
old_text = old.read_text()
new_text = new.read_text()
guide_text = guide.read_text()
def inputs(text):
block = text.split("inputs:", 1)[1] if "inputs:" in text else ""
return re.findall(r"(?m)^ ([A-Za-z0-9_-]+):\s*$", block)
print("old action inputs:", inputs(old_text))
print("new action inputs:", inputs(new_text))
for name in ("gradle-version", "arguments", "build-root-directory"):
pattern = rf"(?m)^ {re.escape(name)}:\s*$"
old_has = bool(re.search(pattern, old_text))
new_has = bool(re.search(pattern, new_text))
print(f"{name}: old={'yes' if old_has else 'no'} new={'yes' if new_has else 'no'}")
for term in ("arguments", "build-root-directory", "gradle-version", "setup-gradle"):
hits = [line.strip() for line in guide_text.splitlines() if term in line]
print(f"guide {term}:", hits[:8])
PYRepository: phantom/react-native-webview
Length of output: 2182
Other (CWE-1104)
Reachability: External
Replace the archived Gradle action.
Replace gradle/gradle-build-action with gradle/actions/setup-gradle. Move the arguments command to a separate run step. Preserve gradle-version: wrapper and build-root-directory: example/android.
🧰 Tools
🪛 zizmor (1.29.0)
[warning] 31-31: action or reusable workflow from archived repository (archived-uses): repository is archived
(archived-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/android-ci.yml at line 31, Update the workflow step using
gradle/gradle-build-action to gradle/actions/setup-gradle, preserving
gradle-version: wrapper and build-root-directory: example/android. Remove the
action’s arguments configuration and add a separate run step that executes the
existing Gradle command.
Source: Linters/SAST tools
Closes FEPLAT-5068
Note
Low risk: Every SHA is the commit its tag already resolved to, so CI runs the same action code as before the change and no workflow logic, inputs, or versions were altered.
Summary
uses:, so the pinned closure is complete and no recursive or vendored pinning is needed.actions/stale@v3.0.14instale.yml, which the finding did not list but carries the same mutable-tag exposure.Pinned references
Each SHA is the commit the previous tag pointed to at the time of this change, verified against the upstream repository.
actions/checkoutv4->11d5960a326750d5838078e36cf38b85af677262(v4.4.0) - android-ci, detox, ios-ci, macos-ci, release, windows-ciactions/setup-nodev4->49933ea5288caeca8642d1e84afbd3f7d6820020(v4.4.0) - android-ci, detox, ios-ci, macos-ci, windows-ciactions/setup-nodev3->3235b876344d2a9aa001b8d1453c930bba69e610(v3.9.1) - releaseactions/setup-javav4->cf277c60eb25467037889841efdb72551f06f6c3(v4.9.1) - android-cigradle/gradle-build-actionv2->a8f75513eafdebd8141bd1cd4e30fcd194af8dfa(v2.12.0) - android-cimicrosoft/setup-msbuildv1.1.3->34cfbaee7f672c76950673338facd8a73f637506- windows-ciactions/stalev3.0.14->87c2b794b9b47a9bec68ae03c01aeb572ffebdb1- stalechangesets/actioninrelease.ymlwas already pinned and is unchanged.Verification
uses:reference in.github/workflows/resolves to anything other than a 40-character hex SHA.runs.usingand contains no nesteduses:, so there is no deeper mutable edge to pin. That matches the finding's "no recursive mutable references" conclusion.Follow-ups (deliberately not in this PR)
These are pre-existing and unchanged by pinning, but worth separate tickets:
actions/setup-node@v3inrelease.ymlis a major version behind the rest of the repo.gradle/gradle-build-actionis deprecated upstream in favor ofgradle/actions/setup-gradle.actions/stale@v3.0.14declares the long-retirednode12runtime.actions/setup-java@v4.9.1emits an upstream deprecation warning for v4..github/dependabot.ymlcovering thegithub-actionsecosystem, so these pins will not be refreshed automatically.casper-run-id: 019fd2d5-2366-7b72-8760-b5d0fc4bf411
Summary by CodeRabbit