Add json output
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
This commit is contained in:
		
							parent
							
								
									01dc739d69
								
							
						
					
					
						commit
						e6f3e4aa91
					
				
							
								
								
									
										24
									
								
								.github/workflows/ci.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										24
									
								
								.github/workflows/ci.yml
									
									
									
									
										vendored
									
									
								
							| @ -165,6 +165,30 @@ jobs: | ||||
|             org.opencontainers.image.description=Another description | ||||
|             org.opencontainers.image.vendor=MyCompany | ||||
| 
 | ||||
|   json: | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - | ||||
|         name: Checkout | ||||
|         uses: actions/checkout@v2 | ||||
|       - | ||||
|         name: Docker meta | ||||
|         id: meta | ||||
|         uses: ./ | ||||
|         with: | ||||
|           images: | | ||||
|             ${{ env.DOCKER_IMAGE }} | ||||
|             ghcr.io/name/app | ||||
|           labels: | | ||||
|             maintainer=CrazyMax | ||||
|       - | ||||
|         name: JSON output | ||||
|         run: | | ||||
|           echo "maintainer=${{ fromJSON(steps.meta.outputs.json).labels['maintainer'] }}" | ||||
|           echo "version=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.version'] }}" | ||||
|           echo "revision=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.revision'] }}" | ||||
|           echo "created=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.created'] }}" | ||||
| 
 | ||||
|   docker-push: | ||||
|     runs-on: ubuntu-latest | ||||
|     services: | ||||
|  | ||||
							
								
								
									
										28
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										28
									
								
								README.md
									
									
									
									
									
								
							| @ -32,6 +32,7 @@ ___ | ||||
