Handle build bake through bake, bake-files and bake-targets
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
This commit is contained in:
		
							parent
							
								
									b07bd1f9df
								
							
						
					
					
						commit
						8be103ff82
					
				
							
								
								
									
										44
									
								
								.github/workflows/ci.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										44
									
								
								.github/workflows/ci.yml
									
									
									
									
										vendored
									
									
								
							| @ -54,4 +54,48 @@ jobs: | ||||
|             localhost:5000/name/app:1.0.0 | ||||
|       - | ||||
|         name: Dump context | ||||
|         if: always() | ||||
|         uses: crazy-max/ghaction-dump-context@v1 | ||||
| 
 | ||||
|   bake: | ||||
|     runs-on: ubuntu-latest | ||||
|     strategy: | ||||
|       fail-fast: false | ||||
|       matrix: | ||||
|         target: | ||||
|           - default | ||||
|           - release | ||||
|     steps: | ||||
|       - | ||||
|         name: Run local registry | ||||
|         run: | | ||||
|           docker run -d -p 5000:5000 registry:2 | ||||
|       - | ||||
|         name: Checkout | ||||
|         uses: actions/checkout@v2.3.1 | ||||
|       - | ||||
|         name: Set up QEMU | ||||
|         uses: ./setup-qemu/ # change to docker/setup-qemu-action@master | ||||
|         with: | ||||
|           platforms: all | ||||
|       - | ||||
|         name: Set up Docker Buildx | ||||
|         id: buildx | ||||
|         uses: ./setup-buildx/ # change to docker/setup-buildx-action@master | ||||
| #        with: | ||||
| #          driver-opt: network=host | ||||
|       - | ||||
|         name: Build and push | ||||
|         uses: ./ | ||||
|         with: | ||||
|           builder: ${{ steps.buildx.outputs.name }} | ||||
|           bake: true | ||||
|           #push: true | ||||
|           bake-files: | | ||||
|             ./test/config.hcl | ||||
|           bake-targets: | | ||||
|             ${{ matrix.target }} | ||||
|       - | ||||
|         name: Dump context | ||||
|         if: always() | ||||
|         uses: crazy-max/ghaction-dump-context@v1 | ||||
|  | ||||
							
								
								
									
										78
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										78
									
								
								README.md
									
									
									
									
									
								
							| @ -66,6 +66,59 @@ jobs: | ||||
|             user/app:1.0.0 | ||||
| ``` | ||||
| 
 | ||||
| ### Bake | ||||
| 
 | ||||
| [Buildx bake](https://github.com/docker/buildx#buildx-bake-options-target) is also available with this action through | ||||
| the [`bake` inputs](#inputs). | ||||
| 
 | ||||
| ```yaml | ||||
| name: ci | ||||
| 
 | ||||
| on: | ||||
|   pull_request: | ||||
|     branches: master | ||||
|   push: | ||||
|     branches: master | ||||
|     tags: | ||||
| 
 | ||||
