Convert a Repo to Use Releaser from Repo#
Follow the steps below to convert a repository to use Jupyter Releaser for releases, where maintainers make releases from the repository itself.
Prerequisites#
See checklist below for details:
Markdown changelog
Bump version configuration (if using Python), for example hatch
Add a trusted publisher to your PyPI project
If needed, access token for npm.
Checklist for Adoption#
Set up a GitHub App on your organization (or personal account for a personal project).
Disable the web hook
Enable Repository permissions > Contents > Read and write
Select “Only on this account”
Click “Create GitHub App”
Browse to the App Settings
Select “Install App” and install on all repositories
Under “General” click “Generate a private key”
Store the
APP_ID
and the private key in a secure location (Jupyter Vault if using a Jupyter Org)
Create a “release” environment on your repository and add an
APP_ID
Environment Variable andAPP_PRIVATE_KEY
secret. The environment should be enabled for “Protected branches only”.Configure Rulesets for the repository
Set up branch protection (with default rules) on publication branches
Remove global tag protection.
Add a branch Ruleset for all branches
Allow the GitHub App to bypass protections
Set up Pull Request and Required Checks
Add a tags Ruleset for all tags
Allow the GitHub App to bypass protections
Copy
prep-release.yml
andpublish-release.yml
(or onlyfull-release.yml
) from the example-workflows folder in this repository.Set up PyPI:
Set up your PyPI project by adding a trusted publisher
if you use the example workflows, the workflow name is
publish-release.yml
(orfull-release.yml
) and the environment should berelease
(the name of the GitHub environment).
Ensure the publish release job as
permissions
:id-token : write
(see the documentation)
If needed, add access token for npm, saved as
NPM_TOKEN
. Again this should be created using a machine account that only has publish access.Ensure that only trusted users with 2FA have admin access to the repository, since they will be able to trigger releases.
Switch to Markdown Changelog
We recommend MyST, especially if some of your docs are in reStructuredText.
Can use
pandoc -s changelog.rst -o changelog.md
and some hand edits as needed.Note that directives can still be used
Add HTML start and end comment markers to Changelog file
see example in CHANGELOG.md (view in raw mode)
# Changelog
<!-- <START NEW CHANGELOG ENTRY> -->
<!-- <END NEW CHANGELOG ENTRY> -->
We recommend using hatch for your build system and for version handling.
If previously providing
version_info
likeversion_info = (1, 7, 0, '.dev', '0')
, use a pattern like the one below in your version file:
import re
from typing import List
# Version string must appear intact for hatch versioning
__version__ = "6.16.0"
# Build up version_info tuple for backwards compatibility
pattern = r"(?P<major>\d+).(?P<minor>\d+).(?P<patch>\d+)(?P<rest>.*)"
match = re.match(pattern, __version__)
assert match is not None
parts: List[object] = [int(match[part]) for part in ["major", "minor", "patch"]]
if match["rest"]:
parts.append(match["rest"])
version_info = tuple(parts)
If you need to keep node and python versions in sync, use hatch-nodejs-version.
See nbformat for example.
Add a GitHub Actions CI step to run the
check_release
action. For example:This should be run on
push
andpull
request events. You can copy thecheck-release.yml
from this repo as an example.
- name: Check Release
uses: jupyter-server/jupyter_releaser/.github/actions/check-release@v2
with:
token: ${{ secrets.GITHUB_TOKEN }}
If you would like the release assets to be uploaded as artifacts, add the following step after the
check_release
action:
- name: Upload Distributions
uses: actions/upload-artifact@v4
with:
name: dist-${{ github.run_number }}
path: .jupyter_releaser_checkout/dist
Add a workflow that uses the
enforce-label
action fromjupyterlab/maintainer-tools
to ensure that all PRs have on of the triage labels used to categorize the changelog.
name: Enforce PR label
on:
pull_request:
types: [labeled, unlabeled, opened, edited, synchronize]
jobs:
enforce-label:
runs-on: ubuntu-latest
permissions:
pull-requests: write
steps:
- name: enforce-triage-label
uses: jupyterlab/maintainer-tools/.github/actions/enforce-label@v1
Update or add
RELEASE.md
that describes the onboarding and release process, e.g. jupyter_server.Optionally add configuration to the repository if non-standard options or hooks are needed.
If desired, add
check_release
job, changelog, andhatch
support to other active release branches
Initial Release Workflow#
Try out the
Prep Release
andPublish Release
process against a fork of the target repo first so you don’t accidentally push tags and GitHub releases to the source repository. Set theTWINE_REPOSITORY_URL
environment variable tohttps://test.pypi.org/legacy/
in the “Finalize Release” action part of the workflowTry the
Publish Release
process using a prerelease version on the main repository before publishing a final version.
Backport Branches#
Create backport branches the usual way, e.g.
git checkout -b 3.0.x v3.0.1; git push origin 3.0.x
When running the
Publish Release
Workflow, an automatic PR is generated for the default branch in the target repo, positioned in the appropriate place in the changelog.