-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathentrypoint.py
More file actions
107 lines (89 loc) · 3.45 KB
/
entrypoint.py
File metadata and controls
107 lines (89 loc) · 3.45 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
"""
Entrypoint for GitHub Metrics service.
Runs database migrations, optional webhook setup, and starts the Uvicorn server.
"""
import asyncio
import subprocess
import sys
import traceback
from pathlib import Path
import uvicorn
from simple_logger.logger import get_logger
from backend.config import get_config
from backend.webhook_setup import setup_webhooks
LOGGER = get_logger(name="backend.entrypoint")
def run_database_migrations() -> None:
"""Run Alembic database migrations.
Applies pending migrations with 'alembic upgrade head'.
Note: Migrations must be generated manually by developers:
alembic revision --autogenerate -m "Description"
Raises:
SystemExit: If migration fails (fail-fast behavior)
"""
try:
alembic_ini = Path(__file__).parent / "alembic.ini"
print("Applying database migrations...")
result = subprocess.run(
["uv", "run", "alembic", "-c", str(alembic_ini), "upgrade", "head"],
check=True,
capture_output=True,
text=True,
timeout=60,
cwd=Path(__file__).parent,
)
print(result.stdout)
if result.stderr:
print(result.stderr, file=sys.stderr)
print("Database migrations completed successfully")
except subprocess.CalledProcessError as e:
print(f"FATAL: Database migration failed: {e}", file=sys.stderr)
if e.stdout:
print(f"stdout: {e.stdout}", file=sys.stderr)
if e.stderr:
print(f"stderr: {e.stderr}", file=sys.stderr)
sys.exit(1)
except subprocess.TimeoutExpired:
print("FATAL: Database migration timed out after 60 seconds", file=sys.stderr)
sys.exit(1)
except Exception as e:
print(f"FATAL: Unexpected error during database migration: {e}\n{traceback.format_exc()}", file=sys.stderr)
sys.exit(1)
if __name__ == "__main__":
# Run database migrations
run_database_migrations()
# Setup webhooks if METRICS_SETUP_WEBHOOK=true
webhook_results = asyncio.run(setup_webhooks())
# Log webhook setup results
if webhook_results:
success_count = sum(1 for success, _ in webhook_results.values() if success)
failure_count = len(webhook_results) - success_count
if failure_count > 0:
LOGGER.warning(
"Webhook setup completed with failures: %d succeeded, %d failed",
success_count,
failure_count,
)
for repo, (success, message) in webhook_results.items():
if not success:
LOGGER.error("Webhook setup failed for %s: %s", repo, message)
else:
LOGGER.info("Webhook setup completed successfully for %d repositories", success_count)
# Load configuration
config = get_config()
# Start uvicorn server
# Note: workers and reload are mutually exclusive in uvicorn
reload_dirs = None
reload_includes = None
if config.server.reload:
# Watch Python files plus web UI files (templates, JS, CSS)
reload_dirs = [str(Path(__file__).parent / "backend")]
reload_includes = ["*.py", "*.html", "*.js", "*.css"]
uvicorn.run(
"backend.app:app",
host=config.server.host,
port=config.server.port,
workers=1 if config.server.reload else config.server.workers,
reload=config.server.reload,
reload_dirs=reload_dirs,
reload_includes=reload_includes,
)