Validate release archives in one pass

This commit is contained in:
rcourtman 2026-07-09 23:28:02 +01:00
parent 20b3102015
commit 453b478ac9
3 changed files with 18 additions and 12 deletions

View file

@ -336,7 +336,8 @@ TLS floor in the dynamic config.
itself is expected to finish much earlier.
Tarball entry validation must extract the requested files once per archive;
it must not decompress a multi-gigabyte release archive again for every
required entry.
required entry, and the release-promotion contract test must reject a return
to per-entry archive streaming.
A manually dispatched release rehearsal must activate the same signed
candidate build whenever its required `version` input is non-empty.
Scheduled watchdog rehearsals omit that input and must skip candidate

View file

@ -533,6 +533,7 @@ class ReleasePromotionPolicyTest(unittest.TestCase):
demo_reachability_helper = read(".github/scripts/check-demo-reachability.sh")
validation_workflow = read(".github/workflows/validate-release-assets.yml")
candidate_workflow = read(".github/workflows/build-release-candidate.yml")
release_validator = read("scripts/validate-release.sh")
helper = read("scripts/trigger-release.sh")
renderer = read("scripts/release_control/render_release_body.py")
policy = read("docs/release-control/v6/internal/RELEASE_PROMOTION_POLICY.md")
@ -619,6 +620,8 @@ class ReleasePromotionPolicyTest(unittest.TestCase):
self.assertIn("PULSE_UPDATE_SIGNING_PUBLIC_KEY=${{ vars.PULSE_UPDATE_SIGNING_PUBLIC_KEY }}", content)
self.assertIn("Validate installer signing key pins", candidate_workflow)
self.assertIn("timeout-minutes: 60", candidate_workflow)
self.assertIn('tar -xzf "$tarball" -C "$extract_dir" -- "$@"', release_validator)
self.assertNotIn('tar -xOf "$tarball" "$entry"', release_validator)
self.assertIn("go run ./scripts/release_update_key.go public-key-ssh", candidate_workflow)
self.assertIn("does not trust the configured release signing key", candidate_workflow)
self.assertIn("TRUSTED_SSH_PUBLIC_KEY", update_demo_workflow)

View file

@ -52,24 +52,26 @@ with_network_blocked() {
check_tar_entries_nonempty() {
local tarball="$1"
shift
local extract_dir
extract_dir="$(mktemp -d "$tmp_root/tar-entries.XXXXXX")"
if ! tar -xzf "$tarball" -C "$extract_dir" -- "$@"; then
error "$(basename "$tarball") is missing one or more required entries"
exit 1
fi
for entry in "$@"; do
if ! tar -tzf "$tarball" "$entry" >/dev/null 2>&1; then
error "$(basename "$tarball") missing entry: $entry"
exit 1
fi
# Examine type; skip size enforcement for symlinks
local type
type=$(tar -tvf "$tarball" "$entry" 2>/dev/null | awk 'NR==1 {print substr($0,1,1)}')
if [ "$type" = "l" ]; then
local extracted_path="$extract_dir/${entry#./}"
if [ -L "$extracted_path" ]; then
continue
fi
local size
size=$(tar -xOf "$tarball" "$entry" 2>/dev/null | wc -c | tr -d '[:space:]')
if [ -z "$size" ] || [ "$size" -le 0 ]; then
if [ ! -s "$extracted_path" ]; then
error "$(basename "$tarball") missing or empty entry: $entry"
exit 1
fi
done
rm -rf "$extract_dir"
}
http_header_value() {