Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions .github/workflows/ci-macos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -579,6 +579,9 @@ jobs:
- name: Compile app-host test product
id: hosted-compile
if: steps.reuse-products.outputs.hit != 'true'
# CANARY: swift-driver explains each incremental decision.
env:
CMUX_CI_EXTRA_SWIFT_FLAGS: -driver-show-incremental
run: |
set -uo pipefail
started="$(python3 -c 'import time; print(time.monotonic())')"
Expand All @@ -593,6 +596,49 @@ jobs:
echo "seconds=$seconds" >> "$GITHUB_OUTPUT"
exit "$status"

# CANARY (do not merge): why does cmuxTests recompile in full after the
# cmux scheme builds, when a cmux-unit null rebuild is cheap?
- name: Canary probe cmuxTests rebuild cause
if: always() && steps.hosted-compile.outcome == 'success'
continue-on-error: true
timeout-minutes: 50
run: |
set +e -u
dd="$CMUX_COMPILE_ADMISSION_DERIVED_DATA"; src=/private/tmp/cmux-ci/src
out="$RUNNER_TEMP/canary"; mkdir -p "$out"
probe() {
local name="$1" flags="$2" log="$out/probe-$1.txt" started=$SECONDS
CMUX_CI_EXTRA_SWIFT_FLAGS="$flags" CMUX_CI_BUILD_SCHEMES=cmux-unit \
scripts/ci/compile-app-host-test-product.sh canonical-build \
"$dd" "$PWD/.ci-source-packages" "$CMUX_COMPILE_ADMISSION_CAS" "$log" > /dev/null 2>&1 \
|| echo "probe $name build failed: $(grep -m3 -E 'error:' "$log")"
local line="probe $name [$flags]: $((SECONDS - started))s"
line+=" cmuxTests=$(grep -cE "^SwiftCompile normal arm64 .*\(in target 'cmuxTests'" "$log")"
line+=" cmux=$(grep -cE "^SwiftCompile normal arm64 .*\(in target 'cmux'" "$log")"
line+=" newerChained=$(grep -c 'Newer: cmuxTests-.*ChainedBridgingHeader' "$log")"
line+=" $(grep -m1 -E 'SwiftCompile \([0-9]+ tasks\)' "$log")"
echo "$line"; echo "- $line" >> "$GITHUB_STEP_SUMMARY"
}
edit() { printf '\n// canary edit %s\n' "$1" >> "$src/cmuxTests/CmuxSSHURLRequestTests.swift"; }
edit baseline; probe baseline-test-edit "-driver-show-incremental"
export CMUX_CI_EXTRA_BUILD_SETTING=SWIFT_PRECOMPILE_BRIDGING_HEADER=NO
probe nopch-prime "-driver-show-incremental"
find "$dd" -name '*ChainedBridgingHeader*' -newer "$src/cmuxTests/CmuxSSHURLRequestTests.swift" -exec stat -f '%Sm %N' {} + 2>/dev/null | head -3
edit nopch1; probe nopch-test-edit "-driver-show-incremental"
edit nopch2; probe nopch-test-edit-2 "-driver-show-incremental"
probe nopch-null "-driver-show-incremental"
unset CMUX_CI_EXTRA_BUILD_SETTING
exit 0

- name: Upload canary probe logs
if: always() && steps.hosted-compile.outcome == 'success'
continue-on-error: true
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: canary-cmuxtests-rebuild-${{ github.run_attempt }}
path: ${{ runner.temp }}/canary
retention-days: 5

# Adoption sets a per-user Xcode default. Only a build whose inputs were
# just replayed should ignore inode changes, so a reused runner does not
# carry it into an unrelated job.
Expand Down
6 changes: 5 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -602,7 +602,11 @@ jobs:
RUN_CLAUDE_WRAPPER: ${{ steps.standalone.outputs.claude_wrapper }}
RUN_CLI: ${{ steps.detect.outputs.cli }}
RUN_REMOTE_DAEMON: ${{ steps.standalone.outputs.remote_daemon }}
run: python3 scripts/ci/pr_runner_pool.py
# CANARY (do not merge): pin an owned mini, which reuses its own build
# state under one Xcode install, so Xcode mtimes cannot differ.
run: |
python3 scripts/ci/pr_runner_pool.py
printf 'runner=blacksmith-12vcpu-macos-26\nxcode_app=\npersistent=false\nretry_runner=blacksmith-12vcpu-macos-26\n' >> "$GITHUB_OUTPUT"

# A job queued on a persistent pool (owned Macs) waits for it however long
# it stays busy. This marker tells ci-owned-pool-rescue.yml, running from
Expand Down
2 changes: 2 additions & 0 deletions cmuxTests/CmuxSSHURLRequestTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1004,3 +1004,5 @@ final class CmuxNavigationURLRequestTests: XCTestCase {
return request.target
}
}

// canary: test-only change for the cmuxTests rebuild probe (do not merge)
3 changes: 2 additions & 1 deletion scripts/ci/compile-app-host-test-product.sh
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ build() {
[ "${#schemes[@]}" -gt 0 ] || { echo "empty product profile scheme list" >&2; exit 1; }
# shellcheck disable=SC2016 # Xcode expands $(inherited), not the shell
for scheme in "${schemes[@]}"; do
case " ${CMUX_CI_BUILD_SCHEMES:-$scheme} " in *" $scheme "*) ;; *) continue ;; esac
FileSystemMode="$XCBUILD_FILE_SYSTEM_MODE" xcodebuild -project cmux.xcodeproj -scheme "$scheme" -configuration Debug \
-derivedDataPath "$derived_data" \
-clonedSourcePackagesDirPath "$source_packages" \
Expand All @@ -161,7 +162,7 @@ build() {
"COMPILATION_CACHE_CAS_PATH=$cas_path" \
"COMPILATION_CACHE_LIMIT_SIZE=$cache_limit_bytes" \
${module_cache_setting[@]+"${module_cache_setting[@]}"} \
-showBuildTimingSummary \
${CMUX_CI_EXTRA_SWIFT_FLAGS:+"OTHER_SWIFT_FLAGS=\$(inherited) $CMUX_CI_EXTRA_SWIFT_FLAGS"} ${CMUX_CI_EXTRA_BUILD_SETTING:+"$CMUX_CI_EXTRA_BUILD_SETTING"} -showBuildTimingSummary \
build-for-testing 2>&1 | tee "$derived_data/$scheme-build.log" | tee -a "$log"
done
}
Expand Down
Loading