Skip to content

Commit

Permalink
Merge pull request #44 from HackerHappyHour/add-support-for-extra-tags
Browse files Browse the repository at this point in the history
BREAKING: Add support for extra tags
  • Loading branch information
LongLiveCHIEF authored Dec 5, 2020
2 parents 477c21d + 55d97e8 commit d136e28
Show file tree
Hide file tree
Showing 11 changed files with 207 additions and 5,775 deletions.
48 changes: 39 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ attached to the tags.
| Name | Type | Required | Description |
|------------------|---------|------------|------------------------------------|
| `image_name` | `String` | no | an image to pass to tags for docker, omit if not using for docker images |
| `latest` | `Boolean` | yes (default `false`)| The strategies to parse the tag paylod with |
| `tags` | [csv/list of strategies](#strategy-parsing), optionally add `::<Boolean>` | yes | The strategies to parse the tag paylod with. See [conditionally including a strategy](#conditionally-including-a-strategy) to learn how to specify conditions for each strategy|
| `tags` | [csv/list of strategies](#strategy-parsing), optionally add `::<Boolean>` | yes | The strategies to parse the tag paylod with. See [conditionally including a strategy](#conditionally-including-a-strategy) to learn how to use conditional expressions for each strategy|
| `tag_name` | `String` | yes (default is `X.Y.Z`) | A semver parseable string |
| `extra_tags` | `csv/list` | no | Optional extra tags appended to output list of tags. These are not parsed by semver, but support conditional expressions |


## Outputs
Expand All @@ -52,10 +52,10 @@ steps:
id: tagging-strategy
uses: HackerHappyHour/tagging-strategy@v2
with:
latest: true
tags: '%X%, %X%-debian, %X.Y%, %X.Y%-debian'
tag_name: '1.0.0'
image_name: hello/world
extra_tags: 'latest,debian,edge'

-
uses: docker/setup-buildx-action@v1
Expand All @@ -82,6 +82,26 @@ Digest OS/ARCH
7fbe9ad1fbc6 linux/arm/v7
ff87a758e329 linux/arm64

Tag
===
debian

Digest OS/ARCH
====== =======
57f8a1d499bb linux/amd64
7fbe9ad1fbc6 linux/arm/v7
ff87a758e329 linux/arm64

Tag
===
edge

Digest OS/ARCH
====== =======
57f8a1d499bb linux/amd64
7fbe9ad1fbc6 linux/arm/v7
ff87a758e329 linux/arm64

Tag
===
1
Expand Down Expand Up @@ -131,6 +151,7 @@ ff87a758e329 linux/arm64
The forumula for each individual entry of the `tags` input: `pattern`+`<prerelease>`+`<variant>`
#### Conditionally Including a Strategy
You can also add a `::<Boolean>` on the end of each tag provided, which allows you to dynamically specify
conditions for which each strategy provided is included. This allows you to use github action [expressions][expressions]
that resolve to `true` or `false` to conditionally specify whether or not to include a given strategy in the output.
Expand All @@ -151,11 +172,11 @@ steps:
uses: HackerHappyHour/tagging-strategy@v2
if: ${{ github.event_name == 'release' }}
with:
latest: true
tags: |
%X%-foobar::${{ github.event.action != 'prerelease' }}
%X.Y%-foobar::${{ github.event.action != 'prerelease' }}
%X.Y.Z%-foobar
extra_tags: 'latest'
```

#### Pattern
Expand All @@ -177,7 +198,6 @@ Valid pattern examples include:

Sections of the pattern are denoted using `%`. Currently only `X`, `Y`, and `Z` will be translated.

`latest` - returns `latest`
`X` - returns Major version
`Y` - returns Minor version
`Z` - returns Patch version
Expand All @@ -187,7 +207,7 @@ Sections of the pattern are denoted using `%`. Currently only `X`, `Y`, and `Z`
A `prerelease` is parsed from the `tag_name` from your release event. This string
will match anything that follows the identified version number from the tag.

For example when created a release tag in github using the examples below,
For example when creating a release tag in github using the examples below,
the highlighted sections indicate what would be returned as the `prerelease` value.

1.0.0`-beta1`
Expand All @@ -210,7 +230,11 @@ Examples of using a variant:

## Examples

All of the features supported by this plugin are used in the [OctoPrint/octoprint-docker release workflow][octoprint-docker-release-workflow].
Check it out for the best example of the flexibility and power this action provides.

### From Release on repo

```yaml
jobs:
myReleaseExample:
Expand All @@ -224,13 +248,14 @@ jobs:
uses: HackerHappyHour/tagging-strategy@v2
if: ${{ github.event_name == 'release' }}
with:
latest: true
tags: |
%X%-foobar
%X.Y%-foobar
%X.Y.Z%-foobar
tag_name: ${{ github.ref }}
image_name: foo/bar
extra_tags: |
latest
- name: Setup Buildx
id: setup
uses: crazy-max/ghaction-docker-buildx@v3
Expand Down Expand Up @@ -289,13 +314,14 @@ jobs:
id: tagging
uses: HackerHappyHour/tagging-strategy@v2
with:
latest: github.event_type
tags: |
%X%-foobar
%X.Y%-foobar
%X.Y.Z%-foobar
tag_name: ${{ github.event.client_payload.tag_name }}
image_name: foo/bar
extra_tags: |
latest
- name: Use Tag
run: echo ${{ steps.tagging.outputs.tags }}

Expand All @@ -313,9 +339,13 @@ steps:
id: tags
uses: HackerHappyHour/tagging-strategy@v2
with:
latest: ${{ github.event_name == 'push'}}
tags: |
%X%
extra_tags: |
latest::${{ github.event_name == 'push'}}
```
[docker-build-and-push]: https://github.com/docker/build-push-action
[expressions]: https://docs.github.com/en/free-pro-team@latest/actions/reference/context-and-expression-syntax-for-github-actions
[release]: https://docs.github.com/en/actions/reference/events-that-trigger-workflows#release
[octoprint-docker-release-workflow]: https://github.com/OctoPrint/octoprint-docker/blob/master/.github/workflows/octoprint-release.yml
36 changes: 22 additions & 14 deletions __tests__/__data__/taggingStrategy.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,31 +21,31 @@ exports.scenarios = [
{inputTags:'%X%,%X.Y%::\'false\',%X.Y.Z%::true', tagName:'1.0.0', imageName: 'foo/bar'}
],
[
'foo/bar:1,foo/bar:1.0,foo/bar:1.0.0,foo/bar:latest',
{inputTags:'%X%,%X.Y%,%X.Y.Z%', tagName:'1.0.0', imageName: 'foo/bar', latest: 'TRUE'}
'foo/bar:1,foo/bar:1.0,foo/bar:1.0.0',
{inputTags:'%X%,%X.Y%,%X.Y.Z%', tagName:'1.0.0', imageName: 'foo/bar' }
],
[
'foo/bar:1.0,foo/bar:1.0.0,foo/bar:latest',
{inputTags:'%X%::false,%X.Y%::true,%X.Y.Z%::\'true\'', tagName:'1.0.0', imageName: 'foo/bar', latest: 'TRUE'}
'foo/bar:1.0,foo/bar:1.0.0',
{inputTags:'%X%::false,%X.Y%::true,%X.Y.Z%::\'true\'', tagName:'1.0.0', imageName: 'foo/bar'}
],
[
'1,1.0,1.0.0,latest',
{inputTags:'%X%,%X.Y%,%X.Y.Z%', tagName:'1.0.0', latest: 'truE'}
'1,1.0,1.0.0',
{inputTags:'%X%,%X.Y%,%X.Y.Z%', tagName:'1.0.0'}
],
[
'1-foobar,1.0-foobar,1.0.0-foobar',
{inputTags:'%X%-foobar,%X.Y%-foobar,%X.Y.Z%-foobar', tagName:'1.0.0'}
],
[
'1-foobar,1.0-foobar,1.0.0-foobar,latest',{inputTags:'%X%-foobar,%X.Y%-foobar,%X.Y.Z%-foobar', tagName:'1.0.0', latest: 'TRue'}
'1-foobar,1.0-foobar,1.0.0-foobar',{inputTags:'%X%-foobar,%X.Y%-foobar,%X.Y.Z%-foobar', tagName:'1.0.0'}
],
[
'hello/world:1-foobar,hello/world:1.0-foobar,hello/world:1.0.0-foobar,hello/world:latest',
{inputTags:'%X%-foobar,%X.Y%-foobar,%X.Y.Z%-foobar', tagName:'1.0.0', latest: 'true', imageName: 'hello/world'}
'hello/world:1-foobar,hello/world:1.0-foobar,hello/world:1.0.0-foobar',
{inputTags:'%X%-foobar,%X.Y%-foobar,%X.Y.Z%-foobar', tagName:'1.0.0', imageName: 'hello/world'}
],
[
'hello/world:1-foobar,hello/world:1.0.0-foobar,hello/world:latest',
{inputTags:'%X%-foobar,%X.Y%-foobar::false,%X.Y.Z%-foobar', tagName:'1.0.0', latest: 'true', imageName: 'hello/world'}
'hello/world:1-foobar,hello/world:1.0.0-foobar',
{inputTags:'%X%-foobar,%X.Y%-foobar::false,%X.Y.Z%-foobar', tagName:'1.0.0', imageName: 'hello/world'}
],
[
'1-rc1,1.0-rc1,1.0.0-rc1',
Expand All @@ -60,11 +60,19 @@ exports.scenarios = [
{inputTags:'%X%-foobar,%X.Y%-foobar,%X.Y.Z%-foobar', tagName:'1.0.0rc1', imageName: 'hello/world'}
],
[
'hello/world:1-rc1-foobar,hello/world:1.0-rc1-foobar,hello/world:1.0.0-rc1-foobar,hello/world:latest',
{latest: 'True', inputTags:'%X%-foobar,%X.Y%-foobar,%X.Y.Z%-foobar', tagName:'1.0.0rc1', imageName: 'hello/world'}
'hello/world:1-rc1-foobar,hello/world:1.0-rc1-foobar,hello/world:1.0.0-rc1-foobar',
{inputTags:'%X%-foobar,%X.Y%-foobar,%X.Y.Z%-foobar', tagName:'1.0.0rc1', imageName: 'hello/world'}
],
[
'hello/world:1-rc1-foobar,hello/world:1.0-rc1-foobar,hello/world:1.0.0-rc1-foobar',
{latest: 'false', inputTags:'%X%-foobar,%X.Y%-foobar,%X.Y.Z%-foobar', tagName:'1.0.0rc1', imageName: 'hello/world'}
{inputTags:'%X%-foobar,%X.Y%-foobar,%X.Y.Z%-foobar', tagName:'1.0.0rc1', imageName: 'hello/world'}
],
[
'hello/world:1-rc1-foobar,hello/world:1.0-rc1-foobar,hello/world:1.0.0-rc1-foobar,hello/world:latest,hello/world:edge',
{inputTags:'%X%-foobar,%X.Y%-foobar,%X.Y.Z%-foobar', tagName:'1.0.0rc1', imageName: 'hello/world', extraTags: 'latest,edge'}
],
[
'hello/world:1-rc1-foobar,hello/world:1.0-rc1-foobar,hello/world:1.0.0-rc1-foobar,hello/world:edge',
{inputTags:'%X%-foobar,%X.Y%-foobar,%X.Y.Z%-foobar', tagName:'1.0.0rc1', imageName: 'hello/world', extraTags: 'latest::false,edge::true'}
],
]
1 change: 1 addition & 0 deletions __tests__/__data__/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,5 @@ exports.getInputListScenarios = [
// [given, expected]
exports.conditionalTagsReducerScenarios = [
[['%X%', '%X.Y%::true', '%X.Y.Z%::false'],['%X%', '%X.Y%']],
[['latest::true'], ['latest']]
]
12 changes: 7 additions & 5 deletions __tests__/utils.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const {getInputBoolean, getInputList, conditionalTagsReducer} = require('../src/utils')
const {conditionalTagsReducerScenarios, getInputBooleanScenarios, getInputListScenarios} = require('./__data__/utils')
const {tagsReducer, getInputBoolean, getInputList} = require('../src/utils')
const {getInputBooleanScenarios, getInputListScenarios} = require('./__data__/utils')

describe('getInputBoolean', () => {
test.each(getInputBooleanScenarios)('%s should be %s', (scenario, expected) => {
Expand All @@ -16,9 +16,11 @@ describe('getInputList', ()=>{

})

describe.skip('conditionalTagFilter', () => {
describe('tagsReducer', () => {
test('reduces imperative booleans',() => {
let inputTags = ['%X%', '%X.Y%::true', '%X.Y.Z%::false', '%X%-foobar::false', '%X.Y%-foobar::true']
expect(inputTags.reduce(conditionalTagsReducer)).toEqual(['%X%', '%X.Y%','%X.Y%-foobar'])

let extraTagsOutput = ['latest::true', 'edge::true', 'canary::false'].reduce(tagsReducer, [])
expect(extraTagsOutput).toEqual(['latest', 'edge'])
})

})
7 changes: 3 additions & 4 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@ branding:
icon: 'check-square'
color: 'orange'
inputs:
latest:
description: 'whether or not to produce a latest tag'
required: false
default: 'false'
tags:
description: 'The tagging strategy for this run'
required: true
Expand All @@ -18,6 +14,9 @@ inputs:
image_name:
description: 'an image to pass to tags for docker, omit if not using with docker'
required: false
extra_tags:
description: 'csv/list of extra tags. These are not parsed by semver, but support conditional expressions'
required: false
outputs:
tags:
description: 'Outputs a comma-separated list of tags'
Expand Down
Loading

0 comments on commit d136e28

Please sign in to comment.