2using System.Collections.Generic;
6using System.Threading.Tasks;
8using Microsoft.EntityFrameworkCore;
9using Microsoft.Extensions.Logging;
134 => exception is OperationCanceledException
135 ?
"The job was cancelled!"
167 ILogger<DreamMaker>
logger,
182 this.logger =
logger ??
throw new ArgumentNullException(nameof(
logger));
184 this.metadata =
metadata ??
throw new ArgumentNullException(nameof(
metadata));
190#pragma warning disable CA1506
195 CancellationToken cancellationToken)
197 ArgumentNullException.ThrowIfNull(job);
198 ArgumentNullException.ThrowIfNull(databaseContextFactory);
199 ArgumentNullException.ThrowIfNull(progressReporter);
210 Models.CompileJob? compileJob =
null;
213 string? repoOwner =
null;
214 string? repoName =
null;
215 TimeSpan? averageSpan =
null;
216 Models.RepositorySettings? repositorySettings =
null;
217 Models.DreamDaemonSettings? ddSettings =
null;
218 Models.DreamMakerSettings? dreamMakerSettings =
null;
221 Models.RevisionInformation? revInfo =
null;
223 async databaseContext =>
227 ddSettings = await databaseContext
230 .Where(x => x.InstanceId ==
metadata.Id)
231 .Select(x =>
new Models.DreamDaemonSettings
233 StartupTimeout = x.StartupTimeout,
234 LogOutput = x.LogOutput,
236 .FirstOrDefaultAsync(cancellationToken);
237 if (ddSettings ==
default)
240 dreamMakerSettings = await databaseContext
243 .Where(x => x.InstanceId ==
metadata.Id)
244 .FirstAsync(cancellationToken);
245 if (dreamMakerSettings ==
default)
248 repositorySettings = await databaseContext
251 .Where(x => x.InstanceId ==
metadata.Id)
252 .Select(x =>
new Models.RepositorySettings
254 AccessToken = x.AccessToken,
255 AccessUser = x.AccessUser,
256 ShowTestMergeCommitters = x.ShowTestMergeCommitters,
257 PushTestMergeCommits = x.PushTestMergeCommits,
258 PostTestMergeComment = x.PostTestMergeComment,
260 .FirstOrDefaultAsync(cancellationToken);
261 if (repositorySettings ==
default)
273 var repoSha = repo.
Head;
276 revInfo = await databaseContext
277 .RevisionInformations
279 .Where(x => x.CommitSha == repoSha && x.InstanceId ==
metadata.Id)
280 .Include(x => x.ActiveTestMerges!)
281 .ThenInclude(x => x.TestMerge!)
282 .ThenInclude(x => x.MergedBy)
283 .FirstOrDefaultAsync(cancellationToken);
291 OriginCommitSha = repoSha,
296 ActiveTestMerges =
new List<RevInfoTestMerge>(),
300 databaseContext.RevisionInformations.Add(revInfo);
301 databaseContext.Instances.Attach(revInfo.Instance);
302 await databaseContext.Save(cancellationToken);
312 var likelyPushedTestMergeCommit =
313 repositorySettings!.PushTestMergeCommits!.Value
314 && repositorySettings.AccessToken !=
null
315 && repositorySettings.AccessUser !=
null;
323 remoteDeploymentManager!,
326 likelyPushedTestMergeCommit,
333 async databaseContext =>
335 var fullJob = compileJob.Job;
336 compileJob.Job =
new Models.Job(job.Require(x => x.Id));
337 var fullRevInfo = compileJob.RevisionInformation;
343 databaseContext.Jobs.Attach(compileJob.Job);
344 databaseContext.RevisionInformations.Attach(compileJob.RevisionInformation);
345 databaseContext.CompileJobs.Add(compileJob);
348 await databaseContext.Save(cancellationToken);
349 logger.LogTrace(
"Created CompileJob {compileJobId}", compileJob.Id);
358 databaseContext.CompileJobs.Remove(compileJob);
361 await databaseContext.Save(CancellationToken.None);
365 compileJob.Job = fullJob;
366 compileJob.RevisionInformation = fullRevInfo;
411#pragma warning restore CA1506
421 var previousCompileJobs = await databaseContext
424 .Where(x => x.Job.Instance!.Id ==
metadata.Id)
425 .OrderByDescending(x => x.Job.StoppedAt)
429 StoppedAt = x.Job.StoppedAt!.Value,
430 StartedAt = x.Job.StartedAt!.Value,
432 .ToListAsync(cancellationToken);
434 TimeSpan? averageSpan =
null;
435 if (previousCompileJobs.Count != 0)
437 var totalSpan = TimeSpan.Zero;
438 foreach (var previousCompileJob
in previousCompileJobs)
439 totalSpan += previousCompileJob.StoppedAt - previousCompileJob.StartedAt;
440 averageSpan = totalSpan / previousCompileJobs.Count;
462 Models.RevisionInformation revisionInformation,
463 Api.Models.Internal.DreamMakerSettings dreamMakerSettings,
468 TimeSpan? estimatedDuration,
469 bool localCommitExistsOnRemote,
470 CancellationToken cancellationToken)
472 logger.LogTrace(
"Begin Compile");
474 using var progressCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
476 progressReporter.StageName =
"Reserving BYOND version";
477 var progressTask =
ProgressTask(progressReporter, estimatedDuration, progressCts.Token);
484 DateTimeOffset.UtcNow + estimatedDuration,
487 localCommitExistsOnRemote);
489 var compileJob =
new Models.CompileJob(job, revisionInformation, engineLock.Version.ToString())
491 DirectoryName = Guid.NewGuid(),
492 DmeName = dreamMakerSettings.ProjectName,
493 RepositoryOrigin = repository.
Origin.ToString(),
496 progressReporter.StageName =
"Creating remote deployment notification";
502 logger.LogTrace(
"Deployment will timeout at {timeoutTime}", DateTimeOffset.UtcNow + dreamMakerSettings.Timeout!.Value);
503 using var timeoutTokenSource =
new CancellationTokenSource(dreamMakerSettings.Timeout.Value);
504 var timeoutToken = timeoutTokenSource.Token;
505 using (timeoutToken.Register(() =>
logger.LogWarning(
"Deployment timed out!")))
507 using var combinedTokenSource = CancellationTokenSource.CreateLinkedTokenSource(timeoutToken, cancellationToken);
517 remoteDeploymentManager,
518 combinedTokenSource.Token);
520 catch (OperationCanceledException) when (timeoutToken.IsCancellationRequested)
528 catch (OperationCanceledException)
531 progressReporter.StageName =
"Running CompileCancelled event";
537 progressCts.Cancel();
556 Models.CompileJob job,
557 Api.Models.Internal.DreamMakerSettings dreamMakerSettings,
562 CancellationToken cancellationToken)
564 var outputDirectory = job.DirectoryName!.Value.ToString();
565 logger.LogTrace(
"Compile output GUID: {dirGuid}", outputDirectory);
570 logger.LogTrace(
"Copying repository to game directory");
571 progressReporter.StageName =
"Copying repository";
573 var repoOrigin = repository.
Origin;
574 var repoReference = repository.
Reference;
576 await repository.
CopyTo(resolvedOutputDirectory, cancellationToken);
581 progressReporter.StageName =
"Running PreCompile event";
586 resolvedOutputDirectory,
587 repoOrigin.ToString(),
595 progressReporter.StageName =
"Determining .dme";
596 if (job.DmeName ==
null)
598 logger.LogTrace(
"Searching for available .dmes");
600 var foundPath = foundPaths.FirstOrDefault();
601 if (foundPath ==
default)
603 job.DmeName = foundPath.Substring(
604 resolvedOutputDirectory.Length + 1,
605 foundPath.Length - resolvedOutputDirectory.Length -
DmeExtension.Length - 2);
614 if (!targetDmeExists)
618 logger.LogDebug(
"Selected \"{dmeName}.dme\" for compilation!", job.DmeName);
620 progressReporter.StageName =
"Modifying .dme";
624 progressReporter.StageName =
"Running PreDreamMaker event";
629 resolvedOutputDirectory,
630 repoOrigin.ToString(),
631 engineLock.Version.ToString(),
637 progressReporter.StageName =
"Running Compiler";
638 var compileSuceeded = await
RunDreamMaker(engineLock, job, dreamMakerSettings.CompilerAdditionalArguments, cancellationToken);
641 var engineVersion = engineLock.
Version;
646 if (!compileSuceeded)
649 new JobException($
"Compilation failed:{Environment.NewLine}{Environment.NewLine}{job.Output}"));
653 dreamMakerSettings.ApiValidationSecurityLevel!.Value,
657 dreamMakerSettings.ApiValidationPort!.Value,
658 dreamMakerSettings.DMApiValidationMode!.Value,
665 progressReporter.StageName =
"Running CompileFailure event";
670 resolvedOutputDirectory,
671 compileSuceeded ?
"1" :
"0",
672 engineVersion.ToString(),
679 progressReporter.StageName =
"Running CompileComplete event";
684 resolvedOutputDirectory,
685 engineVersion.ToString(),
690 logger.LogTrace(
"Applying static game file symlinks...");
691 progressReporter.StageName =
"Symlinking GameStaticFiles";
694 await
configuration.SymlinkStaticFilesTo(resolvedOutputDirectory, cancellationToken);
696 logger.LogDebug(
"Compile complete!");
700 progressReporter.StageName =
"Cleaning output directory";
715 double? lastReport = estimatedDuration.HasValue ? 0 :
null;
718 var minimumSleepInterval = TimeSpan.FromMilliseconds(250);
719 var sleepInterval = estimatedDuration.HasValue ? estimatedDuration.Value / 100 : minimumSleepInterval;
721 if (estimatedDuration.HasValue)
723 logger.LogDebug(
"Compile is expected to take: {estimatedDuration}", estimatedDuration);
727 logger.LogTrace(
"No metric to estimate compile time.");
732 for (var iteration = 0; iteration < (estimatedDuration.HasValue ? 99 : Int32.MaxValue); ++iteration)
734 if (estimatedDuration.HasValue)
736 var nextInterval = DateTimeOffset.UtcNow + sleepInterval;
739 var remainingSleepThisInterval = nextInterval - DateTimeOffset.UtcNow;
740 var nextSleepSpan = remainingSleepThisInterval < minimumSleepInterval ? minimumSleepInterval : remainingSleepThisInterval;
742 await asyncDelayer.Delay(nextSleepSpan, cancellationToken);
745 while (DateTimeOffset.UtcNow < nextInterval);
748 await asyncDelayer.Delay(minimumSleepInterval, cancellationToken);
750 lastReport = estimatedDuration.HasValue ? sleepInterval * (iteration + 1) / estimatedDuration.Value :
null;
754 catch (OperationCanceledException ex)
756 logger.LogTrace(ex,
"ProgressTask aborted.");
760 logger.LogError(ex,
"ProgressTask crashed!");
780 Models.CompileJob job,
786 CancellationToken cancellationToken)
790 logger.LogDebug(
"Skipping DMAPI validation");
795 progressReporter.StageName =
"Validating DMAPI";
798 logger.LogTrace(
"Verifying {possiblyRequired}DMAPI...", requireValidate ?
"required " : String.Empty);
801 AllowWebClient =
false,
803 OpenDreamTopicPort = 0,
804 SecurityLevel = securityLevel,
806 StartupTimeout = timeout,
807 TopicRequestTimeout = 0,
808 HealthCheckSeconds = 0,
809 StartProfiler =
false,
810 LogOutput = logOutput,
814 job.MinimumSecurityLevel = securityLevel;
818 ioManager.ResolvePath(job.DirectoryName!.Value.ToString()),
821 await
using (var controller = await sessionControllerFactory.LaunchNew(provider, engineLock, launchParameters,
true, cancellationToken))
823 var launchResult = await controller.LaunchResult.WaitAsync(cancellationToken);
825 if (launchResult.StartupTime.HasValue)
826 await controller.Lifetime.WaitAsync(cancellationToken);
828 if (!controller.Lifetime.IsCompleted)
829 await controller.DisposeAsync();
831 validationStatus = controller.ApiValidationStatus;
833 logger.LogTrace(
"API validation status: {validationStatus}", validationStatus);
835 job.DMApiVersion = controller.DMApiVersion;
838 switch (validationStatus)
859 throw new InvalidOperationException(
860 $
"Session controller returned unexpected ApiValidationStatus: {validationStatus}");
874 Models.CompileJob job,
875 string? additionalCompilerArguments,
876 CancellationToken cancellationToken)
878 var environment = await engineLock.
LoadEnv(logger,
true, cancellationToken);
879 var arguments = engineLock.
FormatCompilerArguments($
"{job.DmeName}.{DmeExtension}", additionalCompilerArguments);
881 await
using var dm = await processExecutor.LaunchProcess(
883 ioManager.ResolvePath(
884 job.DirectoryName!.Value.ToString()),
888 readStandardHandles:
true,
889 noShellExecute:
true);
891 if (sessionConfiguration.LowPriorityDeploymentProcesses)
892 dm.AdjustPriority(
false);
895 using (cancellationToken.Register(() => dm.Terminate()))
896 exitCode = (await dm.Lifetime).Value;
897 cancellationToken.ThrowIfCancellationRequested();
899 logger.LogDebug(
"DreamMaker exit code: {exitCode}", exitCode);
900 job.Output = $
"{await dm.GetCombinedOutput(cancellationToken)}{Environment.NewLine}{Environment.NewLine}Exit Code: {exitCode}";
901 logger.LogDebug(
"DreamMaker output: {newLine}{output}", Environment.NewLine, job.Output);
903 currentDreamMakerOutput = job.Output;
904 return exitCode == 0;
913 async ValueTask
ModifyDme(Models.CompileJob job, CancellationToken cancellationToken)
915 var dmeFileName = String.Join(
'.', job.DmeName, DmeExtension);
916 var stringDirectoryName = job.DirectoryName!.Value.ToString();
917 var dmePath = ioManager.ConcatPath(stringDirectoryName, dmeFileName);
918 var dmeReadTask = ioManager.ReadAllBytes(dmePath, cancellationToken);
920 var dmeModificationsTask = configuration.CopyDMFilesTo(
922 ioManager.ResolvePath(
923 ioManager.ConcatPath(
925 ioManager.GetDirectoryName(dmeFileName))),
928 var dmeBytes = await dmeReadTask;
929 var dme = Encoding.UTF8.GetString(dmeBytes);
931 var dmeModifications = await dmeModificationsTask;
933 if (dmeModifications ==
null || dmeModifications.TotalDmeOverwrite)
935 if (dmeModifications !=
null)
936 logger.LogDebug(
".dme replacement configured!");
938 logger.LogTrace(
"No .dme modifications required.");
942 var dmeLines =
new List<string>(dme.Split(
'\n', StringSplitOptions.None));
943 for (var dmeLineIndex = 0; dmeLineIndex < dmeLines.Count; ++dmeLineIndex)
945 var line = dmeLines[dmeLineIndex];
946 if (line.Contains(
"BEGIN_INCLUDE", StringComparison.Ordinal) && dmeModifications.HeadIncludeLine !=
null)
948 var headIncludeLineNumber = dmeLineIndex + 1;
950 "Inserting HeadInclude.dm at line {lineNumber}: {includeLine}",
951 headIncludeLineNumber,
952 dmeModifications.HeadIncludeLine);
953 dmeLines.Insert(headIncludeLineNumber, dmeModifications.HeadIncludeLine);
956 else if (line.Contains(
"END_INCLUDE", StringComparison.Ordinal) && dmeModifications.TailIncludeLine !=
null)
959 "Inserting TailInclude.dm at line {lineNumber}: {includeLine}",
961 dmeModifications.TailIncludeLine);
962 dmeLines.Insert(dmeLineIndex, dmeModifications.TailIncludeLine);
967 dmeBytes = Encoding.UTF8.GetBytes(String.Join(
'\n', dmeLines));
968 await ioManager.WriteAllBytes(dmePath, dmeBytes, cancellationToken);
980 async ValueTask CleanDir()
982 if (sessionConfiguration.DelayCleaningFailedDeployments)
984 logger.LogDebug(
"Not cleaning up errored deployment directory {guid} due to config.", job.DirectoryName);
988 logger.LogTrace(
"Cleaning compile directory...");
989 var jobPath = job.DirectoryName!.Value.ToString();
993 await eventConsumer.HandleEvent(
EventType.DeploymentCleanup,
new List<string> { jobPath },
true, CancellationToken.None);
994 await ioManager.DeleteDirectory(jobPath, CancellationToken.None);
998 logger.LogWarning(e,
"Error cleaning up compile directory {path}!", ioManager.ResolvePath(jobPath));
1002 var dirCleanTask = CleanDir();
1004 var failRemoteDeployTask = remoteDeploymentManager.
FailDeployment(
1006 FormatExceptionForUsers(exception),
1007 CancellationToken.None);
1011 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.
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 ISessionControllerFactory sessionControllerFactory
The ISessionControllerFactory for DreamMaker.
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.
DreamMaker(IEngineManager engineManager, IIOManager ioManager, StaticFiles.IConfiguration configuration, ISessionControllerFactory sessionControllerFactory, IEventConsumer eventConsumer, IChatManager chatManager, IProcessExecutor processExecutor, ICompileJobSink compileJobConsumer, IRepositoryManager repositoryManager, IRemoteDeploymentManagerFactory remoteDeploymentManagerFactory, IAsyncDelayer asyncDelayer, ILogger< DreamMaker > logger, SessionConfiguration sessionConfiguration, Api.Models.Instance metadata)
Initializes a new instance of the DreamMaker class.
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.