@@ -24,12 +24,15 @@ func PinActions(inputYaml string, exemptedActions []string, pinToImmutable bool)
24
24
25
25
out := inputYaml
26
26
27
+ // get immutable map for the semantic versions of the actions present in the workflow
28
+ immutableMap := getSemanticActionsImmutableMap (workflow , pinToImmutable )
29
+
27
30
for _ , job := range workflow .Jobs {
28
31
29
32
for _ , step := range job .Steps {
30
33
if len (step .Uses ) > 0 {
31
34
localUpdated := false
32
- out , localUpdated = PinAction (step .Uses , out , exemptedActions , pinToImmutable )
35
+ out , localUpdated = PinAction (step .Uses , out , exemptedActions , immutableMap )
33
36
updated = updated || localUpdated
34
37
}
35
38
}
@@ -38,14 +41,15 @@ func PinActions(inputYaml string, exemptedActions []string, pinToImmutable bool)
38
41
return out , updated , nil
39
42
}
40
43
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 ) {
42
45
43
46
updated := false
44
47
if ! strings .Contains (action , "@" ) || strings .HasPrefix (action , "docker://" ) {
45
48
return inputYaml , updated // Cannot pin local actions and docker actions
46
49
}
47
50
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 ] {
49
53
return inputYaml , updated
50
54
}
51
55
leftOfAt := strings .Split (action , "@" )
@@ -84,7 +88,8 @@ func PinAction(action, inputYaml string, exemptedActions []string, pinToImmutabl
84
88
85
89
// if the action with version is immutable, then pin the action with version instead of sha
86
90
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 ] {
88
93
pinnedAction = pinnedActionWithVersion
89
94
}
90
95
@@ -211,3 +216,59 @@ func ActionExists(actionName string, patterns []string) bool {
211
216
}
212
217
return false
213
218
}
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