Skip to content

Commit b0cd970

Browse files
committed
Git support: first steps
1 parent 19dc75c commit b0cd970

File tree

6 files changed

+359
-2
lines changed

6 files changed

+359
-2
lines changed

source/dlangbot/app.d

+9-1
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,16 @@ void githubHook(HTTPServerRequest req, HTTPServerResponse res)
114114
action = "merged";
115115
goto case;
116116
case "opened", "reopened", "synchronize", "labeled", "edited":
117-
118117
auto pullRequest = json["pull_request"].deserializeJson!PullRequest;
118+
if (action == "labeled")
119+
{
120+
if (json["label"]["name"].get!string == "rebase")
121+
{
122+
import dlangbot.git : rebase;
123+
runTaskHelper(&rebase, &pullRequest);
124+
return res.writeBody("handled");
125+
}
126+
}
119127
runTaskHelper(&handlePR, action, &pullRequest);
120128
return res.writeBody("handled");
121129
default:

source/dlangbot/git.d

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
module dlangbot.git;
2+
3+
import std.conv, std.file, std.path, std.string, std.uuid;
4+
import std.format, std.stdio;
5+
6+
import dlangbot.github;
7+
import vibe.core.log;
8+
9+
string gitURL = "http://0.0.0.0:9006";
10+
11+
void rebase(PullRequest* pr)
12+
{
13+
import std.process;
14+
auto uniqDir = tempDir.buildPath("dlang-bot-git", randomUUID.to!string.replace("-", ""));
15+
uniqDir.mkdirRecurse;
16+
scope(exit) uniqDir.rmdirRecurse;
17+
18+
auto targetBranch = pr.base.ref_;
19+
auto remoteDir = pr.repoURL;
20+
21+
logInfo("[git/%s]: cloning branch %s...", pr.repoSlug, targetBranch);
22+
auto pid = spawnShell("git clone -b %s %s %s".format(targetBranch, remoteDir, uniqDir));
23+
pid.wait;
24+
25+
//auto git = "git -C %s ".format(uniqDir);
26+
//logInfo("[git/%s]: fetching repo...", pr.repoSlug);
27+
//pid = spawnShell(git ~ "fetch origin pull/%s/head:pr-%1$s".format(pr.number));
28+
//pid.wait;
29+
//logInfo("[git/%s]: switching to PR branch...", pr.repoSlug);
30+
//pid = spawnShell(git ~ "checkout pr-%s".format(pr.number));
31+
//pid.wait;
32+
//logInfo("[git/%s]: rebasing...", pr.repoSlug);
33+
//pid = spawnShell(git ~ "rebase " ~ targetBranch);
34+
//pid.wait;
35+
36+
import std.net.curl, std.json;
37+
auto headSlug = pr.head.repo.fullName;
38+
auto headRef = pr.head.ref_;
39+
auto sep = gitURL.startsWith("http") ? "/" : ":";
40+
logInfo("[git/%s]: pushing... to %s", pr.repoSlug, gitURL);
41+
42+
// TODO: use --force here
43+
auto cmd = "git push -vv %s%s%s HEAD:%s".format(gitURL, sep, headSlug, headRef);
44+
writeln("CMD");
45+
uniqDir.writeln;
46+
cmd.writeln;
47+
writeln("CMD");
48+
49+
pid = spawnShell(cmd);
50+
//pid.wait;
51+
import vibe.core.core;
52+
import core.time;
53+
sleep(60.seconds);
54+
pid.wait;
55+
}

source/dlangbot/github.d

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
module dlangbot.github;
22

3+
string githubURL = "https://github.com";
34
import dlangbot.bugzilla : bugzillaURL, Issue, IssueRef;
45
import dlangbot.warnings : printMessages, UserMessage;
56

source/dlangbot/github_api.d

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
module dlangbot.github_api;
22

3+
string githubURL = "https://github.com";
34
string githubAPIURL = "https://api.github.com";
45
string githubAuth, hookSecret;
56

@@ -126,7 +127,7 @@ struct PullRequest
126127
alias repoSlug = baseRepoSlug;
127128
bool isOpen() const { return state == State.open; }
128129

129-
string htmlURL() const { return "https://github.com/%s/pull/%d".format(repoSlug, number); }
130+
string htmlURL() const { return "%s/%s/pull/%d".format(githubURL, repoSlug, number); }
130131
string commentsURL() const { return "%s/repos/%s/issues/%d/comments".format(githubAPIURL, repoSlug, number); }
131132
string commitsURL() const { return "%s/repos/%s/pulls/%d/commits".format(githubAPIURL, repoSlug, number); }
132133
string eventsURL() const { return "%s/repos/%s/issues/%d/events".format(githubAPIURL, repoSlug, number); }
@@ -135,6 +136,7 @@ struct PullRequest
135136
string mergeURL() const { return "%s/repos/%s/pulls/%d/merge".format(githubAPIURL, repoSlug, number); }
136137
string statusURL() const { return "%s/repos/%s/status/%s".format(githubAPIURL, repoSlug, head.sha); }
137138
string membersURL() const { return "%s/orgs/%s/public_members".format(githubAPIURL, base.repo.owner.login); }
139+
string repoURL() const { return "%s/%s".format(githubURL, repoSlug); }
138140

139141
string pid() const
140142
{

test/labels.d

+31
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import utils;
22

3+
/*
34
// send normal label event --> nothing
45
unittest
56
{
@@ -128,3 +129,33 @@ unittest
128129
}
129130
);
130131
}
132+
*/
133+
134+
// send rebase label
135+
unittest
136+
{
137+
setAPIExpectations();
138+
import std.stdio;
139+
140+
gitInfoRefs = (string user, string repo) {
141+
"requesting refs".writeln;
142+
return [
143+
GitInfoRef("6ed2e15cf4a35e274adb8385b3ee8125326509f9", "refs/heads/foo"),
144+
GitInfoRef("6e79d22fdfda446601d969ce77e406b9a5506de9", "refs/heads/Issue_8573"),
145+
GitInfoRef("6e79d22fdfda446601d969ce77e406b9a5506de8", "refs/heads/master"),
146+
];
147+
};
148+
149+
gitReportRefs = (ClientReq clientReq) {
150+
clientReq.writeln;
151+
return [
152+
GitReportRef(GitReportRef.status.ok, "refs/heads/Issue_8573")
153+
];
154+
};
155+
156+
postGitHubHook("dlang_phobos_label_4921.json", "pull_request",
157+
(ref Json j, scope HTTPClientRequest req){
158+
j["pull_request"]["state"] = "open";
159+
j["label"]["name"] = "rebase";
160+
}.toDelegate);
161+
}

0 commit comments

Comments
 (0)