-
Notifications
You must be signed in to change notification settings - Fork 34
354 lines (342 loc) · 15 KB
/
push.yml
File metadata and controls
354 lines (342 loc) · 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
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
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
name: Push
on:
push:
branches:
- master
env:
ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true
concurrency:
group: deploy
jobs:
Lint:
runs-on: ubuntu-latest
if: |
(github.repository == 'PolicyEngine/policyengine-uk')
&& (github.event.head_commit.message == 'Update PolicyEngine API')
steps:
- name: Checkout repo
uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v5
- name: Install ruff
run: pip install ruff>=0.9.0
- name: Format check with ruff
run: ruff format --check .
ensure-staging-model-version-aligns-with-sim-api:
name: Ensure staging model version aligns with simulation API
runs-on: ubuntu-latest
if: |
(github.repository == 'PolicyEngine/policyengine-api')
&& (github.event.head_commit.message == 'Update PolicyEngine API')
environment: staging
steps:
- name: Checkout repo
uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Install dependencies (required for finding API model versions)
run: make install
- name: Install jq (required only for GitHub Actions)
run: sudo apt-get install -y jq
- name: Find API model versions and write to environment variable
run: python3 .github/find-api-model-versions.py
- name: Ensure full API and simulation API model versions are in sync
run: ".github/request-simulation-model-versions.sh -us ${{ env.US_VERSION }} -uk ${{ env.UK_VERSION }}"
env:
SIMULATION_API_URL: ${{ secrets.SIMULATION_API_URL }}
versioning:
name: Update versioning
if: |
(github.repository == 'PolicyEngine/policyengine-api')
&& !(github.event.head_commit.message == 'Update PolicyEngine API')
runs-on: ubuntu-latest
steps:
- name: Generate GitHub App token
id: app-token
uses: actions/create-github-app-token@v1
with:
app-id: ${{ secrets.APP_ID }}
private-key: ${{ secrets.APP_PRIVATE_KEY }}
- name: Checkout repo
uses: actions/checkout@v4
with:
token: ${{ steps.app-token.outputs.token }}
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Build changelog
run: |
pip install towncrier
python .github/bump_version.py
towncrier build --yes --version $(python -c "import re; print(re.search(r'version = \"(.+?)\"', open('pyproject.toml').read()).group(1))")
- name: Preview changelog update
run: ".github/get-changelog-diff.sh"
- name: Update changelog
uses: EndBug/add-and-commit@v9
with:
add: "."
committer_name: Github Actions[bot]
author_name: Github Actions[bot]
message: Update PolicyEngine API
publish-git-tag:
name: Publish Git Tag
runs-on: ubuntu-latest
needs: ensure-staging-model-version-aligns-with-sim-api
if: |
(github.repository == 'PolicyEngine/policyengine-api')
&& (github.event.head_commit.message == 'Update PolicyEngine API')
steps:
- name: Checkout repo
uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Publish Git Tag
run: ".github/publish-git-tag.sh"
deploy-staging:
name: Deploy staging App Engine version
runs-on: ubuntu-latest
needs:
- ensure-staging-model-version-aligns-with-sim-api
- publish-git-tag
if: |
(github.repository == 'PolicyEngine/policyengine-api')
&& (github.event.head_commit.message == 'Update PolicyEngine API')
environment: staging
permissions:
contents: read
id-token: write
outputs:
version: ${{ steps.version.outputs.version }}
url: ${{ steps.version_url.outputs.url }}
steps:
- name: Checkout repo
uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Install system dependencies
run: sudo apt-get update && sudo apt-get install -y redis-server
- name: Start Redis
run: sudo systemctl start redis-server
- name: Compute staging version name
id: version
run: |
echo "version=staging-${GITHUB_RUN_NUMBER}-${GITHUB_SHA::7}" >> "$GITHUB_OUTPUT"
- name: GCP authentication
uses: "google-github-actions/auth@v2"
with:
workload_identity_provider: "${{ secrets.GCP_WORKLOAD_IDENTITY_PROVIDER }}"
service_account: "${{ secrets.GCP_DEPLOY_SERVICE_ACCOUNT }}"
- name: Set up GCloud
uses: "google-github-actions/setup-gcloud@v2"
- name: Install dependencies
run: make install
- name: Run push-time tests
run: make test
env:
POLICYENGINE_DB_PASSWORD: ${{ secrets.POLICYENGINE_DB_PASSWORD }}
POLICYENGINE_GITHUB_MICRODATA_AUTH_TOKEN: ${{ secrets.POLICYENGINE_GITHUB_MICRODATA_AUTH_TOKEN }}
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
HUGGING_FACE_TOKEN: ${{ secrets.HUGGING_FACE_TOKEN }}
- name: Validate App Engine deployment configuration
run: bash .github/scripts/validate_app_engine_deploy_env.sh
env:
# Transitional: these values are still passed into the deploy bundle
# by gcp/export.py. Long-term target is a generic image plus runtime
# config / Secret Manager lookups instead of image bake-in.
SIMULATION_API_URL: ${{ secrets.SIMULATION_API_URL }}
GATEWAY_AUTH_ISSUER: ${{ secrets.GATEWAY_AUTH_ISSUER }}
GATEWAY_AUTH_AUDIENCE: ${{ secrets.GATEWAY_AUTH_AUDIENCE }}
GATEWAY_AUTH_CLIENT_ID: ${{ secrets.GATEWAY_AUTH_CLIENT_ID }}
GATEWAY_AUTH_CLIENT_SECRET_RESOURCE: ${{ secrets.GATEWAY_AUTH_CLIENT_SECRET_RESOURCE }}
- name: Build staging deploy image
run: bash .github/scripts/build_app_engine_image.sh
env:
# Transitional: these values are still rendered into the App Engine
# image today. Long-term target is to stop passing them into the
# image build and supply them as runtime config / Secret Manager data.
APP_ENGINE_IMAGE_TAG: policyengine-api:staging-${{ steps.version.outputs.version }}
POLICYENGINE_DB_PASSWORD: ${{ secrets.POLICYENGINE_DB_PASSWORD }}
POLICYENGINE_GITHUB_MICRODATA_AUTH_TOKEN: ${{ secrets.POLICYENGINE_GITHUB_MICRODATA_AUTH_TOKEN }}
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
HUGGING_FACE_TOKEN: ${{ secrets.HUGGING_FACE_TOKEN }}
SIMULATION_API_URL: ${{ secrets.SIMULATION_API_URL }}
GATEWAY_AUTH_ISSUER: ${{ secrets.GATEWAY_AUTH_ISSUER }}
GATEWAY_AUTH_AUDIENCE: ${{ secrets.GATEWAY_AUTH_AUDIENCE }}
GATEWAY_AUTH_CLIENT_ID: ${{ secrets.GATEWAY_AUTH_CLIENT_ID }}
GATEWAY_AUTH_CLIENT_SECRET_RESOURCE: ${{ secrets.GATEWAY_AUTH_CLIENT_SECRET_RESOURCE }}
- name: Deploy staging version
run: bash .github/scripts/deploy_app_engine_version.sh
env:
# Transitional: deploy_app_engine_version.sh still prepares a bundle
# from these values before App Engine deploy. Long-term target is one
# generic image plus runtime config / Secret Manager.
APP_ENGINE_VERSION: ${{ steps.version.outputs.version }}
APP_ENGINE_PROMOTE: "0"
POLICYENGINE_DB_PASSWORD: ${{ secrets.POLICYENGINE_DB_PASSWORD }}
POLICYENGINE_GITHUB_MICRODATA_AUTH_TOKEN: ${{ secrets.POLICYENGINE_GITHUB_MICRODATA_AUTH_TOKEN }}
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
HUGGING_FACE_TOKEN: ${{ secrets.HUGGING_FACE_TOKEN }}
SIMULATION_API_URL: ${{ secrets.SIMULATION_API_URL }}
GATEWAY_AUTH_ISSUER: ${{ secrets.GATEWAY_AUTH_ISSUER }}
GATEWAY_AUTH_AUDIENCE: ${{ secrets.GATEWAY_AUTH_AUDIENCE }}
GATEWAY_AUTH_CLIENT_ID: ${{ secrets.GATEWAY_AUTH_CLIENT_ID }}
GATEWAY_AUTH_CLIENT_SECRET_RESOURCE: ${{ secrets.GATEWAY_AUTH_CLIENT_SECRET_RESOURCE }}
- name: Resolve staging version URL
id: version_url
run: |
url="$(bash .github/scripts/get_app_engine_version_url.sh)"
echo "url=${url}" >> "$GITHUB_OUTPUT"
env:
APP_ENGINE_VERSION: ${{ steps.version.outputs.version }}
- name: Wait for staging version health
run: bash .github/scripts/health_check.sh "${{ steps.version_url.outputs.url }}/readiness-check"
integration-tests-staging:
name: Run staging integration tests
runs-on: ubuntu-latest
needs: deploy-staging
if: |
(github.repository == 'PolicyEngine/policyengine-api')
&& (github.event.head_commit.message == 'Update PolicyEngine API')
steps:
- name: Checkout repo
uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Install staging test dependencies
run: pip install pytest httpx
- name: Run staging smoke test
run: python -m pytest tests/integration/test_live_calculate.py tests/integration/test_live_economy.py tests/integration/test_live_budget_window_cache.py -v
env:
API_BASE_URL: ${{ needs.deploy-staging.outputs.url }}
STAGING_API_TEST_PROBE_ID: ${{ needs.deploy-staging.outputs.version }}
ensure-production-model-version-aligns-with-sim-api:
name: Ensure production model version aligns with simulation API
runs-on: ubuntu-latest
needs: integration-tests-staging
if: |
(github.repository == 'PolicyEngine/policyengine-api')
&& (github.event.head_commit.message == 'Update PolicyEngine API')
environment: production
steps:
- name: Checkout repo
uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Install dependencies (required for finding API model versions)
run: make install
- name: Install jq (required only for GitHub Actions)
run: sudo apt-get install -y jq
- name: Find API model versions and write to environment variable
run: python3 .github/find-api-model-versions.py
- name: Ensure full API and simulation API model versions are in sync
run: ".github/request-simulation-model-versions.sh -us ${{ env.US_VERSION }} -uk ${{ env.UK_VERSION }}"
env:
SIMULATION_API_URL: ${{ secrets.SIMULATION_API_URL }}
deploy-production:
name: Deploy production App Engine version
runs-on: ubuntu-latest
needs: ensure-production-model-version-aligns-with-sim-api
if: |
(github.repository == 'PolicyEngine/policyengine-api')
&& (github.event.head_commit.message == 'Update PolicyEngine API')
environment: production
permissions:
contents: read
id-token: write
steps:
- name: Checkout repo
uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Compute production version name
id: version
run: |
echo "version=prod-${GITHUB_RUN_NUMBER}-${GITHUB_SHA::7}" >> "$GITHUB_OUTPUT"
- name: GCP authentication
uses: "google-github-actions/auth@v2"
with:
workload_identity_provider: "${{ secrets.GCP_WORKLOAD_IDENTITY_PROVIDER }}"
service_account: "${{ secrets.GCP_DEPLOY_SERVICE_ACCOUNT }}"
- name: Set up GCloud
uses: "google-github-actions/setup-gcloud@v2"
- name: Validate App Engine deployment configuration
run: bash .github/scripts/validate_app_engine_deploy_env.sh
env:
# Transitional: these values are still passed into the deploy bundle
# by gcp/export.py. Long-term target is a generic image plus runtime
# config / Secret Manager lookups instead of image bake-in.
SIMULATION_API_URL: ${{ secrets.SIMULATION_API_URL }}
GATEWAY_AUTH_ISSUER: ${{ secrets.GATEWAY_AUTH_ISSUER }}
GATEWAY_AUTH_AUDIENCE: ${{ secrets.GATEWAY_AUTH_AUDIENCE }}
GATEWAY_AUTH_CLIENT_ID: ${{ secrets.GATEWAY_AUTH_CLIENT_ID }}
GATEWAY_AUTH_CLIENT_SECRET_RESOURCE: ${{ secrets.GATEWAY_AUTH_CLIENT_SECRET_RESOURCE }}
- name: Deploy production version
run: bash .github/scripts/deploy_app_engine_version.sh
env:
# Transitional: deploy_app_engine_version.sh still prepares a bundle
# from these values before App Engine deploy. Long-term target is one
# generic image plus runtime config / Secret Manager.
APP_ENGINE_VERSION: ${{ steps.version.outputs.version }}
APP_ENGINE_PROMOTE: "0"
POLICYENGINE_DB_PASSWORD: ${{ secrets.POLICYENGINE_DB_PASSWORD }}
POLICYENGINE_GITHUB_MICRODATA_AUTH_TOKEN: ${{ secrets.POLICYENGINE_GITHUB_MICRODATA_AUTH_TOKEN }}
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
HUGGING_FACE_TOKEN: ${{ secrets.HUGGING_FACE_TOKEN }}
SIMULATION_API_URL: ${{ secrets.SIMULATION_API_URL }}
GATEWAY_AUTH_ISSUER: ${{ secrets.GATEWAY_AUTH_ISSUER }}
GATEWAY_AUTH_AUDIENCE: ${{ secrets.GATEWAY_AUTH_AUDIENCE }}
GATEWAY_AUTH_CLIENT_ID: ${{ secrets.GATEWAY_AUTH_CLIENT_ID }}
GATEWAY_AUTH_CLIENT_SECRET_RESOURCE: ${{ secrets.GATEWAY_AUTH_CLIENT_SECRET_RESOURCE }}
- name: Resolve production version URL
id: version_url
run: |
url="$(bash .github/scripts/get_app_engine_version_url.sh)"
echo "url=${url}" >> "$GITHUB_OUTPUT"
env:
APP_ENGINE_VERSION: ${{ steps.version.outputs.version }}
- name: Wait for production version health
run: bash .github/scripts/health_check.sh "${{ steps.version_url.outputs.url }}/readiness-check"
- name: Promote production version
run: bash .github/scripts/promote_app_engine_version.sh
env:
APP_ENGINE_VERSION: ${{ steps.version.outputs.version }}
docker:
name: Docker
runs-on: ubuntu-latest
needs: deploy-production
if: |
(github.repository == 'PolicyEngine/policyengine-api')
&& (github.event.head_commit.message == 'Update PolicyEngine API')
permissions:
contents: read
packages: write
steps:
- name: Checkout repo
uses: actions/checkout@v4
- name: Log in to the Container registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build container
run: docker build -t ghcr.io/policyengine/policyengine docker
- name: Push container
run: docker push ghcr.io/policyengine/policyengine