Skip to main content

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.0 for single packages, package-v1.0.0 for 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 readiness
  • relkit bump <major|minor|patch> [--package NAME] - Atomic version bump with changelog, commit, and tag
  • relkit release [--package NAME] - Complete release workflow
  • relkit version - Show current version

Build & Publish

  • relkit build [--package NAME] - Build distribution packages
  • relkit test - Test built packages
  • relkit publish [--package NAME] - Publish to PyPI (requires confirmation)

Development Tools

  • relkit check <all|git|changelog|format|lint|types> [--fix] - Run quality checks
  • relkit 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 --package flag
  • Tags: v1.0.0

2. Pure Workspace

[tool.uv.workspace]
members = ["packages/*"]
# No [project] section in root
  • All commands require --package flag
  • 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-package or --package member-name
  • Tags: v2.0.0 for root, member-v1.0.0 for members

Philosophy

Explicit Over Magic

  • Workspace operations require explicit --package selection
  • 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:

  1. Updates version in pyproject.toml
  2. Updates CHANGELOG.md
  3. Commits changes
  4. Syncs lockfile if needed
  5. Creates appropriate tag
  6. 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.toml with version
  • CHANGELOG.md with 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)

Source distribution for relkit 1.5.5
File Size Uploaded
relkit-1.5.5.tar.gz 39.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for relkit 1.5.5
File Interpreter ABI Platform
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

Release history Release notifications | RSS feed

This release

1.5.5 This release

2 release files

1.5.4

2 release files

1.5.3

2 release files

1.5.2

2 release files

1.5.1

2 release files

1.5.0

2 release files

1.4.0

2 release files

1.3.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page