已关闭
feat(actions): 支持 获取流水线的运行详情 API #446
aflyingto创建于 7月9日关闭于 7月10日
aflyingto
7月10日 评论:
7月10日 评论:
验证记录
- 当前版本: main @ f5533c1(含 #445 merged 的 actions 命令树 + v8 RawREST 模式)
- 需求确认: GitCode API v8 提供
GET /api/v8/repos/{owner}/{repo}/actions/runs/{run_id}(流水线运行详情),OpenAPI 文档已抓取于本 issue body - gc 现状:
pkg/cmd/actions/run/仅有list(#445),无viewapi/queries_actions.go仅有ListActionsRuns,无GetActionsRun- 响应比 list 项多
exist_in_default_branch+stages[](stages 内嵌 jobs→steps,较深)
- 重复检查: 无 merged PR,
origin/main无对应代码,verify-remote-factspassed - 结论: 需求有效且未实现,进入开发
实现计划
- API 层:
GetActionsRuns复用 #445;新增WorkflowRunDetail(embedWorkflowRunbase 字段 +ExistInDefaultBranch+Stages []WorkflowRunStage)+WorkflowRunStage/WorkflowRunJob/WorkflowRunStep。stages 内深度可空字段(parallel/condition/timeout/pre/post 等)用json.RawMessage透传,避免过度建模且保证--json全量忠实。 - 命令层:
pkg/cmd/actions/run/view/view.go—gc actions run view <run_id> -R owner/repo [--json],位置参数run_id(workflow_run_id),内联详情渲染(run 摘要 + stages 表)。注册到run父命令。 - 测试:
api/queries_actions_test.go加GetActionsRun(v8 路径含 run_id + 解析含 stages 的完整响应 + 404 错误);view/view_test.go。 - 真实命令验证: infra-test/gctest1 无流水线运行记录,故只能验证 404 路径(
view <nonexistent>→ exit 3,证 v8 路由 + 错误处理);完整解析路径由单测覆盖(与 #445 同策略)。


背景
GitCode API 文档 2.0.0 已提供 Actions API。该 Issue 用于跟踪 gitcode-cli 对此接口的支持设计与实现。
API 摘要
GET/api/v8/repos/{owner}/{repo}/actions/runs/{run_id}get_api_v8_repos_{owner}_{repo}_actions_runs_{run_id}pipeline-v8falseRequest Parameters
ownerreporun_idaccess_tokenRequest Body
无。
Responses
200
application/jsonapplication/json schema
{ "type": "object", "properties": { "workflow_run_id": { "type": "string", "description": "流水线运行id" }, "workflow_id": { "type": "string", "description": "流水线id" }, "workflow_name": { "type": "string", "description": "流水线名称" }, "file_path": { "type": "string" }, "title": { "type": "string" }, "status": { "type": "string", "description": "运行状态,COMPLETED(已完成),RUNNING(运行中),FAILED(失败),CANCELED(取消),IGNORED(忽略),PAUSED(暂停),SUSPEND(挂起)" }, "event": { "type": "string", "description": "触发事件类型,MR(mr事件),Push(推送事件),Manual(手动触发)" }, "run_number": { "type": "integer" }, "head_branch": { "type": "string" }, "head_sha": { "type": "string" }, "actor": { "type": "object", "properties": { "id": { "type": "string" }, "object_id": { "type": "string" }, "login": { "type": "string" }, "name": { "type": "string" } }, "required": [ "id", "object_id", "login", "name" ], "description": "触发人" }, "start_time": { "type": "integer", "description": "开始时间戳" }, "end_time": { "type": "integer", "description": "结束时间戳" }, "pause_time": { "type": "integer" }, "exist_in_default_branch": { "type": "boolean" }, "stages": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "string" }, "category": { "type": "string" }, "name": { "type": "string" }, "identifier": { "type": "string" }, "run_always": { "type": "boolean" }, "fail_fast": { "type": "boolean" }, "parallel": { "type": "null" }, "is_select": { "type": "boolean" }, "sequence": { "type": "integer" }, "depends_on": { "type": "array", "items": { "type": "string" } }, "condition": { "type": "null" }, "status": { "type": "string" }, "start_time": { "type": "integer" }, "end_time": { "type": "integer" }, "pause_time": { "type": "integer" }, "pre": { "type": "array", "items": { "type": "object", "properties": { "runtime_attribution": { "type": "null" }, "multi_step_editable": { "type": "integer" }, "official_task_version": { "type": "null" }, "icon_url": { "type": "null" }, "name": { "type": "null" }, "task": { "type": "string" }, "business_type": { "type": "null" }, "inputs": { "type": "array", "items": { "type": "string" } }, "env": { "type": "null" }, "sequence": { "type": "null" }, "identifier": { "type": "null" }, "endpoint_ids": { "type": "null" }, "id": { "type": "string" }, "job_run_id": { "type": "string" }, "last_dispatch_id": { "type": "string" }, "status": { "type": "string" }, "message": { "type": "null" }, "start_time": { "type": "integer" }, "end_time": { "type": "integer" }, "daily_build_number": { "type": "null" }, "timeout-minutes": { "type": "null" }, "continue-on-error": { "type": "null" } }, "required": [ "runtime_attribution", "multi_step_editable", "official_task_version", "icon_url", "name", "task", "business_type", "inputs", "env", "sequence", "identifier", "endpoint_ids", "id", "job_run_id", "last_dispatch_id", "status", "message", "start_time", "end_time", "daily_build_number", "timeout-minutes", "continue-on-error" ] } }, "post": { "type": "array", "items": { "type": "string" } }, "jobs": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "string", "description": "任务id" }, "category": { "type": "null" }, "sequence": { "type": "integer" }, "async": { "type": "null" }, "name": { "type": "string", "description": "任务名称" }, "identifier": { "type": "string" }, "depends_on": { "type": "array", "items": { "type": "string" } }, "condition": { "type": "string" }, "resource": { "type": "string" }, "is_select": { "type": "boolean" }, "timeout": { "type": "null" }, "last_dispatch_id": { "type": "string" }, "execute_cost_time": { "type": "integer" }, "status": { "type": "string", "description": "COMPLETED(已完成),RUNNING(运行中),FAILED(失败),CANCELED(取消),IGNORED(忽略),PAUSED(暂停),SUSPEND(挂起)" }, "message": { "type": "null" }, "start_time": { "type": "integer" }, "end_time": { "type": "integer" }, "exec_id": { "type": "string" }, "steps": { "type": "array", "items": { "type": "object", "properties": { "runtime_attribution": { "type": "null" }, "multi_step_editable": { "type": "integer" }, "official_task_version": { "type": "null" }, "icon_url": { "type": "null" }, "name": { "type": "string" }, "task": { "type": "string" }, "business_type": { "type": "null" }, "inputs": { "type": "array", "items": { "type": "object", "properties": { "key": { "type": "string" }, "value": { "type": "string" } }, "required": [ "key", "value" ] } }, "env": { "type": "array", "items": { "type": "string" } }, "sequence": { "type": "integer" }, "identifier": { "type": "string" }, "endpoint_ids": { "type": "null" }, "id": { "type": "string" }, "job_run_id": { "type": "string" }, "last_dispatch_id": { "type": "string" }, "status": { "type": "string" }, "message": { "type": "null" }, "start_time": { "type": "integer" }, "end_time": { "type": "integer" }, "daily_build_number": { "type": "null" }, "timeout-minutes": { "type": "null" }, "continue-on-error": { "type": "null" } }, "required": [ "runtime_attribution", "multi_step_editable", "official_task_version", "icon_url", "name", "task", "business_type", "inputs", "env", "sequence", "identifier", "endpoint_ids", "id", "job_run_id", "last_dispatch_id", "status", "message", "start_time", "end_time", "daily_build_number", "timeout-minutes", "continue-on-error" ] } }, "job_type": { "type": "string" }, "max_parallel": { "type": "null" }, "fail_fast": { "type": "null" }, "from": { "type": "null" }, "with": { "type": "null" }, "secrets": { "type": "null" }, "outputs_define": { "type": "null" }, "concurrency": { "type": "null" }, "timeout_minutes": { "type": "null" }, "continue_on_error": { "type": "null" } }, "required": [ "id", "category", "sequence", "async", "name", "identifier", "depends_on", "condition", "resource", "is_select", "timeout", "last_dispatch_id", "execute_cost_time", "status", "message", "start_time", "end_time", "exec_id", "steps", "job_type", "max_parallel", "fail_fast", "from", "with", "secrets", "outputs_define", "concurrency", "timeout_minutes", "continue_on_error" ] }, "description": "流水线运行任务信息" } }, "required": [ "id", "category", "name", "identifier", "run_always", "fail_fast", "parallel", "is_select", "sequence", "depends_on", "condition", "status", "start_time", "end_time", "pause_time", "pre", "post", "jobs" ], "description": "流水线运行阶段信息" } } }, "required": [ "workflow_run_id", "workflow_id", "workflow_name", "file_path", "title", "status", "event", "run_number", "head_branch", "head_sha", "actor", "start_time", "end_time", "pause_time", "exist_in_default_branch", "stages" ] }原始 OpenAPI Operation
{ "deprecated": false, "description": "", "operationId": "get_api_v8_repos_{owner}_{repo}_actions_runs_{run_id}", "tags": [ "pipeline-v8" ], "parameters": [ { "name": "owner", "in": "path", "description": "仓库所属空间地址(组织或个人的地址path)", "required": true, "schema": { "type": "string" } }, { "name": "repo", "in": "path", "description": "仓库路径(path)", "required": true, "schema": { "type": "string" } }, { "name": "run_id", "in": "path", "description": "流水线运行id", "required": true, "schema": { "type": "string" } }, { "name": "access_token", "in": "query", "description": "用户授权码", "required": false, "schema": { "type": "string" } } ], "responses": { "200": { "description": "", "content": { "application/json": { "schema": { "type": "object", "properties": { "workflow_run_id": { "type": "string", "description": "流水线运行id" }, "workflow_id": { "type": "string", "description": "流水线id" }, "workflow_name": { "type": "string", "description": "流水线名称" }, "file_path": { "type": "string" }, "title": { "type": "string" }, "status": { "type": "string", "description": "运行状态,COMPLETED(已完成),RUNNING(运行中),FAILED(失败),CANCELED(取消),IGNORED(忽略),PAUSED(暂停),SUSPEND(挂起)" }, "event": { "type": "string", "description": "触发事件类型,MR(mr事件),Push(推送事件),Manual(手动触发)" }, "run_number": { "type": "integer" }, "head_branch": { "type": "string" }, "head_sha": { "type": "string" }, "actor": { "type": "object", "properties": { "id": { "type": "string" }, "object_id": { "type": "string" }, "login": { "type": "string" }, "name": { "type": "string" } }, "required": [ "id", "object_id", "login", "name" ], "description": "触发人" }, "start_time": { "type": "integer", "description": "开始时间戳" }, "end_time": { "type": "integer", "description": "结束时间戳" }, "pause_time": { "type": "integer" }, "exist_in_default_branch": { "type": "boolean" }, "stages": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "string" }, "category": { "type": "string" }, "name": { "type": "string" }, "identifier": { "type": "string" }, "run_always": { "type": "boolean" }, "fail_fast": { "type": "boolean" }, "parallel": { "type": "null" }, "is_select": { "type": "boolean" }, "sequence": { "type": "integer" }, "depends_on": { "type": "array", "items": { "type": "string" } }, "condition": { "type": "null" }, "status": { "type": "string" }, "start_time": { "type": "integer" }, "end_time": { "type": "integer" }, "pause_time": { "type": "integer" }, "pre": { "type": "array", "items": { "type": "object", "properties": { "runtime_attribution": { "type": "null" }, "multi_step_editable": { "type": "integer" }, "official_task_version": { "type": "null" }, "icon_url": { "type": "null" }, "name": { "type": "null" }, "task": { "type": "string" }, "business_type": { "type": "null" }, "inputs": { "type": "array", "items": { "type": "string" } }, "env": { "type": "null" }, "sequence": { "type": "null" }, "identifier": { "type": "null" }, "endpoint_ids": { "type": "null" }, "id": { "type": "string" }, "job_run_id": { "type": "string" }, "last_dispatch_id": { "type": "string" }, "status": { "type": "string" }, "message": { "type": "null" }, "start_time": { "type": "integer" }, "end_time": { "type": "integer" }, "daily_build_number": { "type": "null" }, "timeout-minutes": { "type": "null" }, "continue-on-error": { "type": "null" } }, "required": [ "runtime_attribution", "multi_step_editable", "official_task_version", "icon_url", "name", "task", "business_type", "inputs", "env", "sequence", "identifier", "endpoint_ids", "id", "job_run_id", "last_dispatch_id", "status", "message", "start_time", "end_time", "daily_build_number", "timeout-minutes", "continue-on-error" ] } }, "post": { "type": "array", "items": { "type": "string" } }, "jobs": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "string", "description": "任务id" }, "category": { "type": "null" }, "sequence": { "type": "integer" }, "async": { "type": "null" }, "name": { "type": "string", "description": "任务名称" }, "identifier": { "type": "string" }, "depends_on": { "type": "array", "items": { "type": "string" } }, "condition": { "type": "string" }, "resource": { "type": "string" }, "is_select": { "type": "boolean" }, "timeout": { "type": "null" }, "last_dispatch_id": { "type": "string" }, "execute_cost_time": { "type": "integer" }, "status": { "type": "string", "description": "COMPLETED(已完成),RUNNING(运行中),FAILED(失败),CANCELED(取消),IGNORED(忽略),PAUSED(暂停),SUSPEND(挂起)" }, "message": { "type": "null" }, "start_time": { "type": "integer" }, "end_time": { "type": "integer" }, "exec_id": { "type": "string" }, "steps": { "type": "array", "items": { "type": "object", "properties": { "runtime_attribution": { "type": "null" }, "multi_step_editable": { "type": "integer" }, "official_task_version": { "type": "null" }, "icon_url": { "type": "null" }, "name": { "type": "string" }, "task": { "type": "string" }, "business_type": { "type": "null" }, "inputs": { "type": "array", "items": { "type": "object", "properties": { "key": { "type": "string" }, "value": { "type": "string" } }, "required": [ "key", "value" ] } }, "env": { "type": "array", "items": { "type": "string" } }, "sequence": { "type": "integer" }, "identifier": { "type": "string" }, "endpoint_ids": { "type": "null" }, "id": { "type": "string" }, "job_run_id": { "type": "string" }, "last_dispatch_id": { "type": "string" }, "status": { "type": "string" }, "message": { "type": "null" }, "start_time": { "type": "integer" }, "end_time": { "type": "integer" }, "daily_build_number": { "type": "null" }, "timeout-minutes": { "type": "null" }, "continue-on-error": { "type": "null" } }, "required": [ "runtime_attribution", "multi_step_editable", "official_task_version", "icon_url", "name", "task", "business_type", "inputs", "env", "sequence", "identifier", "endpoint_ids", "id", "job_run_id", "last_dispatch_id", "status", "message", "start_time", "end_time", "daily_build_number", "timeout-minutes", "continue-on-error" ] } }, "job_type": { "type": "string" }, "max_parallel": { "type": "null" }, "fail_fast": { "type": "null" }, "from": { "type": "null" }, "with": { "type": "null" }, "secrets": { "type": "null" }, "outputs_define": { "type": "null" }, "concurrency": { "type": "null" }, "timeout_minutes": { "type": "null" }, "continue_on_error": { "type": "null" } }, "required": [ "id", "category", "sequence", "async", "name", "identifier", "depends_on", "condition", "resource", "is_select", "timeout", "last_dispatch_id", "execute_cost_time", "status", "message", "start_time", "end_time", "exec_id", "steps", "job_type", "max_parallel", "fail_fast", "from", "with", "secrets", "outputs_define", "concurrency", "timeout_minutes", "continue_on_error" ] }, "description": "流水线运行任务信息" } }, "required": [ "id", "category", "name", "identifier", "run_always", "fail_fast", "parallel", "is_select", "sequence", "depends_on", "condition", "status", "start_time", "end_time", "pause_time", "pre", "post", "jobs" ], "description": "流水线运行阶段信息" } } }, "required": [ "workflow_run_id", "workflow_id", "workflow_name", "file_path", "title", "status", "event", "run_number", "head_branch", "head_sha", "actor", "start_time", "end_time", "pause_time", "exist_in_default_branch", "stages" ] } } }, "headers": {} } }, "security": [], "method": "get", "path": "/api/v8/repos/{owner}/{repo}/actions/runs/{run_id}", "servers": [ { "url": "https://api.gitcode.com", "description": "正式环境" } ], "securitySchemes": {}, "info": { "title": "GicodeOpenAPI", "description": "", "version": "1.0.0" }, "postman": { "name": "获取流水线的运行详情", "description": { "content": "", "type": "text/plain" }, "url": { "path": [ "api", "v8", "repos", ":owner", ":repo", "actions", "runs", ":run_id" ], "host": [ "{{baseUrl}}" ], "query": [ { "disabled": false, "description": { "content": "用户授权码", "type": "text/plain" }, "key": "access_token", "value": "" } ], "variable": [ { "disabled": false, "description": { "content": "(Required) 仓库所属空间地址(组织或个人的地址path)", "type": "text/plain" }, "type": "any", "value": "", "key": "owner" }, { "disabled": false, "description": { "content": "(Required) 仓库路径(path)", "type": "text/plain" }, "type": "any", "value": "", "key": "repo" }, { "disabled": false, "description": { "content": "(Required) 流水线运行id", "type": "text/plain" }, "type": "any", "value": "", "key": "run_id" } ] }, "header": [ { "key": "Accept", "value": "application/json" } ], "method": "GET" } }初步验收建议
infra-test/*仓库。access_token仅作为 API 参数记录,CLI 优先复用现有认证机制。