| jobs: | ||||
|   buildx: | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - | ||||
|         name: Checkout | ||||
|         uses: actions/checkout@v2 | ||||
|       - | ||||
|         name: Set up QEMU | ||||
|         uses: docker/setup-qemu-action@v1 | ||||
|         with: | ||||
|           platforms: all | ||||
|       - | ||||
|         name: Set up Docker Buildx | ||||
|         id: buildx | ||||
|         uses: docker/setup-buildx-action@v1 | ||||
|         with: | ||||
|           install: true | ||||
|       - | ||||
|         name: Login to DockerHub | ||||
|         uses: docker/login-action@v1 | ||||
|         with: | ||||
|           username: ${{ secrets.DOCKER_USERNAME }} | ||||
|           password: ${{ secrets.DOCKER_PASSWORD }} | ||||
|       - | ||||
|         name: Build and push | ||||
|         uses: docker/build-push-action@v2 | ||||
|         with: | ||||
|           builder: ${{ steps.buildx.outputs.name }} | ||||
|           push: true | ||||
|           bake: true | ||||
|           bake-files: | | ||||
|             ./config.hcl | ||||
|           bake-targets: | | ||||
|             default | ||||
|             release | ||||
| ``` | ||||
| 
 | ||||
| ## Customizing | ||||
| 
 | ||||
| ### inputs | ||||
| @ -74,22 +127,25 @@ Following inputs can be used as `step.with` keys | ||||
| 
 | ||||
| | Name                | Type    | Default                           | Description                        | | ||||
| |---------------------|---------|-----------------------------------|------------------------------------| | ||||
| | `builder`           | String  |                                   | Builder instance | | ||||
| | `builder`           | String  |                                   | Builder instance (see [setup-buildx](https://github.com/docker/setup-buildx-action) action) | | ||||
| | `context`           | String  | `.`                               | Build's context is the set of files located in the specified `PATH` or `URL` | | ||||
| | `file`              | String  | `./Dockerfile`                    | Path to the Dockerfile. | | ||||
| | `build-args`        | String  |                                   | Newline-delimited list of build-time variables | | ||||
| | `labels`            | String  |                                   | Newline-delimited list of metadata for an image | | ||||
| | `tags`              | String  |                                   | Newline-delimited list of tags **required** | | ||||
| | `build-args`        | List    |                                   | Newline-delimited list of build-time variables | | ||||
| | `labels`            | List    |                                   | Newline-delimited list of metadata for an image | | ||||
| | `tags`              | List    |                                   | Newline-delimited list of tags | | ||||
| | `pull`              | Bool    | `false`                           | Always attempt to pull a newer version of the image | | ||||
| | `target`            | String  |                                   | Sets the target stage to build | | ||||
| | `allow`             | String  |                                   | Allow extra privileged entitlement (eg. network.host,security.insecure) | | ||||
| | `allow`             | String  |                                   | [Allow](https://github.com/docker/buildx#--allowentitlement) extra privileged entitlement (eg. network.host,security.insecure) | | ||||
| | `no-cache`          | Bool    | `false`                           | Do not use cache when building the image | | ||||
| | `platforms`         | String  |                                   | Comma-delimited list of target platforms for build | | ||||
| | `load`              | Bool    | `false`                           | Shorthand for `--output=type=docker` | | ||||
| | `push`              | Bool    | `false`                           | Shorthand for `--output=type=registry` | | ||||
| | `outputs`           | String  |                                   | Newline-delimited list of output destinations (format: `type=local,dest=path`) | | ||||
| | `cache-from`        | String  |                                   | Newline-delimited list of external cache sources (eg. `user/app:cache`, `type=local,src=path/to/dir`) | | ||||
| | `cache-to`          | String  |                                   | Newline-delimited list of cache export destinations (eg. `user/app:cache`, `type=local,dest=path/to/dir`) | | ||||
| | `platforms`         | String  |                                   | Comma-delimited list of [target platforms](https://github.com/docker/buildx#---platformvaluevalue) for build | | ||||
| | `load`              | Bool    | `false`                           | [Load](https://github.com/docker/buildx#--load) is a shorthand for `--output=type=docker` | | ||||
| | `push`              | Bool    | `false`                           | [Push](https://github.com/docker/buildx#--push) is a shorthand for `--output=type=registry` | | ||||
| | `outputs`           | List    |                                   | Newline-delimited list of [output destinations](https://github.com/docker/buildx#-o---outputpath-typetypekeyvalue) (format: `type=local,dest=path`) | | ||||
| | `cache-from`        | List    |                                   | Newline-delimited list of [external cache sources](https://github.com/docker/buildx#--cache-fromnametypetypekeyvalue) (eg. `user/app:cache`, `type=local,src=path/to/dir`) | | ||||
| | `cache-to`          | List    |                                   | Newline-delimited list of [cache export destinations](https://github.com/docker/buildx#--cache-tonametypetypekeyvalue) (eg. `user/app:cache`, `type=local,dest=path/to/dir`) | | ||||
| | `bake`              | Bool    | `false`                           | Use [bake](https://github.com/docker/buildx#buildx-bake-options-target) as the high-level build command | | ||||
| | `bake-files`        | List    |                                   | Newline-delimited list of [bake definition files](https://github.com/docker/buildx#file-definition) | | ||||
| | `bake-targets`      | List    |                                   | Newline-delimited list of bake targets | | ||||
| 
 | ||||
| ### outputs | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										16
									
								
								action.yml
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								action.yml
									
									
									
									
									
								
							| @ -25,7 +25,7 @@ inputs: | ||||
|     required: false | ||||
|   tags: | ||||
|     description: "Newline-delimited list of tags" | ||||
|     required: true | ||||
|     required: false | ||||
|   pull: | ||||
|     description: "Always attempt to pull a newer version of the image" | ||||
|     required: false | ||||
| @ -44,11 +44,11 @@ inputs: | ||||
|     description: "Comma-delimited list of target platforms for build" | ||||
|     required: false | ||||
|   load: | ||||
|     description: "Shorthand for --output=type=docker" | ||||
|     description: "Load is a shorthand for --output=type=docker" | ||||
|     required: false | ||||
|     default: 'false' | ||||
|   push: | ||||
|     description: "Shorthand for --output=type=registry" | ||||
|     description: "Push is a shorthand for --output=type=registry" | ||||
|     required: false | ||||
|     default: 'false' | ||||
|   outputs: | ||||
| @ -60,6 +60,16 @@ inputs: | ||||
|   cache-to: | ||||
|     description: "Newline-delimited list of cache export destinations for buildx (eg. user/app:cache, type=local,dest=path/to/dir)" | ||||
|     required: false | ||||
|   bake: | ||||
|     description: "Use bake as the high-level build command" | ||||
|     required: false | ||||
|     default: 'false' | ||||
|   bake-files: | ||||
|     description: "Newline-delimited list of bake definition files" | ||||
|     required: false | ||||
|   bake-targets: | ||||
|     description: "Newline-delimited list of bake targets" | ||||
|     required: false | ||||
| 
 | ||||
| outputs: | ||||
|   digest: | ||||
|  | ||||
							
								
								
									
										290
									
								
								dist/index.js
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										290
									
								
								dist/index.js
									
									
									
										generated
									
									
										vendored
									
									
								
							| @ -1003,7 +1003,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge | ||||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||||
| const os = __importStar(__webpack_require__(87)); | ||||
| const buildx = __importStar(__webpack_require__(982)); | ||||
| const context_helper_1 = __webpack_require__(338); | ||||
| const context_1 = __webpack_require__(482); | ||||
| const core = __importStar(__webpack_require__(470)); | ||||
| const exec = __importStar(__webpack_require__(986)); | ||||
| function run() { | ||||
| @ -1013,149 +1013,28 @@ function run() { | ||||
|                 core.setFailed('Only supported on linux platform'); | ||||
|                 return; | ||||
|             } | ||||
|             const inputs = yield context_helper_1.loadInputs(); | ||||
|             if (!(yield buildx.isAvailable())) { | ||||
|                 core.setFailed(`Buildx is required. See https://github.com/docker/setup-buildx-action to set up buildx.`); | ||||
|                 return; | ||||
|             } | ||||
|             let buildArgs = ['buildx', 'build']; | ||||
|             const inputs = yield context_1.getInputs(); | ||||
|             if (inputs.builder) { | ||||
|                 core.info(`📌 Using builder instance ${inputs.builder}`); | ||||
|                 yield buildx.use(inputs.builder); | ||||
|             } | ||||
|             if (inputs.file) { | ||||
|                 buildArgs.push('--file', inputs.file); | ||||
|             } | ||||
|             yield asyncForEach(inputs.buildArgs, (buildArg) => __awaiter(this, void 0, void 0, function* () { | ||||
|                 buildArgs.push('--build-arg', buildArg); | ||||
|             })); | ||||
|             yield asyncForEach(inputs.labels, (label) => __awaiter(this, void 0, void 0, function* () { | ||||
|                 buildArgs.push('--label', label); | ||||
|             })); | ||||
|             yield asyncForEach(inputs.tags, (tag) => __awaiter(this, void 0, void 0, function* () { | ||||
|                 buildArgs.push('--tag', tag); | ||||
|             })); | ||||
|             if (inputs.pull) { | ||||
|                 buildArgs.push('--pull'); | ||||
|             } | ||||
|             if (inputs.target) { | ||||
|                 buildArgs.push('--target', inputs.target); | ||||
|             } | ||||
|             if (inputs.allow) { | ||||
|                 buildArgs.push('--allow', inputs.allow); | ||||
|             } | ||||
|             if (inputs.noCache) { | ||||
|                 buildArgs.push('--no-cache'); | ||||
|             } | ||||
|             if (inputs.platforms) { | ||||
|                 buildArgs.push('--platform', inputs.platforms); | ||||
|             } | ||||
|             if (inputs.load) { | ||||
|                 buildArgs.push('--load'); | ||||
|             } | ||||
|             if (inputs.push) { | ||||
|                 buildArgs.push('--push'); | ||||
|             } | ||||
|             yield asyncForEach(inputs.outputs, (output) => __awaiter(this, void 0, void 0, function* () { | ||||
|                 buildArgs.push('--output', output); | ||||
|             })); | ||||
|             yield asyncForEach(inputs.cacheFrom, (cacheFrom) => __awaiter(this, void 0, void 0, function* () { | ||||
|                 buildArgs.push('--cache-from', cacheFrom); | ||||
|             })); | ||||
|             yield asyncForEach(inputs.cacheTo, (cacheTo) => __awaiter(this, void 0, void 0, function* () { | ||||
|                 buildArgs.push('--cache-from', cacheTo); | ||||
|             })); | ||||
|             buildArgs.push(inputs.context); | ||||
|             core.info(`🏃 Starting build...`); | ||||
|             yield exec.exec('docker', buildArgs); | ||||
|             yield exec.exec('docker', yield context_1.getArgs(inputs)); | ||||
|         } | ||||
|         catch (error) { | ||||
|             core.setFailed(error.message); | ||||
|         } | ||||
|     }); | ||||
| } | ||||
| const asyncForEach = (array, callback) => __awaiter(void 0, void 0, void 0, function* () { | ||||
|     for (let index = 0; index < array.length; index++) { | ||||
|         yield callback(array[index], index, array); | ||||
|     } | ||||
| }); | ||||
| run(); | ||||
| //# sourceMappingURL=main.js.map
 | ||||
