import { request } from '../core.ts'
import type { GitHubAccount } from '../types.ts'
import { normalizePrLocator } from './pr-input.ts'
/**
* Fetch check-run status for a pull request's head commit.
*
* @param params - PR locator plus optional `account` (default `bot`).
* @returns `{ headSha, state, totalCount, checks }` where `state` is `pending`, `passing`, or `failing`.
* @example
* import getPrChecks from 'kody:@kentcdodds/github/pr/get-checks'
* const checks = await getPrChecks({ owner: 'kentcdodds', repo: 'kody', prNumber: 1 })
* // => { state: 'passing', totalCount: 3, checks: [...] }
*/
export default async function getPrChecks(params: Record<string, unknown> = {}) {
const account = (params.account as GitHubAccount | undefined) ?? 'bot'
const { owner, repo, prNumber } = normalizePrLocator(params)
const prResponse = await request<Record<string, unknown>>({
account,
path: `/repos/${owner}/${repo}/pulls/${prNumber}`,
throwOnError: true,
})
const pr = prResponse.data!
const head = pr.head as { sha?: string } | undefined
const headSha = head?.sha
if (!headSha) {
throw new Error(`Could not resolve head SHA for ${owner}/${repo}#${prNumber}`)
}
const checkRunsResponse = await request<Record<string, unknown>>({
account,
path: `/repos/${owner}/${repo}/commits/${headSha}/check-runs`,
query: { per_page: 100 },
throwOnError: true,
})
const checkRuns = checkRunsResponse.data!
const checks = ((checkRuns.check_runs ?? []) as Array<Record<string, unknown>>).map(
(run) => ({
name: run.name as string,
status: run.status as 'queued' | 'in_progress' | 'completed',
conclusion: (run.conclusion ?? null) as string | null,
detailsUrl: (run.details_url ?? null) as string | null,
startedAt: (run.started_at ?? null) as string | null,
completedAt: (run.completed_at ?? null) as string | null,
}),
)
const hasPending = checks.some((check) => check.status !== 'completed')
const hasFailure = checks.some(
(check) =>
check.status === 'completed' &&
check.conclusion !== 'success' &&
check.conclusion !== 'neutral' &&
check.conclusion !== 'skipped',
)
const state = hasFailure ? 'failing' : hasPending ? 'pending' : 'passing'
return {
repository: `${owner}/${repo}`,
prNumber,
headSha,
state,
totalCount: checks.length,
checks,
}
}