tgstation-server 6.12.0
The /tg/station 13 server suite
Loading...
Searching...
No Matches
BaseRemoteDeploymentManager.cs
Go to the documentation of this file.
1using System;
2using System.Collections.Concurrent;
3using System.Collections.Generic;
4using System.Linq;
5using System.Threading;
6using System.Threading.Tasks;
7
8using Microsoft.Extensions.Logging;
9
13
15{
20 {
24 protected Api.Models.Instance Metadata { get; }
25
29 protected ILogger<BaseRemoteDeploymentManager> Logger { get; }
30
34 readonly ConcurrentDictionary<long, Action<bool>> activationCallbacks;
35
43 ILogger<BaseRemoteDeploymentManager> logger,
44 Api.Models.Instance metadata,
45 ConcurrentDictionary<long, Action<bool>> activationCallbacks)
46 {
47 Logger = logger ?? throw new ArgumentNullException(nameof(logger));
48 Metadata = metadata ?? throw new ArgumentNullException(nameof(metadata));
49 this.activationCallbacks = activationCallbacks ?? throw new ArgumentNullException(nameof(activationCallbacks));
50 }
51
53 public async ValueTask PostDeploymentComments(
54 CompileJob compileJob,
55 RevisionInformation? previousRevisionInformation,
56 RepositorySettings repositorySettings,
57 string? repoOwner,
58 string? repoName,
59 CancellationToken cancellationToken)
60 {
61 ArgumentNullException.ThrowIfNull(compileJob);
62 ArgumentNullException.ThrowIfNull(repositorySettings);
63 ArgumentNullException.ThrowIfNull(repoOwner);
64 ArgumentNullException.ThrowIfNull(repoName);
65
66 if (repositorySettings.AccessToken == null)
67 return;
68
69 var deployedRevisionInformation = compileJob.RevisionInformation;
70 if ((previousRevisionInformation != null && previousRevisionInformation.CommitSha == deployedRevisionInformation.CommitSha)
71 || !repositorySettings.PostTestMergeComment!.Value)
72 return;
73
74 previousRevisionInformation ??= new RevisionInformation();
75 previousRevisionInformation.ActiveTestMerges ??= new List<RevInfoTestMerge>();
76
77 deployedRevisionInformation.ActiveTestMerges ??= new List<RevInfoTestMerge>();
78
79 // added prs
80 var addedTestMerges = deployedRevisionInformation
81 .ActiveTestMerges
82 .Select(x => x.TestMerge)
83 .Where(x => !previousRevisionInformation
84 .ActiveTestMerges
85 .Any(y => y.TestMerge.Number == x.Number))
86 .ToList();
87 var removedTestMerges = previousRevisionInformation
89 .Select(x => x.TestMerge)
90 .Where(x => !deployedRevisionInformation
91 .ActiveTestMerges
92 .Any(y => y.TestMerge.Number == x.Number))
93 .ToList();
94 var updatedTestMerges = deployedRevisionInformation
95 .ActiveTestMerges
96 .Select(x => x.TestMerge)
97 .Where(x => previousRevisionInformation
98 .ActiveTestMerges
99 .Any(y => y.TestMerge.Number == x.Number))
100 .ToList();
101
102 if (addedTestMerges.Count == 0 && removedTestMerges.Count == 0 && updatedTestMerges.Count == 0)
103 return;
104
105 Logger.LogTrace(
106 "Commenting on {addedCount} added, {removedCount} removed, and {updatedCount} updated test merge sources...",
107 addedTestMerges.Count,
108 removedTestMerges.Count,
109 updatedTestMerges.Count);
110
111 var tasks = new List<ValueTask>(addedTestMerges.Count + updatedTestMerges.Count + removedTestMerges.Count);
112 foreach (var addedTestMerge in addedTestMerges)
113 {
114 var addCommentTask = CommentOnTestMergeSource(
115 repositorySettings,
116 repoOwner,
117 repoName,
119 repositorySettings,
120 compileJob,
121 addedTestMerge,
122 repoOwner,
123 repoName,
124 false),
125 addedTestMerge.Number,
126 cancellationToken);
127 tasks.Add(addCommentTask);
128 }
129
130 foreach (var removedTestMerge in removedTestMerges)
131 {
132 var removeCommentTask = CommentOnTestMergeSource(
133 repositorySettings,
134 repoOwner,
135 repoName,
136 "#### Test Merge Removed",
137 removedTestMerge.Number,
138 cancellationToken);
139 tasks.Add(removeCommentTask);
140 }
141
142 foreach (var updatedTestMerge in updatedTestMerges)
143 {
144 var updateCommentTask = CommentOnTestMergeSource(
145 repositorySettings,
146 repoOwner,
147 repoName,
149 repositorySettings,
150 compileJob,
151 updatedTestMerge,
152 repoOwner,
153 repoName,
154 true),
155 updatedTestMerge.Number,
156 cancellationToken);
157 tasks.Add(updateCommentTask);
158 }
159
160 if (tasks.Count > 0)
161 await ValueTaskExtensions.WhenAll(tasks);
162 }
163
165 public ValueTask ApplyDeployment(CompileJob compileJob, CancellationToken cancellationToken)
166 {
167 ArgumentNullException.ThrowIfNull(compileJob);
168
169 if (activationCallbacks.TryGetValue(compileJob.Require(x => x.Id), out var activationCallback))
170 activationCallback(true);
171
172 return ApplyDeploymentImpl(compileJob, cancellationToken);
173 }
174
176 public abstract ValueTask FailDeployment(CompileJob compileJob, string errorMessage, CancellationToken cancellationToken);
177
179 public ValueTask MarkInactive(CompileJob compileJob, CancellationToken cancellationToken)
180 {
181 ArgumentNullException.ThrowIfNull(compileJob);
182
183 if (activationCallbacks.TryRemove(compileJob.Require(x => x.Id), out var activationCallback))
184 activationCallback(false);
185
186 return MarkInactiveImpl(compileJob, cancellationToken);
187 }
188
190 public abstract ValueTask<IReadOnlyCollection<TestMerge>> RemoveMergedTestMerges(
191 IRepository repository,
192 RepositorySettings repositorySettings,
193 RevisionInformation revisionInformation,
194 CancellationToken cancellationToken);
195
197 public ValueTask StageDeployment(CompileJob compileJob, Action<bool>? activationCallback, CancellationToken cancellationToken)
198 {
199 ArgumentNullException.ThrowIfNull(compileJob);
200
201 var compileJobId = compileJob.Require(x => x.Id);
202 if (activationCallback != null && !activationCallbacks.TryAdd(compileJobId, activationCallback))
203 Logger.LogError("activationCallbacks conflicted on CompileJob #{id}!", compileJobId);
204
205 return StageDeploymentImpl(compileJob, cancellationToken);
206 }
207
209 public abstract ValueTask StartDeployment(
210 Api.Models.Internal.IGitRemoteInformation remoteInformation,
211 CompileJob compileJob,
212 CancellationToken cancellationToken);
213
220 protected abstract ValueTask StageDeploymentImpl(CompileJob compileJob, CancellationToken cancellationToken);
221
228 protected abstract ValueTask ApplyDeploymentImpl(CompileJob compileJob, CancellationToken cancellationToken);
229
236 protected abstract ValueTask MarkInactiveImpl(CompileJob compileJob, CancellationToken cancellationToken);
237
248 protected abstract string FormatTestMerge(
249 RepositorySettings repositorySettings,
250 CompileJob compileJob,
251 TestMerge testMerge,
252 string remoteRepositoryOwner,
253 string remoteRepositoryName,
254 bool updated);
255
266 protected abstract ValueTask CommentOnTestMergeSource(
267 RepositorySettings repositorySettings,
268 string remoteRepositoryOwner,
269 string remoteRepositoryName,
270 string comment,
271 int testMergeNumber,
272 CancellationToken cancellationToken);
273 }
274}
Metadata about a server instance.
Definition Instance.cs:9
bool? PostTestMergeComment
If test merging should create a comment. Requires AccessToken to be set to function.
string? AccessToken
The token/password to access the git repository with. Can also be a TGS encoded app private key....
Extension methods for the ValueTask and ValueTask<TResult> classes.
static async ValueTask WhenAll(IEnumerable< ValueTask > tasks)
Fully await a given list of tasks .
ValueTask StartDeployment(Api.Models.Internal.IGitRemoteInformation remoteInformation, CompileJob compileJob, CancellationToken cancellationToken)
Start a deployment for a given compileJob .A ValueTask representing the running operation.
ValueTask ApplyDeploymentImpl(CompileJob compileJob, CancellationToken cancellationToken)
Implementation of ApplyDeployment(CompileJob, CancellationToken).
Api.Models.Instance Metadata
The Api.Models.Instance for the BaseRemoteDeploymentManager.
ValueTask FailDeployment(CompileJob compileJob, string errorMessage, CancellationToken cancellationToken)
Fail a deployment for a given compileJob .A ValueTask representing the running operation.
ValueTask StageDeployment(CompileJob compileJob, Action< bool >? activationCallback, CancellationToken cancellationToken)
Stage a given compileJob 's deployment.A ValueTask representing the running operation.
ValueTask MarkInactiveImpl(CompileJob compileJob, CancellationToken cancellationToken)
Implementation of MarkInactive(CompileJob, CancellationToken).
ValueTask MarkInactive(CompileJob compileJob, CancellationToken cancellationToken)
Mark the deplotment for a given compileJob as inactive.A Task representing the running operation.
ValueTask CommentOnTestMergeSource(RepositorySettings repositorySettings, string remoteRepositoryOwner, string remoteRepositoryName, string comment, int testMergeNumber, CancellationToken cancellationToken)
Create a comment of a given testMergeNumber 's source.
string FormatTestMerge(RepositorySettings repositorySettings, CompileJob compileJob, TestMerge testMerge, string remoteRepositoryOwner, string remoteRepositoryName, bool updated)
Formats a comment for a given testMerge .
ValueTask StageDeploymentImpl(CompileJob compileJob, CancellationToken cancellationToken)
Implementation of StageDeployment(CompileJob, Action<bool>, CancellationToken).
readonly ConcurrentDictionary< long, Action< bool > > activationCallbacks
A map of CompileJob Api.Models.EntityId.Ids to activation callback Action<T1>s.
BaseRemoteDeploymentManager(ILogger< BaseRemoteDeploymentManager > logger, Api.Models.Instance metadata, ConcurrentDictionary< long, Action< bool > > activationCallbacks)
Initializes a new instance of the BaseRemoteDeploymentManager class.
async ValueTask PostDeploymentComments(CompileJob compileJob, RevisionInformation? previousRevisionInformation, RepositorySettings repositorySettings, string? repoOwner, string? repoName, CancellationToken cancellationToken)
Post deployment comments to the test merge ticket.A ValueTask representing the running operation.
ValueTask ApplyDeployment(CompileJob compileJob, CancellationToken cancellationToken)
Stage a given compileJob 's deployment.A ValueTask representing the running operation.
ValueTask< IReadOnlyCollection< TestMerge > > RemoveMergedTestMerges(IRepository repository, RepositorySettings repositorySettings, RevisionInformation revisionInformation, CancellationToken cancellationToken)
Get the updated list of TestMerges for an origin merge.A ValueTask<TResult> resulting in the IReadOnl...
ILogger< BaseRemoteDeploymentManager > Logger
The ILogger for the BaseRemoteDeploymentManager.
RevisionInformation RevisionInformation
See CompileJobResponse.RevisionInformation.
Definition CompileJob.cs:27
ICollection< RevInfoTestMerge >? ActiveTestMerges
See Api.Models.RevisionInformation.ActiveTestMerges.
Represents an on-disk git repository.