From 11487b5777e9ac7d19f769f8bc2ce34ed8686745 Mon Sep 17 00:00:00 2001 From: Fikou Date: Mon, 10 Aug 2020 21:30:50 +0200 Subject: [PATCH 1/3] improves grammar in readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 09032179ea..73d62e853a 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ [![forthebadge](http://forthebadge.com/images/badges/built-with-love.svg)](http://forthebadge.com) [![forthebadge](http://forthebadge.com/images/badges/60-percent-of-the-time-works-every-time.svg)](http://forthebadge.com) -This is a toolset to manage production BYOND servers. It includes the ability to update the server without having to stop or shutdown the server (the update will take effect on a "reboot" of the server) the ability start the server and restart it if it crashes, as well as systems for managing code and game files, and merging GitHub Pull Requests for test deployments. +This is a toolset to manage production BYOND servers. It includes the ability to update the server without having to stop or shutdown the server, (the update will take effect on a "reboot" of the server) the ability to start the server and restart it if it crashes, as well as systems for managing code and game files, and merging GitHub Pull Requests for test deployments. ### Legacy Servers From c9f14bd51cd6e3b3af8722c25ebd89f17105f683 Mon Sep 17 00:00:00 2001 From: Cyberboss Date: Fri, 7 Aug 2020 18:05:18 -0400 Subject: [PATCH 2/3] Add support for GitHub deployments - API to 7.2.0 - Client to 8.2.0 - Core to 4.5.0 - Removed old solution items - Update dotnet-ef tool to 3.1.6 - Schema update --- build/Version.props | 6 +- .../Models/Internal/RepositorySettings.cs | 14 +- .../Rights/RepositoryRights.cs | 6 +- .../.config/dotnet-tools.json | 2 +- .../Components/Deployment/DmbFactory.cs | 47 +- .../Components/Deployment/DreamMaker.cs | 90 +- .../Deployment/GitHubDeploymentManager.cs | 243 ++++++ .../Deployment/IGitHubDeploymentManager.cs | 58 ++ .../Components/InstanceFactory.cs | 15 +- .../Components/Watchdog/BasicWatchdog.cs | 16 +- .../Components/Watchdog/IWatchdogFactory.cs | 4 +- .../Components/Watchdog/PosixWatchdog.cs | 3 + .../Watchdog/PosixWatchdogFactory.cs | 2 + .../Components/Watchdog/WatchdogBase.cs | 30 +- .../Components/Watchdog/WatchdogFactory.cs | 2 + .../Components/Watchdog/WindowsWatchdog.cs | 8 +- .../Watchdog/WindowsWatchdogFactory.cs | 2 + .../Controllers/InstanceController.cs | 3 +- .../Controllers/RepositoryController.cs | 1 + ...7213255_MSAddDeploymentColumns.Designer.cs | 781 ++++++++++++++++++ .../20200807213255_MSAddDeploymentColumns.cs | 53 ++ ...7213742_MYAddDeploymentColumns.Designer.cs | 771 +++++++++++++++++ .../20200807213742_MYAddDeploymentColumns.cs | 53 ++ ...7214330_PGAddDeploymentColumns.Designer.cs | 778 +++++++++++++++++ .../20200807214330_PGAddDeploymentColumns.cs | 53 ++ ...7214754_SLAddDeploymentColumns.Designer.cs | 770 +++++++++++++++++ .../20200807214754_SLAddDeploymentColumns.cs | 53 ++ .../MySqlDatabaseContextModelSnapshot.cs | 18 +- ...PostgresSqlDatabaseContextModelSnapshot.cs | 18 +- .../SqlServerDatabaseContextModelSnapshot.cs | 17 +- .../SqliteDatabaseContextModelSnapshot.cs | 17 +- .../Models/CompileJob.cs | 12 +- tgstation-server.sln | 4 - 33 files changed, 3873 insertions(+), 77 deletions(-) create mode 100644 src/Tgstation.Server.Host/Components/Deployment/GitHubDeploymentManager.cs create mode 100644 src/Tgstation.Server.Host/Components/Deployment/IGitHubDeploymentManager.cs create mode 100644 src/Tgstation.Server.Host/Database/Migrations/20200807213255_MSAddDeploymentColumns.Designer.cs create mode 100644 src/Tgstation.Server.Host/Database/Migrations/20200807213255_MSAddDeploymentColumns.cs create mode 100644 src/Tgstation.Server.Host/Database/Migrations/20200807213742_MYAddDeploymentColumns.Designer.cs create mode 100644 src/Tgstation.Server.Host/Database/Migrations/20200807213742_MYAddDeploymentColumns.cs create mode 100644 src/Tgstation.Server.Host/Database/Migrations/20200807214330_PGAddDeploymentColumns.Designer.cs create mode 100644 src/Tgstation.Server.Host/Database/Migrations/20200807214330_PGAddDeploymentColumns.cs create mode 100644 src/Tgstation.Server.Host/Database/Migrations/20200807214754_SLAddDeploymentColumns.Designer.cs create mode 100644 src/Tgstation.Server.Host/Database/Migrations/20200807214754_SLAddDeploymentColumns.cs diff --git a/build/Version.props b/build/Version.props index c2ecbd805c..b65405fdb7 100644 --- a/build/Version.props +++ b/build/Version.props @@ -2,10 +2,10 @@ - 4.4.3 + 4.5.0 2.0.0 - 7.1.0 - 8.1.0 + 7.2.0 + 8.2.0 5.2.3 0.4.0 1.1.0 diff --git a/src/Tgstation.Server.Api/Models/Internal/RepositorySettings.cs b/src/Tgstation.Server.Api/Models/Internal/RepositorySettings.cs index b211010351..4a852a901b 100644 --- a/src/Tgstation.Server.Api/Models/Internal/RepositorySettings.cs +++ b/src/Tgstation.Server.Api/Models/Internal/RepositorySettings.cs @@ -1,4 +1,4 @@ -using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations; namespace Tgstation.Server.Api.Models.Internal { @@ -35,11 +35,17 @@ namespace Tgstation.Server.Api.Models.Internal public string? AccessToken { get; set; } /// - /// If commits created from testmerges are pushed to the remote + /// If commits created from testmerges are pushed to the remote. Requires and to be set to function. /// [Required] public bool? PushTestMergeCommits { get; set; } + /// + /// If GitHub deployments should be created. Requires , , and to be set to function. + /// + [Required] + public bool? CreateGitHubDeployments { get; set; } + /// /// If test merge commits are signed with the username of the person who merged it. Note this only affects future commits /// @@ -53,13 +59,13 @@ namespace Tgstation.Server.Api.Models.Internal public bool? AutoUpdatesKeepTestMerges { get; set; } /// - /// If synchronization should occur when auto updating + /// If synchronization should occur when auto updating. Requries and to be set to function. /// [Required] public bool? AutoUpdatesSynchronize { get; set; } /// - /// If test merging should create a comment + /// If test merging should create a comment. Requires to be set to function. /// [Required] public bool? PostTestMergeComment { get; set; } diff --git a/src/Tgstation.Server.Api/Rights/RepositoryRights.cs b/src/Tgstation.Server.Api/Rights/RepositoryRights.cs index 094f555e39..2e98783905 100644 --- a/src/Tgstation.Server.Api/Rights/RepositoryRights.cs +++ b/src/Tgstation.Server.Api/Rights/RepositoryRights.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Tgstation.Server.Api.Rights { @@ -14,7 +14,7 @@ namespace Tgstation.Server.Api.Rights None = 0, /// - /// User may cancel synchronize operations + /// User may cancel update operations. /// CancelPendingChanges = 1, @@ -44,7 +44,7 @@ namespace Tgstation.Server.Api.Rights ChangeCommitter = 32, /// - /// User may change and + /// User may change , , and . /// ChangeTestMergeCommits = 64, diff --git a/src/Tgstation.Server.Host/.config/dotnet-tools.json b/src/Tgstation.Server.Host/.config/dotnet-tools.json index d6051bacfe..4947a30bdf 100644 --- a/src/Tgstation.Server.Host/.config/dotnet-tools.json +++ b/src/Tgstation.Server.Host/.config/dotnet-tools.json @@ -3,7 +3,7 @@ "isRoot": true, "tools": { "dotnet-ef": { - "version": "3.1.5", + "version": "3.1.6", "commands": [ "dotnet-ef" ] diff --git a/src/Tgstation.Server.Host/Components/Deployment/DmbFactory.cs b/src/Tgstation.Server.Host/Components/Deployment/DmbFactory.cs index 7e9b0b7767..4a9df3d206 100644 --- a/src/Tgstation.Server.Host/Components/Deployment/DmbFactory.cs +++ b/src/Tgstation.Server.Host/Components/Deployment/DmbFactory.cs @@ -40,6 +40,11 @@ namespace Tgstation.Server.Host.Components.Deployment /// readonly IIOManager ioManager; + /// + /// The for the . + /// + readonly IGitHubDeploymentManager gitHubDeploymentManager; + /// /// The for the /// @@ -75,17 +80,29 @@ namespace Tgstation.Server.Host.Components.Deployment /// IDmbProvider nextDmbProvider; + /// + /// If the is "started" via . + /// + bool started; + /// /// Construct a /// /// The value of /// The value of + /// The value of . /// The value of /// The value of - public DmbFactory(IDatabaseContextFactory databaseContextFactory, IIOManager ioManager, ILogger logger, Api.Models.Instance instance) + public DmbFactory( + IDatabaseContextFactory databaseContextFactory, + IIOManager ioManager, + IGitHubDeploymentManager gitHubDeploymentManager, + ILogger logger, + Api.Models.Instance instance) { this.databaseContextFactory = databaseContextFactory ?? throw new ArgumentNullException(nameof(databaseContextFactory)); this.ioManager = ioManager ?? throw new ArgumentNullException(nameof(ioManager)); + this.gitHubDeploymentManager = gitHubDeploymentManager ?? throw new ArgumentNullException(nameof(gitHubDeploymentManager)); this.logger = logger ?? throw new ArgumentNullException(nameof(logger)); this.instance = instance ?? throw new ArgumentNullException(nameof(instance)); @@ -107,11 +124,11 @@ namespace Tgstation.Server.Host.Components.Deployment async Task HandleCleanup() { var deleteJob = ioManager.DeleteDirectory(job.DirectoryName.ToString(), cleanupCts.Token); - Task otherTask; - // lock (this) //already locked below - otherTask = cleanupTask; - await Task.WhenAll(otherTask, deleteJob).ConfigureAwait(false); + // DCT: None available + var deploymentJob = gitHubDeploymentManager.MarkInactive(job, default); + var otherTask = cleanupTask; + await Task.WhenAll(otherTask, deleteJob, deploymentJob).ConfigureAwait(false); } lock (jobLockCounts) @@ -137,6 +154,14 @@ namespace Tgstation.Server.Host.Components.Deployment var newProvider = await FromCompileJob(job, cancellationToken).ConfigureAwait(false); if (newProvider == null) return; + + // Do this first, because it's entirely possible when we set the tcs it will immediately need to be applied + if (started) + await gitHubDeploymentManager.StageDeployment( + newProvider.CompileJob, + cancellationToken) + .ConfigureAwait(false); + lock (jobLockCounts) { nextDmbProvider?.Dispose(); @@ -184,6 +209,7 @@ namespace Tgstation.Server.Host.Components.Deployment if (cj == default(CompileJob)) return; await LoadCompileJob(cj, cancellationToken).ConfigureAwait(false); + started = true; // we dont do CleanUnusedCompileJobs here because the watchdog may have plans for them yet } @@ -191,8 +217,15 @@ namespace Tgstation.Server.Host.Components.Deployment /// public async Task StopAsync(CancellationToken cancellationToken) { - using (cancellationToken.Register(() => cleanupCts.Cancel())) - await cleanupTask.ConfigureAwait(false); + try + { + using (cancellationToken.Register(() => cleanupCts.Cancel())) + await cleanupTask.ConfigureAwait(false); + } + finally + { + started = false; + } } /// diff --git a/src/Tgstation.Server.Host/Components/Deployment/DreamMaker.cs b/src/Tgstation.Server.Host/Components/Deployment/DreamMaker.cs index 83e68b4778..59bb0e8faa 100644 --- a/src/Tgstation.Server.Host/Components/Deployment/DreamMaker.cs +++ b/src/Tgstation.Server.Host/Components/Deployment/DreamMaker.cs @@ -88,6 +88,11 @@ namespace Tgstation.Server.Host.Components.Deployment /// readonly ICompileJobSink compileJobConsumer; + /// + /// The for . + /// + readonly IGitHubDeploymentManager gitHubDeploymentManager; + /// /// The for /// @@ -112,6 +117,16 @@ namespace Tgstation.Server.Host.Components.Deployment /// bool deploying; + /// + /// Format a given for display to users. + /// + /// The to format. + /// An error for end users. + static string FormatExceptionForUsers(Exception exception) + => exception is OperationCanceledException + ? "The job was cancelled!" + : exception.Message; + /// /// Construct /// @@ -125,6 +140,7 @@ namespace Tgstation.Server.Host.Components.Deployment /// The value of . /// The value of . /// The value of . + /// The value of . /// The value of /// The value of . public DreamMaker( @@ -138,6 +154,7 @@ namespace Tgstation.Server.Host.Components.Deployment IGitHubClientFactory gitHubClientFactory, ICompileJobSink compileJobConsumer, IRepositoryManager repositoryManager, + IGitHubDeploymentManager gitHubDeploymentManager, ILogger logger, Api.Models.Instance metadata) { @@ -151,6 +168,7 @@ namespace Tgstation.Server.Host.Components.Deployment this.gitHubClientFactory = gitHubClientFactory ?? throw new ArgumentNullException(nameof(gitHubClientFactory)); this.compileJobConsumer = compileJobConsumer ?? throw new ArgumentNullException(nameof(compileJobConsumer)); this.repositoryManager = repositoryManager ?? throw new ArgumentNullException(nameof(repositoryManager)); + this.gitHubDeploymentManager = gitHubDeploymentManager ?? throw new ArgumentNullException(nameof(gitHubDeploymentManager)); this.logger = logger ?? throw new ArgumentNullException(nameof(logger)); this.metadata = metadata ?? throw new ArgumentNullException(nameof(metadata)); @@ -345,22 +363,36 @@ namespace Tgstation.Server.Host.Components.Deployment } /// - /// Cleans up a failed compile + /// Cleans up a failed compile . /// - /// The running + /// The running . + /// The that was thrown. /// A representing the running operation - async Task CleanupFailedCompile(Models.CompileJob job) + async Task CleanupFailedCompile(Models.CompileJob job, Exception exception) { - logger.LogTrace("Cleaning compile directory..."); - var jobPath = job.DirectoryName.ToString(); - try + async Task CleanDir() { - await ioManager.DeleteDirectory(jobPath, CancellationToken.None).ConfigureAwait(false); - } - catch (Exception e) - { - logger.LogWarning(e, "Error cleaning up compile directory {0}!", ioManager.ResolvePath(jobPath)); + logger.LogTrace("Cleaning compile directory..."); + var jobPath = job.DirectoryName.ToString(); + try + { + // DCT: None available + await ioManager.DeleteDirectory(jobPath, default).ConfigureAwait(false); + } + catch (Exception e) + { + logger.LogWarning(e, "Error cleaning up compile directory {0}!", ioManager.ResolvePath(jobPath)); + } } + + // DCT: None available + await Task.WhenAll( + CleanDir(), + gitHubDeploymentManager.FailDeployment( + job, + FormatExceptionForUsers(exception), + default)) + .ConfigureAwait(false); } /// @@ -461,9 +493,9 @@ namespace Tgstation.Server.Host.Components.Deployment logger.LogDebug("Compile complete!"); } - catch + catch (Exception ex) { - await CleanupFailedCompile(job).ConfigureAwait(false); + await CleanupFailedCompile(job, ex).ConfigureAwait(false); throw; } } @@ -651,14 +683,14 @@ namespace Tgstation.Server.Host.Components.Deployment }) .ConfigureAwait(false); } - catch + catch (Exception ex) { - await CleanupFailedCompile(compileJob).ConfigureAwait(false); + await CleanupFailedCompile(compileJob, ex).ConfigureAwait(false); throw; } var commentsTask = PostDeploymentComments( - revInfo, + compileJob, activeCompileJob?.RevisionInformation, repositorySettings, repoOwner, @@ -683,9 +715,7 @@ namespace Tgstation.Server.Host.Components.Deployment { if (currentChatCallback != null) await currentChatCallback( - ex is OperationCanceledException - ? "The job was cancelled!" - : ex.Message, + FormatExceptionForUsers(ex), currentDreamMakerOutput) .ConfigureAwait(false); @@ -767,6 +797,12 @@ namespace Tgstation.Server.Host.Components.Deployment ByondVersion = byondLock.Version.ToString() }; + await gitHubDeploymentManager.StartDeployment( + repository, + job, + cancellationToken) + .ConfigureAwait(false); + await RunCompileJob(job, dreamMakerSettings, byondLock, repository, apiValidateTimeout, cancellationToken).ConfigureAwait(false); return job; @@ -787,7 +823,7 @@ namespace Tgstation.Server.Host.Components.Deployment /// /// Post deployment GitHub comments. /// - /// The deployed . + /// The deployed . /// The of the previous deployment. /// The . /// The GitHub repostiory owner. @@ -795,7 +831,7 @@ namespace Tgstation.Server.Host.Components.Deployment /// The for the operation. /// A representing the running operation. async Task PostDeploymentComments( - Models.RevisionInformation deployedRevisionInformation, + Models.CompileJob compileJob, Models.RevisionInformation previousRevisionInformation, Models.RepositorySettings repositorySettings, string repoOwner, @@ -832,7 +868,8 @@ namespace Tgstation.Server.Host.Components.Deployment var tasks = new List(); - string FormatTestMerge(Models.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}", + var deployedRevisionInformation = compileJob.RevisionInformation; + string FormatTestMerge(Models.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}{8}", Environment.NewLine, repositorySettings.ShowTestMergeCommitters.Value ? String.Format(CultureInfo.InvariantCulture, "{0}{0}##### Merged By{0}{1}", Environment.NewLine, testMerge.MergedBy.Name) : String.Empty, testMerge.PullRequestRevision, @@ -840,7 +877,10 @@ namespace Tgstation.Server.Host.Components.Deployment updated ? "Updated" : "Deployed", metadata.Name, deployedRevisionInformation.OriginCommitSha, - deployedRevisionInformation.CommitSha); + deployedRevisionInformation.CommitSha, + compileJob.GitHubDeploymentId.HasValue + ? $"{Environment.NewLine}[GitHub Deployments](https://github.com/{repoOwner}/{repoName}/deployments/activity_log?environment=TGS%3A%20{metadata.Name})" + : String.Empty); // added prs foreach (var I in deployedRevisionInformation @@ -853,8 +893,8 @@ namespace Tgstation.Server.Host.Components.Deployment // removed prs foreach (var I in previousRevisionInformation - .ActiveTestMerges - .Select(x => x.TestMerge) + .ActiveTestMerges + .Select(x => x.TestMerge) .Where(x => !deployedRevisionInformation .ActiveTestMerges .Any(y => y.TestMerge.Number == x.Number))) diff --git a/src/Tgstation.Server.Host/Components/Deployment/GitHubDeploymentManager.cs b/src/Tgstation.Server.Host/Components/Deployment/GitHubDeploymentManager.cs new file mode 100644 index 0000000000..7b931405d5 --- /dev/null +++ b/src/Tgstation.Server.Host/Components/Deployment/GitHubDeploymentManager.cs @@ -0,0 +1,243 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Logging; +using Octokit; +using System; +using System.Collections.ObjectModel; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Tgstation.Server.Host.Components.Repository; +using Tgstation.Server.Host.Core; +using Tgstation.Server.Host.Database; +using Tgstation.Server.Host.Extensions; +using Tgstation.Server.Host.Models; + +namespace Tgstation.Server.Host.Components.Deployment +{ + /// + sealed class GitHubDeploymentManager : IGitHubDeploymentManager + { + /// + /// The for the . + /// + readonly IDatabaseContextFactory databaseContextFactory; + + /// + /// The for the . + /// + readonly IGitHubClientFactory gitHubClientFactory; + + /// + /// The for the . + /// + readonly ILogger logger; + + /// + /// The for the . + /// + readonly Api.Models.Instance metadata; + + /// + /// Initializes a new instance of the . + /// + /// The value of . + /// The value of . + /// The value of . + /// The value of . + public GitHubDeploymentManager( + IDatabaseContextFactory databaseContextFactory, + IGitHubClientFactory gitHubClientFactory, + ILogger logger, + Api.Models.Instance metadata) + { + this.databaseContextFactory = databaseContextFactory ?? throw new ArgumentNullException(nameof(databaseContextFactory)); + this.gitHubClientFactory = gitHubClientFactory ?? throw new ArgumentNullException(nameof(gitHubClientFactory)); + this.logger = logger ?? throw new ArgumentNullException(nameof(logger)); + this.metadata = metadata ?? throw new ArgumentNullException(nameof(metadata)); + } + + /// + public async Task StartDeployment(IRepository repository, CompileJob compileJob, CancellationToken cancellationToken) + { + if (repository == null) + throw new ArgumentNullException(nameof(repository)); + if (compileJob == null) + throw new ArgumentNullException(nameof(compileJob)); + + if (!repository.IsGitHubRepository) + { + logger.LogTrace("Not managing deployment as this is not a GitHub repo"); + return; + } + + logger.LogTrace("Starting deployment..."); + + RepositorySettings repositorySettings = null; + await databaseContextFactory.UseContext( + async databaseContext => + repositorySettings = await databaseContext + .RepositorySettings + .AsQueryable() + .Where(x => x.InstanceId == metadata.Id) + .FirstAsync(cancellationToken) + .ConfigureAwait(false)) + .ConfigureAwait(false); + + var gitHubClient = repositorySettings.AccessToken == null + ? gitHubClientFactory.CreateClient() + : gitHubClientFactory.CreateClient(repositorySettings.AccessToken); + + var repositoryTask = gitHubClient + .Repository + .Get( + repository.GitHubOwner, + repository.GitHubRepoName); + + if (repositorySettings.CreateGitHubDeployments.Value) + { + logger.LogTrace("Creating deployment..."); + var deployment = await gitHubClient + .Repository + .Deployment + .Create( + repository.GitHubOwner, + repository.GitHubRepoName, + new NewDeployment(compileJob.RevisionInformation.CommitSha) + { + AutoMerge = false, + Description = "TGS Game Deployment", + Environment = $"TGS: {metadata.Name}", + ProductionEnvironment = true, + RequiredContexts = new Collection() + }) + .WithToken(cancellationToken) + .ConfigureAwait(false); + + compileJob.GitHubDeploymentId = deployment.Id; + logger.LogDebug("Created deployment ID {0}", deployment.Id); + + await gitHubClient + .Repository + .Deployment + .Status + .Create( + repository.GitHubOwner, + repository.GitHubRepoName, + deployment.Id, + new NewDeploymentStatus(DeploymentState.InProgress) + { + Description = "The project is being deployed", + AutoInactive = false + }) + .WithToken(cancellationToken) + .ConfigureAwait(false); + + logger.LogTrace("In-progress deployment status created"); + } + else + logger.LogTrace("Not creating deployment"); + + try + { + var gitHubRepo = await repositoryTask + .WithToken(cancellationToken) + .ConfigureAwait(false); + + compileJob.GitHubRepoId = gitHubRepo.Id; + logger.LogTrace("Set GitHub ID as {0}", compileJob.GitHubRepoId); + } + catch (RateLimitExceededException ex) when (!repositorySettings.CreateGitHubDeployments.Value) + { + logger.LogWarning(ex, "Unable to set compile job repository ID!"); + } + } + + async Task UpdateDeployment( + CompileJob compileJob, + string description, + DeploymentState deploymentState, + CancellationToken cancellationToken) + { + if (compileJob == null) + throw new ArgumentNullException(nameof(compileJob)); + + if (!compileJob.GitHubRepoId.HasValue || !compileJob.GitHubDeploymentId.HasValue) + { + logger.LogTrace("Not updating deployment as it is missing a repo ID or deployment ID."); + return; + } + + logger.LogTrace("Updating deployment {0} to {1}...", compileJob.GitHubDeploymentId.Value, deploymentState); + + string gitHubAccessToken = null; + await databaseContextFactory.UseContext( + async databaseContext => + gitHubAccessToken = await databaseContext + .RepositorySettings + .AsQueryable() + .Where(x => x.InstanceId == metadata.Id) + .Select(x => x.AccessToken) + .FirstAsync(cancellationToken) + .ConfigureAwait(false)) + .ConfigureAwait(false); + + if (gitHubAccessToken == null) + { + logger.LogWarning( + "GitHub access token disappeared during deployment, can't update to {0}!", + deploymentState); + return; + } + + var gitHubClient = gitHubClientFactory.CreateClient(gitHubAccessToken); + + await gitHubClient + .Repository + .Deployment + .Status + .Create( + compileJob.GitHubRepoId.Value, + compileJob.GitHubDeploymentId.Value, + new NewDeploymentStatus(deploymentState) + { + Description = description + }) + .WithToken(cancellationToken) + .ConfigureAwait(false); + } + + /// + public Task StageDeployment( + CompileJob compileJob, + CancellationToken cancellationToken) + => UpdateDeployment( + compileJob, + "The deployment succeeded and will be applied a the next server reboot.", + DeploymentState.Pending, + cancellationToken); + + /// + public Task ApplyDeployment(CompileJob compileJob, CompileJob oldCompileJob, CancellationToken cancellationToken) + => UpdateDeployment( + compileJob, + "The deployment is now live on the server.", + DeploymentState.Success, + cancellationToken); + + /// + public Task FailDeployment(CompileJob compileJob, string errorMessage, CancellationToken cancellationToken) + => UpdateDeployment( + compileJob, + errorMessage, + DeploymentState.Error, + cancellationToken); + + /// + public Task MarkInactive(CompileJob compileJob, CancellationToken cancellationToken) + => UpdateDeployment( + compileJob, + "The deployment has been superceeded.", + DeploymentState.Inactive, + cancellationToken); + } +} diff --git a/src/Tgstation.Server.Host/Components/Deployment/IGitHubDeploymentManager.cs b/src/Tgstation.Server.Host/Components/Deployment/IGitHubDeploymentManager.cs new file mode 100644 index 0000000000..9b3a955310 --- /dev/null +++ b/src/Tgstation.Server.Host/Components/Deployment/IGitHubDeploymentManager.cs @@ -0,0 +1,58 @@ +using System.Threading; +using System.Threading.Tasks; +using Tgstation.Server.Host.Components.Repository; +using Tgstation.Server.Host.Models; + +namespace Tgstation.Server.Host.Components.Deployment +{ + /// + /// Creates and updates GitHub deployments. + /// + interface IGitHubDeploymentManager + { + /// + /// Start a deployment for a given . + /// + /// The being deployed. + /// The active . + /// The for the operation. + /// A representing the running operation. + Task StartDeployment(IRepository repository, CompileJob compileJob, CancellationToken cancellationToken); + + /// + /// Stage a given 's deployment. + /// + /// The staged . + /// The for the operation. + /// A representing the running operation. + Task StageDeployment( + CompileJob compileJob, + CancellationToken cancellationToken); + + /// + /// Stage a given 's deployment. + /// + /// The being applied. + /// The currently active , if any. + /// The for the operation. + /// A representing the running operation. + Task ApplyDeployment(CompileJob compileJob, CompileJob oldCompileJob, CancellationToken cancellationToken); + + /// + /// Fail a deployment for a given . + /// + /// The failed . + /// The error message. + /// The for the operation. + /// A representing the running operation. + Task FailDeployment(CompileJob compileJob, string errorMessage, CancellationToken cancellationToken); + + /// + /// Mark the deplotment for a given as inactive. + /// + /// The inactive . + /// The for the operation. + /// A representing the running operation. + Task MarkInactive(CompileJob compileJob, CancellationToken cancellationToken); + } +} diff --git a/src/Tgstation.Server.Host/Components/InstanceFactory.cs b/src/Tgstation.Server.Host/Components/InstanceFactory.cs index dc6243b294..548410eeef 100644 --- a/src/Tgstation.Server.Host/Components/InstanceFactory.cs +++ b/src/Tgstation.Server.Host/Components/InstanceFactory.cs @@ -248,7 +248,18 @@ namespace Tgstation.Server.Host.Components loggerFactory.CreateLogger(), metadata.CloneMetadata()); - var dmbFactory = new DmbFactory(databaseContextFactory, gameIoManager, loggerFactory.CreateLogger(), metadata.CloneMetadata()); + var gitHubDeploymentManager = new GitHubDeploymentManager( + databaseContextFactory, + gitHubClientFactory, + loggerFactory.CreateLogger(), + metadata.CloneMetadata()); + + var dmbFactory = new DmbFactory( + databaseContextFactory, + gameIoManager, + gitHubDeploymentManager, + loggerFactory.CreateLogger(), + metadata.CloneMetadata()); try { var reattachInfoHandler = new SessionPersistor( @@ -265,6 +276,7 @@ namespace Tgstation.Server.Host.Components gameIoManager, diagnosticsIOManager, eventConsumer, + gitHubDeploymentManager, metadata.CloneMetadata(), metadata.DreamDaemonSettings); eventConsumer.SetWatchdog(watchdog); @@ -283,6 +295,7 @@ namespace Tgstation.Server.Host.Components gitHubClientFactory, dmbFactory, repoManager, + gitHubDeploymentManager, loggerFactory.CreateLogger(), metadata.CloneMetadata()); diff --git a/src/Tgstation.Server.Host/Components/Watchdog/BasicWatchdog.cs b/src/Tgstation.Server.Host/Components/Watchdog/BasicWatchdog.cs index 7d1426bb86..08d1ecad37 100644 --- a/src/Tgstation.Server.Host/Components/Watchdog/BasicWatchdog.cs +++ b/src/Tgstation.Server.Host/Components/Watchdog/BasicWatchdog.cs @@ -47,6 +47,7 @@ namespace Tgstation.Server.Host.Components.Watchdog /// The for the . /// The for the . /// The for the . + /// The for the . /// The for the . /// The for the . /// The for the . @@ -61,6 +62,7 @@ namespace Tgstation.Server.Host.Components.Watchdog IAsyncDelayer asyncDelayer, IIOManager diagnosticsIOManager, IEventConsumer eventConsumer, + IGitHubDeploymentManager gitHubDeploymentManager, ILogger logger, DreamDaemonLaunchParameters initialLaunchParameters, Api.Models.Instance instance, @@ -75,6 +77,7 @@ namespace Tgstation.Server.Host.Components.Watchdog asyncDelayer, diagnosticsIOManager, eventConsumer, + gitHubDeploymentManager, logger, initialLaunchParameters, instance, @@ -123,7 +126,7 @@ namespace Tgstation.Server.Host.Components.Watchdog switch (rebootState) { case Session.RebootState.Normal: - return HandleNormalReboot(); + return await HandleNormalReboot(cancellationToken).ConfigureAwait(false); case Session.RebootState.Restart: return MonitorAction.Restart; case Session.RebootState.Shutdown: @@ -187,6 +190,7 @@ namespace Tgstation.Server.Host.Components.Watchdog if (!reattachInProgress) { dmbToUse = await PrepServerForLaunch(dmbToUse, cancellationToken).ConfigureAwait(false); + await BeforeApplyDmb(dmbToUse.CompileJob, cancellationToken).ConfigureAwait(false); serverLaunchTask = SessionControllerFactory.LaunchNew( dmbToUse, null, @@ -236,11 +240,13 @@ namespace Tgstation.Server.Host.Components.Watchdog /// /// Handler for when the is . /// - /// The to take. - protected virtual MonitorAction HandleNormalReboot() + /// The for the operation. + /// A resulting in the to take. + protected virtual Task HandleNormalReboot(CancellationToken cancellationToken) { - bool dmbUpdatePending = ActiveLaunchParameters != LastLaunchParameters; - return dmbUpdatePending ? MonitorAction.Restart : MonitorAction.Continue; + var settingsUpdatePending = ActiveLaunchParameters != LastLaunchParameters; + var result = settingsUpdatePending ? MonitorAction.Restart : MonitorAction.Continue; + return Task.FromResult(result); } /// diff --git a/src/Tgstation.Server.Host/Components/Watchdog/IWatchdogFactory.cs b/src/Tgstation.Server.Host/Components/Watchdog/IWatchdogFactory.cs index 836b1d5d8d..128361d841 100644 --- a/src/Tgstation.Server.Host/Components/Watchdog/IWatchdogFactory.cs +++ b/src/Tgstation.Server.Host/Components/Watchdog/IWatchdogFactory.cs @@ -1,4 +1,4 @@ -using Tgstation.Server.Api.Models.Internal; +using Tgstation.Server.Api.Models.Internal; using Tgstation.Server.Host.Components.Chat; using Tgstation.Server.Host.Components.Deployment; using Tgstation.Server.Host.Components.Events; @@ -22,6 +22,7 @@ namespace Tgstation.Server.Host.Components.Watchdog /// The pointing to the Game directory for the . /// The pointing to the Diagnostics directory for the . /// The for the . + /// The for the . /// The for the /// The initial for the /// A new @@ -33,6 +34,7 @@ namespace Tgstation.Server.Host.Components.Watchdog IIOManager gameIOManager, IIOManager diagnosticsIOManager, IEventConsumer eventConsumer, + IGitHubDeploymentManager gitHubDeploymentManager, Api.Models.Instance instance, DreamDaemonSettings settings); } diff --git a/src/Tgstation.Server.Host/Components/Watchdog/PosixWatchdog.cs b/src/Tgstation.Server.Host/Components/Watchdog/PosixWatchdog.cs index cc03802ded..d87202ee07 100644 --- a/src/Tgstation.Server.Host/Components/Watchdog/PosixWatchdog.cs +++ b/src/Tgstation.Server.Host/Components/Watchdog/PosixWatchdog.cs @@ -34,6 +34,7 @@ namespace Tgstation.Server.Host.Components.Watchdog /// The for the . /// The for the . /// The for the . + /// The for the . /// The pointing to the game directory for the .. /// The for the . /// The for the . @@ -50,6 +51,7 @@ namespace Tgstation.Server.Host.Components.Watchdog IAsyncDelayer asyncDelayer, IIOManager diagnosticsIOManager, IEventConsumer eventConsumer, + IGitHubDeploymentManager gitHubDeploymentManager, IIOManager gameIOManager, ISymlinkFactory symlinkFactory, ILogger logger, @@ -66,6 +68,7 @@ namespace Tgstation.Server.Host.Components.Watchdog asyncDelayer, diagnosticsIOManager, eventConsumer, + gitHubDeploymentManager, gameIOManager, symlinkFactory, logger, diff --git a/src/Tgstation.Server.Host/Components/Watchdog/PosixWatchdogFactory.cs b/src/Tgstation.Server.Host/Components/Watchdog/PosixWatchdogFactory.cs index 279fa3b1e9..8a1575f89c 100644 --- a/src/Tgstation.Server.Host/Components/Watchdog/PosixWatchdogFactory.cs +++ b/src/Tgstation.Server.Host/Components/Watchdog/PosixWatchdogFactory.cs @@ -52,6 +52,7 @@ namespace Tgstation.Server.Host.Components.Watchdog IIOManager gameIOManager, IIOManager diagnosticsIOManager, IEventConsumer eventConsumer, + IGitHubDeploymentManager gitHubDeploymentManager, Api.Models.Instance instance, DreamDaemonSettings settings) => new PosixWatchdog( @@ -64,6 +65,7 @@ namespace Tgstation.Server.Host.Components.Watchdog AsyncDelayer, diagnosticsIOManager, eventConsumer, + gitHubDeploymentManager, gameIOManager, SymlinkFactory, LoggerFactory.CreateLogger(), diff --git a/src/Tgstation.Server.Host/Components/Watchdog/WatchdogBase.cs b/src/Tgstation.Server.Host/Components/Watchdog/WatchdogBase.cs index d795a4b9e6..a9a18cfccb 100644 --- a/src/Tgstation.Server.Host/Components/Watchdog/WatchdogBase.cs +++ b/src/Tgstation.Server.Host/Components/Watchdog/WatchdogBase.cs @@ -60,7 +60,7 @@ namespace Tgstation.Server.Host.Components.Watchdog /// /// The for the . /// - protected ILogger Logger { get; } + protected ILogger Logger { get; } /// /// The for the @@ -122,6 +122,11 @@ namespace Tgstation.Server.Host.Components.Watchdog /// readonly IEventConsumer eventConsumer; + /// + /// The for the . + /// + readonly IGitHubDeploymentManager gitHubDeploymentManager; + /// /// If the should in /// @@ -174,6 +179,7 @@ namespace Tgstation.Server.Host.Components.Watchdog /// The value of . /// The value of . /// The value of . + /// The value of . /// The value of /// The initial value of . May be modified /// The value of @@ -188,7 +194,8 @@ namespace Tgstation.Server.Host.Components.Watchdog IAsyncDelayer asyncDelayer, IIOManager diagnosticsIOManager, IEventConsumer eventConsumer, - ILogger logger, + IGitHubDeploymentManager gitHubDeploymentManager, + ILogger logger, DreamDaemonLaunchParameters initialLaunchParameters, Api.Models.Instance instance, bool autoStart) @@ -201,6 +208,7 @@ namespace Tgstation.Server.Host.Components.Watchdog AsyncDelayer = asyncDelayer ?? throw new ArgumentNullException(nameof(asyncDelayer)); this.diagnosticsIOManager = diagnosticsIOManager ?? throw new ArgumentNullException(nameof(diagnosticsIOManager)); this.eventConsumer = eventConsumer ?? throw new ArgumentNullException(nameof(eventConsumer)); + this.gitHubDeploymentManager = gitHubDeploymentManager ?? throw new ArgumentNullException(nameof(gitHubDeploymentManager)); Logger = logger ?? throw new ArgumentNullException(nameof(logger)); ActiveLaunchParameters = initialLaunchParameters ?? throw new ArgumentNullException(nameof(initialLaunchParameters)); this.instance = instance ?? throw new ArgumentNullException(nameof(instance)); @@ -520,6 +528,23 @@ namespace Tgstation.Server.Host.Components.Watchdog MonitorActivationReason activationReason, CancellationToken cancellationToken); + /// + /// To be called before a given goes live. + /// + /// The new being applied. + /// The for the operation. + /// A representing the running operation. + protected Task BeforeApplyDmb(Models.CompileJob newCompileJob, CancellationToken cancellationToken) + { + if (newCompileJob.Id == ActiveCompileJob?.Id) + { + Logger.LogTrace("Same compile job, not sending deployment event"); + return Task.CompletedTask; + } + + return gitHubDeploymentManager.ApplyDeployment(newCompileJob, ActiveCompileJob, cancellationToken); + } + /// /// Attempt to restart the monitor from scratch. /// @@ -528,6 +553,7 @@ namespace Tgstation.Server.Host.Components.Watchdog private async Task MonitorRestart(CancellationToken cancellationToken) { Logger.LogTrace("Monitor restart!"); + await DisposeAndNullControllers(cancellationToken).ConfigureAwait(false); var chatTask = Task.CompletedTask; diff --git a/src/Tgstation.Server.Host/Components/Watchdog/WatchdogFactory.cs b/src/Tgstation.Server.Host/Components/Watchdog/WatchdogFactory.cs index 423892a249..3592b413cf 100644 --- a/src/Tgstation.Server.Host/Components/Watchdog/WatchdogFactory.cs +++ b/src/Tgstation.Server.Host/Components/Watchdog/WatchdogFactory.cs @@ -72,6 +72,7 @@ namespace Tgstation.Server.Host.Components.Watchdog IIOManager gameIOManager, IIOManager diagnosticsIOManager, IEventConsumer eventConsumer, + IGitHubDeploymentManager gitHubDeploymentManager, Api.Models.Instance instance, DreamDaemonSettings settings) => new BasicWatchdog( @@ -84,6 +85,7 @@ namespace Tgstation.Server.Host.Components.Watchdog AsyncDelayer, diagnosticsIOManager, eventConsumer, + gitHubDeploymentManager, LoggerFactory.CreateLogger(), settings, instance, diff --git a/src/Tgstation.Server.Host/Components/Watchdog/WindowsWatchdog.cs b/src/Tgstation.Server.Host/Components/Watchdog/WindowsWatchdog.cs index fd6e49c24a..baf536f923 100644 --- a/src/Tgstation.Server.Host/Components/Watchdog/WindowsWatchdog.cs +++ b/src/Tgstation.Server.Host/Components/Watchdog/WindowsWatchdog.cs @@ -55,6 +55,7 @@ namespace Tgstation.Server.Host.Components.Watchdog /// The for the . /// The for the . /// The for the . + /// The for the . /// The value of . /// The value of . /// The for the . @@ -71,6 +72,7 @@ namespace Tgstation.Server.Host.Components.Watchdog IAsyncDelayer asyncDelayer, IIOManager diagnosticsIOManager, IEventConsumer eventConsumer, + IGitHubDeploymentManager gitHubDeploymentManager, IIOManager gameIOManager, ISymlinkFactory symlinkFactory, ILogger logger, @@ -86,6 +88,7 @@ namespace Tgstation.Server.Host.Components.Watchdog asyncDelayer, diagnosticsIOManager, eventConsumer, + gitHubDeploymentManager, logger, initialLaunchParameters, instance, @@ -118,14 +121,17 @@ namespace Tgstation.Server.Host.Components.Watchdog } /// - protected override MonitorAction HandleNormalReboot() + protected override async Task HandleNormalReboot(CancellationToken cancellationToken) { if (pendingSwappable != null) { + var updateTask = BeforeApplyDmb(pendingSwappable.CompileJob, cancellationToken); Logger.LogTrace("Replacing activeSwappable with pendingSwappable..."); Server.ReplaceDmbProvider(pendingSwappable); ActiveSwappable = pendingSwappable; pendingSwappable = null; + + await updateTask.ConfigureAwait(false); } else Logger.LogTrace("Nothing to do as pendingSwappable is null."); diff --git a/src/Tgstation.Server.Host/Components/Watchdog/WindowsWatchdogFactory.cs b/src/Tgstation.Server.Host/Components/Watchdog/WindowsWatchdogFactory.cs index a597a80997..98c7d1c2c2 100644 --- a/src/Tgstation.Server.Host/Components/Watchdog/WindowsWatchdogFactory.cs +++ b/src/Tgstation.Server.Host/Components/Watchdog/WindowsWatchdogFactory.cs @@ -58,6 +58,7 @@ namespace Tgstation.Server.Host.Components.Watchdog IIOManager gameIOManager, IIOManager diagnosticsIOManager, IEventConsumer eventConsumer, + IGitHubDeploymentManager gitHubDeploymentManager, Api.Models.Instance instance, DreamDaemonSettings settings) => new WindowsWatchdog( @@ -70,6 +71,7 @@ namespace Tgstation.Server.Host.Components.Watchdog AsyncDelayer, diagnosticsIOManager, eventConsumer, + gitHubDeploymentManager, gameIOManager, SymlinkFactory, LoggerFactory.CreateLogger(), diff --git a/src/Tgstation.Server.Host/Controllers/InstanceController.cs b/src/Tgstation.Server.Host/Controllers/InstanceController.cs index 243fe297db..aacf3a0fe6 100644 --- a/src/Tgstation.Server.Host/Controllers/InstanceController.cs +++ b/src/Tgstation.Server.Host/Controllers/InstanceController.cs @@ -132,7 +132,8 @@ namespace Tgstation.Server.Host.Controllers ShowTestMergeCommitters = false, AutoUpdatesKeepTestMerges = false, AutoUpdatesSynchronize = false, - PostTestMergeComment = false + PostTestMergeComment = false, + CreateGitHubDeployments = false }, InstanceUsers = new List // give this user full privileges on the instance { diff --git a/src/Tgstation.Server.Host/Controllers/RepositoryController.cs b/src/Tgstation.Server.Host/Controllers/RepositoryController.cs index 1cb24d8a39..17646202ba 100644 --- a/src/Tgstation.Server.Host/Controllers/RepositoryController.cs +++ b/src/Tgstation.Server.Host/Controllers/RepositoryController.cs @@ -420,6 +420,7 @@ namespace Tgstation.Server.Host.Controllers || CheckModified(x => x.CommitterEmail, RepositoryRights.ChangeCommitter) || CheckModified(x => x.CommitterName, RepositoryRights.ChangeCommitter) || CheckModified(x => x.PushTestMergeCommits, RepositoryRights.ChangeTestMergeCommits) + || CheckModified(x => x.CreateGitHubDeployments, RepositoryRights.ChangeTestMergeCommits) || CheckModified(x => x.ShowTestMergeCommitters, RepositoryRights.ChangeTestMergeCommits) || CheckModified(x => x.PostTestMergeComment, RepositoryRights.ChangeTestMergeCommits) || (model.UpdateFromOrigin == true && !userRights.HasFlag(RepositoryRights.UpdateBranch))) diff --git a/src/Tgstation.Server.Host/Database/Migrations/20200807213255_MSAddDeploymentColumns.Designer.cs b/src/Tgstation.Server.Host/Database/Migrations/20200807213255_MSAddDeploymentColumns.Designer.cs new file mode 100644 index 0000000000..10a205afb4 --- /dev/null +++ b/src/Tgstation.Server.Host/Database/Migrations/20200807213255_MSAddDeploymentColumns.Designer.cs @@ -0,0 +1,781 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Tgstation.Server.Host.Database.Migrations +{ + [DbContext(typeof(SqlServerDatabaseContext))] + [Migration("20200807213255_MSAddDeploymentColumns")] + partial class MSAddDeploymentColumns + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "3.1.6") + .HasAnnotation("Relational:MaxIdentifierLength", 128) + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + modelBuilder.Entity("Tgstation.Server.Host.Models.ChatBot", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("ChannelLimit") + .HasColumnType("int"); + + b.Property("ConnectionString") + .IsRequired() + .HasColumnType("nvarchar(max)") + .HasMaxLength(10000); + + b.Property("Enabled") + .HasColumnType("bit"); + + b.Property("InstanceId") + .HasColumnType("bigint"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); + + b.Property("Provider") + .HasColumnType("int"); + + b.Property("ReconnectionInterval") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("InstanceId", "Name") + .IsUnique(); + + b.ToTable("ChatBots"); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.ChatChannel", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("ChatSettingsId") + .HasColumnType("bigint"); + + b.Property("DiscordChannelId") + .HasColumnType("decimal(20,0)"); + + b.Property("IrcChannel") + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); + + b.Property("IsAdminChannel") + .IsRequired() + .HasColumnType("bit"); + + b.Property("IsUpdatesChannel") + .IsRequired() + .HasColumnType("bit"); + + b.Property("IsWatchdogChannel") + .IsRequired() + .HasColumnType("bit"); + + b.Property("Tag") + .HasColumnType("nvarchar(max)") + .HasMaxLength(10000); + + b.HasKey("Id"); + + b.HasIndex("ChatSettingsId", "DiscordChannelId") + .IsUnique() + .HasFilter("[DiscordChannelId] IS NOT NULL"); + + b.HasIndex("ChatSettingsId", "IrcChannel") + .IsUnique() + .HasFilter("[IrcChannel] IS NOT NULL"); + + b.ToTable("ChatChannels"); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.CompileJob", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("ByondVersion") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("DMApiMajorVersion") + .HasColumnType("int"); + + b.Property("DMApiMinorVersion") + .HasColumnType("int"); + + b.Property("DMApiPatchVersion") + .HasColumnType("int"); + + b.Property("DirectoryName") + .IsRequired() + .HasColumnType("uniqueidentifier"); + + b.Property("DmeName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("GitHubDeploymentId") + .HasColumnType("int"); + + b.Property("GitHubRepoId") + .HasColumnType("bigint"); + + b.Property("JobId") + .HasColumnType("bigint"); + + b.Property("MinimumSecurityLevel") + .HasColumnType("int"); + + b.Property("Output") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("RevisionInformationId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("DirectoryName"); + + b.HasIndex("JobId") + .IsUnique(); + + b.HasIndex("RevisionInformationId"); + + b.ToTable("CompileJobs"); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.DreamDaemonSettings", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("AllowWebClient") + .IsRequired() + .HasColumnType("bit"); + + b.Property("AutoStart") + .IsRequired() + .HasColumnType("bit"); + + b.Property("HeartbeatSeconds") + .HasColumnType("bigint"); + + b.Property("InstanceId") + .HasColumnType("bigint"); + + b.Property("Port") + .HasColumnType("int"); + + b.Property("SecurityLevel") + .HasColumnType("int"); + + b.Property("StartupTimeout") + .HasColumnType("bigint"); + + b.Property("TopicRequestTimeout") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("InstanceId") + .IsUnique(); + + b.ToTable("DreamDaemonSettings"); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.DreamMakerSettings", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("ApiValidationPort") + .HasColumnType("int"); + + b.Property("ApiValidationSecurityLevel") + .HasColumnType("int"); + + b.Property("InstanceId") + .HasColumnType("bigint"); + + b.Property("ProjectName") + .HasColumnType("nvarchar(max)") + .HasMaxLength(10000); + + b.Property("RequireDMApiValidation") + .IsRequired() + .HasColumnType("bit"); + + b.HasKey("Id"); + + b.HasIndex("InstanceId") + .IsUnique(); + + b.ToTable("DreamMakerSettings"); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.Instance", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("AutoUpdateInterval") + .HasColumnType("bigint"); + + b.Property("ChatBotLimit") + .HasColumnType("int"); + + b.Property("ConfigurationType") + .HasColumnType("int"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)") + .HasMaxLength(10000); + + b.Property("Online") + .IsRequired() + .HasColumnType("bit"); + + b.Property("Path") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.HasKey("Id"); + + b.HasIndex("Path") + .IsUnique(); + + b.ToTable("Instances"); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.InstanceUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("ByondRights") + .HasColumnType("decimal(20,0)"); + + b.Property("ChatBotRights") + .HasColumnType("decimal(20,0)"); + + b.Property("ConfigurationRights") + .HasColumnType("decimal(20,0)"); + + b.Property("DreamDaemonRights") + .HasColumnType("decimal(20,0)"); + + b.Property("DreamMakerRights") + .HasColumnType("decimal(20,0)"); + + b.Property("InstanceId") + .HasColumnType("bigint"); + + b.Property("InstanceUserRights") + .HasColumnType("decimal(20,0)"); + + b.Property("RepositoryRights") + .HasColumnType("decimal(20,0)"); + + b.Property("UserId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("InstanceId"); + + b.HasIndex("UserId", "InstanceId") + .IsUnique(); + + b.ToTable("InstanceUsers"); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.Job", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("CancelRight") + .HasColumnType("decimal(20,0)"); + + b.Property("CancelRightsType") + .HasColumnType("decimal(20,0)"); + + b.Property("Cancelled") + .IsRequired() + .HasColumnType("bit"); + + b.Property("CancelledById") + .HasColumnType("bigint"); + + b.Property("Description") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("ErrorCode") + .HasColumnType("bigint"); + + b.Property("ExceptionDetails") + .HasColumnType("nvarchar(max)"); + + b.Property("InstanceId") + .HasColumnType("bigint"); + + b.Property("StartedAt") + .IsRequired() + .HasColumnType("datetimeoffset"); + + b.Property("StartedById") + .HasColumnType("bigint"); + + b.Property("StoppedAt") + .HasColumnType("datetimeoffset"); + + b.HasKey("Id"); + + b.HasIndex("CancelledById"); + + b.HasIndex("InstanceId"); + + b.HasIndex("StartedById"); + + b.ToTable("Jobs"); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.ReattachInformation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("AccessIdentifier") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("CompileJobId") + .HasColumnType("bigint"); + + b.Property("LaunchSecurityLevel") + .HasColumnType("int"); + + b.Property("Port") + .HasColumnType("int"); + + b.Property("ProcessId") + .HasColumnType("int"); + + b.Property("RebootState") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CompileJobId"); + + b.ToTable("ReattachInformations"); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.RepositorySettings", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("AccessToken") + .HasColumnType("nvarchar(max)") + .HasMaxLength(10000); + + b.Property("AccessUser") + .HasColumnType("nvarchar(max)") + .HasMaxLength(10000); + + b.Property("AutoUpdatesKeepTestMerges") + .IsRequired() + .HasColumnType("bit"); + + b.Property("AutoUpdatesSynchronize") + .IsRequired() + .HasColumnType("bit"); + + b.Property("CommitterEmail") + .IsRequired() + .HasColumnType("nvarchar(max)") + .HasMaxLength(10000); + + b.Property("CommitterName") + .IsRequired() + .HasColumnType("nvarchar(max)") + .HasMaxLength(10000); + + b.Property("CreateGitHubDeployments") + .IsRequired() + .HasColumnType("bit"); + + b.Property("InstanceId") + .HasColumnType("bigint"); + + b.Property("PostTestMergeComment") + .IsRequired() + .HasColumnType("bit"); + + b.Property("PushTestMergeCommits") + .IsRequired() + .HasColumnType("bit"); + + b.Property("ShowTestMergeCommitters") + .IsRequired() + .HasColumnType("bit"); + + b.HasKey("Id"); + + b.HasIndex("InstanceId") + .IsUnique(); + + b.ToTable("RepositorySettings"); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.RevInfoTestMerge", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("RevisionInformationId") + .HasColumnType("bigint"); + + b.Property("TestMergeId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("RevisionInformationId"); + + b.HasIndex("TestMergeId"); + + b.ToTable("RevInfoTestMerges"); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.RevisionInformation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("CommitSha") + .IsRequired() + .HasColumnType("nvarchar(40)") + .HasMaxLength(40); + + b.Property("InstanceId") + .HasColumnType("bigint"); + + b.Property("OriginCommitSha") + .IsRequired() + .HasColumnType("nvarchar(40)") + .HasMaxLength(40); + + b.HasKey("Id"); + + b.HasIndex("InstanceId", "CommitSha") + .IsUnique(); + + b.ToTable("RevisionInformations"); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.TestMerge", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("Author") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("BodyAtMerge") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Comment") + .HasColumnType("nvarchar(max)") + .HasMaxLength(10000); + + b.Property("MergedAt") + .HasColumnType("datetimeoffset"); + + b.Property("MergedById") + .HasColumnType("bigint"); + + b.Property("Number") + .HasColumnType("int"); + + b.Property("PrimaryRevisionInformationId") + .IsRequired() + .HasColumnType("bigint"); + + b.Property("PullRequestRevision") + .IsRequired() + .HasColumnType("nvarchar(40)") + .HasMaxLength(40); + + b.Property("TitleAtMerge") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Url") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("MergedById"); + + b.HasIndex("PrimaryRevisionInformationId") + .IsUnique(); + + b.ToTable("TestMerges"); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("AdministrationRights") + .HasColumnType("decimal(20,0)"); + + b.Property("CanonicalName") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.Property("CreatedAt") + .IsRequired() + .HasColumnType("datetimeoffset"); + + b.Property("CreatedById") + .HasColumnType("bigint"); + + b.Property("Enabled") + .IsRequired() + .HasColumnType("bit"); + + b.Property("InstanceManagerRights") + .HasColumnType("decimal(20,0)"); + + b.Property("LastPasswordUpdate") + .HasColumnType("datetimeoffset"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)") + .HasMaxLength(10000); + + b.Property("PasswordHash") + .HasColumnType("nvarchar(max)"); + + b.Property("SystemIdentifier") + .HasColumnType("nvarchar(450)"); + + b.HasKey("Id"); + + b.HasIndex("CanonicalName") + .IsUnique(); + + b.HasIndex("CreatedById"); + + b.HasIndex("SystemIdentifier") + .IsUnique() + .HasFilter("[SystemIdentifier] IS NOT NULL"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.ChatBot", b => + { + b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance") + .WithMany("ChatSettings") + .HasForeignKey("InstanceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.ChatChannel", b => + { + b.HasOne("Tgstation.Server.Host.Models.ChatBot", "ChatSettings") + .WithMany("Channels") + .HasForeignKey("ChatSettingsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.CompileJob", b => + { + b.HasOne("Tgstation.Server.Host.Models.Job", "Job") + .WithOne() + .HasForeignKey("Tgstation.Server.Host.Models.CompileJob", "JobId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tgstation.Server.Host.Models.RevisionInformation", "RevisionInformation") + .WithMany("CompileJobs") + .HasForeignKey("RevisionInformationId") + .OnDelete(DeleteBehavior.ClientNoAction) + .IsRequired(); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.DreamDaemonSettings", b => + { + b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance") + .WithOne("DreamDaemonSettings") + .HasForeignKey("Tgstation.Server.Host.Models.DreamDaemonSettings", "InstanceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.DreamMakerSettings", b => + { + b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance") + .WithOne("DreamMakerSettings") + .HasForeignKey("Tgstation.Server.Host.Models.DreamMakerSettings", "InstanceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.InstanceUser", b => + { + b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance") + .WithMany("InstanceUsers") + .HasForeignKey("InstanceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tgstation.Server.Host.Models.User", null) + .WithMany("InstanceUsers") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.Job", b => + { + b.HasOne("Tgstation.Server.Host.Models.User", "CancelledBy") + .WithMany() + .HasForeignKey("CancelledById"); + + b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance") + .WithMany("Jobs") + .HasForeignKey("InstanceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tgstation.Server.Host.Models.User", "StartedBy") + .WithMany() + .HasForeignKey("StartedById") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.ReattachInformation", b => + { + b.HasOne("Tgstation.Server.Host.Models.CompileJob", "CompileJob") + .WithMany() + .HasForeignKey("CompileJobId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.RepositorySettings", b => + { + b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance") + .WithOne("RepositorySettings") + .HasForeignKey("Tgstation.Server.Host.Models.RepositorySettings", "InstanceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.RevInfoTestMerge", b => + { + b.HasOne("Tgstation.Server.Host.Models.RevisionInformation", "RevisionInformation") + .WithMany("ActiveTestMerges") + .HasForeignKey("RevisionInformationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tgstation.Server.Host.Models.TestMerge", "TestMerge") + .WithMany("RevisonInformations") + .HasForeignKey("TestMergeId") + .OnDelete(DeleteBehavior.ClientNoAction) + .IsRequired(); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.RevisionInformation", b => + { + b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance") + .WithMany("RevisionInformations") + .HasForeignKey("InstanceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.TestMerge", b => + { + b.HasOne("Tgstation.Server.Host.Models.User", "MergedBy") + .WithMany("TestMerges") + .HasForeignKey("MergedById") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("Tgstation.Server.Host.Models.RevisionInformation", "PrimaryRevisionInformation") + .WithOne("PrimaryTestMerge") + .HasForeignKey("Tgstation.Server.Host.Models.TestMerge", "PrimaryRevisionInformationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.User", b => + { + b.HasOne("Tgstation.Server.Host.Models.User", "CreatedBy") + .WithMany("CreatedUsers") + .HasForeignKey("CreatedById"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Tgstation.Server.Host/Database/Migrations/20200807213255_MSAddDeploymentColumns.cs b/src/Tgstation.Server.Host/Database/Migrations/20200807213255_MSAddDeploymentColumns.cs new file mode 100644 index 0000000000..2785f95372 --- /dev/null +++ b/src/Tgstation.Server.Host/Database/Migrations/20200807213255_MSAddDeploymentColumns.cs @@ -0,0 +1,53 @@ +using Microsoft.EntityFrameworkCore.Migrations; +using System; + +namespace Tgstation.Server.Host.Database.Migrations +{ + /// + /// Adds columns for GitHub deployments for MSSQL. + /// + public partial class MSAddDeploymentColumns : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + if (migrationBuilder == null) + throw new ArgumentNullException(nameof(migrationBuilder)); + + migrationBuilder.AddColumn( + name: "CreateGitHubDeployments", + table: "RepositorySettings", + nullable: false, + defaultValue: false); + + migrationBuilder.AddColumn( + name: "GitHubDeploymentId", + table: "CompileJobs", + nullable: true); + + migrationBuilder.AddColumn( + name: "GitHubRepoId", + table: "CompileJobs", + nullable: true); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + if (migrationBuilder == null) + throw new ArgumentNullException(nameof(migrationBuilder)); + + migrationBuilder.DropColumn( + name: "CreateGitHubDeployments", + table: "RepositorySettings"); + + migrationBuilder.DropColumn( + name: "GitHubDeploymentId", + table: "CompileJobs"); + + migrationBuilder.DropColumn( + name: "GitHubRepoId", + table: "CompileJobs"); + } + } +} diff --git a/src/Tgstation.Server.Host/Database/Migrations/20200807213742_MYAddDeploymentColumns.Designer.cs b/src/Tgstation.Server.Host/Database/Migrations/20200807213742_MYAddDeploymentColumns.Designer.cs new file mode 100644 index 0000000000..34a844bc2f --- /dev/null +++ b/src/Tgstation.Server.Host/Database/Migrations/20200807213742_MYAddDeploymentColumns.Designer.cs @@ -0,0 +1,771 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Tgstation.Server.Host.Database.Migrations +{ + [DbContext(typeof(MySqlDatabaseContext))] + [Migration("20200807213742_MYAddDeploymentColumns")] + partial class MYAddDeploymentColumns + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "3.1.6") + .HasAnnotation("Relational:MaxIdentifierLength", 64); + + modelBuilder.Entity("Tgstation.Server.Host.Models.ChatBot", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("ChannelLimit") + .IsRequired() + .HasColumnType("smallint unsigned"); + + b.Property("ConnectionString") + .IsRequired() + .HasColumnType("longtext CHARACTER SET utf8mb4") + .HasMaxLength(10000); + + b.Property("Enabled") + .HasColumnType("tinyint(1)"); + + b.Property("InstanceId") + .HasColumnType("bigint"); + + b.Property("Name") + .IsRequired() + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b.Property("Provider") + .HasColumnType("int"); + + b.Property("ReconnectionInterval") + .IsRequired() + .HasColumnType("int unsigned"); + + b.HasKey("Id"); + + b.HasIndex("InstanceId", "Name") + .IsUnique(); + + b.ToTable("ChatBots"); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.ChatChannel", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("ChatSettingsId") + .HasColumnType("bigint"); + + b.Property("DiscordChannelId") + .HasColumnType("bigint unsigned"); + + b.Property("IrcChannel") + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b.Property("IsAdminChannel") + .IsRequired() + .HasColumnType("tinyint(1)"); + + b.Property("IsUpdatesChannel") + .IsRequired() + .HasColumnType("tinyint(1)"); + + b.Property("IsWatchdogChannel") + .IsRequired() + .HasColumnType("tinyint(1)"); + + b.Property("Tag") + .HasColumnType("longtext CHARACTER SET utf8mb4") + .HasMaxLength(10000); + + b.HasKey("Id"); + + b.HasIndex("ChatSettingsId", "DiscordChannelId") + .IsUnique(); + + b.HasIndex("ChatSettingsId", "IrcChannel") + .IsUnique(); + + b.ToTable("ChatChannels"); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.CompileJob", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("ByondVersion") + .IsRequired() + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("DMApiMajorVersion") + .HasColumnType("int"); + + b.Property("DMApiMinorVersion") + .HasColumnType("int"); + + b.Property("DMApiPatchVersion") + .HasColumnType("int"); + + b.Property("DirectoryName") + .IsRequired() + .HasColumnType("char(36)"); + + b.Property("DmeName") + .IsRequired() + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("GitHubDeploymentId") + .HasColumnType("int"); + + b.Property("GitHubRepoId") + .HasColumnType("bigint"); + + b.Property("JobId") + .HasColumnType("bigint"); + + b.Property("MinimumSecurityLevel") + .HasColumnType("int"); + + b.Property("Output") + .IsRequired() + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("RevisionInformationId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("DirectoryName"); + + b.HasIndex("JobId") + .IsUnique(); + + b.HasIndex("RevisionInformationId"); + + b.ToTable("CompileJobs"); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.DreamDaemonSettings", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("AllowWebClient") + .IsRequired() + .HasColumnType("tinyint(1)"); + + b.Property("AutoStart") + .IsRequired() + .HasColumnType("tinyint(1)"); + + b.Property("HeartbeatSeconds") + .IsRequired() + .HasColumnType("int unsigned"); + + b.Property("InstanceId") + .HasColumnType("bigint"); + + b.Property("Port") + .IsRequired() + .HasColumnType("smallint unsigned"); + + b.Property("SecurityLevel") + .HasColumnType("int"); + + b.Property("StartupTimeout") + .IsRequired() + .HasColumnType("int unsigned"); + + b.Property("TopicRequestTimeout") + .IsRequired() + .HasColumnType("int unsigned"); + + b.HasKey("Id"); + + b.HasIndex("InstanceId") + .IsUnique(); + + b.ToTable("DreamDaemonSettings"); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.DreamMakerSettings", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("ApiValidationPort") + .IsRequired() + .HasColumnType("smallint unsigned"); + + b.Property("ApiValidationSecurityLevel") + .HasColumnType("int"); + + b.Property("InstanceId") + .HasColumnType("bigint"); + + b.Property("ProjectName") + .HasColumnType("longtext CHARACTER SET utf8mb4") + .HasMaxLength(10000); + + b.Property("RequireDMApiValidation") + .IsRequired() + .HasColumnType("tinyint(1)"); + + b.HasKey("Id"); + + b.HasIndex("InstanceId") + .IsUnique(); + + b.ToTable("DreamMakerSettings"); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.Instance", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("AutoUpdateInterval") + .IsRequired() + .HasColumnType("int unsigned"); + + b.Property("ChatBotLimit") + .IsRequired() + .HasColumnType("smallint unsigned"); + + b.Property("ConfigurationType") + .HasColumnType("int"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext CHARACTER SET utf8mb4") + .HasMaxLength(10000); + + b.Property("Online") + .IsRequired() + .HasColumnType("tinyint(1)"); + + b.Property("Path") + .IsRequired() + .HasColumnType("varchar(255) CHARACTER SET utf8mb4"); + + b.HasKey("Id"); + + b.HasIndex("Path") + .IsUnique(); + + b.ToTable("Instances"); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.InstanceUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("ByondRights") + .HasColumnType("bigint unsigned"); + + b.Property("ChatBotRights") + .HasColumnType("bigint unsigned"); + + b.Property("ConfigurationRights") + .HasColumnType("bigint unsigned"); + + b.Property("DreamDaemonRights") + .HasColumnType("bigint unsigned"); + + b.Property("DreamMakerRights") + .HasColumnType("bigint unsigned"); + + b.Property("InstanceId") + .HasColumnType("bigint"); + + b.Property("InstanceUserRights") + .HasColumnType("bigint unsigned"); + + b.Property("RepositoryRights") + .HasColumnType("bigint unsigned"); + + b.Property("UserId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("InstanceId"); + + b.HasIndex("UserId", "InstanceId") + .IsUnique(); + + b.ToTable("InstanceUsers"); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.Job", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("CancelRight") + .HasColumnType("bigint unsigned"); + + b.Property("CancelRightsType") + .HasColumnType("bigint unsigned"); + + b.Property("Cancelled") + .IsRequired() + .HasColumnType("tinyint(1)"); + + b.Property("CancelledById") + .HasColumnType("bigint"); + + b.Property("Description") + .IsRequired() + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("ErrorCode") + .HasColumnType("int unsigned"); + + b.Property("ExceptionDetails") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("InstanceId") + .HasColumnType("bigint"); + + b.Property("StartedAt") + .IsRequired() + .HasColumnType("datetime(6)"); + + b.Property("StartedById") + .HasColumnType("bigint"); + + b.Property("StoppedAt") + .HasColumnType("datetime(6)"); + + b.HasKey("Id"); + + b.HasIndex("CancelledById"); + + b.HasIndex("InstanceId"); + + b.HasIndex("StartedById"); + + b.ToTable("Jobs"); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.ReattachInformation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("AccessIdentifier") + .IsRequired() + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("CompileJobId") + .HasColumnType("bigint"); + + b.Property("LaunchSecurityLevel") + .HasColumnType("int"); + + b.Property("Port") + .HasColumnType("smallint unsigned"); + + b.Property("ProcessId") + .HasColumnType("int"); + + b.Property("RebootState") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CompileJobId"); + + b.ToTable("ReattachInformations"); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.RepositorySettings", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("AccessToken") + .HasColumnType("longtext CHARACTER SET utf8mb4") + .HasMaxLength(10000); + + b.Property("AccessUser") + .HasColumnType("longtext CHARACTER SET utf8mb4") + .HasMaxLength(10000); + + b.Property("AutoUpdatesKeepTestMerges") + .IsRequired() + .HasColumnType("tinyint(1)"); + + b.Property("AutoUpdatesSynchronize") + .IsRequired() + .HasColumnType("tinyint(1)"); + + b.Property("CommitterEmail") + .IsRequired() + .HasColumnType("longtext CHARACTER SET utf8mb4") + .HasMaxLength(10000); + + b.Property("CommitterName") + .IsRequired() + .HasColumnType("longtext CHARACTER SET utf8mb4") + .HasMaxLength(10000); + + b.Property("CreateGitHubDeployments") + .IsRequired() + .HasColumnType("tinyint(1)"); + + b.Property("InstanceId") + .HasColumnType("bigint"); + + b.Property("PostTestMergeComment") + .IsRequired() + .HasColumnType("tinyint(1)"); + + b.Property("PushTestMergeCommits") + .IsRequired() + .HasColumnType("tinyint(1)"); + + b.Property("ShowTestMergeCommitters") + .IsRequired() + .HasColumnType("tinyint(1)"); + + b.HasKey("Id"); + + b.HasIndex("InstanceId") + .IsUnique(); + + b.ToTable("RepositorySettings"); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.RevInfoTestMerge", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("RevisionInformationId") + .HasColumnType("bigint"); + + b.Property("TestMergeId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("RevisionInformationId"); + + b.HasIndex("TestMergeId"); + + b.ToTable("RevInfoTestMerges"); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.RevisionInformation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("CommitSha") + .IsRequired() + .HasColumnType("varchar(40) CHARACTER SET utf8mb4") + .HasMaxLength(40); + + b.Property("InstanceId") + .HasColumnType("bigint"); + + b.Property("OriginCommitSha") + .IsRequired() + .HasColumnType("varchar(40) CHARACTER SET utf8mb4") + .HasMaxLength(40); + + b.HasKey("Id"); + + b.HasIndex("InstanceId", "CommitSha") + .IsUnique(); + + b.ToTable("RevisionInformations"); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.TestMerge", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("Author") + .IsRequired() + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("BodyAtMerge") + .IsRequired() + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("Comment") + .HasColumnType("longtext CHARACTER SET utf8mb4") + .HasMaxLength(10000); + + b.Property("MergedAt") + .HasColumnType("datetime(6)"); + + b.Property("MergedById") + .HasColumnType("bigint"); + + b.Property("Number") + .HasColumnType("int"); + + b.Property("PrimaryRevisionInformationId") + .IsRequired() + .HasColumnType("bigint"); + + b.Property("PullRequestRevision") + .IsRequired() + .HasColumnType("varchar(40) CHARACTER SET utf8mb4") + .HasMaxLength(40); + + b.Property("TitleAtMerge") + .IsRequired() + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("Url") + .IsRequired() + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.HasKey("Id"); + + b.HasIndex("MergedById"); + + b.HasIndex("PrimaryRevisionInformationId") + .IsUnique(); + + b.ToTable("TestMerges"); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("AdministrationRights") + .HasColumnType("bigint unsigned"); + + b.Property("CanonicalName") + .IsRequired() + .HasColumnType("varchar(255) CHARACTER SET utf8mb4"); + + b.Property("CreatedAt") + .IsRequired() + .HasColumnType("datetime(6)"); + + b.Property("CreatedById") + .HasColumnType("bigint"); + + b.Property("Enabled") + .IsRequired() + .HasColumnType("tinyint(1)"); + + b.Property("InstanceManagerRights") + .HasColumnType("bigint unsigned"); + + b.Property("LastPasswordUpdate") + .HasColumnType("datetime(6)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext CHARACTER SET utf8mb4") + .HasMaxLength(10000); + + b.Property("PasswordHash") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("SystemIdentifier") + .HasColumnType("varchar(255) CHARACTER SET utf8mb4"); + + b.HasKey("Id"); + + b.HasIndex("CanonicalName") + .IsUnique(); + + b.HasIndex("CreatedById"); + + b.HasIndex("SystemIdentifier") + .IsUnique(); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.ChatBot", b => + { + b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance") + .WithMany("ChatSettings") + .HasForeignKey("InstanceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.ChatChannel", b => + { + b.HasOne("Tgstation.Server.Host.Models.ChatBot", "ChatSettings") + .WithMany("Channels") + .HasForeignKey("ChatSettingsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.CompileJob", b => + { + b.HasOne("Tgstation.Server.Host.Models.Job", "Job") + .WithOne() + .HasForeignKey("Tgstation.Server.Host.Models.CompileJob", "JobId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tgstation.Server.Host.Models.RevisionInformation", "RevisionInformation") + .WithMany("CompileJobs") + .HasForeignKey("RevisionInformationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.DreamDaemonSettings", b => + { + b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance") + .WithOne("DreamDaemonSettings") + .HasForeignKey("Tgstation.Server.Host.Models.DreamDaemonSettings", "InstanceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.DreamMakerSettings", b => + { + b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance") + .WithOne("DreamMakerSettings") + .HasForeignKey("Tgstation.Server.Host.Models.DreamMakerSettings", "InstanceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.InstanceUser", b => + { + b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance") + .WithMany("InstanceUsers") + .HasForeignKey("InstanceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tgstation.Server.Host.Models.User", null) + .WithMany("InstanceUsers") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.Job", b => + { + b.HasOne("Tgstation.Server.Host.Models.User", "CancelledBy") + .WithMany() + .HasForeignKey("CancelledById"); + + b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance") + .WithMany("Jobs") + .HasForeignKey("InstanceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tgstation.Server.Host.Models.User", "StartedBy") + .WithMany() + .HasForeignKey("StartedById") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.ReattachInformation", b => + { + b.HasOne("Tgstation.Server.Host.Models.CompileJob", "CompileJob") + .WithMany() + .HasForeignKey("CompileJobId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.RepositorySettings", b => + { + b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance") + .WithOne("RepositorySettings") + .HasForeignKey("Tgstation.Server.Host.Models.RepositorySettings", "InstanceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.RevInfoTestMerge", b => + { + b.HasOne("Tgstation.Server.Host.Models.RevisionInformation", "RevisionInformation") + .WithMany("ActiveTestMerges") + .HasForeignKey("RevisionInformationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tgstation.Server.Host.Models.TestMerge", "TestMerge") + .WithMany("RevisonInformations") + .HasForeignKey("TestMergeId") + .OnDelete(DeleteBehavior.ClientNoAction) + .IsRequired(); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.RevisionInformation", b => + { + b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance") + .WithMany("RevisionInformations") + .HasForeignKey("InstanceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.TestMerge", b => + { + b.HasOne("Tgstation.Server.Host.Models.User", "MergedBy") + .WithMany("TestMerges") + .HasForeignKey("MergedById") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("Tgstation.Server.Host.Models.RevisionInformation", "PrimaryRevisionInformation") + .WithOne("PrimaryTestMerge") + .HasForeignKey("Tgstation.Server.Host.Models.TestMerge", "PrimaryRevisionInformationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.User", b => + { + b.HasOne("Tgstation.Server.Host.Models.User", "CreatedBy") + .WithMany("CreatedUsers") + .HasForeignKey("CreatedById"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Tgstation.Server.Host/Database/Migrations/20200807213742_MYAddDeploymentColumns.cs b/src/Tgstation.Server.Host/Database/Migrations/20200807213742_MYAddDeploymentColumns.cs new file mode 100644 index 0000000000..7ec6918437 --- /dev/null +++ b/src/Tgstation.Server.Host/Database/Migrations/20200807213742_MYAddDeploymentColumns.cs @@ -0,0 +1,53 @@ +using Microsoft.EntityFrameworkCore.Migrations; +using System; + +namespace Tgstation.Server.Host.Database.Migrations +{ + /// + /// Adds columns for GitHub deployments for MYSQL. + /// + public partial class MYAddDeploymentColumns : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + if (migrationBuilder == null) + throw new ArgumentNullException(nameof(migrationBuilder)); + + migrationBuilder.AddColumn( + name: "CreateGitHubDeployments", + table: "RepositorySettings", + nullable: false, + defaultValue: false); + + migrationBuilder.AddColumn( + name: "GitHubDeploymentId", + table: "CompileJobs", + nullable: true); + + migrationBuilder.AddColumn( + name: "GitHubRepoId", + table: "CompileJobs", + nullable: true); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + if (migrationBuilder == null) + throw new ArgumentNullException(nameof(migrationBuilder)); + + migrationBuilder.DropColumn( + name: "CreateGitHubDeployments", + table: "RepositorySettings"); + + migrationBuilder.DropColumn( + name: "GitHubDeploymentId", + table: "CompileJobs"); + + migrationBuilder.DropColumn( + name: "GitHubRepoId", + table: "CompileJobs"); + } + } +} diff --git a/src/Tgstation.Server.Host/Database/Migrations/20200807214330_PGAddDeploymentColumns.Designer.cs b/src/Tgstation.Server.Host/Database/Migrations/20200807214330_PGAddDeploymentColumns.Designer.cs new file mode 100644 index 0000000000..a5507e5327 --- /dev/null +++ b/src/Tgstation.Server.Host/Database/Migrations/20200807214330_PGAddDeploymentColumns.Designer.cs @@ -0,0 +1,778 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +namespace Tgstation.Server.Host.Database.Migrations +{ + [DbContext(typeof(PostgresSqlDatabaseContext))] + [Migration("20200807214330_PGAddDeploymentColumns")] + partial class PGAddDeploymentColumns + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn) + .HasAnnotation("ProductVersion", "3.1.6") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + modelBuilder.Entity("Tgstation.Server.Host.Models.ChatBot", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property("ChannelLimit") + .HasColumnType("integer"); + + b.Property("ConnectionString") + .IsRequired() + .HasColumnType("character varying(10000)") + .HasMaxLength(10000); + + b.Property("Enabled") + .HasColumnType("boolean"); + + b.Property("InstanceId") + .HasColumnType("bigint"); + + b.Property("Name") + .IsRequired() + .HasColumnType("character varying(100)") + .HasMaxLength(100); + + b.Property("Provider") + .HasColumnType("integer"); + + b.Property("ReconnectionInterval") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("InstanceId", "Name") + .IsUnique(); + + b.ToTable("ChatBots"); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.ChatChannel", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property("ChatSettingsId") + .HasColumnType("bigint"); + + b.Property("DiscordChannelId") + .HasColumnType("numeric(20,0)"); + + b.Property("IrcChannel") + .HasColumnType("character varying(100)") + .HasMaxLength(100); + + b.Property("IsAdminChannel") + .IsRequired() + .HasColumnType("boolean"); + + b.Property("IsUpdatesChannel") + .IsRequired() + .HasColumnType("boolean"); + + b.Property("IsWatchdogChannel") + .IsRequired() + .HasColumnType("boolean"); + + b.Property("Tag") + .HasColumnType("character varying(10000)") + .HasMaxLength(10000); + + b.HasKey("Id"); + + b.HasIndex("ChatSettingsId", "DiscordChannelId") + .IsUnique(); + + b.HasIndex("ChatSettingsId", "IrcChannel") + .IsUnique(); + + b.ToTable("ChatChannels"); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.CompileJob", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property("ByondVersion") + .IsRequired() + .HasColumnType("text"); + + b.Property("DMApiMajorVersion") + .HasColumnType("integer"); + + b.Property("DMApiMinorVersion") + .HasColumnType("integer"); + + b.Property("DMApiPatchVersion") + .HasColumnType("integer"); + + b.Property("DirectoryName") + .IsRequired() + .HasColumnType("uuid"); + + b.Property("DmeName") + .IsRequired() + .HasColumnType("text"); + + b.Property("GitHubDeploymentId") + .HasColumnType("integer"); + + b.Property("GitHubRepoId") + .HasColumnType("bigint"); + + b.Property("JobId") + .HasColumnType("bigint"); + + b.Property("MinimumSecurityLevel") + .HasColumnType("integer"); + + b.Property("Output") + .IsRequired() + .HasColumnType("text"); + + b.Property("RevisionInformationId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("DirectoryName"); + + b.HasIndex("JobId") + .IsUnique(); + + b.HasIndex("RevisionInformationId"); + + b.ToTable("CompileJobs"); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.DreamDaemonSettings", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property("AllowWebClient") + .IsRequired() + .HasColumnType("boolean"); + + b.Property("AutoStart") + .IsRequired() + .HasColumnType("boolean"); + + b.Property("HeartbeatSeconds") + .HasColumnType("bigint"); + + b.Property("InstanceId") + .HasColumnType("bigint"); + + b.Property("Port") + .HasColumnType("integer"); + + b.Property("SecurityLevel") + .HasColumnType("integer"); + + b.Property("StartupTimeout") + .HasColumnType("bigint"); + + b.Property("TopicRequestTimeout") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("InstanceId") + .IsUnique(); + + b.ToTable("DreamDaemonSettings"); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.DreamMakerSettings", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property("ApiValidationPort") + .HasColumnType("integer"); + + b.Property("ApiValidationSecurityLevel") + .HasColumnType("integer"); + + b.Property("InstanceId") + .HasColumnType("bigint"); + + b.Property("ProjectName") + .HasColumnType("character varying(10000)") + .HasMaxLength(10000); + + b.Property("RequireDMApiValidation") + .IsRequired() + .HasColumnType("boolean"); + + b.HasKey("Id"); + + b.HasIndex("InstanceId") + .IsUnique(); + + b.ToTable("DreamMakerSettings"); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.Instance", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property("AutoUpdateInterval") + .HasColumnType("bigint"); + + b.Property("ChatBotLimit") + .HasColumnType("integer"); + + b.Property("ConfigurationType") + .HasColumnType("integer"); + + b.Property("Name") + .IsRequired() + .HasColumnType("character varying(10000)") + .HasMaxLength(10000); + + b.Property("Online") + .IsRequired() + .HasColumnType("boolean"); + + b.Property("Path") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("Path") + .IsUnique(); + + b.ToTable("Instances"); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.InstanceUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property("ByondRights") + .HasColumnType("numeric(20,0)"); + + b.Property("ChatBotRights") + .HasColumnType("numeric(20,0)"); + + b.Property("ConfigurationRights") + .HasColumnType("numeric(20,0)"); + + b.Property("DreamDaemonRights") + .HasColumnType("numeric(20,0)"); + + b.Property("DreamMakerRights") + .HasColumnType("numeric(20,0)"); + + b.Property("InstanceId") + .HasColumnType("bigint"); + + b.Property("InstanceUserRights") + .HasColumnType("numeric(20,0)"); + + b.Property("RepositoryRights") + .HasColumnType("numeric(20,0)"); + + b.Property("UserId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("InstanceId"); + + b.HasIndex("UserId", "InstanceId") + .IsUnique(); + + b.ToTable("InstanceUsers"); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.Job", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property("CancelRight") + .HasColumnType("numeric(20,0)"); + + b.Property("CancelRightsType") + .HasColumnType("numeric(20,0)"); + + b.Property("Cancelled") + .IsRequired() + .HasColumnType("boolean"); + + b.Property("CancelledById") + .HasColumnType("bigint"); + + b.Property("Description") + .IsRequired() + .HasColumnType("text"); + + b.Property("ErrorCode") + .HasColumnType("bigint"); + + b.Property("ExceptionDetails") + .HasColumnType("text"); + + b.Property("InstanceId") + .HasColumnType("bigint"); + + b.Property("StartedAt") + .IsRequired() + .HasColumnType("timestamp with time zone"); + + b.Property("StartedById") + .HasColumnType("bigint"); + + b.Property("StoppedAt") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("CancelledById"); + + b.HasIndex("InstanceId"); + + b.HasIndex("StartedById"); + + b.ToTable("Jobs"); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.ReattachInformation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property("AccessIdentifier") + .IsRequired() + .HasColumnType("text"); + + b.Property("CompileJobId") + .HasColumnType("bigint"); + + b.Property("LaunchSecurityLevel") + .HasColumnType("integer"); + + b.Property("Port") + .HasColumnType("integer"); + + b.Property("ProcessId") + .HasColumnType("integer"); + + b.Property("RebootState") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("CompileJobId"); + + b.ToTable("ReattachInformations"); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.RepositorySettings", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property("AccessToken") + .HasColumnType("character varying(10000)") + .HasMaxLength(10000); + + b.Property("AccessUser") + .HasColumnType("character varying(10000)") + .HasMaxLength(10000); + + b.Property("AutoUpdatesKeepTestMerges") + .IsRequired() + .HasColumnType("boolean"); + + b.Property("AutoUpdatesSynchronize") + .IsRequired() + .HasColumnType("boolean"); + + b.Property("CommitterEmail") + .IsRequired() + .HasColumnType("character varying(10000)") + .HasMaxLength(10000); + + b.Property("CommitterName") + .IsRequired() + .HasColumnType("character varying(10000)") + .HasMaxLength(10000); + + b.Property("CreateGitHubDeployments") + .IsRequired() + .HasColumnType("boolean"); + + b.Property("InstanceId") + .HasColumnType("bigint"); + + b.Property("PostTestMergeComment") + .IsRequired() + .HasColumnType("boolean"); + + b.Property("PushTestMergeCommits") + .IsRequired() + .HasColumnType("boolean"); + + b.Property("ShowTestMergeCommitters") + .IsRequired() + .HasColumnType("boolean"); + + b.HasKey("Id"); + + b.HasIndex("InstanceId") + .IsUnique(); + + b.ToTable("RepositorySettings"); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.RevInfoTestMerge", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property("RevisionInformationId") + .HasColumnType("bigint"); + + b.Property("TestMergeId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("RevisionInformationId"); + + b.HasIndex("TestMergeId"); + + b.ToTable("RevInfoTestMerges"); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.RevisionInformation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property("CommitSha") + .IsRequired() + .HasColumnType("character varying(40)") + .HasMaxLength(40); + + b.Property("InstanceId") + .HasColumnType("bigint"); + + b.Property("OriginCommitSha") + .IsRequired() + .HasColumnType("character varying(40)") + .HasMaxLength(40); + + b.HasKey("Id"); + + b.HasIndex("InstanceId", "CommitSha") + .IsUnique(); + + b.ToTable("RevisionInformations"); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.TestMerge", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property("Author") + .IsRequired() + .HasColumnType("text"); + + b.Property("BodyAtMerge") + .IsRequired() + .HasColumnType("text"); + + b.Property("Comment") + .HasColumnType("character varying(10000)") + .HasMaxLength(10000); + + b.Property("MergedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("MergedById") + .HasColumnType("bigint"); + + b.Property("Number") + .HasColumnType("integer"); + + b.Property("PrimaryRevisionInformationId") + .IsRequired() + .HasColumnType("bigint"); + + b.Property("PullRequestRevision") + .IsRequired() + .HasColumnType("character varying(40)") + .HasMaxLength(40); + + b.Property("TitleAtMerge") + .IsRequired() + .HasColumnType("text"); + + b.Property("Url") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("MergedById"); + + b.HasIndex("PrimaryRevisionInformationId") + .IsUnique(); + + b.ToTable("TestMerges"); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property("AdministrationRights") + .HasColumnType("numeric(20,0)"); + + b.Property("CanonicalName") + .IsRequired() + .HasColumnType("text"); + + b.Property("CreatedAt") + .IsRequired() + .HasColumnType("timestamp with time zone"); + + b.Property("CreatedById") + .HasColumnType("bigint"); + + b.Property("Enabled") + .IsRequired() + .HasColumnType("boolean"); + + b.Property("InstanceManagerRights") + .HasColumnType("numeric(20,0)"); + + b.Property("LastPasswordUpdate") + .HasColumnType("timestamp with time zone"); + + b.Property("Name") + .IsRequired() + .HasColumnType("character varying(10000)") + .HasMaxLength(10000); + + b.Property("PasswordHash") + .HasColumnType("text"); + + b.Property("SystemIdentifier") + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("CanonicalName") + .IsUnique(); + + b.HasIndex("CreatedById"); + + b.HasIndex("SystemIdentifier") + .IsUnique(); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.ChatBot", b => + { + b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance") + .WithMany("ChatSettings") + .HasForeignKey("InstanceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.ChatChannel", b => + { + b.HasOne("Tgstation.Server.Host.Models.ChatBot", "ChatSettings") + .WithMany("Channels") + .HasForeignKey("ChatSettingsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.CompileJob", b => + { + b.HasOne("Tgstation.Server.Host.Models.Job", "Job") + .WithOne() + .HasForeignKey("Tgstation.Server.Host.Models.CompileJob", "JobId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tgstation.Server.Host.Models.RevisionInformation", "RevisionInformation") + .WithMany("CompileJobs") + .HasForeignKey("RevisionInformationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.DreamDaemonSettings", b => + { + b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance") + .WithOne("DreamDaemonSettings") + .HasForeignKey("Tgstation.Server.Host.Models.DreamDaemonSettings", "InstanceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.DreamMakerSettings", b => + { + b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance") + .WithOne("DreamMakerSettings") + .HasForeignKey("Tgstation.Server.Host.Models.DreamMakerSettings", "InstanceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.InstanceUser", b => + { + b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance") + .WithMany("InstanceUsers") + .HasForeignKey("InstanceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tgstation.Server.Host.Models.User", null) + .WithMany("InstanceUsers") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.Job", b => + { + b.HasOne("Tgstation.Server.Host.Models.User", "CancelledBy") + .WithMany() + .HasForeignKey("CancelledById"); + + b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance") + .WithMany("Jobs") + .HasForeignKey("InstanceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tgstation.Server.Host.Models.User", "StartedBy") + .WithMany() + .HasForeignKey("StartedById") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.ReattachInformation", b => + { + b.HasOne("Tgstation.Server.Host.Models.CompileJob", "CompileJob") + .WithMany() + .HasForeignKey("CompileJobId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.RepositorySettings", b => + { + b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance") + .WithOne("RepositorySettings") + .HasForeignKey("Tgstation.Server.Host.Models.RepositorySettings", "InstanceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.RevInfoTestMerge", b => + { + b.HasOne("Tgstation.Server.Host.Models.RevisionInformation", "RevisionInformation") + .WithMany("ActiveTestMerges") + .HasForeignKey("RevisionInformationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tgstation.Server.Host.Models.TestMerge", "TestMerge") + .WithMany("RevisonInformations") + .HasForeignKey("TestMergeId") + .OnDelete(DeleteBehavior.ClientNoAction) + .IsRequired(); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.RevisionInformation", b => + { + b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance") + .WithMany("RevisionInformations") + .HasForeignKey("InstanceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.TestMerge", b => + { + b.HasOne("Tgstation.Server.Host.Models.User", "MergedBy") + .WithMany("TestMerges") + .HasForeignKey("MergedById") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("Tgstation.Server.Host.Models.RevisionInformation", "PrimaryRevisionInformation") + .WithOne("PrimaryTestMerge") + .HasForeignKey("Tgstation.Server.Host.Models.TestMerge", "PrimaryRevisionInformationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.User", b => + { + b.HasOne("Tgstation.Server.Host.Models.User", "CreatedBy") + .WithMany("CreatedUsers") + .HasForeignKey("CreatedById"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Tgstation.Server.Host/Database/Migrations/20200807214330_PGAddDeploymentColumns.cs b/src/Tgstation.Server.Host/Database/Migrations/20200807214330_PGAddDeploymentColumns.cs new file mode 100644 index 0000000000..41537d05de --- /dev/null +++ b/src/Tgstation.Server.Host/Database/Migrations/20200807214330_PGAddDeploymentColumns.cs @@ -0,0 +1,53 @@ +using Microsoft.EntityFrameworkCore.Migrations; +using System; + +namespace Tgstation.Server.Host.Database.Migrations +{ + /// + /// Adds columns for GitHub deployments for PostgresSQL. + /// + public partial class PGAddDeploymentColumns : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + if (migrationBuilder == null) + throw new ArgumentNullException(nameof(migrationBuilder)); + + migrationBuilder.AddColumn( + name: "CreateGitHubDeployments", + table: "RepositorySettings", + nullable: false, + defaultValue: false); + + migrationBuilder.AddColumn( + name: "GitHubDeploymentId", + table: "CompileJobs", + nullable: true); + + migrationBuilder.AddColumn( + name: "GitHubRepoId", + table: "CompileJobs", + nullable: true); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + if (migrationBuilder == null) + throw new ArgumentNullException(nameof(migrationBuilder)); + + migrationBuilder.DropColumn( + name: "CreateGitHubDeployments", + table: "RepositorySettings"); + + migrationBuilder.DropColumn( + name: "GitHubDeploymentId", + table: "CompileJobs"); + + migrationBuilder.DropColumn( + name: "GitHubRepoId", + table: "CompileJobs"); + } + } +} diff --git a/src/Tgstation.Server.Host/Database/Migrations/20200807214754_SLAddDeploymentColumns.Designer.cs b/src/Tgstation.Server.Host/Database/Migrations/20200807214754_SLAddDeploymentColumns.Designer.cs new file mode 100644 index 0000000000..ead8889ff2 --- /dev/null +++ b/src/Tgstation.Server.Host/Database/Migrations/20200807214754_SLAddDeploymentColumns.Designer.cs @@ -0,0 +1,770 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Tgstation.Server.Host.Database.Migrations +{ + [DbContext(typeof(SqliteDatabaseContext))] + [Migration("20200807214754_SLAddDeploymentColumns")] + partial class SLAddDeploymentColumns + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "3.1.6"); + + modelBuilder.Entity("Tgstation.Server.Host.Models.ChatBot", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ChannelLimit") + .IsRequired() + .HasColumnType("INTEGER"); + + b.Property("ConnectionString") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(10000); + + b.Property("Enabled") + .HasColumnType("INTEGER"); + + b.Property("InstanceId") + .HasColumnType("INTEGER"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b.Property("Provider") + .HasColumnType("INTEGER"); + + b.Property("ReconnectionInterval") + .IsRequired() + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("InstanceId", "Name") + .IsUnique(); + + b.ToTable("ChatBots"); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.ChatChannel", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ChatSettingsId") + .HasColumnType("INTEGER"); + + b.Property("DiscordChannelId") + .HasColumnType("INTEGER"); + + b.Property("IrcChannel") + .HasColumnType("TEXT") + .HasMaxLength(100); + + b.Property("IsAdminChannel") + .IsRequired() + .HasColumnType("INTEGER"); + + b.Property("IsUpdatesChannel") + .IsRequired() + .HasColumnType("INTEGER"); + + b.Property("IsWatchdogChannel") + .IsRequired() + .HasColumnType("INTEGER"); + + b.Property("Tag") + .HasColumnType("TEXT") + .HasMaxLength(10000); + + b.HasKey("Id"); + + b.HasIndex("ChatSettingsId", "DiscordChannelId") + .IsUnique(); + + b.HasIndex("ChatSettingsId", "IrcChannel") + .IsUnique(); + + b.ToTable("ChatChannels"); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.CompileJob", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ByondVersion") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("DMApiMajorVersion") + .HasColumnType("INTEGER"); + + b.Property("DMApiMinorVersion") + .HasColumnType("INTEGER"); + + b.Property("DMApiPatchVersion") + .HasColumnType("INTEGER"); + + b.Property("DirectoryName") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("DmeName") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("GitHubDeploymentId") + .HasColumnType("INTEGER"); + + b.Property("GitHubRepoId") + .HasColumnType("INTEGER"); + + b.Property("JobId") + .HasColumnType("INTEGER"); + + b.Property("MinimumSecurityLevel") + .HasColumnType("INTEGER"); + + b.Property("Output") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("RevisionInformationId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("DirectoryName"); + + b.HasIndex("JobId") + .IsUnique(); + + b.HasIndex("RevisionInformationId"); + + b.ToTable("CompileJobs"); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.DreamDaemonSettings", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AllowWebClient") + .IsRequired() + .HasColumnType("INTEGER"); + + b.Property("AutoStart") + .IsRequired() + .HasColumnType("INTEGER"); + + b.Property("HeartbeatSeconds") + .IsRequired() + .HasColumnType("INTEGER"); + + b.Property("InstanceId") + .HasColumnType("INTEGER"); + + b.Property("Port") + .IsRequired() + .HasColumnType("INTEGER"); + + b.Property("SecurityLevel") + .HasColumnType("INTEGER"); + + b.Property("StartupTimeout") + .IsRequired() + .HasColumnType("INTEGER"); + + b.Property("TopicRequestTimeout") + .IsRequired() + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("InstanceId") + .IsUnique(); + + b.ToTable("DreamDaemonSettings"); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.DreamMakerSettings", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ApiValidationPort") + .IsRequired() + .HasColumnType("INTEGER"); + + b.Property("ApiValidationSecurityLevel") + .HasColumnType("INTEGER"); + + b.Property("InstanceId") + .HasColumnType("INTEGER"); + + b.Property("ProjectName") + .HasColumnType("TEXT") + .HasMaxLength(10000); + + b.Property("RequireDMApiValidation") + .IsRequired() + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("InstanceId") + .IsUnique(); + + b.ToTable("DreamMakerSettings"); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.Instance", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AutoUpdateInterval") + .IsRequired() + .HasColumnType("INTEGER"); + + b.Property("ChatBotLimit") + .IsRequired() + .HasColumnType("INTEGER"); + + b.Property("ConfigurationType") + .HasColumnType("INTEGER"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(10000); + + b.Property("Online") + .IsRequired() + .HasColumnType("INTEGER"); + + b.Property("Path") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("Path") + .IsUnique(); + + b.ToTable("Instances"); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.InstanceUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ByondRights") + .HasColumnType("INTEGER"); + + b.Property("ChatBotRights") + .HasColumnType("INTEGER"); + + b.Property("ConfigurationRights") + .HasColumnType("INTEGER"); + + b.Property("DreamDaemonRights") + .HasColumnType("INTEGER"); + + b.Property("DreamMakerRights") + .HasColumnType("INTEGER"); + + b.Property("InstanceId") + .HasColumnType("INTEGER"); + + b.Property("InstanceUserRights") + .HasColumnType("INTEGER"); + + b.Property("RepositoryRights") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("InstanceId"); + + b.HasIndex("UserId", "InstanceId") + .IsUnique(); + + b.ToTable("InstanceUsers"); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.Job", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CancelRight") + .HasColumnType("INTEGER"); + + b.Property("CancelRightsType") + .HasColumnType("INTEGER"); + + b.Property("Cancelled") + .IsRequired() + .HasColumnType("INTEGER"); + + b.Property("CancelledById") + .HasColumnType("INTEGER"); + + b.Property("Description") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("ErrorCode") + .HasColumnType("INTEGER"); + + b.Property("ExceptionDetails") + .HasColumnType("TEXT"); + + b.Property("InstanceId") + .HasColumnType("INTEGER"); + + b.Property("StartedAt") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("StartedById") + .HasColumnType("INTEGER"); + + b.Property("StoppedAt") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("CancelledById"); + + b.HasIndex("InstanceId"); + + b.HasIndex("StartedById"); + + b.ToTable("Jobs"); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.ReattachInformation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AccessIdentifier") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("CompileJobId") + .HasColumnType("INTEGER"); + + b.Property("LaunchSecurityLevel") + .HasColumnType("INTEGER"); + + b.Property("Port") + .HasColumnType("INTEGER"); + + b.Property("ProcessId") + .HasColumnType("INTEGER"); + + b.Property("RebootState") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("CompileJobId"); + + b.ToTable("ReattachInformations"); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.RepositorySettings", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AccessToken") + .HasColumnType("TEXT") + .HasMaxLength(10000); + + b.Property("AccessUser") + .HasColumnType("TEXT") + .HasMaxLength(10000); + + b.Property("AutoUpdatesKeepTestMerges") + .IsRequired() + .HasColumnType("INTEGER"); + + b.Property("AutoUpdatesSynchronize") + .IsRequired() + .HasColumnType("INTEGER"); + + b.Property("CommitterEmail") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(10000); + + b.Property("CommitterName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(10000); + + b.Property("CreateGitHubDeployments") + .IsRequired() + .HasColumnType("INTEGER"); + + b.Property("InstanceId") + .HasColumnType("INTEGER"); + + b.Property("PostTestMergeComment") + .IsRequired() + .HasColumnType("INTEGER"); + + b.Property("PushTestMergeCommits") + .IsRequired() + .HasColumnType("INTEGER"); + + b.Property("ShowTestMergeCommitters") + .IsRequired() + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("InstanceId") + .IsUnique(); + + b.ToTable("RepositorySettings"); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.RevInfoTestMerge", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("RevisionInformationId") + .HasColumnType("INTEGER"); + + b.Property("TestMergeId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("RevisionInformationId"); + + b.HasIndex("TestMergeId"); + + b.ToTable("RevInfoTestMerges"); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.RevisionInformation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CommitSha") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(40); + + b.Property("InstanceId") + .HasColumnType("INTEGER"); + + b.Property("OriginCommitSha") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(40); + + b.HasKey("Id"); + + b.HasIndex("InstanceId", "CommitSha") + .IsUnique(); + + b.ToTable("RevisionInformations"); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.TestMerge", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Author") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("BodyAtMerge") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Comment") + .HasColumnType("TEXT") + .HasMaxLength(10000); + + b.Property("MergedAt") + .HasColumnType("TEXT"); + + b.Property("MergedById") + .HasColumnType("INTEGER"); + + b.Property("Number") + .HasColumnType("INTEGER"); + + b.Property("PrimaryRevisionInformationId") + .IsRequired() + .HasColumnType("INTEGER"); + + b.Property("PullRequestRevision") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(40); + + b.Property("TitleAtMerge") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Url") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("MergedById"); + + b.HasIndex("PrimaryRevisionInformationId") + .IsUnique(); + + b.ToTable("TestMerges"); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AdministrationRights") + .HasColumnType("INTEGER"); + + b.Property("CanonicalName") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("CreatedAt") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("CreatedById") + .HasColumnType("INTEGER"); + + b.Property("Enabled") + .IsRequired() + .HasColumnType("INTEGER"); + + b.Property("InstanceManagerRights") + .HasColumnType("INTEGER"); + + b.Property("LastPasswordUpdate") + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(10000); + + b.Property("PasswordHash") + .HasColumnType("TEXT"); + + b.Property("SystemIdentifier") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("CanonicalName") + .IsUnique(); + + b.HasIndex("CreatedById"); + + b.HasIndex("SystemIdentifier") + .IsUnique(); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.ChatBot", b => + { + b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance") + .WithMany("ChatSettings") + .HasForeignKey("InstanceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.ChatChannel", b => + { + b.HasOne("Tgstation.Server.Host.Models.ChatBot", "ChatSettings") + .WithMany("Channels") + .HasForeignKey("ChatSettingsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.CompileJob", b => + { + b.HasOne("Tgstation.Server.Host.Models.Job", "Job") + .WithOne() + .HasForeignKey("Tgstation.Server.Host.Models.CompileJob", "JobId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tgstation.Server.Host.Models.RevisionInformation", "RevisionInformation") + .WithMany("CompileJobs") + .HasForeignKey("RevisionInformationId") + .OnDelete(DeleteBehavior.ClientNoAction) + .IsRequired(); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.DreamDaemonSettings", b => + { + b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance") + .WithOne("DreamDaemonSettings") + .HasForeignKey("Tgstation.Server.Host.Models.DreamDaemonSettings", "InstanceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.DreamMakerSettings", b => + { + b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance") + .WithOne("DreamMakerSettings") + .HasForeignKey("Tgstation.Server.Host.Models.DreamMakerSettings", "InstanceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.InstanceUser", b => + { + b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance") + .WithMany("InstanceUsers") + .HasForeignKey("InstanceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tgstation.Server.Host.Models.User", null) + .WithMany("InstanceUsers") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.Job", b => + { + b.HasOne("Tgstation.Server.Host.Models.User", "CancelledBy") + .WithMany() + .HasForeignKey("CancelledById"); + + b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance") + .WithMany("Jobs") + .HasForeignKey("InstanceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tgstation.Server.Host.Models.User", "StartedBy") + .WithMany() + .HasForeignKey("StartedById") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.ReattachInformation", b => + { + b.HasOne("Tgstation.Server.Host.Models.CompileJob", "CompileJob") + .WithMany() + .HasForeignKey("CompileJobId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.RepositorySettings", b => + { + b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance") + .WithOne("RepositorySettings") + .HasForeignKey("Tgstation.Server.Host.Models.RepositorySettings", "InstanceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.RevInfoTestMerge", b => + { + b.HasOne("Tgstation.Server.Host.Models.RevisionInformation", "RevisionInformation") + .WithMany("ActiveTestMerges") + .HasForeignKey("RevisionInformationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tgstation.Server.Host.Models.TestMerge", "TestMerge") + .WithMany("RevisonInformations") + .HasForeignKey("TestMergeId") + .OnDelete(DeleteBehavior.ClientNoAction) + .IsRequired(); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.RevisionInformation", b => + { + b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance") + .WithMany("RevisionInformations") + .HasForeignKey("InstanceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.TestMerge", b => + { + b.HasOne("Tgstation.Server.Host.Models.User", "MergedBy") + .WithMany("TestMerges") + .HasForeignKey("MergedById") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("Tgstation.Server.Host.Models.RevisionInformation", "PrimaryRevisionInformation") + .WithOne("PrimaryTestMerge") + .HasForeignKey("Tgstation.Server.Host.Models.TestMerge", "PrimaryRevisionInformationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.User", b => + { + b.HasOne("Tgstation.Server.Host.Models.User", "CreatedBy") + .WithMany("CreatedUsers") + .HasForeignKey("CreatedById"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Tgstation.Server.Host/Database/Migrations/20200807214754_SLAddDeploymentColumns.cs b/src/Tgstation.Server.Host/Database/Migrations/20200807214754_SLAddDeploymentColumns.cs new file mode 100644 index 0000000000..ea3e46b463 --- /dev/null +++ b/src/Tgstation.Server.Host/Database/Migrations/20200807214754_SLAddDeploymentColumns.cs @@ -0,0 +1,53 @@ +using Microsoft.EntityFrameworkCore.Migrations; +using System; + +namespace Tgstation.Server.Host.Database.Migrations +{ + /// + /// Adds columns for GitHub deployments for SQLite. + /// + public partial class SLAddDeploymentColumns : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + if (migrationBuilder == null) + throw new ArgumentNullException(nameof(migrationBuilder)); + + migrationBuilder.AddColumn( + name: "CreateGitHubDeployments", + table: "RepositorySettings", + nullable: false, + defaultValue: false); + + migrationBuilder.AddColumn( + name: "GitHubDeploymentId", + table: "CompileJobs", + nullable: true); + + migrationBuilder.AddColumn( + name: "GitHubRepoId", + table: "CompileJobs", + nullable: true); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + if (migrationBuilder == null) + throw new ArgumentNullException(nameof(migrationBuilder)); + + migrationBuilder.DropColumn( + name: "CreateGitHubDeployments", + table: "RepositorySettings"); + + migrationBuilder.DropColumn( + name: "GitHubDeploymentId", + table: "CompileJobs"); + + migrationBuilder.DropColumn( + name: "GitHubRepoId", + table: "CompileJobs"); + } + } +} diff --git a/src/Tgstation.Server.Host/Database/Migrations/MySqlDatabaseContextModelSnapshot.cs b/src/Tgstation.Server.Host/Database/Migrations/MySqlDatabaseContextModelSnapshot.cs index 09c546636e..0ff5150d47 100644 --- a/src/Tgstation.Server.Host/Database/Migrations/MySqlDatabaseContextModelSnapshot.cs +++ b/src/Tgstation.Server.Host/Database/Migrations/MySqlDatabaseContextModelSnapshot.cs @@ -1,11 +1,10 @@ -// +// using System; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; namespace Tgstation.Server.Host.Database.Migrations { - /// [DbContext(typeof(MySqlDatabaseContext))] partial class MySqlDatabaseContextModelSnapshot : ModelSnapshot { @@ -13,7 +12,7 @@ namespace Tgstation.Server.Host.Database.Migrations { #pragma warning disable 612, 618 modelBuilder - .HasAnnotation("ProductVersion", "3.1.5") + .HasAnnotation("ProductVersion", "3.1.6") .HasAnnotation("Relational:MaxIdentifierLength", 64); modelBuilder.Entity("Tgstation.Server.Host.Models.ChatBot", b => @@ -127,6 +126,12 @@ namespace Tgstation.Server.Host.Database.Migrations .IsRequired() .HasColumnType("longtext CHARACTER SET utf8mb4"); + b.Property("GitHubDeploymentId") + .HasColumnType("int"); + + b.Property("GitHubRepoId") + .HasColumnType("bigint"); + b.Property("JobId") .HasColumnType("bigint"); @@ -296,8 +301,7 @@ namespace Tgstation.Server.Host.Database.Migrations b.Property("RepositoryRights") .HasColumnType("bigint unsigned"); - b.Property("UserId") - .IsRequired() + b.Property("UserId") .HasColumnType("bigint"); b.HasKey("Id"); @@ -427,6 +431,10 @@ namespace Tgstation.Server.Host.Database.Migrations .HasColumnType("longtext CHARACTER SET utf8mb4") .HasMaxLength(10000); + b.Property("CreateGitHubDeployments") + .IsRequired() + .HasColumnType("tinyint(1)"); + b.Property("InstanceId") .HasColumnType("bigint"); diff --git a/src/Tgstation.Server.Host/Database/Migrations/PostgresSqlDatabaseContextModelSnapshot.cs b/src/Tgstation.Server.Host/Database/Migrations/PostgresSqlDatabaseContextModelSnapshot.cs index 624f956cd1..bfd8abc08b 100644 --- a/src/Tgstation.Server.Host/Database/Migrations/PostgresSqlDatabaseContextModelSnapshot.cs +++ b/src/Tgstation.Server.Host/Database/Migrations/PostgresSqlDatabaseContextModelSnapshot.cs @@ -1,4 +1,4 @@ -// +// using System; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; @@ -9,13 +9,12 @@ namespace Tgstation.Server.Host.Database.Migrations [DbContext(typeof(PostgresSqlDatabaseContext))] partial class PostgresSqlDatabaseContextModelSnapshot : ModelSnapshot { - /// protected override void BuildModel(ModelBuilder modelBuilder) { #pragma warning disable 612, 618 modelBuilder .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn) - .HasAnnotation("ProductVersion", "3.1.5") + .HasAnnotation("ProductVersion", "3.1.6") .HasAnnotation("Relational:MaxIdentifierLength", 63); modelBuilder.Entity("Tgstation.Server.Host.Models.ChatBot", b => @@ -130,6 +129,12 @@ namespace Tgstation.Server.Host.Database.Migrations .IsRequired() .HasColumnType("text"); + b.Property("GitHubDeploymentId") + .HasColumnType("integer"); + + b.Property("GitHubRepoId") + .HasColumnType("bigint"); + b.Property("JobId") .HasColumnType("bigint"); @@ -296,8 +301,7 @@ namespace Tgstation.Server.Host.Database.Migrations b.Property("RepositoryRights") .HasColumnType("numeric(20,0)"); - b.Property("UserId") - .IsRequired() + b.Property("UserId") .HasColumnType("bigint"); b.HasKey("Id"); @@ -430,6 +434,10 @@ namespace Tgstation.Server.Host.Database.Migrations .HasColumnType("character varying(10000)") .HasMaxLength(10000); + b.Property("CreateGitHubDeployments") + .IsRequired() + .HasColumnType("boolean"); + b.Property("InstanceId") .HasColumnType("bigint"); diff --git a/src/Tgstation.Server.Host/Database/Migrations/SqlServerDatabaseContextModelSnapshot.cs b/src/Tgstation.Server.Host/Database/Migrations/SqlServerDatabaseContextModelSnapshot.cs index 9febdf5e05..4643243749 100644 --- a/src/Tgstation.Server.Host/Database/Migrations/SqlServerDatabaseContextModelSnapshot.cs +++ b/src/Tgstation.Server.Host/Database/Migrations/SqlServerDatabaseContextModelSnapshot.cs @@ -1,4 +1,4 @@ -// +// using System; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; @@ -14,7 +14,7 @@ namespace Tgstation.Server.Host.Database.Migrations { #pragma warning disable 612, 618 modelBuilder - .HasAnnotation("ProductVersion", "3.1.5") + .HasAnnotation("ProductVersion", "3.1.6") .HasAnnotation("Relational:MaxIdentifierLength", 128) .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); @@ -132,6 +132,12 @@ namespace Tgstation.Server.Host.Database.Migrations .IsRequired() .HasColumnType("nvarchar(max)"); + b.Property("GitHubDeploymentId") + .HasColumnType("int"); + + b.Property("GitHubRepoId") + .HasColumnType("bigint"); + b.Property("JobId") .HasColumnType("bigint"); @@ -298,8 +304,7 @@ namespace Tgstation.Server.Host.Database.Migrations b.Property("RepositoryRights") .HasColumnType("decimal(20,0)"); - b.Property("UserId") - .IsRequired() + b.Property("UserId") .HasColumnType("bigint"); b.HasKey("Id"); @@ -432,6 +437,10 @@ namespace Tgstation.Server.Host.Database.Migrations .HasColumnType("nvarchar(max)") .HasMaxLength(10000); + b.Property("CreateGitHubDeployments") + .IsRequired() + .HasColumnType("bit"); + b.Property("InstanceId") .HasColumnType("bigint"); diff --git a/src/Tgstation.Server.Host/Database/Migrations/SqliteDatabaseContextModelSnapshot.cs b/src/Tgstation.Server.Host/Database/Migrations/SqliteDatabaseContextModelSnapshot.cs index 3f322ac6eb..dd06a65bdc 100644 --- a/src/Tgstation.Server.Host/Database/Migrations/SqliteDatabaseContextModelSnapshot.cs +++ b/src/Tgstation.Server.Host/Database/Migrations/SqliteDatabaseContextModelSnapshot.cs @@ -1,4 +1,4 @@ -// +// using System; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; @@ -13,7 +13,7 @@ namespace Tgstation.Server.Host.Database.Migrations { #pragma warning disable 612, 618 modelBuilder - .HasAnnotation("ProductVersion", "3.1.5"); + .HasAnnotation("ProductVersion", "3.1.6"); modelBuilder.Entity("Tgstation.Server.Host.Models.ChatBot", b => { @@ -126,6 +126,12 @@ namespace Tgstation.Server.Host.Database.Migrations .IsRequired() .HasColumnType("TEXT"); + b.Property("GitHubDeploymentId") + .HasColumnType("INTEGER"); + + b.Property("GitHubRepoId") + .HasColumnType("INTEGER"); + b.Property("JobId") .HasColumnType("INTEGER"); @@ -295,8 +301,7 @@ namespace Tgstation.Server.Host.Database.Migrations b.Property("RepositoryRights") .HasColumnType("INTEGER"); - b.Property("UserId") - .IsRequired() + b.Property("UserId") .HasColumnType("INTEGER"); b.HasKey("Id"); @@ -426,6 +431,10 @@ namespace Tgstation.Server.Host.Database.Migrations .HasColumnType("TEXT") .HasMaxLength(10000); + b.Property("CreateGitHubDeployments") + .IsRequired() + .HasColumnType("INTEGER"); + b.Property("InstanceId") .HasColumnType("INTEGER"); diff --git a/src/Tgstation.Server.Host/Models/CompileJob.cs b/src/Tgstation.Server.Host/Models/CompileJob.cs index 676eaae590..c74291520d 100644 --- a/src/Tgstation.Server.Host/Models/CompileJob.cs +++ b/src/Tgstation.Server.Host/Models/CompileJob.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.ComponentModel.DataAnnotations; namespace Tgstation.Server.Host.Models @@ -44,6 +44,16 @@ namespace Tgstation.Server.Host.Models /// public int? DMApiPatchVersion { get; set; } + /// + /// The source GitHub repository the deployment came from if any. + /// + public long? GitHubRepoId { get; set; } + + /// + /// The GitHub deployment ID associated with the if any. + /// + public int? GitHubDeploymentId { get; set; } + /// public override Version DMApiVersion { diff --git a/tgstation-server.sln b/tgstation-server.sln index aff47c7971..a42b049c29 100644 --- a/tgstation-server.sln +++ b/tgstation-server.sln @@ -28,12 +28,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{6FF654E6 build\BuildDox.ps1 = build\BuildDox.ps1 build\Dockerfile = build\Dockerfile build\GenerateMigrations.sh = build\GenerateMigrations.sh - build\install_byond.sh = build\install_byond.sh - build\InstallCodeCoverage.ps1 = build\InstallCodeCoverage.ps1 build\OpenApiValidationSettings.json = build\OpenApiValidationSettings.json - build\prep_deployment.ps1 = build\prep_deployment.ps1 build\stylecop.json = build\stylecop.json - build\test_core.sh = build\test_core.sh build\tgs.docker.sh = build\tgs.docker.sh build\tgs.ico = build\tgs.ico build\tgs.png = build\tgs.png From cd9a4c3035ed8a03322d666853d355943a95cc4a Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Thu, 13 Aug 2020 13:44:42 -0400 Subject: [PATCH 3/3] Fix SQLite down migration --- .../20200807214754_SLAddDeploymentColumns.cs | 87 +++++++++++++++++-- 1 file changed, 78 insertions(+), 9 deletions(-) diff --git a/src/Tgstation.Server.Host/Database/Migrations/20200807214754_SLAddDeploymentColumns.cs b/src/Tgstation.Server.Host/Database/Migrations/20200807214754_SLAddDeploymentColumns.cs index ea3e46b463..0635951093 100644 --- a/src/Tgstation.Server.Host/Database/Migrations/20200807214754_SLAddDeploymentColumns.cs +++ b/src/Tgstation.Server.Host/Database/Migrations/20200807214754_SLAddDeploymentColumns.cs @@ -37,17 +37,86 @@ namespace Tgstation.Server.Host.Database.Migrations if (migrationBuilder == null) throw new ArgumentNullException(nameof(migrationBuilder)); - migrationBuilder.DropColumn( - name: "CreateGitHubDeployments", - table: "RepositorySettings"); + migrationBuilder.RenameTable( + name: "RepositorySettings", + newName: "RepositorySettings_down"); - migrationBuilder.DropColumn( - name: "GitHubDeploymentId", - table: "CompileJobs"); + migrationBuilder.CreateTable( + name: "RepositorySettings", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + CommitterName = table.Column(maxLength: 10000, nullable: false), + CommitterEmail = table.Column(maxLength: 10000, nullable: false), + AccessUser = table.Column(maxLength: 10000, nullable: true), + AccessToken = table.Column(maxLength: 10000, nullable: true), + PushTestMergeCommits = table.Column(nullable: false), + ShowTestMergeCommitters = table.Column(nullable: false), + AutoUpdatesKeepTestMerges = table.Column(nullable: false), + AutoUpdatesSynchronize = table.Column(nullable: false), + PostTestMergeComment = table.Column(nullable: false), + InstanceId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_RepositorySettings", x => x.Id); + table.ForeignKey( + name: "FK_RepositorySettings_Instances_InstanceId", + column: x => x.InstanceId, + principalTable: "Instances", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); - migrationBuilder.DropColumn( - name: "GitHubRepoId", - table: "CompileJobs"); + migrationBuilder.Sql( + $"INSERT INTO RepositorySettings SELECT Id,CommitterName,CommitterEmail,AccessUser,AccessToken,PushTestMergeCommits,ShowTestMergeCommitters,AutoUpdatesKeepTestMerges,AutoUpdatesSynchronize,PostTestMergeComment,InstanceId FROM RepositorySettings_down"); + + migrationBuilder.DropTable( + name: "RepositorySettings_down"); + + migrationBuilder.RenameTable( + name: "CompileJobs", + newName: "CompileJobs_down"); + + migrationBuilder.CreateTable( + name: "CompileJobs", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + DmeName = table.Column(nullable: false), + Output = table.Column(nullable: false), + DirectoryName = table.Column(nullable: false), + MinimumSecurityLevel = table.Column(nullable: true), + JobId = table.Column(nullable: false), + RevisionInformationId = table.Column(nullable: false), + ByondVersion = table.Column(nullable: false), + DMApiMajorVersion = table.Column(nullable: true), + DMApiMinorVersion = table.Column(nullable: true), + DMApiPatchVersion = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_CompileJobs", x => x.Id); + table.ForeignKey( + name: "FK_CompileJobs_Jobs_JobId", + column: x => x.JobId, + principalTable: "Jobs", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_CompileJobs_RevisionInformations_RevisionInformationId", + column: x => x.RevisionInformationId, + principalTable: "RevisionInformations", + principalColumn: "Id"); + }); + + migrationBuilder.Sql( + $"INSERT INTO CompileJobs SELECT Id,DmeName,Output,DirectoryName,MinimumSecurityLevel,JobId,RevisionInformationId,ByondVersion,DMApiMajorVersion,DMApiMinorVersion,DMApiPatchVersion FROM CompileJobs_down"); + + migrationBuilder.DropTable( + name: "CompileJobs_down"); } } }