Allow to use secret file mount
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
This commit is contained in:
		
							parent
							
								
									e5f26cdae4
								
							
						
					
					
						commit
						080cadd33e
					
				| @ -1,4 +1,4 @@ | ||||
| #syntax=docker/dockerfile:1.1-experimental | ||||
| #syntax=docker/dockerfile:1.2 | ||||
| 
 | ||||
| FROM node:12 AS deps | ||||
| WORKDIR /src | ||||
|  | ||||
| @ -471,9 +471,6 @@ using [actions/cache](https://github.com/actions/cache) with this action: | ||||
|   ``` | ||||
| </details> | ||||
| 
 | ||||
| > If you want to [export layers for all stages](https://github.com/docker/buildx#--cache-tonametypetypekeyvalue), | ||||
| > you have to specify `mode=max` attribute in `cache-to`. | ||||
| 
 | ||||
| ### Handle tags and labels | ||||
| 
 | ||||
| If you come from [`v1`](https://github.com/docker/build-push-action/tree/releases/v1#readme) and want an | ||||
| @ -622,7 +619,8 @@ Following inputs can be used as `step.with` keys | ||||
| | `outputs`           | List     | List of [output destinations](https://github.com/docker/buildx#-o---outputpath-typetypekeyvalue) (format: `type=local,dest=path`) | | ||||
| | `cache-from`        | List     | List of [external cache sources](https://github.com/docker/buildx#--cache-fromnametypetypekeyvalue) (eg. `type=local,src=path/to/dir`) | | ||||
| | `cache-to`          | List     | List of [cache export destinations](https://github.com/docker/buildx#--cache-tonametypetypekeyvalue) (eg. `type=local,dest=path/to/dir`) | | ||||
| | `secrets`           | List     | List of secrets to expose to the build (eg. `key=value`, `GIT_AUTH_TOKEN=mytoken`) | | ||||
| | `secrets`           | List     | List of secrets to expose to the build (eg. `key=string`, `GIT_AUTH_TOKEN=mytoken`) | | ||||
| | `secret-files`      | List     | List of secret files to expose to the build (eg. `key=filename`, `MY_SECRET=./secret.txt`) | | ||||
| | `ssh`               | List     | List of SSH agent socket or keys to expose to the build | | ||||
| 
 | ||||
| ### outputs | ||||
|  | ||||
| @ -119,21 +119,34 @@ describe('parseVersion', () => { | ||||
| 
 | ||||
| describe('getSecret', () => { | ||||
|   test.each([ | ||||
|     ['A_SECRET=abcdef0123456789', 'A_SECRET', 'abcdef0123456789', false], | ||||
|     ['GIT_AUTH_TOKEN=abcdefghijklmno=0123456789', 'GIT_AUTH_TOKEN', 'abcdefghijklmno=0123456789', false], | ||||
|     ['MY_KEY=c3RyaW5nLXdpdGgtZXF1YWxzCg==', 'MY_KEY', 'c3RyaW5nLXdpdGgtZXF1YWxzCg==', false], | ||||
|     ['aaaaaaaa', '', '', true], | ||||
|     ['aaaaaaaa=', '', '', true], | ||||
|     ['=bbbbbbb', '', '', true] | ||||
|   ])('given %p key and %p secret', async (kvp, key, secret, invalid) => { | ||||
|     ['A_SECRET=abcdef0123456789', false, 'A_SECRET', 'abcdef0123456789', false], | ||||
|     ['GIT_AUTH_TOKEN=abcdefghijklmno=0123456789', false, 'GIT_AUTH_TOKEN', 'abcdefghijklmno=0123456789', false], | ||||
|     ['MY_KEY=c3RyaW5nLXdpdGgtZXF1YWxzCg==', false, 'MY_KEY', 'c3RyaW5nLXdpdGgtZXF1YWxzCg==', false], | ||||
|     ['aaaaaaaa', false, '', '', true], | ||||
|     ['aaaaaaaa=', false, '', '', true], | ||||
|     ['=bbbbbbb', false, '', '', true], | ||||
|     [ | ||||
|       `foo=${path.join(__dirname, 'fixtures', 'secret.txt').split(path.sep).join(path.posix.sep)}`, | ||||
|       true, | ||||
|       'foo', | ||||
|       'bar', | ||||
|       false | ||||
|     ], | ||||
|     [`notfound=secret`, true, '', '', true] | ||||
|   ])('given %p key and %p secret', async (kvp, file, exKey, exValue, invalid) => { | ||||
|     try { | ||||
|       const secretArgs = await buildx.getSecret(kvp); | ||||
|       let secret: string; | ||||
|       if (file) { | ||||
|         secret = await buildx.getSecretFile(kvp); | ||||
|       } else { | ||||
|         secret = await buildx.getSecretString(kvp); | ||||
|       } | ||||
|       expect(true).toBe(!invalid); | ||||
|       console.log(`secretArgs: ${secretArgs}`); | ||||
|       expect(secretArgs).toEqual(`id=${key},src=${tmpNameSync}`); | ||||
|       const secretContent = await fs.readFileSync(tmpNameSync, 'utf-8'); | ||||
|       console.log(`secretValue: ${secretContent}`); | ||||
|       expect(secretContent).toEqual(secret); | ||||
|       console.log(`secret: ${secret}`); | ||||
|       expect(secret).toEqual(`id=${exKey},src=${tmpNameSync}`); | ||||
|       const secretValue = await fs.readFileSync(tmpNameSync, 'utf-8'); | ||||
|       console.log(`secretValue: ${secretValue}`); | ||||
|       expect(secretValue).toEqual(exValue); | ||||
|     } catch (err) { | ||||
|       expect(true).toBe(invalid); | ||||
|     } | ||||
|  | ||||
| @ -337,6 +337,27 @@ ccc`], | ||||
|         '--push', | ||||
|         'https://github.com/docker/build-push-action.git#heads/master' | ||||
|       ] | ||||
|     ], | ||||
|     [ | ||||
|       '0.5.1', | ||||
|       new Map<string, string>([ | ||||
|         ['context', 'https://github.com/docker/build-push-action.git#heads/master'], | ||||
|         ['tag', 'localhost:5000/name/app:latest'], | ||||
|         ['secret-files', `MY_SECRET=${path.join(__dirname, 'fixtures', 'secret.txt').split(path.sep).join(path.posix.sep)}`], | ||||
|         ['file', './test/Dockerfile'], | ||||
|         ['builder', 'builder-git-context-2'], | ||||
|         ['push', 'true'] | ||||
|       ]), | ||||
|       [ | ||||
|         'buildx', | ||||
|         'build', | ||||
|         '--iidfile', '/tmp/.docker-build-push-jest/iidfile', | ||||
|         '--secret', 'id=MY_SECRET,src=/tmp/.docker-build-push-jest/.tmpname-jest', | ||||
|         '--file', './test/Dockerfile', | ||||
|         '--builder', 'builder-git-context-2', | ||||
|         '--push', | ||||
|         'https://github.com/docker/build-push-action.git#heads/master' | ||||
|       ] | ||||
|     ] | ||||
|   ])( | ||||
|     'given %p with %p as inputs, returns %p', | ||||
|  | ||||
							
								
								
									
										1
									
								
								__tests__/fixtures/secret.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								__tests__/fixtures/secret.txt
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1 @@ | ||||
| bar | ||||
							
								
								
									
										39
									
								
								dist/index.js
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										39
									
								
								dist/index.js
									
									
									
										generated
									
									
										vendored
									
									
								
							| @ -4581,7 +4581,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) { | ||||
|     return (mod && mod.__esModule) ? mod : { "default": mod }; | ||||
| }; | ||||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||||
| exports.parseVersion = exports.getVersion = exports.isAvailable = exports.hasGitAuthToken = exports.isLocalOrTarExporter = exports.getSecret = exports.getImageID = exports.getImageIDFile = void 0; | ||||
| exports.parseVersion = exports.getVersion = exports.isAvailable = exports.hasGitAuthToken = exports.isLocalOrTarExporter = exports.getSecret = exports.getSecretFile = exports.getSecretString = exports.getImageID = exports.getImageIDFile = void 0; | ||||
| const sync_1 = __importDefault(__webpack_require__(750)); | ||||
| const fs_1 = __importDefault(__webpack_require__(747)); | ||||
| const path_1 = __importDefault(__webpack_require__(622)); | ||||
| @ -4604,18 +4604,36 @@ function getImageID() { | ||||
|     }); | ||||
| } | ||||
| exports.getImageID = getImageID; | ||||
| function getSecret(kvp) { | ||||
| function getSecretString(kvp) { | ||||
|     return __awaiter(this, void 0, void 0, function* () { | ||||
|         return getSecret(kvp, false); | ||||
|     }); | ||||
| } | ||||
| exports.getSecretString = getSecretString; | ||||
| function getSecretFile(kvp) { | ||||
|     return __awaiter(this, void 0, void 0, function* () { | ||||
|         return getSecret(kvp, true); | ||||
|     }); | ||||
| } | ||||
| exports.getSecretFile = getSecretFile; | ||||
| function getSecret(kvp, file) { | ||||
|     return __awaiter(this, void 0, void 0, function* () { | ||||
|         const delimiterIndex = kvp.indexOf('='); | ||||
|         const key = kvp.substring(0, delimiterIndex); | ||||
|         const value = kvp.substring(delimiterIndex + 1); | ||||
|         let value = kvp.substring(delimiterIndex + 1); | ||||
|         if (key.length == 0 || value.length == 0) { | ||||
|             throw new Error(`${kvp} is not a valid secret`); | ||||
|         } | ||||
|         if (file) { | ||||
|             if (!fs_1.default.existsSync(value)) { | ||||
|                 throw new Error(`secret file ${value} not found`); | ||||
|             } | ||||
|             value = fs_1.default.readFileSync(value, { encoding: 'utf-8' }); | ||||
|         } | ||||
|         const secretFile = context.tmpNameSync({ | ||||
|             tmpdir: context.tmpDir() | ||||
|         }); | ||||
|         yield fs_1.default.writeFileSync(secretFile, value); | ||||
|         fs_1.default.writeFileSync(secretFile, value); | ||||
|         return `id=${key},src=${secretFile}`; | ||||
|     }); | ||||
| } | ||||
| @ -13003,6 +13021,7 @@ function getInputs(defaultContext) { | ||||
|             cacheFrom: yield getInputList('cache-from', true), | ||||
|             cacheTo: yield getInputList('cache-to', true), | ||||
|             secrets: yield getInputList('secrets', true), | ||||
|             secretFiles: yield getInputList('secret-files', true), | ||||
|             githubToken: core.getInput('github-token'), | ||||
|             ssh: yield getInputList('ssh') | ||||
|         }; | ||||
| @ -13055,14 +13074,22 @@ function getBuildArgs(inputs, defaultContext, buildxVersion) { | ||||
|         })); | ||||
|         yield exports.asyncForEach(inputs.secrets, (secret) => __awaiter(this, void 0, void 0, function* () { | ||||
|             try { | ||||
|                 args.push('--secret', yield buildx.getSecret(secret)); | ||||
|                 args.push('--secret', yield buildx.getSecretString(secret)); | ||||
|             } | ||||
|             catch (err) { | ||||
|                 core.warning(err.message); | ||||
|             } | ||||
|         })); | ||||
|         yield exports.asyncForEach(inputs.secretFiles, (secretFile) => __awaiter(this, void 0, void 0, function* () { | ||||
|             try { | ||||
|                 args.push('--secret', yield buildx.getSecretFile(secretFile)); | ||||
|             } | ||||
|             catch (err) { | ||||
|                 core.warning(err.message); | ||||
|             } | ||||
|         })); | ||||
|         if (inputs.githubToken && !buildx.hasGitAuthToken(inputs.secrets) && inputs.context == defaultContext) { | ||||
|             args.push('--secret', yield buildx.getSecret(`GIT_AUTH_TOKEN=${inputs.githubToken}`)); | ||||
|             args.push('--secret', yield buildx.getSecretString(`GIT_AUTH_TOKEN=${inputs.githubToken}`)); | ||||
|         } | ||||
|         yield exports.asyncForEach(inputs.ssh, (ssh) => __awaiter(this, void 0, void 0, function* () { | ||||
|             args.push('--ssh', ssh); | ||||
|  | ||||
| @ -18,17 +18,34 @@ export async function getImageID(): Promise<string | undefined> { | ||||
|   return fs.readFileSync(iidFile, {encoding: 'utf-8'}); | ||||
| } | ||||
| 
 | ||||
| export async function getSecret(kvp: string): Promise<string> { | ||||
| export async function getSecretString(kvp: string): Promise<string> { | ||||
|   return getSecret(kvp, false); | ||||
| } | ||||
| 
 | ||||
| export async function getSecretFile(kvp: string): Promise<string> { | ||||
|   return getSecret(kvp, true); | ||||
| } | ||||
| 
 | ||||
| export async function getSecret(kvp: string, file: boolean): Promise<string> { | ||||
|   const delimiterIndex = kvp.indexOf('='); | ||||
|   const key = kvp.substring(0, delimiterIndex); | ||||
|   const value = kvp.substring(delimiterIndex + 1); | ||||
|   let value = kvp.substring(delimiterIndex + 1); | ||||
|   if (key.length == 0 || value.length == 0) { | ||||
|     throw new Error(`${kvp} is not a valid secret`); | ||||
|   } | ||||
| 
 | ||||
|   if (file) { | ||||
|     if (!fs.existsSync(value)) { | ||||
|       throw new Error(`secret file ${value} not found`); | ||||
|     } | ||||
|     value = fs.readFileSync(value, {encoding: 'utf-8'}); | ||||
|   } | ||||
| 
 | ||||
|   const secretFile = context.tmpNameSync({ | ||||
|     tmpdir: context.tmpDir() | ||||
|   }); | ||||
|   await fs.writeFileSync(secretFile, value); | ||||
|   fs.writeFileSync(secretFile, value); | ||||
| 
 | ||||
|   return `id=${key},src=${secretFile}`; | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -30,6 +30,7 @@ export interface Inputs { | ||||
|   cacheFrom: string[]; | ||||
|   cacheTo: string[]; | ||||
|   secrets: string[]; | ||||
|   secretFiles: string[]; | ||||
|   githubToken: string; | ||||
|   ssh: string[]; | ||||
| } | ||||
| @ -73,6 +74,7 @@ export async function getInputs(defaultContext: string): Promise<Inputs> { | ||||
|     cacheFrom: await getInputList('cache-from', true), | ||||
|     cacheTo: await getInputList('cache-to', true), | ||||
|     secrets: await getInputList('secrets', true), | ||||
|     secretFiles: await getInputList('secret-files', true), | ||||
|     githubToken: core.getInput('github-token'), | ||||
|     ssh: await getInputList('ssh') | ||||
|   }; | ||||
| @ -123,13 +125,20 @@ async function getBuildArgs(inputs: Inputs, defaultContext: string, buildxVersio | ||||
|   }); | ||||
|   await asyncForEach(inputs.secrets, async secret => { | ||||
|     try { | ||||
|       args.push('--secret', await buildx.getSecret(secret)); | ||||
|       args.push('--secret', await buildx.getSecretString(secret)); | ||||
|     } catch (err) { | ||||
|       core.warning(err.message); | ||||
|     } | ||||
|   }); | ||||
|   await asyncForEach(inputs.secretFiles, async secretFile => { | ||||
|     try { | ||||
|       args.push('--secret', await buildx.getSecretFile(secretFile)); | ||||
|     } catch (err) { | ||||
|       core.warning(err.message); | ||||
|     } | ||||
|   }); | ||||
|   if (inputs.githubToken && !buildx.hasGitAuthToken(inputs.secrets) && inputs.context == defaultContext) { | ||||
|     args.push('--secret', await buildx.getSecret(`GIT_AUTH_TOKEN=${inputs.githubToken}`)); | ||||
|     args.push('--secret', await buildx.getSecretString(`GIT_AUTH_TOKEN=${inputs.githubToken}`)); | ||||
|   } | ||||
|   await asyncForEach(inputs.ssh, async ssh => { | ||||
|     args.push('--ssh', ssh); | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 CrazyMax
						CrazyMax