From 667c5e692aad9eeedf94c7dae4793b22eadbddd6 Mon Sep 17 00:00:00 2001 From: rot1024 Date: Wed, 19 Feb 2025 01:13:04 +0900 Subject: [PATCH 1/3] feat: action to rollback cloud run if health check fails --- .github/actions/deploy-cloud-run/action.yml | 77 +++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 .github/actions/deploy-cloud-run/action.yml diff --git a/.github/actions/deploy-cloud-run/action.yml b/.github/actions/deploy-cloud-run/action.yml new file mode 100644 index 0000000..8664b71 --- /dev/null +++ b/.github/actions/deploy-cloud-run/action.yml @@ -0,0 +1,77 @@ +name: Deploy Cloud Run service +description: Create a new revision and rollback if health check fails +inputs: + region: + description: Region of the Cloud Run service + required: true + image: + description: Image nmae + required: true + service: + description: Name of the Cloud Run service + required: true + health_check_url: + description: Health check URL. If not provided, health check will be skipped + +runs: + using: composite + steps: + - name: Get current revision + id: get_revision + shell: bash + run: | + REV=$( \ + gcloud run services describe "${{ inputs.service }}" \ + --region "${{ inputs.region }}" \ + --format="value(status.latestReadyRevisionName)" \ + ) + echo "Current revision: $REV" + echo "revision=$REV" >> "$GITHUB_OUTPUT" + + - name: Deploy + shell: bash + run: | + gcloud run deploy "{{ inputs.service }}" \ + --image "${{ inputs.image }}" \ + --region "${{ inputs.region }}" \ + --platform managed \ + --quiet + + # ensure that the traffic is updated to the latest revision always + - name: Update traffic + shell: bash + run: | + gcloud run services update-traffic "${{ inputs.service }}" \ + --to-latest \ + --region "${{ inputs.region }}" + + - name: Health check + id: health_check + if: ${{ inputs.health_check_url }} + shell: bash + run: | + RESULT=`curl -s -o /dev/null -w "%{http_code}" "${{ inputs.health_check_url }}"` + echo "Status code is $RESULT" + echo "status_code=$RESULT" >> "$GITHUB_OUTPUT" + if [ $RESULT -ge 300 ]; then + echo "Health check failed" + echo "error=true" >> "$GITHUB_OUTPUT" + fi + + - name: Rollback + if: ${{ steps.health_check.outputs.error }} + shell: bash + run: | + gcloud run services update-traffic "${{ inputs.service }}" \ + --to-revision="${{ steps.get_revision.outputs.revision }}" \ + --region "${{ inputs.region }}" + + - name: Finish + shell: bash + run: | + if [ -z "${{ steps.health_check.outputs.error }}" ]; then + echo "Deployment successful" + else + echo "Deployment failed" + exit 1 + fi From bb82f34c870178a7285ddde62b61920423e6beeb Mon Sep 17 00:00:00 2001 From: rot1024 Date: Wed, 19 Feb 2025 01:20:05 +0900 Subject: [PATCH 2/3] update --- .github/actions/deploy-cloud-run/action.yml | 24 ++++++++++++--------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/.github/actions/deploy-cloud-run/action.yml b/.github/actions/deploy-cloud-run/action.yml index 8664b71..c4007e1 100644 --- a/.github/actions/deploy-cloud-run/action.yml +++ b/.github/actions/deploy-cloud-run/action.yml @@ -5,13 +5,13 @@ inputs: description: Region of the Cloud Run service required: true image: - description: Image nmae + description: Image name required: true service: description: Name of the Cloud Run service required: true health_check_url: - description: Health check URL. If not provided, health check will be skipped + description: Health check URL. Multiple URLs can be separated by line breaks. If not provided, health check will be skipped. runs: using: composite @@ -31,7 +31,7 @@ runs: - name: Deploy shell: bash run: | - gcloud run deploy "{{ inputs.service }}" \ + gcloud run deploy "${{ inputs.service }}" \ --image "${{ inputs.image }}" \ --region "${{ inputs.region }}" \ --platform managed \ @@ -45,18 +45,22 @@ runs: --to-latest \ --region "${{ inputs.region }}" + # if the URL is invalid, curl itself will return an error code - name: Health check id: health_check if: ${{ inputs.health_check_url }} shell: bash run: | - RESULT=`curl -s -o /dev/null -w "%{http_code}" "${{ inputs.health_check_url }}"` - echo "Status code is $RESULT" - echo "status_code=$RESULT" >> "$GITHUB_OUTPUT" - if [ $RESULT -ge 300 ]; then - echo "Health check failed" - echo "error=true" >> "$GITHUB_OUTPUT" - fi + for url in ${{ inputs.health_check_url }}; do + echo "Checking health of $url" + RESULT=`curl -m 10 -s -o /dev/null -w "%{http_code}" "$url"` + echo "Status code is $RESULT" + if [ $RESULT -ge 300 ]; then + echo "Health check failed" + echo "error=true" >> "$GITHUB_OUTPUT" + break + fi + done - name: Rollback if: ${{ steps.health_check.outputs.error }} From bb8ed7bd4fd27b18c7818a5bac05ea143c5d4751 Mon Sep 17 00:00:00 2001 From: rot1024 Date: Wed, 19 Feb 2025 01:28:04 +0900 Subject: [PATCH 3/3] fix --- .github/actions/deploy-cloud-run/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/deploy-cloud-run/action.yml b/.github/actions/deploy-cloud-run/action.yml index c4007e1..5da31ca 100644 --- a/.github/actions/deploy-cloud-run/action.yml +++ b/.github/actions/deploy-cloud-run/action.yml @@ -63,7 +63,7 @@ runs: done - name: Rollback - if: ${{ steps.health_check.outputs.error }} + if: ${{ steps.health_check.outputs.error && steps.get_revision.outputs.revision }} shell: bash run: | gcloud run services update-traffic "${{ inputs.service }}" \