tgstation-server 6.1.2
The /tg/station 13 server suite
Loading...
Searching...
No Matches
GitLabRemoteDeploymentManager.cs
Go to the documentation of this file.
1using System;
2using System.Collections.Concurrent;
3using System.Collections.Generic;
4using System.Globalization;
5using System.Linq;
6using System.Threading;
7using System.Threading.Tasks;
8
9using GitLabApiClient;
10using GitLabApiClient.Models.MergeRequests.Responses;
11using GitLabApiClient.Models.Notes.Requests;
12using Microsoft.Extensions.Logging;
13
16
18{
23 {
31 ILogger<GitLabRemoteDeploymentManager> logger,
32 Api.Models.Instance metadata,
33 ConcurrentDictionary<long, Action<bool>> activationCallbacks)
34 : base(logger, metadata, activationCallbacks)
35 {
36 }
37
39 public override async ValueTask<IReadOnlyCollection<TestMerge>> RemoveMergedTestMerges(
40 IRepository repository,
41 RepositorySettings repositorySettings,
42 RevisionInformation revisionInformation,
43 CancellationToken cancellationToken)
44 {
45 ArgumentNullException.ThrowIfNull(repository);
46 ArgumentNullException.ThrowIfNull(repositorySettings);
47 ArgumentNullException.ThrowIfNull(revisionInformation);
48
49 if ((revisionInformation.ActiveTestMerges?.Count > 0) != true)
50 {
51 Logger.LogTrace("No test merges to remove.");
52 return Array.Empty<TestMerge>();
53 }
54
55 var client = repositorySettings.AccessToken != null
56 ? new GitLabClient(GitLabRemoteFeatures.GitLabUrl, repositorySettings.AccessToken)
57 : new GitLabClient(GitLabRemoteFeatures.GitLabUrl);
58
59 var tasks = revisionInformation
61 .Select(x => client
62 .MergeRequests
63 .GetAsync(
64 $"{repository.RemoteRepositoryOwner}/{repository.RemoteRepositoryName}",
65 x.TestMerge.Number)
66 .WaitAsync(cancellationToken));
67 try
68 {
69 await Task.WhenAll(tasks);
70 }
71 catch (Exception ex) when (ex is not OperationCanceledException)
72 {
73 Logger.LogWarning(ex, "Merge requests update check failed!");
74 }
75
76 var newList = revisionInformation.ActiveTestMerges.Select(x => x.TestMerge).ToList();
77
78 MergeRequest? lastMerged = null;
79 async ValueTask CheckRemoveMR(Task<MergeRequest> task)
80 {
81 var mergeRequest = await task;
82 if (mergeRequest.State != MergeRequestState.Merged)
83 return;
84
85 // We don't just assume, actually check the repo contains the merge commit.
86 if (await repository.CommittishIsParent(mergeRequest.MergeCommitSha, cancellationToken))
87 {
88 if (lastMerged == null || lastMerged.ClosedAt < mergeRequest.ClosedAt)
89 lastMerged = mergeRequest;
90 newList.Remove(
91 newList.First(
92 potential => potential.Number == mergeRequest.Id));
93 }
94 }
95
96 foreach (var prTask in tasks)
97 await CheckRemoveMR(prTask);
98
99 return newList;
100 }
101
103 public override ValueTask FailDeployment(
104 CompileJob compileJob,
105 string errorMessage,
106 CancellationToken cancellationToken) => ValueTask.CompletedTask;
107
109 public override ValueTask StartDeployment(
110 Api.Models.Internal.IGitRemoteInformation remoteInformation,
111 CompileJob compileJob,
112 CancellationToken cancellationToken) => ValueTask.CompletedTask;
113
115 protected override ValueTask ApplyDeploymentImpl(
116 CompileJob compileJob,
117 CancellationToken cancellationToken) => ValueTask.CompletedTask;
118
120 protected override ValueTask StageDeploymentImpl(CompileJob compileJob, CancellationToken cancellationToken) => ValueTask.CompletedTask;
121
123 protected override ValueTask MarkInactiveImpl(CompileJob compileJob, CancellationToken cancellationToken) => ValueTask.CompletedTask;
124
126 protected override async ValueTask CommentOnTestMergeSource(
127 RepositorySettings repositorySettings,
128 string remoteRepositoryOwner,
129 string remoteRepositoryName,
130 string comment,
131 int testMergeNumber,
132 CancellationToken cancellationToken)
133 {
134 var client = repositorySettings.AccessToken != null
135 ? new GitLabClient(GitLabRemoteFeatures.GitLabUrl, repositorySettings.AccessToken)
136 : new GitLabClient(GitLabRemoteFeatures.GitLabUrl);
137
138 try
139 {
140 await client
141 .MergeRequests
142 .CreateNoteAsync(
143 $"{remoteRepositoryOwner}/{remoteRepositoryName}",
144 testMergeNumber,
145 new CreateMergeRequestNoteRequest(comment))
146 .WaitAsync(cancellationToken);
147 }
148 catch (Exception ex) when (ex is not OperationCanceledException)
149 {
150 Logger.LogWarning(ex, "Error posting GitHub comment!");
151 }
152 }
153
155 protected override string FormatTestMerge(
156 RepositorySettings repositorySettings,
157 CompileJob compileJob,
158 TestMerge testMerge,
159 string remoteRepositoryOwner,
160 string remoteRepositoryName,
161 bool updated) => String.Format(
162 CultureInfo.InvariantCulture,
163 "#### Test Merge {4}{0}{0}##### Server Instance{0}{5}{1}{0}{0}##### Revision{0}Origin: {6}{0}Merge Request: {2}{0}Server: {7}{3}",
164 Environment.NewLine,
165 repositorySettings.ShowTestMergeCommitters!.Value
166 ? String.Format(
167 CultureInfo.InvariantCulture,
168 "{0}{0}##### Merged By{0}{1}",
169 Environment.NewLine,
170 testMerge.MergedBy!.Name)
171 : String.Empty,
172 testMerge.TargetCommitSha,
173 testMerge.Comment != null
174 ? String.Format(
175 CultureInfo.InvariantCulture,
176 "{0}{0}##### Comment{0}{1}",
177 Environment.NewLine,
178 testMerge.Comment)
179 : String.Empty,
180 updated ? "Updated" : "Deployed",
181 Metadata.Name,
182 compileJob.RevisionInformation.OriginCommitSha,
183 compileJob.RevisionInformation.CommitSha);
184 }
185}
string? AccessToken
The token/password to access the git repository with.
Api.Models.Instance Metadata
The Api.Models.Instance for the BaseRemoteDeploymentManager.
readonly ConcurrentDictionary< long, Action< bool > > activationCallbacks
A map of CompileJob Api.Models.EntityId.Ids to activation callback Action<T1>s.
ILogger< BaseRemoteDeploymentManager > Logger
The ILogger for the BaseRemoteDeploymentManager.
override async 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 IReadOn...
override ValueTask ApplyDeploymentImpl(CompileJob compileJob, CancellationToken cancellationToken)
Implementation of ApplyDeployment(CompileJob, CancellationToken). A ValueTask representing the runnin...
override string FormatTestMerge(RepositorySettings repositorySettings, CompileJob compileJob, TestMerge testMerge, string remoteRepositoryOwner, string remoteRepositoryName, bool updated)
Formats a comment for a given testMerge . A formatted string for posting a informative comment about ...
override async ValueTask CommentOnTestMergeSource(RepositorySettings repositorySettings, string remoteRepositoryOwner, string remoteRepositoryName, string comment, int testMergeNumber, CancellationToken cancellationToken)
Create a comment of a given testMergeNumber 's source. A ValueTask representing the running operation...
override ValueTask StageDeploymentImpl(CompileJob compileJob, CancellationToken cancellationToken)
Implementation of StageDeployment(CompileJob, Action<bool>, CancellationToken). A ValueTask represent...
override ValueTask StartDeployment(Api.Models.Internal.IGitRemoteInformation remoteInformation, CompileJob compileJob, CancellationToken cancellationToken)
Start a deployment for a given compileJob . A ValueTask representing the running operation.
GitLabRemoteDeploymentManager(ILogger< GitLabRemoteDeploymentManager > logger, Api.Models.Instance metadata, ConcurrentDictionary< long, Action< bool > > activationCallbacks)
Initializes a new instance of the GitLabRemoteDeploymentManager class.
override ValueTask MarkInactiveImpl(CompileJob compileJob, CancellationToken cancellationToken)
Implementation of MarkInactive(CompileJob, CancellationToken). A ValueTask representing the running o...
override ValueTask FailDeployment(CompileJob compileJob, string errorMessage, CancellationToken cancellationToken)
Fail a deployment for a given compileJob . A ValueTask representing the running operation.
ICollection< RevInfoTestMerge >? ActiveTestMerges
See Api.Models.RevisionInformation.ActiveTestMerges.
Represents an on-disk git repository.
Definition: IRepository.cs:14
Task< bool > CommittishIsParent(string committish, CancellationToken cancellationToken)
Check if a given committish is a parent of the current Head.