mirror of
https://github.com/renovatebot/renovate.git
synced 2025-01-11 22:46:27 +00:00
feat(github): allow positive PR reviews to override changes requested (#3037)
Closes #3012
This commit is contained in:
parent
60f73779d8
commit
9af3ef2ee1
4 changed files with 157 additions and 4 deletions
|
@ -1061,7 +1061,7 @@ async function getOpenPrs() {
|
|||
}
|
||||
}
|
||||
body
|
||||
reviews(first: 1, states:[CHANGES_REQUESTED]){
|
||||
reviews(first: 100){
|
||||
nodes{
|
||||
state
|
||||
}
|
||||
|
@ -1091,10 +1091,9 @@ async function getOpenPrs() {
|
|||
delete pr.headRefName;
|
||||
// https://developer.github.com/v4/enum/mergeablestate
|
||||
const canMergeStates = ['BEHIND', 'CLEAN'];
|
||||
const hasNegativeReview =
|
||||
pr.reviews && pr.reviews.nodes && pr.reviews.nodes.length > 0;
|
||||
pr.canMerge =
|
||||
canMergeStates.includes(pr.mergeStateStatus) && !hasNegativeReview;
|
||||
canMergeStates.includes(pr.mergeStateStatus) &&
|
||||
!hasNegativeReview(pr.reviews.nodes);
|
||||
// https://developer.github.com/v4/enum/mergestatestatus
|
||||
if (pr.mergeStateStatus === 'DIRTY') {
|
||||
pr.isConflicted = true;
|
||||
|
@ -1537,3 +1536,17 @@ async function getVulnerabilityAlerts() {
|
|||
}
|
||||
return alerts;
|
||||
}
|
||||
|
||||
function hasNegativeReview(reviews) {
|
||||
const negativeReviews = {};
|
||||
for (const review of reviews) {
|
||||
if (review.state === 'CHANGES_REQUESTED') {
|
||||
negativeReviews[review.author.login] = review.state;
|
||||
} else if (review.state === 'APPROVED') {
|
||||
if (negativeReviews[review.author.login]) {
|
||||
delete negativeReviews[review.author.login];
|
||||
}
|
||||
}
|
||||
}
|
||||
return Object.keys(negativeReviews).length > 0;
|
||||
}
|
||||
|
|
|
@ -40,6 +40,24 @@
|
|||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"reviews": {
|
||||
"nodes": [
|
||||
{
|
||||
"state": "CHANGES_REQUESTED",
|
||||
"author": {
|
||||
"login": "login"
|
||||
},
|
||||
"createdAt": "2018-12-30T15:53:22Z"
|
||||
},
|
||||
{
|
||||
"state": "APPROVED",
|
||||
"author": {
|
||||
"login": "login"
|
||||
},
|
||||
"createdAt": "2018-12-30T15:53:29Z"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -72,6 +90,17 @@
|
|||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"reviews": {
|
||||
"nodes": [
|
||||
{
|
||||
"state": "CHANGES_REQUESTED",
|
||||
"author": {
|
||||
"login": "login"
|
||||
},
|
||||
"createdAt": "2018-12-30T15:53:22Z"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
|
@ -308,6 +308,17 @@ Object {
|
|||
"isConflicted": true,
|
||||
"isStale": true,
|
||||
"number": 2500,
|
||||
"reviews": Object {
|
||||
"nodes": Array [
|
||||
Object {
|
||||
"author": Object {
|
||||
"login": "login",
|
||||
},
|
||||
"createdAt": "2018-12-30T15:53:22Z",
|
||||
"state": "CHANGES_REQUESTED",
|
||||
},
|
||||
],
|
||||
},
|
||||
"state": "open",
|
||||
"title": "chore(deps): update dependency jest to v23.6.0",
|
||||
}
|
||||
|
@ -360,6 +371,66 @@ Object {
|
|||
}
|
||||
`;
|
||||
|
||||
exports[`platform/github getPr(prNo) should return a mergeable PR if last review from the user is APPROVED 1`] = `
|
||||
Object {
|
||||
"branchName": "renovate/major-got-packages",
|
||||
"canMerge": true,
|
||||
"canRebase": true,
|
||||
"displayNumber": "Pull Request #2433",
|
||||
"isConflicted": false,
|
||||
"isStale": true,
|
||||
"labels": Array [
|
||||
"blocked",
|
||||
],
|
||||
"number": 2433,
|
||||
"reviews": Object {
|
||||
"nodes": Array [
|
||||
Object {
|
||||
"author": Object {
|
||||
"login": "login",
|
||||
},
|
||||
"createdAt": "2018-12-30T15:53:22Z",
|
||||
"state": "CHANGES_REQUESTED",
|
||||
},
|
||||
Object {
|
||||
"author": Object {
|
||||
"login": "login",
|
||||
},
|
||||
"createdAt": "2018-12-30T15:53:29Z",
|
||||
"state": "APPROVED",
|
||||
},
|
||||
],
|
||||
},
|
||||
"state": "open",
|
||||
"title": "build(deps): update got packages (major)",
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`platform/github getPr(prNo) should return a not mergeable PR if last review from the user is CHANGES_REQUESTED 1`] = `
|
||||
Object {
|
||||
"branchName": "renovate/jest-monorepo",
|
||||
"canMerge": false,
|
||||
"canRebase": true,
|
||||
"displayNumber": "Pull Request #2500",
|
||||
"isConflicted": true,
|
||||
"isStale": true,
|
||||
"number": 2500,
|
||||
"reviews": Object {
|
||||
"nodes": Array [
|
||||
Object {
|
||||
"author": Object {
|
||||
"login": "login",
|
||||
},
|
||||
"createdAt": "2018-12-30T15:53:22Z",
|
||||
"state": "CHANGES_REQUESTED",
|
||||
},
|
||||
],
|
||||
},
|
||||
"state": "open",
|
||||
"title": "chore(deps): update dependency jest to v23.6.0",
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`platform/github getPr(prNo) should return a not rebaseable PR if gitAuthor does not match 1 commit 1`] = `
|
||||
Object {
|
||||
"base": Object {
|
||||
|
|
|
@ -1651,6 +1651,46 @@ describe('platform/github', () => {
|
|||
expect(pr.canRebase).toBe(false);
|
||||
expect(pr).toMatchSnapshot();
|
||||
});
|
||||
it('should return a mergeable PR if last review from the user is APPROVED', async () => {
|
||||
await initRepo({
|
||||
repository: 'some/repo',
|
||||
token: 'token',
|
||||
});
|
||||
get.post.mockImplementationOnce(() => ({
|
||||
body: graphqlOpenPullRequests,
|
||||
}));
|
||||
// getBranchCommit
|
||||
get.mockImplementationOnce(() => ({
|
||||
body: {
|
||||
object: {
|
||||
sha: '1234',
|
||||
},
|
||||
},
|
||||
}));
|
||||
const pr = await github.getPr(2433);
|
||||
expect(pr.canMerge).toBe(true);
|
||||
expect(pr).toMatchSnapshot();
|
||||
});
|
||||
it('should return a not mergeable PR if last review from the user is CHANGES_REQUESTED', async () => {
|
||||
await initRepo({
|
||||
repository: 'some/repo',
|
||||
token: 'token',
|
||||
});
|
||||
get.post.mockImplementationOnce(() => ({
|
||||
body: graphqlOpenPullRequests,
|
||||
}));
|
||||
// getBranchCommit
|
||||
get.mockImplementationOnce(() => ({
|
||||
body: {
|
||||
object: {
|
||||
sha: '1234',
|
||||
},
|
||||
},
|
||||
}));
|
||||
const pr = await github.getPr(2500);
|
||||
expect(pr.canMerge).toBe(false);
|
||||
expect(pr).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
describe('getPrFiles()', () => {
|
||||
it('should return empty if no prNo is passed', async () => {
|
||||
|
|
Loading…
Reference in a new issue