diff --git a/Common/Messages/CompressImagesMessage.cs b/Common/Messages/CompressImagesMessage.cs index 46cf49c87..150563a4c 100644 --- a/Common/Messages/CompressImagesMessage.cs +++ b/Common/Messages/CompressImagesMessage.cs @@ -9,5 +9,7 @@ public class CompressImagesMessage public string Owner { get; set; } public int InstallationId { get; set; } + + public bool IsRebase { get; set; } } } diff --git a/Common/Messages/OpenPrMessage.cs b/Common/Messages/OpenPrMessage.cs index e6fdd95e5..800393716 100644 --- a/Common/Messages/OpenPrMessage.cs +++ b/Common/Messages/OpenPrMessage.cs @@ -7,5 +7,7 @@ public class OpenPrMessage public string RepoName { get; set; } public string CloneUrl { get; set; } + + public bool Update { get; set; } } } diff --git a/Common/Messages/RouterMessage.cs b/Common/Messages/RouterMessage.cs index 14f90df7c..2fd9eba16 100644 --- a/Common/Messages/RouterMessage.cs +++ b/Common/Messages/RouterMessage.cs @@ -9,5 +9,7 @@ public class RouterMessage public string CloneUrl { get; set; } public string Owner { get; set; } + + public bool IsRebase { get; set; } } } diff --git a/CompressImagesFunction/CompressImages.cs b/CompressImagesFunction/CompressImages.cs index 20e09240e..d1243c5e8 100644 --- a/CompressImagesFunction/CompressImages.cs +++ b/CompressImagesFunction/CompressImages.cs @@ -37,7 +37,6 @@ public static bool Run(CompressimagesParameters parameters, ICollector x.CanonicalName == $"refs/heads/{KnownGitHubs.BranchName}")) + if (!parameters.IsRebase && repo.Network.ListReferences(remote, credentialsProvider).Any(x => x.CanonicalName == $"refs/heads/{KnownGitHubs.BranchName}")) { logger.LogInformation("CompressImagesFunction: branch already exists for {Owner}/{RepoName}", parameters.RepoOwner, parameters.RepoName); return false; @@ -123,8 +122,8 @@ public static bool Run(CompressimagesParameters parameters, ICollector addedOrModifiedImagePaths = new List(); + List deletedImagePaths = new List(); + if (parameters.IsRebase) + { + var refspec = string.Format("{0}:{0}", KnownGitHubs.BranchName); + Commands.Fetch(repo, "origin", new List { refspec }, null, "fetch"); + + var diff = repo.Diff.Compare(repo.Branches[KnownGitHubs.BranchName].Commits.ElementAt(1).Tree, repo.Head.Tip.Tree); + + if (diff == null) + { + logger.LogInformation("Something went wrong while doing rebase"); + return false; + } + + foreach (TreeEntryChanges c in diff) + { + if (KnownImgPatterns.ImgExtensions.Contains(Path.GetExtension(c.Path))) + { + var path = Path.Combine(parameters.LocalPath, c.Path).Replace("\\", "/"); + var oldpath = Path.Combine(parameters.LocalPath, c.OldPath).Replace("\\", "/"); + + switch (c.Status) + { + case ChangeKind.Added: + case ChangeKind.Modified: + addedOrModifiedImagePaths.Add(path); + break; + case ChangeKind.Renamed: + addedOrModifiedImagePaths.Add(path); + deletedImagePaths.Add(oldpath); + break; + case ChangeKind.Deleted: + deletedImagePaths.Add(path); + break; + } + } + } + + imagePaths = ImageQuery.FilterOutIgnoredFiles(addedOrModifiedImagePaths, repoConfiguration); + } + else + { + imagePaths = ImageQuery.FindImages(parameters.LocalPath, repoConfiguration); + } + var optimizedImages = OptimizeImages(repo, parameters.LocalPath, imagePaths, logger, repoConfiguration.AggressiveCompression); if (optimizedImages.Length == 0) return false; @@ -156,6 +201,81 @@ public static bool Run(CompressimagesParameters parameters, ICollector(); + + var commitLines = commitBody.Split(new[] { '\r', '\n' }); + for (var i = 0; i < commitLines.Length; i++) + { + if (i == 0 || string.IsNullOrWhiteSpace(commitLines[i])) + { + // skip the first line and blank lines + continue; + } + + if (commitLines[i].StartsWith("Signed-off-by:") || commitLines[i].StartsWith("*Total --")) + { + // skip the DCO line + continue; + } + + var pattern = @"\*?(.*) -- (.*)kb -> (.*)kb \((.*)%\)"; + var capture = Regex.Matches(commitLines[i], pattern)[0]; + + compressionResults.Add(new CompressionResult + { + Title = capture.Groups[1].Value, + SizeBefore = Convert.ToDouble(capture.Groups[2].Value), + SizeAfter = Convert.ToDouble(capture.Groups[3].Value), + }); + } + + return compressionResults.ToArray(); + } + catch + { + // commit messages can be out of our control + return null; + } + } + + public static CompressionResult[] Merge(CompressionResult[] newOptimizedImages, CompressionResult[] previousCommitResults) + { + List list = new List(); + list.AddRange(newOptimizedImages); + list.AddRange(previousCommitResults); + + var nonRepeat = list.GroupBy(x => x.Title).Select(y => y.First()); + + return nonRepeat.ToArray(); + } + + public static CompressionResult[] Filter(CompressionResult[] optimizedImages, string[] toRemove) + { + var relativePaths = toRemove.Select(path => Path.GetFileName(path)); + var filtered = optimizedImages.Where(r => !relativePaths.Contains(r.Title)); + return filtered.ToArray(); + } + } +} diff --git a/CompressImagesFunction/ImageQuery.cs b/CompressImagesFunction/ImageQuery.cs index 68e70c142..156e6a166 100644 --- a/CompressImagesFunction/ImageQuery.cs +++ b/CompressImagesFunction/ImageQuery.cs @@ -15,16 +15,21 @@ public static string[] FindImages(string localPath, RepoConfiguration repoConfig .Where(x => KnownImgPatterns.ImgExtensions.Contains(Path.GetExtension(x).ToLower())) .Select(x => x.Replace("\\", "/")); + return FilterOutIgnoredFiles(images, repoConfiguration); + } + + public static string[] FilterOutIgnoredFiles(IEnumerable imagePaths, RepoConfiguration repoConfiguration) + { if (repoConfiguration.IgnoredFiles != null) { foreach (var ignorePattern in repoConfiguration.IgnoredFiles) { var pattern = new Regex(NormalizePattern(ignorePattern), RegexOptions.IgnoreCase); - images = images.Where(x => !pattern.IsMatch(x)); + imagePaths = imagePaths.Where(x => !pattern.IsMatch(x)); } } - return images.ToArray(); + return imagePaths.ToArray(); } // this is to provide backwards compatibility with the previous globbing diff --git a/OpenPrFunction/IPullRequest.cs b/OpenPrFunction/IPullRequest.cs index 245a171d6..9da48b9af 100644 --- a/OpenPrFunction/IPullRequest.cs +++ b/OpenPrFunction/IPullRequest.cs @@ -6,6 +6,6 @@ namespace OpenPrFunction { public interface IPullRequest { - Task OpenAsync(GitHubClientParameters parameters, Settings settings = null); + Task OpenAsync(GitHubClientParameters parameters, bool update, Settings settings = null); } } diff --git a/OpenPrFunction/OpenPr.cs b/OpenPrFunction/OpenPr.cs index c5c311988..333327864 100644 --- a/OpenPrFunction/OpenPr.cs +++ b/OpenPrFunction/OpenPr.cs @@ -74,6 +74,7 @@ public static async Task RunAsync( RepoName = installation.RepoName, RepoOwner = installation.Owner, }, + openPrMessage.Update, settings); if (result?.Id > 0) diff --git a/OpenPrFunction/PullRequest.cs b/OpenPrFunction/PullRequest.cs index 90e223d4d..db19644e4 100644 --- a/OpenPrFunction/PullRequest.cs +++ b/OpenPrFunction/PullRequest.cs @@ -1,4 +1,6 @@ -using System.Threading.Tasks; +using System; +using System.Linq; +using System.Threading.Tasks; using Common; using Common.TableModels; using Octokit; @@ -8,7 +10,7 @@ namespace OpenPrFunction { public class PullRequest : IPullRequest { - public async Task OpenAsync(GitHubClientParameters parameters, Settings settings = null) + public async Task OpenAsync(GitHubClientParameters parameters, bool update, Settings settings = null) { var inMemoryCredentialStore = new InMemoryCredentialStore(new Credentials(KnownGitHubs.Username, parameters.Password)); var githubClient = new GitHubClient(new ProductHeaderValue("ImgBot"), inMemoryCredentialStore); @@ -29,12 +31,36 @@ public async Task OpenAsync(GitHubClientParameters parameters, Settings sett } var stats = Stats.ParseStats(commit.Commit.Message); - var pr = new NewPullRequest(KnownGitHubs.CommitMessageTitle, KnownGitHubs.BranchName, baseBranch) + + Octokit.PullRequest result; + if (update) { - Body = PullRequestBody.Generate(stats), - }; + // get PR number + var allPrs = await githubClient.PullRequest.GetAllForRepository(parameters.RepoOwner, parameters.RepoName); + + var pr = allPrs.First(p => p.State == ItemState.Open && p.Head.Sha == commit.Sha); + + if (pr == null) + { + throw new Exception("Couldn't update PR. PR not found"); + } + + var pru = new PullRequestUpdate() + { + Body = PullRequestBody.Generate(stats), + }; - var result = await githubClient.PullRequest.Create(parameters.RepoOwner, parameters.RepoName, pr); + result = await githubClient.PullRequest.Update(parameters.RepoOwner, parameters.RepoName, pr.Number, pru); + } + else + { + var pr = new NewPullRequest(KnownGitHubs.CommitMessageTitle, KnownGitHubs.BranchName, baseBranch) + { + Body = PullRequestBody.Generate(stats), + }; + + result = await githubClient.PullRequest.Create(parameters.RepoOwner, parameters.RepoName, pr); + } if (stats == null) { diff --git a/RouterFunction/RouterFunction.cs b/RouterFunction/RouterFunction.cs index 973cb1914..b133d4199 100644 --- a/RouterFunction/RouterFunction.cs +++ b/RouterFunction/RouterFunction.cs @@ -41,6 +41,7 @@ public static void Run( InstallationId = routerMessage.InstallationId, Owner = routerMessage.Owner, RepoName = routerMessage.RepoName, + IsRebase = routerMessage.IsRebase, }); logger.LogInformation("RouterFunction: Added CompressImagesMessage for {Owner}/{RepoName}", routerMessage.Owner, routerMessage.RepoName); diff --git a/Test/CommitMessageTests.cs b/Test/CommitMessageTests.cs index f3d1d934e..84df8a703 100644 --- a/Test/CommitMessageTests.cs +++ b/Test/CommitMessageTests.cs @@ -1,4 +1,5 @@ using System; +using System.IO; using Common; using CompressImagesFunction; using Microsoft.VisualStudio.TestTools.UnitTesting; @@ -140,5 +141,166 @@ public void GivenNullOrEmptyCompressionResults_ShouldCreateEmptyString() var message2 = CommitMessage.Create(new CompressionResult[0]); Assert.AreEqual(string.Empty, message); } + + [TestMethod] + public void GivenTwoCompressionResultArrays_ShouldCreateMergedArray() + { + var images = new[] + { + new CompressionResult + { + Title = "path/to/image.png", + SizeBefore = 100.3678, + SizeAfter = 95.78743 + }, + new CompressionResult + { + Title = "path/to/image2.png", + SizeBefore = 500.3234, + SizeAfter = 360.1321987 + }, + }; + + var images2 = new[] + { + new CompressionResult + { + Title = "path/to/image2.png", + SizeBefore = 101.3678, + SizeAfter = 96.78743 + }, + new CompressionResult + { + Title = "path/to/image3.png", + SizeBefore = 300.3234, + SizeAfter = 760.1321987 + }, + }; + + var expected = new[] + { + new CompressionResult + { + Title = "path/to/image.png", + SizeBefore = 100.3678, + SizeAfter = 95.78743 + }, + new CompressionResult + { + Title = "path/to/image2.png", + SizeBefore = 500.3234, + SizeAfter = 360.1321987 + }, + new CompressionResult + { + Title = "path/to/image3.png", + SizeBefore = 300.3234, + SizeAfter = 760.1321987 + }, + }; + + var mergeResult = CompressionResult.Merge(images, images2); + Assert.AreEqual(mergeResult.Length, expected.Length); + + for (int i = 0; i < mergeResult.Length; ++i) + { + Assert.AreEqual(mergeResult[i].Title, expected[i].Title); + Assert.AreEqual(mergeResult[i].SizeBefore, expected[i].SizeBefore); + Assert.AreEqual(mergeResult[i].SizeAfter, expected[i].SizeAfter); + } + } + + [TestMethod] + public void GivenCompressionResultAndFilterArray_ShouldCorrectlyFilter() + { + var images = new[] + { + new CompressionResult + { + Title = "image.png", + SizeBefore = 100.3678, + SizeAfter = 95.78743 + }, + new CompressionResult + { + Title = "image2.png", + SizeBefore = 500.3234, + SizeAfter = 360.1321987 + }, + new CompressionResult + { + Title = "image3.png", + SizeBefore = 500.3234, + SizeAfter = 360.1321987 + }, + }; + + var filter = new[] { Path.Combine("path", "to", "image3.png") }; + + var expected = new[] + { + new CompressionResult + { + Title = "image.png", + SizeBefore = 100.3678, + SizeAfter = 95.78743 + }, + new CompressionResult + { + Title = "image2.png", + SizeBefore = 500.3234, + SizeAfter = 360.1321987 + }, + }; + + var filterResult = CompressionResult.Filter(images, filter); + Assert.AreEqual(filterResult.Length, expected.Length); + + for (int i = 0; i < filterResult.Length; ++i) + { + Assert.AreEqual(filterResult[i].Title, expected[i].Title); + Assert.AreEqual(filterResult[i].SizeBefore, expected[i].SizeBefore); + Assert.AreEqual(filterResult[i].SizeAfter, expected[i].SizeAfter); + } + } + + [TestMethod] + public void GivenACommitMessage_ShouldCorrectlyParse() + { + var commitMessage = KnownGitHubs.CommitMessageTitle + Environment.NewLine + + Environment.NewLine + + "*Total -- 501.89kb -> 455.68kb (9.21%)" + Environment.NewLine + + Environment.NewLine + + "path/to/image.png -- 200.97kb -> 195.12kb (2.91%)" + Environment.NewLine + + "path/to/image2.png -- 300.92kb -> 260.56kb (13.41%)" + Environment.NewLine + + Environment.NewLine + + "Signed-off-by: ImgBotApp " + Environment.NewLine; + + var expected = new[] + { + new CompressionResult + { + Title = "path/to/image.png", + SizeBefore = 200.97, + SizeAfter = 195.12 + }, + new CompressionResult + { + Title = "path/to/image2.png", + SizeBefore = 300.92, + SizeAfter = 260.56 + }, + }; + + var parsed = CompressionResult.ParseCommitMessage(commitMessage); + Assert.AreEqual(parsed.Length, expected.Length); + + for (int i = 0; i < parsed.Length; ++i) + { + Assert.AreEqual(parsed[i].Title, expected[i].Title); + Assert.AreEqual(parsed[i].SizeBefore, expected[i].SizeBefore); + Assert.AreEqual(parsed[i].SizeAfter, expected[i].SizeAfter); + } + } } } diff --git a/Test/OpenPrTests.cs b/Test/OpenPrTests.cs index 9de3506b1..14db60d54 100644 --- a/Test/OpenPrTests.cs +++ b/Test/OpenPrTests.cs @@ -120,7 +120,7 @@ private Task ExecuteRunAsync(OpenPrMessage openPrMessage, Installation installat })); var pullRequest = Substitute.For(); - pullRequest.OpenAsync(Arg.Any()).Returns(x => Task.FromResult(new Pr(installation.Owner) { Id = prId })); + pullRequest.OpenAsync(Arg.Any(), false).Returns(x => Task.FromResult(new Pr(installation.Owner) { Id = prId })); var settingsTable = Substitute.For(new Uri("https://myaccount.table.core.windows.net/Tables/settings")); diff --git a/WebHook/Model/IssueCommentHook.cs b/WebHook/Model/IssueCommentHook.cs new file mode 100644 index 000000000..7d0fcbc95 --- /dev/null +++ b/WebHook/Model/IssueCommentHook.cs @@ -0,0 +1,240 @@ +// + +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace WebHook.Model +{ + public class IssueCommentHook + { + public string action { get; set; } + public Issue issue { get; set; } + public Comment comment { get; set; } + public Repository repository { get; set; } + public Sender sender { get; set; } + public Installation installation { get; set; } + + [JsonProperty("ref")] + public string @ref { get; set; } + + public class User + { + public string login { get; set; } + public int id { get; set; } + public string node_id { get; set; } + public string avatar_url { get; set; } + public string gravatar_id { get; set; } + public string url { get; set; } + public string html_url { get; set; } + public string followers_url { get; set; } + public string following_url { get; set; } + public string gists_url { get; set; } + public string starred_url { get; set; } + public string subscriptions_url { get; set; } + public string organizations_url { get; set; } + public string repos_url { get; set; } + public string events_url { get; set; } + public string received_events_url { get; set; } + public string type { get; set; } + public bool site_admin { get; set; } + } + + public class PullRequest + { + public string url { get; set; } + public string html_url { get; set; } + public string diff_url { get; set; } + public string patch_url { get; set; } + } + + public class Issue + { + public string url { get; set; } + public string repository_url { get; set; } + public string labels_url { get; set; } + public string comments_url { get; set; } + public string events_url { get; set; } + public string html_url { get; set; } + public int id { get; set; } + public string node_id { get; set; } + public int number { get; set; } + public string title { get; set; } + public User user { get; set; } + public List labels { get; set; } + public string state { get; set; } + public bool locked { get; set; } + public object assignee { get; set; } + public List assignees { get; set; } + public object milestone { get; set; } + public int comments { get; set; } + public string created_at { get; set; } + public string updated_at { get; set; } + public object closed_at { get; set; } + public string author_association { get; set; } + public PullRequest pull_request { get; set; } + public string body { get; set; } + } + + public class User2 + { + public string login { get; set; } + public int id { get; set; } + public string node_id { get; set; } + public string avatar_url { get; set; } + public string gravatar_id { get; set; } + public string url { get; set; } + public string html_url { get; set; } + public string followers_url { get; set; } + public string following_url { get; set; } + public string gists_url { get; set; } + public string starred_url { get; set; } + public string subscriptions_url { get; set; } + public string organizations_url { get; set; } + public string repos_url { get; set; } + public string events_url { get; set; } + public string received_events_url { get; set; } + public string type { get; set; } + public bool site_admin { get; set; } + } + + public class Comment + { + public string url { get; set; } + public string html_url { get; set; } + public string issue_url { get; set; } + public int id { get; set; } + public string node_id { get; set; } + public User2 user { get; set; } + public string created_at { get; set; } + public string updated_at { get; set; } + public string author_association { get; set; } + public string body { get; set; } + } + + public class Owner + { + public string login { get; set; } + public int id { get; set; } + public string node_id { get; set; } + public string avatar_url { get; set; } + public string gravatar_id { get; set; } + public string url { get; set; } + public string html_url { get; set; } + public string followers_url { get; set; } + public string following_url { get; set; } + public string gists_url { get; set; } + public string starred_url { get; set; } + public string subscriptions_url { get; set; } + public string organizations_url { get; set; } + public string repos_url { get; set; } + public string events_url { get; set; } + public string received_events_url { get; set; } + public string type { get; set; } + public bool site_admin { get; set; } + } + + public class Repository + { + public int id { get; set; } + public string node_id { get; set; } + public string name { get; set; } + public string full_name { get; set; } + public bool @private { get; set; } + public Owner owner { get; set; } + public string html_url { get; set; } + public string description { get; set; } + public bool fork { get; set; } + public string url { get; set; } + public string forks_url { get; set; } + public string keys_url { get; set; } + public string collaborators_url { get; set; } + public string teams_url { get; set; } + public string hooks_url { get; set; } + public string issue_events_url { get; set; } + public string events_url { get; set; } + public string assignees_url { get; set; } + public string branches_url { get; set; } + public string tags_url { get; set; } + public string blobs_url { get; set; } + public string git_tags_url { get; set; } + public string git_refs_url { get; set; } + public string trees_url { get; set; } + public string statuses_url { get; set; } + public string languages_url { get; set; } + public string stargazers_url { get; set; } + public string contributors_url { get; set; } + public string subscribers_url { get; set; } + public string subscription_url { get; set; } + public string commits_url { get; set; } + public string git_commits_url { get; set; } + public string comments_url { get; set; } + public string issue_comment_url { get; set; } + public string contents_url { get; set; } + public string compare_url { get; set; } + public string merges_url { get; set; } + public string archive_url { get; set; } + public string downloads_url { get; set; } + public string issues_url { get; set; } + public string pulls_url { get; set; } + public string milestones_url { get; set; } + public string notifications_url { get; set; } + public string labels_url { get; set; } + public string releases_url { get; set; } + public string deployments_url { get; set; } + public string created_at { get; set; } + public string updated_at { get; set; } + public string pushed_at { get; set; } + public string git_url { get; set; } + public string ssh_url { get; set; } + public string clone_url { get; set; } + public string svn_url { get; set; } + public object homepage { get; set; } + public int size { get; set; } + public int stargazers_count { get; set; } + public int watchers_count { get; set; } + public object language { get; set; } + public bool has_issues { get; set; } + public bool has_projects { get; set; } + public bool has_downloads { get; set; } + public bool has_wiki { get; set; } + public bool has_pages { get; set; } + public int forks_count { get; set; } + public object mirror_url { get; set; } + public bool archived { get; set; } + public bool disabled { get; set; } + public int open_issues_count { get; set; } + public object license { get; set; } + public int forks { get; set; } + public int open_issues { get; set; } + public int watchers { get; set; } + public string default_branch { get; set; } + } + + public class Sender + { + public string login { get; set; } + public int id { get; set; } + public string node_id { get; set; } + public string avatar_url { get; set; } + public string gravatar_id { get; set; } + public string url { get; set; } + public string html_url { get; set; } + public string followers_url { get; set; } + public string following_url { get; set; } + public string gists_url { get; set; } + public string starred_url { get; set; } + public string subscriptions_url { get; set; } + public string organizations_url { get; set; } + public string repos_url { get; set; } + public string events_url { get; set; } + public string received_events_url { get; set; } + public string type { get; set; } + public bool site_admin { get; set; } + } + + public class Installation { + public int id { get; set; } + public string node_id { get; set; } + } + } +} \ No newline at end of file diff --git a/WebHook/WebHookFunction.cs b/WebHook/WebHookFunction.cs index 86365cd5d..db1c7a1ad 100644 --- a/WebHook/WebHookFunction.cs +++ b/WebHook/WebHookFunction.cs @@ -54,20 +54,29 @@ public static async Task Run( ILogger logger) { var hookEvent = req.Headers.GetValues("X-GitHub-Event").First(); - var hook = JsonConvert.DeserializeObject(await req.Content.ReadAsStringAsync()); var result = "no action"; switch (hookEvent) { case "installation_repositories": case "installation": - result = await ProcessInstallationAsync(hook, marketplaceTable, routerMessages, installationTable, logger).ConfigureAwait(false); + var instalattionHook = JsonConvert.DeserializeObject(await req.Content.ReadAsStringAsync()); + result = await ProcessInstallationAsync(instalattionHook, marketplaceTable, routerMessages, installationTable, logger).ConfigureAwait(false); break; case "push": - result = await ProcessPushAsync(hook, marketplaceTable, settingsTable, routerMessages, openPrMessages, deleteBranchMessages, logger) + var pushHook = JsonConvert.DeserializeObject(await req.Content.ReadAsStringAsync()); + result = await ProcessPushAsync(pushHook, marketplaceTable, settingsTable, routerMessages, openPrMessages, deleteBranchMessages, logger) .ConfigureAwait(false); break; case "marketplace_purchase": - result = await ProcessMarketplacePurchaseAsync(hook, marketplaceTable, logger).ConfigureAwait(false); + var purchaseHook = JsonConvert.DeserializeObject(await req.Content.ReadAsStringAsync()); + result = await ProcessMarketplacePurchaseAsync(purchaseHook, marketplaceTable, logger).ConfigureAwait(false); + break; + + // TODO: case 'issue-comment' + case "issue_comment": + var commentHook = JsonConvert.DeserializeObject(await req.Content.ReadAsStringAsync()); + result = await ProcessIssueCommentAsync(commentHook, marketplaceTable, settingsTable, routerMessages, openPrMessages, deleteBranchMessages, logger) + .ConfigureAwait(false); break; } @@ -102,6 +111,7 @@ await openPrMessages.AddMessageAsync(new CloudQueueMessage(JsonConvert.Serialize InstallationId = hook.installation.id, RepoName = hook.repository.name, CloneUrl = $"https://github.com/{hook.repository.full_name}", + Update = false, }))); logger.LogInformation("ProcessPush: Added OpenPrMessage for {Owner}/{RepoName}", hook.repository.owner.login, hook.repository.name); @@ -165,6 +175,50 @@ await routerMessages.AddMessageAsync(new CloudQueueMessage(JsonConvert.Serialize return "truth"; } + private static async Task ProcessIssueCommentAsync( + IssueCommentHook hook, + CloudTable marketplaceTable, + CloudTable settingsTable, + CloudQueue routerMessages, + CloudQueue openPrMessages, + CloudQueue deleteBranchMessages, + ILogger logger) + { + if (hook.issue.pull_request == null) + { + return "This is not a PR"; + } + + if (hook.comment.body != "@imgbot rebase" || hook.issue.user.login != "imgbot[bot]") + { + return "Not an ImgBot directive"; + } + + // private check + if (hook.repository?.@private == true) + { + var isPrivateEligible = await IsPrivateEligible(marketplaceTable, hook.repository.owner.login); + if (!isPrivateEligible) + { + logger.LogError("ProcessRebase: Plan mismatch for {Owner}/{RepoName}", hook.repository.owner.login, hook.repository.name); + throw new Exception("Plan mismatch"); + } + } + + await routerMessages.AddMessageAsync(new CloudQueueMessage(JsonConvert.SerializeObject(new RouterMessage + { + InstallationId = hook.installation.id, + Owner = hook.repository.owner.login, + RepoName = hook.repository.name, + CloneUrl = $"https://github.com/{hook.repository.full_name}", + IsRebase = true, + }))); + + logger.LogInformation("ProcessIssueComment: Added RouterMessage for {Owner}/{RepoName}", hook.repository.owner.login, hook.repository.name); + + return "truth"; + } + private static async Task ProcessInstallationAsync(Hook hook, CloudTable marketplaceTable, CloudQueue routerMessages, CloudTable installationTable, ILogger logger) { var isPrivateEligible = false;