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 var likelyPushedTestMergeCommit =
340 repositorySettings!.PushTestMergeCommits!.Value
341 && repositorySettings.AccessToken !=
null
342 && repositorySettings.AccessUser !=
null;
350 remoteDeploymentManager!,
353 likelyPushedTestMergeCommit,
360 async databaseContext =>
362 var fullJob = compileJob.Job;
363 compileJob.Job =
new Models.Job(job.Require(x => x.Id));
364 var fullRevInfo = compileJob.RevisionInformation;
370 databaseContext.Jobs.Attach(compileJob.Job);
371 databaseContext.RevisionInformations.Attach(compileJob.RevisionInformation);
372 databaseContext.CompileJobs.Add(compileJob);
375 await databaseContext.Save(cancellationToken);
376 logger.LogTrace(
"Created CompileJob {compileJobId}", compileJob.Id);
386 databaseContext.CompileJobs.Remove(compileJob);
389 await databaseContext.Save(CancellationToken.None);
393 compileJob.Job = fullJob;
394 compileJob.RevisionInformation = fullRevInfo;
443#pragma warning restore CA1506
453 var previousCompileJobs = await databaseContext
456 .Where(x => x.Job.Instance!.Id ==
metadata.Id)
457 .OrderByDescending(x => x.Job.StoppedAt)
461 StoppedAt = x.Job.StoppedAt!.Value,
462 StartedAt = x.Job.StartedAt!.Value,
464 .ToListAsync(cancellationToken);
466 TimeSpan? averageSpan =
null;
467 if (previousCompileJobs.Count != 0)
469 var totalSpan = TimeSpan.Zero;
470 foreach (var previousCompileJob
in previousCompileJobs)
471 totalSpan += previousCompileJob.StoppedAt - previousCompileJob.StartedAt;
472 averageSpan = totalSpan / previousCompileJobs.Count;
494 Models.RevisionInformation revisionInformation,
495 Api.Models.Internal.DreamMakerSettings dreamMakerSettings,
500 TimeSpan? estimatedDuration,
501 bool localCommitExistsOnRemote,
502 CancellationToken cancellationToken)
504 logger.LogTrace(
"Begin Compile");
506 using var progressCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
508 progressReporter.StageName =
"Reserving BYOND version";
509 var progressTask =
ProgressTask(progressReporter, estimatedDuration, progressCts.Token);
516 DateTimeOffset.UtcNow + estimatedDuration,
519 localCommitExistsOnRemote);
521 var compileJob =
new Models.CompileJob(job, revisionInformation, engineLock.Version.ToString())
523 DirectoryName = Guid.NewGuid(),
524 DmeName = dreamMakerSettings.ProjectName,
525 RepositoryOrigin = repository.
Origin.ToString(),
528 progressReporter.StageName =
"Creating remote deployment notification";
534 logger.LogTrace(
"Deployment will timeout at {timeoutTime}", DateTimeOffset.UtcNow + dreamMakerSettings.Timeout!.Value);
535 using var timeoutTokenSource =
new CancellationTokenSource(dreamMakerSettings.Timeout.Value);
536 var timeoutToken = timeoutTokenSource.Token;
537 using (timeoutToken.Register(() =>
logger.LogWarning(
"Deployment timed out!")))
539 using var combinedTokenSource = CancellationTokenSource.CreateLinkedTokenSource(timeoutToken, cancellationToken);
549 remoteDeploymentManager,
550 combinedTokenSource.Token);
552 catch (OperationCanceledException) when (timeoutToken.IsCancellationRequested)
560 catch (OperationCanceledException)
563 progressReporter.StageName =
"Running CompileCancelled event";
569 progressCts.Cancel();
588 Models.CompileJob job,
589 Api.Models.Internal.DreamMakerSettings dreamMakerSettings,
594 CancellationToken cancellationToken)
596 var outputDirectory = job.DirectoryName!.Value.ToString();
597 logger.LogTrace(
"Compile output GUID: {dirGuid}", outputDirectory);
602 logger.LogTrace(
"Copying repository to game directory");
603 progressReporter.StageName =
"Copying repository";
605 var repoOrigin = repository.
Origin;
606 var repoReference = repository.
Reference;
608 await repository.
CopyTo(resolvedOutputDirectory, cancellationToken);
613 progressReporter.StageName =
"Running PreCompile event";
618 resolvedOutputDirectory,
619 repoOrigin.ToString(),
627 progressReporter.StageName =
"Determining .dme";
628 if (job.DmeName ==
null)
630 logger.LogTrace(
"Searching for available .dmes");
632 var foundPath = foundPaths.FirstOrDefault();
633 if (foundPath ==
default)
635 job.DmeName = foundPath.Substring(
636 resolvedOutputDirectory.Length + 1,
637 foundPath.Length - resolvedOutputDirectory.Length -
DmeExtension.Length - 2);
646 if (!targetDmeExists)
650 logger.LogDebug(
"Selected \"{dmeName}.dme\" for compilation!", job.DmeName);
652 progressReporter.StageName =
"Modifying .dme";
656 progressReporter.StageName =
"Running PreDreamMaker event";
661 resolvedOutputDirectory,
662 repoOrigin.ToString(),
663 engineLock.Version.ToString(),
669 progressReporter.StageName =
"Running Compiler";
670 var compileSuceeded = await
RunDreamMaker(engineLock, job, dreamMakerSettings.CompilerAdditionalArguments, cancellationToken);
673 var engineVersion = engineLock.
Version;
678 if (!compileSuceeded)
681 new JobException($
"Compilation failed:{Environment.NewLine}{Environment.NewLine}{job.Output}"));
685 dreamMakerSettings.ApiValidationSecurityLevel!.Value,
689 dreamMakerSettings.ApiValidationPort!.Value,
690 dreamMakerSettings.DMApiValidationMode!.Value,
697 progressReporter.StageName =
"Running CompileFailure event";
702 resolvedOutputDirectory,
703 compileSuceeded ?
"1" :
"0",
704 engineVersion.ToString(),
711 progressReporter.StageName =
"Running CompileComplete event";
716 resolvedOutputDirectory,
717 engineVersion.ToString(),
722 logger.LogTrace(
"Applying static game file symlinks...");
723 progressReporter.StageName =
"Symlinking GameStaticFiles";
726 await
configuration.SymlinkStaticFilesTo(resolvedOutputDirectory, cancellationToken);
728 logger.LogDebug(
"Compile complete!");
732 progressReporter.StageName =
"Cleaning output directory";
747 double? lastReport = estimatedDuration.HasValue ? 0 :
null;
750 var minimumSleepInterval = TimeSpan.FromMilliseconds(250);
751 var sleepInterval = estimatedDuration.HasValue ? estimatedDuration.Value / 100 : minimumSleepInterval;
753 if (estimatedDuration.HasValue)
755 logger.LogDebug(
"Compile is expected to take: {estimatedDuration}", estimatedDuration);
759 logger.LogTrace(
"No metric to estimate compile time.");
764 for (var iteration = 0; iteration < (estimatedDuration.HasValue ? 99 : Int32.MaxValue); ++iteration)
766 if (estimatedDuration.HasValue)
768 var nextInterval = DateTimeOffset.UtcNow + sleepInterval;
771 var remainingSleepThisInterval = nextInterval - DateTimeOffset.UtcNow;
772 var nextSleepSpan = remainingSleepThisInterval < minimumSleepInterval ? minimumSleepInterval : remainingSleepThisInterval;
774 await asyncDelayer.Delay(nextSleepSpan, cancellationToken);
777 while (DateTimeOffset.UtcNow < nextInterval);
780 await asyncDelayer.Delay(minimumSleepInterval, cancellationToken);
782 lastReport = estimatedDuration.HasValue ? sleepInterval * (iteration + 1) / estimatedDuration.Value :
null;
786 catch (OperationCanceledException ex)
788 logger.LogTrace(ex,
"ProgressTask aborted.");
792 logger.LogError(ex,
"ProgressTask crashed!");
812 Models.CompileJob job,
818 CancellationToken cancellationToken)
822 logger.LogDebug(
"Skipping DMAPI validation");
827 progressReporter.StageName =
"Validating DMAPI";
830 logger.LogTrace(
"Verifying {possiblyRequired}DMAPI...", requireValidate ?
"required " : String.Empty);
833 AllowWebClient =
false,
835 OpenDreamTopicPort = 0,
836 SecurityLevel = securityLevel,
838 StartupTimeout = timeout,
839 TopicRequestTimeout = 0,
840 HealthCheckSeconds = 0,
841 StartProfiler =
false,
842 LogOutput = logOutput,
846 job.MinimumSecurityLevel = securityLevel;
850 ioManager.ResolvePath(job.DirectoryName!.Value.ToString()),
853 await
using (var controller = await sessionControllerFactory.LaunchNew(provider, engineLock, launchParameters,
true, cancellationToken))
855 var launchResult = await controller.LaunchResult.WaitAsync(cancellationToken);
857 if (launchResult.StartupTime.HasValue)
858 await controller.Lifetime.WaitAsync(cancellationToken);
860 if (!controller.Lifetime.IsCompleted)
861 await controller.DisposeAsync();
863 validationStatus = controller.ApiValidationStatus;
865 logger.LogTrace(
"API validation status: {validationStatus}", validationStatus);
867 job.DMApiVersion = controller.DMApiVersion;
870 switch (validationStatus)
891 throw new InvalidOperationException(
892 $
"Session controller returned unexpected ApiValidationStatus: {validationStatus}");
906 Models.CompileJob job,
907 string? additionalCompilerArguments,
908 CancellationToken cancellationToken)
910 var environment = await engineLock.
LoadEnv(logger,
true, cancellationToken);
911 var arguments = engineLock.
FormatCompilerArguments($
"{job.DmeName}.{DmeExtension}", additionalCompilerArguments);
913 await
using var dm = await processExecutor.LaunchProcess(
915 ioManager.ResolvePath(
916 job.DirectoryName!.Value.ToString()),
920 readStandardHandles:
true,
921 noShellExecute:
true);
923 if (sessionConfiguration.LowPriorityDeploymentProcesses)
924 dm.AdjustPriority(
false);
927 using (cancellationToken.Register(() => dm.Terminate()))
928 exitCode = (await dm.Lifetime).Value;
929 cancellationToken.ThrowIfCancellationRequested();
931 logger.LogDebug(
"DreamMaker exit code: {exitCode}", exitCode);
932 job.Output = $
"{await dm.GetCombinedOutput(cancellationToken)}{Environment.NewLine}{Environment.NewLine}Exit Code: {exitCode}";
933 logger.LogDebug(
"DreamMaker output: {newLine}{output}", Environment.NewLine, job.Output);
935 currentDreamMakerOutput = job.Output;
936 return exitCode == 0;
945 async ValueTask
ModifyDme(Models.CompileJob job, CancellationToken cancellationToken)
947 var dmeFileName = String.Join(
'.', job.DmeName, DmeExtension);
948 var stringDirectoryName = job.DirectoryName!.Value.ToString();
949 var dmePath = ioManager.ConcatPath(stringDirectoryName, dmeFileName);
950 var dmeReadTask = ioManager.ReadAllBytes(dmePath, cancellationToken);
952 var dmeModificationsTask = configuration.CopyDMFilesTo(
954 ioManager.ResolvePath(
955 ioManager.ConcatPath(
957 ioManager.GetDirectoryName(dmeFileName))),
960 var dmeBytes = await dmeReadTask;
961 var dme = Encoding.UTF8.GetString(dmeBytes);
963 var dmeModifications = await dmeModificationsTask;
965 if (dmeModifications ==
null || dmeModifications.TotalDmeOverwrite)
967 if (dmeModifications !=
null)
968 logger.LogDebug(
".dme replacement configured!");
970 logger.LogTrace(
"No .dme modifications required.");
974 var dmeLines =
new List<string>(dme.Split(
'\n', StringSplitOptions.None));
975 for (var dmeLineIndex = 0; dmeLineIndex < dmeLines.Count; ++dmeLineIndex)
977 var line = dmeLines[dmeLineIndex];
978 if (line.Contains(
"BEGIN_INCLUDE", StringComparison.Ordinal) && dmeModifications.HeadIncludeLine !=
null)
980 var headIncludeLineNumber = dmeLineIndex + 1;
982 "Inserting HeadInclude.dm at line {lineNumber}: {includeLine}",
983 headIncludeLineNumber,
984 dmeModifications.HeadIncludeLine);
985 dmeLines.Insert(headIncludeLineNumber, dmeModifications.HeadIncludeLine);
988 else if (line.Contains(
"END_INCLUDE", StringComparison.Ordinal) && dmeModifications.TailIncludeLine !=
null)
991 "Inserting TailInclude.dm at line {lineNumber}: {includeLine}",
993 dmeModifications.TailIncludeLine);
994 dmeLines.Insert(dmeLineIndex, dmeModifications.TailIncludeLine);
999 dmeBytes = Encoding.UTF8.GetBytes(String.Join(
'\n', dmeLines));
1000 await ioManager.WriteAllBytes(dmePath, dmeBytes, cancellationToken);
1012 async ValueTask CleanDir()
1014 if (sessionConfiguration.DelayCleaningFailedDeployments)
1016 logger.LogDebug(
"Not cleaning up errored deployment directory {guid} due to config.", job.DirectoryName);
1020 logger.LogTrace(
"Cleaning compile directory...");
1021 var jobPath = job.DirectoryName!.Value.ToString();
1025 await eventConsumer.HandleEvent(
EventType.DeploymentCleanup,
new List<string> { jobPath },
true, CancellationToken.None);
1026 await ioManager.DeleteDirectory(jobPath, CancellationToken.None);
1030 logger.LogWarning(e,
"Error cleaning up compile directory {path}!", ioManager.ResolvePath(jobPath));
1034 var dirCleanTask = CleanDir();
1036 var failRemoteDeployTask = remoteDeploymentManager.
FailDeployment(
1038 FormatExceptionForUsers(exception),
1039 CancellationToken.None);
1043 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.
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.
async ValueTask< Models.CompileJob > Compile(Models.Job job, 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 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, 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.