Use one copy per release (e.g. tick the boxes in a tracking issue or draft PR).
Version referenced below as X.Y[.Z] - replace with the real version throughout.
- Create / fast-forward release branch:
releases/X.Yoffmain. - All release-prep commits land on
releases/X.Y(never directly onmainduring the freeze - commits are usually halted tomainuntil the release branch is cut, after which the release branch is merged back intomainand development resumes).
- Bump
__version__inscenedetect/__init__.py. - Bump
ProductVersioninpackaging/windows/installer/PySceneDetect.aip(must match__version__-scripts/pre_release.py --releaseasserts this). - No
-dev/ pre-release suffix on the version string for a final release.
Note:
setup.cfgreads the package version dynamically viaversion = attr: scenedetect.__version__, andpyproject.tomldoes not declare aversionfield. The single source of truth isscenedetect/__init__.py; the.aipis the only other place to keep in sync.
- Docstrings / API docs reflect any signature changes (
cd docs/ && make htmlbuilds clean). -
docs/api/migration_guide.rstupdated if any public API changed. - Docstring examples still run (nothing references removed symbols).
-
website/pages/changelog.md: rename the bottom Development section toX.Y (YYYY-MM-DD)and add a fresh empty Development section below it for post-release work. - Changelog entry covers: new features, breaking changes, bug fixes, known issues.
-
website/pages/download.mdupdated with the new version / installer link. - Any other version-stamped pages updated (
supporting.md,cli.mdif commands changed).
- Unit tests green locally and in CI:
pytest -vv(should collect-m 'not release'by default). -
ruff check scenedetect/ tests/andruff format --check scenedetect/ tests/pass. - Release test suite green: tag a disposable
vX.Y.Z-release-rcor useworkflow_dispatchon.github/workflows/release-test.yml- all 4 jobs (static,release-tests,install-matrix,long-stress) green across the 3-OS × 2-Python matrix. SeeRELEASE-TEST-PLAN.mdfor what the suite covers. -
resourcesbranch has the artifacts the release tests need (goldens undertests/resources/goldens/,tests/resources/stress_15min.mp4). Re-push if any golden was regenerated. - Manual smoke: fresh venv,
pip install .(pulls opencv-python automatically) thenpip install .[pyav]; runscenedetect -i <video> detect-content list-scenes save-imagesand eyeball the output. Repeat afterpython packaging/build_headless.py && pip install .to verify the headless variant. -
pip-auditclean (or exceptions documented in the changelog).
-
python scripts/pre_release.py --releasepasses (enforces.aip↔__version__parity, writespackaging/windows/.version_info). -
pyinstaller packaging/windows/scenedetect.specproduces a workingscenedetect.exe- run it against a sample video. - Build the MSI via Advanced Installer (
packaging/windows/installer/PySceneDetect.aip); install into a clean Windows VM and run the CLI.
- Final commit on
releases/X.Y: "Release vX.Y[.Z]". - Tag
vX.Y[.Z]-releaseon that commit and push - this firesrelease-test.yml. Wait for all jobs green. - Merge
releases/X.Yintomain(fast-forward or merge commit - keep history clean). - Tag the final release
vX.Y[.Z]on the merged commit and push.
-
publish-pypi.ymlran on the tag and uploaded successfully. Verify both projects: https://pypi.org/project/scenedetect/ and https://pypi.org/project/scenedetect-headless/. - Smoke-test PyPI: in a fresh venv,
pip install scenedetect==X.Y.Z; CLI launches andpip show scenedetectlistsopencv-python. Repeat in a second venv withpip install scenedetect-headless==X.Y.Z; verify it listsopencv-python-headless. - Create GitHub Release from the
vX.Y[.Z]tag, body = changelog section, attach Windows installer MSI + portable.zip. - Deploy website:
generate-website.ymlpicks up the changelog / download page updates. - Deploy docs:
generate-docs.ymlpublishes the new version.
- On
main: bump__version__to the next dev version (e.g.X.(Y+1)-dev0orX.Y.(Z+1)-dev0), matchingpyproject.tomlandPySceneDetect.aip. - Clear / archive release-scoped tracking files (
tracking.md, any release-specific TODOs). - Announce: project site, relevant issues / discussions closed and linked to the release.
- Delete
releases/X.Ybranch once nothing else targets it.
- Branching model: work spans multiple commits on
releases/X.Y; the final one gets thevX.Y[.Z]-releasetag which gates the release-test workflow. A passing release-test is a hard prerequisite for publishing. - Version consistency is enforced in two places (
__init__.py,PySceneDetect.aip). Thestaticjob ofrelease-test.ymlchecks__init__.pyagainst the tag and verifies the changelog has a matching## PySceneDetect X.Yheading; the installer parity is checked byscripts/pre_release.py --release. - Changelog convention: the in-development section lives at the bottom of
website/pages/changelog.mdunder the "Development" heading - don't move it to the top.