From 027b3ea216aa70dbb6f6c944bffae590bb2f1c3a Mon Sep 17 00:00:00 2001 From: CrazyMax Date: Mon, 31 Jul 2023 16:28:54 +0200 Subject: [PATCH] buildx: alternative release repos to download buildx Signed-off-by: CrazyMax --- __tests__/buildx/install.test.ts | 68 ++++++++++++++++++++++++-------- src/buildx/install.ts | 52 +++++++++++++++++++----- src/types/buildx.ts | 7 ++++ 3 files changed, 101 insertions(+), 26 deletions(-) diff --git a/__tests__/buildx/install.test.ts b/__tests__/buildx/install.test.ts index 38b6406f..3618223c 100644 --- a/__tests__/buildx/install.test.ts +++ b/__tests__/buildx/install.test.ts @@ -88,12 +88,6 @@ describe('download', () => { }, 100000 ); - - it('returns latest buildx GitHub release', async () => { - const release = await Install.getRelease('latest'); - expect(release).not.toBeNull(); - expect(release?.tag_name).not.toEqual(''); - }); }); describe('build', () => { @@ -116,30 +110,72 @@ describe('build', () => { }, 100000); }); +describe('getDownloadVersion', () => { + it('returns official latest download version', async () => { + const version = await Install.getDownloadVersion('latest'); + expect(version.key).toEqual('official'); + expect(version.version).toEqual('latest'); + expect(version.downloadURL).toEqual('https://github.com/docker/buildx/releases/download/v%s/%s'); + expect(version.releasesURL).toEqual('https://raw.githubusercontent.com/docker/actions-toolkit/main/.github/buildx-releases.json'); + }); + + it('returns official v0.10.1 download version', async () => { + const version = await Install.getDownloadVersion('v0.10.1'); + expect(version.key).toEqual('official'); + expect(version.version).toEqual('v0.10.1'); + expect(version.downloadURL).toEqual('https://github.com/docker/buildx/releases/download/v%s/%s'); + expect(version.releasesURL).toEqual('https://raw.githubusercontent.com/docker/actions-toolkit/main/.github/buildx-releases.json'); + }); + + it('returns lab latest download version', async () => { + const version = await Install.getDownloadVersion('lab:latest'); + expect(version.key).toEqual('lab'); + expect(version.version).toEqual('latest'); + expect(version.downloadURL).toEqual('https://github.com/docker/buildx-desktop/releases/download/v%s/%s'); + expect(version.releasesURL).toEqual('https://raw.githubusercontent.com/docker/actions-toolkit/main/.github/buildx-lab-releases.json'); + }); + + it('returns lab v0.11.2-desktop.2 download version', async () => { + const version = await Install.getDownloadVersion('lab:v0.11.2-desktop.2'); + expect(version.key).toEqual('lab'); + expect(version.version).toEqual('v0.11.2-desktop.2'); + expect(version.downloadURL).toEqual('https://github.com/docker/buildx-desktop/releases/download/v%s/%s'); + expect(version.releasesURL).toEqual('https://raw.githubusercontent.com/docker/actions-toolkit/main/.github/buildx-lab-releases.json'); + }); + + it('unknown repo', async () => { + await expect(Install.getDownloadVersion('foo:bar')).rejects.toThrow(new Error('Cannot find buildx version for foo:bar')); + }); +}); + describe('getRelease', () => { - it('returns latest buildx GitHub release', async () => { - const release = await Install.getRelease('latest'); + it('returns latest official GitHub release', async () => { + const version = await Install.getDownloadVersion('latest'); + const release = await Install.getRelease(version); expect(release).not.toBeNull(); expect(release?.tag_name).not.toEqual(''); }); - it('returns v0.10.1 buildx GitHub release', async () => { - const release = await Install.getRelease('v0.10.1'); + it('returns v0.10.1 official GitHub release', async () => { + const version = await Install.getDownloadVersion('v0.10.1'); + const release = await Install.getRelease(version); expect(release).not.toBeNull(); expect(release?.id).toEqual(90346950); expect(release?.tag_name).toEqual('v0.10.1'); expect(release?.html_url).toEqual('https://github.com/docker/buildx/releases/tag/v0.10.1'); }); - it('returns v0.2.2 buildx GitHub release', async () => { - const release = await Install.getRelease('v0.2.2'); + it('returns v0.11.2-desktop.2 lab GitHub release', async () => { + const version = await Install.getDownloadVersion('lab:v0.11.2-desktop.2'); + const release = await Install.getRelease(version); expect(release).not.toBeNull(); - expect(release?.id).toEqual(17671545); - expect(release?.tag_name).toEqual('v0.2.2'); - expect(release?.html_url).toEqual('https://github.com/docker/buildx/releases/tag/v0.2.2'); + expect(release?.id).toEqual(90346950); + expect(release?.tag_name).toEqual('v0.11.2-desktop.2'); + expect(release?.html_url).toEqual('https://github.com/docker/buildx-desktop/releases/tag/v0.11.2-desktop.2'); }); it('unknown release', async () => { - await expect(Install.getRelease('foo')).rejects.toThrow(new Error('Cannot find Buildx release foo in https://raw.githubusercontent.com/docker/actions-toolkit/main/.github/buildx-releases.json')); + const version = await Install.getDownloadVersion('foo'); + await expect(Install.getRelease(version)).rejects.toThrow(new Error('Cannot find Buildx release foo in https://raw.githubusercontent.com/docker/actions-toolkit/main/.github/buildx-releases.json')); }); }); diff --git a/src/buildx/install.ts b/src/buildx/install.ts index 90a013a4..e359e1a3 100644 --- a/src/buildx/install.ts +++ b/src/buildx/install.ts @@ -32,6 +32,7 @@ import {Docker} from '../docker/docker'; import {Git} from '../git'; import {Util} from '../util'; +import {DownloadVersion} from '../types/buildx'; import {GitHubRelease} from '../types/github'; export interface InstallOpts { @@ -50,7 +51,10 @@ export class Install { * @param version semver version or latest * @returns path to the buildx binary */ - public async download(version: string): Promise { + public async download(v: string): Promise { + const version: DownloadVersion = await Install.getDownloadVersion(v); + core.debug(`Install.download version: ${version.version}`); + const release: GitHubRelease = await Install.getRelease(version); core.debug(`Install.download release tag name: ${release.tag_name}`); @@ -62,7 +66,7 @@ export class Install { throw new Error(`Invalid Buildx version "${vspec}".`); } - const installCache = new InstallCache('buildx-dl-bin', vspec); + const installCache = new InstallCache(version.key != 'official' ? `buildx-dl-bin-${version.key}` : 'buildx-dl-bin', vspec); const cacheFoundPath = await installCache.find(); if (cacheFoundPath) { @@ -70,7 +74,7 @@ export class Install { return cacheFoundPath; } - const downloadURL = util.format('https://github.com/docker/buildx/releases/download/v%s/%s', vspec, this.filename(vspec)); + const downloadURL = util.format(version.downloadURL, vspec, this.filename(vspec)); core.info(`Downloading ${downloadURL}`); const htcDownloadPath = await tc.downloadTool(downloadURL); @@ -253,20 +257,48 @@ export class Install { return hash; } - public static async getRelease(version: string): Promise { - const url = `https://raw.githubusercontent.com/docker/actions-toolkit/main/.github/buildx-releases.json`; + public static async getDownloadVersion(v: string): Promise { + let [repoKey, version] = v.split(':'); + if (!version) { + version = repoKey; + repoKey = 'official'; + } + switch (repoKey) { + case 'official': { + return { + key: repoKey, + version: version, + downloadURL: 'https://github.com/docker/buildx/releases/download/v%s/%s', + releasesURL: 'https://raw.githubusercontent.com/docker/actions-toolkit/main/.github/buildx-releases.json' + }; + } + case 'lab': { + return { + key: repoKey, + version: version, + downloadURL: 'https://github.com/docker/buildx-desktop/releases/download/v%s/%s', + releasesURL: 'https://raw.githubusercontent.com/docker/actions-toolkit/main/.github/buildx-lab-releases.json' + }; + } + default: { + throw new Error(`Cannot find buildx version for ${v}`); + } + } + } + + public static async getRelease(version: DownloadVersion): Promise { const http: httpm.HttpClient = new httpm.HttpClient('docker-actions-toolkit'); - const resp: httpm.HttpClientResponse = await http.get(url); + const resp: httpm.HttpClientResponse = await http.get(version.releasesURL); const body = await resp.readBody(); const statusCode = resp.message.statusCode || 500; if (statusCode >= 400) { - throw new Error(`Failed to get Buildx release ${version} from ${url} with status code ${statusCode}: ${body}`); + throw new Error(`Failed to get Buildx releases from ${version.releasesURL} with status code ${statusCode}: ${body}`); } const releases = >JSON.parse(body); - if (!releases[version]) { - throw new Error(`Cannot find Buildx release ${version} in ${url}`); + if (!releases[version.version]) { + throw new Error(`Cannot find Buildx release ${version.version} in ${version.releasesURL}`); } - return releases[version]; + return releases[version.version]; } } diff --git a/src/types/buildx.ts b/src/types/buildx.ts index 64be2be9..f479961c 100644 --- a/src/types/buildx.ts +++ b/src/types/buildx.ts @@ -19,3 +19,10 @@ export interface Cert { cert?: string; key?: string; } + +export interface DownloadVersion { + key: string; + version: string; + downloadURL: string; + releasesURL: string; +}