diff --git a/lib/pr_checker.js b/lib/pr_checker.js index c4058f12..e28d1616 100644 --- a/lib/pr_checker.js +++ b/lib/pr_checker.js @@ -29,6 +29,30 @@ const FAST_TRACK_RE = /^Fast-track has been requested by @(.+?)\. Please 👍 to const FAST_TRACK_MIN_APPROVALS = 2; const GIT_CONFIG_GUIDE_URL = 'https://github.com/nodejs/node/blob/99b1ada/doc/guides/contributing/pull-requests.md#step-1-fork'; +function getLatestGitHubActionsCheckSuites(checkSuites) { + const latestByWorkflow = new Map(); + + for (const suite of checkSuites) { + const { app, workflowRun } = suite; + + if (app?.slug !== 'github-actions') { + continue; + } + + // Runs triggered by different events are independent and must not + // supersede one another. + const key = `${workflowRun.workflow.id}:${workflowRun.event}`; + const current = latestByWorkflow.get(key); + + if (!current || + workflowRun.runNumber > current.workflowRun.runNumber) { + latestByWorkflow.set(key, suite); + } + } + + return [...latestByWorkflow.values()]; +} + export const PR_CHECK_REASON_CODES = Object.freeze({ CANCELLED_GITHUB_CI: 'cancelled-github-ci', CLOSED: 'closed', @@ -459,14 +483,9 @@ export default class PRChecker { const pendingJobs = []; // GitHub new Check API - for (const { status, conclusion, app, checkRuns } of checkSuites.nodes) { - if (app.slug !== 'github-actions') { - // Ignore all non-github check suites, such as Dependabot and Codecov. - // They are expected to show up on PRs whose head branch is not on a - // fork and never complete. - continue; - } - + const latestCheckSuites = + getLatestGitHubActionsCheckSuites(checkSuites.nodes); + for (const { status, conclusion, app, checkRuns } of latestCheckSuites) { if (status !== 'COMPLETED') { pendingJobs.push({ app: app.slug, status, conclusion }); continue; diff --git a/lib/queries/PRCommits.gql b/lib/queries/PRCommits.gql index 70cf2e4e..9c415c9a 100644 --- a/lib/queries/PRCommits.gql +++ b/lib/queries/PRCommits.gql @@ -32,7 +32,14 @@ query Commits($prid: Int!, $owner: String!, $repo: String!, $after: String) { } conclusion, status, - checkRuns(first: 40) { + workflowRun { + event + runNumber + workflow { + id + } + } + checkRuns(first: 40, filterBy: { checkType: LATEST }) { nodes { name status