Add property-based tests for SBOM/VEX document ordering and Unicode normalization determinism

- Implement `SbomVexOrderingDeterminismProperties` for testing component list and vulnerability metadata hash consistency.
- Create `UnicodeNormalizationDeterminismProperties` to validate NFC normalization and Unicode string handling.
- Add project file for `StellaOps.Testing.Determinism.Properties` with necessary dependencies.
- Introduce CI/CD template validation tests including YAML syntax checks and documentation content verification.
- Create validation script for CI/CD templates ensuring all required files and structures are present.
This commit is contained in:
StellaOps Bot
2025-12-26 15:17:15 +02:00
parent 7792749bb4
commit 907783f625
354 changed files with 79727 additions and 1346 deletions

View File

@@ -0,0 +1,243 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
// Sprint: SPRINT_20251226_001_BE_cicd_gate_integration
// Task: CICD-GATE-01 - Create gate/evaluate endpoint contracts
namespace StellaOps.Policy.Gateway.Contracts;
/// <summary>
/// Request to evaluate a CI/CD gate for an image.
/// </summary>
public sealed record GateEvaluateRequest
{
/// <summary>
/// The image digest to evaluate (e.g., sha256:abc123...).
/// </summary>
public required string ImageDigest { get; init; }
/// <summary>
/// The container repository name.
/// </summary>
public string? Repository { get; init; }
/// <summary>
/// The image tag, if any.
/// </summary>
public string? Tag { get; init; }
/// <summary>
/// The baseline reference for comparison.
/// Can be a snapshot ID, image digest, or strategy name (e.g., "last-approved", "production").
/// </summary>
public string? BaselineRef { get; init; }
/// <summary>
/// Optional policy ID to use for evaluation.
/// </summary>
public string? PolicyId { get; init; }
/// <summary>
/// Whether to allow override of blocking gates.
/// </summary>
public bool AllowOverride { get; init; }
/// <summary>
/// Justification for override (required if AllowOverride is true and gate would block).
/// </summary>
public string? OverrideJustification { get; init; }
/// <summary>
/// Source of the request (e.g., "cli", "api", "webhook").
/// </summary>
public string? Source { get; init; }
/// <summary>
/// CI/CD context identifier (e.g., "github-actions", "gitlab-ci").
/// </summary>
public string? CiContext { get; init; }
/// <summary>
/// Additional context for the gate evaluation.
/// </summary>
public GateEvaluationContext? Context { get; init; }
}
/// <summary>
/// Additional context for gate evaluation.
/// </summary>
public sealed record GateEvaluationContext
{
/// <summary>
/// Git branch name.
/// </summary>
public string? Branch { get; init; }
/// <summary>
/// Git commit SHA.
/// </summary>
public string? CommitSha { get; init; }
/// <summary>
/// CI/CD pipeline ID or job ID.
/// </summary>
public string? PipelineId { get; init; }
/// <summary>
/// Environment being deployed to (e.g., "production", "staging").
/// </summary>
public string? Environment { get; init; }
/// <summary>
/// Actor triggering the gate (e.g., user or service identity).
/// </summary>
public string? Actor { get; init; }
}
/// <summary>
/// Response from gate evaluation.
/// </summary>
public sealed record GateEvaluateResponse
{
/// <summary>
/// Unique decision ID for audit and tracking.
/// </summary>
public required string DecisionId { get; init; }
/// <summary>
/// The gate decision status.
/// </summary>
public required GateStatus Status { get; init; }
/// <summary>
/// Suggested CI exit code.
/// 0 = Pass, 1 = Warn (configurable pass-through), 2 = Fail/Block
/// </summary>
public required int ExitCode { get; init; }
/// <summary>
/// The image digest that was evaluated.
/// </summary>
public required string ImageDigest { get; init; }
/// <summary>
/// The baseline reference used for comparison.
/// </summary>
public string? BaselineRef { get; init; }
/// <summary>
/// When the decision was made (UTC).
/// </summary>
public required DateTimeOffset DecidedAt { get; init; }
/// <summary>
/// Summary message for the decision.
/// </summary>
public string? Summary { get; init; }
/// <summary>
/// Advisory or suggestion for the developer.
/// </summary>
public string? Advisory { get; init; }
/// <summary>
/// List of gate results.
/// </summary>
public IReadOnlyList<GateResultDto>? Gates { get; init; }
/// <summary>
/// Gate that caused the block (if blocked).
/// </summary>
public string? BlockedBy { get; init; }
/// <summary>
/// Detailed reason for the block.
/// </summary>
public string? BlockReason { get; init; }
/// <summary>
/// Suggestion for resolving the block.
/// </summary>
public string? Suggestion { get; init; }
/// <summary>
/// Whether an override was applied.
/// </summary>
public bool OverrideApplied { get; init; }
/// <summary>
/// Delta summary if available.
/// </summary>
public DeltaSummaryDto? DeltaSummary { get; init; }
}
/// <summary>
/// Result of a single gate evaluation.
/// </summary>
public sealed record GateResultDto
{
/// <summary>
/// Gate name/ID.
/// </summary>
public required string Name { get; init; }
/// <summary>
/// Gate result type.
/// </summary>
public required string Result { get; init; }
/// <summary>
/// Reason for the result.
/// </summary>
public required string Reason { get; init; }
/// <summary>
/// Additional note.
/// </summary>
public string? Note { get; init; }
/// <summary>
/// Condition expression that was evaluated.
/// </summary>
public string? Condition { get; init; }
}
/// <summary>
/// Gate evaluation status.
/// </summary>
public enum GateStatus
{
/// <summary>
/// Gate passed - proceed with deployment.
/// </summary>
Pass = 0,
/// <summary>
/// Gate produced warnings - proceed with caution.
/// </summary>
Warn = 1,
/// <summary>
/// Gate blocked - do not proceed.
/// </summary>
Fail = 2
}
/// <summary>
/// CI exit codes for gate evaluation.
/// </summary>
public static class GateExitCodes
{
/// <summary>
/// Gate passed - proceed with deployment.
/// </summary>
public const int Pass = 0;
/// <summary>
/// Gate produced warnings - configurable pass-through.
/// </summary>
public const int Warn = 1;
/// <summary>
/// Gate blocked - do not proceed.
/// </summary>
public const int Fail = 2;
}