diff --git a/__tests__/buildx.test.ts b/__tests__/buildx.test.ts index 944633a..78ea338 100644 --- a/__tests__/buildx.test.ts +++ b/__tests__/buildx.test.ts @@ -257,6 +257,34 @@ describe('getProvenanceAttrs', () => { }); }); +describe('getRelease', () => { + it('returns latest buildx GitHub release', async () => { + const release = await Buildx.getRelease('latest'); + expect(release).not.toBeNull(); + expect(release?.tag_name).not.toEqual(''); + }); + + it('returns v0.10.1 buildx GitHub release', async () => { + const release = await Buildx.getRelease('v0.10.1'); + 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 Buildx.getRelease('v0.2.2'); + 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'); + }); + + it('unknown release', async () => { + await expect(Buildx.getRelease('foo')).rejects.toThrowError(new Error('Cannot find Buildx release foo in https://raw.githubusercontent.com/docker/buildx/master/.github/releases.json')); + }); +}); + describe('generateBuildSecret', () => { test.each([ ['A_SECRET=abcdef0123456789', false, 'A_SECRET', 'abcdef0123456789', null], diff --git a/package.json b/package.json index 1c19988..a835115 100644 --- a/package.json +++ b/package.json @@ -40,6 +40,7 @@ "@actions/core": "^1.10.0", "@actions/exec": "^1.1.1", "@actions/github": "^5.1.1", + "@actions/http-client": "^2.0.1", "csv-parse": "^5.3.3", "jwt-decode": "^3.1.2", "semver": "^7.3.8", diff --git a/src/buildx.ts b/src/buildx.ts index cfda283..0373863 100644 --- a/src/buildx.ts +++ b/src/buildx.ts @@ -2,12 +2,20 @@ import fs from 'fs'; import path from 'path'; import * as core from '@actions/core'; import * as exec from '@actions/exec'; +import * as httpm from '@actions/http-client'; import {parse} from 'csv-parse/sync'; import * as semver from 'semver'; import {Docker} from './docker'; import {Context} from './context'; +export interface GitHubRelease { + id: number; + tag_name: string; + html_url: string; + assets: Array; +} + export interface BuildxOpts { context: Context; standalone?: boolean; @@ -204,6 +212,22 @@ export class Buildx { return `${input},builder-id=${this.context.provenanceBuilderID}`; } + public static async getRelease(version: string): Promise { + const url = `https://raw.githubusercontent.com/docker/buildx/master/.github/releases.json`; + const http: httpm.HttpClient = new httpm.HttpClient('docker-actions-toolkit'); + const resp: httpm.HttpClientResponse = await http.get(url); + 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}`); + } + const releases = >JSON.parse(body); + if (!releases[version]) { + throw new Error(`Cannot find Buildx release ${version} in ${url}`); + } + return releases[version]; + } + public static hasLocalExporter(exporters: string[]): boolean { return Buildx.hasExporterType('local', exporters); } diff --git a/yarn.lock b/yarn.lock index 8d8f330..07d384c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -744,6 +744,7 @@ __metadata: "@actions/core": ^1.10.0 "@actions/exec": ^1.1.1 "@actions/github": ^5.1.1 + "@actions/http-client": ^2.0.1 "@types/csv-parse": ^1.2.2 "@types/node": ^16.18.11 "@types/semver": ^7.3.13