diff --git a/.github/workflows/cd-ec2-ansible.yml b/.github/workflows/cd-ec2-ansible.yml new file mode 100644 index 0000000..f64a833 --- /dev/null +++ b/.github/workflows/cd-ec2-ansible.yml @@ -0,0 +1,411 @@ +############################################################################### +# CD — Option 3: EC2 / Ansible Deployment +############################################################################### +# +# Repository separation: +# mypythonproject1 ← app code + release orchestration (YOU ARE HERE) +# mypythonproject1-infra3 ← EC2 Terraform + Ansible deployment execution +# +# Pipeline: +# CI passes on develop → build + push images (staging tag) → dispatch +# to infra3 ansible workflow → verify +# +# Tag v* is pushed → build + push images (semver + latest) → dispatch +# to infra3 ansible workflow → verify +# +# Manual rollback → dispatch rollback to infra3 ansible workflow +# and wait for completion +############################################################################### +name: "CD — EC2/Ansible" + +on: + workflow_run: + workflows: ["CI"] + branches: [develop] + types: [completed] + push: + tags: + - "v*" + workflow_dispatch: + inputs: + environment: + description: "Target environment" + required: true + type: choice + options: [staging, prod] + default: staging + operation: + description: "Operation to run" + required: true + type: choice + options: [deploy, rollback] + default: deploy + rollback_tag: + description: "Required when operation=rollback (for example: staging-a1b2c3d or v1.2.3)" + required: false + type: string + +permissions: + contents: read + +concurrency: + group: >- + ${{ startsWith(github.ref, 'refs/tags/v') && 'cd-ec2-production' + || github.event_name == 'workflow_dispatch' && format('cd-ec2-{0}-{1}', inputs.environment, inputs.operation) + || 'cd-ec2-staging' }} + cancel-in-progress: ${{ !startsWith(github.ref, 'refs/tags/v') }} + +jobs: + build-staging: + name: "Build & Push [staging] (${{ matrix.service }})" + runs-on: ubuntu-latest + timeout-minutes: 20 + if: > + (github.event_name == 'workflow_run' + && github.event.workflow_run.conclusion == 'success') || + (github.event_name == 'workflow_dispatch' + && inputs.environment == 'staging' + && inputs.operation == 'deploy') + environment: staging + strategy: + matrix: + service: [backend, frontend] + fail-fast: true + permissions: + contents: read + id-token: write + steps: + - uses: actions/checkout@v4 + with: + ref: ${{ github.event.workflow_run.head_sha || github.sha }} + + - name: Authenticate with AWS + uses: ./.github/actions/aws-auth + with: + role-arn: ${{ secrets.AWS_ROLE_TO_ASSUME }} + aws-region: ${{ secrets.AWS_REGION }} + + - name: Log in to Amazon ECR + id: ecr-login + uses: aws-actions/amazon-ecr-login@v2 + + - name: Build, tag & push + uses: ./.github/actions/docker-build + with: + context: ./${{ matrix.service }} + dockerfile: ./${{ matrix.service }}/Dockerfile + image-name: mypythonproject1/${{ matrix.service }} + registry: ${{ steps.ecr-login.outputs.registry }} + tags: | + type=raw,value=staging + type=sha,prefix=staging-,format=short + build-args: | + BUILD_ENV=staging + GIT_SHA=${{ github.event.workflow_run.head_sha || github.sha }} + platforms: linux/amd64 + scan: "true" + scan-severity: "CRITICAL,HIGH" + scan-exit-code: "0" + cache-scope: ${{ matrix.service }}-staging + + ec2-deploy-staging: + name: "EC2 Deploy [staging] via Ansible" + runs-on: ubuntu-latest + timeout-minutes: 5 + needs: [build-staging] + if: needs.build-staging.result == 'success' + environment: staging + steps: + - name: Dispatch ansible-ec2-deploy to infra3 repo + uses: actions/github-script@v7 + with: + github-token: ${{ secrets.INFRA_DEPLOY_TOKEN }} + script: | + const headSha = (context.payload.workflow_run && context.payload.workflow_run.head_sha) || context.sha; + const imageTag = `staging-${headSha.substring(0, 7)}`; + await github.rest.actions.createWorkflowDispatch({ + owner: context.repo.owner, + repo: 'mypythonproject1-infra3', + workflow_id: 'ansible-ec2-deploy.yml', + ref: 'main', + inputs: { + environment: 'staging', + operation: 'deploy', + image_tag: imageTag, + }, + }); + core.notice(`Dispatched ansible-ec2-deploy on mypythonproject1-infra3 (staging, tag=${imageTag})`); + + ec2-verify-staging: + name: "Verify EC2 Deploy [staging]" + runs-on: ubuntu-latest + timeout-minutes: 30 + needs: [ec2-deploy-staging] + if: needs.ec2-deploy-staging.result == 'success' + environment: staging + steps: + - name: Wait for infra3 ansible workflow result + uses: actions/github-script@v7 + with: + github-token: ${{ secrets.INFRA_DEPLOY_TOKEN }} + script: | + const owner = context.repo.owner; + const repo = 'mypythonproject1-infra3'; + const expectedTag = `${((context.payload.workflow_run && context.payload.workflow_run.head_sha) || context.sha).substring(0, 7)}`; + const tagNeedle = `tag=staging-${expectedTag}`; + const deadline = Date.now() + 30 * 60 * 1000; + + while (Date.now() < deadline) { + const resp = await github.rest.actions.listWorkflowRuns({ + owner, + repo, + workflow_id: 'ansible-ec2-deploy.yml', + event: 'workflow_dispatch', + per_page: 20, + }); + + const matchedRun = resp.data.workflow_runs.find((r) => { + const title = (r.display_title || '').toLowerCase(); + return title.includes('[staging]') && title.includes(tagNeedle.toLowerCase()); + }); + + if (!matchedRun || matchedRun.status !== 'completed') { + await new Promise((resolve) => setTimeout(resolve, 15000)); + continue; + } + + if (matchedRun.conclusion !== 'success') { + core.setFailed(`infra3 ansible deploy failed: ${matchedRun.html_url}`); + return; + } + + core.notice(`infra3 ansible deploy succeeded: ${matchedRun.html_url}`); + return; + } + + core.setFailed('Timed out waiting for infra3 ansible staging deployment run to complete'); + + build-production: + name: "Build & Push [production] (${{ matrix.service }})" + runs-on: ubuntu-latest + timeout-minutes: 20 + if: startsWith(github.ref, 'refs/tags/v') + environment: prod + strategy: + matrix: + service: [backend, frontend] + fail-fast: true + permissions: + contents: read + id-token: write + steps: + - uses: actions/checkout@v4 + with: + ref: ${{ github.ref }} + + - name: Resolve version tag + id: ver + run: | + TAG="${GITHUB_REF#refs/tags/}" + echo "tag=$TAG" >> "$GITHUB_OUTPUT" + echo "sha_short=$(git rev-parse --short HEAD)" >> "$GITHUB_OUTPUT" + + - name: Authenticate with AWS + uses: ./.github/actions/aws-auth + with: + role-arn: ${{ secrets.AWS_ROLE_TO_ASSUME }} + aws-region: ${{ secrets.AWS_REGION }} + + - name: Log in to Amazon ECR + id: ecr-login + uses: aws-actions/amazon-ecr-login@v2 + + - name: Build, tag & push (CRITICAL blocks deploy) + uses: ./.github/actions/docker-build + with: + context: ./${{ matrix.service }} + dockerfile: ./${{ matrix.service }}/Dockerfile + image-name: mypythonproject1/${{ matrix.service }} + registry: ${{ steps.ecr-login.outputs.registry }} + tags: | + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + type=raw,value=latest + type=sha,prefix=,format=short + build-args: | + BUILD_ENV=production + GIT_SHA=${{ steps.ver.outputs.sha_short }} + VERSION=${{ steps.ver.outputs.tag }} + platforms: linux/amd64 + scan: "true" + scan-severity: "CRITICAL" + scan-exit-code: "1" + cache-scope: ${{ matrix.service }}-production + + ec2-deploy-production: + name: "EC2 Deploy [production] via Ansible" + runs-on: ubuntu-latest + timeout-minutes: 5 + needs: [build-production] + if: needs.build-production.result == 'success' + environment: prod + steps: + - name: Dispatch ansible-ec2-deploy to infra3 repo + uses: actions/github-script@v7 + with: + github-token: ${{ secrets.INFRA_DEPLOY_TOKEN }} + script: | + const tag = context.ref.replace('refs/tags/', ''); + await github.rest.actions.createWorkflowDispatch({ + owner: context.repo.owner, + repo: 'mypythonproject1-infra3', + workflow_id: 'ansible-ec2-deploy.yml', + ref: 'main', + inputs: { + environment: 'prod', + operation: 'deploy', + image_tag: tag, + production_confirmation: 'APPROVE_PROD_DEPLOY', + }, + }); + core.notice(`Dispatched ansible-ec2-deploy on mypythonproject1-infra3 (prod, tag=${tag})`); + + ec2-verify-production: + name: "Verify EC2 Deploy [production]" + runs-on: ubuntu-latest + timeout-minutes: 45 + needs: [ec2-deploy-production] + if: needs.ec2-deploy-production.result == 'success' + environment: prod + steps: + - name: Wait for infra3 ansible workflow result + uses: actions/github-script@v7 + with: + github-token: ${{ secrets.INFRA_DEPLOY_TOKEN }} + script: | + const owner = context.repo.owner; + const repo = 'mypythonproject1-infra3'; + const tag = context.ref.replace('refs/tags/', ''); + const tagNeedle = `tag=${tag}`; + const deadline = Date.now() + 45 * 60 * 1000; + + while (Date.now() < deadline) { + const resp = await github.rest.actions.listWorkflowRuns({ + owner, + repo, + workflow_id: 'ansible-ec2-deploy.yml', + event: 'workflow_dispatch', + per_page: 20, + }); + + const matchedRun = resp.data.workflow_runs.find((r) => { + const title = (r.display_title || '').toLowerCase(); + return title.includes('[prod]') && title.includes(tagNeedle.toLowerCase()); + }); + + if (!matchedRun || matchedRun.status !== 'completed') { + await new Promise((resolve) => setTimeout(resolve, 20000)); + continue; + } + + if (matchedRun.conclusion !== 'success') { + core.setFailed(`infra3 ansible deploy failed: ${matchedRun.html_url}`); + return; + } + + core.notice(`infra3 ansible deploy succeeded: ${matchedRun.html_url}`); + return; + } + + core.setFailed('Timed out waiting for infra3 ansible production deployment run to complete'); + + ec2-rollback-manual: + name: "EC2 Rollback [manual] via Ansible" + runs-on: ubuntu-latest + timeout-minutes: 5 + if: github.event_name == 'workflow_dispatch' && inputs.operation == 'rollback' + environment: ${{ inputs.environment }} + steps: + - name: Validate rollback tag input + shell: bash + run: | + if [ -z "${{ inputs.rollback_tag }}" ]; then + echo "::error::rollback_tag is required when operation=rollback" + exit 1 + fi + + - name: Dispatch ansible rollback to infra3 repo + uses: actions/github-script@v7 + with: + github-token: ${{ secrets.INFRA_DEPLOY_TOKEN }} + script: | + const env = '${{ inputs.environment }}'; + const rollbackTag = '${{ inputs.rollback_tag }}'; + const isProd = env === 'prod'; + await github.rest.actions.createWorkflowDispatch({ + owner: context.repo.owner, + repo: 'mypythonproject1-infra3', + workflow_id: 'ansible-ec2-deploy.yml', + ref: 'main', + inputs: { + environment: env, + operation: 'rollback', + image_tag: rollbackTag, + production_confirmation: isProd ? 'APPROVE_PROD_DEPLOY' : '', + }, + }); + core.notice(`Dispatched ansible rollback on mypythonproject1-infra3 (${env}, tag=${rollbackTag})`); + + ec2-verify-rollback-manual: + name: "Verify EC2 Rollback [manual]" + runs-on: ubuntu-latest + timeout-minutes: 45 + if: github.event_name == 'workflow_dispatch' && inputs.operation == 'rollback' + needs: [ec2-rollback-manual] + environment: ${{ inputs.environment }} + steps: + - name: Wait for infra3 ansible rollback result + uses: actions/github-script@v7 + with: + github-token: ${{ secrets.INFRA_DEPLOY_TOKEN }} + script: | + const owner = context.repo.owner; + const repo = 'mypythonproject1-infra3'; + const env = '${{ inputs.environment }}'; + const rollbackTag = '${{ inputs.rollback_tag }}'; + const envNeedle = `[${env}]`; + const opNeedle = 'rollback'; + const tagNeedle = `tag=${rollbackTag}`; + const timeoutMs = env === 'prod' ? 45 * 60 * 1000 : 30 * 60 * 1000; + const pollMs = 20000; + const deadline = Date.now() + timeoutMs; + + while (Date.now() < deadline) { + const resp = await github.rest.actions.listWorkflowRuns({ + owner, + repo, + workflow_id: 'ansible-ec2-deploy.yml', + event: 'workflow_dispatch', + per_page: 20, + }); + + const matchedRun = resp.data.workflow_runs.find((r) => { + const title = (r.display_title || '').toLowerCase(); + return title.includes(envNeedle.toLowerCase()) && title.includes(opNeedle) && title.includes(tagNeedle.toLowerCase()); + }); + + if (!matchedRun || matchedRun.status !== 'completed') { + await new Promise((resolve) => setTimeout(resolve, pollMs)); + continue; + } + + if (matchedRun.conclusion !== 'success') { + core.setFailed(`infra3 ansible rollback failed: ${matchedRun.html_url}`); + return; + } + + core.notice(`infra3 ansible rollback succeeded: ${matchedRun.html_url}`); + return; + } + + core.setFailed('Timed out waiting for infra3 ansible rollback run to complete'); \ No newline at end of file diff --git a/.github/workflows/cd-ecs.yml b/.github/workflows/cd-ecs-fargate.yml similarity index 55% rename from .github/workflows/cd-ecs.yml rename to .github/workflows/cd-ecs-fargate.yml index 03ea4a2..a26ba61 100644 --- a/.github/workflows/cd-ecs.yml +++ b/.github/workflows/cd-ecs-fargate.yml @@ -23,7 +23,7 @@ # Variables (GitHub Environments): # APP_URL — Base URL for smoke test health check ############################################################################### -name: "CD \u2014 ECS/Fargate" +name: "CD — ECS/Fargate" on: workflow_run: @@ -41,16 +41,6 @@ on: type: choice options: [staging, prod] default: staging - operation: - description: "Operation to run" - required: true - type: choice - options: [deploy, rollback] - default: deploy - rollback_tag: - description: "Required when operation=rollback (for example: staging-a1b2c3d or v1.2.3)" - required: false - type: string permissions: contents: read @@ -78,9 +68,8 @@ jobs: timeout-minutes: 20 if: > (github.event_name == 'workflow_run' - && github.event.workflow_run.conclusion == 'success') || (github.event_name == 'workflow_dispatch' - && inputs.environment == 'staging' - && inputs.operation != 'rollback') + && github.event.workflow_run.conclusion == 'success')|| (github.event_name == 'workflow_dispatch' + && inputs.environment == 'staging') environment: staging strategy: matrix: @@ -159,92 +148,6 @@ jobs: echo "Waiting 10 minutes for Terraform apply to complete..." sleep 600 - # --------------------------------------------------------------------------- - # 1b2. Trigger Ansible deploy on EC2 infra repo (staging) - # --------------------------------------------------------------------------- - ec2-deploy-staging: - name: "EC2 Deploy [staging] via Ansible" - runs-on: ubuntu-latest - timeout-minutes: 5 - needs: [build-staging] - environment: staging - steps: - - name: Dispatch ansible-ec2-deploy to infra3 repo - id: dispatch_ec2_staging - uses: actions/github-script@v7 - with: - github-token: ${{ secrets.INFRA_DEPLOY_TOKEN }} - script: | - const headSha = (context.payload.workflow_run && context.payload.workflow_run.head_sha) || context.sha; - const imageTag = `staging-${headSha.substring(0, 7)}`; - await github.rest.actions.createWorkflowDispatch({ - owner: context.repo.owner, - repo: 'mypythonproject1-infra3', - workflow_id: 'ansible-ec2-deploy.yml', - ref: 'main', - inputs: { - environment: 'staging', - operation: 'deploy', - image_tag: imageTag, - }, - }); - console.log(`Dispatched ansible-ec2-deploy on mypythonproject1-infra3 (staging, tag=${imageTag})`); - core.setOutput('image_tag', imageTag); - - ec2-verify-staging: - name: "Verify EC2 Deploy [staging]" - runs-on: ubuntu-latest - timeout-minutes: 30 - needs: [ec2-deploy-staging] - environment: staging - steps: - - name: Wait for infra3 ansible workflow result - uses: actions/github-script@v7 - with: - github-token: ${{ secrets.INFRA_DEPLOY_TOKEN }} - script: | - const owner = context.repo.owner; - const repo = 'mypythonproject1-infra3'; - const expectedTag = `${((context.payload.workflow_run && context.payload.workflow_run.head_sha) || context.sha).substring(0, 7)}`; - const tagNeedle = `tag=staging-${expectedTag}`; - const deadline = Date.now() + 30 * 60 * 1000; - - let matchedRun = null; - while (Date.now() < deadline) { - const resp = await github.rest.actions.listWorkflowRuns({ - owner, - repo, - workflow_id: 'ansible-ec2-deploy.yml', - event: 'workflow_dispatch', - per_page: 20, - }); - - matchedRun = resp.data.workflow_runs.find((r) => { - const title = r.display_title || ''; - return title.includes('[staging]') && title.includes(tagNeedle); - }); - - if (!matchedRun) { - await new Promise((resolve) => setTimeout(resolve, 15000)); - continue; - } - - if (matchedRun.status !== 'completed') { - await new Promise((resolve) => setTimeout(resolve, 15000)); - continue; - } - - if (matchedRun.conclusion !== 'success') { - core.setFailed(`infra3 ansible deploy failed: ${matchedRun.html_url}`); - return; - } - - core.notice(`infra3 ansible deploy succeeded: ${matchedRun.html_url}`); - return; - } - - core.setFailed('Timed out waiting for infra3 ansible staging deployment run to complete'); - # --------------------------------------------------------------------------- # 1c. ECS rolling deploy (staging) # --------------------------------------------------------------------------- @@ -350,9 +253,7 @@ jobs: name: "Build & Push [production] (${{ matrix.service }})" runs-on: ubuntu-latest timeout-minutes: 20 - if: > - startsWith(github.ref, 'refs/tags/v') || - (github.event_name == 'workflow_dispatch' && inputs.environment == 'prod' && inputs.operation != 'rollback') + if: startsWith(github.ref, 'refs/tags/v') environment: prod strategy: matrix: @@ -438,191 +339,6 @@ jobs: echo "Waiting 15 minutes for Terraform apply to complete..." sleep 900 - # --------------------------------------------------------------------------- - # 2c2. Trigger Ansible deploy on EC2 infra repo (production) - # --------------------------------------------------------------------------- - ec2-deploy-production: - name: "EC2 Deploy [production] via Ansible" - runs-on: ubuntu-latest - timeout-minutes: 5 - needs: [build-production] - environment: prod - steps: - - name: Dispatch ansible-ec2-deploy to infra3 repo - id: dispatch_ec2_prod - uses: actions/github-script@v7 - with: - github-token: ${{ secrets.INFRA_DEPLOY_TOKEN }} - script: | - const tag = context.ref.replace('refs/tags/', ''); - await github.rest.actions.createWorkflowDispatch({ - owner: context.repo.owner, - repo: 'mypythonproject1-infra3', - workflow_id: 'ansible-ec2-deploy.yml', - ref: 'main', - inputs: { - environment: 'prod', - operation: 'deploy', - image_tag: tag, - production_confirmation: 'APPROVE_PROD_DEPLOY', - }, - }); - console.log(`Dispatched ansible-ec2-deploy on mypythonproject1-infra3 (prod, tag=${tag})`); - core.setOutput('image_tag', tag); - - ec2-verify-production: - name: "Verify EC2 Deploy [production]" - runs-on: ubuntu-latest - timeout-minutes: 45 - needs: [ec2-deploy-production] - environment: prod - steps: - - name: Wait for infra3 ansible workflow result - uses: actions/github-script@v7 - with: - github-token: ${{ secrets.INFRA_DEPLOY_TOKEN }} - script: | - const owner = context.repo.owner; - const repo = 'mypythonproject1-infra3'; - const tag = context.ref.replace('refs/tags/', ''); - const tagNeedle = `tag=${tag}`; - const deadline = Date.now() + 45 * 60 * 1000; - - let matchedRun = null; - while (Date.now() < deadline) { - const resp = await github.rest.actions.listWorkflowRuns({ - owner, - repo, - workflow_id: 'ansible-ec2-deploy.yml', - event: 'workflow_dispatch', - per_page: 20, - }); - - matchedRun = resp.data.workflow_runs.find((r) => { - const title = r.display_title || ''; - return title.includes('[prod]') && title.includes(tagNeedle); - }); - - if (!matchedRun) { - await new Promise((resolve) => setTimeout(resolve, 20000)); - continue; - } - - if (matchedRun.status !== 'completed') { - await new Promise((resolve) => setTimeout(resolve, 20000)); - continue; - } - - if (matchedRun.conclusion !== 'success') { - core.setFailed(`infra3 ansible deploy failed: ${matchedRun.html_url}`); - return; - } - - core.notice(`infra3 ansible deploy succeeded: ${matchedRun.html_url}`); - return; - } - - core.setFailed('Timed out waiting for infra3 ansible production deployment run to complete'); - - # --------------------------------------------------------------------------- - # 3. Manual rollback on EC2 infra repo via Ansible - # --------------------------------------------------------------------------- - ec2-rollback-manual: - name: "EC2 Rollback [manual] via Ansible" - runs-on: ubuntu-latest - timeout-minutes: 5 - if: github.event_name == 'workflow_dispatch' && inputs.operation == 'rollback' - environment: ${{ inputs.environment }} - outputs: - rollback_tag: ${{ steps.dispatch_rollback.outputs.rollback_tag }} - steps: - - name: Validate rollback tag input - shell: bash - run: | - if [ -z "${{ inputs.rollback_tag }}" ]; then - echo "::error::rollback_tag is required when operation=rollback" - exit 1 - fi - - - name: Dispatch ansible rollback to infra3 repo - id: dispatch_rollback - uses: actions/github-script@v7 - with: - github-token: ${{ secrets.INFRA_DEPLOY_TOKEN }} - script: | - const env = '${{ inputs.environment }}'; - const rollbackTag = '${{ inputs.rollback_tag }}'; - const isProd = env === 'prod'; - await github.rest.actions.createWorkflowDispatch({ - owner: context.repo.owner, - repo: 'mypythonproject1-infra3', - workflow_id: 'ansible-ec2-deploy.yml', - ref: 'main', - inputs: { - environment: env, - operation: 'rollback', - image_tag: rollbackTag, - production_confirmation: isProd ? 'APPROVE_PROD_DEPLOY' : '', - }, - }); - console.log(`Dispatched ansible rollback on mypythonproject1-infra3 (${env}, tag=${rollbackTag})`); - core.setOutput('rollback_tag', rollbackTag); - - ec2-verify-rollback-manual: - name: "Verify EC2 Rollback [manual]" - runs-on: ubuntu-latest - timeout-minutes: 45 - if: github.event_name == 'workflow_dispatch' && inputs.operation == 'rollback' - needs: [ec2-rollback-manual] - environment: ${{ inputs.environment }} - steps: - - name: Wait for infra3 ansible rollback result - uses: actions/github-script@v7 - with: - github-token: ${{ secrets.INFRA_DEPLOY_TOKEN }} - script: | - const owner = context.repo.owner; - const repo = 'mypythonproject1-infra3'; - const env = '${{ inputs.environment }}'; - const rollbackTag = '${{ inputs.rollback_tag }}'; - const envNeedle = `[${env}]`; - const opNeedle = 'rollback'; - const tagNeedle = `tag=${rollbackTag}`; - const timeoutMs = env === 'prod' ? 45 * 60 * 1000 : 30 * 60 * 1000; - const pollMs = 20000; - const deadline = Date.now() + timeoutMs; - - let matchedRun = null; - while (Date.now() < deadline) { - const resp = await github.rest.actions.listWorkflowRuns({ - owner, - repo, - workflow_id: 'ansible-ec2-deploy.yml', - event: 'workflow_dispatch', - per_page: 20, - }); - - matchedRun = resp.data.workflow_runs.find((r) => { - const title = (r.display_title || '').toLowerCase(); - return title.includes(envNeedle.toLowerCase()) && title.includes(opNeedle) && title.includes(tagNeedle.toLowerCase()); - }); - - if (!matchedRun || matchedRun.status !== 'completed') { - await new Promise((resolve) => setTimeout(resolve, pollMs)); - continue; - } - - if (matchedRun.conclusion !== 'success') { - core.setFailed(`infra3 ansible rollback failed: ${matchedRun.html_url}`); - return; - } - - core.notice(`infra3 ansible rollback succeeded: ${matchedRun.html_url}`); - return; - } - - core.setFailed('Timed out waiting for infra3 ansible rollback run to complete'); - # --------------------------------------------------------------------------- # 2d. ECS rolling deploy (production) # --------------------------------------------------------------------------- @@ -678,4 +394,4 @@ jobs: warmup-seconds: 20 deploy-version: ${{ github.ref_name }} deploy-sha: ${{ github.sha }} - secrets: inherit + secrets: inherit \ No newline at end of file