Files
sanguo_moziplus_v2/.gitea/workflows/ci.yml
T
claude_dev 19a76e25d6
CI / lint (pull_request) Failing after 18s
CI / test (pull_request) Has been skipped
CI / frontend (pull_request) Has been skipped
CI / notify-on-failure (pull_request) Successful in 10s
[moz] ci(lint): 锁定 flake8==7.3.0,修复版本漂移致 E122 全线误报
根因:ci.yml lint 步骤 pip install flake8 未锁版本,runner 每次装最新版。
2026-09-11 新版 pycodestyle 对 main 现存代码(toolchain_routes.py:1217)报
E122,而该代码 2026-06-23 后未改动、06-25 CI 绿——纯工具版本漂移,main
全量 lint 现已必红,阻塞所有 PR(含挂起 9 天的 #131)。

证据:本地 flake8 7.3.0 (pycodestyle 2.14.0) 对 origin/main 全量 src/
零报错(exit=0);CI 同款命令最新版报 1217:21 E122。

处置:锁定 7.3.0(实证绿版本),版本策略写入 ci.yml 行内注释。
纯 CI 配置变更,不碰业务代码。

交付检查:
- docs/design:无需更新(设计文档未规定 flake8 版本策略,ci.yml 注释即现行说明)
- tests:无需更新(纯 CI 配置,本 PR 自身 CI 即验证)
2026-09-11 05:19:29 +08:00

135 lines
5.4 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.
# CI 管道 — moziplus v2.0
#
# 触发条件:
# - pull_requestopened, synchronize
# - 所有 PR 均触发 CI,确保 status check 始终产出
# (移除 paths-ignore:与分支保护 enable_status_check 冲突,
# 纯文档 PR 无 CI status 导致无法合并)
#
# 注意:只保留 pull_request 触发,避免 push + pull_request 双倍触发
#
# Gitea v1.23.4 限制注意:
# - 不支持 failure() 表达式,用 always() + shell 条件判断替代
# - 不支持 concurrency / continue-on-error / timeout-minutes / permissions
# - 无内置 GITEA_TOKEN,需手动配置 PAT 为 secret
# - runs-on 只支持单个 label
name: CI
on:
pull_request:
types: [opened, synchronize]
jobs:
# ── Job 1: Lint ──────────────────────────────────────
lint:
runs-on: macos-arm64
steps:
- uses: actions/checkout@v4
- name: Setup Python
env:
no_proxy: "*"
run: |
rm -rf /tmp/ci-venv-lint
python3 -m venv /tmp/ci-venv-lint
/tmp/ci-venv-lint/bin/pip install --quiet --upgrade pip
/tmp/ci-venv-lint/bin/pip install --quiet 'flake8==7.3.0' # 锁版本:防漂移。2026-09-11 新版 pycodestyle 对现存代码报 E122 致 lint 全线误报,7.3.0 经全量 src/ 实证零报错
- name: Lint with flake8
run: |
/tmp/ci-venv-lint/bin/flake8 src/ --max-line-length=120 --extend-ignore=E501
# ── Job 2: Test ──────────────────────────────────────
test:
runs-on: macos-arm64
needs: lint
steps:
- uses: actions/checkout@v4
- name: Setup Python
env:
no_proxy: "*"
run: |
rm -rf /tmp/ci-venv-test
python3 -m venv /tmp/ci-venv-test
/tmp/ci-venv-test/bin/pip install --quiet --upgrade pip
/tmp/ci-venv-test/bin/pip install --quiet 'fastapi' 'pydantic<2' pyyaml uvicorn requests pytest pytest-asyncio httpx
- name: Debug environment
run: |
echo "PWD=$(pwd)"
echo "PYTHONPATH=$PYTHONPATH"
python3 -c "import sys; [print(p) for p in sys.path if 'sanguo' in p.lower() or 'openclaw' in p.lower()]"
grep -c "assignee = agent_id" src/daemon/toolchain_handler.py || true
grep -c "_BUSINESS_FAIL_THRESHOLD" src/daemon/toolchain_handler.py || true
- name: Run tests (exclude E2E)
run: |
PYTHONPATH=$(pwd) /tmp/ci-venv-test/bin/pytest tests/ -m "not e2e" -x -q || \
(echo '=== RETRY WITH VERBOSE ===' && \
PYTHONPATH=$(pwd) /tmp/ci-venv-test/bin/pytest tests/ -m "not e2e" -x -v 2>&1 | tail -30)
# ── Job 3: Frontend Build ───────────────────────────
frontend:
runs-on: macos-arm64
needs: lint
steps:
- uses: actions/checkout@v4
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 20
- name: Install & Build
run: |
cd src/frontend
npm ci || npm install
npm run build
# ── Job 4: CI 失败通知 ───────────────────────────────
# 使用 needs.<job>.result 直接判断,不查询 commit status API
# 根因:notify 自身的 pending status 会污染 commit status 查询结果(竞态条件)
notify-on-failure:
runs-on: macos-arm64
needs: [lint, test, frontend]
if: always()
steps:
- name: Check results and notify
env:
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
LINT_RESULT: ${{ needs.lint.result }}
TEST_RESULT: ${{ needs.test.result }}
FRONTEND_RESULT: ${{ needs.frontend.result }}
run: |
echo "Lint result: $LINT_RESULT"
echo "Test result: $TEST_RESULT"
# 只有 lint 或 test 明确失败时才发通知
if [ "$LINT_RESULT" = "failure" ] || [ "$TEST_RESULT" = "failure" ] || [ "$FRONTEND_RESULT" = "failure" ]; then
echo "CI has failures, sending notification..."
# 如果是 PR 事件,写评论通知
PR_NUMBER="${{ gitea.event.pull_request.number }}"
if [ -n "$PR_NUMBER" ]; then
# 构建失败摘要
FAILED_JOBS=""
[ "$LINT_RESULT" = "failure" ] && FAILED_JOBS="${FAILED_JOBS}lint "
[ "$TEST_RESULT" = "failure" ] && FAILED_JOBS="${FAILED_JOBS}test "
[ "$FRONTEND_RESULT" = "failure" ] && FAILED_JOBS="${FAILED_JOBS}frontend "
curl -sf -X POST \
-H "Authorization: token $GITEA_TOKEN" \
-H "Content-Type: application/json" \
"${{ gitea.api_url }}/repos/${{ gitea.repository }}/issues/${PR_NUMBER}/comments" \
-d "{\"body\": \"[CI] 失败\\n\\n分支: ${{ gitea.ref_name }}\\n触发 commit: \`${{ gitea.sha }}\`\\n失败 Job: ${FAILED_JOBS}\\n请检查 CI 日志并修复。\"}" \
|| echo "Failed to post PR comment"
echo "PR comment posted."
else
echo "Not a PR event, skipping PR comment."
fi
else
echo "No explicit failures (results: lint=$LINT_RESULT, test=$TEST_RESULT), no notification needed."
fi