@@ -278,6 +278,95 @@ func TestSecureWorkflow(t *testing.T) {
278278 }
279279}
280280
281+ func TestSecureWorkflowContainerJob (t * testing.T ) {
282+ const inputDirectory = "../../testfiles/secureworkflow/input"
283+ const outputDirectory = "../../testfiles/secureworkflow/output"
284+
285+ httpmock .Activate ()
286+ defer httpmock .DeactivateAndReset ()
287+
288+ // Mock APIs for actions/checkout
289+ httpmock .RegisterResponder ("GET" , "https://api.github.com/repos/actions/checkout/commits/v3" ,
290+ httpmock .NewStringResponder (200 , `c85c95e3d7251135ab7dc9ce3241c5835cc595a9` ))
291+
292+ httpmock .RegisterResponder ("GET" , "https://api.github.com/repos/actions/checkout/git/matching-refs/tags/v3." ,
293+ httpmock .NewStringResponder (200 ,
294+ `[
295+ {
296+ "ref": "refs/tags/v3.5.3",
297+ "object": {
298+ "sha": "c85c95e3d7251135ab7dc9ce3241c5835cc595a9",
299+ "type": "commit"
300+ }
301+ }
302+ ]` ),
303+ )
304+
305+ // Mock APIs for step-security/harden-runner
306+ httpmock .RegisterResponder ("GET" , "https://api.github.com/repos/step-security/harden-runner/commits/v2" ,
307+ httpmock .NewStringResponder (200 , `17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6` ))
308+
309+ httpmock .RegisterResponder ("GET" , "https://api.github.com/repos/step-security/harden-runner/git/matching-refs/tags/v2." ,
310+ httpmock .NewStringResponder (200 ,
311+ `[
312+ {
313+ "ref": "refs/tags/v2.8.1",
314+ "object": {
315+ "sha": "17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6",
316+ "type": "commit"
317+ }
318+ }
319+ ]` ),
320+ )
321+
322+ var err error
323+ var input []byte
324+ input , err = ioutil .ReadFile (path .Join (inputDirectory , "container-job.yml" ))
325+
326+ if err != nil {
327+ log .Fatal (err )
328+ }
329+
330+ os .Setenv ("KBFolder" , "../../knowledge-base/actions" )
331+
332+ // Test with skipHardenRunnerForContainers = true
333+ queryParams := make (map [string ]string )
334+ queryParams ["skipHardenRunnerForContainers" ] = "true"
335+ queryParams ["addProjectComment" ] = "false"
336+
337+ output , err := SecureWorkflow (queryParams , string (input ), & mockDynamoDBClient {})
338+
339+ if err != nil {
340+ t .Errorf ("Error not expected" )
341+ }
342+
343+ // Verify that harden runner was not added
344+ if output .AddedHardenRunner {
345+ t .Errorf ("Harden runner should not be added for container job with skipHardenRunnerForContainers=true" )
346+ }
347+
348+ // Verify that the output matches expected output file
349+ expectedOutput , err := ioutil .ReadFile (path .Join (outputDirectory , "container-job.yml" ))
350+ if err != nil {
351+ log .Fatal (err )
352+ }
353+
354+ if output .FinalOutput != string (expectedOutput ) {
355+ t .Errorf ("test failed container-job.yml did not match expected output\n Expected:\n %s\n \n Got:\n %s" ,
356+ string (expectedOutput ), output .FinalOutput )
357+ }
358+
359+ // Verify permissions were added
360+ if ! output .AddedPermissions {
361+ t .Errorf ("Permissions should be added even for container jobs" )
362+ }
363+
364+ // Verify actions were pinned
365+ if ! output .PinnedActions {
366+ t .Errorf ("Actions should be pinned even for container jobs" )
367+ }
368+ }
369+
281370func TestSecureWorkflowEmptyPermissions (t * testing.T ) {
282371 const inputDirectory = "../../testfiles/secureworkflow/input"
283372 const outputDirectory = "../../testfiles/secureworkflow/output"
0 commit comments