如何使用 GitLab API 获取子管道的作业工件?

时间:2021-03-29 18:32:18

标签: gitlab gitlab-ci gitlab-api

job 1 ________ child-pipeline ________ job 3 (x)
         /                       \
job 2 __/                         \___ job 4

我正在尝试接触 job 3 的神器。这是我目前到达的地方:

根据the GitLab docs,我需要job 3 的ID。我使用 Gitbeaker 来简化 NodeJS 中的事情,但如果您不熟悉它,可以使用 curl 示例来回答。

首先,我获得了提交的管道,然后我检索了这些管道的作业,但那些只给了我 job 1job 2,即使文档说“在 GitLab 13.3 及更高版本中,这个端点返回任何管道的数据,包括子管道。(ref)"

api.Pipelines.all(PROJECT_ID, {
  sha: 'commit_sha',
  ref: 'master',
}).then(async (commitPipelines) => {
  for await (const pipeline of commitPipelines) {
    api.Jobs.showPipelineJobs(PROJECT_ID, pipeline.id, {
      scope: 'success',
    }).then((pipelineJobs) => {
      console.log(pipelineJobs);
    });
  }
});

然后我选择了另一条路线来获取 child-pipelines 阶段的提交状态,假设我将获得子管道的管道 ID 并且我会到达它们的作业。但我得到的 ID 不是管道 ID。

api.Commits.status(PROJECT_ID, 'commit_sha', {
  stage: 'child-pipelines',
  ref: 'master',
}).then((state) => {
  state.forEach(async (commitStatus) => {
    if (commitStatus.status === 'success') {
      console.log(commitStatus);
    }
  });
});

最后,我的两种方法都卡在了子管道上。也许,我忽略了这一点。有什么建议吗?

1 个答案:

答案 0 :(得分:1)

我发现 Gitlab 有一个端点可以访问名为 pipeline bridges 的子管道,它帮助我找到了解决方案。

async function getCommitPipelines(commitId) {
  return await api.Pipelines.all(GITLAB_PROJECT_ID, {
    sha: commitId,
    ref: 'master',
    status: 'success',
  });
}

async function getPipelineJobs(pipelineId) {
  return await api.Jobs.showPipelineJobs(GITLAB_PROJECT_ID, pipelineId, {
    scope: 'success',
  });
}

async function getPipelineBridges(pipelineId) {
  return await api.Jobs.showPipelineBridges(GITLAB_PROJECT_ID, pipelineId);
}

async function downloadArtifactFile(jobId) {
  return await api.Jobs.downloadSingleArtifactFile(
    GITLAB_PROJECT_ID,
    jobId,
    'artifact-file.json',
  );
}

async function downloadCommitArtifacts(commitId) {
  const commitArtifacts = [];
  // 1. Get all of the pipelines of a the commit
  const commitPipelines = await getCommitPipelines(commitId);

  for (const commitPipeline of commitPipelines) {
    // 2. Get all of the downstream pipelines of each pipeline
    const bridgePipelines = await getPipelineBridges(commitPipeline.id);

    for (const bridgePipeline of bridgePipelines) {
      // 3. Get all the child pipeline jobs
      // Here you are looking at the job 3 and job 4
      const job = await getPipelineJobs(
        bridgePipeline.downstream_pipeline.id
      );

      for (const job of jobs) {
        if (job.name !== 'job-3') {
          continue;
        }

        // 4. Get the artifact (the artifact file in this case) from the job
        const artifactFile = await downloadArtifactFile(job.id);
        commitArtifacts.push(artifactFile);
      }
    }
  }

  return commitArtifacts;
}