Skip to content
Merged
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
2 changes: 1 addition & 1 deletion .github/warm-sources.json
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@
"nightly-next-canary.yml:canary": {"class": "mac-sign", "warm": [], "exempt": "verification only: checks the feed's signed DMG with Gatekeeper and the notary tickets, compiles nothing"},
"nightly-next-launch-smoke.yml:smoke": {"class": "nightly-release-compile", "warm": [], "exempt": "launches the feed's published DMG from a fresh home; compiles nothing"},
"nightly-next-train.yml:build": {"class": "nightly-release-compile", "warm": ["deriveddata-reuse"]},
"nightly.yml:build-nightly-app": {"class": "nightly-release-compile", "warm": ["actions-cache", "product-reuse"]},
"nightly.yml:build-nightly-app": {"class": "nightly-release-compile", "warm": ["actions-cache", "product-reuse", "ssd-cas"]},
"nightly.yml:build-nightly-ghostty-cli-helper": {"class": "nightly-release-compile", "warm": ["actions-cache"]},
"nightly.yml:build-nightly-inputs": {"class": "webview", "warm": ["actions-cache"]},
"nightly.yml:build-nightly-remote-daemon": {"class": "linux-build", "warm": [], "exempt": "cold: a build script from a clean tree; no warm source wired yet"},
Expand Down
4 changes: 3 additions & 1 deletion .github/workflows/ci-guards.yml
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,9 @@ jobs:

- name: Validate fleet compiler-cache wiring
if: ${{ !cancelled() && matrix.group == 'ci' }}
run: bash tests/test_ci_fleet_compilation_cache.sh
run: |
bash tests/test_ci_fleet_compilation_cache.sh
python3 tests/test_ci_fleet_compilation_cache.py

- name: Validate feature flag linter scope
if: ${{ !cancelled() && matrix.group == 'ci' }}
Expand Down
5 changes: 5 additions & 0 deletions .github/workflows/ci-macos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2519,6 +2519,10 @@ jobs:
started="$(date +%s)"
# Bundle cmux-tui bundles none (deferred); "Install Release helpers"
# installs this tree's client (install-cmux-tui-client.sh).
fleet_cache_settings=()
while IFS= read -r setting; do
fleet_cache_settings+=("$setting")
done < <(bash scripts/ci/fleet-compilation-cache.sh)
CMUX_NEXT_TUI_MODE=deferred CMUX_SKIP_ZIG_BUILD=1 xcodebuild -project cmux.xcodeproj -scheme cmux -configuration Release -derivedDataPath build-universal \
-destination 'generic/platform=macOS' \
-clonedSourcePackagesDirPath .spm-cache \
Expand All @@ -2527,6 +2531,7 @@ jobs:
ONLY_ACTIVE_ARCH=NO \
COMPILATION_CACHE_ENABLE_CACHING=YES \
COMPILATION_CACHE_LIMIT_SIZE=3221225472 \
"${fleet_cache_settings[@]}" \
COMPILER_INDEX_STORE_ENABLE=NO \
CODE_SIGNING_ALLOWED=NO ASSETCATALOG_COMPILER_APPICON_NAME=AppIcon-Nightly build
ended="$(date +%s)"
Expand Down
11 changes: 11 additions & 0 deletions .github/workflows/nightly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1144,6 +1144,10 @@ jobs:
# The warmer only fills the Swift compilation cache; the Chromium
# engine is a prebuilt artifact the shipped build embeds itself.
# Bundle cmux-tui bundles none (deferred): this build only fills the cache.
fleet_cache_settings=()
while IFS= read -r setting; do
fleet_cache_settings+=("$setting")
done < <(bash scripts/ci/fleet-compilation-cache.sh)
CMUX_NEXT_TUI_MODE=deferred CMUX_NEXT_SKIP_CEF=1 CMUX_SKIP_ZIG_BUILD=1 xcodebuild -scheme cmux -configuration Release -derivedDataPath build-universal \
-destination 'generic/platform=macOS' \
-clonedSourcePackagesDirPath .spm-cache \
Expand All @@ -1153,6 +1157,7 @@ jobs:
ONLY_ACTIVE_ARCH=NO \
COMPILATION_CACHE_ENABLE_CACHING=YES \
COMPILATION_CACHE_LIMIT_SIZE=3221225472 \
"${fleet_cache_settings[@]}" \
COMPILER_INDEX_STORE_ENABLE=NO \
CODE_SIGNING_ALLOWED=NO ASSETCATALOG_COMPILER_APPICON_NAME=AppIcon-Nightly build

