Skip to content

Commit d60e957

Browse files
rolfedhclaude
andcommitted
feat: Implement single-source versioning
- Version now maintained only in pyproject.toml - __init__.py dynamically reads version from pyproject.toml - Tests no longer hardcode version numbers - Add release.py script for complete release automation - Add bump-version.py for simple version updates - Update scripts README with new tools The release.py script automates the entire release process: 1. Bump version (major/minor/patch) 2. Run tests 3. Build and upload to PyPI 4. Create git commit and tag 5. Create GitHub release This eliminates the need to update version in multiple places. Fixes #18 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 763e92b commit d60e957

File tree

6 files changed

+425
-12
lines changed

6 files changed

+425
-12
lines changed

CLAUDE.md

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -308,26 +308,26 @@ A comprehensive test suite prevents Jekyll deployment failures:
308308
## Recent Development Focus (July 2025)
309309
310310
### Statistics
311-
- Total commits: 198
311+
- Total commits: 220
312312
313313
### Latest Achievements
314+
- ✅ Implement single-source versioning.
314315
- ✅ Add intermediate recheck step and fix accurate fix counting in journey workflow.
315316
- ✅ Add vale configuration and update asciidocdita styles for improved validation.
316317
- ✅ Reintroduce claude.md updater workflow with enhanced commit parsing.
317318
- ✅ Improve directory selection ui for better user experience.
318-
- ✅ Add demo script for getting started with aditi toolkit.
319319
320320
### Development Focus
321-
- **Ci/Cd**: 79 commits
322-
- **Features**: 22 commits
323-
- **Documentation**: 16 commits
324-
- **Bug Fixes**: 15 commits
325-
- **Testing**: 11 commits
321+
- **Ci/Cd**: 89 commits
322+
- **Features**: 23 commits
323+
- **Bug Fixes**: 18 commits
324+
- **Documentation**: 17 commits
325+
- **Testing**: 12 commits
326326
327327
### Most Active Files
328-
- `docs/_data/recent_commits.yml`: 76 changes
329-
- `CLAUDE.md`: 58 changes
330-
- `src/aditi/commands/journey.py`: 18 changes
328+
- `docs/_data/recent_commits.yml`: 85 changes
329+
- `CLAUDE.md`: 63 changes
330+
- `src/aditi/commands/journey.py`: 19 changes
331331
<!-- /AUTO-GENERATED:RECENT -->
332332
333333
## Building and Publishing

scripts/README.md

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,60 @@
22

33
Utility scripts for the Aditi project.
44

5+
## Release Management
6+
7+
### 🚀 release.py
8+
**Complete release automation script** - Handles the entire release process in one command.
9+
10+
```bash
11+
# Bump patch version and release (0.1.7 → 0.1.8)
12+
python scripts/release.py patch
13+
14+
# Bump minor version and release (0.1.7 → 0.2.0)
15+
python scripts/release.py minor
16+
17+
# Bump major version and release (0.1.7 → 1.0.0)
18+
python scripts/release.py major
19+
20+
# Dry run to see what would happen
21+
python scripts/release.py patch --dry-run
22+
23+
# Skip tests during release
24+
python scripts/release.py patch --skip-tests
25+
26+
# Only do git operations (no PyPI upload)
27+
python scripts/release.py patch --skip-pypi
28+
```
29+
30+
**What it does:**
31+
1. Bumps version in `pyproject.toml` (single source of truth!)
32+
2. Runs tests
33+
3. Builds the package
34+
4. Uploads to PyPI
35+
5. Creates git commit and tag
36+
6. Pushes to GitHub
37+
7. Creates GitHub release
38+
39+
### 📝 bump-version.py
40+
**Simple version bump script** - Only updates the version number.
41+
42+
```bash
43+
# Show current version
44+
python scripts/bump-version.py
45+
46+
# Bump patch version (0.1.7 → 0.1.8)
47+
python scripts/bump-version.py patch
48+
49+
# Bump minor version (0.1.7 → 0.2.0)
50+
python scripts/bump-version.py minor
51+
52+
# Set specific version
53+
python scripts/bump-version.py --set 1.2.3
54+
```
55+
56+
### 📦 publish-to-pypi.sh (Legacy)
57+
**Note:** This script is being replaced by `release.py`. It still works but requires manual version updates in multiple files.
58+
559
## Blog Post Creation
660

