Files
claudetools/api/routers/version.py
Mike Swanson a6eedc1b77 Add deployment safeguards to prevent code mismatch issues
- Add /api/version endpoint with git commit and file checksums
- Create automated deploy.ps1 script with pre-flight checks
- Document file dependencies to prevent partial deployments
- Add version verification before and after deployment

Prevents: 4-hour debugging sessions due to production/local mismatch
Ensures: All dependent files deploy together atomically
Verifies: Production matches local code after deployment
2026-01-18 15:13:47 -07:00

92 lines
2.6 KiB
Python

"""
Version endpoint for ClaudeTools API.
Returns version information to detect code mismatches.
"""
from fastapi import APIRouter
from datetime import datetime
import subprocess
import os
router = APIRouter()
@router.get(
"/version",
response_model=dict,
summary="Get API version information",
description="Returns version, git commit, and deployment timestamp",
)
def get_version():
"""
Get API version information.
Returns:
dict: Version info including git commit, branch, deployment time
"""
version_info = {
"api_version": "1.0.0",
"component": "claudetools-api",
"deployment_timestamp": datetime.utcnow().isoformat() + "Z"
}
# Try to get git information
try:
# Get current commit hash
result = subprocess.run(
["git", "rev-parse", "HEAD"],
capture_output=True,
text=True,
timeout=5,
cwd=os.path.dirname(os.path.dirname(__file__))
)
if result.returncode == 0:
version_info["git_commit"] = result.stdout.strip()
version_info["git_commit_short"] = result.stdout.strip()[:7]
# Get current branch
result = subprocess.run(
["git", "rev-parse", "--abbrev-ref", "HEAD"],
capture_output=True,
text=True,
timeout=5,
cwd=os.path.dirname(os.path.dirname(__file__))
)
if result.returncode == 0:
version_info["git_branch"] = result.stdout.strip()
# Get last commit date
result = subprocess.run(
["git", "log", "-1", "--format=%ci"],
capture_output=True,
text=True,
timeout=5,
cwd=os.path.dirname(os.path.dirname(__file__))
)
if result.returncode == 0:
version_info["last_commit_date"] = result.stdout.strip()
except Exception:
version_info["git_info"] = "Not available (not a git repository)"
# Add file checksums for critical files
import hashlib
critical_files = [
"api/routers/conversation_contexts.py",
"api/services/conversation_context_service.py"
]
checksums = {}
base_dir = os.path.dirname(os.path.dirname(__file__))
for file_path in critical_files:
full_path = os.path.join(base_dir, file_path)
try:
with open(full_path, 'rb') as f:
checksums[file_path] = hashlib.md5(f.read()).hexdigest()[:8]
except Exception:
checksums[file_path] = "not_found"
version_info["file_checksums"] = checksums
return version_info