Files
markitect-main/capabilities/release-management/docs/version_management.md
tegwick d0ffdc057c 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>
2025-11-09 01:29:15 +01:00

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:

  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

# 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

  1. Ensure Clean State:

    git status  # Should be clean
    git pull    # Latest changes
    
  2. Validate Release Readiness:

    make release-validate
    
  3. 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

  1. Development happens on main
  2. Release tags created on main when ready
  3. 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

  1. "No tags found":

    # Create initial tag
    git tag v0.1.0
    git push origin v0.1.0
    
  2. "Dirty working tree":

    # Commit or stash changes
    git add . && git commit -m "Changes"
    # Or
    git stash
    
  3. "Version not updating":

    # Clear setuptools-scm cache
    rm -rf build/ *.egg-info/
    python -m setuptools_scm
    
  4. "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.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

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.