Skip to content

feat: Stage 2 Phase 1 - Meta-Learning Retention Tracking #917

feat: Stage 2 Phase 1 - Meta-Learning Retention Tracking

feat: Stage 2 Phase 1 - Meta-Learning Retention Tracking #917

Workflow file for this run

name: Tests
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main, develop ]
workflow_dispatch:
permissions:
contents: read
pull-requests: write
checks: write
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
test:
name: Test on Python ${{ matrix.python-version }}
runs-on: ubuntu-latest
timeout-minutes: 30
strategy:
fail-fast: false
matrix:
python-version: ["3.11", "3.12"]
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v6
with:
python-version: ${{ matrix.python-version }}
cache: 'pip'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
pip install pytest pytest-asyncio pytest-cov pytest-xdist
continue-on-error: false
- name: List test files
run: |
echo "Available test files:"
find tests -name "test_*.py" -type f | head -20
echo "Total test files:"
find tests -name "test_*.py" -type f | wc -l
- name: Run tests with coverage (Codecov format)
run: |
pytest tests/ \
--cov=backend \
--cov-branch \
--cov-report=xml \
--cov-report=term \
--cov-report=html \
--junit-xml=junit.xml \
-v \
--tb=short \
--maxfail=10
env:
ENVIRONMENT: test
DEEPSEEK_API_KEY: ${{ secrets.DEEPSEEK_API_KEY || 'test_key' }}
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY || 'test_key' }}
PYTHONPATH: ${{ github.workspace }}
continue-on-error: true
- name: Verify coverage.xml was created
run: |
if [ -f coverage.xml ]; then
echo "✅ coverage.xml exists"
ls -lh coverage.xml
echo "First 20 lines of coverage.xml:"
head -20 coverage.xml
else
echo "❌ coverage.xml not found!"
echo "Listing files in current directory:"
ls -la
echo "Listing files in tests directory:"
ls -la tests/ | head -10
exit 1
fi
continue-on-error: true
- name: Upload coverage to Codecov
if: hashFiles('coverage.xml') != ''
uses: codecov/codecov-action@v5
with:
file: ./coverage.xml
flags: unittests
name: codecov-umbrella
fail_ci_if_error: false
token: ${{ secrets.CODECOV_TOKEN }}
continue-on-error: true
- name: Upload test results
uses: actions/upload-artifact@v6
if: always()
with:
name: test-results-${{ matrix.python-version }}
path: |
junit.xml
htmlcov/
coverage.xml
retention-days: 7
if-no-files-found: ignore
- name: Publish test results
uses: EnricoMi/publish-unit-test-result-action@v2
if: always()
with:
files: junit.xml
check_name: "Test Results (Python ${{ matrix.python-version }})"
comment_mode: always
report_individual_runs: true
continue-on-error: true
docker-build:
name: Docker Build (no push)
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build Docker image (CHROMA_WARMUP=false)
run: |
docker build \
--build-arg CHROMA_WARMUP=false \
-t stillme-api:ci \
.
- name: Build Docker image (CHROMA_WARMUP=true)
run: |
docker build \
--build-arg CHROMA_WARMUP=true \
-t stillme-api:ci-warmup \
.
continue-on-error: true # Warmup may fail, but build should still work
- name: Smoke test built image
run: |
# Start container in background
docker run -d \
--name stillme-test \
-p 8000:8000 \
-e PORT=8000 \
-e ENVIRONMENT=test \
stillme-api:ci
# Wait for server to start
echo "Waiting for server to start..."
sleep 15
# Test /health endpoint
for i in {1..10}; do
if curl -f http://localhost:8000/health > /dev/null 2>&1; then
echo "✅ /health endpoint returned 200 OK"
curl -i http://localhost:8000/health
break
fi
echo "Waiting for /health endpoint... ($i/10)"
sleep 2
done
# Clean up
docker stop stillme-test || true
docker rm stillme-test || true
continue-on-error: true # Smoke test is optional
smoke-test:
name: Smoke Test (Health & Ready Endpoints)
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: "3.12"
cache: 'pip'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
pip install pytest httpx
- name: Start server in background
run: |
export PORT=8000
python start_backend.py &
SERVER_PID=$!
echo "SERVER_PID=$SERVER_PID" >> $GITHUB_ENV
# Wait for server to start
sleep 10
env:
ENVIRONMENT: test
PYTHONPATH: ${{ github.workspace }}
DEEPSEEK_API_KEY: ${{ secrets.DEEPSEEK_API_KEY || 'test_key' }}
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY || 'test_key' }}
- name: Test /health endpoint (liveness)
run: |
for i in {1..30}; do
if curl -f http://localhost:8000/health > /dev/null 2>&1; then
echo "✅ /health endpoint returned 200 OK"
curl -i http://localhost:8000/health
exit 0
fi
echo "Waiting for /health endpoint... ($i/30)"
sleep 2
done
echo "❌ /health endpoint did not return 200 after 60 seconds"
exit 1
- name: Test /ready endpoint (readiness)
run: |
response=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:8000/ready)
echo "Response code: $response"
if [ "$response" = "200" ] || [ "$response" = "503" ]; then
echo "✅ /ready endpoint returned $response (expected 200 or 503)"
curl -i http://localhost:8000/ready
else
echo "❌ /ready endpoint returned unexpected status: $response"
exit 1
fi
- name: Stop server
if: always()
run: |
if [ -n "$SERVER_PID" ]; then
kill $SERVER_PID || true
fi
pkill -f "python start_backend.py" || true
coverage:
name: Coverage Report
runs-on: ubuntu-latest
needs: test
if: github.event_name == 'pull_request'
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: "3.12"
cache: 'pip'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
pip install pytest pytest-asyncio pytest-cov
- name: Generate coverage report
run: |
pytest tests/ \
--cov=backend \
--cov-branch \
--cov-report=term \
--cov-report=html \
-v
env:
ENVIRONMENT: test
PYTHONPATH: ${{ github.workspace }}
- name: Comment PR with coverage
uses: py-cov-action/python-coverage-comment-action@v3
if: github.event_name == 'pull_request'
with:
GITHUB_TOKEN: ${{ github.token }}
MINIMUM_GREEN: 40
MINIMUM_ORANGE: 30