📝 initial release docs
This commit is contained in:
29
CHANGELOG.md
Normal file
29
CHANGELOG.md
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
# Changelog
|
||||||
|
|
||||||
|
All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
||||||
|
and this project uses date-based versioning (YYYY.MM.DD).
|
||||||
|
|
||||||
|
## [Unreleased]
|
||||||
|
|
||||||
|
### Added
|
||||||
|
### Changed
|
||||||
|
### Deprecated
|
||||||
|
### Removed
|
||||||
|
### Fixed
|
||||||
|
### Security
|
||||||
|
|
||||||
|
## [2025.11.15] - 2025-11-15
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- Initial version tracking system
|
||||||
|
- `version.py` module for source code version reference
|
||||||
|
- `VERSION` file at project root for easy access
|
||||||
|
- HTML meta tag (`generator`) displaying version in page source
|
||||||
|
- Version number injected into all template contexts
|
||||||
|
- This CHANGELOG.md file to track version history
|
||||||
|
- Version bump script (`scripts/bump_version.py`) to automate releases
|
||||||
|
|
||||||
|
[Unreleased]: https://git.puercito.net/mi/sunday/compare/v2025.11.15...HEAD
|
||||||
|
[2025.11.15]: https://git.puercito.net/mi/sunday/releases/tag/v2025.11.15
|
||||||
27
CLAUDE.md
27
CLAUDE.md
@@ -56,6 +56,33 @@ python scripts/rebuild_cache.py
|
|||||||
```
|
```
|
||||||
Force rebuild the comics cache from YAML files. Normally not needed (cache auto-invalidates).
|
Force rebuild the comics cache from YAML files. Normally not needed (cache auto-invalidates).
|
||||||
|
|
||||||
|
**Bump version:**
|
||||||
|
```bash
|
||||||
|
python scripts/bump_version.py
|
||||||
|
```
|
||||||
|
Updates the project version to today's date (YYYY.MM.DD format) in both `version.py` and `VERSION` files. Optionally opens CHANGELOG.md for editing.
|
||||||
|
|
||||||
|
**Bump version to specific date:**
|
||||||
|
```bash
|
||||||
|
python scripts/bump_version.py 2025.12.25
|
||||||
|
```
|
||||||
|
Sets version to a specific date instead of using today's date.
|
||||||
|
|
||||||
|
## Versioning
|
||||||
|
|
||||||
|
The project uses date-based versioning (YYYY.MM.DD format):
|
||||||
|
- **`version.py`**: Python module containing `__version__` variable (import with `from version import __version__`)
|
||||||
|
- **`VERSION`**: Plain text file at project root for easy access by scripts and CI/CD
|
||||||
|
- **`CHANGELOG.md`**: Tracks version history and changes following [Keep a Changelog](https://keepachangelog.com/) format
|
||||||
|
- **HTML meta tag**: Version appears in page source as `<meta name="generator" content="Sunday Comics X.Y.Z">`
|
||||||
|
|
||||||
|
When releasing a new version:
|
||||||
|
1. Run `python scripts/bump_version.py` to update version files
|
||||||
|
2. Edit `CHANGELOG.md` to document changes under the new version
|
||||||
|
3. Commit changes: `git commit -m "Release version YYYY.MM.DD"`
|
||||||
|
4. Tag the release: `git tag -a vYYYY.MM.DD -m "Version YYYY.MM.DD"`
|
||||||
|
5. Push with tags: `git push && git push --tags`
|
||||||
|
|
||||||
## Architecture
|
## Architecture
|
||||||
|
|
||||||
### Data Layer: YAML Files in data/comics/
|
### Data Layer: YAML Files in data/comics/
|
||||||
|
|||||||
154
scripts/bump_version.py
Executable file
154
scripts/bump_version.py
Executable file
@@ -0,0 +1,154 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# Sunday Comics - Version bump script
|
||||||
|
# Copyright (c) 2025 Tomasita Cabrera
|
||||||
|
# Licensed under the MIT License - see LICENSE file for details
|
||||||
|
|
||||||
|
"""
|
||||||
|
Script to bump the project version number
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
python scripts/bump_version.py # Use today's date
|
||||||
|
python scripts/bump_version.py 2025.12.25 # Use specific date
|
||||||
|
"""
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
from datetime import datetime
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
|
||||||
|
def validate_version(version_str):
|
||||||
|
"""Validate version format (YYYY.MM.DD)"""
|
||||||
|
pattern = r'^\d{4}\.\d{2}\.\d{2}$'
|
||||||
|
if not re.match(pattern, version_str):
|
||||||
|
return False
|
||||||
|
|
||||||
|
# Try to parse as a date to ensure it's valid
|
||||||
|
try:
|
||||||
|
parts = version_str.split('.')
|
||||||
|
year, month, day = int(parts[0]), int(parts[1]), int(parts[2])
|
||||||
|
datetime(year, month, day)
|
||||||
|
return True
|
||||||
|
except ValueError:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def get_current_version(parent_dir):
|
||||||
|
"""Read current version from version.py"""
|
||||||
|
version_file = os.path.join(parent_dir, 'version.py')
|
||||||
|
try:
|
||||||
|
with open(version_file, 'r', encoding='utf-8') as f:
|
||||||
|
content = f.read()
|
||||||
|
match = re.search(r'__version__\s*=\s*["\']([^"\']+)["\']', content)
|
||||||
|
if match:
|
||||||
|
return match.group(1)
|
||||||
|
except FileNotFoundError:
|
||||||
|
pass
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def update_version_py(parent_dir, new_version):
|
||||||
|
"""Update version.py with new version"""
|
||||||
|
version_file = os.path.join(parent_dir, 'version.py')
|
||||||
|
|
||||||
|
content = f"""# Sunday Comics Version
|
||||||
|
# This file contains the version number for the project
|
||||||
|
# Format: YYYY.MM.DD (date-based versioning)
|
||||||
|
|
||||||
|
__version__ = "{new_version}"
|
||||||
|
"""
|
||||||
|
|
||||||
|
with open(version_file, 'w', encoding='utf-8') as f:
|
||||||
|
f.write(content)
|
||||||
|
|
||||||
|
print(f"✓ Updated {version_file}")
|
||||||
|
|
||||||
|
|
||||||
|
def update_version_file(parent_dir, new_version):
|
||||||
|
"""Update VERSION file with new version"""
|
||||||
|
version_file = os.path.join(parent_dir, 'VERSION')
|
||||||
|
|
||||||
|
with open(version_file, 'w', encoding='utf-8') as f:
|
||||||
|
f.write(f"{new_version}\n")
|
||||||
|
|
||||||
|
print(f"✓ Updated {version_file}")
|
||||||
|
|
||||||
|
|
||||||
|
def remind_changelog(parent_dir, new_version, current_version):
|
||||||
|
"""Remind user to update CHANGELOG.md"""
|
||||||
|
changelog_file = os.path.join(parent_dir, 'CHANGELOG.md')
|
||||||
|
|
||||||
|
print(f"\n📝 Don't forget to update {changelog_file}!")
|
||||||
|
print(f"\nAdd your changes under the new version section:")
|
||||||
|
print(f"\n## [{new_version}] - {datetime.now().strftime('%Y-%m-%d')}")
|
||||||
|
print(f"\n### Added")
|
||||||
|
print(f"### Changed")
|
||||||
|
print(f"### Fixed")
|
||||||
|
|
||||||
|
if os.path.exists(changelog_file):
|
||||||
|
print(f"\n💡 Tip: Edit the file now with: nano {changelog_file}")
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser = argparse.ArgumentParser(
|
||||||
|
description='Bump project version number',
|
||||||
|
epilog='Examples:\n %(prog)s\n %(prog)s 2025.12.25',
|
||||||
|
formatter_class=argparse.RawDescriptionHelpFormatter
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
'version',
|
||||||
|
nargs='?',
|
||||||
|
help='Version number in YYYY.MM.DD format (defaults to today\'s date)'
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
'--no-changelog-reminder',
|
||||||
|
action='store_true',
|
||||||
|
help='Skip the changelog reminder'
|
||||||
|
)
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
# Determine new version
|
||||||
|
if args.version:
|
||||||
|
new_version = args.version
|
||||||
|
if not validate_version(new_version):
|
||||||
|
print(f"Error: Invalid version format '{new_version}'")
|
||||||
|
print(f"Expected format: YYYY.MM.DD (e.g., 2025.12.25)")
|
||||||
|
sys.exit(1)
|
||||||
|
else:
|
||||||
|
# Use today's date
|
||||||
|
new_version = datetime.now().strftime('%Y.%m.%d')
|
||||||
|
|
||||||
|
# Get parent directory (project root)
|
||||||
|
parent_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||||
|
|
||||||
|
# Get current version
|
||||||
|
current_version = get_current_version(parent_dir)
|
||||||
|
|
||||||
|
if current_version:
|
||||||
|
print(f"Current version: {current_version}")
|
||||||
|
|
||||||
|
print(f"New version: {new_version}")
|
||||||
|
|
||||||
|
# Check if version is the same
|
||||||
|
if current_version == new_version:
|
||||||
|
print(f"\n⚠️ Version is already {new_version}")
|
||||||
|
response = input("Continue anyway? [y/N]: ").lower().strip()
|
||||||
|
if response != 'y':
|
||||||
|
print("Aborted.")
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
# Update files
|
||||||
|
print(f"\nUpdating version files...")
|
||||||
|
update_version_py(parent_dir, new_version)
|
||||||
|
update_version_file(parent_dir, new_version)
|
||||||
|
|
||||||
|
print(f"\n✅ Version bumped to {new_version}")
|
||||||
|
|
||||||
|
# Remind about changelog
|
||||||
|
if not args.no_changelog_reminder:
|
||||||
|
remind_changelog(parent_dir, new_version, current_version)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
Reference in New Issue
Block a user