| 
 | ||||
| /***/ }), | ||||
| 
 | ||||
| /***/ 338: | ||||
| /***/ (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.loadInputs = void 0; | ||||
| const core = __importStar(__webpack_require__(470)); | ||||
| function loadInputs() { | ||||
|     return __awaiter(this, void 0, void 0, function* () { | ||||
|         return { | ||||
|             context: core.getInput('context') || '.', | ||||
|             file: core.getInput('file') || './Dockerfile', | ||||
|             buildArgs: yield getInputList('build-args'), | ||||
|             labels: yield getInputList('labels'), | ||||
|             tags: yield getInputList('tags'), | ||||
|             pull: /true/i.test(core.getInput('pull')), | ||||
|             target: core.getInput('target'), | ||||
|             allow: core.getInput('allow'), | ||||
|             noCache: /true/i.test(core.getInput('no-cache')), | ||||
|             builder: core.getInput('builder'), | ||||
|             platforms: core.getInput('platforms'), | ||||
|             load: /true/i.test(core.getInput('load')), | ||||
|             push: /true/i.test(core.getInput('push')), | ||||
|             outputs: yield getInputList('outputs'), | ||||
|             cacheFrom: yield getInputList('cache-from'), | ||||
|             cacheTo: yield getInputList('cache-to') | ||||
|         }; | ||||
|     }); | ||||
| } | ||||
| exports.loadInputs = loadInputs; | ||||
| function getInputList(name) { | ||||
|     return __awaiter(this, void 0, void 0, function* () { | ||||
|         const items = core.getInput(name); | ||||
|         if (items == '') { | ||||
|             return []; | ||||
|         } | ||||
|         return items.split(/\r?\n/).reduce((acc, line) => acc.concat(line.split(',')).map(pat => pat.trim()), []); | ||||
|     }); | ||||
| } | ||||
| //# sourceMappingURL=context-helper.js.map
 | ||||
| 
 | ||||
| /***/ }), | ||||
| 
 | ||||
