Add recipe to pin GitHub Actions to commit SHAs#169
Open
Conversation
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.
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.
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
PinGitHubActionsToSharecipe that replaces mutable tag/branchuses:references with immutable commit SHAs, complementing the existingUnpinnedActionsRecipe(which finds the problem) with an automated fixknown-action-shas.jsonwith 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 mappinOfficialActionsoption (defaultfalse) controls whetheractions/*andgithub/*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 commentshouldNotPinOfficialActionsByDefault— no-op whenpinOfficialActions = falseshouldPinOfficialActionsWhenOptedIn— pinsactions/*when opted inshouldPinGitHubOrgWhenOptedIn— pinsgithub/*(e.g.codeql-action) when opted inshouldNotModifyAlreadyPinnedAction— idempotent on already-SHA-pinned refsshouldSkipLocalActions— ignores./refsshouldSkipDockerReferences— ignoresdocker://refsshouldPinMultipleThirdPartyActions— pins multiple actions in one workflowshouldIgnoreNonWorkflowFiles— only applies to.github/workflows/files viaIsGitHubActionsWorkflowshouldPinActionWithSubpath— handlesowner/repo/subpath@refcorrectlyshouldMixPinnedAndUnpinnedActions— mixed workflow with already-pinned, local, and unpinned actions