Skip to content

Commit a247e11

Browse files
authored
Merge pull request #159 from wilzbach/improve-merge2
Improve mergeableState recognition merged-on-behalf-of: Sebastian Wilzbach <sebi.wilzbach@gmail.com>
2 parents 378757c + 5e8691c commit a247e11

File tree

2 files changed

+61
-23
lines changed

2 files changed

+61
-23
lines changed

source/dlangbot/cron.d

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -74,15 +74,17 @@ auto detectInactiveStablePR(PRTuple t)
7474

7575
auto detectPRWithMergeConflicts(PRTuple t)
7676
{
77+
import std.typecons : Nullable;
78+
7779
if (t.pr.mergeable.isNull)
7880
{
79-
logInfo("[cron-daily/%s/%d]: detectMerge - mergeable is null.", t.pr.repoSlug, t.pr.number);
81+
logInfo("[cron-daily/%s/%d/detectMerge]: mergeable is null.", t.pr.repoSlug, t.pr.number);
8082
// repeat request to receive computed mergeable information
8183
foreach (i; 0 .. 4)
8284
{
8385
import vibe.core.core : sleep;
8486
t.config.waitAfterMergeNullState.sleep;
85-
logInfo("[cron-daily/%s/%d]: detectMerge - repeating request", t.pr.repoSlug, t.pr.number);
87+
logInfo("[cron-daily/%s/%d/detectMerge]: repeating request", t.pr.repoSlug, t.pr.number);
8688
t.pr = t.pr.refresh;
8789
if (!t.pr.mergeable.isNull)
8890
goto mergable;
@@ -91,30 +93,40 @@ auto detectPRWithMergeConflicts(PRTuple t)
9193
}
9294
mergable:
9395

94-
bool isMergeable;
96+
Nullable!bool isMergeable;
9597
if (!t.pr.mergeableState.isNull)
9698
{
97-
logInfo("[cron-daily/%s/%d]: mergableState = %s", t.pr.repoSlug, t.pr.number, t.pr.mergeableState.get);
99+
logInfo("[cron-daily/%s/%d/detectMerge]: mergeableState = %s", t.pr.repoSlug, t.pr.number, t.pr.mergeableState.get);
98100
with (PullRequest.MergeableState)
99101
final switch(t.pr.mergeableState)
100102
{
101-
case unknown, checking:
102-
// should only be set if mergeable is null
103-
return LabelResponse(LabelAction.none, "");
104-
case clean, unstable:
103+
case clean:
104+
// branch is up to date with master and has no conflicts
105+
isMergeable = true;
106+
break;
107+
case unstable:
108+
// branch isn't up to date with master, but has no conflicts
105109
isMergeable = true;
106110
break;
107111
case dirty:
112+
// GitHub detected conflicts
108113
isMergeable = false;
109114
break;
110-
// a reviewer has blocked the merge (not observed yet)
115+
case unknown, checking:
116+
// should only be set if mergeable is null
111117
case blocked:
112-
return LabelResponse(LabelAction.none, "");
118+
// the repo requires reviews and the PR hasn't been approved yet
119+
// the repo requires status checks and they have failed
120+
break;
113121
}
114122
}
115-
else
123+
124+
if (isMergeable.isNull)
116125
{
117-
logInfo("[cron-daily/%s/%d]: mergable = %s", t.pr.repoSlug, t.pr.number, t.pr.mergeable.get);
126+
if (t.pr.mergeable.isNull)
127+
return LabelResponse(LabelAction.none, "");
128+
129+
logInfo("[cron-daily/%s/%d/detectMerge]: mergeable = %s", t.pr.repoSlug, t.pr.number, t.pr.mergeable.get);
118130
isMergeable = t.pr.mergeable.get;
119131
}
120132

test/cronjob.d

Lines changed: 37 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,13 @@ import std.stdio;
55

66
string[] repositories = ["dlang/phobos"];
77

8+
void dontTestStalled(ref Json j)
9+
{
10+
import std.datetime : Clock, days;
11+
j[$ - 1]["created_at"] = (Clock.currTime - 2.days).toISOExtString;
12+
j[$ - 1]["updated_at"] = (Clock.currTime - 2.days).toISOExtString;
13+
}
14+
815
// test the first items of the cron job
916
unittest
1017
{
@@ -62,13 +69,13 @@ unittest
6269
// test that stalled isn't falsely removed (e.g. by recent labelling)
6370
unittest
6471
{
65-
import std.datetime : Clock, days;
6672
setAPIExpectations(
6773
"/github/repos/dlang/phobos/issues?state=open&sort=updated&direction=asc", (ref Json j) {
6874
// only test one pull request
6975
j = Json([j[0]]);
7076
},
7177
"/github/repos/dlang/phobos/pulls/2526", (ref Json j) {
78+
import std.datetime : Clock, days;
7279
// simulate a recent label update
7380
j["updated_at"] = (Clock.currTime - 2.days).toISOExtString;
7481
},
@@ -88,7 +95,6 @@ unittest
8895
// test that no label updates are sent if no activity was found
8996
unittest
9097
{
91-
import std.datetime : Clock, days;
9298
setAPIExpectations(
9399
"/github/repos/dlang/phobos/issues?state=open&sort=updated&direction=asc", (ref Json j) {
94100
// only test one pull request
@@ -98,10 +104,7 @@ unittest
98104
j["mergeable"] = false;
99105
},
100106
"/github/repos/dlang/phobos/status/a04acd6a2813fb344d3e47369cf7fd64523ece44",
101-
"/github/repos/dlang/phobos/issues/2526/comments", (ref Json j) {
102-
j[$ - 1]["created_at"] = (Clock.currTime - 2.days).toISOExtString;
103-
j[$ - 1]["updated_at"] = (Clock.currTime - 2.days).toISOExtString;
104-
},
107+
"/github/repos/dlang/phobos/issues/2526/comments", &dontTestStalled,
105108
"/github/repos/dlang/phobos/pulls/2526/comments",
106109
);
107110

@@ -111,7 +114,6 @@ unittest
111114
// test that the merge state gets refreshed
112115
unittest
113116
{
114-
import std.datetime : Clock, days;
115117
setAPIExpectations(
116118
"/github/repos/dlang/phobos/issues?state=open&sort=updated&direction=asc", (ref Json j) {
117119
// only test one pull request
@@ -125,10 +127,7 @@ unittest
125127
j["mergeable_state"] = "dirty";
126128
},
127129
"/github/repos/dlang/phobos/status/a04acd6a2813fb344d3e47369cf7fd64523ece44",
128-
"/github/repos/dlang/phobos/issues/2526/comments", (ref Json j) {
129-
j[$ - 1]["created_at"] = (Clock.currTime - 2.days).toISOExtString;
130-
j[$ - 1]["updated_at"] = (Clock.currTime - 2.days).toISOExtString;
131-
},
130+
"/github/repos/dlang/phobos/issues/2526/comments", &dontTestStalled,
132131
"/github/repos/dlang/phobos/pulls/2526/comments",
133132
"/github/repos/dlang/phobos/issues/2526/labels",
134133
(scope HTTPServerRequest req, scope HTTPServerResponse res){
@@ -139,3 +138,30 @@ unittest
139138

140139
testCronDaily(repositories);
141140
}
141+
142+
// for "blocked" PRs, the `mergeable` attribute should be preferred
143+
// if mergeable is true, "needs rebase" should be removed
144+
unittest
145+
{
146+
setAPIExpectations(
147+
"/github/repos/dlang/phobos/issues?state=open&sort=updated&direction=asc", (ref Json j) {
148+
// only test one pull request
149+
j = Json([j[0]]);
150+
j[0]["labels"][0]["name"] = "needs rebase";
151+
},
152+
"/github/repos/dlang/phobos/pulls/2526", (ref Json j) {
153+
j["mergeable"] = true;
154+
j["mergeable_state"] = "blocked";
155+
},
156+
"/github/repos/dlang/phobos/status/a04acd6a2813fb344d3e47369cf7fd64523ece44",
157+
"/github/repos/dlang/phobos/issues/2526/comments", &dontTestStalled,
158+
"/github/repos/dlang/phobos/pulls/2526/comments",
159+
"/github/repos/dlang/phobos/issues/2526/labels",
160+
(scope HTTPServerRequest req, scope HTTPServerResponse res){
161+
assert(req.method == HTTPMethod.PUT);
162+
assert(req.json[].length == 0);
163+
},
164+
);
165+
166+
testCronDaily(repositories);
167+
}

0 commit comments

Comments
 (0)