| /***/ 357: | ||||
| /***/ (function(module) { | ||||
| 
 | ||||
| @ -1491,6 +1370,169 @@ exports.getState = getState; | ||||
| 
 | ||||
| /***/ }), | ||||
| 
 | ||||
| /***/ 482: | ||||
| /***/ (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.getArgs = exports.getInputs = void 0; | ||||
| const core = __importStar(__webpack_require__(470)); | ||||
| function getInputs() { | ||||
|     return __awaiter(this, void 0, void 0, function* () { | ||||
|         return { | ||||
|             context: core.getInput('context') || '.', | ||||
|             file: core.getInput('file') || './Dockerfile', | ||||
|             buildArgs: yield getInputList('build-args'), | ||||
|             labels: yield getInputList('labels'), | ||||
|             tags: yield getInputList('tags'), | ||||
|             pull: /true/i.test(core.getInput('pull')), | ||||
|             target: core.getInput('target'), | ||||
|             allow: core.getInput('allow'), | ||||
|             noCache: /true/i.test(core.getInput('no-cache')), | ||||
|             builder: core.getInput('builder'), | ||||
|             platforms: core.getInput('platforms'), | ||||
|             load: /true/i.test(core.getInput('load')), | ||||
|             push: /true/i.test(core.getInput('push')), | ||||
|             outputs: yield getInputList('outputs'), | ||||
|             cacheFrom: yield getInputList('cache-from'), | ||||
|             cacheTo: yield getInputList('cache-to'), | ||||
|             bake: /true/i.test(core.getInput('bake')), | ||||
|             bakeFiles: yield getInputList('bake-files'), | ||||
|             bakeTargets: yield getInputList('bake-targets') | ||||
|         }; | ||||
|     }); | ||||
| } | ||||
| exports.getInputs = getInputs; | ||||
| function getArgs(inputs) { | ||||
|     return __awaiter(this, void 0, void 0, function* () { | ||||
|         let args = ['buildx']; | ||||
|         if (inputs.bake) { | ||||
|             args.concat(yield getBakeArgs(inputs)); | ||||
|         } | ||||
|         else { | ||||
|             args.concat(yield getBuildArgs(inputs)); | ||||
|         } | ||||
|         args.concat(yield getCommonArgs(inputs)); | ||||
|         if (!inputs.bake) { | ||||
|             args.push(inputs.context); | ||||
|         } | ||||
|         else { | ||||
|             args.concat(inputs.bakeTargets); | ||||
|         } | ||||
|         return args; | ||||
|     }); | ||||
| } | ||||
| exports.getArgs = getArgs; | ||||
| function getCommonArgs(inputs) { | ||||
|     return __awaiter(this, void 0, void 0, function* () { | ||||
|         let args = []; | ||||
|         if (inputs.noCache) { | ||||
|             args.push('--no-cache'); | ||||
|         } | ||||
|         if (inputs.pull) { | ||||
|             args.push('--pull'); | ||||
|         } | ||||
|         if (inputs.load) { | ||||
|             args.push('--load'); | ||||
|         } | ||||
|         if (inputs.push) { | ||||
|             args.push('--push'); | ||||
|         } | ||||
|         return args; | ||||
|     }); | ||||
| } | ||||
| function getBakeArgs(inputs) { | ||||
|     return __awaiter(this, void 0, void 0, function* () { | ||||
|         let args = ['bake']; | ||||
|         yield asyncForEach(inputs.bakeFiles, (bakeFile) => __awaiter(this, void 0, void 0, function* () { | ||||
|             args.push('--file', bakeFile); | ||||
|         })); | ||||
|         return args; | ||||
|     }); | ||||
| } | ||||
| function getBuildArgs(inputs) { | ||||
|     return __awaiter(this, void 0, void 0, function* () { | ||||
|         let args = ['build']; | ||||
|         yield asyncForEach(inputs.buildArgs, (buildArg) => __awaiter(this, void 0, void 0, function* () { | ||||
|             args.push('--build-arg', buildArg); | ||||
|         })); | ||||
|         yield asyncForEach(inputs.labels, (label) => __awaiter(this, void 0, void 0, function* () { | ||||
|             args.push('--label', label); | ||||
|         })); | ||||
|         yield asyncForEach(inputs.tags, (tag) => __awaiter(this, void 0, void 0, function* () { | ||||
|             args.push('--tag', tag); | ||||
|         })); | ||||
|         if (inputs.target) { | ||||
|             args.push('--target', inputs.target); | ||||
|         } | ||||
|         if (inputs.allow) { | ||||
|             args.push('--allow', inputs.allow); | ||||
|         } | ||||
|         if (inputs.platforms) { | ||||
|             args.push('--platform', inputs.platforms); | ||||
|         } | ||||
|         yield asyncForEach(inputs.outputs, (output) => __awaiter(this, void 0, void 0, function* () { | ||||
|             args.push('--output', output); | ||||
|         })); | ||||
|         yield asyncForEach(inputs.cacheFrom, (cacheFrom) => __awaiter(this, void 0, void 0, function* () { | ||||
|             args.push('--cache-from', cacheFrom); | ||||
|         })); | ||||
|         yield asyncForEach(inputs.cacheTo, (cacheTo) => __awaiter(this, void 0, void 0, function* () { | ||||
|             args.push('--cache-from', cacheTo); | ||||
|         })); | ||||
|         if (inputs.file) { | ||||
|             args.push('--file', inputs.file); | ||||
|         } | ||||
|         return args; | ||||
|     }); | ||||
| } | ||||
| function getInputList(name) { | ||||
|     return __awaiter(this, void 0, void 0, function* () { | ||||
|         const items = core.getInput(name); | ||||
|         if (items == '') { | ||||
|             return []; | ||||
|         } | ||||
|         return items.split(/\r?\n/).reduce((acc, line) => acc.concat(line.split(',')).map(pat => pat.trim()), []); | ||||
|     }); | ||||
| } | ||||
| const asyncForEach = (array, callback) => __awaiter(void 0, void 0, void 0, function* () { | ||||
|     for (let index = 0; index < array.length; index++) { | ||||
|         yield callback(array[index], index, array); | ||||
|     } | ||||
| }); | ||||
| //# sourceMappingURL=context.js.map
 | ||||
| 
 | ||||
| /***/ }), | ||||
| 
 | ||||
