Skip to content

Commit 71279c2

Browse files
authored
Merge pull request #56 from wilzbach/user-title-labelling
Fix #53 - recognize common attributes in the PR title
2 parents a121412 + 7e9cb38 commit 71279c2

File tree

4 files changed

+81
-3
lines changed

4 files changed

+81
-3
lines changed

source/dlangbot/app.d

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ void githubHook(HTTPServerRequest req, HTTPServerResponse res)
152152
if (json["pull_request"]["merged"].get!bool)
153153
action = "merged";
154154
goto case;
155-
case "opened", "reopened", "synchronize", "labeled":
155+
case "opened", "reopened", "synchronize", "labeled", "edited":
156156

157157
auto pullRequest = json["pull_request"].deserializeJson!PullRequest;
158158
runTaskHelper(toDelegate(&handlePR), action, pullRequest);
@@ -189,6 +189,9 @@ void handlePR(string action, PullRequest pr)
189189
}
190190
}
191191

192+
if (action == "opened" || action == "edited")
193+
checkTitleForLabels(pr);
194+
192195
// we only query the commits once
193196
if (commits is null)
194197
commits = ghGetRequest(pr.commitsURL).readJson[];

source/dlangbot/github.d

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ void checkAndRemoveLabels(Json[] labels, in ref PullRequest pr, in string[] toRe
237237
.each!(l => pr.removeLabel(l));
238238
}
239239

240-
void addLabels(in ref PullRequest pr, string[] labels)
240+
void addLabels(in ref PullRequest pr, inout string[] labels)
241241
{
242242
auto labelUrl = "%s/repos/%s/issues/%d/labels"
243243
.format(githubAPIURL, pr.repoSlug, pr.number);
@@ -286,4 +286,39 @@ void searchForAutoMergePrs(string repoSlug)
286286
}
287287
}
288288

289+
/**
290+
Allows contributors to use [<label>] messages in the title.
291+
If they are part of a pre-defined, allowed list, the bot will add the
292+
respective label.
293+
*/
294+
void checkTitleForLabels(in ref PullRequest pr)
295+
{
296+
import std.algorithm.iteration : splitter;
297+
import std.regex;
298+
import std.string : strip, toLower;
299+
300+
static labelRe = regex(`\[(.*)\]`);
301+
string[] userLabels;
302+
foreach (m; pr.title.matchAll(labelRe))
303+
{
304+
foreach (el; m[1].splitter(","))
305+
userLabels ~= el;
306+
}
289307

308+
const string[string] userLabelsMap = [
309+
"trivial": "trivial",
310+
"wip": "WIP"
311+
];
312+
313+
auto mappedLabels = userLabels
314+
.sort()
315+
.uniq
316+
.map!strip
317+
.map!toLower
318+
.filter!(l => l in userLabelsMap)
319+
.map!(l => userLabelsMap[l])
320+
.array;
321+
322+
if (mappedLabels.length)
323+
pr.addLabels(mappedLabels);
324+
}

test/labels.d

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,3 +86,43 @@ unittest
8686
}
8787
);
8888
}
89+
90+
// test whether users can label their PR via the title
91+
unittest
92+
{
93+
setAPIExpectations(
94+
"/github/repos/dlang/dmd/pulls/6359/commits", (ref Json json) {
95+
json = Json.emptyArray;
96+
},
97+
"/github/repos/dlang/dmd/issues/6359/comments",
98+
"/github/repos/dlang/dmd/issues/6359/labels",
99+
(scope HTTPServerRequest req, scope HTTPServerResponse res) {
100+
assert(req.method == HTTPMethod.POST);
101+
assert(req.json.deserializeJson!(string[]) == ["trivial"]);
102+
res.writeVoidBody;
103+
}
104+
);
105+
106+
postGitHubHook("dlang_dmd_open_6359.json", "pull_request",
107+
(ref Json j, scope HTTPClientRequest req){
108+
j["pull_request"]["title"] = "[Trivial] foo bar";
109+
}
110+
);
111+
}
112+
113+
// test that not only a selection of labels is accepted
114+
unittest
115+
{
116+
setAPIExpectations(
117+
"/github/repos/dlang/dmd/pulls/6359/commits", (ref Json json) {
118+
json = Json.emptyArray;
119+
},
120+
"/github/repos/dlang/dmd/issues/6359/comments",
121+
);
122+
123+
postGitHubHook("dlang_dmd_open_6359.json", "pull_request",
124+
(ref Json j, scope HTTPClientRequest req){
125+
j["pull_request"]["title"] = "[auto-merge] foo bar";
126+
}
127+
);
128+
}

test/utils.d

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ public import vibe.http.common : HTTPMethod;
99
public import vibe.http.client : HTTPClientRequest;
1010
public import vibe.http.server : HTTPServerRequest, HTTPServerResponse;
1111
public import std.functional : toDelegate;
12-
public import vibe.data.json : Json;
12+
public import vibe.data.json : deserializeJson, Json;
1313
public import std.datetime : SysTime;
1414

1515
// existing dlang bot comment -> update comment

0 commit comments

Comments
 (0)