mirror of
				https://github.com/docker/setup-buildx-action.git
				synced 2025-10-31 01:20:09 +08:00 
			
		
		
		
	Merge pull request #99 from crazy-max/build-ref
Allow building buildx from source
This commit is contained in:
		
						commit
						e673438944
					
				
							
								
								
									
										34
									
								
								.github/workflows/ci.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										34
									
								
								.github/workflows/ci.yml
									
									
									
									
										vendored
									
									
								
							| @ -313,3 +313,37 @@ jobs: | ||||
|           echo "Status:    ${{ steps.buildx.outputs.status }}" | ||||
|           echo "Flags:     ${{ steps.buildx.outputs.flags }}" | ||||
|           echo "Platforms: ${{ steps.buildx.outputs.platforms }}" | ||||
| 
 | ||||
|   build-ref: | ||||
|     runs-on: ubuntu-latest | ||||
|     strategy: | ||||
|       fail-fast: false | ||||
|       matrix: | ||||
|         ref: | ||||
|           - master | ||||
|           - refs/tags/v0.5.1 | ||||
|           - refs/pull/648/head | ||||
|     steps: | ||||
|       - | ||||
|         name: Checkout | ||||
|         uses: actions/checkout@v2 | ||||
|       - | ||||
|         name: Set up Docker Buildx | ||||
|         uses: ./ | ||||
|         with: | ||||
|           version: https://github.com/docker/buildx.git#${{ matrix.ref }} | ||||
|       - | ||||
|         name: Check version | ||||
|         run: | | ||||
|           docker buildx version | ||||
|       - | ||||
|         name: Create Dockerfile | ||||
|         run: | | ||||
|           cat > ./Dockerfile <<EOL | ||||
|           FROM alpine | ||||
|           EOL | ||||
|       - | ||||
|         name: Build | ||||
|         uses: docker/build-push-action@master | ||||
|         with: | ||||
|           context: . | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| { | ||||
|   "printWidth": 120, | ||||
|   "printWidth": 240, | ||||
|   "tabWidth": 2, | ||||
|   "useTabs": false, | ||||
|   "semi": true, | ||||
|  | ||||
| @ -125,7 +125,7 @@ Following inputs can be used as `step.with` keys | ||||
| 
 | ||||
| | Name               | Type    | Description                       | | ||||
| |--------------------|---------|-----------------------------------| | ||||
| | `version`          | String  | [Buildx](https://github.com/docker/buildx) version. (eg. `v0.3.0`, `latest`) | | ||||
| | `version`          | String  | [buildx](https://github.com/docker/buildx) version. (eg. `v0.3.0`, `latest`, `https://github.com/docker/buildx.git#master`) | | ||||
| | `driver`           | String  | Sets the [builder driver](https://github.com/docker/buildx/blob/master/docs/reference/buildx_create.md#driver) to be used (default `docker-container`) | | ||||
| | `driver-opts`      | CSV     | List of additional [driver-specific options](https://github.com/docker/buildx/blob/master/docs/reference/buildx_create.md#driver-opt) (eg. `image=moby/buildkit:master`) | | ||||
| | `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)) | | ||||
|  | ||||
| @ -1,10 +1,19 @@ | ||||
| import fs = require('fs'); | ||||
| import * as buildx from '../src/buildx'; | ||||
| import * as path from 'path'; | ||||
| import * as fs from 'fs'; | ||||
| import * as os from 'os'; | ||||
| import * as path from 'path'; | ||||
| import * as buildx from '../src/buildx'; | ||||
| import * as context from '../src/context'; | ||||
| import * as semver from 'semver'; | ||||
| import * as exec from '@actions/exec'; | ||||
| 
 | ||||
| jest.spyOn(context, 'tmpDir').mockImplementation((): string => { | ||||
|   const tmpDir = path.join('/tmp/.docker-setup-buildx-jest').split(path.sep).join(path.posix.sep); | ||||
|   if (!fs.existsSync(tmpDir)) { | ||||
|     fs.mkdirSync(tmpDir, {recursive: true}); | ||||
|   } | ||||
|   return tmpDir; | ||||
| }); | ||||
| 
 | ||||
| describe('isAvailable', () => { | ||||
|   const execSpy: jest.SpyInstance = jest.spyOn(exec, 'getExecOutput'); | ||||
|   buildx.isAvailable(); | ||||
| @ -41,9 +50,20 @@ 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'] | ||||
|     ['github.com/docker/buildx v0.4.2 fb7b670b764764dc4716df3eba07ffdae4cc47b2', '0.4.2'], | ||||
|     ['github.com/docker/buildx f117971 f11797113e5a9b86bd976329c5dbb8a8bfdfadfa', 'f117971'] | ||||
|   ])('given %p', async (stdout, expected) => { | ||||
|     expect(await buildx.parseVersion(stdout)).toEqual(expected); | ||||
|     expect(buildx.parseVersion(stdout)).toEqual(expected); | ||||
|   }); | ||||
| }); | ||||
| 
 | ||||
| describe('satisfies', () => { | ||||
|   test.each([ | ||||
|     ['0.4.1', '>=0.3.2', true], | ||||
|     ['bda4882a65349ca359216b135896bddc1d92461c', '>0.1.0', false], | ||||
|     ['f117971', '>0.6.0', true] | ||||
|   ])('given %p', async (version, range, expected) => { | ||||
|     expect(buildx.satisfies(version, range)).toBe(expected); | ||||
|   }); | ||||
| }); | ||||
| 
 | ||||
| @ -72,6 +92,15 @@ describe('inspect', () => { | ||||
|   ); | ||||
| }); | ||||
| 
 | ||||
| describe('build', () => { | ||||
|   it.skip('valid', async () => { | ||||
|     const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'setup-buildx-')); | ||||
|     const buildxBin = await buildx.build('https://github.com/docker/buildx.git#refs/pull/648/head', tmpDir); | ||||
|     console.log(buildxBin); | ||||
|     expect(fs.existsSync(buildxBin)).toBe(true); | ||||
|   }, 100000); | ||||
| }); | ||||
| 
 | ||||
| describe('install', () => { | ||||
|   const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'setup-buildx-')); | ||||
|   it('acquires v0.4.1 version of buildx', async () => { | ||||
|  | ||||
| @ -1,6 +1,16 @@ | ||||
| import * as fs from 'fs'; | ||||
| import * as os from 'os'; | ||||
| import * as path from 'path'; | ||||
| import * as context from '../src/context'; | ||||
| 
 | ||||
| jest.spyOn(context, 'tmpDir').mockImplementation((): string => { | ||||
|   const tmpDir = path.join('/tmp/.docker-setup-buildx-jest').split(path.sep).join(path.posix.sep); | ||||
|   if (!fs.existsSync(tmpDir)) { | ||||
|     fs.mkdirSync(tmpDir, {recursive: true}); | ||||
|   } | ||||
|   return tmpDir; | ||||
| }); | ||||
| 
 | ||||
| describe('getInputList', () => { | ||||
|   it('handles single line correctly', async () => { | ||||
|     await setInput('foo', 'bar'); | ||||
|  | ||||
							
								
								
									
										9
									
								
								__tests__/git.test.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								__tests__/git.test.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,9 @@ | ||||
| import * as git from '../src/git'; | ||||
| 
 | ||||
| describe('git', () => { | ||||
|   it('returns git remote ref', async () => { | ||||
|     const ref: string = await git.getRemoteSha('https://github.com/docker/buildx.git', 'refs/pull/648/head'); | ||||
|     console.log(`ref: ${ref}`); | ||||
|     expect(ref).toEqual('f11797113e5a9b86bd976329c5dbb8a8bfdfadfa'); | ||||
|   }); | ||||
| }); | ||||
							
								
								
									
										11
									
								
								__tests__/util.test.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								__tests__/util.test.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,11 @@ | ||||
| import * as util from '../src/util'; | ||||
| 
 | ||||
| describe('isValidUrl', () => { | ||||
|   test.each([ | ||||
|     ['https://github.com/docker/buildx.git', true], | ||||
|     ['https://github.com/docker/buildx.git#refs/pull/648/head', true], | ||||
|     ['v0.4.1', false] | ||||
|   ])('given %p', async (url, expected) => { | ||||
|     expect(util.isValidUrl(url)).toEqual(expected); | ||||
|   }); | ||||
| }); | ||||
							
								
								
									
										3
									
								
								codecov.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								codecov.yml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,3 @@ | ||||
| comment: false | ||||
| github_checks: | ||||
|   annotations: false | ||||
							
								
								
									
										167
									
								
								dist/index.js
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										167
									
								
								dist/index.js
									
									
									
										generated
									
									
										vendored
									
									
								
							| @ -35,12 +35,13 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge | ||||
|     }); | ||||
| }; | ||||
| Object.defineProperty(exports, "__esModule", ({ value: true })); | ||||
| exports.getBuildKitVersion = exports.install = exports.inspect = exports.parseVersion = exports.getVersion = exports.isAvailable = void 0; | ||||
| exports.getBuildKitVersion = exports.install = exports.build = exports.inspect = exports.satisfies = exports.parseVersion = exports.getVersion = exports.isAvailable = void 0; | ||||
| const fs = __importStar(__nccwpck_require__(5747)); | ||||
| const path = __importStar(__nccwpck_require__(5622)); | ||||
| const semver = __importStar(__nccwpck_require__(1383)); | ||||
| const util = __importStar(__nccwpck_require__(1669)); | ||||
| const context = __importStar(__nccwpck_require__(3842)); | ||||
| const git = __importStar(__nccwpck_require__(3374)); | ||||
| const github = __importStar(__nccwpck_require__(5928)); | ||||
| const core = __importStar(__nccwpck_require__(2186)); | ||||
| const exec = __importStar(__nccwpck_require__(1514)); | ||||
| @ -78,15 +79,17 @@ function getVersion() { | ||||
| } | ||||
| 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]); | ||||
|     }); | ||||
|     const matches = /\sv?([0-9a-f]{7}|[0-9.]+)/.exec(stdout); | ||||
|     if (!matches) { | ||||
|         throw new Error(`Cannot parse buildx version`); | ||||
|     } | ||||
|     return matches[1]; | ||||
| } | ||||
| exports.parseVersion = parseVersion; | ||||
| function satisfies(version, range) { | ||||
|     return semver.satisfies(version, range) || /^[0-9a-f]{7}$/.exec(version) !== null; | ||||
| } | ||||
| exports.satisfies = satisfies; | ||||
| function inspect(name) { | ||||
|     return __awaiter(this, void 0, void 0, function* () { | ||||
|         return yield exec | ||||
| @ -142,6 +145,33 @@ function inspect(name) { | ||||
|     }); | ||||
| } | ||||
| exports.inspect = inspect; | ||||
| function build(inputBuildRef, dockerConfigHome) { | ||||
|     return __awaiter(this, void 0, void 0, function* () { | ||||
|         let [repo, ref] = inputBuildRef.split('#'); | ||||
|         if (ref.length == 0) { | ||||
|             ref = 'master'; | ||||
|         } | ||||
|         const sha = yield git.getRemoteSha(repo, ref); | ||||
|         core.debug(`Remote ref ${sha} found`); | ||||
|         let toolPath; | ||||
|         toolPath = tc.find('buildx', sha); | ||||
|         if (!toolPath) { | ||||
|             const outFolder = path.join(context.tmpDir(), 'out').split(path.sep).join(path.posix.sep); | ||||
|             toolPath = yield exec | ||||
|                 .getExecOutput('docker', ['buildx', 'build', '--target', 'binaries', '--build-arg', 'BUILDKIT_CONTEXT_KEEP_GIT_DIR=1', '--output', `type=local,dest=${outFolder}`, inputBuildRef], { | ||||
|                 ignoreReturnCode: true | ||||
|             }) | ||||
|                 .then(res => { | ||||
|                 if (res.stderr.length > 0 && res.exitCode != 0) { | ||||
|                     core.warning(res.stderr.trim()); | ||||
|                 } | ||||
|                 return tc.cacheFile(`${outFolder}/buildx`, context.osPlat == 'win32' ? 'docker-buildx.exe' : 'docker-buildx', 'buildx', sha); | ||||
|             }); | ||||
|         } | ||||
|         return setPlugin(toolPath, dockerConfigHome); | ||||
|     }); | ||||
| } | ||||
| exports.build = build; | ||||
| function install(inputVersion, dockerConfigHome) { | ||||
|     return __awaiter(this, void 0, void 0, function* () { | ||||
|         const release = yield github.getRelease(inputVersion); | ||||
| @ -159,6 +189,12 @@ function install(inputVersion, dockerConfigHome) { | ||||
|             } | ||||
|             toolPath = yield download(version); | ||||
|         } | ||||
|         return setPlugin(toolPath, dockerConfigHome); | ||||
|     }); | ||||
| } | ||||
| exports.install = install; | ||||
| function setPlugin(toolPath, dockerConfigHome) { | ||||
|     return __awaiter(this, void 0, void 0, function* () { | ||||
|         const pluginsDir = path.join(dockerConfigHome, 'cli-plugins'); | ||||
|         core.debug(`Plugins dir is ${pluginsDir}`); | ||||
|         if (!fs.existsSync(pluginsDir)) { | ||||
| @ -173,7 +209,6 @@ function install(inputVersion, dockerConfigHome) { | ||||
|         return pluginPath; | ||||
|     }); | ||||
| } | ||||
| exports.install = install; | ||||
| function download(version) { | ||||
|     return __awaiter(this, void 0, void 0, function* () { | ||||
|         const targetFile = context.osPlat == 'win32' ? 'docker-buildx.exe' : 'docker-buildx'; | ||||
| @ -286,21 +321,33 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge | ||||
|         step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||||
|     }); | ||||
| }; | ||||
| var __importDefault = (this && this.__importDefault) || function (mod) { | ||||
|     return (mod && mod.__esModule) ? mod : { "default": mod }; | ||||
| }; | ||||
| Object.defineProperty(exports, "__esModule", ({ value: true })); | ||||
| exports.setOutput = exports.asyncForEach = exports.getInputList = exports.getInputs = exports.osArch = exports.osPlat = void 0; | ||||
| exports.setOutput = exports.asyncForEach = exports.getInputList = exports.getInputs = exports.tmpDir = exports.osArch = exports.osPlat = void 0; | ||||
| const fs_1 = __importDefault(__nccwpck_require__(5747)); | ||||
| const os = __importStar(__nccwpck_require__(2087)); | ||||
| const path_1 = __importDefault(__nccwpck_require__(5622)); | ||||
| const core = __importStar(__nccwpck_require__(2186)); | ||||
| const command_1 = __nccwpck_require__(7351); | ||||
| let _tmpDir; | ||||
| exports.osPlat = os.platform(); | ||||
| exports.osArch = os.arch(); | ||||
| function tmpDir() { | ||||
|     if (!_tmpDir) { | ||||
|         _tmpDir = fs_1.default.mkdtempSync(path_1.default.join(os.tmpdir(), 'docker-setup-buildx-')).split(path_1.default.sep).join(path_1.default.posix.sep); | ||||
|     } | ||||
|     return _tmpDir; | ||||
| } | ||||
| exports.tmpDir = tmpDir; | ||||
| function getInputs() { | ||||
|     return __awaiter(this, void 0, void 0, function* () { | ||||
|         return { | ||||
|             version: core.getInput('version'), | ||||
|             driver: core.getInput('driver') || 'docker-container', | ||||
|             driverOpts: yield getInputList('driver-opts', true), | ||||
|             buildkitdFlags: core.getInput('buildkitd-flags') || | ||||
|                 '--allow-insecure-entitlement security.insecure --allow-insecure-entitlement network.host', | ||||
|             buildkitdFlags: core.getInput('buildkitd-flags') || '--allow-insecure-entitlement security.insecure --allow-insecure-entitlement network.host', | ||||
|             install: core.getBooleanInput('install'), | ||||
|             use: core.getBooleanInput('use'), | ||||
|             endpoint: core.getInput('endpoint'), | ||||
| @ -337,6 +384,66 @@ exports.setOutput = setOutput; | ||||
| 
 | ||||
| /***/ }), | ||||
| 
 | ||||
| /***/ 3374: | ||||
| /***/ (function(__unused_webpack_module, exports, __nccwpck_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.prototype.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.getRemoteSha = void 0; | ||||
| const exec = __importStar(__nccwpck_require__(1514)); | ||||
| function getRemoteSha(repo, ref) { | ||||
|     return __awaiter(this, void 0, void 0, function* () { | ||||
|         return yield exec | ||||
|             .getExecOutput(`git`, ['ls-remote', repo, ref], { | ||||
|             ignoreReturnCode: true, | ||||
|             silent: true | ||||
|         }) | ||||
|             .then(res => { | ||||
|             if (res.stderr.length > 0 && res.exitCode != 0) { | ||||
|                 throw new Error(res.stderr); | ||||
|             } | ||||
|             const [rsha, rref] = res.stdout.trim().split(/[\s\t]/); | ||||
|             if (rsha.length == 0) { | ||||
|                 throw new Error(`Cannot find remote ref for ${repo}#${ref}`); | ||||
|             } | ||||
|             return rsha; | ||||
|         }); | ||||
|     }); | ||||
| } | ||||
| exports.getRemoteSha = getRemoteSha; | ||||
| //# sourceMappingURL=git.js.map
 | ||||
