178 lines
4.7 KiB
YAML
178 lines
4.7 KiB
YAML
name: CI/CD Pipeline
|
|
|
|
on:
|
|
push:
|
|
branches: [ main, dev, feature/* ]
|
|
pull_request:
|
|
branches: [ main, dev ]
|
|
|
|
jobs:
|
|
# ===== TESTING PHASE =====
|
|
test:
|
|
runs-on: ubuntu-latest
|
|
services:
|
|
redis:
|
|
image: redis:7-alpine
|
|
ports:
|
|
- 6379:6379
|
|
options: >-
|
|
--health-cmd "redis-cli ping"
|
|
--health-interval 10s
|
|
--health-timeout 5s
|
|
--health-retries 5
|
|
|
|
steps:
|
|
- name: Checkout code
|
|
uses: actions/checkout@v3
|
|
|
|
- name: Setup Python
|
|
uses: actions/setup-python@v4
|
|
with:
|
|
python-version: "3.13"
|
|
|
|
- name: Install uv
|
|
uses: astral-sh/setup-uv@v1
|
|
with:
|
|
version: "1.0.0"
|
|
|
|
- name: Cache dependencies
|
|
uses: actions/cache@v3
|
|
with:
|
|
path: |
|
|
.venv
|
|
.uv_cache
|
|
key: ${{ runner.os }}-uv-3.13-${{ hashFiles('**/uv.lock') }}
|
|
restore-keys: ${{ runner.os }}-uv-3.13-
|
|
|
|
- name: Install dependencies
|
|
run: |
|
|
uv sync --group dev
|
|
cd panel && npm ci && cd ..
|
|
|
|
- name: Setup test database
|
|
run: |
|
|
touch database.db
|
|
uv run python -c "
|
|
from orm.base import Base
|
|
from services.db import get_engine
|
|
engine = get_engine()
|
|
Base.metadata.create_all(engine)
|
|
print('Test database initialized')
|
|
"
|
|
|
|
- name: Start servers
|
|
run: |
|
|
chmod +x scripts/ci-server.py
|
|
timeout 300 python scripts/ci-server.py &
|
|
echo $! > ci-server.pid
|
|
|
|
echo "Waiting for servers..."
|
|
timeout 120 bash -c '
|
|
while ! (curl -f http://localhost:8000/ > /dev/null 2>&1 && \
|
|
curl -f http://localhost:3000/ > /dev/null 2>&1); do
|
|
sleep 2
|
|
done
|
|
echo "Servers ready!"
|
|
'
|
|
|
|
- name: Run tests
|
|
run: |
|
|
for test_type in "not e2e" "integration" "e2e" "browser"; do
|
|
echo "Running $test_type tests..."
|
|
uv run pytest tests/ -m "$test_type" -v --tb=short || \
|
|
if [ "$test_type" = "browser" ]; then echo "Browser tests failed (expected)"; else exit 1; fi
|
|
done
|
|
|
|
- name: Generate coverage
|
|
run: |
|
|
uv run pytest tests/ --cov=. --cov-report=xml --cov-report=html
|
|
|
|
- name: Upload coverage
|
|
uses: codecov/codecov-action@v3
|
|
with:
|
|
file: ./coverage.xml
|
|
fail_ci_if_error: false
|
|
|
|
- name: Cleanup
|
|
if: always()
|
|
run: |
|
|
[ -f ci-server.pid ] && kill $(cat ci-server.pid) 2>/dev/null || true
|
|
pkill -f "python dev.py|npm run dev|vite|ci-server.py" || true
|
|
rm -f backend.pid frontend.pid ci-server.pid
|
|
|
|
# ===== CODE QUALITY PHASE =====
|
|
quality:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- name: Checkout code
|
|
uses: actions/checkout@v3
|
|
|
|
- name: Setup Python
|
|
uses: actions/setup-python@v4
|
|
with:
|
|
python-version: "3.13"
|
|
|
|
- name: Install uv
|
|
uses: astral-sh/setup-uv@v1
|
|
with:
|
|
version: "1.0.0"
|
|
|
|
- name: Install dependencies
|
|
run: |
|
|
uv sync --group lint
|
|
uv sync --group dev
|
|
|
|
- name: Run quality checks
|
|
run: |
|
|
uv run ruff check .
|
|
uv run mypy . --strict
|
|
|
|
# ===== DEPLOYMENT PHASE =====
|
|
deploy:
|
|
runs-on: ubuntu-latest
|
|
needs: [test, quality]
|
|
if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/dev'
|
|
environment: production
|
|
|
|
steps:
|
|
- name: Checkout code
|
|
uses: actions/checkout@v3
|
|
with:
|
|
fetch-depth: 0
|
|
|
|
- name: Setup SSH
|
|
uses: webfactory/ssh-agent@v0.8.0
|
|
with:
|
|
ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }}
|
|
|
|
- name: Deploy
|
|
env:
|
|
HOST_KEY: ${{ secrets.HOST_KEY }}
|
|
TARGET: ${{ github.ref == 'refs/heads/main' && 'discoursio-api' || 'discoursio-api-staging' }}
|
|
ENV: ${{ github.ref == 'refs/heads/main' && 'PRODUCTION' || 'STAGING' }}
|
|
run: |
|
|
echo "🚀 Deploying to $ENV..."
|
|
mkdir -p ~/.ssh
|
|
echo "$HOST_KEY" > ~/.ssh/known_hosts
|
|
chmod 600 ~/.ssh/known_hosts
|
|
|
|
git remote add dokku dokku@v2.discours.io:$TARGET
|
|
git push dokku HEAD:main -f
|
|
|
|
echo "✅ $ENV deployment completed!"
|
|
|
|
# ===== SUMMARY =====
|
|
summary:
|
|
runs-on: ubuntu-latest
|
|
needs: [test, quality, deploy]
|
|
if: always()
|
|
steps:
|
|
- name: Pipeline Summary
|
|
run: |
|
|
echo "## 🎯 CI/CD Pipeline Summary" >> $GITHUB_STEP_SUMMARY
|
|
echo "" >> $GITHUB_STEP_SUMMARY
|
|
echo "### 📊 Test Results: ${{ needs.test.result }}" >> $GITHUB_STEP_SUMMARY
|
|
echo "### 🔍 Code Quality: ${{ needs.quality.result }}" >> $GITHUB_STEP_SUMMARY
|
|
echo "### 🚀 Deployment: ${{ needs.deploy.result || 'skipped' }}" >> $GITHUB_STEP_SUMMARY
|
|
echo "### 📈 Coverage: Generated (XML + HTML)" >> $GITHUB_STEP_SUMMARY
|