Skip to content

Commit 1d2a1e7

Browse files
author
Jonathan Alvarez Delgado
committed
feat(ci): add stage deploy workflow with preview-only mode and safety scaling
1 parent bdebe9f commit 1d2a1e7

1 file changed

Lines changed: 157 additions & 0 deletions

File tree

.github/workflows/deploy-stage.yml

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
---
2+
# Deploy to Stage
3+
#
4+
# Runs `pulumi up` against the stage stack after a successful image push to ECR
5+
# This requires manual approval via the _staging_ environment protection rule
6+
#
7+
# Trigger options
8+
# - workflow_dispatch: manual trigger from GH Actions UI
9+
# - workflow_run: automatically after build-and-push succeeds on stage
10+
#
11+
# Authentication: GH OIDC -> AWS IAM role
12+
# Required secrets: PULUMI_ACCESS_TOKEN, PULUMI_PASSPHRASE
13+
# Required variables: AWS_ROLE_ARN
14+
15+
name: deploy-stage
16+
17+
concurrency:
18+
group: deploy-stage
19+
cancel-in-progress: false # To avoid cancelling in-progress deploys
20+
21+
on:
22+
workflow_dispatch:
23+
inputs:
24+
preview_only:
25+
description: "Run pulumi preview only (no apply)"
26+
required: false
27+
default: "false"
28+
type: choice
29+
options:
30+
- "false"
31+
- "true"
32+
33+
workflow_run:
34+
workflows: ["Build and Push to ECR"]
35+
types: [completed]
36+
branches: [stage]
37+
38+
permissions:
39+
contents: read
40+
id-token: write # OIDC authn
41+
42+
env:
43+
AWS_REGION: us-west-2
44+
PULUMI_STACK: thunderbird/thunderbird-addons/stage
45+
46+
jobs:
47+
# Gate: only proceed if the triggering workflow succeeded (or manual)
48+
check-trigger:
49+
runs-on: ubuntu-latest
50+
outputs:
51+
should-deploy: ${{ steps.check.outputs.result }}
52+
steps:
53+
- name: Evaluate trigger
54+
id: check
55+
run: |
56+
if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
57+
echo "result=true" >> $GITHUB_OUTPUT
58+
elif [[ "${{ github.event.workflow_run.conclusion }}" == "success" ]]; then
59+
echo "result=true" >> $GITHUB_OUTPUT
60+
else
61+
echo "result=false" >> $GITHUB_OUTPUT
62+
echo "Skipping: triggering workflow did not succeed"
63+
fi
64+
65+
deploy:
66+
needs: check-trigger
67+
if: needs.check-trigger.outputs.should-deploy == 'true'
68+
runs-on: ubuntu-latest
69+
timeout-minutes: 30
70+
environment: staging # Would require approval if environment protection rules are set
71+
steps:
72+
- name: Checkout repository
73+
uses: actions/checkout@v4
74+
75+
- name: Configure AWS credentials
76+
uses: aws-actions/configure-aws-credentials@v4
77+
with:
78+
role-to-assume: ${{ vars.AWS_ROLE_ARN }}
79+
aws-region: ${{ env.AWS_REGION }}
80+
81+
- name: Set up Python
82+
uses: actions/setup-python@v5
83+
with:
84+
python-version: "3.13"
85+
86+
- name: Install Pulumi CLI
87+
uses: pulumi/actions@v6
88+
with:
89+
command: version
90+
91+
- name: Install dependencies
92+
working-directory: infra/pulumi
93+
run: |
94+
python -m venv .venv
95+
source .venv/bin/activate
96+
pip install -r requirements.txt
97+
98+
- name: Pulumi preview
99+
working-directory: infra/pulumi
100+
env:
101+
PULUMI_ACCESS_TOKEN: ${{ secrets.PULUMI_ACCESS_TOKEN }}
102+
PULUMI_CONFIG_PASSPHRASE: ${{ secrets.PULUMI_PASSPHRASE }}
103+
run: |
104+
source .venv/bin/activate
105+
pulumi stack select ${{ env.PULUMI_STACK }}
106+
pulumi preview --diff
107+
108+
- name: Pulumi up
109+
if: github.event.inputs.preview_only != 'true'
110+
working-directory: infra/pulumi
111+
env:
112+
PULUMI_ACCESS_TOKEN: ${{ secrets.PULUMI_ACCESS_TOKEN }}
113+
PULUMI_CONFIG_PASSPHRASE: ${{ secrets.PULUMI_PASSPHRASE }}
114+
run: |
115+
source .venv/bin/activate
116+
pulumi stack select ${{ env.PULUMI_STACK }}
117+
pulumi up --yes --diff
118+
119+
- name: "Post-deploy: scale services to 0"
120+
if: github.event.inputs.preview_only != 'true'
121+
run: |
122+
echo "Scaling ECS services to 0 (safety: prevents writes to shared stage DB)"
123+
echo "Scale up manually after RO healthcheck validation"
124+
for svc in web worker versioncheck; do
125+
aws ecs update-service \
126+
--cluster thunderbird-addons-stage-${svc} \
127+
--service thunderbird-addons-stage-${svc} \
128+
--desired-count 0 \
129+
--region ${{ env.AWS_REGION }} \
130+
--query 'service.[serviceName,desiredCount]' \
131+
--output text
132+
done
133+
134+
- name: Post-deploy summary
135+
if: github.event.inputs.preview_only != 'true'
136+
working-directory: infra/pulumi
137+
env:
138+
PULUMI_ACCESS_TOKEN: ${{ secrets.PULUMI_ACCESS_TOKEN }}
139+
PULUMI_CONFIG_PASSPHRASE: ${{ secrets.PULUMI_PASSPHRASE }}
140+
run: |
141+
source .venv/bin/activate
142+
echo "## Deploy Summary" >> $GITHUB_STEP_SUMMARY
143+
echo "" >> $GITHUB_STEP_SUMMARY
144+
echo "Stack: ${{ env.PULUMI_STACK }}" >> $GITHUB_STEP_SUMMARY
145+
echo "" >> $GITHUB_STEP_SUMMARY
146+
pulumi stack output --json | python -c "
147+
import sys, json
148+
outputs = json.load(sys.stdin)
149+
print('| Output | Value |')
150+
print('|--------|-------|')
151+
for k, v in sorted(outputs.items()):
152+
if isinstance(v, list):
153+
v = ', '.join(str(i) for i in v)
154+
print(f'| {k} | \`{v}\` |')
155+
" >> $GITHUB_STEP_SUMMARY
156+
echo "" >> $GITHUB_STEP_SUMMARY
157+
echo "Services scaled to 0. Run RO healthcheck before scaling up" >> $GITHUB_STEP_SUMMARY

0 commit comments

Comments
 (0)