From 5bb3f5433b613bc4ec36d8dcd92b20b0b179c62c Mon Sep 17 00:00:00 2001 From: CrazyMax Date: Wed, 12 Aug 2020 15:58:09 +0200 Subject: [PATCH] Check if buildx available on runner Use default buildx on runner Signed-off-by: CrazyMax --- setup-buildx/README.md | 14 +- setup-buildx/__tests__/buildx.test.ts | 24 ++ setup-buildx/__tests__/installer.test.ts | 20 -- setup-buildx/action.yml | 1 - setup-buildx/dist/index.js | 317 ++++++++++++------- setup-buildx/src/{installer.ts => buildx.ts} | 16 +- setup-buildx/src/exec.ts | 34 ++ setup-buildx/src/github.ts | 2 +- setup-buildx/src/main.ts | 42 +-- 9 files changed, 299 insertions(+), 171 deletions(-) create mode 100644 setup-buildx/__tests__/buildx.test.ts delete mode 100644 setup-buildx/__tests__/installer.test.ts rename setup-buildx/src/{installer.ts => buildx.ts} (82%) create mode 100644 setup-buildx/src/exec.ts diff --git a/setup-buildx/README.md b/setup-buildx/README.md index fe19622..a5cfeb9 100644 --- a/setup-buildx/README.md +++ b/setup-buildx/README.md @@ -88,13 +88,13 @@ jobs: Following inputs can be used as `step.with` keys -| Name | Type | Default | Description | -|------------------|---------|---------------------|------------------------------------| -| `buildx-version` | String | `latest` | [Buildx](https://github.com/docker/buildx) version. e.g. `v0.3.0` | -| `driver` | String | `docker-container` | Sets the [builder driver](https://github.com/docker/buildx#--driver-driver) to be used. | -| `driver-opt` | String | | Passes additional [driver-specific options](https://github.com/docker/buildx#--driver-opt-options). e.g. `image=moby/buildkit:master` | -| `install` | Bool | `false` | Sets up `docker build` command as an alias to `docker buildx` | -| `use` | Bool | `true` | Switch to this builder instance | +| Name | Type | Default | Description | +|------------------|---------|-----------------------------------|------------------------------------| +| `buildx-version` | String | _the one installed on the runner_ | [Buildx](https://github.com/docker/buildx) version. e.g. `v0.3.0`, `latest` | +| `driver` | String | `docker-container` | Sets the [builder driver](https://github.com/docker/buildx#--driver-driver) to be used. | +| `driver-opt` | String | | Passes additional [driver-specific options](https://github.com/docker/buildx#--driver-opt-options). e.g. `image=moby/buildkit:master` | +| `install` | Bool | `false` | Sets up `docker build` command as an alias to `docker buildx` | +| `use` | Bool | `true` | Switch to this builder instance | ### outputs diff --git a/setup-buildx/__tests__/buildx.test.ts b/setup-buildx/__tests__/buildx.test.ts new file mode 100644 index 0000000..65e8de6 --- /dev/null +++ b/setup-buildx/__tests__/buildx.test.ts @@ -0,0 +1,24 @@ +import fs = require('fs'); +import * as buildx from '../src/buildx'; +import * as path from 'path'; +import * as os from 'os'; + +const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'setup-buildx-')); + +describe('buildx', () => { + it('is available', async () => { + expect(await buildx.isAvailable()).toBe(true); + }, 100000); + + 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); + expect(fs.existsSync(buildxBin)).toBe(true); + }, 100000); +}); diff --git a/setup-buildx/__tests__/installer.test.ts b/setup-buildx/__tests__/installer.test.ts deleted file mode 100644 index e9a6990..0000000 --- a/setup-buildx/__tests__/installer.test.ts +++ /dev/null @@ -1,20 +0,0 @@ -import fs = require('fs'); -import * as installer from '../src/installer'; -import * as path from 'path'; -import * as os from 'os'; - -const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'ghaction-docker-buildx-')); - -describe('installer', () => { - it('acquires v0.2.2 version of buildx', async () => { - const buildx = await installer.buildx('v0.2.2', tmpDir); - console.log(buildx); - expect(fs.existsSync(buildx)).toBe(true); - }, 100000); - - it('acquires latest version of buildx', async () => { - const buildx = await installer.buildx('latest', tmpDir); - console.log(buildx); - expect(fs.existsSync(buildx)).toBe(true); - }, 100000); -}); diff --git a/setup-buildx/action.yml b/setup-buildx/action.yml index 10f2409..1ee677d 100644 --- a/setup-buildx/action.yml +++ b/setup-buildx/action.yml @@ -9,7 +9,6 @@ branding: inputs: buildx-version: description: 'Buildx version. e.g. v0.3.0' - default: 'latest' required: false driver: description: 'Sets the builder driver to be used' diff --git a/setup-buildx/dist/index.js b/setup-buildx/dist/index.js index 64c4791..d0bf75b 100644 --- a/setup-buildx/dist/index.js +++ b/setup-buildx/dist/index.js @@ -2477,13 +2477,12 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge }); }; Object.defineProperty(exports, "__esModule", { value: true }); -const child_process = __importStar(__webpack_require__(129)); const os = __importStar(__webpack_require__(87)); const path = __importStar(__webpack_require__(622)); -const installer = __importStar(__webpack_require__(749)); +const buildx = __importStar(__webpack_require__(982)); +const exec = __importStar(__webpack_require__(807)); const stateHelper = __importStar(__webpack_require__(153)); const core = __importStar(__webpack_require__(470)); -const exec = __importStar(__webpack_require__(986)); function run() { return __awaiter(this, void 0, void 0, function* () { try { @@ -2491,15 +2490,17 @@ function run() { core.setFailed('Only supported on linux platform'); return; } - const buildxVer = core.getInput('buildx-version') || 'latest'; + const buildxVer = core.getInput('buildx-version'); const driver = core.getInput('driver') || 'docker-container'; const driverOpt = core.getInput('driver-opt'); const install = /true/i.test(core.getInput('install')); const use = /true/i.test(core.getInput('use')); const dockerConfigHome = process.env.DOCKER_CONFIG || path.join(os.homedir(), '.docker'); - yield installer.buildx(buildxVer, dockerConfigHome); + if (!(yield buildx.isAvailable()) || buildxVer) { + yield buildx.install(buildxVer || 'latest', dockerConfigHome); + } core.info('📣 Buildx info'); - yield exec.exec('docker', ['buildx', 'version']); + yield exec.exec('docker', ['buildx', 'version'], false); core.info('🔨 Creating a new builder instance...'); let createArgs = [ 'buildx', @@ -2515,25 +2516,27 @@ function run() { if (use) { createArgs.push('--use'); } - yield exec.exec('docker', createArgs); + yield exec.exec('docker', createArgs, false); core.info('🏃 Booting builder...'); - yield exec.exec('docker', ['buildx', 'inspect', '--bootstrap']); + yield exec.exec('docker', ['buildx', 'inspect', '--bootstrap'], false); if (install) { core.info('🤝 Setting buildx as default builder...'); - yield exec.exec('docker', ['buildx', 'install']); + yield exec.exec('docker', ['buildx', 'install'], false); } core.info('🐳 Docker info'); - yield exec.exec('docker', ['info']); + yield exec.exec('docker', ['info'], false); core.info('🛒 Extracting available platforms...'); - const inspect = child_process.execSync('docker buildx inspect', { - encoding: 'utf8' - }); - for (const line of inspect.split(os.EOL)) { - if (line.startsWith('Platforms')) { - core.setOutput('platforms', line.replace('Platforms: ', '').replace(/\s/g, '').trim()); - break; + yield exec.exec(`docker`, ['buildx', 'inspect'], true).then(res => { + if (res.stderr != '' && !res.success) { + throw new Error(res.stderr); } - } + for (const line of res.stdout.trim().split(os.EOL)) { + if (line.startsWith('Platforms')) { + core.setOutput('platforms', line.replace('Platforms: ', '').replace(/\s/g, '').trim()); + break; + } + } + }); } catch (error) { core.setFailed(error.message); @@ -2544,7 +2547,7 @@ function cleanup() { return __awaiter(this, void 0, void 0, function* () { try { core.info('🚿 Removing builder instance...'); - yield exec.exec('docker', ['buildx', 'rm', `builder-${process.env.GITHUB_SHA}`]); + yield exec.exec('docker', ['buildx', 'rm', `builder-${process.env.GITHUB_SHA}`], false); } catch (error) { core.warning(error.message); @@ -6259,106 +6262,6 @@ module.exports = require("fs"); /***/ }), -/***/ 749: -/***/ (function(__unusedmodule, exports, __webpack_require__) { - -"use strict"; - -var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); -}) : (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - o[k2] = m[k]; -})); -var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { - Object.defineProperty(o, "default", { enumerable: true, value: v }); -}) : function(o, v) { - o["default"] = v; -}); -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); - __setModuleDefault(result, mod); - return result; -}; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.buildx = void 0; -const fs = __importStar(__webpack_require__(747)); -const os = __importStar(__webpack_require__(87)); -const path = __importStar(__webpack_require__(622)); -const semver = __importStar(__webpack_require__(876)); -const util = __importStar(__webpack_require__(669)); -const github = __importStar(__webpack_require__(824)); -const core = __importStar(__webpack_require__(470)); -const tc = __importStar(__webpack_require__(533)); -const osPlat = os.platform(); -function buildx(inputVersion, dockerConfigHome) { - return __awaiter(this, void 0, void 0, function* () { - const release = yield github.getRelease(inputVersion); - if (!release) { - throw new Error(`Cannot find buildx ${inputVersion} release`); - } - core.debug(`Release found: ${release.tag_name}`); - const version = release.tag_name.replace(/^v+|v+$/g, ''); - let toolPath; - toolPath = tc.find('buildx', version); - if (!toolPath) { - const c = semver.clean(version) || ''; - if (!semver.valid(c)) { - throw new Error(`Invalid Buildx version "${version}".`); - } - toolPath = yield installBuildx(version); - } - const pluginsDir = path.join(dockerConfigHome, 'cli-plugins'); - core.debug(`Plugins dir is ${pluginsDir}`); - if (!fs.existsSync(pluginsDir)) { - fs.mkdirSync(pluginsDir, { recursive: true }); - } - const filename = osPlat == 'win32' ? 'docker-buildx.exe' : 'docker-buildx'; - const pluginPath = path.join(pluginsDir, filename); - core.debug(`Plugin path is ${pluginPath}`); - fs.copyFileSync(path.join(toolPath, filename), pluginPath); - core.info('🔨 Fixing perms...'); - fs.chmodSync(pluginPath, '0755'); - return pluginPath; - }); -} -exports.buildx = buildx; -function installBuildx(version) { - return __awaiter(this, void 0, void 0, function* () { - version = semver.clean(version) || ''; - const platform = osPlat == 'win32' ? 'windows' : osPlat; - const ext = osPlat == 'win32' ? '.exe' : ''; - const filename = util.format('buildx-v%s.%s-amd64%s', version, platform, ext); - const targetFile = osPlat == 'win32' ? 'docker-buildx.exe' : 'docker-buildx'; - const downloadUrl = util.format('https://github.com/docker/buildx/releases/download/v%s/%s', version, filename); - let downloadPath; - try { - core.info(`⬇️ Downloading ${downloadUrl}...`); - downloadPath = yield tc.downloadTool(downloadUrl); - core.debug(`Downloaded to ${downloadPath}`); - } - catch (error) { - throw error; - } - return yield tc.cacheFile(downloadPath, targetFile, 'buildx', version); - }); -} -//# sourceMappingURL=installer.js.map - -/***/ }), - /***/ 752: /***/ (function(module, __unusedexports, __webpack_require__) { @@ -6560,6 +6463,68 @@ function escapeProperty(s) { /***/ }), +/***/ 807: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.exec = void 0; +const actionsExec = __importStar(__webpack_require__(986)); +exports.exec = (command, args = [], silent) => __awaiter(void 0, void 0, void 0, function* () { + let stdout = ''; + let stderr = ''; + const options = { + silent: silent, + ignoreReturnCode: true + }; + options.listeners = { + stdout: (data) => { + stdout += data.toString(); + }, + stderr: (data) => { + stderr += data.toString(); + } + }; + const returnCode = yield actionsExec.exec(command, args, options); + return { + success: returnCode === 0, + stdout: stdout.trim(), + stderr: stderr.trim() + }; +}); +//# sourceMappingURL=exec.js.map + +/***/ }), + /***/ 811: /***/ (function(module, __unusedexports, __webpack_require__) { @@ -6667,7 +6632,7 @@ exports.getRelease = void 0; const httpm = __importStar(__webpack_require__(539)); exports.getRelease = (version) => __awaiter(void 0, void 0, void 0, function* () { const url = `https://github.com/docker/buildx/releases/${version}`; - const http = new httpm.HttpClient('ghaction-docker-buildx'); + const http = new httpm.HttpClient('setup-buildx'); return (yield http.getJson(url)).result; }); //# sourceMappingURL=github.js.map @@ -7244,6 +7209,118 @@ exports.RetryHelper = RetryHelper; /***/ }), +/***/ 982: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.install = exports.isAvailable = void 0; +const fs = __importStar(__webpack_require__(747)); +const os = __importStar(__webpack_require__(87)); +const path = __importStar(__webpack_require__(622)); +const semver = __importStar(__webpack_require__(876)); +const util = __importStar(__webpack_require__(669)); +const exec = __importStar(__webpack_require__(807)); +const github = __importStar(__webpack_require__(824)); +const core = __importStar(__webpack_require__(470)); +const tc = __importStar(__webpack_require__(533)); +const osPlat = os.platform(); +function isAvailable() { + return __awaiter(this, void 0, void 0, function* () { + return yield exec.exec(`docker`, ['buildx'], true).then(res => { + if (res.stderr != '' && !res.success) { + return false; + } + return res.success; + }); + }); +} +exports.isAvailable = isAvailable; +function install(inputVersion, dockerConfigHome) { + return __awaiter(this, void 0, void 0, function* () { + const release = yield github.getRelease(inputVersion); + if (!release) { + throw new Error(`Cannot find buildx ${inputVersion} release`); + } + core.debug(`Release found: ${release.tag_name}`); + const version = release.tag_name.replace(/^v+|v+$/g, ''); + let toolPath; + toolPath = tc.find('buildx', version); + if (!toolPath) { + const c = semver.clean(version) || ''; + if (!semver.valid(c)) { + throw new Error(`Invalid Buildx version "${version}".`); + } + toolPath = yield download(version); + } + const pluginsDir = path.join(dockerConfigHome, 'cli-plugins'); + core.debug(`Plugins dir is ${pluginsDir}`); + if (!fs.existsSync(pluginsDir)) { + fs.mkdirSync(pluginsDir, { recursive: true }); + } + const filename = osPlat == 'win32' ? 'docker-buildx.exe' : 'docker-buildx'; + const pluginPath = path.join(pluginsDir, filename); + core.debug(`Plugin path is ${pluginPath}`); + fs.copyFileSync(path.join(toolPath, filename), pluginPath); + core.info('🔨 Fixing perms...'); + fs.chmodSync(pluginPath, '0755'); + return pluginPath; + }); +} +exports.install = install; +function download(version) { + return __awaiter(this, void 0, void 0, function* () { + version = semver.clean(version) || ''; + const platform = osPlat == 'win32' ? 'windows' : osPlat; + const ext = osPlat == 'win32' ? '.exe' : ''; + const filename = util.format('buildx-v%s.%s-amd64%s', version, platform, ext); + const targetFile = osPlat == 'win32' ? 'docker-buildx.exe' : 'docker-buildx'; + const downloadUrl = util.format('https://github.com/docker/buildx/releases/download/v%s/%s', version, filename); + let downloadPath; + try { + core.info(`⬇️ Downloading ${downloadUrl}...`); + downloadPath = yield tc.downloadTool(downloadUrl); + core.debug(`Downloaded to ${downloadPath}`); + } + catch (error) { + throw error; + } + return yield tc.cacheFile(downloadPath, targetFile, 'buildx', version); + }); +} +//# sourceMappingURL=buildx.js.map + +/***/ }), + /***/ 986: /***/ (function(__unusedmodule, exports, __webpack_require__) { diff --git a/setup-buildx/src/installer.ts b/setup-buildx/src/buildx.ts similarity index 82% rename from setup-buildx/src/installer.ts rename to setup-buildx/src/buildx.ts index 6b9e0a0..0e43fc7 100644 --- a/setup-buildx/src/installer.ts +++ b/setup-buildx/src/buildx.ts @@ -3,13 +3,23 @@ import * as os from 'os'; import * as path from 'path'; import * as semver from 'semver'; import * as util from 'util'; +import * as exec from './exec'; import * as github from './github'; import * as core from '@actions/core'; import * as tc from '@actions/tool-cache'; const osPlat: string = os.platform(); -export async function buildx(inputVersion: string, dockerConfigHome: string): Promise { +export async function isAvailable(): Promise { + return await exec.exec(`docker`, ['buildx'], true).then(res => { + if (res.stderr != '' && !res.success) { + return false; + } + return res.success; + }); +} + +export async function install(inputVersion: string, dockerConfigHome: string): Promise { const release: github.GitHubRelease | null = await github.getRelease(inputVersion); if (!release) { throw new Error(`Cannot find buildx ${inputVersion} release`); @@ -24,7 +34,7 @@ export async function buildx(inputVersion: string, dockerConfigHome: string): Pr if (!semver.valid(c)) { throw new Error(`Invalid Buildx version "${version}".`); } - toolPath = await installBuildx(version); + toolPath = await download(version); } const pluginsDir: string = path.join(dockerConfigHome, 'cli-plugins'); @@ -44,7 +54,7 @@ export async function buildx(inputVersion: string, dockerConfigHome: string): Pr return pluginPath; } -async function installBuildx(version: string): Promise { +async function download(version: string): Promise { version = semver.clean(version) || ''; const platform: string = osPlat == 'win32' ? 'windows' : osPlat; const ext: string = osPlat == 'win32' ? '.exe' : ''; diff --git a/setup-buildx/src/exec.ts b/setup-buildx/src/exec.ts new file mode 100644 index 0000000..9ae09ca --- /dev/null +++ b/setup-buildx/src/exec.ts @@ -0,0 +1,34 @@ +import * as actionsExec from '@actions/exec'; +import {ExecOptions} from '@actions/exec'; + +export interface ExecResult { + success: boolean; + stdout: string; + stderr: string; +} + +export const exec = async (command: string, args: string[] = [], silent: boolean): Promise => { + let stdout: string = ''; + let stderr: string = ''; + + const options: ExecOptions = { + silent: silent, + ignoreReturnCode: true + }; + options.listeners = { + stdout: (data: Buffer) => { + stdout += data.toString(); + }, + stderr: (data: Buffer) => { + stderr += data.toString(); + } + }; + + const returnCode: number = await actionsExec.exec(command, args, options); + + return { + success: returnCode === 0, + stdout: stdout.trim(), + stderr: stderr.trim() + }; +}; diff --git a/setup-buildx/src/github.ts b/setup-buildx/src/github.ts index abd797e..12d7b08 100644 --- a/setup-buildx/src/github.ts +++ b/setup-buildx/src/github.ts @@ -7,6 +7,6 @@ export interface GitHubRelease { export const getRelease = async (version: string): Promise => { const url: string = `https://github.com/docker/buildx/releases/${version}`; - const http: httpm.HttpClient = new httpm.HttpClient('ghaction-docker-buildx'); + const http: httpm.HttpClient = new httpm.HttpClient('setup-buildx'); return (await http.getJson(url)).result; }; diff --git a/setup-buildx/src/main.ts b/setup-buildx/src/main.ts index a29da5c..c65efa1 100644 --- a/setup-buildx/src/main.ts +++ b/setup-buildx/src/main.ts @@ -1,10 +1,9 @@ -import * as child_process from 'child_process'; import * as os from 'os'; import * as path from 'path'; -import * as installer from './installer'; +import * as buildx from './buildx'; +import * as exec from './exec'; import * as stateHelper from './state-helper'; import * as core from '@actions/core'; -import * as exec from '@actions/exec'; async function run(): Promise { try { @@ -13,17 +12,20 @@ async function run(): Promise { return; } - const buildxVer: string = core.getInput('buildx-version') || 'latest'; + const buildxVer: string = core.getInput('buildx-version'); const driver: string = core.getInput('driver') || 'docker-container'; const driverOpt: string = core.getInput('driver-opt'); const install: boolean = /true/i.test(core.getInput('install')); const use: boolean = /true/i.test(core.getInput('use')); const dockerConfigHome: string = process.env.DOCKER_CONFIG || path.join(os.homedir(), '.docker'); - await installer.buildx(buildxVer, dockerConfigHome); + + if (!(await buildx.isAvailable()) || buildxVer) { + await buildx.install(buildxVer || 'latest', dockerConfigHome); + } core.info('📣 Buildx info'); - await exec.exec('docker', ['buildx', 'version']); + await exec.exec('docker', ['buildx', 'version'], false); core.info('🔨 Creating a new builder instance...'); let createArgs: Array = [ @@ -41,29 +43,31 @@ async function run(): Promise { createArgs.push('--use'); } - await exec.exec('docker', createArgs); + await exec.exec('docker', createArgs, false); core.info('🏃 Booting builder...'); - await exec.exec('docker', ['buildx', 'inspect', '--bootstrap']); + await exec.exec('docker', ['buildx', 'inspect', '--bootstrap'], false); if (install) { core.info('🤝 Setting buildx as default builder...'); - await exec.exec('docker', ['buildx', 'install']); + await exec.exec('docker', ['buildx', 'install'], false); } core.info('🐳 Docker info'); - await exec.exec('docker', ['info']); + await exec.exec('docker', ['info'], false); core.info('🛒 Extracting available platforms...'); - const inspect = child_process.execSync('docker buildx inspect', { - encoding: 'utf8' - }); - for (const line of inspect.split(os.EOL)) { - if (line.startsWith('Platforms')) { - core.setOutput('platforms', line.replace('Platforms: ', '').replace(/\s/g, '').trim()); - break; + await exec.exec(`docker`, ['buildx', 'inspect'], true).then(res => { + if (res.stderr != '' && !res.success) { + throw new Error(res.stderr); } - } + for (const line of res.stdout.trim().split(os.EOL)) { + if (line.startsWith('Platforms')) { + core.setOutput('platforms', line.replace('Platforms: ', '').replace(/\s/g, '').trim()); + break; + } + } + }); } catch (error) { core.setFailed(error.message); } @@ -72,7 +76,7 @@ async function run(): Promise { async function cleanup(): Promise { try { core.info('🚿 Removing builder instance...'); - await exec.exec('docker', ['buildx', 'rm', `builder-${process.env.GITHUB_SHA}`]); + await exec.exec('docker', ['buildx', 'rm', `builder-${process.env.GITHUB_SHA}`], false); } catch (error) { core.warning(error.message); }