✨ feat(gitea-fix-ci): add authenticated log collector
This commit is contained in:
+162
-103
@@ -1,151 +1,210 @@
|
||||
---
|
||||
name: gitea-fix-ci
|
||||
description: Use when a user asks to debug or fix failing Gitea Actions, Gitea PR checks, or CI workflow runs for a Gitea-hosted repository.
|
||||
description: "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
|
||||
|
||||
## Overview
|
||||
## 概述
|
||||
|
||||
Diagnose failing Gitea Actions from the pull request or workflow run, extract the
|
||||
smallest useful failure context, then propose a fix plan before changing code.
|
||||
Core principle: CI logs are evidence; do not guess from the red status alone.
|
||||
从 pull request 或 workflow run 诊断失败的 Gitea Actions,提取最小可用的失败上下文,
|
||||
然后在改代码之前先给出修复计划。核心原则:CI 日志是证据,不要仅凭红色状态臆测原因。
|
||||
|
||||
This is not a standalone executor. It guides use of `tea`, local `git`, and the
|
||||
Gitea API from the current workspace.
|
||||
本 skill 不是独立执行器。它指导你在当前工作区中使用随附的取证脚本
|
||||
`scripts/fetch_ci_logs.py`、`tea`、本地 `git` 和 Gitea API。
|
||||
|
||||
## When to Use
|
||||
取证阶段(step 2-4)优先使用随附脚本,把「探测版本 → 找失败 run → 列 job →
|
||||
下载失败 job 日志」这段易记错 API 路径的逻辑交给它。脚本仅取证到日志,分类、
|
||||
修复计划与改代码仍由你按本文档执行。将 `<skill-dir>` 替换为包含本 `SKILL.md`
|
||||
的目录:
|
||||
|
||||
- A Gitea-hosted repository has failing Gitea Actions or PR checks
|
||||
- The user asks to inspect a failed workflow run, job, or CI status
|
||||
- The user asks to fix CI after a push, branch update, or pull request update
|
||||
- Local tests pass but remote Gitea Actions fail
|
||||
```bash
|
||||
# 方式一(优先):通过环境变量提供 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> # 日志存临时文件并回显尾部
|
||||
|
||||
## When Not to Use
|
||||
# 方式二:显式复用当前仓库的 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
|
||||
```
|
||||
|
||||
- The repository is not hosted on Gitea or Forgejo-compatible infrastructure
|
||||
- The failure belongs to an external CI provider and only links out from Gitea
|
||||
- The user only wants a local test or lint run
|
||||
- Credentials, tokens, or network access are unavailable and the user has not
|
||||
provided the failing log text
|
||||
`base-url`、owner 和 repo 默认从 git remote 推导。认证规则如下:
|
||||
|
||||
## Inputs
|
||||
- 设置了 `GITEA_TOKEN` 时始终优先使用它,即使同时传入 `--use-git-credential`。
|
||||
- 只有显式传入 `--use-git-credential` 才会非交互调用 `git credential fill`,并将
|
||||
当前仓库对应的用户名和密码用于 HTTP Basic 认证;脚本不会静默读取 Git 凭据。
|
||||
- 未设置 token 且未传入该参数时按匿名方式访问,私有仓库通常会返回 401。
|
||||
- 所有携带凭据的请求必须使用 HTTPS;认证 header 只发送到配置的 Gitea 同源地址,
|
||||
跨源请求和跨源重定向会被拒绝。凭据不会出现在命令参数、日志或异常文本中。
|
||||
|
||||
- Repository path, defaulting to the current workspace
|
||||
- Gitea base URL and repository owner/name, from `git remote -v` when possible
|
||||
- Pull request number, branch, commit SHA, or workflow run ID
|
||||
- Authentication method: `tea` login profile, `GITEA_TOKEN` for API requests,
|
||||
or an existing git credential for the Gitea web fallback
|
||||
- Any pasted CI log if remote access is unavailable
|
||||
脚本不可用(未装 Python、旧版 Gitea 无 job-log API、脱离 Gitea 环境)时,回退到
|
||||
下文的手动 `tea`/API/web 路径。
|
||||
|
||||
## Procedure
|
||||
## 适用场景
|
||||
|
||||
1. **Baseline local state**
|
||||
- Gitea 托管的仓库出现失败的 Gitea Actions 或 PR checks
|
||||
- 用户要求检查某个失败的 workflow run、job 或 CI 状态
|
||||
- 用户要求在 push、更新分支或更新 pull request 之后修复 CI
|
||||
- 本地测试通过,但远端 Gitea Actions 失败
|
||||
|
||||
- Record `git status --short`, current branch, and latest commit SHA.
|
||||
- Identify the Gitea remote URL and owner/repo.
|
||||
- Do not modify files while gathering CI evidence.
|
||||
## 不适用场景
|
||||
|
||||
2. **Verify Gitea access**
|
||||
- 仓库并非托管在 Gitea 或 Forgejo 兼容的基础设施上
|
||||
- 失败属于外部 CI 服务,只是从 Gitea 链接出去
|
||||
- 用户只想在本地跑测试或 lint
|
||||
- 没有凭据、token 或网络访问权限,且用户也未提供失败的日志文本
|
||||
|
||||
- Prefer `tea` if it is installed and authenticated:
|
||||
## 输入
|
||||
|
||||
- 仓库路径,默认为当前工作区
|
||||
- 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>`
|
||||
- If `tea` is unavailable or lacks an Actions command for the installed
|
||||
version, use the Gitea API directly.
|
||||
- Check `/api/v1/version` and `/swagger.v1.json` when API behavior is
|
||||
unclear. Gitea 1.21 exposes Actions pages but not workflow run/job/log API
|
||||
endpoints.
|
||||
- Never print tokens. Pass API tokens through environment variables.
|
||||
- 若 `tea` 不可用,或已安装版本缺少 Actions 命令,则直接使用 Gitea API。
|
||||
- 当 API 行为不明确时,检查 `/api/v1/version` 和 `/swagger.v1.json`。较旧的
|
||||
Gitea(1.21 及更早)在 web UI 中提供 Actions 页面,但不提供 workflow
|
||||
run/job/log 的 API 端点;应对照上报的版本确认可用性,而不是想当然。
|
||||
- 绝不打印 token、用户名或密码。API token 只通过环境变量传递;Git 凭据只通过
|
||||
`git credential fill` 的标准输入/输出在脚本进程内传递,不放入 argv。
|
||||
|
||||
3. **Find failing workflow runs**
|
||||
3. **定位失败的 workflow run**
|
||||
|
||||
- For a known run ID, fetch that run directly.
|
||||
- Otherwise list recent workflow runs filtered by branch, event, status, or
|
||||
commit SHA.
|
||||
- API patterns:
|
||||
- 若入口是 PR 而非 run ID,先把 PR 解析成 run:取 PR 的 head 分支与 head SHA
|
||||
(`fetch_ci_logs.py` 的 `runs` 支持 `--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`
|
||||
- Web fallback for older Gitea:
|
||||
- 较旧 Gitea 的 web 回退:
|
||||
- `GET /<owner>/<repo>/actions`
|
||||
- Parse `/<owner>/<repo>/actions/runs/<run>` links and status labels.
|
||||
- Treat `failure`, `cancelled`, and missing required checks differently.
|
||||
Cancelled jobs may require rerun or queue investigation rather than code
|
||||
changes.
|
||||
- 解析 `/<owner>/<repo>/actions/runs/<run>` 链接和状态标签。
|
||||
- 区别对待 `failure`、`cancelled` 和缺失的必需 checks。被取消(cancelled)的
|
||||
job 可能需要重跑或排查队列,而非改代码。
|
||||
|
||||
4. **Fetch job logs**
|
||||
4. **获取 job 日志**
|
||||
|
||||
- For each failed job, download the job logs:
|
||||
- 优先用脚本:`fetch_ci_logs.py logs <job-id>`。它把日志存到受跟踪源码路径
|
||||
之外的临时文件、只回显尾部若干行,并打印临时文件路径供进一步查看
|
||||
(`--tail N` 调整行数,`--json` 输出结构化结果)。
|
||||
- 脚本不可用时回退到手动方式。对每个失败的 job,下载其日志:
|
||||
- `GET /api/v1/repos/<owner>/<repo>/actions/jobs/<job_id>/logs`
|
||||
- On Gitea 1.21 web fallback, download logs by UI job index:
|
||||
- 在较旧 Gitea 的 web 回退(无 job-log API)下,按 UI 的 job index 下载日志:
|
||||
- `GET /<owner>/<repo>/actions/runs/<run>/jobs/<job-index>/logs`
|
||||
- First open the run page and read each job's status; take the index of a
|
||||
job whose status is `failure`, not index `0` by default. The failing job
|
||||
is rarely the first one, so a blind index `0` usually returns a passing
|
||||
job's log. Only fall back to scanning indices when the run page does not
|
||||
expose per-job status.
|
||||
- Save large logs to a temporary file outside tracked source paths.
|
||||
- Extract the first actionable error block, surrounding command, job name,
|
||||
workflow name, run URL, branch, and SHA.
|
||||
- If logs are missing, report that explicitly instead of inventing causes.
|
||||
- 先打开 run 页面读取每个 job 的状态;取状态为 `failure` 的 job 的 index,
|
||||
不要默认用 index `0`。失败的 job 很少是第一个,盲目用 index `0` 通常会返回
|
||||
某个通过的 job 的日志。只有当 run 页面不暴露每个 job 的状态时,才回退到逐一
|
||||
扫描 index。
|
||||
- 大日志保存到受跟踪源码路径之外的临时文件。
|
||||
- 提取首个可操作的错误块、其上下文命令、job 名、workflow 名、run URL、分支和 SHA。
|
||||
- 若日志缺失,明确报告,而不是编造原因。
|
||||
|
||||
5. **Classify the failure**
|
||||
5. **分类失败**
|
||||
|
||||
- Code/test failure: failing assertion, compile error, lint error, type error
|
||||
- Environment failure: missing secret, runner image, dependency install,
|
||||
network, cache, permission, or service startup
|
||||
- Workflow failure: invalid YAML, unsupported syntax, wrong trigger, bad path,
|
||||
wrong branch/ref assumption
|
||||
- Infrastructure failure: offline runner, stuck queue, cancelled run, timeout
|
||||
- 代码/测试失败:断言失败、编译错误、lint 错误、类型错误
|
||||
- 环境失败:缺失 secret、runner 镜像、依赖安装、网络、缓存、权限或服务启动
|
||||
- 工作流失败:YAML 非法、语法不支持、触发条件错误、路径错误、分支/ref 假设错误
|
||||
- 基础设施失败:runner 离线、队列卡住、run 被取消、超时
|
||||
|
||||
6. **Create a fix plan**
|
||||
6. **制定修复计划**
|
||||
|
||||
- Summarize the failure evidence with exact job/run identifiers.
|
||||
- Propose the smallest code or workflow change that matches the evidence.
|
||||
- Include local verification commands and the remote recheck path.
|
||||
- Do not implement before the user approves the fix plan.
|
||||
- 用确切的 job/run 标识总结失败证据。
|
||||
- 提出与证据匹配的最小代码或工作流改动。
|
||||
- 包含本地验证命令和远端复检路径。
|
||||
- 在用户批准修复计划之前不要实施。
|
||||
|
||||
7. **Implement after approval**
|
||||
7. **批准后实施**
|
||||
|
||||
- Apply only the approved fix.
|
||||
- Run the local command that most closely reproduces the failed job.
|
||||
- If the failure is workflow-only, validate the workflow file syntax and any
|
||||
referenced paths or scripts.
|
||||
- 只应用已批准的修复。
|
||||
- 运行最接近复现该失败 job 的本地命令。
|
||||
- 若失败仅涉及工作流,验证工作流文件语法及其引用的路径或脚本。
|
||||
|
||||
8. **Recheck**
|
||||
8. **复检**
|
||||
|
||||
- Tell the user what must be pushed or rerun in Gitea.
|
||||
- If permitted, use the Gitea API to inspect the rerun status.
|
||||
- Final output must distinguish local verification from remote CI status.
|
||||
- 告诉用户需要在 Gitea 中 push 或重跑什么。
|
||||
- 若获准,使用 Gitea API 检查重跑状态。
|
||||
- 最终输出必须区分本地验证与远端 CI 状态。
|
||||
|
||||
## Output Contract
|
||||
## 输出约定
|
||||
|
||||
- `Target:` repo, branch/SHA, PR or run ID
|
||||
- `Failed CI:` workflow, job, status, run URL or API path
|
||||
- `Evidence:` concise log snippet and classification
|
||||
- `Plan:` proposed fix, local verification, remote recheck
|
||||
- `Changes:` files changed after approval
|
||||
- `Result:` local checks run and remaining remote status
|
||||
- `Target:` 仓库、分支/SHA、PR 或 run ID
|
||||
- `Failed CI:` workflow、job、状态、run URL 或 API 路径
|
||||
- `Evidence:` 精简的日志片段与分类
|
||||
- `Plan:` 提出的修复、本地验证、远端复检
|
||||
- `Changes:` 批准后改动的文件
|
||||
- `Result:` 已运行的本地检查与剩余的远端状态
|
||||
|
||||
## Success Criteria
|
||||
## 成功标准
|
||||
|
||||
- Failure analysis is based on Gitea Actions run/job data or pasted logs
|
||||
- The fix plan names the exact workflow run or job it addresses
|
||||
- No code or workflow edits happen before plan approval
|
||||
- Verification distinguishes local commands from remote Gitea Actions results
|
||||
- Tokens and private log content are not echoed unnecessarily
|
||||
- 失败分析基于 Gitea Actions 的 run/job 数据或粘贴的日志
|
||||
- 修复计划指明其针对的确切 workflow run 或 job
|
||||
- 计划批准前不发生任何代码或工作流改动
|
||||
- 验证区分本地命令与远端 Gitea Actions 结果
|
||||
- 不回显 token;私有日志只保留可操作的片段,不整段外泄
|
||||
|
||||
## Failure Handling
|
||||
## 危险信号(Red Flags)
|
||||
|
||||
- If authentication fails, ask the user to authenticate `tea` or provide a token
|
||||
through the environment; do not request secrets in chat
|
||||
- If the Gitea version lacks Actions API endpoints, ask for the relevant log text
|
||||
or a browser-copied job log
|
||||
- If an external CI provider owns the failing check, report the external URL and
|
||||
stop at evidence collection
|
||||
- If the failure is infrastructure-only, recommend rerun/runner investigation
|
||||
instead of editing code
|
||||
出现以下情况说明流程走偏,停下纠正而非继续:
|
||||
|
||||
- **凭红色状态臆测原因**:还没下载 job 日志就断言失败原因或动手改代码。
|
||||
- **误读双字段结果**:把 `status`(生命周期)当成结果判定。Gitea Actions 沿用
|
||||
GitHub 兼容的双字段模型——`status=completed` 只表示跑完了,真正的成败在
|
||||
`conclusion`(`failure`/`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,而非改代码
|
||||
|
||||
Reference in New Issue
Block a user