mirror of
				https://github.com/docker/setup-buildx-action.git
				synced 2025-11-01 03:55:49 +08:00 
			
		
		
		
	Use built-in getExecOutput
				
					
				
			Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
This commit is contained in:
		
							parent
							
								
									faca7837b0
								
							
						
					
					
						commit
						29f1eeb9e5
					
				| @ -1,18 +1,40 @@ | ||||
| import fs = require('fs'); | ||||
| 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'; | ||||
| 
 | ||||
| describe('isAvailable', () => { | ||||
|   const execSpy: jest.SpyInstance = jest.spyOn(exec, 'getExecOutput'); | ||||
|   buildx.isAvailable(); | ||||
| 
 | ||||
|   expect(execSpy).toHaveBeenCalledWith(`docker`, ['buildx'], { | ||||
|     silent: true, | ||||
|     ignoreReturnCode: true | ||||
|   }); | ||||
| }); | ||||
| 
 | ||||
| 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); | ||||
|   async function isDaemonRunning() { | ||||
|     return await exec | ||||
|       .getExecOutput(`docker`, ['version', '--format', '{{.Server.Os}}'], { | ||||
|         ignoreReturnCode: true, | ||||
|         silent: true | ||||
|       }) | ||||
|       .then(res => { | ||||
|         return !res.stdout.includes(' ') && res.exitCode == 0; | ||||
|       }); | ||||
|   } | ||||
|   (isDaemonRunning() ? it : it.skip)( | ||||
|     'valid', | ||||
|     async () => { | ||||
|       const version = await buildx.getVersion(); | ||||
|       console.log(`version: ${version}`); | ||||
|       expect(semver.valid(version)).not.toBeNull(); | ||||
|     }, | ||||
|     100000 | ||||
|   ); | ||||
| }); | ||||
| 
 | ||||
