168 lines
6.3 KiB
PowerShell
168 lines
6.3 KiB
PowerShell
param(
|
|
[string]$ApiUrl = "http://192.168.3.90:8001/api/v1",
|
|
[string]$ArtifactRoot = "",
|
|
[string]$SampleContractPath = "",
|
|
[string]$MemberPassword = "123456"
|
|
)
|
|
|
|
$ErrorActionPreference = "Stop"
|
|
|
|
$repoRoot = (Resolve-Path (Join-Path $PSScriptRoot "..")).Path
|
|
$backendDir = Join-Path $repoRoot "backend"
|
|
$timestamp = Get-Date -Format "yyyy-MM-ddTHH-mm-ss-fff"
|
|
|
|
if ([string]::IsNullOrWhiteSpace($ArtifactRoot)) {
|
|
$ArtifactRoot = Join-Path $repoRoot "project-docs\qa-artifacts\pdf-acceptance-gate"
|
|
}
|
|
if (-not [System.IO.Path]::IsPathRooted($ArtifactRoot)) {
|
|
$ArtifactRoot = Join-Path $repoRoot $ArtifactRoot
|
|
}
|
|
if (-not [string]::IsNullOrWhiteSpace($SampleContractPath) -and -not [System.IO.Path]::IsPathRooted($SampleContractPath)) {
|
|
$SampleContractPath = Join-Path $repoRoot $SampleContractPath
|
|
}
|
|
|
|
$artifactDir = Join-Path $ArtifactRoot $timestamp
|
|
New-Item -ItemType Directory -Force -Path $artifactDir | Out-Null
|
|
|
|
$summaryJson = Join-Path $artifactDir "pdf-acceptance-gate-wrapper-summary.json"
|
|
$summaryMd = Join-Path $artifactDir "pdf-acceptance-gate-wrapper-summary.md"
|
|
$logPath = Join-Path $artifactDir "pdf-acceptance-gate.log"
|
|
$gitStatusPath = Join-Path $artifactDir "git-status.txt"
|
|
|
|
$checks = New-Object System.Collections.Generic.List[object]
|
|
|
|
function Add-Check {
|
|
param(
|
|
[string]$Key,
|
|
[string]$Label,
|
|
[ValidateSet("pass", "fail", "warn", "skip")]
|
|
[string]$Status,
|
|
[string]$Detail,
|
|
[bool]$Required = $true,
|
|
[hashtable]$Meta = @{}
|
|
)
|
|
|
|
$checks.Add([ordered]@{
|
|
key = $Key
|
|
label = $Label
|
|
status = $Status
|
|
required = $Required
|
|
detail = $Detail
|
|
meta = $Meta
|
|
}) | Out-Null
|
|
}
|
|
|
|
function Save-Json {
|
|
param([string]$Path, [object]$Value)
|
|
$Value | ConvertTo-Json -Depth 18 | Set-Content -Encoding UTF8 -Path $Path
|
|
}
|
|
|
|
if (-not (Test-Path "$HOME\.Codex\skills\gstack\bin")) {
|
|
Add-Check -Key "gstack" -Label "gstack preflight" -Status "fail" -Detail "gstack is missing"
|
|
} else {
|
|
Add-Check -Key "gstack" -Label "gstack preflight" -Status "pass" -Detail "GSTACK_OK"
|
|
}
|
|
|
|
$pythonPath = Join-Path $backendDir ".venv\Scripts\python.exe"
|
|
if (-not (Test-Path $pythonPath)) {
|
|
Add-Check -Key "python" -Label "backend venv python" -Status "fail" -Detail "Backend venv python missing" -Meta @{ path = $pythonPath }
|
|
} else {
|
|
Add-Check -Key "python" -Label "backend venv python" -Status "pass" -Detail "Backend venv python found" -Meta @{ path = $pythonPath }
|
|
}
|
|
|
|
$toolPath = Join-Path $backendDir "tools\pdf_acceptance_gate.py"
|
|
if (-not (Test-Path $toolPath)) {
|
|
Add-Check -Key "tool" -Label "pdf acceptance tool" -Status "fail" -Detail "Tool missing" -Meta @{ path = $toolPath }
|
|
} else {
|
|
Add-Check -Key "tool" -Label "pdf acceptance tool" -Status "pass" -Detail "Tool found" -Meta @{ path = $toolPath }
|
|
}
|
|
|
|
$gitStatus = git -C $repoRoot status --short
|
|
($gitStatus -join [Environment]::NewLine) | Set-Content -Encoding UTF8 -Path $gitStatusPath
|
|
if ($gitStatus) {
|
|
Add-Check -Key "working_tree" -Label "working tree" -Status "warn" -Required $false -Detail "Working tree has uncommitted changes; gate is advisory" -Meta @{ artifact = $gitStatusPath }
|
|
} else {
|
|
Add-Check -Key "working_tree" -Label "working tree" -Status "pass" -Detail "Working tree is clean" -Meta @{ artifact = $gitStatusPath }
|
|
}
|
|
|
|
$failedPreflight = @($checks | Where-Object { $_.required -and $_.status -eq "fail" })
|
|
if ($failedPreflight.Count -eq 0) {
|
|
$args = @(
|
|
$toolPath,
|
|
"--api-base", $ApiUrl,
|
|
"--artifact-dir", $artifactDir,
|
|
"--password", $MemberPassword
|
|
)
|
|
if (-not [string]::IsNullOrWhiteSpace($SampleContractPath)) {
|
|
$args += @("--sample-contract-path", $SampleContractPath)
|
|
}
|
|
|
|
Push-Location $backendDir
|
|
$previousErrorActionPreference = $ErrorActionPreference
|
|
$ErrorActionPreference = "Continue"
|
|
try {
|
|
$output = & $pythonPath @args 2>&1
|
|
$exitCode = $LASTEXITCODE
|
|
} finally {
|
|
$ErrorActionPreference = $previousErrorActionPreference
|
|
Pop-Location
|
|
}
|
|
($output -join [Environment]::NewLine) | Set-Content -Encoding UTF8 -Path $logPath
|
|
|
|
if ($exitCode -eq 0) {
|
|
Add-Check -Key "pdf_acceptance_gate" -Label "pdf acceptance gate" -Status "pass" -Detail "PDF acceptance gate passed" -Meta @{ artifact_dir = $artifactDir; log = $logPath }
|
|
} else {
|
|
Add-Check -Key "pdf_acceptance_gate" -Label "pdf acceptance gate" -Status "fail" -Detail "PDF acceptance gate failed" -Meta @{ artifact_dir = $artifactDir; log = $logPath }
|
|
}
|
|
}
|
|
|
|
$failedRequired = @($checks | Where-Object { $_.required -and $_.status -eq "fail" })
|
|
$warningsList = @($checks | Where-Object { $_.status -eq "warn" })
|
|
$overallStatus = if ($failedRequired.Count -gt 0) { "FAIL" } elseif ($warningsList.Count -gt 0) { "WARN" } else { "PASS" }
|
|
|
|
$summary = [ordered]@{
|
|
name = "pdf-acceptance-gate-wrapper"
|
|
status = $overallStatus
|
|
generated_at = (Get-Date).ToUniversalTime().ToString("o")
|
|
artifact_dir = $artifactDir
|
|
targets = [ordered]@{
|
|
api_url = $ApiUrl
|
|
sample_contract_path = $SampleContractPath
|
|
}
|
|
checks = $checks
|
|
totals = [ordered]@{
|
|
total = $checks.Count
|
|
failed_required = $failedRequired.Count
|
|
warnings = $warningsList.Count
|
|
}
|
|
}
|
|
Save-Json -Path $summaryJson -Value $summary
|
|
|
|
$markdown = New-Object System.Collections.Generic.List[string]
|
|
$markdown.Add("# PDF Acceptance Gate Wrapper") | Out-Null
|
|
$markdown.Add("") | Out-Null
|
|
$markdown.Add("- Status: $overallStatus") | Out-Null
|
|
$markdown.Add("- Generated at: $($summary.generated_at)") | Out-Null
|
|
$markdown.Add("- Artifact dir: $artifactDir") | Out-Null
|
|
$markdown.Add("- API URL: $ApiUrl") | Out-Null
|
|
$markdown.Add("") | Out-Null
|
|
$markdown.Add("| Check | Required | Status | Detail |") | Out-Null
|
|
$markdown.Add("|---|---:|---|---|") | Out-Null
|
|
foreach ($check in $checks) {
|
|
$markdown.Add("| $($check.label) | $($check.required) | $($check.status.ToUpperInvariant()) | $($check.detail) |") | Out-Null
|
|
}
|
|
$markdown.Add("") | Out-Null
|
|
$markdown.Add("Artifacts:") | Out-Null
|
|
$markdown.Add("") | Out-Null
|
|
$markdown.Add('- `pdf-acceptance-gate-wrapper-summary.json`') | Out-Null
|
|
$markdown.Add('- `pdf-acceptance-gate-wrapper-summary.md`') | Out-Null
|
|
$markdown.Add('- `pdf-acceptance-gate.log`') | Out-Null
|
|
$markdown.Add('- `pdf-acceptance-gate-summary.json`') | Out-Null
|
|
$markdown.Add('- `pdf-acceptance-gate-summary.md`') | Out-Null
|
|
$markdown | Set-Content -Encoding UTF8 -Path $summaryMd
|
|
|
|
Write-Host "PDF_ACCEPTANCE_GATE_$overallStatus $artifactDir"
|
|
if ($overallStatus -eq "FAIL") {
|
|
throw "PDF acceptance gate failed. See $summaryMd"
|
|
}
|