| /***/ 614: | ||||
| /***/ (function(module) { | ||||
| 
 | ||||
|  | ||||
| @ -1,49 +0,0 @@ | ||||
| import * as core from '@actions/core'; | ||||
| 
 | ||||
| export interface Inputs { | ||||
|   context: string; | ||||
|   file: string; | ||||
|   buildArgs: string[]; | ||||
|   labels: string[]; | ||||
|   tags: string[]; | ||||
|   pull: boolean; | ||||
|   target: string; | ||||
|   allow: string; | ||||
|   noCache: boolean; | ||||
|   builder: string; | ||||
|   platforms: string; | ||||
|   load: boolean; | ||||
|   push: boolean; | ||||
|   outputs: string[]; | ||||
|   cacheFrom: string[]; | ||||
|   cacheTo: string[]; | ||||
| } | ||||
| 
 | ||||
| export async function loadInputs(): Promise<Inputs> { | ||||
|   return { | ||||
|     context: core.getInput('context') || '.', | ||||
|     file: core.getInput('file') || './Dockerfile', | ||||
|     buildArgs: await getInputList('build-args'), | ||||
|     labels: await getInputList('labels'), | ||||
|     tags: await getInputList('tags'), | ||||
|     pull: /true/i.test(core.getInput('pull')), | ||||
|     target: core.getInput('target'), | ||||
|     allow: core.getInput('allow'), | ||||
|     noCache: /true/i.test(core.getInput('no-cache')), | ||||
|     builder: core.getInput('builder'), | ||||
|     platforms: core.getInput('platforms'), | ||||
|     load: /true/i.test(core.getInput('load')), | ||||
|     push: /true/i.test(core.getInput('push')), | ||||
|     outputs: await getInputList('outputs'), | ||||
|     cacheFrom: await getInputList('cache-from'), | ||||
|     cacheTo: await getInputList('cache-to') | ||||
|   }; | ||||
| } | ||||
| 
 | ||||
| async function getInputList(name: string): Promise<string[]> { | ||||
|   const items = core.getInput(name); | ||||
|   if (items == '') { | ||||
|     return []; | ||||
|   } | ||||
|   return items.split(/\r?\n/).reduce<string[]>((acc, line) => acc.concat(line.split(',')).map(pat => pat.trim()), []); | ||||
| } | ||||
							
								
								
									
										139
									
								
								src/context.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										139
									
								
								src/context.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,139 @@ | ||||
| import * as core from '@actions/core'; | ||||
| 
 | ||||
| export interface Inputs { | ||||
|   context: string; | ||||
|   file: string; | ||||
|   buildArgs: string[]; | ||||
|   labels: string[]; | ||||
|   tags: string[]; | ||||
|   pull: boolean; | ||||
|   target: string; | ||||
|   allow: string; | ||||
|   noCache: boolean; | ||||
|   builder: string; | ||||
|   platforms: string; | ||||
|   load: boolean; | ||||
|   push: boolean; | ||||
|   outputs: string[]; | ||||
|   cacheFrom: string[]; | ||||
|   cacheTo: string[]; | ||||
|   bake: boolean; | ||||
|   bakeFiles: string[]; | ||||
|   bakeTargets: string[]; | ||||
| } | ||||
| 
 | ||||
| export async function getInputs(): Promise<Inputs> { | ||||
|   return { | ||||
|     context: core.getInput('context') || '.', | ||||
|     file: core.getInput('file') || './Dockerfile', | ||||
|     buildArgs: await getInputList('build-args'), | ||||
|     labels: await getInputList('labels'), | ||||
|     tags: await getInputList('tags'), | ||||
|     pull: /true/i.test(core.getInput('pull')), | ||||
|     target: core.getInput('target'), | ||||
|     allow: core.getInput('allow'), | ||||
|     noCache: /true/i.test(core.getInput('no-cache')), | ||||
|     builder: core.getInput('builder'), | ||||
|     platforms: core.getInput('platforms'), | ||||
|     load: /true/i.test(core.getInput('load')), | ||||
|     push: /true/i.test(core.getInput('push')), | ||||
|     outputs: await getInputList('outputs'), | ||||
|     cacheFrom: await getInputList('cache-from'), | ||||
|     cacheTo: await getInputList('cache-to'), | ||||
|     bake: /true/i.test(core.getInput('bake')), | ||||
|     bakeFiles: await getInputList('bake-files'), | ||||
|     bakeTargets: await getInputList('bake-targets') | ||||
|   }; | ||||
| } | ||||
| 
 | ||||
| export async function getArgs(inputs: Inputs): Promise<string[]> { | ||||
|   let args: Array<string> = ['buildx']; | ||||
|   if (inputs.bake) { | ||||
|     args.concat(await getBakeArgs(inputs)); | ||||
|   } else { | ||||
|     args.concat(await getBuildArgs(inputs)); | ||||
|   } | ||||
|   args.concat(await getCommonArgs(inputs)); | ||||
| 
 | ||||
|   if (!inputs.bake) { | ||||
|     args.push(inputs.context); | ||||
|   } else { | ||||
|     args.concat(inputs.bakeTargets); | ||||
|   } | ||||
| 
 | ||||
|   return args; | ||||
| } | ||||
| 
 | ||||
| async function getCommonArgs(inputs: Inputs): Promise<string[]> { | ||||
|   let args: Array<string> = []; | ||||
|   if (inputs.noCache) { | ||||
|     args.push('--no-cache'); | ||||
|   } | ||||
|   if (inputs.pull) { | ||||
|     args.push('--pull'); | ||||
|   } | ||||
|   if (inputs.load) { | ||||
|     args.push('--load'); | ||||
|   } | ||||
|   if (inputs.push) { | ||||
|     args.push('--push'); | ||||
|   } | ||||
|   return args; | ||||
| } | ||||
| 
 | ||||
| async function getBakeArgs(inputs: Inputs): Promise<string[]> { | ||||
|   let args: Array<string> = ['bake']; | ||||
|   await asyncForEach(inputs.bakeFiles, async bakeFile => { | ||||
|     args.push('--file', bakeFile); | ||||
|   }); | ||||
|   return args; | ||||
| } | ||||
| 
 | ||||
| async function getBuildArgs(inputs: Inputs): Promise<string[]> { | ||||
|   let args: Array<string> = ['build']; | ||||
|   await asyncForEach(inputs.buildArgs, async buildArg => { | ||||
|     args.push('--build-arg', buildArg); | ||||
|   }); | ||||
|   await asyncForEach(inputs.labels, async label => { | ||||
|     args.push('--label', label); | ||||
|   }); | ||||
|   await asyncForEach(inputs.tags, async tag => { | ||||
|     args.push('--tag', tag); | ||||
|   }); | ||||
|   if (inputs.target) { | ||||
|     args.push('--target', inputs.target); | ||||
|   } | ||||
|   if (inputs.allow) { | ||||
|     args.push('--allow', inputs.allow); | ||||
|   } | ||||
|   if (inputs.platforms) { | ||||
|     args.push('--platform', inputs.platforms); | ||||
|   } | ||||
|   await asyncForEach(inputs.outputs, async output => { | ||||
|     args.push('--output', output); | ||||
|   }); | ||||
|   await asyncForEach(inputs.cacheFrom, async cacheFrom => { | ||||
|     args.push('--cache-from', cacheFrom); | ||||
|   }); | ||||
|   await asyncForEach(inputs.cacheTo, async cacheTo => { | ||||
|     args.push('--cache-from', cacheTo); | ||||
|   }); | ||||
|   if (inputs.file) { | ||||
|     args.push('--file', inputs.file); | ||||
|   } | ||||
|   return args; | ||||
| } | ||||
| 
 | ||||
| async function getInputList(name: string): Promise<string[]> { | ||||
|   const items = core.getInput(name); | ||||
|   if (items == '') { | ||||
|     return []; | ||||
|   } | ||||
|   return items.split(/\r?\n/).reduce<string[]>((acc, line) => acc.concat(line.split(',')).map(pat => pat.trim()), []); | ||||
| } | ||||
| 
 | ||||
| const asyncForEach = async (array, callback) => { | ||||
|   for (let index = 0; index < array.length; index++) { | ||||
|     await callback(array[index], index, array); | ||||
|   } | ||||
| }; | ||||
							
								
								
									
										57
									
								
								src/main.ts
									
									
									
									
									
								
							
							
						
						
									
										57
									
								
								src/main.ts
									
									
									
									
									
								
							| @ -1,6 +1,6 @@ | ||||
| import * as os from 'os'; | ||||
| import * as buildx from './buildx'; | ||||
| import {Inputs, loadInputs} from './context-helper'; | ||||
| import {Inputs, getInputs, getArgs} from './context'; | ||||
| import * as core from '@actions/core'; | ||||
| import * as exec from '@actions/exec'; | ||||
| 
 | ||||
| @ -11,74 +11,23 @@ async function run(): Promise<void> { | ||||
|       return; | ||||
|     } | ||||
| 
 | ||||
|     const inputs: Inputs = await loadInputs(); | ||||
| 
 | ||||
|     if (!(await buildx.isAvailable())) { | ||||
|       core.setFailed(`Buildx is required. See https://github.com/docker/setup-buildx-action to set up buildx.`); | ||||
|       return; | ||||
|     } | ||||
| 
 | ||||
|     let buildArgs: Array<string> = ['buildx', 'build']; | ||||
|     const inputs: Inputs = await getInputs(); | ||||
| 
 | ||||
|     if (inputs.builder) { | ||||
|       core.info(`📌 Using builder instance ${inputs.builder}`); | ||||
|       await buildx.use(inputs.builder); | ||||
|     } | ||||
|     if (inputs.file) { | ||||
|       buildArgs.push('--file', inputs.file); | ||||
|     } | ||||
|     await asyncForEach(inputs.buildArgs, async buildArg => { | ||||
|       buildArgs.push('--build-arg', buildArg); | ||||
|     }); | ||||
|     await asyncForEach(inputs.labels, async label => { | ||||
|       buildArgs.push('--label', label); | ||||
|     }); | ||||
|     await asyncForEach(inputs.tags, async tag => { | ||||
|       buildArgs.push('--tag', tag); | ||||
|     }); | ||||
|     if (inputs.pull) { | ||||
|       buildArgs.push('--pull'); | ||||
|     } | ||||
|     if (inputs.target) { | ||||
|       buildArgs.push('--target', inputs.target); | ||||
|     } | ||||
|     if (inputs.allow) { | ||||
|       buildArgs.push('--allow', inputs.allow); | ||||
|     } | ||||
|     if (inputs.noCache) { | ||||
|       buildArgs.push('--no-cache'); | ||||
|     } | ||||
|     if (inputs.platforms) { | ||||
|       buildArgs.push('--platform', inputs.platforms); | ||||
|     } | ||||
|     if (inputs.load) { | ||||
|       buildArgs.push('--load'); | ||||
|     } | ||||
|     if (inputs.push) { | ||||
|       buildArgs.push('--push'); | ||||
|     } | ||||
|     await asyncForEach(inputs.outputs, async output => { | ||||
|       buildArgs.push('--output', output); | ||||
|     }); | ||||
|     await asyncForEach(inputs.cacheFrom, async cacheFrom => { | ||||
|       buildArgs.push('--cache-from', cacheFrom); | ||||
|     }); | ||||
|     await asyncForEach(inputs.cacheTo, async cacheTo => { | ||||
|       buildArgs.push('--cache-from', cacheTo); | ||||
|     }); | ||||
|     buildArgs.push(inputs.context); | ||||
| 
 | ||||
|     core.info(`🏃 Starting build...`); | ||||
|     await exec.exec('docker', buildArgs); | ||||
|     await exec.exec('docker', await getArgs(inputs)); | ||||
|   } catch (error) { | ||||
|     core.setFailed(error.message); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| const asyncForEach = async (array, callback) => { | ||||
|   for (let index = 0; index < array.length; index++) { | ||||
|     await callback(array[index], index, array); | ||||
|   } | ||||
| }; | ||||
| 
 | ||||
| run(); | ||||
|  | ||||
							
								
								
									
										4
									
								
								test/Dockerfile-bake
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								test/Dockerfile-bake
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,4 @@ | ||||
| FROM alpine | ||||
| 
 | ||||
| ARG name=world | ||||
| RUN echo "Hello ${name}!" | ||||
							
								
								
									
										39
									
								
								test/config.hcl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								test/config.hcl
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,39 @@ | ||||
| group "default" { | ||||
|   targets = ["db", "app"] | ||||
| } | ||||
| 
 | ||||
| group "release" { | ||||
|   targets = ["db", "app-plus"] | ||||
| } | ||||
| 
 | ||||
| target "db" { | ||||
|   context = "./test" | ||||
|   tags = ["docker.io/tonistiigi/db"] | ||||
| } | ||||
| 
 | ||||
| target "app" { | ||||
|   context = "./test" | ||||
|   dockerfile = "Dockerfile-bake" | ||||
|   args = { | ||||
|     name = "foo" | ||||
|   } | ||||
|   tags = [ | ||||
|     "localhost:5000/name/app:latest", | ||||
|     "localhost:5000/name/app:1.0.0" | ||||
|   ] | ||||
| } | ||||
| 
 | ||||
| target "cross" { | ||||
|   platforms = [ | ||||
|     "linux/amd64", | ||||
|     "linux/arm64", | ||||
|     "linux/386" | ||||
|   ] | ||||
| } | ||||
| 
 | ||||
| target "app-plus" { | ||||
|   inherits = ["app", "cross"] | ||||
|   args = { | ||||
|     IAMPLUS = "true" | ||||
|   } | ||||
| } | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 CrazyMax
						CrazyMax