Skip to content

Commit f77a660

Browse files
committed
Add CI workflow with smoke test for module imports
1 parent c0fa6e3 commit f77a660

File tree

6 files changed

+119
-11
lines changed

6 files changed

+119
-11
lines changed

.github/workflows/ci.yml

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [ main, develop ]
6+
pull_request:
7+
branches: [ main, develop ]
8+
9+
jobs:
10+
test:
11+
runs-on: ubuntu-latest
12+
strategy:
13+
matrix:
14+
python-version: [3.9, 3.10, 3.11]
15+
16+
steps:
17+
- name: Checkout code
18+
uses: actions/checkout@v4
19+
20+
- name: Set up Python ${{ matrix.python-version }}
21+
uses: actions/setup-python@v4
22+
with:
23+
python-version: ${{ matrix.python-version }}
24+
25+
- name: Cache pip dependencies
26+
uses: actions/cache@v3
27+
with:
28+
path: ~/.cache/pip
29+
key: ${{ runner.os }}-pip-${{ hashFiles('backend/requirements.txt') }}
30+
restore-keys: |
31+
${{ runner.os }}-pip-
32+
33+
- name: Install dependencies
34+
run: |
35+
python -m pip install --upgrade pip
36+
cd backend
37+
pip install -r requirements.txt
38+
39+
- name: Smoke test - Verify module imports
40+
run: |
41+
export PYTHONPATH=backend
42+
python - <<'PY'
43+
# Test imports for relocated modules
44+
try:
45+
from app.agents.state import AgentState
46+
print("AgentState import successful")
47+
except ImportError as e:
48+
print(f"AgentState import failed: {e}")
49+
exit(1)
50+
51+
try:
52+
from app.agents.devrel.nodes.summarization import store_summary_to_database
53+
print("store_summary_to_database import successful")
54+
except ImportError as e:
55+
print(f"store_summary_to_database import failed: {e}")
56+
exit(1)
57+
58+
print("🎉 All smoke test imports successful!")
59+
PY
60+
61+
- name: Run tests
62+
run: |
63+
export PYTHONPATH=backend
64+
cd backend
65+
# Add actual test commands here when tests are available
66+
# python -m pytest tests/ -v
67+
echo "Test placeholder - add actual test commands when available"
68+
69+
lint:
70+
runs-on: ubuntu-latest
71+
steps:
72+
- name: Checkout code
73+
uses: actions/checkout@v4
74+
75+
- name: Set up Python
76+
uses: actions/setup-python@v4
77+
with:
78+
python-version: 3.11
79+
80+
- name: Install linting dependencies
81+
run: |
82+
python -m pip install --upgrade pip
83+
pip install flake8 black isort
84+
85+
- name: Run linting checks
86+
run: |
87+
cd backend
88+
# Check code formatting
89+
black --check --diff .
90+
# Check import sorting
91+
isort --check-only --diff .
92+
# Run flake8 linting
93+
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics

backend/app/agents/devrel/nodes/handlers/__init__.py

Whitespace-only changes.

backend/app/agents/devrel/nodes/handlers/web_search.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
from typing import Dict, Any
33
from app.agents.state import AgentState
44
from langchain_core.messages import HumanMessage
5-
from ...prompts.search_prompt import EXTRACT_SEARCH_QUERY_PROMPT
5+
from app.agents.devrel.prompts.search_prompt import EXTRACT_SEARCH_QUERY_PROMPT
6+
67

78
logger = logging.getLogger(__name__)
89

backend/app/api/v1/health.py

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,18 @@
11
import logging
2-
from fastapi import APIRouter, HTTPException
2+
from fastapi import APIRouter, HTTPException, Depends
33
from app.database.weaviate.client import get_weaviate_client
4+
from app.core.dependencies import get_app_instance
5+
from typing import TYPE_CHECKING
6+
7+
if TYPE_CHECKING:
8+
from main import DevRAIApplication
49

510
router = APIRouter()
611
logger = logging.getLogger(__name__)
712

813

914
@router.get("/health")
10-
async def health_check():
15+
async def health_check(app_instance: "DevRAIApplication" = Depends(get_app_instance)):
1116
"""
1217
General health check endpoint to verify services are running.
1318
@@ -18,8 +23,6 @@ async def health_check():
1823
async with get_weaviate_client() as client:
1924
weaviate_ready = await client.is_ready()
2025

21-
from main import app_instance
22-
2326
return {
2427
"status": "healthy",
2528
"services": {
@@ -35,7 +38,7 @@ async def health_check():
3538
"status": "unhealthy",
3639
"error": str(e)
3740
}
38-
)
41+
) from e
3942

4043

4144
@router.get("/health/weaviate")
@@ -58,15 +61,13 @@ async def weaviate_health():
5861
"status": "unhealthy",
5962
"error": str(e)
6063
}
61-
)
64+
) from e
6265

6366

6467
@router.get("/health/discord")
65-
async def discord_health():
68+
async def discord_health(app_instance: "DevRAIApplication" = Depends(get_app_instance)):
6669
"""Check specifically Discord bot health."""
6770
try:
68-
from main import app_instance
69-
7071
bot_status = "running" if app_instance.discord_bot and not app_instance.discord_bot.is_closed() else "stopped"
7172

7273
return {
@@ -82,4 +83,4 @@ async def discord_health():
8283
"status": "unhealthy",
8384
"error": str(e)
8485
}
85-
)
86+
) from e

backend/app/core/dependencies.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
from fastapi import Request
2+
from typing import TYPE_CHECKING
3+
4+
if TYPE_CHECKING:
5+
from main import DevRAIApplication
6+
7+
async def get_app_instance(request: Request) -> "DevRAIApplication":
8+
"""
9+
Dependency to get the application instance from FastAPI's state.
10+
This avoids circular imports by using dependency injection.
11+
"""
12+
return request.app.state.app_instance

backend/main.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ async def lifespan(app: FastAPI):
9191
"""
9292
Lifespan manager for the FastAPI application. Handles startup and shutdown events.
9393
"""
94+
app.state.app_instance = app_instance
9495
await app_instance.start_background_tasks()
9596
yield
9697
await app_instance.stop_background_tasks()

0 commit comments

Comments
 (0)