Close the free headroom in the clean-machine simulation
Assert arch and signature on every downloaded Mach-O. This is the one genuine gap the simulation had: Rosetta 2 is preinstalled on hosted runners and absent from a factory-fresh Mac, so an x86_64-only llama.cpp, whisper.cpp, Node or uv payload runs green here and dies with "bad CPU type in executable" for the user. llama-server launching under `assert-llama-loads.sh` does not rule that out, because Rosetta makes it launch. The new `macho` check reads `file -b` (`lipo` is an xcrun shim and is gone after masking, as the desktop lane already notes) and keys the expected arch off `uname -m`, so macos-15-intel expects x86_64. It also requires at least an ad-hoc signature on arm64, which closes the AMFI "Killed: 9" class that uv has already been bitten by; the check is skipped on x86_64, where unsigned code loads fine and so is not the same defect. It fails when the scan finds nothing, since an empty scan reads exactly like a clean one. Make absence real rather than PATH-hidden. uv probes well-known interpreter locations and the framework loader ignores PATH entirely, so hiding the toolcache only hid it from `command -v`. Empty /usr/local (it EXISTS on a factory-fresh Mac as a SIP-exempt firmlink, and is empty; it is /usr/local/bin that is absent, so the directory itself stays), move the hosted toolcache and /Library/Frameworks/Python.framework aside, and clear the developer dotdirs and caches. A populated uv or pip cache can also satisfy a resolution that would fail on a user's machine. Every removal goes through --remove and is recorded in the generated restore.sh, guarded so a path the install recreated is not buried inside its own restore. Unset CI, GITHUB_* and RUNNER_* for the installer process only. An installer branching on CI=true is a hidden dependency no consumer exercises. Scoped to the child so the step's own $GITHUB_OUTPUT still resolves. Record spctl --status and csrutil status. Neither is documented for these images and both change what a binary is allowed to do.
This commit is contained in:
parent
7d4311fe58
commit
83c3dba5ab
3 changed files with 116 additions and 7 deletions
29
.github/workflows/clean-machine-install-ci.yml
vendored
29
.github/workflows/clean-machine-install-ci.yml
vendored
|
|
@ -155,6 +155,10 @@ jobs:
|
|||
echo "brew : $(command -v brew || echo none)"
|
||||
echo "cmake : $(command -v cmake || echo none)"
|
||||
echo "python3 : $(command -v python3 || echo none)"
|
||||
# Neither is documented for these images, and both change what a binary is
|
||||
# allowed to do. One line settles it for anyone reading the artifact.
|
||||
echo "spctl --status : $(spctl --status 2>&1 || true)"
|
||||
echo "csrutil status : $(csrutil status 2>&1 || true)"
|
||||
} | tee runner-baseline.txt
|
||||
|
||||
- name: Simulate a clean machine (${{ matrix.mode }})
|
||||
|
|
@ -208,6 +212,15 @@ jobs:
|
|||
set -o pipefail
|
||||
rc=0
|
||||
FLAGS="${{ matrix.flags }}"
|
||||
# A consumer has no CI=true, no GITHUB_*, no RUNNER_*: an installer branching
|
||||
# on any of them is a hidden dependency nobody outside CI exercises. Scoped to
|
||||
# the installer's own process, so $GITHUB_OUTPUT below still resolves. `case`
|
||||
# rather than `sed`, whose BRE has no \| alternation on macOS.
|
||||
CLEAN_ENV=""
|
||||
for v in $(env | cut -d= -f1); do
|
||||
case "$v" in CI|GITHUB_*|RUNNER_*) CLEAN_ENV="$CLEAN_ENV -u $v" ;; esac
|
||||
done
|
||||
echo "unset for the installer:$CLEAN_ENV"
|
||||
# A `published` dispatch asks whether unsloth.ai's script works. Only `pipe`
|
||||
# honoured it, so six of the eight macOS rows ran the checked-out script and
|
||||
# were still reported as published coverage. Resolve it once, here, for every
|
||||
|
|
@ -224,7 +237,7 @@ jobs:
|
|||
file)
|
||||
# Plain file execution isolates "installer logic broken" from
|
||||
# "curl-pipe delivery broken".
|
||||
bash "$SCRIPT" $FLAGS 2>&1 | tee logs/install.log || rc=$?
|
||||
env $CLEAN_ENV bash "$SCRIPT" $FLAGS 2>&1 | tee logs/install.log || rc=$?
|
||||
;;
|
||||
pipe)
|
||||
# The shape users actually run. install.sh is ~150KB of top-level
|
||||
|
|
@ -234,14 +247,14 @@ jobs:
|
|||
# re-fetches rather than piping $SCRIPT: the live transport is half of
|
||||
# what this delivery tests.
|
||||
if [ "${{ inputs.installer_source }}" = "published" ]; then
|
||||
curl -fsSL https://unsloth.ai/install.sh | sh -s -- $FLAGS 2>&1 | tee logs/install.log || rc=$?
|
||||
curl -fsSL https://unsloth.ai/install.sh | env $CLEAN_ENV sh -s -- $FLAGS 2>&1 | tee logs/install.log || rc=$?
|
||||
else
|
||||
# `sh -s --` with no further args would pass an empty positional,
|
||||
# so only add the separator when there are flags to pass.
|
||||
if [ -n "$FLAGS" ]; then
|
||||
cat install.sh | sh -s -- $FLAGS 2>&1 | tee logs/install.log || rc=$?
|
||||
cat install.sh | env $CLEAN_ENV sh -s -- $FLAGS 2>&1 | tee logs/install.log || rc=$?
|
||||
else
|
||||
cat install.sh | sh 2>&1 | tee logs/install.log || rc=$?
|
||||
cat install.sh | env $CLEAN_ENV sh 2>&1 | tee logs/install.log || rc=$?
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
|
|
@ -252,7 +265,7 @@ jobs:
|
|||
# every other leg relies on must be dropped or the installer exits
|
||||
# before doing any work. The runner is ephemeral, so the real home is
|
||||
# as disposable as the override.
|
||||
env -u UNSLOTH_STUDIO_HOME \
|
||||
env -u UNSLOTH_STUDIO_HOME $CLEAN_ENV \
|
||||
bash "$SCRIPT" --tauri $FLAGS < /dev/null 2>&1 | tee logs/install.log || rc=$?
|
||||
;;
|
||||
esac
|
||||
|
|
@ -291,7 +304,7 @@ jobs:
|
|||
UNSLOTH_CLEAN_ALLOW_WORKING='${{ matrix.allow_working }}' \
|
||||
bash .github/scripts/clean-machine-assert.sh $checks
|
||||
|
||||
- name: Assert llama.cpp loads
|
||||
- name: Assert llama.cpp loads, and every downloaded Mach-O is native and signed
|
||||
if: steps.install.outcome == 'success'
|
||||
run: |
|
||||
set -a; . ./clean-machine.env; set +a
|
||||
|
|
@ -304,6 +317,10 @@ jobs:
|
|||
HOME_DIR="$UNSLOTH_STUDIO_HOME"
|
||||
fi
|
||||
STUDIO_HOME="$HOME_DIR" bash .github/scripts/assert-llama-loads.sh
|
||||
# Rosetta 2 is on this runner and not on a fresh Mac, so llama-server
|
||||
# launching above does not prove it would launch for a user. Assert the arch
|
||||
# of every payload (llama.cpp, whisper.cpp, the Node prebuilt, uv) instead.
|
||||
MACHO_ROOT="$HOME_DIR" bash .github/scripts/clean-machine-assert.sh macho
|
||||
|
||||
- name: Restore the runner
|
||||
if: always()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue