diff --git a/Dockerfile b/Dockerfile index 302f2de..477ef39 100644 --- a/Dockerfile +++ b/Dockerfile @@ -10,7 +10,7 @@ ADD entrypoint.sh /entrypoint.sh ENTRYPOINT ["/entrypoint.sh"] FROM runtime as testEnv -RUN apk add --no-cache coreutils bats ncurses +RUN apk add --no-cache coreutils bats ADD test.bats /test.bats ADD mock.sh /usr/local/bin/docker ADD mock.sh /usr/bin/date diff --git a/README.md b/README.md index ff97adf..a8edbfa 100644 --- a/README.md +++ b/README.md @@ -130,9 +130,6 @@ Use `buildoptions` when you want to configure [options](https://docs.docker.com/ ```yaml - name: Publish to Registry uses: elgohr/Publish-Docker-Github-Action@master - env: - MY_FIRST: variableContent - MY_SECOND: variableContent with: name: myDocker/repository username: ${{ secrets.DOCKER_USERNAME }} @@ -140,6 +137,19 @@ Use `buildoptions` when you want to configure [options](https://docs.docker.com/ buildoptions: "--compress --force-rm" ``` +### tags +Use `tags` when you want to bring your own tags (separated by comma). + +```yaml +- name: Publish to Registry + uses: elgohr/Publish-Docker-Github-Action@master + with: + name: myDocker/repository + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + tags: "latest,another" +``` + ### cache Use `cache` when you have big images, that you would only like to build partially (changed layers). > CAUTION: Docker builds will cache non-repoducable commands, such as installing packages. If you use this option, your packages will never update. To avoid this, run this action on a schedule with caching **disabled** to rebuild the cache periodically. @@ -167,6 +177,8 @@ jobs: ``` ### tag_names +> DEPRECATED: Please use tags instead. This option will be removed in a future release. + Use `tag_names` when you want to push tags/release by their git name (e.g. `refs/tags/MY_TAG_NAME`). > CAUTION: Images produced by this feature can be override by branches with the same name - without a way to restore. diff --git a/entrypoint.sh b/entrypoint.sh index 428c66c..2c3577d 100755 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -13,8 +13,11 @@ function main() { INPUT_NAME="${REGISTRY_NO_PROTOCOL}/${INPUT_NAME}" fi - translateDockerTag - DOCKERNAME="${INPUT_NAME}:${TAG}" + if uses "${INPUT_TAGS}"; then + TAGS=$(echo "${INPUT_TAGS}" | sed "s/,/ /g") + else + translateDockerTag + fi if uses "${INPUT_WORKDIR}"; then changeWorkingDirectory @@ -22,6 +25,8 @@ function main() { echo ${INPUT_PASSWORD} | docker login -u ${INPUT_USERNAME} --password-stdin ${INPUT_REGISTRY} + FIRST_TAG=$(echo $TAGS | cut -d ' ' -f1) + DOCKERNAME="${INPUT_NAME}:${FIRST_TAG}" BUILDPARAMS="" CONTEXT="." @@ -37,13 +42,13 @@ function main() { if usesBoolean "${INPUT_CACHE}"; then useBuildCache fi - if usesBoolean "${INPUT_SNAPSHOT}"; then - pushWithSnapshot - else - pushWithoutSnapshot + useSnapshot fi - echo "::set-output name=tag::${TAG}" + + push + + echo "::set-output name=tag::${FIRST_TAG}" DIGEST=$(docker inspect --format='{{index .RepoDigests 0}}' ${DOCKERNAME}) echo "::set-output name=digest::${DIGEST}" @@ -64,18 +69,18 @@ function isPartOfTheName() { function translateDockerTag() { local BRANCH=$(echo ${GITHUB_REF} | sed -e "s/refs\/heads\///g" | sed -e "s/\//-/g") if hasCustomTag; then - TAG=$(echo ${INPUT_NAME} | cut -d':' -f2) + TAGS=$(echo ${INPUT_NAME} | cut -d':' -f2) INPUT_NAME=$(echo ${INPUT_NAME} | cut -d':' -f1) elif isOnMaster; then - TAG="latest" + TAGS="latest" elif isGitTag && usesBoolean "${INPUT_TAG_NAMES}"; then - TAG=$(echo ${GITHUB_REF} | sed -e "s/refs\/tags\///g") + TAGS=$(echo ${GITHUB_REF} | sed -e "s/refs\/tags\///g") elif isGitTag; then - TAG="latest" + TAGS="latest" elif isPullRequest; then - TAG="${GITHUB_SHA}" + TAGS="${GITHUB_SHA}" else - TAG="${BRANCH}" + TAGS="${BRANCH}" fi; } @@ -124,20 +129,26 @@ function usesBoolean() { [ ! -z "${1}" ] && [ "${1}" = "true" ] } -function pushWithSnapshot() { +function useSnapshot() { local TIMESTAMP=`date +%Y%m%d%H%M%S` local SHORT_SHA=$(echo "${GITHUB_SHA}" | cut -c1-6) local SNAPSHOT_TAG="${TIMESTAMP}${SHORT_SHA}" - local SHA_DOCKER_NAME="${INPUT_NAME}:${SNAPSHOT_TAG}" - docker build ${INPUT_BUILDOPTIONS} ${BUILDPARAMS} -t ${DOCKERNAME} -t ${SHA_DOCKER_NAME} ${CONTEXT} - docker push ${DOCKERNAME} - docker push ${SHA_DOCKER_NAME} + TAGS="${TAGS} ${SNAPSHOT_TAG}" echo ::set-output name=snapshot-tag::"${SNAPSHOT_TAG}" } -function pushWithoutSnapshot() { - docker build ${INPUT_BUILDOPTIONS} ${BUILDPARAMS} -t ${DOCKERNAME} ${CONTEXT} - docker push ${DOCKERNAME} +function push() { + local BUILD_TAGS="" + for TAG in ${TAGS} + do + BUILD_TAGS="${BUILD_TAGS}-t ${INPUT_NAME}:${TAG} " + done + docker build ${INPUT_BUILDOPTIONS} ${BUILDPARAMS} ${BUILD_TAGS} ${CONTEXT} + + for TAG in ${TAGS} + do + docker push "${INPUT_NAME}:${TAG}" + done } main diff --git a/test.bats b/test.bats index f43601d..07aa657 100755 --- a/test.bats +++ b/test.bats @@ -441,6 +441,47 @@ teardown() { expectMockCalled "/usr/local/bin/docker build --compress --force-rm -t my/repository:latest -t my/repository:19700101010112169e ." } +@test "it provides a possibility to define multiple tags" { + export GITHUB_REF='refs/heads/master' + export INPUT_TAGS='A,B,C' + + run /entrypoint.sh + + expectMockCalled "/usr/local/bin/docker login -u USERNAME --password-stdin +/usr/local/bin/docker build -t my/repository:A -t my/repository:B -t my/repository:C . +/usr/local/bin/docker push my/repository:A +/usr/local/bin/docker push my/repository:B +/usr/local/bin/docker push my/repository:C +/usr/local/bin/docker inspect --format={{index .RepoDigests 0}} my/repository:A +/usr/local/bin/docker logout" +} + +@test "it provides a possibility to define one tag" { + export GITHUB_REF='refs/heads/master' + export INPUT_TAGS='A' + + run /entrypoint.sh + + expectMockCalled "/usr/local/bin/docker login -u USERNAME --password-stdin +/usr/local/bin/docker build -t my/repository:A . +/usr/local/bin/docker push my/repository:A +/usr/local/bin/docker inspect --format={{index .RepoDigests 0}} my/repository:A +/usr/local/bin/docker logout" +} + +@test "it caches the first image when multiple tags defined" { + export GITHUB_REF='refs/heads/master' + export INPUT_TAGS='A,B' + export INPUT_CACHE='true' + + run /entrypoint.sh + + expectMockCalled "/usr/local/bin/docker pull my/repository:A +/usr/local/bin/docker build --cache-from my/repository:A -t my/repository:A -t my/repository:B . +/usr/local/bin/docker push my/repository:A +/usr/local/bin/docker push my/repository:B" +} + function expectStdOutContains() { local expected=$(echo "${1}" | tr -d '\n') local got=$(echo "${output}" | tr -d '\n')