|   * [Latest tag](#latest-tag) | ||||
|   * [Global expressions](#global-expressions) | ||||
|   * [Major version zero](#major-version-zero) | ||||
|   * [JSON output object](#json-output-object) | ||||
|   * [Overwrite labels](#overwrite-labels) | ||||
| * [Keep up-to-date with GitHub Dependabot](#keep-up-to-date-with-github-dependabot) | ||||
| 
 | ||||
| @ -274,6 +275,7 @@ Following outputs are available | ||||
| | `version`     | String  | Docker image version | | ||||
| | `tags`        | String  | Docker tags | | ||||
| | `labels`      | String  | Docker labels | | ||||
| | `json`        | String  | JSON output of tags and labels | | ||||
| | `bake-file`   | File    | [Bake definition file](https://github.com/docker/buildx#file-definition) path | | ||||
| 
 | ||||
| ## `flavor` input | ||||
| @ -586,6 +588,30 @@ tags: | | ||||
|   type=semver,pattern={{major}},enable=${{ !startsWith(github.ref, 'refs/tags/v0.') }} | ||||
| ``` | ||||
| 
 | ||||
| ### JSON output object | ||||
| 
 | ||||
| The `json` output is a JSON object composed of the generated tags and labels so that you can reuse them further in your | ||||
| workflow using the [`fromJSON` function](https://docs.github.com/en/actions/reference/context-and-expression-syntax-for-github-actions#fromjson): | ||||
| 
 | ||||
| ```yaml | ||||
|       - | ||||
|         name: Docker meta | ||||
|         uses: docker/metadata-action@v3 | ||||
|         id: meta | ||||
|         with: | ||||
|           images: name/app | ||||
|       - | ||||
|         name: Build and push | ||||
|         uses: docker/build-push-action@v2 | ||||
|         with: | ||||
|           tags: ${{ steps.meta.outputs.tags }} | ||||
|           labels: ${{ steps.meta.outputs.labels }} | ||||
|           build-args: | | ||||
|             BUILDTIME=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.created'] }} | ||||
|             VERSION=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.version'] }} | ||||
|             REVISION=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.revision'] }} | ||||
| ``` | ||||
| 
 | ||||
| ### Overwrite labels | ||||
| 
 | ||||
| If some of the [OCI Image Format Specification](https://github.com/opencontainers/image-spec/blob/master/annotations.md) | ||||
| @ -594,7 +620,7 @@ labels generated are not suitable, you can overwrite them like this: | ||||
| ```yaml | ||||
|       - | ||||
|         name: Docker meta | ||||
|         id: docker_meta | ||||
|         id: meta | ||||
|         uses: docker/metadata-action@v3 | ||||
|         with: | ||||
|           images: name/app | ||||
|  | ||||
| @ -2394,6 +2394,258 @@ describe('raw', () => { | ||||
|   ])('given %p wth %p event', tagsLabelsTest); | ||||
| }); | ||||
| 
 | ||||
| describe('json', () => { | ||||
|   // prettier-ignore
 | ||||
|   test.each([ | ||||
|     [ | ||||
|       'json01', | ||||
|       'event_push.env', | ||||
|       { | ||||
|         images: ['user/app'], | ||||
|         tags: [ | ||||
|           `type=ref,event=branch`, | ||||
|           `type=raw,my`, | ||||
|           `type=raw,custom`, | ||||
|           `type=raw,tags` | ||||
|         ], | ||||
|         labels: [ | ||||
|           "invalid" | ||||
|         ] | ||||
|       } as Inputs, | ||||
|       { | ||||
|         "tags": [ | ||||
|           "user/app:dev", | ||||
|           "user/app:my", | ||||
|           "user/app:custom", | ||||
|           "user/app:tags" | ||||
|         ], | ||||
|         "labels": { | ||||
|           "org.opencontainers.image.title": "Hello-World", | ||||
|           "org.opencontainers.image.description": "This your first repo!", | ||||
|           "org.opencontainers.image.url": "https://github.com/octocat/Hello-World", | ||||
|           "org.opencontainers.image.source": "https://github.com/octocat/Hello-World", | ||||
|           "org.opencontainers.image.version": "dev", | ||||
|           "org.opencontainers.image.created": "2020-01-10T00:30:00.000Z", | ||||
|           "org.opencontainers.image.revision": "90dd6032fac8bda1b6c4436a2e65de27961ed071", | ||||
|           "org.opencontainers.image.licenses": "MIT" | ||||
|         } | ||||
|       } | ||||
|     ], | ||||
|     [ | ||||
|       'json02', | ||||
|       'event_push.env', | ||||
|       { | ||||
|         images: ['user/app'], | ||||
|         tags: [ | ||||
|           `type=ref,event=branch`, | ||||
|           `type=raw,my` | ||||
|         ] | ||||
|       } as Inputs, | ||||
|       { | ||||
|         "tags": [ | ||||
|           "user/app:dev", | ||||
|           "user/app:my", | ||||
|         ], | ||||
|         "labels": { | ||||
|           "org.opencontainers.image.title": "Hello-World", | ||||
|           "org.opencontainers.image.description": "This your first repo!", | ||||
|           "org.opencontainers.image.url": "https://github.com/octocat/Hello-World", | ||||
|           "org.opencontainers.image.source": "https://github.com/octocat/Hello-World", | ||||
|           "org.opencontainers.image.version": "dev", | ||||
|           "org.opencontainers.image.created": "2020-01-10T00:30:00.000Z", | ||||
|           "org.opencontainers.image.revision": "90dd6032fac8bda1b6c4436a2e65de27961ed071", | ||||
|           "org.opencontainers.image.licenses": "MIT" | ||||
|         } | ||||
|       } | ||||
|     ], | ||||
|     [ | ||||
|       'json03', | ||||
|       'event_tag_release1.env', | ||||
|       { | ||||
|         images: ['user/app'], | ||||
|         tags: [ | ||||
|           `type=ref,event=tag`, | ||||
|           `type=raw,my`, | ||||
|           `type=raw,custom`, | ||||
|           `type=raw,tags` | ||||
|         ], | ||||
|         bakeTarget: "meta" | ||||
|       } as Inputs, | ||||
|       { | ||||
|         "tags": [ | ||||
|           "user/app:release1", | ||||
|           "user/app:my", | ||||
|           "user/app:custom", | ||||
|           "user/app:tags", | ||||
|           "user/app:latest" | ||||
|         ], | ||||
|         "labels": { | ||||
|           "org.opencontainers.image.title": "Hello-World", | ||||
|           "org.opencontainers.image.description": "This your first repo!", | ||||
|           "org.opencontainers.image.url": "https://github.com/octocat/Hello-World", | ||||
|           "org.opencontainers.image.source": "https://github.com/octocat/Hello-World", | ||||
|           "org.opencontainers.image.version": "release1", | ||||
|           "org.opencontainers.image.created": "2020-01-10T00:30:00.000Z", | ||||
|           "org.opencontainers.image.revision": "90dd6032fac8bda1b6c4436a2e65de27961ed071", | ||||
|           "org.opencontainers.image.licenses": "MIT" | ||||
|         } | ||||
|       } | ||||
|     ], | ||||
|     [ | ||||
|       'json04', | ||||
|       'event_tag_20200110-RC2.env', | ||||
|       { | ||||
|         images: ['user/app'], | ||||
|         tags: [ | ||||
|           `type=match,pattern=\\d{8}`, | ||||
|           `type=raw,my`, | ||||
|           `type=raw,custom`, | ||||
|           `type=raw,tags` | ||||
|         ], | ||||
|         flavor: [ | ||||
|           `latest=false` | ||||
|         ] | ||||
|       } as Inputs, | ||||
|       { | ||||
|         "tags": [ | ||||
|           "user/app:20200110", | ||||
|           "user/app:my", | ||||
|           "user/app:custom", | ||||
|           "user/app:tags" | ||||
|         ], | ||||
|         "labels": { | ||||
|           "org.opencontainers.image.title": "Hello-World", | ||||
|           "org.opencontainers.image.description": "This your first repo!", | ||||
|           "org.opencontainers.image.url": "https://github.com/octocat/Hello-World", | ||||
|           "org.opencontainers.image.source": "https://github.com/octocat/Hello-World", | ||||
|           "org.opencontainers.image.version": "20200110", | ||||
|           "org.opencontainers.image.created": "2020-01-10T00:30:00.000Z", | ||||
|           "org.opencontainers.image.revision": "90dd6032fac8bda1b6c4436a2e65de27961ed071", | ||||
|           "org.opencontainers.image.licenses": "MIT" | ||||
|         } | ||||
|       } | ||||
|     ], | ||||
|     [ | ||||
|       'json05', | ||||
|       'event_tag_v1.1.1.env', | ||||
|       { | ||||
|         images: ['org/app', 'ghcr.io/user/app'], | ||||
|         tags: [ | ||||
|           `type=semver,pattern={{version}}`, | ||||
|           `type=semver,pattern={{major}}.{{minor}}`, | ||||
|           `type=semver,pattern={{major}}`, | ||||
|           `type=raw,my`, | ||||
|           `type=raw,custom`, | ||||
|           `type=raw,tags` | ||||
|         ] | ||||
|       } as Inputs, | ||||
|       { | ||||
|         "tags": [ | ||||
|           "org/app:1.1.1", | ||||
|           "org/app:1.1", | ||||
|           "org/app:1", | ||||
|           "org/app:my", | ||||
|           "org/app:custom", | ||||
|           "org/app:tags", | ||||
|           "org/app:latest", | ||||
|           "ghcr.io/user/app:1.1.1", | ||||
|           "ghcr.io/user/app:1.1", | ||||
|           "ghcr.io/user/app:1", | ||||
|           "ghcr.io/user/app:my", | ||||
|           "ghcr.io/user/app:custom", | ||||
|           "ghcr.io/user/app:tags", | ||||
|           "ghcr.io/user/app:latest" | ||||
|         ], | ||||
|         "labels": { | ||||
|           "org.opencontainers.image.title": "Hello-World", | ||||
|           "org.opencontainers.image.description": "This your first repo!", | ||||
|           "org.opencontainers.image.url": "https://github.com/octocat/Hello-World", | ||||
|           "org.opencontainers.image.source": "https://github.com/octocat/Hello-World", | ||||
|           "org.opencontainers.image.version": "1.1.1", | ||||
|           "org.opencontainers.image.created": "2020-01-10T00:30:00.000Z", | ||||
|           "org.opencontainers.image.revision": "90dd6032fac8bda1b6c4436a2e65de27961ed071", | ||||
|           "org.opencontainers.image.licenses": "MIT" | ||||
|         } | ||||
|       } | ||||
|     ], | ||||
|     [ | ||||
|       'json06', | ||||
|       'event_tag_v1.1.1.env', | ||||
|       { | ||||
|         images: ['org/app', 'ghcr.io/user/app'], | ||||
|         tags: [ | ||||
|           `type=raw,my`, | ||||
|           `type=raw,custom`, | ||||
|           `type=raw,tags` | ||||
|         ] | ||||
|       } as Inputs, | ||||
|       { | ||||
|         "tags": [ | ||||
|           "org/app:my", | ||||
|           "org/app:custom", | ||||
|           "org/app:tags", | ||||
|           "ghcr.io/user/app:my", | ||||
|           "ghcr.io/user/app:custom", | ||||
|           "ghcr.io/user/app:tags" | ||||
|         ], | ||||
|         "labels": { | ||||
|           "org.opencontainers.image.title": "Hello-World", | ||||
|           "org.opencontainers.image.description": "This your first repo!", | ||||
|           "org.opencontainers.image.url": "https://github.com/octocat/Hello-World", | ||||
|           "org.opencontainers.image.source": "https://github.com/octocat/Hello-World", | ||||
|           "org.opencontainers.image.version": "my", | ||||
|           "org.opencontainers.image.created": "2020-01-10T00:30:00.000Z", | ||||
|           "org.opencontainers.image.revision": "90dd6032fac8bda1b6c4436a2e65de27961ed071", | ||||
|           "org.opencontainers.image.licenses": "MIT" | ||||
|         } | ||||
|       } | ||||
|     ], | ||||
|     [ | ||||
|       'json07', | ||||
|       'event_tag_v1.1.1.env', | ||||
|       { | ||||
|         images: ['org/app'], | ||||
|         labels: [ | ||||
|           "foo", | ||||
|           "maintainer=CrazyMax", | ||||
|           "org.opencontainers.image.title=MyCustom=Title", | ||||
|           "org.opencontainers.image.description=Another description", | ||||
|           "org.opencontainers.image.vendor=MyCompany", | ||||
|         ], | ||||
|       } as Inputs, | ||||
|       { | ||||
|         "tags": [ | ||||
|           "org/app:v1.1.1", | ||||
|           "org/app:latest" | ||||
|         ], | ||||
|         "labels": { | ||||
|           "maintainer": "CrazyMax", | ||||
|           "org.opencontainers.image.title": "MyCustom=Title", | ||||
|           "org.opencontainers.image.description": "Another description", | ||||
|           "org.opencontainers.image.url": "https://github.com/octocat/Hello-World", | ||||
|           "org.opencontainers.image.source": "https://github.com/octocat/Hello-World", | ||||
|           "org.opencontainers.image.vendor": "MyCompany", | ||||
|           "org.opencontainers.image.version": "v1.1.1", | ||||
|           "org.opencontainers.image.created": "2020-01-10T00:30:00.000Z", | ||||
|           "org.opencontainers.image.revision": "90dd6032fac8bda1b6c4436a2e65de27961ed071", | ||||
|           "org.opencontainers.image.licenses": "MIT" | ||||
|         } | ||||
|       } | ||||
|     ] | ||||
|   ])('given %p with %p event', async (name: string, envFile: string, inputs: Inputs, exJSON: {}) => { | ||||
|     process.env = dotenv.parse(fs.readFileSync(path.join(__dirname, 'fixtures', envFile))); | ||||
|     const context = github.context(); | ||||
|     console.log(process.env, context); | ||||
| 
 | ||||
|     const repo = await github.repo(process.env.GITHUB_TOKEN || ''); | ||||
|     const meta = new Meta({...getInputs(), ...inputs}, context, repo); | ||||
| 
 | ||||
|     const jsonOutput = meta.getJSON(); | ||||
|     console.log('json', jsonOutput); | ||||
|     expect(jsonOutput).toEqual(exJSON); | ||||
|   }); | ||||
| }); | ||||
| 
 | ||||
| describe('bake', () => { | ||||
|   // prettier-ignore
 | ||||
|   test.each([ | ||||
|  | ||||
							
								
								
									
										36
									
								
								dist/index.js
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										36
									
								
								dist/index.js
									
									
									
										generated
									
									
										vendored
									
									
								
							| @ -321,6 +321,12 @@ function run() { | ||||
|             } | ||||
|             core.endGroup(); | ||||
|             context_1.setOutput('labels', labels.join(inputs.sepLabels)); | ||||
|             // JSON
 | ||||
|             const jsonOutput = meta.getJSON(); | ||||
|             core.startGroup(`JSON output`); | ||||
|             core.info(JSON.stringify(jsonOutput, null, 2)); | ||||
|             core.endGroup(); | ||||
|             context_1.setOutput('json', jsonOutput); | ||||
|             // Bake definition file
 | ||||
|             const bakeFile = meta.getBakeFile(); | ||||
|             core.startGroup(`Bake definition file`); | ||||
| @ -644,21 +650,33 @@ class Meta { | ||||
|         labels.push(...this.inputs.labels); | ||||
|         return labels; | ||||
|     } | ||||
|     getJSON() { | ||||
|         return { | ||||
|             tags: this.getTags(), | ||||
|             labels: this.getLabels().reduce((res, label) => { | ||||
|                 const matches = label.match(/([^=]*)=(.*)/); | ||||
|                 if (!matches) { | ||||
|                     return res; | ||||
|                 } | ||||
|                 res[matches[1]] = matches[2]; | ||||
|                 return res; | ||||
|             }, {}) | ||||
|         }; | ||||
|     } | ||||
|     getBakeFile() { | ||||
|         let jsonLabels = {}; | ||||
|         for (let label of this.getLabels()) { | ||||
|             const matches = label.match(/([^=]*)=(.*)/); | ||||
|             if (!matches) { | ||||
|                 continue; | ||||
|             } | ||||
|             jsonLabels[matches[1]] = matches[2]; | ||||
|         } | ||||
|         const bakeFile = path.join(context_1.tmpDir(), 'docker-metadata-action-bake.json').split(path.sep).join(path.posix.sep); | ||||
|         fs.writeFileSync(bakeFile, JSON.stringify({ | ||||
|             target: { | ||||
|                 [this.inputs.bakeTarget]: { | ||||
|                     tags: this.getTags(), | ||||
|                     labels: jsonLabels, | ||||
|                     labels: this.getLabels().reduce((res, label) => { | ||||
|                         const matches = label.match(/([^=]*)=(.*)/); | ||||
|                         if (!matches) { | ||||
|                             return res; | ||||
|                         } | ||||
|                         res[matches[1]] = matches[2]; | ||||
|                         return res; | ||||
|                     }, {}), | ||||
|                     args: { | ||||
|                         DOCKER_META_IMAGES: this.inputs.images.join(','), | ||||
|                         DOCKER_META_VERSION: this.version.main | ||||
|  | ||||
| @ -60,6 +60,13 @@ async function run() { | ||||
|     core.endGroup(); | ||||
|     setOutput('labels', labels.join(inputs.sepLabels)); | ||||
| 
 | ||||
|     // JSON
 | ||||
|     const jsonOutput = meta.getJSON(); | ||||
|     core.startGroup(`JSON output`); | ||||
|     core.info(JSON.stringify(jsonOutput, null, 2)); | ||||
|     core.endGroup(); | ||||
|     setOutput('json', jsonOutput); | ||||
| 
 | ||||
|     // Bake definition file
 | ||||
|     const bakeFile: string = meta.getBakeFile(); | ||||
|     core.startGroup(`Bake definition file`); | ||||
|  | ||||
							
								
								
									
										32
									
								
								src/meta.ts
									
									
									
									
									
								
							
							
						
						
									
										32
									
								
								src/meta.ts
									
									
									
									
									
								
							| @ -318,16 +318,21 @@ export class Meta { | ||||
|     return labels; | ||||
|   } | ||||
| 
 | ||||
|   public getBakeFile(): string { | ||||
|     let jsonLabels = {}; | ||||
|     for (let label of this.getLabels()) { | ||||
|       const matches = label.match(/([^=]*)=(.*)/); | ||||
|       if (!matches) { | ||||
|         continue; | ||||
|       } | ||||
|       jsonLabels[matches[1]] = matches[2]; | ||||
|     } | ||||
|   public getJSON(): {} { | ||||
|     return { | ||||
|       tags: this.getTags(), | ||||
|       labels: this.getLabels().reduce((res, label) => { | ||||
|         const matches = label.match(/([^=]*)=(.*)/); | ||||
|         if (!matches) { | ||||
|           return res; | ||||
|         } | ||||
|         res[matches[1]] = matches[2]; | ||||
|         return res; | ||||
|       }, {}) | ||||
|     }; | ||||
|   } | ||||
| 
 | ||||
|   public getBakeFile(): string { | ||||
|     const bakeFile = path.join(tmpDir(), 'docker-metadata-action-bake.json').split(path.sep).join(path.posix.sep); | ||||
|     fs.writeFileSync( | ||||
|       bakeFile, | ||||
| @ -336,7 +341,14 @@ export class Meta { | ||||
|           target: { | ||||
|             [this.inputs.bakeTarget]: { | ||||
|               tags: this.getTags(), | ||||
|               labels: jsonLabels, | ||||
|               labels: this.getLabels().reduce((res, label) => { | ||||
|                 const matches = label.match(/([^=]*)=(.*)/); | ||||
|                 if (!matches) { | ||||
|                   return res; | ||||
|                 } | ||||
|                 res[matches[1]] = matches[2]; | ||||
|                 return res; | ||||
|               }, {}), | ||||
|               args: { | ||||
|                 DOCKER_META_IMAGES: this.inputs.images.join(','), | ||||
|                 DOCKER_META_VERSION: this.version.main | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 CrazyMax
						CrazyMax