Files
playbook/skills/gitea-fix-ci/SKILL.md
T

12 KiB
Raw Blame History

name, description
name description
gitea-fix-ci Use when a user asks to debug or fix failing Gitea Actions, Gitea PR checks, or CI workflow runs for a Gitea-hosted repository. Also triggers on Chinese phrasing such as CI 挂了/流水线红了/构建失败/工作流失败.

Gitea Fix CI

概述

从 pull request 或 workflow run 诊断失败的 Gitea Actions,提取最小可用的失败上下文, 然后在改代码之前先给出修复计划。核心原则:CI 日志是证据,不要仅凭红色状态臆测原因。

本 skill 不是独立执行器。它指导你在当前工作区中使用随附的取证脚本 scripts/fetch_ci_logs.pytea、本地 git 和 Gitea API。

取证阶段(step 2-4)优先使用随附脚本,把「探测版本 → 找失败 run → 列 job → 下载失败 job 日志」这段易记错 API 路径的逻辑交给它。脚本仅取证到日志,分类、 修复计划与改代码仍由你按本文档执行。将 <skill-dir> 替换为包含本 SKILL.md 的目录:

# 方式一(优先):通过环境变量提供 API token
export GITEA_TOKEN=<token>
python <skill-dir>/scripts/fetch_ci_logs.py version           # 探测实例版本并确认连通性
python <skill-dir>/scripts/fetch_ci_logs.py runs --status failure --branch <branch>
python <skill-dir>/scripts/fetch_ci_logs.py jobs <run-id>     # 标注 failure 的 job
python <skill-dir>/scripts/fetch_ci_logs.py logs <job-id>     # 日志存临时文件并回显尾部

# 方式二:显式复用当前仓库的 Git HTTP 凭据
python <skill-dir>/scripts/fetch_ci_logs.py --use-git-credential version
python <skill-dir>/scripts/fetch_ci_logs.py --use-git-credential runs --status failure

base-url、owner 和 repo 默认从 git remote 推导。认证规则如下:

  • 设置了 GITEA_TOKEN 时始终优先使用它,即使同时传入 --use-git-credential
  • 只有显式传入 --use-git-credential 才会非交互调用 git credential fill,并将 当前仓库对应的用户名和密码用于 HTTP Basic 认证;脚本不会静默读取 Git 凭据。
  • 未设置 token 且未传入该参数时按匿名方式访问,私有仓库通常会返回 401。
  • 所有携带凭据的请求必须使用 HTTPS;认证 header 只发送到配置的 Gitea 同源地址, 跨源请求和跨源重定向会被拒绝。凭据不会出现在命令参数、日志或异常文本中。

脚本不可用(未装 Python、旧版 Gitea 无 job-log API、脱离 Gitea 环境)时,回退到 下文的手动 tea/API/web 路径。

适用场景

  • Gitea 托管的仓库出现失败的 Gitea Actions 或 PR checks
  • 用户要求检查某个失败的 workflow run、job 或 CI 状态
  • 用户要求在 push、更新分支或更新 pull request 之后修复 CI
  • 本地测试通过,但远端 Gitea Actions 失败

不适用场景

  • 仓库并非托管在 Gitea 或 Forgejo 兼容的基础设施上
  • 失败属于外部 CI 服务,只是从 Gitea 链接出去
  • 用户只想在本地跑测试或 lint
  • 没有凭据、token 或网络访问权限,且用户也未提供失败的日志文本

输入

  • 仓库路径,默认为当前工作区
  • Gitea base URL 和仓库 owner/name,尽量从 git remote -v 获取
  • Pull request 编号、分支、commit SHA 或 workflow run ID
  • 认证方式:tea 登录 profile、用于 API 请求的 GITEA_TOKEN,或通过 --use-git-credential 显式读取的当前仓库 Git HTTP 凭据
  • 若无法远端访问,则由用户粘贴的 CI 日志

