Release and versioning policy#
This page defines how HydroModPy is versioned, tagged, branched, and published. It is the contract between maintainers and users about what a version number means and how a release reaches PyPI.
Version syntax#
HydroModPy uses Semantic Versioning 2.0.0 for release meaning and PEP 440 for Python-compatible version strings.
Final releases use:
MAJOR.MINOR.PATCH
Pre-releases use:
MAJOR.MINOR.PATCHaN
MAJOR.MINOR.PATCHbN
MAJOR.MINOR.PATCHrcN
Git tags always add the leading v:
v1.1.0
v1.1.1
v2.0.0a1
v2.0.0b1
v2.0.0rc1
v2.0.0
Do not create tags such as release-v2, v2-beta, v2.0-alpha,
or pre-refonte-v2. Historical non-conforming tags remain as archive
markers, but new release tags must follow the format above.
Version meaning#
Given a final version MAJOR.MINOR.PATCH:
MAJOR (
X.0.0): incompatible public contract change. Examples: removed or renamed public API, CLI verb, config field, storage format, solver behavior, or workflow behavior that requires user migration.MINOR (
X.Y.0): backward-compatible feature addition. Examples: new solver backend, optional config field with a default, new CLI verb, new public function, or new report output that does not break existing users.PATCH (
X.Y.Z): backward-compatible bug fix only. No new public API, no config schema change, no behavior change that users must adapt to.
HydroModPy does not keep compatibility shims for removed public contracts.
If a change requires users to edit their code, TOML config, CLI calls, or
stored project layout, it is a MAJOR change unless it happens before a
stable release in an a, b, or rc pre-release.
Pre-release stages#
Use pre-releases when code should be published for testing before the contract is final.
Stage |
Example |
Use |
|---|---|---|
Alpha |
|
Public testing while the API, config, storage, or behavior can still change. |
Beta |
|
Feature-complete release line. The public contract should change only when needed to fix a release blocker. |
Release candidate |
|
Candidate for the final release. Only release-blocking fixes should land. |
Final |
|
Stable release recommended to normal users. |
Python installers ignore pre-releases by default unless the user asks for them explicitly:
pip install hydromodpy
pip install --pre hydromodpy
pip install hydromodpy==2.0.0b1
Branch model#
Branches are moving development lines. Tags are immutable release points. Users should identify released code through tags and GitHub Releases, not through branch names.
Long-lived branches:
Branch |
Role |
|---|---|
|
Current v2 line and future stable default branch. During the v2
transition it may carry |
|
Active integration branch for the next release line. |
|
Frozen v1.0.0 source and documentation line. It is kept for users who still need v1, but it is not actively maintained. |
|
Optional maintenance branch for |
Short-lived branches:
Branch |
Role |
|---|---|
|
Feature work. |
|
Bug fix work. |
|
Documentation-only work. |
|
Stabilization branch for |
|
Temporary branch for a single urgent patch release. |
Do not name long-lived branches v1 or v2. Use archive-v1 for
the frozen v1 branch, maint/1.x only for active maintenance, and tags
such as v1.0.0 or v2.0.0a1 for exact releases.
Example: archiving v1 while preparing v2#
When main is created from the current v2 development line, keep the v1
source explicit but frozen:
main current v2 line, first published as v2.0.0a1
dev active integration for the next v2 pre-release
archive-v1 frozen v1.0.0 source and docs with an upgrade warning
release/2.0 temporary v2 stabilization branch
Use maint/1.x only if the project decides to actively maintain v1
again. A frozen branch is an archive branch, not a maintenance branch.
Typical tags during the v2 transition:
v1.0.0 final v1 release kept on archive-v1
v2.0.0a1 first public v2 alpha from main
v2.0.0b1 v2 beta
v2.0.0rc1 v2 release candidate
v2.0.0 final v2 release on main
Archive branch warning#
The archive-v1 documentation must show a visible warning on the home
page, install page, and contributor page:
v1 is frozen and no longer updated.
Existing v1 users can keep using tagged releases such as
v1.0.0.New work should move to
mainand the v2 documentation.The warning should link to
https://hydromodpy-docs.readthedocs.io/en/main/.
Tagging discipline#
Every published release has exactly one Git tag.
Final tags use
vX.Y.Z.Pre-release tags use
vX.Y.ZaN,vX.Y.ZbN, orvX.Y.ZrcN.Tags are immutable. A botched release is fixed by tagging a new release, never by force-moving an existing tag.
Prefer annotated tags (
git tag -a). Use signed tags when maintainer keys are available.The tag must match the package version exactly after removing the leading
v.
The following files must agree before a tag is pushed:
pyproject.toml
hydromodpy/core/version.py
CHANGELOG.md
Git tag
pyproject.toml is the package metadata source.
hydromodpy/core/version.py contains the source-checkout fallback and
must be kept in sync while the project uses a static package version.
Release flow#
Decide the target version from the change:
bugfix on the stable line:
PATCHcompatible feature:
MINORbreaking public contract change:
MAJORunfinished public testing: add
aN,bN, orrcN
Create the correct branch:
normal work from
devcurrent v2 release work from
mainorrelease/2.0frozen v1 documentation from
archive-v1only for legacy warningsactive v1 maintenance from
maint/1.xonly if maintenance resumesstabilization from
release/X.Y
Update the version in
pyproject.tomlandhydromodpy/core/version.py.Move
CHANGELOG.mdcontent from[Unreleased]to a section named:## [vX.Y.Z] - YYYY-MM-DD ## [vX.Y.ZaN] - YYYY-MM-DD ## [vX.Y.ZbN] - YYYY-MM-DD ## [vX.Y.ZrcN] - YYYY-MM-DD
Run the required quality checks for the release branch. At minimum, run
ruff check --fix .andruff format .before the release commit. Run targeted tests or docs builds according to the changed area.Commit the release preparation with a Conventional Commit subject, for example:
chore(release): prepare v2.0.0b1
Tag the release commit:
git tag -a v2.0.0b1 -m "v2.0.0b1" git push origin v2.0.0b1
The
publish.ymlworkflow builds the distributions, verifies that the tag matchespyproject.toml, uploads to PyPI, and creates the GitHub Release. Tags containingaN,bN, orrcNmust be marked as GitHub pre-releases.After a final release, merge the release branch back into
mainanddev. After a maintenance release, merge the maintenance fix forward intodevif the bug still exists there.
Hotfix policy#
A regression in vX.Y.Z is fixed by branching from the released tag,
applying the minimal patch, and releasing vX.Y.(Z+1). Hotfixes do not
carry new features.
For a maintained older major line, branch from the relevant maintenance
branch. Do not use archive-v1 for hotfix work unless it has first been
promoted back to an active maintenance branch.
maint/1.x -> hotfix/1.0.4 -> v1.0.4
Changelog policy#
CHANGELOG.md follows Keep a Changelog categories. Use:
Addedfor new features.Changedfor behavior or public contract updates.Deprecatedonly for announced future removal. Do not add compatibility shims solely for deprecation.Removedfor deleted features or files.Fixedfor bug fixes.Securityfor security improvements.
Each published tag must have a matching changelog section. Pre-releases get their own sections because users may install and cite them.
See also#
Changelog for shipped releases.
Contribute for contributor setup and pull request workflow.
VERSIONING.mdat the repository root for the short maintainer checklist.SECURITY.mdat the repository root for supported security versions when that file exists.