# CI 管道 — moziplus v2.0 # # 触发条件: # - push(非 main 分支)→ 快速门控(lint + unit test) # - pull_request(opened, synchronize)→ 同上 # # 注意:main 分支的 CI 由 deploy.yml 负责(完整 CI + 部署) # # Gitea v1.23.4 限制注意: # - 不支持 failure() 表达式,用 always() + shell 条件判断替代 # - 不支持 concurrency / continue-on-error / timeout-minutes / permissions # - 无内置 CI_TOKEN,需手动配置 PAT 为 secret # - runs-on 只支持单个 label name: CI on: push: branches: - '**' - '!main' pull_request: types: [opened, synchronize] jobs: # ── Job 1: Lint ────────────────────────────────────── lint: runs-on: macos-arm64 steps: - uses: actions/checkout@v4 - name: Setup Python run: | python3 -m venv .venv .venv/bin/pip install --quiet ruff - name: Lint with ruff run: | test -d src && .venv/bin/ruff check src/ || echo "No src/ directory, skipping lint" # ── Job 2: Test ────────────────────────────────────── test: runs-on: macos-arm64 needs: lint steps: - uses: actions/checkout@v4 - name: Setup Python run: | python3 -m venv .venv if [ -f pyproject.toml ]; then .venv/bin/pip install --quiet -e ".[dev]" else echo "No pyproject.toml, skipping dev install" fi - name: Run tests (exclude E2E) run: | if [ -d tests ]; then .venv/bin/pytest tests/ -m "not e2e" -x -q else echo "No tests/ directory, skipping tests" fi # ── Job 3: CI 失败通知 ─────────────────────────────── # v1.23 不支持 failure(),用 always() + shell 检查 commit status 替代 notify-on-failure: runs-on: macos-arm64 needs: [lint, test] if: always() steps: - name: Check results and notify env: CI_TOKEN: ${{ secrets.CI_TOKEN }} run: | # 查询当前 commit 的 status STATUS=$(curl -sf \ -H "Authorization: token $CI_TOKEN" \ "${{ gitea.api_url }}/repos/${{ gitea.repository }}/commits/${{ gitea.sha }}/status" \ | python3 -c "import sys,json; print(json.load(sys.stdin).get('state',''))" 2>/dev/null || echo "") echo "Commit status: $STATUS" if [ "$STATUS" != "success" ]; then echo "CI failed or status unknown, sending notification..." # 如果是 PR 事件,写评论通知 PR_NUMBER="${{ gitea.event.pull_request.number }}" if [ -n "$PR_NUMBER" ]; then curl -sf -X POST \ -H "Authorization: token $CI_TOKEN" \ -H "Content-Type: application/json" \ "${{ gitea.api_url }}/repos/${{ gitea.repository }}/issues/${PR_NUMBER}/comments" \ -d "{\"body\": \"❌ **CI 失败**\\n\\n请检查 CI 日志并修复。\\n\\n触发 commit: \`${{ gitea.sha }}\`\"}" \ || echo "Failed to post PR comment" echo "PR comment posted." else # 非 PR 事件(push 分支),创建 Issue 通知 BRANCH="${{ gitea.ref_name }}" curl -sf -X POST \ -H "Authorization: token $CI_TOKEN" \ -H "Content-Type: application/json" \ "${{ gitea.api_url }}/repos/${{ gitea.repository }}/issues" \ -d "{\"title\": \"🔴 CI 失败: branch $BRANCH\", \"body\": \"非 main 分支 push CI 失败。\\n\\n触发 commit: \`${{ gitea.sha }}\`\\n分支: $BRANCH\\n\\n请检查 CI 日志并修复。\", \"labels\": [\"bug\"]}" \ || echo "Failed to create issue" echo "Issue created for branch push CI failure." fi else echo "CI passed, no notification needed." fi