- 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
92 lines
2.6 KiB
Python
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
|