🐛 fix(gitea-fix-ci): trace workflow_run CI chains
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
# Actions API 取证
|
||||
|
||||
仅在 `fetch_ci_logs.py` 可运行且 Gitea Actions API 可用时读取本文件。
|
||||
|
||||
## CLI 规则
|
||||
|
||||
全局选项放在子命令前:`--remote`、`--base-url`、`--owner`、`--repo`、
|
||||
`--use-git-credential`、`--json`。`logs` 的 `--tail` 与 `--out` 放在 job ID 后。
|
||||
|
||||
```bash
|
||||
python <skill-dir>/scripts/fetch_ci_logs.py --remote origin --json runs --limit 20
|
||||
python <skill-dir>/scripts/fetch_ci_logs.py --json logs <job-id> --tail 80 --out /tmp/job.log
|
||||
```
|
||||
|
||||
`runs` 默认过滤 `failure`;发现触发链时用 `--status all`,查上游门禁结果时也检查
|
||||
`cancelled` 与 `skipped`。`--sha` 使用完整 SHA。`--workflow checks.yml` 通过 workflow
|
||||
专用 endpoint 过滤,并在输出中保留 `path`、时间、run number 与 attempt。
|
||||
|
||||
## 直接触发
|
||||
|
||||
1. 从 `GET /pulls/<pr>` 取得 `head.ref` 与完整 `head.sha`。
|
||||
2. 按目标 workflow、事件和完整 SHA 列 runs。Gitea 的 PR run 可能保存隐藏 PR ref,
|
||||
`head_branch` 不一定等于 `head.ref`;只有在目标实例实测匹配时才追加 `--branch`。
|
||||
3. 用 `path` 确认 workflow,再列 jobs 和失败日志。
|
||||
|
||||
```bash
|
||||
python <skill-dir>/scripts/fetch_ci_logs.py --json runs \
|
||||
--workflow <workflow.yml> --event pull_request --status all --sha <full-pr-head-sha>
|
||||
```
|
||||
|
||||
## Prepare → workflow_run 链
|
||||
|
||||
先读取仓库 workflow 的 `on:` 段,确认上游 workflow 名与下游文件。
|
||||
|
||||
1. **定位上游**:按 PR 完整 head SHA 定位 Prepare 候选;用 workflow path、事件和时间
|
||||
排除无关 run,记录 run ID、attempt、`conclusion` 与 `completed_at`。同一 SHA 有多个
|
||||
run 或 attempt 时逐个保留,不静默任选。
|
||||
2. **判断门禁**:
|
||||
- `failure`/`cancelled`:列上游 jobs 并读取上游失败日志;分类为“上游门禁未通过”。
|
||||
下游通常会产生 `skipped` run/job,也可能缺失,不要寻找下游失败日志。
|
||||
- `success`:继续查对应下游 workflow。
|
||||
3. **定位下游候选**:按 workflow 文件、`event=workflow_run`、`status=all` 列 runs,选择
|
||||
`started_at` 紧随该上游 attempt 完成时间的候选;重跑上游会生成新一组下游 run。
|
||||
4. **处理缺失**:上游成功却没有下游候选时,核对默认分支上是否存在并启用了下游
|
||||
workflow、`workflow_run.workflows` 名称是否与上游一致,以及事件/条件是否排除了该
|
||||
run。仍无下游时,把“应存在但缺失”作为工作流或 Actions 基础设施证据,不虚构下游
|
||||
日志。
|
||||
5. **核验关联**:公开 Gitea run API 不暴露父 run ID 或事件 payload。下游 API 的
|
||||
`head_branch/head_sha` 属于默认分支 run 本身,不是 PR head。必须用 job 日志中实际
|
||||
checkout/ref/SHA、PR 页给出的 run URL,或 workflow 自己输出的 provenance 核验。
|
||||
未核验前把关联标为推断。
|
||||
|
||||
```bash
|
||||
python <skill-dir>/scripts/fetch_ci_logs.py --json runs \
|
||||
--workflow prepare.yml --event pull_request --status all --sha <full-pr-head-sha>
|
||||
python <skill-dir>/scripts/fetch_ci_logs.py --json runs \
|
||||
--workflow checks.yml --event workflow_run --status all --limit 30
|
||||
```
|
||||
|
||||
## Jobs 与日志
|
||||
|
||||
```bash
|
||||
python <skill-dir>/scripts/fetch_ci_logs.py --json jobs <run-id>
|
||||
python <skill-dir>/scripts/fetch_ci_logs.py --json logs <job-id> --tail 80
|
||||
```
|
||||
|
||||
下载失败 job 日志;取消或基础设施场景读取最后执行或被取消的相关 job。上游门禁场景
|
||||
只取上游证据。完整日志默认写临时文件,或用 `--out` 指向仓库外路径。提取首个可操作
|
||||
错误块,不输出凭据或整段私有日志。
|
||||
|
||||
## 原始 API
|
||||
|
||||
- `/api/v1/version` 只证明实例连通;Actions endpoint 仍需实际调用验证
|
||||
- API 字段或过滤器不明确时读取 `/swagger.v1.json`,不要猜参数语义
|
||||
- `GET /api/v1/repos/<owner>/<repo>/actions/runs`
|
||||
- `GET /api/v1/repos/<owner>/<repo>/actions/workflows/<workflow>/runs`
|
||||
- `GET /api/v1/repos/<owner>/<repo>/actions/runs/<run>/jobs`
|
||||
- `GET /api/v1/repos/<owner>/<repo>/actions/jobs/<job_id>/logs`
|
||||
@@ -0,0 +1,37 @@
|
||||
# 取证回退路径
|
||||
|
||||
仅在脚本不可用、Actions API 返回 404,或只有用户日志时读取本文件。
|
||||
|
||||
## tea actions
|
||||
|
||||
先确认安装、登录和子命令能力;不同 tea 版本不一定提供 Actions:
|
||||
|
||||
```bash
|
||||
tea login list
|
||||
tea actions --help
|
||||
tea pulls view <pr>
|
||||
tea actions runs list --status failure
|
||||
tea actions runs view <run-id>
|
||||
tea actions runs logs <run-id> --job <job-id>
|
||||
```
|
||||
|
||||
仍需先读取 workflow `on:` 段。遇到 `workflow_run` 链时,先查 Prepare,再按下游
|
||||
workflow 和时间定位候选;不要用 PR 分支过滤下游 run。
|
||||
|
||||
## Legacy web
|
||||
|
||||
Gitea 1.21 及更早可能有 Actions web UI,但没有 run/job/log API:
|
||||
|
||||
1. 打开 `/<owner>/<repo>/actions`,找到目标 run。
|
||||
2. 打开 `/<owner>/<repo>/actions/runs/<run>`,读取每个 job 的状态。
|
||||
3. 选择状态为 `failure` 的 job index,再下载
|
||||
`/<owner>/<repo>/actions/runs/<run>/jobs/<job-index>/logs`。
|
||||
4. 不要默认 index `0`;只有页面不暴露 job 状态时才逐一扫描。
|
||||
|
||||
Prepare 失败时读取 Prepare 页和其失败 job;下游可能显示 `skipped` 或根本不出现在
|
||||
PR checks 中,不要把它误报为“找不到失败 run”。
|
||||
|
||||
## 用户粘贴日志
|
||||
|
||||
把日志标记为用户提供的证据,并明确:远端 run/job、workflow、SHA 与状态均未核验。
|
||||
只引用首个可操作错误块;日志不含 run/job 身份时,不把推测写成事实。
|
||||
Reference in New Issue
Block a user