Skip to content

Commit f8de3a7

Browse files
authored
Merge pull request #22 from YilingCAI/feature/cai
add dev env in workflow
2 parents c5cf449 + b550293 commit f8de3a7

2 files changed

Lines changed: 267 additions & 13 deletions

File tree

.github/workflows/cd-ec2-ansible.yml

Lines changed: 127 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ on:
3232
description: "Target environment"
3333
required: true
3434
type: choice
35-
options: [staging, prod]
35+
options: [dev, staging, prod]
3636
default: staging
3737
operation:
3838
description: "Operation to run"
@@ -56,6 +56,132 @@ concurrency:
5656
cancel-in-progress: ${{ !startsWith(github.ref, 'refs/tags/v') }}
5757

5858
jobs:
59+
build-dev:
60+
name: "Build & Push [dev] (${{ matrix.service }})"
61+
runs-on: ubuntu-latest
62+
timeout-minutes: 20
63+
if: >
64+
github.event_name == 'workflow_dispatch'
65+
&& inputs.environment == 'dev'
66+
&& inputs.operation == 'deploy'
67+
environment: dev
68+
strategy:
69+
matrix:
70+
service: [backend, frontend]
71+
fail-fast: true
72+
permissions:
73+
contents: read
74+
id-token: write
75+
steps:
76+
- uses: actions/checkout@v4
77+
with:
78+
ref: ${{ github.sha }}
79+
80+
- name: Authenticate with AWS
81+
uses: ./.github/actions/aws-auth
82+
with:
83+
role-arn: ${{ secrets.AWS_ROLE_TO_ASSUME }}
84+
aws-region: ${{ secrets.AWS_REGION }}
85+
86+
- name: Log in to Amazon ECR
87+
id: ecr-login
88+
uses: aws-actions/amazon-ecr-login@v2
89+
90+
- name: Build, tag & push
91+
uses: ./.github/actions/docker-build
92+
with:
93+
context: ./${{ matrix.service }}
94+
dockerfile: ./${{ matrix.service }}/Dockerfile
95+
image-name: mypythonproject1/${{ matrix.service }}
96+
registry: ${{ steps.ecr-login.outputs.registry }}
97+
tags: |
98+
type=raw,value=dev
99+
type=sha,prefix=dev-,format=short
100+
build-args: |
101+
BUILD_ENV=dev
102+
GIT_SHA=${{ github.sha }}
103+
platforms: linux/amd64
104+
scan: "true"
105+
scan-severity: "CRITICAL,HIGH"
106+
scan-exit-code: "0"
107+
cache-scope: ${{ matrix.service }}-dev
108+
109+
ec2-deploy-dev:
110+
name: "EC2 Deploy [dev] via Ansible"
111+
runs-on: ubuntu-latest
112+
timeout-minutes: 5
113+
needs: [build-dev]
114+
if: needs.build-dev.result == 'success'
115+
environment: dev
116+
steps:
117+
- name: Dispatch ansible-ec2-deploy to infra3 repo
118+
uses: actions/github-script@v7
119+
with:
120+
github-token: ${{ secrets.INFRA_DEPLOY_TOKEN }}
121+
script: |
122+
const imageTag = `dev-${context.sha.substring(0, 7)}`;
123+
await github.rest.actions.createWorkflowDispatch({
124+
owner: context.repo.owner,
125+
repo: 'mypythonproject1-infra3',
126+
workflow_id: 'ansible-ec2-deploy.yml',
127+
ref: 'main',
128+
inputs: {
129+
environment: 'dev',
130+
operation: 'deploy',
131+
image_tag: imageTag,
132+
},
133+
});
134+
core.notice(`Dispatched ansible-ec2-deploy on mypythonproject1-infra3 (dev, tag=${imageTag})`);
135+
136+
ec2-verify-dev:
137+
name: "Verify EC2 Deploy [dev]"
138+
runs-on: ubuntu-latest
139+
timeout-minutes: 30
140+
needs: [ec2-deploy-dev]
141+
if: needs.ec2-deploy-dev.result == 'success'
142+
environment: dev
143+
steps:
144+
- name: Wait for infra3 ansible workflow result
145+
uses: actions/github-script@v7
146+
with:
147+
github-token: ${{ secrets.INFRA_DEPLOY_TOKEN }}
148+
script: |
149+
const owner = context.repo.owner;
150+
const repo = 'mypythonproject1-infra3';
151+
const expectedTag = `${context.sha.substring(0, 7)}`;
152+
const tagNeedle = `tag=dev-${expectedTag}`;
153+
const deadline = Date.now() + 30 * 60 * 1000;
154+
155+
while (Date.now() < deadline) {
156+
const resp = await github.rest.actions.listWorkflowRuns({
157+
owner,
158+
repo,
159+
workflow_id: 'ansible-ec2-deploy.yml',
160+
event: 'workflow_dispatch',
161+
per_page: 20,
162+
});
163+
164+
const matchedRun = resp.data.workflow_runs.find((r) => {
165+
const title = (r.display_title || '').toLowerCase();
166+
return title.includes('[dev]') && title.includes(tagNeedle.toLowerCase());
167+
});
168+
169+
if (!matchedRun || matchedRun.status !== 'completed') {
170+
await new Promise((resolve) => setTimeout(resolve, 15000));
171+
continue;
172+
}
173+
174+
if (matchedRun.conclusion !== 'success') {
175+
core.setFailed(`infra3 ansible deploy failed: ${matchedRun.html_url}`);
176+
return;
177+
}
178+
179+
core.notice(`infra3 ansible deploy succeeded: ${matchedRun.html_url}`);
180+
return;
181+
}
182+
183+
core.setFailed('Timed out waiting for infra3 ansible dev deployment run to complete');
184+
59185
build-staging:
60186
name: "Build & Push [staging] (${{ matrix.service }})"
61187
runs-on: ubuntu-latest

