From 585ab8356cceca068ecdee9736a6b33922f85979 Mon Sep 17 00:00:00 2001 From: CrazyMax <1951866+crazy-max@users.noreply.github.com> Date: Fri, 4 Dec 2020 18:12:39 +0100 Subject: [PATCH] Allow to add custom tags (#24) Co-authored-by: CrazyMax --- README.md | 4 +- __tests__/meta.test.ts | 190 +++++++++++++++++++++++++++++++++++++++++ action.yml | 6 ++ dist/index.js | 16 +++- src/context.ts | 4 + src/meta.ts | 14 ++- 6 files changed, 231 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 623df68..486270b 100644 --- a/README.md +++ b/README.md @@ -246,6 +246,8 @@ Following inputs can be used as `step.with` keys | `tag-match-group` | Number | Group to get if `tag-match` matches (default `0`) | | `tag-latest` | Bool | Set `latest` Docker tag if `tag-semver`, `tag-match` or Git tag event occurs (default `true`) | | `tag-schedule` | String | [Template](#schedule-tag) to apply to schedule tag (default `nightly`) | +| `tag-custom` | List/CSV | List of custom tags | +| `tag-custom-only` | Bool | Only use `tag-custom` as Docker tags | | `sep-tags` | String | Separator to use for tags output (default `\n`) | | `sep-labels` | String | Separator to use for labels output (default `\n`) | @@ -270,7 +272,7 @@ Following outputs are available Latest Docker tag will be generated by default on `push tag` event. If for example you push the `v1.2.3` Git tag, you will have at the output of this action the Docker tags `v1.2.3` and `latest`. But you can allow the latest tag to be generated only if `tag-semver` is a valid [semver](https://semver.org/) or if Git tag matches a regular expression -with the [`tag-match` input](#tag-match-examples). +with the [`tag-match` input](#tag-match-examples). Can be disabled if `tag-latest` is `false`. ### Handle semver tag diff --git a/__tests__/meta.test.ts b/__tests__/meta.test.ts index ad63e7f..303ffbe 100644 --- a/__tests__/meta.test.ts +++ b/__tests__/meta.test.ts @@ -1229,3 +1229,193 @@ describe('release', () => { ], ])('given %p event ', tagsLabelsTest); }); + +describe('custom', () => { + // prettier-ignore + test.each([ + [ + 'event_push.env', + { + images: ['user/app'], + tagCustom: ['my', 'custom', 'tags'] + } as Inputs, + { + main: 'dev', + partial: ['my', 'custom', 'tags'], + latest: false + } as Version, + [ + 'user/app:dev', + 'user/app:my', + 'user/app:custom', + 'user/app:tags' + ], + [ + "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" + ] + ], + [ + 'event_push.env', + { + images: ['user/app'], + tagCustom: ['my'] + } as Inputs, + { + main: 'dev', + partial: ['my'], + latest: false + } as Version, + [ + 'user/app:dev', + 'user/app:my' + ], + [ + "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" + ] + ], + [ + 'event_tag_release1.env', + { + images: ['user/app'], + tagCustom: ['my', 'custom', 'tags'] + } as Inputs, + { + main: 'release1', + partial: ['my', 'custom', 'tags'], + latest: true + } as Version, + [ + 'user/app:release1', + 'user/app:my', + 'user/app:custom', + 'user/app:tags', + 'user/app:latest' + ], + [ + "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" + ] + ], + [ + 'event_tag_20200110-RC2.env', + { + images: ['user/app'], + tagMatch: `\\d{8}`, + tagLatest: false, + tagCustom: ['my', 'custom', 'tags'] + } as Inputs, + { + main: '20200110', + partial: ['my', 'custom', 'tags'], + latest: false + } as Version, + [ + 'user/app:20200110', + 'user/app:my', + 'user/app:custom', + 'user/app:tags' + ], + [ + "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" + ] + ], + [ + 'event_tag_v1.1.1.env', + { + images: ['org/app', 'ghcr.io/user/app'], + tagSemver: ['{{version}}', '{{major}}.{{minor}}', '{{major}}'], + tagCustom: ['my', 'custom', 'tags'] + } as Inputs, + { + main: '1.1.1', + partial: ['1.1', '1', 'my', 'custom', 'tags'], + latest: true + } as Version, + [ + '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' + ], + [ + "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" + ] + ], + [ + 'event_tag_v1.1.1.env', + { + images: ['org/app', 'ghcr.io/user/app'], + tagSemver: ['{{version}}', '{{major}}.{{minor}}.{{patch}}'], + tagCustom: ['my', 'custom', 'tags'], + tagCustomOnly: true, + } as Inputs, + { + main: 'my', + partial: ['custom', 'tags'], + latest: false + } as Version, + [ + 'org/app:my', + 'org/app:custom', + 'org/app:tags', + 'ghcr.io/user/app:my', + 'ghcr.io/user/app:custom', + 'ghcr.io/user/app:tags' + ], + [ + "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" + ] + ], + ])('given %p event ', tagsLabelsTest); +}); diff --git a/action.yml b/action.yml index 8eadd19..8a4181d 100644 --- a/action.yml +++ b/action.yml @@ -44,6 +44,12 @@ inputs: description: 'Template to apply to schedule tag' default: 'nightly' required: false + tag-custom: + description: 'List of custom tags' + required: false + tag-custom-only: + description: 'Only use tag-custom as Docker tags' + required: false sep-tags: description: 'Separator to use for tags output (default \n)' required: false diff --git a/dist/index.js b/dist/index.js index 72fb643..20d044b 100644 --- a/dist/index.js +++ b/dist/index.js @@ -30,6 +30,8 @@ function getInputs() { tagMatchGroup: Number(core.getInput('tag-match-group')) || 0, tagLatest: /true/i.test(core.getInput('tag-latest') || core.getInput('tag-match-latest') || 'true'), tagSchedule: core.getInput('tag-schedule') || 'nightly', + tagCustom: getInputList('tag-custom'), + tagCustomOnly: /true/i.test(core.getInput('tag-custom-only') || 'false'), sepTags: core.getInput('sep-tags') || `\n`, sepLabels: core.getInput('sep-labels') || `\n`, githubToken: core.getInput('github-token') @@ -185,7 +187,7 @@ class Meta { } getVersion() { const currentDate = this.date; - const version = { + let version = { main: undefined, partial: [], latest: false @@ -248,6 +250,18 @@ class Meta { else if (/^refs\/pull\//.test(this.context.ref)) { version.main = `pr-${this.context.ref.replace(/^refs\/pull\//g, '').replace(/\/merge$/g, '')}`; } + if (this.inputs.tagCustom.length > 0) { + if (this.inputs.tagCustomOnly) { + version = { + main: this.inputs.tagCustom.shift(), + partial: this.inputs.tagCustom, + latest: false + }; + } + else { + version.partial.push(...this.inputs.tagCustom); + } + } version.partial = version.partial.filter((item, index) => version.partial.indexOf(item) === index); return version; } diff --git a/src/context.ts b/src/context.ts index e50221d..8252565 100644 --- a/src/context.ts +++ b/src/context.ts @@ -10,6 +10,8 @@ export interface Inputs { tagMatchGroup: number; tagLatest: boolean; tagSchedule: string; + tagCustom: string[]; + tagCustomOnly: boolean; sepTags: string; sepLabels: string; githubToken: string; @@ -26,6 +28,8 @@ export function getInputs(): Inputs { tagMatchGroup: Number(core.getInput('tag-match-group')) || 0, tagLatest: /true/i.test(core.getInput('tag-latest') || core.getInput('tag-match-latest') || 'true'), tagSchedule: core.getInput('tag-schedule') || 'nightly', + tagCustom: getInputList('tag-custom'), + tagCustomOnly: /true/i.test(core.getInput('tag-custom-only') || 'false'), sepTags: core.getInput('sep-tags') || `\n`, sepLabels: core.getInput('sep-labels') || `\n`, githubToken: core.getInput('github-token') diff --git a/src/meta.ts b/src/meta.ts index 8fae9b9..8414415 100644 --- a/src/meta.ts +++ b/src/meta.ts @@ -33,7 +33,7 @@ export class Meta { private getVersion(): Version { const currentDate = this.date; - const version: Version = { + let version: Version = { main: undefined, partial: [], latest: false @@ -91,6 +91,18 @@ export class Meta { version.main = `pr-${this.context.ref.replace(/^refs\/pull\//g, '').replace(/\/merge$/g, '')}`; } + if (this.inputs.tagCustom.length > 0) { + if (this.inputs.tagCustomOnly) { + version = { + main: this.inputs.tagCustom.shift(), + partial: this.inputs.tagCustom, + latest: false + }; + } else { + version.partial.push(...this.inputs.tagCustom); + } + } + version.partial = version.partial.filter((item, index) => version.partial.indexOf(item) === index); return version; }