| 
 | ||||
| /***/ }), | ||||
| 
 | ||||
| /***/ 5928: | ||||
| /***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { | ||||
| 
 | ||||
| @ -419,10 +526,10 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge | ||||
| Object.defineProperty(exports, "__esModule", ({ value: true })); | ||||
| const os = __importStar(__nccwpck_require__(2087)); | ||||
| const path = __importStar(__nccwpck_require__(5622)); | ||||
| const semver = __importStar(__nccwpck_require__(1383)); | ||||
| const buildx = __importStar(__nccwpck_require__(9295)); | ||||
| const context = __importStar(__nccwpck_require__(3842)); | ||||
| const stateHelper = __importStar(__nccwpck_require__(8647)); | ||||
| const util = __importStar(__nccwpck_require__(4024)); | ||||
| const core = __importStar(__nccwpck_require__(2186)); | ||||
| const exec = __importStar(__nccwpck_require__(1514)); | ||||
| function run() { | ||||
| @ -435,8 +542,13 @@ function run() { | ||||
|             core.endGroup(); | ||||
|             const inputs = yield context.getInputs(); | ||||
|             const dockerConfigHome = process.env.DOCKER_CONFIG || path.join(os.homedir(), '.docker'); | ||||
|             if (!(yield buildx.isAvailable()) || inputs.version) { | ||||
|                 core.startGroup(`Installing buildx`); | ||||
|             if (util.isValidUrl(inputs.version)) { | ||||
|                 core.startGroup(`Build and install buildx`); | ||||
|                 yield buildx.build(inputs.version, dockerConfigHome); | ||||
|                 core.endGroup(); | ||||
|             } | ||||
|             else if (!(yield buildx.isAvailable()) || inputs.version) { | ||||
|                 core.startGroup(`Download and install buildx`); | ||||
|                 yield buildx.install(inputs.version || 'latest', dockerConfigHome); | ||||
|                 core.endGroup(); | ||||
|             } | ||||
| @ -447,7 +559,7 @@ function run() { | ||||
|             if (inputs.driver !== 'docker') { | ||||
|                 core.startGroup(`Creating a new builder instance`); | ||||
|                 let createArgs = ['buildx', 'create', '--name', builderName, '--driver', inputs.driver]; | ||||
|                 if (semver.satisfies(buildxVersion, '>=0.3.0')) { | ||||
|                 if (buildx.satisfies(buildxVersion, '>=0.3.0')) { | ||||
|                     yield context.asyncForEach(inputs.driverOpts, (driverOpt) => __awaiter(this, void 0, void 0, function* () { | ||||
|                         createArgs.push('--driver-opt', driverOpt); | ||||
|                     })); | ||||
| @ -468,7 +580,7 @@ function run() { | ||||
|                 core.endGroup(); | ||||
|                 core.startGroup(`Booting builder`); | ||||
|                 let bootstrapArgs = ['buildx', 'inspect', '--bootstrap']; | ||||
|                 if (semver.satisfies(buildxVersion, '>=0.4.0')) { | ||||
|                 if (buildx.satisfies(buildxVersion, '>=0.4.0')) { | ||||
|                     bootstrapArgs.push('--builder', builderName); | ||||
|                 } | ||||
|                 yield exec.exec('docker', bootstrapArgs); | ||||
| @ -593,6 +705,27 @@ if (!exports.IsPost) { | ||||
| 
 | ||||
| /***/ }), | ||||
| 
 | ||||