761
### `new-blog-post.sh`

scripts/bump-version.py

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
#!/usr/bin/env python3
2+
"""
3+
Simple version bump script for Aditi.
4+
5+
This script only bumps the version in pyproject.toml.
6+
Use this when you want to bump the version without doing a full release.
7+
"""
8+
9+
import argparse
10+
import sys
11+
import re
12+
from pathlib import Path
13+
14+
try:
15+
import tomllib
16+
except ImportError:
17+
try:
18+
import tomli as tomllib
19+
except ImportError:
20+
print("Error: tomli/tomllib not found. Install with: pip install tomli")
21+
sys.exit(1)
22+
23+
24+
def get_current_version():
25+
"""Get current version from pyproject.toml."""
26+
with open("pyproject.toml", "rb") as f:
27+
data = tomllib.load(f)
28+
return data["project"]["version"]
29+
30+
31+
def bump_version(version, bump_type):
32+
"""Bump version based on type (major, minor, patch)."""
33+
parts = version.split(".")
34+
major, minor, patch = int(parts[0]), int(parts[1]), int(parts[2])
35+
36+
if bump_type == "major":
37+
return f"{major + 1}.0.0"
38+
elif bump_type == "minor":
39+
return f"{major}.{minor + 1}.0"
40+
else: # patch
41+
return f"{major}.{minor}.{patch + 1}"
42+
43+
44+
def update_version_in_file(file_path, old_version, new_version):
45+
"""Update version in a file."""
46+
content = file_path.read_text()
47+
# Match version = "x.y.z" pattern
48+
pattern = f'version = "{re.escape(old_version)}"'
49+
replacement = f'version = "{new_version}"'
50+
51+
if pattern in content:
52+
new_content = content.replace(pattern, replacement)
53+
file_path.write_text(new_content)
54+
return True
55+
return False
56+
57+
58+
def main():
59+
parser = argparse.ArgumentParser(description="Bump Aditi version")
60+
parser.add_argument(
61+
"bump_type",
62+
choices=["major", "minor", "patch"],
63+
nargs="?",
64+
help="Version bump type (optional - will show current version if not provided)"
65+
)
66+
parser.add_argument(
67+
"--set",
68+
help="Set version to a specific value (e.g., --set 1.2.3)"
69+
)
70+
71+
args = parser.parse_args()
72+
73+
# Check we're in the right directory
74+
if not Path("pyproject.toml").exists():
75+
print("❌ Error: pyproject.toml not found. Are you in the project root?")
76+
sys.exit(1)
77+
78+
# Get current version
79+
current_version = get_current_version()
80+
81+
# If no arguments, just show current version
82+
if not args.bump_type and not args.set:
83+
print(f"Current version: {current_version}")
84+
print("\nUsage:")
85+
print(" Bump version: python scripts/bump-version.py [major|minor|patch]")
86+
print(" Set version: python scripts/bump-version.py --set 1.2.3")
87+
return
88+
89+
# Determine new version
90+
if args.set:
91+
new_version = args.set
92+
# Validate version format
93+
if not re.match(r'^\d+\.\d+\.\d+$', new_version):
94+
print(f"❌ Invalid version format: {new_version}")
95+
print("Version must be in format X.Y.Z (e.g., 1.2.3)")
96+
sys.exit(1)
97+
else:
98+
new_version = bump_version(current_version, args.bump_type)
99+
100+
print(f"🔄 Bumping version from {current_version} to {new_version}")
101+
102+
# Update version in pyproject.toml
103+
if not update_version_in_file(Path("pyproject.toml"), current_version, new_version):
104+
print("❌ Failed to update version in pyproject.toml")
105+
sys.exit(1)
106+
107+
print(f"✅ Version updated to {new_version} in pyproject.toml")
108+
print("\nNext steps:")
109+
print(" 1. Review the change: git diff pyproject.toml")
110+
print(" 2. Run tests: pytest")
111+
print(f" 3. Full release: python scripts/release.py patch")
112+
113+
114+
if __name__ == "__main__":
115+
main()

0 commit comments

Comments
 (0)