Skip to content

Add recipe to pin GitHub Actions to commit SHAs#169

Open
timtebeek wants to merge 14 commits intomainfrom
pin-actions-to-sha
Open

Add recipe to pin GitHub Actions to commit SHAs#169
timtebeek wants to merge 14 commits intomainfrom
pin-actions-to-sha

Conversation

@timtebeek
Copy link
Member

Summary

  • Adds PinGitHubActionsToSha recipe that replaces mutable tag/branch uses: references with immutable commit SHAs, complementing the existing UnpinnedActionsRecipe (which finds the problem) with an automated fix
  • Includes a bundled known-action-shas.json with 37 well-known action → SHA mappings (Codecov, Docker, AWS, Google, Gradle, GitHub official actions, etc.), with fallback to the GitHub API for any action not in the static map
  • pinOfficialActions option (default false) controls whether actions/* and github/* org actions are also pinned; original ref is preserved as an inline comment (e.g. uses: actions/checkout@b4ffde65... # v4)

Test plan

  • shouldPinThirdPartyActionFromStaticMap — verifies static map lookup and SHA substitution with comment
  • shouldNotPinOfficialActionsByDefault — no-op when pinOfficialActions = false
  • shouldPinOfficialActionsWhenOptedIn — pins actions/* when opted in
  • shouldPinGitHubOrgWhenOptedIn — pins github/* (e.g. codeql-action) when opted in
  • shouldNotModifyAlreadyPinnedAction — idempotent on already-SHA-pinned refs
  • shouldSkipLocalActions — ignores ./ refs
  • shouldSkipDockerReferences — ignores docker:// refs
  • shouldPinMultipleThirdPartyActions — pins multiple actions in one workflow
  • shouldIgnoreNonWorkflowFiles — only applies to .github/workflows/ files via IsGitHubActionsWorkflow
  • shouldPinActionWithSubpath — handles owner/repo/subpath@ref correctly
  • shouldMixPinnedAndUnpinnedActions — mixed workflow with already-pinned, local, and unpinned actions

New recipe that replaces mutable tag/branch references in GitHub Actions
uses: declarations with immutable commit SHAs. Includes static SHA
mapping for common actions with GitHub API fallback, configurable
official action pinning, and comprehensive test coverage.
@github-project-automation github-project-automation bot moved this to In Progress in OpenRewrite Mar 26, 2026
@timtebeek timtebeek marked this pull request as draft March 26, 2026 22:13
All SHA mappings now live exclusively in known-action-shas.json.
If the resource cannot be loaded, return an empty map instead of
falling back to a duplicate in-code copy.
Runs weekly (Monday 06:00 UTC) and on manual dispatch. Scans the
repo's own workflow files for uses: references with tags/branches,
resolves each to a commit SHA via the GitHub API, and appends any
new entries to known-action-shas.json (existing entries are never
modified or removed). Opens a PR with the new mappings listed.
- Replace Set.of() with Collections.unmodifiableSet(new HashSet<>(Arrays.asList()))
- Replace String.isBlank() with trim().isEmpty()
- Replace InputStream.readAllBytes() with a ByteArrayOutputStream read loop
- Remove withSuffix() call (not present on Yaml.Scalar); drop inline ref comment
- Update test expectations to match (no trailing # ref comment)
Add the missing recipe catalog entry for PinGitHubActionsToSha to fix
CI validation. Also apply minor style cleanups (static imports,
consistent test indentation).
Load known SHAs in getInitialValue() instead of a static field,
following the ScanningRecipe pattern for proper lifecycle management.
…anch refs

- Replace known-action-shas.json with known-action-shas.properties to
  drop the Jackson dependency from PinGitHubActionsToSha
- Expand from 38 to 88 well-known action mappings covering the most
  popular GitHub Actions across CI/CD, Docker, cloud providers, build
  tools, security scanning, and language setup
- Remove branch references (@master) since only tags are stable
- Parse GitHub API responses with a simple regex instead of Jackson
- Update the update-known-shas workflow for the new properties format
Move the action-to-SHA resolution logic from the GHA workflow inline
run into .github/scripts/update-known-shas.sh so it can be run
locally outside of GitHub Actions. The workflow now calls the script
and uses git diff to detect changes.
Resolve all major version tags (v1, v2, v3, ...) for every action in
the properties file, bringing the total from 88 to 232 entries. This
ensures the recipe can pin any major version reference without falling
back to the GitHub API.
@timtebeek timtebeek marked this pull request as ready for review March 27, 2026 10:36
The script now checks all existing entries against the GitHub API and
updates any whose floating tags (e.g. v4) have moved to a new commit.
The workflow PR body distinguishes between updated and newly added entries.
Explains what the file contains, how to add new actions, and that
header comments are preserved across regeneration by the update script.
Expand the update script to resolve all version tags (v1, v1.2, v1.2.3)
for every action, not just major versions. Patch and minor versions are
more likely to be pinned to a stable SHA. Also fix bash 3.2 compat by
replacing mapfile with a while-read loop.

Grows the properties file from 232 to 4057 entries.
Minor and patch version tags (v1.2, v1.2.3) are immutable, so skip
them during drift detection. Only major version tags (v1, v2) can
float to new commits. Also update the properties file header comment
to accurately describe this behavior.
Expand the known-action-shas.properties from ~230 to ~9,400 entries
covering popular actions across CI/build, security, deployment, Docker,
GitHub/PR, linting, notifications, infrastructure, and utility
categories. Each action includes all major, minor, and patch version
tags.

Also add a SEED_ACTIONS list to the update script so these actions are
always expanded on future runs, even if not referenced in local
workflow files. 24 actions hit GitHub API rate limits and will be
resolved on the next run.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: In Progress

Development

Successfully merging this pull request may close these issues.

1 participant