feat: Implement centralized version management and sync process
This commit is contained in:
parent
c1133ae8e9
commit
0d9464854d
7 changed files with 523 additions and 45 deletions
140
VERSIONING_SIMPLIFIED.md
Normal file
140
VERSIONING_SIMPLIFIED.md
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
# Simplified Versioning System
|
||||
|
||||
## Problem Solved
|
||||
|
||||
Previously, the application version had to be manually updated in **multiple places**:
|
||||
1. `src/webdrop_bridge/__init__.py` - source of truth
|
||||
2. `pyproject.toml` - package version
|
||||
3. `.env.example` - environment example
|
||||
4. Run `scripts/sync_version.py` - manual sync step
|
||||
|
||||
This was error-prone and tedious.
|
||||
|
||||
## Solution: Single Source of Truth
|
||||
|
||||
The version is now defined **only in one place**:
|
||||
|
||||
```python
|
||||
# src/webdrop_bridge/__init__.py
|
||||
__version__ = "1.0.0"
|
||||
```
|
||||
|
||||
All other components automatically read from this single source.
|
||||
|
||||
## How It Works
|
||||
|
||||
### 1. **pyproject.toml** (Automatic)
|
||||
```toml
|
||||
[tool.setuptools.dynamic]
|
||||
version = {attr = "webdrop_bridge.__version__"}
|
||||
|
||||
[project]
|
||||
name = "webdrop-bridge"
|
||||
dynamic = ["version"] # Reads from __init__.py
|
||||
```
|
||||
|
||||
When you build the package, setuptools automatically extracts the version from `__init__.py`.
|
||||
|
||||
### 2. **config.py** (Automatic - with ENV override)
|
||||
```python
|
||||
# Lazy import to avoid circular imports
|
||||
if not os.getenv("APP_VERSION"):
|
||||
from webdrop_bridge import __version__
|
||||
app_version = __version__
|
||||
else:
|
||||
app_version = os.getenv("APP_VERSION")
|
||||
```
|
||||
|
||||
The config automatically reads from `__init__.py`, but can be overridden with the `APP_VERSION` environment variable if needed.
|
||||
|
||||
### 3. **sync_version.py** (Simplified)
|
||||
The script now only handles:
|
||||
- Updating `__init__.py` with a new version
|
||||
- Updating `CHANGELOG.md` with a new version header
|
||||
- Optional: updating `.env.example` if it explicitly sets `APP_VERSION`
|
||||
|
||||
It **no longer** needs to manually sync pyproject.toml or config defaults.
|
||||
|
||||
## Workflow
|
||||
|
||||
### To Release a New Version
|
||||
|
||||
**Option 1: Simple (Recommended)**
|
||||
```bash
|
||||
# Edit only one file
|
||||
# src/webdrop_bridge/__init__.py:
|
||||
__version__ = "1.1.0" # Change this
|
||||
|
||||
# Then run sync script to update changelog
|
||||
python scripts/sync_version.py
|
||||
```
|
||||
|
||||
**Option 2: Using the Sync Script**
|
||||
```bash
|
||||
python scripts/sync_version.py --version 1.1.0
|
||||
```
|
||||
|
||||
The script will:
|
||||
- ✅ Update `__init__.py`
|
||||
- ✅ Update `CHANGELOG.md`
|
||||
- ✅ (Optional) Update `.env.example` if it has `APP_VERSION=`
|
||||
|
||||
### What Happens Automatically
|
||||
|
||||
When you run your application:
|
||||
1. Config loads and checks environment for `APP_VERSION`
|
||||
2. If not set, it imports `__version__` from `__init__.py`
|
||||
3. The version is displayed in the UI
|
||||
4. Update checks use the correct version
|
||||
|
||||
When you build with `pip install`:
|
||||
1. setuptools reads `__version__` from `__init__.py`
|
||||
2. Package metadata is set automatically
|
||||
3. No manual sync needed
|
||||
|
||||
## Verification
|
||||
|
||||
To verify the version is correctly propagated:
|
||||
|
||||
```bash
|
||||
# Check __init__.py
|
||||
python -c "from webdrop_bridge import __version__; print(__version__)"
|
||||
|
||||
# Check config loading
|
||||
python -c "from webdrop_bridge.config import Config; c = Config.from_env(); print(c.app_version)"
|
||||
|
||||
# Check package metadata (after building)
|
||||
pip show webdrop-bridge
|
||||
```
|
||||
|
||||
All should show the same version.
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Always edit `__init__.py` first** - it's the single source of truth
|
||||
2. **Run `sync_version.py` to update changelog** - keeps release notes organized
|
||||
3. **Use environment variables only for testing** - don't hardcode overrides
|
||||
4. **Run tests after version changes** - config tests verify version loading
|
||||
|
||||
## Migration Notes
|
||||
|
||||
If you had other places where version was defined:
|
||||
- ❌ Remove version from `pyproject.toml` `[project]` section
|
||||
- ✅ Add `dynamic = ["version"]` instead
|
||||
- ❌ Don't manually edit `.env.example` for version
|
||||
- ✅ Let `sync_version.py` handle it
|
||||
- ❌ Don't hardcode version in config.py defaults
|
||||
- ✅ Use lazy import from `__init__.py`
|
||||
|
||||
## Testing the System
|
||||
|
||||
Run the config tests to verify everything works:
|
||||
```bash
|
||||
pytest tests/unit/test_config.py -v
|
||||
```
|
||||
|
||||
All tests should pass, confirming version loading works correctly.
|
||||
|
||||
---
|
||||
|
||||
**Result**: One place to change, multiple places automatically updated. Simple, clean, professional.
|
||||
Loading…
Add table
Add a link
Reference in a new issue