-
Notifications
You must be signed in to change notification settings - Fork 1
183 lines (154 loc) · 6.55 KB
/
preview-env.yml
File metadata and controls
183 lines (154 loc) · 6.55 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
name: Preview Environment
on:
pull_request:
types: [opened, reopened, synchronize, closed]
env:
AWS_REGION: eu-west-2
AWS_ACCOUNT_ID: "900119715266"
ECR_REPOSITORY_NAME: "whoami"
TF_STATE_BUCKET: "cds-cdg-dev-tfstate-900119715266"
CORE_STATE_KEY: "dev/terraform.tfstate"
PREVIEW_STATE_PREFIX: "dev/preview/"
python_version: "3.14"
jobs:
preview:
name: Manage preview environment
runs-on: ubuntu-latest
# Needed for OIDC → AWS (recommended)
permissions:
id-token: write
contents: read
pull-requests: write
# One job per branch at a time
concurrency:
group: preview-${{ github.head_ref || github.ref_name }}
cancel-in-progress: true
env:
AWS_ROLE_ARN: ${{ secrets.DEV_AWS_CREDENTIALS }}
steps:
- name: Checkout repo
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8
# Configure AWS credentials (OIDC recommended)
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@e0972b3bd31781e38954064665dc227f3e67b9d5
with:
role-to-assume: ${{ env.AWS_ROLE_ARN }}
aws-region: ${{ env.AWS_REGION }}
- name: Login to Amazon ECR
id: ecr-login
uses: aws-actions/amazon-ecr-login@062b18b96a7aff071d4dc91bc00c4c1a7945b076
- name: Compute branch metadata
id: meta
run: |
# For PRs, head_ref is the source branch name
RAW_BRANCH="${GITHUB_HEAD_REF:-${GITHUB_REF_NAME}}"
# Sanitize branch name for tags / hostnames (lowercase, only allowed chars)
SANITIZED_BRANCH=$(
printf '%s' "$RAW_BRANCH" \
| tr '[:upper:]' '[:lower:]' \
| tr '._' '-' \
| tr -c 'a-z0-9-' '-' \
| sed -E 's/-{2,}/-/g; s/^-+//; s/-+$//'
)
# Last resort fallback if everything got stripped
if [ -z "$SANITIZED_BRANCH" ]; then
SANITIZED_BRANCH="invalid-branch-name"
fi
echo "raw_branch=$RAW_BRANCH" >> $GITHUB_OUTPUT
echo "branch_name=$SANITIZED_BRANCH" >> $GITHUB_OUTPUT
# ECR repo URL (must match core stack's ECR repo)
ECR_URL="${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/${ECR_REPOSITORY_NAME}"
echo "ecr_url=$ECR_URL" >> $GITHUB_OUTPUT
# Terraform state key for this preview env
TF_STATE_KEY="${PREVIEW_STATE_PREFIX}${SANITIZED_BRANCH}.tfstate"
echo "tf_state_key=$TF_STATE_KEY" >> $GITHUB_OUTPUT
# ALB listener rule priority - derive from PR number (must be unique per listener)
# You can tweak this formula if you like.
if [ -n "${{ github.event.number }}" ]; then
PRIORITY=$(( 1000 + ${{ github.event.number }} ))
else
PRIORITY=1999
fi
echo "alb_rule_priority=$PRIORITY" >> $GITHUB_OUTPUT
- name: Setup Python project
if: github.event.action != 'closed'
uses: ./.github/actions/setup-python-project
with:
python-version: ${{ env.python_version }}
- name: Build Docker image
if: github.event.action != 'closed'
env:
PYTHON_VERSION: ${{ env.python_version }}
run: |
IMAGE_TAG="${{ steps.meta.outputs.branch_name }}"
ECR_URL="${{ steps.meta.outputs.ecr_url }}"
make build IMAGE_TAG="${IMAGE_TAG}" ECR_URL="${ECR_URL}"
- name: Push Docker image to ECR
if: github.event.action != 'closed'
run: |
IMAGE_TAG="${{ steps.meta.outputs.branch_name }}"
ECR_URL="${{ steps.meta.outputs.ecr_url }}"
docker push "${ECR_URL}:${IMAGE_TAG}"
- name: Setup Terraform
uses: hashicorp/setup-terraform@b9cd54a3c349d3f38e8881555d616ced269862dd
with:
terraform_version: 1.14.0
# ---------- APPLY (PR opened / updated) ----------
- name: Terraform init (apply)
if: github.event.action != 'closed'
working-directory: infrastructure/environments/preview
run: |
terraform init \
-backend-config="bucket=${TF_STATE_BUCKET}" \
-backend-config="key=${{ steps.meta.outputs.tf_state_key }}" \
-backend-config="region=${AWS_REGION}"
- name: Terraform apply preview env
if: github.event.action != 'closed'
working-directory: infrastructure/environments/preview
env:
TF_VAR_branch_name: ${{ steps.meta.outputs.branch_name }}
TF_VAR_image_tag: ${{ steps.meta.outputs.branch_name }}
TF_VAR_alb_rule_priority: ${{ steps.meta.outputs.alb_rule_priority }}
run: |
terraform apply -auto-approve
- name: Capture preview TF outputs
if: github.event.action != 'closed'
id: tf-output
working-directory: infrastructure/environments/preview
run: |
terraform output -json > tf-output.json
URL=$(jq -r '.url.value' tf-output.json)
TG=$(jq -r '.target_group_arn.value' tf-output.json)
echo "preview_url=$URL" >> $GITHUB_OUTPUT
echo "target_group=$TG" >> $GITHUB_OUTPUT
# ---------- DESTROY (PR closed) ----------
- name: Terraform init (destroy)
if: github.event.action == 'closed'
working-directory: infrastructure/environments/preview
run: |
terraform init \
-backend-config="bucket=${TF_STATE_BUCKET}" \
-backend-config="key=${{ steps.meta.outputs.tf_state_key }}" \
-backend-config="region=${AWS_REGION}"
- name: Terraform destroy preview env
if: github.event.action == 'closed'
working-directory: infrastructure/environments/preview
env:
TF_VAR_branch_name: ${{ steps.meta.outputs.branch_name }}
TF_VAR_image_tag: ${{ steps.meta.outputs.branch_name }}
TF_VAR_alb_rule_priority: ${{ steps.meta.outputs.alb_rule_priority }}
run: |
terraform destroy -auto-approve
- name: Comment function name on PR
if: github.event_name == 'pull_request' && github.event.action != 'closed'
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd
with:
script: |
const alb = '${{ steps.tf-output.outputs.target_group }}';
const url = '${{ steps.tf-output.outputs.preview_url }}';
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: `ALB Target: \`${alb}\`\nPreview URL: ${url}`
});