Version numbers communicate the state and evolution of your software to users and collaborators. Good versioning practices help others understand compatibility, track changes, and decide when to upgrade.
We recommend Semantic Versioning (SemVer) for most research software projects. A semantic version
has the format MAJOR.MINOR.PATCH (e.g., 2.4.1):
1.0.0 → 1.0.1: Fixed a bug, no API changes1.0.1 → 1.1.0: Added a new feature, existing code still works1.1.0 → 2.0.0: Changed function signatures, users need to update their codeFor development versions, append a pre-release identifier:
1.0.0-alpha.1: Early development, unstable1.0.0-beta.2: Feature-complete, testing for bugs1.0.0-rc.1: Release candidate, potentially ready for releaseNote that these are just general examples. Not every ecosystem uses the same pre-release identifiers. Always follow the general practices used in the ecosystem you’re working in!
Versions starting with 0 (e.g., 0.3.2) indicate that the software is in initial development and the API may change
at any time. Once your API stabilises, release 1.0.0.
Use Git tags to mark specific points in your repository’s history as important (typically releases):
# Create an annotated tag
git tag -a v1.2.0 -m "Release version 1.2.0"
# Push tags to remote
git push origin v1.2.0
# Or push all tags
git push origin --tags
# List all tags
git tag -l
Always use annotated tags (-a flag) for releases, as they store metadata about who created the tag and when.
v: v1.2.0 (recommended)Keep your version number in a single, authoritative location to avoid inconsistencies:
Maintain a CHANGELOG.md file to document changes between versions. Follow the
Keep a Changelog format:
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com), and this project adheres to
[Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
### Added
- New feature X
## [1.2.0] - 2024-03-15
### Added
- Feature Y for improved performance
- Support for new data format Z
### Fixed
- Bug in calculation function
## [1.1.0] - 2024-02-01
### Changed
- Improved documentation
Keep in mind that changelogs are written for humans, not machines, so they should be clear, concise, and easy to read.
## Version compatibility
### Deprecation warnings
When removing features, provide deprecation warnings for at least one minor version before removal:
```python
from deprecated import deprecated
@deprecated(version='2.0.0', reason="You should use new_function() instead.")
def old_function():
# ... existing implementation
```
### Dependency version constraints
Specify version constraints for your dependencies to ensure compatibility:
- **Python** (e.g. at least a `pyproject.toml` with dependencies and a `pylock.toml` or `uv.lock` lockfile):
```
numpy>=1.20,<2.0
pandas~=2.0.0 # Compatible with 2.0.x
```
- **R** (`DESCRIPTION`):
```
Imports:
dplyr (>= 1.0.0),
ggplot2 (>= 3.3.0)
```
## Further reading
- [Semantic Versioning specification](https://semver.org/)
- [Keep a Changelog](https://keepachangelog.com/)
- [Git tagging documentation](https://git-scm.com/book/en/v2/Git-Basics-Tagging)