From 0be6f6575b54363efe456abea0a2b92bc47077f7 Mon Sep 17 00:00:00 2001
From: CrazyMax <crazy-max@users.noreply.github.com>
Date: Thu, 3 Sep 2020 21:02:36 +0200
Subject: [PATCH] Check buildx version

Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
---
 .github/workflows/ci.yml |  4 ++--
 README.md                |  2 +-
 __tests__/buildx.test.ts | 48 +++++++++++++++++++++++++++-------------
 dist/index.js            | 30 +++++++++++++++++++++----
 src/buildx.ts            | 17 ++++++++++++++
 src/main.ts              |  7 +++---
 6 files changed, 83 insertions(+), 25 deletions(-)

diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 19efaae..4837fbc 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -22,7 +22,7 @@ jobs:
       matrix:
         buildx-version:
           - latest
-          - v0.4.1
+          - v0.2.2
           - ""
     steps:
       -
@@ -150,7 +150,7 @@ jobs:
       matrix:
         buildx-version:
           - latest
-          - v0.4.1
+          - v0.2.2
           - ""
         qemu-platforms:
           - all
diff --git a/README.md b/README.md
index baa42ed..3f7bb03 100644
--- a/README.md
+++ b/README.md
@@ -131,7 +131,7 @@ Following inputs can be used as `step.with` keys
 | `version`          | String  | [Buildx](https://github.com/docker/buildx) version. (e.g. `v0.3.0`, `latest`) |
 | `driver`           | String  | Sets the [builder driver](https://github.com/docker/buildx#--driver-driver) to be used (default `docker-container`) |
 | `driver-opts`      | CSV     | List of additional [driver-specific options](https://github.com/docker/buildx#--driver-opt-options) |
-| `buildkitd-flags`  | String  | [Flags for buildkitd](https://github.com/moby/buildkit/blob/master/docs/buildkitd.toml.md) daemon (default `--allow-insecure-entitlement security.insecure --allow-insecure-entitlement network.host`) |
+| `buildkitd-flags`  | String  | [Flags for buildkitd](https://github.com/moby/buildkit/blob/master/docs/buildkitd.toml.md) daemon (since [buildx v0.3.0](https://github.com/docker/buildx/releases/tag/v0.3.0)) |
 | `install`          | Bool    | Sets up `docker build` command as an alias to `docker buildx` (default `false`) |
 | `use`              | Bool    | Switch to this builder instance (default `true`) |
 
diff --git a/__tests__/buildx.test.ts b/__tests__/buildx.test.ts
index 8720846..f09ff3d 100644
--- a/__tests__/buildx.test.ts
+++ b/__tests__/buildx.test.ts
@@ -3,26 +3,34 @@ import * as docker from '../src/docker';
 import * as buildx from '../src/buildx';
 import * as path from 'path';
 import * as os from 'os';
+import * as semver from 'semver';
+import * as exec from '@actions/exec';
 
-const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'setup-buildx-'));
+describe('getVersion', () => {
+  it('valid', async () => {
+    await exec.exec('docker', ['buildx', 'version']);
+    const version = await buildx.getVersion();
+    console.log(`version: ${version}`);
+    expect(semver.valid(version)).not.toBeNull();
+  }, 100000);
+});
 
-describe('buildx', () => {
+describe('parseVersion', () => {
+  test.each([
+    ['github.com/docker/buildx 0.4.1+azure bda4882a65349ca359216b135896bddc1d92461c', '0.4.1'],
+    ['github.com/docker/buildx v0.4.1 bda4882a65349ca359216b135896bddc1d92461c', '0.4.1'],
+    ['github.com/docker/buildx v0.4.2 fb7b670b764764dc4716df3eba07ffdae4cc47b2', '0.4.2']
+  ])('given %p', async (stdout, expected) => {
+    expect(await buildx.parseVersion(stdout)).toEqual(expected);
+  });
+});
+
+describe('platforms', () => {
   async function isDaemonRunning() {
     return await docker.isDaemonRunning();
   }
-
-  it('is available', async () => {
-    expect(await buildx.isAvailable()).toBe(true);
-  }, 100000);
-
-  it('count builders', async () => {
-    const countBuilders = await buildx.countBuilders();
-    console.log(`countBuilders: ${countBuilders}`);
-    expect(countBuilders).toBeGreaterThan(0);
-  }, 100000);
-
   (isDaemonRunning() ? it : it.skip)(
-    'platforms',
+    'valid',
     async () => {
       const platforms = buildx.platforms();
       console.log(`platforms: ${platforms}`);
@@ -31,13 +39,23 @@ describe('buildx', () => {
     },
     100000
   );
+});
 
+describe('countBuilders', () => {
+  it('valid', async () => {
+    const countBuilders = await buildx.countBuilders();
+    console.log(`countBuilders: ${countBuilders}`);
+    expect(countBuilders).toBeGreaterThan(0);
+  }, 100000);
+});
+
+describe('install', () => {
+  const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'setup-buildx-'));
   it('acquires v0.2.2 version of buildx', async () => {
     const buildxBin = await buildx.install('v0.2.2', tmpDir);
     console.log(buildxBin);
     expect(fs.existsSync(buildxBin)).toBe(true);
   }, 100000);
-
   it('acquires latest version of buildx', async () => {
     const buildxBin = await buildx.install('latest', tmpDir);
     console.log(buildxBin);
diff --git a/dist/index.js b/dist/index.js
index c07d16f..5c89cb5 100644
--- a/dist/index.js
+++ b/dist/index.js
@@ -500,6 +500,7 @@ const core = __importStar(__webpack_require__(186));
 const exec = __importStar(__webpack_require__(514));
 const os = __importStar(__webpack_require__(87));
 const path = __importStar(__webpack_require__(622));
+const semver = __importStar(__webpack_require__(383));
 const buildx = __importStar(__webpack_require__(295));
 const context = __importStar(__webpack_require__(842));
 const mexec = __importStar(__webpack_require__(757));
@@ -516,8 +517,8 @@ function run() {
             if (!(yield buildx.isAvailable()) || inputs.version) {
                 yield buildx.install(inputs.version || 'latest', dockerConfigHome);
             }
-            core.info('📣 Buildx info');
-            yield exec.exec('docker', ['buildx', 'version']);
+            const buildxVersion = yield buildx.getVersion();
+            core.info(`📣 Buildx version: ${buildxVersion}`);
             const builderName = inputs.driver == 'docker' ? 'default' : `builder-${process.env.GITHUB_JOB}-${(yield buildx.countBuilders()) + 1}`;
             core.setOutput('name', builderName);
             stateHelper.setBuilderName(builderName);
@@ -527,7 +528,7 @@ function run() {
                 yield context.asyncForEach(inputs.driverOpts, (driverOpt) => __awaiter(this, void 0, void 0, function* () {
                     createArgs.push('--driver-opt', driverOpt);
                 }));
-                if (inputs.buildkitdFlags) {
+                if (inputs.buildkitdFlags && semver.satisfies(buildxVersion, '>=0.3.0')) {
                     createArgs.push('--buildkitd-flags', inputs.buildkitdFlags);
                 }
                 if (inputs.use) {
@@ -1936,7 +1937,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
     });
 };
 Object.defineProperty(exports, "__esModule", { value: true });
-exports.install = exports.platforms = exports.countBuilders = exports.isAvailable = void 0;
+exports.install = exports.platforms = exports.countBuilders = exports.isAvailable = exports.parseVersion = exports.getVersion = void 0;
 const fs = __importStar(__webpack_require__(747));
 const path = __importStar(__webpack_require__(622));
 const semver = __importStar(__webpack_require__(383));
@@ -1946,6 +1947,27 @@ const exec = __importStar(__webpack_require__(757));
 const github = __importStar(__webpack_require__(928));
 const core = __importStar(__webpack_require__(186));
 const tc = __importStar(__webpack_require__(784));
+function getVersion() {
+    return __awaiter(this, void 0, void 0, function* () {
+        return yield exec.exec(`docker`, ['buildx', 'version'], true).then(res => {
+            if (res.stderr != '' && !res.success) {
+                throw new Error(res.stderr);
+            }
+            return parseVersion(res.stdout);
+        });
+    });
+}
+exports.getVersion = getVersion;
+function parseVersion(stdout) {
+    return __awaiter(this, void 0, void 0, function* () {
+        const matches = /\sv?([0-9.]+)/.exec(stdout);
+        if (!matches) {
+            throw new Error(`Cannot parse Buildx version`);
+        }
+        return semver.clean(matches[1]);
+    });
+}
+exports.parseVersion = parseVersion;
 function isAvailable() {
     return __awaiter(this, void 0, void 0, function* () {
         return yield exec.exec(`docker`, ['buildx'], true).then(res => {
diff --git a/src/buildx.ts b/src/buildx.ts
index 244fe7c..7415bc9 100644
--- a/src/buildx.ts
+++ b/src/buildx.ts
@@ -8,6 +8,23 @@ import * as github from './github';
 import * as core from '@actions/core';
 import * as tc from '@actions/tool-cache';
 
+export async function getVersion(): Promise<string> {
+  return await exec.exec(`docker`, ['buildx', 'version'], true).then(res => {
+    if (res.stderr != '' && !res.success) {
+      throw new Error(res.stderr);
+    }
+    return parseVersion(res.stdout);
+  });
+}
+
+export async function parseVersion(stdout: string): Promise<string> {
+  const matches = /\sv?([0-9.]+)/.exec(stdout);
+  if (!matches) {
+    throw new Error(`Cannot parse Buildx version`);
+  }
+  return semver.clean(matches[1]);
+}
+
 export async function isAvailable(): Promise<Boolean> {
   return await exec.exec(`docker`, ['buildx'], true).then(res => {
     if (res.stderr != '' && !res.success) {
diff --git a/src/main.ts b/src/main.ts
index 3fa19e0..608d0f9 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -2,6 +2,7 @@ import * as core from '@actions/core';
 import * as exec from '@actions/exec';
 import * as os from 'os';
 import * as path from 'path';
+import * as semver from 'semver';
 import * as buildx from './buildx';
 import * as context from './context';
 import * as mexec from './exec';
@@ -21,8 +22,8 @@ async function run(): Promise<void> {
       await buildx.install(inputs.version || 'latest', dockerConfigHome);
     }
 
-    core.info('📣 Buildx info');
-    await exec.exec('docker', ['buildx', 'version']);
+    const buildxVersion = await buildx.getVersion();
+    core.info(`📣 Buildx version: ${buildxVersion}`);
 
     const builderName: string =
       inputs.driver == 'docker' ? 'default' : `builder-${process.env.GITHUB_JOB}-${(await buildx.countBuilders()) + 1}`;
@@ -35,7 +36,7 @@ async function run(): Promise<void> {
       await context.asyncForEach(inputs.driverOpts, async driverOpt => {
         createArgs.push('--driver-opt', driverOpt);
       });
-      if (inputs.buildkitdFlags) {
+      if (inputs.buildkitdFlags && semver.satisfies(buildxVersion, '>=0.3.0')) {
         createArgs.push('--buildkitd-flags', inputs.buildkitdFlags);
       }
       if (inputs.use) {