.github/workflows/cd-ecs-fargate.yml

Lines changed: 140 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ on:
3939
description: "Target environment"
4040
required: true
4141
type: choice
42-
options: [staging, prod]
42+
options: [dev, staging, prod]
4343
default: staging
4444

4545
permissions:
@@ -62,6 +62,136 @@ concurrency:
6262
# 1a. Build + push staging images
6363
# ---------------------------------------------------------------------------
6464
jobs:
65+
build-dev:
66+
name: "Build & Push [dev] (${{ matrix.service }})"
67+
runs-on: ubuntu-latest
68+
timeout-minutes: 20
69+
if: >
70+
github.event_name == 'workflow_dispatch'
71+
&& inputs.environment == 'dev'
72+
environment: dev
73+
strategy:
74+
matrix:
75+
service: [backend, frontend]
76+
fail-fast: true
77+
permissions:
78+
contents: read
79+
id-token: write
80+
outputs:
81+
registry: ${{ steps.ecr-login.outputs.registry }}
82+
steps:
83+
- uses: actions/checkout@v4
84+
with:
85+
ref: ${{ github.sha }}
86+
87+
- name: Authenticate with AWS
88+
uses: ./.github/actions/aws-auth
89+
with:
90+
role-arn: ${{ secrets.AWS_ROLE_TO_ASSUME }}
91+
aws-region: ${{ secrets.AWS_REGION }}
92+
93+
- name: Log in to Amazon ECR
94+
id: ecr-login
95+
uses: aws-actions/amazon-ecr-login@v2
96+
97+
- name: Build, tag & push
98+
uses: ./.github/actions/docker-build
99+
with:
100+
context: ./${{ matrix.service }}
101+
dockerfile: ./${{ matrix.service }}/Dockerfile
102+
image-name: mypythonproject1/${{ matrix.service }}
103+
registry: ${{ steps.ecr-login.outputs.registry }}
104+
tags: |
105+
type=raw,value=dev
106+
type=sha,prefix=dev-,format=short
107+
build-args: |
108+
BUILD_ENV=dev
109+
GIT_SHA=${{ github.sha }}
110+
platforms: linux/amd64
111+
scan: "true"
112+
scan-severity: "CRITICAL,HIGH"
113+
scan-exit-code: "0"
114+
cache-scope: ${{ matrix.service }}-dev
115+
116+
infra-dev:
117+
name: "Infra Apply [dev]"
118+
runs-on: ubuntu-latest
119+
timeout-minutes: 5
120+
needs: [build-dev]
121+
environment: dev
122+
steps:
123+
- name: Dispatch terraform apply to infra repo
124+
uses: actions/github-script@v7
125+
with:
126+
github-token: ${{ secrets.INFRA_DEPLOY_TOKEN }}
127+
script: |
128+
await github.rest.actions.createWorkflowDispatch({
129+
owner: context.repo.owner,
130+
repo: 'mypythonproject1-infra',
131+
workflow_id: 'terraform-plan-apply.yml',
132+
ref: 'main',
133+
inputs: {
134+
environment: 'dev',
135+
action: 'apply',
136+
},
137+
});
138+
console.log('Dispatched terraform-plan-apply on mypythonproject1-infra (dev)');
139+
140+
- name: Wait for infra apply
141+
run: |
142+
echo "Waiting 10 minutes for Terraform apply to complete..."
143+
sleep 600
144+
145+
deploy-dev:
146+
name: "ECS Deploy [dev] (${{ matrix.service }})"
147+
runs-on: ubuntu-latest
148+
timeout-minutes: 20
149+
needs: [infra-dev]
150+
environment: dev
151+
strategy:
152+
matrix:
153+
service: [backend, frontend]
154+
fail-fast: false
155+
permissions:
156+
id-token: write
157+
steps:
158+
- name: Authenticate with AWS
159+
uses: aws-actions/configure-aws-credentials@v4
160+
with:
161+
role-to-assume: ${{ secrets.AWS_ROLE_TO_ASSUME }}
162+
aws-region: ${{ secrets.AWS_REGION }}
163+
164+
- name: Force new ECS deployment
165+
run: |
166+
CLUSTER="mypythonproject1-dev-cluster"
167+
SERVICE="mypythonproject1-dev-${{ matrix.service }}-service"
168+
aws ecs update-service \
169+
--cluster "$CLUSTER" \
170+
--service "$SERVICE" \
171+
--force-new-deployment \
172+
--region "${{ secrets.AWS_REGION }}"
173+
174+
- name: Wait for service stability
175+
timeout-minutes: 15
176+
run: |
177+
CLUSTER="mypythonproject1-dev-cluster"
178+
SERVICE="mypythonproject1-dev-${{ matrix.service }}-service"
179+
aws ecs wait services-stable \
180+
--cluster "$CLUSTER" \
181+
--services "$SERVICE" \
182+
--region "${{ secrets.AWS_REGION }}"
183+
184+
smoke-test-dev:
185+
name: "Smoke Test [dev]"
186+
needs: [deploy-dev]
187+
uses: ./.github/workflows/_smoke-test.yml
188+
with:
189+
environment: dev
190+
app-url: ${{ vars.APP_URL }}
191+
warmup-seconds: 15
192+
deploy-sha: ${{ github.sha }}
193+
secrets: inherit
194+
65195
build-staging:
66196
name: "Build & Push [staging] (${{ matrix.service }})"
67197
runs-on: ubuntu-latest
@@ -80,7 +210,6 @@ jobs:
80210
id-token: write
81211
outputs:
82212
registry: ${{ steps.ecr-login.outputs.registry }}
83-
image-backend: ${{ steps.meta.outputs.tags }}
84213
steps:
85214
- uses: actions/checkout@v4
86215
with:
@@ -125,22 +254,22 @@ jobs:
125254
needs: [build-staging]
126255
environment: staging
127256
steps:
128-
- name: Dispatch terraform-apply to infra repo
257+
- name: Dispatch terraform apply to infra repo
129258
uses: actions/github-script@v7
130259
with:
131260
github-token: ${{ secrets.INFRA_DEPLOY_TOKEN }}
132261
script: |
133262
await github.rest.actions.createWorkflowDispatch({
134263
owner: context.repo.owner,
135264
repo: 'mypythonproject1-infra',
136-
workflow_id: 'terraform-apply.yml',
265+
workflow_id: 'terraform-plan-apply.yml',
137266
ref: 'main',
138267
inputs: {
139268
environment: 'staging',
140-
image_tag: 'staging',
269+
action: 'apply',
141270
},
142271
});
143-
console.log('Dispatched terraform-apply on mypythonproject1-infra (staging)');
272+
console.log('Dispatched terraform-plan-apply on mypythonproject1-infra (staging)');
144273
145274
# Give Terraform apply ~10 min to complete before ECS deploy
146275
- name: Wait for infra apply
@@ -316,23 +445,22 @@ jobs:
316445
needs: [build-production]
317446
environment: prod
318447
steps:
319-
- name: Dispatch terraform-apply to infra repo
448+
- name: Dispatch terraform apply to infra repo
320449
uses: actions/github-script@v7
321450
with:
322451
github-token: ${{ secrets.INFRA_DEPLOY_TOKEN }}
323452
script: |
324-
const tag = context.ref.replace('refs/tags/', '');
325453
await github.rest.actions.createWorkflowDispatch({
326454
owner: context.repo.owner,
327455
repo: 'mypythonproject1-infra',
328-
workflow_id: 'terraform-apply.yml',
456+
workflow_id: 'terraform-plan-apply.yml',
329457
ref: 'main',
330458
inputs: {
331-
environment: 'production',
332-
image_tag: tag,
459+
environment: 'prod',
460+
action: 'apply',
333461
},
334462
});
335-
console.log(`Dispatched terraform-apply on mypythonproject1-infra (production, tag=${tag})`);
463+
console.log('Dispatched terraform-plan-apply on mypythonproject1-infra (prod)');
336464
337465
- name: Wait for infra apply
338466
run: |

0 commit comments

Comments
 (0)