Skip to content

Commit

Permalink
Add tz attribute to handlebar date function
Browse files Browse the repository at this point in the history
Signed-off-by: chroju <chroju@users.noreply.github.com>
  • Loading branch information
chroju committed Jan 6, 2023
1 parent c98ac5e commit 90a1d5c
Show file tree
Hide file tree
Showing 10 changed files with 136 additions and 31 deletions.
19 changes: 11 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -399,14 +399,16 @@ 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).

`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 |
|--------------------------|----------------------|
Expand Down Expand Up @@ -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` |
| 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

Expand Down
37 changes: 34 additions & 3 deletions __tests__/meta.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -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(() => {
Expand Down Expand Up @@ -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}}`
Expand All @@ -608,6 +609,7 @@ describe('push', () => {
main: 'mytag-master',
partial: [
'mytag-20200110',
'mytag-20200110-093000',
'mytag-tag-',
'mytag-baseref-',
'mytag-defbranch'
Expand All @@ -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'
Expand Down Expand Up @@ -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);
});

Expand Down
12 changes: 12 additions & 0 deletions __tests__/tag.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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}}`,
{
Expand Down
30 changes: 18 additions & 12 deletions dist/index.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/index.js.map

Large diffs are not rendered by default.

23 changes: 23 additions & 0 deletions dist/licenses.txt

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": {
Expand Down
32 changes: 27 additions & 5 deletions src/meta.ts
Original file line number Diff line number Diff line change
@@ -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';
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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);
}
});
}
Expand Down
2 changes: 1 addition & 1 deletion src/tag.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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];
Expand Down
9 changes: 8 additions & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -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==
Expand Down

0 comments on commit 90a1d5c

Please sign in to comment.