Skip to content

Let a host that needs no launcher run its own smoke test - #168

Merged
frangarcj merged 2 commits into
masterfrom
next-macos-smoke-bash32
Aug 25, 2026
Merged

Let a host that needs no launcher run its own smoke test#168
frangarcj merged 2 commits into
masterfrom
next-macos-smoke-bash32

Conversation

@frangarcj

Copy link
Copy Markdown
Contributor

Every macOS leg of the executor has been dying since the Rosetta gate landed, after a complete and valid build. From the arm64 job of vitasdk/autobuilds#36:

21:55:13  self-contained headers OK (73 checked)
21:55:18  Vita GCC/binutils contract OK
21:55:18  [100%] Built target check-toolchain-contract
21:55:18  scripts/ci/build-host.sh: line 160: run[@]: unbound variable
21:55:19  ##[error]No files were found with the provided path: out/*. No artifacts will be uploaded.

The SDK is finalized, the static validation passes, the toolchain contract passes, and then the script exits and stages nothing. The Intel host fails behind it for the reason it should — no build-machine SDK found for x86_64-apple-darwin (needs arm64-apple-darwin) — because the arm64 artifact it cross-builds from was never uploaded. arm64-apple-darwin is a required host, so no snapshot can publish at all; the last one that did, sdk-snapshot-20260825.612.1, was built from 79a92784, the commit before this landed.

smoke_test_bootstrap's launcher prefix is an array that is empty for every host that runs its own binaries — the comment above it says so — and macOS's /bin/bash is 3.2:

$ /bin/bash --version | head -1
GNU bash, version 3.2.57(1)-release (arm64-apple-darwin25)
$ /bin/bash -c 'set -u; run=(); "${run[@]}" echo hola'
/bin/bash: run[@]: unbound variable
$ /bin/bash -c 'set -u; run=(); ${run[@]+"${run[@]}"} echo hola'
hola
$ /bin/bash -c 'set -u; run=(arch -x86_64); ${run[@]+"${run[@]}"} uname -m'
x86_64

build_and_stage() already carries the tolerant form, and the reason for it, three lines below the break.

The second commit is separable — take only the first if you would rather. This is the second time the same class has hit this file: fixed once in 9233c494a, reintroduced by the launcher. Deciding case by case which array can be empty is the judgement that failed, so every expansion in the scripts that run on a published host takes the tolerant form, and a test refuses any that do not. Run against the parent of this branch it names lines 161–165 of build-host.sh — the ones that broke the nightly:

$ tests/ci/test-empty-array-expansion.sh
scripts/ci/build-host.sh:161:  "${run[@]}" build/vitasdk/share/vdpm/bootstrap-vitasdk.sh --install-dir "$install_root"
scripts/ci/build-host.sh:162:  VITASDK="$install_root" "${run[@]}" "$install_root/bin/vdpm" --help >/dev/null
...

The test is static because it has to be: BASH_COMPAT=32 does not restore the 3.2 behaviour, so nothing on a Linux runner reproduces this by executing. The rewrite is mechanical and means the same thing whenever the array has elements; ${#name[@]} and ${!name[@]} are fine in 3.2 and are left alone. tests/ is outside the rule — it runs on ubuntu only.

Every suite in the checks job passes locally, and both bashes parse every rewritten script (bash -n, /bin/bash -n). tests/package/test-vdpm-bundle.sh fails here with and without this change: it wants a stage-1 SDK, and it is not in checks.


AI tools were used in preparing this PR (Claude Opus 5, Anthropic).

Every macOS leg of the executor has been dying since the Rosetta gate
landed, after a complete and valid build: the SDK is finalized, the
static validation passes, the toolchain contract passes, and then
build-host.sh exits with `run[@]: unbound variable` and stages nothing.
The upload finds an empty out/ and the Intel host, which needs the arm64
SDK to cross from, fails behind it. arm64-apple-darwin is a required
host, so no snapshot could publish at all.

The launcher prefix is an array that is empty for every host that runs
its own binaries -- as the comment above it says -- and macOS's
/bin/bash is 3.2, where expanding an empty array under `set -u` is an
error rather than nothing:

    $ /bin/bash -c 'set -u; run=(); "${run[@]}" echo hola'
    /bin/bash: run[@]: unbound variable
    $ /bin/bash -c 'set -u; run=(); ${run[@]+"${run[@]}"} echo hola'
    hola

build_and_stage() already carries the tolerant form, and the reason for
it, three lines below.
This has now bitten twice in the same file: fixed once in "Expand
possibly-empty arrays the way macOS's bash 3.2 tolerates", reintroduced
with the Rosetta launcher, and both times it cost a full macOS build
that finished, validated, and then staged nothing.

Deciding case by case which array can be empty is the judgement that
failed, so the remaining expansions in the scripts that run on a
published host all take the tolerant form -- it means the same thing as
the plain one whenever the array has elements -- and a test refuses any
that do not. Against the parent of this branch it names lines 161 to 165
of build-host.sh, the ones that broke the nightly.

The test is static because it has to be: BASH_COMPAT=32 does not restore
the 3.2 behaviour, so nothing running on a Linux runner can reproduce it
by executing anything.
@frangarcj
frangarcj merged commit d831fe3 into master Aug 25, 2026
13 of 19 checks passed
@frangarcj
frangarcj deleted the next-macos-smoke-bash32 branch August 26, 2026 19:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant