Skip to main content

Opinionated release toolkit for modern Python projects

Project description

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.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

relkit-1.4.0.tar.gz (39.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

relkit-1.4.0-py3-none-any.whl (53.7 kB view details)

Uploaded Python 3

File details

Details for the file relkit-1.4.0.tar.gz.

File metadata

  • Download URL: relkit-1.4.0.tar.gz
  • Upload date:
  • Size: 39.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.8.9

File hashes

Hashes for relkit-1.4.0.tar.gz
Algorithm Hash digest
SHA256 e317f6b3c43a81cfb7c46c2424b38b23425cfec2e815ea68f2c576c51e6cb594
MD5 10c419bfcdf56640ed2375c840fe7649
BLAKE2b-256 961b9868a34fd164067d5824a4688a4d1148b26a03e2938ee361840f63e971f6

See more details on using hashes here.

File details

Details for the file relkit-1.4.0-py3-none-any.whl.

File metadata

  • Download URL: relkit-1.4.0-py3-none-any.whl
  • Upload date:
  • Size: 53.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.8.9

File hashes

Hashes for relkit-1.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 bcb1371ae7c93e7423d573e3268041f506036243991eec4cfaa54c4fff4692b3
MD5 b70ea527b765ef84440292574416a664
BLAKE2b-256 cc62d7b5890d578b42fc4272b10646513e10d07e41ee5581aef3a6ac42ebb47f

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page