Skip to content

Commit 29c2403

Browse files
authored
chore(ci): increase release automation and limit to one manual step (aws-powertools#1297)
1 parent 2945acb commit 29c2403

File tree

7 files changed

+103
-69
lines changed

7 files changed

+103
-69
lines changed

.chglog/CHANGELOG.tpl.md

+10-6
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
1+
<!-- changelog is partially generated, so it doesn't follow headings and required structure, so we disable it. -->
2+
<!-- markdownlint-disable -->
3+
14
{{ if .Versions -}}
25
<a name="unreleased"></a>
3-
## Unreleased
6+
# Unreleased
47

58
{{ if .Unreleased.CommitGroups -}}
69
{{ range .Unreleased.CommitGroups -}}
7-
### {{ .Title }}
10+
## {{ .Title }}
811

912
{{ range .Commits -}}
1013
* {{ if .Scope }}**{{ .Scope }}:** {{ end }}{{ .Subject }}
@@ -17,22 +20,23 @@
1720
<a name="{{ .Tag.Name }}"></a>
1821
## {{ if .Tag.Previous }}[{{ .Tag.Name }}]{{ else }}{{ .Tag.Name }}{{ end }} - {{ datetime "2006-01-02" .Tag.Date }}
1922
{{ range .CommitGroups -}}
20-
### {{ .Title }}
23+
24+
## {{ .Title }}
2125

2226
{{ range .Commits -}}
2327
* {{ if .Scope }}**{{ .Scope }}:** {{ end }}{{ .Subject }}
2428
{{ end }}
2529
{{ end -}}
2630

2731
{{- if .RevertCommits -}}
28-
### Reverts
32+
## Reverts
2933
{{ range .RevertCommits -}}
3034
* {{ .Revert.Header }}
3135
{{ end }}
3236
{{ end -}}
3337

3438
{{- if .MergeCommits -}}
35-
### Pull Requests
39+
## Pull Requests
3640

3741
{{ range .MergeCommits -}}
3842
* {{ .Header }}
@@ -41,7 +45,7 @@
4145

4246
{{- if .NoteGroups -}}
4347
{{ range .NoteGroups -}}
44-
### {{ .Title }}
48+
## {{ .Title }}
4549
{{ range .Notes }}
4650
{{ .Body }}
4751
{{ end }}

.chglog/config.yml

+3
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,6 @@ options:
3232
notes:
3333
keywords:
3434
- BREAKING CHANGE
35+
# issues:
36+
# prefix:
37+
# - #

.github/scripts/post_release.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -100,13 +100,13 @@ const notifyRelease = async ({
100100

101101
// context: https://github.com/actions/toolkit/blob/main/packages/github/src/context.ts
102102
module.exports = async ({ github, context }) => {
103-
const { RELEASE_TAG_VERSION } = process.env;
104-
console.log(`Running post-release script for ${RELEASE_TAG_VERSION} version`);
103+
const { RELEASE_VERSION } = process.env;
104+
console.log(`Running post-release script for ${RELEASE_VERSION} version`);
105105

106106
await notifyRelease({
107107
gh_client: github,
108108
owner: context.repo.owner,
109109
repository: context.repo.repo,
110-
release_version: RELEASE_TAG_VERSION,
110+
release_version: RELEASE_VERSION,
111111
});
112112
};

.github/workflows/publish.yml

+63-37
Original file line numberDiff line numberDiff line change
@@ -4,44 +4,38 @@ name: Publish to PyPi
44
#
55
# === Manual activities ===
66
#
7-
# 1. Document human readable changes in CHANGELOG (pre-generate unreleased changes with `make changelog`)
8-
# 2. Bump package version using poetry version <major|minor|patch|specific version>
9-
# 3. Merge version changes to develop branch
10-
# 4. Edit the current draft release notes
11-
# 5. If not already set, use `v<new version>` as a tag, and select develop as target branch
7+
# 1. Edit the current draft release notes
8+
# 2. If not already set, use `v<new version>` as a tag, e.g., v1.26.4, and select develop as target branch
129
#
1310
# === Automated activities ===
1411
#
1512
# 1. Extract release notes tag that was published
16-
# 2. Ensure release notes tag match what's in CHANGELOG and pyproject
17-
# 3. Run tests, linting, security and complexity base line
18-
# 4. Publish package to PyPi test repository
19-
# 5. Publish package to PyPi prod repository
20-
# 6. Kick off Lambda Layer pipeline to publish latest version with minimal dependencies as a SAR App
21-
# 7. Kick off Lambda Layer pipeline to publish latest version with extra dependencies as a SAR App
22-
# 8. Builds a fresh version of docs including Changelog updates
23-
# 9. Builds latest documentation for new release, and update latest alias pointing to the new release tag
24-
# 10. Close and notify all issues labeled "pending-release" about the release details
13+
# 2. Run tests, linting, security and complexity base line
14+
# 3. Bump package version and generate latest Changelog
15+
# 4. Publish package to PyPi test and prod repository
16+
# 5. Kick off SAR App pipeline to publish latest version with minimal and extra dependencies
17+
# 6. Builds a new user guide and API docs with release version; update /latest pointing to newly released version
18+
# 7. Close all issues labeled "pending-release" and notify customers about the release
2519

26-
#
27-
# === Fallback mechanism due to external failures ===
28-
#
29-
# 1. Trigger "Publish to PyPi" workflow manually: https://docs.github.com/en/actions/managing-workflow-runs/manually-running-a-workflow
30-
# 2. Use the version released under Releases e.g. v1.13.0
31-
#
32-
33-
#
34-
# === Documentation hotfix ===
35-
#
36-
# Look for rebuild latest docs workflow
20+
# See MAINTAINERS.md "Releasing a new version" for release mechanisms
3721

3822
on:
3923
release:
4024
types: [published]
25+
workflow_dispatch:
26+
inputs:
27+
version_to_publish:
28+
description: "Version to be released in PyPi, Docs, and Lambda Layer, e.g. v1.26.4"
29+
default: v1.26.4
30+
required: true
4131

4232
jobs:
4333
release:
4434
runs-on: ubuntu-latest
35+
outputs:
36+
RELEASE_VERSION: ${{ steps.release_version.outputs.RELEASE_VERSION }}
37+
env:
38+
RELEASE_TAG_VERSION: ${{ github.event.release.tag_name || inputs.version_to_publish }}
4539
steps:
4640
- uses: actions/checkout@v3
4741
with:
@@ -51,17 +45,30 @@ jobs:
5145
with:
5246
python-version: "3.8"
5347
- name: Set release notes tag
48+
id: release_version
49+
# transform tag format `v<version` to `<version`
5450
run: |
55-
RELEASE_TAG_VERSION=${{ github.event.release.tag_name }}
56-
echo "RELEASE_TAG_VERSION=${RELEASE_TAG_VERSION:1}" >> $GITHUB_ENV
57-
- name: Ensure new version is also set in pyproject and CHANGELOG
58-
run: |
59-
grep --regexp "${RELEASE_TAG_VERSION}" CHANGELOG.md
60-
grep --regexp "version \= \"${RELEASE_TAG_VERSION}\"" pyproject.toml
51+
RELEASE_VERSION=${RELEASE_TAG_VERSION:1}
52+
echo "RELEASE_VERSION=${RELEASE_VERSION}" >> $GITHUB_ENV
53+
echo "::set-output name=RELEASE_VERSION::${RELEASE_VERSION}"
6154
- name: Install dependencies
6255
run: make dev
6356
- name: Run all tests, linting and baselines
6457
run: make pr
58+
- name: Bump package version
59+
run: poetry version ${RELEASE_VERSION}
60+
- name: Generate latest CHANGELOG
61+
run: make changelog
62+
- name: Setup git client
63+
run: |
64+
git config user.name "Release bot"
65+
git config user.email [email protected]
66+
- name: Push project metadata and changelog to trunk
67+
run: |
68+
git add CHANGELOG.md
69+
git add pyproject.toml
70+
git commit -m "chore(ci): update project with version ${RELEASE_VERSION}"
71+
git push origin HEAD:refs/heads/develop
6572
- name: Build python package and wheel
6673
run: poetry build
6774
- name: Upload to PyPi test
@@ -76,39 +83,58 @@ jobs:
7683
PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }}
7784
- name: publish lambda layer in SAR by triggering the internal codepipeline
7885
run: |
79-
aws ssm put-parameter --name "powertools-python-release-version" --value $RELEASE_TAG_VERSION --overwrite
86+
aws ssm put-parameter --name "powertools-python-release-version" --value $RELEASE_VERSION --overwrite
8087
aws codepipeline start-pipeline-execution --name ${{ secrets.CODEPIPELINE_NAME }}
8188
env:
8289
# Maintenance: Migrate to new OAuth mechanism
8390
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
8491
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
8592
AWS_DEFAULT_REGION: eu-west-1
8693
AWS_DEFAULT_OUTPUT: json
87-
- name: Setup doc deploy
94+
95+
docs:
96+
needs: release
97+
runs-on: ubuntu-latest
98+
env:
99+
RELEASE_VERSION: ${{ needs.release.outputs.RELEASE_VERSION }}
100+
steps:
101+
- uses: actions/checkout@v3
102+
with:
103+
fetch-depth: 0
104+
- name: Setup git client
88105
run: |
89-
git config --global user.name Docs deploy
90-
git config --global user.email [email protected]
106+
git config user.name "Release bot"
107+
git config user.email [email protected]
91108
- name: Build docs website and API reference
92109
run: |
93-
make release-docs VERSION=${RELEASE_TAG_VERSION} ALIAS="latest"
110+
make release-docs VERSION=${RELEASE_VERSION} ALIAS="latest"
94111
poetry run mike set-default --push latest
95112
- name: Release API docs to release version
96113
uses: peaceiris/actions-gh-pages@068dc23d9710f1ba62e86896f84735d869951305 # v3.8.0
97114
with:
98115
github_token: ${{ secrets.GITHUB_TOKEN }}
99116
publish_dir: ./api
100117
keep_files: true
101-
destination_dir: ${{ env.RELEASE_TAG_VERSION }}/api
118+
destination_dir: ${{ env.RELEASE_VERSION }}/api
102119
- name: Release API docs to latest
103120
uses: peaceiris/actions-gh-pages@068dc23d9710f1ba62e86896f84735d869951305 # v3.8.0
104121
with:
105122
github_token: ${{ secrets.GITHUB_TOKEN }}
106123
publish_dir: ./api
107124
keep_files: true
108125
destination_dir: latest/api
126+
127+
post_release:
128+
needs: release
129+
runs-on: ubuntu-latest
130+
env:
131+
RELEASE_VERSION: ${{ needs.release.outputs.RELEASE_VERSION }}
132+
steps:
133+
- uses: actions/checkout@v3
109134
- name: Close issues related to this release
110135
uses: actions/github-script@v6
111136
with:
137+
github-token: ${{ secrets.GITHUB_TOKEN }}
112138
script: |
113139
const post_release = require('.github/scripts/post_release.js')
114140
await post_release({github, context, core})

.github/workflows/python_docs.yml

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
name: Docs
22

3+
# Maintenance: Create a reusable workflow to be more easily reused across release, push, and doc hot fixes
4+
# this should include inputs on whether to release API docs, what version to release, and whether to rebuild /latest
5+
36
on:
47
push:
58
branches:
69
- develop
710
paths:
811
- "docs/**"
9-
- "CHANGELOG.md"
1012
- "mkdocs.yml"
1113
- "examples/**"
1214

MAINTAINERS.md

+18-20
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,6 @@
1313
- [Triage Bug Reports](#triage-bug-reports)
1414
- [Triage RFCs](#triage-rfcs)
1515
- [Releasing a new version](#releasing-a-new-version)
16-
- [Changelog generation](#changelog-generation)
17-
- [Bumping the version](#bumping-the-version)
1816
- [Drafting release notes](#drafting-release-notes)
1917
- [Run end to end tests](#run-end-to-end-tests)
2018
- [Releasing a documentation hotfix](#releasing-a-documentation-hotfix)
@@ -170,23 +168,15 @@ Some examples using our initial and new RFC templates: #92, #94, #95, #991, #122
170168

171169
### Releasing a new version
172170

173-
> TODO: This is an area we want to increase automation while keeping communication at human level.
171+
Firstly, make sure the commit history in the `develop` branch **(1)** it's up to date, **(2)** commit messages are semantic, and **(3)** commit messages have their respective area, for example `feat(logger): <change>`, `chore(ci): ...`).
174172

175-
Firstly, make sure you are using the `develop` branch and it is up to date with the origin.
173+
**Found typos or unclear commit messages?**
176174

177-
There are three main steps to release a new version: Changelog generation, version bumping, and drafting release notes.
175+
Reword through rebase and push with `--force-with-lease` once you're confident. This will ensure [CHANGELOG](./CHANGELOG.md) is always clear for customers looking to understand what changed in between releases - was that a bug? what new features and for which utility?
178176

179-
#### Changelog generation
177+
**Looks good, what's next?**
180178

181-
You can pre-generate a temporary CHANGELOG using `make changelog`. This will generate a `TMP_CHANGELOG.md` with all staged changes under the `unreleased` section.
182-
183-
Each unreleased line item is a commit. You can adjust them if you find the commit titles are insufficient to describe their intent. Once you're comfortable, bring these changes to the `CHANGELOG.md` with a new version heading like in previous versions.
184-
185-
#### Bumping the version
186-
187-
Use `poetry version <major|minor|patch|specific version>` to bump the version. For example, you can use `poetry version minor` when releasing a minor version.
188-
189-
NOTE. Make sure both `CHANGELOG` and `pyproject.toml` are committed and pushed to the remote `develop` branch before proceeding.
179+
The only step is to draft and publish a good release notes, everything else is automated.
190180

191181
#### Drafting release notes
192182

@@ -196,28 +186,36 @@ Make sure the `tag` field reflects the new version you're releasing, the target
196186

197187
You'll notice we group all changes based on their [labels](#labels) like `feature`, `bug`, `documentation`, etc.
198188

199-
> **Q: What if there's an incorrect title or grouping?**
189+
**I spotted a typo or incorrect grouping - how do I fix it?**
200190

201191
Edit the respective PR title and update their [labels](#labels). Then run the [Release Drafter workflow](https://github.com/awslabs/aws-lambda-powertools-python/actions/workflows/release-drafter.yml) to update the Draft release.
202192

203-
The best part comes now. Replace the placeholder `[Human readable summary of changes]` with what you'd like to communicate to customers what this release is all about. Always put yourself in the customers shoes. For that, these are some questions to keep in mind when drafting your first or future release notes:
193+
**All looking good, what's next?**
194+
195+
The best part comes now. Replace the placeholder `[Human readable summary of changes]` with what you'd like to communicate to customers what this release is all about. Rule of thumb: always put yourself in the customers shoes.
196+
197+
These are some questions to keep in mind when drafting your first or future release notes:
204198

205199
- Can customers understand at a high level what changed in this release?
206200
- Is there a link to the documentation where they can read more about each main change?
207-
- Are there any graphics or code snippets that can enhance readability?
201+
- Are there any graphics or [code snippets](carbon.now.sh/) that can enhance readability?
208202
- Are we calling out any key contributor(s) to this release?
209203
- All contributors are automatically credited, use this as an exceptional case to feature them
210204

211-
Once you're happy, hit `Publish release`. This will kick off the [Publishing workflow](https://github.com/awslabs/aws-lambda-powertools-python/actions/workflows/publish.yml) and within a few minutes you should see the latest version in PyPi, and all issues labeled as `pending-release` will be notified.
205+
Once you're happy, hit `Publish release` 🎉🎉🎉.
206+
207+
This will kick off the [Publishing workflow](https://github.com/awslabs/aws-lambda-powertools-python/actions/workflows/publish.yml) and within a few minutes you should see the latest version in PyPi, and all issues labeled as `pending-release` will be closed and notified.
208+
209+
> TODO: Include information to verify SAR and Lambda Layers deployment; we're still finalizing Lambda Layer automated deployment in GitHub Actions - ping @am29d when in doubt.
212210
213-
> TODO: Wait for @am29d new Lambda Layers pipeline work to complete, then add how Lambda Layers are published
214211
### Run end to end tests
215212

216213
In order to run end to end tests you need to install CDK CLI first and bootstrap your account with `cdk bootstrap` command. For additional details follow [documentation](https://docs.aws.amazon.com/cdk/v2/guide/bootstrapping.html).
217214

218215
To run locally, export `AWS_PROFILE` environment variable and run `make e2e tests`. To run from GitHub Actions, use [run-e2e-tests workflow](https://github.com/awslabs/aws-lambda-powertools-python/actions/workflows/run-e2e-tests.yml) and pick the branch you want to run tests against.
219216

220217
**NOTE**: E2E tests are run as part of each merge to `develop` branch.
218+
221219
### Releasing a documentation hotfix
222220

223221
You can rebuild the latest documentation without a full release via this [GitHub Actions Workflow](https://github.com/awslabs/aws-lambda-powertools-python/actions/workflows/rebuild_latest_docs.yml). Choose `Run workflow`, keep `develop` as the branch, and input the latest Powertools version available.

Makefile

+3-2
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,9 @@ release: pr
9494

9595
changelog:
9696
git fetch --tags origin
97-
@echo "[+] Pre-generating CHANGELOG for tag: $$(git describe --abbrev=0 --tag)"
98-
docker run -v "${PWD}":/workdir quay.io/git-chglog/git-chglog $$(git describe --abbrev=0 --tag).. > TMP_CHANGELOG.md
97+
CURRENT_VERSION=$(shell git describe --abbrev=0 --tag) ;\
98+
echo "[+] Pre-generating CHANGELOG for tag: $$CURRENT_VERSION" ;\
99+
docker run -v "${PWD}":/workdir quay.io/git-chglog/git-chglog > CHANGELOG.md
99100

100101
mypy:
101102
poetry run mypy --pretty aws_lambda_powertools

0 commit comments

Comments
 (0)