mirror of
https://gitea.com/docker/metadata-action.git
synced 2024-11-25 13:39:33 +01:00
Add tz attribute to handlebar date function
Signed-off-by: chroju <chroju@users.noreply.github.com>
This commit is contained in:
parent
c98ac5e987
commit
90a1d5cf21
10 changed files with 136 additions and 31 deletions
13
README.md
13
README.md
|
@ -43,7 +43,7 @@ ___
|
|||
* [`{{sha}}`](#sha)
|
||||
* [`{{base_ref}}`](#base_ref)
|
||||
* [`{{is_default_branch}}`](#is_default_branch)
|
||||
* [`{{date '<format>'}}`](#date-format)
|
||||
* [`{{date '<format>' tz='<timezone>'}}`](#date-format)
|
||||
* [Major version zero](#major-version-zero)
|
||||
* [JSON output object](#json-output-object)
|
||||
* [Overwrite labels](#overwrite-labels)
|
||||
|
@ -399,6 +399,8 @@ tags: |
|
|||
type=schedule,pattern=nightly
|
||||
# handlebars
|
||||
type=schedule,pattern={{date 'YYYYMMDD'}}
|
||||
# handlebars with timezone
|
||||
type=schedule,pattern={{date 'YYYYMMDD-hhmmss' tz='Asia/Tokyo'}}
|
||||
```
|
||||
|
||||
Will be used on [schedule event](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#schedule).
|
||||
|
@ -406,7 +408,7 @@ Will be used on [schedule event](https://docs.github.com/en/actions/using-workfl
|
|||
`pattern` is a specially crafted attribute to support [Handlebars' template](https://handlebarsjs.com/guide/)
|
||||
with the following expressions:
|
||||
|
||||
* `date 'format'` ; render date by its [moment format](https://momentjs.com/docs/#/displaying/format/)
|
||||
* `date 'format' tz='Timezone'` ; render date by its [moment format](https://momentjs.com/docs/#/displaying/format/). Default `tz` is UTC.
|
||||
|
||||
| Pattern | Output |
|
||||
|--------------------------|----------------------|
|
||||
|
@ -776,14 +778,15 @@ workflow run. Will be empty for a branch reference:
|
|||
Returns `true` if the branch that triggered the workflow run is the default
|
||||
one, otherwise `false`.
|
||||
|
||||
#### `{{date '<format>'}}`
|
||||
#### `{{date '<format>' tz='<timezone>'}}`
|
||||
|
||||
Returns the current date rendered by its [moment format](https://momentjs.com/docs/#/displaying/format/).
|
||||
Returns the current date rendered by its [moment format](https://momentjs.com/docs/#/displaying/format/). Default `tz` is UTC.
|
||||
|
||||
| Expression | Output example |
|
||||
|--------------------------------------------|-----------------------------------------|
|
||||
|------------------------------------------------------------|--------------------------------------------|
|
||||
| `{{date 'YYYYMMDD'}}` | `20200110` |
|
||||
| `{{date 'dddd, MMMM Do YYYY, h:mm:ss a'}}` | `Friday, January 10th 2020, 3:25:50 pm` |
|
||||
| `{{date 'dddd, MMMM Do YYYY, h:mm:ss a' tz='Asia/Tokyo'}}` | `Saturday, January 11th 2020, 12:25:50 am` |
|
||||
|
||||
### Major version zero
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ import {beforeEach, describe, expect, jest, test} from '@jest/globals';
|
|||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import * as dotenv from 'dotenv';
|
||||
import * as moment from 'moment';
|
||||
import moment from 'moment-timezone';
|
||||
import {getInputs, Inputs} from '../src/context';
|
||||
import * as github from '../src/github';
|
||||
import {Meta, Version} from '../src/meta';
|
||||
|
@ -21,8 +21,8 @@ jest.spyOn(global.Date.prototype, 'toISOString').mockImplementation(() => {
|
|||
return '2020-01-10T00:30:00.000Z';
|
||||
});
|
||||
|
||||
jest.mock('moment', () => {
|
||||
return () => (jest.requireActual('moment') as typeof import('moment'))('2020-01-10T00:30:00.000Z');
|
||||
jest.mock('moment-timezone', () => {
|
||||
return () => (jest.requireActual('moment-timezone') as typeof import('moment-timezone'))('2020-01-10T00:30:00.000Z');
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
|
@ -599,6 +599,7 @@ describe('push', () => {
|
|||
tags: [
|
||||
`type=raw,value=mytag-{{branch}}`,
|
||||
`type=raw,value=mytag-{{date 'YYYYMMDD'}}`,
|
||||
`type=raw,value=mytag-{{date 'YYYYMMDD-HHmmss' tz='Asia/Tokyo'}}`,
|
||||
`type=raw,value=mytag-tag-{{tag}}`,
|
||||
`type=raw,value=mytag-baseref-{{base_ref}}`,
|
||||
`type=raw,value=mytag-defbranch,enable={{is_default_branch}}`
|
||||
|
@ -608,6 +609,7 @@ describe('push', () => {
|
|||
main: 'mytag-master',
|
||||
partial: [
|
||||
'mytag-20200110',
|
||||
'mytag-20200110-093000',
|
||||
'mytag-tag-',
|
||||
'mytag-baseref-',
|
||||
'mytag-defbranch'
|
||||
|
@ -617,6 +619,7 @@ describe('push', () => {
|
|||
[
|
||||
'user/app:mytag-master',
|
||||
'user/app:mytag-20200110',
|
||||
'user/app:mytag-20200110-093000',
|
||||
'user/app:mytag-tag-',
|
||||
'user/app:mytag-baseref-',
|
||||
'user/app:mytag-defbranch'
|
||||
|
@ -2995,6 +2998,34 @@ describe('schedule', () => {
|
|||
"org.opencontainers.image.licenses=MIT"
|
||||
]
|
||||
],
|
||||
[
|
||||
'schedule08',
|
||||
'event_schedule.env',
|
||||
{
|
||||
images: ['user/app'],
|
||||
tags: [
|
||||
`type=schedule,pattern={{date 'YYYYMMDD-HHmmss' tz='Asia/Tokyo'}}`
|
||||
]
|
||||
} as Inputs,
|
||||
{
|
||||
main: '20200110-093000',
|
||||
partial: [],
|
||||
latest: false
|
||||
} as Version,
|
||||
[
|
||||
'user/app:20200110-093000'
|
||||
],
|
||||
[
|
||||
"org.opencontainers.image.title=Hello-World",
|
||||
"org.opencontainers.image.description=This your first repo!",
|
||||
"org.opencontainers.image.url=https://github.com/octocat/Hello-World",
|
||||
"org.opencontainers.image.source=https://github.com/octocat/Hello-World",
|
||||
"org.opencontainers.image.version=20200110-093000",
|
||||
"org.opencontainers.image.created=2020-01-10T00:30:00.000Z",
|
||||
"org.opencontainers.image.revision=860c1904a1ce19322e91ac35af1ab07466440c37",
|
||||
"org.opencontainers.image.licenses=MIT"
|
||||
]
|
||||
],
|
||||
])('given %p with %p event', tagsLabelsTest);
|
||||
});
|
||||
|
||||
|
|
|
@ -126,6 +126,18 @@ describe('parse', () => {
|
|||
} as Tag,
|
||||
false
|
||||
],
|
||||
[
|
||||
`type=schedule,enable=true,pattern={{date 'YYYYMMDD' tz='Asia/Tokyo'}}`,
|
||||
{
|
||||
type: Type.Schedule,
|
||||
attrs: {
|
||||
"priority": DefaultPriorities[Type.Schedule],
|
||||
"enable": "true",
|
||||
"pattern": `{{date 'YYYYMMDD' tz='Asia/Tokyo'}}`
|
||||
}
|
||||
} as Tag,
|
||||
false
|
||||
],
|
||||
[
|
||||
`type=semver,enable=true,pattern={{version}}`,
|
||||
{
|
||||
|
|
30
dist/index.js
generated
vendored
30
dist/index.js
generated
vendored
File diff suppressed because one or more lines are too long
2
dist/index.js.map
generated
vendored
2
dist/index.js.map
generated
vendored
File diff suppressed because one or more lines are too long
23
dist/licenses.txt
generated
vendored
23
dist/licenses.txt
generated
vendored
|
@ -627,6 +627,29 @@ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
moment-timezone
|
||||
MIT
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) JS Foundation and other contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
node-fetch
|
||||
MIT
|
||||
The MIT License (MIT)
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
"csv-parse": "^5.3.3",
|
||||
"handlebars": "^4.7.7",
|
||||
"moment": "^2.29.4",
|
||||
"moment-timezone": "^0.5.40",
|
||||
"semver": "^7.3.7"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
32
src/meta.ts
32
src/meta.ts
|
@ -1,7 +1,7 @@
|
|||
import * as handlebars from 'handlebars';
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import moment from 'moment';
|
||||
import moment from 'moment-timezone';
|
||||
import * as pep440 from '@renovate/pep440';
|
||||
import * as semver from 'semver';
|
||||
import {Inputs, tmpDir} from './context';
|
||||
|
@ -129,8 +129,19 @@ export class Meta {
|
|||
const currentDate = this.date;
|
||||
const vraw = this.setValue(
|
||||
handlebars.compile(tag.attrs['pattern'])({
|
||||
date: function (format) {
|
||||
return moment(currentDate).utc().format(format);
|
||||
date: function (format, options) {
|
||||
const m = moment(currentDate);
|
||||
let tz = 'UTC';
|
||||
Object.keys(options.hash).forEach(key => {
|
||||
switch (key) {
|
||||
case 'tz':
|
||||
tz = options.hash[key];
|
||||
break;
|
||||
default:
|
||||
throw new Error(`Unknown ${key} attribute`);
|
||||
}
|
||||
});
|
||||
return m.tz(tz).format(format);
|
||||
}
|
||||
}),
|
||||
tag
|
||||
|
@ -411,8 +422,19 @@ export class Meta {
|
|||
}
|
||||
return 'false';
|
||||
},
|
||||
date: function (format) {
|
||||
return moment(currentDate).utc().format(format);
|
||||
date: function (format, options) {
|
||||
const m = moment(currentDate);
|
||||
let tz = 'UTC';
|
||||
Object.keys(options.hash).forEach(key => {
|
||||
switch (key) {
|
||||
case 'tz':
|
||||
tz = options.hash[key];
|
||||
break;
|
||||
default:
|
||||
throw new Error(`Unknown ${key} attribute`);
|
||||
}
|
||||
});
|
||||
return m.tz(tz).format(format);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -95,7 +95,7 @@ export function Parse(s: string): Tag {
|
|||
for (const field of fields) {
|
||||
const parts = field
|
||||
.toString()
|
||||
.split('=')
|
||||
.split(/(?<=^[^=]+?)=/)
|
||||
.map(item => item.trim());
|
||||
if (parts.length == 1) {
|
||||
tag.attrs['value'] = parts[0];
|
||||
|
|
|
@ -2954,7 +2954,14 @@ minimist@^1.2.5:
|
|||
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44"
|
||||
integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==
|
||||
|
||||
moment@^2.29.4:
|
||||
moment-timezone@^0.5.40:
|
||||
version "0.5.40"
|
||||
resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.5.40.tgz#c148f5149fd91dd3e29bf481abc8830ecba16b89"
|
||||
integrity sha512-tWfmNkRYmBkPJz5mr9GVDn9vRlVZOTe6yqY92rFxiOdWXbjaR0+9LwQnZGGuNR63X456NqmEkbskte8tWL5ePg==
|
||||
dependencies:
|
||||
moment ">= 2.9.0"
|
||||
|
||||
"moment@>= 2.9.0", moment@^2.29.4:
|
||||
version "2.29.4"
|
||||
resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.4.tgz#3dbe052889fe7c1b2ed966fcb3a77328964ef108"
|
||||
integrity sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==
|
||||
|
|
Loading…
Reference in a new issue