流程

  1. 基线本地状态

    • 记录 git status --short、当前分支和最新 commit SHA。
    • git remote -v 识别 remote URL 和 owner/repo。
    • 继续之前先确认 remote 是 Gitea/Forgejo:对照已知的 Gitea 实例核对 host, 或探测 /api/v1/version。若 remote 是 GitHub、GitLab 或其他服务,按"不适用场景"停止。
    • 收集 CI 证据期间不要修改文件。
  2. 验证 Gitea 访问

    • 优先运行 fetch_ci_logs.py version 探测实例版本并确认脚本能连通实例。脚本从 remote 推导 base URL,认证按 GITEA_TOKEN → 显式 --use-git-credential → 匿名的顺序选择。注意:version 只读 /api/v1/version,成功仅代表连通与鉴权 可用,不代表 Actions API 一定可用。Actions 端点是否存在需在后续 runs/jobs 步骤中实际验证;旧版 Gitea(见下)会在此才暴露 404。
    • 脚本不可用时,回退到手动方式。优先使用已安装并已认证的 tea
      • tea login list
      • 使用前先运行 tea actions --help 确认已安装的 tea 版本存在 actions 子命令;并非所有版本都带这些子命令。
      • tea actions runs list --status failure --branch <branch>
      • tea actions runs view <run-id>
      • tea actions runs logs <run-id> --job <job-id>
      • tea pulls view <pr>
    • tea 不可用,或已安装版本缺少 Actions 命令,则直接使用 Gitea API。
    • 当 API 行为不明确时,检查 /api/v1/version/swagger.v1.json。较旧的 Gitea1.21 及更早)在 web UI 中提供 Actions 页面,但不提供 workflow run/job/log 的 API 端点;应对照上报的版本确认可用性,而不是想当然。
    • 绝不打印 token、用户名或密码。API token 只通过环境变量传递;Git 凭据只通过 git credential fill 的标准输入/输出在脚本进程内传递,不放入 argv。
  3. 定位失败的 workflow run

    • 若入口是 PR 而非 run ID,先把 PR 解析成 run:取 PR 的 head 分支与 head SHA fetch_ci_logs.pyruns 支持 --branch/--sha;手动则 GET /api/v1/repos/<owner>/<repo>/pulls/<pr>head.ref/head.sha), 再按该 SHA 过滤 runs。PR 页面的 checks 列表可能聚合多个 workflow,逐一定位到 具体失败 run,不要假设只有一个。
    • 优先用脚本:fetch_ci_logs.py runs --status failure --branch <branch> (也支持 --sha/--event/--limit),已知 run ID 时用 fetch_ci_logs.py jobs <run-id> 直接列出各 job 并标注失败项。
    • 脚本不可用时回退到手动方式。已知 run ID 时,直接获取该 run。
    • 否则按分支、事件、状态或 commit SHA 过滤,列出最近的 workflow runs。
    • API 模式:
      • GET /api/v1/repos/<owner>/<repo>/actions/runs
      • GET /api/v1/repos/<owner>/<repo>/actions/runs/<run>
      • GET /api/v1/repos/<owner>/<repo>/actions/runs/<run>/jobs
    • 较旧 Gitea 的 web 回退:
      • GET /<owner>/<repo>/actions
      • 解析 /<owner>/<repo>/actions/runs/<run> 链接和状态标签。
    • 区别对待 failurecancelled 和缺失的必需 checks。被取消(cancelled)的 job 可能需要重跑或排查队列,而非改代码。
  4. 获取 job 日志

    • 优先用脚本:fetch_ci_logs.py logs <job-id>。它把日志存到受跟踪源码路径 之外的临时文件、只回显尾部若干行,并打印临时文件路径供进一步查看 (--tail N 调整行数,--json 输出结构化结果)。
    • 脚本不可用时回退到手动方式。对每个失败的 job,下载其日志:
      • GET /api/v1/repos/<owner>/<repo>/actions/jobs/<job_id>/logs
    • 在较旧 Gitea 的 web 回退(无 job-log API)下,按 UI 的 job index 下载日志:
      • GET /<owner>/<repo>/actions/runs/<run>/jobs/<job-index>/logs
      • 先打开 run 页面读取每个 job 的状态;取状态为 failure 的 job 的 index 不要默认用 index 0。失败的 job 很少是第一个,盲目用 index 0 通常会返回 某个通过的 job 的日志。只有当 run 页面不暴露每个 job 的状态时,才回退到逐一 扫描 index。
    • 大日志保存到受跟踪源码路径之外的临时文件。
    • 提取首个可操作的错误块、其上下文命令、job 名、workflow 名、run URL、分支和 SHA。
    • 若日志缺失,明确报告,而不是编造原因。
  5. 分类失败

    • 代码/测试失败:断言失败、编译错误、lint 错误、类型错误
    • 环境失败:缺失 secret、runner 镜像、依赖安装、网络、缓存、权限或服务启动
    • 工作流失败:YAML 非法、语法不支持、触发条件错误、路径错误、分支/ref 假设错误
    • 基础设施失败:runner 离线、队列卡住、run 被取消、超时
  6. 制定修复计划

    • 用确切的 job/run 标识总结失败证据。
    • 提出与证据匹配的最小代码或工作流改动。
    • 包含本地验证命令和远端复检路径。
    • 在用户批准修复计划之前不要实施。
  7. 批准后实施

    • 只应用已批准的修复。
    • 运行最接近复现该失败 job 的本地命令。
    • 若失败仅涉及工作流,验证工作流文件语法及其引用的路径或脚本。
  8. 复检

    • 告诉用户需要在 Gitea 中 push 或重跑什么。
    • 若获准,使用 Gitea API 检查重跑状态。
    • 最终输出必须区分本地验证与远端 CI 状态。

