@@ -24,12 +24,15 @@ func PinActions(inputYaml string, exemptedActions []string, pinToImmutable bool)
2424
2525 out := inputYaml
2626
27+ // get immutable map for the semantic versions of the actions present in the workflow
28+ immutableMap := getSemanticActionsImmutableMap (workflow , pinToImmutable )
29+
2730 for _ , job := range workflow .Jobs {
2831
2932 for _ , step := range job .Steps {
3033 if len (step .Uses ) > 0 {
3134 localUpdated := false
32- out , localUpdated = PinAction (step .Uses , out , exemptedActions , pinToImmutable )
35+ out , localUpdated = PinAction (step .Uses , out , exemptedActions , immutableMap )
3336 updated = updated || localUpdated
3437 }
3538 }
@@ -38,14 +41,15 @@ func PinActions(inputYaml string, exemptedActions []string, pinToImmutable bool)
3841 return out , updated , nil
3942}
4043
41- func PinAction (action , inputYaml string , exemptedActions []string , pinToImmutable bool ) (string , bool ) {
44+ func PinAction (action , inputYaml string , exemptedActions []string , immutableMap map [ string ] bool ) (string , bool ) {
4245
4346 updated := false
4447 if ! strings .Contains (action , "@" ) || strings .HasPrefix (action , "docker://" ) {
4548 return inputYaml , updated // Cannot pin local actions and docker actions
4649 }
4750
48- if isAbsolute (action ) || (pinToImmutable && IsImmutableAction (action )) {
51+ // if already semantic than the action must be present in immutableMap
52+ if isAbsolute (action ) || immutableMap [action ] {
4953 return inputYaml , updated
5054 }
5155 leftOfAt := strings .Split (action , "@" )
@@ -84,7 +88,8 @@ func PinAction(action, inputYaml string, exemptedActions []string, pinToImmutabl
8488
8589 // if the action with version is immutable, then pin the action with version instead of sha
8690 pinnedActionWithVersion := fmt .Sprintf ("%s@%s" , leftOfAt [0 ], tagOrBranch )
87- if pinToImmutable && semanticTagRegex .MatchString (tagOrBranch ) && IsImmutableAction (pinnedActionWithVersion ) {
91+ // if found update pinned action with immutable pinned version
92+ if semanticTagRegex .MatchString (tagOrBranch ) && immutableMap [pinnedActionWithVersion ] {
8893 pinnedAction = pinnedActionWithVersion
8994 }
9095
@@ -211,3 +216,59 @@ func ActionExists(actionName string, patterns []string) bool {
211216 }
212217 return false
213218}
219+
220+ func getSemanticActionsImmutableMap (workflow metadata.Workflow , pinToImmutable bool ) map [string ]bool {
221+ var allActions []string
222+ var allSemanticActions []string
223+ immutableMap := make (map [string ]bool )
224+
225+ // return if pinToImmutable is set to false
226+ if ! pinToImmutable {
227+ return immutableMap
228+ }
229+
230+ // get all jobs present in the workflow
231+ for _ , job := range workflow .Jobs {
232+ for _ , step := range job .Steps {
233+ if strings .Contains (step .Uses , "@" ) && ! strings .HasPrefix (step .Uses , "docker://" ) && ! isAbsolute (step .Uses ) {
234+ allActions = append (allActions , step .Uses )
235+ }
236+ }
237+ }
238+
239+ PAT := os .Getenv ("PAT" )
240+
241+ ctx := context .Background ()
242+ ts := oauth2 .StaticTokenSource (
243+ & oauth2.Token {AccessToken : PAT },
244+ )
245+ tc := oauth2 .NewClient (ctx , ts )
246+
247+ client := github .NewClient (tc )
248+
249+ // get corresponding semantic actions for the actions present in the workflow
250+ for _ , action := range allActions {
251+ leftOfAt := strings .Split (action , "@" )
252+ tagOrBranch := leftOfAt [1 ]
253+
254+ splitOnSlash := strings .Split (leftOfAt [0 ], "/" )
255+ owner := splitOnSlash [0 ]
256+ repo := splitOnSlash [1 ]
257+
258+ commitSHA , _ , err := client .Repositories .GetCommitSHA1 (ctx , owner , repo , tagOrBranch , "" )
259+ if err != nil {
260+ return immutableMap
261+ }
262+
263+ tagOrBranch , err = getSemanticVersion (client , owner , repo , tagOrBranch , commitSHA )
264+ if err != nil {
265+ return immutableMap
266+ }
267+
268+ pinnedActionWithSemanticVersion := fmt .Sprintf ("%s@%s" , leftOfAt [0 ], tagOrBranch )
269+
270+ allSemanticActions = append (allSemanticActions , pinnedActionWithSemanticVersion )
271+ }
272+
273+ return IsImmutableActionConcurrently (allSemanticActions )
274+ }
0 commit comments