IronClaw GitHub 扩展实战:使用 `github.get_workflow_runs` 精准查询 GitHub Actions 工作流运行记录
IronClaw GitHub 扩展实战:使用 github.get_workflow_runs 精准查询 GitHub Actions 工作流运行记录
github.get_workflow_runs 是 IronClaw GitHub 扩展(extension id github)中用于列出 GitHub Actions 工作流运行记录的核心能力工具,属于工作流(workflow)工具族的一员。本文将以官方 prompt 文档 get_workflow_runs.md 为骨架,结合输入 Schema、WASM 实现源码与扩展清单,完整讲解该工具的调用方式、全部筛选参数、底层请求构造原理与认证安全模型,帮助你(或接入该能力的 Agent)准确、高效地查询 CI/CD 运行状态,而不是盲目翻页。
工具定位与适用场景
在 IronClaw 的扩展目录中,GitHub 是覆盖面最大的工具面,共提供 49 个工具(github.get_repo … github.handle_webhook)以及 <a href="https://link.gitcode.com/i/8344fb348bb61834269d9246a6465357" target="_blank">auth.github] 认证。该扩展是一个 data-only 包:不携带 Rust crate,行为以 WASM guest 形式发布,产物提交在 wasm/ 目录,guest 源码位于 wasm-src/(不参与工作区编译图)。详见 [crates/extensions/packages/github/README.md 与 manifest.toml。
github.get_workflow_runs 的典型使用场景包括:
- 查看某个仓库最近的 CI 运行历史,判断某个提交、分支或事件触发的构建是否成功;
- 按状态(success / failure / in_progress 等)筛选出失败或进行中的运行;
- 配合
github.get_workflow_run_jobs、github.get_job_logs定位具体失败任务与日志; - 配合
github.trigger_workflow触发工作流后回查运行结果。
官方 prompt 文档对本工具的使用提出三条核心指引,这也是本文展开的主线:
- 优先使用过滤器精确定位:使用
head_sha、branch、event、status、actor、created、check_suite_id、exclude_pull_requests等过滤器找到相关运行,而不要分页拉取宽泛结果; - 严格使用 Schema 中的精确 JSON 字段名:字段名必须与该能力的输入 Schema 完全一致;若用户提供了 GitHub URL,应提取
owner与repo字段,以及 Schema 特有的 number / path / ref 键(PR 类工具用pr_number,issue 类工具用issue_number); - 网络与认证前提:该能力通过主机 HTTP egress 访问 GitHub API,需要配置 GitHub product-auth 账号。
输入参数全解析
工具的输入由 JSON Schema 严格约束,定义于 get_workflow_runs.input.v1.json。该 Schema 声明 additionalProperties: false,即传入未定义的字段会被拒绝,因此必须使用精确字段名。完整参数如下:
| 字段 | 类型 | 必填 | 约束 | 说明 |
|---|---|---|---|---|
owner |
string | 是 | 1–100 字符,^[^\s/?#]+$,禁止 .. |
仓库所有者或组织名 |
repo |
string | 是 | 1–100 字符,^[^\s/?#]+$,禁止 .. |
仓库名 |
workflow_id |
string | 否 | 最长 255 字符 | 工作流文件名或数字 ID(如 ci.yml 或 1234567) |
actor |
string | 否 | 1–100 字符 | 触发者登录名过滤器 |
branch |
string | 否 | 1–255 字符 | 分支过滤器 |
event |
string | 否 | 1–100 字符 | 工作流触发事件过滤器(如 push、pull_request) |
status |
string | 否 | 枚举,见下表 | 运行状态过滤器 |
created |
string | 否 | 1–100 字符 | 创建时间筛选,GitHub 支持 >=YYYY-MM-DD 等格式 |
exclude_pull_requests |
boolean | 否 | — | 是否排除 PR 触发的工作流运行 |
check_suite_id |
integer | 否 | ≥ 1 | Check Suite ID 过滤器 |
head_sha |
string | 否 | 1–100 字符 | 提交 SHA 过滤器 |
page |
integer | 否 | ≥ 1,默认 1 | 分页页码 |
limit |
integer | 否 | 1–100,默认 30 | 每页条数,上限 100 |
status 的合法取值在 Schema 中通过 enum 固化,与 guest 源码 types.rs 中 WorkflowRunStatus 枚举一一对应,共 14 个值:
completed、action_required、cancelled、failure、neutral、skipped、stale、success、timed_out、in_progress、queued、requested、waiting、pending
一个典型的最小调用(仅必填字段)为:
{
"owner": "octocat",
"repo": "Hello-World"
}
源码实现:请求是如何构造的
理解了 Schema 之后,我们再深入 guest 源码 actions.rs 中 get_workflow_runs 的实现,可以看到请求构造的完整逻辑:
1. 输入校验(防御性检查)
owner与repo通过validate_path_segment校验,禁止包含/、..、?、#以及控制字符和空白;page与limit分别通过validate_page、validate_limit校验:page不能为 0,limit必须在 1–100 之间(见 validation.rs);workflow_id若提供,必须是不含/、..、:的文件名或数字 ID。
2. 端点选择(两条 REST 路径)
let mut path = if let Some(workflow_id) = workflow_id {
// /repos/{owner}/{repo}/actions/workflows/{workflow_id}/runs?per_page={limit}
...
} else {
// /repos/{owner}/{repo}/actions/runs?per_page={limit}
...
};
- 提供
workflow_id:走/repos/{owner}/{repo}/actions/workflows/{workflow_id}/runs,仅查询该工作流; - 未提供:走
/repos/{owner}/{repo}/actions/runs,查询仓库下全部工作流运行。
3. 查询参数组装
limit 默认 30 且强制 min(100) 封顶;随后按顺序追加可选过滤器:actor、branch、event、status、created、exclude_pull_requests(true/false 字面量)、check_suite_id、head_sha,最后追加 page。所有查询值经 url_encode_query 百分号编码,确保特殊字符安全。
4. 发起 GET 请求
最终通过 request.rs 的 github_request("GET", &path, None) 发出请求,请求头包括:
Accept: application/vnd.github+jsonContent-Type: application/jsonX-GitHub-Api-Version: 2026-03-10(固定 API 版本)User-Agent: IronClaw-GitHub-Reborn-WASM- HTTP 超时 10 秒(
HTTP_TIMEOUT_MS = 10_000)
筛选策略实战:用过滤器代替盲目翻页
官方 prompt 文档强调的核心实践是:不要分页拉取宽泛结果,而是先用过滤器收敛。下面给出几种高频组合:
按提交 SHA 定位(CI 回归排查最常用)
{
"owner": "octocat",
"repo": "Hello-World",
"head_sha": "6dcb09b5b57875f334f61aebed695e2e4193db5e"
}
按分支 + 状态组合
{
"owner": "octocat",
"repo": "Hello-World",
"branch": "main",
"status": "failure"
}
只看某个特定工作流,并排除 PR 触发的运行
{
"owner": "octocat",
"repo": "Hello-World",
"workflow_id": "ci.yml",
"exclude_pull_requests": true,
"status": "in_progress"
}
按触发者与事件收敛
{
"owner": "octocat",
"repo": "Hello-World",
"actor": "octocat",
"event": "push",
"created": ">=2026-01-01"
}
按 Check Suite 关联(配合 PR 状态检查)
{
"owner": "octocat",
"repo": "Hello-World",
"check_suite_id": 42
}
实践建议:优先使用高区分度的过滤器(head_sha、workflow_id、check_suite_id)缩小范围;limit 默认 30、上限 100,只有当确实需要遍历全部历史时才使用 page 翻页,并且应当将 page 与 limit 组合使用以控制每次返回的数据量。
从 GitHub URL 提取参数
文档指出:如果用户提供了 GitHub URL,应提取 owner 与 repo 字段,以及 Schema 特有的 number / path / ref 键。例如:
https://github.com/octocat/Hello-World/actions→owner = "octocat"、repo = "Hello-World";https://github.com/octocat/Hello-World/actions/workflows/ci.yml→workflow_id = "ci.yml";- 对于 PR 类工具(如
github.get_pull_request)应提取pr_number,对于 issue 类工具应提取issue_number,而本工具对应的 Schema 特有键则是workflow_id(或用于精确定位的head_sha、check_suite_id)。
这一约定的本质是:参数名必须与各能力 Schema 完全一致,不同工具族共享 owner/repo 基线字段,但资源定位键各不相同,模型在调用前应先解析 URL 中的路径段再映射到对应的 Schema 字段。
认证、权限与安全模型
在 manifest.toml 中,github.get_workflow_runs 的声明信息如下:
- effects:
["network", "use_secret"],即需要网络出口并消费密钥; - default_permission:
allow,属于只读查询类工具,默认放行(对比写操作类工具如github.trigger_workflow为ask); - visibility:
model,对模型可见; - origin_gate_matrix:
loop_run = "gated_unless_granted"、product = "forbidden"、automation = "forbidden",即该工具仅可在 loop 运行场景中按授权门控使用; - credentials:句柄
github_runtime_token,vendor 为github,audience 限定https://api.github.com,注入方式为请求头authorization: token <TOKEN>,占位环境变量GH_TOKEN。
认证侧,[auth.github] 采用 api_key 方式,字段 github_runtime_token(Personal access token),并通过 GET https://api.github.com/user(期望 200)做账号校验。
安全上值得注意:该工具通过主机 HTTP egress 访问 GitHub API,网络目标由主机侧策略管控;令牌只对 api.github.com 注入,绝不会泄露到其他主机。这与你之前接触过的 github.get_job_logs 类似——后者在 302 重定向到 Azure blob 下载地址时,主机 egress 会先对目标重新鉴权并剥离 Authorization 头,确保 GitHub token 不会发送到 blob 存储。
错误处理与边界情况
从 request.rs 可以看到该工具的错误语义:
- HTTP 非 2xx:统一返回
github_api_error_status_{status}错误码;其中422若响应体是 GitHub "Validation Failed" 且带errors数组,会返回更精确的github_api_error_status_422_validation; - 401 认证失败:会从响应体提取 provider 的
message字段(如 "Bad credentials"),截断到 512 字符后附带在错误中,便于模型识别"需要重新认证"; - 主机 egress 失败:映射为
AuthRequired、github_api_egress_denied、github_api_request_failed、github_api_body_limit等错误码(后者对应输出过大被主机拒绝)。
输入端还有两处隐含边界值得注意:一是所有可选字符串过滤器在追加为查询参数前会经过 validate_input_length(上限 65536 字符);二是 workflow_id 拒绝包含 /、..、:,从根源上防止路径注入类问题。
与工作流工具族的配合
github.get_workflow_runs 只是工作流工具族的第一步,官方在 wasm-src/src/api/actions.rs 中集中实现了整组 Actions 能力,典型配合链路为:
| 环节 | 工具 | 输入要点 |
|---|---|---|
| 触发 | github.trigger_workflow |
workflow_id + ref + 可选 inputs |
| 查询运行 | github.get_workflow_runs |
本文主题,得到 run_id |
| 查看任务 | github.get_workflow_run_jobs |
run_id(+ filter/limit/page) |
| 拉取日志 | github.get_job_logs |
job_id |
| 查看产物 | github.get_workflow_run_artifacts |
run_id(+ name/direction) |
| 重跑 | github.rerun_failed_workflow_run_jobs / github.rerun_workflow_job |
run_id / job_id |
典型排障流程:先用 get_workflow_runs 按 head_sha 或 branch 定位失败运行 → 取 run_id 调 get_workflow_run_jobs 定位失败 job → 取 job_id 调 get_job_logs 拉取日志分析根因 → 修复后可用重跑工具恢复 CI。
总结
github.get_workflow_runs 是一个设计精良的只读查询能力:输入侧由 JSON Schema 严格约束,14 种状态枚举与 8 类过滤器完整覆盖了 GitHub Actions 运行查询的主要维度;实现侧在 WASM guest 中完成了输入校验、URL 编码、端点选择与查询参数组装,并通过主机 egress + 令牌定向注入保障了凭据安全。正确用法是:先提取 URL 中的 owner/repo 与 Schema 特有键,再用 head_sha、branch、status、workflow_id 等过滤器精确收敛,最后才考虑分页——这既是官方 prompt 文档的核心指引,也与底层实现的能力边界完全一致。