From 81c60dfb8b905e3a16457c3da8880fc62e9051b8 Mon Sep 17 00:00:00 2001 From: CrazyMax <1951866+crazy-max@users.noreply.github.com> Date: Thu, 31 Jul 2025 17:39:10 +0200 Subject: [PATCH] allow to match part of the git tag or value for semver type Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com> --- README.md | 58 +++++++++++++++++++++----------------- __tests__/meta.test.ts | 63 ++++++++++++++++++++++++++++++++++++++++++ __tests__/tag.test.ts | 26 ++++++++++++++--- src/meta.ts | 14 +++++++++- src/tag.ts | 3 ++ 5 files changed, 133 insertions(+), 31 deletions(-) diff --git a/README.md b/README.md index 5cbde6e..e922a73 100644 --- a/README.md +++ b/README.md @@ -495,6 +495,8 @@ tags: | type=semver,pattern={{version}} # use custom value instead of git tag type=semver,pattern={{version}},value=v1.0.0 + # use custom value and match part of it + type=semver,pattern={{version}},value=p1/v1.0.0,match=v(\d.\d.\d)$ ``` Will be used on a [push tag event](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#push) @@ -510,18 +512,19 @@ with the following expressions: * `minor` ; minor version identifier * `patch` ; patch version identifier -| Git tag | Pattern | Output | -|--------------------|-----------------------|----------------------| -| `v1.2.3` | `{{raw}}` | `v1.2.3` | -| `v1.2.3` | `{{version}}` | `1.2.3` | -| `v1.2.3` | `{{major}}.{{minor}}` | `1.2` | -| `v1.2.3` | `v{{major}}` | `v1` | -| `v1.2.3` | `{{minor}}` | `2` | -| `v1.2.3` | `{{patch}}` | `3` | -| `v2.0.8-beta.67` | `{{raw}}` | `v2.0.8-beta.67` | -| `v2.0.8-beta.67` | `{{version}}` | `2.0.8-beta.67` | -| `v2.0.8-beta.67` | `{{major}}` | `2.0.8-beta.67`* | -| `v2.0.8-beta.67` | `{{major}}.{{minor}}` | `2.0.8-beta.67`* | +| Git tag | Pattern | Match | Output | +|------------------|-----------------------|----------------|------------------| +| `v1.2.3` | `{{raw}}` | | `v1.2.3` | +| `v1.2.3` | `{{version}}` | | `1.2.3` | +| `v1.2.3` | `{{major}}.{{minor}}` | | `1.2` | +| `v1.2.3` | `v{{major}}` | | `v1` | +| `v1.2.3` | `{{minor}}` | | `2` | +| `v1.2.3` | `{{patch}}` | | `3` | +| `p1/v1.2.3` | `{{version}}` | `v(\d.\d.\d)$` | `1.2.3` | +| `v2.0.8-beta.67` | `{{raw}}` | | `v2.0.8-beta.67` | +| `v2.0.8-beta.67` | `{{version}}` | | `2.0.8-beta.67` | +| `v2.0.8-beta.67` | `{{major}}` | | `2.0.8-beta.67`* | +| `v2.0.8-beta.67` | `{{major}}.{{minor}}` | | `2.0.8-beta.67`* | > [!IMPORTANT] > *Pre-release (rc, beta, alpha) will only extend `{{version}}` (or `{{raw}}` @@ -533,7 +536,7 @@ Extended attributes and default values: ```yaml tags: | - type=semver,enable=true,priority=900,prefix=,suffix=,pattern=,value= + type=semver,enable=true,priority=900,prefix=,suffix=,pattern=,value=,match= ``` ### `type=pep440` @@ -544,6 +547,8 @@ tags: | type=pep440,pattern={{version}} # use custom value instead of git tag type=pep440,pattern={{version}},value=1.0.0 + # use custom value and match part of it + type=pep440,pattern={{version}},value=p1/v1.0.0,match=v(\d.\d.\d)$ ``` Will be used on a [push tag event](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#push) @@ -559,19 +564,20 @@ with the following expressions: * `minor` ; minor version identifier * `patch` ; patch version identifier -| Git tag | Pattern | Output | -|--------------------|----------------------------------------------------------|----------------------| -| `1.2.3` | `{{raw}}` | `1.2.3` | -| `1.2.3` | `{{version}}` | `1.2.3` | -| `v1.2.3` | `{{version}}` | `1.2.3` | -| `1.2.3` | `{{major}}.{{minor}}` | `1.2` | -| `1.2.3` | `v{{major}}` | `v1` | -| `v1.2.3rc2` | `{{raw}}` | `v1.2.3rc2` | -| `1.2.3rc2` | `{{version}}` | `1.2.3rc2` | -| `1.2.3rc2` | `{{major}}.{{minor}}` | `1.2.3rc2`* | -| `1.2.3post1` | `{{major}}.{{minor}}` | `1.2.3.post1`* | -| `1.2.3beta2` | `{{major}}.{{minor}}` | `1.2.3b2`* | -| `1.0dev4` | `{{major}}.{{minor}}` | `1.0.dev4`* | +| Git tag | Pattern | Match | Output | +|--------------|-----------------------|----------------|----------------| +| `1.2.3` | `{{raw}}` | | `1.2.3` | +| `1.2.3` | `{{version}}` | | `1.2.3` | +| `v1.2.3` | `{{version}}` | | `1.2.3` | +| `1.2.3` | `{{major}}.{{minor}}` | | `1.2` | +| `1.2.3` | `v{{major}}` | | `v1` | +| `v1.2.3rc2` | `{{raw}}` | | `v1.2.3rc2` | +| `1.2.3rc2` | `{{version}}` | | `1.2.3rc2` | +| `p1/v1.2.3` | `{{version}}` | `v(\d.\d.\d)$` | `1.2.3` | +| `1.2.3rc2` | `{{major}}.{{minor}}` | | `1.2.3rc2`* | +| `1.2.3post1` | `{{major}}.{{minor}}` | | `1.2.3.post1`* | +| `1.2.3beta2` | `{{major}}.{{minor}}` | | `1.2.3b2`* | +| `1.0dev4` | `{{major}}.{{minor}}` | | `1.0.dev4`* | > [!IMPORTANT] > *dev/pre/post release will only extend `{{version}}` (or `{{raw}}` if diff --git a/__tests__/meta.test.ts b/__tests__/meta.test.ts index 91bfa35..8132728 100644 --- a/__tests__/meta.test.ts +++ b/__tests__/meta.test.ts @@ -1971,6 +1971,69 @@ describe('tag', () => { "org.opencontainers.image.version=1.1.1" ], undefined + ], + [ + 'tag34', + 'event_tag_p1-v1.0.0.env', + { + images: ['org/app'], + tags: [ + `type=semver,pattern={{version}},"match=v(\\d.\\d.\\d)$"`, + ] + } as Inputs, + { + main: '1.0.0', + partial: [], + latest: true + } as Version, + [ + 'org/app:1.0.0', + 'org/app:latest' + ], + [ + "org.opencontainers.image.created=2020-01-10T00:30:00.000Z", + "org.opencontainers.image.description=This your first repo!", + "org.opencontainers.image.licenses=MIT", + "org.opencontainers.image.revision=860c1904a1ce19322e91ac35af1ab07466440c37", + "org.opencontainers.image.source=https://github.com/octocat/Hello-World", + "org.opencontainers.image.title=Hello-World", + "org.opencontainers.image.url=https://github.com/octocat/Hello-World", + "org.opencontainers.image.version=1.0.0" + ], + undefined + ], + [ + 'push35', + 'event_push_master.env', + { + images: ['user/app'], + tags: [ + `type=semver,pattern={{version}},value=p1/v1.2.3,"match=v(\\d.\\d.\\d)$"`, + `type=pep440,pattern={{version}},value=p1/v1.2.3,"match=v(\\d.\\d.\\d)$"`, + `type=edge` + ], + } as Inputs, + { + main: '1.2.3', + partial: ['edge'], + latest: true + } as Version, + [ + 'user/app:1.2.3', + 'user/app:edge', + 'user/app:latest' + ], + [ + "org.opencontainers.image.created=2020-01-10T00:30:00.000Z", + "org.opencontainers.image.description=This your first repo!", + "org.opencontainers.image.licenses=MIT", + "org.opencontainers.image.revision=266574110acf203503badf966df2ea24b5d732d7", + "org.opencontainers.image.source=https://github.com/octocat/Hello-World", + "org.opencontainers.image.title=Hello-World", + "org.opencontainers.image.url=https://github.com/octocat/Hello-World", + "org.opencontainers.image.version=1.2.3" + ], + undefined ] ])('given %p with %p event', tagsLabelsTest); }); diff --git a/__tests__/tag.test.ts b/__tests__/tag.test.ts index 3828e4f..622ebde 100644 --- a/__tests__/tag.test.ts +++ b/__tests__/tag.test.ts @@ -32,7 +32,8 @@ describe('transform', () => { "priority": DefaultPriorities[Type.Semver], "enable": "true", "pattern": "{{version}}", - "value": "" + "value": "", + "match": "" } }, { @@ -147,7 +148,8 @@ describe('parse', () => { "priority": DefaultPriorities[Type.Semver], "enable": "true", "pattern": "{{version}}", - "value": "" + "value": "", + "match": "" } } as Tag, false @@ -160,7 +162,8 @@ describe('parse', () => { "priority": "1", "enable": "true", "pattern": "{{version}}", - "value": "" + "value": "", + "match": "" } } as Tag, false @@ -173,7 +176,22 @@ describe('parse', () => { "priority": "1", "enable": "true", "pattern": "{{version}}", - "value": "v1.0.0" + "value": "v1.0.0", + "match": "" + } + } as Tag, + false + ], + [ + `type=semver,priority=1,enable=true,pattern={{version}},value=p1/v1.0.0,"match=v(\\d.\\d.\\d)$"`, + { + type: Type.Semver, + attrs: { + "priority": "1", + "enable": "true", + "pattern": "{{version}}", + "value": "p1/v1.0.0", + "match": "v(\\d.\\d.\\d)$" } } as Tag, false diff --git a/src/meta.ts b/src/meta.ts index f96d9e7..378634b 100644 --- a/src/meta.ts +++ b/src/meta.ts @@ -161,8 +161,20 @@ export class Meta { if (tag.attrs['value'].length > 0) { vraw = this.setGlobalExp(tag.attrs['value']); } else { - vraw = this.context.ref.replace(/^refs\/tags\//g, '').replace(/\//g, '-'); + vraw = this.context.ref.replace(/^refs\/tags\//g, ''); } + + if (tag.attrs['match'].length > 0) { + const tmatch = vraw.match(tag.attrs['match']); + if (!tmatch) { + core.warning(`${tag.attrs['match']} does not match ${vraw}.`); + } else { + vraw = this.setValue(tmatch[1], tag); + } + } + + vraw = vraw.replace(/\//g, '-'); + if (!semver.valid(vraw)) { core.warning(`${vraw} is not a valid semver. More info: https://semver.org/`); return version; diff --git a/src/tag.ts b/src/tag.ts index 2512828..4469abf 100644 --- a/src/tag.ts +++ b/src/tag.ts @@ -137,6 +137,9 @@ export function Parse(s: string): Tag { if (!Object.prototype.hasOwnProperty.call(tag.attrs, 'value')) { tag.attrs['value'] = ''; } + if (!Object.prototype.hasOwnProperty.call(tag.attrs, 'match')) { + tag.attrs['match'] = ''; + } break; } case Type.Match: {