This document describes the release process for nwp500-python, including code quality checks, formatting, and publishing.
Install development dependencies:
pip install -e ".[dev]"
# or
make install-devFor a full automated release check and build:
make releaseThis will:
- Run linting checks
- Verify code formatting
- Run all tests
- Clean build artifacts
- Build distribution packages
Format all code with ruff:
make format
# or
tox -e formatThis will:
- Automatically fix linting issues where possible
- Format code to comply with PEP 8 and project standards
- Sort imports according to isort rules
Check code without making changes:
make lint
# or
tox -e lintCheck that code is properly formatted:
make format-checkRun the test suite:
make test
# or
pytestRun tests with coverage report:
make test-covRun all quality checks at once:
make check-releaseThis runs:
- Linting checks
- Format verification
- Full test suite
IMPORTANT: This project uses setuptools_scm to manage versions from git tags.
The version is NOT stored in any Python files or config files.
DO NOT edit the version field in setup.cfg's [pyscaffold] section!
That field stores the PyScaffold tool version (4.6), not the package version.
- Update
CHANGELOG.rstwith changes for this release:
# Get current date
date +"%Y-%m-%d"
# Edit CHANGELOG.rst and add a new section:
# Version X.Y.Z (YYYY-MM-DD)
# ==========================- Commit the changelog:
git add CHANGELOG.rst
git commit -m "Update changelog for vX.Y.Z"- Use the version bump script to create a git tag:
# For a patch release (X.Y.Z -> X.Y.Z+1)
make version-bump BUMP=patch
# For a minor release (X.Y.Z -> X.Y+1.0)
make version-bump BUMP=minor
# For a major release (X.Y.Z -> X+1.0.0)
make version-bump BUMP=major
# Or specify an explicit version
make version-bump BUMP=3.1.5The script will:
- Get the current version from git tags
- Calculate the new version
- Validate the version progression (prevents large jumps)
- Create a git tag (e.g.,
v3.1.5) - Display next steps
- Push the tag to trigger the release:
git push origin vX.Y.ZIf you need to create a tag manually:
git tag -a vX.Y.Z -m "Release version X.Y.Z"
git push origin vX.Y.ZWarning: Manual tagging bypasses validation checks. Use the version bump script instead.
Clean and build distribution packages:
make buildThis creates:
dist/nwp500_python-X.Y.Z.tar.gz(source distribution)dist/nwp500_python-X.Y.Z-py3-none-any.whl(wheel)
Test the distribution on TestPyPI first:
make publish-testOr manually:
python -m twine upload --repository testpypi dist/*Test installation from TestPyPI:
pip install --index-url https://test.pypi.org/simple/ nwp500-pythonOnce verified on TestPyPI, publish to production PyPI:
make publishOr manually:
python -m twine upload dist/*Note: If you used the version bump script, the tag is already created. Just push it:
git push origin vX.Y.ZIf you created a tag manually, push it now.
You can also use tox directly for all steps:
# Run lint checks
tox -e lint
# Format code
tox -e format
# Run tests
tox
# Build package
tox -e build
# Clean artifacts
tox -e cleanRuff is configured in pyproject.toml with the following rules:
- Line length: 88 characters (Black-compatible)
- Target version: Python 3.7+
- Enabled rules:
E,W: pycodestyle errors and warningsF: PyflakesI: isort (import sorting)UP: pyupgrade (Python version upgrades)B: flake8-bugbear (common bugs)C4: flake8-comprehensionsSIM: flake8-simplify
# Check specific file
ruff check src/nwp500/auth.py
# Format specific file
ruff format src/nwp500/auth.py
# Check and fix specific directory
ruff check --fix src/nwp500/If you encounter linting errors:
- Try auto-fixing:
make format - Review remaining errors:
make lint - Manually fix any errors that can't be auto-fixed
- Re-run checks:
make check-release
If tests fail:
- Review the test output
- Fix the issues in the code
- Re-run tests:
make test - Ensure all tests pass before release
If build fails:
- Clean build artifacts:
make clean - Verify dependencies are installed:
pip install -e ".[dev]" - Try building again:
make build
Before releasing, ensure:
- All code is formatted:
make format - Linting passes:
make lint - All tests pass:
make test - Version configuration is valid:
make validate-version - Changelog is updated
- Version is bumped appropriately using
make version-bump - Documentation is up to date
- Examples work correctly
- Build succeeds:
make build - TestPyPI upload works:
make publish-test
Set these environment variables for Twine:
export TWINE_USERNAME=__token__
export TWINE_PASSWORD=pypi-your-api-token-hereOr use a .pypirc file:
[distutils]
index-servers =
pypi
testpypi
[pypi]
username = __token__
password = pypi-your-api-token
[testpypi]
repository = https://test.pypi.org/legacy/
username = __token__
password = pypi-your-test-api-tokenConsider setting up CI/CD to automatically:
- Run linting on pull requests
- Run tests on multiple Python versions
- Check code formatting
- Build and verify distributions
- Publish releases automatically on git tags
Example GitHub Actions workflow could run:
- name: Install dependencies
run: pip install -e ".[dev]"
- name: Lint with ruff
run: make lint
- name: Check formatting
run: make format-check
- name: Run tests
run: make test
- name: Build
run: make build| Command | Description |
|---|---|
make version-bump |
Bump version (requires BUMP=patch/minor/major/X.Y.Z) |
make help |
Show all available commands |
make install-dev |
Install with dev dependencies |
make format |
Format code with ruff |
make lint |
Check code with ruff |
make test |
Run tests |
make check-release |
Run all pre-release checks |
make release |
Full release build process |
make build |
Build distribution packages |
make publish-test |
Upload to TestPyPI |
make publish |
Upload to PyPI |
make clean |
Remove build artifacts |