diff --git a/CHECKSUMS.txt b/CHECKSUMS.txt index 8e22d86..910794f 100644 --- a/CHECKSUMS.txt +++ b/CHECKSUMS.txt @@ -8,14 +8,14 @@ f1fb8fb35ec468cf9c084e28f77398b59479daab06fe96909c6c2e7e8ea1a561 zchecksums.cmd 7f967d89feeeaf4ca1fbea93a3d013a1a7b0141e11ec6f2888b6d4ac0bdb3485 zchecksums.ps1 6126973cbc0ccb22785340354afb9a1495f3d9798f60d3e6fc1c3d3a92285d67 zdeploy.cmd -bd4868914e022bb1cf4a4e755d69d76a42eddbcfbce5ae441f08969233a4004d zdeploy.ps1 +d14f1d1f51b4a82c8166d81ae87f7a13663a2b0386c8c1c94ec556caa9ce62bb zdeploy.ps1 1c2c99cbb986fa8993d47404eaba89ae05b854b6396a541783b46ee22ba359e9 zec2.cmd 6b427881c670e2c1ba2ce95bee1ee446be770da85cde1fd91c36cbf40c39cff0 zec2.ps1 0e4e9cbd19fdd151bdc07df8d72aee577e446e2280dbc7afa0039d503364e991 zec2_rotatekeys.cmd 25068fa51dddd221c0b05628d78c7fa14f1d8c853c6c3f94ec760430122a1589 zec2_rotatekeys.ps1 408d43e37a6febf3543dd74f449b00d6cdb4cfa6d5ae6ab48b6b840bbfd63ecb zec2online.cmd f1c3a0f911da86e018f9b3d4d7c9be048210aa56c016548570edfbab79fed8ef zec2online.ps1 -832ff9fb1f9b318b0868272ba64194f6f7bb4259dea2e6d0417787cec990f2c1 ZHelpers.ps1 +e904b06017619f0ea13a79c34f56c70e642a5f0aae7dfab55159885aac2ac384 ZHelpers.ps1 1e1dcdc76250d57b2b393a650fa853452f4cb271b58a05a7dc8c01f436958424 zkill.cmd 1eb4c23bdc0ed1a82dc495c623b49e5dcd4e342f026b4d896e32c79d592667db zkill.ps1 1c908b69fb9200610e080ac6bb8f4c15d3d7edf402d2e119c2405158e1986a52 ZKiller.ps1 diff --git a/ZHelpers.ps1 b/ZHelpers.ps1 index eb807ba..e1c7396 100644 --- a/ZHelpers.ps1 +++ b/ZHelpers.ps1 @@ -563,14 +563,50 @@ function Get-LabelFromVersionJson { } function Get-LabelFromBuildJsonObj { + <# + .SYNOPSIS + The build label out of a parsed build-version.json, or $null. + + .DESCRIPTION + Three stamp shapes, and this has to read all of them because deploy + verification runs BOTH sides through it - the local stamp and the one read + back from the running container. A shape it cannot read does not fail + loudly; it collapses both sides to the same wrong string and the comparison + passes unconditionally, which is worse than having no check at all. + + { "major":1, "rc":0, "beta":0, "alpha":0, "build":98 } object form + { "version": "v1.0.0.0.98" } string form + { "productVersion": "1.2", "buildNumber": 7 } legacy form + + The string form is what the versioning scheme specifies and what zbump + writes, so it is checked FIRST - a stamp carrying both an explicit version + and stray numeric fields means the version it states. + + Earned the hard way: the string form used to fall through to the legacy + branch, where productVersion is null ("") and buildNumber is null (0), so + EVERY string-form stamp became "v.0". A site verified `expect v.0` against + a live `v.0` and reported PASS while serving whatever it liked. + #> param($obj) if (-not $obj) { return $null } - # Five-segment scheme: v{major}.{rc}.{beta}.{alpha}.{build} + + # String form: the version is stated, so state it back. Trimmed, and given + # the leading v the other branches add, so all three shapes are comparable. + if (-not [string]::IsNullOrWhiteSpace([string]$obj.version)) { + $v = ([string]$obj.version).Trim() + return $(if ($v -match '^[vV]') { 'v' + $v.Substring(1) } else { "v$v" }) + } + + # Object form: v{major}.{rc}.{beta}.{alpha}.{build} if ($null -ne $obj.build -or $null -ne $obj.alpha) { $alpha = if ($null -ne $obj.alpha) { [int]$obj.alpha } else { 1 } return "v$([int]$obj.major).$([int]$obj.rc).$([int]$obj.beta).$alpha.$([int]$obj.build)" } + # Legacy two-part stamp (projects not yet migrated): v{productVersion}.{buildNumber} + # Only reached when there is something to build it from; otherwise $null, so + # a caller sees "no label" instead of a label that matches everything. + if ([string]::IsNullOrWhiteSpace([string]$obj.productVersion) -and $null -eq $obj.buildNumber) { return $null } return "v$([string]$obj.productVersion).$([int]$obj.buildNumber)" } diff --git a/zdeploy.ps1 b/zdeploy.ps1 index 2de3557..e96b777 100644 --- a/zdeploy.ps1 +++ b/zdeploy.ps1 @@ -546,6 +546,16 @@ function Wait-VerifyStaticBuild { # advances deliberately — one version bump per release — so "is the # build I just packed live?" means an exact match. $expectedLabel = Get-LabelFromBuildJsonObj $PreZipBuildState + # A stamp we cannot read is not a version to check against. Comparing an + # unreadable local label to an unreadable remote one is how a verification + # once passed while the container served anything it liked, so refuse to + # run rather than run a comparison that cannot fail. + if ([string]::IsNullOrWhiteSpace($expectedLabel)) { + Write-Host "`n--- [$Key version] NOT VERIFIED - build-version.json is present but unreadable ---" -ForegroundColor Yellow + Write-Host " Got: $(($PreZipBuildState | ConvertTo-Json -Compress -Depth 4))" -ForegroundColor DarkGray + Write-Host " Expected one of: {`"version`":`"v1.0.0.0.0`"} | {major,rc,beta,alpha,build} | {productVersion,buildNumber}" -ForegroundColor DarkGray + return + } Write-Host "`n--- [$Key] Live build verification (expect $expectedLabel) ---" -ForegroundColor Cyan $containerName = $Proj.remote.containerName $deadline = (Get-Date).AddSeconds(45) @@ -565,7 +575,7 @@ function Wait-VerifyStaticBuild { } if ($r) { $remoteLabel = Get-LabelFromBuildJsonObj $r - if ($remoteLabel -eq $expectedLabel) { + if ($remoteLabel -and $remoteLabel -eq $expectedLabel) { Write-Host " PASS - live build $remoteLabel matches expected." -ForegroundColor Green return }