feat(admin): dispatch allowlisted maintenance jobs
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
using System.Net.Http.Headers;
|
||||
using System.Net.Http.Json;
|
||||
|
||||
namespace JobTrackerApi.Services;
|
||||
|
||||
public sealed record MaintenanceJobDefinition(string Id, string Title, string Description, bool Available, string? RunsUrl);
|
||||
|
||||
public sealed class MaintenanceJobDispatcher(IConfiguration configuration, IHttpClientFactory httpClientFactory)
|
||||
{
|
||||
public const string CvBenchmarkJobId = "cv-benchmark";
|
||||
|
||||
public IReadOnlyList<MaintenanceJobDefinition> GetJobs()
|
||||
{
|
||||
var settings = ReadSettings();
|
||||
return
|
||||
[
|
||||
new(
|
||||
CvBenchmarkJobId,
|
||||
"CV extraction benchmark",
|
||||
"Runs the CV corpus benchmark and retains the report and fixture candidates as a workflow artifact.",
|
||||
settings.IsConfigured,
|
||||
settings.RunsUrl)
|
||||
];
|
||||
}
|
||||
|
||||
public async Task DispatchAsync(string jobId, CancellationToken cancellationToken)
|
||||
{
|
||||
if (!string.Equals(jobId, CvBenchmarkJobId, StringComparison.Ordinal))
|
||||
{
|
||||
throw new KeyNotFoundException("Unknown maintenance job.");
|
||||
}
|
||||
|
||||
var settings = ReadSettings();
|
||||
if (!settings.IsConfigured)
|
||||
{
|
||||
throw new InvalidOperationException("Maintenance job dispatch is not configured.");
|
||||
}
|
||||
|
||||
using var request = new HttpRequestMessage(
|
||||
HttpMethod.Post,
|
||||
$"{settings.BaseUrl}/api/v1/repos/{Uri.EscapeDataString(settings.Owner)}/{Uri.EscapeDataString(settings.Repository)}/actions/workflows/maintenance.yml/dispatches");
|
||||
request.Headers.Authorization = new AuthenticationHeaderValue("token", settings.Token);
|
||||
request.Content = JsonContent.Create(new
|
||||
{
|
||||
@ref = "main",
|
||||
inputs = new Dictionary<string, string> { ["job"] = jobId }
|
||||
});
|
||||
|
||||
using var response = await httpClientFactory.CreateClient("maintenance-jobs")
|
||||
.SendAsync(request, cancellationToken);
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
throw new HttpRequestException(
|
||||
$"Gitea rejected the maintenance workflow dispatch with HTTP {(int)response.StatusCode}.",
|
||||
null,
|
||||
response.StatusCode);
|
||||
}
|
||||
}
|
||||
|
||||
private Settings ReadSettings()
|
||||
{
|
||||
var baseUrl = (configuration["MaintenanceJobs:GiteaBaseUrl"] ?? "https://git.cesnimda.uk").Trim().TrimEnd('/');
|
||||
var owner = (configuration["MaintenanceJobs:GiteaOwner"] ?? "cesnimda").Trim();
|
||||
var repository = (configuration["MaintenanceJobs:GiteaRepository"] ?? "jobtrackingapp").Trim();
|
||||
var token = (configuration["MaintenanceJobs:GiteaToken"] ?? string.Empty).Trim();
|
||||
var configured = Uri.TryCreate(baseUrl, UriKind.Absolute, out var uri)
|
||||
&& uri.Scheme == Uri.UriSchemeHttps
|
||||
&& !string.IsNullOrWhiteSpace(owner)
|
||||
&& !string.IsNullOrWhiteSpace(repository)
|
||||
&& !string.IsNullOrWhiteSpace(token);
|
||||
var runsUrl = configured ? $"{baseUrl}/{owner}/{repository}/actions" : null;
|
||||
return new Settings(baseUrl, owner, repository, token, configured, runsUrl);
|
||||
}
|
||||
|
||||
private sealed record Settings(string BaseUrl, string Owner, string Repository, string Token, bool IsConfigured, string? RunsUrl);
|
||||
}
|
||||
Reference in New Issue
Block a user