Skip to content

Commit 5ce085b

Browse files
committed
feat: CLone repo and perform auto-merge operation
1 parent 827dc4b commit 5ce085b

File tree

2 files changed

+145
-3
lines changed

2 files changed

+145
-3
lines changed

Git/Project.cs

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Diagnostics;
4+
using System.IO;
5+
using System.Text;
6+
7+
namespace Open_Rails_Code_Bot.Git
8+
{
9+
public class Project
10+
{
11+
string GitPath;
12+
bool Verbose;
13+
14+
public Project(string gitPath, bool verbose)
15+
{
16+
GitPath = gitPath;
17+
Verbose = verbose;
18+
}
19+
20+
public void Init(string repository)
21+
{
22+
if (!Directory.Exists(GitPath))
23+
{
24+
Directory.CreateDirectory(GitPath);
25+
RunCommand($"clone --mirror {repository} .");
26+
}
27+
}
28+
29+
public void Fetch()
30+
{
31+
RunCommand("fetch --update-head-ok");
32+
}
33+
34+
public string ParseRef(string reference)
35+
{
36+
foreach (var line in GetCommandOutput($"rev-parse {reference}"))
37+
{
38+
return line;
39+
}
40+
throw new ApplicationException("Unable to find ref");
41+
}
42+
43+
public void CheckoutDetached(string reference)
44+
{
45+
RunCommand($"checkout --quiet --detach {reference}");
46+
}
47+
48+
public void ResetHard()
49+
{
50+
RunCommand("reset --hard");
51+
}
52+
53+
public void Merge(string reference)
54+
{
55+
RunCommand($"merge --no-edit --no-ff {reference}");
56+
}
57+
58+
void RunCommand(string command)
59+
{
60+
foreach (var line in GetCommandOutput(command))
61+
{
62+
}
63+
}
64+
65+
IEnumerable<string> GetCommandOutput(string command)
66+
{
67+
var args = $"--no-pager {command}";
68+
if (Verbose)
69+
{
70+
Console.WriteLine("```shell");
71+
Console.WriteLine($"{GitPath}> git {args}");
72+
}
73+
var git = Process.Start(new ProcessStartInfo()
74+
{
75+
WorkingDirectory = GitPath,
76+
FileName = "git",
77+
Arguments = args,
78+
StandardOutputEncoding = Encoding.UTF8,
79+
RedirectStandardOutput = true,
80+
});
81+
while (!git.StandardOutput.EndOfStream)
82+
{
83+
yield return git.StandardOutput.ReadLine();
84+
}
85+
git.WaitForExit();
86+
if (git.ExitCode != 0)
87+
{
88+
throw new ApplicationException($"git {command} failed: {git.ExitCode}");
89+
}
90+
if (Verbose)
91+
{
92+
Console.WriteLine("```");
93+
}
94+
}
95+
}
96+
}

Program.cs

Lines changed: 49 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,12 @@ static async Task AsyncMain(IConfigurationRoot config)
4343
var gitHubConfig = config.GetSection("github");
4444
var query = new Query(gitHubConfig["token"]);
4545

46+
Console.WriteLine($"GitHub organisation: {gitHubConfig["organization"]}");
47+
Console.WriteLine($"GitHub team: {gitHubConfig["team"]}");
48+
Console.WriteLine($"GitHub repository: {gitHubConfig["repository"]}");
49+
4650
var members = await query.GetTeamMembers(gitHubConfig["organization"], gitHubConfig["team"]);
47-
Console.WriteLine($"Org '{gitHubConfig["organization"]}' team '{gitHubConfig["team"]}' members ({members.Count})");
51+
Console.WriteLine($"Team members ({members.Count}):");
4852
foreach (var member in members)
4953
{
5054
Console.WriteLine($" {member.Login}");
@@ -53,7 +57,7 @@ static async Task AsyncMain(IConfigurationRoot config)
5357

5458
var pullRequests = await query.GetOpenPullRequests(gitHubConfig["organization"], gitHubConfig["repository"]);
5559
var autoMergePullRequests = new List<GraphPullRequest>();
56-
Console.WriteLine($"Org '{gitHubConfig["organization"]}' repo '{gitHubConfig["repository"]}' open pull requests ({pullRequests.Count})");
60+
Console.WriteLine($"Open pull requests ({pullRequests.Count}):");
5761
foreach (var pullRequest in pullRequests)
5862
{
5963
var autoMerge = memberLogins.Contains(pullRequest.Author.Login)
@@ -69,11 +73,53 @@ static async Task AsyncMain(IConfigurationRoot config)
6973
}
7074
}
7175

72-
Console.WriteLine($"Org '{gitHubConfig["organization"]}' repo '{gitHubConfig["repository"]}' auto-merge pull requests ({autoMergePullRequests.Count})");
76+
Console.WriteLine($"Pull requests suitable for auto-merging ({autoMergePullRequests.Count}):");
77+
foreach (var pullRequest in autoMergePullRequests)
78+
{
79+
Console.WriteLine($" #{pullRequest.Number} {pullRequest.Title}");
80+
}
81+
82+
var git = new Git.Project(GetGitPath(), false);
83+
git.Init($"https://github.com/{gitHubConfig["organization"]}/{gitHubConfig["repository"]}.git");
84+
git.Fetch();
85+
git.ResetHard();
86+
var baseCommit = git.ParseRef("master");
87+
git.CheckoutDetached(baseCommit);
88+
var autoMergePullRequestsSuccess = new List<GraphPullRequest>();
89+
var autoMergePullRequestsFailure = new List<GraphPullRequest>();
7390
foreach (var pullRequest in autoMergePullRequests)
91+
{
92+
var mergeCommit = git.ParseRef($"pull/{pullRequest.Number}/head");
93+
try
94+
{
95+
git.Merge(mergeCommit);
96+
autoMergePullRequestsSuccess.Add(pullRequest);
97+
}
98+
catch (ApplicationException)
99+
{
100+
autoMergePullRequestsFailure.Add(pullRequest);
101+
git.ResetHard();
102+
}
103+
}
104+
Console.WriteLine($"Final commit: {git.ParseRef("HEAD")}");
105+
106+
Console.WriteLine($"Pull requests successfully auto-merged ({autoMergePullRequestsSuccess.Count}):");
107+
foreach (var pullRequest in autoMergePullRequestsSuccess)
108+
{
109+
Console.WriteLine($" #{pullRequest.Number} {pullRequest.Title}");
110+
}
111+
112+
Console.WriteLine($"Pull requests not auto-merged ({autoMergePullRequestsFailure.Count}):");
113+
foreach (var pullRequest in autoMergePullRequestsFailure)
74114
{
75115
Console.WriteLine($" #{pullRequest.Number} {pullRequest.Title}");
76116
}
77117
}
118+
119+
static string GetGitPath()
120+
{
121+
var appFilePath = System.Reflection.Assembly.GetEntryAssembly().Location;
122+
return Path.Combine(Path.GetDirectoryName(appFilePath), "git");
123+
}
78124
}
79125
}

0 commit comments

Comments
 (0)