-
Notifications
You must be signed in to change notification settings - Fork 473
335 lines (299 loc) · 12.1 KB
/
release-v3.yml
File metadata and controls
335 lines (299 loc) · 12.1 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
name: Release V3
# RELEASE PROCESS
#
# === Automated activities ===
#
# 1. [Seal] Bump to release version and export source code with integrity hash
# 2. [Quality check] Restore sealed source code, run tests, linting, security and complexity base line
# 3. [Build] Restore sealed source code, create and export hashed build artifact for PyPi release (wheel, tarball)
# 4. [Provenance] Generates provenance for build, signs attestation with GitHub OIDC claims to confirm it came from this release pipeline, commit, org, repo, branch, hash, etc.
# 5. [Release] Restore built artifact, and publish package to PyPi prod repository
# 6. [Create Tag] Restore sealed source code, create a new git tag using released version, uploads provenance to latest draft release
# 7. [PR to bump version] Restore sealed source code, and create a PR to update trunk with latest released project metadata
# 8. [Publish Layer v3] Compile Layer in multiple Python versions and kick off pipeline for beta, prod, and canary releases
# 9. [Publish Layer v3] Update docs with latest Layer ARNs and Changelog
# 10. [Publish Layer v3] Create PR to update trunk so staged docs also point to the latest Layer ARN, when merged
# 12. [Post release] Close all issues labeled "pending-release" and notify customers about the release
#
# === Manual activities ===
#
# 1. Kick off this workflow with the intended version
# 2. Update draft release notes after this workflow completes
# 3. If not already set, use `v<new version>` as a tag, e.g., v3.0.0, and select develop as target branch
# NOTE
#
# See MAINTAINERS.md "Releasing a new version" for release mechanisms
#
# Every job is isolated and starts a new fresh container.
env:
RELEASE_COMMIT: ${{ github.sha }}
RELEASE_TAG_VERSION: ${{ inputs.version_to_publish }}
on:
workflow_dispatch:
inputs:
version_to_publish:
description: "Version to be released in PyPi, Docs, and Lambda Layer, e.g. v3.0.0, v3.0.0a0 (pre-release)"
default: v3.0.0
required: true
layer_documentation_version:
description: "Lambda layer version to be updated in our documentation. e.g. if the current layer number is 3, this value must be 4."
type: string
required: true
skip_pypi:
description: "Skip publishing to PyPi as it can't publish more than once. Useful for semi-failed releases"
default: false
type: boolean
required: false
skip_lambda_layer:
description: "Skip publishing Lambda Layers as it can publish duplicated versions of the same layer. Useful for semi-failed releases"
default: false
type: boolean
required: false
skip_code_quality:
description: "Skip tests, linting, and baseline. Only use if release fail for reasons beyond our control and you need a quick release."
default: false
type: boolean
required: false
pre_release:
description: "Publishes documentation using a pre-release tag (v3.0.0a0). You are still responsible for passing a pre-release version tag to the workflow."
default: false
type: boolean
required: false
permissions:
contents: read
jobs:
seal:
runs-on: ubuntu-latest
permissions:
contents: read
outputs:
integrity_hash: ${{ steps.seal_source_code.outputs.integrity_hash }}
artifact_name: ${{ steps.seal_source_code.outputs.artifact_name }}
RELEASE_VERSION: ${{ steps.release_version.outputs.RELEASE_VERSION }}
steps:
- name: Export release version
id: release_version
# transform tag format `v<version` to `<version>`
run: |
RELEASE_VERSION="${RELEASE_TAG_VERSION:1}"
echo "RELEASE_VERSION=${RELEASE_VERSION}" >> "$GITHUB_OUTPUT"
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
ref: ${{ env.RELEASE_COMMIT }}
- name: Update version in pyproject.toml
run: sed -i 's/^version = ".*"/version = "${{ steps.release_version.outputs.RELEASE_VERSION }}"/' pyproject.toml
- name: Update version in version.py
run: sed -i 's/^VERSION = ".*"/VERSION = "${{ steps.release_version.outputs.RELEASE_VERSION }}"/' aws_lambda_powertools/shared/version.py
- name: Seal and upload
id: seal_source_code
uses: ./.github/actions/seal
with:
artifact_name_prefix: "source"
quality_check:
needs: seal
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
ref: ${{ env.RELEASE_COMMIT }}
- name: Restore sealed source code
uses: ./.github/actions/seal-restore
with:
integrity_hash: ${{ needs.seal.outputs.integrity_hash }}
artifact_name: ${{ needs.seal.outputs.artifact_name }}
- name: Debug cache restore
run: cat pyproject.toml
- name: Install uv
uses: astral-sh/setup-uv@6b9c6063abd6010835644d4c2e1bef4cf5cd0fca # v6.0.1
with:
enable-cache: true
- name: Set up Python
uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0
with:
python-version: "3.14"
- name: Install dependencies
run: make dev
- name: Run all tests, linting and baselines
run: make pr
build:
runs-on: ubuntu-latest
needs: [quality_check, seal]
permissions:
contents: read
outputs:
integrity_hash: ${{ steps.seal_build.outputs.integrity_hash }}
artifact_name: ${{ steps.seal_build.outputs.artifact_name }}
attestation_hashes: ${{ steps.encoded_hash.outputs.attestation_hashes }}
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
ref: ${{ env.RELEASE_COMMIT }}
- name: Restore sealed source code
uses: ./.github/actions/seal-restore
with:
integrity_hash: ${{ needs.seal.outputs.integrity_hash }}
artifact_name: ${{ needs.seal.outputs.artifact_name }}
- name: Install uv
uses: astral-sh/setup-uv@6b9c6063abd6010835644d4c2e1bef4cf5cd0fca # v6.0.1
with:
enable-cache: true
- name: Set up Python
uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0
with:
python-version: "3.14"
- name: Build python package and wheel
run: uv build
- name: Seal and upload
id: seal_build
uses: ./.github/actions/seal
with:
artifact_name_prefix: "build"
files: "dist/"
- name: Create attestation encoded hash for provenance
id: encoded_hash
working-directory: dist
run: echo "attestation_hashes=$(sha256sum ./* | base64 -w0)" >> "$GITHUB_OUTPUT"
provenance:
needs: [seal, build]
permissions:
contents: write
actions: read
id-token: write
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v2.1.0
with:
base64-subjects: ${{ needs.build.outputs.attestation_hashes }}
upload-assets: false
release:
needs: [build, seal, provenance]
environment: release
runs-on: ubuntu-latest
permissions:
id-token: write
env:
RELEASE_VERSION: ${{ needs.seal.outputs.RELEASE_VERSION }}
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
ref: ${{ env.RELEASE_COMMIT }}
- name: Restore sealed source code
uses: ./.github/actions/seal-restore
with:
integrity_hash: ${{ needs.build.outputs.integrity_hash }}
artifact_name: ${{ needs.build.outputs.artifact_name }}
- name: Upload to PyPi prod
if: ${{ !inputs.skip_pypi }}
uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # v1.13.0
create_tag:
needs: [release, seal, provenance]
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
ref: ${{ env.RELEASE_COMMIT }}
- name: Restore sealed source code
uses: ./.github/actions/seal-restore
with:
integrity_hash: ${{ needs.seal.outputs.integrity_hash }}
artifact_name: ${{ needs.seal.outputs.artifact_name }}
- id: setup-git
name: Git client setup and refresh tip
run: |
git config user.name "Powertools for AWS Lambda (Python) bot"
git config user.email "151832416+aws-powertools-bot@users.noreply.github.com"
git config remote.origin.url >&-
- name: Create Git Tag
run: |
git add pyproject.toml aws_lambda_powertools/shared/version.py
git commit -m "chore: version bump"
git tag -a v"${RELEASE_VERSION}" -m "release_version: v${RELEASE_VERSION}"
git push origin v"${RELEASE_VERSION}"
env:
RELEASE_VERSION: ${{ needs.seal.outputs.RELEASE_VERSION }}
- name: Upload provenance
id: upload-provenance
uses: ./.github/actions/upload-release-provenance
with:
release_version: ${{ needs.seal.outputs.RELEASE_VERSION }}
provenance_name: ${{needs.provenance.outputs.provenance-name}}
github_token: ${{ secrets.GITHUB_TOKEN }}
bump_version:
needs: [release, seal]
permissions:
contents: write
pull-requests: write
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
ref: ${{ env.RELEASE_COMMIT }}
- name: Restore sealed source code
uses: ./.github/actions/seal-restore
with:
integrity_hash: ${{ needs.seal.outputs.integrity_hash }}
artifact_name: ${{ needs.seal.outputs.artifact_name }}
- name: Create PR
id: create-pr
uses: ./.github/actions/create-pr
with:
files: "pyproject.toml aws_lambda_powertools/shared/version.py"
temp_branch_prefix: "ci-bump"
pull_request_title: "chore(ci): bump version to ${{ needs.seal.outputs.RELEASE_VERSION }}"
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_layer:
needs: [seal, release, create_tag]
secrets: inherit
permissions:
id-token: write
contents: write
pages: write
pull-requests: write
uses: ./.github/workflows/publish_v3_layer.yml
with:
latest_published_version: ${{ needs.seal.outputs.RELEASE_VERSION }}
layer_documentation_version: ${{ inputs.layer_documentation_version }}
pre_release: ${{ inputs.pre_release }}
source_code_artifact_name: ${{ needs.seal.outputs.artifact_name }}
source_code_integrity_hash: ${{ needs.seal.outputs.integrity_hash }}
skip_lambda_layer: ${{ inputs.skip_lambda_layer }}
post_release:
needs: [seal, release, publish_layer]
permissions:
contents: read
issues: write
discussions: write
pull-requests: write
runs-on: ubuntu-latest
env:
RELEASE_VERSION: ${{ needs.seal.outputs.RELEASE_VERSION }}
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
ref: ${{ env.RELEASE_COMMIT }}
- name: Restore sealed source code
uses: ./.github/actions/seal-restore
with:
integrity_hash: ${{ needs.seal.outputs.integrity_hash }}
artifact_name: ${{ needs.seal.outputs.artifact_name }}
- name: Close issues related to this release
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const post_release = require('.github/scripts/post_release.js')
await post_release({github, context, core})
update_ssm:
needs: [seal, release, publish_layer]
secrets: inherit
permissions:
id-token: write
contents: read
uses: ./.github/workflows/update_ssm.yml
with:
environment: "Prod"
write_latest: true
package_version: ${{ needs.seal.outputs.RELEASE_VERSION }}
layer_version: ${{ inputs.layer_documentation_version }}