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
57 changes: 56 additions & 1 deletion .github/workflows/ci-macos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -523,13 +523,68 @@ jobs:
echo "seconds=$seconds" >> "$GITHUB_OUTPUT"
exit "$status"

# CANARY (do not merge): measure what an incremental rebuild recompiles.
- name: Canary probe incremental rebuilds
if: always() && steps.hosted-compile.outcome == 'success'
continue-on-error: true
timeout-minutes: 40
run: |
set +e -u
report() {
local log="$1" name="$2" seconds="$3"
echo "== probe $name: ${seconds}s"
echo " GenerateAssetSymbols tasks: $(grep -cE '^GenerateAssetSymbols ' "$log")"
echo " CompileAssetCatalog tasks: $(grep -cE '^CompileAssetCatalog' "$log")"
echo " EmitSwiftModule/SwiftEmitModule cmux: $(grep -cE "^(SwiftEmitModule|EmitSwiftModule) .*\(in target 'cmux' " "$log")"
grep -oE "^SwiftCompile normal arm64 [^ ]+ \(in target '[^']+'" "$log" | sed -E "s/.*target '//;s/'//" | sort | uniq -c | sort -rn | head -8 | sed 's/^/ /'
{ echo "### probe $name: ${seconds}s"; grep -oE "^SwiftCompile normal arm64 [^ ]+ \(in target '[^']+'" "$log" | sed -E "s/.*target '//;s/'//" | sort | uniq -c | sort -rn | head -5; } >> "$GITHUB_STEP_SUMMARY"
}
probe() {
local name="$1" log="$RUNNER_TEMP/probe-$1.txt" started=$SECONDS
CMUX_CI_BUILD_SCHEMES=cmux-unit scripts/ci/compile-app-host-test-product.sh canonical-build \
"$CMUX_COMPILE_ADMISSION_DERIVED_DATA" \
"$PWD/.ci-source-packages" \
"$CMUX_COMPILE_ADMISSION_CAS" \
"$log" > /dev/null 2>&1 || echo "probe $name build failed"
report "$log" "$name" "$((SECONDS - started))"
}
src=/private/tmp/cmux-ci/src
stat -f '%Sm %N' "$src/Assets.xcassets" "$src/Assets.xcassets/AppIcon.appiconset" 2>/dev/null || true
find "$src/Assets.xcassets" -type f | head -2 | xargs stat -f '%Sm %N' 2>/dev/null || true
probe null
touch "$src/cmuxTests/CmuxSSHURLRequestTests.swift"
probe test-file-mtime
touch "$src/Assets.xcassets"
probe assets-dir-mtime
touch "$src/Sources/Sidebar/GPUSpinner.swift"
probe app-file-mtime
# Where does the first "Resolve Package Graph" spend ~45 s?
manifests="$HOME/Library/Caches/org.swift.swiftpm/manifests"
echo "manifest cache: $(du -sh "$manifests" 2>/dev/null | cut -f1) entries=$(sqlite3 "$manifests/manifest.db" 'select count(*) from MANIFEST_CACHE' 2>/dev/null)"
resolve_probe() {
local name="$1" started=$SECONDS
(cd "$src" && xcodebuild -project cmux.xcodeproj -scheme cmux-unit -configuration Debug \
-derivedDataPath "$CMUX_COMPILE_ADMISSION_DERIVED_DATA" \
-clonedSourcePackagesDirPath "$src/.ci-source-packages" \
-packageCachePath "$src/.ci-source-packages/.package-cache" \
-skipPackageUpdates -resolvePackageDependencies > "$RUNNER_TEMP/resolve-$name.txt" 2>&1)
echo "== resolve $name: $((SECONDS - started))s rc=$?"
echo "### resolve $name: $((SECONDS - started))s" >> "$GITHUB_STEP_SUMMARY"
}
resolve_probe warm-manifests
mv "$manifests" "$manifests.aside" 2>/dev/null
resolve_probe no-manifest-cache
echo "manifest cache rebuilt: entries=$(sqlite3 "$manifests/manifest.db" 'select count(*) from MANIFEST_CACHE' 2>/dev/null)"
resolve_probe rebuilt-manifests

# 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.
- name: Forget the adopted-build inode override
if: always() && steps.seed-derived-data.outcome != 'skipped'
continue-on-error: true
run: defaults delete com.apple.dt.XCBuild IgnoreFileSystemDeviceInodeChanges || true
run: |
defaults delete com.apple.dt.XCBuild IgnoreFileSystemDeviceInodeChanges || true

- name: Generate Xcode build metrics receipt
id: build-metrics
Expand Down
1 change: 1 addition & 0 deletions scripts/ci/compile-app-host-test-product.sh
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ build() {
# job warning-budget scope; subsequent schemes reuse the same app objects.
# shellcheck disable=SC2016 # Xcode expands $(inherited), not the shell
for scheme in cmux cmux-unit cmux-numeric-locale cmux-cli-tests; do
case " ${CMUX_CI_BUILD_SCHEMES:-$scheme} " in *" $scheme "*) ;; *) continue ;; esac
xcodebuild -project cmux.xcodeproj -scheme "$scheme" -configuration Debug \
-derivedDataPath "$derived_data" \
-clonedSourcePackagesDirPath "$source_packages" \
Expand Down
Loading