diff --git a/src/Tgstation.Server.Host/Components/Instance.cs b/src/Tgstation.Server.Host/Components/Instance.cs
index 254fb1eb57..18a50f6143 100644
--- a/src/Tgstation.Server.Host/Components/Instance.cs
+++ b/src/Tgstation.Server.Host/Components/Instance.cs
@@ -1,7 +1,9 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
+using Octokit;
using System;
using System.Collections.Generic;
+using System.Globalization;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
@@ -60,6 +62,11 @@ namespace Tgstation.Server.Host.Components
///
readonly IEventConsumer eventConsumer;
+ ///
+ /// The for the
+ ///
+ readonly IGitHubClientFactory gitHubClientFactory;
+
///
/// The for the
///
@@ -94,8 +101,9 @@ namespace Tgstation.Server.Host.Components
/// The value of
/// The value of
/// The value of
+ /// The value of
/// The value of
- public Instance(Api.Models.Instance metadata, IRepositoryManager repositoryManager, IByondManager byondManager, IDreamMaker dreamMaker, IWatchdog watchdog, IChat chat, StaticFiles.IConfiguration configuration, ICompileJobConsumer compileJobConsumer, IDatabaseContextFactory databaseContextFactory, IDmbFactory dmbFactory, IJobManager jobManager, IEventConsumer eventConsumer, ILogger logger)
+ public Instance(Api.Models.Instance metadata, IRepositoryManager repositoryManager, IByondManager byondManager, IDreamMaker dreamMaker, IWatchdog watchdog, IChat chat, StaticFiles.IConfiguration configuration, ICompileJobConsumer compileJobConsumer, IDatabaseContextFactory databaseContextFactory, IDmbFactory dmbFactory, IJobManager jobManager, IEventConsumer eventConsumer, IGitHubClientFactory gitHubClientFactory, ILogger logger)
{
this.metadata = metadata ?? throw new ArgumentNullException(nameof(metadata));
RepositoryManager = repositoryManager ?? throw new ArgumentNullException(nameof(repositoryManager));
@@ -109,6 +117,7 @@ namespace Tgstation.Server.Host.Components
this.dmbFactory = dmbFactory ?? throw new ArgumentNullException(nameof(dmbFactory));
this.jobManager = jobManager ?? throw new ArgumentNullException(nameof(jobManager));
this.eventConsumer = eventConsumer ?? throw new ArgumentNullException(nameof(eventConsumer));
+ this.gitHubClientFactory = gitHubClientFactory ?? throw new ArgumentNullException(nameof(gitHubClientFactory));
this.logger = logger ?? throw new ArgumentNullException(nameof(logger));
}
@@ -159,6 +168,9 @@ namespace Tgstation.Server.Host.Components
if (ddSettings == default)
throw new JobException("Missing DreamDaemonSettings in DB!");
+ Task repositorySettingsTask = null;
+ string repoOwner = null;
+ string repoName = null;
CompileJob compileJob;
RevisionInformation revInfo;
using (var repo = await RepositoryManager.LoadRepository(cancellationToken).ConfigureAwait(false))
@@ -166,8 +178,19 @@ namespace Tgstation.Server.Host.Components
if (repo == null)
throw new JobException("Missing Repository!");
+ if (repo.IsGitHubRepository)
+ {
+ repoOwner = repo.GitHubOwner;
+ repoName = repo.GitHubRepoName;
+ repositorySettingsTask = databaseContext.RepositorySettings.Where(x => x.InstanceId == metadata.Id).Select(x => new RepositorySettings
+ {
+ AccessToken = x.AccessToken,
+ ShowTestMergeCommitters = x.ShowTestMergeCommitters
+ }).FirstOrDefaultAsync(cancellationToken);
+ }
+
var repoSha = repo.Head;
- revInfo = await databaseContext.RevisionInformations.Where(x => x.CommitSha == repoSha && x.Instance.Id == metadata.Id).Include(x => x.ActiveTestMerges).ThenInclude(x => x.TestMerge).FirstOrDefaultAsync().ConfigureAwait(false);
+ revInfo = await databaseContext.RevisionInformations.Where(x => x.CommitSha == repoSha && x.Instance.Id == metadata.Id).Include(x => x.ActiveTestMerges).ThenInclude(x => x.TestMerge).ThenInclude(x => x.MergedBy).FirstOrDefaultAsync().ConfigureAwait(false);
if (revInfo == default)
{
@@ -200,8 +223,87 @@ namespace Tgstation.Server.Host.Components
compileJob.Job = job;
databaseContext.CompileJobs.Add(compileJob); //will be saved by job context
-
+
job.PostComplete = ct => CompileJobConsumer.LoadCompileJob(compileJob, ct);
+
+ if (repositorySettingsTask != null)
+ {
+ var repositorySettings = await repositorySettingsTask.ConfigureAwait(false);
+ if (repositorySettings == default)
+ throw new JobException("Missing repository settings!");
+
+ if (repositorySettings.AccessToken != null)
+ {
+ //potential for commenting on a test merge change
+ var outgoingCompileJob = LatestCompileJob();
+
+ if(outgoingCompileJob != null && outgoingCompileJob.RevisionInformation.CommitSha != compileJob.RevisionInformation.CommitSha)
+ {
+ var gitHubClient = gitHubClientFactory.CreateClient(repositorySettings.AccessToken);
+
+ async Task CommentOnPR(int prNumber, string comment)
+ {
+ try
+ {
+ await gitHubClient.Issue.Comment.Create(repoOwner, repoName, prNumber, comment).ConfigureAwait(false);
+ }
+ catch (ApiException e)
+ {
+ logger.LogWarning("Error posting GitHub comment! Exception: {0}", e);
+ }
+ }
+
+ var tasks = new List();
+
+ string FormatTestMerge(TestMerge testMerge, bool updated) => String.Format(CultureInfo.InvariantCulture, "#### Test Merge {4}{0}{0}##### Server Instance{0}{5}{1}{0}{0}##### Revision{0}Origin: {6}{0}Pull Request: {2}{0}Server: {7}{3}",
+ Environment.NewLine,
+ repositorySettings.ShowTestMergeCommitters.Value ? String.Format(CultureInfo.InvariantCulture, "{0}{0}##### Merged By{0}{1}", Environment.NewLine, testMerge.MergedBy.Name) : String.Empty,
+ testMerge.PullRequestRevision,
+ testMerge.Comment != null ? String.Format(CultureInfo.InvariantCulture, "{0}{0}##### Comment{0}{1}", Environment.NewLine, testMerge.Comment) : String.Empty,
+ updated ? "Updated" : "Deployed",
+ metadata.Name,
+ compileJob.RevisionInformation.OriginCommitSha,
+ compileJob.RevisionInformation.CommitSha
+ );
+
+ //added prs
+ foreach (var I in compileJob
+ .RevisionInformation
+ .ActiveTestMerges
+ .Select(x => x.TestMerge)
+ .Where(x => !outgoingCompileJob
+ .RevisionInformation
+ .ActiveTestMerges
+ .Any(y => y.TestMerge.Number == x.Number)))
+ tasks.Add(CommentOnPR(I.Number.Value, FormatTestMerge(I, false)));
+
+ //removed prs
+ foreach (var I in outgoingCompileJob
+ .RevisionInformation
+ .ActiveTestMerges
+ .Select(x => x.TestMerge)
+ .Where(x => !compileJob
+ .RevisionInformation
+ .ActiveTestMerges
+ .Any(y => y.TestMerge.Number == x.Number)))
+ tasks.Add(CommentOnPR(I.Number.Value, "#### Test Merge Removed"));
+
+ //updated prs
+ foreach(var I in compileJob
+ .RevisionInformation
+ .ActiveTestMerges
+ .Select(x => x.TestMerge)
+ .Where(x => outgoingCompileJob
+ .RevisionInformation
+ .ActiveTestMerges
+ .Any(y => y.TestMerge.Number == x.Number)))
+ tasks.Add(CommentOnPR(I.Number.Value, FormatTestMerge(I, true)));
+
+ if (tasks.Any())
+ await Task.WhenAll(tasks).ConfigureAwait(false);
+ }
+ }
+ }
}
///
diff --git a/src/Tgstation.Server.Host/Components/InstanceFactory.cs b/src/Tgstation.Server.Host/Components/InstanceFactory.cs
index 0823f16db8..7d087d1c08 100644
--- a/src/Tgstation.Server.Host/Components/InstanceFactory.cs
+++ b/src/Tgstation.Server.Host/Components/InstanceFactory.cs
@@ -98,6 +98,11 @@ namespace Tgstation.Server.Host.Components
///
readonly INetworkPromptReaper networkPromptReaper;
+ ///
+ /// The for the
+ ///
+ readonly IGitHubClientFactory gitHubClientFactory;
+
///
/// Construct an
///
@@ -117,7 +122,8 @@ namespace Tgstation.Server.Host.Components
/// The value of
/// The value of
/// The value of
- public InstanceFactory(IIOManager ioManager, IDatabaseContextFactory databaseContextFactory, IApplication application, ILoggerFactory loggerFactory, IByondTopicSender byondTopicSender, ICryptographySuite cryptographySuite, ISynchronousIOManager synchronousIOManager, ISymlinkFactory symlinkFactory, IByondInstaller byondInstaller, IChatFactory chatFactory, IProcessExecutor processExecutor, IPostWriteHandler postWriteHandler, IWatchdogFactory watchdogFactory, IJobManager jobManager, ICredentialsProvider credentialsProvider, INetworkPromptReaper networkPromptReaper)
+ /// The value of
+ public InstanceFactory(IIOManager ioManager, IDatabaseContextFactory databaseContextFactory, IApplication application, ILoggerFactory loggerFactory, IByondTopicSender byondTopicSender, ICryptographySuite cryptographySuite, ISynchronousIOManager synchronousIOManager, ISymlinkFactory symlinkFactory, IByondInstaller byondInstaller, IChatFactory chatFactory, IProcessExecutor processExecutor, IPostWriteHandler postWriteHandler, IWatchdogFactory watchdogFactory, IJobManager jobManager, ICredentialsProvider credentialsProvider, INetworkPromptReaper networkPromptReaper, IGitHubClientFactory gitHubClientFactory)
{
this.ioManager = ioManager ?? throw new ArgumentNullException(nameof(ioManager));
this.databaseContextFactory = databaseContextFactory ?? throw new ArgumentNullException(nameof(databaseContextFactory));
@@ -135,6 +141,7 @@ namespace Tgstation.Server.Host.Components
this.jobManager = jobManager ?? throw new ArgumentNullException(nameof(jobManager));
this.credentialsProvider = credentialsProvider ?? throw new ArgumentNullException(nameof(credentialsProvider));
this.networkPromptReaper = networkPromptReaper ?? throw new ArgumentNullException(nameof(networkPromptReaper));
+ this.gitHubClientFactory = gitHubClientFactory ?? throw new ArgumentNullException(nameof(gitHubClientFactory));
}
///
@@ -174,7 +181,7 @@ namespace Tgstation.Server.Host.Components
{
var dreamMaker = new DreamMaker(byond, gameIoManager, configuration, sessionControllerFactory, dmbFactory, application, eventConsumer, chat, processExecutor, watchdog, loggerFactory.CreateLogger());
- return new Instance(metadata.CloneMetadata(), repoManager, byond, dreamMaker, watchdog, chat, configuration, dmbFactory, databaseContextFactory, dmbFactory, jobManager, eventConsumer, loggerFactory.CreateLogger());
+ return new Instance(metadata.CloneMetadata(), repoManager, byond, dreamMaker, watchdog, chat, configuration, dmbFactory, databaseContextFactory, dmbFactory, jobManager, eventConsumer, gitHubClientFactory, loggerFactory.CreateLogger());
}
catch
{
diff --git a/src/Tgstation.Server.Host/Components/Repository/Repository.cs b/src/Tgstation.Server.Host/Components/Repository/Repository.cs
index 6608fcd753..d9d0daaa8d 100644
--- a/src/Tgstation.Server.Host/Components/Repository/Repository.cs
+++ b/src/Tgstation.Server.Host/Components/Repository/Repository.cs
@@ -381,6 +381,10 @@ namespace Tgstation.Server.Host.Components.Repository
{
cancellationToken.ThrowIfCancellationRequested();
}
+ catch(LibGit2SharpException e)
+ {
+ logger.LogWarning("Unable to push to temporary branch! Exception: {0}", e);
+ }
}
finally
{
@@ -581,6 +585,11 @@ namespace Tgstation.Server.Host.Components.Repository
cancellationToken.ThrowIfCancellationRequested();
throw new InvalidOperationException("Caught UserCancelledException without cancellationToken triggering", e);
}
+ catch (LibGit2SharpException e)
+ {
+ logger.LogWarning("Unable to make synchronization push! Exception: {0}", e);
+ return false;
+ }
}, cancellationToken, TaskCreationOptions.LongRunning, TaskScheduler.Current).ConfigureAwait(false);
}
diff --git a/src/Tgstation.Server.Host/Core/Process.cs b/src/Tgstation.Server.Host/Core/Process.cs
index 10e9712d39..813ea77519 100644
--- a/src/Tgstation.Server.Host/Core/Process.cs
+++ b/src/Tgstation.Server.Host/Core/Process.cs
@@ -56,7 +56,7 @@ namespace Tgstation.Server.Host.Core
catch (InvalidOperationException) { }
}, default, TaskCreationOptions.LongRunning, TaskScheduler.Current);
- logger.LogTrace("Created proces ID: {0}", Id);
+ logger.LogTrace("Created process ID: {0}", Id);
}
///