Coerces Git tag to semver (#3)

Co-authored-by: CrazyMax <crazy-max@users.noreply.github.com>
This commit is contained in:
CrazyMax 2020-10-26 01:39:21 +01:00 committed by GitHub
parent 8ec02f11ef
commit 5bc3bf6dce
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 785 additions and 443 deletions

View File

@ -53,6 +53,29 @@ jobs:
tag-sha: true tag-sha: true
tag-schedule: ${{ matrix.tag-schedule }} 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: docker-push:
runs-on: ubuntu-latest runs-on: ubuntu-latest
services: services:

View File

@ -23,6 +23,8 @@ ___
* [inputs](#inputs) * [inputs](#inputs)
* [outputs](#outputs) * [outputs](#outputs)
* [Notes](#notes) * [Notes](#notes)
* [Latest tag](#latest-tag)
* [Coerces Git tag](#coerces-git-tag)
* [Templates available for schedule tag](#templates-available-for-schedule-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) * [Keep up-to-date with GitHub Dependabot](#keep-up-to-date-with-github-dependabot)
* [How can I help?](#how-can-i-help) * [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-sha` | Bool | Add git short SHA as Docker tag (default `false`) |
| `tag-edge` | Bool | Enable edge branch tagging (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-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`) | | `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-tags` | String | Separator to use for tags output (default `\n`) |
| `sep-labels` | String | Separator to use for labels output (default `\n`) | | `sep-labels` | String | Separator to use for labels output (default `\n`) |
@ -132,6 +135,27 @@ Following outputs are available
## Notes ## 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 ### Templates available for schedule tag
`tag-schedule` is specially crafted input to support [Handlebars template](https://handlebarsjs.com/guide/) with `tag-schedule` is specially crafted input to support [Handlebars template](https://handlebarsjs.com/guide/) with

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -4,7 +4,7 @@ import * as dotenv from 'dotenv';
import * as moment from 'moment'; import * as moment from 'moment';
import {getInputs, Inputs} from '../src/context'; import {getInputs, Inputs} from '../src/context';
import * as github from '../src/github'; 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 {Context} from '@actions/github/lib/context';
import {ReposGetResponseData} from '@octokit/types'; import {ReposGetResponseData} from '@octokit/types';
@ -28,7 +28,6 @@ jest.mock('moment', () => {
return () => jest.requireActual('moment')('2020-01-10T00:30:00.000Z'); return () => jest.requireActual('moment')('2020-01-10T00:30:00.000Z');
}); });
describe('tags and labels', () => {
beforeEach(() => { beforeEach(() => {
Object.keys(process.env).forEach(function (key) { Object.keys(process.env).forEach(function (key) {
if (key !== 'GITHUB_TOKEN' && key.startsWith('GITHUB_')) { if (key !== 'GITHUB_TOKEN' && key.startsWith('GITHUB_')) {
@ -37,6 +36,28 @@ describe('tags and labels', () => {
}); });
}); });
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 // prettier-ignore
test.each([ test.each([
[ [
@ -44,7 +65,10 @@ describe('tags and labels', () => {
{ {
images: ['user/app'], images: ['user/app'],
} as Inputs, } as Inputs,
undefined, {
version: undefined,
latest: false
} as Version,
[], [],
[ [
"org.opencontainers.image.title=Hello-World", "org.opencontainers.image.title=Hello-World",
@ -62,7 +86,10 @@ describe('tags and labels', () => {
{ {
images: ['user/app'], images: ['user/app'],
} as Inputs, } as Inputs,
undefined, {
version: undefined,
latest: false
} as Version,
[], [],
[ [
"org.opencontainers.image.title=Hello-World", "org.opencontainers.image.title=Hello-World",
@ -75,32 +102,21 @@ describe('tags and labels', () => {
"org.opencontainers.image.licenses=MIT" "org.opencontainers.image.licenses=MIT"
] ]
], ],
[ ])('given %p event ', tagsLabelsTest);
'event_pull_request.env', });
{
images: ['user/app'], describe('push', () => {
} as Inputs, // prettier-ignore
'pr-2', test.each([
[
'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_push.env', 'event_push.env',
{ {
images: ['user/app'], images: ['user/app'],
} as Inputs, } as Inputs,
'dev', {
version: 'dev',
latest: false
} as Version,
[ [
'user/app:dev' 'user/app:dev'
], ],
@ -121,7 +137,10 @@ describe('tags and labels', () => {
images: ['user/app'], images: ['user/app'],
tagEdge: true, tagEdge: true,
} as Inputs, } as Inputs,
'edge', {
version: 'edge',
latest: false
} as Version,
[ [
'user/app:edge' 'user/app:edge'
], ],
@ -141,7 +160,10 @@ describe('tags and labels', () => {
{ {
images: ['user/app'], images: ['user/app'],
} as Inputs, } as Inputs,
'master', {
version: 'master',
latest: false
} as Version,
[ [
'user/app:master' 'user/app:master'
], ],
@ -156,137 +178,16 @@ describe('tags and labels', () => {
"org.opencontainers.image.licenses=MIT" "org.opencontainers.image.licenses=MIT"
] ]
], ],
[
'event_release.env',
{
images: ['user/app'],
} as Inputs,
'1.1.1',
[
'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=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',
{
images: ['user/app'],
} as Inputs,
'nightly',
[
'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=nightly",
"org.opencontainers.image.created=2020-01-10T00:30:00.000Z",
"org.opencontainers.image.revision=90dd6032fac8bda1b6c4436a2e65de27961ed071",
"org.opencontainers.image.licenses=MIT"
]
],
[
'event_schedule.env',
{
images: ['user/app'],
tagSchedule: `{{date 'YYYYMMDD'}}`
} as Inputs,
'20200110',
[
'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=20200110",
"org.opencontainers.image.created=2020-01-10T00:30:00.000Z",
"org.opencontainers.image.revision=90dd6032fac8bda1b6c4436a2e65de27961ed071",
"org.opencontainers.image.licenses=MIT"
]
],
[
'event_schedule.env',
{
images: ['user/app'],
tagSchedule: `{{date 'YYYYMMDD-HHmmss'}}`
} as Inputs,
'20200110-003000',
[
'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=20200110-003000",
"org.opencontainers.image.created=2020-01-10T00:30:00.000Z",
"org.opencontainers.image.revision=90dd6032fac8bda1b6c4436a2e65de27961ed071",
"org.opencontainers.image.licenses=MIT"
]
],
[
'event_tag.env',
{
images: ['user/app'],
} as Inputs,
'release1',
[
'user/app:release1'
],
[
"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=release1",
"org.opencontainers.image.created=2020-01-10T00:30:00.000Z",
"org.opencontainers.image.revision=90dd6032fac8bda1b6c4436a2e65de27961ed071",
"org.opencontainers.image.licenses=MIT"
]
],
[
'event_tag_semver.env',
{
images: ['user/app'],
} as Inputs,
'1.1.1',
[
'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=1.1.1",
"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_workflow_dispatch.env',
{ {
images: ['user/app'], images: ['user/app'],
tagEdge: true, tagEdge: true,
} as Inputs, } as Inputs,
'edge', {
version: 'edge',
latest: false
} as Version,
[ [
'user/app:edge' 'user/app:edge'
], ],
@ -301,33 +202,15 @@ describe('tags and labels', () => {
"org.opencontainers.image.licenses=MIT" "org.opencontainers.image.licenses=MIT"
] ]
], ],
[
'event_pull_request.env',
{
images: ['org/app', 'ghcr.io/user/app'],
} as Inputs,
'pr-2',
[
'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_push.env', 'event_push.env',
{ {
images: ['org/app', 'ghcr.io/user/app'], images: ['org/app', 'ghcr.io/user/app'],
} as Inputs, } as Inputs,
'dev', {
version: 'dev',
latest: false
} as Version,
[ [
'org/app:dev', 'org/app:dev',
'ghcr.io/user/app:dev' 'ghcr.io/user/app:dev'
@ -349,7 +232,10 @@ describe('tags and labels', () => {
images: ['org/app', 'ghcr.io/user/app'], images: ['org/app', 'ghcr.io/user/app'],
tagEdge: true, tagEdge: true,
} as Inputs, } as Inputs,
'edge', {
version: 'edge',
latest: false
} as Version,
[ [
'org/app:edge', 'org/app:edge',
'ghcr.io/user/app:edge' 'ghcr.io/user/app:edge'
@ -365,81 +251,16 @@ describe('tags and labels', () => {
"org.opencontainers.image.licenses=MIT" "org.opencontainers.image.licenses=MIT"
] ]
], ],
[
'event_schedule.env',
{
images: ['org/app', 'ghcr.io/user/app'],
} as Inputs,
'nightly',
[
'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=nightly",
"org.opencontainers.image.created=2020-01-10T00:30:00.000Z",
"org.opencontainers.image.revision=90dd6032fac8bda1b6c4436a2e65de27961ed071",
"org.opencontainers.image.licenses=MIT"
]
],
[
'event_tag_semver.env',
{
images: ['org/app', 'ghcr.io/user/app'],
} as Inputs,
'1.1.1',
[
'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=1.1.1",
"org.opencontainers.image.created=2020-01-10T00:30:00.000Z",
"org.opencontainers.image.revision=90dd6032fac8bda1b6c4436a2e65de27961ed071",
"org.opencontainers.image.licenses=MIT"
]
],
[
'event_pull_request.env',
{
images: ['org/app', 'ghcr.io/user/app'],
tagSha: true,
} as Inputs,
'pr-2',
[
'org/app:pr-2',
'org/app:sha-1e9249f',
'ghcr.io/user/app:pr-2',
'ghcr.io/user/app:sha-1e9249f'
],
[
"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_push.env', 'event_push.env',
{ {
images: ['org/app', 'ghcr.io/user/app'], images: ['org/app', 'ghcr.io/user/app'],
tagSha: true, tagSha: true,
} as Inputs, } as Inputs,
'dev', {
version: 'dev',
latest: false
} as Version,
[ [
'org/app:dev', 'org/app:dev',
'org/app:sha-90dd603', 'org/app:sha-90dd603',
@ -464,7 +285,10 @@ describe('tags and labels', () => {
tagSha: true, tagSha: true,
tagEdge: true, tagEdge: true,
} as Inputs, } as Inputs,
'edge', {
version: 'edge',
latest: false
} as Version,
[ [
'org/app:edge', 'org/app:edge',
'org/app:sha-90dd603', 'org/app:sha-90dd603',
@ -482,56 +306,6 @@ describe('tags and labels', () => {
"org.opencontainers.image.licenses=MIT" "org.opencontainers.image.licenses=MIT"
] ]
], ],
[
'event_schedule.env',
{
images: ['org/app', 'ghcr.io/user/app'],
tagSha: true,
} as Inputs,
'nightly',
[
'org/app:nightly',
'org/app:sha-90dd603',
'ghcr.io/user/app:nightly',
'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.created=2020-01-10T00:30:00.000Z",
"org.opencontainers.image.revision=90dd6032fac8bda1b6c4436a2e65de27961ed071",
"org.opencontainers.image.licenses=MIT"
]
],
[
'event_tag_semver.env',
{
images: ['org/app', 'ghcr.io/user/app'],
tagSha: true,
} as Inputs,
'1.1.1',
[
'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=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.env', 'event_push.env',
{ {
@ -540,7 +314,10 @@ describe('tags and labels', () => {
tagEdge: true, tagEdge: true,
tagEdgeBranch: 'dev' tagEdgeBranch: 'dev'
} as Inputs, } as Inputs,
'edge', {
version: 'edge',
latest: false
} as Version,
[ [
'org/app:edge', 'org/app:edge',
'org/app:sha-90dd603', 'org/app:sha-90dd603',
@ -566,7 +343,10 @@ describe('tags and labels', () => {
tagEdge: true, tagEdge: true,
tagEdgeBranch: 'dev' tagEdgeBranch: 'dev'
} as Inputs, } as Inputs,
'master', {
version: 'master',
latest: false
} as Version,
[ [
'org/app:master', 'org/app:master',
'org/app:sha-90dd603', 'org/app:sha-90dd603',
@ -584,24 +364,477 @@ describe('tags and labels', () => {
"org.opencontainers.image.licenses=MIT" "org.opencontainers.image.licenses=MIT"
] ]
], ],
])('given %p event ', async (envFile, inputs, exVersion, exTags, exLabels) => { ])('given %p event ', tagsLabelsTest);
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('push tag', () => {
// prettier-ignore
test.each([
[
'event_tag_release1.env',
{
images: ['user/app'],
} as Inputs,
{
version: 'release1',
latest: false
} as Version,
[
'user/app:release1'
],
[
"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=release1",
"org.opencontainers.image.created=2020-01-10T00:30:00.000Z",
"org.opencontainers.image.revision=90dd6032fac8bda1b6c4436a2e65de27961ed071",
"org.opencontainers.image.licenses=MIT"
]
],
[
'event_tag_20200110-RC2.env',
{
images: ['user/app'],
} as Inputs,
{
version: '20200110-RC2',
latest: false
} as Version,
[
'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=20200110-RC2",
"org.opencontainers.image.created=2020-01-10T00:30:00.000Z",
"org.opencontainers.image.revision=90dd6032fac8bda1b6c4436a2e65de27961ed071",
"org.opencontainers.image.licenses=MIT"
]
],
[
'event_tag_20200110-RC2.env',
{
images: ['user/app'],
tagCoerceTag: '{{major}}',
} as Inputs,
{
version: '20200110',
latest: true
} as Version,
[
'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=20200110",
"org.opencontainers.image.created=2020-01-10T00:30:00.000Z",
"org.opencontainers.image.revision=90dd6032fac8bda1b6c4436a2e65de27961ed071",
"org.opencontainers.image.licenses=MIT"
]
],
[
'event_tag_v1.1.1.env',
{
images: ['user/app'],
} as Inputs,
{
version: '1.1.1',
latest: true
} as Version,
[
'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=1.1.1",
"org.opencontainers.image.created=2020-01-10T00:30:00.000Z",
"org.opencontainers.image.revision=90dd6032fac8bda1b6c4436a2e65de27961ed071",
"org.opencontainers.image.licenses=MIT"
]
],
[
'event_tag_v1.1.1.env',
{
images: ['org/app', 'ghcr.io/user/app'],
} as Inputs,
{
version: '1.1.1',
latest: true
} as Version,
[
'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=1.1.1",
"org.opencontainers.image.created=2020-01-10T00:30:00.000Z",
"org.opencontainers.image.revision=90dd6032fac8bda1b6c4436a2e65de27961ed071",
"org.opencontainers.image.licenses=MIT"
]
],
[
'event_tag_v1.1.1.env',
{
images: ['org/app', 'ghcr.io/user/app'],
tagSha: true,
} as Inputs,
{
version: '1.1.1',
latest: true
} 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.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.created=2020-01-10T00:30:00.000Z",
"org.opencontainers.image.revision=90dd6032fac8bda1b6c4436a2e65de27961ed071",
"org.opencontainers.image.licenses=MIT"
]
],
[
'event_tag_v2.0.8-beta.67.env',
{
images: ['org/app', 'ghcr.io/user/app'],
} as Inputs,
{
version: '2.0.8-beta.67',
latest: true
} as Version,
[
'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=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_v2.0.8-beta.67.env',
{
images: ['org/app', 'ghcr.io/user/app'],
tagCoerceTag: '{{major}}.{{minor}}',
} as Inputs,
{
version: '2.0',
latest: true
} as Version,
[
'org/app:2.0',
'org/app:latest',
'ghcr.io/user/app:2.0',
'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=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,
{
version: 'pr-2',
latest: false
} as Version,
[
'org/app:pr-2',
'org/app:sha-1e9249f',
'ghcr.io/user/app:pr-2',
'ghcr.io/user/app:sha-1e9249f'
],
[
"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"
]
],
])('given %p event ', tagsLabelsTest);
});
describe('schedule', () => {
// prettier-ignore
test.each([
[
'event_schedule.env',
{
images: ['user/app'],
} as Inputs,
{
version: 'nightly',
latest: false
} as Version,
[
'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=nightly",
"org.opencontainers.image.created=2020-01-10T00:30:00.000Z",
"org.opencontainers.image.revision=90dd6032fac8bda1b6c4436a2e65de27961ed071",
"org.opencontainers.image.licenses=MIT"
]
],
[
'event_schedule.env',
{
images: ['user/app'],
tagSchedule: `{{date 'YYYYMMDD'}}`
} as Inputs,
{
version: '20200110',
latest: false
} as Version,
[
'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=20200110",
"org.opencontainers.image.created=2020-01-10T00:30:00.000Z",
"org.opencontainers.image.revision=90dd6032fac8bda1b6c4436a2e65de27961ed071",
"org.opencontainers.image.licenses=MIT"
]
],
[
'event_schedule.env',
{
images: ['user/app'],
tagSchedule: `{{date 'YYYYMMDD-HHmmss'}}`
} as Inputs,
{
version: '20200110-003000',
latest: false
} as Version,
[
'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=20200110-003000",
"org.opencontainers.image.created=2020-01-10T00:30:00.000Z",
"org.opencontainers.image.revision=90dd6032fac8bda1b6c4436a2e65de27961ed071",
"org.opencontainers.image.licenses=MIT"
]
],
[
'event_schedule.env',
{
images: ['org/app', 'ghcr.io/user/app'],
} as Inputs,
{
version: 'nightly',
latest: false
} as Version,
[
'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=nightly",
"org.opencontainers.image.created=2020-01-10T00:30:00.000Z",
"org.opencontainers.image.revision=90dd6032fac8bda1b6c4436a2e65de27961ed071",
"org.opencontainers.image.licenses=MIT"
]
],
[
'event_schedule.env',
{
images: ['org/app', 'ghcr.io/user/app'],
tagSha: true,
} as Inputs,
{
version: 'nightly',
latest: false
} as Version,
[
'org/app:nightly',
'org/app:sha-90dd603',
'ghcr.io/user/app:nightly',
'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.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_release.env',
{
images: ['user/app'],
} as Inputs,
{
version: '1.1.1',
latest: true
} as Version,
[
'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=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 ', tagsLabelsTest);
}); });

View File

@ -21,6 +21,9 @@ inputs:
tag-edge-branch: tag-edge-branch:
description: 'Branch that will be tagged as edge (default repo.default_branch)' description: 'Branch that will be tagged as edge (default repo.default_branch)'
required: false required: false
tag-coerce-tag:
description: 'Coerces Git tag to semver if possible using Handlebars template'
required: false
tag-schedule: tag-schedule:
description: 'Handlebars template to apply to schedule tag' description: 'Handlebars template to apply to schedule tag'
default: 'nightly' default: 'nightly'

115
dist/index.js generated vendored
View File

@ -25,6 +25,7 @@ function getInputs() {
tagSha: /true/i.test(core.getInput('tag-sha') || 'false'), tagSha: /true/i.test(core.getInput('tag-sha') || 'false'),
tagEdge: /true/i.test(core.getInput('tag-edge') || 'false'), tagEdge: /true/i.test(core.getInput('tag-edge') || 'false'),
tagEdgeBranch: core.getInput('tag-edge-branch'), tagEdgeBranch: core.getInput('tag-edge-branch'),
tagCoerceTag: core.getInput('tag-coerce-tag'),
tagSchedule: core.getInput('tag-schedule') || 'nightly', tagSchedule: core.getInput('tag-schedule') || 'nightly',
sepTags: core.getInput('sep-tags') || `\n`, sepTags: core.getInput('sep-tags') || `\n`,
sepLabels: core.getInput('sep-labels') || `\n`, sepLabels: core.getInput('sep-labels') || `\n`,
@ -129,9 +130,9 @@ function run() {
const meta = new meta_1.Meta(inputs, context, repo); const meta = new meta_1.Meta(inputs, context, repo);
const version = meta.version(); const version = meta.version();
core.startGroup(`Docker image version`); core.startGroup(`Docker image version`);
core.info(`${version}`); core.info(version.version || '');
core.endGroup(); core.endGroup();
core.setOutput('version', version || ''); core.setOutput('version', version.version || '');
const tags = meta.tags(); const tags = meta.tags();
core.startGroup(`Docker tags`); core.startGroup(`Docker tags`);
for (let tag of tags) { for (let tag of tags) {
@ -167,7 +168,6 @@ exports.Meta = void 0;
const handlebars = __webpack_require__(7492); const handlebars = __webpack_require__(7492);
const moment = __webpack_require__(9623); const moment = __webpack_require__(9623);
const semver = __webpack_require__(1383); const semver = __webpack_require__(1383);
const core = __webpack_require__(2186);
class Meta { class Meta {
constructor(inputs, context, repo) { constructor(inputs, context, repo) {
this.inputs = inputs; this.inputs = inputs;
@ -179,40 +179,64 @@ class Meta {
this.date = new Date(); this.date = new Date();
} }
version() { version() {
const currentDate = this.date;
const version = {
version: undefined,
latest: false
};
if (/schedule/.test(this.context.eventName)) { 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)) { else if (/^refs\/tags\//.test(this.context.ref)) {
const tag = this.context.ref.replace(/^refs\/tags\//g, '').replace(/\//g, '-'); const tag = this.context.ref.replace(/^refs\/tags\//g, '').replace(/\//g, '-');
const sver = semver.clean(tag); 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 (/^refs\/heads\//.test(this.context.ref)) { else if (sver) {
const branch = this.context.ref.replace(/^refs\/heads\//g, '').replace(/\//g, '-'); version.version = sver;
return this.inputs.tagEdge && this.inputs.tagEdgeBranch === branch ? 'edge' : branch; version.latest = true;
}
else if (/^refs\/pull\//.test(this.context.ref)) {
const pr = this.context.ref.replace(/^refs\/pull\//g, '').replace(/\/merge$/g, '');
return `pr-${pr}`;
}
}
tags() {
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 { else {
core.warning(`Unknown event "${this.context.eventName}" with ref "${this.context.ref}"`); version.version = tag;
}
}
else if (sver) {
version.version = sver;
version.latest = true;
}
else {
version.version = tag;
}
}
else if (/^refs\/heads\//.test(this.context.ref)) {
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)) {
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) {
tags.push(`${image}:${version.version}`);
if (version.latest) {
tags.push(`${image}:latest`);
} }
if (this.context.sha && this.inputs.tagSha) { if (this.context.sha && this.inputs.tagSha) {
tags.push(`${image}:sha-${this.context.sha.substr(0, 7)}`); 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.description=${this.repo.description || ''}`,
`org.opencontainers.image.url=${this.repo.html_url || ''}`, `org.opencontainers.image.url=${this.repo.html_url || ''}`,
`org.opencontainers.image.source=${this.repo.clone_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.created=${this.date.toISOString()}`,
`org.opencontainers.image.revision=${this.context.sha || ''}`, `org.opencontainers.image.revision=${this.context.sha || ''}`,
`org.opencontainers.image.licenses=${((_a = this.repo.license) === null || _a === void 0 ? void 0 : _a.spdx_id) || ''}` `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; exports.Meta = Meta;
//# sourceMappingURL=meta.js.map //# sourceMappingURL=meta.js.map

View File

@ -5,6 +5,7 @@ export interface Inputs {
tagSha: boolean; tagSha: boolean;
tagEdge: boolean; tagEdge: boolean;
tagEdgeBranch: string; tagEdgeBranch: string;
tagCoerceTag: string;
tagSchedule: string; tagSchedule: string;
sepTags: string; sepTags: string;
sepLabels: string; sepLabels: string;
@ -17,6 +18,7 @@ export function getInputs(): Inputs {
tagSha: /true/i.test(core.getInput('tag-sha') || 'false'), tagSha: /true/i.test(core.getInput('tag-sha') || 'false'),
tagEdge: /true/i.test(core.getInput('tag-edge') || 'false'), tagEdge: /true/i.test(core.getInput('tag-edge') || 'false'),
tagEdgeBranch: core.getInput('tag-edge-branch'), tagEdgeBranch: core.getInput('tag-edge-branch'),
tagCoerceTag: core.getInput('tag-coerce-tag'),
tagSchedule: core.getInput('tag-schedule') || 'nightly', tagSchedule: core.getInput('tag-schedule') || 'nightly',
sepTags: core.getInput('sep-tags') || `\n`, sepTags: core.getInput('sep-tags') || `\n`,
sepLabels: core.getInput('sep-labels') || `\n`, sepLabels: core.getInput('sep-labels') || `\n`,

View File

@ -1,6 +1,6 @@
import {getInputs, Inputs} from './context'; import {getInputs, Inputs} from './context';
import * as github from './github'; import * as github from './github';
import {Meta} from './meta'; import {Meta, Version} from './meta';
import * as core from '@actions/core'; import * as core from '@actions/core';
import {Context} from '@actions/github/lib/context'; import {Context} from '@actions/github/lib/context';
import {ReposGetResponseData} from '@octokit/types'; import {ReposGetResponseData} from '@octokit/types';
@ -27,11 +27,11 @@ async function run() {
const meta: Meta = new Meta(inputs, context, repo); 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.startGroup(`Docker image version`);
core.info(`${version}`); core.info(version.version || '');
core.endGroup(); core.endGroup();
core.setOutput('version', version || ''); core.setOutput('version', version.version || '');
const tags: Array<string> = meta.tags(); const tags: Array<string> = meta.tags();
core.startGroup(`Docker tags`); core.startGroup(`Docker tags`);

View File

@ -2,10 +2,14 @@ import * as handlebars from 'handlebars';
import * as moment from 'moment'; import * as moment from 'moment';
import * as semver from 'semver'; import * as semver from 'semver';
import {Inputs} from './context'; import {Inputs} from './context';
import * as core from '@actions/core';
import {Context} from '@actions/github/lib/context'; import {Context} from '@actions/github/lib/context';
import {ReposGetResponseData} from '@octokit/types'; import {ReposGetResponseData} from '@octokit/types';
export interface Version {
version: string | undefined;
latest: boolean;
}
export class Meta { export class Meta {
private readonly inputs: Inputs; private readonly inputs: Inputs;
private readonly context: Context; private readonly context: Context;
@ -22,35 +26,62 @@ export class Meta {
this.date = new Date(); 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)) { 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)) { } else if (/^refs\/tags\//.test(this.context.ref)) {
const tag = this.context.ref.replace(/^refs\/tags\//g, '').replace(/\//g, '-'); const tag = this.context.ref.replace(/^refs\/tags\//g, '').replace(/\//g, '-');
const sver = semver.clean(tag); const sver = semver.clean(tag);
return sver ? sver : tag; if (this.inputs.tagCoerceTag) {
} else if (/^refs\/heads\//.test(this.context.ref)) { const coerce = semver.coerce(tag);
const branch = this.context.ref.replace(/^refs\/heads\//g, '').replace(/\//g, '-'); if (coerce) {
return this.inputs.tagEdge && this.inputs.tagEdgeBranch === branch ? 'edge' : branch; version.version = handlebars.compile(this.inputs.tagCoerceTag)(coerce);
} else if (/^refs\/pull\//.test(this.context.ref)) { version.latest = true;
const pr = this.context.ref.replace(/^refs\/pull\//g, '').replace(/\/merge$/g, ''); } else if (sver) {
return `pr-${pr}`; 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)) {
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)) {
version.version = `pr-${this.context.ref.replace(/^refs\/pull\//g, '').replace(/\/merge$/g, '')}`;
}
return version;
} }
public tags(): Array<string> { public tags(): Array<string> {
const version: Version = this.version();
if (!version.version) {
return [];
}
let tags: Array<string> = []; let tags: Array<string> = [];
for (const image of this.inputs.images) { for (const image of this.inputs.images) {
if (/schedule/.test(this.context.eventName)) { tags.push(`${image}:${version.version}`);
tags.push.apply(tags, this.eventSchedule(image)); if (version.latest) {
} else if (/^refs\/tags\//.test(this.context.ref)) { tags.push(`${image}:latest`);
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}"`);
} }
if (this.context.sha && this.inputs.tagSha) { if (this.context.sha && this.inputs.tagSha) {
tags.push(`${image}:sha-${this.context.sha.substr(0, 7)}`); 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.description=${this.repo.description || ''}`,
`org.opencontainers.image.url=${this.repo.html_url || ''}`, `org.opencontainers.image.url=${this.repo.html_url || ''}`,
`org.opencontainers.image.source=${this.repo.clone_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.created=${this.date.toISOString()}`,
`org.opencontainers.image.revision=${this.context.sha || ''}`, `org.opencontainers.image.revision=${this.context.sha || ''}`,
`org.opencontainers.image.licenses=${this.repo.license?.spdx_id || ''}` `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);
}
};
}
} }