Repository navigation
Fix nightly Xcode selection on single-Xcode runners #5694
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,90 @@ | ||
| #!/usr/bin/env bash | ||
| # Select Xcodes for the nightly macOS build. | ||
| set -euo pipefail | ||
|
|
||
| APPLICATIONS_DIR="${CMUX_XCODE_APPLICATIONS_DIR:-/Applications}" | ||
| PRINT_VERSION="${CMUX_SELECT_XCODE_PRINT_VERSION:-1}" | ||
|
|
||
| sdk_major() { | ||
| local v="$1" maj | ||
| maj="${v%%.*}" | ||
| case "$maj" in | ||
| ''|*[!0-9]*) return 1 ;; | ||
| esac | ||
| printf '%d' "$maj" | ||
| } | ||
|
|
||
| sdk_rank() { | ||
| local v="$1" maj min | ||
| maj="${v%%.*}" | ||
| min="${v#*.}" | ||
| [ "$min" = "$v" ] && min=0 | ||
| min="${min%%.*}" | ||
| case "$maj" in | ||
| ''|*[!0-9]*) return 1 ;; | ||
| esac | ||
| case "$min" in | ||
| ''|*[!0-9]*) min=0 ;; | ||
| esac | ||
| printf '%d' "$(( maj * 1000 + min ))" | ||
| } | ||
|
|
||
| APP_DEVELOPER_DIR="" | ||
| APP_SDK_VER="" | ||
| APP_RANK=-1 | ||
| HELPER_DEVELOPER_DIR="" | ||
| HELPER_SDK_VER="" | ||
| HELPER_RANK=-1 | ||
|
|
||
| while IFS= read -r app; do | ||
| [ -n "$app" ] || continue | ||
| dev="$app/Contents/Developer" | ||
| [ -d "$dev" ] || continue | ||
| sdk_ver="$(DEVELOPER_DIR="$dev" xcrun --sdk macosx --show-sdk-version 2>/dev/null || true)" | ||
| [ -n "$sdk_ver" ] || continue | ||
| if ! major="$(sdk_major "$sdk_ver")"; then | ||
| echo "Ignoring $app with unparsable macOS SDK version: $sdk_ver" >&2 | ||
| continue | ||
| fi | ||
| if ! rank="$(sdk_rank "$sdk_ver")"; then | ||
| echo "Ignoring $app with unparsable macOS SDK version: $sdk_ver" >&2 | ||
| continue | ||
| fi | ||
| echo "Found $app -> macOS SDK $sdk_ver (rank $rank)" | ||
| if [ "$major" -ge 26 ]; then | ||
| if [ "$rank" -gt "$APP_RANK" ]; then | ||
| APP_DEVELOPER_DIR="$dev" | ||
| APP_SDK_VER="$sdk_ver" | ||
| APP_RANK="$rank" | ||
| fi | ||
| else | ||
| if [ "$rank" -gt "$HELPER_RANK" ]; then | ||
| HELPER_DEVELOPER_DIR="$dev" | ||
| HELPER_SDK_VER="$sdk_ver" | ||
| HELPER_RANK="$rank" | ||
| fi | ||
| fi | ||
| done < <(find "$APPLICATIONS_DIR" -maxdepth 1 -name 'Xcode*.app' -print 2>/dev/null | sort) | ||
|
|
||
| if [ -z "$APP_DEVELOPER_DIR" ]; then | ||
| echo "No Xcode with the macOS 26+ SDK found; the app would ship without Liquid Glass on Tahoe." >&2 | ||
| exit 1 | ||
| fi | ||
|
|
||
| if [ -z "$HELPER_DEVELOPER_DIR" ]; then | ||
| HELPER_DEVELOPER_DIR="$APP_DEVELOPER_DIR" | ||
| HELPER_SDK_VER="$APP_SDK_VER" | ||
| echo "No pre-26 Xcode found for the Ghostty CLI helper; falling back to the app Xcode. The universal helper build and lipo verification remain required." >&2 | ||
| fi | ||
|
Comment on lines
+74
to
+78
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time! |
||
|
|
||
| echo "App build Xcode (DEVELOPER_DIR): $APP_DEVELOPER_DIR (macOS SDK $APP_SDK_VER)" | ||
| echo "Helper build Xcode (HELPER_DEVELOPER_DIR): $HELPER_DEVELOPER_DIR (macOS SDK $HELPER_SDK_VER)" | ||
|
|
||
| if [ -n "${GITHUB_ENV:-}" ]; then | ||
| echo "DEVELOPER_DIR=$APP_DEVELOPER_DIR" >> "$GITHUB_ENV" | ||
| echo "HELPER_DEVELOPER_DIR=$HELPER_DEVELOPER_DIR" >> "$GITHUB_ENV" | ||
| fi | ||
|
|
||
| if [ "$PRINT_VERSION" != "0" ]; then | ||
| DEVELOPER_DIR="$APP_DEVELOPER_DIR" xcodebuild -version | ||
| fi | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,89 @@ | ||
| #!/usr/bin/env bash | ||
| # Regression test for nightly Xcode selection on one-Xcode runner images. | ||
| set -euo pipefail | ||
|
|
||
| ROOT_DIR="$(cd "$(dirname "$0")/.." && pwd)" | ||
| SCRIPT="$ROOT_DIR/scripts/select-nightly-xcodes.sh" | ||
| TMP_DIR="$(mktemp -d)" | ||
| trap 'rm -rf "$TMP_DIR"' EXIT | ||
|
|
||
| BIN_DIR="$TMP_DIR/bin" | ||
| APPS_DIR="$TMP_DIR/Applications" | ||
| mkdir -p "$BIN_DIR" "$APPS_DIR" | ||
|
|
||
| cat > "$BIN_DIR/xcrun" <<'EOF' | ||
| #!/usr/bin/env bash | ||
| set -euo pipefail | ||
|
|
||
| if [ "${1:-}" = "--sdk" ] && [ "${2:-}" = "macosx" ] && [ "${3:-}" = "--show-sdk-version" ]; then | ||
| cat "${DEVELOPER_DIR:?}/sdk-version" | ||
| exit 0 | ||
| fi | ||
|
|
||
| echo "unexpected xcrun invocation: $*" >&2 | ||
| exit 2 | ||
| EOF | ||
| chmod +x "$BIN_DIR/xcrun" | ||
|
|
||
| make_xcode() { | ||
| local name="$1" sdk="$2" dev | ||
| dev="$APPS_DIR/$name/Contents/Developer" | ||
| mkdir -p "$dev" | ||
| printf '%s\n' "$sdk" > "$dev/sdk-version" | ||
| } | ||
|
|
||
| run_selector() { | ||
| local out="$1" env_file="$2" | ||
| PATH="$BIN_DIR:$PATH" \ | ||
| CMUX_XCODE_APPLICATIONS_DIR="$APPS_DIR" \ | ||
| CMUX_SELECT_XCODE_PRINT_VERSION=0 \ | ||
| GITHUB_ENV="$env_file" \ | ||
| "$SCRIPT" > "$out" 2>&1 | ||
| } | ||
|
|
||
| assert_env_line() { | ||
| local env_file="$1" expected="$2" | ||
| if ! grep -Fxq "$expected" "$env_file"; then | ||
| echo "FAIL: missing env line: $expected" >&2 | ||
| echo "--- env file ---" >&2 | ||
| cat "$env_file" >&2 | ||
| exit 1 | ||
| fi | ||
| } | ||
|
|
||
| make_xcode "Xcode.app" "26.2" | ||
| ONLY_OUT="$TMP_DIR/only.out" | ||
| ONLY_ENV="$TMP_DIR/only.env" | ||
| run_selector "$ONLY_OUT" "$ONLY_ENV" | ||
| assert_env_line "$ONLY_ENV" "DEVELOPER_DIR=$APPS_DIR/Xcode.app/Contents/Developer" | ||
| assert_env_line "$ONLY_ENV" "HELPER_DEVELOPER_DIR=$APPS_DIR/Xcode.app/Contents/Developer" | ||
| if ! grep -Fq "falling back to the app Xcode" "$ONLY_OUT"; then | ||
| echo "FAIL: one-Xcode selection must explain the helper fallback" >&2 | ||
| cat "$ONLY_OUT" >&2 | ||
| exit 1 | ||
| fi | ||
|
|
||
| make_xcode "Xcode_16.app" "15.5" | ||
| DUAL_OUT="$TMP_DIR/dual.out" | ||
| DUAL_ENV="$TMP_DIR/dual.env" | ||
| run_selector "$DUAL_OUT" "$DUAL_ENV" | ||
| assert_env_line "$DUAL_ENV" "DEVELOPER_DIR=$APPS_DIR/Xcode.app/Contents/Developer" | ||
| assert_env_line "$DUAL_ENV" "HELPER_DEVELOPER_DIR=$APPS_DIR/Xcode_16.app/Contents/Developer" | ||
|
Comment on lines
+54
to
+71
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The dual-Xcode case tests one macOS 26 Xcode and one pre-26 Xcode. There is no test with two macOS 26+ Xcodes (e.g. |
||
|
|
||
| rm -rf "$APPS_DIR" | ||
| mkdir -p "$APPS_DIR" | ||
| make_xcode "Xcode_16.app" "15.5" | ||
| MISSING_OUT="$TMP_DIR/missing.out" | ||
| MISSING_ENV="$TMP_DIR/missing.env" | ||
| if run_selector "$MISSING_OUT" "$MISSING_ENV"; then | ||
| echo "FAIL: selection must fail when no macOS 26+ SDK app Xcode exists" >&2 | ||
| cat "$MISSING_OUT" >&2 | ||
| exit 1 | ||
| fi | ||
| if ! grep -Fq "No Xcode with the macOS 26+ SDK found" "$MISSING_OUT"; then | ||
| echo "FAIL: missing app Xcode failure did not explain the macOS 26 requirement" >&2 | ||
| cat "$MISSING_OUT" >&2 | ||
| exit 1 | ||
| fi | ||
|
|
||
| echo "PASS: nightly Xcode selection supports one-Xcode macOS 26 runners" | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On single-Xcode runners this fallback sets
HELPER_DEVELOPER_DIRto the same Xcode 26 SDK selected for the app, but the very next nightly step runs the realbuild-ghostty-cli-helper.sh --universalwith that value asDEVELOPER_DIR. The repo's release lane still builds this helper on the macOS 15/pre-26 lane because Zig 0.15.2 cannot link it on macOS 26, so the intended single-Xcode nightly will get past selection only to fail during the required helper build rather than producing a nightly.Useful? React with 👍 / 👎.