diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a843995..ebc549a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -102,7 +102,7 @@ jobs: strategy: fail-fast: false matrix: - tag-latest: + flavor-latest: - "auto" - "true" - "false" @@ -122,10 +122,12 @@ jobs: type=ref,event=branch type=ref,event=tag type=ref,event=pr - type=semver,latest=${{ matrix.tag-latest }},pattern={{raw}} - type=semver,latest=${{ matrix.tag-latest }},pattern={{version}} - type=semver,latest=${{ matrix.tag-latest }},pattern={{major}}.{{minor}}.{{patch}} + type=semver,pattern={{raw}} + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}}.{{patch}} type=sha + flavor: | + latest=${{ matrix.flavor-latest }} label-custom: runs-on: ubuntu-latest diff --git a/__tests__/flavor.test.ts b/__tests__/flavor.test.ts new file mode 100644 index 0000000..fcd6642 --- /dev/null +++ b/__tests__/flavor.test.ts @@ -0,0 +1,115 @@ +import {Flavor, Transform} from '../src/flavor'; + +describe('transform', () => { + // prettier-ignore + test.each([ + [ + [ + `randomstr`, + `latest=auto` + ], + {} as Flavor, + true + ], + [ + [ + `unknwown=foo` + ], + {} as Flavor, + true + ], + [ + [ + `latest`, + ], + {} as Flavor, + true + ], + [ + [ + `latest=true` + ], + { + latest: "true", + prefix: "", + suffix: "" + } as Flavor, + false + ], + [ + [ + `latest=false` + ], + { + latest: "false", + prefix: "", + suffix: "" + } as Flavor, + false + ], + [ + [ + `latest=auto` + ], + { + latest: "auto", + prefix: "", + suffix: "" + } as Flavor, + false + ], + [ + [ + `latest=foo` + ], + {} as Flavor, + true + ], + [ + [ + `prefix=sha-` + ], + { + latest: "auto", + prefix: "sha-", + suffix: "" + } as Flavor, + false + ], + [ + [ + `suffix=-alpine` + ], + { + latest: "auto", + prefix: "", + suffix: "-alpine" + } as Flavor, + false + ], + [ + [ + `latest=false`, + `prefix=dev-`, + `suffix=-alpine` + ], + { + latest: "false", + prefix: "dev-", + suffix: "-alpine" + } as Flavor, + false + ], + ])('given %p attributes ', async (inputs: string[], expected: Flavor, invalid: boolean) => { + try { + const flavor = Transform(inputs); + console.log(flavor); + expect(flavor).toEqual(expected); + } catch (err) { + if (!invalid) { + console.error(err); + } + expect(true).toBe(invalid); + } + }); +}); diff --git a/__tests__/meta.test.ts b/__tests__/meta.test.ts index 9b83785..897a322 100644 --- a/__tests__/meta.test.ts +++ b/__tests__/meta.test.ts @@ -433,6 +433,36 @@ describe('push', () => { "org.opencontainers.image.licenses=MIT" ] ], + [ + 'push12', + 'event_push_invalidchars.env', + { + images: ['org/app', 'ghcr.io/user/app'], + tags: [ + `type=semver,pattern={{version}}`, + `type=edge` + ], + } as Inputs, + { + main: 'my-feature-1245', + partial: [], + latest: false + } as Version, + [ + 'org/app:my-feature-1245', + 'ghcr.io/user/app:my-feature-1245' + ], + [ + "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-feature-1245", + "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', tagsLabelsTest); }); @@ -497,7 +527,10 @@ describe('tag', () => { { images: ['user/app'], tags: [ - `type=match,latest=false,pattern=\\d{8}` + `type=match,pattern=\\d{8}` + ], + flavor: [ + `latest=false` ] } as Inputs, { @@ -525,7 +558,10 @@ describe('tag', () => { { images: ['user/app'], tags: [ - `type=match,latest=false,pattern=(.*)-RC,group=1` + `type=match,pattern=(.*)-RC,group=1` + ], + flavor: [ + `latest=false` ] } as Inputs, { @@ -834,10 +870,13 @@ describe('tag', () => { { images: ['ghcr.io/user/app'], tags: [ - `type=ref,latest=false,event=tag`, - `type=semver,latest=false,pattern={{version}}`, - `type=semver,latest=false,pattern={{major}}.{{minor}}`, - `type=semver,latest=false,pattern={{major}}` + `type=ref,event=tag`, + `type=semver,pattern={{version}}`, + `type=semver,pattern={{major}}.{{minor}}`, + `type=semver,pattern={{major}}` + ], + flavor: [ + `latest=false` ] } as Inputs, { @@ -858,7 +897,7 @@ describe('tag', () => { "org.opencontainers.image.revision=90dd6032fac8bda1b6c4436a2e65de27961ed071", "org.opencontainers.image.licenses=MIT" ] - ], + ] ])('given %p with %p event', tagsLabelsTest); }); @@ -1046,7 +1085,10 @@ describe('latest', () => { { images: ['org/app', 'ghcr.io/user/app'], tags: [ - `type=ref,latest=false,event=tag` + `type=ref,event=tag` + ], + flavor: [ + `latest=false` ] } as Inputs, { @@ -1075,7 +1117,10 @@ describe('latest', () => { { images: ['org/app', 'ghcr.io/MyUSER/MyApp'], tags: [ - `type=ref,latest=false,event=tag` + `type=ref,event=tag` + ], + flavor: [ + `latest=false` ] } as Inputs, { @@ -1104,7 +1149,10 @@ describe('latest', () => { { images: ['org/app', 'ghcr.io/MyUSER/MyApp'], tags: [ - `type=ref,latest=false,event=tag` + `type=ref,event=tag` + ], + flavor: [ + `latest=false` ], labels: [ "maintainer=CrazyMax", @@ -1374,6 +1422,38 @@ describe('schedule', () => { "org.opencontainers.image.licenses=MIT" ] ], + [ + 'schedule06', + 'event_schedule.env', + { + images: ['org/app', 'ghcr.io/user/app'], + tags: [ + `type=schedule`, + `type=sha,priority=2000` + ] + } as Inputs, + { + main: 'sha-90dd603', + partial: ['nightly'], + latest: false + } as Version, + [ + 'org/app:sha-90dd603', + 'org/app:nightly', + 'ghcr.io/user/app:sha-90dd603', + 'ghcr.io/user/app:nightly' + ], + [ + "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=sha-90dd603", + "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', tagsLabelsTest); }); @@ -1517,10 +1597,13 @@ describe('raw', () => { { images: ['user/app'], tags: [ - `type=match,latest=false,pattern=\\d{8}`, + `type=match,pattern=\\d{8}`, `type=raw,my`, `type=raw,custom`, `type=raw,tags` + ], + flavor: [ + `latest=false` ] } as Inputs, { @@ -1633,9 +1716,12 @@ describe('raw', () => { images: ['user/app'], tags: [ `type=ref,priority=90,event=branch`, - `type=raw,latest=true,my`, + `type=raw,my`, `type=raw,custom`, `type=raw,tags` + ], + flavor: [ + `latest=true` ] } as Inputs, { @@ -1787,10 +1873,13 @@ describe('bake', () => { { images: ['user/app'], tags: [ - `type=match,latest=false,pattern=\\d{8}`, + `type=match,pattern=\\d{8}`, `type=raw,my`, `type=raw,custom`, `type=raw,tags` + ], + flavor: [ + `latest=false` ] } as Inputs, { diff --git a/__tests__/tag.test.ts b/__tests__/tag.test.ts index d336d9d..299b25b 100644 --- a/__tests__/tag.test.ts +++ b/__tests__/tag.test.ts @@ -21,7 +21,6 @@ describe('transform', () => { attrs: { "priority": DefaultPriorities[Type.Schedule], "enable": "true", - "latest": "auto", "prefix": "", "suffix": "", "pattern": "nightly" @@ -32,7 +31,6 @@ describe('transform', () => { attrs: { "priority": DefaultPriorities[Type.Semver], "enable": "true", - "latest": "auto", "prefix": "", "suffix": "", "pattern": "{{version}}" @@ -43,7 +41,6 @@ describe('transform', () => { attrs: { "priority": DefaultPriorities[Type.Match], "enable": "true", - "latest": "auto", "prefix": "", "suffix": "", "pattern": "\\d{1,3}.\\d{1,3}.\\d{1,3}", @@ -55,7 +52,6 @@ describe('transform', () => { attrs: { "priority": DefaultPriorities[Type.Edge], "enable": "true", - "latest": "auto", "prefix": "", "suffix": "", "branch": "" @@ -66,7 +62,6 @@ describe('transform', () => { attrs: { "priority": DefaultPriorities[Type.Ref], "enable": "true", - "latest": "auto", "prefix": "", "suffix": "", "event": RefEvent.Branch @@ -77,7 +72,6 @@ describe('transform', () => { attrs: { "priority": DefaultPriorities[Type.Ref], "enable": "true", - "latest": "auto", "prefix": "", "suffix": "", "event": RefEvent.Tag @@ -88,7 +82,6 @@ describe('transform', () => { attrs: { "priority": DefaultPriorities[Type.Ref], "enable": "true", - "latest": "auto", "prefix": "pr-", "suffix": "", "event": RefEvent.PR @@ -99,7 +92,6 @@ describe('transform', () => { attrs: { "priority": DefaultPriorities[Type.Raw], "enable": "true", - "latest": "auto", "prefix": "", "suffix": "", "value": "foo" @@ -110,7 +102,6 @@ describe('transform', () => { attrs: { "priority": DefaultPriorities[Type.Sha], "enable": "true", - "latest": "auto", "prefix": "sha-", "suffix": "" } @@ -142,7 +133,6 @@ describe('parse', () => { attrs: { "priority": DefaultPriorities[Type.Schedule], "enable": "true", - "latest": "auto", "prefix": "", "suffix": "", "pattern": "{{date 'YYYYMMDD'}}" @@ -162,7 +152,6 @@ describe('parse', () => { attrs: { "priority": DefaultPriorities[Type.Semver], "enable": "true", - "latest": "auto", "prefix": "", "suffix": "", "pattern": "{{version}}" @@ -177,7 +166,6 @@ describe('parse', () => { attrs: { "priority": "1", "enable": "true", - "latest": "auto", "prefix": "", "suffix": "", "pattern": "{{version}}" @@ -197,7 +185,6 @@ describe('parse', () => { attrs: { "priority": DefaultPriorities[Type.Match], "enable": "true", - "latest": "auto", "prefix": "", "suffix": "", "pattern": "v(.*)", @@ -213,7 +200,6 @@ describe('parse', () => { attrs: { "priority": DefaultPriorities[Type.Match], "enable": "true", - "latest": "auto", "prefix": "", "suffix": "", "pattern": "^v(\\d{1,3}.\\d{1,3}.\\d{1,3})$", @@ -229,7 +215,6 @@ describe('parse', () => { attrs: { "priority": "700", "enable": "true", - "latest": "auto", "prefix": "", "suffix": "", "pattern": "v(.*)", @@ -250,7 +235,6 @@ describe('parse', () => { attrs: { "priority": DefaultPriorities[Type.Edge], "enable": "true", - "latest": "auto", "prefix": "", "suffix": "", "branch": "" @@ -265,7 +249,6 @@ describe('parse', () => { attrs: { "priority": DefaultPriorities[Type.Edge], "enable": "true", - "latest": "auto", "prefix": "", "suffix": "", "branch": "master" @@ -280,7 +263,6 @@ describe('parse', () => { attrs: { "priority": DefaultPriorities[Type.Ref], "enable": "true", - "latest": "auto", "prefix": "", "suffix": "", "event": RefEvent.Tag @@ -295,7 +277,6 @@ describe('parse', () => { attrs: { "priority": DefaultPriorities[Type.Ref], "enable": "true", - "latest": "auto", "prefix": "", "suffix": "", "event": RefEvent.Branch @@ -310,7 +291,6 @@ describe('parse', () => { attrs: { "priority": DefaultPriorities[Type.Ref], "enable": "true", - "latest": "auto", "prefix": "pr-", "suffix": "", "event": RefEvent.PR @@ -335,7 +315,6 @@ describe('parse', () => { attrs: { "priority": DefaultPriorities[Type.Raw], "enable": "true", - "latest": "auto", "prefix": "", "suffix": "", "value": "acustomtag" @@ -355,7 +334,6 @@ describe('parse', () => { attrs: { "priority": DefaultPriorities[Type.Raw], "enable": "true", - "latest": "auto", "prefix": "", "suffix": "", "value": "acustomtag2" @@ -370,7 +348,6 @@ describe('parse', () => { attrs: { "priority": DefaultPriorities[Type.Raw], "enable": "true", - "latest": "auto", "prefix": "", "suffix": "", "value": "acustomtag4" @@ -385,7 +362,6 @@ describe('parse', () => { attrs: { "priority": DefaultPriorities[Type.Raw], "enable": "false", - "latest": "auto", "prefix": "", "suffix": "", "value": "acustomtag5" @@ -400,7 +376,6 @@ describe('parse', () => { attrs: { "priority": DefaultPriorities[Type.Sha], "enable": "true", - "latest": "auto", "prefix": "sha-", "suffix": "" } @@ -414,7 +389,6 @@ describe('parse', () => { attrs: { "priority": DefaultPriorities[Type.Sha], "enable": "true", - "latest": "auto", "prefix": "", "suffix": "" } @@ -428,7 +402,6 @@ describe('parse', () => { attrs: { "priority": DefaultPriorities[Type.Sha], "enable": "false", - "latest": "auto", "prefix": "sha-", "suffix": "" } diff --git a/action.yml b/action.yml index 6ce2702..d7fdf12 100644 --- a/action.yml +++ b/action.yml @@ -11,7 +11,10 @@ inputs: description: 'List of Docker images to use as base name for tags' required: true tags: - description: 'List of tags as key-value pair (format: type=ref,...)' + description: 'List of tags as key-value pair attributes' + required: false + flavor: + description: 'Flavors to apply' required: false labels: description: 'List of custom labels' diff --git a/dist/index.js b/dist/index.js index 4f9a0d2..56aa382 100644 --- a/dist/index.js +++ b/dist/index.js @@ -57,6 +57,7 @@ function getInputs() { return { images: getInputList('images'), tags: getInputList('tags', true), + flavor: getInputList('flavor', true), labels: getInputList('labels', true), sepTags: core.getInput('sep-tags') || `\n`, sepLabels: core.getInput('sep-labels') || `\n`, @@ -97,6 +98,52 @@ exports.asyncForEach = (array, callback) => __awaiter(void 0, void 0, void 0, fu /***/ }), +/***/ 3716: +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.Transform = void 0; +function Transform(inputs) { + const flavor = { + latest: 'auto', + prefix: '', + suffix: '' + }; + for (const input of inputs) { + const parts = input.split('=', 2); + if (parts.length == 1) { + throw new Error(`Invalid entry: ${input}`); + } + switch (parts[0]) { + case 'latest': { + flavor.latest = parts[1]; + if (!['auto', 'true', 'false'].includes(flavor.latest)) { + throw new Error(`Invalid latest flavor entry: ${input}`); + } + break; + } + case 'prefix': { + flavor.prefix = parts[1]; + break; + } + case 'suffix': { + flavor.suffix = parts[1]; + break; + } + default: { + throw new Error(`Unknown entry: ${input}`); + } + } + } + return flavor; +} +exports.Transform = Transform; +//# sourceMappingURL=flavor.js.map + +/***/ }), + /***/ 5928: /***/ (function(__unused_webpack_module, exports, __webpack_require__) { @@ -285,6 +332,7 @@ const moment_1 = __importDefault(__webpack_require__(9623)); const semver = __importStar(__webpack_require__(1383)); const context_1 = __webpack_require__(3842); const tcl = __importStar(__webpack_require__(2829)); +const fcl = __importStar(__webpack_require__(3716)); const core = __importStar(__webpack_require__(2186)); class Meta { constructor(inputs, context, repo) { @@ -292,6 +340,7 @@ class Meta { this.context = context; this.repo = repo; this.tags = tcl.Transform(inputs.tags); + this.flavor = fcl.Transform(inputs.flavor); this.date = new Date(); this.version = this.getVersion(); } @@ -356,7 +405,7 @@ class Meta { version.partial.push(vraw); } if (version.latest == undefined) { - version.latest = tag.attrs['latest'] == 'auto' ? false : tag.attrs['latest'] == 'true'; + version.latest = this.flavor.latest == 'auto' ? false : this.flavor.latest == 'true'; } return version; } @@ -393,7 +442,7 @@ class Meta { latest = true; } if (version.latest == undefined) { - version.latest = tag.attrs['latest'] == 'auto' ? latest : tag.attrs['latest'] == 'true'; + version.latest = this.flavor.latest == 'auto' ? latest : this.flavor.latest == 'true'; } return version; } @@ -422,7 +471,7 @@ class Meta { version.partial.push(vraw); } if (version.latest == undefined) { - version.latest = tag.attrs['latest'] == 'auto' ? latest : tag.attrs['latest'] == 'true'; + version.latest = this.flavor.latest == 'auto' ? latest : this.flavor.latest == 'true'; } return version; } @@ -450,7 +499,7 @@ class Meta { version.partial.push(vraw); } if (version.latest == undefined) { - version.latest = tag.attrs['latest'] == 'auto' ? false : tag.attrs['latest'] == 'true'; + version.latest = this.flavor.latest == 'auto' ? false : this.flavor.latest == 'true'; } return version; } @@ -466,7 +515,7 @@ class Meta { version.partial.push(vraw); } if (version.latest == undefined) { - version.latest = tag.attrs['latest'] == 'auto' ? true : tag.attrs['latest'] == 'true'; + version.latest = this.flavor.latest == 'auto' ? true : this.flavor.latest == 'true'; } return version; } @@ -482,7 +531,7 @@ class Meta { version.partial.push(vraw); } if (version.latest == undefined) { - version.latest = tag.attrs['latest'] == 'auto' ? false : tag.attrs['latest'] == 'true'; + version.latest = this.flavor.latest == 'auto' ? false : this.flavor.latest == 'true'; } return version; } @@ -505,7 +554,7 @@ class Meta { version.partial.push(vraw); } if (version.latest == undefined) { - version.latest = tag.attrs['latest'] == 'auto' ? false : tag.attrs['latest'] == 'true'; + version.latest = this.flavor.latest == 'auto' ? false : this.flavor.latest == 'true'; } return version; } @@ -518,7 +567,7 @@ class Meta { version.partial.push(vraw); } if (version.latest == undefined) { - version.latest = tag.attrs['latest'] == 'auto' ? false : tag.attrs['latest'] == 'true'; + version.latest = this.flavor.latest == 'auto' ? false : this.flavor.latest == 'true'; } return version; } @@ -534,7 +583,7 @@ class Meta { version.partial.push(vraw); } if (version.latest == undefined) { - version.latest = tag.attrs['latest'] == 'auto' ? false : tag.attrs['latest'] == 'true'; + version.latest = this.flavor.latest == 'auto' ? false : this.flavor.latest == 'true'; } return version; } @@ -542,9 +591,15 @@ class Meta { if (tag.attrs['prefix'].length > 0) { val = `${tag.attrs['prefix']}${val}`; } + else if (this.flavor.prefix.length > 0) { + val = `${this.flavor.prefix}${val}`; + } if (tag.attrs['suffix'].length > 0) { val = `${val}${tag.attrs['suffix']}`; } + else if (this.flavor.suffix.length > 0) { + val = `${this.flavor.suffix}${val}`; + } return val; } getTags() { @@ -618,16 +673,16 @@ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.Parse = exports.Transform = exports.DefaultPriorities = exports.RefEvents = exports.RefEvent = exports.Type = void 0; +exports.Parse = exports.Transform = exports.DefaultPriorities = exports.RefEvent = exports.Type = void 0; const sync_1 = __importDefault(__webpack_require__(8750)); var Type; (function (Type) { - Type["Raw"] = "raw"; Type["Schedule"] = "schedule"; Type["Semver"] = "semver"; Type["Match"] = "match"; Type["Edge"] = "edge"; Type["Ref"] = "ref"; + Type["Raw"] = "raw"; Type["Sha"] = "sha"; })(Type = exports.Type || (exports.Type = {})); var RefEvent; @@ -636,7 +691,6 @@ var RefEvent; RefEvent["Tag"] = "tag"; RefEvent["PR"] = "pr"; })(RefEvent = exports.RefEvent || (exports.RefEvent = {})); -exports.RefEvents = Object.keys(RefEvent).map(key => RefEvent[key]); exports.DefaultPriorities = { [Type.Schedule]: '1000', [Type.Semver]: '900', @@ -743,7 +797,9 @@ function Parse(s) { if (!tag.attrs.hasOwnProperty('event')) { throw new Error(`Missing event attribute for ${s}`); } - if (!exports.RefEvents.includes(tag.attrs['event'])) { + if (!Object.keys(RefEvent) + .map(k => RefEvent[k]) + .includes(tag.attrs['event'])) { throw new Error(`Invalid event for ${s}`); } if (tag.attrs['event'] == RefEvent.PR && !tag.attrs.hasOwnProperty('prefix')) { @@ -770,9 +826,6 @@ function Parse(s) { if (!tag.attrs.hasOwnProperty('priority')) { tag.attrs['priority'] = exports.DefaultPriorities[tag.type]; } - if (!tag.attrs.hasOwnProperty('latest')) { - tag.attrs['latest'] = 'auto'; - } if (!tag.attrs.hasOwnProperty('prefix')) { tag.attrs['prefix'] = ''; } @@ -782,9 +835,6 @@ function Parse(s) { if (!['true', 'false'].includes(tag.attrs['enable'])) { throw new Error(`Invalid value for enable attribute: ${tag.attrs['enable']}`); } - if (!['auto', 'true', 'false'].includes(tag.attrs['latest'])) { - throw new Error(`Invalid value for latest attribute: ${tag.attrs['latest']}`); - } return tag; } exports.Parse = Parse; diff --git a/src/context.ts b/src/context.ts index 46f3147..22a6e31 100644 --- a/src/context.ts +++ b/src/context.ts @@ -9,6 +9,7 @@ let _tmpDir: string; export interface Inputs { images: string[]; tags: string[]; + flavor: string[]; labels: string[]; sepTags: string; sepLabels: string; @@ -26,6 +27,7 @@ export function getInputs(): Inputs { return { images: getInputList('images'), tags: getInputList('tags', true), + flavor: getInputList('flavor', true), labels: getInputList('labels', true), sepTags: core.getInput('sep-tags') || `\n`, sepLabels: core.getInput('sep-labels') || `\n`, diff --git a/src/flavor.ts b/src/flavor.ts new file mode 100644 index 0000000..3ae13b7 --- /dev/null +++ b/src/flavor.ts @@ -0,0 +1,42 @@ +export interface Flavor { + latest: string; + prefix: string; + suffix: string; +} + +export function Transform(inputs: string[]): Flavor { + const flavor: Flavor = { + latest: 'auto', + prefix: '', + suffix: '' + }; + + for (const input of inputs) { + const parts = input.split('=', 2); + if (parts.length == 1) { + throw new Error(`Invalid entry: ${input}`); + } + switch (parts[0]) { + case 'latest': { + flavor.latest = parts[1]; + if (!['auto', 'true', 'false'].includes(flavor.latest)) { + throw new Error(`Invalid latest flavor entry: ${input}`); + } + break; + } + case 'prefix': { + flavor.prefix = parts[1]; + break; + } + case 'suffix': { + flavor.suffix = parts[1]; + break; + } + default: { + throw new Error(`Unknown entry: ${input}`); + } + } + } + + return flavor; +} diff --git a/src/meta.ts b/src/meta.ts index 844c4e7..e8e85c3 100644 --- a/src/meta.ts +++ b/src/meta.ts @@ -5,6 +5,7 @@ import moment from 'moment'; import * as semver from 'semver'; import {Inputs, tmpDir} from './context'; import * as tcl from './tag'; +import * as fcl from './flavor'; import * as core from '@actions/core'; import {Context} from '@actions/github/lib/context'; import {ReposGetResponseData} from '@octokit/types'; @@ -22,6 +23,7 @@ export class Meta { private readonly context: Context; private readonly repo: ReposGetResponseData; private readonly tags: tcl.Tag[]; + private readonly flavor: fcl.Flavor; private readonly date: Date; constructor(inputs: Inputs, context: Context, repo: ReposGetResponseData) { @@ -29,6 +31,7 @@ export class Meta { this.context = context; this.repo = repo; this.tags = tcl.Transform(inputs.tags); + this.flavor = fcl.Transform(inputs.flavor); this.date = new Date(); this.version = this.getVersion(); } @@ -99,7 +102,7 @@ export class Meta { version.partial.push(vraw); } if (version.latest == undefined) { - version.latest = tag.attrs['latest'] == 'auto' ? false : tag.attrs['latest'] == 'true'; + version.latest = this.flavor.latest == 'auto' ? false : this.flavor.latest == 'true'; } return version; @@ -136,7 +139,7 @@ export class Meta { latest = true; } if (version.latest == undefined) { - version.latest = tag.attrs['latest'] == 'auto' ? latest : tag.attrs['latest'] == 'true'; + version.latest = this.flavor.latest == 'auto' ? latest : this.flavor.latest == 'true'; } return version; @@ -167,7 +170,7 @@ export class Meta { version.partial.push(vraw); } if (version.latest == undefined) { - version.latest = tag.attrs['latest'] == 'auto' ? latest : tag.attrs['latest'] == 'true'; + version.latest = this.flavor.latest == 'auto' ? latest : this.flavor.latest == 'true'; } return version; @@ -196,7 +199,7 @@ export class Meta { version.partial.push(vraw); } if (version.latest == undefined) { - version.latest = tag.attrs['latest'] == 'auto' ? false : tag.attrs['latest'] == 'true'; + version.latest = this.flavor.latest == 'auto' ? false : this.flavor.latest == 'true'; } return version; @@ -214,7 +217,7 @@ export class Meta { version.partial.push(vraw); } if (version.latest == undefined) { - version.latest = tag.attrs['latest'] == 'auto' ? true : tag.attrs['latest'] == 'true'; + version.latest = this.flavor.latest == 'auto' ? true : this.flavor.latest == 'true'; } return version; @@ -232,7 +235,7 @@ export class Meta { version.partial.push(vraw); } if (version.latest == undefined) { - version.latest = tag.attrs['latest'] == 'auto' ? false : tag.attrs['latest'] == 'true'; + version.latest = this.flavor.latest == 'auto' ? false : this.flavor.latest == 'true'; } return version; @@ -258,7 +261,7 @@ export class Meta { version.partial.push(vraw); } if (version.latest == undefined) { - version.latest = tag.attrs['latest'] == 'auto' ? false : tag.attrs['latest'] == 'true'; + version.latest = this.flavor.latest == 'auto' ? false : this.flavor.latest == 'true'; } return version; @@ -272,7 +275,7 @@ export class Meta { version.partial.push(vraw); } if (version.latest == undefined) { - version.latest = tag.attrs['latest'] == 'auto' ? false : tag.attrs['latest'] == 'true'; + version.latest = this.flavor.latest == 'auto' ? false : this.flavor.latest == 'true'; } return version; @@ -290,7 +293,7 @@ export class Meta { version.partial.push(vraw); } if (version.latest == undefined) { - version.latest = tag.attrs['latest'] == 'auto' ? false : tag.attrs['latest'] == 'true'; + version.latest = this.flavor.latest == 'auto' ? false : this.flavor.latest == 'true'; } return version; @@ -299,9 +302,13 @@ export class Meta { private setFlavor(val: string, tag: tcl.Tag): string { if (tag.attrs['prefix'].length > 0) { val = `${tag.attrs['prefix']}${val}`; + } else if (this.flavor.prefix.length > 0) { + val = `${this.flavor.prefix}${val}`; } if (tag.attrs['suffix'].length > 0) { val = `${val}${tag.attrs['suffix']}`; + } else if (this.flavor.suffix.length > 0) { + val = `${this.flavor.suffix}${val}`; } return val; } diff --git a/src/tag.ts b/src/tag.ts index 6b5dd59..8560146 100644 --- a/src/tag.ts +++ b/src/tag.ts @@ -1,27 +1,25 @@ import csvparse from 'csv-parse/lib/sync'; export enum Type { - Raw = 'raw', Schedule = 'schedule', Semver = 'semver', Match = 'match', Edge = 'edge', Ref = 'ref', + Raw = 'raw', Sha = 'sha' } -export interface Tag { - type: Type; - attrs: Record; -} - export enum RefEvent { Branch = 'branch', Tag = 'tag', PR = 'pr' } -export const RefEvents = Object.keys(RefEvent).map(key => RefEvent[key]); +export interface Tag { + type: Type; + attrs: Record; +} export const DefaultPriorities: Record = { [Type.Schedule]: '1000', @@ -132,7 +130,11 @@ export function Parse(s: string): Tag { if (!tag.attrs.hasOwnProperty('event')) { throw new Error(`Missing event attribute for ${s}`); } - if (!RefEvents.includes(tag.attrs['event'])) { + if ( + !Object.keys(RefEvent) + .map(k => RefEvent[k]) + .includes(tag.attrs['event']) + ) { throw new Error(`Invalid event for ${s}`); } if (tag.attrs['event'] == RefEvent.PR && !tag.attrs.hasOwnProperty('prefix')) { @@ -160,9 +162,6 @@ export function Parse(s: string): Tag { if (!tag.attrs.hasOwnProperty('priority')) { tag.attrs['priority'] = DefaultPriorities[tag.type]; } - if (!tag.attrs.hasOwnProperty('latest')) { - tag.attrs['latest'] = 'auto'; - } if (!tag.attrs.hasOwnProperty('prefix')) { tag.attrs['prefix'] = ''; } @@ -172,9 +171,6 @@ export function Parse(s: string): Tag { if (!['true', 'false'].includes(tag.attrs['enable'])) { throw new Error(`Invalid value for enable attribute: ${tag.attrs['enable']}`); } - if (!['auto', 'true', 'false'].includes(tag.attrs['latest'])) { - throw new Error(`Invalid value for latest attribute: ${tag.attrs['latest']}`); - } return tag; }