Repository navigation
110 lines (103 loc) · 4.16 KB
/
Copy pathdeploy.yml
File metadata and controls
110 lines (103 loc) · 4.16 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
# Deploys one commit's image and frontend build to an environment (aws-deployment tickets 07 and
# 08), as two jobs side by side: the backend applies the main configuration, which points both
# functions at the image's digest, and runs one build; the frontend publishes outside data/. Both
# start together, so one approval of a protected environment releases both. Called by pipeline.yml.
#
# Neither waits for the other, so for the minute or so a contract bump takes to land, pages say
# the data and interface are out of step (PRD §7.3) until the other job finishes.
name: deploy
on:
workflow_call:
inputs:
environment:
description: dev or prod; picks the GitHub environment, CI role, workspace and tfvars.
type: string
required: true
image_uri:
description: The image by digest, as push-image.sh printed it.
type: string
required: true
permissions:
contents: read
env:
AWS_REGION: ap-southeast-1
ENVIRONMENT: ${{ inputs.environment }}
CI_ROLE: arn:aws:iam::132218943709:role/github-actions-interface-${{ inputs.environment }}
jobs:
backend:
runs-on: ubuntu-26.04
environment: ${{ inputs.environment }}
# One deploy per environment at a time; a newer one waits rather than cancelling one half done.
concurrency:
group: deploy-${{ inputs.environment }}-backend
cancel-in-progress: false
permissions:
contents: read
id-token: write
env:
IMAGE_URI: ${{ inputs.image_uri }}
TF_IN_AUTOMATION: "1"
# Selected before init: each CI role can reach only its own environment's state.
TF_WORKSPACE: ${{ inputs.environment }}
steps:
- uses: actions/checkout@v7
- uses: aws-actions/configure-aws-credentials@v6
with:
role-to-assume: ${{ env.CI_ROLE }}
aws-region: ${{ env.AWS_REGION }}
- uses: hashicorp/setup-terraform@v4
with:
terraform_version: "v1.17.0"
terraform_wrapper: false
- name: terraform apply
id: terraform
working-directory: infra/main
run: |
terraform init -input=false
terraform apply -input=false -auto-approve -var-file="$ENVIRONMENT.tfvars" -var "image_uri=$IMAGE_URI"
{
echo "build_function=$(terraform output -raw build_function)"
echo "extract_function=$(terraform output -raw extract_function)"
} >> "$GITHUB_OUTPUT"
{
echo "Deployed \`$IMAGE_URI\` to $ENVIRONMENT"
echo "- $(terraform output -raw site_url)"
echo "- https://$(terraform output -raw distribution_domain)"
} >> "$GITHUB_STEP_SUMMARY"
# A build on the new image, so the data is built to its contract version.
- name: Build the data
env:
BUILD_FUNCTION: ${{ steps.terraform.outputs.build_function }}
EXTRACT_FUNCTION: ${{ steps.terraform.outputs.extract_function }}
run: |
for function in "$BUILD_FUNCTION" "$EXTRACT_FUNCTION"; do
aws lambda wait function-updated-v2 --function-name "$function"
done
error="$(aws lambda invoke --function-name "$BUILD_FUNCTION" \
--cli-read-timeout 0 --query FunctionError --output text build.json)"
cat build.json; echo
if [ "$error" != "None" ]; then echo "the build failed: $error" >&2; exit 1; fi
frontend:
runs-on: ubuntu-26.04
environment: ${{ inputs.environment }}
concurrency:
group: deploy-${{ inputs.environment }}-frontend
cancel-in-progress: false
permissions:
contents: read
id-token: write
env:
# Named by the admin configuration (infra/admin, ADR 0005), so no terraform is needed here.
SITE_BUCKET: snacker-tracker-${{ inputs.environment }}-site
steps:
- uses: actions/checkout@v7
- uses: aws-actions/configure-aws-credentials@v6
with:
role-to-assume: ${{ env.CI_ROLE }}
aws-region: ${{ env.AWS_REGION }}
- uses: actions/download-artifact@v8
with:
name: frontend-${{ github.sha }}
path: frontend/dist
- name: Publish the frontend
run: frontend/scripts/sync-site.sh "$SITE_BUCKET"