Files
getDomain/verify_domain_release.ps1
Your Name 7cbde2aa78 d
2026-04-22 14:13:21 +08:00

135 lines
4.0 KiB
PowerShell

param(
[string]$ZipPath,
[string]$HashPath
)
$ErrorActionPreference = "Stop"
function Resolve-LatestReleaseFile {
param(
[string]$ReleaseRoot,
[string]$Filter
)
$item = Get-ChildItem -LiteralPath $ReleaseRoot -Filter $Filter | Sort-Object LastWriteTime -Descending | Select-Object -First 1
if (-not $item) {
throw "No file found for filter: $Filter"
}
return $item.FullName
}
$root = Split-Path -Parent $MyInvocation.MyCommand.Path
$releaseRoot = Join-Path $root "release"
if (-not $ZipPath) {
$ZipPath = Resolve-LatestReleaseFile -ReleaseRoot $releaseRoot -Filter "*.zip"
}
if (-not $HashPath) {
$baseName = [System.IO.Path]::GetFileNameWithoutExtension($ZipPath)
$candidate = Join-Path $releaseRoot "$baseName.sha256.txt"
if (Test-Path -LiteralPath $candidate) {
$HashPath = $candidate
}
else {
$HashPath = Resolve-LatestReleaseFile -ReleaseRoot $releaseRoot -Filter "*.sha256.txt"
}
}
if (-not (Test-Path -LiteralPath $ZipPath)) {
throw "Zip not found: $ZipPath"
}
if (-not (Test-Path -LiteralPath $HashPath)) {
throw "Hash file not found: $HashPath"
}
$hashLines = Get-Content -LiteralPath $HashPath
$expectedHash = ($hashLines | Where-Object { $_ -like "sha256=*" } | Select-Object -First 1) -replace "^sha256=", ""
$expectedFile = ($hashLines | Where-Object { $_ -like "file=*" } | Select-Object -First 1) -replace "^file=", ""
if (-not $expectedHash) {
throw "sha256 entry missing in $HashPath"
}
$actualHash = (Get-FileHash -LiteralPath $ZipPath -Algorithm SHA256).Hash.ToLowerInvariant()
$fileName = [System.IO.Path]::GetFileName($ZipPath)
Add-Type -AssemblyName System.IO.Compression.FileSystem
$zip = [System.IO.Compression.ZipFile]::OpenRead($ZipPath)
$missingEntries = @()
$expectsSmokeReport = $false
try {
$requiredEntries = @(
"README_RELEASE.txt",
"release_manifest.json",
"domain-api/README.md",
"domain-web/README.md",
"domainCheck/detect_worker.py",
"domainCheck/app/config.py",
"domainCheck/detect/register.py",
"domainCheck/.env.example",
"scripts/package_domain_release.ps1",
"scripts/verify_domain_release.ps1",
"scripts/package_domain_release.sh",
"scripts/verify_domain_release.sh",
"scripts/smoke_test_stack.ps1"
)
$entryNames = $zip.Entries | ForEach-Object { $_.FullName.Replace('\', '/') }
$manifestEntry = $zip.Entries | Where-Object { $_.FullName.Replace('\', '/') -eq "release_manifest.json" } | Select-Object -First 1
if ($manifestEntry) {
$manifestStream = $manifestEntry.Open()
$manifestReader = $null
try {
$manifestReader = New-Object System.IO.StreamReader($manifestStream)
$manifestText = $manifestReader.ReadToEnd()
$manifest = $manifestText | ConvertFrom-Json
$smokeReport = [string]$manifest.smoke_test.report
if (-not [string]::IsNullOrWhiteSpace($smokeReport)) {
$expectsSmokeReport = $true
}
}
finally {
if ($manifestReader) {
$manifestReader.Dispose()
}
$manifestStream.Dispose()
}
}
foreach ($required in $requiredEntries) {
if ($entryNames -notcontains $required) {
$missingEntries += $required
}
}
if ($expectsSmokeReport -and ($entryNames -notcontains "smoke_test_report.json")) {
$missingEntries += "smoke_test_report.json"
}
}
finally {
$zip.Dispose()
}
$ok = ($actualHash -eq $expectedHash.ToLowerInvariant()) -and ($missingEntries.Count -eq 0) -and (($expectedFile -eq "") -or ($expectedFile -eq $fileName))
$report = [ordered]@{
ok = $ok
zip = $ZipPath
hash_file = $HashPath
expected_file = $expectedFile
actual_file = $fileName
expected_sha256 = $expectedHash.ToLowerInvariant()
actual_sha256 = $actualHash
missing_entries = $missingEntries
}
$report | ConvertTo-Json -Depth 6
if (-not $ok) {
exit 1
}