输出约定

  • Target: 仓库、分支/SHA、PR 或 run ID
  • Failed CI: workflow、job、状态、run URL 或 API 路径
  • Evidence: 精简的日志片段与分类
  • Plan: 提出的修复、本地验证、远端复检
  • Changes: 批准后改动的文件
  • Result: 已运行的本地检查与剩余的远端状态

成功标准

  • 失败分析基于 Gitea Actions 的 run/job 数据或粘贴的日志
  • 修复计划指明其针对的确切 workflow run 或 job
  • 计划批准前不发生任何代码或工作流改动
  • 验证区分本地命令与远端 Gitea Actions 结果
  • 不回显 token;私有日志只保留可操作的片段,不整段外泄

危险信号(Red Flags

出现以下情况说明流程走偏,停下纠正而非继续:

  • 凭红色状态臆测原因:还没下载 job 日志就断言失败原因或动手改代码。
  • 误读双字段结果:把 status(生命周期)当成结果判定。Gitea Actions 沿用 GitHub 兼容的双字段模型——status=completed 只表示跑完了,真正的成败在 conclusionfailure/success/cancelled)。判定失败必须看有效结果, 而非 status=completed 就当通过。
  • 盲取 job index 0:在 web 回退下不看每个 job 状态就用 index 0 下载日志; 失败的 job 很少是第一个,通常会误取到某个通过 job 的日志。
  • version 成功当作 Actions API 可用version 只探连通与鉴权,Actions 端点可能仍返回 404(旧版 Gitea)。
  • cancelled/基础设施问题当代码 bug 修:被取消、runner 离线、队列卡住、 超时应重跑或排查环境,不是改代码。
  • 回显 token 或整段私有日志:只保留可操作的最小片段。
  • 静默读取或降级传输凭据Git 凭据必须由 --use-git-credential 显式启用; token 和 Git 凭据都不得通过 HTTP 或跨源重定向发送。

失败处理

  • 401 且未使用认证时,通过环境提供 GITEA_TOKEN 或显式传入 --use-git-credential;401 且已使用认证时检查凭据是否有效,不要在对话中索要 secret
  • 403 表示所选凭据缺少仓库或 Actions 读取权限;补足权限,而不是切换到匿名访问
  • 404 优先核对 owner/repo、端点和 Gitea 版本;旧版本缺少 Actions API 时使用 web 回退
  • 若 Gitea 版本缺少 Actions API 端点,请用户提供相关日志文本或从浏览器复制的 job 日志
  • 若失败的 check 归属外部 CI 服务,报告外部 URL 并在证据收集处停止
  • 若失败仅为基础设施问题,建议重跑/排查 runner,而非改代码