Expand Down Expand Up @@ -2498,6 +2503,11 @@ jobs:
# Bundle cmux-tui bundles none (deferred): "Bundle the fast cmux-tui client"
# or build-sign-notarize-nightly's "Bundle the cmux-tui client" installs
# this tree's client (install-cmux-tui-client.sh).
# Reuse the managed fleet CAS; unavailable nodes keep the local cache.
fleet_cache_settings=()
while IFS= read -r setting; do
fleet_cache_settings+=("$setting")
done < <(CMUX_CI_DISABLE_COMPILATION_CACHE="${{ needs.decide.outputs.cold_cache == 'true' && '1' || '' }}" bash scripts/ci/fleet-compilation-cache.sh)
python3 scripts/ci/run-with-helper-prebuild.py \
--derived-data build-universal --configuration Release --archs "$archs" \
--log "$RUNNER_TEMP/helper-prebuild.log" -- \
Expand All @@ -2511,6 +2521,7 @@ jobs:
ONLY_ACTIVE_ARCH="$only_active" \
COMPILATION_CACHE_ENABLE_CACHING=YES \
COMPILATION_CACHE_LIMIT_SIZE=3221225472 \
"${fleet_cache_settings[@]}" \
COMPILER_INDEX_STORE_ENABLE=NO \
CODE_SIGNING_ALLOWED=NO ASSETCATALOG_COMPILER_APPICON_NAME="$CHANNEL_ICON_NAME" \
"${notary_test_flags[@]}"
Expand Down
45 changes: 3 additions & 42 deletions scripts/ci/compile-app-host-test-product.sh
Original file line number Diff line number Diff line change
Expand Up @@ -223,15 +223,6 @@ build() {
# shellcheck disable=SC2016 # Xcode expands $(TARGET_NAME), not the shell
local -a cache_setting=(
'COMPILATION_CACHE_ENABLE_CACHING=$(CMUX_CI_COMPILATION_CACHE_$(TARGET_NAME):default=YES)'
# Keep cache keys stable when a PR runner's checkout and DerivedData live
# under a different absolute root than the fleet CAS writer.
SWIFT_ENABLE_PREFIX_MAPPING=YES
CLANG_ENABLE_PREFIX_MAPPING=YES
SWIFT_ENABLE_PROJECT_PREFIX_MAPPING=YES
CLANG_ENABLE_PROJECT_PREFIX_MAPPING=YES
# Xcode 26.6 emits one bounded remark per cache query. The build metrics
# receipt turns those remarks into cacheable-task and hit counters.
COMPILATION_CACHE_ENABLE_DIAGNOSTIC_REMARKS=YES
)
# Xcode's explicit-module dependency graph can survive a clean DerivedData
# rebuild when a reused CAS entry is incomplete. Admission recovery sets
Expand All @@ -255,40 +246,10 @@ build() {
if [ "${CMUX_CI_DISABLE_COMPILATION_CACHE:-}" = 1 ]; then
cache_setting+=(COMPILATION_CACHE_ENABLE_CACHING=NO)
fi
# Owned minis carry the fleet-cas node installed by glaeda. Its settings
# select the node's fixed CAS and Unix socket; Blacksmith and unprovisioned
# runners simply keep the local CAS path above. The helper is probed once
# per build and is advisory, so a down node never refuses a CI job.
local -a fleet_cache_setting=()
local fleet_cas_root="${CMUX_FLEET_CAS_ROOT:-/Users/Shared/cmux-build-fleet/xcode}"
local fleet_cas_settings="${CMUX_FLEET_CAS_SETTINGS:-$fleet_cas_root/bin/fleet-cas-settings.sh}"
local fleet_cas_socket="${CMUX_FLEET_CAS_SOCKET:-$fleet_cas_root/fleet-cas.sock}"
if [ -x "$fleet_cas_settings" ] && [ -S "$fleet_cas_socket" ]; then
local fleet_settings=''
fleet_settings="$("$fleet_cas_settings" "$fleet_cas_socket" 2>/dev/null | head -n 8)" || fleet_settings=''
local fleet_plugin_ok=0
local fleet_remote_ok=0
while IFS= read -r setting; do
case "$setting" in
COMPILATION_CACHE_ENABLE_PLUGIN=YES) fleet_plugin_ok=1 ;;
COMPILATION_CACHE_REMOTE_SERVICE_PATH=/*) fleet_remote_ok=1 ;;
COMPILATION_CACHE_CAS_PATH=/*) ;;
esac
done <<< "$fleet_settings"
if [ "$fleet_plugin_ok" -eq 1 ] && [ "$fleet_remote_ok" -eq 1 ]; then
fleet_cache_setting+=("COMPILATION_CACHE_CAS_PATH=$fleet_cas_root/cas")
while IFS= read -r setting; do
case "$setting" in
COMPILATION_CACHE_ENABLE_PLUGIN=YES|COMPILATION_CACHE_REMOTE_SERVICE_PATH=/*)
fleet_cache_setting+=("$setting")
;;
esac
done <<< "$fleet_settings"
fi
fi
if [ "${CMUX_CI_DISABLE_COMPILATION_CACHE:-}" = 1 ]; then
fleet_cache_setting=()
fi
while IFS= read -r setting; do
fleet_cache_setting+=("$setting")
done < <(bash "$SCRIPT_DIR/fleet-compilation-cache.sh")
Comment on lines +250 to +252

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: A failing fleet-compilation-cache.sh is ignored here, so the build continues without the prefix-mapping and diagnostic settings and gets silent cache misses. Capture the output with a plain assignment so set -e stops the build on helper failure.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At scripts/ci/compile-app-host-test-product.sh, line 250:

<comment>A failing `fleet-compilation-cache.sh` is ignored here, so the build continues without the prefix-mapping and diagnostic settings and gets silent cache misses. Capture the output with a plain assignment so `set -e` stops the build on helper failure.</comment>

<file context>
@@ -255,40 +246,10 @@ build() {
-  if [ "${CMUX_CI_DISABLE_COMPILATION_CACHE:-}" = 1 ]; then
-    fleet_cache_setting=()
-  fi
+  while IFS= read -r setting; do
+    fleet_cache_setting+=("$setting")
+  done < <(bash "$SCRIPT_DIR/fleet-compilation-cache.sh")
</file context>
Suggested change
while IFS= read -r setting; do
fleet_cache_setting+=("$setting")
done < <(bash "$SCRIPT_DIR/fleet-compilation-cache.sh")
local fleet_cache_output
fleet_cache_output="$(bash "$SCRIPT_DIR/fleet-compilation-cache.sh")"
while IFS= read -r setting; do
fleet_cache_setting+=("$setting")
done <<< "$fleet_cache_output"

# xcodebuild runs under the resolve's fixed environment (see resolve()), but
# the app's script phases still need the caller's: PATH for cargo, rustup,
# go and zig (the diff sidecar, wireguard-go, bundled
Expand Down
46 changes: 46 additions & 0 deletions scripts/ci/fleet-compilation-cache.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#!/usr/bin/env bash
# Print one allowlisted Xcode setting per line. Shared by app-host admission
# and nightly Release builds; an absent or unhealthy managed CAS stays local.
set -euo pipefail

fleet_cache_setting=(
# Keep cache keys stable when a PR runner's checkout and DerivedData live
# under a different absolute root than the fleet CAS writer.
SWIFT_ENABLE_PREFIX_MAPPING=YES
CLANG_ENABLE_PREFIX_MAPPING=YES
SWIFT_ENABLE_PROJECT_PREFIX_MAPPING=YES
CLANG_ENABLE_PROJECT_PREFIX_MAPPING=YES
# Xcode 26.6 emits one bounded remark per cache query. The build metrics
# receipt turns those remarks into cacheable-task and hit counters.
COMPILATION_CACHE_ENABLE_DIAGNOSTIC_REMARKS=YES
)
# Keep mapping and diagnostics when caching is disabled, as admission did.
if [ "${CMUX_CI_DISABLE_COMPILATION_CACHE:-}" != 1 ]; then
fleet_cas_root="${CMUX_FLEET_CAS_ROOT:-/Users/Shared/cmux-build-fleet/xcode}"
fleet_cas_settings="${CMUX_FLEET_CAS_SETTINGS:-$fleet_cas_root/bin/fleet-cas-settings.sh}"
fleet_cas_socket="${CMUX_FLEET_CAS_SOCKET:-$fleet_cas_root/fleet-cas.sock}"
if [ -x "$fleet_cas_settings" ] && [ -S "$fleet_cas_socket" ]; then
fleet_settings=''
fleet_settings="$("$fleet_cas_settings" "$fleet_cas_socket" 2>/dev/null | head -n 8)" || fleet_settings=''

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: The helper call has no timeout, so a hung fleet node blocks the build instead of falling back to local compilation. Bound the call with a timeout, and send its stderr to the build log instead of /dev/null so unhealthy-CAS fallbacks stay diagnosable.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At scripts/ci/fleet-compilation-cache.sh, line 24:

<comment>The helper call has no timeout, so a hung fleet node blocks the build instead of falling back to local compilation. Bound the call with a timeout, and send its stderr to the build log instead of `/dev/null` so unhealthy-CAS fallbacks stay diagnosable.</comment>

<file context>
@@ -0,0 +1,46 @@
+  fleet_cas_socket="${CMUX_FLEET_CAS_SOCKET:-$fleet_cas_root/fleet-cas.sock}"
+  if [ -x "$fleet_cas_settings" ] && [ -S "$fleet_cas_socket" ]; then
+    fleet_settings=''
+    fleet_settings="$("$fleet_cas_settings" "$fleet_cas_socket" 2>/dev/null | head -n 8)" || fleet_settings=''
+    fleet_plugin_ok=0
+    fleet_remote_ok=0
</file context>

fleet_plugin_ok=0
fleet_remote_ok=0
while IFS= read -r setting; do
case "$setting" in
COMPILATION_CACHE_ENABLE_PLUGIN=YES) fleet_plugin_ok=1 ;;
COMPILATION_CACHE_REMOTE_SERVICE_PATH=/*) fleet_remote_ok=1 ;;
COMPILATION_CACHE_CAS_PATH=/*) ;;
esac
done <<< "$fleet_settings"
if [ "$fleet_plugin_ok" -eq 1 ] && [ "$fleet_remote_ok" -eq 1 ]; then
fleet_cache_setting+=("COMPILATION_CACHE_CAS_PATH=$fleet_cas_root/cas")
while IFS= read -r setting; do
case "$setting" in
COMPILATION_CACHE_ENABLE_PLUGIN=YES|COMPILATION_CACHE_REMOTE_SERVICE_PATH=/*)
fleet_cache_setting+=("$setting")
;;
esac
done <<< "$fleet_settings"
fi
fi
fi
printf '%s\n' "${fleet_cache_setting[@]}"
2 changes: 1 addition & 1 deletion scripts/ci/nightly_build_state.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
INCREMENTAL_STATE = 'incremental.json'
KEY_PATHS = re.compile(r'(^|/)(Package\.resolved|Cargo\.lock|build\.zig\.zon|rust-toolchain(\.toml)?|\.xcode-version'
r'|cef-manifest\.json|ensure-cef\.sh|ensure-remote-browser-host\.sh|download-prebuilt-ghosttykit\.sh'
r'|nightly-swift-defines\.sh|run-xcodebuild-with-diagnostics\.sh)$')
r'|nightly-swift-defines\.sh|run-xcodebuild-with-diagnostics\.sh|fleet-compilation-cache\.sh)$')
# The build's own settings: the Release build step's text (its xcodebuild settings and how it forms
# OTHER_SWIFT_FLAGS) and the decide outputs it reads (BUILD_SETTINGS in the environment of the
# prepare step). A change to either is a clean build: objects compiled under other -D flags,
Expand Down
1 change: 1 addition & 0 deletions scripts/ci/product_input_identity.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ def scheme_action(scheme: str) -> str:
PRODUCT_CI_INPUTS = frozenset({
"scripts/ci/app_host_test_products.py",
"scripts/ci/compile-app-host-test-product.sh",
"scripts/ci/fleet-compilation-cache.sh",
"scripts/ci/canonical-build-root.sh",
# canonical-build-root.sh copies the source tree the product compiles from with it.
"scripts/ci/apfs_clone.py",
Expand Down
4 changes: 4 additions & 0 deletions tests/test-execution.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@
# wall-clock bounds a busy machine could miss.
version = 1

[[test]]
path = "tests/test_ci_fleet_compilation_cache.py"
lane = "linux-guard"

[[test]]
path = "tests/test_web_ota_publication_contract.py"
lane = "linux-guard"
Expand Down
114 changes: 114 additions & 0 deletions tests/test_ci_fleet_compilation_cache.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
#!/usr/bin/env python3
"""Exercise managed CAS settings and the nightly's emitted Xcode command."""
import json
import os
from pathlib import Path
import shutil
import socket
import subprocess
import tempfile
import unittest

ROOT = Path(__file__).resolve().parents[1]
SETTINGS = ROOT / "scripts/ci/fleet-compilation-cache.sh"


class FleetCacheTests(unittest.TestCase):
def setUp(self):
# Runner TMPDIR may exceed sockaddr_un's ~100-byte pathname limit.
self.scratch = tempfile.TemporaryDirectory(prefix="fleet-cas-", dir="/tmp")
self.addCleanup(self.scratch.cleanup)
self.root = Path(self.scratch.name)
self.cache = self.root / "cache with spaces"
self.cache.mkdir()
self.sock = socket.socket(socket.AF_UNIX)
self.addCleanup(self.sock.close)
self.sock.bind(str(self.cache / "fleet-cas.sock"))
self.helper = self.cache / "settings.sh"
self.env = {**os.environ, "CMUX_FLEET_CAS_ROOT": str(self.cache),
"CMUX_FLEET_CAS_SETTINGS": str(self.helper),
"CMUX_FLEET_CAS_SOCKET": str(self.cache / "fleet-cas.sock"),
"CMUX_CI_DISABLE_COMPILATION_CACHE": ""}
self.helper.write_text('#!/bin/bash\nprintf "%s\\n" COMPILATION_CACHE_ENABLE_PLUGIN=YES '
'"COMPILATION_CACHE_REMOTE_SERVICE_PATH=$1" '
'COMPILATION_CACHE_CAS_PATH=/untrusted '
'OTHER_SWIFT_FLAGS=-unsafe\n')
self.helper.chmod(0o755)

def settings(self):
return subprocess.check_output(["bash", str(SETTINGS)], env=self.env, text=True).splitlines()

def assert_local(self):
settings = self.settings()
self.assertIn("SWIFT_ENABLE_PREFIX_MAPPING=YES", settings)
self.assertIn("CLANG_ENABLE_PROJECT_PREFIX_MAPPING=YES", settings)
self.assertFalse(any("REMOTE_SERVICE" in s or "CAS_PATH=" in s or "ENABLE_PLUGIN" in s for s in settings))

def test_healthy_node_uses_fixed_cas_and_filters_helper_settings(self):
settings = self.settings()
self.assertIn(f"COMPILATION_CACHE_CAS_PATH={self.cache}/cas", settings)
self.assertIn(f"COMPILATION_CACHE_REMOTE_SERVICE_PATH={self.cache}/fleet-cas.sock", settings)
self.assertNotIn("COMPILATION_CACHE_CAS_PATH=/untrusted", settings)
self.assertNotIn("OTHER_SWIFT_FLAGS=-unsafe", settings)

def test_missing_socket_keeps_local_cache(self):
self.env["CMUX_FLEET_CAS_SOCKET"] = str(self.root / "absent.sock")
self.assert_local()

def test_failed_helper_keeps_local_cache(self):
self.helper.write_text("#!/bin/bash\nexit 1\n")
self.assert_local()

def test_partial_response_keeps_local_cache(self):
self.helper.write_text("#!/bin/bash\necho COMPILATION_CACHE_ENABLE_PLUGIN=YES\n")
self.assert_local()

def test_disabled_cache_never_probes_node(self):
self.env["CMUX_CI_DISABLE_COMPILATION_CACHE"] = "1"
marker = self.root / "probed"
self.helper.write_text(f"#!/bin/bash\ntouch '{marker}'\n")
self.assert_local()
self.assertFalse(marker.exists())

def test_nightly_xcode_command_receives_shared_settings(self):
# Execute the workflow's actual compile command through tiny pass-through
# wrappers. No Xcode or compiler runs; the last executable records argv.
workflow = (ROOT / ".github/workflows/nightly.yml").read_text()
step = workflow.split(" - name: Build nightly app (Release)\n", 1)[1].split(" - name:", 1)[0]
command = step[step.index(" fleet_cache_settings=()") :]
command = "\n".join(line[10:] for line in command.splitlines() if line.startswith(" "))
command = command.replace("${{ needs.decide.outputs.cold_cache == 'true' && '1' || '' }}", "")
scripts = self.root / "scripts/ci"
scripts.mkdir(parents=True)
shutil.copyfile(SETTINGS, scripts / SETTINGS.name)
(scripts / "run-with-helper-prebuild.py").write_text(
"import os,sys\na=sys.argv[sys.argv.index('--')+1:]\nos.execvp(a[0],a)\n")
wrapper = scripts / "run-xcodebuild-with-diagnostics.sh"
wrapper.write_text('#!/bin/bash\nshift\nexec "$@"\n')
wrapper.chmod(0o755)
xcode = self.root / "xcodebuild"
xcode.write_text('#!/usr/bin/env python3\nimport json,sys\nprint(json.dumps(sys.argv[1:]))\n')
xcode.chmod(0o755)
env = {**self.env, "PATH": str(self.root) + os.pathsep + self.env["PATH"],
"RUNNER_TEMP": str(self.root), "CHANNEL_ICON_NAME": "AppIcon-Nightly"}
result = subprocess.run(["bash", "-euc", 'archs=arm64; only_active=YES; notary_test_flags=(build)\n' + command],
cwd=self.root, env=env, text=True, capture_output=True, check=True)
args = json.loads(result.stdout)
self.assertIn(f"COMPILATION_CACHE_CAS_PATH={self.cache}/cas", args)
self.assertIn("COMPILATION_CACHE_ENABLE_PLUGIN=YES", args)
self.assertIn("SWIFT_ENABLE_PROJECT_PREFIX_MAPPING=YES", args)
self.assertIn("CODE_SIGNING_ALLOWED=NO", args)
self.assertEqual(args[-1], "build")

def test_warmer_and_pr_release_use_the_same_cache_settings(self):
nightly = (ROOT / ".github/workflows/nightly.yml").read_text()
ci_macos = (ROOT / ".github/workflows/ci-macos.yml").read_text()
warmer = nightly.split(" - name: Refresh universal nightly compilation cache\n", 1)[1].split(" - name:", 1)[0]
release = ci_macos.split(" - name: Build app (Release)\n", 1)[1].split(" - name:", 1)[0]
for step in (warmer, release):
self.assertIn("bash scripts/ci/fleet-compilation-cache.sh", step)
self.assertIn('"${fleet_cache_settings[@]}"', step)


if __name__ == "__main__":
unittest.main()
4 changes: 3 additions & 1 deletion tests/test_ci_fleet_compilation_cache.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
set -euo pipefail

ROOT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
SCRIPT="$ROOT_DIR/scripts/ci/compile-app-host-test-product.sh"
SCRIPT="$ROOT_DIR/scripts/ci/fleet-compilation-cache.sh"
COMPILE="$ROOT_DIR/scripts/ci/compile-app-host-test-product.sh"
WORKFLOW="$ROOT_DIR/.github/workflows/ci-macos.yml"

fail() { echo "FAIL: $*" >&2; exit 1; }
Expand All @@ -28,4 +29,5 @@ grep -Fq 'fleet_cache_setting+=("COMPILATION_CACHE_CAS_PATH=$fleet_cas_root/cas"

grep -Fq 'glaeda-compile-telemetry.json' "$WORKFLOW" || fail 'compile admission must publish the host telemetry sidecar'

grep -Fq 'bash "$SCRIPT_DIR/fleet-compilation-cache.sh"' "$COMPILE" || fail 'admission must use the shared settings'
echo 'PASS: fleet compiler-cache settings and host telemetry are wired'
6 changes: 6 additions & 0 deletions tests/test_nightly_build_state.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,12 @@ def test_an_unfinished_build_makes_the_next_one_clean(self):
self.build(finish=False)
self.assertEqual(self.build()[:2], ('mode=clean', False))

def test_a_fleet_cache_settings_change_invalidates_incremental_state(self):
self.build()
self.commit({'scripts/ci/fleet-compilation-cache.sh': 'echo SWIFT_ENABLE_PREFIX_MAPPING=YES\n'})
self.assertEqual(self.build()[0], 'mode=clean')
self.assertEqual(self.build()[0], 'mode=incremental')

def test_a_toolchain_lockfile_or_submodule_change_makes_it_clean(self):
self.build()
self.assertEqual(self.build(toolchain='Xcode 26.7')[:2], ('mode=clean', False))
Expand Down
4 changes: 3 additions & 1 deletion tests/test_nightly_release_product_reuse.py
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,9 @@ def test_skipped_steps_read_no_unkeyed_decide_output(self):
self.assertIn(f"needs.decide.outputs.{excluded} != 'true'", condition)
self.assertIn("github.event_name == 'push'", condition)
self.assertIn("github.ref == 'refs/heads/nightly-next'", condition)
allowed = set(fingerprint.NIGHTLY_PRODUCT_FLAGS) | {"fast_build", "build_only", "should_publish"}
# cold_cache only chooses local versus shared compiler-cache transport;
# both produce the same compiled inputs, so it does not key the product.
allowed = set(fingerprint.NIGHTLY_PRODUCT_FLAGS) | {"fast_build", "build_only", "should_publish", "cold_cache"}
skipped = [step for step in self.steps() if "steps.nightly-product.outputs.hit != 'true'" in step]
self.assertGreaterEqual(len(skipped), 15)
for step in skipped:
Expand Down
Loading