A GitHub Action for releasing a Python project to PyPI after every relevant, merged PR.
The purpose of this action is to make project maintenance as easy as possible for PyPI-hosted projects by removing the need to decide when to release. By releasing after every relevant PR is merged, not only is the question of whether to release gone, but the overhead of remembering how to even do a release and then preparing one is also gone. It also allows for releases to occur in situations where you may not have easy access to a checkout or machine setup to make a release (e.g. merging a PR from your phone). As well, contributors will be able to benefit from their hard work much faster than having to wait for the gathering of multiple changes together into a single release.
Do note that this action is not designed to work for all projects. There are legitimate reasons to bundle multiple changes in a release. This action is specifically tailored towards smaller -- typically single-maintainer -- projects where PR merges are infrequent and the release process alone makes up a sizable amount of the cost of maintenance.
- Update the version number according to a label on the merged PR
- Update the changelog based on the commit message
- Commit the above updates
- Build sdist and wheels
- Upload to PyPI
- Create a release on GitHub
Due to the fact that the action commits back to the repository you cannot have required status checks on PRs as that prevents direct commits from non-admins.
release:
needs: [test, lint]
if: github.event_name == 'pull_request' && github.ref == 'refs/heads/master' && github.event.action == 'closed' && github.event.pull_request.merged
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: brettcannon/release-often@v1
with:
changelog-path: doc/CHANGELOG.rst
pypi-token: ${{ secrets.PYPI_TOKEN }}
github-token: ${{ secret.GITHUB_TOKEN }}
Required: The path to the changelog file. Paths must end in one of the following extensions to denote the file format:
.md
.rst
Leaving this input out will disable automatic changelog updating.
The PyPI API token for this project. It is strongly suggested that you create a token scoped to just this project.
Leaving this input out will disable uploading to PyPI.
Required: The GitHub access token (i.e. ${{ secrets.GITHUB_TOKEN }}
). This allows for committing changes back to the repository.
Leaving this input out will disable committing any changes made and creating a release.
Based on which of the following labels are applied to a PR, update the version number:
impact:breaking
to bump the major versionimpact:feature
to bump the minor versionimpact:bugfix
to bump the micro versionimpact:post-release
to bump thepost
versionimpact:project
to make no change
Input:
- build tool
Supported build tools:
- poetry
- flit
The first line of the commit message is used as the entry in the changelog for the change. The PR and the author of the change are mentioned as part of the changelog entry.
Input:
- Path to changelog file
Supported changelog formats are:
.md
.rst
Build the project's release artifacts.
- Build sdist and wheel via pep517
Once the above changes are made and the build artifacts can be successfully built, commit the changes that were made.
- Allow for specifying the author details?
With the checkout and repository in the appropriate state for release, the code can now be built and pushed to PyPI.
Input:
- PyPI token
- Upload via twine
Finally, when everything is live, create a release on GitHub to both tag the release in the repository and store the artifacts uploaded to PyPI. The name of the release is the version prepended by v
and the body of the release is the changelog entry.
- Upload release artifacts
- Customization of the release name?