Github API get all workflow run for an pull request

Viewed 1155

I want to use Github API to find the workflow runs that are triggered by a particular pull requests, but this information isn't include in GET /repos/{owner}/{repo}/pulls/{pull_number}.

I also tried to associate workflow runs and pr by searching through list of workflow runs, but for workflow runs that are triggered by forked pr, response of GET /repos/{owner}/{repo}/actions/runs/{run_id} has empty "pull_requests" attribute.

I am wondering if anyone know how to I can associate pull request with respective workflow runs? Thanks!

2 Answers

Here is how to do this with JavaScript / octokit.js (usable in an actions/github-script step):

// Obtain the check runs for the head SHA1 of this pull request.
const check_runs = (await github.rest.checks.listForRef({
  owner : context.payload.repository.owner.login,
  repo : context.payload.repository.name,
  ref: pull_request.head.sha,
})).data.check_runs;

// For every relevant run:
for (var run of check_runs) {
  if (run.app.slug == 'github-actions') {

    // Get the corresponding Actions job.
    // The Actions job ID is the same as the Checks run ID
    // (not to be confused with the Actions run ID).
    const job = (await github.rest.actions.getJobForWorkflowRun({
      owner : context.payload.repository.owner.login,
      repo : context.payload.repository.name,
      job_id : run.id,
    })).data;

    // Now, get the Actions run that this job is in.
    const actions_run = (await github.rest.actions.getWorkflowRun({
      owner : context.payload.repository.owner.login,
      repo : context.payload.repository.name,
      run_id : job.run_id,
    })).data;

    if (actions_run.event == 'pull_request') {
      // ...
    }
  }
}

One possible solution is to iterate over each object in workflow_runs and compare the workflow_runs.head_sha to the pull request head.sha.

Solution in JavaScript might look like:

const getWorkflowRunsForPullRequest = async pullNumber => {
  const pullResponse = await fetch(`https://api.github.com/repos/{owner}/{repo}/pulls/${pullNumber}`)
  const workflowsResponse = await fetch('https://api.github.com/repos/{owner}/{repo}/actions/runs?event=pull_request')
  const pull = await pullResponse.json()
  const workflows = await workflowsResponse.json()

  return workflows.workflow_runs.filter(workflow => {
    return workflow.head_sha === pull.head.sha
  })
}

Note, this solution does not consider paging of the workflow API response, you would want to include logic for paging as well, and possibly include more query parameters for filtering the response set further. You could also optimize further by making these API requests in parallel with Promise.all.

Related