Files
StarPunk/docs/standards/versioning-strategy.md
2025-11-18 19:21:31 -07:00

1320 lines
32 KiB
Markdown

# StarPunk Versioning Strategy
## Overview
StarPunk uses **Semantic Versioning 2.0.0** (SemVer) with Python ecosystem compliance (PEP 440) for version numbering. This strategy provides clear, predictable version numbers that communicate the nature of changes to users and developers.
**Current Version**: 0.1.0 (pre-release/development)
**Version Format**: `MAJOR.MINOR.PATCH` (e.g., `1.0.0`)
## Rationale
Semantic Versioning was chosen because:
1. **Industry Standard**: Widely used in Python ecosystem (Flask, Django, etc.)
2. **Clear Communication**: Version number immediately conveys type of changes
3. **Dependency Management**: Works seamlessly with pip, uv, and Python packaging
4. **Simple and Predictable**: Easy for indie developers to understand and apply
5. **IndieWeb Aligned**: Transparent versioning supports independent, sustainable software
## Version Number Format
### Structure
```
MAJOR.MINOR.PATCH[-PRERELEASE][+BUILDMETADATA]
Examples:
0.1.0 - Development version
1.0.0 - First stable release
1.1.0 - Minor feature addition
1.1.1 - Bug fix
2.0.0 - Breaking change
1.0.0-alpha.1 - Alpha pre-release
1.0.0-beta.2 - Beta pre-release
1.0.0-rc.1 - Release candidate
```
### Component Definitions
**MAJOR** - Increment when making incompatible changes:
- Breaking API changes (e.g., removing endpoints, changing response formats)
- Database schema changes requiring migration
- Configuration file format changes requiring user intervention
- Major architectural rewrites
- Removal of deprecated features
**MINOR** - Increment when adding functionality in a backward-compatible manner:
- New features (e.g., adding tags, categories)
- New API endpoints
- Non-breaking enhancements to existing features
- Addition of optional configuration parameters
- Performance improvements (significant)
**PATCH** - Increment for backward-compatible bug fixes:
- Bug fixes
- Security patches
- Documentation corrections
- Minor performance improvements
- Dependency updates (without feature changes)
**PRE-RELEASE** (optional) - Alpha, beta, and release candidate versions:
- `alpha.N` - Early development, unstable, missing features
- `beta.N` - Feature complete, testing and stabilization
- `rc.N` - Release candidate, final testing before stable release
**BUILD METADATA** (optional, rarely used) - Build information:
- Not used for version precedence
- Example: `1.0.0+20241118.abc123`
## Version Lifecycle
### Development Phase (Current: 0.x.y)
**Status**: Pre-1.0, anything may change at any time
- Version format: `0.MINOR.PATCH`
- MINOR increments for new features (Phase 1.1, 1.2, etc.)
- PATCH increments for bug fixes
- Public API should not be considered stable
- Breaking changes allowed without major version increment
**Examples**:
```
0.1.0 - Phase 1.1: Core utilities
0.2.0 - Phase 1.2: Data models
0.3.0 - Phase 1.3: Web routes
0.3.1 - Bug fix in web routes
0.4.0 - Phase 2.1: Micropub endpoint
1.0.0 - First stable release (V1 complete)
```
### Pre-Release Versions
**Alpha** - Early development, experimental features:
```
1.0.0-alpha.1 - First alpha
1.0.0-alpha.2 - Second alpha
```
**Beta** - Feature complete, testing phase:
```
1.0.0-beta.1 - First beta
1.0.0-beta.2 - Second beta (bug fixes)
```
**Release Candidate** - Final testing before stable:
```
1.0.0-rc.1 - First release candidate
1.0.0-rc.2 - Second RC (critical fixes only)
```
**Usage**: Pre-releases are optional. For StarPunk V1, we may skip directly to 1.0.0 if development version (0.x.y) is sufficiently tested.
### Stable Releases
**First Stable Release**: `1.0.0`
- Indicates production-ready software
- All V1 features implemented and tested
- Public API is stable and documented
- Breaking changes require MAJOR version increment
**Maintenance Releases**: `1.0.x`
- Bug fixes only
- Security patches
- Documentation updates
- No new features
- No breaking changes
**Feature Releases**: `1.x.0`
- New backward-compatible features
- Enhancements to existing features
- Non-breaking API additions
- Optional new configuration parameters
**Major Releases**: `x.0.0`
- Breaking changes
- Major new features requiring incompatible changes
- Database schema changes
- Configuration format changes
## Version Increment Decision Tree
```
┌─────────────────────────────────────────┐
│ Does the change break existing usage? │
│ (API, config, database schema) │
└─────────┬───────────────────────────────┘
┌─────┴─────┐
│ YES │
└─────┬─────┘
┌───────────────┐
│ Increment │
│ MAJOR │
└───────────────┘
┌─────┴─────┐
│ NO │
└─────┬─────┘
┌─────────────────────────────────────────┐
│ Does the change add new functionality? │
└─────────┬───────────────────────────────┘
┌─────┴─────┐
│ YES │
└─────┬─────┘
┌───────────────┐
│ Increment │
│ MINOR │
└───────────────┘
┌─────┴─────┐
│ NO │
└─────┬─────┘
┌─────────────────────────────────────────┐
│ Is this a bug fix, security patch, │
│ or documentation update? │
└─────────┬───────────────────────────────┘
┌─────┴─────┐
│ YES │
└─────┬─────┘
┌───────────────┐
│ Increment │
│ PATCH │
└───────────────┘
```
## Practical Examples
### Scenario 1: Adding Tags Feature (Backward Compatible)
**Change**: Add optional tags to notes, new API endpoint `/api/tags`
**Impact**:
- Database: Add `tags` table (migration script provided)
- API: Add new `/api/tags` endpoint (doesn't break existing endpoints)
- Config: Add optional `ENABLE_TAGS` setting (defaults to false)
**Version**: `1.0.0``1.1.0` (MINOR increment)
**Rationale**: New feature, backward compatible, existing functionality unchanged
---
### Scenario 2: Fixing RSS Feed Date Format Bug
**Change**: Fix RFC-822 date formatting in RSS feed
**Impact**:
- Bug fix only
- No API changes
- No configuration changes
- No breaking changes
**Version**: `1.1.0``1.1.1` (PATCH increment)
**Rationale**: Bug fix, backward compatible
---
### Scenario 3: Changing Micropub Response Format
**Change**: Change Micropub endpoint response from `201 Created` with `Location` header to JSON body with `url` field
**Impact**:
- Breaks existing Micropub clients
- API contract changed
- Incompatible with previous version
**Version**: `1.1.1``2.0.0` (MAJOR increment)
**Rationale**: Breaking API change requires major version
---
### Scenario 4: Performance Optimization
**Change**: Optimize database queries for note listing
**Impact**:
- No API changes
- No configuration changes
- Faster response times
- No breaking changes
**Version**: `1.1.1``1.1.2` (PATCH increment)
**Rationale**: Internal improvement, no user-facing changes
## Version Scope
### Application Version
**What**: The overall StarPunk software version
**Where Stored**:
- `starpunk/__init__.py` - `__version__` variable
- `pyproject.toml` - `version` field
- Git tag - `vMAJOR.MINOR.PATCH`
**What It Covers**:
- All StarPunk code
- API endpoints
- Web interface
- File storage format
- Configuration format
**Example**:
```python
# starpunk/__init__.py
__version__ = "1.0.0"
```
---
### API Version (Future Consideration)
**When Needed**: If we need to support multiple API versions simultaneously (V2+)
**Format**: URL-based versioning (e.g., `/api/v1/notes`, `/api/v2/notes`)
**Relationship to Application Version**:
- API v1 introduced in StarPunk 1.0.0
- API v2 might be introduced in StarPunk 2.0.0
- Both can coexist (e.g., StarPunk 2.5.0 supports both API v1 and v2)
**V1 Decision**: Not needed. Simple versioning via application version is sufficient.
---
### Database Schema Version
**What**: Version of database schema structure
**When Needed**: If database migrations are required (V2+)
**Format**: Integer sequence (1, 2, 3, ...)
**Storage**: `schema_version` table or SQLite `PRAGMA user_version`
**Relationship to Application Version**:
- Schema version increments independently
- Application version specifies compatible schema versions
- Migration scripts bridge schema versions
**V1 Decision**: Not needed. Database schema is simple and stable. If migrations are needed in V2+, we'll add this.
**Example (if implemented)**:
```sql
-- Store schema version
PRAGMA user_version = 1;
-- Migration script 001-to-002.sql increments to 2
PRAGMA user_version = 2;
```
---
### Configuration Version
**What**: Version of configuration file format
**When Needed**: If `.env` or config format changes incompatibly
**V1 Decision**: Not needed. Configuration is simple and backward compatible.
**V2+ Consideration**: If config format changes:
- Add `CONFIG_VERSION=1` to `.env`
- Migration tool or clear upgrade documentation
- Version mismatch warning in application
---
### Documentation Version
**Strategy**: Documentation is versioned with the code
**Implementation**:
- Docs stored in Git alongside code
- Git tags include documentation
- README shows current version
- Changelog documents changes
**Multiple Versions**: Not maintained. Latest documentation is for latest version.
**Historical Docs**: Available via Git tags (e.g., `git checkout v1.0.0` shows docs for that version)
## Git Workflow
### Tag Naming Convention
**Format**: `vMAJOR.MINOR.PATCH[-PRERELEASE]`
**Examples**:
```
v0.1.0 Development version
v0.2.0 Development version with new features
v1.0.0-alpha.1 First alpha of 1.0
v1.0.0-beta.1 First beta of 1.0
v1.0.0-rc.1 Release candidate
v1.0.0 Stable release
v1.0.1 Bug fix release
v1.1.0 Feature release
v2.0.0 Major release
```
**Prefix**: Use `v` prefix for Git tags (common convention, distinguishes from other tags)
### Tag Type
**Use Annotated Tags** (not lightweight tags)
**Why**:
- Contains tagger name, email, date
- Can include release notes
- Treated as full objects in Git
- Can be signed with GPG
**Command**:
```bash
git tag -a v1.0.0 -m "Release 1.0.0: First stable release"
```
### Branch Strategy
**Main Branch**: `main`
- Always contains stable code
- Tagged for releases
- Protected (no direct commits)
**Development Branch**: `develop` (optional, V2+)
- Integration branch for features
- Not needed for single developer in V1
**Release Branches**: `release/vX.Y.Z` (optional, for testing)
- Created when preparing release
- Final testing and bug fixes
- Merged to main when ready
- Tagged on main branch
**Feature Branches**: `feature/feature-name`
- For new features
- Merged to main when complete
- Deleted after merge
**Hotfix Branches**: `hotfix/issue-description`
- For critical bug fixes
- Merged to main
- Tagged immediately
**V1 Simple Workflow** (current):
```
main branch only
|
|-- feature work ---> commit ---> tag v0.1.0
|
|-- more features --> commit ---> tag v0.2.0
|
|-- ready for 1.0 -> commit ---> tag v1.0.0
|
|-- bug fix --------> commit ---> tag v1.0.1
```
### Release Process
**Step-by-step**:
1. **Ensure all changes are committed and tested**
```bash
git status
pytest
```
2. **Update version in code**
```bash
# Edit starpunk/__init__.py
__version__ = "1.0.0"
# Edit pyproject.toml (if exists)
version = "1.0.0"
```
3. **Update CHANGELOG.md**
```bash
# Add release notes (see Changelog Format below)
```
4. **Commit version bump**
```bash
git add starpunk/__init__.py pyproject.toml CHANGELOG.md
git commit -m "Bump version to 1.0.0"
```
5. **Create annotated tag**
```bash
git tag -a v1.0.0 -m "Release 1.0.0: First stable release
- IndieAuth authentication
- Micropub support
- RSS feed generation
- File-based note storage
- Basic web interface
See CHANGELOG.md for full details."
```
6. **Push to repository**
```bash
git push origin main
git push origin v1.0.0
```
7. **Create GitHub release** (if applicable)
- Go to GitHub Releases
- Create release from tag v1.0.0
- Add release notes
- Attach any binaries (not needed for Python)
## Changelog Format
### File Location
**Path**: `/home/phil/Projects/starpunk/CHANGELOG.md`
**Purpose**: Human-readable record of all notable changes
### Format
Based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
**Structure**:
```markdown
# Changelog
All notable changes to StarPunk will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
### Added
- Work in progress features
### Changed
- Work in progress changes
### Fixed
- Work in progress fixes
## [1.1.0] - 2024-12-01
### Added
- Tags support for organizing notes
- New `/api/tags` endpoint
- Tag filtering on homepage
### Changed
- Improved RSS feed performance
- Updated markdown rendering library
### Fixed
- RSS feed date format now RFC-822 compliant
- Session timeout handling
### Security
- Updated dependencies to patch vulnerabilities
## [1.0.1] - 2024-11-20
### Fixed
- Corrected RSS feed date formatting
- Fixed slug generation for non-ASCII content
### Security
- Patched XSS vulnerability in note rendering
## [1.0.0] - 2024-11-18
### Added
- IndieAuth authentication via IndieLogin
- Micropub endpoint for publishing
- RSS feed generation
- File-based note storage (Markdown)
- SQLite metadata database
- Web admin interface
- Public note viewing
- Slug generation and uniqueness
- Session management
- Basic security headers
[Unreleased]: https://github.com/username/starpunk/compare/v1.1.0...HEAD
[1.1.0]: https://github.com/username/starpunk/compare/v1.0.1...v1.1.0
[1.0.1]: https://github.com/username/starpunk/compare/v1.0.0...v1.0.1
[1.0.0]: https://github.com/username/starpunk/releases/tag/v1.0.0
```
### Entry Categories
**Added** - New features
**Changed** - Changes to existing functionality
**Deprecated** - Features that will be removed in future versions
**Removed** - Features that have been removed
**Fixed** - Bug fixes
**Security** - Security vulnerability fixes
### Writing Changelog Entries
**Good Entries** (clear, specific, user-focused):
```markdown
### Added
- Tags support for organizing notes with `/api/tags` endpoint
- Dark mode toggle in user preferences
### Fixed
- RSS feed now uses RFC-822 date format as required by spec
- Micropub endpoint returns correct HTTP 201 status code
```
**Bad Entries** (vague, technical, unclear):
```markdown
### Added
- New feature
### Fixed
- Bug fixes
- Various improvements
```
## Communication Strategy
### Version Display
**In Web Interface**:
```html
<!-- Footer of all pages -->
<footer>
StarPunk v1.0.0
<a href="https://github.com/username/starpunk/releases/tag/v1.0.0">Release Notes</a>
</footer>
```
**In CLI**:
```bash
$ python -m starpunk --version
StarPunk 1.0.0
```
**In API**:
```http
GET /api/info HTTP/1.1
HTTP/1.1 200 OK
Content-Type: application/json
{
"name": "StarPunk",
"version": "1.0.0",
"micropub_endpoint": "/api/micropub",
"indieauth_endpoint": "https://indielogin.com/auth"
}
```
**In HTTP Headers** (optional):
```http
HTTP/1.1 200 OK
X-StarPunk-Version: 1.0.0
```
**In User-Agent** (when making HTTP requests):
```
User-Agent: StarPunk/1.0.0 (https://github.com/username/starpunk)
```
### Release Announcements
**Channels**:
1. GitHub Releases (primary)
2. README.md (update version badge)
3. Personal website/blog (optional)
4. IndieWeb community (optional)
**Template**:
```markdown
# StarPunk 1.0.0 Released
I'm excited to announce the first stable release of StarPunk, a minimal IndieWeb CMS!
## What's New
- Full IndieAuth authentication
- Micropub endpoint for publishing from any client
- RSS feed for syndication
- File-based storage (your notes, your files)
- Lightweight and self-hostable
## Upgrade Instructions
This is the first stable release. If you're upgrading from a development version (0.x):
1. Backup your `data/` directory
2. Pull the latest code: `git pull origin main`
3. Check for any configuration changes in `.env.example`
4. Restart the application
## Download
- [Source code](https://github.com/username/starpunk/archive/refs/tags/v1.0.0.zip)
- [Installation instructions](https://github.com/username/starpunk#quick-start)
## Changelog
See [CHANGELOG.md](https://github.com/username/starpunk/blob/v1.0.0/CHANGELOG.md) for full details.
```
### Deprecation Warnings
**When to Warn**:
- One MINOR version before removal (e.g., deprecated in 1.1.0, removed in 2.0.0)
- At least 6 months notice (for longer release cycles)
**How to Warn**:
**In Documentation**:
```markdown
## Configuration
### `OLD_SETTING` (Deprecated)
**Status**: Deprecated in v1.1.0, will be removed in v2.0.0
**Replacement**: Use `NEW_SETTING` instead
**Migration**:
```env
# Old (deprecated)
OLD_SETTING=value
# New
NEW_SETTING=value
```
```
**In Application Logs**:
```python
import warnings
if config.get('OLD_SETTING'):
warnings.warn(
"OLD_SETTING is deprecated and will be removed in StarPunk 2.0.0. "
"Use NEW_SETTING instead.",
DeprecationWarning,
stacklevel=2
)
```
**In Changelog**:
```markdown
### Deprecated
- `OLD_SETTING` configuration option (use `NEW_SETTING` instead)
- Will be removed in v2.0.0
```
### Upgrade Guides
**Location**: `docs/upgrade/`
**Files**:
- `docs/upgrade/0.x-to-1.0.md` - Development to stable
- `docs/upgrade/1.x-to-2.0.md` - Major version upgrade
**Template**:
```markdown
# Upgrading from 0.x to 1.0
## Overview
StarPunk 1.0 is the first stable release. This guide helps you upgrade from development versions (0.x).
## Breaking Changes
### Configuration Format
**Change**: Configuration moved from JSON to .env file
**Action Required**:
1. Create `.env` file from `.env.example`
2. Migrate settings from old `config.json`
3. Delete `config.json`
### Database Schema
**Change**: Added `content_hash` column to `notes` table
**Action Required**:
Run migration script:
```bash
python scripts/migrate_0x_to_10.py
```
## New Features
- IndieAuth authentication
- Micropub endpoint
- RSS feed
See [CHANGELOG.md](../../CHANGELOG.md) for full details.
## Step-by-Step Upgrade
1. **Backup your data**:
```bash
cp -r data/ data-backup-$(date +%Y%m%d)/
```
2. **Pull latest code**:
```bash
git pull origin main
git checkout v1.0.0
```
3. **Update dependencies**:
```bash
uv pip install -r requirements.txt
```
4. **Migrate configuration**:
```bash
cp .env.example .env
# Edit .env with your settings
```
5. **Run database migration**:
```bash
python scripts/migrate_0x_to_10.py
```
6. **Test**:
```bash
pytest
flask --app app.py run
# Visit http://localhost:5000 and verify
```
7. **Restart production**:
```bash
sudo systemctl restart starpunk
```
## Rollback
If you encounter issues:
1. Stop application
2. Restore backup: `cp -r data-backup-*/ data/`
3. Checkout previous version: `git checkout v0.9.0`
4. Restart application
## Support
- [GitHub Issues](https://github.com/username/starpunk/issues)
- [Documentation](../../README.md)
```
## Version Management in Code
### Primary Version Storage
**File**: `starpunk/__init__.py`
```python
"""
StarPunk - Minimal IndieWeb CMS
Version: 1.0.0
"""
__version__ = "1.0.0"
__version_info__ = (1, 0, 0)
# Make version easily importable
from starpunk import __version__
```
**Usage**:
```python
from starpunk import __version__
print(f"StarPunk version {__version__}")
```
### Package Metadata
**File**: `pyproject.toml` (if using)
```toml
[project]
name = "starpunk"
version = "1.0.0"
description = "Minimal IndieWeb CMS"
authors = [
{name = "Your Name", email = "your.email@example.com"}
]
dependencies = [
"flask>=3.0.0",
# ... other dependencies
]
[project.urls]
Homepage = "https://github.com/username/starpunk"
Repository = "https://github.com/username/starpunk"
Changelog = "https://github.com/username/starpunk/blob/main/CHANGELOG.md"
```
### Keeping Versions in Sync
**Problem**: Version defined in multiple places (`__init__.py`, `pyproject.toml`, Git tags)
**Solution**: Single source of truth in `starpunk/__init__.py`
**Implementation**:
Option 1 - Manual sync (simple, V1):
```bash
# Update version in __init__.py
# Update version in pyproject.toml manually
# Commit and tag
```
Option 2 - Automated sync (V2+):
```bash
# Use bumpversion/bump2version tool
pip install bump2version
# Configure in .bumpversion.cfg
[bumpversion]
current_version = 1.0.0
commit = True
tag = True
[bumpversion:file:starpunk/__init__.py]
[bumpversion:file:pyproject.toml]
# Then bump version with:
bump2version patch # 1.0.0 -> 1.0.1
bump2version minor # 1.0.1 -> 1.1.0
bump2version major # 1.1.0 -> 2.0.0
```
**V1 Decision**: Manual sync (simple, no extra dependencies)
### Version Check Utility
**File**: `starpunk/utils.py` (or dedicated `starpunk/version.py`)
```python
from starpunk import __version__, __version_info__
def get_version() -> str:
"""Get StarPunk version string"""
return __version__
def get_version_info() -> tuple:
"""Get StarPunk version as tuple (major, minor, patch)"""
return __version_info__
def check_version_compatibility(min_version: str) -> bool:
"""
Check if current version meets minimum requirement
Args:
min_version: Minimum version required (e.g., "1.0.0")
Returns:
True if current version >= min_version
"""
min_parts = tuple(int(x) for x in min_version.split('.'))
return __version_info__ >= min_parts
```
### CLI Version Display
**Implementation**:
```python
# In app.py or starpunk/cli.py
import click
from starpunk import __version__
@click.group()
@click.version_option(version=__version__, prog_name="StarPunk")
def cli():
"""StarPunk - Minimal IndieWeb CMS"""
pass
if __name__ == '__main__':
cli()
```
**Usage**:
```bash
$ python app.py --version
StarPunk, version 1.0.0
```
## Development Workflow
### Starting New Development
**After Release**:
1. Create new section in CHANGELOG.md:
```markdown
## [Unreleased]
### Added
### Changed
### Fixed
```
2. Continue developing on main branch
3. Track changes in `[Unreleased]` section
### Preparing for Release
**Checklist**:
- [ ] All features complete and tested
- [ ] All tests pass
- [ ] Documentation updated
- [ ] CHANGELOG.md updated with release date
- [ ] Version bumped in `starpunk/__init__.py`
- [ ] Version bumped in `pyproject.toml` (if exists)
- [ ] Migration scripts created (if needed)
- [ ] Upgrade guide written (if major/minor)
### Release Testing
**Pre-release**:
1. Create release branch: `git checkout -b release/v1.1.0`
2. Run full test suite: `pytest`
3. Test upgrade from previous version
4. Manual testing of all features
5. Fix any bugs found
6. Merge to main: `git checkout main && git merge release/v1.1.0`
7. Tag and release
## Python Ecosystem Compliance
### PEP 440 Compatibility
**Reference**: [PEP 440 - Version Identification](https://peps.python.org/pep-0440/)
**Format**: Our SemVer format is PEP 440 compliant:
```
MAJOR.MINOR.PATCH[{a|b|rc}N]
Examples:
1.0.0 - Final release
1.0.0a1 - Alpha (note: no dot before 'a')
1.0.0b2 - Beta
1.0.0rc1 - Release candidate
```
**Difference from SemVer**:
- SemVer: `1.0.0-alpha.1` (hyphen and dot)
- PEP 440: `1.0.0a1` (no separators)
**Decision**: Use PEP 440 format for Python package compatibility
**Git Tags**: Still use `v1.0.0-alpha.1` (hyphen allowed in Git tags, not in Python version)
**Mapping**:
```
Git Tag Python Version (__version__)
v1.0.0-alpha.1 "1.0.0a1"
v1.0.0-beta.2 "1.0.0b2"
v1.0.0-rc.1 "1.0.0rc1"
v1.0.0 "1.0.0"
```
### Version Specifiers
**For dependencies** (`requirements.txt`, `pyproject.toml`):
```
# Exact version
starpunk==1.0.0
# Minimum version
starpunk>=1.0.0
# Compatible version (same major version)
starpunk~=1.0.0 # Allows 1.0.x, not 1.1.0
# Version range
starpunk>=1.0.0,<2.0.0
```
## Current State and Transition
### Current Terminology
**Documentation References**:
- "V1" - Overall first release goal
- "Phase 1.1", "Phase 1.2" - Implementation milestones
- "v1.1", "v2.0" - Future iteration references
### Clarifications
**Phases vs Versions**:
- **Phases**: Development milestones (internal planning)
- Phase 1.1: Core utilities (development version 0.1.0)
- Phase 1.2: Data models (development version 0.2.0)
- Phase 1.3: Web routes (development version 0.3.0)
- etc.
- **Versions**: Public release numbers (external communication)
- 0.1.0, 0.2.0 - Development versions
- 1.0.0 - First stable release (when all V1 phases complete)
- 1.1.0, 1.2.0 - Feature releases
- 2.0.0 - Next major version
**Mapping**:
```
Implementation Phase → Version Number → Git Tag
Phase 1.1 complete → 0.1.0 → v0.1.0
Phase 1.2 complete → 0.2.0 → v0.2.0
Phase 1.3 complete → 0.3.0 → v0.3.0
Phase 2.1 complete → 0.4.0 → v0.4.0
All V1 phases done → 1.0.0 → v1.0.0
V1.1 features added → 1.1.0 → v1.1.0
V2.0 features added → 2.0.0 → v2.0.0
```
### First Release Name
**Question**: What should the first production release be called?
**Answer**: `1.0.0`
**Rationale**:
- Signals production-ready software
- Follows semantic versioning convention
- "V1" in documentation refers to the feature set, not the version number
- Version 1.0.0 implements the "V1 feature set"
### Updating Documentation
**Action Items**:
1. Update references from "V1", "V2" to "version 1.0", "version 2.0"
2. Clarify that "V1" is a feature scope, not a version number
3. Use version numbers (1.0.0, 1.1.0) in user-facing communication
4. Use phases (Phase 1.1, Phase 1.2) in development documentation
**Example Updates**:
Before:
```markdown
# V1 Features
- IndieAuth authentication
- Micropub support
```
After:
```markdown
# Version 1.0 Features (V1 Scope)
- IndieAuth authentication
- Micropub support
```
## FAQ
### Q: When should I create version 1.0.0?
**A**: When all features planned for the first production release are complete, tested, and documented. For StarPunk, this means:
- All core features working (auth, publishing, RSS)
- Full test coverage
- Complete documentation
- Production deployment tested
- Ready for public use
### Q: Can I skip 0.x versions and go straight to 1.0.0?
**A**: Yes, but not recommended for StarPunk. Since we're actively developing, 0.x versions signal "not yet production ready" and give us freedom to make breaking changes.
### Q: Should I version my API separately?
**A**: Not needed for V1. Simple version numbers are sufficient. If you need to support multiple API versions simultaneously (e.g., breaking changes but maintain backward compatibility), consider API versioning in URLs (`/api/v1/`, `/api/v2/`).
### Q: How do I handle hotfixes?
**A**:
1. Create hotfix branch from tag: `git checkout -b hotfix/critical-bug v1.0.0`
2. Fix bug
3. Increment PATCH version: 1.0.0 → 1.0.1
4. Tag: `v1.0.1`
5. Merge to main
6. If developing next version, merge hotfix to develop branch too
### Q: What if I need to change the database schema?
**A**:
- **Backward compatible** (adding optional column): MINOR version (1.0.0 → 1.1.0)
- **Breaking change** (removing column, changing format): MAJOR version (1.0.0 → 2.0.0)
- Provide migration script
- Document in upgrade guide
### Q: How do I handle dependency updates?
**A**:
- **Security patches**: PATCH version (1.0.0 → 1.0.1)
- **Minor updates** (no feature changes): PATCH version
- **Major updates** (with feature changes): MINOR or MAJOR depending on impact
### Q: Should I version documentation separately?
**A**: No. Documentation lives with code in Git. Version the whole repository together.
### Q: What about version numbers for forks?
**A**: If someone forks StarPunk:
- They should use their own version numbers
- Or add suffix: `1.0.0-fork` or `1.0.0+myname.1`
- Keep major.minor.patch in sync with upstream if merging changes
### Q: How do I communicate breaking changes?
**A**:
1. Increment MAJOR version
2. Document in CHANGELOG under "Breaking Changes" section
3. Provide upgrade guide
4. Deprecate features one version early if possible
5. Announce prominently in release notes
### Q: Can I use dates in version numbers?
**A**: Not recommended. Calendar versioning (CalVer) like `2024.11.18` is valid but doesn't communicate change impact. Semantic versioning is clearer for StarPunk's use case.
## Tools and Automation
### Manual Version Management (V1)
**Current Approach**: Simple, manual versioning
**Process**:
1. Edit `starpunk/__init__.py`: `__version__ = "1.0.0"`
2. Edit `pyproject.toml`: `version = "1.0.0"`
3. Update `CHANGELOG.md`
4. Commit: `git commit -m "Bump version to 1.0.0"`
5. Tag: `git tag -a v1.0.0 -m "Release 1.0.0"`
6. Push: `git push origin main v1.0.0`
**Pros**: Simple, no dependencies, full control
**Cons**: Manual, error-prone, easy to forget steps
### Automated Version Management (V2+)
**Tools to Consider**:
**1. bump2version** / **bumpversion**
```bash
pip install bump2version
# Configure in .bumpversion.cfg
bump2version patch # Increments, commits, tags automatically
```
**2. python-semantic-release**
```bash
pip install python-semantic-release
# Analyzes commit messages, determines version bump
semantic-release version
```
**3. setuptools_scm**
```bash
# Derives version from Git tags automatically
pip install setuptools_scm
```
**V1 Decision**: Manual versioning (simplest, aligns with indie philosophy)
**V2+ Consideration**: Add `bump2version` if versioning becomes tedious
### Version Check on Install
**Feature**: Warn user if running outdated version
**Implementation** (optional, V2+):
```python
import requests
from starpunk import __version__
def check_for_updates():
"""Check if a newer version is available"""
try:
response = requests.get(
"https://api.github.com/repos/username/starpunk/releases/latest",
timeout=2
)
latest = response.json()["tag_name"].lstrip('v')
if latest != __version__:
print(f"Update available: {latest} (you have {__version__})")
print("Visit: https://github.com/username/starpunk/releases")
except:
pass # Silently fail, don't block application
```
**V1 Decision**: Not needed (manual update check)
## References
### Standards
- [Semantic Versioning 2.0.0](https://semver.org/spec/v2.0.0.html) - Official SemVer spec
- [PEP 440](https://peps.python.org/pep-0440/) - Python version identification
- [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) - Changelog format
- [Calendar Versioning](https://calver.org/) - Alternative versioning (not used)
### Tools
- [bump2version](https://github.com/c4urself/bump2version) - Version bump automation
- [python-semantic-release](https://python-semantic-release.readthedocs.io/) - Semantic release automation
- [setuptools_scm](https://github.com/pypa/setuptools_scm) - SCM-based versioning
### Examples
- [Flask versioning](https://github.com/pallets/flask) - SemVer with PEP 440
- [Django versioning](https://docs.djangoproject.com/en/stable/internals/release-process/) - Modified SemVer
- [Requests versioning](https://github.com/psf/requests) - SemVer
### Internal Documentation
- [ADR-008: Versioning Strategy](/home/phil/Projects/starpunk/docs/decisions/ADR-008-versioning-strategy.md)
- [Architecture Overview](/home/phil/Projects/starpunk/docs/architecture/overview.md)
- [Development Setup](/home/phil/Projects/starpunk/docs/standards/development-setup.md)
---
**Document Version**: 1.0
**Last Updated**: 2024-11-18
**Author**: StarPunk Architecture Team
**Status**: Active