diff --git a/lib/pr_checker.js b/lib/pr_checker.js index 8128ef0d..3ed2d00a 100644 --- a/lib/pr_checker.js +++ b/lib/pr_checker.js @@ -404,6 +404,14 @@ export default class PRChecker { return false; } + const files = pr.files.nodes; + + // Don't require Jenkins run if pr is doc-only change + const isDocOnlyChange = files.every(({ path }) => path.endsWith('.md')); + if (isDocOnlyChange) { + return false; + } + const ciNeededFolderRx = /^(deps|lib|src|test)\//; const ciNeededToolFolderRx = /^tools\/(code_cache|gyp|icu|inspector|msvs|snapshot|v8_gypfiles)/; @@ -416,7 +424,7 @@ export default class PRChecker { ]; const ciNeededExtensionList = ['.gyp', '.gypi', '.bat']; - return pr.files.nodes.some( + return files.some( ({ path }) => ciNeededFolderRx.test(path) || ciNeededToolFolderRx.test(path) || diff --git a/test/fixtures/pull_requests/code-change.json b/test/fixtures/pull_requests/code-change.json new file mode 100644 index 00000000..a9f75f8a --- /dev/null +++ b/test/fixtures/pull_requests/code-change.json @@ -0,0 +1,23 @@ +{ + "createdAt": "2022-07-12T11:55:42Z", + "authorAssociation": "MEMBER", + "author": { + "login": "F3n67u", + "email": "F3n67u@outlook.com", + "name": "Feng Yu" + }, + "url": "https://github.com/nodejs/node/pull/43796", + "bodyHTML": "\n

Fix #43795

", + "bodyText": "Fix #43795", + "labels": { "nodes": [{ "name": "http" }, { "name": "needs-ci" }] }, + "files": { "nodes": [{ "path": "lib/_http_server.js" }] }, + "title": "http: check if `socket` is null before destroy", + "baseRefName": "main", + "headRefName": "closeIdleConnections", + "changedFiles": 1, + "mergeable": "MERGEABLE", + "closed": false, + "closedAt": null, + "merged": false, + "mergedAt": null +} diff --git a/test/fixtures/pull_requests/doc-only-in-tools.json b/test/fixtures/pull_requests/doc-only-in-tools.json new file mode 100644 index 00000000..6904e705 --- /dev/null +++ b/test/fixtures/pull_requests/doc-only-in-tools.json @@ -0,0 +1,31 @@ +{ + "createdAt": "2022-06-19T03:31:58Z", + "authorAssociation": "MEMBER", + "author": { + "login": "F3n67u", + "email": "F3n67u@outlook.com", + "name": "Feng Yu" + }, + "url": "https://github.com/nodejs/node/pull/43483", + "bodyHTML": "\n

unicode-org/icu repo has renamed its default branch to main also, this pr update the link to unicode-org/icu old master branch.

", + "bodyText": "unicode-org/icu repo has renamed its default branch to main also, this pr update the link to unicode-org/icu old master branch.", + "labels": { + "nodes": [ + { "name": "tools" }, + { "name": "i18n-api" }, + { "name": "fast-track" }, + { "name": "author ready" }, + { "name": "icu" } + ] + }, + "files": { "nodes": [{ "path": "tools/icu/README.md" }] }, + "title": "tools: update link of `ICU data slicer`", + "baseRefName": "main", + "headRefName": "doc/icu", + "changedFiles": 1, + "mergeable": "UNKNOWN", + "closed": true, + "closedAt": "2022-06-20T09:20:58Z", + "merged": true, + "mergedAt": "2022-06-20T09:20:58Z" +} diff --git a/test/unit/pr_checker.test.js b/test/unit/pr_checker.test.js index 761bb83b..eed5ef19 100644 --- a/test/unit/pr_checker.test.js +++ b/test/unit/pr_checker.test.js @@ -923,6 +923,92 @@ describe('PRChecker', () => { }); }); + it('should succeed if doc-only changes in tools dir without Jenkins', + async() => { + const cli = new TestCLI(); + + const expectedLogs = { + ok: [ + ['Last GitHub CI successful'] + ], + info: [ + ['Green GitHub CI is sufficient'] + ] + }; + + const data = { + pr: pullRequests['doc-only-in-tools'], + reviewers: allGreenReviewers, + comments: [], + reviews: approvingReviews, + commits: githubCI['check-suite-success'], + collaborators, + authorIsNew: () => true, + getThread() { + return PRData.prototype.getThread.call(this); + } + }; + const checker = new PRChecker( + cli, + data, + { + json: sinon.stub().callsFake(await function() { + return undefined; + }) + }, + argv); + + cli.clearCalls(); + const status = await checker.checkCI(); + assert(status); + cli.assertCalledWith(expectedLogs, { + ignore: ['startSpinner', 'updateSpinner', 'stopSpinner'] + }); + } + ); + + it('should fail if code changes without Jenkins', async() => { + const cli = new TestCLI(); + + const expectedLogs = { + error: [ + ['No Jenkins CI runs detected'] + ], + ok: [ + ['Last GitHub CI successful'] + ] + }; + + const data = { + pr: pullRequests['code-change'], + reviewers: allGreenReviewers, + comments: [], + reviews: approvingReviews, + commits: githubCI['check-suite-success'], + collaborators, + authorIsNew: () => true, + getThread() { + return PRData.prototype.getThread.call(this); + } + }; + const checker = new PRChecker( + cli, + data, + { + json: sinon.stub().callsFake(await function() { + return undefined; + }) + }, + argv); + + cli.clearCalls(); + const status = await checker.checkCI(); + assert(!status); + cli.assertCalledWith(expectedLogs, { + ignore: ['startSpinner', 'updateSpinner', 'stopSpinner'] + }); + }); + it('should succeed if doc-only changes with failed Jenkins', async() => { const cli = new TestCLI();