604 lines
13 KiB
Markdown
604 lines
13 KiB
Markdown
# Version Implementation Guide
|
|
|
|
## Quick Reference
|
|
|
|
This guide shows exactly where and how version information is stored in StarPunk.
|
|
|
|
**See Also**: [versioning-strategy.md](versioning-strategy.md) for complete strategy documentation.
|
|
|
|
## Version Storage Locations
|
|
|
|
### 1. Primary Source: `starpunk/__init__.py`
|
|
|
|
**Status**: ✅ Already implemented
|
|
|
|
**Location**: `/home/phil/Projects/starpunk/starpunk/__init__.py`
|
|
|
|
**Content**:
|
|
```python
|
|
# Package version (Semantic Versioning 2.0.0)
|
|
# See docs/standards/versioning-strategy.md for details
|
|
__version__ = "0.1.0"
|
|
__version_info__ = (0, 1, 0)
|
|
```
|
|
|
|
**Usage**:
|
|
```python
|
|
from starpunk import __version__, __version_info__
|
|
|
|
print(f"StarPunk version {__version__}")
|
|
print(f"Version info: {__version_info__}") # (0, 1, 0)
|
|
```
|
|
|
|
**Format**:
|
|
- `__version__`: String in PEP 440 format (e.g., `"1.0.0"`, `"1.0.0a1"`, `"1.0.0rc1"`)
|
|
- `__version_info__`: Tuple of integers (major, minor, patch) for programmatic comparison
|
|
|
|
---
|
|
|
|
### 2. README.md
|
|
|
|
**Status**: ✅ Already implemented
|
|
|
|
**Location**: `/home/phil/Projects/starpunk/README.md`
|
|
|
|
**Content**: Shows current version at the top of the file:
|
|
```markdown
|
|
# StarPunk
|
|
|
|
A minimal, self-hosted IndieWeb CMS for publishing notes with RSS syndication.
|
|
|
|
**Current Version**: 0.1.0 (development)
|
|
|
|
## Versioning
|
|
|
|
StarPunk follows [Semantic Versioning 2.0.0](https://semver.org/):
|
|
- Version format: `MAJOR.MINOR.PATCH`
|
|
- Current: `0.1.0` (pre-release development)
|
|
- First stable release will be `1.0.0`
|
|
```
|
|
|
|
**Update when**: Version changes (manually)
|
|
|
|
---
|
|
|
|
### 3. CHANGELOG.md
|
|
|
|
**Status**: ✅ Created
|
|
|
|
**Location**: `/home/phil/Projects/starpunk/CHANGELOG.md`
|
|
|
|
**Format**: Based on [Keep a Changelog](https://keepachangelog.com/)
|
|
|
|
**Structure**:
|
|
```markdown
|
|
# Changelog
|
|
|
|
## [Unreleased]
|
|
|
|
### Added
|
|
- Features being developed
|
|
|
|
## [1.0.0] - 2024-11-18
|
|
|
|
### Added
|
|
- New features
|
|
|
|
### Changed
|
|
- Changes to existing features
|
|
|
|
### Fixed
|
|
- Bug fixes
|
|
|
|
### Security
|
|
- Security patches
|
|
```
|
|
|
|
**Update when**: Every change (add to `[Unreleased]`), then move to versioned section on release
|
|
|
|
---
|
|
|
|
### 4. Git Tags
|
|
|
|
**Status**: ⏳ To be created when releasing
|
|
|
|
**Format**: `vMAJOR.MINOR.PATCH[-PRERELEASE]`
|
|
|
|
**Examples**:
|
|
```bash
|
|
v0.1.0 # Development version
|
|
v0.2.0 # Next development version
|
|
v1.0.0-alpha.1 # Alpha pre-release
|
|
v1.0.0-beta.1 # Beta pre-release
|
|
v1.0.0-rc.1 # Release candidate
|
|
v1.0.0 # Stable release
|
|
```
|
|
|
|
**How to Create**:
|
|
```bash
|
|
# Annotated tag (recommended)
|
|
git tag -a v0.1.0 -m "Development version 0.1.0: Phase 1.1 complete
|
|
|
|
- Core utilities implemented
|
|
- Slug generation
|
|
- File operations
|
|
- Content hashing
|
|
|
|
See CHANGELOG.md for full details."
|
|
|
|
# Push tag
|
|
git push origin v0.1.0
|
|
```
|
|
|
|
**Current Tags**: None yet (will create when Phase 1.1 is complete)
|
|
|
|
---
|
|
|
|
### 5. pyproject.toml (Optional, Future)
|
|
|
|
**Status**: ⚠️ Not currently used
|
|
|
|
**Location**: `/home/phil/Projects/starpunk/pyproject.toml` (if created)
|
|
|
|
**Content** (if we create this file):
|
|
```toml
|
|
[project]
|
|
name = "starpunk"
|
|
version = "0.1.0"
|
|
description = "Minimal IndieWeb CMS"
|
|
authors = [
|
|
{name = "Your Name", email = "your@email.com"}
|
|
]
|
|
dependencies = [
|
|
"flask>=3.0.0",
|
|
"python-markdown>=3.5.0",
|
|
"feedgen>=1.0.0",
|
|
"httpx>=0.25.0",
|
|
]
|
|
|
|
[project.urls]
|
|
Homepage = "https://github.com/YOUR_USERNAME/starpunk"
|
|
Repository = "https://github.com/YOUR_USERNAME/starpunk"
|
|
Changelog = "https://github.com/YOUR_USERNAME/starpunk/blob/main/CHANGELOG.md"
|
|
```
|
|
|
|
**Decision**: Not needed for V1 (keeping it simple)
|
|
|
|
---
|
|
|
|
## How to Update Version
|
|
|
|
### Step-by-Step Process
|
|
|
|
When you're ready to release a new version:
|
|
|
|
#### 1. Decide on Version Number
|
|
|
|
Use the decision tree from `versioning-strategy.md`:
|
|
|
|
- **Breaking changes?** → Increment MAJOR (e.g., 1.0.0 → 2.0.0)
|
|
- **New features?** → Increment MINOR (e.g., 1.0.0 → 1.1.0)
|
|
- **Bug fixes only?** → Increment PATCH (e.g., 1.0.0 → 1.0.1)
|
|
|
|
**During 0.x development**:
|
|
- **Phase complete?** → Increment MINOR (e.g., 0.1.0 → 0.2.0)
|
|
- **Bug fix?** → Increment PATCH (e.g., 0.1.0 → 0.1.1)
|
|
|
|
#### 2. Update `starpunk/__init__.py`
|
|
|
|
```python
|
|
# Change version strings
|
|
__version__ = "0.2.0" # New version
|
|
__version_info__ = (0, 2, 0) # New version tuple
|
|
```
|
|
|
|
#### 3. Update `CHANGELOG.md`
|
|
|
|
Move `[Unreleased]` items to new version section:
|
|
|
|
```markdown
|
|
## [Unreleased]
|
|
|
|
### Added
|
|
|
|
### Changed
|
|
|
|
### Fixed
|
|
|
|
## [0.2.0] - 2024-11-19
|
|
|
|
### Added
|
|
- Data models implementation
|
|
- Database schema
|
|
- Note class with validation
|
|
|
|
### Changed
|
|
- Improved error handling in utilities
|
|
|
|
[Unreleased]: https://github.com/YOUR_USERNAME/starpunk/compare/v0.2.0...HEAD
|
|
[0.2.0]: https://github.com/YOUR_USERNAME/starpunk/compare/v0.1.0...v0.2.0
|
|
[0.1.0]: https://github.com/YOUR_USERNAME/starpunk/releases/tag/v0.1.0
|
|
```
|
|
|
|
#### 4. Update `README.md`
|
|
|
|
Change current version:
|
|
```markdown
|
|
**Current Version**: 0.2.0 (development)
|
|
```
|
|
|
|
#### 5. Commit Changes
|
|
|
|
```bash
|
|
git add starpunk/__init__.py CHANGELOG.md README.md
|
|
git commit -m "Bump version to 0.2.0"
|
|
```
|
|
|
|
#### 6. Create Git Tag
|
|
|
|
```bash
|
|
git tag -a v0.2.0 -m "Development version 0.2.0: Phase 1.2 complete
|
|
|
|
- Data models implementation
|
|
- Database schema defined
|
|
- Note class with full validation
|
|
- Session and token models
|
|
|
|
See CHANGELOG.md for full details."
|
|
```
|
|
|
|
#### 7. Push to Repository
|
|
|
|
```bash
|
|
git push origin main
|
|
git push origin v0.2.0
|
|
```
|
|
|
|
#### 8. Create GitHub Release (Optional)
|
|
|
|
If using GitHub:
|
|
1. Go to repository → Releases
|
|
2. Click "Draft a new release"
|
|
3. Choose tag: `v0.2.0`
|
|
4. Release title: `Version 0.2.0`
|
|
5. Description: Copy from CHANGELOG.md
|
|
6. Publish release
|
|
|
|
---
|
|
|
|
## How to Check Version
|
|
|
|
### From Python Code
|
|
|
|
```python
|
|
# Method 1: Import from package
|
|
from starpunk import __version__
|
|
print(f"Version: {__version__}")
|
|
|
|
# Method 2: Use version_info for comparisons
|
|
from starpunk import __version_info__
|
|
if __version_info__ >= (1, 0, 0):
|
|
print("Stable release")
|
|
else:
|
|
print("Development version")
|
|
```
|
|
|
|
### From Command Line
|
|
|
|
```bash
|
|
# Method 1: Python one-liner
|
|
python -c "from starpunk import __version__; print(__version__)"
|
|
|
|
# Method 2: Check Git tags
|
|
git tag -l
|
|
|
|
# Method 3: Check current HEAD tag
|
|
git describe --tags --abbrev=0
|
|
|
|
# Method 4: Show all version info
|
|
git describe --tags
|
|
```
|
|
|
|
### From Web Interface (Future)
|
|
|
|
When implemented, will show in:
|
|
- Footer of all pages
|
|
- `/api/info` endpoint
|
|
- Admin dashboard
|
|
|
|
---
|
|
|
|
## Version Comparison Examples
|
|
|
|
### Using `__version_info__`
|
|
|
|
```python
|
|
from starpunk import __version_info__
|
|
|
|
# Check minimum version
|
|
def require_version(major, minor, patch):
|
|
return __version_info__ >= (major, minor, patch)
|
|
|
|
# Examples
|
|
if require_version(1, 0, 0):
|
|
print("Running stable version")
|
|
|
|
if require_version(0, 2, 0):
|
|
print("Has data models")
|
|
```
|
|
|
|
### Parsing `__version__` String
|
|
|
|
```python
|
|
from starpunk import __version__
|
|
from packaging.version import Version
|
|
|
|
current = Version(__version__)
|
|
required = Version("1.0.0")
|
|
|
|
if current >= required:
|
|
print("Version requirement met")
|
|
```
|
|
|
|
---
|
|
|
|
## Release Checklist
|
|
|
|
Use this checklist when releasing a new version:
|
|
|
|
### Pre-Release
|
|
|
|
- [ ] All tests pass: `pytest`
|
|
- [ ] Code formatted: `black starpunk/ tests/`
|
|
- [ ] Code linted: `flake8 starpunk/ tests/`
|
|
- [ ] Documentation updated
|
|
- [ ] All features working
|
|
- [ ] Manual testing completed
|
|
|
|
### Version Bump
|
|
|
|
- [ ] Decide version number (MAJOR.MINOR.PATCH)
|
|
- [ ] Update `starpunk/__init__.py` → `__version__`
|
|
- [ ] Update `starpunk/__init__.py` → `__version_info__`
|
|
- [ ] Update `CHANGELOG.md` with changes and date
|
|
- [ ] Update `README.md` with current version
|
|
- [ ] Review changes: `git diff`
|
|
|
|
### Commit and Tag
|
|
|
|
- [ ] Stage files: `git add starpunk/__init__.py CHANGELOG.md README.md`
|
|
- [ ] Commit: `git commit -m "Bump version to X.Y.Z"`
|
|
- [ ] Create annotated tag: `git tag -a vX.Y.Z -m "Release X.Y.Z: [description]"`
|
|
- [ ] Push commits: `git push origin main`
|
|
- [ ] Push tag: `git push origin vX.Y.Z`
|
|
|
|
### Post-Release
|
|
|
|
- [ ] Verify tag exists: `git tag -l`
|
|
- [ ] Create GitHub release (if applicable)
|
|
- [ ] Test installation from tag
|
|
- [ ] Announce release (if applicable)
|
|
- [ ] Create `[Unreleased]` section in CHANGELOG.md for next development
|
|
|
|
---
|
|
|
|
## Common Scenarios
|
|
|
|
### Scenario 1: Completing a Development Phase
|
|
|
|
**Situation**: Phase 1.2 is complete (data models implemented)
|
|
|
|
**Action**:
|
|
1. Version: 0.1.0 → 0.2.0 (increment MINOR during 0.x)
|
|
2. Update `__init__.py`: `__version__ = "0.2.0"`, `__version_info__ = (0, 2, 0)`
|
|
3. Update CHANGELOG: Add `[0.2.0]` section with date
|
|
4. Commit: `"Bump version to 0.2.0"`
|
|
5. Tag: `v0.2.0`
|
|
6. Push
|
|
|
|
### Scenario 2: Fixing a Bug
|
|
|
|
**Situation**: Found bug in slug generation, fixed it
|
|
|
|
**Action**:
|
|
1. Version: 0.2.0 → 0.2.1 (increment PATCH)
|
|
2. Update `__init__.py`: `__version__ = "0.2.1"`, `__version_info__ = (0, 2, 1)`
|
|
3. Update CHANGELOG: Add `[0.2.1]` section with bug fix
|
|
4. Commit: `"Bump version to 0.2.1"`
|
|
5. Tag: `v0.2.1`
|
|
6. Push
|
|
|
|
### Scenario 3: First Stable Release
|
|
|
|
**Situation**: All V1 features complete, ready for production
|
|
|
|
**Action**:
|
|
1. Version: 0.9.0 → 1.0.0 (first stable release!)
|
|
2. Update `__init__.py`: `__version__ = "1.0.0"`, `__version_info__ = (1, 0, 0)`
|
|
3. Update CHANGELOG: Comprehensive `[1.0.0]` section
|
|
4. Update README: Change "0.x.0 (development)" to "1.0.0 (stable)"
|
|
5. Commit: `"Bump version to 1.0.0 - First stable release"`
|
|
6. Tag: `v1.0.0` with detailed release notes
|
|
7. Push
|
|
8. Create GitHub release with announcement
|
|
|
|
### Scenario 4: Adding New Feature (Post-1.0)
|
|
|
|
**Situation**: Added tags feature in version 1.0.0, want to release it
|
|
|
|
**Action**:
|
|
1. Version: 1.0.0 → 1.1.0 (increment MINOR for new feature)
|
|
2. Update `__init__.py`: `__version__ = "1.1.0"`, `__version_info__ = (1, 1, 0)`
|
|
3. Update CHANGELOG: Add `[1.1.0]` section with "Added: Tags support"
|
|
4. Commit and tag
|
|
5. Push
|
|
|
|
### Scenario 5: Breaking Change (Post-1.0)
|
|
|
|
**Situation**: Changed Micropub API response format (breaking change)
|
|
|
|
**Action**:
|
|
1. Version: 1.5.0 → 2.0.0 (increment MAJOR for breaking change)
|
|
2. Update `__init__.py`: `__version__ = "2.0.0"`, `__version_info__ = (2, 0, 0)`
|
|
3. Update CHANGELOG: Clear "Breaking Changes" section
|
|
4. Create upgrade guide: `docs/upgrade/1.x-to-2.0.md`
|
|
5. Commit and tag
|
|
6. Push
|
|
7. Prominently announce breaking changes
|
|
|
|
---
|
|
|
|
## Troubleshooting
|
|
|
|
### Version Mismatch
|
|
|
|
**Problem**: `__version__` and `__version_info__` don't match
|
|
|
|
**Solution**: They must always match:
|
|
```python
|
|
# Correct
|
|
__version__ = "1.2.3"
|
|
__version_info__ = (1, 2, 3)
|
|
|
|
# Wrong
|
|
__version__ = "1.2.3"
|
|
__version_info__ = (1, 2, 0) # Mismatch!
|
|
```
|
|
|
|
### Forgot to Update CHANGELOG
|
|
|
|
**Problem**: Released version without updating CHANGELOG
|
|
|
|
**Solution**:
|
|
1. Update CHANGELOG now
|
|
2. Commit: `"Update CHANGELOG for version X.Y.Z"`
|
|
3. Don't change version number or tag
|
|
4. Consider creating patch release with corrected changelog
|
|
|
|
### Wrong Version Number
|
|
|
|
**Problem**: Tagged v1.1.0 but should have been v2.0.0
|
|
|
|
**Solution**:
|
|
```bash
|
|
# Delete local tag
|
|
git tag -d v1.1.0
|
|
|
|
# Delete remote tag
|
|
git push origin :refs/tags/v1.1.0
|
|
|
|
# Create correct tag
|
|
git tag -a v2.0.0 -m "Release 2.0.0"
|
|
git push origin v2.0.0
|
|
```
|
|
|
|
**Warning**: Only do this immediately after release, before anyone uses the tag!
|
|
|
|
### Git Tag vs Python Version Mismatch
|
|
|
|
**Problem**: Git tag says `v1.0.0` but `__version__` says `"0.9.0"`
|
|
|
|
**Solution**: These must always match:
|
|
1. Check Git tag: `git describe --tags`
|
|
2. Check Python version: `python -c "from starpunk import __version__; print(__version__)"`
|
|
3. They should match (ignoring `v` prefix)
|
|
4. If mismatch, fix `__init__.py` and create new tag
|
|
|
|
---
|
|
|
|
## Pre-Release Versions
|
|
|
|
### Alpha Releases
|
|
|
|
**When**: Early development, unstable, missing features
|
|
|
|
**Format**:
|
|
- Git tag: `v1.0.0-alpha.1`
|
|
- Python `__version__`: `"1.0.0a1"` (PEP 440 format)
|
|
- `__version_info__`: `(1, 0, 0, "alpha", 1)` (extended tuple)
|
|
|
|
**Example**:
|
|
```python
|
|
__version__ = "1.0.0a1"
|
|
__version_info__ = (1, 0, 0) # Simplified, or extended: (1, 0, 0, "alpha", 1)
|
|
```
|
|
|
|
### Beta Releases
|
|
|
|
**When**: Feature complete, testing phase
|
|
|
|
**Format**:
|
|
- Git tag: `v1.0.0-beta.1`
|
|
- Python `__version__`: `"1.0.0b1"`
|
|
- `__version_info__`: `(1, 0, 0)`
|
|
|
|
### Release Candidates
|
|
|
|
**When**: Final testing before stable release
|
|
|
|
**Format**:
|
|
- Git tag: `v1.0.0-rc.1`
|
|
- Python `__version__`: `"1.0.0rc1"`
|
|
- `__version_info__`: `(1, 0, 0)`
|
|
|
|
**Note**: For V1, we may skip pre-releases entirely and go straight to 1.0.0 if 0.x testing is sufficient.
|
|
|
|
---
|
|
|
|
## Integration with Other Systems
|
|
|
|
### Flask Application
|
|
|
|
```python
|
|
# In Flask app
|
|
from starpunk import __version__
|
|
|
|
@app.route('/api/info')
|
|
def api_info():
|
|
return {
|
|
"name": "StarPunk",
|
|
"version": __version__,
|
|
"micropub_endpoint": "/api/micropub"
|
|
}
|
|
```
|
|
|
|
### CLI Tool (Future)
|
|
|
|
```python
|
|
import click
|
|
from starpunk import __version__
|
|
|
|
@click.group()
|
|
@click.version_option(version=__version__, prog_name="StarPunk")
|
|
def cli():
|
|
"""StarPunk CMS"""
|
|
pass
|
|
```
|
|
|
|
### User-Agent String
|
|
|
|
```python
|
|
from starpunk import __version__
|
|
|
|
USER_AGENT = f"StarPunk/{__version__} (https://github.com/YOUR_USERNAME/starpunk)"
|
|
|
|
# Use in HTTP requests
|
|
headers = {"User-Agent": USER_AGENT}
|
|
```
|
|
|
|
---
|
|
|
|
## References
|
|
|
|
- [Versioning Strategy (complete spec)](versioning-strategy.md)
|
|
- [ADR-008: Versioning Strategy](../decisions/ADR-008-versioning-strategy.md)
|
|
- [Semantic Versioning 2.0.0](https://semver.org/)
|
|
- [PEP 440 - Version Identification](https://peps.python.org/pep-0440/)
|
|
- [Keep a Changelog](https://keepachangelog.com/)
|
|
|
|
---
|
|
|
|
**Document Version**: 1.0
|
|
**Last Updated**: 2024-11-18
|
|
**Status**: Active
|