Skip to content

Commit 1264ee1

Browse files
chore: automate release process (#1394)
1 parent 0c14426 commit 1264ee1

File tree

5 files changed

+212
-111
lines changed

5 files changed

+212
-111
lines changed

.github/maintainers_guide.md

Lines changed: 101 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,14 @@ this project. If you use this package within your own software as is but don't p
1010

1111
We recommend using [pyenv](https://github.com/pyenv/pyenv) for Python runtime management. If you use macOS, follow the following steps:
1212

13-
```bash
14-
$ brew update
15-
$ brew install pyenv
13+
```sh
14+
brew update
15+
brew install pyenv
1616
```
1717

1818
Install necessary Python runtimes for development/testing. You can rely on GitHub Actions workflows for testing with various major versions. <https://github.com/slackapi/bolt-python/tree/main/.github/workflows>
1919

20-
```bash
20+
```sh
2121
$ pyenv install -l | grep -v "-e[conda|stackless|pypy]"
2222

2323
$ pyenv install 3.8.5 # select the latest patch version
@@ -34,9 +34,9 @@ $ pyenv rehash
3434

3535
Then, you can create a new Virtual Environment this way:
3636

37-
```bash
38-
$ python -m venv env_3.8.5
39-
$ source env_3.8.5/bin/activate
37+
```sh
38+
python -m venv env_3.8.5
39+
source env_3.8.5/bin/activate
4040
```
4141

4242
## Tasks
@@ -49,27 +49,27 @@ If you make some changes to this SDK, please write corresponding unit tests as m
4949

5050
If this is your first time to run tests, although it may take a bit long time, running the following script is the easiest.
5151

52-
```bash
53-
$ ./scripts/install_all_and_run_tests.sh
52+
```sh
53+
./scripts/install_all_and_run_tests.sh
5454
```
5555

5656
Once you installed all the required dependencies, you can use the following one.
5757

58-
```bash
59-
$ ./scripts/run_tests.sh
58+
```sh
59+
./scripts/run_tests.sh
6060
```
6161

6262
Also, you can run a single test this way.
6363

64-
```bash
65-
$ ./scripts/run_tests.sh tests/scenario_tests/test_app.py
64+
```sh
65+
./scripts/run_tests.sh tests/scenario_tests/test_app.py
6666
```
6767

6868
#### Run the Samples
6969

7070
If you make changes to `slack_bolt/adapter/*`, please verify if it surely works by running the apps under `examples` directory.
7171

72-
```bash
72+
```sh
7373
# Install all optional dependencies
7474
$ pip install -r requirements/adapter.txt
7575
$ pip install -r requirements/adapter_testing.txt
@@ -97,121 +97,123 @@ If you want to test the package locally you can.
9797

9898
1. Build the package locally
9999
- Run
100-
```bash
100+
```sh
101101
scripts/build_pypi_package.sh
102102
```
103103
- This will create a `.whl` file in the `./dist` folder
104104
2. Use the built package
105105
- Example `/dist/slack_bolt-1.2.3-py2.py3-none-any.whl` was created
106106
- From anywhere on your machine you can install this package to a project with
107-
```bash
107+
```sh
108108
pip install <project path>/dist/slack_bolt-1.2.3-py2.py3-none-any.whl
109109
```
110110
- It is also possible to include `slack_bolt @ file:///<project path>/dist/slack_bolt-1.2.3-py2.py3-none-any.whl` in a [requirements.txt](https://pip.pypa.io/en/stable/user_guide/#requirements-files) file
111111

112-
### Releasing
113-
114-
#### Generate API reference documents
112+
### Generate API reference documents
115113

116-
```bash
114+
```sh
117115
./scripts/generate_api_docs.sh
118116
```
119117

118+
### Releasing
119+
120120
#### test.pypi.org deployment
121121

122-
##### $HOME/.pypirc
122+
[TestPyPI](https://test.pypi.org/) is a separate instance of the Python Package
123+
Index that allows you to try distribution tools and processes without affecting
124+
the real index. This is particularly useful when making changes related to the
125+
package configuration itself, for example, modifications to the `pyproject.toml` file.
126+
127+
You can deploy this project to TestPyPI using GitHub Actions.
123128

124-
```toml
125-
[testpypi]
126-
username: {your username}
127-
password: {your password}
129+
To deploy using GitHub Actions:
130+
131+
1. Push your changes to a branch or tag
132+
2. Navigate to <https://github.com/slackapi/bolt-python/actions/workflows/pypi-release.yml>
133+
3. Click on "Run workflow"
134+
4. Select your branch or tag from the dropdown
135+
5. Click "Run workflow" to build and deploy your branch to TestPyPI
136+
137+
Alternatively, you can deploy from your local machine with:
138+
139+
```sh
140+
./scripts/deploy_to_test_pypi.sh
128141
```
129142

130143
#### Development Deployment
131144

132-
1. Create a branch in which the development release will live:
133-
- Bump the version number in adherence to [Semantic Versioning](http://semver.org/) and [Developmental Release](https://peps.python.org/pep-0440/#developmental-releases) in `slack_bolt/version.py`
134-
- Example the current version is `1.2.3` a proper development bump would be `1.3.0.dev0`
145+
Deploying a new version of this library to PyPI is triggered by publishing a GitHub Release.
146+
Before creating a new release, ensure that everything on a stable branch has
147+
landed, then [run the tests](#run-all-the-unit-tests).
148+
149+
1. Create the commit for the release
150+
1. In `slack_bolt/version.py` bump the version number in adherence to [Semantic Versioning](http://semver.org/) and [Developmental Release](https://peps.python.org/pep-0440/#developmental-releases).
151+
- Example: if the current version is `1.2.3`, a proper development bump would be `1.2.4.dev0`
135152
- `.dev` will indicate to pip that this is a [Development Release](https://peps.python.org/pep-0440/#developmental-releases)
136-
- Note that the `dev` version can be bumped in development releases: `1.3.0.dev0` -> `1.3.0.dev1`
137-
- Commit with a message including the new version number. For example `1.3.0.dev0` & Push the commit to a branch where the development release will live (create it if it does not exist)
138-
- `git checkout -b future-release`
139-
- `git commit -m 'version 1.3.0.dev0'`
140-
- `git push future-release`
141-
- Create a git tag for the release. For example `git tag v1.3.0.dev0`.
142-
- Push the tag up to github with `git push origin --tags`
143-
144-
2. Distribute the release
145-
- Use the latest stable Python runtime
146-
- `python -m venv .venv`
147-
- `./scripts/deploy_to_pypi_org.sh`
148-
- You do not need to create a GitHub release
149-
150-
3. (Slack Internal) Communicate the release internally
153+
- Note that the `dev` version can be bumped in development releases: `1.2.4.dev0` -> `1.2.4.dev1`
154+
2. Build the docs with `./scripts/generate_api_docs.sh`.
155+
3. Commit with a message including the new version number. For example `1.2.4.dev0` & push the commit to a branch where the development release will live (create it if it does not exist)
156+
1. `git checkout -b future-release`
157+
2. `git commit -m 'chore(release): version 1.2.4.dev0'`
158+
3. `git push -u origin future-release`
159+
2. Create a new GitHub Release
160+
1. Navigate to the [Releases page](https://github.com/slackapi/bolt-python/releases).
161+
2. Click the "Draft a new release" button.
162+
3. Set the "Target" to the feature branch with the development changes.
163+
4. Click "Tag: Select tag"
164+
5. Input a new tag name manually. The tag name must match the version in `slack_bolt/version.py` prefixed with "v" (e.g., if version is `1.2.4.dev0`, enter `v1.2.4.dev0`)
165+
6. Click the "Create a new tag" button. This won't create your tag immediately.
166+
7. Click the "Generate release notes" button.
167+
8. The release name should match the tag name!
168+
9. Edit the resulting notes to ensure they have decent messaging that is understandable by non-contributors, but each commit should still have its own line.
169+
10. Set this release as a pre-release.
170+
11. Publish the release by clicking the "Publish release" button!
171+
3. Navigate to the [release workflow run](https://github.com/slackapi/bolt-python/actions/workflows/pypi-release.yml). You will need to approve the deployment!
172+
4. After a few minutes, the corresponding version will be available on <https://pypi.org/project/slack-bolt>.
173+
5. (Slack Internal) Communicate the release internally
151174
152175
#### Production Deployment
153176
154-
1. Create the commit for the release:
155-
- Bump the version number in adherence to [Semantic Versioning](http://semver.org/) in `slack_bolt/version.py`
156-
- Build the docs with `./scripts/generate_api_docs.sh`.
157-
- Commit with a message including the new version number. For example `1.2.3` & Push the commit to a branch and create a PR to sanity check.
158-
- `git checkout -b v1.2.3`
159-
- `git commit -a -m 'version 1.2.3'`
160-
- `git push -u origin HEAD`
161-
- Open a PR and merge after receiving at least one approval from other maintainers.
162-
163-
2. Distribute the release
164-
- Use the latest stable Python runtime
165-
- `git checkout main && git pull`
166-
- `python --version`
167-
- `python -m venv .venv`
168-
- `./scripts/deploy_to_pypi_org.sh`
169-
- Create a new GitHub Release from the [Releases page](https://github.com/slackapi/bolt-python/releases) by clicking the "Draft a new release" button.
170-
- Enter the new version number updated from the commit (e.g. `v1.2.3`) into the "Choose a tag" input.
171-
- Ensure the tag `Target` branch is `main` (e.g `Target:main`).
172-
- Click the "Create a new tag: x.x.x on publish" button. This won't create your tag immediately.
173-
- Name the release after the version number updated from the commit (e.g. `version 1.2.3`)
174-
- Auto-generate the release notes by clicking the "Auto-generate release
175-
notes" button. This will pull in changes that will be included in your
176-
release.
177-
- Edit the resulting notes to ensure they have decent messaging that are
178-
understandable by non-contributors, but each commit should still have it's
179-
own line.
180-
- Ensure that this version adheres to [semantic versioning](http://semver.org/). See
181-
[Versioning](#versioning-and-tags) for correct version format. Version tags
182-
should match the following pattern: `v2.5.0`.
183-
184-
```markdown
185-
## New Features
186-
187-
### Awesome Feature 1
188-
189-
Description here.
190-
191-
### Awesome Feature 2
192-
193-
Description here.
194-
195-
## Changes
196-
197-
* #123 Make it better - thanks @SlackHQ
198-
* #123 Fix something wrong - thanks @seratch
199-
```
200-
201-
3. (Slack Internal) Communicate the release internally
202-
- Include a link to the GitHub release
203-
204-
4. Make announcements
205-
- #tools-bolt in community.slack.com
206-
207-
5. (Slack Internal) Tweet by @SlackAPI
208-
- Not necessary for patch updates, might be needed for minor updates, definitely needed for major updates. Include a link to the GitHub release
177+
Deploying a new version of this library to PyPI is triggered by publishing a GitHub Release.
178+
Before creating a new release, ensure that everything on the `main` branch since
179+
the last tag is in a releasable state! At a minimum, [run the tests](#run-all-the-unit-tests).
180+
181+
1. Create the commit for the release
182+
1. In `slack_bolt/version.py` bump the version number in adherence to [Semantic Versioning](http://semver.org/) and the [Versioning](#versioning-and-tags) section.
183+
2. Build the docs with `./scripts/generate_api_docs.sh`.
184+
3. Commit with a message including the new version number. For example `1.2.3` & push the commit to a branch and create a PR to sanity check.
185+
1. `git checkout -b 1.2.3-release`
186+
2. `git commit -m 'chore(release): version 1.2.3'`
187+
3. `git push -u origin 1.2.3-release`
188+
4. Add relevant labels to the PR and add the PR to a GitHub Milestone.
189+
5. Merge in release PR after getting an approval from at least one maintainer.
190+
2. Create a new GitHub Release
191+
1. Navigate to the [Releases page](https://github.com/slackapi/bolt-python/releases).
192+
2. Click the "Draft a new release" button.
193+
3. Set the "Target" to the `main` branch.
194+
4. Click "Tag: Select tag"
195+
5. Input a new tag name manually. The tag name must match the version in `slack_bolt/version.py` prefixed with "v" (e.g., if version is `1.2.3`, enter `v1.2.3`)
196+
6. Click the "Create a new tag" button. This won't create your tag immediately.
197+
7. Click the "Generate release notes" button.
198+
8. The release name should match the tag name!
199+
9. Edit the resulting notes to ensure they have decent messaging that is understandable by non-contributors, but each commit should still have its own line.
200+
10. Include a link to the current GitHub Milestone.
201+
11. Ensure the "latest release" checkbox is checked to mark this as the latest stable release.
202+
12. Publish the release by clicking the "Publish release" button!
203+
3. Navigate to the [release workflow run](https://github.com/slackapi/bolt-python/actions/workflows/pypi-release.yml). You will need to approve the deployment!
204+
4. After a few minutes, the corresponding version will be available on <https://pypi.org/project/slack-bolt/>.
205+
5. Close the current GitHub Milestone and create one for the next patch version.
206+
6. (Slack Internal) Communicate the release internally
207+
- Include a link to the GitHub release
208+
7. (Slack Internal) Tweet by @SlackAPI
209+
- Not necessary for patch updates, might be needed for minor updates,
210+
definitely needed for major updates. Include a link to the GitHub release
209211

210212
## Workflow
211213

212214
### Versioning and Tags
213215

214-
This project uses semantic versioning, expressed through the numbering scheme of
216+
This project uses [Semantic Versioning](http://semver.org/), expressed through the numbering scheme of
215217
[PEP-0440](https://www.python.org/dev/peps/pep-0440/).
216218

217219
### Branches

.github/release.yml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# https://docs.github.com/en/repositories/releasing-projects-on-github/automatically-generated-release-notes#configuring-automatically-generated-release-notes
2+
changelog:
3+
categories:
4+
- title: 🚀 Enhancements
5+
labels:
6+
- enhancement
7+
- title: 🐛 Bug Fixes
8+
labels:
9+
- bug
10+
- title: 📚 Documentation
11+
labels:
12+
- docs
13+
- title: 🤖 Build
14+
labels:
15+
- build
16+
- title: 🧪 Testing/Code Health
17+
labels:
18+
- code health
19+
- title: 🔒 Security
20+
labels:
21+
- security
22+
- title: 📦 Other changes
23+
labels:
24+
- "*"

.github/workflows/pypi-release.yml

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
name: Upload A Release to pypi.org or test.pypi.org
2+
3+
on:
4+
release:
5+
types:
6+
- published
7+
workflow_dispatch:
8+
inputs:
9+
dry_run:
10+
description: "Dry run (build only, do not publish)"
11+
required: false
12+
type: boolean
13+
14+
jobs:
15+
release-build:
16+
runs-on: ubuntu-latest
17+
permissions:
18+
contents: read
19+
20+
steps:
21+
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
22+
with:
23+
ref: ${{ github.event.release.tag_name || github.ref }}
24+
persist-credentials: false
25+
26+
- name: Set up Python
27+
uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
28+
with:
29+
python-version: "3.x"
30+
31+
- name: Build release distributions
32+
run: |
33+
scripts/build_pypi_package.sh
34+
35+
- name: Persist dist folder
36+
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
37+
with:
38+
name: release-dist
39+
path: dist/
40+
41+
test-pypi-publish:
42+
runs-on: ubuntu-latest
43+
needs:
44+
- release-build
45+
# Run this job for workflow_dispatch events when dry_run input is not 'true'
46+
# Note: The comparison is against a string value 'true' since GitHub Actions inputs are strings
47+
if: github.event_name == 'workflow_dispatch' && github.event.inputs.dry_run != 'true'
48+
environment:
49+
name: testpypi
50+
permissions:
51+
id-token: write
52+
53+
steps:
54+
- name: Retrieve dist folder
55+
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
56+
with:
57+
name: release-dist
58+
path: dist/
59+
60+
- name: Publish release distributions to test.pypi.org
61+
# Using OIDC for PyPI publishing (no API tokens needed)
62+
# See: https://docs.github.com/en/actions/how-tos/secure-your-work/security-harden-deployments/oidc-in-pypi
63+
uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # v1.13.0
64+
with:
65+
repository-url: https://test.pypi.org/legacy/
66+
67+
pypi-publish:
68+
runs-on: ubuntu-latest
69+
needs:
70+
- release-build
71+
if: github.event_name == 'release'
72+
environment:
73+
name: pypi
74+
permissions:
75+
id-token: write
76+
77+
steps:
78+
- name: Retrieve dist folder
79+
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
80+
with:
81+
name: release-dist
82+
path: dist/
83+
84+
- name: Publish release distributions to pypi.org
85+
# Using OIDC for PyPI publishing (no API tokens needed)
86+
# See: https://docs.github.com/en/actions/how-tos/secure-your-work/security-harden-deployments/oidc-in-pypi
87+
uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # v1.13.0

0 commit comments

Comments
 (0)