GitLab GraphQL API多循环问题:无法获取流水线全部任务
问题根源
你当前的查询使用全局的jobCursor变量,但每个流水线的任务分页状态是独立的——一次查询中所有流水线的jobs字段都会复用同一个jobCursor,导致无法为每个流水线单独遍历任务分页,最终只能拿到每个流水线的前100个任务。
修改方案
需要拆分查询流程:先批量获取所有符合条件的流水线,再对每个流水线单独发起任务查询,为每个流水线维护独立的任务分页游标。
步骤1:查询所有目标流水线(仅获取必要字段)
先循环分页拿到当天所有成功流水线的完整信息(不含任务),保存每个流水线的id:
query($projectPath: ID!, $pipelineCursor: String) { project(fullPath: $projectPath) { pipelines(updatedAfter:"2023-09-06T00:00:00Z",updatedBefore:"2023-09-06T23:59:59Z",status:SUCCESS,first: 100,after: $pipelineCursor,source:"pipeline") { pageInfo{ hasNextPage endCursor } nodes { id createdAt startedAt updatedAt project { id webUrl } ref status duration queuedDuration user { username } configSource } } } }
步骤2:单独查询每个流水线的所有任务
对每个流水线的id,使用独立的jobCursor循环分页获取所有任务:
query($pipelineId: ID!, $jobCursor: String) { pipeline(id: $pipelineId) { jobs(first: 100, after: $jobCursor) { pageInfo { hasNextPage endCursor } nodes { id status name } } } }
Python代码调整示例
# 第一步:获取所有流水线 all_pipelines = [] pipeline_cursor = None while True: response = requests.post( api_url, json={ "query": 第一步的查询语句, "variables": { "projectPath": project_path, "pipelineCursor": pipeline_cursor } }, headers=headers ) data = response.json() pipeline_nodes = data["data"]["project"]["pipelines"]["nodes"] all_pipelines.extend(pipeline_nodes) page_info = data["data"]["project"]["pipelines"]["pageInfo"] if not page_info["hasNextPage"]: break pipeline_cursor = page_info["endCursor"] # 第二步:为每个流水线获取所有任务 for pipeline in all_pipelines: pipeline_id = pipeline["id"] all_jobs = [] job_cursor = None while True: response = requests.post( api_url, json={ "query": 第二步的查询语句, "variables": { "pipelineId": pipeline_id, "jobCursor": job_cursor } }, headers=headers ) data = response.json() job_nodes = data["data"]["pipeline"]["jobs"]["nodes"] all_jobs.extend(job_nodes) page_info = data["data"]["pipeline"]["jobs"]["pageInfo"] if not page_info["hasNextPage"]: break job_cursor = page_info["endCursor"] # 将任务列表附加到流水线对象中 pipeline["jobs"] = all_jobs
为什么原方案无效
GraphQL的变量是全局作用域,一次查询中所有jobs(first:100, after:$jobCursor)都会使用同一个$jobCursor值——但每个流水线的任务分页游标是独立的,流水线A的任务结束游标不能用于流水线B的任务查询,这就导致除了第一个流水线外,其他流水线的任务分页逻辑完全失效。
内容的提问来源于stack exchange,提问作者Sasanth
相关产品推荐
相关产品推荐

