2using System.Collections.Generic;
6using System.Threading.Tasks;
8using Microsoft.EntityFrameworkCore;
9using Microsoft.Extensions.Logging;
151 => exception is OperationCanceledException
152 ?
"The job was cancelled!"
185 IMetricFactory metricFactory,
186 ILogger<DreamMaker>
logger,
201 ArgumentNullException.ThrowIfNull(metricFactory);
202 this.logger =
logger ??
throw new ArgumentNullException(nameof(
logger));
204 this.metadata =
metadata ??
throw new ArgumentNullException(nameof(
metadata));
206 successfulDeployments = metricFactory.CreateCounter(
"tgs_successful_deployments",
"The number of deployments that have completed successfully");
207 failedDeployments = metricFactory.CreateCounter(
"tgs_failed_deployments",
"The number of deployments that have failed");
208 attemptedDeployments = metricFactory.CreateCounter(
"tgs_total_deployments",
"The number of deployments that have been attempted");
214#pragma warning disable CA1506
219 CancellationToken cancellationToken)
221 ArgumentNullException.ThrowIfNull(job);
222 ArgumentNullException.ThrowIfNull(databaseContextFactory);
223 ArgumentNullException.ThrowIfNull(progressReporter);
236 Models.CompileJob? compileJob =
null;
237 bool success =
false;
240 string? repoOwner =
null;
241 string? repoName =
null;
242 TimeSpan? averageSpan =
null;
243 Models.RepositorySettings? repositorySettings =
null;
244 Models.DreamDaemonSettings? ddSettings =
null;
245 Models.DreamMakerSettings? dreamMakerSettings =
null;
248 Models.RevisionInformation? revInfo =
null;
250 async databaseContext =>
254 ddSettings = await databaseContext
257 .Where(x => x.InstanceId ==
metadata.Id)
258 .Select(x =>
new Models.DreamDaemonSettings
260 StartupTimeout = x.StartupTimeout,
261 LogOutput = x.LogOutput,
263 .FirstOrDefaultAsync(cancellationToken);
264 if (ddSettings ==
default)
267 dreamMakerSettings = await databaseContext
270 .Where(x => x.InstanceId ==
metadata.Id)
271 .FirstAsync(cancellationToken);
272 if (dreamMakerSettings ==
default)
275 repositorySettings = await databaseContext
278 .Where(x => x.InstanceId ==
metadata.Id)
279 .Select(x =>
new Models.RepositorySettings
281 AccessToken = x.AccessToken,
282 AccessUser = x.AccessUser,
283 ShowTestMergeCommitters = x.ShowTestMergeCommitters,
284 PushTestMergeCommits = x.PushTestMergeCommits,
285 PostTestMergeComment = x.PostTestMergeComment,
287 .FirstOrDefaultAsync(cancellationToken);
288 if (repositorySettings ==
default)
300 var repoSha = repo.
Head;
303 revInfo = await databaseContext
304 .RevisionInformations
306 .Where(x => x.CommitSha == repoSha && x.InstanceId ==
metadata.Id)
307 .Include(x => x.ActiveTestMerges!)
308 .ThenInclude(x => x.TestMerge!)
309 .ThenInclude(x => x.MergedBy)
310 .FirstOrDefaultAsync(cancellationToken);
318 OriginCommitSha = repoSha,
323 ActiveTestMerges =
new List<RevInfoTestMerge>(),
327 databaseContext.RevisionInformations.Add(revInfo);
328 databaseContext.Instances.Attach(revInfo.Instance);
329 await databaseContext.Save(cancellationToken);
339 Models.CompileJob? oldCompileJob;
342 var likelyPushedTestMergeCommit =
343 repositorySettings!.PushTestMergeCommits!.Value
344 && repositorySettings.AccessToken !=
null
345 && repositorySettings.AccessUser !=
null;
354 remoteDeploymentManager!,
357 likelyPushedTestMergeCommit,
364 async databaseContext =>
366 var fullJob = compileJob.Job;
367 compileJob.Job =
new Models.Job(job.Require(x => x.Id));
368 var fullRevInfo = compileJob.RevisionInformation;
374 databaseContext.Jobs.Attach(compileJob.Job);
375 databaseContext.RevisionInformations.Attach(compileJob.RevisionInformation);
376 databaseContext.CompileJobs.Add(compileJob);
379 await databaseContext.Save(cancellationToken);
380 logger.LogTrace(
"Created CompileJob {compileJobId}", compileJob.Id);
390 databaseContext.CompileJobs.Remove(compileJob);
393 await databaseContext.Save(CancellationToken.None);
397 compileJob.Job = fullJob;
398 compileJob.RevisionInformation = fullRevInfo;
447#pragma warning restore CA1506
457 var previousCompileJobs = await databaseContext
460 .Where(x => x.Job.Instance!.Id ==
metadata.Id)
461 .OrderByDescending(x => x.Job.StoppedAt)
465 StoppedAt = x.Job.StoppedAt!.Value,
466 StartedAt = x.Job.StartedAt!.Value,
468 .ToListAsync(cancellationToken);
470 TimeSpan? averageSpan =
null;
471 if (previousCompileJobs.Count != 0)
473 var totalSpan = TimeSpan.Zero;
474 foreach (var previousCompileJob
in previousCompileJobs)
475 totalSpan += previousCompileJob.StoppedAt - previousCompileJob.StartedAt;
476 averageSpan = totalSpan / previousCompileJobs.Count;
499 Models.CompileJob? oldCompileJob,
500 Models.RevisionInformation revisionInformation,
501 Api.Models.Internal.DreamMakerSettings dreamMakerSettings,
506 TimeSpan? estimatedDuration,
507 bool localCommitExistsOnRemote,
508 CancellationToken cancellationToken)
510 logger.LogTrace(
"Begin Compile");
512 using var progressCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
514 progressReporter.StageName =
"Reserving BYOND version";
515 var progressTask =
ProgressTask(progressReporter, estimatedDuration, progressCts.Token);
523 DateTimeOffset.UtcNow + estimatedDuration,
526 localCommitExistsOnRemote);
528 var compileJob =
new Models.CompileJob(job, revisionInformation, engineLock.Version.ToString())
530 DirectoryName = Guid.NewGuid(),
531 DmeName = dreamMakerSettings.ProjectName,
532 RepositoryOrigin = repository.
Origin.ToString(),
535 progressReporter.StageName =
"Creating remote deployment notification";
541 logger.LogTrace(
"Deployment will timeout at {timeoutTime}", DateTimeOffset.UtcNow + dreamMakerSettings.Timeout!.Value);
542 using var timeoutTokenSource =
new CancellationTokenSource(dreamMakerSettings.Timeout.Value);
543 var timeoutToken = timeoutTokenSource.Token;
544 using (timeoutToken.Register(() =>
logger.LogWarning(
"Deployment timed out!")))
546 using var combinedTokenSource = CancellationTokenSource.CreateLinkedTokenSource(timeoutToken, cancellationToken);
556 remoteDeploymentManager,
557 combinedTokenSource.Token);
559 catch (OperationCanceledException) when (timeoutToken.IsCancellationRequested)
567 catch (OperationCanceledException)
570 progressReporter.StageName =
"Running CompileCancelled event";
576 progressCts.Cancel();
595 Models.CompileJob job,
596 Api.Models.Internal.DreamMakerSettings dreamMakerSettings,
601 CancellationToken cancellationToken)
603 var outputDirectory = job.DirectoryName!.Value.ToString();
604 logger.LogTrace(
"Compile output GUID: {dirGuid}", outputDirectory);
609 logger.LogTrace(
"Copying repository to game directory");
610 progressReporter.StageName =
"Copying repository";
612 var repoOrigin = repository.
Origin;
613 var repoReference = repository.
Reference;
615 await repository.
CopyTo(resolvedOutputDirectory, cancellationToken);
620 progressReporter.StageName =
"Running PreCompile event";
625 resolvedOutputDirectory,
626 repoOrigin.ToString(),
634 progressReporter.StageName =
"Determining .dme";
635 if (job.DmeName ==
null)
637 logger.LogTrace(
"Searching for available .dmes");
639 var foundPath = foundPaths.FirstOrDefault();
640 if (foundPath ==
default)
642 job.DmeName = foundPath.Substring(
643 resolvedOutputDirectory.Length + 1,
644 foundPath.Length - resolvedOutputDirectory.Length -
DmeExtension.Length - 2);
653 if (!targetDmeExists)
657 logger.LogDebug(
"Selected \"{dmeName}.dme\" for compilation!", job.DmeName);
659 progressReporter.StageName =
"Modifying .dme";
663 progressReporter.StageName =
"Running PreDreamMaker event";
668 resolvedOutputDirectory,
669 repoOrigin.ToString(),
670 engineLock.Version.ToString(),
676 progressReporter.StageName =
"Running Compiler";
677 var compileSuceeded = await
RunDreamMaker(engineLock, job, dreamMakerSettings.CompilerAdditionalArguments, cancellationToken);
680 var engineVersion = engineLock.
Version;
685 if (!compileSuceeded)
688 new JobException($
"Compilation failed:{Environment.NewLine}{Environment.NewLine}{job.Output}"));
692 dreamMakerSettings.ApiValidationSecurityLevel!.Value,
696 dreamMakerSettings.ApiValidationPort!.Value,
697 dreamMakerSettings.DMApiValidationMode!.Value,
704 progressReporter.StageName =
"Running CompileFailure event";
709 resolvedOutputDirectory,
710 compileSuceeded ?
"1" :
"0",
711 engineVersion.ToString(),
718 progressReporter.StageName =
"Running CompileComplete event";
723 resolvedOutputDirectory,
724 engineVersion.ToString(),
729 logger.LogTrace(
"Applying static game file symlinks...");
730 progressReporter.StageName =
"Symlinking GameStaticFiles";
733 await
configuration.SymlinkStaticFilesTo(resolvedOutputDirectory, cancellationToken);
735 logger.LogDebug(
"Compile complete!");
739 progressReporter.StageName =
"Cleaning output directory";
754 double? lastReport = estimatedDuration.HasValue ? 0 :
null;
757 var minimumSleepInterval = TimeSpan.FromMilliseconds(250);
758 var sleepInterval = estimatedDuration.HasValue ? estimatedDuration.Value / 100 : minimumSleepInterval;
760 if (estimatedDuration.HasValue)
762 logger.LogDebug(
"Compile is expected to take: {estimatedDuration}", estimatedDuration);
766 logger.LogTrace(
"No metric to estimate compile time.");
771 for (var iteration = 0; iteration < (estimatedDuration.HasValue ? 99 : Int32.MaxValue); ++iteration)
773 if (estimatedDuration.HasValue)
775 var nextInterval = DateTimeOffset.UtcNow + sleepInterval;
778 var remainingSleepThisInterval = nextInterval - DateTimeOffset.UtcNow;
779 var nextSleepSpan = remainingSleepThisInterval < minimumSleepInterval ? minimumSleepInterval : remainingSleepThisInterval;
781 await asyncDelayer.Delay(nextSleepSpan, cancellationToken);
784 while (DateTimeOffset.UtcNow < nextInterval);
787 await asyncDelayer.Delay(minimumSleepInterval, cancellationToken);
789 lastReport = estimatedDuration.HasValue ? sleepInterval * (iteration + 1) / estimatedDuration.Value :
null;
793 catch (OperationCanceledException ex)
795 logger.LogTrace(ex,
"ProgressTask aborted.");
799 logger.LogError(ex,
"ProgressTask crashed!");
819 Models.CompileJob job,
825 CancellationToken cancellationToken)
829 logger.LogDebug(
"Skipping DMAPI validation");
834 progressReporter.StageName =
"Validating DMAPI";
837 logger.LogTrace(
"Verifying {possiblyRequired}DMAPI...", requireValidate ?
"required " : String.Empty);
840 AllowWebClient =
false,
842 OpenDreamTopicPort = 0,
843 SecurityLevel = securityLevel,
845 StartupTimeout = timeout,
846 TopicRequestTimeout = 0,
847 HealthCheckSeconds = 0,
848 StartProfiler =
false,
849 LogOutput = logOutput,
853 job.MinimumSecurityLevel = securityLevel;
857 ioManager.ResolvePath(job.DirectoryName!.Value.ToString()),
860 await
using (var controller = await sessionControllerFactory.LaunchNew(provider, engineLock, launchParameters,
true, cancellationToken))
862 var launchResult = await controller.LaunchResult.WaitAsync(cancellationToken);
864 if (launchResult.StartupTime.HasValue)
865 await controller.Lifetime.WaitAsync(cancellationToken);
867 if (!controller.Lifetime.IsCompleted)
868 await controller.DisposeAsync();
870 validationStatus = controller.ApiValidationStatus;
872 logger.LogTrace(
"API validation status: {validationStatus}", validationStatus);
874 job.DMApiVersion = controller.DMApiVersion;
877 switch (validationStatus)
898 throw new InvalidOperationException(
899 $
"Session controller returned unexpected ApiValidationStatus: {validationStatus}");
913 Models.CompileJob job,
914 string? additionalCompilerArguments,
915 CancellationToken cancellationToken)
917 var environment = await engineLock.
LoadEnv(logger,
true, cancellationToken);
918 var arguments = engineLock.
FormatCompilerArguments($
"{job.DmeName}.{DmeExtension}", additionalCompilerArguments);
920 await
using var dm = await processExecutor.LaunchProcess(
922 ioManager.ResolvePath(
923 job.DirectoryName!.Value.ToString()),
927 readStandardHandles:
true,
928 noShellExecute:
true);
930 if (sessionConfiguration.LowPriorityDeploymentProcesses)
931 dm.AdjustPriority(
false);
934 using (cancellationToken.Register(() => dm.Terminate()))
935 exitCode = (await dm.Lifetime).Value;
936 cancellationToken.ThrowIfCancellationRequested();
938 logger.LogDebug(
"DreamMaker exit code: {exitCode}", exitCode);
939 job.Output = $
"{await dm.GetCombinedOutput(cancellationToken)}{Environment.NewLine}{Environment.NewLine}Exit Code: {exitCode}";
940 logger.LogDebug(
"DreamMaker output: {newLine}{output}", Environment.NewLine, job.Output);
942 currentDreamMakerOutput = job.Output;
943 return exitCode == 0;
952 async ValueTask
ModifyDme(Models.CompileJob job, CancellationToken cancellationToken)
954 var dmeFileName = String.Join(
'.', job.DmeName, DmeExtension);
955 var stringDirectoryName = job.DirectoryName!.Value.ToString();
956 var dmePath = ioManager.ConcatPath(stringDirectoryName, dmeFileName);
957 var dmeReadTask = ioManager.ReadAllBytes(dmePath, cancellationToken);
959 var dmeModificationsTask = configuration.CopyDMFilesTo(
961 ioManager.ResolvePath(
962 ioManager.ConcatPath(
964 ioManager.GetDirectoryName(dmeFileName))),
967 var dmeBytes = await dmeReadTask;
968 var dme = Encoding.UTF8.GetString(dmeBytes);
970 var dmeModifications = await dmeModificationsTask;
972 if (dmeModifications ==
null || dmeModifications.TotalDmeOverwrite)
974 if (dmeModifications !=
null)
975 logger.LogDebug(
".dme replacement configured!");
977 logger.LogTrace(
"No .dme modifications required.");
981 var dmeLines =
new List<string>(dme.Split(
'\n', StringSplitOptions.None));
982 for (var dmeLineIndex = 0; dmeLineIndex < dmeLines.Count; ++dmeLineIndex)
984 var line = dmeLines[dmeLineIndex];
985 if (line.Contains(
"BEGIN_INCLUDE", StringComparison.Ordinal) && dmeModifications.HeadIncludeLine !=
null)
987 var headIncludeLineNumber = dmeLineIndex + 1;
989 "Inserting HeadInclude.dm at line {lineNumber}: {includeLine}",
990 headIncludeLineNumber,
991 dmeModifications.HeadIncludeLine);
992 dmeLines.Insert(headIncludeLineNumber, dmeModifications.HeadIncludeLine);
995 else if (line.Contains(
"END_INCLUDE", StringComparison.Ordinal) && dmeModifications.TailIncludeLine !=
null)
998 "Inserting TailInclude.dm at line {lineNumber}: {includeLine}",
1000 dmeModifications.TailIncludeLine);
1001 dmeLines.Insert(dmeLineIndex, dmeModifications.TailIncludeLine);
1006 dmeBytes = Encoding.UTF8.GetBytes(String.Join(
'\n', dmeLines));
1007 await ioManager.WriteAllBytes(dmePath, dmeBytes, cancellationToken);
1019 async ValueTask CleanDir()
1021 if (sessionConfiguration.DelayCleaningFailedDeployments)
1023 logger.LogDebug(
"Not cleaning up errored deployment directory {guid} due to config.", job.DirectoryName);
1027 logger.LogTrace(
"Cleaning compile directory...");
1028 var jobPath = job.DirectoryName!.Value.ToString();
1032 await eventConsumer.HandleEvent(
EventType.DeploymentCleanup,
new List<string> { jobPath },
true, CancellationToken.None);
1033 await ioManager.DeleteDirectory(jobPath, CancellationToken.None);
1037 logger.LogWarning(e,
"Error cleaning up compile directory {path}!", ioManager.ResolvePath(jobPath));
1041 var dirCleanTask = CleanDir();
1043 var failRemoteDeployTask = remoteDeploymentManager.
FailDeployment(
1045 FormatExceptionForUsers(exception),
1046 CancellationToken.None);
1050 failRemoteDeployTask);
override string ToString()
Metadata about a server instance.
Launch settings for DreamDaemon.
bool? LogOutput
If process output/error text should be logged.
uint? StartupTimeout
The DreamDaemon startup timeout in seconds.
Extension methods for the ValueTask and ValueTask<TResult> classes.
static async ValueTask WhenAll(IEnumerable< ValueTask > tasks)
Fully await a given list of tasks .
Func< string?, string, Action< bool > >? currentChatCallback
The active callback from IChatManager.QueueDeploymentMessage.
async ValueTask< Models.CompileJob > Compile(Models.Job job, Models.CompileJob? oldCompileJob, Models.RevisionInformation revisionInformation, Api.Models.Internal.DreamMakerSettings dreamMakerSettings, DreamDaemonLaunchParameters launchParameters, IRepository repository, IRemoteDeploymentManager remoteDeploymentManager, JobProgressReporter progressReporter, TimeSpan? estimatedDuration, bool localCommitExistsOnRemote, CancellationToken cancellationToken)
Run the compile implementation.
readonly IRepositoryManager repositoryManager
The IRepositoryManager for DreamMaker.
ValueTask CleanupFailedCompile(Models.CompileJob job, IRemoteDeploymentManager remoteDeploymentManager, Exception exception)
Cleans up a failed compile job .
async ValueTask ProgressTask(JobProgressReporter progressReporter, TimeSpan? estimatedDuration, CancellationToken cancellationToken)
Gradually triggers a given progressReporter over a given estimatedDuration .
async ValueTask VerifyApi(uint timeout, DreamDaemonSecurity securityLevel, Models.CompileJob job, JobProgressReporter progressReporter, IEngineExecutableLock engineLock, ushort portToUse, DMApiValidationMode validationMode, bool logOutput, CancellationToken cancellationToken)
Run a quick DD instance to test the DMAPI is installed on the target code.
DreamMaker(IEngineManager engineManager, IIOManager ioManager, StaticFiles.IConfiguration configuration, ISessionControllerFactory sessionControllerFactory, IEventConsumer eventConsumer, IChatManager chatManager, IProcessExecutor processExecutor, ICompileJobSink compileJobConsumer, IRepositoryManager repositoryManager, IRemoteDeploymentManagerFactory remoteDeploymentManagerFactory, IAsyncDelayer asyncDelayer, IMetricFactory metricFactory, ILogger< DreamMaker > logger, SessionConfiguration sessionConfiguration, Api.Models.Instance metadata)
Initializes a new instance of the DreamMaker class.
readonly ILogger< DreamMaker > logger
The ILogger for DreamMaker.
readonly SessionConfiguration sessionConfiguration
The SessionConfiguration for DreamMaker.
async ValueTask RunCompileJob(JobProgressReporter progressReporter, Models.CompileJob job, Api.Models.Internal.DreamMakerSettings dreamMakerSettings, DreamDaemonLaunchParameters launchParameters, IEngineExecutableLock engineLock, IRepository repository, IRemoteDeploymentManager remoteDeploymentManager, CancellationToken cancellationToken)
Executes and populate a given job .
readonly StaticFiles.IConfiguration configuration
The StaticFiles.IConfiguration for DreamMaker.
const string DmeExtension
Extension for .dmes.
async ValueTask DeploymentProcess(Models.Job job, IDatabaseContextFactory databaseContextFactory, JobProgressReporter progressReporter, CancellationToken cancellationToken)
Create and a compile job and insert it into the database. Meant to be called by a IJobManager....
string? currentDreamMakerOutput
Cached for currentChatCallback.
async ValueTask< TimeSpan?> CalculateExpectedDeploymentTime(IDatabaseContext databaseContext, CancellationToken cancellationToken)
Calculate the average length of a deployment using a given databaseContext .
readonly IIOManager ioManager
The IIOManager for DreamMaker.
readonly IRemoteDeploymentManagerFactory remoteDeploymentManagerFactory
The IRemoteDeploymentManagerFactory for DreamMaker.
readonly Counter successfulDeployments
The number of successful deployments.
readonly Counter attemptedDeployments
The number of attempted deployments.
readonly ISessionControllerFactory sessionControllerFactory
The ISessionControllerFactory for DreamMaker.
readonly Counter failedDeployments
The number of failed deployments.
static string FormatExceptionForUsers(Exception exception)
Format a given Exception for display to users.
readonly IProcessExecutor processExecutor
The IProcessExecutor for DreamMaker.
bool deploying
If a compile job is running.
readonly IEngineManager engineManager
The IEngineManager for DreamMaker.
readonly ICompileJobSink compileJobConsumer
The ICompileJobSink for DreamMaker.
readonly IEventConsumer eventConsumer
The IEventConsumer for DreamMaker.
readonly Api.Models.Instance metadata
The Instance DreamMaker belongs to.
async ValueTask ModifyDme(Models.CompileJob job, CancellationToken cancellationToken)
Adds server side includes to the .dme being compiled.
readonly IChatManager chatManager
The IChatManager for DreamMaker.
async ValueTask< bool > RunDreamMaker(IEngineExecutableLock engineLock, Models.CompileJob job, string? additionalCompilerArguments, CancellationToken cancellationToken)
Compiles a .dme with DreamMaker.
readonly object deploymentLock
lock object for deploying.
readonly IAsyncDelayer asyncDelayer
The IAsyncDelayer for DreamMaker.
Repository(LibGit2Sharp.IRepository libGitRepo, ILibGit2Commands commands, IIOManager ioManager, IEventConsumer eventConsumer, ICredentialsProvider credentialsProvider, IPostWriteHandler postWriteHandler, IGitRemoteFeaturesFactory gitRemoteFeaturesFactory, ILibGit2RepositoryFactory submoduleFactory, ILogger< Repository > logger, GeneralConfiguration generalConfiguration, Action disposeAction)
Initializes a new instance of the Repository class.
Configuration options for the game sessions.
Operation exceptions thrown from the context of a Models.Job.
Progress reporter for a Job.
void ReportProgress(double? progress)
Report progress.
Represents an Api.Models.Instance in the database.
For managing connected chat services.
Func< string?, string, Action< bool > > QueueDeploymentMessage(Models.RevisionInformation revisionInformation, Models.RevisionInformation? previousRevisionInformation, Api.Models.EngineVersion engineVersion, DateTimeOffset? estimatedCompletionTime, string? gitHubOwner, string? gitHubRepo, bool localCommitPushed)
Send the message for a deployment to configured deployment channels.
ValueTask LoadCompileJob(CompileJob job, Action< bool >? activationAction, CancellationToken cancellationToken)
Load a new job into the ICompileJobSink.
For managing the compiler.
ValueTask< CompileJob?> LatestCompileJob()
Gets the latest CompileJob.
Factory for creating IRemoteDeploymentManagers.
IRemoteDeploymentManager CreateRemoteDeploymentManager(Api.Models.Instance metadata, RemoteGitProvider remoteGitProvider)
Creates a IRemoteDeploymentManager for a given remoteGitProvider .
Creates and updates remote deployments.
ValueTask PostDeploymentComments(CompileJob compileJob, RevisionInformation? previousRevisionInformation, RepositorySettings repositorySettings, string? repoOwner, string? repoName, CancellationToken cancellationToken)
Post deployment comments to the test merge ticket.
ValueTask StartDeployment(Api.Models.Internal.IGitRemoteInformation remoteInformation, CompileJob compileJob, CancellationToken cancellationToken)
Start a deployment for a given compileJob .
ValueTask FailDeployment(CompileJob compileJob, string errorMessage, CancellationToken cancellationToken)
Fail a deployment for a given compileJob .
Represents usage of the two primary BYOND server executables.
string FormatCompilerArguments(string dmePath, string? additionalArguments)
Return the command line arguments for compiling a given dmePath if compilation is necessary.
ValueTask< Dictionary< string, string >?> LoadEnv(ILogger logger, bool forCompiler, CancellationToken cancellationToken)
Loads the environment settings for either the server or compiler.
EngineVersion Version
The EngineVersion of the IEngineInstallation.
string CompilerExePath
The full path to the dm/DreamMaker executable.
For managing the engine installations.
ValueTask< IEngineExecutableLock > UseExecutables(EngineVersion? requiredVersion, string? trustDmbFullPath, CancellationToken cancellationToken)
Lock the current installation's location and return a IEngineExecutableLock.
Consumes EventTypes and takes the appropriate actions.
ValueTask HandleEvent(EventType eventType, IEnumerable< string?> parameters, bool deploymentPipeline, CancellationToken cancellationToken)
Handle a given eventType .
Represents an on-disk git repository.
Task< DateTimeOffset > TimestampCommit(string sha, CancellationToken cancellationToken)
Gets the DateTimeOffset a given sha was created on.
string Reference
The current reference the IRepository HEAD is using. This can be a branch or tag.
ValueTask CopyTo(string path, CancellationToken cancellationToken)
Copies the current working directory to a given path .
string Head
The SHA of the IRepository HEAD.
Uri Origin
The current origin remote the IRepository is using.
Factory for creating and loading IRepositorys.
ValueTask< IRepository?> LoadRepository(CancellationToken cancellationToken)
Attempt to load the IRepository from the default location.
Factory for ISessionControllers.
For managing the Configuration directory.
Factory for scoping usage of IDatabaseContexts. Meant for use by Components.
ValueTask UseContext(Func< IDatabaseContext, ValueTask > operation)
Run an operation in the scope of an IDatabaseContext.
IDatabaseCollection< CompileJob > CompileJobs
The CompileJobs in the IDatabaseContext.
Interface for using filesystems.
Task< bool > PathIsChildOf(string parentPath, string childPath, CancellationToken cancellationToken)
Check if a given parentPath is a parent of a given parentPath .
string ResolvePath()
Retrieve the full path of the current working directory.
string ConcatPath(params string[] paths)
Combines an array of strings into a path.
Task< bool > FileExists(string path, CancellationToken cancellationToken)
Check that the file at path exists.
Task< List< string > > GetFilesWithExtension(string path, string extension, bool recursive, CancellationToken cancellationToken)
Gets a list of files in path with the given extension .
For waiting asynchronously.
ErrorCode
Types of Response.ErrorMessageResponses that the API may return.
DreamDaemonVisibility
The visibility setting for DreamDaemon.
DreamDaemonSecurity
DreamDaemon's security level.
DMApiValidationMode
The DMAPI validation setting for deployments.
EventType
Types of events. Mirror in tgs.dm. Prefer last listed name for script.
ApiValidationStatus
Status of DMAPI validation.