diff --git a/.github/workflows/canvas-audit.yml b/.github/workflows/canvas-audit.yml index d29b28f..4f1103d 100644 --- a/.github/workflows/canvas-audit.yml +++ b/.github/workflows/canvas-audit.yml @@ -23,7 +23,7 @@ jobs: canvas-interaction-audit: name: iPad canvas interaction stall audit runs-on: macos-15 - timeout-minutes: 60 + timeout-minutes: 80 env: IOS_SIMULATOR_FAMILY: ipad steps: @@ -78,6 +78,8 @@ jobs: path: ${{ runner.temp }}/photo-picker-test.log if-no-files-found: warn retention-days: 7 + - name: Wait for the simulator host to settle + run: node scripts/ci/wait-for-audit-host.mjs - name: Run real native interaction workloads id: interaction_workloads run: | diff --git a/package-lock.json b/package-lock.json index 60bdc0b..4167ee4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,7 @@ "license": "Apache-2.0", "dependencies": { "@expo/vector-icons": "^15.0.3", - "@mathnotes/mobile-ink": "file:vendor/mathnotes-mobile-ink-testflight-c56a32d.tgz", + "@mathnotes/mobile-ink": "file:vendor/mathnotes-mobile-ink-testflight-89cb900.tgz", "@react-native-async-storage/async-storage": "2.2.0", "@shopify/react-native-skia": "2.2.12", "expo": "54.0.34", @@ -2567,8 +2567,8 @@ }, "node_modules/@mathnotes/mobile-ink": { "version": "0.3.11", - "resolved": "file:vendor/mathnotes-mobile-ink-testflight-c56a32d.tgz", - "integrity": "sha512-gNonN5GA95gGsHz7+xVf177+5udHNwePKpwoOEX9rGu861X43DoxI2TpAASv+bxdx0QGzx4BaXmBdgJlFWN+ow==", + "resolved": "file:vendor/mathnotes-mobile-ink-testflight-89cb900.tgz", + "integrity": "sha512-tgWEQfeTW+Tm9POnTM1BlMxnxD1+xt2LwFd61YkkiR1kQbiwfG+mmEGKTw1GbesLCRncANr+Uxs/BI0QsRvrDA==", "license": "Apache-2.0", "peerDependencies": { "@shopify/react-native-skia": ">=2.0.0", diff --git a/package.json b/package.json index 32204c0..a73083b 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ }, "dependencies": { "@expo/vector-icons": "^15.0.3", - "@mathnotes/mobile-ink": "file:vendor/mathnotes-mobile-ink-testflight-c56a32d.tgz", + "@mathnotes/mobile-ink": "file:vendor/mathnotes-mobile-ink-testflight-89cb900.tgz", "@react-native-async-storage/async-storage": "2.2.0", "@shopify/react-native-skia": "2.2.12", "expo": "54.0.34", diff --git a/scripts/ci/wait-for-audit-host.mjs b/scripts/ci/wait-for-audit-host.mjs new file mode 100644 index 0000000..9d22ad7 --- /dev/null +++ b/scripts/ci/wait-for-audit-host.mjs @@ -0,0 +1,33 @@ +import os from 'node:os'; + +// Load averages on hosted macOS can include work outside the VM. Measure the +// CPUs visible to this process instead, and leave the app's budgets unchanged. +function sampleCpu() { + const cpus = os.cpus(); + return cpus.reduce((sum, cpu) => { + const { user, nice, sys, idle, irq } = cpu.times; + sum.total += user + nice + sys + idle + irq; + sum.idle += idle; + return sum; + }, { total: 0, idle: 0 }); +} + +const intervalMs = 5000; +const minimumIdleFraction = 0.35; +const deadline = Date.now() + 8 * 60 * 1000; +let previous = sampleCpu(); +let consecutiveIdle = 0; +console.log(`Waiting for audit host: ${os.availableParallelism?.() ?? os.cpus().length} available CPUs, ${os.cpus().length} reported CPUs, minimum idle 35%`); +while (Date.now() < deadline) { + await new Promise(resolve => setTimeout(resolve, intervalMs)); + const current = sampleCpu(); + const total = current.total - previous.total; + const idle = current.idle - previous.idle; + previous = current; + const idleFraction = total > 0 && idle >= 0 ? idle / total : 0; + console.log(`Host CPU idle: ${(idleFraction * 100).toFixed(1)}%`); + consecutiveIdle = idleFraction >= minimumIdleFraction ? consecutiveIdle + 1 : 0; + if (consecutiveIdle >= 3) process.exit(0); +} +console.error('Audit host did not settle; responsiveness measurements would be unreliable'); +process.exit(1); diff --git a/vendor/mathnotes-mobile-ink-testflight-89cb900.tgz b/vendor/mathnotes-mobile-ink-testflight-89cb900.tgz new file mode 100644 index 0000000..643565a Binary files /dev/null and b/vendor/mathnotes-mobile-ink-testflight-89cb900.tgz differ diff --git a/vendor/mobile-ink-source.json b/vendor/mobile-ink-source.json index 5715b6f..731a2e1 100644 --- a/vendor/mobile-ink-source.json +++ b/vendor/mobile-ink-source.json @@ -2,7 +2,7 @@ "package": "@mathnotes/mobile-ink", "version": "0.3.11", "source": "https://github.com/mathnotes-app/mobile-ink", - "commit": "c56a32dcd90d75fc1fef7d111e073841a5162179", - "sha256": "22e5cefb34304b75d4473790c1956629f43bbbbdf019483470a5b1db697b2b1a", - "pull_request": "https://github.com/mathnotes-app/mobile-ink/pull/65" + "commit": "89cb900c4b4175c6af8470d6d1113f77118fec95", + "sha256": "8d4f8a32f5a59348810b06acb4632393445a6e53e522d6f12ad0a15a50686734", + "pull_request": "https://github.com/mathnotes-app/mobile-ink/pull/66" }