From 7a091238dcf1e12d06d1a2f8ab0a6baa449cc44e Mon Sep 17 00:00:00 2001 From: Jiun Bae Date: Tue, 22 Sep 2026 19:27:36 +0900 Subject: [PATCH] ci(release): wait for the installer fixture server to actually serve MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Both installer rehearsals start `http.server` in the background and then `sleep 1` before pointing the installer at it. The Windows rehearsal failed twice in a row on v0.1.13 with Invoke-WebRequest: No connection could be made because the target machine actively refused it. and nothing else: the server's own output went to a hidden window, so a server that never came up looked exactly like a broken installer. Wait for the port to accept instead of guessing, and fail with the server's output when it never does. Both rehearsals get it; the POSIX one has the same race and has simply been luckier. On Windows, also refuse the Microsoft Store alias stub. It is named `python`, it is on PATH, and it starts — so `Start-Process` succeeds and `$server.HasExited` stays false — while serving nothing, which matches the failure exactly. Resolving `python`/`python3` past `WindowsApps` and capturing stderr turns that into a named error rather than a refused connection six seconds later. Co-Authored-By: Claude Opus 5 (1M context) --- .github/workflows/release.yml | 53 +++++++++++++++++++++++++++++++---- 1 file changed, 48 insertions(+), 5 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c808b80..2ca1852 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -196,10 +196,23 @@ jobs: mkdir -p "$fixture" "$install_dir" cp "$ARCHIVE" "$fixture/aas-$TARGET.tar.gz" cp "$CHECKSUM" "$fixture/aas-$TARGET.sha256" - python3 -m http.server 18765 --bind 127.0.0.1 --directory "$fixture" >/dev/null 2>&1 & + server_log="$RUNNER_TEMP/aas-installer-fixture.log" + python3 -m http.server 18765 --bind 127.0.0.1 --directory "$fixture" >"$server_log" 2>&1 & server_pid=$! trap 'kill "$server_pid" 2>/dev/null || true' EXIT - sleep 1 + # Wait for the port to accept. A fixed sleep raced the interpreter's startup, and a + # server that never came up was indistinguishable from the installer being broken. + ready=0 + for _ in $(seq 1 150); do + if ! kill -0 "$server_pid" 2>/dev/null; then break; fi + if curl -fsS -o /dev/null "http://127.0.0.1:18765/aas-$TARGET.sha256"; then ready=1; break; fi + sleep 0.2 + done + if [ "$ready" != 1 ]; then + echo "installer fixture server never served on 127.0.0.1:18765" >&2 + cat "$server_log" >&2 || true + exit 1 + fi AAS_DOWNLOAD_BASE=http://127.0.0.1:18765 \ AAS_BIN_DIR="$install_dir" \ AAS_SKIP_ATTESTATION=1 \ @@ -227,12 +240,42 @@ jobs: New-Item -ItemType Directory -Force -Path $fixture, $installDir | Out-Null Copy-Item $env:ARCHIVE (Join-Path $fixture "aas-$env:TARGET.zip") Copy-Item $env:CHECKSUM (Join-Path $fixture "aas-$env:TARGET.sha256") - $server = Start-Process python -ArgumentList @( + # The Microsoft Store alias stub is named `python` and on PATH: it starts, so + # `Start-Process` succeeds, and then serves nothing. + $python = $null + foreach ($candidate in @("python", "python3")) { + $resolved = Get-Command $candidate -ErrorAction SilentlyContinue + if ($resolved -and $resolved.Source -notlike "*WindowsApps*") { + $python = $resolved.Source + break + } + } + if (-not $python) { throw "no usable python on PATH to serve the installer fixture" } + $serverLog = Join-Path $env:RUNNER_TEMP "aas-installer-fixture.log" + $server = Start-Process $python -ArgumentList @( "-m", "http.server", "18766", "--bind", "127.0.0.1", "--directory", $fixture - ) -PassThru -WindowStyle Hidden + ) -PassThru -NoNewWindow -RedirectStandardError $serverLog $originalUserPath = [Environment]::GetEnvironmentVariable("Path", "User") try { - Start-Sleep -Seconds 1 + # Wait for the port to accept. A fixed sleep raced the interpreter's startup, and a + # server that never came up was indistinguishable from the installer being broken. + $ready = $false + foreach ($attempt in 1..150) { + if ($server.HasExited) { break } + try { + $probe = New-Object System.Net.Sockets.TcpClient + $probe.Connect("127.0.0.1", 18766) + $probe.Close() + $ready = $true + break + } catch { + Start-Sleep -Milliseconds 200 + } + } + if (-not $ready) { + $detail = if (Test-Path $serverLog) { Get-Content $serverLog -Raw } else { "(no output)" } + throw "installer fixture server never accepted on 127.0.0.1:18766. $detail" + } $env:AAS_DOWNLOAD_BASE = "http://127.0.0.1:18766" $env:AAS_BIN_DIR = $installDir $env:AAS_SKIP_ATTESTATION = "1"