Repository navigation
105 lines (98 loc) · 4.15 KB
/
Copy pathdeploy.yml
File metadata and controls
105 lines (98 loc) · 4.15 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
# 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 every
# function of the stepdag graph at the image's digest, and the graph's next scheduled run
# publishes data/ on it. The frontend publishes outside data/. Both start together, so one
# approval of a protected environment releases both. Called by pipeline.yml.
#
# So after a contract bump, pages say the data and interface are out of step (PRD §7.3) until the
# graph's next run, up to 30 minutes later.
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 }}
# No concurrency group: one held every newer deploy behind a run awaiting approval. So approve
# only the newest run (an older one deploys older code); overlapping applies take turns on the
# state lock.
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.1"
terraform_wrapper: false
- name: terraform apply
working-directory: infra/main
run: |
terraform init -input=false
terraform apply -input=false -auto-approve -lock-timeout=15m -var-file="$ENVIRONMENT.tfvars" -var "image_uri=$IMAGE_URI"
{
echo "Deployed \`$IMAGE_URI\` to $ENVIRONMENT"
echo "- $(terraform output -raw site_url)"
echo "- https://$(terraform output -raw distribution_domain)"
} >> "$GITHUB_STEP_SUMMARY"
# Tags the image `<environment>-<UTC time>`, so the repository's lifecycle rules (aws-infra's
# ecr.tf) keep it while it's among this environment's latest deploys. The same manifest under
# a new tag, checked against the digest: tags are immutable, so this never moves one.
- name: Tag the deployed image
run: |
repository="${IMAGE_URI#*/}"
repository="${repository%@*}"
digest="${IMAGE_URI#*@}"
image() {
aws ecr batch-get-image --repository-name "$repository" --image-ids imageDigest="$digest" \
--query "images[0].$1" --output text
}
aws ecr put-image --repository-name "$repository" --image-digest "$digest" \
--image-tag "$ENVIRONMENT-$(date -u +%Y%m%dT%H%M%SZ)" \
--image-manifest "$(image imageManifest)" --image-manifest-media-type "$(image imageManifestMediaType)" \
--query image.imageId.imageTag --output text
frontend:
runs-on: ubuntu-26.04
environment: ${{ inputs.environment }}
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"