1
1
# Release process
2
2
3
- _ Black_ has had a lot of work automating its release process. This document sets out to
4
- explain what everything does and how to release _ Black_ using said automation.
5
-
6
- ## Cutting a Release
7
-
8
- To cut a release, you must be a _ Black_ maintainer with ` GitHub Release ` creation
9
- access. Using this access, the release process is:
10
-
11
- 1 . Cut a new PR editing ` CHANGES.md ` and the docs to version the latest changes
3
+ _ Black_ has had a lot of work done into standardizing and automating its release
4
+ process. This document sets out to explain how everything works and how to release
5
+ _ Black_ using said automation.
6
+
7
+ ## Release cadence
8
+
9
+ ** We aim to release whatever is on ` main ` every 1-2 months.** This ensures merged
10
+ improvements and bugfixes are shipped to users reasonably quickly, while not massively
11
+ fracturing the user-base with too many versions. This also keeps the workload on
12
+ maintainers consistent and predictable.
13
+
14
+ If there's not much new on ` main ` to justify a release, it's acceptable to skip a
15
+ month's release. Ideally January releases should not be skipped because as per our
16
+ [ stability policy] ( labels/stability-policy ) , the first release in a new calendar year
17
+ may make changes to the _ stable_ style. While the policy applies to the first release
18
+ (instead of only January releases), confining changes to the stable style to January
19
+ will keep things predictable (and nicer) for users.
20
+
21
+ Unless there is a serious regression or bug that requires immediate patching, ** there
22
+ should not be more than one release per month** . While version numbers are cheap,
23
+ releases require a maintainer to both commit to do the actual cutting of a release, but
24
+ also to be able to deal with the potential fallout post-release. Releasing more
25
+ frequently than monthly nets rapidly diminishing returns.
26
+
27
+ ## Cutting a release
28
+
29
+ ** You must have ` write ` permissions for the _ Black_ repository to cut a release.**
30
+
31
+ The 10,000 foot view of the release process is that you prepare a release PR and then
32
+ publish a [ GitHub Release] . This triggers [ release automation] ( #release-workflows ) that
33
+ builds all release artifacts and publishes them to the various platforms we publish to.
34
+
35
+ To cut a release:
36
+
37
+ 1 . Determine the release's version number
38
+ - ** _ Black_ follows the [ CalVer] versioning standard using the ` YY.M.N ` format**
39
+ - So unless there already has been a release during this month, ` N ` should be ` 0 `
40
+ - Example: the first release in January, 2022 → ` 22.1.0 `
41
+ 1 . File a PR editing ` CHANGES.md ` and the docs to version the latest changes
42
+ 1 . Replace the ` ## Unreleased ` header with the version number
12
43
1 . Remove any empty sections for the current release
13
- 2 . Add a new empty template for the next release (template below)
14
- 3 . Example PR: [ #2616 ] ( https://github.com/psf/black/pull/2616 )
15
- 4 . Example title: ` Update CHANGES.md for XX.X release `
16
- 2 . Once the release PR is merged ensure all CI passes
17
- 1 . If not, ensure there is an Issue open for the cause of failing CI (generally we'd
18
- want this fixed before cutting a release)
19
- 3 . Open ` CHANGES.md ` and copy the _ raw markdown_ of the latest changes to use in the
20
- description of the GitHub Release.
21
- 4 . Go and [ cut a release] ( https://github.com/psf/black/releases ) using the GitHub UI so
22
- that all workflows noted below are triggered.
23
- 1 . The release version and tag should be the [ CalVer] ( https://calver.org ) version
24
- _ Black_ used for the current release e.g. ` 21.6 ` / ` 21.5b1 `
25
- 2 . _ Black_ uses [ setuptools scm] ( https://pypi.org/project/setuptools-scm/ ) to pull
26
- the current version for the package builds and release.
27
- 5 . Once the release is cut, you're basically done. It's a good practice to go and watch
28
- to make sure all the [ GitHub Actions] ( https://github.com/psf/black/actions ) pass,
29
- although you should receive an email to your registered GitHub email address should
30
- one fail.
31
- 1 . You should see all the release workflows and lint/unittests workflows running on
32
- the new tag in the Actions UI
33
-
34
- If anything fails, please go read the respective action's log output and configuration
35
- file to reverse engineer your way to a fix/soluton.
36
-
37
- ## Changelog template
44
+ 1 . (_ optional_ ) Read through and copy-edit the changelog (eg. by moving entries,
45
+ fixing typos, or rephrasing entries)
46
+ 1 . Add a new empty template for the next release above
47
+ ([ template below] ( #changelog-template ) )
48
+ 1 . Update references to the latest version in
49
+ {doc}` /integrations/source_version_control ` and
50
+ {doc}` /usage_and_configuration/the_basics `
51
+ - Example PR: [ GH-3139 ]
52
+ 1 . Once the release PR is merged, wait until all CI passes
53
+ - If CI does not pass, ** stop** and investigate the failure(s) as generally we'd want
54
+ to fix failing CI before cutting a release
55
+ 1 . [ Draft a new GitHub Release] [ new-release ]
56
+ 1 . Click ` Choose a tag ` and type in the version number, then select the
57
+ ` Create new tag: YY.M.N on publish ` option that appears
58
+ 1 . Verify that the new tag targets the ` main ` branch
59
+ 1 . You can leave the release title blank, GitHub will default to the tag name
60
+ 1 . Copy and paste the _ raw changelog Markdown_ for the current release into the
61
+ description box
62
+ 1 . Publish the GitHub Release, triggering [ release automation] ( #release-workflows ) that
63
+ will handle the rest
64
+ 1 . At this point, you're basically done. It's good practice to go and [ watch and verify
65
+ that all the release workflows pass] [ black-actions ] , although you will receive a
66
+ GitHub notification should something fail.
67
+ - If something fails, don't panic. Please go read the respective workflow's logs and
68
+ configuration file to reverse-engineer your way to a fix/solution.
69
+
70
+ Congratulations! You've successfully cut a new release of _ Black_ . Go and stand up and
71
+ take a break, you deserve it.
72
+
73
+ ``` {important}
74
+ Once the release artifacts reach PyPI, you may see new issues being filed indicating
75
+ regressions. While regressions are not great, they don't automatically mean a hotfix
76
+ release is warranted. Unless the regressions are serious and impact many users, a hotfix
77
+ release is probably unnecessary.
78
+
79
+ In the end, use your best judgement and ask other maintainers for their thoughts.
80
+ ```
81
+
82
+ ### Changelog template
38
83
39
84
Use the following template for a clean changelog after the release:
40
85
@@ -45,101 +90,123 @@ Use the following template for a clean changelog after the release:
45
90
46
91
<!-- Include any especially major or disruptive changes here -->
47
92
48
- ### Style
93
+ ### Stable style
49
94
50
95
<!-- Changes that affect Black's stable style -->
51
96
52
97
### Preview style
53
98
54
99
<!-- Changes that affect Black's preview style -->
55
100
56
- ### _Blackd_
57
-
58
- <!-- Changes to blackd -->
59
-
60
101
### Configuration
61
102
62
103
<!-- Changes to how Black can be configured -->
63
104
64
- ### Documentation
105
+ ### Packaging
65
106
66
- <!-- Major changes to documentation and policies. Small docs changes
67
- don't need a changelog entry. -->
107
+ <!-- Changes to how Black is packaged, such as dependency requirements -->
68
108
69
- ### Integrations
109
+ ### Parser
70
110
71
- <!-- For example, Docker, GitHub Actions, pre-commit, editors -->
111
+ <!-- Changes to the parser or to version autodetection -->
112
+
113
+ ### Performance
114
+
115
+ <!-- Changes that improve Black's performance. -->
72
116
73
117
### Output
74
118
75
119
<!-- Changes to Black's terminal output and error messages -->
76
120
77
- ### Packaging
78
-
79
- <!-- Changes to how Black is packaged, such as dependency requirements -->
121
+ ### _Blackd_
80
122
81
- ### Parser
123
+ <!-- Changes to blackd -->
82
124
83
- <!-- Changes to the parser or to version autodetection -->
125
+ ### Integrations
84
126
85
- ### Performance
127
+ <!-- For example, Docker, GitHub Actions, pre-commit, editors -->
86
128
87
- <!-- Changes that improve Black's performance. -->
129
+ ### Documentation
88
130
131
+ <!-- Major changes to documentation and policies. Small docs changes
132
+ don't need a changelog entry. -->
89
133
```
90
134
91
135
## Release workflows
92
136
93
- All _ Blacks _ 's automation workflows use GitHub Actions. All workflows are therefore
94
- configured using ` .yml ` files in the ` .github/workflows ` directory of the _ Black_
137
+ All of _ Black _ 's release automation uses [ GitHub Actions] . All workflows are therefore
138
+ configured using YAML files in the ` .github/workflows ` directory of the _ Black_
95
139
repository.
96
140
141
+ They are triggered by the publication of a [ GitHub Release] .
142
+
97
143
Below are descriptions of our release workflows.
98
144
99
- ### Docker
145
+ ### Publish to PyPI
146
+
147
+ This is our main workflow. It builds an [ sdist] and [ wheels] to upload to PyPI where the
148
+ vast majority of users will download Black from. It's divided into three job groups:
149
+
150
+ #### sdist + pure wheel
100
151
101
- This workflow uses the QEMU powered ` buildx ` feature of docker to upload a ` arm64 ` and
102
- ` amd64 ` /` x86_64 ` build of the official _ Black_ docker image™.
152
+ This single job builds the sdist and pure Python wheel (i.e., a wheel that only contains
153
+ Python code) using [ build] and then uploads them to PyPI using [ twine] . These artifacts
154
+ are general-purpose and can be used on basically any platform supported by Python.
103
155
104
- - Currently this workflow uses an API Token associated with @ cooperlees account
156
+ #### mypyc wheels (…)
105
157
106
- ### pypi_upload
158
+ We use [ mypyc] to compile _ Black_ into a CPython C extension for significantly improved
159
+ performance. Wheels built with mypyc are platform and Python version specific.
160
+ [ Supported platforms are documented in the FAQ] ( labels/mypyc-support ) .
107
161
108
- This workflow builds a Python
109
- [ sdist] ( https://docs.python.org/3/distutils/sourcedist.html ) and
110
- [ wheel] ( https://pythonwheels.com ) using the latest
111
- [ setuptools] ( https://pypi.org/project/setuptools/ ) and
112
- [ wheel] ( https://pypi.org/project/wheel/ ) modules.
162
+ These matrix jobs use [ cibuildwheel] which handles the complicated task of building C
163
+ extensions for many environments for us. Since building these wheels is slow, there are
164
+ multiple mypyc wheels jobs (hence the term "matrix") that build for a specific platform
165
+ (as noted in the job name in parentheses).
113
166
114
- It will then use [ twine] ( https://pypi.org/project/twine/ ) to upload both release formats
115
- to PyPI for general downloading of the _ Black_ Python package. This is where
116
- [ pip] ( https://pypi.org/project/pip/ ) looks by default.
167
+ Like the previous job group, the built wheels are uploaded to PyPI using [ twine] .
117
168
118
- - Currently this workflow uses an API token associated with @ ambv 's PyPI account
169
+ #### Update stable branch
119
170
120
- ### Upload self-contained binaries
171
+ So this job doesn't _ really_ belong here, but updating the ` stable ` branch after the
172
+ other PyPI jobs pass (they must pass for this job to start) makes the most sense. This
173
+ saves us from remembering to update the branch sometime after cutting the release.
121
174
122
- This workflow builds self-contained binaries for multiple platforms. This allows people
123
- to download the executable for their platform and run _ Black_ without a
124
- [ Python Runtime] ( https://wiki.python.org/moin/PythonImplementations ) installed.
175
+ - _ Currently this workflow uses an API token associated with @ambv 's PyPI account_
125
176
126
- The created binaries are attached/stored on the associated
127
- [ GitHub Release] ( https://github.com/psf/black/releases ) for download over _ IPv4 only_
128
- (GitHub still does not have IPv6 access 😢).
177
+ ### Publish executables
129
178
130
- ## Moving the ` stable ` tag
179
+ This workflow builds native executables for multiple platforms using [ PyInstaller] . This
180
+ allows people to download the executable for their platform and run _ Black_ without a
181
+ [ Python runtime] ( https://wiki.python.org/moin/PythonImplementations ) installed.
131
182
132
- _ Black_ provides a stable tag for people who want to move along as _ Black_ developers
133
- deem the newest version reliable. Here the _ Black_ developers will move once the release
134
- has been problem free for at least ~ 24 hours from release. Given the large _ Black_
135
- userbase we hear about bad bugs quickly. We do strive to continually improve our CI too.
183
+ The created binaries are stored on the associated GitHub Release for download over _ IPv4
184
+ only_ (GitHub still does not have IPv6 access 😢).
136
185
137
- ### Tag moving process
186
+ ### docker
138
187
139
- #### stable
188
+ This workflow uses the QEMU powered ` buildx ` feature of Docker to upload an ` arm64 ` and
189
+ ` amd64 ` /` x86_64 ` build of the official _ Black_ Docker image™.
140
190
141
- From a rebased ` main ` checkout:
191
+ - _ Currently this workflow uses an API Token associated with @cooperlees account_
192
+
193
+ ``` {note}
194
+ This also runs on each push to `main`.
195
+ ```
142
196
143
- 1 . ` git tag -f stable VERSION_TAG `
144
- 1 . e.g. ` git tag -f stable 21.5b1 `
145
- 1 . ` git push --tags -f `
197
+ [ black-actions ] : https://github.com/psf/black/actions
198
+ [ build ] : https://pypa-build.readthedocs.io/
199
+ [ calver ] : https://calver.org
200
+ [ cibuildwheel ] : https://cibuildwheel.readthedocs.io/
201
+ [ gh-3139 ] : https://github.com/psf/black/pull/3139
202
+ [ github actions ] : https://github.com/features/actions
203
+ [ github release ] : https://github.com/psf/black/releases
204
+ [ new-release ] : https://github.com/psf/black/releases/new
205
+ [ mypyc ] : https://mypyc.readthedocs.io/
206
+ [ mypyc-platform-support] :
207
+ /faq.html#what-is-compiled-yes-no-all-about-in-the-version-output
208
+ [ pyinstaller ] : https://www.pyinstaller.org/
209
+ [ sdist] :
210
+ https://packaging.python.org/en/latest/glossary/#term-Source-Distribution-or-sdist
211
+ [ twine ] : https://github.com/features/actions
212
+ [ wheels ] : https://packaging.python.org/en/latest/glossary/#term-Wheel
0 commit comments