Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 27 additions & 8 deletions lib/pr_checker.js
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down Expand Up @@ -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;
Expand Down
9 changes: 8 additions & 1 deletion lib/queries/PR.gql
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,14 @@ query PR($prid: Int!, $owner: String!, $repo: String!) {
}
conclusion,
status,
checkRuns(first: 40) {
workflowRun {
event
runNumber
workflow {
id
}
}
checkRuns(first: 40, filterBy: { checkType: LATEST }) {
nodes {
name
status
Expand Down
2 changes: 1 addition & 1 deletion test/fixtures/github-ci/both-apis-failure.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"nodes": [
{
"app": { "slug": "github-actions" },
"workflowRun": { "event": "pull_request", "runNumber": 1, "workflow": { "id": "workflow-1" } },
"status": "COMPLETED",
"conclusion": "FAILURE"
}
Expand All @@ -22,4 +23,3 @@
}
}
]

2 changes: 1 addition & 1 deletion test/fixtures/github-ci/both-apis-success.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"nodes": [
{
"app": { "slug": "github-actions" },
"workflowRun": { "event": "pull_request", "runNumber": 1, "workflow": { "id": "workflow-1" } },
"status": "COMPLETED",
"conclusion": "SUCCESS"
}
Expand All @@ -22,4 +23,3 @@
}
}
]

1 change: 1 addition & 0 deletions test/fixtures/github-ci/check-suite-cancelled.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
"nodes": [
{
"app": { "slug": "github-actions" },
"workflowRun": { "event": "pull_request", "runNumber": 1, "workflow": { "id": "workflow-1" } },
"status": "COMPLETED",
"conclusion": "CANCELLED",
"checkRuns": {
Expand Down
1 change: 1 addition & 0 deletions test/fixtures/github-ci/check-suite-failure.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
"nodes": [
{
"app": { "slug": "github-actions" },
"workflowRun": { "event": "pull_request", "runNumber": 1, "workflow": { "id": "workflow-1" } },
"status": "COMPLETED",
"conclusion": "FAILURE",
"checkRuns": {
Expand Down
2 changes: 1 addition & 1 deletion test/fixtures/github-ci/check-suite-pending.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@
"nodes": [
{
"app": { "slug": "github-actions" },
"workflowRun": { "event": "pull_request", "runNumber": 1, "workflow": { "id": "workflow-1" } },
"status": "IN_PROGRESS"
}
]
}
}
}
]

1 change: 1 addition & 0 deletions test/fixtures/github-ci/check-suite-skipped.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
"nodes": [
{
"app": { "slug": "github-actions" },
"workflowRun": { "event": "pull_request", "runNumber": 1, "workflow": { "id": "workflow-1" } },
"status": "COMPLETED",
"conclusion": "SKIPPED"
}
Expand Down
1 change: 1 addition & 0 deletions test/fixtures/github-ci/check-suite-success.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
"nodes": [
{
"app": { "slug": "github-actions" },
"workflowRun": { "event": "pull_request", "runNumber": 1, "workflow": { "id": "workflow-1" } },
"status": "COMPLETED",
"conclusion": "SUCCESS"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"nodes": [
{
"app": { "slug": "github-actions" },
"workflowRun": { "event": "pull_request", "runNumber": 1, "workflow": { "id": "workflow-1" } },
"status": "COMPLETED",
"conclusion": "SUCCESS"
}
Expand All @@ -22,4 +23,3 @@
}
}
]

Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"nodes": [
{
"app": { "slug": "github-actions" },
"workflowRun": { "event": "pull_request", "runNumber": 1, "workflow": { "id": "workflow-1" } },
"status": "COMPLETED",
"conclusion": "FAILURE"
}
Expand All @@ -22,4 +23,3 @@
}
}
]

2 changes: 1 addition & 1 deletion test/fixtures/github-ci/success-dependabot-queued.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
},
{
"app": { "slug": "github-actions" },
"workflowRun": { "event": "pull_request", "runNumber": 1, "workflow": { "id": "workflow-1" } },
"status": "COMPLETED",
"conclusion": "SUCCESS"
}
Expand All @@ -26,4 +27,3 @@
}
}
]

