-
Notifications
You must be signed in to change notification settings - Fork 0
248 lines (219 loc) · 8.68 KB
/
Copy pathdeploy-to-production.yml
File metadata and controls
248 lines (219 loc) · 8.68 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
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
name: Deploy to AWS Production
on:
workflow_dispatch:
inputs:
release_type:
description: "Part of version to increment (major, minor, patch)"
required: true
default: "minor"
type: choice
options: [patch, minor, major]
release_title:
description: "Optional title to replace auto-generated one"
required: false
type: string
push:
branches: [main]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
tests:
uses: ./.github/workflows/ci.yml
tag_and_notify:
runs-on: ubuntu-latest
needs: ["tests"]
steps:
- run: echo 'Linter and tests passed.'
- name: Check branch is main # Un-comment if you want to test out github action changes on not-main branch
if: github.ref != 'refs/heads/main'
run: |
echo "This workflow can only be run on main branch."
exit 1
- name: Checkout
uses: actions/checkout@v6
with:
fetch-depth: 0 # fetch full history and tags
- name: Fetch tags explicitly
run: git fetch --tags
- name: Get latest tag
id: get_tag
run: |
latest=$(git describe --tags --abbrev=0 || echo "v0.0.0")
echo "Latest tag is $latest"
echo "tag=$latest" >> "$GITHUB_OUTPUT"
- name: Bump version
id: bump
run: |
version="${{ steps.get_tag.outputs.tag }}"
version="${version#v}"
IFS='.' read -r major minor patch <<< "$version"
case "${{ github.event.inputs.release_type }}" in
major)
major=$((major + 1)); minor=0; patch=0;;
minor)
minor=$((minor + 1)); patch=0;;
patch)
patch=$((patch + 1));;
*)
echo "Invalid release_type"; exit 1;;
esac
new_version="v$major.$minor.$patch"
echo "new_tag=$new_version" >> "$GITHUB_OUTPUT"
echo "Next tag: $new_version"
- name: Create and push new tag
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git tag ${{ steps.bump.outputs.new_tag }}
git push origin ${{ steps.bump.outputs.new_tag }}
- name: Create GitHub Release with auto-generated notes
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
TITLE="${{ github.event.inputs.release_title }}"
if [ -z "$TITLE" ]; then
TITLE="${{ steps.bump.outputs.new_tag }}"
fi
echo "Using release title: $TITLE"
gh release create ${{ steps.bump.outputs.new_tag }} --title "$TITLE" --generate-notes
- name: Build Slack payload for release notes
id: slack_payload
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
RAW_NOTES=$(gh release view ${{ steps.bump.outputs.new_tag }} \
--repo ${{ github.repository }} --json body -q .body)
ESCAPED_NOTES=$(jq -Rs '.' <<< "$RAW_NOTES") # raw string literal, properly escaped
PAYLOAD=$(jq -n \
--arg tag "${{ steps.bump.outputs.new_tag }}" \
--arg repo "${{ github.repository }}" \
--argjson notes "$ESCAPED_NOTES" \
--arg logs_url "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" \
'{
text: (
":rocket: A new PYA release *\($tag)* is starting!\nTag: `\($tag)`\n<https://github.com/\($repo)/releases/tag/\($tag)|View on GitHub>\n:page_facing_up: *Release Notes:*\n"
+ $notes
+ "\n:gear: <\($logs_url)|View Action Logs>"
)
}'
)
echo "payload<<EOF" >> $GITHUB_OUTPUT
echo "$PAYLOAD" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
- name: Notify Slack
uses: slackapi/slack-github-action@v3.0.3
if: success()
with:
webhook-type: webhook-trigger
payload: ${{ steps.slack_payload.outputs.payload }}
env:
SLACK_WEBHOOK_URL: ${{ secrets.TAX_ENG_SLACK_URL }}
- name: Notify tag_and_notify failure on Slack
uses: 8398a7/action-slack@v3
if: failure() # && github.ref == 'refs/heads/main' <-- if you want to not alert channel while you work on this
with:
text: "<!subteam^S06P99RGJDS> <@U07QATMB6SW> <@U07Q39HFLBG> PYA production deploy tag_and_notify ${{ job.status }} :sob:"
status: ${{ job.status }}
fields: message,commit,author,workflow,took
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
deploy:
name: deploy
needs: ["tag_and_notify"]
environment: production
runs-on: ubuntu-latest
env:
ECR_REPOSITORY: pya-production-web
IMAGE_TAG: ${{ github.sha }}
INFRA_REPO: tax-benefits-backend
steps:
- run: echo 'Starting the production deploy'
- name: Check out code
uses: actions/checkout@v6
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v6.1.1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_KEY }}
aws-region: us-east-1
- name: Log in to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v2
- name: Build and push Docker image
env:
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
BUNDLE_GITHUB__COM: ${{ secrets.DEPLOY_PAT }}
run: |
docker build -t 828007041297.dkr.ecr.us-east-1.amazonaws.com/pya-production-web:${{env.IMAGE_TAG}} --secret id=github_pat,env=BUNDLE_GITHUB__COM --platform linux/amd64 .
docker push 828007041297.dkr.ecr.us-east-1.amazonaws.com/pya-production-web:${{env.IMAGE_TAG}}
- name: Update SSM Version Parameter
run: |
echo "tag:$IMAGE_TAG"
aws ssm put-parameter \
--name /pya/production/web/version \
--value "$IMAGE_TAG" \
--overwrite
- name: Get a deployment token
uses: actions/create-github-app-token@v3.1.1
id: token
with:
app-id: ${{ secrets.DEPLOYMENT_APP_ID }}
private-key: ${{ secrets.DEPLOYMENT_APP_KEY }}
owner: codeforamerica
repositories: tax-benefits-backend
- name: Trigger infrastructure deployment
uses: codex-/return-dispatch@v3
id: dispatch
with:
token: ${{ steps.token.outputs.token }}
# Update this to match the reference (branch, tag, or
# commit SHA) you want to deploy.
ref: main
# Replace this with the name of the target repository.
repo: tax-benefits-backend
owner: codeforamerica
# Replace this with the name of the workflow to call.
workflow: deploy.yaml
# Workflow inputs should be formatted as JSON. You can
# pass additional inputs as needed.
workflow_inputs: |
{
"environment": "pya-prod",
"config": "pya.fileyourstatetaxes.org"
}
- name: Wait on Workflow
uses: lucasssvaz/wait-on-workflow@v1
id: waiter
with:
github-token: ${{ steps.token.outputs.token }}
repository: codeforamerica/${{ env.INFRA_REPO }}
workflow: ${{ steps.dispatch.outputs.run_id }}
- name: Fail unless the workflow succeeded
if: ${{ steps.waiter.outputs.conclusion != 'success' }}
uses: actions/github-script@v9
with:
script: |
core.setFailed('Deployment workflow completed with status: ${{ steps.waiter.outputs.conclusion }}')
- name: Notify deploy failure on Slack
uses: 8398a7/action-slack@v3
if: failure()
with:
text: "<!subteam^S06P99RGJDS> PYA production deploy ${{ job.status }} :sob:"
status: ${{ job.status }}
fields: message,commit,author,workflow,took
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
- name: Notify deploy success on Slack
uses: slackapi/slack-github-action@v3.0.3
if: success()
with:
webhook-type: webhook-trigger
payload: |
{
"text": ":mega: :sparkles: PYA production deploy ${{ job.status }} :sparkles: Please monitor infrastructure deploy: https://github.com/codeforamerica/tax-benefits-backend/actions/workflows/deploy.yaml\n<!subteam^S06P99RGJDS>"
}
env:
SLACK_WEBHOOK_URL: ${{ secrets.TAX_ENG_SLACK_URL }}