Repository: crazy-max/ghaction-docker-meta
Pull request #3 (2020-10-26 00:25:21)

Coerces Git tag to semver

codecov[bot]: # [Codecov](https://codecov.io/gh/crazy-max/ghaction-docker-meta/pull/3?src=pr&el=h1) Report
> Merging [#3](https://codecov.io/gh/crazy-max/ghaction-docker-meta/pull/3?src=pr&el=desc) into [master](https://codecov.io/gh/crazy-max/ghaction-docker-meta/commit/82966b76615b9ebafc0c4224ba837bc79d466073?el=desc) will **decrease** coverage by `1.53%`.
> The diff coverage is `71.42%`.

[![Impacted file tree graph](https://codecov.io/gh/crazy-max/ghaction-docker-meta/pull/3/graphs/tree.svg?width=650&height=150&src=pr&token=NgkCTCjmB1)](https://codecov.io/gh/crazy-max/ghaction-docker-meta/pull/3?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##           master       #3      +/-   ##
==========================================
- Coverage   72.36%   70.83%   -1.54%     
==========================================
  Files           3        3              
  Lines          76       72       -4     
  Branches       16       15       -1     
==========================================
- Hits           55       51       -4     
- Misses          5        7       +2     
+ Partials       16       14       -2     
```


| [Impacted Files](https://codecov.io/gh/crazy-max/ghaction-docker-meta/pull/3?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [src/context.ts](https://codecov.io/gh/crazy-max/ghaction-docker-meta/pull/3/diff?src=pr&el=tree#diff-c3JjL2NvbnRleHQudHM=) | `92.30% <ø> (ø)` | |
| [src/meta.ts](https://codecov.io/gh/crazy-max/ghaction-docker-meta/pull/3/diff?src=pr&el=tree#diff-c3JjL21ldGEudHM=) | `72.00% <71.42%> (-2.08%)` | :arrow_down: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/crazy-max/ghaction-docker-meta/pull/3?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/crazy-max/ghaction-docker-meta/pull/3?src=pr&el=footer). Last update [8ec02f1...25a761e](https://codecov.io/gh/crazy-max/ghaction-docker-meta/pull/3?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).


Patch:
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 7cc55c3..17f9174 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -53,6 +53,29 @@ jobs:
           tag-sha: true
           tag-schedule: ${{ matrix.tag-schedule }}
 
+  coerce:
+    runs-on: ubuntu-latest
+    strategy:
+      fail-fast: false
+      matrix:
+        tag-coerce-tag:
+          - "{{raw}}"
+          - "{{major}}.{{minor}}"
+          - "{{patch}}"
+    steps:
+      -
+        name: Checkout
+        uses: actions/checkout@v2.3.3
+      -
+        name: Docker meta
+        uses: ./
+        with:
+          images: |
+            ${{ env.DOCKER_IMAGE }}
+            ghcr.io/name/app
+          tag-coerce-tag: ${{ matrix.tag-coerce-tag }}
+          tag-sha: true
+
   docker-push:
     runs-on: ubuntu-latest
     services:
diff --git a/README.md b/README.md
index 0df9c92..e5d8747 100644
--- a/README.md
+++ b/README.md
@@ -23,6 +23,8 @@ ___
   * [inputs](#inputs)
   * [outputs](#outputs)
 * [Notes](#notes)
+  * [Latest tag](#latest-tag)
+  * [Coerces Git tag](#coerces-git-tag)
   * [Templates available for schedule tag](#templates-available-for-schedule-tag)
 * [Keep up-to-date with GitHub Dependabot](#keep-up-to-date-with-github-dependabot)
 * [How can I help?](#how-can-i-help)
@@ -114,6 +116,7 @@ Following inputs can be used as `step.with` keys
 | `tag-sha`           | Bool     | Add git short SHA as Docker tag (default `false`) |
 | `tag-edge`          | Bool     | Enable edge branch tagging (default `false`) |
 | `tag-edge-branch`   | String   | Branch that will be tagged as edge (default `repo.default_branch`) |
+| `tag-coerce-tag`    | String   | Coerces Git tag to semver if possible using [Handlebars template](https://handlebarsjs.com/guide/) |
 | `tag-schedule`      | String   | [Handlebars template](https://handlebarsjs.com/guide/) to apply to schedule tag (default `nightly`) |
 | `sep-tags`          | String   | Separator to use for tags output (default `\n`) |
 | `sep-labels`        | String   | Separator to use for labels output (default `\n`) |
@@ -132,6 +135,27 @@ Following outputs are available
 
 ## Notes
 
+### Latest tag
+
+`latest` tag is created only on `push tag` event and resolves one of the following conditions:
+
+* Git tag is a valid [semver](https://semver.org/)
+* Provided `tag-coerce-tag` is valid
+
+### Coerces Git tag
+
+Provides a very forgiving translation of a non-semver tag to semver. For more information see
+[Coercion section](https://www.npmjs.com/package/semver#coercion). `tag-coerce-tag` supports
+[Handlebars template](https://handlebarsjs.com/guide/) with the following inputs:
+
+| `tag-coerce-tag`        | Git tag  | Version |
+|-------------------------|----------|---------|
+| `{{raw}}`               | `v1.2.3` | `1.2.3` |
+| `{{major}}.{{minor}}`   | `v1.2.3` | `1.2`   |
+| `{{major}}`             | `v1.2.3` | `1`     |
+| `{{minor}}`             | `v1.2.3` | `2`     |
+| `{{patch}}`             | `v1.2.3` | `3`     |
+
 ### Templates available for schedule tag
 
 `tag-schedule` is specially crafted input to support [Handlebars template](https://handlebarsjs.com/guide/) with
diff --git a/action.yml b/action.yml
index 1b3d523..973f8ba 100644
--- a/action.yml
+++ b/action.yml
@@ -21,6 +21,9 @@ inputs:
   tag-edge-branch:
     description: 'Branch that will be tagged as edge (default repo.default_branch)'
     required: false
+  tag-coerce-tag:
+    description: 'Coerces Git tag to semver if possible using Handlebars template'
+    required: false
   tag-schedule:
     description: 'Handlebars template to apply to schedule tag'
     default: 'nightly'
diff --git a/dist/index.js b/dist/index.js
index de6f95d..2b34e4a 100644
--- a/dist/index.js
+++ b/dist/index.js
@@ -25,6 +25,7 @@ function getInputs() {
         tagSha: /true/i.test(core.getInput('tag-sha') || 'false'),
         tagEdge: /true/i.test(core.getInput('tag-edge') || 'false'),
         tagEdgeBranch: core.getInput('tag-edge-branch'),
+        tagCoerceTag: core.getInput('tag-coerce-tag'),
         tagSchedule: core.getInput('tag-schedule') || 'nightly',
         sepTags: core.getInput('sep-tags') || `\n`,
         sepLabels: core.getInput('sep-labels') || `\n`,
@@ -129,9 +130,9 @@ function run() {
             const meta = new meta_1.Meta(inputs, context, repo);
             const version = meta.version();
             core.startGroup(`Docker image version`);
-            core.info(`${version}`);
+            core.info(version.version || '');
             core.endGroup();
-            core.setOutput('version', version || '');
+            core.setOutput('version', version.version || '');
             const tags = meta.tags();
             core.startGroup(`Docker tags`);
             for (let tag of tags) {
@@ -167,7 +168,6 @@ exports.Meta = void 0;
 const handlebars = __webpack_require__(7492);
 const moment = __webpack_require__(9623);
 const semver = __webpack_require__(1383);
-const core = __webpack_require__(2186);
 class Meta {
     constructor(inputs, context, repo) {
         this.inputs = inputs;
@@ -179,40 +179,64 @@ class Meta {
         this.date = new Date();
     }
     version() {
+        const currentDate = this.date;
+        const version = {
+            version: undefined,
+            latest: false
+        };
         if (/schedule/.test(this.context.eventName)) {
-            return handlebars.compile(this.inputs.tagSchedule)(this.scheduleTplContext());
+            version.version = handlebars.compile(this.inputs.tagSchedule)({
+                date: function (format) {
+                    return moment(currentDate).utc().format(format);
+                }
+            });
         }
         else if (/^refs\/tags\//.test(this.context.ref)) {
             const tag = this.context.ref.replace(/^refs\/tags\//g, '').replace(/\//g, '-');
             const sver = semver.clean(tag);
-            return sver ? sver : tag;
+            if (this.inputs.tagCoerceTag) {
+                const coerce = semver.coerce(tag);
+                if (coerce) {
+                    version.version = handlebars.compile(this.inputs.tagCoerceTag)(coerce);
+                    version.latest = true;
+                }
+                else if (sver) {
+                    version.version = sver;
+                    version.latest = true;
+                }
+                else {
+                    version.version = tag;
+                }
+            }
+            else if (sver) {
+                version.version = sver;
+                version.latest = true;
+            }
+            else {
+                version.version = tag;
+            }
         }
         else if (/^refs\/heads\//.test(this.context.ref)) {
-            const branch = this.context.ref.replace(/^refs\/heads\//g, '').replace(/\//g, '-');
-            return this.inputs.tagEdge && this.inputs.tagEdgeBranch === branch ? 'edge' : branch;
+            version.version = this.context.ref.replace(/^refs\/heads\//g, '').replace(/\//g, '-');
+            if (this.inputs.tagEdge && this.inputs.tagEdgeBranch === version.version) {
+                version.version = 'edge';
+            }
         }
         else if (/^refs\/pull\//.test(this.context.ref)) {
-            const pr = this.context.ref.replace(/^refs\/pull\//g, '').replace(/\/merge$/g, '');
-            return `pr-${pr}`;
+            version.version = `pr-${this.context.ref.replace(/^refs\/pull\//g, '').replace(/\/merge$/g, '')}`;
         }
+        return version;
     }
     tags() {
+        const version = this.version();
+        if (!version.version) {
+            return [];
+        }
         let tags = [];
         for (const image of this.inputs.images) {
-            if (/schedule/.test(this.context.eventName)) {
-                tags.push.apply(tags, this.eventSchedule(image));
-            }
-            else if (/^refs\/tags\//.test(this.context.ref)) {
-                tags.push.apply(tags, this.eventTag(image));
-            }
-            else if (/^refs\/heads\//.test(this.context.ref)) {
-                tags.push.apply(tags, this.eventBranch(image));
-            }
-            else if (/^refs\/pull\//.test(this.context.ref)) {
-                tags.push.apply(tags, this.eventPullRequest(image));
-            }
-            else {
-                core.warning(`Unknown event "${this.context.eventName}" with ref "${this.context.ref}"`);
+            tags.push(`${image}:${version.version}`);
+            if (version.latest) {
+                tags.push(`${image}:latest`);
             }
             if (this.context.sha && this.inputs.tagSha) {
                 tags.push(`${image}:sha-${this.context.sha.substr(0, 7)}`);
@@ -227,43 +251,12 @@ class Meta {
             `org.opencontainers.image.description=${this.repo.description || ''}`,
             `org.opencontainers.image.url=${this.repo.html_url || ''}`,
             `org.opencontainers.image.source=${this.repo.clone_url || ''}`,
-            `org.opencontainers.image.version=${this.version() || ''}`,
+            `org.opencontainers.image.version=${this.version().version || ''}`,
             `org.opencontainers.image.created=${this.date.toISOString()}`,
             `org.opencontainers.image.revision=${this.context.sha || ''}`,
             `org.opencontainers.image.licenses=${((_a = this.repo.license) === null || _a === void 0 ? void 0 : _a.spdx_id) || ''}`
         ];
     }
-    eventSchedule(image) {
-        const schedule = handlebars.compile(this.inputs.tagSchedule)(this.scheduleTplContext());
-        return [`${image}:${schedule}`];
-    }
-    eventTag(image) {
-        const tag = this.context.ref.replace(/^refs\/tags\//g, '').replace(/\//g, '-');
-        const version = semver.clean(tag);
-        if (version) {
-            return [`${image}:${version}`, `${image}:latest`];
-        }
-        return [`${image}:${tag}`];
-    }
-    eventBranch(image) {
-        const branch = this.context.ref.replace(/^refs\/heads\//g, '').replace(/\//g, '-');
-        if (this.inputs.tagEdge && this.inputs.tagEdgeBranch === branch) {
-            return [`${image}:edge`];
-        }
-        return [`${image}:${branch}`];
-    }
-    eventPullRequest(image) {
-        const pr = this.context.ref.replace(/^refs\/pull\//g, '').replace(/\/merge$/g, '');
-        return [`${image}:pr-${pr}`];
-    }
-    scheduleTplContext() {
-        const currentDate = this.date;
-        return {
-            date: function (format) {
-                return moment(currentDate).utc().format(format);
-            }
-        };
-    }
 }
 exports.Meta = Meta;
 //# sourceMappingURL=meta.js.map
diff --git a/src/context.ts b/src/context.ts
index 805e840..fcc39f4 100644
--- a/src/context.ts
+++ b/src/context.ts
@@ -5,6 +5,7 @@ export interface Inputs {
   tagSha: boolean;
   tagEdge: boolean;
   tagEdgeBranch: string;
+  tagCoerceTag: string;
   tagSchedule: string;
   sepTags: string;
   sepLabels: string;
@@ -17,6 +18,7 @@ export function getInputs(): Inputs {
     tagSha: /true/i.test(core.getInput('tag-sha') || 'false'),
     tagEdge: /true/i.test(core.getInput('tag-edge') || 'false'),
     tagEdgeBranch: core.getInput('tag-edge-branch'),
+    tagCoerceTag: core.getInput('tag-coerce-tag'),
     tagSchedule: core.getInput('tag-schedule') || 'nightly',
     sepTags: core.getInput('sep-tags') || `\n`,
     sepLabels: core.getInput('sep-labels') || `\n`,
diff --git a/src/main.ts b/src/main.ts
index b03187c..692ef21 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -1,6 +1,6 @@
 import {getInputs, Inputs} from './context';
 import * as github from './github';
-import {Meta} from './meta';
+import {Meta, Version} from './meta';
 import * as core from '@actions/core';
 import {Context} from '@actions/github/lib/context';
 import {ReposGetResponseData} from '@octokit/types';
@@ -27,11 +27,11 @@ async function run() {
 
     const meta: Meta = new Meta(inputs, context, repo);
 
-    const version: string | undefined = meta.version();
+    const version: Version = meta.version();
     core.startGroup(`Docker image version`);
-    core.info(`${version}`);
+    core.info(version.version || '');
     core.endGroup();
-    core.setOutput('version', version || '');
+    core.setOutput('version', version.version || '');
 
     const tags: Array<string> = meta.tags();
     core.startGroup(`Docker tags`);
diff --git a/src/meta.ts b/src/meta.ts
index 4904394..c8bb127 100644
--- a/src/meta.ts
+++ b/src/meta.ts
@@ -2,10 +2,14 @@ import * as handlebars from 'handlebars';
 import * as moment from 'moment';
 import * as semver from 'semver';
 import {Inputs} from './context';
-import * as core from '@actions/core';
 import {Context} from '@actions/github/lib/context';
 import {ReposGetResponseData} from '@octokit/types';
 
+export interface Version {
+  version: string | undefined;
+  latest: boolean;
+}
+
 export class Meta {
   private readonly inputs: Inputs;
   private readonly context: Context;
@@ -22,35 +26,62 @@ export class Meta {
     this.date = new Date();
   }
 
-  public version(): string | undefined {
+  public version(): Version {
+    const currentDate = this.date;
+    const version: Version = {
+      version: undefined,
+      latest: false
+    };
+
     if (/schedule/.test(this.context.eventName)) {
-      return handlebars.compile(this.inputs.tagSchedule)(this.scheduleTplContext());
+      version.version = handlebars.compile(this.inputs.tagSchedule)({
+        date: function (format) {
+          return moment(currentDate).utc().format(format);
+        }
+      });
     } else if (/^refs\/tags\//.test(this.context.ref)) {
       const tag = this.context.ref.replace(/^refs\/tags\//g, '').replace(/\//g, '-');
       const sver = semver.clean(tag);
-      return sver ? sver : tag;
+      if (this.inputs.tagCoerceTag) {
+        const coerce = semver.coerce(tag);
+        if (coerce) {
+          version.version = handlebars.compile(this.inputs.tagCoerceTag)(coerce);
+          version.latest = true;
+        } else if (sver) {
+          version.version = sver;
+          version.latest = true;
+        } else {
+          version.version = tag;
+        }
+      } else if (sver) {
+        version.version = sver;
+        version.latest = true;
+      } else {
+        version.version = tag;
+      }
     } else if (/^refs\/heads\//.test(this.context.ref)) {
-      const branch = this.context.ref.replace(/^refs\/heads\//g, '').replace(/\//g, '-');
-      return this.inputs.tagEdge && this.inputs.tagEdgeBranch === branch ? 'edge' : branch;
+      version.version = this.context.ref.replace(/^refs\/heads\//g, '').replace(/\//g, '-');
+      if (this.inputs.tagEdge && this.inputs.tagEdgeBranch === version.version) {
+        version.version = 'edge';
+      }
     } else if (/^refs\/pull\//.test(this.context.ref)) {
-      const pr = this.context.ref.replace(/^refs\/pull\//g, '').replace(/\/merge$/g, '');
-      return `pr-${pr}`;
+      version.version = `pr-${this.context.ref.replace(/^refs\/pull\//g, '').replace(/\/merge$/g, '')}`;
     }
+
+    return version;
   }
 
   public tags(): Array<string> {
+    const version: Version = this.version();
+    if (!version.version) {
+      return [];
+    }
+
     let tags: Array<string> = [];
     for (const image of this.inputs.images) {
-      if (/schedule/.test(this.context.eventName)) {
-        tags.push.apply(tags, this.eventSchedule(image));
-      } else if (/^refs\/tags\//.test(this.context.ref)) {
-        tags.push.apply(tags, this.eventTag(image));
-      } else if (/^refs\/heads\//.test(this.context.ref)) {
-        tags.push.apply(tags, this.eventBranch(image));
-      } else if (/^refs\/pull\//.test(this.context.ref)) {
-        tags.push.apply(tags, this.eventPullRequest(image));
-      } else {
-        core.warning(`Unknown event "${this.context.eventName}" with ref "${this.context.ref}"`);
+      tags.push(`${image}:${version.version}`);
+      if (version.latest) {
+        tags.push(`${image}:latest`);
       }
       if (this.context.sha && this.inputs.tagSha) {
         tags.push(`${image}:sha-${this.context.sha.substr(0, 7)}`);
@@ -65,46 +96,10 @@ export class Meta {
       `org.opencontainers.image.description=${this.repo.description || ''}`,
       `org.opencontainers.image.url=${this.repo.html_url || ''}`,
       `org.opencontainers.image.source=${this.repo.clone_url || ''}`,
-      `org.opencontainers.image.version=${this.version() || ''}`,
+      `org.opencontainers.image.version=${this.version().version || ''}`,
       `org.opencontainers.image.created=${this.date.toISOString()}`,
       `org.opencontainers.image.revision=${this.context.sha || ''}`,
       `org.opencontainers.image.licenses=${this.repo.license?.spdx_id || ''}`
     ];
   }
-
-  private eventSchedule(image: string): Array<string> {
-    const schedule = handlebars.compile(this.inputs.tagSchedule)(this.scheduleTplContext());
-    return [`${image}:${schedule}`];
-  }
-
-  private eventTag(image: string): Array<string> {
-    const tag = this.context.ref.replace(/^refs\/tags\//g, '').replace(/\//g, '-');
-    const version = semver.clean(tag);
-    if (version) {
-      return [`${image}:${version}`, `${image}:latest`];
-    }
-    return [`${image}:${tag}`];
-  }
-
-  private eventBranch(image: string): Array<string> {
-    const branch = this.context.ref.replace(/^refs\/heads\//g, '').replace(/\//g, '-');
-    if (this.inputs.tagEdge && this.inputs.tagEdgeBranch === branch) {
-      return [`${image}:edge`];
-    }
-    return [`${image}:${branch}`];
-  }
-
-  private eventPullRequest(image: string): Array<string> {
-    const pr = this.context.ref.replace(/^refs\/pull\//g, '').replace(/\/merge$/g, '');
-    return [`${image}:pr-${pr}`];
-  }
-
-  private scheduleTplContext(): any {
-    const currentDate = this.date;
-    return {
-      date: function (format) {
-        return moment(currentDate).utc().format(format);
-      }
-    };
-  }
 }


Test patch:
diff --git a/__tests__/fixtures/event_tag_20200110-RC2.env b/__tests__/fixtures/event_tag_20200110-RC2.env
new file mode 100644
index 0000000..3e2a425
--- /dev/null
+++ b/__tests__/fixtures/event_tag_20200110-RC2.env
@@ -0,0 +1,23 @@
+GITHUB_ACTION=crazy-maxghaction-dump-context
+GITHUB_ACTIONS=true
+GITHUB_ACTION_PATH=/home/runner/work/_actions/crazy-max/ghaction-dump-context/v1
+GITHUB_ACTOR=crazy-max
+GITHUB_API_URL=https://api.github.com
+GITHUB_BASE_REF=
+GITHUB_ENV=/home/runner/work/_temp/_runner_file_commands/set_env_6ee180c2-b331-434a-a867-89534cbefd83
+GITHUB_EVENT_NAME=push
+#GITHUB_EVENT_PATH=/home/runner/work/_temp/_github_workflow/event.json
+GITHUB_GRAPHQL_URL=https://api.github.com/graphql
+GITHUB_HEAD_REF=
+GITHUB_JOB=event
+GITHUB_PATH=/home/runner/work/_temp/_runner_file_commands/add_path_6ee180c2-b331-434a-a867-89534cbefd83
+GITHUB_REF=refs/tags/20200110-RC2
+GITHUB_REPOSITORY=crazy-max/test-docker-action
+GITHUB_REPOSITORY_OWNER=crazy-max
+GITHUB_RETENTION_DAYS=90
+GITHUB_RUN_ID=325968230
+GITHUB_RUN_NUMBER=4
+GITHUB_SERVER_URL=https://github.com
+GITHUB_SHA=90dd6032fac8bda1b6c4436a2e65de27961ed071
+GITHUB_WORKFLOW=event
+GITHUB_WORKSPACE=/home/runner/work/test-docker-action/test-docker-action
diff --git a/__tests__/fixtures/event_tag.env b/__tests__/fixtures/event_tag_release1.env
similarity index 100%
rename from __tests__/fixtures/event_tag.env
rename to __tests__/fixtures/event_tag_release1.env
diff --git a/__tests__/fixtures/event_tag_sometag.env b/__tests__/fixtures/event_tag_sometag.env
new file mode 100644
index 0000000..2001bce
--- /dev/null
+++ b/__tests__/fixtures/event_tag_sometag.env
@@ -0,0 +1,23 @@
+GITHUB_ACTION=crazy-maxghaction-dump-context
+GITHUB_ACTIONS=true
+GITHUB_ACTION_PATH=/home/runner/work/_actions/crazy-max/ghaction-dump-context/v1
+GITHUB_ACTOR=crazy-max
+GITHUB_API_URL=https://api.github.com
+GITHUB_BASE_REF=
+GITHUB_ENV=/home/runner/work/_temp/_runner_file_commands/set_env_6ee180c2-b331-434a-a867-89534cbefd83
+GITHUB_EVENT_NAME=push
+#GITHUB_EVENT_PATH=/home/runner/work/_temp/_github_workflow/event.json
+GITHUB_GRAPHQL_URL=https://api.github.com/graphql
+GITHUB_HEAD_REF=
+GITHUB_JOB=event
+GITHUB_PATH=/home/runner/work/_temp/_runner_file_commands/add_path_6ee180c2-b331-434a-a867-89534cbefd83
+GITHUB_REF=refs/tags/sometag
+GITHUB_REPOSITORY=crazy-max/test-docker-action
+GITHUB_REPOSITORY_OWNER=crazy-max
+GITHUB_RETENTION_DAYS=90
+GITHUB_RUN_ID=325968230
+GITHUB_RUN_NUMBER=4
+GITHUB_SERVER_URL=https://github.com
+GITHUB_SHA=90dd6032fac8bda1b6c4436a2e65de27961ed071
+GITHUB_WORKFLOW=event
+GITHUB_WORKSPACE=/home/runner/work/test-docker-action/test-docker-action
diff --git a/__tests__/fixtures/event_tag_semver.env b/__tests__/fixtures/event_tag_v1.1.1.env
similarity index 100%
rename from __tests__/fixtures/event_tag_semver.env
rename to __tests__/fixtures/event_tag_v1.1.1.env
diff --git a/__tests__/fixtures/event_tag_v2.0.8-beta.67.env b/__tests__/fixtures/event_tag_v2.0.8-beta.67.env
new file mode 100644
index 0000000..2bd31bb
--- /dev/null
+++ b/__tests__/fixtures/event_tag_v2.0.8-beta.67.env
@@ -0,0 +1,23 @@
+GITHUB_ACTION=crazy-maxghaction-dump-context
+GITHUB_ACTIONS=true
+GITHUB_ACTION_PATH=/home/runner/work/_actions/crazy-max/ghaction-dump-context/v1
+GITHUB_ACTOR=crazy-max
+GITHUB_API_URL=https://api.github.com
+GITHUB_BASE_REF=
+GITHUB_ENV=/home/runner/work/_temp/_runner_file_commands/set_env_6ee180c2-b331-434a-a867-89534cbefd83
+GITHUB_EVENT_NAME=push
+#GITHUB_EVENT_PATH=/home/runner/work/_temp/_github_workflow/event.json
+GITHUB_GRAPHQL_URL=https://api.github.com/graphql
+GITHUB_HEAD_REF=
+GITHUB_JOB=event
+GITHUB_PATH=/home/runner/work/_temp/_runner_file_commands/add_path_6ee180c2-b331-434a-a867-89534cbefd83
+GITHUB_REF=refs/tags/v2.0.8-beta.67
+GITHUB_REPOSITORY=crazy-max/test-docker-action
+GITHUB_REPOSITORY_OWNER=crazy-max
+GITHUB_RETENTION_DAYS=90
+GITHUB_RUN_ID=325968230
+GITHUB_RUN_NUMBER=4
+GITHUB_SERVER_URL=https://github.com
+GITHUB_SHA=90dd6032fac8bda1b6c4436a2e65de27961ed071
+GITHUB_WORKFLOW=event
+GITHUB_WORKSPACE=/home/runner/work/test-docker-action/test-docker-action
diff --git a/__tests__/meta.test.ts b/__tests__/meta.test.ts
index 6411922..6ea0f5b 100644
--- a/__tests__/meta.test.ts
+++ b/__tests__/meta.test.ts
@@ -4,7 +4,7 @@ import * as dotenv from 'dotenv';
 import * as moment from 'moment';
 import {getInputs, Inputs} from '../src/context';
 import * as github from '../src/github';
-import {Meta} from '../src/meta';
+import {Meta, Version} from '../src/meta';
 import {Context} from '@actions/github/lib/context';
 import {ReposGetResponseData} from '@octokit/types';
 
@@ -28,15 +28,36 @@ jest.mock('moment', () => {
   return () => jest.requireActual('moment')('2020-01-10T00:30:00.000Z');
 });
 
-describe('tags and labels', () => {
-  beforeEach(() => {
-    Object.keys(process.env).forEach(function (key) {
-      if (key !== 'GITHUB_TOKEN' && key.startsWith('GITHUB_')) {
-        delete process.env[key];
-      }
-    });
+beforeEach(() => {
+  Object.keys(process.env).forEach(function (key) {
+    if (key !== 'GITHUB_TOKEN' && key.startsWith('GITHUB_')) {
+      delete process.env[key];
+    }
   });
+});
+
+const tagsLabelsTest = async (envFile: string, inputs: Inputs, exVersion: Version, exTags: Array<string>, exLabels: Array<string>) => {
+  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 version = meta.version();
+  console.log('version', version);
+  expect(version).toEqual(exVersion);
+
+  const tags = meta.tags();
+  console.log('tags', tags);
+  expect(tags).toEqual(exTags);
+
+  const labels = meta.labels();
+  console.log('labels', labels);
+  expect(labels).toEqual(exLabels);
+};
 
+describe('null', () => {
   // prettier-ignore
   test.each([
     [
@@ -44,7 +65,10 @@ describe('tags and labels', () => {
       {
         images: ['user/app'],
       } as Inputs,
-      undefined,
+      {
+        version: undefined,
+        latest: false
+      } as Version,
       [],
       [
         "org.opencontainers.image.title=Hello-World",
@@ -62,7 +86,10 @@ describe('tags and labels', () => {
       {
         images: ['user/app'],
       } as Inputs,
-      undefined,
+      {
+        version: undefined,
+        latest: false
+      } as Version,
       [],
       [
         "org.opencontainers.image.title=Hello-World",
@@ -75,41 +102,54 @@ describe('tags and labels', () => {
         "org.opencontainers.image.licenses=MIT"
       ]
     ],
+  ])('given %p event ', tagsLabelsTest);
+});
+
+describe('push', () => {
+  // prettier-ignore
+  test.each([
     [
-      'event_pull_request.env',
+      'event_push.env',
       {
         images: ['user/app'],
       } as Inputs,
-      'pr-2',
+      {
+        version: 'dev',
+        latest: false
+      } as Version,
       [
-        'user/app:pr-2'
+        'user/app:dev'
       ],
       [
         "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.git",
-        "org.opencontainers.image.version=pr-2",
+        "org.opencontainers.image.version=dev",
         "org.opencontainers.image.created=2020-01-10T00:30:00.000Z",
-        "org.opencontainers.image.revision=1e9249f05bfc090e0688b8fb9c1b347586add504",
+        "org.opencontainers.image.revision=90dd6032fac8bda1b6c4436a2e65de27961ed071",
         "org.opencontainers.image.licenses=MIT"
       ]
     ],
     [
-      'event_push.env',
+      'event_push_defbranch.env',
       {
         images: ['user/app'],
+        tagEdge: true,
       } as Inputs,
-      'dev',
+      {
+        version: 'edge',
+        latest: false
+      } as Version,
       [
-        'user/app:dev'
+        'user/app:edge'
       ],
       [
         "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.git",
-        "org.opencontainers.image.version=dev",
+        "org.opencontainers.image.version=edge",
         "org.opencontainers.image.created=2020-01-10T00:30:00.000Z",
         "org.opencontainers.image.revision=90dd6032fac8bda1b6c4436a2e65de27961ed071",
         "org.opencontainers.image.licenses=MIT"
@@ -117,11 +157,37 @@ describe('tags and labels', () => {
     ],
     [
       'event_push_defbranch.env',
+      {
+        images: ['user/app'],
+      } as Inputs,
+      {
+        version: 'master',
+        latest: false
+      } as Version,
+      [
+        'user/app:master'
+      ],
+      [
+        "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.git",
+        "org.opencontainers.image.version=master",
+        "org.opencontainers.image.created=2020-01-10T00:30:00.000Z",
+        "org.opencontainers.image.revision=90dd6032fac8bda1b6c4436a2e65de27961ed071",
+        "org.opencontainers.image.licenses=MIT"
+      ]
+    ],
+    [
+      'event_workflow_dispatch.env',
       {
         images: ['user/app'],
         tagEdge: true,
       } as Inputs,
-      'edge',
+      {
+        version: 'edge',
+        latest: false
+      } as Version,
       [
         'user/app:edge'
       ],
@@ -136,115 +202,183 @@ describe('tags and labels', () => {
         "org.opencontainers.image.licenses=MIT"
       ]
     ],
+    [
+      'event_push.env',
+      {
+        images: ['org/app', 'ghcr.io/user/app'],
+      } as Inputs,
+      {
+        version: 'dev',
+        latest: false
+      } as Version,
+      [
+        'org/app:dev',
+        'ghcr.io/user/app:dev'
+      ],
+      [
+        "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.git",
+        "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_defbranch.env',
       {
-        images: ['user/app'],
+        images: ['org/app', 'ghcr.io/user/app'],
+        tagEdge: true,
       } as Inputs,
-      'master',
+      {
+        version: 'edge',
+        latest: false
+      } as Version,
       [
-        'user/app:master'
+        'org/app:edge',
+        'ghcr.io/user/app:edge'
       ],
       [
         "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.git",
-        "org.opencontainers.image.version=master",
+        "org.opencontainers.image.version=edge",
         "org.opencontainers.image.created=2020-01-10T00:30:00.000Z",
         "org.opencontainers.image.revision=90dd6032fac8bda1b6c4436a2e65de27961ed071",
         "org.opencontainers.image.licenses=MIT"
       ]
     ],
     [
-      'event_release.env',
+      'event_push.env',
       {
-        images: ['user/app'],
+        images: ['org/app', 'ghcr.io/user/app'],
+        tagSha: true,
       } as Inputs,
-      '1.1.1',
+      {
+        version: 'dev',
+        latest: false
+      } as Version,
       [
-        'user/app:1.1.1',
-        'user/app:latest'
+        'org/app:dev',
+        'org/app:sha-90dd603',
+        'ghcr.io/user/app:dev',
+        'ghcr.io/user/app:sha-90dd603'
       ],
       [
         "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.git",
-        "org.opencontainers.image.version=1.1.1",
+        "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_schedule.env',
+      'event_push_defbranch.env',
       {
-        images: ['user/app'],
+        images: ['org/app', 'ghcr.io/user/app'],
+        tagSha: true,
+        tagEdge: true,
       } as Inputs,
-      'nightly',
+      {
+        version: 'edge',
+        latest: false
+      } as Version,
       [
-        'user/app:nightly'
+        'org/app:edge',
+        'org/app:sha-90dd603',
+        'ghcr.io/user/app:edge',
+        'ghcr.io/user/app:sha-90dd603'
       ],
       [
         "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.git",
-        "org.opencontainers.image.version=nightly",
+        "org.opencontainers.image.version=edge",
         "org.opencontainers.image.created=2020-01-10T00:30:00.000Z",
         "org.opencontainers.image.revision=90dd6032fac8bda1b6c4436a2e65de27961ed071",
         "org.opencontainers.image.licenses=MIT"
       ]
     ],
     [
-      'event_schedule.env',
+      'event_push.env',
       {
-        images: ['user/app'],
-        tagSchedule: `{{date 'YYYYMMDD'}}`
+        images: ['org/app', 'ghcr.io/user/app'],
+        tagSha: true,
+        tagEdge: true,
+        tagEdgeBranch: 'dev'
       } as Inputs,
-      '20200110',
+      {
+        version: 'edge',
+        latest: false
+      } as Version,
       [
-        'user/app:20200110'
+        'org/app:edge',
+        'org/app:sha-90dd603',
+        'ghcr.io/user/app:edge',
+        'ghcr.io/user/app:sha-90dd603'
       ],
       [
         "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.git",
-        "org.opencontainers.image.version=20200110",
+        "org.opencontainers.image.version=edge",
         "org.opencontainers.image.created=2020-01-10T00:30:00.000Z",
         "org.opencontainers.image.revision=90dd6032fac8bda1b6c4436a2e65de27961ed071",
         "org.opencontainers.image.licenses=MIT"
       ]
     ],
     [
-      'event_schedule.env',
+      'event_push_defbranch.env',
       {
-        images: ['user/app'],
-        tagSchedule: `{{date 'YYYYMMDD-HHmmss'}}`
+        images: ['org/app', 'ghcr.io/user/app'],
+        tagSha: true,
+        tagEdge: true,
+        tagEdgeBranch: 'dev'
       } as Inputs,
-      '20200110-003000',
+      {
+        version: 'master',
+        latest: false
+      } as Version,
       [
-        'user/app:20200110-003000'
+        'org/app:master',
+        'org/app:sha-90dd603',
+        'ghcr.io/user/app:master',
+        'ghcr.io/user/app:sha-90dd603'
       ],
       [
         "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.git",
-        "org.opencontainers.image.version=20200110-003000",
+        "org.opencontainers.image.version=master",
         "org.opencontainers.image.created=2020-01-10T00:30:00.000Z",
         "org.opencontainers.image.revision=90dd6032fac8bda1b6c4436a2e65de27961ed071",
         "org.opencontainers.image.licenses=MIT"
       ]
     ],
+  ])('given %p event ', tagsLabelsTest);
+});
+
+describe('push tag', () => {
+  // prettier-ignore
+  test.each([
     [
-      'event_tag.env',
+      'event_tag_release1.env',
       {
         images: ['user/app'],
       } as Inputs,
-      'release1',
+      {
+        version: 'release1',
+        latest: false
+      } as Version,
       [
         'user/app:release1'
       ],
@@ -260,142 +394,172 @@ describe('tags and labels', () => {
       ]
     ],
     [
-      'event_tag_semver.env',
+      'event_tag_20200110-RC2.env',
       {
         images: ['user/app'],
       } as Inputs,
-      '1.1.1',
+      {
+        version: '20200110-RC2',
+        latest: false
+      } as Version,
       [
-        'user/app:1.1.1',
-        'user/app:latest'
+        'user/app:20200110-RC2'
       ],
       [
         "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.git",
-        "org.opencontainers.image.version=1.1.1",
+        "org.opencontainers.image.version=20200110-RC2",
         "org.opencontainers.image.created=2020-01-10T00:30:00.000Z",
         "org.opencontainers.image.revision=90dd6032fac8bda1b6c4436a2e65de27961ed071",
         "org.opencontainers.image.licenses=MIT"
       ]
     ],
     [
-      'event_workflow_dispatch.env',
+      'event_tag_20200110-RC2.env',
       {
         images: ['user/app'],
-        tagEdge: true,
+        tagCoerceTag: '{{major}}',
       } as Inputs,
-      'edge',
+      {
+        version: '20200110',
+        latest: true
+      } as Version,
       [
-        'user/app:edge'
+        'user/app:20200110',
+        '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.git",
-        "org.opencontainers.image.version=edge",
+        "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_pull_request.env',
+      'event_tag_v1.1.1.env',
       {
-        images: ['org/app', 'ghcr.io/user/app'],
+        images: ['user/app'],
       } as Inputs,
-      'pr-2',
+      {
+        version: '1.1.1',
+        latest: true
+      } as Version,
       [
-        'org/app:pr-2',
-        'ghcr.io/user/app:pr-2'
+        'user/app:1.1.1',
+        '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.git",
-        "org.opencontainers.image.version=pr-2",
+        "org.opencontainers.image.version=1.1.1",
         "org.opencontainers.image.created=2020-01-10T00:30:00.000Z",
-        "org.opencontainers.image.revision=1e9249f05bfc090e0688b8fb9c1b347586add504",
+        "org.opencontainers.image.revision=90dd6032fac8bda1b6c4436a2e65de27961ed071",
         "org.opencontainers.image.licenses=MIT"
       ]
     ],
     [
-      'event_push.env',
+      'event_tag_v1.1.1.env',
       {
         images: ['org/app', 'ghcr.io/user/app'],
       } as Inputs,
-      'dev',
+      {
+        version: '1.1.1',
+        latest: true
+      } as Version,
       [
-        'org/app:dev',
-        'ghcr.io/user/app:dev'
+        'org/app:1.1.1',
+        'org/app:latest',
+        'ghcr.io/user/app:1.1.1',
+        '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.git",
-        "org.opencontainers.image.version=dev",
+        "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_push_defbranch.env',
+      'event_tag_v1.1.1.env',
       {
         images: ['org/app', 'ghcr.io/user/app'],
-        tagEdge: true,
+        tagSha: true,
       } as Inputs,
-      'edge',
+      {
+        version: '1.1.1',
+        latest: true
+      } as Version,
       [
-        'org/app:edge',
-        'ghcr.io/user/app:edge'
+        'org/app:1.1.1',
+        'org/app:latest',
+        'org/app:sha-90dd603',
+        'ghcr.io/user/app:1.1.1',
+        'ghcr.io/user/app:latest',
+        'ghcr.io/user/app:sha-90dd603'
       ],
       [
         "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.git",
-        "org.opencontainers.image.version=edge",
+        "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_schedule.env',
+      'event_tag_v2.0.8-beta.67.env',
       {
         images: ['org/app', 'ghcr.io/user/app'],
       } as Inputs,
-      'nightly',
+      {
+        version: '2.0.8-beta.67',
+        latest: true
+      } as Version,
       [
-        'org/app:nightly',
-        'ghcr.io/user/app:nightly'
+        'org/app:2.0.8-beta.67',
+        'org/app:latest',
+        'ghcr.io/user/app:2.0.8-beta.67',
+        '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.git",
-        "org.opencontainers.image.version=nightly",
+        "org.opencontainers.image.version=2.0.8-beta.67",
         "org.opencontainers.image.created=2020-01-10T00:30:00.000Z",
         "org.opencontainers.image.revision=90dd6032fac8bda1b6c4436a2e65de27961ed071",
         "org.opencontainers.image.licenses=MIT"
       ]
     ],
     [
-      'event_tag_semver.env',
+      'event_tag_v2.0.8-beta.67.env',
       {
         images: ['org/app', 'ghcr.io/user/app'],
+        tagCoerceTag: '{{major}}.{{minor}}',
       } as Inputs,
-      '1.1.1',
+      {
+        version: '2.0',
+        latest: true
+      } as Version,
       [
-        'org/app:1.1.1',
+        'org/app:2.0',
         'org/app:latest',
-        'ghcr.io/user/app:1.1.1',
+        'ghcr.io/user/app:2.0',
         'ghcr.io/user/app:latest'
       ],
       [
@@ -403,19 +567,100 @@ describe('tags and labels', () => {
         "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.git",
-        "org.opencontainers.image.version=1.1.1",
+        "org.opencontainers.image.version=2.0",
         "org.opencontainers.image.created=2020-01-10T00:30:00.000Z",
         "org.opencontainers.image.revision=90dd6032fac8bda1b6c4436a2e65de27961ed071",
         "org.opencontainers.image.licenses=MIT"
       ]
     ],
+    [
+      'event_tag_sometag.env',
+      {
+        images: ['org/app', 'ghcr.io/user/app'],
+        tagCoerceTag: '{{major}}.{{minor}}',
+      } as Inputs,
+      {
+        version: 'sometag',
+        latest: false
+      } as Version,
+      [
+        'org/app:sometag',
+        'ghcr.io/user/app:sometag'
+      ],
+      [
+        "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.git",
+        "org.opencontainers.image.version=sometag",
+        "org.opencontainers.image.created=2020-01-10T00:30:00.000Z",
+        "org.opencontainers.image.revision=90dd6032fac8bda1b6c4436a2e65de27961ed071",
+        "org.opencontainers.image.licenses=MIT"
+      ]
+    ],
+  ])('given %p event ', tagsLabelsTest);
+});
+
+describe('pull_request', () => {
+  // prettier-ignore
+  test.each([
+    [
+      'event_pull_request.env',
+      {
+        images: ['user/app'],
+      } as Inputs,
+      {
+        version: 'pr-2',
+        latest: false
+      } as Version,
+      [
+        'user/app:pr-2'
+      ],
+      [
+        "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.git",
+        "org.opencontainers.image.version=pr-2",
+        "org.opencontainers.image.created=2020-01-10T00:30:00.000Z",
+        "org.opencontainers.image.revision=1e9249f05bfc090e0688b8fb9c1b347586add504",
+        "org.opencontainers.image.licenses=MIT"
+      ]
+    ],
+    [
+      'event_pull_request.env',
+      {
+        images: ['org/app', 'ghcr.io/user/app'],
+      } as Inputs,
+      {
+        version: 'pr-2',
+        latest: false
+      } as Version,
+      [
+        'org/app:pr-2',
+        'ghcr.io/user/app:pr-2'
+      ],
+      [
+        "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.git",
+        "org.opencontainers.image.version=pr-2",
+        "org.opencontainers.image.created=2020-01-10T00:30:00.000Z",
+        "org.opencontainers.image.revision=1e9249f05bfc090e0688b8fb9c1b347586add504",
+        "org.opencontainers.image.licenses=MIT"
+      ]
+    ],
     [
       'event_pull_request.env',
       {
         images: ['org/app', 'ghcr.io/user/app'],
         tagSha: true,
       } as Inputs,
-      'pr-2',
+      {
+        version: 'pr-2',
+        latest: false
+      } as Version,
       [
         'org/app:pr-2',
         'org/app:sha-1e9249f',
@@ -433,50 +678,54 @@ describe('tags and labels', () => {
         "org.opencontainers.image.licenses=MIT"
       ]
     ],
+  ])('given %p event ', tagsLabelsTest);
+});
+
+describe('schedule', () => {
+  // prettier-ignore
+  test.each([
     [
-      'event_push.env',
+      'event_schedule.env',
       {
-        images: ['org/app', 'ghcr.io/user/app'],
-        tagSha: true,
+        images: ['user/app'],
       } as Inputs,
-      'dev',
+      {
+        version: 'nightly',
+        latest: false
+      } as Version,
       [
-        'org/app:dev',
-        'org/app:sha-90dd603',
-        'ghcr.io/user/app:dev',
-        'ghcr.io/user/app:sha-90dd603'
+        '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.git",
-        "org.opencontainers.image.version=dev",
+        "org.opencontainers.image.version=nightly",
         "org.opencontainers.image.created=2020-01-10T00:30:00.000Z",
         "org.opencontainers.image.revision=90dd6032fac8bda1b6c4436a2e65de27961ed071",
         "org.opencontainers.image.licenses=MIT"
       ]
     ],
     [
-      'event_push_defbranch.env',
+      'event_schedule.env',
       {
-        images: ['org/app', 'ghcr.io/user/app'],
-        tagSha: true,
-        tagEdge: true,
+        images: ['user/app'],
+        tagSchedule: `{{date 'YYYYMMDD'}}`
       } as Inputs,
-      'edge',
+      {
+        version: '20200110',
+        latest: false
+      } as Version,
       [
-        'org/app:edge',
-        'org/app:sha-90dd603',
-        'ghcr.io/user/app:edge',
-        'ghcr.io/user/app:sha-90dd603'
+        'user/app:20200110'
       ],
       [
         "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.git",
-        "org.opencontainers.image.version=edge",
+        "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"
@@ -485,66 +734,65 @@ describe('tags and labels', () => {
     [
       'event_schedule.env',
       {
-        images: ['org/app', 'ghcr.io/user/app'],
-        tagSha: true,
+        images: ['user/app'],
+        tagSchedule: `{{date 'YYYYMMDD-HHmmss'}}`
       } as Inputs,
-      'nightly',
+      {
+        version: '20200110-003000',
+        latest: false
+      } as Version,
       [
-        'org/app:nightly',
-        'org/app:sha-90dd603',
-        'ghcr.io/user/app:nightly',
-        'ghcr.io/user/app:sha-90dd603'
+        'user/app:20200110-003000'
       ],
       [
         "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.git",
-        "org.opencontainers.image.version=nightly",
+        "org.opencontainers.image.version=20200110-003000",
         "org.opencontainers.image.created=2020-01-10T00:30:00.000Z",
         "org.opencontainers.image.revision=90dd6032fac8bda1b6c4436a2e65de27961ed071",
         "org.opencontainers.image.licenses=MIT"
       ]
     ],
     [
-      'event_tag_semver.env',
+      'event_schedule.env',
       {
         images: ['org/app', 'ghcr.io/user/app'],
-        tagSha: true,
       } as Inputs,
-      '1.1.1',
+      {
+        version: 'nightly',
+        latest: false
+      } as Version,
       [
-        'org/app:1.1.1',
-        'org/app:latest',
-        'org/app:sha-90dd603',
-        'ghcr.io/user/app:1.1.1',
-        'ghcr.io/user/app:latest',
-        'ghcr.io/user/app:sha-90dd603'
+        'org/app:nightly',
+        '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.git",
-        "org.opencontainers.image.version=1.1.1",
+        "org.opencontainers.image.version=nightly",
         "org.opencontainers.image.created=2020-01-10T00:30:00.000Z",
         "org.opencontainers.image.revision=90dd6032fac8bda1b6c4436a2e65de27961ed071",
         "org.opencontainers.image.licenses=MIT"
       ]
     ],
     [
-      'event_push.env',
+      'event_schedule.env',
       {
         images: ['org/app', 'ghcr.io/user/app'],
         tagSha: true,
-        tagEdge: true,
-        tagEdgeBranch: 'dev'
       } as Inputs,
-      'edge',
+      {
+        version: 'nightly',
+        latest: false
+      } as Version,
       [
-        'org/app:edge',
+        'org/app:nightly',
         'org/app:sha-90dd603',
-        'ghcr.io/user/app:edge',
+        'ghcr.io/user/app:nightly',
         'ghcr.io/user/app:sha-90dd603'
       ],
       [
@@ -552,56 +800,41 @@ describe('tags and labels', () => {
         "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.git",
-        "org.opencontainers.image.version=edge",
+        "org.opencontainers.image.version=nightly",
         "org.opencontainers.image.created=2020-01-10T00:30:00.000Z",
         "org.opencontainers.image.revision=90dd6032fac8bda1b6c4436a2e65de27961ed071",
         "org.opencontainers.image.licenses=MIT"
       ]
     ],
+  ])('given %p event ', tagsLabelsTest);
+});
+
+describe('release', () => {
+  // prettier-ignore
+  test.each([
     [
-      'event_push_defbranch.env',
+      'event_release.env',
       {
-        images: ['org/app', 'ghcr.io/user/app'],
-        tagSha: true,
-        tagEdge: true,
-        tagEdgeBranch: 'dev'
+        images: ['user/app'],
       } as Inputs,
-      'master',
+      {
+        version: '1.1.1',
+        latest: true
+      } as Version,
       [
-        'org/app:master',
-        'org/app:sha-90dd603',
-        'ghcr.io/user/app:master',
-        'ghcr.io/user/app:sha-90dd603'
+        'user/app:1.1.1',
+        '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.git",
-        "org.opencontainers.image.version=master",
+        "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"
       ]
     ],
-  ])('given %p event ', async (envFile, inputs, exVersion, exTags, exLabels) => {
-    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 version = meta.version();
-    console.log('version', version);
-    expect(version).toEqual(exVersion);
-
-    const tags = meta.tags();
-    console.log('tags', tags);
-    expect(tags).toEqual(exTags);
-
-    const labels = meta.labels();
-    console.log('labels', labels);
-    expect(labels).toEqual(exLabels);
-  });
+  ])('given %p event ', tagsLabelsTest);
 });