mirror of
https://github.com/docker/metadata-action.git
synced 2025-04-11 03:50:24 +02:00
labelPrefix flavor for annotations support
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
This commit is contained in:
parent
62339db73c
commit
3e5e65e4c1
29
README.md
29
README.md
@ -47,6 +47,7 @@ ___
|
|||||||
* [`{{date '<format>' tz='<timezone>'}}`](#date-format-tztimezone)
|
* [`{{date '<format>' tz='<timezone>'}}`](#date-format-tztimezone)
|
||||||
* [Major version zero](#major-version-zero)
|
* [Major version zero](#major-version-zero)
|
||||||
* [JSON output object](#json-output-object)
|
* [JSON output object](#json-output-object)
|
||||||
|
* [Labels prefix](#labels-prefix)
|
||||||
* [Overwrite labels](#overwrite-labels)
|
* [Overwrite labels](#overwrite-labels)
|
||||||
* [Contributing](#contributing)
|
* [Contributing](#contributing)
|
||||||
|
|
||||||
@ -368,6 +369,7 @@ flavor: |
|
|||||||
latest=auto
|
latest=auto
|
||||||
prefix=
|
prefix=
|
||||||
suffix=
|
suffix=
|
||||||
|
labelPrefix=
|
||||||
```
|
```
|
||||||
|
|
||||||
* `latest=<auto|true|false>`: Handle [latest tag](#latest-tag) (default `auto`)
|
* `latest=<auto|true|false>`: Handle [latest tag](#latest-tag) (default `auto`)
|
||||||
@ -375,6 +377,8 @@ flavor: |
|
|||||||
tag and optionally for `latest`
|
tag and optionally for `latest`
|
||||||
* `suffix=<string>,onlatest=<true|false>`: A global suffix for each generated
|
* `suffix=<string>,onlatest=<true|false>`: A global suffix for each generated
|
||||||
tag and optionally for `latest`
|
tag and optionally for `latest`
|
||||||
|
* `labelPrefix=<string>`: A global prefix to apply to each label. Can be
|
||||||
|
useful to [set annotations at manifest or index level](#labels-prefix).
|
||||||
|
|
||||||
## `tags` input
|
## `tags` input
|
||||||
|
|
||||||
@ -867,6 +871,31 @@ that you can reuse them further in your workflow using the [`fromJSON` function]
|
|||||||
REVISION=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.revision'] }}
|
REVISION=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.revision'] }}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Labels prefix
|
||||||
|
|
||||||
|
Since Buildx 0.12, it is possible to set annotations to your image through the
|
||||||
|
`--annotation` flag. When using the metadata-action you can set the `manifest:`
|
||||||
|
or `index:` prefix to each label using the `labelPrefix` attribute in the
|
||||||
|
`flavor` input. When used with the [`build-push-action`](https://github.com/docker/build-push-action/)
|
||||||
|
and the `annotations` input, it will either set annotations at the manifest or
|
||||||
|
index level:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
-
|
||||||
|
name: Docker meta
|
||||||
|
uses: docker/metadata-action@v5
|
||||||
|
with:
|
||||||
|
images: name/app
|
||||||
|
flavor: |
|
||||||
|
labelPrefix=index:
|
||||||
|
-
|
||||||
|
name: Build and push
|
||||||
|
uses: docker/build-push-action@v5
|
||||||
|
with:
|
||||||
|
tags: ${{ steps.meta.outputs.tags }}
|
||||||
|
annotations: ${{ steps.meta.outputs.labels }}
|
||||||
|
```
|
||||||
|
|
||||||
### Overwrite labels
|
### Overwrite labels
|
||||||
|
|
||||||
If some [OCI Image Format Specification](https://github.com/opencontainers/image-spec/blob/master/annotations.md)
|
If some [OCI Image Format Specification](https://github.com/opencontainers/image-spec/blob/master/annotations.md)
|
||||||
|
@ -37,6 +37,7 @@ describe('transform', () => {
|
|||||||
prefixLatest: false,
|
prefixLatest: false,
|
||||||
suffix: "",
|
suffix: "",
|
||||||
suffixLatest: false,
|
suffixLatest: false,
|
||||||
|
labelPrefix: "",
|
||||||
} as Flavor,
|
} as Flavor,
|
||||||
false
|
false
|
||||||
],
|
],
|
||||||
@ -50,6 +51,7 @@ describe('transform', () => {
|
|||||||
prefixLatest: false,
|
prefixLatest: false,
|
||||||
suffix: "",
|
suffix: "",
|
||||||
suffixLatest: false,
|
suffixLatest: false,
|
||||||
|
labelPrefix: "",
|
||||||
} as Flavor,
|
} as Flavor,
|
||||||
false
|
false
|
||||||
],
|
],
|
||||||
@ -63,6 +65,7 @@ describe('transform', () => {
|
|||||||
prefixLatest: false,
|
prefixLatest: false,
|
||||||
suffix: "",
|
suffix: "",
|
||||||
suffixLatest: false,
|
suffixLatest: false,
|
||||||
|
labelPrefix: "",
|
||||||
} as Flavor,
|
} as Flavor,
|
||||||
false
|
false
|
||||||
],
|
],
|
||||||
@ -83,6 +86,7 @@ describe('transform', () => {
|
|||||||
prefixLatest: false,
|
prefixLatest: false,
|
||||||
suffix: "",
|
suffix: "",
|
||||||
suffixLatest: false,
|
suffixLatest: false,
|
||||||
|
labelPrefix: "",
|
||||||
} as Flavor,
|
} as Flavor,
|
||||||
false
|
false
|
||||||
],
|
],
|
||||||
@ -96,6 +100,7 @@ describe('transform', () => {
|
|||||||
prefixLatest: false,
|
prefixLatest: false,
|
||||||
suffix: "-alpine",
|
suffix: "-alpine",
|
||||||
suffixLatest: false,
|
suffixLatest: false,
|
||||||
|
labelPrefix: "",
|
||||||
} as Flavor,
|
} as Flavor,
|
||||||
false
|
false
|
||||||
],
|
],
|
||||||
@ -111,6 +116,7 @@ describe('transform', () => {
|
|||||||
prefixLatest: false,
|
prefixLatest: false,
|
||||||
suffix: "-alpine",
|
suffix: "-alpine",
|
||||||
suffixLatest: false,
|
suffixLatest: false,
|
||||||
|
labelPrefix: "",
|
||||||
} as Flavor,
|
} as Flavor,
|
||||||
false
|
false
|
||||||
],
|
],
|
||||||
@ -124,6 +130,7 @@ describe('transform', () => {
|
|||||||
prefixLatest: true,
|
prefixLatest: true,
|
||||||
suffix: "",
|
suffix: "",
|
||||||
suffixLatest: false,
|
suffixLatest: false,
|
||||||
|
labelPrefix: "",
|
||||||
} as Flavor,
|
} as Flavor,
|
||||||
false
|
false
|
||||||
],
|
],
|
||||||
@ -137,6 +144,7 @@ describe('transform', () => {
|
|||||||
prefixLatest: false,
|
prefixLatest: false,
|
||||||
suffix: "-alpine",
|
suffix: "-alpine",
|
||||||
suffixLatest: true,
|
suffixLatest: true,
|
||||||
|
labelPrefix: "",
|
||||||
} as Flavor,
|
} as Flavor,
|
||||||
false
|
false
|
||||||
],
|
],
|
||||||
@ -151,6 +159,7 @@ describe('transform', () => {
|
|||||||
prefixLatest: true,
|
prefixLatest: true,
|
||||||
suffix: "-alpine",
|
suffix: "-alpine",
|
||||||
suffixLatest: true,
|
suffixLatest: true,
|
||||||
|
labelPrefix: "",
|
||||||
} as Flavor,
|
} as Flavor,
|
||||||
false
|
false
|
||||||
],
|
],
|
||||||
@ -164,6 +173,21 @@ describe('transform', () => {
|
|||||||
prefixLatest: false,
|
prefixLatest: false,
|
||||||
suffix: "",
|
suffix: "",
|
||||||
suffixLatest: false,
|
suffixLatest: false,
|
||||||
|
labelPrefix: "",
|
||||||
|
} as Flavor,
|
||||||
|
false
|
||||||
|
],
|
||||||
|
[
|
||||||
|
[
|
||||||
|
`labelPrefix=manifest:`,
|
||||||
|
],
|
||||||
|
{
|
||||||
|
latest: "auto",
|
||||||
|
prefix: "",
|
||||||
|
prefixLatest: false,
|
||||||
|
suffix: "",
|
||||||
|
suffixLatest: false,
|
||||||
|
labelPrefix: "manifest:",
|
||||||
} as Flavor,
|
} as Flavor,
|
||||||
false
|
false
|
||||||
]
|
]
|
||||||
|
@ -3463,6 +3463,37 @@ describe('raw', () => {
|
|||||||
"org.opencontainers.image.version=foo"
|
"org.opencontainers.image.version=foo"
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
|
[
|
||||||
|
'raw11',
|
||||||
|
'event_push_dev.env',
|
||||||
|
{
|
||||||
|
images: ['user/app'],
|
||||||
|
tags: [
|
||||||
|
`type=raw,foo`
|
||||||
|
],
|
||||||
|
flavor: [
|
||||||
|
`labelPrefix=index:`,
|
||||||
|
]
|
||||||
|
} as Inputs,
|
||||||
|
{
|
||||||
|
main: 'foo',
|
||||||
|
partial: [],
|
||||||
|
latest: false
|
||||||
|
} as Version,
|
||||||
|
[
|
||||||
|
'user/app:foo'
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"index:org.opencontainers.image.created=2020-01-10T00:30:00.000Z",
|
||||||
|
"index:org.opencontainers.image.description=This your first repo!",
|
||||||
|
"index:org.opencontainers.image.licenses=MIT",
|
||||||
|
"index:org.opencontainers.image.revision=860c1904a1ce19322e91ac35af1ab07466440c37",
|
||||||
|
"index:org.opencontainers.image.source=https://github.com/octocat/Hello-World",
|
||||||
|
"index:org.opencontainers.image.title=Hello-World",
|
||||||
|
"index:org.opencontainers.image.url=https://github.com/octocat/Hello-World",
|
||||||
|
"index:org.opencontainers.image.version=foo"
|
||||||
|
]
|
||||||
|
]
|
||||||
])('given %p wth %p event', tagsLabelsTest);
|
])('given %p wth %p event', tagsLabelsTest);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -3706,7 +3737,35 @@ describe('json', () => {
|
|||||||
"org.opencontainers.image.version": "v1.1.1"
|
"org.opencontainers.image.version": "v1.1.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
[
|
||||||
|
'json08',
|
||||||
|
'event_push_dev.env',
|
||||||
|
{
|
||||||
|
images: ['user/app'],
|
||||||
|
tags: [
|
||||||
|
`type=raw,foo`
|
||||||
|
],
|
||||||
|
flavor: [
|
||||||
|
"labelPrefix=manifest:",
|
||||||
|
]
|
||||||
|
} as Inputs,
|
||||||
|
{
|
||||||
|
"tags": [
|
||||||
|
"user/app:foo"
|
||||||
|
],
|
||||||
|
"labels": {
|
||||||
|
"manifest:org.opencontainers.image.created": "2020-01-10T00:30:00.000Z",
|
||||||
|
"manifest:org.opencontainers.image.description": "This your first repo!",
|
||||||
|
"manifest:org.opencontainers.image.licenses": "MIT",
|
||||||
|
"manifest:org.opencontainers.image.revision": "860c1904a1ce19322e91ac35af1ab07466440c37",
|
||||||
|
"manifest:org.opencontainers.image.source": "https://github.com/octocat/Hello-World",
|
||||||
|
"manifest:org.opencontainers.image.title": "Hello-World",
|
||||||
|
"manifest:org.opencontainers.image.url": "https://github.com/octocat/Hello-World",
|
||||||
|
"manifest:org.opencontainers.image.version": "foo"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
])('given %p with %p event', async (name: string, envFile: string, inputs: Inputs, exJSON: unknown) => {
|
])('given %p with %p event', async (name: string, envFile: string, inputs: Inputs, exJSON: unknown) => {
|
||||||
process.env = dotenv.parse(fs.readFileSync(path.join(__dirname, 'fixtures', envFile)));
|
process.env = dotenv.parse(fs.readFileSync(path.join(__dirname, 'fixtures', envFile)));
|
||||||
|
|
||||||
@ -4012,6 +4071,42 @@ describe('bake', () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'bake08',
|
||||||
|
'event_push_dev.env',
|
||||||
|
{
|
||||||
|
images: ['user/app'],
|
||||||
|
tags: [
|
||||||
|
`type=raw,foo`
|
||||||
|
],
|
||||||
|
flavor: [
|
||||||
|
"labelPrefix=index:",
|
||||||
|
]
|
||||||
|
} as Inputs,
|
||||||
|
{
|
||||||
|
"target": {
|
||||||
|
"docker-metadata-action": {
|
||||||
|
"tags": [
|
||||||
|
"user/app:foo"
|
||||||
|
],
|
||||||
|
"labels": {
|
||||||
|
"index:org.opencontainers.image.created": "2020-01-10T00:30:00.000Z",
|
||||||
|
"index:org.opencontainers.image.description": "This your first repo!",
|
||||||
|
"index:org.opencontainers.image.licenses": "MIT",
|
||||||
|
"index:org.opencontainers.image.revision": "860c1904a1ce19322e91ac35af1ab07466440c37",
|
||||||
|
"index:org.opencontainers.image.source": "https://github.com/octocat/Hello-World",
|
||||||
|
"index:org.opencontainers.image.title": "Hello-World",
|
||||||
|
"index:org.opencontainers.image.url": "https://github.com/octocat/Hello-World",
|
||||||
|
"index:org.opencontainers.image.version": "foo"
|
||||||
|
},
|
||||||
|
"args": {
|
||||||
|
"DOCKER_META_IMAGES": "user/app",
|
||||||
|
"DOCKER_META_VERSION": "foo",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
]
|
]
|
||||||
])('given %p with %p event', async (name: string, envFile: string, inputs: Inputs, exBakeDefinition: unknown) => {
|
])('given %p with %p event', async (name: string, envFile: string, inputs: Inputs, exBakeDefinition: unknown) => {
|
||||||
process.env = dotenv.parse(fs.readFileSync(path.join(__dirname, 'fixtures', envFile)));
|
process.env = dotenv.parse(fs.readFileSync(path.join(__dirname, 'fixtures', envFile)));
|
||||||
|
@ -7,6 +7,7 @@ export interface Flavor {
|
|||||||
prefixLatest: boolean;
|
prefixLatest: boolean;
|
||||||
suffix: string;
|
suffix: string;
|
||||||
suffixLatest: boolean;
|
suffixLatest: boolean;
|
||||||
|
labelPrefix: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function Transform(inputs: string[]): Flavor {
|
export function Transform(inputs: string[]): Flavor {
|
||||||
@ -15,7 +16,8 @@ export function Transform(inputs: string[]): Flavor {
|
|||||||
prefix: '',
|
prefix: '',
|
||||||
prefixLatest: false,
|
prefixLatest: false,
|
||||||
suffix: '',
|
suffix: '',
|
||||||
suffixLatest: false
|
suffixLatest: false,
|
||||||
|
labelPrefix: ''
|
||||||
};
|
};
|
||||||
|
|
||||||
for (const input of inputs) {
|
for (const input of inputs) {
|
||||||
@ -68,6 +70,10 @@ export function Transform(inputs: string[]): Flavor {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case 'labelprefix': {
|
||||||
|
flavor.labelPrefix = value;
|
||||||
|
break;
|
||||||
|
}
|
||||||
default: {
|
default: {
|
||||||
throw new Error(`Unknown flavor entry: ${input}`);
|
throw new Error(`Unknown flavor entry: ${input}`);
|
||||||
}
|
}
|
||||||
@ -81,6 +87,7 @@ export function Transform(inputs: string[]): Flavor {
|
|||||||
core.info(`prefixLatest=${flavor.prefixLatest}`);
|
core.info(`prefixLatest=${flavor.prefixLatest}`);
|
||||||
core.info(`suffix=${flavor.suffix}`);
|
core.info(`suffix=${flavor.suffix}`);
|
||||||
core.info(`suffixLatest=${flavor.suffixLatest}`);
|
core.info(`suffixLatest=${flavor.suffixLatest}`);
|
||||||
|
core.info(`labelPrefix=${flavor.labelPrefix}`);
|
||||||
core.endGroup();
|
core.endGroup();
|
||||||
|
|
||||||
return flavor;
|
return flavor;
|
||||||
|
@ -455,7 +455,7 @@ export class Meta {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public getLabels(): Array<string> {
|
public getLabels(): Array<string> {
|
||||||
const labels: Array<string> = [
|
let labels: Array<string> = [
|
||||||
`org.opencontainers.image.title=${this.repo.name || ''}`,
|
`org.opencontainers.image.title=${this.repo.name || ''}`,
|
||||||
`org.opencontainers.image.description=${this.repo.description || ''}`,
|
`org.opencontainers.image.description=${this.repo.description || ''}`,
|
||||||
`org.opencontainers.image.url=${this.repo.html_url || ''}`,
|
`org.opencontainers.image.url=${this.repo.html_url || ''}`,
|
||||||
@ -466,6 +466,9 @@ export class Meta {
|
|||||||
`org.opencontainers.image.licenses=${this.repo.license?.spdx_id || ''}`
|
`org.opencontainers.image.licenses=${this.repo.license?.spdx_id || ''}`
|
||||||
];
|
];
|
||||||
labels.push(...this.inputs.labels);
|
labels.push(...this.inputs.labels);
|
||||||
|
if (this.flavor.labelPrefix.length > 0) {
|
||||||
|
labels = labels.map(label => this.flavor.labelPrefix + label);
|
||||||
|
}
|
||||||
|
|
||||||
return Array.from(
|
return Array.from(
|
||||||
new Map<string, string>(
|
new Map<string, string>(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user