research-software-practices

Versioning

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.

Semantic Versioning

We recommend Semantic Versioning (SemVer) for most research software projects. A semantic version has the format MAJOR.MINOR.PATCH (e.g., 2.4.1):

Examples

Pre-release versions

For development versions, append a pre-release identifier:

Note 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!

The 0.x.y convention

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.

Version control systems

Git tags

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.

Tag naming conventions

Version metadata in code

Keep your version number in a single, authoritative location to avoid inconsistencies:

Changelog management

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)