Release Process¶
This document describes the complete process for making a MolPy release.
Release Goals¶
- Predictable - Releases follow a consistent process
- Documented - Users can see what changed
- Stable - Releases are well-tested
- Semantic - Version numbers convey meaning
Versioning¶
MolPy follows Semantic Versioning (SemVer):
MAJOR.MINOR.PATCH
- MAJOR - Incompatible API changes (e.g., 1.0.0 → 2.0.0)
- MINOR - New features, backwards-compatible (e.g., 1.0.0 → 1.1.0)
- PATCH - Bug fixes, backwards-compatible (e.g., 1.0.0 → 1.0.1)
Version Examples¶
0.1.0→0.2.0- Added new IO module (minor)0.2.0→0.2.1- Fixed PDB reader bug (patch)0.9.0→1.0.0- First stable release (major)1.5.0→2.0.0- Changed Frame API (major, breaking)
Pre-release Versions¶
For development versions:
1.0.0a1- Alpha release1.0.0b1- Beta release1.0.0rc1- Release candidate
Release Checklist¶
1. Pre-release Preparation¶
Code Quality: - [ ] All tests pass on all supported Python versions - [ ] Coverage meets threshold (>80%) - [ ] No critical bugs in issue tracker - [ ] Code style checks pass (Black, isort) - [ ] Type hints are complete
Documentation: - [ ] Documentation builds without errors - [ ] All examples run successfully - [ ] API documentation is up-to-date - [ ] Changelog is updated - [ ] Migration guide written (if breaking changes)
Testing:
- [ ] Run full test suite: pytest
- [ ] Test on multiple platforms (Linux, macOS, Windows)
- [ ] Test with minimum and maximum supported Python versions
- [ ] Manual testing of key workflows
- [ ] Test installation from source
2. Update Version Number¶
Update version in src/molpy/version.py:
__version__ = "0.3.0"
Update version in pyproject.toml:
[project]
name = "molcrafts-molpy"
version = "0.3.0"
3. Update Changelog¶
Update changelog/releases.md with release notes:
## [0.3.0] - 2024-01-15
### Added
- New `compute` module for molecular property calculations
- Support for XYZ trajectory files
- RDF calculation in `compute.rdkit`
### Changed
- Improved PDB reader performance by 2x
- Updated `Frame.merge()` to preserve metadata
### Fixed
- Fixed atom indexing bug in topology detection
- Corrected periodic boundary handling in packmol
### Deprecated
- `old_function()` is deprecated, use `new_function()` instead
### Removed
- Removed deprecated `legacy_module`
### Breaking Changes
- `Frame.blocks()` now returns a list instead of dict
- Migration: Use `Frame.block_names()` for names
4. Create Release Branch¶
# Ensure main is up-to-date
git checkout main
git pull upstream main
# Create release branch
git checkout -b release/v0.3.0
# Commit version changes
git add src/molpy/version.py pyproject.toml changelog/releases.md
git commit -m "[release] prepare v0.3.0"
# Push release branch
git push origin release/v0.3.0
5. Final Testing¶
Run comprehensive tests on the release branch:
# Full test suite
pytest -v
# Test with coverage
pytest --cov=molpy --cov-report=html tests/
# Test documentation build
mkdocs build
# Test package build
python -m build
# Test installation from built package
pip install dist/molcrafts_molpy-0.3.0-py3-none-any.whl
6. Create Pull Request¶
Create a PR from release/v0.3.0 to main:
- Title: "Release v0.3.0"
- Description: Include changelog highlights
- Labels:
release
Wait for: - [ ] CI checks to pass - [ ] Code review approval - [ ] Final testing confirmation
7. Merge and Tag¶
Once PR is approved:
# Merge to main
git checkout main
git merge release/v0.3.0
# Create annotated tag
git tag -a v0.3.0 -m "Release v0.3.0"
# Push to GitHub
git push upstream main --tags
8. Build and Publish¶
Build the package:
# Clean previous builds
rm -rf dist/ build/ *.egg-info
# Build source distribution and wheel
python -m build
# Verify contents
tar -tzf dist/molcrafts-molpy-0.3.0.tar.gz
unzip -l dist/molcrafts_molpy-0.3.0-py3-none-any.whl
Publish to PyPI:
# Upload to Test PyPI first
python -m twine upload --repository testpypi dist/*
# Test installation from Test PyPI
pip install --index-url https://test.pypi.org/simple/ molcrafts-molpy
# If successful, upload to PyPI
python -m twine upload dist/*
9. Create GitHub Release¶
On GitHub:
- Go to Releases
- Click "Draft a new release"
- Select tag
v0.3.0 - Set title: "MolPy v0.3.0"
- Copy changelog content to description
- Attach built distributions (optional)
- Click "Publish release"
10. Post-release Tasks¶
Update Documentation: - [ ] Verify docs deployed to GitHub Pages - [ ] Update README if needed - [ ] Announce on GitHub Discussions
Prepare for Next Release:
- [ ] Create new "Unreleased" section in changelog
- [ ] Update version to next development version (e.g., 0.4.0-dev)
- [ ] Create milestone for next release
Communication: - [ ] Announce release on GitHub Discussions - [ ] Update project README with new version - [ ] Notify downstream projects of breaking changes
Release Schedule¶
MolPy follows a time-based release schedule:
- Minor releases - Every 2-3 months
- Patch releases - As needed for critical bugs
- Major releases - When significant breaking changes accumulate
Breaking Changes¶
When introducing breaking changes:
1. Deprecation Period¶
Deprecate old API before removing:
import warnings
def old_function():
"""Old function (deprecated).
.. deprecated:: 0.3.0
Use :func:`new_function` instead.
"""
warnings.warn(
"old_function is deprecated, use new_function instead",
DeprecationWarning,
stacklevel=2
)
return new_function()
2. Migration Guide¶
Provide clear migration instructions:
## Migration Guide: v0.2 → v0.3
### Frame.blocks() returns list instead of dict
**Before (v0.2):**
```python
blocks = frame.blocks()
for name, block in blocks.items():
print(name, len(block))
After (v0.3):
names = frame.block_names()
for name in names:
block = frame[name]
print(name, len(block))
### 3. Changelog Highlighting
Clearly mark breaking changes:
```markdown
### Breaking Changes
⚠️ **Frame.blocks() API changed**
- `Frame.blocks()` now returns `list[str]` instead of `dict[str, Block]`
- Use `Frame.block_names()` for block names
- Use `Frame[name]` to access individual blocks
- See migration guide for details
Hotfix Process¶
For critical bugs in released versions:
# Create hotfix branch from tag
git checkout -b hotfix/v0.3.1 v0.3.0
# Fix the bug
# ... make changes ...
# Update version to 0.3.1
# Update changelog
# Commit and tag
git commit -am "[hotfix] fix critical bug"
git tag -a v0.3.1 -m "Hotfix v0.3.1"
# Merge to main
git checkout main
git merge hotfix/v0.3.1
# Push
git push upstream main --tags
CI/CD Integration¶
Automated Checks¶
On every push and PR: - Run full test suite - Check code style (Black, isort) - Verify documentation builds - Check coverage threshold
Automated Publishing¶
On tag push (e.g., v0.3.0):
- Build package
- Run tests
- Publish to PyPI (if tests pass)
- Deploy documentation to GitHub Pages
GitHub Actions Example¶
name: Release
on:
push:
tags:
- 'v*'
jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: '3.12'
- name: Install dependencies
run: |
pip install build twine
- name: Run tests
run: |
pip install -e ".[dev]"
pytest
- name: Build package
run: python -m build
- name: Publish to PyPI
env:
TWINE_USERNAME: __token__
TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }}
run: twine upload dist/*
Version Support¶
Supported Versions¶
- Latest minor version - Full support
- Previous minor version - Security fixes only
- Older versions - No support
Example:
- Current: 0.3.x - Full support
- Previous: 0.2.x - Security fixes
- Older: 0.1.x - No support
Python Version Support¶
Follow NEP 29:
- Support Python versions released in last 42 months
- Drop support with 6 months notice
Troubleshooting¶
Build Fails¶
Issue: Package build fails
Solutions:
- Check pyproject.toml syntax
- Verify all files are included in MANIFEST.in
- Clean build artifacts: rm -rf dist/ build/
Tests Fail on CI¶
Issue: Tests pass locally but fail on CI
Solutions:
- Check Python version matches
- Verify all dependencies in pyproject.toml
- Check for platform-specific issues
PyPI Upload Fails¶
Issue: Upload to PyPI fails
Solutions: - Verify PyPI token is correct - Check version doesn't already exist - Ensure package name is available
Summary Checklist¶
Before releasing:
- All tests pass
- Documentation builds
- Changelog updated
- Version numbers updated
- Migration guide written (if breaking changes)
- Release branch created
- PR reviewed and approved
- Tag created
- Package built and tested
- Published to PyPI
- GitHub release created
- Documentation deployed
- Announcement posted