Forge
csharp3407750f
1using AgentForge.Plugin.Ci.Contracts;
2using AgentForge.Plugin.Ci.Data;
3using AgentForge.Plugin.Ci.Ir;
4using Microsoft.Extensions.DependencyInjection;
5
6namespace AgentForge.Plugin.Ci.Execution;
7
8public sealed class ForgeCiRunQueueService(
9 IServiceScopeFactory scopeFactory,
10 ForgeCiRunExecutor executor)
11{
12 public async Task<CiRunDetailResponse> QueueAsync(
13 string repoId,
14 string repoName,
15 QueueCiRunRequest request,
16 string queuedBy,
17 CancellationToken cancellationToken = default)
18 {
19 var definitionName = ForgeCiTemplates.NormalizeDefinitionName(request.DefinitionName);
20 var gitRef = string.IsNullOrWhiteSpace(request.Ref) ? "main" : request.Ref.Trim();
21 var commit = request.Commit?.Trim() ?? string.Empty;
22 var actor = string.IsNullOrWhiteSpace(queuedBy) ? "queue" : queuedBy;
23
24 ForgeCiPipelineRunRecord run;
25 using (var scope = scopeFactory.CreateScope())
26 {
27 var definitions = scope.ServiceProvider.GetRequiredService<ForgeCiDefinitionStore>();
28 var runs = scope.ServiceProvider.GetRequiredService<ForgeCiRunStore>();
29
30 var record = definitions.GetByName(repoId, definitionName)
31 ?? throw new KeyNotFoundException($"CI definition '{definitionName}' not found.");
32
33 var document = definitions.LoadDocument(record);
34 var plan = ForgeCiPlanBuilder.Build(document);
35 run = runs.CreateQueuedRun(
36 repoId,
37 definitionName,
38 gitRef,
39 commit,
40 request.MrNumber,
41 plan,
42 actor);
43 }
44
45 await executor.ExecuteAsync(run.Id, cancellationToken).ConfigureAwait(false);
46
47 using (var scope = scopeFactory.CreateScope())
48 {
49 var runs = scope.ServiceProvider.GetRequiredService<ForgeCiRunStore>();
50 var finished = runs.GetRun(repoId, run.Id)
51 ?? throw new InvalidOperationException($"CI run '{run.Id}' disappeared after execution.");
52 var steps = runs.ListSteps(run.Id);
53 return ToDetail(repoName, finished, steps);
54 }
55 }
56
57 internal static CiRunDetailResponse ToDetail(
58 string repoName,
59 ForgeCiPipelineRunRecord run,
60 IReadOnlyList<ForgeCiStepRunRecord> steps) =>
61 new(
62 run.Id,
63 repoName,
64 run.DefinitionName,
65 run.Ref,
66 run.Commit,
67 run.MrNumber,
68 run.Status,
69 run.QueuedBy,
70 run.CreatedAt,
71 run.UpdatedAt,
72 run.StartedAt,
73 run.FinishedAt,
74 steps.Select(s => new CiStepRunResponse(
75 s.Id,
76 s.NodeId,
77 s.TaskId,
78 s.DisplayName,
79 s.OrderIndex,
80 s.Status,
81 s.LogText,
82 s.StartedAt,
83 s.FinishedAt)).ToList());
84}
85
View only · write via MCP/CIDE