1
1
import * as core from '@actions/core'
2
+ import * as jose from 'jose'
3
+ import nock from 'nock'
2
4
import * as main from '../src/main'
3
5
4
- // Mock the GitHub Actions core library
5
- jest . mock ( '@actions/core' )
6
+ // Mock the GitHub Actions core library functions
6
7
const setOutputMock = jest . spyOn ( core , 'setOutput' )
7
8
const setFailedMock = jest . spyOn ( core , 'setFailed' )
8
9
@@ -11,50 +12,76 @@ setFailedMock.mockImplementation(() => {})
11
12
12
13
describe ( 'main' , ( ) => {
13
14
let outputs = { } as Record < string , string >
15
+ const originalEnv = process . env
16
+ const issuer = 'https://token.actions.githubusercontent.com'
17
+ const audience = 'nobody'
18
+ const jwksPath = '/.well-known/jwks.json'
19
+ const tokenPath = '/token'
14
20
15
- beforeEach ( ( ) => {
21
+ const claims = {
22
+ iss : issuer ,
23
+ aud : 'nobody' ,
24
+ repository : 'owner/repo' ,
25
+ ref : 'refs/heads/main' ,
26
+ sha : 'babca52ab0c93ae16539e5923cb0d7403b9a093b' ,
27
+ workflow_ref : 'owner/repo/.github/workflows/main.yml@main' ,
28
+ event_name : 'push' ,
29
+ repository_id : 'repo-id' ,
30
+ repository_owner_id : 'owner-id' ,
31
+ run_id : 'run-id' ,
32
+ run_attempt : 'run-attempt' ,
33
+ runner_environment : 'github-hosted'
34
+ }
35
+
36
+ beforeEach ( async ( ) => {
16
37
jest . resetAllMocks ( )
38
+
17
39
setOutputMock . mockImplementation ( ( key , value ) => {
18
40
outputs [ key ] = value
19
41
} )
42
+
43
+ process . env = {
44
+ ...originalEnv ,
45
+ ACTIONS_ID_TOKEN_REQUEST_URL : `${ issuer } ${ tokenPath } ?` ,
46
+ ACTIONS_ID_TOKEN_REQUEST_TOKEN : 'token' ,
47
+ GITHUB_SERVER_URL : 'https://github.com' ,
48
+ GITHUB_REPOSITORY : claims . repository
49
+ }
50
+
51
+ // Generate JWT signing key
52
+ const key = await jose . generateKeyPair ( 'PS256' )
53
+
54
+ // Create JWK, JWKS, and JWT
55
+ const kid = '12345'
56
+ const jwk = await jose . exportJWK ( key . publicKey )
57
+ const jwks = { keys : [ { ...jwk , kid } ] }
58
+ const jwt = await new jose . SignJWT ( claims )
59
+ . setProtectedHeader ( { alg : 'PS256' , kid } )
60
+ . sign ( key . privateKey )
61
+
62
+ // Mock OpenID configuration and JWKS endpoints
63
+ nock ( issuer )
64
+ . get ( '/.well-known/openid-configuration' )
65
+ . reply ( 200 , { jwks_uri : `${ issuer } ${ jwksPath } ` } )
66
+ nock ( issuer ) . get ( jwksPath ) . reply ( 200 , jwks )
67
+
68
+ // Mock OIDC token endpoint for populating the provenance
69
+ nock ( issuer ) . get ( tokenPath ) . query ( { audience } ) . reply ( 200 , { value : jwt } )
20
70
} )
21
71
22
72
afterEach ( ( ) => {
23
73
outputs = { }
74
+ process . env = originalEnv
24
75
} )
25
76
26
77
it ( 'successfully run main' , async ( ) => {
27
- const originalEnv = process . env
28
- process . env = {
29
- ...originalEnv ,
30
- GITHUB_REPOSITORY : 'owner/repo' ,
31
- GITHUB_REF : 'refs/heads/main' ,
32
- GITHUB_SHA : 'babca52ab0c93ae16539e5923cb0d7403b9a093b' ,
33
- GITHUB_WORKFLOW_REF : 'owner/repo/.github/workflows/main.yml@main' ,
34
- GITHUB_SERVER_URL : 'https://github.com' ,
35
- GITHUB_EVENT_NAME : 'push' ,
36
- GITHUB_REPOSITORY_ID : 'repo-id' ,
37
- GITHUB_REPOSITORY_OWNER_ID : 'owner-id' ,
38
- GITHUB_RUN_ID : 'run-id' ,
39
- GITHUB_RUN_ATTEMPT : 'run-attempt' ,
40
- RUNNER_ENVIRONMENT : 'github-hosted'
41
- }
42
-
43
78
// Run the main function
44
79
await main . run ( )
45
80
46
81
// Verify that outputs were set correctly
47
82
expect ( setOutputMock ) . toHaveBeenCalledTimes ( 2 )
48
83
49
- // Use the expected object in the test assertion
50
84
expect ( outputs [ 'predicate' ] ) . toMatchSnapshot ( )
51
-
52
- expect ( setOutputMock ) . toHaveBeenNthCalledWith (
53
- 2 ,
54
- 'predicate-type' ,
55
- 'https://slsa.dev/provenance/v1'
56
- )
57
-
58
- process . env = originalEnv
85
+ expect ( outputs [ 'predicate-type' ] ) . toBe ( 'https://slsa.dev/provenance/v1' )
59
86
} )
60
87
} )
0 commit comments