| /***/ 4024: | ||||
| /***/ ((__unused_webpack_module, exports) => { | ||||
| 
 | ||||
| "use strict"; | ||||
| 
 | ||||
| Object.defineProperty(exports, "__esModule", ({ value: true })); | ||||
| exports.isValidUrl = void 0; | ||||
| function isValidUrl(url) { | ||||
|     try { | ||||
|         new URL(url); | ||||
|     } | ||||
|     catch (e) { | ||||
|         return false; | ||||
|     } | ||||
|     return true; | ||||
| } | ||||
| exports.isValidUrl = isValidUrl; | ||||
| //# sourceMappingURL=util.js.map
 | ||||
| 
 | ||||
| /***/ }), | ||||
| 
 | ||||
| /***/ 7351: | ||||
| /***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { | ||||
| 
 | ||||
|  | ||||
| @ -3,6 +3,7 @@ import * as path from 'path'; | ||||
| import * as semver from 'semver'; | ||||
| import * as util from 'util'; | ||||
| import * as context from './context'; | ||||
| import * as git from './git'; | ||||
| import * as github from './github'; | ||||
| import * as core from '@actions/core'; | ||||
| import * as exec from '@actions/exec'; | ||||
| @ -46,12 +47,16 @@ export async function getVersion(): Promise<string> { | ||||
|     }); | ||||
| } | ||||
| 
 | ||||
| export async function parseVersion(stdout: string): Promise<string> { | ||||
|   const matches = /\sv?([0-9.]+)/.exec(stdout); | ||||
| export function parseVersion(stdout: string): string { | ||||
|   const matches = /\sv?([0-9a-f]{7}|[0-9.]+)/.exec(stdout); | ||||
|   if (!matches) { | ||||
|     throw new Error(`Cannot parse buildx version`); | ||||
|   } | ||||
|   return semver.clean(matches[1]); | ||||
|   return matches[1]; | ||||
| } | ||||
| 
 | ||||
| export function satisfies(version: string, range: string): boolean { | ||||
|   return semver.satisfies(version, range) || /^[0-9a-f]{7}$/.exec(version) !== null; | ||||
| } | ||||
| 
 | ||||
| export async function inspect(name: string): Promise<Builder> { | ||||
| @ -106,6 +111,34 @@ export async function inspect(name: string): Promise<Builder> { | ||||
|     }); | ||||
| } | ||||
| 
 | ||||
| export async function build(inputBuildRef: string, dockerConfigHome: string): Promise<string> { | ||||
|   let [repo, ref] = inputBuildRef.split('#'); | ||||
|   if (ref.length == 0) { | ||||
|     ref = 'master'; | ||||
|   } | ||||
| 
 | ||||
|   const sha = await git.getRemoteSha(repo, ref); | ||||
|   core.debug(`Remote ref ${sha} found`); | ||||
| 
 | ||||
|   let toolPath: string; | ||||
|   toolPath = tc.find('buildx', sha); | ||||
|   if (!toolPath) { | ||||
|     const outFolder = path.join(context.tmpDir(), 'out').split(path.sep).join(path.posix.sep); | ||||
|     toolPath = await exec | ||||
|       .getExecOutput('docker', ['buildx', 'build', '--target', 'binaries', '--build-arg', 'BUILDKIT_CONTEXT_KEEP_GIT_DIR=1', '--output', `type=local,dest=${outFolder}`, inputBuildRef], { | ||||
|         ignoreReturnCode: true | ||||
|       }) | ||||
|       .then(res => { | ||||
|         if (res.stderr.length > 0 && res.exitCode != 0) { | ||||
|           core.warning(res.stderr.trim()); | ||||
|         } | ||||
|         return tc.cacheFile(`${outFolder}/buildx`, context.osPlat == 'win32' ? 'docker-buildx.exe' : 'docker-buildx', 'buildx', sha); | ||||
|       }); | ||||
|   } | ||||
| 
 | ||||
|   return setPlugin(toolPath, dockerConfigHome); | ||||
| } | ||||
| 
 | ||||
| export async function install(inputVersion: string, dockerConfigHome: string): Promise<string> { | ||||
|   const release: github.GitHubRelease | null = await github.getRelease(inputVersion); | ||||
|   if (!release) { | ||||
| @ -124,6 +157,10 @@ export async function install(inputVersion: string, dockerConfigHome: string): P | ||||
|     toolPath = await download(version); | ||||
|   } | ||||
| 
 | ||||
|   return setPlugin(toolPath, dockerConfigHome); | ||||
| } | ||||
| 
 | ||||
| async function setPlugin(toolPath: string, dockerConfigHome: string): Promise<string> { | ||||
|   const pluginsDir: string = path.join(dockerConfigHome, 'cli-plugins'); | ||||
|   core.debug(`Plugins dir is ${pluginsDir}`); | ||||
|   if (!fs.existsSync(pluginsDir)) { | ||||
| @ -143,11 +180,7 @@ export async function install(inputVersion: string, dockerConfigHome: string): P | ||||
| 
 | ||||
| async function download(version: string): Promise<string> { | ||||
|   const targetFile: string = context.osPlat == 'win32' ? 'docker-buildx.exe' : 'docker-buildx'; | ||||
|   const downloadUrl = util.format( | ||||
|     'https://github.com/docker/buildx/releases/download/v%s/%s', | ||||
|     version, | ||||
|     await filename(version) | ||||
|   ); | ||||
|   const downloadUrl = util.format('https://github.com/docker/buildx/releases/download/v%s/%s', version, await filename(version)); | ||||
|   let downloadPath: string; | ||||
| 
 | ||||
|   try { | ||||
|  | ||||
| @ -1,10 +1,20 @@ | ||||
| import fs from 'fs'; | ||||
| import * as os from 'os'; | ||||
| import path from 'path'; | ||||
| import * as core from '@actions/core'; | ||||
| import {issueCommand} from '@actions/core/lib/command'; | ||||
| 
 | ||||
| let _tmpDir: string; | ||||
| export const osPlat: string = os.platform(); | ||||
| export const osArch: string = os.arch(); | ||||
| 
 | ||||
| export function tmpDir(): string { | ||||
|   if (!_tmpDir) { | ||||
|     _tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'docker-setup-buildx-')).split(path.sep).join(path.posix.sep); | ||||
|   } | ||||
|   return _tmpDir; | ||||
| } | ||||
| 
 | ||||
| export interface Inputs { | ||||
|   version: string; | ||||
|   driver: string; | ||||
| @ -21,9 +31,7 @@ export async function getInputs(): Promise<Inputs> { | ||||
|     version: core.getInput('version'), | ||||
|     driver: core.getInput('driver') || 'docker-container', | ||||
|     driverOpts: await getInputList('driver-opts', true), | ||||
|     buildkitdFlags: | ||||
|       core.getInput('buildkitd-flags') || | ||||
|       '--allow-insecure-entitlement security.insecure --allow-insecure-entitlement network.host', | ||||
|     buildkitdFlags: core.getInput('buildkitd-flags') || '--allow-insecure-entitlement security.insecure --allow-insecure-entitlement network.host', | ||||
|     install: core.getBooleanInput('install'), | ||||
|     use: core.getBooleanInput('use'), | ||||
|     endpoint: core.getInput('endpoint'), | ||||
| @ -39,10 +47,7 @@ export async function getInputList(name: string, ignoreComma?: boolean): Promise | ||||
|   return items | ||||
|     .split(/\r?\n/) | ||||
|     .filter(x => x) | ||||
|     .reduce<string[]>( | ||||
|       (acc, line) => acc.concat(!ignoreComma ? line.split(',').filter(x => x) : line).map(pat => pat.trim()), | ||||
|       [] | ||||
|     ); | ||||
|     .reduce<string[]>((acc, line) => acc.concat(!ignoreComma ? line.split(',').filter(x => x) : line).map(pat => pat.trim()), []); | ||||
| } | ||||
| 
 | ||||
| export const asyncForEach = async (array, callback) => { | ||||
|  | ||||
							
								
								
									
										19
									
								
								src/git.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								src/git.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,19 @@ | ||||
| import * as exec from '@actions/exec'; | ||||
| 
 | ||||
| export async function getRemoteSha(repo: string, ref: string): Promise<string> { | ||||
|   return await exec | ||||
|     .getExecOutput(`git`, ['ls-remote', repo, ref], { | ||||
|       ignoreReturnCode: true, | ||||
|       silent: true | ||||
|     }) | ||||
|     .then(res => { | ||||
|       if (res.stderr.length > 0 && res.exitCode != 0) { | ||||
|         throw new Error(res.stderr); | ||||
|       } | ||||
|       const [rsha, rref] = res.stdout.trim().split(/[\s\t]/); | ||||
|       if (rsha.length == 0) { | ||||
|         throw new Error(`Cannot find remote ref for ${repo}#${ref}`); | ||||
|       } | ||||
|       return rsha; | ||||
|     }); | ||||
| } | ||||
							
								
								
									
										14
									
								
								src/main.ts
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								src/main.ts
									
									
									
									
									
								
							| @ -1,9 +1,9 @@ | ||||
| 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 stateHelper from './state-helper'; | ||||
| import * as util from './util'; | ||||
| import * as core from '@actions/core'; | ||||
| import * as exec from '@actions/exec'; | ||||
| 
 | ||||
| @ -17,8 +17,12 @@ async function run(): Promise<void> { | ||||
|     const inputs: context.Inputs = await context.getInputs(); | ||||
|     const dockerConfigHome: string = process.env.DOCKER_CONFIG || path.join(os.homedir(), '.docker'); | ||||
| 
 | ||||
|     if (!(await buildx.isAvailable()) || inputs.version) { | ||||
|       core.startGroup(`Installing buildx`); | ||||
|     if (util.isValidUrl(inputs.version)) { | ||||
|       core.startGroup(`Build and install buildx`); | ||||
|       await buildx.build(inputs.version, dockerConfigHome); | ||||
|       core.endGroup(); | ||||
|     } else if (!(await buildx.isAvailable()) || inputs.version) { | ||||
|       core.startGroup(`Download and install buildx`); | ||||
|       await buildx.install(inputs.version || 'latest', dockerConfigHome); | ||||
|       core.endGroup(); | ||||
|     } | ||||
| @ -31,7 +35,7 @@ async function run(): Promise<void> { | ||||
|     if (inputs.driver !== 'docker') { | ||||
|       core.startGroup(`Creating a new builder instance`); | ||||
|       let createArgs: Array<string> = ['buildx', 'create', '--name', builderName, '--driver', inputs.driver]; | ||||
|       if (semver.satisfies(buildxVersion, '>=0.3.0')) { | ||||
|       if (buildx.satisfies(buildxVersion, '>=0.3.0')) { | ||||
|         await context.asyncForEach(inputs.driverOpts, async driverOpt => { | ||||
|           createArgs.push('--driver-opt', driverOpt); | ||||
|         }); | ||||
| @ -53,7 +57,7 @@ async function run(): Promise<void> { | ||||
| 
 | ||||
|       core.startGroup(`Booting builder`); | ||||
|       let bootstrapArgs: Array<string> = ['buildx', 'inspect', '--bootstrap']; | ||||
|       if (semver.satisfies(buildxVersion, '>=0.4.0')) { | ||||
|       if (buildx.satisfies(buildxVersion, '>=0.4.0')) { | ||||
|         bootstrapArgs.push('--builder', builderName); | ||||
|       } | ||||
|       await exec.exec('docker', bootstrapArgs); | ||||
|  | ||||
							
								
								
									
										8
									
								
								src/util.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								src/util.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,8 @@ | ||||
| export function isValidUrl(url: string): boolean { | ||||
|   try { | ||||
|     new URL(url); | ||||
|   } catch (e) { | ||||
|     return false; | ||||
|   } | ||||
|   return true; | ||||
| } | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 CrazyMax
						CrazyMax