mirror of
https://github.com/kellymichels/zscripts-token-savers
synced 2026-10-07 07:18:18 +00:00
The mirror's deploy pair had drifted ~280 lines behind: it lacked the
transactional .env preserve/restore (an interrupted deploy could destroy
server-side env files), the stderr-flattening step wrapper (a successful
deploy reported failure and skipped its own verification), and the
verification rework (channel re-picked every retry, edge only with a Host
to route by, verify.timeoutSeconds, honest split of "stale build" vs "no
channel answered").
The sync is byte-faithful to the private tree except where the mirror's
own Sanitization suite demands otherwise - and it caught the first copy:
three failures for private project names, a private domain, and a
private-only script name that rode along in comments. Each war story keeps
its lesson and loses its cast, per the convention already in the file
("EvoCivilCode: deploy/" was already published as "(deploy/, infra/,
...)"). That suite going red on an unsanitized copy is exactly what it
exists for.
Also in this change:
- tests/VerifyPlan.Tests.ps1 - the channel-selection rules are pure
functions and Pester pins them (no domain => no edge attempt; the PS 5.1
one-element-unroll trap). First verification tests in the mirror.
- README: the verify block now documents viaProxy/upstream (they shipped
in the docker-network read but were never in the README),
timeoutSeconds, and the channel order with why it re-resolves per retry.
- README.txt: generated plain-text twin, via scripts/readme_txt.py
(vendored from the fleet's reference implementation; the file is
generated, never edited by hand).
- CHANGELOG.md/.txt: entries merged into the existing Unreleased sections.
CHECKSUMS.txt refreshed (42 entries). Pester: 240 passed, 0 failed.
Both synced files parse clean.
Observed, untouched: the Unreleased section carries duplicate "### Fixed"
headings from earlier appends; folding them risks reordering entries whose
prose references their neighbours, so it is left for the next release cut
(zbump #110 rolls Unreleased into the version being cut).
97 lines
4.3 KiB
PowerShell
97 lines
4.3 KiB
PowerShell
# Deploy-verification planning (#101).
|
|
#
|
|
# Invoke-Pester .\tests
|
|
#
|
|
# The wrong-vhost failure was never about parsing a response - it was about
|
|
# WHICH channel got asked. So the channel-selection rules live in a pure
|
|
# function (Get-VerifyAttempts) and are pinned here, where they can be tested
|
|
# without an EC2 box: a project with no domain must never produce an edge
|
|
# attempt, because an edge request with no Host header can only reach the
|
|
# default vhost - which is a different product. That exact gap read evo.ehs's
|
|
# build number during evo-ai deploys twice on 2026-08-31 alone.
|
|
#
|
|
# ZHelpers.ps1 is dot-sourced rather than zdeploy.ps1: zdeploy executes its
|
|
# main flow on load, helpers only define functions.
|
|
|
|
BeforeAll {
|
|
. (Join-Path (Split-Path -Parent $PSScriptRoot) "ZHelpers.ps1")
|
|
|
|
function New-Proj {
|
|
param($Verify = $null, $Domain = $null, $Deploy = $null)
|
|
$p = [pscustomobject]@{}
|
|
if ($null -ne $Verify) { $p | Add-Member verify ([pscustomobject]$Verify) }
|
|
if ($null -ne $Domain) { $p | Add-Member domain $Domain }
|
|
if ($null -ne $Deploy) { $p | Add-Member deploy ([pscustomobject]$Deploy) }
|
|
return $p
|
|
}
|
|
}
|
|
|
|
Describe "Get-VerifyAttempts" {
|
|
|
|
It "puts the docker-network read first when configured" {
|
|
$proj = New-Proj -Verify @{ viaProxy = "evo_edge_proxy"; upstream = "app:80"; port = 8005 } -Domain "x.example"
|
|
$attempts = Get-VerifyAttempts -Proj $proj -ExecCmd "docker exec ..."
|
|
$attempts[0].Kind | Should -Be 'exec'
|
|
($attempts | ForEach-Object Kind) | Should -Be @('exec', 'port', 'edge')
|
|
}
|
|
|
|
It "never asks the edge for a project with no domain (the #101 trap)" {
|
|
# The shape that hit #101: viaProxy + port, no domain. The old code
|
|
# fell back to the bare IP here and read another product's counter.
|
|
$proj = New-Proj -Verify @{ viaProxy = "evo_edge_proxy"; upstream = "deploy-app-1:8000"; port = 8005; path = "/health" }
|
|
$attempts = Get-VerifyAttempts -Proj $proj -ExecCmd "docker exec ..."
|
|
($attempts | ForEach-Object Kind) | Should -Not -Contain 'edge'
|
|
}
|
|
|
|
It "returns an empty plan when nothing trustworthy exists" {
|
|
# No verify config, no domain: the caller must SKIP, not guess.
|
|
$attempts = Get-VerifyAttempts -Proj (New-Proj) -ExecCmd ""
|
|
$attempts.Count | Should -Be 0
|
|
}
|
|
|
|
It "keeps the edge for a project with a domain, with its Host header" {
|
|
$proj = New-Proj -Domain "jwks.example"
|
|
$attempts = Get-VerifyAttempts -Proj $proj -ExecCmd ""
|
|
$attempts.Count | Should -Be 1
|
|
$attempts[0].Kind | Should -Be 'edge'
|
|
$attempts[0].HostHeader | Should -Be "jwks.example"
|
|
}
|
|
|
|
It "prefers deploy.verifyHost over domain for the edge Host header" {
|
|
$proj = New-Proj -Domain "old.example" -Deploy @{ verifyHost = "new.example" }
|
|
$attempts = Get-VerifyAttempts -Proj $proj -ExecCmd ""
|
|
$attempts[0].HostHeader | Should -Be "new.example"
|
|
}
|
|
|
|
It "carries the verify path into the port attempt, defaulting sensibly" {
|
|
$proj = New-Proj -Verify @{ port = 8005; path = "/health" }
|
|
(Get-VerifyAttempts -Proj $proj -ExecCmd "")[0].Path | Should -Be "/health"
|
|
$proj2 = New-Proj -Verify @{ port = 9000 }
|
|
(Get-VerifyAttempts -Proj $proj2 -ExecCmd "")[0].Path | Should -Be "/api/build-version"
|
|
}
|
|
|
|
It "survives the PS 5.1 one-element unroll" {
|
|
# A single attempt must still come back as something with .Count and
|
|
# index access - the pipeline trap that deadlocked ztests day 2.
|
|
$proj = New-Proj -Verify @{ port = 8005 }
|
|
$attempts = Get-VerifyAttempts -Proj $proj -ExecCmd ""
|
|
$attempts.Count | Should -Be 1
|
|
$attempts[0].Kind | Should -Be 'port'
|
|
}
|
|
}
|
|
|
|
Describe "Get-VerifyTimeout" {
|
|
|
|
It "uses the caller's default when the project says nothing" {
|
|
Get-VerifyTimeout -Proj (New-Proj) -DefaultSec 30 | Should -Be 30
|
|
}
|
|
|
|
It "lets a slow-booting project widen its own window" {
|
|
# An app that runs database migrations in its entrypoint exceeds
|
|
# 30s on every deploy that ships one, and a warning that fires on
|
|
# routine success trains people to ignore the real one.
|
|
$proj = New-Proj -Verify @{ viaProxy = "p"; upstream = "u"; timeoutSeconds = 120 }
|
|
Get-VerifyTimeout -Proj $proj -DefaultSec 30 | Should -Be 120
|
|
}
|
|
}
|