Releases and Versioning¶
This page defines the release policy for rs-embed: where users should look for changes, how version numbers move, and which kinds of changes are treated as compatibility-sensitive.
Source of Truth¶
rs-embed keeps a repository-level CHANGELOG as the canonical release record.
GitHub Releases should mirror the matching changelog entry for each tagged version. This avoids a split workflow where the repository says one thing and the release page says another.
In practice:
- Update
CHANGELOG.md - Bump the package version
- Run the manual TestPyPI publish workflow for the candidate version
- Create a Git tag such as
v0.2.0 - Let the tag-triggered release workflow publish to PyPI and then create the GitHub Release from the matching
CHANGELOG.mdentry
Versioning Policy¶
The project follows Semantic Versioning, but uses a stricter interpretation than a typical early-stage research package because users depend on stable API and embedding semantics.
Patch Releases¶
Use PATCH for changes such as:
- bug fixes
- documentation-only improvements
- internal refactors that do not change public behavior
- packaging or CI fixes that do not affect runtime semantics
Example: 0.1.0 -> 0.1.1
Minor Releases¶
Use MINOR for backward-compatible feature work such as:
- adding a new model adapter
- adding a new public API that does not break existing callers
- adding new optional parameters with compatible defaults
- improving defaults without breaking existing results contracts
Example: 0.1.0 -> 0.2.0
Major Releases¶
Use MAJOR for breaking changes such as:
- removing or renaming a public API
- removing or renaming a public model ID
- changing a return type, output field, or shape contract
- changing the default semantics of an existing model in a way that can invalidate prior experiments
Example: 1.4.2 -> 2.0.0
Pre-1.0 Rule¶
The current package metadata still marks the library as alpha. Even so, breaking changes should not be hidden inside patch releases.
Before 1.0, the project should treat compatibility conservatively:
- use
PATCHonly for safe fixes - use
MINORwhen a change is user-visible, even if Python signatures stay the same - clearly call out any migration work in the changelog and GitHub Release
This means 0.y.z releases should already feel predictable to downstream users.
What Counts as a Breaking Change Here¶
For a normal Python library, breakage is often just an import or signature issue. For rs-embed, model behavior matters just as much as function signatures.
The following should be treated as compatibility-sensitive and called out explicitly:
- changing default preprocessing, normalization, or pooling for an existing model
- changing the default sensor, band order, temporal window interpretation, or compositing behavior
- changing the meaning or layout of
gridorpooledoutputs - changing model-specific defaults in a way that can alter benchmark comparability
- removing a previously documented alias or adapter
If a user could rerun the same script and get embeddings with meaningfully different semantics, that change should be treated like a breaking API change even when the call signature looks identical.
Release Checklist¶
For each package release:
- Move notable changes from
Unreleasedinto a dated version section inCHANGELOG.md - Bump
src/rs_embed/_version.py - Merge any required changelog updates before cutting the release tag
- Run
release.ymlmanually to publish the candidate build to TestPyPI - Confirm the TestPyPI smoke test can install, import, and invoke the
rs-embedCLI forrs-embed==X.Y.Z - Tag the release as
vX.Y.Z - Let GitHub Actions publish the package to PyPI and then create the GitHub Release
- If the change affects public behavior, update the relevant docs page and examples
Package Publishing¶
rs-embed publishes wheel and source distributions through PyPI Trusted Publishing, not long-lived API tokens.
Before the first package release:
- Create separate owner accounts on PyPI and TestPyPI.
- In GitHub, create repository environments named
testpypiandpypi. - Require manual approval on the
pypienvironment. Thetestpypienvironment can stay unprotected. - In PyPI Trusted Publishers, register package name
rs-embedfor repositorycybergis/rs-embed, workflow filerelease.yml, and environmentpypi. - In TestPyPI Trusted Publishers, register the same package and repository, but use environment
testpypi. - Remove any old
PYPI_API_TOKENorTEST_PYPI_API_TOKENrepository secrets if earlier experiments used token-based uploads.
After that setup:
Actions -> release -> Run workflowbuilds the current ref, uploads it to TestPyPI, and then runs a smoke test that installs the published package, importsrs_embed, and invokesrs-embed --help.- Pushing a tag like
v0.2.0runs the same build, checks that the tag matchessrc/rs_embed/_version.py, validates thatCHANGELOG.mdhas a matching version section, publishes to PyPI, and only then creates the GitHub Release from the prevalidated release notes artifact.
For a local install check against TestPyPI, use:
python -m pip install \
--index-url https://test.pypi.org/simple/ \
--extra-index-url https://pypi.org/simple/ \
rs-embed==X.Y.Z
Package versions on PyPI and TestPyPI are immutable. If a TestPyPI dry run exposed a packaging problem after upload, fix the issue and test again with a new version number rather than trying to overwrite the same release.
Pull Request Enforcement¶
GitHub Actions checks pull requests for changelog coverage.
The check passes when any one of the following is true:
CHANGELOG.mdis updated in the PR- the PR only touches docs, tests, CI, or other explicitly exempt internal files
- the PR has the
skip-changeloglabel
This keeps the default behavior strict for public changes without forcing changelog edits for every maintenance-only PR.
Where Users Should Look¶
- Repository changelog: CHANGELOG.md
- Package index: PyPI and TestPyPI
- Tagged releases: GitHub Releases
- Current package version:
src/rs_embed/_version.py