From 12299862529544e341567879f040c09eb26c0dec Mon Sep 17 00:00:00 2001 From: CrazyMax <1951866+crazy-max@users.noreply.github.com> Date: Mon, 20 Jan 2025 15:38:48 +0100 Subject: [PATCH 1/2] compose: cloud releases support Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com> --- __tests__/compose/install.test.ts | 35 +++++++++++++++++++++++++++---- src/compose/install.ts | 33 +++++++++++++++++++++++------ src/types/compose/compose.ts | 1 + 3 files changed, 59 insertions(+), 10 deletions(-) diff --git a/__tests__/compose/install.test.ts b/__tests__/compose/install.test.ts index 447412d..e30d059 100644 --- a/__tests__/compose/install.test.ts +++ b/__tests__/compose/install.test.ts @@ -98,28 +98,47 @@ describe('download', () => { }); describe('getDownloadVersion', () => { - it('returns latest download version', async () => { + 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/compose/releases/download/v%s/%s'); expect(version.releasesURL).toEqual('https://raw.githubusercontent.com/docker/actions-toolkit/main/.github/compose-releases.json'); }); - it('returns v2.24.3 download version', async () => { + it('returns official v2.24.3 download version', async () => { const version = await Install.getDownloadVersion('v2.24.3'); + expect(version.key).toEqual('official'); expect(version.version).toEqual('v2.24.3'); expect(version.downloadURL).toEqual('https://github.com/docker/compose/releases/download/v%s/%s'); expect(version.releasesURL).toEqual('https://raw.githubusercontent.com/docker/actions-toolkit/main/.github/compose-releases.json'); }); + it('returns cloud latest download version', async () => { + const version = await Install.getDownloadVersion('cloud:latest'); + expect(version.key).toEqual('cloud'); + expect(version.version).toEqual('latest'); + expect(version.downloadURL).toEqual('https://github.com/docker/compose-desktop/releases/download/v%s/%s'); + expect(version.releasesURL).toEqual('https://raw.githubusercontent.com/docker/actions-toolkit/main/.github/compose-lab-releases.json'); + }); + it('returns cloud v2.27.1-desktop.1 download version', async () => { + const version = await Install.getDownloadVersion('cloud:v2.27.1-desktop.1'); + expect(version.key).toEqual('cloud'); + expect(version.version).toEqual('v2.27.1-desktop.1'); + expect(version.downloadURL).toEqual('https://github.com/docker/compose-desktop/releases/download/v%s/%s'); + expect(version.releasesURL).toEqual('https://raw.githubusercontent.com/docker/actions-toolkit/main/.github/compose-lab-releases.json'); + }); + it('unknown repo', async () => { + await expect(Install.getDownloadVersion('foo:bar')).rejects.toThrow(new Error('Cannot find compose version for foo:bar')); + }); }); describe('getRelease', () => { - it('returns latest GitHub release', async () => { + 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 v2.24.3 GitHub release', async () => { + it('returns v2.24.3 official GitHub release', async () => { const version = await Install.getDownloadVersion('v2.24.3'); const release = await Install.getRelease(version); expect(release).not.toBeNull(); @@ -127,6 +146,14 @@ describe('getRelease', () => { expect(release?.tag_name).toEqual('v2.24.3'); expect(release?.html_url).toEqual('https://github.com/docker/compose/releases/tag/v2.24.3'); }); + it('returns v2.27.1-desktop.1 cloud GitHub release', async () => { + const version = await Install.getDownloadVersion('cloud:v2.27.1-desktop.1'); + const release = await Install.getRelease(version); + expect(release).not.toBeNull(); + expect(release?.id).toEqual(157591108); + expect(release?.tag_name).toEqual('v2.27.1-desktop.1'); + expect(release?.html_url).toEqual('https://github.com/docker/compose-desktop/releases/tag/v2.27.1-desktop.1'); + }); it('unknown release', async () => { const version = await Install.getDownloadVersion('foo'); await expect(Install.getRelease(version)).rejects.toThrow(new Error('Cannot find Compose release foo in https://raw.githubusercontent.com/docker/actions-toolkit/main/.github/compose-releases.json')); diff --git a/src/compose/install.ts b/src/compose/install.ts index d249f29..acc6b13 100644 --- a/src/compose/install.ts +++ b/src/compose/install.ts @@ -63,7 +63,7 @@ export class Install { } const installCache = new Cache({ - htcName: 'compose-dl-bin', + htcName: version.key != 'official' ? `compose-dl-bin-${version.key}` : 'compose-dl-bin', htcVersion: vspec, baseCacheDir: path.join(os.homedir(), '.bin'), cacheFile: os.platform() == 'win32' ? 'docker-compose.exe' : 'docker-compose', @@ -172,11 +172,32 @@ export class Install { } public static async getDownloadVersion(v: string): Promise { - return { - version: v, - downloadURL: 'https://github.com/docker/compose/releases/download/v%s/%s', - releasesURL: 'https://raw.githubusercontent.com/docker/actions-toolkit/main/.github/compose-releases.json' - }; + 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/compose/releases/download/v%s/%s', + releasesURL: 'https://raw.githubusercontent.com/docker/actions-toolkit/main/.github/compose-releases.json' + }; + } + case 'cloud': { + return { + key: repoKey, + version: version, + downloadURL: 'https://github.com/docker/compose-desktop/releases/download/v%s/%s', + releasesURL: 'https://raw.githubusercontent.com/docker/actions-toolkit/main/.github/compose-lab-releases.json' + }; + } + default: { + throw new Error(`Cannot find compose version for ${v}`); + } + } } public static async getRelease(version: DownloadVersion): Promise { diff --git a/src/types/compose/compose.ts b/src/types/compose/compose.ts index f06edeb..41d9cc9 100644 --- a/src/types/compose/compose.ts +++ b/src/types/compose/compose.ts @@ -15,6 +15,7 @@ */ export interface DownloadVersion { + key: string; version: string; downloadURL: string; releasesURL: string; From d9bd2d45ba633e761e6ebb26b881832e5309fe0c Mon Sep 17 00:00:00 2001 From: CrazyMax <1951866+crazy-max@users.noreply.github.com> Date: Mon, 20 Jan 2025 15:40:14 +0100 Subject: [PATCH 2/2] test: increase timeout for binary download Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com> --- __tests__/buildx/install.test.ts | 26 +++++++++++++++----------- __tests__/compose/install.test.ts | 28 ++++++++++++++++------------ 2 files changed, 31 insertions(+), 23 deletions(-) diff --git a/__tests__/buildx/install.test.ts b/__tests__/buildx/install.test.ts index 945a381..de6e9b9 100644 --- a/__tests__/buildx/install.test.ts +++ b/__tests__/buildx/install.test.ts @@ -57,22 +57,26 @@ describe('download', () => { ['v0.9.0'], ['v0.10.5'], ])( - 'acquires %p of buildx with cache', async (version) => { - const install = new Install({standalone: false}); - const toolPath = await install.download(version); - expect(fs.existsSync(toolPath)).toBe(true); - }); + 'acquires %p of buildx with cache', async (version) => { + const install = new Install({standalone: false}); + const toolPath = await install.download(version); + expect(fs.existsSync(toolPath)).toBe(true); + }, + 100000 + ); // prettier-ignore test.each([ ['v0.11.2'], ['v0.12.0'], ])( - 'acquires %p of buildx without cache', async (version) => { - const install = new Install({standalone: false}); - const toolPath = await install.download(version, true); - expect(fs.existsSync(toolPath)).toBe(true); - }); + 'acquires %p of buildx without cache', async (version) => { + const install = new Install({standalone: false}); + const toolPath = await install.download(version, true); + expect(fs.existsSync(toolPath)).toBe(true); + }, + 100000 + ); // TODO: add tests for arm // prettier-ignore @@ -86,7 +90,7 @@ describe('download', () => { ['linux', 'ppc64'], ['linux', 's390x'], ])( - 'acquires buildx for %s/%s', async (os, arch) => { + 'acquires buildx for %s/%s', async (os, arch) => { jest.spyOn(osm, 'platform').mockImplementation(() => os as NodeJS.Platform); jest.spyOn(osm, 'arch').mockImplementation(() => arch); const install = new Install(); diff --git a/__tests__/compose/install.test.ts b/__tests__/compose/install.test.ts index e30d059..af8e28f 100644 --- a/__tests__/compose/install.test.ts +++ b/__tests__/compose/install.test.ts @@ -36,7 +36,7 @@ describe('download', () => { ['v2.32.4', true], ['latest', true] ])( - 'acquires %p of compose (standalone: %p)', async (version, standalone) => { + 'acquires %p of compose (standalone: %p)', async (version, standalone) => { const install = new Install({standalone: standalone}); const toolPath = await install.download(version); expect(fs.existsSync(toolPath)).toBe(true); @@ -57,22 +57,26 @@ describe('download', () => { ['v2.31.0'], ['v2.32.4'], ])( - 'acquires %p of compose with cache', async (version) => { - const install = new Install({standalone: false}); - const toolPath = await install.download(version); - expect(fs.existsSync(toolPath)).toBe(true); - }); + 'acquires %p of compose with cache', async (version) => { + const install = new Install({standalone: false}); + const toolPath = await install.download(version); + expect(fs.existsSync(toolPath)).toBe(true); + }, + 100000 + ); // prettier-ignore test.each([ ['v2.27.1'], ['v2.28.0'], ])( - 'acquires %p of compose without cache', async (version) => { - const install = new Install({standalone: false}); - const toolPath = await install.download(version, true); - expect(fs.existsSync(toolPath)).toBe(true); - }); + 'acquires %p of compose without cache', async (version) => { + const install = new Install({standalone: false}); + const toolPath = await install.download(version, true); + expect(fs.existsSync(toolPath)).toBe(true); + }, + 100000 + ); // TODO: add tests for arm // prettier-ignore @@ -86,7 +90,7 @@ describe('download', () => { ['linux', 'ppc64'], ['linux', 's390x'], ])( - 'acquires compose for %s/%s', async (os, arch) => { + 'acquires compose for %s/%s', async (os, arch) => { jest.spyOn(osm, 'platform').mockImplementation(() => os as NodeJS.Platform); jest.spyOn(osm, 'arch').mockImplementation(() => arch); const install = new Install();