11#!/usr/bin/env python3
2+ """
3+ Version management script for Socket Basics.
4+
5+ This script:
6+ 1. Ensures version.py and pyproject.toml are in sync
7+ 2. Auto-bumps version on commits if unchanged
8+ 3. Automatically updates version references in:
9+ - README.md (GitHub Action versions and Docker build tags)
10+ - docs/github-action.md (all action version references)
11+ - docs/pre-commit-hook.md (Docker build tags)
12+
13+ Pattern matching:
14+ - GitHub Actions: SocketDev/[email protected] -> @vNEW_VERSION 15+ - Docker builds: docker build -t IMAGE_NAME -> docker build -t IMAGE_NAME:NEW_VERSION
16+
17+ Usage:
18+ - Normal commit: Will auto-bump patch version if unchanged
19+ - Dev mode: python3 .hooks/version-check.py --dev
20+ """
221import subprocess
322import pathlib
423import re
827
928VERSION_FILE = pathlib .Path ("socket_basics/version.py" )
1029PYPROJECT_FILE = pathlib .Path ("pyproject.toml" )
30+ README_FILES = [
31+ pathlib .Path ("README.md" ),
32+ pathlib .Path ("docs/github-action.md" ),
33+ pathlib .Path ("docs/pre-commit-hook.md" ),
34+ ]
1135
1236VERSION_PATTERN = re .compile (r"__version__\s*=\s*['\"]([^'\"]+)['\"]" )
1337PYPROJECT_PATTERN = re .compile (r'^version\s*=\s*"([^"]+)"$' , re .MULTILINE )
38+ # Pattern to match SocketDev/[email protected] or @vX.X.X 39+ ACTION_VERSION_PATTERN = re .compile (r'(SocketDev/socket-basics|socket-basics)@v\d+\.\d+\.\d+' )
40+ # Pattern to match docker build with version tag
41+ DOCKER_BUILD_PATTERN = re .compile (r'docker build -t (socketdev/socket-basics|socket-basics)(?::\d+\.\d+\.\d+)?' )
1442# Update this URL to match your actual PyPI package if you publish it
1543PYPI_API = "https://pypi.org/pypi/security-wrapper/json"
1644
@@ -71,6 +99,31 @@ def find_next_available_dev_version(base_version: str) -> str:
7199 print ("❌ Could not find available .devN slot after 100 attempts." )
72100 sys .exit (1 )
73101
102+ def update_readme_versions (version : str ):
103+ """Update version references in README files"""
104+ for readme_file in README_FILES :
105+ if not readme_file .exists ():
106+ print (f"⚠️ { readme_file } not found, skipping" )
107+ continue
108+
109+ content = readme_file .read_text ()
110+ original_content = content
111+
112+ # Update action version references (SocketDev/[email protected] ) 113+ content = ACTION_VERSION_PATTERN .sub (rf'\1@v{ version } ' , content )
114+
115+ # Update docker build commands to include version tag
116+ def docker_replacement (match ):
117+ image_name = match .group (1 )
118+ return f'docker build -t { image_name } :{ version } '
119+ content = DOCKER_BUILD_PATTERN .sub (docker_replacement , content )
120+
121+ if content != original_content :
122+ readme_file .write_text (content )
123+ print (f"✅ Updated version references in { readme_file } " )
124+ else :
125+ print (f"ℹ️ No version updates needed in { readme_file } " )
126+
74127def inject_version (version : str ):
75128 print (f"🔁 Updating version to: { version } " )
76129
@@ -85,6 +138,9 @@ def inject_version(version: str):
85138 print (f"✅ Updated { PYPROJECT_FILE } " )
86139 else :
87140 print (f"⚠️ Could not find version field in { PYPROJECT_FILE } " )
141+
142+ # Update README files with version references
143+ update_readme_versions (version )
88144
89145def check_version_sync ():
90146 """Ensure version.py and pyproject.toml are in sync"""
0 commit comments