Release Process

Releases are published to PyPI automatically by the release.yml GitHub Actions workflow whenever a GitHub Release is published. Publishing uses PyPI Trusted Publishing (OIDC), so no API tokens are involved. The job runs uv build and uploads the resulting sdist and wheel.

This document covers the manual steps a maintainer performs before creating that release.

Before a MAJOR or MINOR release

  • Review deprecation notes (e.g. search the codebase for "deprecated") and remove deprecated features as appropriate.
  • Squash unreleased migrations — see below.

Squash migrations

If there is more than one unreleased migration on main, consider squashing them with squashmigrations immediately before tagging the new release. Only ever squash migrations that have never been part of a tagged release.

  • Create a squashed migration with ./manage.py squashmigrations.
  • Commit it with a message like Squash x.y.0dev migrations. This lets users running main safely upgrade.
  • Transition the squashed migration to a normal migration, per Django's migration-squashing docs:
    • Delete the migration files it replaces.
    • Update migrations that depended on the deleted ones to depend on the squashed migration instead.
    • Remove the replaces attribute from the squashed migration's Migration class (this is how Django recognises a squashed migration).
  • Commit these changes with a message like Transition squashed migration to normal migration.

Prepare the release commit

  • Choose the version number following semver. If the release contains a new migration, it must be a MAJOR.0.0 or MAJOR.MINOR.0 version.
  • Update the changelog under docs/changes/: finalise the section for this version and check that it summarises the changes since the last release.
  • Bump version in pyproject.toml.
  • Review the tested Stripe API version. The value that matters is DjstripeSettings.DEFAULT_STRIPE_API_VERSION in djstripe/settings.py — the most recent Stripe account version the maintainers have tested against.

Commit these changes (a message like Release $VERSION is conventional) and push to main.

Publish the release

  • Create the GitHub Release for the new version, tagging the release commit. Publishing it triggers release.yml, which builds and uploads to PyPI.
  • Verify the new version appears on PyPI.

Update the stable branch

Push the release to the matching stable/MAJOR.MINOR branch (e.g. stable/2.11). The documentation site builds versioned docs for each stable branch; pushing to main or a stable/* branch triggers the docs sync workflow, which rebuilds dj-stripe.dev.