diff --git a/.github/docker/Dockerfile b/.github/docker/Dockerfile new file mode 100644 index 0000000..e2ccf2a --- /dev/null +++ b/.github/docker/Dockerfile @@ -0,0 +1,3 @@ +FROM alpine:3.10.3 + +ENTRYPOINT ["echo", "'hello world'"] \ No newline at end of file diff --git a/.github/workflows/dockerhub.yml b/.github/workflows/dockerhub.yml new file mode 100644 index 0000000..58263e8 --- /dev/null +++ b/.github/workflows/dockerhub.yml @@ -0,0 +1,22 @@ +name: Test Dockerhub Push +on: [push] + +jobs: + build: + runs-on: ubuntu-latest + steps: + + - name: Copy Repo Files + uses: actions/checkout@v1 + with: + fetch-depth: 1 + - name: Build and Publish Docker image to Dockerhub + uses: ./ + with: + TAG: 'my-optional-tag-name' + DOCKERFILE_PATH: '.github/docker/Dockerfile' + BUILD_CONTEXT: '.' + DOCKERHUB_REPOSITORY: 'pinkrobin/gpr-docker-publish-example' + DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }} + env: + REGISTRY_TOKEN: ${{ secrets.DOCKERHUB_PAT }} \ No newline at end of file diff --git a/.github/workflows/test.yaml b/.github/workflows/gpr.yaml similarity index 65% rename from .github/workflows/test.yaml rename to .github/workflows/gpr.yaml index 2274240..57acb9a 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/gpr.yaml @@ -1,4 +1,4 @@ -name: Tests +name: Test GPR Push on: push jobs: @@ -7,14 +7,15 @@ jobs: steps: - name: Copy Repo Files - uses: actions/checkout@master - + uses: actions/checkout@v1 + with: + fetch-depth: 1 - name: Publish Docker Image to GPR - uses: machine-learning-apps/gpr-docker-publish@master + uses: ./ with: IMAGE_NAME: 'test-docker-action-v2' TAG: 'my-optional-tag-name' DOCKERFILE_PATH: 'Dockerfile' BUILD_CONTEXT: '.' env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + REGISTRY_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..62e7820 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +# Created by .ignore support plugin (hsz.mobi) +.idea \ No newline at end of file diff --git a/README.md b/README.md index c825606..1bad440 100644 --- a/README.md +++ b/README.md @@ -23,11 +23,14 @@ The GitHub Package Registry allows you to develop your code and host your packag This Action will automatically tag each image as follows: - {Image_Name}:{shortSHA} + {Image_Name}:{IMAGE_TAG} Where: - `Image_Name` is provided by the user as an input. -- `shortSHA` is the first 12 characters of the GitHub SHA that triggered the action. +- `IMAGE_TAG` is either the first 12 characters of the GitHub commit SHA or the value of INPUT_IMAGE_TAG env variable + +Additionally it will use Git Tags pointing to the HEAD commit to create docker tags accordingly. +E.g. Git Tag v1.1 will result in an additional docker tag v1.1. ## Usage @@ -57,7 +60,19 @@ jobs: DOCKERFILE_PATH: 'argo/gpu.Dockerfile' BUILD_CONTEXT: 'argo/' env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + REGISTRY_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + #To access another docker registry like dockerhub you'll have to add `DOCKERHUB_UERNAME` and `DOCKERHUB_PAT` in github secrets. + - name: Build and Publish Docker image to Dockerhub instead of GPR + uses: saubermacherag/gpr-docker-publish@master + with: + IMAGE_TAG: 'v0.0' + DOCKERFILE_PATH: '.github/docker/Dockerfile' + BUILD_CONTEXT: './' + DOCKERHUB_REPOSITORY: 'pinkrobin/gpr-docker-publish-example' + DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }} + env: + REGISTRY_TOKEN: ${{ secrets.DOCKERHUB_PAT }} # This second step is illustrative and shows how to reference the # output variables. This is completely optional. @@ -80,12 +95,15 @@ jobs: 1. `cache`: if value is `true`, attempts to use the last pushed image as a cache. Default value is `false`. 2. `tag`: a custom tag you wish to assign to the image. +3. `DOCKERHUB_REPOSITORY`: if value is set, you don't need to set `IMAGE_NAME`. It will push the image to the given dockerhub repository instead of using GPR. +Why? Because Github Actions don't support downloading images without authentication at the moment. See: https://github.community/t5/GitHub-Actions/docker-pull-from-public-GitHub-Package-Registry-fail-with-quot/m-p/32782 +4. `DOCKERHUB_USERNAME`: required when `DOCKERHUB_REPOSITORY` set to true. ## Outputs You can reference the outputs of an action using [expression syntax](https://help.github.com/en/articles/contexts-and-expression-syntax-for-github-actions), as illustrated in the Example Pipeline above. -1. `IMAGE_SHA_NAME`: This is the `{Image_Name}:{shortSHA}` as described above. +1. `IMAGE_SHA_NAME`: This is the `{Image_Name}:{IMAGE_TAG}` as described above. 2. `IMAGE_URL`: This is the URL on GitHub where you can view your hosted Docker images. This will always be located at `https://github.com/{OWNER}/{REPOSITORY}/packages` in reference to the repository where the action was called. -These outputs are merely provided as convenience incase you want to use these values in subsequent steps. +These outputs are merely provided as convenience incase you want to use these values in subsequent steps. \ No newline at end of file diff --git a/action.yml b/action.yml index 3f08903..a77b716 100644 --- a/action.yml +++ b/action.yml @@ -4,22 +4,28 @@ author: Hamel Husain inputs: image_name: description: name of the image. Example - myContainer - require: true + required: true build_context: description: the path in your repo that will serve as the build context - require: true + required: true default: './' dockerfile_path: description: the full path (including the filename) to the dockerfile that you want to build - require: true + required: true default: ./Dockerfile cache: description: attempt to use last image as the cache - require: false + required: false default: false tag: - description: custom tag you want to assign to the image. - require: false + description: custom tag you want to assign to the image. + required: false + dockerhub_repository: + description: Optional input to push image to dockerhub repository instead of GPR. + required: false + dockerhub_username: + description: Required if dockerhub_repository set to true. + required: false outputs: IMAGE_SHA_NAME: description: name of the Docker Image including the tag diff --git a/entrypoint.sh b/entrypoint.sh index 42a87a2..2cac12d 100644 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -7,13 +7,13 @@ set -e #check inputs -if [[ -z "$GITHUB_TOKEN" ]]; then - echo "You must supply the environment variable GITHUB_TOKEN." +if [[ -z "$REGISTRY_TOKEN" ]]; then + echo "You must supply the environment variable REGISTRY_TOKEN." exit 1 fi -if [[ -z "$INPUT_IMAGE_NAME" ]]; then - echo "Set the IMAGE_NAME input." +if [[ -z "$INPUT_IMAGE_NAME" && -z "$INPUT_DOCKERHUB_REPOSITORY" ]]; then + echo "Set either the IMAGE_NAME or a valid DOCKERHUB_REPOSITORY." exit 1 fi @@ -30,17 +30,39 @@ fi # The following environment variables will be provided by the environment automatically: GITHUB_REPOSITORY, GITHUB_SHA -# send credentials through stdin (it is more secure) -user=$(curl -s -H "Authorization: token ${GITHUB_TOKEN}" https://api.github.com/user | jq -r .login) -# lowercase the username -username="$(echo ${user} | tr "[:upper:]" "[:lower:]")" -echo ${GITHUB_TOKEN} | docker login docker.pkg.github.com -u "${username}" --password-stdin +if [[ -z "$INPUT_DOCKERHUB_REPOSITORY" ]]; then + DOCKER_REGISTRY=docker.pkg.github.com + BASE_NAME="${DOCKER_REGISTRY}/${GITHUB_REPOSITORY}/${INPUT_IMAGE_NAME}" + # send credentials through stdin (it is more secure) + user=$(curl -s -H "Authorization: token ${REGISTRY_TOKEN}" https://api.github.com/user | jq -r .login) + # lowercase the username + username="$(echo ${user} | tr "[:upper:]" "[:lower:]")" +else + if [ -z "$INPUT_DOCKERHUB_USERNAME" ] + then + echo "If you use Docker Hub as repository please provide your username as DOCKERHUB_USERNAME." + exit 1 + fi + username="${INPUT_DOCKERHUB_USERNAME}" + BASE_NAME="${INPUT_DOCKERHUB_REPOSITORY}" +fi + + +echo ${REGISTRY_TOKEN} | docker login -u "${username}" --password-stdin ${DOCKER_REGISTRY} # Set Local Variables shortSHA=$(echo "${GITHUB_SHA}" | cut -c1-12) -BASE_NAME="docker.pkg.github.com/${GITHUB_REPOSITORY}/${INPUT_IMAGE_NAME}" SHA_NAME="${BASE_NAME}:${shortSHA}" +# Build additional tags based on the GIT Tags pointing to the current commit +ADDITIONAL_TAGS= +for git_tag in $(git tag -l --points-at HEAD) +do + echo "Processing ${git_tag}" + ADDITIONAL_TAGS="${ADDITIONAL_TAGS} -t ${BASE_NAME}:${git_tag}" +done +echo "following additional tags will be created: ${ADDITIONAL_TAGS}" + # Add Arguments For Caching BUILDPARAMS="" if [ "${INPUT_CACHE}" == "true" ]; then @@ -54,10 +76,10 @@ fi # Build The Container if [ "${INPUT_TAG}" ]; then CUSTOM_TAG="${BASE_NAME}:${INPUT_TAG}" - docker build $BUILDPARAMS -t ${SHA_NAME} -t ${BASE_NAME} -t ${CUSTOM_TAG} -f ${INPUT_DOCKERFILE_PATH} ${INPUT_BUILD_CONTEXT} + docker build $BUILDPARAMS -t ${SHA_NAME} -t ${BASE_NAME}${ADDITIONAL_TAGS} -t ${CUSTOM_TAG} -f ${INPUT_DOCKERFILE_PATH} ${INPUT_BUILD_CONTEXT} docker push ${CUSTOM_TAG} else - docker build $BUILDPARAMS -t ${SHA_NAME} -t ${BASE_NAME} -f ${INPUT_DOCKERFILE_PATH} ${INPUT_BUILD_CONTEXT} + docker build $BUILDPARAMS -t ${SHA_NAME} -t ${BASE_NAME}${ADDITIONAL_TAGS} -f ${INPUT_DOCKERFILE_PATH} ${INPUT_BUILD_CONTEXT} fi @@ -66,4 +88,8 @@ docker push ${BASE_NAME} docker push ${SHA_NAME} echo "::set-output name=IMAGE_SHA_NAME::${SHA_NAME}" -echo "::set-output name=IMAGE_URL::https://github.com/${GITHUB_REPOSITORY}/packages" +if [[ -z "$INPUT_DOCKERHUB_REPOSITORY" ]]; then + echo "::set-output name=IMAGE_URL::https://github.com/${GITHUB_REPOSITORY}/packages" +else + echo "::set-output name=IMAGE_URL::https://hub.docker.com/r/${INPUT_DOCKERHUB_REPOSITORY}" +fi