# 架构文档 §16.2:这些防线是机器可执行的检查,任一失败即阻断合并。 name: CI on: push: branches: [main] pull_request: workflow_dispatch: concurrency: group: ci-${{ github.ref }} cancel-in-progress: true env: UV_CACHE_DIR: /tmp/.uv-cache jobs: quality-gate: name: lint / typecheck / import-linter / tests / secrets runs-on: ubuntu-latest timeout-minutes: 20 services: postgres: image: pgvector/pgvector:pg16 env: POSTGRES_USER: meida POSTGRES_PASSWORD: meida POSTGRES_DB: meida_test ports: ["5432:5432"] options: >- --health-cmd "pg_isready -U meida" --health-interval 5s --health-timeout 5s --health-retries 20 redis: image: redis:7-alpine ports: ["6379:6379"] options: >- --health-cmd "redis-cli ping" --health-interval 5s --health-timeout 5s --health-retries 20 env: APP_ENV: dev JWT_SECRET: ci-only-not-a-real-secret-0123456789abcdef DATABASE_URL: postgresql+asyncpg://meida:meida@localhost:5432/meida_test REDIS_URL: redis://localhost:6379/0 CELERY_BROKER_URL: redis://localhost:6379/1 CELERY_RESULT_BACKEND: redis://localhost:6379/2 DEEPSEEK_API_KEY: ci-placeholder-no-network-calls-in-ci steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - name: Install uv uses: astral-sh/setup-uv@v5 with: enable-cache: true - name: Set up Python 3.12 run: uv python install 3.12 - name: Install dependencies run: uv sync --extra dev --frozen # --- 防线 1: 静态检查 (ruff lint + format) --- - name: Ruff lint run: uv run ruff check --output-format=github . - name: Ruff format check run: uv run ruff format --check . # --- 防线 2: mypy strict 覆盖 packages/domain 与 packages/llm --- - name: Mypy (strict scope) run: uv run mypy packages/domain packages/llm - name: Mypy (remaining scope) run: uv run mypy apps packages/shared packages/identity packages/billing packages/task packages/agent packages/compliance # --- 防线 3: 分层依赖检查 (架构文档 §4.2) --- - name: Import contracts run: uv run lint-imports --verbose # --- 防线 4: 单元测试 + 覆盖率 --- - name: Pytest run: uv run pytest --cov-report=xml # --- 防线 5: 数据库迁移必须可正向执行并可回滚 (T-P1-06) --- - name: Alembic upgrade/downgrade round-trip run: | uv run alembic upgrade head uv run alembic downgrade base uv run alembic upgrade head # --- 防线 6: 敏感信息扫描 --- - name: Secrets scan (detect-secrets) run: | uv run detect-secrets scan --baseline .secrets.baseline git diff --exit-code .secrets.baseline - name: Gitleaks uses: gitleaks/gitleaks-action@v2 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Upload coverage if: always() uses: actions/upload-artifact@v4 with: name: coverage path: coverage.xml if-no-files-found: ignore