- Move release management to capabilities/release-management/ with complete Makefile - Create automatic capability discovery system in scripts/capability_discovery.mk - Add capability-manager subagent for managing modular architecture - Implement target delegation system enabling capability-name-target patterns - Create Makefiles for markitect-content, markitect-utils, and issue-facade capabilities - Remove legacy release management code and documentation from main project - Update main Makefile to use capability discovery and delegation - Add comprehensive capability status, help, and management targets The capability system provides: - Automatic discovery of capabilities with Makefiles - Clean target delegation without conflicts - Modular architecture following established patterns - Comprehensive help and status reporting - Zero-conflict capability integration 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
7.2 KiB
Version Management Guide
MarkiTect uses setuptools-scm for automatic version management based on git tags. This eliminates manual version bumping and ensures versions are always in sync with git history.
How It Works
Version Calculation
setuptools-scm automatically determines the version based on:
- Git Tags: The latest tag matching
v*pattern (e.g.,v0.7.0) - Commits Since Tag: Number of commits since the latest tag
- Current Commit: Short commit hash
- Dirty State: Whether there are uncommitted changes
Version Examples
| Git State | Version Output |
|---|---|
v0.7.0 tag (clean) |
0.7.0 |
v0.7.0 + 3 commits |
0.7.1.dev3+g1a2b3c4d |
v0.7.0 + 3 commits + dirty |
0.7.1.dev3+g1a2b3c4d.d20251108 |
| No tags + 10 commits | 0.1.dev10+g5e6f7g8h |
Version Commands
Check Current Version
# Quick version check
python -m setuptools_scm
# Detailed version information
make release-status
python release.py status
Access Version in Code
from markitect.__version__ import __version__
print(f"MarkiTect version: {__version__}")
Creating Releases
Release Workflow
-
Ensure Clean State:
git status # Should be clean git pull # Latest changes -
Validate Release Readiness:
make release-validate -
Create Release:
# Standard release make release-publish VERSION=0.8.0 # Release with Gitea publishing make release-publish-gitea VERSION=0.8.0
Version Naming Conventions
Follow Semantic Versioning:
- Major Version (
1.0.0): Breaking changes - Minor Version (
0.8.0): New features (backward compatible) - Patch Version (
0.7.1): Bug fixes (backward compatible) - Pre-release (
0.8.0-rc1): Release candidates - Development (
0.8.1.dev3+hash): Automatic between releases
Git Tag Format
Always use the format vX.Y.Z:
# Correct
git tag v0.8.0
git tag v1.0.0-rc1
# Incorrect
git tag 0.8.0 # Missing 'v' prefix
git tag version-0.8.0 # Wrong format
Development Versions
Understanding Development Versions
Between releases, setuptools-scm generates development versions:
0.7.1.dev3+g1a2b3c4d.d20251108
│ │ │ │ │ │
│ │ │ │ │ └── Date (dirty state)
│ │ │ │ └─────────── Commit hash
│ │ │ └───────────── Commits since tag
│ │ └──────────────── Dev marker
│ └─────────────────── Next version
└─────────────────────── Base version
Working with Development Versions
Development versions are automatically:
- Sorted correctly by pip (dev versions < release versions)
- Excluded from releases (only tagged versions are released)
- Unique (each commit has a different version)
Configuration
setuptools-scm Configuration
Configuration in pyproject.toml:
[tool.setuptools_scm]
write_to = "markitect/_version.py"
Version File Generation
setuptools-scm automatically generates markitect/_version.py:
# Auto-generated - do not edit
__version__ = "0.7.1.dev3+g1a2b3c4d"
__version_tuple__ = (0, 7, 1, 'dev3', 'g1a2b3c4d')
This file is:
- ✅ Auto-generated during package builds
- ✅ Added to .gitignore (never committed)
- ✅ Available at runtime for version checks
Release Branches
Main Branch Strategy
MarkiTect uses a simple branching strategy:
main: Primary development branch- Tags: Mark release points (
v0.7.0,v0.8.0) - Feature branches: Merged via pull requests
Release Process
- Development happens on
main - Release tags created on
mainwhen ready - Hotfix tags can be created on older commits if needed
# Standard release from main
git checkout main
git pull
make release-publish-gitea VERSION=0.8.0
# Hotfix release from older commit
git checkout v0.7.0
git cherry-pick <hotfix-commit>
git tag v0.7.1
git push origin v0.7.1
Package Building
Build Commands
# Build packages with version info
make package
# Build using release script
make release-build
python release.py build
# Manual build
python -m build
Build Output
Packages are built to dist/ directory:
- Wheel (
.whl): Binary distribution - Source Distribution (
.tar.gz): Source code
Version in Package Names
setuptools-scm ensures package names include correct versions:
dist/
├── markitect-0.8.0-py3-none-any.whl # Release
├── markitect-0.8.0.tar.gz # Release
├── markitect-0.8.1.dev3+hash-py3-none-any.whl # Development
└── markitect-0.8.1.dev3+hash.tar.gz # Development
Troubleshooting
Common Issues
-
"No tags found":
# Create initial tag git tag v0.1.0 git push origin v0.1.0 -
"Dirty working tree":
# Commit or stash changes git add . && git commit -m "Changes" # Or git stash -
"Version not updating":
# Clear setuptools-scm cache rm -rf build/ *.egg-info/ python -m setuptools_scm -
"Import error in version.py":
# Rebuild package to generate _version.py make package
Debug Version Issues
# Verbose setuptools-scm output
python -m setuptools_scm --debug
# Check git state
git describe --tags --dirty --always
# Verify tag format
git tag --list | grep "^v"
Best Practices
Do's ✅
- Always use
vX.Y.Ztag format - Create annotated tags:
git tag -a v0.8.0 -m "Release 0.8.0" - Push tags to origin:
git push origin v0.8.0 - Keep clean working tree for releases
- Follow semantic versioning
- Test version detection before releasing
Don'ts ❌
- Don't edit
_version.pymanually (auto-generated) - Don't commit version numbers to source files
- Don't use non-standard tag formats
- Don't create releases from dirty tree
- Don't delete old tags (breaks version history)
Version Strategy
- Development: Let setuptools-scm handle automatically
- Pre-releases: Use
-rc1,-alpha1,-beta1suffixes - Releases: Create tags only for stable releases
- Hotfixes: Tag from appropriate commit, not necessarily
main
Integration with CI/CD
GitHub Actions Example
name: Release
on:
push:
tags: ['v*']
jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0 # Important for setuptools-scm
- name: Build packages
run: make package
- name: Upload to Gitea
env:
GITEA_API_TOKEN: ${{ secrets.GITEA_API_TOKEN }}
run: python release.py upload
Key Points
fetch-depth: 0: Required for setuptools-scm to access git history- Environment variables: Use secrets for API tokens
- Tag-based triggers: Only build releases for version tags
This version management system provides automatic, reliable, and traceable versioning that scales with your development workflow.