chore: import upstream snapshot with attribution
fuzz / fuzz (3.11) (push) Failing after 1s
fuzz / fuzz (3.12) (push) Failing after 1s
build and publish / sdist + pure wheel (push) Failing after 0s
diff-shades / analysis / base / ${{ matrix.mode }} (push) Has been skipped
docs / docs (ubuntu-latest) (push) Failing after 2s
fuzz / fuzz (3.10) (push) Failing after 1s
fuzz / fuzz (3.14) (push) Failing after 0s
lint and format / lint (push) Failing after 1s
diff-shades / configure (push) Failing after 1s
docker / build (linux/amd64) (push) Has been skipped
diff-shades / analysis / target / ${{ matrix.mode }} (push) Has been skipped
fuzz / fuzz (3.13) (push) Failing after 0s
build and publish / generate wheels matrix (push) Failing after 0s
test release tool / test-release-tool (ubuntu-latest, 3.13) (push) Failing after 1s
build and publish / mypyc wheels ${{ matrix.only }} (push) Has been skipped
test / test (ubuntu-latest, 3.10) (push) Failing after 0s
test / test (ubuntu-latest, 3.11) (push) Failing after 1s
test / test (ubuntu-latest, 3.13) (push) Failing after 0s
test / test (ubuntu-latest, pypy3.11-v7.3.22) (push) Failing after 1s
test / test (ubuntu-latest, 3.15) (push) Failing after 1s
test release tool / test-release-tool (ubuntu-latest, 3.15) (push) Failing after 0s
zizmor / zizmor (push) Failing after 0s
test release tool / test-release-tool (ubuntu-latest, 3.12) (push) Failing after 4s
test release tool / test-release-tool (ubuntu-latest, 3.14) (push) Failing after 3s
test / uvloop (ubuntu-latest) (push) Failing after 1s
test / test (ubuntu-latest, 3.14) (push) Failing after 1s
test / test (ubuntu-latest, 3.12.10) (push) Failing after 5s
docker / build (linux/arm64) (push) Has been cancelled
docker / push (push) Has been cancelled
docs / docs (windows-latest) (push) Has been cancelled
test release tool / test-release-tool (windows-latest, 3.14) (push) Has been cancelled
test release tool / test-release-tool (windows-latest, 3.15) (push) Has been cancelled
test release tool / test-release-tool (macOS-latest, 3.12) (push) Has been cancelled
test release tool / test-release-tool (macOS-latest, 3.13) (push) Has been cancelled
test release tool / test-release-tool (macOS-latest, 3.14) (push) Has been cancelled
test release tool / test-release-tool (macOS-latest, 3.15) (push) Has been cancelled
test release tool / test-release-tool (windows-latest, 3.12) (push) Has been cancelled
test release tool / test-release-tool (windows-latest, 3.13) (push) Has been cancelled
test / test (macOS-latest, 3.11) (push) Has been cancelled
test / test (macOS-latest, 3.12.10) (push) Has been cancelled
test / test (macOS-latest, 3.13) (push) Has been cancelled
test / test (macOS-latest, 3.14) (push) Has been cancelled
test / test (macOS-latest, 3.15) (push) Has been cancelled
test / test (macOS-latest, pypy3.11-v7.3.22) (push) Has been cancelled
test / test (windows-11-arm, 3.11) (push) Has been cancelled
test / test (windows-11-arm, 3.12.10) (push) Has been cancelled
test / test (windows-11-arm, 3.13) (push) Has been cancelled
test / test (macOS-latest, 3.10) (push) Has been cancelled
test / coveralls-finish (push) Has been cancelled
test / uvloop (macOS-latest) (push) Has been cancelled
test / uvloop (windows-11-arm) (push) Has been cancelled
test / uvloop (windows-latest) (push) Has been cancelled
test / test (windows-11-arm, 3.14) (push) Has been cancelled
test / test (windows-11-arm, 3.15) (push) Has been cancelled
test / test (windows-latest, 3.10) (push) Has been cancelled
test / test (windows-latest, 3.11) (push) Has been cancelled
test / test (windows-latest, 3.12.10) (push) Has been cancelled
test / test (windows-latest, 3.13) (push) Has been cancelled
test / test (windows-latest, 3.14) (push) Has been cancelled
test / test (windows-latest, 3.15) (push) Has been cancelled
test / test (windows-latest, pypy3.11-v7.3.22) (push) Has been cancelled
diff-shades / compare / ${{ matrix.mode }} (push) Has been cancelled
fuzz / create-issue (push) Has been cancelled
build and publish / publish-mypyc (push) Has been cancelled
build and publish / publish-hatch (push) Has been cancelled
fuzz / fuzz (3.11) (push) Failing after 1s
fuzz / fuzz (3.12) (push) Failing after 1s
build and publish / sdist + pure wheel (push) Failing after 0s
diff-shades / analysis / base / ${{ matrix.mode }} (push) Has been skipped
docs / docs (ubuntu-latest) (push) Failing after 2s
fuzz / fuzz (3.10) (push) Failing after 1s
fuzz / fuzz (3.14) (push) Failing after 0s
lint and format / lint (push) Failing after 1s
diff-shades / configure (push) Failing after 1s
docker / build (linux/amd64) (push) Has been skipped
diff-shades / analysis / target / ${{ matrix.mode }} (push) Has been skipped
fuzz / fuzz (3.13) (push) Failing after 0s
build and publish / generate wheels matrix (push) Failing after 0s
test release tool / test-release-tool (ubuntu-latest, 3.13) (push) Failing after 1s
build and publish / mypyc wheels ${{ matrix.only }} (push) Has been skipped
test / test (ubuntu-latest, 3.10) (push) Failing after 0s
test / test (ubuntu-latest, 3.11) (push) Failing after 1s
test / test (ubuntu-latest, 3.13) (push) Failing after 0s
test / test (ubuntu-latest, pypy3.11-v7.3.22) (push) Failing after 1s
test / test (ubuntu-latest, 3.15) (push) Failing after 1s
test release tool / test-release-tool (ubuntu-latest, 3.15) (push) Failing after 0s
zizmor / zizmor (push) Failing after 0s
test release tool / test-release-tool (ubuntu-latest, 3.12) (push) Failing after 4s
test release tool / test-release-tool (ubuntu-latest, 3.14) (push) Failing after 3s
test / uvloop (ubuntu-latest) (push) Failing after 1s
test / test (ubuntu-latest, 3.14) (push) Failing after 1s
test / test (ubuntu-latest, 3.12.10) (push) Failing after 5s
docker / build (linux/arm64) (push) Has been cancelled
docker / push (push) Has been cancelled
docs / docs (windows-latest) (push) Has been cancelled
test release tool / test-release-tool (windows-latest, 3.14) (push) Has been cancelled
test release tool / test-release-tool (windows-latest, 3.15) (push) Has been cancelled
test release tool / test-release-tool (macOS-latest, 3.12) (push) Has been cancelled
test release tool / test-release-tool (macOS-latest, 3.13) (push) Has been cancelled
test release tool / test-release-tool (macOS-latest, 3.14) (push) Has been cancelled
test release tool / test-release-tool (macOS-latest, 3.15) (push) Has been cancelled
test release tool / test-release-tool (windows-latest, 3.12) (push) Has been cancelled
test release tool / test-release-tool (windows-latest, 3.13) (push) Has been cancelled
test / test (macOS-latest, 3.11) (push) Has been cancelled
test / test (macOS-latest, 3.12.10) (push) Has been cancelled
test / test (macOS-latest, 3.13) (push) Has been cancelled
test / test (macOS-latest, 3.14) (push) Has been cancelled
test / test (macOS-latest, 3.15) (push) Has been cancelled
test / test (macOS-latest, pypy3.11-v7.3.22) (push) Has been cancelled
test / test (windows-11-arm, 3.11) (push) Has been cancelled
test / test (windows-11-arm, 3.12.10) (push) Has been cancelled
test / test (windows-11-arm, 3.13) (push) Has been cancelled
test / test (macOS-latest, 3.10) (push) Has been cancelled
test / coveralls-finish (push) Has been cancelled
test / uvloop (macOS-latest) (push) Has been cancelled
test / uvloop (windows-11-arm) (push) Has been cancelled
test / uvloop (windows-latest) (push) Has been cancelled
test / test (windows-11-arm, 3.14) (push) Has been cancelled
test / test (windows-11-arm, 3.15) (push) Has been cancelled
test / test (windows-latest, 3.10) (push) Has been cancelled
test / test (windows-latest, 3.11) (push) Has been cancelled
test / test (windows-latest, 3.12.10) (push) Has been cancelled
test / test (windows-latest, 3.13) (push) Has been cancelled
test / test (windows-latest, 3.14) (push) Has been cancelled
test / test (windows-latest, 3.15) (push) Has been cancelled
test / test (windows-latest, pypy3.11-v7.3.22) (push) Has been cancelled
diff-shades / compare / ${{ matrix.mode }} (push) Has been cancelled
fuzz / create-issue (push) Has been cancelled
build and publish / publish-mypyc (push) Has been cancelled
build and publish / publish-hatch (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
# Gauging changes
|
||||
|
||||
A lot of the time, your change will affect formatting and/or performance. Quantifying
|
||||
these changes is hard, so we have tooling to help make it easier.
|
||||
|
||||
It's recommended you evaluate the quantifiable changes your _Black_ formatting
|
||||
modification causes before submitting a PR. Think about if the change seems disruptive
|
||||
enough to cause frustration to projects that are already "Black-formatted".
|
||||
|
||||
## diff-shades
|
||||
|
||||
diff-shades is a tool that runs _Black_ across a list of open-source projects recording
|
||||
the results. The main highlight feature of diff-shades is being able to compare two
|
||||
revisions of _Black_. This is incredibly useful as it allows us to see what exact
|
||||
changes will occur, say merging a certain PR.
|
||||
|
||||
For more information, please see the [diff-shades documentation][diff-shades].
|
||||
|
||||
### CI integration
|
||||
|
||||
diff-shades is also the tool behind the "diff-shades results comparing ..." comments on
|
||||
PRs. The project has a GitHub Actions workflow that analyzes and compares two revisions
|
||||
of _Black_ according to these rules:
|
||||
|
||||
| | Baseline revision | Target revision |
|
||||
| --------------------- | ------------------------------- | ---------------------------- |
|
||||
| On PRs | latest commit on PR base branch | PR commit with `main` merged |
|
||||
| On pushes (main only) | latest PyPI version | the pushed commit |
|
||||
|
||||
For pushes to main, there's only one analysis job named `preview-new-changes` where the
|
||||
preview style is used for all projects.
|
||||
|
||||
For PRs they get one more analysis job: `assert-no-changes`. It's similar to
|
||||
`preview-new-changes` but runs with the stable code style. It will fail if changes were
|
||||
made. This makes sure code won't be reformatted again and again within the same year in
|
||||
accordance to Black's stability policy.
|
||||
|
||||
Additionally for PRs, a PR comment will be posted embedding a summary previewing any
|
||||
changes in both styles and links to further information. The next time the workflow is
|
||||
triggered on the same PR, it'll update the pre-existing diff-shades comment.
|
||||
|
||||
```{note}
|
||||
Jobs will only fail intentionally if a file failed to format while analyzing, or if
|
||||
changes were made to the stable style. Otherwise a failure indicates a bug in the
|
||||
workflow.
|
||||
```
|
||||
|
||||
The workflow uploads several artifacts upon completion:
|
||||
|
||||
- HTML diffs (.html)
|
||||
- handy for pushes where there's no PR to post a comment
|
||||
- The raw analyses (.json)
|
||||
- in case you want to do further analysis using the collected data locally
|
||||
- `.preview.pr-comment.md` and `.stable.pr-comment.md` (if triggered by a PR)
|
||||
- used to generate the PR comment and shouldn't be downloaded
|
||||
|
||||
[diff-shades]: https://github.com/ichard26/diff-shades#readme
|
||||
@@ -0,0 +1,45 @@
|
||||
# Contributing
|
||||
|
||||
```{toctree}
|
||||
---
|
||||
hidden:
|
||||
---
|
||||
|
||||
the_basics
|
||||
gauging_changes
|
||||
issue_triage
|
||||
release_process
|
||||
```
|
||||
|
||||
Welcome! Happy to see you willing to make the project better. Have you read the entire
|
||||
[user documentation](https://black.readthedocs.io/en/latest/) yet?
|
||||
|
||||
```{rubric} Bird's eye view
|
||||
|
||||
```
|
||||
|
||||
In terms of inspiration, _Black_ is about as configurable as _gofmt_ (which is to say,
|
||||
not very). This is deliberate. _Black_ aims to provide a consistent style and take away
|
||||
opportunities for arguing about style.
|
||||
|
||||
Bug reports and fixes are always welcome! Please follow the
|
||||
[issue templates on GitHub](https://github.com/psf/black/issues/new/choose) for best
|
||||
results.
|
||||
|
||||
Before you suggest a new feature or configuration knob, ask yourself why you want it. If
|
||||
it enables better integration with some workflow, fixes an inconsistency, speeds things
|
||||
up, and so on - go for it! On the other hand, if your answer is "because I don't like a
|
||||
particular formatting" then you're not ready to embrace _Black_ yet. Such changes are
|
||||
unlikely to get accepted. You can still try but prepare to be disappointed.
|
||||
|
||||
```{rubric} Contents
|
||||
|
||||
```
|
||||
|
||||
This section covers the following topics:
|
||||
|
||||
- {doc}`the_basics`
|
||||
- {doc}`gauging_changes`
|
||||
- {doc}`release_process`
|
||||
|
||||
For an overview on contributing to the _Black_, please checkout {doc}`the_basics`.
|
||||
@@ -0,0 +1,173 @@
|
||||
# Issue triage
|
||||
|
||||
Currently, _Black_ uses the issue tracker for bugs, feature requests, proposed style
|
||||
modifications, and general user support. Each of these issues have to be triaged so they
|
||||
can be eventually be resolved somehow. This document outlines the triaging process and
|
||||
also the current guidelines and recommendations.
|
||||
|
||||
```{tip}
|
||||
If you're looking for a way to contribute without submitting patches, this might be the
|
||||
area for you. Since _Black_ is a popular project, its issue tracker is quite busy and
|
||||
always needs more attention than is available. While triage isn't the most glamorous or
|
||||
technically challenging form of contribution, it's still important. For example, we
|
||||
would love to know whether that old bug report is still reproducible!
|
||||
|
||||
You can get easily started by reading over this document and then responding to issues.
|
||||
|
||||
If you contribute enough and have stayed for long enough, you may even be given
|
||||
Triage permissions!
|
||||
```
|
||||
|
||||
## The basics
|
||||
|
||||
_Black_ gets a whole bunch of different issues, they range from bug reports to user
|
||||
support issues. To triage is to identify, organize, and kickstart the issue's journey
|
||||
through its lifecycle to resolution.
|
||||
|
||||
More specifically, to triage an issue means to:
|
||||
|
||||
- identify what type and categories the issue falls under
|
||||
- confirm bugs
|
||||
- ask questions / for further information if necessary
|
||||
- link related issues
|
||||
- provide the first initial feedback / support
|
||||
|
||||
Note that triage is typically the first response to an issue, so don't fret if the issue
|
||||
doesn't make much progress after initial triage. The main goal of triaging to prepare
|
||||
the issue for future more specific development or discussion, so _eventually_ it will be
|
||||
resolved.
|
||||
|
||||
The lifecycle of a bug report or user support issue typically goes something like this:
|
||||
|
||||
1. _the issue is waiting for triage_
|
||||
2. **identified** - has been marked with a type label and other relevant labels, more
|
||||
details or a functional reproduction may be still needed (and therefore should be
|
||||
marked with `S: needs repro` or `S: awaiting response`)
|
||||
3. **confirmed** - the issue can reproduced and necessary details have been provided
|
||||
4. **discussion** - initial triage has been done and now the general details on how the
|
||||
issue should be best resolved are being hashed out
|
||||
5. **awaiting fix** - no further discussion on the issue is necessary and a resolving PR
|
||||
is the next step
|
||||
6. **closed** - the issue has been resolved, reasons include:
|
||||
- the issue couldn't be reproduced
|
||||
- the issue has been fixed
|
||||
- duplicate of another pre-existing issue or is invalid
|
||||
|
||||
For enhancement, documentation, and style issues, the lifecycle looks very similar but
|
||||
the details are different:
|
||||
|
||||
1. _the issue is waiting for triage_
|
||||
2. **identified** - has been marked with a type label and other relevant labels
|
||||
3. **discussion** - the merits of the suggested changes are currently being discussed, a
|
||||
PR would be acceptable but would be at significant risk of being rejected
|
||||
4. **accepted & awaiting PR** - it's been determined the suggested changes are OK and a
|
||||
PR would be welcomed (`S: accepted`)
|
||||
5. **closed**: - the issue has been resolved, reasons include:
|
||||
- the suggested changes were implemented
|
||||
- it was rejected (due to technical concerns, ethos conflicts, etc.)
|
||||
- duplicate of a pre-existing issue or is invalid
|
||||
|
||||
**Note**: documentation issues don't use the `S: accepted` label currently since they're
|
||||
less likely to be rejected.
|
||||
|
||||
## Labelling
|
||||
|
||||
We use labels to organize, track progress, and help effectively divvy up work.
|
||||
|
||||
Our labels are divided up into several groups identified by their prefix:
|
||||
|
||||
- **T - Type**: the general flavor of issue / PR
|
||||
- **C - Category**: areas of concerns, ranges from bug types to project maintenance
|
||||
- **F - Formatting Area**: like C but for formatting specifically
|
||||
- **S - Status**: what stage of resolution is this issue currently in?
|
||||
- **R - Resolution**: how / why was the issue / PR resolved?
|
||||
|
||||
We also have a few standalone labels:
|
||||
|
||||
- **`good first issue`**: issues that are beginner-friendly (and will show up in GitHub
|
||||
banners for first-time visitors to the repository)
|
||||
- **`help wanted`**: complex issues that need and are looking for a fair bit of work as
|
||||
to progress (will also show up in various GitHub pages)
|
||||
- **`ci: skip news`**: for PRs that are trivial and don't need a CHANGELOG entry (and
|
||||
skips the CHANGELOG entry check)
|
||||
- **`ci: build all wheels`**: when a full wheel build is needed, such as to debug
|
||||
platform-specific issues. Black does not build wheels for every platform on each pull
|
||||
request because the full build matrix is expensive. After the label is added, the
|
||||
workflow starts only when a new commit is pushed.
|
||||
|
||||
```{note}
|
||||
We do use labels for PRs, in particular the `ci: skip news` label, but we aren't that
|
||||
rigorous about it. Just follow your judgement on what labels make sense for the specific
|
||||
PR (if any even make sense).
|
||||
```
|
||||
|
||||
## Projects
|
||||
|
||||
For more general and broad goals we use projects to track work. Some may be long-term
|
||||
projects with no true end (e.g. the "Amazing documentation" project) while others may be
|
||||
more focused and have a definite end (like the "Getting to beta" project).
|
||||
|
||||
```{note}
|
||||
To modify GitHub Projects you need the
|
||||
[Write repository permission level or higher](https://docs.github.com/en/organizations/managing-access-to-your-organizations-repositories/repository-permission-levels-for-an-organization#repository-access-for-each-permission-level).
|
||||
```
|
||||
|
||||
## Closing issues
|
||||
|
||||
Closing an issue signifies the issue has reached the end of its life, so closing issues
|
||||
should be taken with care. The following is the general recommendation for each type of
|
||||
issue. Note that these are only guidelines and if your judgement says something else
|
||||
it's totally cool to go with it instead.
|
||||
|
||||
For most issues, closing the issue manually or automatically after a resolving PR is
|
||||
ideal. For bug reports specifically, if the bug has already been fixed, try to check in
|
||||
with the issue opener that their specific case has been resolved before closing. Note
|
||||
that we close issues as soon as they're fixed in the `main` branch. This doesn't
|
||||
necessarily mean they've been released yet.
|
||||
|
||||
Design and enhancement issues should be also closed when it's clear the proposed change
|
||||
won't be implemented, whether that has been determined after a lot of discussion or just
|
||||
simply goes against _Black_'s ethos. If such an issue turns heated, closing and locking
|
||||
is acceptable if it's severe enough (although checking in with the core team is probably
|
||||
a good idea).
|
||||
|
||||
User support issues are best closed by the author or when it's clear the issue has been
|
||||
resolved in some sort of manner.
|
||||
|
||||
Duplicates and invalid issues should always be closed since they serve no purpose and
|
||||
add noise to an already busy issue tracker. Although be careful to make sure it's truly
|
||||
a duplicate and not just very similar before labelling and closing an issue as
|
||||
duplicate.
|
||||
|
||||
## Common reports
|
||||
|
||||
Some issues are frequently opened, like issues about _Black_ formatted code causing E203
|
||||
messages. Even though these issues are probably heavily duplicated, they still require
|
||||
triage sucking up valuable time from other things (although they usually skip most of
|
||||
their lifecycle since they're closed on triage).
|
||||
|
||||
Here's some of the most common issues and also pre-made responses you can use:
|
||||
|
||||
### "The trailing comma isn't being removed by Black!"
|
||||
|
||||
```text
|
||||
Black used to remove the trailing comma if the expression fits in a single line, but this was changed by #826 and #1288. Now a trailing comma tells Black to always explode the expression. This change was made mostly for the cases where you _know_ a collection or whatever will grow in the future. Having it always exploded as one element per line reduces diff noise when adding elements. Before the "magic trailing comma" feature, you couldn't anticipate a collection's growth reliably since collections that fitted in one line were ruthlessly collapsed regardless of your intentions. One of Black's goals is reducing diff noise, so this was a good pragmatic change.
|
||||
|
||||
So no, this is not a bug, but an intended feature. Anyway, [here's the documentation](https://github.com/psf/black/blob/master/docs/the_black_code_style.md#the-magic-trailing-comma) on the "magic trailing comma", including the ability to skip this functionality with the `--skip-magic-trailing-comma` option. Hopefully that helps solve the possible confusion.
|
||||
```
|
||||
|
||||
### "Black formatted code is violating Flake8's E203!"
|
||||
|
||||
```text
|
||||
Hi,
|
||||
|
||||
This is expected behaviour, please see the documentation regarding this case (emphasis mine):
|
||||
|
||||
> PEP 8 recommends to treat : in slices as a binary operator with the lowest priority, and to leave an equal amount of space on either side, **except if a parameter is omitted (e.g. ham[1 + 1 :])**. It recommends no spaces around : operators for “simple expressions” (ham[lower:upper]), and **extra space for “complex expressions” (ham[lower : upper + offset])**. **Black treats anything more than variable names as “complex” (ham[lower : upper + 1]).** It also states that for extended slices, both : operators have to have the same amount of spacing, except if a parameter is omitted (ham[1 + 1 ::]). Black enforces these rules consistently.
|
||||
|
||||
> This behaviour may raise E203 whitespace before ':' warnings in style guide enforcement tools like Flake8. **Since E203 is not PEP 8 compliant, you should tell Flake8 to ignore these warnings**.
|
||||
|
||||
https://black.readthedocs.io/en/stable/the_black_code_style/current_style.html#slices
|
||||
|
||||
Have a good day!
|
||||
```
|
||||
@@ -0,0 +1,180 @@
|
||||
# Release process
|
||||
|
||||
_Black_ has had a lot of work done into standardizing and automating its release
|
||||
process. This document sets out to explain how everything works and how to release
|
||||
_Black_ using said automation.
|
||||
|
||||
## Release cadence
|
||||
|
||||
**We aim to release whatever is on `main` every 1-2 months.** This ensures merged
|
||||
improvements and bugfixes are shipped to users reasonably quickly, while not massively
|
||||
fracturing the user-base with too many versions. This also keeps the workload on
|
||||
maintainers consistent and predictable.
|
||||
|
||||
If there's not much new on `main` to justify a release, it's acceptable to skip a
|
||||
month's release. Ideally January releases should not be skipped because as per our
|
||||
[stability policy](labels/stability-policy), the first release in a new calendar year
|
||||
may make changes to the _stable_ style. While the policy applies to the first release
|
||||
(instead of only January releases), confining changes to the stable style to January
|
||||
will keep things predictable (and nicer) for users.
|
||||
|
||||
Unless there is a serious regression or bug that requires immediate patching, **there
|
||||
should not be more than one release per month**. While version numbers are cheap,
|
||||
releases require a maintainer to both commit to do the actual cutting of a release, but
|
||||
also to be able to deal with the potential fallout post-release. Releasing more
|
||||
frequently than monthly nets rapidly diminishing returns.
|
||||
|
||||
## Cutting a release
|
||||
|
||||
**You must have `write` permissions for the _Black_ repository to cut a release.**
|
||||
|
||||
The 10,000 foot view of the release process is that you prepare a release PR and then
|
||||
publish a [GitHub Release]. This triggers [release automation](#release-workflows) that
|
||||
builds all release artifacts and publishes them to the various platforms we publish to.
|
||||
|
||||
We now have a `scripts/release.py` script to help with cutting the release PRs.
|
||||
|
||||
- `python3 scripts/release.py --help` is your friend.
|
||||
- `release.py` has only been tested in Python 3.12+ (so get with the times :D)
|
||||
|
||||
To cut a release:
|
||||
|
||||
1. Determine the release's version number
|
||||
- **_Black_ follows the [CalVer] versioning standard using the `YY.M.N` format**
|
||||
- So unless there already has been a release during this month, `N` should be `0`
|
||||
- Example: the first release in January, 2026 → `26.1.0`
|
||||
- `release.py` will calculate this and log it to stdout for your copy-paste pleasure
|
||||
1. Double-check that no changelog entries since the last release were put in the wrong
|
||||
section (e.g., run `git diff origin/stable CHANGES.md`)
|
||||
1. File a PR editing `CHANGES.md` and the docs to version the latest changes
|
||||
- Run `python3 scripts/release.py [--debug]` to generate most changes
|
||||
1. If `release.py` fails manually edit; otherwise, yay, skip this step!
|
||||
1. Replace the `## Unreleased` header with the version number
|
||||
1. Remove any empty sections for the current release
|
||||
1. (_optional_) Read through and copy-edit the changelog (eg. by moving entries,
|
||||
fixing typos, or rephrasing entries)
|
||||
1. Update references to the latest version in
|
||||
{doc}`/integrations/source_version_control` and
|
||||
{doc}`/usage_and_configuration/the_basics`
|
||||
- Example PR: [GH-4563]
|
||||
1. Once the release PR is merged, wait until all CI passes
|
||||
- If CI does not pass, **stop** and investigate the failure(s) as generally we'd want
|
||||
to fix failing CI before cutting a release
|
||||
1. [Draft a new GitHub Release][new-release]
|
||||
1. Click `Choose a tag` and type in the version number, then select the
|
||||
`Create new tag: YY.M.N on publish` option that appears
|
||||
1. Verify that the new tag targets the `main` branch
|
||||
1. Make sure the release title is set to the version (`YY.M.N`), as otherwise the
|
||||
default title is the last commit's title
|
||||
1. Copy and paste the _raw changelog Markdown_ for the current release into the
|
||||
description box
|
||||
1. Publish the GitHub Release, triggering [release automation](#release-workflows) that
|
||||
will handle the rest
|
||||
1. Once CI is done add + PR a new empty template for the next release to CHANGES.md
|
||||
_(Template is able to be copy pasted from release.py should we fail)_
|
||||
1. `python3 scripts/release.py --add-changes-template|-a [--debug]`
|
||||
1. Should that fail, please return to copy + paste
|
||||
1. At this point, you're basically done. It's good practice to go and [watch and verify
|
||||
that all the release workflows pass][black-actions], although you will receive a
|
||||
GitHub notification should something fail.
|
||||
- If something fails, don't panic. Please go read the respective workflow's logs and
|
||||
configuration file to reverse-engineer your way to a fix/solution.
|
||||
|
||||
Congratulations! You've successfully cut a new release of _Black_. Go and stand up and
|
||||
take a break, you deserve it.
|
||||
|
||||
```{important}
|
||||
Once the release artifacts reach PyPI, you may see new issues being filed indicating
|
||||
regressions. While regressions are not great, they don't automatically mean a hotfix
|
||||
release is warranted. Unless the regressions are serious and impact many users, a hotfix
|
||||
release is probably unnecessary.
|
||||
|
||||
In the end, use your best judgement and ask other maintainers for their thoughts.
|
||||
```
|
||||
|
||||
## Release workflows
|
||||
|
||||
All of _Black_'s release automation uses [GitHub Actions]. All workflows are therefore
|
||||
configured using YAML files in the `.github/workflows` directory of the _Black_
|
||||
repository.
|
||||
|
||||
They are triggered by the publication of a [GitHub Release].
|
||||
|
||||
Below are descriptions of our release workflows.
|
||||
|
||||
### build and publish
|
||||
|
||||
This is our main workflow. It builds an [sdist] and [wheels] to upload to PyPI where the
|
||||
vast majority of users will download Black from. It's divided into three job groups:
|
||||
|
||||
#### sdist + pure wheel
|
||||
|
||||
This single job builds the sdist and pure Python wheel (i.e., a wheel that only contains
|
||||
Python code) using [Hatch]. These artifacts are general-purpose and can be used on
|
||||
basically any platform supported by Python.
|
||||
|
||||
#### generate wheels matrix / mypyc wheels (…)
|
||||
|
||||
We use [mypyc] to compile _Black_ into a CPython C extension for significantly improved
|
||||
performance. Wheels built with mypyc are platform and Python version specific.
|
||||
[Supported platforms are documented in the FAQ](labels/mypyc-support).
|
||||
|
||||
These matrix jobs use [cibuildwheel] which handles the complicated task of building C
|
||||
extensions for many environments for us. Since building these wheels is slow, there are
|
||||
multiple mypyc wheels jobs (hence the term "matrix") that build for a specific platform
|
||||
(as noted in the job name in parentheses).
|
||||
|
||||
#### publish-hatch / publish-mypyc
|
||||
|
||||
These jobs upload the built sdist and all wheels to PyPI using [Trusted
|
||||
publishing][trusted-publishing].
|
||||
|
||||
### publish binaries
|
||||
|
||||
This workflow builds native executables for multiple platforms using [PyInstaller]. This
|
||||
allows people to download the executable for their platform and run _Black_ without a
|
||||
[Python runtime](https://wiki.python.org/moin/PythonImplementations) installed.
|
||||
|
||||
The created binaries are stored on the associated GitHub Release for download over _IPv4
|
||||
only_ (GitHub still does not have IPv6 access 😢).
|
||||
|
||||
### docker
|
||||
|
||||
This workflow uses the QEMU powered `buildx` feature of Docker to upload an `arm64` and
|
||||
`amd64`/`x86_64` build of the official _Black_ Docker image™.
|
||||
|
||||
- _Currently this workflow uses an API Token associated with @cooperlees account_
|
||||
|
||||
```{note}
|
||||
This also runs on each push to `main`.
|
||||
```
|
||||
|
||||
### post release
|
||||
|
||||
This workflow runs a few miscellaneous jobs related to repository maintenance.
|
||||
|
||||
#### update-stable
|
||||
|
||||
Updates the `stable` branch by force pushing it to the most recent tag. This saves us
|
||||
from remembering to update the branch sometime after cutting the release.
|
||||
|
||||
#### new-changelog
|
||||
|
||||
Opens a new PR to add the "Unreleased" section back to the changelog. The PR is
|
||||
intentionally not auto-merged, in case there's an issue and the release needs to be
|
||||
re-cut.
|
||||
|
||||
[black-actions]: https://github.com/psf/black/actions
|
||||
[calver]: https://calver.org
|
||||
[cibuildwheel]: https://cibuildwheel.readthedocs.io/
|
||||
[gh-4563]: https://github.com/psf/black/pull/4563
|
||||
[github actions]: https://github.com/features/actions
|
||||
[github release]: https://github.com/psf/black/releases
|
||||
[hatch]: https://hatch.pypa.io/latest/
|
||||
[mypyc]: https://mypyc.readthedocs.io/
|
||||
[new-release]: https://github.com/psf/black/releases/new
|
||||
[pyinstaller]: https://www.pyinstaller.org/
|
||||
[sdist]:
|
||||
https://packaging.python.org/en/latest/glossary/#term-source-distribution-or-sdist
|
||||
[trusted-publishing]: https://docs.pypi.org/trusted-publishers/
|
||||
[wheels]: https://packaging.python.org/en/latest/glossary/#term-wheel
|
||||
@@ -0,0 +1,152 @@
|
||||
# The basics
|
||||
|
||||
An overview on contributing to the _Black_ project.
|
||||
|
||||
## Technicalities
|
||||
|
||||
Development on the latest version of Python is preferred. You can use any operating
|
||||
system.
|
||||
|
||||
First clone the _Black_ repository:
|
||||
|
||||
```console
|
||||
$ git clone https://github.com/psf/black.git
|
||||
$ cd black
|
||||
```
|
||||
|
||||
Then install development dependencies inside a virtual environment of your choice, for
|
||||
example:
|
||||
|
||||
```console
|
||||
$ python3 -m venv .venv
|
||||
$ source .venv/bin/activate # activation for linux and mac
|
||||
$ .venv\Scripts\activate # activation for windows
|
||||
|
||||
(.venv)$ pip install --group dev
|
||||
(.venv)$ pip install -e ".[d]"
|
||||
(.venv)$ pre-commit install
|
||||
```
|
||||
|
||||
Before submitting pull requests, run lints and tests with the following commands from
|
||||
the root of the black repo:
|
||||
|
||||
```console
|
||||
(.venv)$ pre-commit run -a # Linting
|
||||
(.venv)$ tox -e py # Unit tests
|
||||
(.venv)$ tox -e fuzz # Optional Fuzz testing
|
||||
(.venv)$ tox -e run_self # Format Black itself
|
||||
```
|
||||
|
||||
### Development
|
||||
|
||||
Further examples of invoking the tests
|
||||
|
||||
```console
|
||||
(.venv)$ tox --parallel=auto # Run all the above in parallel
|
||||
(.venv)$ tox -e py314 # Run tests on a specific python version
|
||||
(.venv)$ pytest -k <test name> # Run an individual test
|
||||
(.venv)$ tox -e py -- --no-cov # Pass arguments to pytest
|
||||
```
|
||||
|
||||
### Testing
|
||||
|
||||
All aspects of the _Black_ style should be tested. Normally, tests should be created as
|
||||
files in the `tests/data/cases` directory. These files consist of up to three parts:
|
||||
|
||||
- A line that starts with `# flags: ` followed by a set of command-line options. For
|
||||
example, if the line is `# flags: --preview --skip-magic-trailing-comma`, the test
|
||||
case will be run with preview mode on and the magic trailing comma off. The options
|
||||
accepted are mostly a subset of those of _Black_ itself, except for the
|
||||
`--minimum-version=` flag, which should be used when testing a grammar feature that
|
||||
works only in newer versions of Python. This flag ensures that we don't try to
|
||||
validate the AST on older versions and tests that we autodetect the Python version
|
||||
correctly when the feature is used. For the exact flags accepted, see the function
|
||||
`get_flags_parser` in `tests/util.py`. If this line is omitted, the default options
|
||||
are used.
|
||||
- A block of Python code used as input for the formatter.
|
||||
- The line `# output`, followed by the output of _Black_ when run on the previous block.
|
||||
If this is omitted, the test asserts that _Black_ will leave the input code unchanged.
|
||||
|
||||
_Black_ has two pytest command-line options affecting test files in `tests/data/` that
|
||||
are split into an input part, and an output part, separated by a line with `# output`.
|
||||
These can be passed to `pytest` through `tox`, or directly into pytest if not using
|
||||
`tox`.
|
||||
|
||||
#### `--print-full-tree`
|
||||
|
||||
Upon a failing test, print the full concrete syntax tree (CST) as it is after processing
|
||||
the input ("actual"), and the tree that's yielded after parsing the output ("expected").
|
||||
Note that a test can fail with different output with the same CST. This used to be the
|
||||
default, but now defaults to `False`.
|
||||
|
||||
```console
|
||||
(.venv)$ tox -e py -- --print-full-tree
|
||||
```
|
||||
|
||||
#### `--print-tree-diff`
|
||||
|
||||
Upon a failing test, print the diff of the trees as described above. This is the
|
||||
default. To turn it off pass `--print-tree-diff=False`.
|
||||
|
||||
```console
|
||||
(.venv)$ tox -e py -- --print-tree-diff=False
|
||||
```
|
||||
|
||||
### News / Changelog Requirement
|
||||
|
||||
`Black` has CI that will check for an entry corresponding to your PR in `CHANGES.md`. If
|
||||
you feel this PR does not require a changelog entry please state that in a comment and a
|
||||
maintainer can add a `ci: skip news` label to make the CI pass. Otherwise, please ensure
|
||||
you have a line in the following format added below the appropriate header:
|
||||
|
||||
```md
|
||||
- `Black` is now more awesome (#X)
|
||||
```
|
||||
|
||||
<!---
|
||||
The Next PR Number link uses HTML because of a bug in MyST-Parser that double-escapes the ampersand, causing the query parameters to not be processed.
|
||||
MyST-Parser issue: https://github.com/executablebooks/MyST-Parser/issues/760
|
||||
MyST-Parser stalled fix PR: https://github.com/executablebooks/MyST-Parser/pull/929
|
||||
-->
|
||||
|
||||
Note that X should be your PR number, not issue number! To workout X, please use
|
||||
<a href="https://ichard26.github.io/next-pr-number/?owner=psf&name=black">Next PR
|
||||
Number</a>. This is not perfect but saves a lot of release overhead as now the releaser
|
||||
does not need to go back and workout what to add to the `CHANGES.md` for each release.
|
||||
|
||||
### Style Changes
|
||||
|
||||
Please familiarize yourself with our [stability policy](labels/stability-policy).
|
||||
Therefore, most style changes must be added to the `--preview` style. Exceptions are
|
||||
fixing crashes or changes that would not affect an already-formatted file.
|
||||
|
||||
If a change would affect the advertised code style, please modify the documentation (The
|
||||
_Black_ code style) to reflect that change. Patches that fix unintended bugs in
|
||||
formatting don't need to be mentioned separately.
|
||||
|
||||
If the change is implemented with the `--preview` flag, please include the change in the
|
||||
Future Style document instead and write the changelog entry under the dedicated "Preview
|
||||
style" heading.
|
||||
|
||||
### Docs Testing
|
||||
|
||||
If you make changes to docs, you can test they still build locally too.
|
||||
|
||||
```console
|
||||
(.venv)$ pip install --group docs
|
||||
(.venv)$ pip install -e ".[d]"
|
||||
(.venv)$ sphinx-build -a -b html -W docs/ docs/_build/
|
||||
```
|
||||
|
||||
## Hygiene
|
||||
|
||||
If you're fixing a bug, add a test. Run it first to confirm it fails, then fix the bug,
|
||||
and run the test again to confirm it's really fixed.
|
||||
|
||||
If adding a new feature, add a test. In fact, always add a test. If adding a large
|
||||
feature, please first open an issue to discuss it beforehand.
|
||||
|
||||
## Finally
|
||||
|
||||
Thanks again for your interest in improving the project! You're taking action when most
|
||||
people decide to sit and watch.
|
||||
Reference in New Issue
Block a user