Preserve SHA-pinned actions in ChangeAction/ChangeActionVersion via opt-in oldSha#199
Open
MBoegers wants to merge 1 commit into
Open
Preserve SHA-pinned actions in ChangeAction/ChangeActionVersion via opt-in oldSha#199MBoegers wants to merge 1 commit into
MBoegers wants to merge 1 commit into
Conversation
ChangeActionVersion and ChangeAction stripped deliberate commit-SHA pins when rewriting a `uses:` reference. Add an opt-in `oldSha` sentinel mirroring Docker ChangeFrom's `oldDigest`: - unset -> change regardless of ref (default, unchanged behavior) - "" -> change only non-SHA refs, preserving SHA pins (per-entry) - <sha> -> change only refs pinned to exactly that SHA The per-uses match/filter/rewrite logic is shared via a new ChangeUsesVisitor; SHA parsing and the sentinel live in UsesRefs. recipes.csv updated for the new option (two rows only). Refs: moderneinc/customer-requests#2594, openrewrite/rewrite#8110
timtebeek
reviewed
Jun 24, 2026
Comment on lines
26
to
+51
| @Option(displayName = "Action", | ||
| description = "Name of the action to match.", | ||
| example = "gradle/wrapper-validation-action") | ||
| String oldAction; | ||
|
|
||
| @Option(displayName = "Action", | ||
| description = "Name of the action to use instead.", | ||
| example = "gradle/actions/wrapper-validation") | ||
| String newAction; | ||
|
|
||
| @Option(displayName = "Version", | ||
| description = "New version to use.", | ||
| example = "v3") | ||
| String newVersion; | ||
|
|
||
| @Option(displayName = "Old commit SHA", | ||
| description = "Restricts the change by the existing `uses:` ref. When omitted, the " + | ||
| "action is changed regardless of how it is pinned (the default; commit SHA pins " + | ||
| "are rewritten). When set to an empty string, only references that are **not** " + | ||
| "pinned to a 40-character commit SHA are changed, leaving deliberate SHA pins on " + | ||
| "the original action untouched. When set to a specific commit SHA, only " + | ||
| "references pinned to exactly that SHA are changed.", | ||
| required = false, | ||
| example = "8f4b7f84864484a7bf31766abe9204da3cbe65b3") | ||
| @Nullable | ||
| String oldSha; |
Member
There was a problem hiding this comment.
I worry a bit about the order of the fields here becoming confusing, especially since they are all Stirngs.
Contributor
Author
There was a problem hiding this comment.
I wanted the new option to be last, this allows the recipe deal with it.
Agree the order could be better but if we rearrange, thanks to all stings, strange things can happen if you just append null
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.
What
ChangeActionVersionandChangeActionrewrite auses:reference. Today they also strip a deliberate commit-SHA pin (e.g.actions/checkout@8f4b7f84…→actions/checkout@v4), silently downgrading a workflow's supply-chain posture and potentially leaving a stale# vXcomment.This adds an opt-in, per-
uses:oldShaoption mirroring the DockerChangeFromoldDigestsentinel:oldSha""The filter is per-entry, so a workflow mixing SHA-pinned and tag-pinned steps upgrades only the tag-pinned ones.
How
UsesRefs— parses the ref from auses:value and implements theoldShasentinel (matchesOldSha).ChangeUsesVisitor— shared match → filter → rewrite visitor; the two recipes differ only by their value-transform lambda (ChangeActionVersionpreserves each entry's action path,ChangeActionsubstitutes the new action).JsonPathMatcher(the same mechanism the priorChangeValuedelegation used), so matching — including theactions/nested.*wildcard and job-leveluses:— is unchanged.recipes.csvupdated for the new option.Tests
Both recipes get the full matrix: skip SHA pin, skip SHA pin with
# vXcomment preserved, still-upgrade tag, per-entry mixed file, specific-SHA match, and a null-default regression guard. Existing tests unchanged.