diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index b975fcf..46db785 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -15,6 +15,7 @@ on: env: NODE_VERSION: "20" + BUILDX_VERSION: "v0.14.0-rc1" jobs: test: @@ -102,6 +103,13 @@ jobs: with: node-version: ${{ env.NODE_VERSION }} cache: 'yarn' + - + name: Set up Docker Buildx + if: startsWith(matrix.os, 'ubuntu') + uses: docker/setup-buildx-action@v3 + with: + version: ${{ env.BUILDX_VERSION }} + driver: docker - name: Install run: yarn install diff --git a/__tests__/buildx/bake.test.itg.ts b/__tests__/buildx/bake.test.itg.ts index b3ce79a..42918a8 100644 --- a/__tests__/buildx/bake.test.itg.ts +++ b/__tests__/buildx/bake.test.itg.ts @@ -35,14 +35,28 @@ maybe('getDefinition', () => { [ 'https://github.com/docker/buildx.git#v0.10.4', ['binaries-cross'], - path.join(fixturesDir, 'bake-buildx-0.10.4-binaries-cross.json') + path.join(fixturesDir, 'bake-buildx-0.10.4-binaries-cross.json'), + false, ], - ])('given %p', async (source: string, targets: string[], out: string) => { + // TODO: uncomment this test case when we have access to the private repo using an access token + // [ + // 'https://github.com/docker/test-docker-action.git#remote-private', + // ['default'], + // path.join(fixturesDir, 'bake-test-docker-action-remote-private.json'), + // true, + // ] + ])('given %p', async (source: string, targets: string[], out: string, auth) => { + const gitAuthToken = process.env.GITHUB_TOKEN || ''; + if (auth && !gitAuthToken) { + console.log(`Git auth token not available, skipping test`); + return; + } const bake = new Bake(); const expectedDef = JSON.parse(fs.readFileSync(out, {encoding: 'utf-8'}).trim()) expect(await bake.getDefinition({ source: source, - targets: targets + targets: targets, + githubToken: gitAuthToken, })).toEqual(expectedDef); }); }); diff --git a/__tests__/fixtures/bake-test-docker-action-remote-private.json b/__tests__/fixtures/bake-test-docker-action-remote-private.json new file mode 100644 index 0000000..3e70fd7 --- /dev/null +++ b/__tests__/fixtures/bake-test-docker-action-remote-private.json @@ -0,0 +1,11 @@ +{ + "target": { + "default": { + "context": "https://github.com/docker/test-docker-action.git#remote-private", + "dockerfile": "Dockerfile", + "tags": [ + "foo" + ] + } + } +} diff --git a/dev.Dockerfile b/dev.Dockerfile index 6bc3ceb..d001b74 100644 --- a/dev.Dockerfile +++ b/dev.Dockerfile @@ -16,7 +16,7 @@ ARG NODE_VERSION=20 ARG DOCKER_VERSION=26.0.0 -ARG BUILDX_VERSION=0.13.1 +ARG BUILDX_VERSION=0.14.0-rc1 FROM node:${NODE_VERSION}-alpine AS base RUN apk add --no-cache cpio findutils git diff --git a/src/buildx/bake.ts b/src/buildx/bake.ts index 93f158f..4835a07 100644 --- a/src/buildx/bake.ts +++ b/src/buildx/bake.ts @@ -36,6 +36,8 @@ export interface BakeCmdOpts { sbom?: string; source?: string; targets?: Array; + + githubToken?: string; // for auth with remote definitions on private repos } export class Bake { @@ -48,6 +50,13 @@ export class Bake { public async getDefinition(cmdOpts: BakeCmdOpts, execOptions?: ExecOptions): Promise { execOptions = execOptions || {ignoreReturnCode: true}; execOptions.ignoreReturnCode = true; + if (cmdOpts.githubToken) { + execOptions.env = Object.assign({}, process.env, { + BUILDX_BAKE_GIT_AUTH_TOKEN: cmdOpts.githubToken + }) as { + [key: string]: string; + }; + } const args = ['bake']; diff --git a/src/buildx/inputs.ts b/src/buildx/inputs.ts index 77e5b5b..491eb8d 100644 --- a/src/buildx/inputs.ts +++ b/src/buildx/inputs.ts @@ -77,24 +77,23 @@ export class Inputs { } public static resolveBuildSecretString(kvp: string): string { - return Inputs.resolveBuildSecret(kvp, false); + const [key, file] = Inputs.resolveBuildSecret(kvp, false); + return `id=${key},src=${file}`; } public static resolveBuildSecretFile(kvp: string): string { - return Inputs.resolveBuildSecret(kvp, true); + const [key, file] = Inputs.resolveBuildSecret(kvp, true); + return `id=${key},src=${file}`; } public static resolveBuildSecretEnv(kvp: string): string { const [key, value] = parseKvp(kvp); - return `id=${key},env=${value}`; } - public static resolveBuildSecret(kvp: string, file: boolean): string { + public static resolveBuildSecret(kvp: string, file: boolean): [string, string] { const [key, _value] = parseKvp(kvp); - let value = _value; - if (file) { if (!fs.existsSync(value)) { throw new Error(`secret file ${value} not found`); @@ -103,7 +102,7 @@ export class Inputs { } const secretFile = Context.tmpName({tmpdir: Context.tmpDir()}); fs.writeFileSync(secretFile, value); - return `id=${key},src=${secretFile}`; + return [key, secretFile]; } public static getProvenanceInput(name: string): string {