switch to actions-toolkit implementation
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
This commit is contained in:
		
							parent
							
								
									7944f9a25b
								
							
						
					
					
						commit
						d8823bfaed
					
				| @ -2,7 +2,7 @@ | ||||
|   "env": { | ||||
|     "node": true, | ||||
|     "es2021": true, | ||||
|     "jest/globals": true | ||||
|     "jest": true | ||||
|   }, | ||||
|   "extends": [ | ||||
|     "eslint:recommended", | ||||
|  | ||||
							
								
								
									
										4
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -1,10 +1,6 @@ | ||||
| node_modules | ||||
| lib | ||||
| 
 | ||||
| # Jetbrains | ||||
| /.idea | ||||
| /*.iml | ||||
| 
 | ||||
| # Rest of the file pulled from https://github.com/github/gitignore/blob/master/Node.gitignore | ||||
| # Logs | ||||
| logs | ||||
|  | ||||
							
								
								
									
										207
									
								
								__mocks__/@actions/github.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										207
									
								
								__mocks__/@actions/github.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,207 @@ | ||||
| import {jest} from '@jest/globals'; | ||||
| 
 | ||||
| export const context = { | ||||
|   repo: { | ||||
|     owner: 'docker', | ||||
|     repo: 'build-push-action' | ||||
|   }, | ||||
|   ref: 'refs/heads/master', | ||||
|   runId: 123456789, | ||||
|   payload: { | ||||
|     after: '860c1904a1ce19322e91ac35af1ab07466440c37', | ||||
|     base_ref: null, | ||||
|     before: '5f3331d7f7044c18ca9f12c77d961c4d7cf3276a', | ||||
|     commits: [ | ||||
|       { | ||||
|         author: { | ||||
|           email: 'crazy-max@users.noreply.github.com', | ||||
|           name: 'CrazyMax', | ||||
|           username: 'crazy-max' | ||||
|         }, | ||||
|         committer: { | ||||
|           email: 'crazy-max@users.noreply.github.com', | ||||
|           name: 'CrazyMax', | ||||
|           username: 'crazy-max' | ||||
|         }, | ||||
|         distinct: true, | ||||
|         id: '860c1904a1ce19322e91ac35af1ab07466440c37', | ||||
|         message: 'hello dev', | ||||
|         timestamp: '2022-04-19T11:27:24+02:00', | ||||
|         tree_id: 'd2c60af597e863787d2d27f569e30495b0b92820', | ||||
|         url: 'https://github.com/docker/test-docker-action/commit/860c1904a1ce19322e91ac35af1ab07466440c37' | ||||
|       } | ||||
|     ], | ||||
|     compare: 'https://github.com/docker/test-docker-action/compare/5f3331d7f704...860c1904a1ce', | ||||
|     created: false, | ||||
|     deleted: false, | ||||
|     forced: false, | ||||
|     head_commit: { | ||||
|       author: { | ||||
|         email: 'crazy-max@users.noreply.github.com', | ||||
|         name: 'CrazyMax', | ||||
|         username: 'crazy-max' | ||||
|       }, | ||||
|       committer: { | ||||
|         email: 'crazy-max@users.noreply.github.com', | ||||
|         name: 'CrazyMax', | ||||
|         username: 'crazy-max' | ||||
|       }, | ||||
|       distinct: true, | ||||
|       id: '860c1904a1ce19322e91ac35af1ab07466440c37', | ||||
|       message: 'hello dev', | ||||
|       timestamp: '2022-04-19T11:27:24+02:00', | ||||
|       tree_id: 'd2c60af597e863787d2d27f569e30495b0b92820', | ||||
|       url: 'https://github.com/docker/test-docker-action/commit/860c1904a1ce19322e91ac35af1ab07466440c37' | ||||
|     }, | ||||
|     organization: { | ||||
|       avatar_url: 'https://avatars.githubusercontent.com/u/5429470?v=4', | ||||
|       description: 'Docker helps developers bring their ideas to life by conquering the complexity of app development.', | ||||
|       events_url: 'https://api.github.com/orgs/docker/events', | ||||
|       hooks_url: 'https://api.github.com/orgs/docker/hooks', | ||||
|       id: 5429470, | ||||
|       issues_url: 'https://api.github.com/orgs/docker/issues', | ||||
|       login: 'docker', | ||||
|       members_url: 'https://api.github.com/orgs/docker/members{/member}', | ||||
|       node_id: 'MDEyOk9yZ2FuaXphdGlvbjU0Mjk0NzA=', | ||||
|       public_members_url: 'https://api.github.com/orgs/docker/public_members{/member}', | ||||
|       repos_url: 'https://api.github.com/orgs/docker/repos', | ||||
|       url: 'https://api.github.com/orgs/docker' | ||||
|     }, | ||||
|     pusher: { | ||||
|       email: 'github@crazymax.dev', | ||||
|       name: 'crazy-max' | ||||
|     }, | ||||
|     ref: 'refs/heads/dev', | ||||
|     repository: { | ||||
|       allow_forking: true, | ||||
|       archive_url: 'https://api.github.com/repos/docker/test-docker-action/{archive_format}{/ref}', | ||||
|       archived: false, | ||||
|       assignees_url: 'https://api.github.com/repos/docker/test-docker-action/assignees{/user}', | ||||
|       blobs_url: 'https://api.github.com/repos/docker/test-docker-action/git/blobs{/sha}', | ||||
|       branches_url: 'https://api.github.com/repos/docker/test-docker-action/branches{/branch}', | ||||
|       clone_url: 'https://github.com/docker/test-docker-action.git', | ||||
|       collaborators_url: 'https://api.github.com/repos/docker/test-docker-action/collaborators{/collaborator}', | ||||
|       comments_url: 'https://api.github.com/repos/docker/test-docker-action/comments{/number}', | ||||
|       commits_url: 'https://api.github.com/repos/docker/test-docker-action/commits{/sha}', | ||||
|       compare_url: 'https://api.github.com/repos/docker/test-docker-action/compare/{base}...{head}', | ||||
|       contents_url: 'https://api.github.com/repos/docker/test-docker-action/contents/{+path}', | ||||
|       contributors_url: 'https://api.github.com/repos/docker/test-docker-action/contributors', | ||||
|       created_at: 1596792180, | ||||
|       default_branch: 'master', | ||||
|       deployments_url: 'https://api.github.com/repos/docker/test-docker-action/deployments', | ||||
|       description: 'Test "Docker" Actions', | ||||
|       disabled: false, | ||||
|       downloads_url: 'https://api.github.com/repos/docker/test-docker-action/downloads', | ||||
|       events_url: 'https://api.github.com/repos/docker/test-docker-action/events', | ||||
|       fork: false, | ||||
|       forks: 1, | ||||
|       forks_count: 1, | ||||
|       forks_url: 'https://api.github.com/repos/docker/test-docker-action/forks', | ||||
|       full_name: 'docker/test-docker-action', | ||||
|       git_commits_url: 'https://api.github.com/repos/docker/test-docker-action/git/commits{/sha}', | ||||
|       git_refs_url: 'https://api.github.com/repos/docker/test-docker-action/git/refs{/sha}', | ||||
|       git_tags_url: 'https://api.github.com/repos/docker/test-docker-action/git/tags{/sha}', | ||||
|       git_url: 'git://github.com/docker/test-docker-action.git', | ||||
|       has_downloads: true, | ||||
|       has_issues: true, | ||||
|       has_pages: false, | ||||
|       has_projects: true, | ||||
|       has_wiki: true, | ||||
|       homepage: '', | ||||
|       hooks_url: 'https://api.github.com/repos/docker/test-docker-action/hooks', | ||||
|       html_url: 'https://github.com/docker/test-docker-action', | ||||
|       id: 285789493, | ||||
|       is_template: false, | ||||
|       issue_comment_url: 'https://api.github.com/repos/docker/test-docker-action/issues/comments{/number}', | ||||
|       issue_events_url: 'https://api.github.com/repos/docker/test-docker-action/issues/events{/number}', | ||||
|       issues_url: 'https://api.github.com/repos/docker/test-docker-action/issues{/number}', | ||||
|       keys_url: 'https://api.github.com/repos/docker/test-docker-action/keys{/key_id}', | ||||
|       labels_url: 'https://api.github.com/repos/docker/test-docker-action/labels{/name}', | ||||
|       language: 'JavaScript', | ||||
|       languages_url: 'https://api.github.com/repos/docker/test-docker-action/languages', | ||||
|       license: { | ||||
|         key: 'mit', | ||||
|         name: 'MIT License', | ||||
|         node_id: 'MDc6TGljZW5zZTEz', | ||||
|         spdx_id: 'MIT', | ||||
|         url: 'https://api.github.com/licenses/mit' | ||||
|       }, | ||||
|       master_branch: 'master', | ||||
|       merges_url: 'https://api.github.com/repos/docker/test-docker-action/merges', | ||||
|       milestones_url: 'https://api.github.com/repos/docker/test-docker-action/milestones{/number}', | ||||
|       mirror_url: null, | ||||
|       name: 'test-docker-action', | ||||
|       node_id: 'MDEwOlJlcG9zaXRvcnkyODU3ODk0OTM=', | ||||
|       notifications_url: 'https://api.github.com/repos/docker/test-docker-action/notifications{?since,all,participating}', | ||||
|       open_issues: 6, | ||||
|       open_issues_count: 6, | ||||
|       organization: 'docker', | ||||
|       owner: { | ||||
|         avatar_url: 'https://avatars.githubusercontent.com/u/5429470?v=4', | ||||
|         email: 'info@docker.com', | ||||
|         events_url: 'https://api.github.com/users/docker/events{/privacy}', | ||||
|         followers_url: 'https://api.github.com/users/docker/followers', | ||||
|         following_url: 'https://api.github.com/users/docker/following{/other_user}', | ||||
|         gists_url: 'https://api.github.com/users/docker/gists{/gist_id}', | ||||
|         gravatar_id: '', | ||||
|         html_url: 'https://github.com/docker', | ||||
|         id: 5429470, | ||||
|         login: 'docker', | ||||
|         name: 'docker', | ||||
|         node_id: 'MDEyOk9yZ2FuaXphdGlvbjU0Mjk0NzA=', | ||||
|         organizations_url: 'https://api.github.com/users/docker/orgs', | ||||
|         received_events_url: 'https://api.github.com/users/docker/received_events', | ||||
|         repos_url: 'https://api.github.com/users/docker/repos', | ||||
|         site_admin: false, | ||||
|         starred_url: 'https://api.github.com/users/docker/starred{/owner}{/repo}', | ||||
|         subscriptions_url: 'https://api.github.com/users/docker/subscriptions', | ||||
|         type: 'Organization', | ||||
|         url: 'https://api.github.com/users/docker' | ||||
|       }, | ||||
|       private: true, | ||||
|       pulls_url: 'https://api.github.com/repos/docker/test-docker-action/pulls{/number}', | ||||
|       pushed_at: 1650360446, | ||||
|       releases_url: 'https://api.github.com/repos/docker/test-docker-action/releases{/id}', | ||||
|       size: 796, | ||||
|       ssh_url: 'git@github.com:docker/test-docker-action.git', | ||||
|       stargazers: 0, | ||||
|       stargazers_count: 0, | ||||
|       stargazers_url: 'https://api.github.com/repos/docker/test-docker-action/stargazers', | ||||
|       statuses_url: 'https://api.github.com/repos/docker/test-docker-action/statuses/{sha}', | ||||
|       subscribers_url: 'https://api.github.com/repos/docker/test-docker-action/subscribers', | ||||
|       subscription_url: 'https://api.github.com/repos/docker/test-docker-action/subscription', | ||||
|       svn_url: 'https://github.com/docker/test-docker-action', | ||||
|       tags_url: 'https://api.github.com/repos/docker/test-docker-action/tags', | ||||
|       teams_url: 'https://api.github.com/repos/docker/test-docker-action/teams', | ||||
|       topics: [], | ||||
|       trees_url: 'https://api.github.com/repos/docker/test-docker-action/git/trees{/sha}', | ||||
|       updated_at: '2022-04-19T09:05:09Z', | ||||
|       url: 'https://github.com/docker/test-docker-action', | ||||
|       visibility: 'private', | ||||
|       watchers: 0, | ||||
|       watchers_count: 0 | ||||
|     }, | ||||
|     sender: { | ||||
|       avatar_url: 'https://avatars.githubusercontent.com/u/1951866?v=4', | ||||
|       events_url: 'https://api.github.com/users/crazy-max/events{/privacy}', | ||||
|       followers_url: 'https://api.github.com/users/crazy-max/followers', | ||||
|       following_url: 'https://api.github.com/users/crazy-max/following{/other_user}', | ||||
|       gists_url: 'https://api.github.com/users/crazy-max/gists{/gist_id}', | ||||
|       gravatar_id: '', | ||||
|       html_url: 'https://github.com/crazy-max', | ||||
|       id: 1951866, | ||||
|       login: 'crazy-max', | ||||
|       node_id: 'MDQ6VXNlcjE5NTE4NjY=', | ||||
|       organizations_url: 'https://api.github.com/users/crazy-max/orgs', | ||||
|       received_events_url: 'https://api.github.com/users/crazy-max/received_events', | ||||
|       repos_url: 'https://api.github.com/users/crazy-max/repos', | ||||
|       site_admin: false, | ||||
|       starred_url: 'https://api.github.com/users/crazy-max/starred{/owner}{/repo}', | ||||
|       subscriptions_url: 'https://api.github.com/users/crazy-max/subscriptions', | ||||
|       type: 'User', | ||||
|       url: 'https://api.github.com/users/crazy-max' | ||||
|     } | ||||
|   } | ||||
| }; | ||||
| 
 | ||||
| export const getOctokit = jest.fn(); | ||||
| @ -1,146 +0,0 @@ | ||||
| import {describe, expect, it, jest, test} from '@jest/globals'; | ||||
| import * as fs from 'fs'; | ||||
| import * as path from 'path'; | ||||
| import * as semver from 'semver'; | ||||
| import * as exec from '@actions/exec'; | ||||
| import * as buildx from '../src/buildx'; | ||||
| import * as context from '../src/context'; | ||||
| 
 | ||||
| const tmpNameSync = path.join('/tmp/.docker-build-push-jest', '.tmpname-jest').split(path.sep).join(path.posix.sep); | ||||
| const imageID = 'sha256:bfb45ab72e46908183546477a08f8867fc40cebadd00af54b071b097aed127a9'; | ||||
| const metadata = `{
 | ||||
|   "containerimage.config.digest": "sha256:059b68a595b22564a1cbc167af369349fdc2ecc1f7bc092c2235cbf601a795fd", | ||||
|   "containerimage.digest": "sha256:b09b9482c72371486bb2c1d2c2a2633ed1d0b8389e12c8d52b9e052725c0c83c" | ||||
| }`;
 | ||||
| 
 | ||||
| jest.spyOn(context, 'tmpDir').mockImplementation((): string => { | ||||
|   const tmpDir = path.join('/tmp/.docker-build-push-jest').split(path.sep).join(path.posix.sep); | ||||
|   if (!fs.existsSync(tmpDir)) { | ||||
|     fs.mkdirSync(tmpDir, {recursive: true}); | ||||
|   } | ||||
|   return tmpDir; | ||||
| }); | ||||
| 
 | ||||
| jest.spyOn(context, 'tmpNameSync').mockImplementation((): string => { | ||||
|   return tmpNameSync; | ||||
| }); | ||||
| 
 | ||||
| describe('getImageID', () => { | ||||
|   it('matches', async () => { | ||||
|     const imageIDFile = await buildx.getImageIDFile(); | ||||
|     await fs.writeFileSync(imageIDFile, imageID); | ||||
|     const expected = await buildx.getImageID(); | ||||
|     expect(expected).toEqual(imageID); | ||||
|   }); | ||||
| }); | ||||
| 
 | ||||
| describe('getMetadata', () => { | ||||
|   it('matches', async () => { | ||||
|     const metadataFile = await buildx.getMetadataFile(); | ||||
|     await fs.writeFileSync(metadataFile, metadata); | ||||
|     const expected = await buildx.getMetadata(); | ||||
|     expect(expected).toEqual(metadata); | ||||
|   }); | ||||
| }); | ||||
| 
 | ||||
| describe('getDigest', () => { | ||||
|   it('matches', async () => { | ||||
|     const metadataFile = await buildx.getMetadataFile(); | ||||
|     await fs.writeFileSync(metadataFile, metadata); | ||||
|     const expected = await buildx.getDigest(metadata); | ||||
|     expect(expected).toEqual('sha256:b09b9482c72371486bb2c1d2c2a2633ed1d0b8389e12c8d52b9e052725c0c83c'); | ||||
|   }); | ||||
| }); | ||||
| 
 | ||||
| describe('isLocalOrTarExporter', () => { | ||||
|   test.each([ | ||||
|     [['type=registry,ref=user/app'], false], | ||||
|     [['type=docker'], false], | ||||
|     [['type=local,dest=./release-out'], true], | ||||
|     [['type=tar,dest=/tmp/image.tar'], true], | ||||
|     [['type=docker', 'type=tar,dest=/tmp/image.tar'], true], | ||||
|     [['"type=tar","dest=/tmp/image.tar"'], true], | ||||
|     [['" type= local" , dest=./release-out'], true], | ||||
|     [['.'], true] | ||||
|   ])('given %p returns %p', async (outputs: Array<string>, expected: boolean) => { | ||||
|     expect(buildx.isLocalOrTarExporter(outputs)).toEqual(expected); | ||||
|   }); | ||||
| }); | ||||
| 
 | ||||
| describe('isAvailable', () => { | ||||
|   const execSpy = jest.spyOn(exec, 'getExecOutput'); | ||||
|   buildx.isAvailable(); | ||||
| 
 | ||||
|   // eslint-disable-next-line jest/no-standalone-expect
 | ||||
|   expect(execSpy).toHaveBeenCalledWith(`docker`, ['buildx'], { | ||||
|     silent: true, | ||||
|     ignoreReturnCode: true | ||||
|   }); | ||||
| }); | ||||
| 
 | ||||
| describe('isAvailable standalone', () => { | ||||
|   const execSpy = jest.spyOn(exec, 'getExecOutput'); | ||||
|   buildx.isAvailable(true); | ||||
| 
 | ||||
|   // eslint-disable-next-line jest/no-standalone-expect
 | ||||
|   expect(execSpy).toHaveBeenCalledWith(`buildx`, [], { | ||||
|     silent: true, | ||||
|     ignoreReturnCode: true | ||||
|   }); | ||||
| }); | ||||
| 
 | ||||
| describe('getVersion', () => { | ||||
|   it('valid', async () => { | ||||
|     const version = await buildx.getVersion(); | ||||
|     expect(semver.valid(version)).not.toBeNull(); | ||||
|   }); | ||||
| }); | ||||
| 
 | ||||
| describe('parseVersion', () => { | ||||
|   test.each([ | ||||
|     ['github.com/docker/buildx 0.4.1+azure bda4882a65349ca359216b135896bddc1d92461c', '0.4.1'], | ||||
|     ['github.com/docker/buildx v0.4.1 bda4882a65349ca359216b135896bddc1d92461c', '0.4.1'], | ||||
|     ['github.com/docker/buildx v0.4.2 fb7b670b764764dc4716df3eba07ffdae4cc47b2', '0.4.2'], | ||||
|     ['github.com/docker/buildx f117971 f11797113e5a9b86bd976329c5dbb8a8bfdfadfa', 'f117971'] | ||||
|   ])('given %p', async (stdout, expected) => { | ||||
|     expect(buildx.parseVersion(stdout)).toEqual(expected); | ||||
|   }); | ||||
| }); | ||||
| 
 | ||||
| describe('satisfies', () => { | ||||
|   test.each([ | ||||
|     ['0.4.1', '>=0.3.2', true], | ||||
|     ['bda4882a65349ca359216b135896bddc1d92461c', '>0.1.0', false], | ||||
|     ['f117971', '>0.6.0', true] | ||||
|   ])('given %p', async (version, range, expected) => { | ||||
|     expect(buildx.satisfies(version, range)).toBe(expected); | ||||
|   }); | ||||
| }); | ||||
| 
 | ||||
| describe('getSecret', () => { | ||||
|   test.each([ | ||||
|     ['A_SECRET=abcdef0123456789', false, 'A_SECRET', 'abcdef0123456789', false], | ||||
|     ['GIT_AUTH_TOKEN=abcdefghijklmno=0123456789', false, 'GIT_AUTH_TOKEN', 'abcdefghijklmno=0123456789', false], | ||||
|     ['MY_KEY=c3RyaW5nLXdpdGgtZXF1YWxzCg==', false, 'MY_KEY', 'c3RyaW5nLXdpdGgtZXF1YWxzCg==', false], | ||||
|     ['aaaaaaaa', false, '', '', true], | ||||
|     ['aaaaaaaa=', false, '', '', true], | ||||
|     ['=bbbbbbb', false, '', '', true], | ||||
|     [`foo=${path.join(__dirname, 'fixtures', 'secret.txt').split(path.sep).join(path.posix.sep)}`, true, 'foo', 'bar', false], | ||||
|     [`notfound=secret`, true, '', '', true] | ||||
|   ])('given %p key and %p secret', async (kvp, file, exKey, exValue, invalid) => { | ||||
|     try { | ||||
|       let secret: string; | ||||
|       if (file) { | ||||
|         secret = await buildx.getSecretFile(kvp); | ||||
|       } else { | ||||
|         secret = await buildx.getSecretString(kvp); | ||||
|       } | ||||
|       expect(true).toBe(!invalid); | ||||
|       expect(secret).toEqual(`id=${exKey},src=${tmpNameSync}`); | ||||
|       expect(fs.readFileSync(tmpNameSync, 'utf-8')).toEqual(exValue); | ||||
|     } catch (err) { | ||||
|       // eslint-disable-next-line jest/no-conditional-expect
 | ||||
|       expect(true).toBe(invalid); | ||||
|     } | ||||
|   }); | ||||
| }); | ||||
| @ -1,134 +1,58 @@ | ||||
| import {beforeEach, describe, expect, it, jest, test} from '@jest/globals'; | ||||
| import {beforeEach, describe, expect, jest, test} from '@jest/globals'; | ||||
| import * as fs from 'fs'; | ||||
| import * as path from 'path'; | ||||
| import {Builder} from '@docker/actions-toolkit/lib/buildx/builder'; | ||||
| import {Buildx} from '@docker/actions-toolkit/lib/buildx/buildx'; | ||||
| import {Context} from '@docker/actions-toolkit/lib/context'; | ||||
| import {Docker} from '@docker/actions-toolkit/lib/docker'; | ||||
| import {GitHub} from '@docker/actions-toolkit/lib/github'; | ||||
| import {Toolkit} from '@docker/actions-toolkit/lib/toolkit'; | ||||
| import {BuilderInfo} from '@docker/actions-toolkit/lib/types/builder'; | ||||
| import {GitHubRepo} from '@docker/actions-toolkit/lib/types/github'; | ||||
| 
 | ||||
| import * as buildx from '../src/buildx'; | ||||
| import * as context from '../src/context'; | ||||
| 
 | ||||
| const pgp = `-----BEGIN PGP PRIVATE KEY BLOCK-----
 | ||||
| const tmpDir = path.join('/tmp', '.docker-build-push-jest'); | ||||
| const tmpName = path.join(tmpDir, '.tmpname-jest'); | ||||
| 
 | ||||
| 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 | ||||
| PejgXO0uIRolYQ3sz2tMGhx1MfBqH64= | ||||
| =WbwB | ||||
| -----END PGP PRIVATE KEY BLOCK-----`;
 | ||||
| 
 | ||||
| jest.spyOn(context, 'defaultContext').mockImplementation((): string => { | ||||
|   return 'https://github.com/docker/build-push-action.git#refs/heads/test-jest'; | ||||
| import repoFixture from './fixtures/github-repo.json'; | ||||
| jest.spyOn(GitHub.prototype, 'repoData').mockImplementation((): Promise<GitHubRepo> => { | ||||
|   return <Promise<GitHubRepo>>(repoFixture as unknown); | ||||
| }); | ||||
| 
 | ||||
| jest.spyOn(context, 'tmpDir').mockImplementation((): string => { | ||||
|   const tmpDir = path.join('/tmp/.docker-build-push-jest').split(path.sep).join(path.posix.sep); | ||||
| jest.spyOn(Context, 'tmpDir').mockImplementation((): string => { | ||||
|   if (!fs.existsSync(tmpDir)) { | ||||
|     fs.mkdirSync(tmpDir, {recursive: true}); | ||||
|   } | ||||
|   return tmpDir; | ||||
| }); | ||||
| 
 | ||||
| jest.spyOn(context, 'tmpNameSync').mockImplementation((): string => { | ||||
|   return path.join('/tmp/.docker-build-push-jest', '.tmpname-jest').split(path.sep).join(path.posix.sep); | ||||
| jest.spyOn(Context, 'tmpName').mockImplementation((): string => { | ||||
|   return tmpName; | ||||
| }); | ||||
| 
 | ||||
| jest.spyOn(buildx, 'satisfiesBuildKitVersion').mockResolvedValueOnce(true); | ||||
| jest.spyOn(Docker, 'isAvailable').mockImplementation(async (): Promise<boolean> => { | ||||
|   return true; | ||||
| }); | ||||
| 
 | ||||
| jest.spyOn(Builder.prototype, 'inspect').mockImplementation(async (): Promise<BuilderInfo> => { | ||||
|   return { | ||||
|     name: 'builder2', | ||||
|     driver: 'docker-container', | ||||
|     lastActivity: new Date('2023-01-16 09:45:23 +0000 UTC'), | ||||
|     nodes: [ | ||||
|       { | ||||
|         buildkitVersion: 'v0.11.0', | ||||
|         buildkitdFlags: '--debug --allow-insecure-entitlement security.insecure --allow-insecure-entitlement network.host', | ||||
|         driverOpts: ['BUILDKIT_STEP_LOG_MAX_SIZE=10485760', 'BUILDKIT_STEP_LOG_MAX_SPEED=10485760', 'JAEGER_TRACE=localhost:6831', 'image=moby/buildkit:latest', 'network=host'], | ||||
|         endpoint: 'unix:///var/run/docker.sock', | ||||
|         name: 'builder20', | ||||
|         platforms: 'linux/amd64,linux/amd64/v2,linux/amd64/v3,linux/arm64,linux/riscv64,linux/ppc64le,linux/s390x,linux/386,linux/mips64le,linux/mips64,linux/arm/v7,linux/arm/v6', | ||||
|         status: 'running' | ||||
|       } | ||||
|     ] | ||||
|   }; | ||||
| }); | ||||
| 
 | ||||
| describe('getArgs', () => { | ||||
|   beforeEach(() => { | ||||
| @ -154,7 +78,7 @@ describe('getArgs', () => { | ||||
|       ]), | ||||
|       [ | ||||
|         'build', | ||||
|         '--iidfile', '/tmp/.docker-build-push-jest/iidfile', | ||||
|         '--iidfile', path.join(tmpDir, 'iidfile'), | ||||
|         '.' | ||||
|       ] | ||||
|     ], | ||||
| @ -177,8 +101,8 @@ ccc"`], | ||||
|         '--build-arg', 'MY_ARG=val1,val2,val3', | ||||
|         '--build-arg', 'ARG=val', | ||||
|         '--build-arg', `MULTILINE=aaaa\nbbbb\nccc`, | ||||
|         '--iidfile', '/tmp/.docker-build-push-jest/iidfile', | ||||
|         'https://github.com/docker/build-push-action.git#refs/heads/test-jest' | ||||
|         '--iidfile', path.join(tmpDir, 'iidfile'), | ||||
|         'https://github.com/docker/build-push-action.git#refs/heads/master' | ||||
|       ] | ||||
|     ], | ||||
|     [ | ||||
| @ -193,10 +117,10 @@ ccc"`], | ||||
|       ]), | ||||
|       [ | ||||
|         'build', | ||||
|         '--iidfile', '/tmp/.docker-build-push-jest/iidfile', | ||||
|         '--iidfile', path.join(tmpDir, 'iidfile'), | ||||
|         '--tag', 'name/app:7.4', | ||||
|         '--tag', 'name/app:latest', | ||||
|         'https://github.com/docker/build-push-action.git#refs/heads/test-jest' | ||||
|         'https://github.com/docker/build-push-action.git#refs/heads/master' | ||||
|       ] | ||||
|     ], | ||||
|     [ | ||||
| @ -248,7 +172,7 @@ ccc"`], | ||||
|       ]), | ||||
|       [ | ||||
|         'build', | ||||
|         '--iidfile', '/tmp/.docker-build-push-jest/iidfile', | ||||
|         '--iidfile', path.join(tmpDir, 'iidfile'), | ||||
|         '.' | ||||
|       ] | ||||
|     ], | ||||
| @ -265,8 +189,8 @@ ccc"`], | ||||
|       ]), | ||||
|       [ | ||||
|         'build', | ||||
|         '--iidfile', '/tmp/.docker-build-push-jest/iidfile', | ||||
|         '--secret', 'id=GIT_AUTH_TOKEN,src=/tmp/.docker-build-push-jest/.tmpname-jest', | ||||
|         '--iidfile', path.join(tmpDir, 'iidfile'), | ||||
|         '--secret', `id=GIT_AUTH_TOKEN,src=${tmpName}`, | ||||
|         '.' | ||||
|       ] | ||||
|     ], | ||||
| @ -284,8 +208,8 @@ ccc"`], | ||||
|       [ | ||||
|         'build', | ||||
|         '--output', '.', | ||||
|         '--secret', 'id=GIT_AUTH_TOKEN,src=/tmp/.docker-build-push-jest/.tmpname-jest', | ||||
|         'https://github.com/docker/build-push-action.git#refs/heads/test-jest' | ||||
|         '--secret', `id=GIT_AUTH_TOKEN,src=${tmpName}`, | ||||
|         'https://github.com/docker/build-push-action.git#refs/heads/master' | ||||
|       ] | ||||
|     ], | ||||
|     [ | ||||
| @ -306,9 +230,9 @@ ccc"`], | ||||
|       [ | ||||
|         'build', | ||||
|         '--file', './test/Dockerfile', | ||||
|         '--iidfile', '/tmp/.docker-build-push-jest/iidfile', | ||||
|         '--iidfile', path.join(tmpDir, 'iidfile'), | ||||
|         '--platform', 'linux/amd64,linux/arm64', | ||||
|         '--secret', 'id=GIT_AUTH_TOKEN,src=/tmp/.docker-build-push-jest/.tmpname-jest', | ||||
|         '--secret', `id=GIT_AUTH_TOKEN,src=${tmpName}`, | ||||
|         '--builder', 'builder-git-context-2', | ||||
|         '--push', | ||||
|         'https://github.com/docker/build-push-action.git#refs/heads/master' | ||||
| @ -340,12 +264,12 @@ ccc"`], | ||||
|       [ | ||||
|         'build', | ||||
|         '--file', './test/Dockerfile', | ||||
|         '--iidfile', '/tmp/.docker-build-push-jest/iidfile', | ||||
|         '--iidfile', path.join(tmpDir, 'iidfile'), | ||||
|         '--platform', 'linux/amd64,linux/arm64', | ||||
|         '--secret', 'id=GIT_AUTH_TOKEN,src=/tmp/.docker-build-push-jest/.tmpname-jest', | ||||
|         '--secret', 'id=MYSECRET,src=/tmp/.docker-build-push-jest/.tmpname-jest', | ||||
|         '--secret', 'id=FOO,src=/tmp/.docker-build-push-jest/.tmpname-jest', | ||||
|         '--secret', 'id=EMPTYLINE,src=/tmp/.docker-build-push-jest/.tmpname-jest', | ||||
|         '--secret', `id=GIT_AUTH_TOKEN,src=${tmpName}`, | ||||
|         '--secret', `id=MYSECRET,src=${tmpName}`, | ||||
|         '--secret', `id=FOO,src=${tmpName}`, | ||||
|         '--secret', `id=EMPTYLINE,src=${tmpName}`, | ||||
|         '--builder', 'builder-git-context-2', | ||||
|         '--push', | ||||
|         'https://github.com/docker/build-push-action.git#refs/heads/master' | ||||
| @ -377,12 +301,12 @@ ccc`], | ||||
|       [ | ||||
|         'build', | ||||
|         '--file', './test/Dockerfile', | ||||
|         '--iidfile', '/tmp/.docker-build-push-jest/iidfile', | ||||
|         '--iidfile', path.join(tmpDir, 'iidfile'), | ||||
|         '--platform', 'linux/amd64,linux/arm64', | ||||
|         '--secret', 'id=GIT_AUTH_TOKEN,src=/tmp/.docker-build-push-jest/.tmpname-jest', | ||||
|         '--secret', 'id=MYSECRET,src=/tmp/.docker-build-push-jest/.tmpname-jest', | ||||
|         '--secret', 'id=FOO,src=/tmp/.docker-build-push-jest/.tmpname-jest', | ||||
|         '--secret', 'id=EMPTYLINE,src=/tmp/.docker-build-push-jest/.tmpname-jest', | ||||
|         '--secret', `id=GIT_AUTH_TOKEN,src=${tmpName}`, | ||||
|         '--secret', `id=MYSECRET,src=${tmpName}`, | ||||
|         '--secret', `id=FOO,src=${tmpName}`, | ||||
|         '--secret', `id=EMPTYLINE,src=${tmpName}`, | ||||
|         '--builder', 'builder-git-context-2', | ||||
|         '--push', | ||||
|         'https://github.com/docker/build-push-action.git#refs/heads/master' | ||||
| @ -394,7 +318,7 @@ ccc`], | ||||
|       new Map<string, string>([ | ||||
|         ['context', 'https://github.com/docker/build-push-action.git#refs/heads/master'], | ||||
|         ['tag', 'localhost:5000/name/app:latest'], | ||||
|         ['secret-files', `MY_SECRET=${path.join(__dirname, 'fixtures', 'secret.txt').split(path.sep).join(path.posix.sep)}`], | ||||
|         ['secret-files', `MY_SECRET=${path.join(__dirname, 'fixtures', 'secret.txt')}`], | ||||
|         ['file', './test/Dockerfile'], | ||||
|         ['builder', 'builder-git-context-2'], | ||||
|         ['network', 'host'], | ||||
| @ -406,8 +330,8 @@ ccc`], | ||||
|       [ | ||||
|         'build', | ||||
|         '--file', './test/Dockerfile', | ||||
|         '--iidfile', '/tmp/.docker-build-push-jest/iidfile', | ||||
|         '--secret', 'id=MY_SECRET,src=/tmp/.docker-build-push-jest/.tmpname-jest', | ||||
|         '--iidfile', path.join(tmpDir, 'iidfile'), | ||||
|         '--secret', `id=MY_SECRET,src=${tmpName}`, | ||||
|         '--builder', 'builder-git-context-2', | ||||
|         '--network', 'host', | ||||
|         '--push', | ||||
| @ -453,8 +377,8 @@ ccc`], | ||||
|         '--add-host', 'docker:10.180.0.1', | ||||
|         '--add-host', 'foo:10.0.0.1', | ||||
|         '--file', './test/Dockerfile', | ||||
|         '--iidfile', '/tmp/.docker-build-push-jest/iidfile', | ||||
|         '--metadata-file', '/tmp/.docker-build-push-jest/metadata-file', | ||||
|         '--iidfile', path.join(tmpDir, 'iidfile'), | ||||
|         '--metadata-file', path.join(tmpDir, 'metadata-file'), | ||||
|         '--network', 'host', | ||||
|         '--push', | ||||
|         '.' | ||||
| @ -482,11 +406,11 @@ nproc=3`], | ||||
|         '--add-host', 'foo:10.0.0.1', | ||||
|         '--cgroup-parent', 'foo', | ||||
|         '--file', './test/Dockerfile', | ||||
|         '--iidfile', '/tmp/.docker-build-push-jest/iidfile', | ||||
|         '--iidfile', path.join(tmpDir, 'iidfile'), | ||||
|         '--shm-size', '2g', | ||||
|         '--ulimit', 'nofile=1024:1024', | ||||
|         '--ulimit', 'nproc=3', | ||||
|         '--metadata-file', '/tmp/.docker-build-push-jest/metadata-file', | ||||
|         '--metadata-file', path.join(tmpDir, 'metadata-file'), | ||||
|         '.' | ||||
|       ] | ||||
|     ], | ||||
| @ -502,9 +426,9 @@ nproc=3`], | ||||
|       ]), | ||||
|       [ | ||||
|         'build', | ||||
|         '--iidfile', '/tmp/.docker-build-push-jest/iidfile', | ||||
|         '--metadata-file', '/tmp/.docker-build-push-jest/metadata-file', | ||||
|         'https://github.com/docker/build-push-action.git#refs/heads/test-jest:docker' | ||||
|         '--iidfile', path.join(tmpDir, 'iidfile'), | ||||
|         '--metadata-file', path.join(tmpDir, 'metadata-file'), | ||||
|         'https://github.com/docker/build-push-action.git#refs/heads/master:docker' | ||||
|       ] | ||||
|     ], | ||||
|     [ | ||||
| @ -520,10 +444,10 @@ nproc=3`], | ||||
|       ]), | ||||
|       [ | ||||
|         'build', | ||||
|         '--iidfile', '/tmp/.docker-build-push-jest/iidfile', | ||||
|         '--secret', 'id=GIT_AUTH_TOKEN,src=/tmp/.docker-build-push-jest/.tmpname-jest', | ||||
|         '--metadata-file', '/tmp/.docker-build-push-jest/metadata-file', | ||||
|         'https://github.com/docker/build-push-action.git#refs/heads/test-jest:subdir' | ||||
|         '--iidfile', path.join(tmpDir, 'iidfile'), | ||||
|         '--secret', `id=GIT_AUTH_TOKEN,src=${tmpName}`, | ||||
|         '--metadata-file', path.join(tmpDir, 'metadata-file'), | ||||
|         'https://github.com/docker/build-push-action.git#refs/heads/master:subdir' | ||||
|       ] | ||||
|     ], | ||||
|     [ | ||||
| @ -539,8 +463,8 @@ nproc=3`], | ||||
|       ]), | ||||
|       [ | ||||
|         'build', | ||||
|         '--iidfile', '/tmp/.docker-build-push-jest/iidfile', | ||||
|         '--metadata-file', '/tmp/.docker-build-push-jest/metadata-file', | ||||
|         '--iidfile', path.join(tmpDir, 'iidfile'), | ||||
|         '--metadata-file', path.join(tmpDir, 'metadata-file'), | ||||
|         '.' | ||||
|       ] | ||||
|     ], | ||||
| @ -556,9 +480,9 @@ nproc=3`], | ||||
|       ]), | ||||
|       [ | ||||
|         'build', | ||||
|         '--iidfile', '/tmp/.docker-build-push-jest/iidfile', | ||||
|         '--iidfile', path.join(tmpDir, 'iidfile'), | ||||
|         "--provenance", `mode=min,inline-only=true,builder-id=https://github.com/docker/build-push-action/actions/runs/123456789`, | ||||
|         '--metadata-file', '/tmp/.docker-build-push-jest/metadata-file', | ||||
|         '--metadata-file', path.join(tmpDir, 'metadata-file'), | ||||
|         '.' | ||||
|       ] | ||||
|     ], | ||||
| @ -575,9 +499,9 @@ nproc=3`], | ||||
|       ]), | ||||
|       [ | ||||
|         'build', | ||||
|         '--iidfile', '/tmp/.docker-build-push-jest/iidfile', | ||||
|         '--iidfile', path.join(tmpDir, 'iidfile'), | ||||
|         "--provenance", `builder-id=https://github.com/docker/build-push-action/actions/runs/123456789`, | ||||
|         '--metadata-file', '/tmp/.docker-build-push-jest/metadata-file', | ||||
|         '--metadata-file', path.join(tmpDir, 'metadata-file'), | ||||
|         '.' | ||||
|       ] | ||||
|     ], | ||||
| @ -594,9 +518,9 @@ nproc=3`], | ||||
|       ]), | ||||
|       [ | ||||
|         'build', | ||||
|         '--iidfile', '/tmp/.docker-build-push-jest/iidfile', | ||||
|         '--iidfile', path.join(tmpDir, 'iidfile'), | ||||
|         "--provenance", `mode=max,builder-id=https://github.com/docker/build-push-action/actions/runs/123456789`, | ||||
|         '--metadata-file', '/tmp/.docker-build-push-jest/metadata-file', | ||||
|         '--metadata-file', path.join(tmpDir, 'metadata-file'), | ||||
|         '.' | ||||
|       ] | ||||
|     ], | ||||
| @ -613,9 +537,9 @@ nproc=3`], | ||||
|       ]), | ||||
|       [ | ||||
|         'build', | ||||
|         '--iidfile', '/tmp/.docker-build-push-jest/iidfile', | ||||
|         '--iidfile', path.join(tmpDir, 'iidfile'), | ||||
|         "--provenance", 'false', | ||||
|         '--metadata-file', '/tmp/.docker-build-push-jest/metadata-file', | ||||
|         '--metadata-file', path.join(tmpDir, 'metadata-file'), | ||||
|         '.' | ||||
|       ] | ||||
|     ], | ||||
| @ -632,9 +556,9 @@ nproc=3`], | ||||
|       ]), | ||||
|       [ | ||||
|         'build', | ||||
|         '--iidfile', '/tmp/.docker-build-push-jest/iidfile', | ||||
|         '--iidfile', path.join(tmpDir, 'iidfile'), | ||||
|         "--provenance", 'builder-id=foo', | ||||
|         '--metadata-file', '/tmp/.docker-build-push-jest/metadata-file', | ||||
|         '--metadata-file', path.join(tmpDir, 'metadata-file'), | ||||
|         '.' | ||||
|       ] | ||||
|     ], | ||||
| @ -651,9 +575,9 @@ nproc=3`], | ||||
|       ]), | ||||
|       [ | ||||
|         'build', | ||||
|         '--iidfile', '/tmp/.docker-build-push-jest/iidfile', | ||||
|         '--iidfile', path.join(tmpDir, 'iidfile'), | ||||
|         "--output", 'type=docker', | ||||
|         '--metadata-file', '/tmp/.docker-build-push-jest/metadata-file', | ||||
|         '--metadata-file', path.join(tmpDir, 'metadata-file'), | ||||
|         '.' | ||||
|       ] | ||||
|     ], | ||||
| @ -669,9 +593,9 @@ nproc=3`], | ||||
|       ]), | ||||
|       [ | ||||
|         'build', | ||||
|         '--iidfile', '/tmp/.docker-build-push-jest/iidfile', | ||||
|         "--load", | ||||
|         '--metadata-file', '/tmp/.docker-build-push-jest/metadata-file', | ||||
|         '--iidfile', path.join(tmpDir, 'iidfile'), | ||||
|         '--load', | ||||
|         '--metadata-file', path.join(tmpDir, 'metadata-file'), | ||||
|         '.' | ||||
|       ] | ||||
|     ], | ||||
| @ -681,171 +605,17 @@ nproc=3`], | ||||
|       inputs.forEach((value: string, name: string) => { | ||||
|         setInput(name, value); | ||||
|       }); | ||||
|       const defContext = context.defaultContext(); | ||||
|       const inp = await context.getInputs(defContext); | ||||
|       const res = await context.getArgs(inp, defContext, buildxVersion); | ||||
|       const toolkit = new Toolkit(); | ||||
|       jest.spyOn(Buildx.prototype, 'version').mockImplementation(async (): Promise<string> => { | ||||
|         return buildxVersion; | ||||
|       }); | ||||
|       const inp = await context.getInputs(); | ||||
|       const res = await context.getArgs(inp, toolkit); | ||||
|       expect(res).toEqual(expected); | ||||
|     } | ||||
|   ); | ||||
| }); | ||||
| 
 | ||||
| describe('getInputList', () => { | ||||
|   it('single line correctly', async () => { | ||||
|     await setInput('foo', 'bar'); | ||||
|     const res = await context.getInputList('foo'); | ||||
|     expect(res).toEqual(['bar']); | ||||
|   }); | ||||
| 
 | ||||
|   it('multiline correctly', async () => { | ||||
|     setInput('foo', 'bar\nbaz'); | ||||
|     const res = await context.getInputList('foo'); | ||||
|     expect(res).toEqual(['bar', 'baz']); | ||||
|   }); | ||||
| 
 | ||||
|   it('empty lines correctly', async () => { | ||||
|     setInput('foo', 'bar\n\nbaz'); | ||||
|     const res = await context.getInputList('foo'); | ||||
|     expect(res).toEqual(['bar', 'baz']); | ||||
|   }); | ||||
| 
 | ||||
|   it('comma correctly', async () => { | ||||
|     setInput('foo', 'bar,baz'); | ||||
|     const res = await context.getInputList('foo'); | ||||
|     expect(res).toEqual(['bar', 'baz']); | ||||
|   }); | ||||
| 
 | ||||
|   it('empty result correctly', async () => { | ||||
|     setInput('foo', 'bar,baz,'); | ||||
|     const res = await context.getInputList('foo'); | ||||
|     expect(res).toEqual(['bar', 'baz']); | ||||
|   }); | ||||
| 
 | ||||
|   it('different new lines correctly', async () => { | ||||
|     setInput('foo', 'bar\r\nbaz'); | ||||
|     const res = await context.getInputList('foo'); | ||||
|     expect(res).toEqual(['bar', 'baz']); | ||||
|   }); | ||||
| 
 | ||||
|   it('different new lines and comma correctly', async () => { | ||||
|     setInput('foo', 'bar\r\nbaz,bat'); | ||||
|     const res = await context.getInputList('foo'); | ||||
|     expect(res).toEqual(['bar', 'baz', 'bat']); | ||||
|   }); | ||||
| 
 | ||||
|   it('multiline and ignoring comma correctly', async () => { | ||||
|     setInput('cache-from', 'user/app:cache\ntype=local,src=path/to/dir'); | ||||
|     const res = await context.getInputList('cache-from', true); | ||||
|     expect(res).toEqual(['user/app:cache', 'type=local,src=path/to/dir']); | ||||
|   }); | ||||
| 
 | ||||
|   it('different new lines and ignoring comma correctly', async () => { | ||||
|     setInput('cache-from', 'user/app:cache\r\ntype=local,src=path/to/dir'); | ||||
|     const res = await context.getInputList('cache-from', true); | ||||
|     expect(res).toEqual(['user/app:cache', 'type=local,src=path/to/dir']); | ||||
|   }); | ||||
| 
 | ||||
|   it('multiline values', async () => { | ||||
|     setInput( | ||||
|       'secrets', | ||||
|       `GIT_AUTH_TOKEN=abcdefgh,ijklmno=0123456789
 | ||||
| "MYSECRET=aaaaaaaa | ||||
| bbbbbbb | ||||
| ccccccccc" | ||||
| FOO=bar` | ||||
|     ); | ||||
|     const res = await context.getInputList('secrets', true); | ||||
|     expect(res).toEqual([ | ||||
|       'GIT_AUTH_TOKEN=abcdefgh,ijklmno=0123456789', | ||||
|       `MYSECRET=aaaaaaaa
 | ||||
| bbbbbbb | ||||
| ccccccccc`,
 | ||||
|       'FOO=bar' | ||||
|     ]); | ||||
|   }); | ||||
| 
 | ||||
|   it('multiline values with empty lines', async () => { | ||||
|     setInput( | ||||
|       'secrets', | ||||
|       `GIT_AUTH_TOKEN=abcdefgh,ijklmno=0123456789
 | ||||
| "MYSECRET=aaaaaaaa | ||||
| bbbbbbb | ||||
| ccccccccc" | ||||
| FOO=bar | ||||
| "EMPTYLINE=aaaa | ||||
| 
 | ||||
| bbbb | ||||
| ccc"` | ||||
|     ); | ||||
|     const res = await context.getInputList('secrets', true); | ||||
|     expect(res).toEqual([ | ||||
|       'GIT_AUTH_TOKEN=abcdefgh,ijklmno=0123456789', | ||||
|       `MYSECRET=aaaaaaaa
 | ||||
| bbbbbbb | ||||
| ccccccccc`,
 | ||||
|       'FOO=bar', | ||||
|       `EMPTYLINE=aaaa
 | ||||
| 
 | ||||
| bbbb | ||||
| ccc` | ||||
|     ]); | ||||
|   }); | ||||
| 
 | ||||
|   it('multiline values without quotes', async () => { | ||||
|     setInput( | ||||
|       'secrets', | ||||
|       `GIT_AUTH_TOKEN=abcdefgh,ijklmno=0123456789
 | ||||
| MYSECRET=aaaaaaaa | ||||
| bbbbbbb | ||||
| ccccccccc | ||||
| FOO=bar` | ||||
|     ); | ||||
|     const res = await context.getInputList('secrets', true); | ||||
|     expect(res).toEqual(['GIT_AUTH_TOKEN=abcdefgh,ijklmno=0123456789', 'MYSECRET=aaaaaaaa', 'bbbbbbb', 'ccccccccc', 'FOO=bar']); | ||||
|   }); | ||||
| 
 | ||||
|   it('large multiline values', async () => { | ||||
|     setInput( | ||||
|       'secrets', | ||||
|       `"GPG_KEY=${pgp}"
 | ||||
| FOO=bar` | ||||
|     ); | ||||
|     const res = await context.getInputList('secrets', true); | ||||
|     expect(res).toEqual([`GPG_KEY=${pgp}`, 'FOO=bar']); | ||||
|   }); | ||||
| 
 | ||||
|   it('multiline values escape quotes', async () => { | ||||
|     setInput( | ||||
|       'secrets', | ||||
|       `GIT_AUTH_TOKEN=abcdefgh,ijklmno=0123456789
 | ||||
| "MYSECRET=aaaaaaaa | ||||
| bbbb""bbb | ||||
| ccccccccc" | ||||
| FOO=bar` | ||||
|     ); | ||||
|     const res = await context.getInputList('secrets', true); | ||||
|     expect(res).toEqual([ | ||||
|       'GIT_AUTH_TOKEN=abcdefgh,ijklmno=0123456789', | ||||
|       `MYSECRET=aaaaaaaa
 | ||||
| bbbb"bbb | ||||
| ccccccccc`,
 | ||||
|       'FOO=bar' | ||||
|     ]); | ||||
|   }); | ||||
| }); | ||||
| 
 | ||||
| describe('asyncForEach', () => { | ||||
|   it('executes async tasks sequentially', async () => { | ||||
|     const testValues = [1, 2, 3, 4, 5]; | ||||
|     const results: number[] = []; | ||||
| 
 | ||||
|     await context.asyncForEach(testValues, async value => { | ||||
|       results.push(value); | ||||
|     }); | ||||
| 
 | ||||
|     expect(results).toEqual(testValues); | ||||
|   }); | ||||
| }); | ||||
| 
 | ||||
| // See: https://github.com/actions/toolkit/blob/a1b068ec31a042ff1e10a522d8fdf0b8869d53ca/packages/core/src/core.ts#L89
 | ||||
| function getInputName(name: string): string { | ||||
|   return `INPUT_${name.replace(/ /g, '_').toUpperCase()}`; | ||||
|  | ||||
| @ -1,16 +0,0 @@ | ||||
| import {describe, expect, it, jest} from '@jest/globals'; | ||||
| import * as docker from '../src/docker'; | ||||
| import * as exec from '@actions/exec'; | ||||
| 
 | ||||
| describe('isAvailable', () => { | ||||
|   it('cli', () => { | ||||
|     const execSpy = jest.spyOn(exec, 'getExecOutput'); | ||||
|     docker.isAvailable(); | ||||
| 
 | ||||
|     // eslint-disable-next-line jest/no-standalone-expect
 | ||||
|     expect(execSpy).toHaveBeenCalledWith(`docker`, undefined, { | ||||
|       silent: true, | ||||
|       ignoreReturnCode: true | ||||
|     }); | ||||
|   }); | ||||
| }); | ||||
							
								
								
									
										362
									
								
								__tests__/fixtures/github-repo.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										362
									
								
								__tests__/fixtures/github-repo.json
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,362 @@ | ||||
| { | ||||
|   "id": 1296269, | ||||
|   "node_id": "MDEwOlJlcG9zaXRvcnkxMjk2MjY5", | ||||
|   "name": "Hello-World", | ||||
|   "full_name": "octocat/Hello-World", | ||||
|   "owner": { | ||||
|     "login": "octocat", | ||||
|     "id": 1, | ||||
|     "node_id": "MDQ6VXNlcjE=", | ||||
|     "avatar_url": "https://github.com/images/error/octocat_happy.gif", | ||||
|     "gravatar_id": "", | ||||
|     "url": "https://api.github.com/users/octocat", | ||||
|     "html_url": "https://github.com/octocat", | ||||
|     "followers_url": "https://api.github.com/users/octocat/followers", | ||||
|     "following_url": "https://api.github.com/users/octocat/following{/other_user}", | ||||
|     "gists_url": "https://api.github.com/users/octocat/gists{/gist_id}", | ||||
|     "starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}", | ||||
|     "subscriptions_url": "https://api.github.com/users/octocat/subscriptions", | ||||
|     "organizations_url": "https://api.github.com/users/octocat/orgs", | ||||
|     "repos_url": "https://api.github.com/users/octocat/repos", | ||||
|     "events_url": "https://api.github.com/users/octocat/events{/privacy}", | ||||
|     "received_events_url": "https://api.github.com/users/octocat/received_events", | ||||
|     "type": "User", | ||||
|     "site_admin": false | ||||
|   }, | ||||
|   "private": false, | ||||
|   "html_url": "https://github.com/octocat/Hello-World", | ||||
|   "description": "This your first repo!", | ||||
|   "fork": false, | ||||
|   "url": "https://api.github.com/repos/octocat/Hello-World", | ||||
|   "archive_url": "http://api.github.com/repos/octocat/Hello-World/{archive_format}{/ref}", | ||||
|   "assignees_url": "http://api.github.com/repos/octocat/Hello-World/assignees{/user}", | ||||
|   "blobs_url": "http://api.github.com/repos/octocat/Hello-World/git/blobs{/sha}", | ||||
|   "branches_url": "http://api.github.com/repos/octocat/Hello-World/branches{/branch}", | ||||
|   "collaborators_url": "http://api.github.com/repos/octocat/Hello-World/collaborators{/collaborator}", | ||||
|   "comments_url": "http://api.github.com/repos/octocat/Hello-World/comments{/number}", | ||||
|   "commits_url": "http://api.github.com/repos/octocat/Hello-World/commits{/sha}", | ||||
|   "compare_url": "http://api.github.com/repos/octocat/Hello-World/compare/{base}...{head}", | ||||
|   "contents_url": "http://api.github.com/repos/octocat/Hello-World/contents/{+path}", | ||||
|   "contributors_url": "http://api.github.com/repos/octocat/Hello-World/contributors", | ||||
|   "deployments_url": "http://api.github.com/repos/octocat/Hello-World/deployments", | ||||
|   "downloads_url": "http://api.github.com/repos/octocat/Hello-World/downloads", | ||||
|   "events_url": "http://api.github.com/repos/octocat/Hello-World/events", | ||||
|   "forks_url": "http://api.github.com/repos/octocat/Hello-World/forks", | ||||
|   "git_commits_url": "http://api.github.com/repos/octocat/Hello-World/git/commits{/sha}", | ||||
|   "git_refs_url": "http://api.github.com/repos/octocat/Hello-World/git/refs{/sha}", | ||||
|   "git_tags_url": "http://api.github.com/repos/octocat/Hello-World/git/tags{/sha}", | ||||
|   "git_url": "git:github.com/octocat/Hello-World.git", | ||||
|   "issue_comment_url": "http://api.github.com/repos/octocat/Hello-World/issues/comments{/number}", | ||||
|   "issue_events_url": "http://api.github.com/repos/octocat/Hello-World/issues/events{/number}", | ||||
|   "issues_url": "http://api.github.com/repos/octocat/Hello-World/issues{/number}", | ||||
|   "keys_url": "http://api.github.com/repos/octocat/Hello-World/keys{/key_id}", | ||||
|   "labels_url": "http://api.github.com/repos/octocat/Hello-World/labels{/name}", | ||||
|   "languages_url": "http://api.github.com/repos/octocat/Hello-World/languages", | ||||
|   "merges_url": "http://api.github.com/repos/octocat/Hello-World/merges", | ||||
|   "milestones_url": "http://api.github.com/repos/octocat/Hello-World/milestones{/number}", | ||||
|   "notifications_url": "http://api.github.com/repos/octocat/Hello-World/notifications{?since,all,participating}", | ||||
|   "pulls_url": "http://api.github.com/repos/octocat/Hello-World/pulls{/number}", | ||||
|   "releases_url": "http://api.github.com/repos/octocat/Hello-World/releases{/id}", | ||||
|   "ssh_url": "git@github.com:octocat/Hello-World.git", | ||||
|   "stargazers_url": "http://api.github.com/repos/octocat/Hello-World/stargazers", | ||||
|   "statuses_url": "http://api.github.com/repos/octocat/Hello-World/statuses/{sha}", | ||||
|   "subscribers_url": "http://api.github.com/repos/octocat/Hello-World/subscribers", | ||||
|   "subscription_url": "http://api.github.com/repos/octocat/Hello-World/subscription", | ||||
|   "tags_url": "http://api.github.com/repos/octocat/Hello-World/tags", | ||||
|   "teams_url": "http://api.github.com/repos/octocat/Hello-World/teams", | ||||
|   "trees_url": "http://api.github.com/repos/octocat/Hello-World/git/trees{/sha}", | ||||
|   "clone_url": "https://github.com/octocat/Hello-World.git", | ||||
|   "mirror_url": "git:git.example.com/octocat/Hello-World", | ||||
|   "hooks_url": "http://api.github.com/repos/octocat/Hello-World/hooks", | ||||
|   "svn_url": "https://svn.github.com/octocat/Hello-World", | ||||
|   "homepage": "https://github.com", | ||||
|   "language": null, | ||||
|   "forks_count": 9, | ||||
|   "stargazers_count": 80, | ||||
|   "watchers_count": 80, | ||||
|   "size": 108, | ||||
|   "default_branch": "master", | ||||
|   "open_issues_count": 0, | ||||
|   "is_template": true, | ||||
|   "topics": [ | ||||
|     "octocat", | ||||
|     "atom", | ||||
|     "electron", | ||||
|     "api" | ||||
|   ], | ||||
|   "has_issues": true, | ||||
|   "has_projects": true, | ||||
|   "has_wiki": true, | ||||
|   "has_pages": false, | ||||
|   "has_downloads": true, | ||||
|   "archived": false, | ||||
|   "disabled": false, | ||||
|   "visibility": "public", | ||||
|   "pushed_at": "2011-01-26T19:06:43Z", | ||||
|   "created_at": "2011-01-26T19:01:12Z", | ||||
|   "updated_at": "2011-01-26T19:14:43Z", | ||||
|   "permissions": { | ||||
|     "pull": true, | ||||
|     "triage": true, | ||||
|     "push": false, | ||||
|     "maintain": false, | ||||
|     "admin": false | ||||
|   }, | ||||
|   "allow_rebase_merge": true, | ||||
|   "template_repository": null, | ||||
|   "temp_clone_token": "ABTLWHOULUVAXGTRYU7OC2876QJ2O", | ||||
|   "allow_squash_merge": true, | ||||
|   "delete_branch_on_merge": true, | ||||
|   "allow_merge_commit": true, | ||||
|   "subscribers_count": 42, | ||||
|   "network_count": 0, | ||||
|   "license": { | ||||
|     "key": "mit", | ||||
|     "name": "MIT License", | ||||
|     "spdx_id": "MIT", | ||||
|     "url": "https://api.github.com/licenses/mit", | ||||
|     "node_id": "MDc6TGljZW5zZW1pdA==" | ||||
|   }, | ||||
|   "organization": { | ||||
|     "login": "octocat", | ||||
|     "id": 1, | ||||
|     "node_id": "MDQ6VXNlcjE=", | ||||
|     "avatar_url": "https://github.com/images/error/octocat_happy.gif", | ||||
|     "gravatar_id": "", | ||||
|     "url": "https://api.github.com/users/octocat", | ||||
|     "html_url": "https://github.com/octocat", | ||||
|     "followers_url": "https://api.github.com/users/octocat/followers", | ||||
|     "following_url": "https://api.github.com/users/octocat/following{/other_user}", | ||||
|     "gists_url": "https://api.github.com/users/octocat/gists{/gist_id}", | ||||
|     "starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}", | ||||
|     "subscriptions_url": "https://api.github.com/users/octocat/subscriptions", | ||||
|     "organizations_url": "https://api.github.com/users/octocat/orgs", | ||||
|     "repos_url": "https://api.github.com/users/octocat/repos", | ||||
|     "events_url": "https://api.github.com/users/octocat/events{/privacy}", | ||||
|     "received_events_url": "https://api.github.com/users/octocat/received_events", | ||||
|     "type": "Organization", | ||||
|     "site_admin": false | ||||
|   }, | ||||
|   "parent": { | ||||
|     "id": 1296269, | ||||
|     "node_id": "MDEwOlJlcG9zaXRvcnkxMjk2MjY5", | ||||
|     "name": "Hello-World", | ||||
|     "full_name": "octocat/Hello-World", | ||||
|     "owner": { | ||||
|       "login": "octocat", | ||||
|       "id": 1, | ||||
|       "node_id": "MDQ6VXNlcjE=", | ||||
|       "avatar_url": "https://github.com/images/error/octocat_happy.gif", | ||||
|       "gravatar_id": "", | ||||
|       "url": "https://api.github.com/users/octocat", | ||||
|       "html_url": "https://github.com/octocat", | ||||
|       "followers_url": "https://api.github.com/users/octocat/followers", | ||||
|       "following_url": "https://api.github.com/users/octocat/following{/other_user}", | ||||
|       "gists_url": "https://api.github.com/users/octocat/gists{/gist_id}", | ||||
|       "starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}", | ||||
|       "subscriptions_url": "https://api.github.com/users/octocat/subscriptions", | ||||
|       "organizations_url": "https://api.github.com/users/octocat/orgs", | ||||
|       "repos_url": "https://api.github.com/users/octocat/repos", | ||||
|       "events_url": "https://api.github.com/users/octocat/events{/privacy}", | ||||
|       "received_events_url": "https://api.github.com/users/octocat/received_events", | ||||
|       "type": "User", | ||||
|       "site_admin": false | ||||
|     }, | ||||
|     "private": false, | ||||
|     "html_url": "https://github.com/octocat/Hello-World", | ||||
|     "description": "This your first repo!", | ||||
|     "fork": false, | ||||
|     "url": "https://api.github.com/repos/octocat/Hello-World", | ||||
|     "archive_url": "http://api.github.com/repos/octocat/Hello-World/{archive_format}{/ref}", | ||||
|     "assignees_url": "http://api.github.com/repos/octocat/Hello-World/assignees{/user}", | ||||
|     "blobs_url": "http://api.github.com/repos/octocat/Hello-World/git/blobs{/sha}", | ||||
|     "branches_url": "http://api.github.com/repos/octocat/Hello-World/branches{/branch}", | ||||
|     "collaborators_url": "http://api.github.com/repos/octocat/Hello-World/collaborators{/collaborator}", | ||||
|     "comments_url": "http://api.github.com/repos/octocat/Hello-World/comments{/number}", | ||||
|     "commits_url": "http://api.github.com/repos/octocat/Hello-World/commits{/sha}", | ||||
|     "compare_url": "http://api.github.com/repos/octocat/Hello-World/compare/{base}...{head}", | ||||
|     "contents_url": "http://api.github.com/repos/octocat/Hello-World/contents/{+path}", | ||||
|     "contributors_url": "http://api.github.com/repos/octocat/Hello-World/contributors", | ||||
|     "deployments_url": "http://api.github.com/repos/octocat/Hello-World/deployments", | ||||
|     "downloads_url": "http://api.github.com/repos/octocat/Hello-World/downloads", | ||||
|     "events_url": "http://api.github.com/repos/octocat/Hello-World/events", | ||||
|     "forks_url": "http://api.github.com/repos/octocat/Hello-World/forks", | ||||
|     "git_commits_url": "http://api.github.com/repos/octocat/Hello-World/git/commits{/sha}", | ||||
|     "git_refs_url": "http://api.github.com/repos/octocat/Hello-World/git/refs{/sha}", | ||||
|     "git_tags_url": "http://api.github.com/repos/octocat/Hello-World/git/tags{/sha}", | ||||
|     "git_url": "git:github.com/octocat/Hello-World.git", | ||||
|     "issue_comment_url": "http://api.github.com/repos/octocat/Hello-World/issues/comments{/number}", | ||||
|     "issue_events_url": "http://api.github.com/repos/octocat/Hello-World/issues/events{/number}", | ||||
|     "issues_url": "http://api.github.com/repos/octocat/Hello-World/issues{/number}", | ||||
|     "keys_url": "http://api.github.com/repos/octocat/Hello-World/keys{/key_id}", | ||||
|     "labels_url": "http://api.github.com/repos/octocat/Hello-World/labels{/name}", | ||||
|     "languages_url": "http://api.github.com/repos/octocat/Hello-World/languages", | ||||
|     "merges_url": "http://api.github.com/repos/octocat/Hello-World/merges", | ||||
|     "milestones_url": "http://api.github.com/repos/octocat/Hello-World/milestones{/number}", | ||||
|     "notifications_url": "http://api.github.com/repos/octocat/Hello-World/notifications{?since,all,participating}", | ||||
|     "pulls_url": "http://api.github.com/repos/octocat/Hello-World/pulls{/number}", | ||||
|     "releases_url": "http://api.github.com/repos/octocat/Hello-World/releases{/id}", | ||||
|     "ssh_url": "git@github.com:octocat/Hello-World.git", | ||||
|     "stargazers_url": "http://api.github.com/repos/octocat/Hello-World/stargazers", | ||||
|     "statuses_url": "http://api.github.com/repos/octocat/Hello-World/statuses/{sha}", | ||||
|     "subscribers_url": "http://api.github.com/repos/octocat/Hello-World/subscribers", | ||||
|     "subscription_url": "http://api.github.com/repos/octocat/Hello-World/subscription", | ||||
|     "tags_url": "http://api.github.com/repos/octocat/Hello-World/tags", | ||||
|     "teams_url": "http://api.github.com/repos/octocat/Hello-World/teams", | ||||
|     "trees_url": "http://api.github.com/repos/octocat/Hello-World/git/trees{/sha}", | ||||
|     "clone_url": "https://github.com/octocat/Hello-World.git", | ||||
|     "mirror_url": "git:git.example.com/octocat/Hello-World", | ||||
|     "hooks_url": "http://api.github.com/repos/octocat/Hello-World/hooks", | ||||
|     "svn_url": "https://svn.github.com/octocat/Hello-World", | ||||
|     "homepage": "https://github.com", | ||||
|     "language": null, | ||||
|     "forks_count": 9, | ||||
|     "stargazers_count": 80, | ||||
|     "watchers_count": 80, | ||||
|     "size": 108, | ||||
|     "default_branch": "master", | ||||
|     "open_issues_count": 0, | ||||
|     "is_template": true, | ||||
|     "topics": [ | ||||
|       "octocat", | ||||
|       "atom", | ||||
|       "electron", | ||||
|       "api" | ||||
|     ], | ||||
|     "has_issues": true, | ||||
|     "has_projects": true, | ||||
|     "has_wiki": true, | ||||
|     "has_pages": false, | ||||
|     "has_downloads": true, | ||||
|     "archived": false, | ||||
|     "disabled": false, | ||||
|     "visibility": "public", | ||||
|     "pushed_at": "2011-01-26T19:06:43Z", | ||||
|     "created_at": "2011-01-26T19:01:12Z", | ||||
|     "updated_at": "2011-01-26T19:14:43Z", | ||||
|     "permissions": { | ||||
|       "admin": false, | ||||
|       "push": false, | ||||
|       "pull": true | ||||
|     }, | ||||
|     "allow_rebase_merge": true, | ||||
|     "template_repository": null, | ||||
|     "temp_clone_token": "ABTLWHOULUVAXGTRYU7OC2876QJ2O", | ||||
|     "allow_squash_merge": true, | ||||
|     "delete_branch_on_merge": true, | ||||
|     "allow_merge_commit": true, | ||||
|     "subscribers_count": 42, | ||||
|     "network_count": 0 | ||||
|   }, | ||||
|   "source": { | ||||
|     "id": 1296269, | ||||
|     "node_id": "MDEwOlJlcG9zaXRvcnkxMjk2MjY5", | ||||
|     "name": "Hello-World", | ||||
|     "full_name": "octocat/Hello-World", | ||||
|     "owner": { | ||||
|       "login": "octocat", | ||||
|       "id": 1, | ||||
|       "node_id": "MDQ6VXNlcjE=", | ||||
|       "avatar_url": "https://github.com/images/error/octocat_happy.gif", | ||||
|       "gravatar_id": "", | ||||
|       "url": "https://api.github.com/users/octocat", | ||||
|       "html_url": "https://github.com/octocat", | ||||
|       "followers_url": "https://api.github.com/users/octocat/followers", | ||||
|       "following_url": "https://api.github.com/users/octocat/following{/other_user}", | ||||
|       "gists_url": "https://api.github.com/users/octocat/gists{/gist_id}", | ||||
|       "starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}", | ||||
|       "subscriptions_url": "https://api.github.com/users/octocat/subscriptions", | ||||
|       "organizations_url": "https://api.github.com/users/octocat/orgs", | ||||
|       "repos_url": "https://api.github.com/users/octocat/repos", | ||||
|       "events_url": "https://api.github.com/users/octocat/events{/privacy}", | ||||
|       "received_events_url": "https://api.github.com/users/octocat/received_events", | ||||
|       "type": "User", | ||||
|       "site_admin": false | ||||
|     }, | ||||
|     "private": false, | ||||
|     "html_url": "https://github.com/octocat/Hello-World", | ||||
|     "description": "This your first repo!", | ||||
|     "fork": false, | ||||
|     "url": "https://api.github.com/repos/octocat/Hello-World", | ||||
|     "archive_url": "http://api.github.com/repos/octocat/Hello-World/{archive_format}{/ref}", | ||||
|     "assignees_url": "http://api.github.com/repos/octocat/Hello-World/assignees{/user}", | ||||
|     "blobs_url": "http://api.github.com/repos/octocat/Hello-World/git/blobs{/sha}", | ||||
|     "branches_url": "http://api.github.com/repos/octocat/Hello-World/branches{/branch}", | ||||
|     "collaborators_url": "http://api.github.com/repos/octocat/Hello-World/collaborators{/collaborator}", | ||||
|     "comments_url": "http://api.github.com/repos/octocat/Hello-World/comments{/number}", | ||||
|     "commits_url": "http://api.github.com/repos/octocat/Hello-World/commits{/sha}", | ||||
|     "compare_url": "http://api.github.com/repos/octocat/Hello-World/compare/{base}...{head}", | ||||
|     "contents_url": "http://api.github.com/repos/octocat/Hello-World/contents/{+path}", | ||||
|     "contributors_url": "http://api.github.com/repos/octocat/Hello-World/contributors", | ||||
|     "deployments_url": "http://api.github.com/repos/octocat/Hello-World/deployments", | ||||
|     "downloads_url": "http://api.github.com/repos/octocat/Hello-World/downloads", | ||||
|     "events_url": "http://api.github.com/repos/octocat/Hello-World/events", | ||||
|     "forks_url": "http://api.github.com/repos/octocat/Hello-World/forks", | ||||
|     "git_commits_url": "http://api.github.com/repos/octocat/Hello-World/git/commits{/sha}", | ||||
|     "git_refs_url": "http://api.github.com/repos/octocat/Hello-World/git/refs{/sha}", | ||||
|     "git_tags_url": "http://api.github.com/repos/octocat/Hello-World/git/tags{/sha}", | ||||
|     "git_url": "git:github.com/octocat/Hello-World.git", | ||||
|     "issue_comment_url": "http://api.github.com/repos/octocat/Hello-World/issues/comments{/number}", | ||||
|     "issue_events_url": "http://api.github.com/repos/octocat/Hello-World/issues/events{/number}", | ||||
|     "issues_url": "http://api.github.com/repos/octocat/Hello-World/issues{/number}", | ||||
|     "keys_url": "http://api.github.com/repos/octocat/Hello-World/keys{/key_id}", | ||||
|     "labels_url": "http://api.github.com/repos/octocat/Hello-World/labels{/name}", | ||||
|     "languages_url": "http://api.github.com/repos/octocat/Hello-World/languages", | ||||
|     "merges_url": "http://api.github.com/repos/octocat/Hello-World/merges", | ||||
|     "milestones_url": "http://api.github.com/repos/octocat/Hello-World/milestones{/number}", | ||||
|     "notifications_url": "http://api.github.com/repos/octocat/Hello-World/notifications{?since,all,participating}", | ||||
|     "pulls_url": "http://api.github.com/repos/octocat/Hello-World/pulls{/number}", | ||||
|     "releases_url": "http://api.github.com/repos/octocat/Hello-World/releases{/id}", | ||||
|     "ssh_url": "git@github.com:octocat/Hello-World.git", | ||||
|     "stargazers_url": "http://api.github.com/repos/octocat/Hello-World/stargazers", | ||||
|     "statuses_url": "http://api.github.com/repos/octocat/Hello-World/statuses/{sha}", | ||||
|     "subscribers_url": "http://api.github.com/repos/octocat/Hello-World/subscribers", | ||||
|     "subscription_url": "http://api.github.com/repos/octocat/Hello-World/subscription", | ||||
|     "tags_url": "http://api.github.com/repos/octocat/Hello-World/tags", | ||||
|     "teams_url": "http://api.github.com/repos/octocat/Hello-World/teams", | ||||
|     "trees_url": "http://api.github.com/repos/octocat/Hello-World/git/trees{/sha}", | ||||
|     "clone_url": "https://github.com/octocat/Hello-World.git", | ||||
|     "mirror_url": "git:git.example.com/octocat/Hello-World", | ||||
|     "hooks_url": "http://api.github.com/repos/octocat/Hello-World/hooks", | ||||
|     "svn_url": "https://svn.github.com/octocat/Hello-World", | ||||
|     "homepage": "https://github.com", | ||||
|     "language": null, | ||||
|     "forks_count": 9, | ||||
|     "stargazers_count": 80, | ||||
|     "watchers_count": 80, | ||||
|     "size": 108, | ||||
|     "default_branch": "master", | ||||
|     "open_issues_count": 0, | ||||
|     "is_template": true, | ||||
|     "topics": [ | ||||
|       "octocat", | ||||
|       "atom", | ||||
|       "electron", | ||||
|       "api" | ||||
|     ], | ||||
|     "has_issues": true, | ||||
|     "has_projects": true, | ||||
|     "has_wiki": true, | ||||
|     "has_pages": false, | ||||
|     "has_downloads": true, | ||||
|     "archived": false, | ||||
|     "disabled": false, | ||||
|     "visibility": "public", | ||||
|     "pushed_at": "2011-01-26T19:06:43Z", | ||||
|     "created_at": "2011-01-26T19:01:12Z", | ||||
|     "updated_at": "2011-01-26T19:14:43Z", | ||||
|     "permissions": { | ||||
|       "admin": false, | ||||
|       "push": false, | ||||
|       "pull": true | ||||
|     }, | ||||
|     "allow_rebase_merge": true, | ||||
|     "template_repository": null, | ||||
|     "temp_clone_token": "ABTLWHOULUVAXGTRYU7OC2876QJ2O", | ||||
|     "allow_squash_merge": true, | ||||
|     "delete_branch_on_merge": true, | ||||
|     "allow_merge_commit": true, | ||||
|     "subscribers_count": 42, | ||||
|     "network_count": 0 | ||||
|   } | ||||
| } | ||||
| @ -1,8 +1,14 @@ | ||||
| import fs from 'fs'; | ||||
| import os from 'os'; | ||||
| import path from 'path'; | ||||
| 
 | ||||
| const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'docker-build-push-action-')); | ||||
| 
 | ||||
| process.env = Object.assign({}, process.env, { | ||||
|   RUNNER_TEMP: '/tmp/github_runner', | ||||
|   RUNNER_TOOL_CACHE: '/tmp/github_tool_cache', | ||||
|   TEMP: tmpDir, | ||||
|   GITHUB_REPOSITORY: 'docker/build-push-action', | ||||
|   GITHUB_RUN_ID: '123456789' | ||||
|   RUNNER_TEMP: path.join(tmpDir, 'runner-temp'), | ||||
|   RUNNER_TOOL_CACHE: path.join(tmpDir, 'runner-tool-cache') | ||||
| }) as { | ||||
|   [key: string]: string; | ||||
| }; | ||||
| @ -11,7 +17,6 @@ module.exports = { | ||||
|   clearMocks: false, | ||||
|   testEnvironment: 'node', | ||||
|   moduleFileExtensions: ['js', 'ts'], | ||||
|   setupFiles: ['dotenv/config'], | ||||
|   testMatch: ['**/*.test.ts'], | ||||
|   transform: { | ||||
|     '^.+\\.ts$': 'ts-jest' | ||||
| @ -19,5 +24,7 @@ module.exports = { | ||||
|   moduleNameMapper: { | ||||
|     '^csv-parse/sync': '<rootDir>/node_modules/csv-parse/dist/cjs/sync.cjs' | ||||
|   }, | ||||
|   collectCoverageFrom: ['src/**/{!(main.ts),}.ts'], | ||||
|   coveragePathIgnorePatterns: ['lib/', 'node_modules/', '__mocks__/', '__tests__/'], | ||||
|   verbose: true | ||||
| }; | ||||
|  | ||||
							
								
								
									
										11
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								package.json
									
									
									
									
									
								
							| @ -29,23 +29,16 @@ | ||||
|   "license": "Apache-2.0", | ||||
|   "dependencies": { | ||||
|     "@actions/core": "^1.10.0", | ||||
|     "@actions/exec": "^1.1.1", | ||||
|     "@actions/github": "^5.1.1", | ||||
|     "@docker/actions-toolkit": "^0.1.0-beta.14", | ||||
|     "csv-parse": "^5.3.5", | ||||
|     "handlebars": "^4.7.7", | ||||
|     "jwt-decode": "^3.1.2", | ||||
|     "semver": "^7.3.7", | ||||
|     "tmp": "^0.2.1" | ||||
|     "handlebars": "^4.7.7" | ||||
|   }, | ||||
|   "devDependencies": { | ||||
|     "@types/csv-parse": "^1.2.2", | ||||
|     "@types/node": "^16.11.26", | ||||
|     "@types/semver": "^7.3.9", | ||||
|     "@types/tmp": "^0.2.3", | ||||
|     "@typescript-eslint/eslint-plugin": "^5.14.0", | ||||
|     "@typescript-eslint/parser": "^5.14.0", | ||||
|     "@vercel/ncc": "^0.33.3", | ||||
|     "dotenv": "^16.0.0", | ||||
|     "eslint": "^8.11.0", | ||||
|     "eslint-config-prettier": "^8.5.0", | ||||
|     "eslint-plugin-jest": "^26.1.1", | ||||
|  | ||||
							
								
								
									
										282
									
								
								src/buildx.ts
									
									
									
									
									
								
							
							
						
						
									
										282
									
								
								src/buildx.ts
									
									
									
									
									
								
							| @ -1,282 +0,0 @@ | ||||
| import {parse} from 'csv-parse/sync'; | ||||
| import fs from 'fs'; | ||||
| import path from 'path'; | ||||
| import * as semver from 'semver'; | ||||
| import * as exec from '@actions/exec'; | ||||
| import * as context from './context'; | ||||
| 
 | ||||
| export type Builder = { | ||||
|   name?: string; | ||||
|   driver?: string; | ||||
|   nodes: Node[]; | ||||
| }; | ||||
| 
 | ||||
| export type Node = { | ||||
|   name?: string; | ||||
|   endpoint?: string; | ||||
|   'driver-opts'?: Array<string>; | ||||
|   status?: string; | ||||
|   'buildkitd-flags'?: string; | ||||
|   buildkit?: string; | ||||
|   platforms?: string; | ||||
| }; | ||||
| 
 | ||||
| export async function getImageIDFile(): Promise<string> { | ||||
|   return path.join(context.tmpDir(), 'iidfile').split(path.sep).join(path.posix.sep); | ||||
| } | ||||
| 
 | ||||
| export async function getImageID(): Promise<string | undefined> { | ||||
|   const iidFile = await getImageIDFile(); | ||||
|   if (!fs.existsSync(iidFile)) { | ||||
|     return undefined; | ||||
|   } | ||||
|   return fs.readFileSync(iidFile, {encoding: 'utf-8'}).trim(); | ||||
| } | ||||
| 
 | ||||
| export async function getMetadataFile(): Promise<string> { | ||||
|   return path.join(context.tmpDir(), 'metadata-file').split(path.sep).join(path.posix.sep); | ||||
| } | ||||
| 
 | ||||
| export async function getMetadata(): Promise<string | undefined> { | ||||
|   const metadataFile = await getMetadataFile(); | ||||
|   if (!fs.existsSync(metadataFile)) { | ||||
|     return undefined; | ||||
|   } | ||||
|   const content = fs.readFileSync(metadataFile, {encoding: 'utf-8'}).trim(); | ||||
|   if (content === 'null') { | ||||
|     return undefined; | ||||
|   } | ||||
|   return content; | ||||
| } | ||||
| 
 | ||||
| export async function getDigest(metadata: string | undefined): Promise<string | undefined> { | ||||
|   if (metadata === undefined) { | ||||
|     return undefined; | ||||
|   } | ||||
|   const metadataJSON = JSON.parse(metadata); | ||||
|   if (metadataJSON['containerimage.digest']) { | ||||
|     return metadataJSON['containerimage.digest']; | ||||
|   } | ||||
|   return undefined; | ||||
| } | ||||
| 
 | ||||
| export async function getSecretString(kvp: string): Promise<string> { | ||||
|   return getSecret(kvp, false); | ||||
| } | ||||
| 
 | ||||
| export async function getSecretFile(kvp: string): Promise<string> { | ||||
|   return getSecret(kvp, true); | ||||
| } | ||||
| 
 | ||||
| export async function getSecret(kvp: string, file: boolean): Promise<string> { | ||||
|   const delimiterIndex = kvp.indexOf('='); | ||||
|   const key = kvp.substring(0, delimiterIndex); | ||||
|   let value = kvp.substring(delimiterIndex + 1); | ||||
|   if (key.length == 0 || value.length == 0) { | ||||
|     throw new Error(`${kvp} is not a valid secret`); | ||||
|   } | ||||
| 
 | ||||
|   if (file) { | ||||
|     if (!fs.existsSync(value)) { | ||||
|       throw new Error(`secret file ${value} not found`); | ||||
|     } | ||||
|     value = fs.readFileSync(value, {encoding: 'utf-8'}); | ||||
|   } | ||||
| 
 | ||||
|   const secretFile = context.tmpNameSync({ | ||||
|     tmpdir: context.tmpDir() | ||||
|   }); | ||||
|   fs.writeFileSync(secretFile, value); | ||||
| 
 | ||||
|   return `id=${key},src=${secretFile}`; | ||||
| } | ||||
| 
 | ||||
| export function isLocalOrTarExporter(outputs: string[]): boolean { | ||||
|   const records = parse(outputs.join(`\n`), { | ||||
|     delimiter: ',', | ||||
|     trim: true, | ||||
|     columns: false, | ||||
|     relaxColumnCount: true | ||||
|   }); | ||||
|   for (const record of records) { | ||||
|     // Local if no type is defined
 | ||||
|     // https://github.com/docker/buildx/blob/d2bf42f8b4784d83fde17acb3ed84703ddc2156b/build/output.go#L29-L43
 | ||||
|     if (record.length == 1 && !record[0].startsWith('type=')) { | ||||
|       return true; | ||||
|     } | ||||
|     for (const [key, value] of record.map(chunk => chunk.split('=').map(item => item.trim()))) { | ||||
|       if (key == 'type' && (value == 'local' || value == 'tar')) { | ||||
|         return true; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|   return false; | ||||
| } | ||||
| 
 | ||||
| export function hasGitAuthToken(secrets: string[]): boolean { | ||||
|   for (const secret of secrets) { | ||||
|     if (secret.startsWith('GIT_AUTH_TOKEN=')) { | ||||
|       return true; | ||||
|     } | ||||
|   } | ||||
|   return false; | ||||
| } | ||||
| 
 | ||||
| export async function isAvailable(standalone?: boolean): Promise<boolean> { | ||||
|   const cmd = getCommand([], standalone); | ||||
|   return await exec | ||||
|     .getExecOutput(cmd.command, cmd.args, { | ||||
|       ignoreReturnCode: true, | ||||
|       silent: true | ||||
|     }) | ||||
|     .then(res => { | ||||
|       if (res.stderr.length > 0 && res.exitCode != 0) { | ||||
|         return false; | ||||
|       } | ||||
|       return res.exitCode == 0; | ||||
|     }) | ||||
|     // eslint-disable-next-line @typescript-eslint/no-unused-vars
 | ||||
|     .catch(error => { | ||||
|       return false; | ||||
|     }); | ||||
| } | ||||
| 
 | ||||
| export async function satisfiesBuildKitVersion(builderName: string, range: string, standalone?: boolean): Promise<boolean> { | ||||
|   const builderInspect = await inspect(builderName, standalone); | ||||
|   for (const node of builderInspect.nodes) { | ||||
|     if (!node.buildkit) { | ||||
|       return false; | ||||
|     } | ||||
|     // BuildKit version reported by moby is in the format of `v0.11.0-moby`
 | ||||
|     if (builderInspect.driver == 'docker' && !node.buildkit.endsWith('-moby')) { | ||||
|       return false; | ||||
|     } | ||||
|     const version = node.buildkit.replace(/-moby$/, ''); | ||||
|     if (!semver.satisfies(version, range)) { | ||||
|       return false; | ||||
|     } | ||||
|   } | ||||
|   return true; | ||||
| } | ||||
| 
 | ||||
| async function inspect(name: string, standalone?: boolean): Promise<Builder> { | ||||
|   const cmd = getCommand(['inspect', name], standalone); | ||||
|   return await exec | ||||
|     .getExecOutput(cmd.command, cmd.args, { | ||||
|       ignoreReturnCode: true, | ||||
|       silent: true | ||||
|     }) | ||||
|     .then(res => { | ||||
|       if (res.stderr.length > 0 && res.exitCode != 0) { | ||||
|         throw new Error(res.stderr.trim()); | ||||
|       } | ||||
|       return parseInspect(res.stdout); | ||||
|     }); | ||||
| } | ||||
| 
 | ||||
| async function parseInspect(data: string): Promise<Builder> { | ||||
|   const builder: Builder = { | ||||
|     nodes: [] | ||||
|   }; | ||||
|   let node: Node = {}; | ||||
|   for (const line of data.trim().split(`\n`)) { | ||||
|     const [key, ...rest] = line.split(':'); | ||||
|     const value = rest.map(v => v.trim()).join(':'); | ||||
|     if (key.length == 0 || value.length == 0) { | ||||
|       continue; | ||||
|     } | ||||
|     switch (key.toLowerCase()) { | ||||
|       case 'name': { | ||||
|         if (builder.name == undefined) { | ||||
|           builder.name = value; | ||||
|         } else { | ||||
|           if (Object.keys(node).length > 0) { | ||||
|             builder.nodes.push(node); | ||||
|             node = {}; | ||||
|           } | ||||
|           node.name = value; | ||||
|         } | ||||
|         break; | ||||
|       } | ||||
|       case 'driver': { | ||||
|         builder.driver = value; | ||||
|         break; | ||||
|       } | ||||
|       case 'endpoint': { | ||||
|         node.endpoint = value; | ||||
|         break; | ||||
|       } | ||||
|       case 'driver options': { | ||||
|         node['driver-opts'] = (value.match(/(\w+)="([^"]*)"/g) || []).map(v => v.replace(/^(.*)="(.*)"$/g, '$1=$2')); | ||||
|         break; | ||||
|       } | ||||
|       case 'status': { | ||||
|         node.status = value; | ||||
|         break; | ||||
|       } | ||||
|       case 'flags': { | ||||
|         node['buildkitd-flags'] = value; | ||||
|         break; | ||||
|       } | ||||
|       case 'buildkit': { | ||||
|         node.buildkit = value; | ||||
|         break; | ||||
|       } | ||||
|       case 'platforms': { | ||||
|         let platforms: Array<string> = []; | ||||
|         // if a preferred platform is being set then use only these
 | ||||
|         // https://docs.docker.com/engine/reference/commandline/buildx_inspect/#get-information-about-a-builder-instance
 | ||||
|         if (value.includes('*')) { | ||||
|           for (const platform of value.split(', ')) { | ||||
|             if (platform.includes('*')) { | ||||
|               platforms.push(platform.replace('*', '')); | ||||
|             } | ||||
|           } | ||||
|         } else { | ||||
|           // otherwise set all platforms available
 | ||||
|           platforms = value.split(', '); | ||||
|         } | ||||
|         node.platforms = platforms.join(','); | ||||
|         break; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|   if (Object.keys(node).length > 0) { | ||||
|     builder.nodes.push(node); | ||||
|   } | ||||
|   return builder; | ||||
| } | ||||
| 
 | ||||
| export async function getVersion(standalone?: boolean): Promise<string> { | ||||
|   const cmd = getCommand(['version'], standalone); | ||||
|   return await exec | ||||
|     .getExecOutput(cmd.command, cmd.args, { | ||||
|       ignoreReturnCode: true, | ||||
|       silent: true | ||||
|     }) | ||||
|     .then(res => { | ||||
|       if (res.stderr.length > 0 && res.exitCode != 0) { | ||||
|         throw new Error(res.stderr.trim()); | ||||
|       } | ||||
|       return parseVersion(res.stdout.trim()); | ||||
|     }); | ||||
| } | ||||
| 
 | ||||
| export function parseVersion(stdout: string): string { | ||||
|   const matches = /\sv?([0-9a-f]{7}|[0-9.]+)/.exec(stdout); | ||||
|   if (!matches) { | ||||
|     throw new Error(`Cannot parse buildx version`); | ||||
|   } | ||||
|   return matches[1]; | ||||
| } | ||||
| 
 | ||||
| export function satisfies(version: string, range: string): boolean { | ||||
|   return semver.satisfies(version, range) || /^[0-9a-f]{7}$/.exec(version) !== null; | ||||
| } | ||||
| 
 | ||||
| export function getCommand(args: Array<string>, standalone?: boolean) { | ||||
|   return { | ||||
|     command: standalone ? 'buildx' : 'docker', | ||||
|     args: standalone ? args : ['buildx', ...args] | ||||
|   }; | ||||
| } | ||||
							
								
								
									
										230
									
								
								src/context.ts
									
									
									
									
									
								
							
							
						
						
									
										230
									
								
								src/context.ts
									
									
									
									
									
								
							| @ -1,14 +1,11 @@ | ||||
| import * as fs from 'fs'; | ||||
| import * as os from 'os'; | ||||
| import * as path from 'path'; | ||||
| import * as tmp from 'tmp'; | ||||
| import * as buildx from './buildx'; | ||||
| import * as core from '@actions/core'; | ||||
| import * as github from '@actions/github'; | ||||
| import {parse} from 'csv-parse/sync'; | ||||
| import * as handlebars from 'handlebars'; | ||||
| 
 | ||||
| let _defaultContext, _tmpDir: string; | ||||
| import {Context} from '@docker/actions-toolkit/lib/context'; | ||||
| import {GitHub} from '@docker/actions-toolkit/lib/github'; | ||||
| import {Inputs as BuildxInputs} from '@docker/actions-toolkit/lib/buildx/inputs'; | ||||
| import {Toolkit} from '@docker/actions-toolkit/lib/toolkit'; | ||||
| import {Util} from '@docker/actions-toolkit/lib/util'; | ||||
| 
 | ||||
| export interface Inputs { | ||||
|   addHosts: string[]; | ||||
| @ -43,105 +40,78 @@ export interface Inputs { | ||||
|   githubToken: string; | ||||
| } | ||||
| 
 | ||||
| export function defaultContext(): string { | ||||
|   if (!_defaultContext) { | ||||
|     let ref = github.context.ref; | ||||
|     if (github.context.sha && ref && !ref.startsWith('refs/')) { | ||||
|       ref = `refs/heads/${github.context.ref}`; | ||||
|     } | ||||
|     if (github.context.sha && !ref.startsWith(`refs/pull/`)) { | ||||
|       ref = github.context.sha; | ||||
|     } | ||||
|     _defaultContext = `${process.env.GITHUB_SERVER_URL || 'https://github.com'}/${github.context.repo.owner}/${github.context.repo.repo}.git#${ref}`; | ||||
|   } | ||||
|   return _defaultContext; | ||||
| } | ||||
| 
 | ||||
| export function tmpDir(): string { | ||||
|   if (!_tmpDir) { | ||||
|     _tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'docker-build-push-')).split(path.sep).join(path.posix.sep); | ||||
|   } | ||||
|   return _tmpDir; | ||||
| } | ||||
| 
 | ||||
| export function tmpNameSync(options?: tmp.TmpNameOptions): string { | ||||
|   return tmp.tmpNameSync(options); | ||||
| } | ||||
| 
 | ||||
| export function provenanceBuilderID(): string { | ||||
|   return `${process.env.GITHUB_SERVER_URL || 'https://github.com'}/${github.context.repo.owner}/${github.context.repo.repo}/actions/runs/${github.context.runId}`; | ||||
| } | ||||
| 
 | ||||
| export async function getInputs(defaultContext: string): Promise<Inputs> { | ||||
| export async function getInputs(): Promise<Inputs> { | ||||
|   return { | ||||
|     addHosts: await getInputList('add-hosts'), | ||||
|     allow: await getInputList('allow'), | ||||
|     attests: await getInputList('attests', true), | ||||
|     buildArgs: await getInputList('build-args', true), | ||||
|     buildContexts: await getInputList('build-contexts', true), | ||||
|     addHosts: Util.getInputList('add-hosts'), | ||||
|     allow: Util.getInputList('allow'), | ||||
|     attests: Util.getInputList('attests', {ignoreComma: true}), | ||||
|     buildArgs: Util.getInputList('build-args', {ignoreComma: true}), | ||||
|     buildContexts: Util.getInputList('build-contexts', {ignoreComma: true}), | ||||
|     builder: core.getInput('builder'), | ||||
|     cacheFrom: await getInputList('cache-from', true), | ||||
|     cacheTo: await getInputList('cache-to', true), | ||||
|     cacheFrom: Util.getInputList('cache-from', {ignoreComma: true}), | ||||
|     cacheTo: Util.getInputList('cache-to', {ignoreComma: true}), | ||||
|     cgroupParent: core.getInput('cgroup-parent'), | ||||
|     context: core.getInput('context') || defaultContext, | ||||
|     context: core.getInput('context') || Context.gitContext(), | ||||
|     file: core.getInput('file'), | ||||
|     labels: await getInputList('labels', true), | ||||
|     labels: Util.getInputList('labels', {ignoreComma: true}), | ||||
|     load: core.getBooleanInput('load'), | ||||
|     network: core.getInput('network'), | ||||
|     noCache: core.getBooleanInput('no-cache'), | ||||
|     noCacheFilters: await getInputList('no-cache-filters'), | ||||
|     outputs: await getInputList('outputs', true), | ||||
|     platforms: await getInputList('platforms'), | ||||
|     noCacheFilters: Util.getInputList('no-cache-filters'), | ||||
|     outputs: Util.getInputList('outputs', {ignoreComma: true}), | ||||
|     platforms: Util.getInputList('platforms'), | ||||
|     provenance: getProvenanceInput('provenance'), | ||||
|     pull: core.getBooleanInput('pull'), | ||||
|     push: core.getBooleanInput('push'), | ||||
|     sbom: core.getInput('sbom'), | ||||
|     secrets: await getInputList('secrets', true), | ||||
|     secretFiles: await getInputList('secret-files', true), | ||||
|     secrets: Util.getInputList('secrets', {ignoreComma: true}), | ||||
|     secretFiles: Util.getInputList('secret-files', {ignoreComma: true}), | ||||
|     shmSize: core.getInput('shm-size'), | ||||
|     ssh: await getInputList('ssh'), | ||||
|     tags: await getInputList('tags'), | ||||
|     ssh: Util.getInputList('ssh'), | ||||
|     tags: Util.getInputList('tags'), | ||||
|     target: core.getInput('target'), | ||||
|     ulimit: await getInputList('ulimit', true), | ||||
|     ulimit: Util.getInputList('ulimit', {ignoreComma: true}), | ||||
|     githubToken: core.getInput('github-token') | ||||
|   }; | ||||
| } | ||||
| 
 | ||||
| export async function getArgs(inputs: Inputs, defaultContext: string, buildxVersion: string, standalone?: boolean): Promise<Array<string>> { | ||||
|   const context = handlebars.compile(inputs.context)({defaultContext}); | ||||
| export async function getArgs(inputs: Inputs, toolkit: Toolkit): Promise<Array<string>> { | ||||
|   const context = handlebars.compile(inputs.context)({ | ||||
|     defaultContext: Context.gitContext() | ||||
|   }); | ||||
|   // prettier-ignore
 | ||||
|   return [ | ||||
|     ...await getBuildArgs(inputs, defaultContext, context, buildxVersion, standalone), | ||||
|     ...await getCommonArgs(inputs, buildxVersion), | ||||
|     ...await getBuildArgs(inputs, context, toolkit), | ||||
|     ...await getCommonArgs(inputs, toolkit), | ||||
|     context | ||||
|   ]; | ||||
| } | ||||
| 
 | ||||
| async function getBuildArgs(inputs: Inputs, defaultContext: string, context: string, buildxVersion: string, standalone?: boolean): Promise<Array<string>> { | ||||
| async function getBuildArgs(inputs: Inputs, context: string, toolkit: Toolkit): Promise<Array<string>> { | ||||
|   const args: Array<string> = ['build']; | ||||
|   await asyncForEach(inputs.addHosts, async addHost => { | ||||
|   await Util.asyncForEach(inputs.addHosts, async addHost => { | ||||
|     args.push('--add-host', addHost); | ||||
|   }); | ||||
|   if (inputs.allow.length > 0) { | ||||
|     args.push('--allow', inputs.allow.join(',')); | ||||
|   } | ||||
|   if (buildx.satisfies(buildxVersion, '>=0.10.0')) { | ||||
|     await asyncForEach(inputs.attests, async attest => { | ||||
|   if (await toolkit.buildx.versionSatisfies('>=0.10.0')) { | ||||
|     await Util.asyncForEach(inputs.attests, async attest => { | ||||
|       args.push('--attest', attest); | ||||
|     }); | ||||
|   } | ||||
|   await asyncForEach(inputs.buildArgs, async buildArg => { | ||||
|   await Util.asyncForEach(inputs.buildArgs, async buildArg => { | ||||
|     args.push('--build-arg', buildArg); | ||||
|   }); | ||||
|   if (buildx.satisfies(buildxVersion, '>=0.8.0')) { | ||||
|     await asyncForEach(inputs.buildContexts, async buildContext => { | ||||
|   if (await toolkit.buildx.versionSatisfies('>=0.8.0')) { | ||||
|     await Util.asyncForEach(inputs.buildContexts, async buildContext => { | ||||
|       args.push('--build-context', buildContext); | ||||
|     }); | ||||
|   } | ||||
|   await asyncForEach(inputs.cacheFrom, async cacheFrom => { | ||||
|   await Util.asyncForEach(inputs.cacheFrom, async cacheFrom => { | ||||
|     args.push('--cache-from', cacheFrom); | ||||
|   }); | ||||
|   await asyncForEach(inputs.cacheTo, async cacheTo => { | ||||
|   await Util.asyncForEach(inputs.cacheTo, async cacheTo => { | ||||
|     args.push('--cache-to', cacheTo); | ||||
|   }); | ||||
|   if (inputs.cgroupParent) { | ||||
| @ -150,29 +120,29 @@ async function getBuildArgs(inputs: Inputs, defaultContext: string, context: str | ||||
|   if (inputs.file) { | ||||
|     args.push('--file', inputs.file); | ||||
|   } | ||||
|   if (!buildx.isLocalOrTarExporter(inputs.outputs) && (inputs.platforms.length == 0 || buildx.satisfies(buildxVersion, '>=0.4.2'))) { | ||||
|     args.push('--iidfile', await buildx.getImageIDFile()); | ||||
|   if (!BuildxInputs.hasLocalExporter(inputs.outputs) && !BuildxInputs.hasTarExporter(inputs.outputs) && (inputs.platforms.length == 0 || (await toolkit.buildx.versionSatisfies('>=0.4.2')))) { | ||||
|     args.push('--iidfile', toolkit.buildx.inputs.getBuildImageIDFilePath()); | ||||
|   } | ||||
|   await asyncForEach(inputs.labels, async label => { | ||||
|   await Util.asyncForEach(inputs.labels, async label => { | ||||
|     args.push('--label', label); | ||||
|   }); | ||||
|   await asyncForEach(inputs.noCacheFilters, async noCacheFilter => { | ||||
|   await Util.asyncForEach(inputs.noCacheFilters, async noCacheFilter => { | ||||
|     args.push('--no-cache-filter', noCacheFilter); | ||||
|   }); | ||||
|   await asyncForEach(inputs.outputs, async output => { | ||||
|   await Util.asyncForEach(inputs.outputs, async output => { | ||||
|     args.push('--output', output); | ||||
|   }); | ||||
|   if (inputs.platforms.length > 0) { | ||||
|     args.push('--platform', inputs.platforms.join(',')); | ||||
|   } | ||||
|   if (buildx.satisfies(buildxVersion, '>=0.10.0')) { | ||||
|   if (await toolkit.buildx.versionSatisfies('>=0.10.0')) { | ||||
|     if (inputs.provenance) { | ||||
|       args.push('--provenance', inputs.provenance); | ||||
|     } else if ((await buildx.satisfiesBuildKitVersion(inputs.builder, '>=0.11.0', standalone)) && !hasDockerExport(inputs)) { | ||||
|     } else if ((await toolkit.buildkit.versionSatisfies(inputs.builder, '>=0.11.0')) && !BuildxInputs.hasDockerExporter(inputs.outputs, inputs.load)) { | ||||
|       // if provenance not specified and BuildKit version compatible for
 | ||||
|       // attestation, set default provenance. Also needs to make sure user
 | ||||
|       // doesn't want to explicitly load the image to docker.
 | ||||
|       if (fromPayload('repository.private') !== false) { | ||||
|       if (GitHub.context.payload.repository?.private ?? false) { | ||||
|         // if this is a private repository, we set the default provenance
 | ||||
|         // attributes being set in buildx: https://github.com/docker/buildx/blob/fb27e3f919dcbf614d7126b10c2bc2d0b1927eb6/build/build.go#L603
 | ||||
|         args.push('--provenance', getProvenanceAttrs(`mode=min,inline-only=true`)); | ||||
| @ -185,42 +155,42 @@ async function getBuildArgs(inputs: Inputs, defaultContext: string, context: str | ||||
|       args.push('--sbom', inputs.sbom); | ||||
|     } | ||||
|   } | ||||
|   await asyncForEach(inputs.secrets, async secret => { | ||||
|   await Util.asyncForEach(inputs.secrets, async secret => { | ||||
|     try { | ||||
|       args.push('--secret', await buildx.getSecretString(secret)); | ||||
|       args.push('--secret', toolkit.buildx.inputs.resolveBuildSecretString(secret)); | ||||
|     } catch (err) { | ||||
|       core.warning(err.message); | ||||
|     } | ||||
|   }); | ||||
|   await asyncForEach(inputs.secretFiles, async secretFile => { | ||||
|   await Util.asyncForEach(inputs.secretFiles, async secretFile => { | ||||
|     try { | ||||
|       args.push('--secret', await buildx.getSecretFile(secretFile)); | ||||
|       args.push('--secret', toolkit.buildx.inputs.resolveBuildSecretFile(secretFile)); | ||||
|     } catch (err) { | ||||
|       core.warning(err.message); | ||||
|     } | ||||
|   }); | ||||
|   if (inputs.githubToken && !buildx.hasGitAuthToken(inputs.secrets) && context.startsWith(defaultContext)) { | ||||
|     args.push('--secret', await buildx.getSecretString(`GIT_AUTH_TOKEN=${inputs.githubToken}`)); | ||||
|   if (inputs.githubToken && !BuildxInputs.hasGitAuthTokenSecret(inputs.secrets) && context.startsWith(Context.gitContext())) { | ||||
|     args.push('--secret', toolkit.buildx.inputs.resolveBuildSecretString(`GIT_AUTH_TOKEN=${inputs.githubToken}`)); | ||||
|   } | ||||
|   if (inputs.shmSize) { | ||||
|     args.push('--shm-size', inputs.shmSize); | ||||
|   } | ||||
|   await asyncForEach(inputs.ssh, async ssh => { | ||||
|   await Util.asyncForEach(inputs.ssh, async ssh => { | ||||
|     args.push('--ssh', ssh); | ||||
|   }); | ||||
|   await asyncForEach(inputs.tags, async tag => { | ||||
|   await Util.asyncForEach(inputs.tags, async tag => { | ||||
|     args.push('--tag', tag); | ||||
|   }); | ||||
|   if (inputs.target) { | ||||
|     args.push('--target', inputs.target); | ||||
|   } | ||||
|   await asyncForEach(inputs.ulimit, async ulimit => { | ||||
|   await Util.asyncForEach(inputs.ulimit, async ulimit => { | ||||
|     args.push('--ulimit', ulimit); | ||||
|   }); | ||||
|   return args; | ||||
| } | ||||
| 
 | ||||
| async function getCommonArgs(inputs: Inputs, buildxVersion: string): Promise<Array<string>> { | ||||
| async function getCommonArgs(inputs: Inputs, toolkit: Toolkit): Promise<Array<string>> { | ||||
|   const args: Array<string> = []; | ||||
|   if (inputs.builder) { | ||||
|     args.push('--builder', inputs.builder); | ||||
| @ -228,8 +198,8 @@ async function getCommonArgs(inputs: Inputs, buildxVersion: string): Promise<Arr | ||||
|   if (inputs.load) { | ||||
|     args.push('--load'); | ||||
|   } | ||||
|   if (buildx.satisfies(buildxVersion, '>=0.6.0')) { | ||||
|     args.push('--metadata-file', await buildx.getMetadataFile()); | ||||
|   if (await toolkit.buildx.versionSatisfies('>=0.6.0')) { | ||||
|     args.push('--metadata-file', toolkit.buildx.inputs.getBuildMetadataFilePath()); | ||||
|   } | ||||
|   if (inputs.network) { | ||||
|     args.push('--network', inputs.network); | ||||
| @ -246,68 +216,14 @@ async function getCommonArgs(inputs: Inputs, buildxVersion: string): Promise<Arr | ||||
|   return args; | ||||
| } | ||||
| 
 | ||||
| export async function getInputList(name: string, ignoreComma?: boolean): Promise<string[]> { | ||||
|   const res: Array<string> = []; | ||||
| 
 | ||||
|   const items = core.getInput(name); | ||||
|   if (items == '') { | ||||
|     return res; | ||||
|   } | ||||
| 
 | ||||
|   const records = await parse(items, { | ||||
|     columns: false, | ||||
|     relaxQuotes: true, | ||||
|     relaxColumnCount: true, | ||||
|     skipEmptyLines: true | ||||
|   }); | ||||
| 
 | ||||
|   for (const record of records as Array<string[]>) { | ||||
|     if (record.length == 1) { | ||||
|       res.push(record[0]); | ||||
|       continue; | ||||
|     } else if (!ignoreComma) { | ||||
|       res.push(...record); | ||||
|       continue; | ||||
|     } | ||||
|     res.push(record.join(',')); | ||||
|   } | ||||
| 
 | ||||
|   return res.filter(item => item).map(pat => pat.trim()); | ||||
| } | ||||
| 
 | ||||
| export const asyncForEach = async (array, callback) => { | ||||
|   for (let index = 0; index < array.length; index++) { | ||||
|     await callback(array[index], index, array); | ||||
|   } | ||||
| }; | ||||
| 
 | ||||
| // eslint-disable-next-line @typescript-eslint/no-explicit-any
 | ||||
| function fromPayload(path: string): any { | ||||
|   return select(github.context.payload, path); | ||||
| } | ||||
| 
 | ||||
| // eslint-disable-next-line @typescript-eslint/no-explicit-any
 | ||||
| function select(obj: any, path: string): any { | ||||
|   if (!obj) { | ||||
|     return undefined; | ||||
|   } | ||||
|   const i = path.indexOf('.'); | ||||
|   if (i < 0) { | ||||
|     return obj[path]; | ||||
|   } | ||||
|   const key = path.slice(0, i); | ||||
|   return select(obj[key], path.slice(i + 1)); | ||||
| } | ||||
| 
 | ||||
| function getProvenanceInput(name: string): string { | ||||
|   const input = core.getInput(name); | ||||
|   if (!input) { | ||||
|     // if input is not set, default values will be set later.
 | ||||
|     return input; | ||||
|   } | ||||
|   const builderID = provenanceBuilderID(); | ||||
|   try { | ||||
|     return core.getBooleanInput(name) ? `builder-id=${builderID}` : 'false'; | ||||
|     return core.getBooleanInput(name) ? `builder-id=${Context.provenanceBuilderID()}` : 'false'; | ||||
|   } catch (err) { | ||||
|     // not a valid boolean, so we assume it's a string
 | ||||
|     return getProvenanceAttrs(input); | ||||
| @ -315,7 +231,6 @@ function getProvenanceInput(name: string): string { | ||||
| } | ||||
| 
 | ||||
| function getProvenanceAttrs(input: string): string { | ||||
|   const builderID = provenanceBuilderID(); | ||||
|   // parse attributes from input
 | ||||
|   const fields = parse(input, { | ||||
|     relaxColumnCount: true, | ||||
| @ -332,30 +247,5 @@ function getProvenanceAttrs(input: string): string { | ||||
|     } | ||||
|   } | ||||
|   // if not add builder-id attribute
 | ||||
|   return `${input},builder-id=${builderID}`; | ||||
| } | ||||
| 
 | ||||
| function hasDockerExport(inputs: Inputs): boolean { | ||||
|   if (inputs.load) { | ||||
|     return true; | ||||
|   } | ||||
|   for (const output of inputs.outputs) { | ||||
|     const fields = parse(output, { | ||||
|       relaxColumnCount: true, | ||||
|       skipEmptyLines: true | ||||
|     })[0]; | ||||
|     for (const field of fields) { | ||||
|       const parts = field | ||||
|         .toString() | ||||
|         .split(/(?<=^[^=]+?)=/) | ||||
|         .map(item => item.trim()); | ||||
|       if (parts.length != 2) { | ||||
|         continue; | ||||
|       } | ||||
|       if (parts[0] == 'type' && parts[1] == 'docker') { | ||||
|         return true; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|   return false; | ||||
|   return `${input},builder-id=${Context.provenanceBuilderID()}`; | ||||
| } | ||||
|  | ||||
| @ -1,19 +0,0 @@ | ||||
| import * as exec from '@actions/exec'; | ||||
| 
 | ||||
| export async function isAvailable(): Promise<boolean> { | ||||
|   return await exec | ||||
|     .getExecOutput('docker', undefined, { | ||||
|       ignoreReturnCode: true, | ||||
|       silent: true | ||||
|     }) | ||||
|     .then(res => { | ||||
|       if (res.stderr.length > 0 && res.exitCode != 0) { | ||||
|         return false; | ||||
|       } | ||||
|       return res.exitCode == 0; | ||||
|     }) | ||||
|     // eslint-disable-next-line @typescript-eslint/no-unused-vars
 | ||||
|     .catch(error => { | ||||
|       return false; | ||||
|     }); | ||||
| } | ||||
| @ -1,9 +0,0 @@ | ||||
| import jwt_decode, {JwtPayload} from 'jwt-decode'; | ||||
| 
 | ||||
| interface Jwt extends JwtPayload { | ||||
|   ac?: string; | ||||
| } | ||||
| 
 | ||||
| export const parseRuntimeToken = (token: string): Jwt => { | ||||
|   return jwt_decode<Jwt>(token); | ||||
| }; | ||||
							
								
								
									
										101
									
								
								src/main.ts
									
									
									
									
									
								
							
							
						
						
									
										101
									
								
								src/main.ts
									
									
									
									
									
								
							| @ -1,71 +1,62 @@ | ||||
| import * as fs from 'fs'; | ||||
| import * as buildx from './buildx'; | ||||
| import * as context from './context'; | ||||
| import * as docker from './docker'; | ||||
| import * as github from './github'; | ||||
| import * as stateHelper from './state-helper'; | ||||
| import * as core from '@actions/core'; | ||||
| import * as exec from '@actions/exec'; | ||||
| import * as actionsToolkit from '@docker/actions-toolkit'; | ||||
| import {Context} from '@docker/actions-toolkit/lib/context'; | ||||
| import {Docker} from '@docker/actions-toolkit/lib/docker'; | ||||
| import {Exec} from '@docker/actions-toolkit/lib/exec'; | ||||
| import {GitHub} from '@docker/actions-toolkit/lib/github'; | ||||
| import {Toolkit} from '@docker/actions-toolkit/lib/toolkit'; | ||||
| 
 | ||||
| async function run(): Promise<void> { | ||||
| import * as context from './context'; | ||||
| 
 | ||||
| actionsToolkit.run( | ||||
|   // main
 | ||||
|   async () => { | ||||
|     const inputs: context.Inputs = await context.getInputs(); | ||||
|     const toolkit = new Toolkit(); | ||||
| 
 | ||||
|     await core.group(`GitHub Actions runtime token ACs`, async () => { | ||||
|       try { | ||||
|     const defContext = context.defaultContext(); | ||||
|     const inputs: context.Inputs = await context.getInputs(defContext); | ||||
| 
 | ||||
|     // standalone if docker cli not available
 | ||||
|     const standalone = !(await docker.isAvailable()); | ||||
| 
 | ||||
|     await core.group(`GitHub Actions runtime token access controls`, async () => { | ||||
|       const actionsRuntimeToken = process.env['ACTIONS_RUNTIME_TOKEN']; | ||||
|       if (actionsRuntimeToken) { | ||||
|         core.info(JSON.stringify(JSON.parse(github.parseRuntimeToken(actionsRuntimeToken).ac as string), undefined, 2)); | ||||
|       } else { | ||||
|         core.info(`ACTIONS_RUNTIME_TOKEN not set`); | ||||
|         await GitHub.printActionsRuntimeTokenACs(); | ||||
|       } catch (e) { | ||||
|         core.warning(e.message); | ||||
|       } | ||||
|     }); | ||||
| 
 | ||||
|     core.startGroup(`Docker info`); | ||||
|     if (standalone) { | ||||
|       core.info(`Docker info skipped in standalone mode`); | ||||
|     } else { | ||||
|       await exec.exec('docker', ['version'], { | ||||
|         failOnStdErr: false | ||||
|       }); | ||||
|       await exec.exec('docker', ['info'], { | ||||
|         failOnStdErr: false | ||||
|       }); | ||||
|     await core.group(`Docker info`, async () => { | ||||
|       try { | ||||
|         await Docker.printVersion(); | ||||
|         await Docker.printInfo(); | ||||
|       } catch (e) { | ||||
|         core.info(e.message); | ||||
|       } | ||||
|     core.endGroup(); | ||||
|     }); | ||||
| 
 | ||||
|     if (!(await buildx.isAvailable(standalone))) { | ||||
|     if (!(await toolkit.buildx.isAvailable())) { | ||||
|       core.setFailed(`Docker buildx is required. See https://github.com/docker/setup-buildx-action to set up buildx.`); | ||||
|       return; | ||||
|     } | ||||
|     stateHelper.setTmpDir(context.tmpDir()); | ||||
| 
 | ||||
|     const buildxVersion = await buildx.getVersion(standalone); | ||||
|     stateHelper.setTmpDir(Context.tmpDir()); | ||||
| 
 | ||||
|     await core.group(`Buildx version`, async () => { | ||||
|       const versionCmd = buildx.getCommand(['version'], standalone); | ||||
|       await exec.exec(versionCmd.command, versionCmd.args, { | ||||
|         failOnStdErr: false | ||||
|       }); | ||||
|       await toolkit.buildx.printVersion(); | ||||
|     }); | ||||
| 
 | ||||
|     const args: string[] = await context.getArgs(inputs, defContext, buildxVersion, standalone); | ||||
|     const buildCmd = buildx.getCommand(args, standalone); | ||||
|     await exec | ||||
|       .getExecOutput(buildCmd.command, buildCmd.args, { | ||||
|     const args: string[] = await context.getArgs(inputs, toolkit); | ||||
|     const buildCmd = await toolkit.buildx.getCommand(args); | ||||
|     await Exec.getExecOutput(buildCmd.command, buildCmd.args, { | ||||
|       ignoreReturnCode: true | ||||
|       }) | ||||
|       .then(res => { | ||||
|     }).then(res => { | ||||
|       if (res.stderr.length > 0 && res.exitCode != 0) { | ||||
|         throw new Error(`buildx failed with: ${res.stderr.match(/(.*)\s*$/)?.[0]?.trim() ?? 'unknown error'}`); | ||||
|       } | ||||
|     }); | ||||
| 
 | ||||
|     const imageID = await buildx.getImageID(); | ||||
|     const metadata = await buildx.getMetadata(); | ||||
|     const digest = await buildx.getDigest(metadata); | ||||
|     const imageID = await toolkit.buildx.inputs.resolveBuildImageID(); | ||||
|     const metadata = await toolkit.buildx.inputs.resolveBuildMetadata(); | ||||
|     const digest = await toolkit.buildx.inputs.resolveDigest(); | ||||
| 
 | ||||
|     if (imageID) { | ||||
|       await core.group(`ImageID`, async () => { | ||||
| @ -85,21 +76,13 @@ async function run(): Promise<void> { | ||||
|         core.setOutput('metadata', metadata); | ||||
|       }); | ||||
|     } | ||||
|   } catch (error) { | ||||
|     core.setFailed(error.message); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| async function cleanup(): Promise<void> { | ||||
|   }, | ||||
|   // post
 | ||||
|   async () => { | ||||
|     if (stateHelper.tmpDir.length > 0) { | ||||
|     core.startGroup(`Removing temp folder ${stateHelper.tmpDir}`); | ||||
|       await core.group(`Removing temp folder ${stateHelper.tmpDir}`, async () => { | ||||
|         fs.rmSync(stateHelper.tmpDir, {recursive: true}); | ||||
|     core.endGroup(); | ||||
|       }); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
| if (!stateHelper.IsPost) { | ||||
|   run(); | ||||
| } else { | ||||
|   cleanup(); | ||||
| } | ||||
| ); | ||||
|  | ||||
| @ -1,12 +1,7 @@ | ||||
| import * as core from '@actions/core'; | ||||
| 
 | ||||
| export const IsPost = !!process.env['STATE_isPost']; | ||||
| export const tmpDir = process.env['STATE_tmpDir'] || ''; | ||||
| 
 | ||||
| export function setTmpDir(tmpDir: string) { | ||||
|   core.saveState('tmpDir', tmpDir); | ||||
| } | ||||
| 
 | ||||
| if (!IsPost) { | ||||
|   core.saveState('isPost', 'true'); | ||||
| } | ||||
|  | ||||
| @ -1,19 +1,22 @@ | ||||
| { | ||||
|   "compilerOptions": { | ||||
|     "esModuleInterop": true, | ||||
|     "target": "es6", | ||||
|     "module": "commonjs", | ||||
|     "strict": true, | ||||
|     "newLine": "lf", | ||||
|     "outDir": "./lib", | ||||
|     "rootDir": "./src", | ||||
|     "esModuleInterop": true, | ||||
|     "forceConsistentCasingInFileNames": true, | ||||
|     "strict": true, | ||||
|     "noImplicitAny": false, | ||||
|     "resolveJsonModule": true, | ||||
|     "useUnknownInCatchVariables": false, | ||||
|   }, | ||||
|   "exclude": [ | ||||
|     "./__mocks__/**/*", | ||||
|     "./__tests__/**/*", | ||||
|     "./lib/**/*", | ||||
|     "node_modules", | ||||
|     "**/*.test.ts", | ||||
|     "jest.config.ts" | ||||
|   ] | ||||
| } | ||||
|  | ||||
							
								
								
									
										68
									
								
								yarn.lock
									
									
									
									
									
								
							
							
						
						
									
										68
									
								
								yarn.lock
									
									
									
									
									
								
							| @ -2,7 +2,7 @@ | ||||
| # yarn lockfile v1 | ||||
| 
 | ||||
| 
 | ||||
| "@actions/core@^1.10.0": | ||||
| "@actions/core@^1.10.0", "@actions/core@^1.2.6": | ||||
|   version "1.10.0" | ||||
|   resolved "https://registry.yarnpkg.com/@actions/core/-/core-1.10.0.tgz#44551c3c71163949a2f06e94d9ca2157a0cfac4f" | ||||
|   integrity sha512-2aZDDa3zrrZbP5ZYg159sNoLRb61nQ7awl5pSvIq5Qpj81vwDzdMRKzkWJGJuwVvWpvZKx7vspJALyvaaIQyug== | ||||
| @ -10,7 +10,7 @@ | ||||
|     "@actions/http-client" "^2.0.1" | ||||
|     uuid "^8.3.2" | ||||
| 
 | ||||
| "@actions/exec@^1.1.1": | ||||
| "@actions/exec@^1.0.0", "@actions/exec@^1.1.1": | ||||
|   version "1.1.1" | ||||
|   resolved "https://registry.yarnpkg.com/@actions/exec/-/exec-1.1.1.tgz#2e43f28c54022537172819a7cf886c844221a611" | ||||
|   integrity sha512-+sCcHHbVdk93a0XT19ECtO/gIXoxvdsgQLzb2fE2/5sIZmWQuluYyjPQtrtTHdU1YzTZ7bAPN4sITq2xi1679w== | ||||
| @ -39,6 +39,23 @@ | ||||
|   resolved "https://registry.yarnpkg.com/@actions/io/-/io-1.0.2.tgz#2f614b6e69ce14d191180451eb38e6576a6e6b27" | ||||
|   integrity sha512-J8KuFqVPr3p6U8W93DOXlXW6zFvrQAJANdS+vw0YhusLIq+bszW8zmK2Fh1C2kDPX8FMvwIl1OUcFgvJoXLbAg== | ||||
| 
 | ||||
| "@actions/io@^1.1.1", "@actions/io@^1.1.2": | ||||
|   version "1.1.2" | ||||
|   resolved "https://registry.yarnpkg.com/@actions/io/-/io-1.1.2.tgz#766ac09674a289ce0f1550ffe0a6eac9261a8ea9" | ||||
|   integrity sha512-d+RwPlMp+2qmBfeLYPLXuSRykDIFEwdTA0MMxzS9kh4kvP1ftrc/9fzy6pX6qAjthdXruHQ6/6kjT/DNo5ALuw== | ||||
| 
 | ||||
| "@actions/tool-cache@^2.0.1": | ||||
|   version "2.0.1" | ||||
|   resolved "https://registry.yarnpkg.com/@actions/tool-cache/-/tool-cache-2.0.1.tgz#8a649b9c07838d9d750c9864814e66a7660ab720" | ||||
|   integrity sha512-iPU+mNwrbA8jodY8eyo/0S/QqCKDajiR8OxWTnSk/SnYg0sj8Hp4QcUEVC1YFpHWXtrfbQrE13Jz4k4HXJQKcA== | ||||
|   dependencies: | ||||
|     "@actions/core" "^1.2.6" | ||||
|     "@actions/exec" "^1.0.0" | ||||
|     "@actions/http-client" "^2.0.1" | ||||
|     "@actions/io" "^1.1.1" | ||||
|     semver "^6.1.0" | ||||
|     uuid "^3.3.2" | ||||
| 
 | ||||
| "@ampproject/remapping@^2.1.0": | ||||
|   version "2.1.2" | ||||
|   resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.1.2.tgz#4edca94973ded9630d20101cd8559cedb8d8bd34" | ||||
| @ -546,6 +563,22 @@ | ||||
|   dependencies: | ||||
|     "@cspotcode/source-map-consumer" "0.8.0" | ||||
| 
 | ||||
| "@docker/actions-toolkit@^0.1.0-beta.14": | ||||
|   version "0.1.0-beta.14" | ||||
|   resolved "https://registry.yarnpkg.com/@docker/actions-toolkit/-/actions-toolkit-0.1.0-beta.14.tgz#82fa8a6b9802a7f770fde3ddcef1cf591739a80b" | ||||
|   integrity sha512-N+aqiO0E2ygoaBORN8fx4K7j/CzJ2nCSgOewtDm0gdzrch8qZmTU14e3oNAbZlP8Q34Lk45KKefm5wDfLipRqg== | ||||
|   dependencies: | ||||
|     "@actions/core" "^1.10.0" | ||||
|     "@actions/exec" "^1.1.1" | ||||
|     "@actions/github" "^5.1.1" | ||||
|     "@actions/http-client" "^2.0.1" | ||||
|     "@actions/io" "^1.1.2" | ||||
|     "@actions/tool-cache" "^2.0.1" | ||||
|     csv-parse "^5.3.5" | ||||
|     jwt-decode "^3.1.2" | ||||
|     semver "^7.3.8" | ||||
|     tmp "^0.2.1" | ||||
| 
 | ||||
| "@eslint/eslintrc@^1.2.1": | ||||
|   version "1.2.1" | ||||
|   resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.2.1.tgz#8b5e1c49f4077235516bc9ec7d41378c0f69b8c6" | ||||
| @ -1077,21 +1110,11 @@ | ||||
|   resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.4.4.tgz#5d9b63132df54d8909fce1c3f8ca260fdd693e17" | ||||
|   integrity sha512-ReVR2rLTV1kvtlWFyuot+d1pkpG2Fw/XKE3PDAdj57rbM97ttSp9JZ2UsP+2EHTylra9cUf6JA7tGwW1INzUrA== | ||||
| 
 | ||||
| "@types/semver@^7.3.9": | ||||
|   version "7.3.9" | ||||
|   resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.3.9.tgz#152c6c20a7688c30b967ec1841d31ace569863fc" | ||||
|   integrity sha512-L/TMpyURfBkf+o/526Zb6kd/tchUP3iBDEPjqjb+U2MAJhVRxxrmr2fwpe08E7QsV7YLcpq0tUaQ9O9x97ZIxQ== | ||||
| 
 | ||||
| "@types/stack-utils@^2.0.0": | ||||
|   version "2.0.0" | ||||
|   resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.0.tgz#7036640b4e21cc2f259ae826ce843d277dad8cff" | ||||
|   integrity sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw== | ||||
| 
 | ||||
| "@types/tmp@^0.2.3": | ||||
|   version "0.2.3" | ||||
|   resolved "https://registry.yarnpkg.com/@types/tmp/-/tmp-0.2.3.tgz#908bfb113419fd6a42273674c00994d40902c165" | ||||
|   integrity sha512-dDZH/tXzwjutnuk4UacGgFRwV+JSLaXL1ikvidfJprkb7L9Nx1njcRHHmi3Dsvt7pgqqTEeucQuOrWHPFgzVHA== | ||||
| 
 | ||||
| "@types/yargs-parser@*": | ||||
|   version "20.2.0" | ||||
|   resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-20.2.0.tgz#dd3e6699ba3237f0348cd085e4698780204842f9" | ||||
| @ -1701,11 +1724,6 @@ domexception@^2.0.1: | ||||
|   dependencies: | ||||
|     webidl-conversions "^5.0.0" | ||||
| 
 | ||||
| dotenv@^16.0.0: | ||||
|   version "16.0.0" | ||||
|   resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.0.0.tgz#c619001253be89ebb638d027b609c75c26e47411" | ||||
|   integrity sha512-qD9WU0MPM4SWLPJy/r2Be+2WgQj8plChsyrCNQzW/0WjvcJQiKQJ9mH3ZgB3fxbUUxgc/11ZJ0Fi5KiimWGz2Q== | ||||
| 
 | ||||
| electron-to-chromium@^1.3.723: | ||||
|   version "1.3.755" | ||||
|   resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.755.tgz#4b6101f13de910cf3f0a1789ddc57328133b9332" | ||||
| @ -3275,18 +3293,25 @@ saxes@^5.0.1: | ||||
|   dependencies: | ||||
|     xmlchars "^2.2.0" | ||||
| 
 | ||||
| semver@7.x, semver@^7.3.2, semver@^7.3.5, semver@^7.3.7: | ||||
| semver@7.x, semver@^7.3.2, semver@^7.3.5: | ||||
|   version "7.3.7" | ||||
|   resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f" | ||||
|   integrity sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g== | ||||
|   dependencies: | ||||
|     lru-cache "^6.0.0" | ||||
| 
 | ||||
| semver@^6.0.0, semver@^6.3.0: | ||||
| semver@^6.0.0, semver@^6.1.0, semver@^6.3.0: | ||||
|   version "6.3.0" | ||||
|   resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" | ||||
|   integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== | ||||
| 
 | ||||
| semver@^7.3.8: | ||||
|   version "7.3.8" | ||||
|   resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.8.tgz#07a78feafb3f7b32347d725e33de7e2a2df67798" | ||||
|   integrity sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A== | ||||
|   dependencies: | ||||
|     lru-cache "^6.0.0" | ||||
| 
 | ||||
| shebang-command@^2.0.0: | ||||
|   version "2.0.0" | ||||
|   resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" | ||||
| @ -3624,6 +3649,11 @@ uri-js@^4.2.2: | ||||
|   dependencies: | ||||
|     punycode "^2.1.0" | ||||
| 
 | ||||
| uuid@^3.3.2: | ||||
|   version "3.4.0" | ||||
|   resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" | ||||
|   integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== | ||||
| 
 | ||||
| uuid@^8.3.2: | ||||
|   version "8.3.2" | ||||
|   resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user