🐛 fix(gitea-fix-ci): trace workflow_run CI chains

This commit is contained in:
csh
2026-08-20 15:56:40 +08:00
parent 5a8d95ebcf
commit 77ab8211b1
6 changed files with 429 additions and 194 deletions
@@ -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`