diff --git a/lib/platform/bitbucket-server/index.js b/lib/platform/bitbucket-server/index.js index c2a716a558a32a3e81cd135f82dda3a9b598ccea..1a15af6f827649306df47e228acbaaab2a645806 100644 --- a/lib/platform/bitbucket-server/index.js +++ b/lib/platform/bitbucket-server/index.js @@ -729,7 +729,43 @@ async function getPr(prNo, refreshCache) { ); pr.isConflicted = !!mergeRes.body.conflicted; pr.canMerge = !!mergeRes.body.canMerge; - pr.canRebase = true; + + const prCommits = (await api.get( + `./rest/api/1.0/projects/${config.projectKey}/repos/${ + config.repositorySlug + }/pull-requests/${prNo}/commits?withCounts=true` + )).body; + + if (prCommits.totalCount === 1) { + if (global.gitAuthor) { + const commitAuthorEmail = prCommits.values[0].author.emailAddress; + if (commitAuthorEmail === global.gitAuthor.email) { + logger.debug( + { prNo }, + '1 commit matches configured gitAuthor so can rebase' + ); + pr.canRebase = true; + } else { + logger.debug( + { prNo }, + '1 commit and not by configured gitAuthor so cannot rebase' + ); + pr.canRebase = false; + } + } else { + logger.debug( + { prNo }, + '1 commit and no configured gitAuthor so can rebase' + ); + pr.canRebase = true; + } + } else { + logger.debug( + { prNo }, + `${prCommits.totalCount} commits so cannot rebase` + ); + pr.canRebase = false; + } } if (await branchExists(pr.branchName)) { diff --git a/lib/platform/bitbucket-server/utils.js b/lib/platform/bitbucket-server/utils.js index f8d3c7d5464ef280b9930167aff268b45a7654ee..9e3887401e8973c33021b9cb9d25cd8699ae7380 100644 --- a/lib/platform/bitbucket-server/utils.js +++ b/lib/platform/bitbucket-server/utils.js @@ -17,6 +17,7 @@ const prInfo = pr => ({ title: pr.title, state: prStateMapping[pr.state], createdAt: pr.createdDate, + canRebase: false, }); const addMaxLength = (inputUrl, limit = 100) => { diff --git a/test/platform/bitbucket-server/__snapshots__/index.spec.js.snap b/test/platform/bitbucket-server/__snapshots__/index.spec.js.snap index 3c9ea451309c47b8967c40749ec770ce4ece225b..79979eedcf13727190f3d39a89f47f623f3c3c67 100644 --- a/test/platform/bitbucket-server/__snapshots__/index.spec.js.snap +++ b/test/platform/bitbucket-server/__snapshots__/index.spec.js.snap @@ -241,6 +241,7 @@ Object { "body": "* Line 1 * Line 2", "branchName": "userName1/pullRequest5", + "canRebase": false, "createdAt": 1547853840016, "number": 5, "state": "open", @@ -320,6 +321,9 @@ Array [ Array [ "./rest/api/1.0/projects/SOME/repos/repo/pull-requests/5/merge", ], + Array [ + "./rest/api/1.0/projects/SOME/repos/repo/pull-requests/5/commits?withCounts=true", + ], ] `; @@ -435,6 +439,113 @@ Array [ ] `; +exports[`platform/bitbucket-server endpoint with no path getPr() canRebase 1`] = ` +Object { + "body": "* Line 1 +* Line 2", + "branchName": "userName1/pullRequest5", + "canMerge": false, + "canRebase": false, + "createdAt": 1547853840016, + "displayNumber": "Pull Request #5", + "isConflicted": false, + "number": 5, + "reviewers": Array [ + "userName2", + ], + "state": "open", + "title": "title", + "version": 1, +} +`; + +exports[`platform/bitbucket-server endpoint with no path getPr() canRebase 2`] = ` +Object { + "body": "* Line 1 +* Line 2", + "branchName": "userName1/pullRequest5", + "canMerge": false, + "canRebase": true, + "createdAt": 1547853840016, + "displayNumber": "Pull Request #5", + "isConflicted": false, + "number": 5, + "reviewers": Array [ + "userName2", + ], + "state": "open", + "title": "title", + "version": 1, +} +`; + +exports[`platform/bitbucket-server endpoint with no path getPr() canRebase 3`] = ` +Object { + "body": "* Line 1 +* Line 2", + "branchName": "userName1/pullRequest5", + "canMerge": false, + "canRebase": false, + "createdAt": 1547853840016, + "displayNumber": "Pull Request #5", + "isConflicted": false, + "number": 5, + "reviewers": Array [ + "userName2", + ], + "state": "open", + "title": "title", + "version": 1, +} +`; + +exports[`platform/bitbucket-server endpoint with no path getPr() canRebase 4`] = ` +Array [ + Array [ + "./rest/api/1.0/projects/SOME/repos/repo", + ], + Array [ + "./rest/api/1.0/projects/SOME/repos/repo/branches/default", + ], + Array [ + "./rest/api/1.0/projects/SOME/repos/repo/pull-requests/3", + Object { + "useCache": true, + }, + ], + Array [ + "./rest/api/1.0/projects/SOME/repos/repo/pull-requests/3/merge", + ], + Array [ + "./rest/api/1.0/projects/SOME/repos/repo/pull-requests/3/commits?withCounts=true", + ], + Array [ + "./rest/api/1.0/projects/SOME/repos/repo/pull-requests/5", + Object { + "useCache": true, + }, + ], + Array [ + "./rest/api/1.0/projects/SOME/repos/repo/pull-requests/5/merge", + ], + Array [ + "./rest/api/1.0/projects/SOME/repos/repo/pull-requests/5/commits?withCounts=true", + ], + Array [ + "./rest/api/1.0/projects/SOME/repos/repo/pull-requests/5", + Object { + "useCache": true, + }, + ], + Array [ + "./rest/api/1.0/projects/SOME/repos/repo/pull-requests/5/merge", + ], + Array [ + "./rest/api/1.0/projects/SOME/repos/repo/pull-requests/5/commits?withCounts=true", + ], +] +`; + exports[`platform/bitbucket-server endpoint with no path getPr() gets a PR 1`] = ` Object { "body": "* Line 1 @@ -472,6 +583,9 @@ Array [ Array [ "./rest/api/1.0/projects/SOME/repos/repo/pull-requests/5/merge", ], + Array [ + "./rest/api/1.0/projects/SOME/repos/repo/pull-requests/5/commits?withCounts=true", + ], ] `; @@ -479,6 +593,7 @@ exports[`platform/bitbucket-server endpoint with no path getPr() gets a closed P Object { "body": undefined, "branchName": undefined, + "canRebase": false, "createdAt": undefined, "displayNumber": "Pull Request #undefined", "number": undefined, @@ -531,6 +646,7 @@ Array [ "body": "* Line 1 * Line 2", "branchName": "userName1/pullRequest5", + "canRebase": false, "createdAt": 1547853840016, "number": 5, "state": "open", @@ -597,6 +713,9 @@ Array [ Array [ "./rest/api/1.0/projects/SOME/repos/repo/pull-requests/5/merge", ], + Array [ + "./rest/api/1.0/projects/SOME/repos/repo/pull-requests/5/commits?withCounts=true", + ], Array [ "./rest/api/1.0/projects/SOME/repos/repo/pull-requests/5", Object { @@ -606,6 +725,9 @@ Array [ Array [ "./rest/api/1.0/projects/SOME/repos/repo/pull-requests/5/merge", ], + Array [ + "./rest/api/1.0/projects/SOME/repos/repo/pull-requests/5/commits?withCounts=true", + ], ] `; @@ -634,6 +756,9 @@ Array [ Array [ "./rest/api/1.0/projects/SOME/repos/repo/pull-requests/5/merge", ], + Array [ + "./rest/api/1.0/projects/SOME/repos/repo/pull-requests/5/commits?withCounts=true", + ], ] `; @@ -668,6 +793,9 @@ Array [ Array [ "./rest/api/1.0/projects/SOME/repos/repo/pull-requests/5/merge", ], + Array [ + "./rest/api/1.0/projects/SOME/repos/repo/pull-requests/5/commits?withCounts=true", + ], ] `; @@ -696,6 +824,9 @@ Array [ Array [ "./rest/api/1.0/projects/SOME/repos/repo/pull-requests/5/merge", ], + Array [ + "./rest/api/1.0/projects/SOME/repos/repo/pull-requests/5/commits?withCounts=true", + ], ] `; @@ -824,6 +955,9 @@ Array [ Array [ "./rest/api/1.0/projects/SOME/repos/repo/pull-requests/5/merge", ], + Array [ + "./rest/api/1.0/projects/SOME/repos/repo/pull-requests/5/commits?withCounts=true", + ], Array [ "./rest/api/1.0/projects/SOME/repos/repo/pull-requests/5", Object { @@ -833,6 +967,9 @@ Array [ Array [ "./rest/api/1.0/projects/SOME/repos/repo/pull-requests/5/merge", ], + Array [ + "./rest/api/1.0/projects/SOME/repos/repo/pull-requests/5/commits?withCounts=true", + ], ] `; @@ -875,6 +1012,9 @@ Array [ Array [ "./rest/api/1.0/projects/SOME/repos/repo/pull-requests/5/merge", ], + Array [ + "./rest/api/1.0/projects/SOME/repos/repo/pull-requests/5/commits?withCounts=true", + ], ] `; @@ -923,6 +1063,9 @@ Array [ Array [ "./rest/api/1.0/projects/SOME/repos/repo/pull-requests/5/merge", ], + Array [ + "./rest/api/1.0/projects/SOME/repos/repo/pull-requests/5/commits?withCounts=true", + ], ] `; @@ -965,6 +1108,9 @@ Array [ Array [ "./rest/api/1.0/projects/SOME/repos/repo/pull-requests/5/merge", ], + Array [ + "./rest/api/1.0/projects/SOME/repos/repo/pull-requests/5/commits?withCounts=true", + ], ] `; @@ -1231,6 +1377,7 @@ Object { "body": "* Line 1 * Line 2", "branchName": "userName1/pullRequest5", + "canRebase": false, "createdAt": 1547853840016, "number": 5, "state": "open", @@ -1310,6 +1457,9 @@ Array [ Array [ "./rest/api/1.0/projects/SOME/repos/repo/pull-requests/5/merge", ], + Array [ + "./rest/api/1.0/projects/SOME/repos/repo/pull-requests/5/commits?withCounts=true", + ], ] `; @@ -1425,6 +1575,113 @@ Array [ ] `; +exports[`platform/bitbucket-server endpoint with path getPr() canRebase 1`] = ` +Object { + "body": "* Line 1 +* Line 2", + "branchName": "userName1/pullRequest5", + "canMerge": false, + "canRebase": false, + "createdAt": 1547853840016, + "displayNumber": "Pull Request #5", + "isConflicted": false, + "number": 5, + "reviewers": Array [ + "userName2", + ], + "state": "open", + "title": "title", + "version": 1, +} +`; + +exports[`platform/bitbucket-server endpoint with path getPr() canRebase 2`] = ` +Object { + "body": "* Line 1 +* Line 2", + "branchName": "userName1/pullRequest5", + "canMerge": false, + "canRebase": true, + "createdAt": 1547853840016, + "displayNumber": "Pull Request #5", + "isConflicted": false, + "number": 5, + "reviewers": Array [ + "userName2", + ], + "state": "open", + "title": "title", + "version": 1, +} +`; + +exports[`platform/bitbucket-server endpoint with path getPr() canRebase 3`] = ` +Object { + "body": "* Line 1 +* Line 2", + "branchName": "userName1/pullRequest5", + "canMerge": false, + "canRebase": false, + "createdAt": 1547853840016, + "displayNumber": "Pull Request #5", + "isConflicted": false, + "number": 5, + "reviewers": Array [ + "userName2", + ], + "state": "open", + "title": "title", + "version": 1, +} +`; + +exports[`platform/bitbucket-server endpoint with path getPr() canRebase 4`] = ` +Array [ + Array [ + "./rest/api/1.0/projects/SOME/repos/repo", + ], + Array [ + "./rest/api/1.0/projects/SOME/repos/repo/branches/default", + ], + Array [ + "./rest/api/1.0/projects/SOME/repos/repo/pull-requests/3", + Object { + "useCache": true, + }, + ], + Array [ + "./rest/api/1.0/projects/SOME/repos/repo/pull-requests/3/merge", + ], + Array [ + "./rest/api/1.0/projects/SOME/repos/repo/pull-requests/3/commits?withCounts=true", + ], + Array [ + "./rest/api/1.0/projects/SOME/repos/repo/pull-requests/5", + Object { + "useCache": true, + }, + ], + Array [ + "./rest/api/1.0/projects/SOME/repos/repo/pull-requests/5/merge", + ], + Array [ + "./rest/api/1.0/projects/SOME/repos/repo/pull-requests/5/commits?withCounts=true", + ], + Array [ + "./rest/api/1.0/projects/SOME/repos/repo/pull-requests/5", + Object { + "useCache": true, + }, + ], + Array [ + "./rest/api/1.0/projects/SOME/repos/repo/pull-requests/5/merge", + ], + Array [ + "./rest/api/1.0/projects/SOME/repos/repo/pull-requests/5/commits?withCounts=true", + ], +] +`; + exports[`platform/bitbucket-server endpoint with path getPr() gets a PR 1`] = ` Object { "body": "* Line 1 @@ -1462,6 +1719,9 @@ Array [ Array [ "./rest/api/1.0/projects/SOME/repos/repo/pull-requests/5/merge", ], + Array [ + "./rest/api/1.0/projects/SOME/repos/repo/pull-requests/5/commits?withCounts=true", + ], ] `; @@ -1469,6 +1729,7 @@ exports[`platform/bitbucket-server endpoint with path getPr() gets a closed PR 1 Object { "body": undefined, "branchName": undefined, + "canRebase": false, "createdAt": undefined, "displayNumber": "Pull Request #undefined", "number": undefined, @@ -1521,6 +1782,7 @@ Array [ "body": "* Line 1 * Line 2", "branchName": "userName1/pullRequest5", + "canRebase": false, "createdAt": 1547853840016, "number": 5, "state": "open", @@ -1587,6 +1849,9 @@ Array [ Array [ "./rest/api/1.0/projects/SOME/repos/repo/pull-requests/5/merge", ], + Array [ + "./rest/api/1.0/projects/SOME/repos/repo/pull-requests/5/commits?withCounts=true", + ], Array [ "./rest/api/1.0/projects/SOME/repos/repo/pull-requests/5", Object { @@ -1596,6 +1861,9 @@ Array [ Array [ "./rest/api/1.0/projects/SOME/repos/repo/pull-requests/5/merge", ], + Array [ + "./rest/api/1.0/projects/SOME/repos/repo/pull-requests/5/commits?withCounts=true", + ], ] `; @@ -1624,6 +1892,9 @@ Array [ Array [ "./rest/api/1.0/projects/SOME/repos/repo/pull-requests/5/merge", ], + Array [ + "./rest/api/1.0/projects/SOME/repos/repo/pull-requests/5/commits?withCounts=true", + ], ] `; @@ -1658,6 +1929,9 @@ Array [ Array [ "./rest/api/1.0/projects/SOME/repos/repo/pull-requests/5/merge", ], + Array [ + "./rest/api/1.0/projects/SOME/repos/repo/pull-requests/5/commits?withCounts=true", + ], ] `; @@ -1686,6 +1960,9 @@ Array [ Array [ "./rest/api/1.0/projects/SOME/repos/repo/pull-requests/5/merge", ], + Array [ + "./rest/api/1.0/projects/SOME/repos/repo/pull-requests/5/commits?withCounts=true", + ], ] `; @@ -1814,6 +2091,9 @@ Array [ Array [ "./rest/api/1.0/projects/SOME/repos/repo/pull-requests/5/merge", ], + Array [ + "./rest/api/1.0/projects/SOME/repos/repo/pull-requests/5/commits?withCounts=true", + ], Array [ "./rest/api/1.0/projects/SOME/repos/repo/pull-requests/5", Object { @@ -1823,6 +2103,9 @@ Array [ Array [ "./rest/api/1.0/projects/SOME/repos/repo/pull-requests/5/merge", ], + Array [ + "./rest/api/1.0/projects/SOME/repos/repo/pull-requests/5/commits?withCounts=true", + ], ] `; @@ -1865,6 +2148,9 @@ Array [ Array [ "./rest/api/1.0/projects/SOME/repos/repo/pull-requests/5/merge", ], + Array [ + "./rest/api/1.0/projects/SOME/repos/repo/pull-requests/5/commits?withCounts=true", + ], ] `; @@ -1913,6 +2199,9 @@ Array [ Array [ "./rest/api/1.0/projects/SOME/repos/repo/pull-requests/5/merge", ], + Array [ + "./rest/api/1.0/projects/SOME/repos/repo/pull-requests/5/commits?withCounts=true", + ], ] `; @@ -1955,6 +2244,9 @@ Array [ Array [ "./rest/api/1.0/projects/SOME/repos/repo/pull-requests/5/merge", ], + Array [ + "./rest/api/1.0/projects/SOME/repos/repo/pull-requests/5/commits?withCounts=true", + ], ] `; diff --git a/test/platform/bitbucket-server/_fixtures/responses.js b/test/platform/bitbucket-server/_fixtures/responses.js index 34605e25ef3cf944e9a3274882a363c4556800ec..22400d45c3dd972efd838085aa320e136ad0acd2 100644 --- a/test/platform/bitbucket-server/_fixtures/responses.js +++ b/test/platform/bitbucket-server/_fixtures/responses.js @@ -160,6 +160,17 @@ function generateServerResponses(endpoint) { values: [generatePR(endpoint, 'SOME', 'repo')], }, }, + [`${endpoint}/rest/api/1.0/projects/SOME/repos/repo/pull-requests/3`]: { + GET: generatePR(endpoint, 'SOME', 'repo'), + }, + [`${endpoint}/rest/api/1.0/projects/SOME/repos/repo/pull-requests/3/merge`]: { + GET: { conflicted: false }, + }, + [`${endpoint}/rest/api/1.0/projects/SOME/repos/repo/pull-requests/3/commits?withCounts=true`]: { + GET: { + totalCount: 2, + }, + }, [`${endpoint}/rest/api/1.0/projects/SOME/repos/repo/pull-requests/4`]: { GET: Promise.reject({ statusCode: 404 }), }, @@ -167,6 +178,12 @@ function generateServerResponses(endpoint) { GET: generatePR(endpoint, 'SOME', 'repo'), PUT: generatePR(endpoint, 'SOME', 'repo'), }, + [`${endpoint}/rest/api/1.0/projects/SOME/repos/repo/pull-requests/5/commits?withCounts=true`]: { + GET: { + totalCount: 1, + values: [ { author: { emailAddress: 'bot@renovateapp.com'} } ], + }, + }, [`${endpoint}/rest/api/1.0/projects/SOME/repos/repo/pull-requests/5/participants`]: { POST: { user: { diff --git a/test/platform/bitbucket-server/index.spec.js b/test/platform/bitbucket-server/index.spec.js index eb92d65528d830a7b9a583638d41fecac18830ec..10880bfffaaf093b723825d60308b697ceee4165 100644 --- a/test/platform/bitbucket-server/index.spec.js +++ b/test/platform/bitbucket-server/index.spec.js @@ -409,6 +409,25 @@ describe('platform/bitbucket-server', () => { expect(api.get.mock.calls).toMatchSnapshot(); }); + it('canRebase', async () => { + expect.assertions(4); + await initRepo(); + const author = global.gitAuthor; + try { + expect(await bitbucket.getPr(3)).toMatchSnapshot(); + + global.gitAuthor = { email: 'bot@renovateapp.com' }; + expect(await bitbucket.getPr(5)).toMatchSnapshot(); + + global.gitAuthor = { email: 'jane@example.com' }; + expect(await bitbucket.getPr(5)).toMatchSnapshot(); + + expect(api.get.mock.calls).toMatchSnapshot(); + } finally { + global.gitAuthor = author; + } + }); + it('gets a closed PR', async () => { expect.assertions(2); await initRepo();