relkit: Opinionated Release Toolkit for Modern Python Projects
"This Way or No Way" - A strict, opinionated release workflow enforcer for Python projects using uv.
Features
- 🚀 Workspace Support: Per-package versioning in monorepos
- 🔒 Atomic Releases: Version, changelog, commit, tag, and push in one command
- 🎯 Explicit Operations: No magic, every action is intentional
- ✅ Pre-flight Checks: Validates everything before release
- 📝 Changelog Enforcement: Required for all releases
- 🏷️ Smart Tagging:
v1.0.0for single packages,package-v1.0.0for workspaces - 🚫 Safety First: Blocks dangerous operations before they happen
Installation
# Add to your project as a dev dependency
uv add --dev relkit
# Or install from GitHub
uv add --dev git+https://github.com/angelsen/relkit.git
Quick Start
Single Package Projects
# Initialize git hooks (recommended)
relkit init-hooks
# Check project status
relkit status
# Make changes, update CHANGELOG.md, then bump version
relkit bump patch # or minor/major
# Full release workflow
relkit release
Workspace Projects
# Show workspace overview
relkit status
# Work with specific packages (--package is required)
relkit status --package termtap
relkit bump patch --package termtap
relkit build --package termtap
relkit publish --package termtap
# Package-specific tags are created automatically
# e.g., termtap-v1.0.0, webtap-v2.1.0
Commands
Core Commands
relkit status [--package NAME]- Show release readinessrelkit bump <major|minor|patch> [--package NAME]- Atomic version bump with changelog, commit, and tagrelkit release [--package NAME]- Complete release workflowrelkit version- Show current version
Build & Publish
relkit build [--package NAME]- Build distribution packagesrelkit test- Test built packagesrelkit publish [--package NAME]- Publish to PyPI (requires confirmation)
Development Tools
relkit check <all|git|changelog|format|lint|types> [--fix]- Run quality checksrelkit init-hooks- Install git hooks
Git Wrappers
relkit git <command>- Pass-through to git with awareness
Workspace Support
Relkit seamlessly handles three project types:
1. Single Package (default)
[project]
name = "mypackage"
version = "1.0.0"
- Commands work without
--packageflag - Tags:
v1.0.0
2. Pure Workspace
[tool.uv.workspace]
members = ["packages/*"]
# No [project] section in root
- All commands require
--packageflag - Tags:
package-v1.0.0
3. Hybrid Workspace
[project]
name = "root-package"
version = "2.0.0"
[tool.uv.workspace]
members = ["packages/*"]
- Root package and workspace members
- Use
--package root-packageor--package member-name - Tags:
v2.0.0for root,member-v1.0.0for members
Philosophy
Explicit Over Magic
- Workspace operations require explicit
--packageselection - No automatic dependency cascades
- Clear errors when package selection is ambiguous
Separation of Concerns
- uv: Manages dependencies and workspace setup
- relkit: Manages releases and versioning
- git: Version control (wrapped for safety)
Atomic Operations
The bump command is atomic - it handles everything in one transaction:
- Updates version in pyproject.toml
- Updates CHANGELOG.md
- Commits changes
- Syncs lockfile if needed
- Creates appropriate tag
- Pushes to remote
Safety Features
Blocked Operations
❌ Direct version edits
# Editing version in pyproject.toml directly is blocked
git commit -am "bump version" # BLOCKED by pre-commit hook
❌ Manual tag creation
git tag v1.0.0 # BLOCKED by git hook
# Tags must be created via: relkit bump
❌ Dirty working directory
# With uncommitted changes:
relkit bump patch # BLOCKED - requires clean git
Required Confirmations
- Publishing to PyPI requires explicit confirmation
- Major version bumps trigger breaking change warning
- All operations show clear next steps on failure
Configuration
Relkit reads from pyproject.toml:
[project]
name = "your-package"
version = "0.1.0" # Never edit directly!
[tool.uv.workspace]
members = ["packages/*"] # Optional workspace config
Each package maintains its own:
pyproject.tomlwith versionCHANGELOG.mdwith release notes- Git tags with appropriate naming
Error Messages
All errors are actionable:
✗ Workspace requires --package
Available packages: termtap, webtap, logtap
Next steps:
1. Specify a package: relkit bump patch --package <name>
2. Use package name from pyproject.toml [project] section
Development
# Clone repository
git clone https://github.com/angelsen/relkit.git
cd relkit
# Install in development mode
uv sync
# Run tests
uv run pytest
# Check types
uv run pyright
Contributing
This tool is intentionally opinionated. We welcome contributions that:
- Improve error messages
- Add safety checks
- Enhance workspace support
- Fix bugs
We generally reject:
- Features that add "escape hatches"
- Options to bypass safety checks
- Implicit or magical behaviors
License
MIT
Credits
Created by Fredrik Angelsen. Built with Python 3.12+ and uv.
Metadata
Release files for relkit 1.5.5
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| relkit-1.5.5.tar.gz | 39.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| relkit-1.5.5-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 93.0 kB
Release files / relkit-1.5.5.tar.gz
| Download URL | relkit-1.5.5.tar.gz |
|---|---|
| Size | 39.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
6ef7efc85ce3ff1b804c81f05b6d729ec353c86eda11bdcb4bc0e770d54130be
|
|
BLAKE2b-256 checksum How to use checksums |
9f80486484548f8934fe65300a36b6b91e9bf9789447d33735682d47fdb8f988
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.8.13
|
Release files / relkit-1.5.5-py3-none-any.whl
| Download URL | relkit-1.5.5-py3-none-any.whl |
|---|---|
| Size | 53.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
d2261424f679b64bd95d37b4062007957e6cd7dd6eb6df1ed51b30cd8668553b
|
|
BLAKE2b-256 checksum How to use checksums |
fbc256095ff0038941a2a224e8ce8508a45920d7fea1da62d5699ee7869f0556
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.8.13
|