From de296110bfe4cdce3c2ecd875ab7bc6c3d8e7fdc Mon Sep 17 00:00:00 2001 From: Jeremy R DeYoung Date: Sat, 8 Apr 2023 12:25:16 -0400 Subject: [PATCH 1/5] adding docker_flags --- action.yaml | 10 +++++++--- entrypoint.sh | 30 +++++++++++++++--------------- 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/action.yaml b/action.yaml index 9a6f031..b677424 100644 --- a/action.yaml +++ b/action.yaml @@ -11,7 +11,7 @@ inputs: registry: description: The registry where the image should be pushed required: false - default: 'gcr.io' + default: "gcr.io" project_id: description: The project id required: true @@ -31,7 +31,7 @@ inputs: context: description: Docker build context required: false - default: '.' + default: "." target: description: Multi-staged build target required: false @@ -42,7 +42,11 @@ inputs: push_only: description: Skip the build step and just push an image required: false - default: false + default: "false" + docker_flags: + description: An optional param to pass flags & other build parameters to docker + required: false + default: "" runs: using: docker image: docker://ghcr.io/rafikfarhad/push-to-gcr-action:1.0.0 diff --git a/entrypoint.sh b/entrypoint.sh index 86e28dd..0a4a3f9 100755 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -6,25 +6,25 @@ #version :2.0.1 #usage :./entrypoint.sh #notes :Required env values are: INPUT_REGISTRY,INPUT_PROJECT_ID,INPUT_IMAGE_NAME -# Optional env values are: INPUT_GCLOUD_SERVICE_KEY,INPUT_IMAGE_TAG,INPUT_DOCKERFILE,INPUT_TARGET,INPUT_CONTEXT,INPUT_BUILD_ARGS +# Optional env values are: INPUT_GCLOUD_SERVICE_KEY,INPUT_IMAGE_TAG,INPUT_DOCKERFILE,INPUT_TARGET,INPUT_CONTEXT,INPUT_BUILD_ARGS,INPUT_DOCKER_FLAGS #bash_version :5.0.17(1)-release ################################################### ALL_IMAGE_TAG=() # detect service_account json flavour -if [ $GOOGLE_APPLICATION_CREDENTIALS ] && ls $GOOGLE_APPLICATION_CREDENTIALS; then +if [ "$GOOGLE_APPLICATION_CREDENTIALS" ] && ls "$GOOGLE_APPLICATION_CREDENTIALS"; then # workload identity echo "Workload identity found ..." - cp $GOOGLE_APPLICATION_CREDENTIALS /tmp/key.json + cp "$GOOGLE_APPLICATION_CREDENTIALS" /tmp/key.json else - if [ -z $INPUT_GCLOUD_SERVICE_KEY ]; then + if [ -z "$INPUT_GCLOUD_SERVICE_KEY" ]; then echo "GCLOUD_SERVICE_KEY is a required field when workload identity is not used. Exiting ..." exit 1 fi # persing service account json - if ! echo $INPUT_GCLOUD_SERVICE_KEY | python3 -m base64 -d >/tmp/key.json 2>/dev/null; then - if ! echo $INPUT_GCLOUD_SERVICE_KEY >/tmp/key.json 2>/dev/null; then + if ! echo "$INPUT_GCLOUD_SERVICE_KEY" | python3 -m base64 -d >/tmp/key.json 2>/dev/null; then + if ! echo "$INPUT_GCLOUD_SERVICE_KEY" >/tmp/key.json 2>/dev/null; then echo "Failed to get gcloud_service_key. It could be plain text or base64 encoded service account JSON file" exit 1 else @@ -42,7 +42,7 @@ if ! gcloud auth login --cred-file=/tmp/key.json --quiet; then exit 1 fi -if gcloud auth configure-docker $INPUT_REGISTRY --quiet; then +if gcloud auth configure-docker "$INPUT_REGISTRY" --quiet; then echo "Authentication successful to $INPUT_REGISTRY ..." else echo "Docker login failed. Exiting ..." @@ -53,7 +53,7 @@ fi ALL_IMAGE_TAG=($(python3 -c "print(' '.join(list(set([v for v in [v.strip() for v in '$INPUT_IMAGE_TAG'.split(',')] if v]))))")) # default to 'latest' when $ALL_IMAGE_TAG is empty -if [ ${#ALL_IMAGE_TAG[@]} -eq 0 ] ; then +if [ ${#ALL_IMAGE_TAG[@]} -eq 0 ]; then echo "INPUT_IMAGE_TAG tag is not parsable. Using latest by default" ALL_IMAGE_TAG=(latest) fi @@ -64,10 +64,10 @@ if [ "$INPUT_PUSH_ONLY" = true ]; then echo "Skipping image build ..." else echo "Building image ..." - [ -z $INPUT_TARGET ] && TARGET_ARG="" || TARGET_ARG="--target $INPUT_TARGET" - [ -z $INPUT_DOCKERFILE ] && FILE_ARG="" || FILE_ARG="--file $INPUT_DOCKERFILE" + [ -z "$INPUT_TARGET" ] && TARGET_ARG="" || TARGET_ARG="--target $INPUT_TARGET" + [ -z "$INPUT_DOCKERFILE" ] && FILE_ARG="" || FILE_ARG="--file $INPUT_DOCKERFILE" - if [ ! -z "$INPUT_BUILD_ARGS" ]; then + if [ -n "$INPUT_BUILD_ARGS" ]; then for ARG in $(echo "$INPUT_BUILD_ARGS" | tr ',' '\n'); do BUILD_PARAMS="$BUILD_PARAMS --build-arg ${ARG}" done @@ -75,7 +75,7 @@ else echo "docker build $BUILD_PARAMS $TARGET_ARG -t $TEMP_IMAGE_NAME $FILE_ARG $INPUT_CONTEXT" - if docker build $BUILD_PARAMS $TARGET_ARG -t $TEMP_IMAGE_NAME $FILE_ARG $INPUT_CONTEXT; then + if docker build "$INPUT_DOCKER_FLAGS" "$BUILD_PARAMS" '$TARGET_ARG' -t "$TEMP_IMAGE_NAME" "$FILE_ARG" "$INPUT_CONTEXT"; then echo "Image built ..." else echo "Image building failed. Exiting ..." @@ -83,7 +83,7 @@ else fi fi -for IMAGE_TAG in ${ALL_IMAGE_TAG[@]}; do +for IMAGE_TAG in "${ALL_IMAGE_TAG[@]}"; do IMAGE_NAME="$INPUT_REGISTRY/$INPUT_PROJECT_ID/$INPUT_IMAGE_NAME:$IMAGE_TAG" @@ -91,11 +91,11 @@ for IMAGE_TAG in ${ALL_IMAGE_TAG[@]}; do echo "Creating docker tag ..." - docker tag $TEMP_IMAGE_NAME $IMAGE_NAME + docker tag "$TEMP_IMAGE_NAME" "$IMAGE_NAME" echo "Pushing image $IMAGE_NAME ..." - if ! docker push $IMAGE_NAME; then + if ! docker push "$IMAGE_NAME"; then echo "Pushing failed. Exiting ..." exit 1 else From b2247c1e1084d422d74ef629f67b222b5aa5d6d3 Mon Sep 17 00:00:00 2001 From: Jeremy R DeYoung Date: Sat, 8 Apr 2023 12:45:01 -0400 Subject: [PATCH 2/5] switching to a different repo --- ReadMe.md | 20 ++++++++++++++++++-- action.yaml | 2 +- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/ReadMe.md b/ReadMe.md index bee8077..3a7416e 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -7,21 +7,27 @@ This action can be used to perform on every git `push` or every `tag` creation. ## Inputs ### `gcloud_service_key` -The service account key of google cloud. The JSON file can be encoded in base64 or in plain text. + +The service account key of google cloud. The JSON file can be encoded in base64 or in plain text. Prior to version 4.1 - This field is required. From version 5 - This field is optional when you are using workload identity with [google-github-actions/auth](https://github.com/google-github-actions/auth) + ### `registry` + The registry where the image should be pushed. Default `gcr.io`. ### `project_id` + The project id. This field is required. ### `image_name` + The image name. This field is required. ### `image_tag` + The tag for the image. To create multiple tags of the same image, provide a comma (`,`) separated tag name (e.g. `v2.1,v2,latest`). Default: `latest`. @@ -29,24 +35,30 @@ Default: `latest`. To use the pushed `Tag Name` as image tag, see the [example](https://github.com/RafikFarhad/push-to-gcr-github-action/blob/master/examples/build_only_tags.yml). ### `dockerfile` -The image building Dockerfile. + +The image building Dockerfile. If the context is not the root of the repository, `Dockerfile` from the context folder will be used. Default: `./Dockerfile`. ### `context` + The docker build context. Default: `.` ### `target` + If you use a multi-stage build and want to stop building at a certain image, you can use this field. The default value is empty. ### `build_args` + Pass a list of env vars as build-args for docker-build, separated by commas. ie: `HOST=db.default.svc.cluster.local:5432,USERNAME=db_user` ### `push_only` + If you want to skip the build step and just push the image built by any previous step, use this option. The default for this is `false`. ## Permissions + The service key you provided must have the `Storage Admin` permission to push the image to GCR. It is possible to use a lower access level `Storage Object Admin`, but it will work only if the registry is already created. You must also add the `Storage Legacy Bucket Reader` permission to the `artifacts..appspot.com` bucket for the given service account. @@ -57,9 +69,11 @@ It is possible to use a lower access level `Storage Object Admin`, but it will w To create service key/account visit [here](https://console.cloud.google.com/iam-admin/serviceaccounts) ### Workload Identity Federation + If you want to use [Workload Identity Federation](https://cloud.google.com/iam/docs/workload-identity-federation), follow the steps from [here](https://github.com/google-github-actions/auth#setting-up-workload-identity-federation) to set up **Workload Identity Federation** ## Example usage + ```yaml name: Push to GCR GitHub Action on: [push] @@ -87,11 +101,13 @@ jobs: dockerfile: ./docker/Dockerfile.prod context: ./docker ``` + [A complete workflow example](https://github.com/RafikFarhad/push-to-gcr-github-action/tree/master/.github/workflows) with all type of authentication flavour [More Example](https://github.com/RafikFarhad/push-to-gcr-github-action/tree/master/examples) ## Contribution + - Fork - Implement your awesome idea or fix a bug - Create PR 🎉 diff --git a/action.yaml b/action.yaml index b677424..bd54cef 100644 --- a/action.yaml +++ b/action.yaml @@ -49,4 +49,4 @@ inputs: default: "" runs: using: docker - image: docker://ghcr.io/rafikfarhad/push-to-gcr-action:1.0.0 + image: docker://ghcr.io/nextstepguru/push-to-gcr-action:1.0.0 From e154a52c9cebd8d01e173ac34b82bb7252a42d4f Mon Sep 17 00:00:00 2001 From: Jeremy R DeYoung Date: Sat, 8 Apr 2023 13:00:15 -0400 Subject: [PATCH 3/5] docker grc update --- action.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/action.yaml b/action.yaml index bd54cef..a96ad90 100644 --- a/action.yaml +++ b/action.yaml @@ -49,4 +49,4 @@ inputs: default: "" runs: using: docker - image: docker://ghcr.io/nextstepguru/push-to-gcr-action:1.0.0 + image: docker://gcr.io/nextstepguru/push-to-gcr-action:latest From daa17d23ddac99556aa8b2d68f55f5f78047aa39 Mon Sep 17 00:00:00 2001 From: Jeremy R DeYoung Date: Sat, 8 Apr 2023 14:28:23 -0400 Subject: [PATCH 4/5] using public repo --- action.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/action.yaml b/action.yaml index a96ad90..f055d4f 100644 --- a/action.yaml +++ b/action.yaml @@ -49,4 +49,4 @@ inputs: default: "" runs: using: docker - image: docker://gcr.io/nextstepguru/push-to-gcr-action:latest + image: docker://ghcr.io/nextstepguru/push-to-gcr-action:latest From 4716a0a521eac24d58beabe468f468a8b9d15710 Mon Sep 17 00:00:00 2001 From: Jeremy R DeYoung Date: Sat, 8 Apr 2023 14:43:30 -0400 Subject: [PATCH 5/5] . --- action.yaml | 2 +- entrypoint.sh | 28 ++++++++++++++-------------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/action.yaml b/action.yaml index f055d4f..846e0e0 100644 --- a/action.yaml +++ b/action.yaml @@ -49,4 +49,4 @@ inputs: default: "" runs: using: docker - image: docker://ghcr.io/nextstepguru/push-to-gcr-action:latest + image: docker://ghcr.io/nextstepguru/push-to-gcr-action:v1.0.0 diff --git a/entrypoint.sh b/entrypoint.sh index 0a4a3f9..aa46cb2 100755 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -13,18 +13,18 @@ ALL_IMAGE_TAG=() # detect service_account json flavour -if [ "$GOOGLE_APPLICATION_CREDENTIALS" ] && ls "$GOOGLE_APPLICATION_CREDENTIALS"; then +if [ $GOOGLE_APPLICATION_CREDENTIALS ] && ls $GOOGLE_APPLICATION_CREDENTIALS; then # workload identity echo "Workload identity found ..." - cp "$GOOGLE_APPLICATION_CREDENTIALS" /tmp/key.json + cp $GOOGLE_APPLICATION_CREDENTIALS /tmp/key.json else - if [ -z "$INPUT_GCLOUD_SERVICE_KEY" ]; then + if [ -z $INPUT_GCLOUD_SERVICE_KEY ]; then echo "GCLOUD_SERVICE_KEY is a required field when workload identity is not used. Exiting ..." exit 1 fi # persing service account json - if ! echo "$INPUT_GCLOUD_SERVICE_KEY" | python3 -m base64 -d >/tmp/key.json 2>/dev/null; then - if ! echo "$INPUT_GCLOUD_SERVICE_KEY" >/tmp/key.json 2>/dev/null; then + if ! echo $INPUT_GCLOUD_SERVICE_KEY | python3 -m base64 -d >/tmp/key.json 2>/dev/null; then + if ! echo $INPUT_GCLOUD_SERVICE_KEY >/tmp/key.json 2>/dev/null; then echo "Failed to get gcloud_service_key. It could be plain text or base64 encoded service account JSON file" exit 1 else @@ -42,7 +42,7 @@ if ! gcloud auth login --cred-file=/tmp/key.json --quiet; then exit 1 fi -if gcloud auth configure-docker "$INPUT_REGISTRY" --quiet; then +if gcloud auth configure-docker $INPUT_REGISTRY --quiet; then echo "Authentication successful to $INPUT_REGISTRY ..." else echo "Docker login failed. Exiting ..." @@ -64,18 +64,18 @@ if [ "$INPUT_PUSH_ONLY" = true ]; then echo "Skipping image build ..." else echo "Building image ..." - [ -z "$INPUT_TARGET" ] && TARGET_ARG="" || TARGET_ARG="--target $INPUT_TARGET" - [ -z "$INPUT_DOCKERFILE" ] && FILE_ARG="" || FILE_ARG="--file $INPUT_DOCKERFILE" + [ -z $INPUT_TARGET ] && TARGET_ARG="" || TARGET_ARG="--target $INPUT_TARGET" + [ -z $INPUT_DOCKERFILE ] && FILE_ARG="" || FILE_ARG="--file $INPUT_DOCKERFILE" - if [ -n "$INPUT_BUILD_ARGS" ]; then + if [ ! -z "$INPUT_BUILD_ARGS" ]; then for ARG in $(echo "$INPUT_BUILD_ARGS" | tr ',' '\n'); do BUILD_PARAMS="$BUILD_PARAMS --build-arg ${ARG}" done fi - echo "docker build $BUILD_PARAMS $TARGET_ARG -t $TEMP_IMAGE_NAME $FILE_ARG $INPUT_CONTEXT" + echo "docker build $INPUT_DOCKER_FLAGS $BUILD_PARAMS $TARGET_ARG -t $TEMP_IMAGE_NAME $FILE_ARG $INPUT_CONTEXT" - if docker build "$INPUT_DOCKER_FLAGS" "$BUILD_PARAMS" '$TARGET_ARG' -t "$TEMP_IMAGE_NAME" "$FILE_ARG" "$INPUT_CONTEXT"; then + if docker build $INPUT_DOCKER_FLAGS $BUILD_PARAMS $TARGET_ARG -t $TEMP_IMAGE_NAME $FILE_ARG $INPUT_CONTEXT; then echo "Image built ..." else echo "Image building failed. Exiting ..." @@ -83,7 +83,7 @@ else fi fi -for IMAGE_TAG in "${ALL_IMAGE_TAG[@]}"; do +for IMAGE_TAG in ${ALL_IMAGE_TAG[@]}; do IMAGE_NAME="$INPUT_REGISTRY/$INPUT_PROJECT_ID/$INPUT_IMAGE_NAME:$IMAGE_TAG" @@ -91,11 +91,11 @@ for IMAGE_TAG in "${ALL_IMAGE_TAG[@]}"; do echo "Creating docker tag ..." - docker tag "$TEMP_IMAGE_NAME" "$IMAGE_NAME" + docker tag $TEMP_IMAGE_NAME $IMAGE_NAME echo "Pushing image $IMAGE_NAME ..." - if ! docker push "$IMAGE_NAME"; then + if ! docker push $IMAGE_NAME; then echo "Pushing failed. Exiting ..." exit 1 else