docs: project docs, scripts, deployment configs, and evidence

This commit is contained in:
2026-04-02 11:22:17 +08:00
parent 4718980ab5
commit bbeeb63dfa
396 changed files with 165018 additions and 0 deletions

View File

@@ -0,0 +1,196 @@
param(
[string]$EvidenceDate = (Get-Date -Format 'yyyy-MM-dd')
)
$ErrorActionPreference = 'Stop'
$projectRoot = (Resolve-Path (Join-Path $PSScriptRoot '..\..')).Path
$frontendRoot = Join-Path $projectRoot 'frontend\admin'
$evidenceRoot = Join-Path $projectRoot "docs\evidence\ops\$EvidenceDate\sca"
$goCacheRoot = Join-Path $projectRoot '.cache'
$goBuildCache = Join-Path $goCacheRoot 'go-build'
$goModCache = Join-Path $goCacheRoot 'gomod'
$goPath = Join-Path $goCacheRoot 'gopath'
New-Item -ItemType Directory -Force $evidenceRoot, $goBuildCache, $goModCache, $goPath | Out-Null
function Invoke-CapturedCommand {
param(
[Parameter(Mandatory = $true)][string]$FilePath,
[string[]]$ArgumentList = @(),
[Parameter(Mandatory = $true)][string]$WorkingDirectory,
[Parameter(Mandatory = $true)][string]$StdOutPath,
[Parameter(Mandatory = $true)][string]$StdErrPath
)
Remove-Item $StdOutPath, $StdErrPath -Force -ErrorAction SilentlyContinue
$process = Start-Process `
-FilePath $FilePath `
-ArgumentList $ArgumentList `
-WorkingDirectory $WorkingDirectory `
-PassThru `
-WindowStyle Hidden `
-RedirectStandardOutput $StdOutPath `
-RedirectStandardError $StdErrPath `
-Wait
return $process.ExitCode
}
function Get-NpmAuditCounts {
param(
[Parameter(Mandatory = $true)][string]$JsonPath
)
if (-not (Test-Path $JsonPath)) {
return $null
}
$raw = Get-Content $JsonPath -Raw
if ([string]::IsNullOrWhiteSpace($raw)) {
return $null
}
$payload = $raw | ConvertFrom-Json
if (-not $payload.metadata -or -not $payload.metadata.vulnerabilities) {
return $null
}
return $payload.metadata.vulnerabilities
}
function Get-GovulnFindingCount {
param(
[Parameter(Mandatory = $true)][string]$JsonPath
)
if (-not (Test-Path $JsonPath)) {
return [pscustomobject]@{
Count = 0
IDs = @()
}
}
$count = 0
$ids = New-Object System.Collections.Generic.HashSet[string]
$insideFinding = $false
foreach ($line in Get-Content $JsonPath) {
if ($line -match '"finding"') {
$insideFinding = $true
$count++
continue
}
if ($insideFinding -and $line -match '"osv":\s*"([^"]+)"') {
[void]$ids.Add($Matches[1])
$insideFinding = $false
}
}
return [pscustomobject]@{
Count = $count
IDs = @($ids)
}
}
$timestamp = Get-Date -Format 'yyyyMMdd-HHmmss'
$prodAuditJson = Join-Path $evidenceRoot "npm-audit-prod-$timestamp.json"
$prodAuditErr = Join-Path $evidenceRoot "npm-audit-prod-$timestamp.stderr.txt"
$fullAuditJson = Join-Path $evidenceRoot "npm-audit-full-$timestamp.json"
$fullAuditErr = Join-Path $evidenceRoot "npm-audit-full-$timestamp.stderr.txt"
$govulnJson = Join-Path $evidenceRoot "govulncheck-$timestamp.jsonl"
$govulnErr = Join-Path $evidenceRoot "govulncheck-$timestamp.stderr.txt"
$summaryPath = Join-Path $evidenceRoot "SCA_SUMMARY_$timestamp.md"
$prodAuditExit = Invoke-CapturedCommand `
-FilePath 'npm.cmd' `
-ArgumentList @('audit', '--omit=dev', '--json', '--registry=https://registry.npmjs.org/') `
-WorkingDirectory $frontendRoot `
-StdOutPath $prodAuditJson `
-StdErrPath $prodAuditErr
$fullAuditExit = Invoke-CapturedCommand `
-FilePath 'npm.cmd' `
-ArgumentList @('audit', '--json', '--registry=https://registry.npmjs.org/') `
-WorkingDirectory $frontendRoot `
-StdOutPath $fullAuditJson `
-StdErrPath $fullAuditErr
Push-Location $projectRoot
try {
$env:GOCACHE = $goBuildCache
$env:GOMODCACHE = $goModCache
$env:GOPATH = $goPath
$govulnExit = Invoke-CapturedCommand `
-FilePath 'go' `
-ArgumentList @('run', 'golang.org/x/vuln/cmd/govulncheck@latest', '-json', './...') `
-WorkingDirectory $projectRoot `
-StdOutPath $govulnJson `
-StdErrPath $govulnErr
} finally {
Pop-Location
Remove-Item Env:GOCACHE, Env:GOMODCACHE, Env:GOPATH -ErrorAction SilentlyContinue
}
$prodCounts = Get-NpmAuditCounts -JsonPath $prodAuditJson
$fullCounts = Get-NpmAuditCounts -JsonPath $fullAuditJson
$govulnFindings = Get-GovulnFindingCount -JsonPath $govulnJson
$prodFindingSummary = if ($prodCounts) {
"info=$($prodCounts.info) low=$($prodCounts.low) moderate=$($prodCounts.moderate) high=$($prodCounts.high) critical=$($prodCounts.critical) total=$($prodCounts.total)"
} else {
'unavailable'
}
$fullFindingSummary = if ($fullCounts) {
"info=$($fullCounts.info) low=$($fullCounts.low) moderate=$($fullCounts.moderate) high=$($fullCounts.high) critical=$($fullCounts.critical) total=$($fullCounts.total)"
} else {
'unavailable'
}
$govulnIDsSummary = if ($govulnFindings.IDs.Count -gt 0) {
($govulnFindings.IDs | Sort-Object) -join ', '
} else {
'none'
}
$prodAuditJsonName = Split-Path $prodAuditJson -Leaf
$prodAuditErrName = Split-Path $prodAuditErr -Leaf
$fullAuditJsonName = Split-Path $fullAuditJson -Leaf
$fullAuditErrName = Split-Path $fullAuditErr -Leaf
$govulnJsonName = Split-Path $govulnJson -Leaf
$govulnErrName = Split-Path $govulnErr -Leaf
$summaryLines = @(
'# SCA Summary',
'',
"- Generated at: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss zzz')",
"- Project root: $projectRoot",
'',
'## Commands',
'',
'- `cd frontend/admin && npm.cmd audit --omit=dev --json --registry=https://registry.npmjs.org/`',
'- `cd frontend/admin && npm.cmd audit --json --registry=https://registry.npmjs.org/`',
'- `go run golang.org/x/vuln/cmd/govulncheck@latest -json ./...`',
'',
'## Exit Codes',
'',
"- npm audit production: $prodAuditExit",
"- npm audit full: $fullAuditExit",
"- govulncheck: $govulnExit",
'',
'## Findings',
'',
"- npm audit production: $prodFindingSummary",
"- npm audit full: $fullFindingSummary",
"- govulncheck reachable findings: $($govulnFindings.Count)",
"- govulncheck reachable IDs: $govulnIDsSummary",
'',
'## Evidence Files',
'',
"- $prodAuditJsonName",
"- $prodAuditErrName",
"- $fullAuditJsonName",
"- $fullAuditErrName",
"- $govulnJsonName",
"- $govulnErrName",
''
)
Set-Content -Path $summaryPath -Value ($summaryLines -join [Environment]::NewLine) -Encoding UTF8
Get-Content $summaryPath