| describe('parseVersion', () => { | ||||
| @ -27,7 +49,14 @@ describe('parseVersion', () => { | ||||
| 
 | ||||
| describe('inspect', () => { | ||||
|   async function isDaemonRunning() { | ||||
|     return await docker.isDaemonRunning(); | ||||
|     return await exec | ||||
|       .getExecOutput(`docker`, ['version', '--format', '{{.Server.Os}}'], { | ||||
|         ignoreReturnCode: true, | ||||
|         silent: true | ||||
|       }) | ||||
|       .then(res => { | ||||
|         return !res.stdout.includes(' ') && res.exitCode == 0; | ||||
|       }); | ||||
|   } | ||||
|   (isDaemonRunning() ? it : it.skip)( | ||||
|     'valid', | ||||
|  | ||||
							
								
								
									
										860
									
								
								dist/index.js
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										860
									
								
								dist/index.js
									
									
									
										generated
									
									
										vendored
									
									
								
							| @ -49,6 +49,13 @@ module.exports = | ||||
| /************************************************************************/ | ||||
| /******/ ({ | ||||
| 
 | ||||
| /***/ 4: | ||||
| /***/ (function(module) { | ||||
| 
 | ||||
| module.exports = require("child_process"); | ||||
| 
 | ||||
| /***/ }), | ||||
| 
 | ||||
| /***/ 8: | ||||
| /***/ (function(module, __unusedexports, __webpack_require__) { | ||||
| 
 | ||||
| @ -509,15 +516,14 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge | ||||
|     }); | ||||
| }; | ||||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||||
| 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)); | ||||
| const stateHelper = __importStar(__webpack_require__(647)); | ||||
| const core = __importStar(__webpack_require__(186)); | ||||
| const exec = __importStar(__webpack_require__(514)); | ||||
| function run() { | ||||
|     var _a; | ||||
|     return __awaiter(this, void 0, void 0, function* () { | ||||
| @ -600,18 +606,26 @@ function cleanup() { | ||||
|     return __awaiter(this, void 0, void 0, function* () { | ||||
|         if (stateHelper.IsDebug && stateHelper.containerName.length > 0) { | ||||
|             core.startGroup(`BuildKit container logs`); | ||||
|             yield mexec.exec('docker', ['logs', `${stateHelper.containerName}`], false).then(res => { | ||||
|                 if (res.stderr.length > 0 && !res.success) { | ||||
|                     core.warning(res.stderr); | ||||
|             yield exec | ||||
|                 .getExecOutput('docker', ['logs', `${stateHelper.containerName}`], { | ||||
|                 ignoreReturnCode: true | ||||
|             }) | ||||
|                 .then(res => { | ||||
|                 if (res.stderr.length > 0 && res.exitCode != 0) { | ||||
|                     core.warning(res.stderr.trim()); | ||||
|                 } | ||||
|             }); | ||||
|             core.endGroup(); | ||||
|         } | ||||
|         if (stateHelper.builderName.length > 0) { | ||||
|             core.startGroup(`Removing builder`); | ||||
|             yield mexec.exec('docker', ['buildx', 'rm', `${stateHelper.builderName}`], false).then(res => { | ||||
|                 if (res.stderr.length > 0 && !res.success) { | ||||
|                     core.warning(res.stderr); | ||||
|             yield exec | ||||
|                 .getExecOutput('docker', ['buildx', 'rm', `${stateHelper.builderName}`], { | ||||
|                 ignoreReturnCode: true | ||||
|             }) | ||||
|                 .then(res => { | ||||
|                 if (res.stderr.length > 0 && res.exitCode != 0) { | ||||
|                     core.warning(res.stderr.trim()); | ||||
|                 } | ||||
|             }); | ||||
|             core.endGroup(); | ||||
| @ -706,9 +720,344 @@ module.exports = gt | ||||
| /***/ }), | ||||
| 
 | ||||
| /***/ 129: | ||||
| /***/ (function(module) { | ||||
| /***/ (function(module, __unusedexports, __webpack_require__) { | ||||
| 
 | ||||
| "use strict"; | ||||
| 
 | ||||
| 
 | ||||
| // A linked list to keep track of recently-used-ness
 | ||||
| const Yallist = __webpack_require__(665) | ||||
| 
 | ||||
| const MAX = Symbol('max') | ||||
| const LENGTH = Symbol('length') | ||||
| const LENGTH_CALCULATOR = Symbol('lengthCalculator') | ||||
| const ALLOW_STALE = Symbol('allowStale') | ||||
| const MAX_AGE = Symbol('maxAge') | ||||
| const DISPOSE = Symbol('dispose') | ||||
| const NO_DISPOSE_ON_SET = Symbol('noDisposeOnSet') | ||||
| const LRU_LIST = Symbol('lruList') | ||||
| const CACHE = Symbol('cache') | ||||
| const UPDATE_AGE_ON_GET = Symbol('updateAgeOnGet') | ||||
| 
 | ||||
| const naiveLength = () => 1 | ||||
| 
 | ||||
| // lruList is a yallist where the head is the youngest
 | ||||
| // item, and the tail is the oldest.  the list contains the Hit
 | ||||
| // objects as the entries.
 | ||||
| // Each Hit object has a reference to its Yallist.Node.  This
 | ||||
| // never changes.
 | ||||
| //
 | ||||
| // cache is a Map (or PseudoMap) that matches the keys to
 | ||||
| // the Yallist.Node object.
 | ||||
| class LRUCache { | ||||
|   constructor (options) { | ||||
|     if (typeof options === 'number') | ||||
|       options = { max: options } | ||||
| 
 | ||||
|     if (!options) | ||||
|       options = {} | ||||
| 
 | ||||
|     if (options.max && (typeof options.max !== 'number' || options.max < 0)) | ||||
|       throw new TypeError('max must be a non-negative number') | ||||
|     // Kind of weird to have a default max of Infinity, but oh well.
 | ||||
|     const max = this[MAX] = options.max || Infinity | ||||
| 
 | ||||
|     const lc = options.length || naiveLength | ||||
|     this[LENGTH_CALCULATOR] = (typeof lc !== 'function') ? naiveLength : lc | ||||
|     this[ALLOW_STALE] = options.stale || false | ||||
|     if (options.maxAge && typeof options.maxAge !== 'number') | ||||
|       throw new TypeError('maxAge must be a number') | ||||
|     this[MAX_AGE] = options.maxAge || 0 | ||||
|     this[DISPOSE] = options.dispose | ||||
|     this[NO_DISPOSE_ON_SET] = options.noDisposeOnSet || false | ||||
|     this[UPDATE_AGE_ON_GET] = options.updateAgeOnGet || false | ||||
|     this.reset() | ||||
|   } | ||||
| 
 | ||||
|   // resize the cache when the max changes.
 | ||||
|   set max (mL) { | ||||
|     if (typeof mL !== 'number' || mL < 0) | ||||
|       throw new TypeError('max must be a non-negative number') | ||||
| 
 | ||||
|     this[MAX] = mL || Infinity | ||||
|     trim(this) | ||||
|   } | ||||
|   get max () { | ||||
|     return this[MAX] | ||||
|   } | ||||
| 
 | ||||
|   set allowStale (allowStale) { | ||||
|     this[ALLOW_STALE] = !!allowStale | ||||
|   } | ||||
|   get allowStale () { | ||||
|     return this[ALLOW_STALE] | ||||
|   } | ||||
| 
 | ||||
|   set maxAge (mA) { | ||||
|     if (typeof mA !== 'number') | ||||
|       throw new TypeError('maxAge must be a non-negative number') | ||||
| 
 | ||||
|     this[MAX_AGE] = mA | ||||
|     trim(this) | ||||
|   } | ||||
|   get maxAge () { | ||||
|     return this[MAX_AGE] | ||||
|   } | ||||
| 
 | ||||
|   // resize the cache when the lengthCalculator changes.
 | ||||
|   set lengthCalculator (lC) { | ||||
|     if (typeof lC !== 'function') | ||||
|       lC = naiveLength | ||||
| 
 | ||||
|     if (lC !== this[LENGTH_CALCULATOR]) { | ||||
|       this[LENGTH_CALCULATOR] = lC | ||||
|       this[LENGTH] = 0 | ||||
|       this[LRU_LIST].forEach(hit => { | ||||
|         hit.length = this[LENGTH_CALCULATOR](hit.value, hit.key) | ||||
|         this[LENGTH] += hit.length | ||||
|       }) | ||||
|     } | ||||
|     trim(this) | ||||
|   } | ||||
|   get lengthCalculator () { return this[LENGTH_CALCULATOR] } | ||||
| 
 | ||||
|   get length () { return this[LENGTH] } | ||||
|   get itemCount () { return this[LRU_LIST].length } | ||||
| 
 | ||||
|   rforEach (fn, thisp) { | ||||
|     thisp = thisp || this | ||||
|     for (let walker = this[LRU_LIST].tail; walker !== null;) { | ||||
|       const prev = walker.prev | ||||
|       forEachStep(this, fn, walker, thisp) | ||||
|       walker = prev | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   forEach (fn, thisp) { | ||||
|     thisp = thisp || this | ||||
|     for (let walker = this[LRU_LIST].head; walker !== null;) { | ||||
|       const next = walker.next | ||||
|       forEachStep(this, fn, walker, thisp) | ||||
|       walker = next | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   keys () { | ||||
|     return this[LRU_LIST].toArray().map(k => k.key) | ||||
|   } | ||||
| 
 | ||||
|   values () { | ||||
|     return this[LRU_LIST].toArray().map(k => k.value) | ||||
|   } | ||||
| 
 | ||||
|   reset () { | ||||
|     if (this[DISPOSE] && | ||||
|         this[LRU_LIST] && | ||||
|         this[LRU_LIST].length) { | ||||
|       this[LRU_LIST].forEach(hit => this[DISPOSE](hit.key, hit.value)) | ||||
|     } | ||||
| 
 | ||||
|     this[CACHE] = new Map() // hash of items by key
 | ||||
|     this[LRU_LIST] = new Yallist() // list of items in order of use recency
 | ||||
|     this[LENGTH] = 0 // length of items in the list
 | ||||
|   } | ||||
| 
 | ||||
|   dump () { | ||||
|     return this[LRU_LIST].map(hit => | ||||
|       isStale(this, hit) ? false : { | ||||
|         k: hit.key, | ||||
|         v: hit.value, | ||||
|         e: hit.now + (hit.maxAge || 0) | ||||
|       }).toArray().filter(h => h) | ||||
|   } | ||||
| 
 | ||||
|   dumpLru () { | ||||
|     return this[LRU_LIST] | ||||
|   } | ||||
| 
 | ||||
|   set (key, value, maxAge) { | ||||
|     maxAge = maxAge || this[MAX_AGE] | ||||
| 
 | ||||
|     if (maxAge && typeof maxAge !== 'number') | ||||
|       throw new TypeError('maxAge must be a number') | ||||
| 
 | ||||
|     const now = maxAge ? Date.now() : 0 | ||||
|     const len = this[LENGTH_CALCULATOR](value, key) | ||||
| 
 | ||||
|     if (this[CACHE].has(key)) { | ||||
|       if (len > this[MAX]) { | ||||
|         del(this, this[CACHE].get(key)) | ||||
|         return false | ||||
|       } | ||||
| 
 | ||||
|       const node = this[CACHE].get(key) | ||||
|       const item = node.value | ||||
| 
 | ||||
|       // dispose of the old one before overwriting
 | ||||
|       // split out into 2 ifs for better coverage tracking
 | ||||
|       if (this[DISPOSE]) { | ||||
|         if (!this[NO_DISPOSE_ON_SET]) | ||||
|           this[DISPOSE](key, item.value) | ||||
|       } | ||||
| 
 | ||||
|       item.now = now | ||||
|       item.maxAge = maxAge | ||||
|       item.value = value | ||||
|       this[LENGTH] += len - item.length | ||||
|       item.length = len | ||||
|       this.get(key) | ||||
|       trim(this) | ||||
|       return true | ||||
|     } | ||||
| 
 | ||||
|     const hit = new Entry(key, value, len, now, maxAge) | ||||
| 
 | ||||
|     // oversized objects fall out of cache automatically.
 | ||||
|     if (hit.length > this[MAX]) { | ||||
|       if (this[DISPOSE]) | ||||
|         this[DISPOSE](key, value) | ||||
| 
 | ||||
|       return false | ||||
|     } | ||||
| 
 | ||||
|     this[LENGTH] += hit.length | ||||
|     this[LRU_LIST].unshift(hit) | ||||
|     this[CACHE].set(key, this[LRU_LIST].head) | ||||
|     trim(this) | ||||
|     return true | ||||
|   } | ||||
| 
 | ||||
|   has (key) { | ||||
|     if (!this[CACHE].has(key)) return false | ||||
|     const hit = this[CACHE].get(key).value | ||||
|     return !isStale(this, hit) | ||||
|   } | ||||
| 
 | ||||
|   get (key) { | ||||
|     return get(this, key, true) | ||||
|   } | ||||
| 
 | ||||
|   peek (key) { | ||||
|     return get(this, key, false) | ||||
|   } | ||||
| 
 | ||||
|   pop () { | ||||
|     const node = this[LRU_LIST].tail | ||||
|     if (!node) | ||||
|       return null | ||||
| 
 | ||||
|     del(this, node) | ||||
|     return node.value | ||||
|   } | ||||
| 
 | ||||
|   del (key) { | ||||
|     del(this, this[CACHE].get(key)) | ||||
|   } | ||||
| 
 | ||||
|   load (arr) { | ||||
|     // reset the cache
 | ||||
|     this.reset() | ||||
| 
 | ||||
|     const now = Date.now() | ||||
|     // A previous serialized cache has the most recent items first
 | ||||
|     for (let l = arr.length - 1; l >= 0; l--) { | ||||
|       const hit = arr[l] | ||||
|       const expiresAt = hit.e || 0 | ||||
|       if (expiresAt === 0) | ||||
|         // the item was created without expiration in a non aged cache
 | ||||
|         this.set(hit.k, hit.v) | ||||
|       else { | ||||
|         const maxAge = expiresAt - now | ||||
|         // dont add already expired items
 | ||||
|         if (maxAge > 0) { | ||||
|           this.set(hit.k, hit.v, maxAge) | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   prune () { | ||||
|     this[CACHE].forEach((value, key) => get(this, key, false)) | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| const get = (self, key, doUse) => { | ||||
|   const node = self[CACHE].get(key) | ||||
|   if (node) { | ||||
|     const hit = node.value | ||||
|     if (isStale(self, hit)) { | ||||
|       del(self, node) | ||||
|       if (!self[ALLOW_STALE]) | ||||
|         return undefined | ||||
|     } else { | ||||
|       if (doUse) { | ||||
|         if (self[UPDATE_AGE_ON_GET]) | ||||
|           node.value.now = Date.now() | ||||
|         self[LRU_LIST].unshiftNode(node) | ||||
|       } | ||||
|     } | ||||
|     return hit.value | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| const isStale = (self, hit) => { | ||||
|   if (!hit || (!hit.maxAge && !self[MAX_AGE])) | ||||
|     return false | ||||
| 
 | ||||
|   const diff = Date.now() - hit.now | ||||
|   return hit.maxAge ? diff > hit.maxAge | ||||
|     : self[MAX_AGE] && (diff > self[MAX_AGE]) | ||||
| } | ||||
| 
 | ||||
| const trim = self => { | ||||
|   if (self[LENGTH] > self[MAX]) { | ||||
|     for (let walker = self[LRU_LIST].tail; | ||||
|       self[LENGTH] > self[MAX] && walker !== null;) { | ||||
|       // We know that we're about to delete this one, and also
 | ||||
|       // what the next least recently used key will be, so just
 | ||||
|       // go ahead and set it now.
 | ||||
|       const prev = walker.prev | ||||
|       del(self, walker) | ||||
|       walker = prev | ||||
|     } | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| const del = (self, node) => { | ||||
|   if (node) { | ||||
|     const hit = node.value | ||||
|     if (self[DISPOSE]) | ||||
|       self[DISPOSE](hit.key, hit.value) | ||||
| 
 | ||||
|     self[LENGTH] -= hit.length | ||||
|     self[CACHE].delete(hit.key) | ||||
|     self[LRU_LIST].removeNode(node) | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| class Entry { | ||||
|   constructor (key, value, length, now, maxAge) { | ||||
|     this.key = key | ||||
|     this.value = value | ||||
|     this.length = length | ||||
|     this.now = now | ||||
|     this.maxAge = maxAge || 0 | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| const forEachStep = (self, fn, node, thisp) => { | ||||
|   let hit = node.value | ||||
|   if (isStale(self, hit)) { | ||||
|     del(self, node) | ||||
|     if (!self[ALLOW_STALE]) | ||||
|       hit = undefined | ||||
|   } | ||||
|   if (hit) | ||||
|     fn.call(thisp, hit.value, hit.key, self) | ||||
| } | ||||
| 
 | ||||
| module.exports = LRUCache | ||||
| 
 | ||||
| module.exports = require("child_process"); | ||||
| 
 | ||||
| /***/ }), | ||||
| 
 | ||||
| @ -763,7 +1112,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); | ||||
| exports.argStringToArray = exports.ToolRunner = void 0; | ||||
| const os = __importStar(__webpack_require__(87)); | ||||
| const events = __importStar(__webpack_require__(614)); | ||||
| const child = __importStar(__webpack_require__(129)); | ||||
| const child = __importStar(__webpack_require__(4)); | ||||
| const path = __importStar(__webpack_require__(622)); | ||||
| const io = __importStar(__webpack_require__(436)); | ||||
| const ioUtil = __importStar(__webpack_require__(962)); | ||||
| @ -2243,21 +2592,42 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge | ||||
|     }); | ||||
| }; | ||||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||||
| exports.getBuildKitVersion = exports.install = exports.inspect = exports.isAvailable = exports.parseVersion = exports.getVersion = void 0; | ||||
| exports.getBuildKitVersion = exports.install = exports.inspect = exports.parseVersion = exports.getVersion = exports.isAvailable = void 0; | ||||
| const fs = __importStar(__webpack_require__(747)); | ||||
| const path = __importStar(__webpack_require__(622)); | ||||
| const semver = __importStar(__webpack_require__(383)); | ||||
| const util = __importStar(__webpack_require__(669)); | ||||
| const context = __importStar(__webpack_require__(842)); | ||||
| const exec = __importStar(__webpack_require__(757)); | ||||
| const github = __importStar(__webpack_require__(928)); | ||||
| const core = __importStar(__webpack_require__(186)); | ||||
| const exec = __importStar(__webpack_require__(514)); | ||||
| const tc = __importStar(__webpack_require__(784)); | ||||
| function isAvailable() { | ||||
|     return __awaiter(this, void 0, void 0, function* () { | ||||
|         return yield exec | ||||
|             .getExecOutput('docker', ['buildx'], { | ||||
|             ignoreReturnCode: true, | ||||
|             silent: true | ||||
|         }) | ||||
|             .then(res => { | ||||
|             if (res.stderr.length > 0 && res.exitCode != 0) { | ||||
|                 return false; | ||||
|             } | ||||
|             return res.exitCode == 0; | ||||
|         }); | ||||
|     }); | ||||
| } | ||||
| exports.isAvailable = isAvailable; | ||||
| function getVersion() { | ||||
|     return __awaiter(this, void 0, void 0, function* () { | ||||
|         return yield exec.exec(`docker`, ['buildx', 'version'], true).then(res => { | ||||
|             if (res.stderr.length > 0 && !res.success) { | ||||
|                 throw new Error(res.stderr); | ||||
|         return yield exec | ||||
|             .getExecOutput('docker', ['buildx', 'version'], { | ||||
|             ignoreReturnCode: true, | ||||
|             silent: true | ||||
|         }) | ||||
|             .then(res => { | ||||
|             if (res.stderr.length > 0 && res.exitCode != 0) { | ||||
|                 throw new Error(res.stderr.trim()); | ||||
|             } | ||||
|             return parseVersion(res.stdout); | ||||
|         }); | ||||
| @ -2268,28 +2638,22 @@ 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`); | ||||
|             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 => { | ||||
|             if (res.stderr.length > 0 && !res.success) { | ||||
|                 return false; | ||||
|             } | ||||
|             return res.success; | ||||
|         }); | ||||
|     }); | ||||
| } | ||||
| exports.isAvailable = isAvailable; | ||||
| function inspect(name) { | ||||
|     return __awaiter(this, void 0, void 0, function* () { | ||||
|         return yield exec.exec(`docker`, ['buildx', 'inspect', name], true).then(res => { | ||||
|             if (res.stderr.length > 0 && !res.success) { | ||||
|                 throw new Error(res.stderr); | ||||
|         return yield exec | ||||
|             .getExecOutput(`docker`, ['buildx', 'inspect', name], { | ||||
|             ignoreReturnCode: true, | ||||
|             silent: true | ||||
|         }) | ||||
|             .then(res => { | ||||
|             if (res.stderr.length > 0 && res.exitCode != 0) { | ||||
|                 throw new Error(res.stderr.trim()); | ||||
|             } | ||||
|             const builder = {}; | ||||
|             itlines: for (const line of res.stdout.trim().split(`\n`)) { | ||||
| @ -2412,20 +2776,30 @@ function filename(version) { | ||||
| } | ||||
| function getBuildKitVersion(containerID) { | ||||
|     return __awaiter(this, void 0, void 0, function* () { | ||||
|         return exec.exec(`docker`, ['inspect', '--format', '{{.Config.Image}}', containerID], true).then(bkitimage => { | ||||
|             if (bkitimage.success && bkitimage.stdout.length > 0) { | ||||
|                 return exec.exec(`docker`, ['run', '--rm', bkitimage.stdout, '--version'], true).then(bkitversion => { | ||||
|                     if (bkitversion.success && bkitversion.stdout.length > 0) { | ||||
|         return exec | ||||
|             .getExecOutput(`docker`, ['inspect', '--format', '{{.Config.Image}}', containerID], { | ||||
|             ignoreReturnCode: true, | ||||
|             silent: true | ||||
|         }) | ||||
|             .then(bkitimage => { | ||||
|             if (bkitimage.exitCode == 0 && bkitimage.stdout.length > 0) { | ||||
|                 return exec | ||||
|                     .getExecOutput(`docker`, ['run', '--rm', bkitimage.stdout, '--version'], { | ||||
|                     ignoreReturnCode: true, | ||||
|                     silent: true | ||||
|                 }) | ||||
|                     .then(bkitversion => { | ||||
|                     if (bkitversion.exitCode == 0 && bkitversion.stdout.length > 0) { | ||||
|                         return `${bkitimage.stdout} => ${bkitversion.stdout}`; | ||||
|                     } | ||||
|                     else if (bkitversion.stderr.length > 0) { | ||||
|                         core.warning(bkitversion.stderr); | ||||
|                         core.warning(bkitversion.stderr.trim()); | ||||
|                     } | ||||
|                     return bkitversion.stdout; | ||||
|                 }); | ||||
|             } | ||||
|             else if (bkitimage.stderr.length > 0) { | ||||
|                 core.warning(bkitimage.stderr); | ||||
|                 core.warning(bkitimage.stderr.trim()); | ||||
|             } | ||||
|             return bkitimage.stdout; | ||||
|         }); | ||||
| @ -2879,7 +3253,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge | ||||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||||
| exports.findInPath = exports.which = exports.mkdirP = exports.rmRF = exports.mv = exports.cp = void 0; | ||||
| const assert_1 = __webpack_require__(357); | ||||
| const childProcess = __importStar(__webpack_require__(129)); | ||||
| const childProcess = __importStar(__webpack_require__(4)); | ||||
| const path = __importStar(__webpack_require__(622)); | ||||
| const util_1 = __webpack_require__(669); | ||||
| const ioUtil = __importStar(__webpack_require__(962)); | ||||
| @ -3430,7 +3804,7 @@ const core_1 = __webpack_require__(186); | ||||
| // needs to be require for core node modules to be mocked
 | ||||
| /* eslint @typescript-eslint/no-require-imports: 0 */ | ||||
| const os = __webpack_require__(87); | ||||
| const cp = __webpack_require__(129); | ||||
| const cp = __webpack_require__(4); | ||||
| const fs = __webpack_require__(747); | ||||
| function _findMatch(versionSpec, stable, candidates, archFilter) { | ||||
|     return __awaiter(this, void 0, void 0, function* () { | ||||
| @ -6458,348 +6832,6 @@ function issueCommand(command, message) { | ||||
| exports.issueCommand = issueCommand; | ||||
| //# sourceMappingURL=file-command.js.map
 | ||||
| 
 | ||||
| /***/ }), | ||||
| 
 | ||||
| /***/ 722: | ||||
| /***/ (function(module, __unusedexports, __webpack_require__) { | ||||
| 
 | ||||
| "use strict"; | ||||
| 
 | ||||
| 
 | ||||
| // A linked list to keep track of recently-used-ness
 | ||||
| const Yallist = __webpack_require__(665) | ||||
| 
 | ||||
| const MAX = Symbol('max') | ||||
| const LENGTH = Symbol('length') | ||||
| const LENGTH_CALCULATOR = Symbol('lengthCalculator') | ||||
| const ALLOW_STALE = Symbol('allowStale') | ||||
| const MAX_AGE = Symbol('maxAge') | ||||
| const DISPOSE = Symbol('dispose') | ||||
| const NO_DISPOSE_ON_SET = Symbol('noDisposeOnSet') | ||||
| const LRU_LIST = Symbol('lruList') | ||||
| const CACHE = Symbol('cache') | ||||
| const UPDATE_AGE_ON_GET = Symbol('updateAgeOnGet') | ||||
| 
 | ||||
| const naiveLength = () => 1 | ||||
| 
 | ||||
| // lruList is a yallist where the head is the youngest
 | ||||
| // item, and the tail is the oldest.  the list contains the Hit
 | ||||
| // objects as the entries.
 | ||||
| // Each Hit object has a reference to its Yallist.Node.  This
 | ||||
| // never changes.
 | ||||
| //
 | ||||
| // cache is a Map (or PseudoMap) that matches the keys to
 | ||||
| // the Yallist.Node object.
 | ||||
| class LRUCache { | ||||
|   constructor (options) { | ||||
|     if (typeof options === 'number') | ||||
|       options = { max: options } | ||||
| 
 | ||||
|     if (!options) | ||||
|       options = {} | ||||
| 
 | ||||
|     if (options.max && (typeof options.max !== 'number' || options.max < 0)) | ||||
|       throw new TypeError('max must be a non-negative number') | ||||
|     // Kind of weird to have a default max of Infinity, but oh well.
 | ||||
|     const max = this[MAX] = options.max || Infinity | ||||
| 
 | ||||
|     const lc = options.length || naiveLength | ||||
|     this[LENGTH_CALCULATOR] = (typeof lc !== 'function') ? naiveLength : lc | ||||
|     this[ALLOW_STALE] = options.stale || false | ||||
|     if (options.maxAge && typeof options.maxAge !== 'number') | ||||
|       throw new TypeError('maxAge must be a number') | ||||
|     this[MAX_AGE] = options.maxAge || 0 | ||||
|     this[DISPOSE] = options.dispose | ||||
|     this[NO_DISPOSE_ON_SET] = options.noDisposeOnSet || false | ||||
|     this[UPDATE_AGE_ON_GET] = options.updateAgeOnGet || false | ||||
|     this.reset() | ||||
|   } | ||||
| 
 | ||||
|   // resize the cache when the max changes.
 | ||||
|   set max (mL) { | ||||
|     if (typeof mL !== 'number' || mL < 0) | ||||
|       throw new TypeError('max must be a non-negative number') | ||||
| 
 | ||||
|     this[MAX] = mL || Infinity | ||||
|     trim(this) | ||||
|   } | ||||
|   get max () { | ||||
|     return this[MAX] | ||||
|   } | ||||
| 
 | ||||
|   set allowStale (allowStale) { | ||||
|     this[ALLOW_STALE] = !!allowStale | ||||
|   } | ||||
|   get allowStale () { | ||||
|     return this[ALLOW_STALE] | ||||
|   } | ||||
| 
 | ||||
|   set maxAge (mA) { | ||||
|     if (typeof mA !== 'number') | ||||
|       throw new TypeError('maxAge must be a non-negative number') | ||||
| 
 | ||||
|     this[MAX_AGE] = mA | ||||
|     trim(this) | ||||
|   } | ||||
|   get maxAge () { | ||||
|     return this[MAX_AGE] | ||||
|   } | ||||
| 
 | ||||
|   // resize the cache when the lengthCalculator changes.
 | ||||
|   set lengthCalculator (lC) { | ||||
|     if (typeof lC !== 'function') | ||||
|       lC = naiveLength | ||||
| 
 | ||||
|     if (lC !== this[LENGTH_CALCULATOR]) { | ||||
|       this[LENGTH_CALCULATOR] = lC | ||||
|       this[LENGTH] = 0 | ||||
|       this[LRU_LIST].forEach(hit => { | ||||
|         hit.length = this[LENGTH_CALCULATOR](hit.value, hit.key) | ||||
|         this[LENGTH] += hit.length | ||||
|       }) | ||||
|     } | ||||
|     trim(this) | ||||
|   } | ||||
|   get lengthCalculator () { return this[LENGTH_CALCULATOR] } | ||||
| 
 | ||||
|   get length () { return this[LENGTH] } | ||||
|   get itemCount () { return this[LRU_LIST].length } | ||||
| 
 | ||||
|   rforEach (fn, thisp) { | ||||
|     thisp = thisp || this | ||||
|     for (let walker = this[LRU_LIST].tail; walker !== null;) { | ||||
|       const prev = walker.prev | ||||
|       forEachStep(this, fn, walker, thisp) | ||||
|       walker = prev | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   forEach (fn, thisp) { | ||||
|     thisp = thisp || this | ||||
|     for (let walker = this[LRU_LIST].head; walker !== null;) { | ||||
|       const next = walker.next | ||||
|       forEachStep(this, fn, walker, thisp) | ||||
|       walker = next | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   keys () { | ||||
|     return this[LRU_LIST].toArray().map(k => k.key) | ||||
|   } | ||||
| 
 | ||||
|   values () { | ||||
|     return this[LRU_LIST].toArray().map(k => k.value) | ||||
|   } | ||||
| 
 | ||||
|   reset () { | ||||
|     if (this[DISPOSE] && | ||||
|         this[LRU_LIST] && | ||||
|         this[LRU_LIST].length) { | ||||
|       this[LRU_LIST].forEach(hit => this[DISPOSE](hit.key, hit.value)) | ||||
|     } | ||||
| 
 | ||||
|     this[CACHE] = new Map() // hash of items by key
 | ||||
|     this[LRU_LIST] = new Yallist() // list of items in order of use recency
 | ||||
|     this[LENGTH] = 0 // length of items in the list
 | ||||
|   } | ||||
| 
 | ||||
|   dump () { | ||||
|     return this[LRU_LIST].map(hit => | ||||
|       isStale(this, hit) ? false : { | ||||
|         k: hit.key, | ||||
|         v: hit.value, | ||||
|         e: hit.now + (hit.maxAge || 0) | ||||
|       }).toArray().filter(h => h) | ||||
|   } | ||||
| 
 | ||||
|   dumpLru () { | ||||
|     return this[LRU_LIST] | ||||
|   } | ||||
| 
 | ||||
|   set (key, value, maxAge) { | ||||
|     maxAge = maxAge || this[MAX_AGE] | ||||
| 
 | ||||
|     if (maxAge && typeof maxAge !== 'number') | ||||
|       throw new TypeError('maxAge must be a number') | ||||
| 
 | ||||
|     const now = maxAge ? Date.now() : 0 | ||||
|     const len = this[LENGTH_CALCULATOR](value, key) | ||||
| 
 | ||||
|     if (this[CACHE].has(key)) { | ||||
|       if (len > this[MAX]) { | ||||
|         del(this, this[CACHE].get(key)) | ||||
|         return false | ||||
|       } | ||||
| 
 | ||||
|       const node = this[CACHE].get(key) | ||||
|       const item = node.value | ||||
| 
 | ||||
|       // dispose of the old one before overwriting
 | ||||
|       // split out into 2 ifs for better coverage tracking
 | ||||
|       if (this[DISPOSE]) { | ||||
|         if (!this[NO_DISPOSE_ON_SET]) | ||||
|           this[DISPOSE](key, item.value) | ||||
|       } | ||||
| 
 | ||||
|       item.now = now | ||||
|       item.maxAge = maxAge | ||||
|       item.value = value | ||||
|       this[LENGTH] += len - item.length | ||||
|       item.length = len | ||||
|       this.get(key) | ||||
|       trim(this) | ||||
|       return true | ||||
|     } | ||||
| 
 | ||||
|     const hit = new Entry(key, value, len, now, maxAge) | ||||
| 
 | ||||
|     // oversized objects fall out of cache automatically.
 | ||||
|     if (hit.length > this[MAX]) { | ||||
|       if (this[DISPOSE]) | ||||
|         this[DISPOSE](key, value) | ||||
| 
 | ||||
|       return false | ||||
|     } | ||||
| 
 | ||||
|     this[LENGTH] += hit.length | ||||
|     this[LRU_LIST].unshift(hit) | ||||
|     this[CACHE].set(key, this[LRU_LIST].head) | ||||
|     trim(this) | ||||
|     return true | ||||
|   } | ||||
| 
 | ||||
|   has (key) { | ||||
|     if (!this[CACHE].has(key)) return false | ||||
|     const hit = this[CACHE].get(key).value | ||||
|     return !isStale(this, hit) | ||||
|   } | ||||
| 
 | ||||
|   get (key) { | ||||
|     return get(this, key, true) | ||||
|   } | ||||
| 
 | ||||
|   peek (key) { | ||||
|     return get(this, key, false) | ||||
|   } | ||||
| 
 | ||||
|   pop () { | ||||
|     const node = this[LRU_LIST].tail | ||||
|     if (!node) | ||||
|       return null | ||||
| 
 | ||||
|     del(this, node) | ||||
|     return node.value | ||||
|   } | ||||
| 
 | ||||
|   del (key) { | ||||
|     del(this, this[CACHE].get(key)) | ||||
|   } | ||||
| 
 | ||||
|   load (arr) { | ||||
|     // reset the cache
 | ||||
|     this.reset() | ||||
| 
 | ||||
|     const now = Date.now() | ||||
|     // A previous serialized cache has the most recent items first
 | ||||
|     for (let l = arr.length - 1; l >= 0; l--) { | ||||
|       const hit = arr[l] | ||||
|       const expiresAt = hit.e || 0 | ||||
|       if (expiresAt === 0) | ||||
|         // the item was created without expiration in a non aged cache
 | ||||
|         this.set(hit.k, hit.v) | ||||
|       else { | ||||
|         const maxAge = expiresAt - now | ||||
|         // dont add already expired items
 | ||||
|         if (maxAge > 0) { | ||||
|           this.set(hit.k, hit.v, maxAge) | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   prune () { | ||||
|     this[CACHE].forEach((value, key) => get(this, key, false)) | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| const get = (self, key, doUse) => { | ||||
|   const node = self[CACHE].get(key) | ||||
|   if (node) { | ||||
|     const hit = node.value | ||||
|     if (isStale(self, hit)) { | ||||
|       del(self, node) | ||||
|       if (!self[ALLOW_STALE]) | ||||
|         return undefined | ||||
|     } else { | ||||
|       if (doUse) { | ||||
|         if (self[UPDATE_AGE_ON_GET]) | ||||
|           node.value.now = Date.now() | ||||
|         self[LRU_LIST].unshiftNode(node) | ||||
|       } | ||||
|     } | ||||
|     return hit.value | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| const isStale = (self, hit) => { | ||||
|   if (!hit || (!hit.maxAge && !self[MAX_AGE])) | ||||
|     return false | ||||
| 
 | ||||
|   const diff = Date.now() - hit.now | ||||
|   return hit.maxAge ? diff > hit.maxAge | ||||
|     : self[MAX_AGE] && (diff > self[MAX_AGE]) | ||||
| } | ||||
| 
 | ||||
| const trim = self => { | ||||
|   if (self[LENGTH] > self[MAX]) { | ||||
|     for (let walker = self[LRU_LIST].tail; | ||||
|       self[LENGTH] > self[MAX] && walker !== null;) { | ||||
|       // We know that we're about to delete this one, and also
 | ||||
|       // what the next least recently used key will be, so just
 | ||||
|       // go ahead and set it now.
 | ||||
|       const prev = walker.prev | ||||
|       del(self, walker) | ||||
|       walker = prev | ||||
|     } | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| const del = (self, node) => { | ||||
|   if (node) { | ||||
|     const hit = node.value | ||||
|     if (self[DISPOSE]) | ||||
|       self[DISPOSE](hit.key, hit.value) | ||||
| 
 | ||||
|     self[LENGTH] -= hit.length | ||||
|     self[CACHE].delete(hit.key) | ||||
|     self[LRU_LIST].removeNode(node) | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| class Entry { | ||||
|   constructor (key, value, length, now, maxAge) { | ||||
|     this.key = key | ||||
|     this.value = value | ||||
|     this.length = length | ||||
|     this.now = now | ||||
|     this.maxAge = maxAge || 0 | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| const forEachStep = (self, fn, node, thisp) => { | ||||
|   let hit = node.value | ||||
|   if (isStale(self, hit)) { | ||||
|     del(self, node) | ||||
|     if (!self[ALLOW_STALE]) | ||||
|       hit = undefined | ||||
|   } | ||||
|   if (hit) | ||||
|     fn.call(thisp, hit.value, hit.key, self) | ||||
| } | ||||
| 
 | ||||
| module.exports = LRUCache | ||||
| 
 | ||||
| 
 | ||||
| /***/ }), | ||||
| 
 | ||||
| /***/ 741: | ||||
| @ -6879,68 +6911,6 @@ module.exports = require("fs"); | ||||
| 
 | ||||
| /***/ }), | ||||
| 
 | ||||
| /***/ 757: | ||||
| /***/ (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 aexec = __importStar(__webpack_require__(514)); | ||||
| 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 aexec.exec(command, args, options); | ||||
|     return { | ||||
|         success: returnCode === 0, | ||||
|         stdout: stdout.trim(), | ||||
|         stderr: stderr.trim() | ||||
|     }; | ||||
| }); | ||||
| //# sourceMappingURL=exec.js.map
 | ||||
| 
 | ||||
| /***/ }), | ||||
| 
 | ||||
| /***/ 783: | ||||
| /***/ (function(__unusedmodule, exports, __webpack_require__) { | ||||
| 
 | ||||
| @ -7907,7 +7877,7 @@ class Range { | ||||
| } | ||||
| module.exports = Range | ||||
| 
 | ||||
| const LRU = __webpack_require__(722) | ||||
| const LRU = __webpack_require__(129) | ||||
| const cache = new LRU({ max: 1000 }) | ||||
| 
 | ||||
| const parseOptions = __webpack_require__(785) | ||||
|  | ||||
							
								
								
									
										169
									
								
								src/buildx.ts
									
									
									
									
									
								
							
							
						
						
									
										169
									
								
								src/buildx.ts
									
									
									
									
									
								
							| @ -3,9 +3,9 @@ import * as path from 'path'; | ||||
| import * as semver from 'semver'; | ||||
| import * as util from 'util'; | ||||
| import * as context from './context'; | ||||
| import * as exec from './exec'; | ||||
| import * as github from './github'; | ||||
| import * as core from '@actions/core'; | ||||
| import * as exec from '@actions/exec'; | ||||
| import * as tc from '@actions/tool-cache'; | ||||
| 
 | ||||
| export type Builder = { | ||||
| @ -18,77 +18,92 @@ export type Builder = { | ||||
|   node_platforms?: string; | ||||
| }; | ||||
| 
 | ||||
| export async function isAvailable(): Promise<Boolean> { | ||||
|   return await exec | ||||
|     .getExecOutput('docker', ['buildx'], { | ||||
|       ignoreReturnCode: true, | ||||
|       silent: true | ||||
|     }) | ||||
|     .then(res => { | ||||
|       if (res.stderr.length > 0 && res.exitCode != 0) { | ||||
|         return false; | ||||
|       } | ||||
|       return res.exitCode == 0; | ||||
|     }); | ||||
| } | ||||
| 
 | ||||
| export async function getVersion(): Promise<string> { | ||||
|   return await exec.exec(`docker`, ['buildx', 'version'], true).then(res => { | ||||
|     if (res.stderr.length > 0 && !res.success) { | ||||
|       throw new Error(res.stderr); | ||||
|     } | ||||
|     return parseVersion(res.stdout); | ||||
|   }); | ||||
|   return await exec | ||||
|     .getExecOutput('docker', ['buildx', 'version'], { | ||||
|       ignoreReturnCode: true, | ||||
|       silent: true | ||||
|     }) | ||||
|     .then(res => { | ||||
|       if (res.stderr.length > 0 && res.exitCode != 0) { | ||||
|         throw new Error(res.stderr.trim()); | ||||
|       } | ||||
|       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`); | ||||
|     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.length > 0 && !res.success) { | ||||
|       return false; | ||||
|     } | ||||
|     return res.success; | ||||
|   }); | ||||
| } | ||||
| 
 | ||||
| export async function inspect(name: string): Promise<Builder> { | ||||
|   return await exec.exec(`docker`, ['buildx', 'inspect', name], true).then(res => { | ||||
|     if (res.stderr.length > 0 && !res.success) { | ||||
|       throw new Error(res.stderr); | ||||
|     } | ||||
|     const builder: Builder = {}; | ||||
|     itlines: for (const line of res.stdout.trim().split(`\n`)) { | ||||
|       const [key, ...rest] = line.split(':'); | ||||
|       const value = rest.map(v => v.trim()).join(':'); | ||||
|       if (key.length == 0 || value.length == 0) { | ||||
|         continue; | ||||
|   return await exec | ||||
|     .getExecOutput(`docker`, ['buildx', 'inspect', name], { | ||||
|       ignoreReturnCode: true, | ||||
|       silent: true | ||||
|     }) | ||||
|     .then(res => { | ||||
|       if (res.stderr.length > 0 && res.exitCode != 0) { | ||||
|         throw new Error(res.stderr.trim()); | ||||
|       } | ||||
|       switch (key) { | ||||
|         case 'Name': { | ||||
|           if (builder.name == undefined) { | ||||
|             builder.name = value; | ||||
|           } else { | ||||
|             builder.node_name = value; | ||||
|       const builder: Builder = {}; | ||||
|       itlines: for (const line of res.stdout.trim().split(`\n`)) { | ||||
|         const [key, ...rest] = line.split(':'); | ||||
|         const value = rest.map(v => v.trim()).join(':'); | ||||
|         if (key.length == 0 || value.length == 0) { | ||||
|           continue; | ||||
|         } | ||||
|         switch (key) { | ||||
|           case 'Name': { | ||||
|             if (builder.name == undefined) { | ||||
|               builder.name = value; | ||||
|             } else { | ||||
|               builder.node_name = value; | ||||
|             } | ||||
|             break; | ||||
|           } | ||||
|           case 'Driver': { | ||||
|             builder.driver = value; | ||||
|             break; | ||||
|           } | ||||
|           case 'Endpoint': { | ||||
|             builder.node_endpoint = value; | ||||
|             break; | ||||
|           } | ||||
|           case 'Status': { | ||||
|             builder.node_status = value; | ||||
|             break; | ||||
|           } | ||||
|           case 'Flags': { | ||||
|             builder.node_flags = value; | ||||
|             break; | ||||
|           } | ||||
|           case 'Platforms': { | ||||
|             builder.node_platforms = value.replace(/\s/g, ''); | ||||
|             break itlines; | ||||
|           } | ||||
|           break; | ||||
|         } | ||||
|         case 'Driver': { | ||||
|           builder.driver = value; | ||||
|           break; | ||||
|         } | ||||
|         case 'Endpoint': { | ||||
|           builder.node_endpoint = value; | ||||
|           break; | ||||
|         } | ||||
|         case 'Status': { | ||||
|           builder.node_status = value; | ||||
|           break; | ||||
|         } | ||||
|         case 'Flags': { | ||||
|           builder.node_flags = value; | ||||
|           break; | ||||
|         } | ||||
|         case 'Platforms': { | ||||
|           builder.node_platforms = value.replace(/\s/g, ''); | ||||
|           break itlines; | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|     return builder; | ||||
|   }); | ||||
|       return builder; | ||||
|     }); | ||||
| } | ||||
| 
 | ||||
| export async function install(inputVersion: string, dockerConfigHome: string): Promise<string> { | ||||
| @ -173,19 +188,29 @@ async function filename(version: string): Promise<string> { | ||||
| } | ||||
| 
 | ||||
| export async function getBuildKitVersion(containerID: string): Promise<string> { | ||||
|   return exec.exec(`docker`, ['inspect', '--format', '{{.Config.Image}}', containerID], true).then(bkitimage => { | ||||
|     if (bkitimage.success && bkitimage.stdout.length > 0) { | ||||
|       return exec.exec(`docker`, ['run', '--rm', bkitimage.stdout, '--version'], true).then(bkitversion => { | ||||
|         if (bkitversion.success && bkitversion.stdout.length > 0) { | ||||
|           return `${bkitimage.stdout} => ${bkitversion.stdout}`; | ||||
|         } else if (bkitversion.stderr.length > 0) { | ||||
|           core.warning(bkitversion.stderr); | ||||
|         } | ||||
|         return bkitversion.stdout; | ||||
|       }); | ||||
|     } else if (bkitimage.stderr.length > 0) { | ||||
|       core.warning(bkitimage.stderr); | ||||
|     } | ||||
|     return bkitimage.stdout; | ||||
|   }); | ||||
|   return exec | ||||
|     .getExecOutput(`docker`, ['inspect', '--format', '{{.Config.Image}}', containerID], { | ||||
|       ignoreReturnCode: true, | ||||
|       silent: true | ||||
|     }) | ||||
|     .then(bkitimage => { | ||||
|       if (bkitimage.exitCode == 0 && bkitimage.stdout.length > 0) { | ||||
|         return exec | ||||
|           .getExecOutput(`docker`, ['run', '--rm', bkitimage.stdout, '--version'], { | ||||
|             ignoreReturnCode: true, | ||||
|             silent: true | ||||
|           }) | ||||
|           .then(bkitversion => { | ||||
|             if (bkitversion.exitCode == 0 && bkitversion.stdout.length > 0) { | ||||
|               return `${bkitimage.stdout} => ${bkitversion.stdout}`; | ||||
|             } else if (bkitversion.stderr.length > 0) { | ||||
|               core.warning(bkitversion.stderr.trim()); | ||||
|             } | ||||
|             return bkitversion.stdout; | ||||
|           }); | ||||
|       } else if (bkitimage.stderr.length > 0) { | ||||
|         core.warning(bkitimage.stderr.trim()); | ||||
|       } | ||||
|       return bkitimage.stdout; | ||||
|     }); | ||||
| } | ||||
|  | ||||
| @ -1,7 +0,0 @@ | ||||
| import * as exec from './exec'; | ||||
| 
 | ||||
| export async function isDaemonRunning(): Promise<boolean> { | ||||
|   return await exec.exec(`docker`, ['version', '--format', '{{.Server.Os}}'], true).then(res => { | ||||
|     return !res.stdout.includes(' ') && res.success; | ||||
|   }); | ||||
| } | ||||
							
								
								
									
										34
									
								
								src/exec.ts
									
									
									
									
									
								
							
							
						
						
									
										34
									
								
								src/exec.ts
									
									
									
									
									
								
							| @ -1,34 +0,0 @@ | ||||
| import * as aexec 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<ExecResult> => { | ||||
|   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 aexec.exec(command, args, options); | ||||
| 
 | ||||
|   return { | ||||
|     success: returnCode === 0, | ||||
|     stdout: stdout.trim(), | ||||
|     stderr: stderr.trim() | ||||
|   }; | ||||
| }; | ||||
							
								
								
									
										33
									
								
								src/main.ts
									
									
									
									
									
								
							
							
						
						
									
										33
									
								
								src/main.ts
									
									
									
									
									
								
							| @ -1,12 +1,11 @@ | ||||
| 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'; | ||||
| import * as stateHelper from './state-helper'; | ||||
| import * as core from '@actions/core'; | ||||
| import * as exec from '@actions/exec'; | ||||
| 
 | ||||
| async function run(): Promise<void> { | ||||
|   try { | ||||
| @ -94,21 +93,29 @@ async function run(): Promise<void> { | ||||
| async function cleanup(): Promise<void> { | ||||
|   if (stateHelper.IsDebug && stateHelper.containerName.length > 0) { | ||||
|     core.startGroup(`BuildKit container logs`); | ||||
|     await mexec.exec('docker', ['logs', `${stateHelper.containerName}`], false).then(res => { | ||||
|       if (res.stderr.length > 0 && !res.success) { | ||||
|         core.warning(res.stderr); | ||||
|       } | ||||
|     }); | ||||
|     await exec | ||||
|       .getExecOutput('docker', ['logs', `${stateHelper.containerName}`], { | ||||
|         ignoreReturnCode: true | ||||
|       }) | ||||
|       .then(res => { | ||||
|         if (res.stderr.length > 0 && res.exitCode != 0) { | ||||
|           core.warning(res.stderr.trim()); | ||||
|         } | ||||
|       }); | ||||
|     core.endGroup(); | ||||
|   } | ||||
| 
 | ||||
|   if (stateHelper.builderName.length > 0) { | ||||
|     core.startGroup(`Removing builder`); | ||||
|     await mexec.exec('docker', ['buildx', 'rm', `${stateHelper.builderName}`], false).then(res => { | ||||
|       if (res.stderr.length > 0 && !res.success) { | ||||
|         core.warning(res.stderr); | ||||
|       } | ||||
|     }); | ||||
|     await exec | ||||
|       .getExecOutput('docker', ['buildx', 'rm', `${stateHelper.builderName}`], { | ||||
|         ignoreReturnCode: true | ||||
|       }) | ||||
|       .then(res => { | ||||
|         if (res.stderr.length > 0 && res.exitCode != 0) { | ||||
|           core.warning(res.stderr.trim()); | ||||
|         } | ||||
|       }); | ||||
|     core.endGroup(); | ||||
|   } | ||||
| } | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 CrazyMax
						CrazyMax