feat: Enhance Task Runner with simulation and failure policy support
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled

- Added tests for output projection and failure policy population in TaskPackPlanner.
- Introduced new failure policy manifest in TestManifests.
- Implemented simulation endpoints in the web service for task execution.
- Created TaskRunnerServiceOptions for configuration management.
- Updated appsettings.json to include TaskRunner configuration.
- Enhanced PackRunWorkerService to handle execution graphs and state management.
- Added support for parallel execution and conditional steps in the worker service.
- Updated documentation to reflect new features and changes in execution flow.
This commit is contained in:
master
2025-11-04 19:05:50 +02:00
parent 2eb6852d34
commit 3bd0955202
83 changed files with 15161 additions and 10678 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -25,6 +25,8 @@ internal interface IBackendOperationsClient
Task<PolicySimulationResult> SimulatePolicyAsync(string policyId, PolicySimulationInput input, CancellationToken cancellationToken);
Task<TaskRunnerSimulationResult> SimulateTaskRunnerAsync(TaskRunnerSimulationRequest request, CancellationToken cancellationToken);
Task<PolicyActivationResult> ActivatePolicyRevisionAsync(string policyId, int version, PolicyActivationRequest request, CancellationToken cancellationToken);
Task<OfflineKitDownloadResult> DownloadOfflineKitAsync(string? bundleId, string destinationDirectory, bool overwrite, bool resume, CancellationToken cancellationToken);

View File

@@ -0,0 +1,36 @@
using System.Collections.Generic;
using System.Text.Json.Nodes;
namespace StellaOps.Cli.Services.Models;
internal sealed record TaskRunnerSimulationRequest(string Manifest, JsonObject? Inputs);
internal sealed record TaskRunnerSimulationResult(
string PlanHash,
TaskRunnerSimulationFailurePolicy FailurePolicy,
IReadOnlyList<TaskRunnerSimulationStep> Steps,
IReadOnlyList<TaskRunnerSimulationOutput> Outputs,
bool HasPendingApprovals);
internal sealed record TaskRunnerSimulationFailurePolicy(int MaxAttempts, int BackoffSeconds, bool ContinueOnError);
internal sealed record TaskRunnerSimulationStep(
string Id,
string TemplateId,
string Kind,
bool Enabled,
string Status,
string? StatusReason,
string? Uses,
string? ApprovalId,
string? GateMessage,
int? MaxParallel,
bool ContinueOnError,
IReadOnlyList<TaskRunnerSimulationStep> Children);
internal sealed record TaskRunnerSimulationOutput(
string Name,
string Type,
bool RequiresRuntimeValue,
string? PathExpression,
string? ValueExpression);

View File

@@ -0,0 +1,73 @@
using System.Collections.Generic;
using System.Text.Json.Nodes;
namespace StellaOps.Cli.Services.Models.Transport;
internal sealed class TaskRunnerSimulationRequestDocument
{
public string Manifest { get; set; } = string.Empty;
public JsonObject? Inputs { get; set; }
}
internal sealed class TaskRunnerSimulationResponseDocument
{
public string PlanHash { get; set; } = string.Empty;
public TaskRunnerSimulationFailurePolicyDocument? FailurePolicy { get; set; }
public List<TaskRunnerSimulationStepDocument>? Steps { get; set; }
public List<TaskRunnerSimulationOutputDocument>? Outputs { get; set; }
public bool HasPendingApprovals { get; set; }
}
internal sealed class TaskRunnerSimulationFailurePolicyDocument
{
public int MaxAttempts { get; set; }
public int BackoffSeconds { get; set; }
public bool ContinueOnError { get; set; }
}
internal sealed class TaskRunnerSimulationStepDocument
{
public string Id { get; set; } = string.Empty;
public string TemplateId { get; set; } = string.Empty;
public string Kind { get; set; } = string.Empty;
public bool Enabled { get; set; }
public string Status { get; set; } = string.Empty;
public string? StatusReason { get; set; }
public string? Uses { get; set; }
public string? ApprovalId { get; set; }
public string? GateMessage { get; set; }
public int? MaxParallel { get; set; }
public bool ContinueOnError { get; set; }
public List<TaskRunnerSimulationStepDocument>? Children { get; set; }
}
internal sealed class TaskRunnerSimulationOutputDocument
{
public string Name { get; set; } = string.Empty;
public string Type { get; set; } = string.Empty;
public bool RequiresRuntimeValue { get; set; }
public string? PathExpression { get; set; }
public string? ValueExpression { get; set; }
}

View File

@@ -13,6 +13,7 @@ internal static class CliMetrics
private static readonly Counter<long> OfflineKitDownloadCounter = Meter.CreateCounter<long>("stellaops.cli.offline.kit.download.count");
private static readonly Counter<long> OfflineKitImportCounter = Meter.CreateCounter<long>("stellaops.cli.offline.kit.import.count");
private static readonly Counter<long> PolicySimulationCounter = Meter.CreateCounter<long>("stellaops.cli.policy.simulate.count");
private static readonly Counter<long> TaskRunnerSimulationCounter = Meter.CreateCounter<long>("stellaops.cli.taskrunner.simulate.count");
private static readonly Counter<long> PolicyActivationCounter = Meter.CreateCounter<long>("stellaops.cli.policy.activate.count");
private static readonly Counter<long> SourcesDryRunCounter = Meter.CreateCounter<long>("stellaops.cli.sources.dryrun.count");
private static readonly Counter<long> AocVerifyCounter = Meter.CreateCounter<long>("stellaops.cli.aoc.verify.count");
@@ -57,6 +58,12 @@ internal static class CliMetrics
new("outcome", string.IsNullOrWhiteSpace(outcome) ? "unknown" : outcome)
});
public static void RecordTaskRunnerSimulation(string outcome)
=> TaskRunnerSimulationCounter.Add(1, new KeyValuePair<string, object?>[]
{
new("outcome", string.IsNullOrWhiteSpace(outcome) ? "unknown" : outcome)
});
public static void RecordPolicyActivation(string outcome)
=> PolicyActivationCounter.Add(1, new KeyValuePair<string, object?>[]
{