name: CI/CD Pipeline on: push: branches: [main, develop] pull_request: branches: [main, develop] jobs: backend: name: Backend Build & Test runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Set up JDK 21 uses: actions/setup-java@v4 with: java-version: '21' distribution: 'temurin' cache: maven working-directory: backend - name: Build and Test working-directory: backend run: mvn verify -B - name: Upload Test Results if: always() uses: actions/upload-artifact@v4 with: name: backend-test-results path: backend/target/surefire-reports/ admin-web: name: Admin Web Build runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Set up Node.js uses: actions/setup-node@v4 with: node-version: '20' cache: 'pnpm' cache-dependency-path: admin-web/pnpm-lock.yaml - name: Install Dependencies working-directory: admin-web run: pnpm install --frozen-lockfile - name: Build working-directory: admin-web run: pnpm build miniapp: name: Mini Program Compile Check runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Set up Node.js uses: actions/setup-node@v4 with: node-version: '20' - name: Install Dependencies working-directory: miniapp run: npm install - name: TypeScript Compile Check working-directory: miniapp run: npx tsc --noEmit migration: name: Migration Validation runs-on: ubuntu-latest needs: [backend] steps: - uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v5 with: python-version: '3.11' # Phase 23 KEEP-VERIFY:本步骤原注释称「验证 migration SQL 语法」,实际只检查文件非空, # 属名不副实的假校验(SQL 语法与基线表完整性由后端测试 MigrationValidationTest 覆盖, # 该测试随 backend job 的 `mvn verify` 运行)。现改为该测试未覆盖的**序列**校验。 - name: 迁移序列校验(命名 / 非空 / 版本号唯一 / 无缺号) run: | python3 - <<'PY' import re, sys, pathlib, collections d = pathlib.Path("backend/src/main/resources/db/migration") files = sorted(d.glob("V*.sql")) if not files: sys.exit("ERROR: 未找到任何迁移文件") vers, bad_name, empty = [], [], [] for f in files: m = re.match(r"V(\d+)__", f.name) if not m: bad_name.append(f.name) continue if f.stat().st_size == 0: empty.append(f.name) vers.append(int(m.group(1))) problems = [] if bad_name: problems.append(f"迁移文件命名不合规(应为 V<序号>__<描述>.sql): {bad_name}") if empty: problems.append(f"空迁移文件: {empty}") dups = sorted(v for v, c in collections.Counter(vers).items() if c > 1) if dups: problems.append(f"迁移版本号重复: {dups}") gaps = [v for v in range(min(vers), max(vers) + 1) if v not in set(vers)] if gaps: problems.append(f"迁移版本号缺号: {gaps}") if problems: for p in problems: print("ERROR: " + p, file=sys.stderr) sys.exit(1) print(f"OK: {len(files)} 个迁移文件,版本 {min(vers)}~{max(vers)} 连续且唯一") PY test-shell-guard: name: Test Shell Guard (Phase 23 Gate) runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v5 with: python-version: '3.11' # Phase 23 Gate:「不允许 skip/pass 空壳」。 # 机械阻断空壳回归 —— 详见 scripts/check-no-empty-tests.py。 - name: 禁止 skip/pass 空壳测试 run: python3 scripts/check-no-empty-tests.py tests