feat: implement modular capability system with automatic discovery
- 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>
This commit is contained in:
309
capabilities/release-management/docs/version_management.md
Normal file
309
capabilities/release-management/docs/version_management.md
Normal file
@@ -0,0 +1,309 @@
|
||||
# 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:
|
||||
|
||||
1. **Git Tags**: The latest tag matching `v*` pattern (e.g., `v0.7.0`)
|
||||
2. **Commits Since Tag**: Number of commits since the latest tag
|
||||
3. **Current Commit**: Short commit hash
|
||||
4. **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
|
||||
|
||||
```bash
|
||||
# Quick version check
|
||||
python -m setuptools_scm
|
||||
|
||||
# Detailed version information
|
||||
make release-status
|
||||
python release.py status
|
||||
```
|
||||
|
||||
### Access Version in Code
|
||||
|
||||
```python
|
||||
from markitect.__version__ import __version__
|
||||
print(f"MarkiTect version: {__version__}")
|
||||
```
|
||||
|
||||
## Creating Releases
|
||||
|
||||
### Release Workflow
|
||||
|
||||
1. **Ensure Clean State**:
|
||||
```bash
|
||||
git status # Should be clean
|
||||
git pull # Latest changes
|
||||
```
|
||||
|
||||
2. **Validate Release Readiness**:
|
||||
```bash
|
||||
make release-validate
|
||||
```
|
||||
|
||||
3. **Create Release**:
|
||||
```bash
|
||||
# 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](https://semver.org/):
|
||||
|
||||
- **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`:
|
||||
|
||||
```bash
|
||||
# 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`:
|
||||
|
||||
```toml
|
||||
[tool.setuptools_scm]
|
||||
write_to = "markitect/_version.py"
|
||||
```
|
||||
|
||||
### Version File Generation
|
||||
|
||||
setuptools-scm automatically generates `markitect/_version.py`:
|
||||
|
||||
```python
|
||||
# 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
|
||||
|
||||
1. **Development** happens on `main`
|
||||
2. **Release tags** created on `main` when ready
|
||||
3. **Hotfix tags** can be created on older commits if needed
|
||||
|
||||
```bash
|
||||
# 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
|
||||
|
||||
```bash
|
||||
# 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
|
||||
|
||||
1. **"No tags found"**:
|
||||
```bash
|
||||
# Create initial tag
|
||||
git tag v0.1.0
|
||||
git push origin v0.1.0
|
||||
```
|
||||
|
||||
2. **"Dirty working tree"**:
|
||||
```bash
|
||||
# Commit or stash changes
|
||||
git add . && git commit -m "Changes"
|
||||
# Or
|
||||
git stash
|
||||
```
|
||||
|
||||
3. **"Version not updating"**:
|
||||
```bash
|
||||
# Clear setuptools-scm cache
|
||||
rm -rf build/ *.egg-info/
|
||||
python -m setuptools_scm
|
||||
```
|
||||
|
||||
4. **"Import error in __version__.py"**:
|
||||
```bash
|
||||
# Rebuild package to generate _version.py
|
||||
make package
|
||||
```
|
||||
|
||||
### Debug Version Issues
|
||||
|
||||
```bash
|
||||
# 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.Z` tag 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.py`** manually (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
|
||||
|
||||
1. **Development**: Let setuptools-scm handle automatically
|
||||
2. **Pre-releases**: Use `-rc1`, `-alpha1`, `-beta1` suffixes
|
||||
3. **Releases**: Create tags only for stable releases
|
||||
4. **Hotfixes**: Tag from appropriate commit, not necessarily `main`
|
||||
|
||||
## Integration with CI/CD
|
||||
|
||||
### GitHub Actions Example
|
||||
|
||||
```yaml
|
||||
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.
|
||||
Reference in New Issue
Block a user