Files
awoooi/.github/workflows/ci.yaml
OG T 77c6bf349c perf(ci): Skip Docker Verify on main push - PR only
CI 優化: Docker Verify 改為只在 PR 時執行
- main push 跳過 (CD 會構建)
- 預估省下 10-15 分鐘

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-24 23:01:46 +08:00

266 lines
7.3 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# =============================================================================
# AWOOOI CI Pipeline v2.0 (沿用 AIOPS 最佳實踐)
# =============================================================================
name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
workflow_dispatch:
concurrency:
group: ci-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
env:
NODE_VERSION: '20'
PNPM_VERSION: '9'
PYTHON_VERSION: '3.11'
# OTEL CI/CD 監控 (2026-03-24 批准)
OTEL_EXPORTER_OTLP_ENDPOINT: http://192.168.0.121:4318
OTEL_SERVICE_NAME: awoooi-ci
OTEL_RESOURCE_ATTRIBUTES: service.version=${{ github.sha }},deployment.environment=ci
jobs:
# ==================== Pre-flight (10s Fail-Fast) ====================
pre-flight:
name: "Pre-flight"
runs-on: [self-hosted, harbor, k8s]
timeout-minutes: 1
steps:
- name: Quick sanity check
run: |
echo "✅ Runner 可用"
node --version || echo "⚠️ Node not found"
python3 --version || echo "⚠️ Python not found"
# ==================== Lint & Type Check ====================
lint:
name: Lint & Type Check
runs-on: [self-hosted, harbor, k8s]
needs: pre-flight
timeout-minutes: 10
steps:
- uses: actions/checkout@v4
- name: Setup pnpm
uses: pnpm/action-setup@v3
with:
version: ${{ env.PNPM_VERSION }}
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'pnpm'
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Lint
run: pnpm lint
- name: Type check
run: pnpm typecheck
- name: ADR Compliance Check
run: |
echo "🔍 檢查 ADR 規定..."
# 檢查 1: 前端禁止直連資料庫 (ADR-005)
if grep -rE "psycopg2|asyncpg|redis|sqlalchemy|pg|ioredis" apps/web/src/ 2>/dev/null; then
echo "❌ ADR-005 違規: 前端禁止直連資料庫"
exit 1
fi
# 檢查 2: 禁止 Redux (ADR-004)
if grep -rE "@reduxjs/toolkit|react-redux" apps/web/package.json 2>/dev/null; then
echo "❌ ADR-004 違規: 禁止 Redux"
exit 1
fi
# 檢查 3: 禁止 import 舊專案
if grep -rE "from ['\"].*wooo-aiops" apps/ packages/ 2>/dev/null; then
echo "❌ 禁止 import 舊專案"
exit 1
fi
echo "✅ ADR 檢查通過"
# ==================== Test ====================
test:
name: Test
runs-on: [self-hosted, harbor, k8s]
needs: lint
timeout-minutes: 15
steps:
- uses: actions/checkout@v4
- name: Setup pnpm
uses: pnpm/action-setup@v3
with:
version: ${{ env.PNPM_VERSION }}
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'pnpm'
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Run tests
run: pnpm test
continue-on-error: true
- name: Upload coverage
uses: codecov/codecov-action@v4
with:
token: ${{ secrets.CODECOV_TOKEN }}
fail_ci_if_error: false
# ==================== Build ====================
build:
name: Build
runs-on: [self-hosted, harbor, k8s]
needs: lint
timeout-minutes: 15
steps:
- uses: actions/checkout@v4
- name: Setup pnpm
uses: pnpm/action-setup@v3
with:
version: ${{ env.PNPM_VERSION }}
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'pnpm'
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Setup Turborepo Cache
uses: dtinth/setup-github-actions-caching-for-turbo@v1
- name: Build packages
env:
NEXT_PUBLIC_API_URL: https://awoooi.wooo.work
# Sentry DSN (透過 /api/sentry-tunnel 避免區域網路權限問題)
NEXT_PUBLIC_SENTRY_DSN: http://da02d4e5d6542e4d1ed6b2dd6542efeb@192.168.0.110:9000/2
run: pnpm turbo build
- name: Upload build artifacts
uses: actions/upload-artifact@v4
with:
name: build-artifacts
path: |
apps/*/dist
packages/*/dist
retention-days: 7
# ==================== API Lint (Python) ====================
api-lint:
name: API Lint
runs-on: [self-hosted, harbor, k8s]
needs: pre-flight
timeout-minutes: 5
steps:
- uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: ${{ env.PYTHON_VERSION }}
- name: Install uv
uses: astral-sh/setup-uv@v3
- name: Install & Lint
working-directory: apps/api
run: |
uv sync
uv run ruff check .
- name: Type check
working-directory: apps/api
run: uv run mypy src/ --exclude 'tests/|scripts/' || true
continue-on-error: true
# ==================== API Test ====================
api-test:
name: API Test
runs-on: [self-hosted, harbor, k8s]
needs: api-lint
timeout-minutes: 10
steps:
- uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: ${{ env.PYTHON_VERSION }}
- name: Install uv
uses: astral-sh/setup-uv@v3
- name: Install & Test
working-directory: apps/api
env:
PYTHONPATH: ${{ github.workspace }}/apps/api
run: |
uv sync
uv run pytest tests/ --cov=src --cov-report=xml -v || true
continue-on-error: true
# ==================== OpenAPI Validation ====================
openapi-validate:
name: OpenAPI Validate
runs-on: [self-hosted, harbor, k8s]
needs: pre-flight
timeout-minutes: 3
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
- name: Validate
run: |
npm install -g @stoplight/spectral-cli
spectral lint docs/api/api-contract.yaml || true
# ==================== Docker Build Verify ====================
# 🚀 優化 (2026-03-24): 只在 PR 時執行main push 跳過 (CD 會構建)
docker-build:
name: Docker Verify
runs-on: [self-hosted, harbor, k8s]
needs: [test, api-test, build]
if: github.event_name == 'pull_request'
timeout-minutes: 20
strategy:
matrix:
app: [web, api]
steps:
- uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build (no push)
uses: docker/build-push-action@v5
with:
context: .
file: apps/${{ matrix.app }}/Dockerfile
push: false
tags: awoooi-${{ matrix.app }}:test
build-args: |
NEXT_PUBLIC_API_URL=https://awoooi.wooo.work
NEXT_PUBLIC_SENTRY_DSN=http://da02d4e5d6542e4d1ed6b2dd6542efeb@192.168.0.110:9000/2
cache-from: type=gha
cache-to: type=gha,mode=max