3 changes: 2 additions & 1 deletion test/unit/graphql_queries.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ describe('GraphQL queries', () => {
assert.notStrictEqual(headCommitStart, -1);
assert.notStrictEqual(headCommitEnd, -1);
assert.match(headCommitQuery, /checkSuites\(first: 100\)/);
assert.match(headCommitQuery, /checkRuns\(first: 40\)/);
assert.match(headCommitQuery,
/checkRuns\(first: 40, filterBy: \{ checkType: LATEST \}\)/);
assert.match(headCommitQuery, /status \{\s+state\s+\}/);
assert.doesNotMatch(commitsQuery, /checkSuites/);
assert.doesNotMatch(commitsQuery, /checkRuns/);
Expand Down
69 changes: 69 additions & 0 deletions test/unit/pr_checker.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1825,6 +1825,45 @@ describe('PRChecker', () => {
cli.assertCalledWith(expectedLogs);
});

it('should ignore a superseded Check suite', async() => {
const cli = new TestCLI();
const commits = [{
commit: {
checkSuites: {
nodes: [
{
app: { slug: 'github-actions' },
workflowRun: {
event: 'pull_request',
runNumber: 2,
workflow: { id: 'workflow-1' }
},
status: 'COMPLETED',
conclusion: 'SUCCESS'
},
{
app: { slug: 'github-actions' },
workflowRun: {
event: 'pull_request',
runNumber: 1,
workflow: { id: 'workflow-1' }
},
status: 'COMPLETED',
conclusion: 'FAILURE'
}
]
}
}
}];
const data = Object.assign({}, baseData, { commits });
const checker = new PRChecker(cli, data, {}, testArgv);

const status = await checker.checkCI();

assert(status);
cli.assertCalledWith({ ok: [['Last GitHub CI successful']] });
});

it('should error if commit status failed', async() => {
const cli = new TestCLI();

Expand Down Expand Up @@ -2010,6 +2049,11 @@ describe('PRChecker', () => {
checkSuites: {
nodes: [{
app: { slug: 'github-actions' },
workflowRun: {
event: 'pull_request',
runNumber: 1,
workflow: { id: 'workflow-1' }
},
status: 'COMPLETED',
conclusion: 'FAILURE',
checkRuns: {
Expand Down Expand Up @@ -2067,6 +2111,11 @@ describe('PRChecker', () => {
checkSuites: {
nodes: [{
app: { slug: 'github-actions' },
workflowRun: {
event: 'pull_request',
runNumber: 1,
workflow: { id: 'workflow-1' }
},
status: 'COMPLETED',
conclusion: 'FAILURE',
checkRuns: {
Expand Down Expand Up @@ -2119,6 +2168,11 @@ describe('PRChecker', () => {
checkSuites: {
nodes: [{
app: { slug: 'github-actions' },
workflowRun: {
event: 'pull_request',
runNumber: 1,
workflow: { id: 'workflow-1' }
},
status: 'COMPLETED',
conclusion: 'CANCELLED'
// No checkRuns field
Expand Down Expand Up @@ -2154,6 +2208,11 @@ describe('PRChecker', () => {
checkSuites: {
nodes: [{
app: { slug: 'github-actions' },
workflowRun: {
event: 'pull_request',
runNumber: 1,
workflow: { id: 'workflow-1' }
},
status: 'COMPLETED',
conclusion: 'FAILURE',
checkRuns: { nodes: [] }
Expand Down Expand Up @@ -2189,6 +2248,11 @@ describe('PRChecker', () => {
checkSuites: {
nodes: [{
app: { slug: 'github-actions' },
workflowRun: {
event: 'pull_request',
runNumber: 1,
workflow: { id: 'workflow-1' }
},
status: 'COMPLETED',
conclusion: 'FAILURE',
checkRuns: {
Expand Down Expand Up @@ -2231,6 +2295,11 @@ describe('PRChecker', () => {
checkSuites: {
nodes: [{
app: { slug: 'github-actions' },
workflowRun: {
event: 'pull_request',
runNumber: 1,
workflow: { id: 'workflow-1' }
},
status: 'COMPLETED',
conclusion: 'FAILURE',
checkRuns: {
Expand Down
Loading