diff --git a/README.md b/README.md index 686a2cdc..fcbfaced 100644 --- a/README.md +++ b/README.md @@ -187,3 +187,16 @@ with: password: ${{ secrets.DOCKER_PASSWORD }} tag_names: true ``` + +### tag_semver +Use `tag_semver` when you want to push tags using the semver syntax by their git name (e.g. `refs/tags/v1.2.3`). This will push four +docker tags: `1.2.3`, `1.2` and `1`. A prefix 'v' will automatically be removed. +> CAUTION: Images produced by this feature can be override by branches with the same name - without a way to restore. + +```yaml +with: + name: myDocker/repository + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + tag_semver: true +``` diff --git a/action.yml b/action.yml index 3d5289cc..43fe4164 100644 --- a/action.yml +++ b/action.yml @@ -35,6 +35,9 @@ inputs: tag_names: description: 'Use tag_names when you want to push tags/release by their git name' required: false + tag_semver: + description: 'Push semver docker tags. e.g. image:1.2.3, image:1.2, image:1' + required: false outputs: tag: description: 'Is the tag, which was pushed' diff --git a/entrypoint.sh b/entrypoint.sh index 2c3577d8..1cf468ca 100755 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -73,6 +73,8 @@ function translateDockerTag() { INPUT_NAME=$(echo ${INPUT_NAME} | cut -d':' -f1) elif isOnMaster; then TAGS="latest" + elif isGitTag && usesBoolean "${INPUT_TAG_SEMVER}" && isSemver "${GITHUB_REF}"; then + TAGS=$(echo ${GITHUB_REF} | sed -e "s/refs\/tags\///g" | sed -E "s/v?([0-9]+)\.([0-9+])\.([0-9]+)/\1.\2.\3 \1.\2 \1/g") elif isGitTag && usesBoolean "${INPUT_TAG_NAMES}"; then TAGS=$(echo ${GITHUB_REF} | sed -e "s/refs\/tags\///g") elif isGitTag; then @@ -129,6 +131,10 @@ function usesBoolean() { [ ! -z "${1}" ] && [ "${1}" = "true" ] } +function isSemver() { + echo "${1}" | grep -Eq '^refs/tags/v?([0-9]+)\.([0-9+])\.([0-9]+)$' +} + function useSnapshot() { local TIMESTAMP=`date +%Y%m%d%H%M%S` local SHORT_SHA=$(echo "${GITHUB_SHA}" | cut -c1-6) diff --git a/test.bats b/test.bats index 07aa657d..01a6b8fe 100755 --- a/test.bats +++ b/test.bats @@ -98,6 +98,64 @@ teardown() { /usr/local/bin/docker push my/repository:latest" } +@test "with tag semver it pushes tags using the major and minor versions" { + export GITHUB_REF='refs/tags/v1.2.34' + export INPUT_TAG_SEMVER="true" + + run /entrypoint.sh + + expectStdOutContains "::set-output name=tag::1.2.34" + + expectMockCalled "/usr/local/bin/docker login -u USERNAME --password-stdin +/usr/local/bin/docker build -t my/repository:1.2.34 -t my/repository:1.2 -t my/repository:1 . +/usr/local/bin/docker push my/repository:1.2.34 +/usr/local/bin/docker push my/repository:1.2 +/usr/local/bin/docker push my/repository:1 +/usr/local/bin/docker inspect --format={{index .RepoDigests 0}} my/repository:1.2.34 +/usr/local/bin/docker logout" +} + +@test "with tag semver it pushes tags without 'v' prefix" { + export GITHUB_REF='refs/tags/1.2.34' + export INPUT_TAG_SEMVER="true" + + run /entrypoint.sh + + expectStdOutContains "::set-output name=tag::1.2.34" + + expectMockCalled "/usr/local/bin/docker login -u USERNAME --password-stdin +/usr/local/bin/docker build -t my/repository:1.2.34 -t my/repository:1.2 -t my/repository:1 . +/usr/local/bin/docker push my/repository:1.2.34 +/usr/local/bin/docker push my/repository:1.2 +/usr/local/bin/docker push my/repository:1 +/usr/local/bin/docker inspect --format={{index .RepoDigests 0}} my/repository:1.2.34 +/usr/local/bin/docker logout" +} + +@test "with tag semver it pushes latest when tag has invalid semver version" { + export GITHUB_REF='refs/tags/vAA.BB.CC' + export INPUT_TAG_SEMVER="true" + + run /entrypoint.sh + + expectStdOutContains "::set-output name=tag::latest" + + expectMockCalled "/usr/local/bin/docker build -t my/repository:latest . +/usr/local/bin/docker push my/repository:latest" +} + +@test "with tag semver set to false it doesn't push tags using semver" { + export GITHUB_REF='refs/tags/v1.2.34' + export INPUT_TAG_NAMES="false" + + run /entrypoint.sh + + expectStdOutContains "::set-output name=tag::latest" + + expectMockCalled "/usr/local/bin/docker build -t my/repository:latest . +/usr/local/bin/docker push my/repository:latest" +} + @test "it pushes specific Dockerfile to latest" { export INPUT_DOCKERFILE='MyDockerFileName'