From 15788e8b934f4fcb435f6470178aca9cb3be9532 Mon Sep 17 00:00:00 2001 From: CrazyMax <1951866+crazy-max@users.noreply.github.com> Date: Wed, 5 Jun 2024 13:59:57 +0200 Subject: [PATCH] buildx(build): resolveCacheToAttrs func Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com> --- __tests__/buildx/build.test.ts | 48 ++++++++++++++++++++++++++++++++++ __tests__/github.test.ts | 8 +++++- src/buildx/build.ts | 39 +++++++++++++++++++++++++++ src/github.ts | 6 ++++- 4 files changed, 99 insertions(+), 2 deletions(-) diff --git a/__tests__/buildx/build.test.ts b/__tests__/buildx/build.test.ts index b98a95be..01070fff 100644 --- a/__tests__/buildx/build.test.ts +++ b/__tests__/buildx/build.test.ts @@ -202,6 +202,54 @@ describe('resolveSecret', () => { }); }); +describe('resolveCacheToAttrs', () => { + // prettier-ignore + test.each([ + [ + '', + undefined, + '' + ], + [ + 'user/app:cache', + undefined, + 'user/app:cache' + ], + [ + 'type=inline', + undefined, + 'type=inline' + ], + [ + 'type=gha', + undefined, + 'type=gha,repository=docker/actions-toolkit', + ], + [ + 'type=gha,mode=max', + undefined, + 'type=gha,mode=max,repository=docker/actions-toolkit', + ], + [ + 'type=gha,mode=max', + 'abcd1234', + 'type=gha,mode=max,repository=docker/actions-toolkit,ghtoken=abcd1234', + ], + [ + 'type=gha,repository=foo/bar,mode=max', + undefined, + 'type=gha,repository=foo/bar,mode=max', + ], + [ + 'type=gha,repository=foo/bar,mode=max', + 'abcd1234', + 'type=gha,repository=foo/bar,mode=max,ghtoken=abcd1234', + ], + ])('given %p', async (input: string, githubToken: string | undefined, expected: string) => { + expect(Build.resolveCacheToAttrs(input, githubToken)).toEqual(expected); + }); +}); + describe('hasLocalExporter', () => { // prettier-ignore test.each([ diff --git a/__tests__/github.test.ts b/__tests__/github.test.ts index 4ae8ff2b..37a771fe 100644 --- a/__tests__/github.test.ts +++ b/__tests__/github.test.ts @@ -32,7 +32,7 @@ jest.spyOn(GitHub.prototype, 'repoData').mockImplementation((): Promise { - it('returns GitHub repository', async () => { + it('returns GitHub repo data', async () => { const github = new GitHub(); expect((await github.repoData()).name).toEqual('Hello-World'); }); @@ -89,6 +89,12 @@ describe('apiURL', () => { }); }); +describe('repository', () => { + it('returns GitHub repository', async () => { + expect(GitHub.repository).toEqual('docker/actions-toolkit'); + }); +}); + describe('workflowRunURL', () => { it('returns 2188748038', async () => { expect(GitHub.workflowRunURL).toEqual('https://github.com/docker/actions-toolkit/actions/runs/2188748038/attempts/2'); diff --git a/src/buildx/build.ts b/src/buildx/build.ts index c368c45e..c2f5263d 100644 --- a/src/buildx/build.ts +++ b/src/buildx/build.ts @@ -161,6 +161,45 @@ export class Build { return `${input},builder-id=${GitHub.workflowRunURL}`; } + public static resolveCacheToAttrs(input: string, githubToken?: string): string { + if (!input) { + return input; + } + + let cacheType = 'registry'; + let ghaCacheRepository = ''; + let ghaCacheGHToken = ''; + + const fields = parse(input, { + relaxColumnCount: true, + skipEmptyLines: true + })[0]; + for (const field of fields) { + const parts = field + .toString() + .split(/(?<=^[^=]+?)=/) + .map(item => item.trim()); + if (parts[0] === 'type') { + cacheType = parts[1]; + } else if (parts[0] === 'repository') { + ghaCacheRepository = parts[1]; + } else if (parts[0] === 'ghtoken') { + ghaCacheGHToken = parts[1]; + } + } + + if (cacheType === 'gha') { + if (!ghaCacheRepository) { + input = `${input},repository=${GitHub.repository}`; + } + if (!ghaCacheGHToken && githubToken) { + input = `${input},ghtoken=${githubToken}`; + } + } + + return input; + } + public static hasLocalExporter(exporters: string[]): boolean { return Build.hasExporterType('local', exporters); } diff --git a/src/github.ts b/src/github.ts index c7e414f5..d0da7488 100644 --- a/src/github.ts +++ b/src/github.ts @@ -64,10 +64,14 @@ export class GitHub { return process.env.GITHUB_API_URL || 'https://api.github.com'; } + static get repository(): string { + return `${github.context.repo.owner}/${github.context.repo.repo}`; + } + static get workflowRunURL(): string { const runID = process.env.GITHUB_RUN_ID || github.context.runId; const runAttempt = process.env.GITHUB_RUN_ATTEMPT || 1; - return `${GitHub.serverURL}/${github.context.repo.owner}/${github.context.repo.repo}/actions/runs/${runID}/attempts/${runAttempt}`; + return `${GitHub.serverURL}/${GitHub.repository}/actions/runs/${runID}/attempts/${runAttempt}`; } static get actionsRuntimeToken(): GitHubActionsRuntimeToken | undefined {