diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index 2bde5f48f5f..0d27ea92204 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -432,8 +432,8 @@ jobs: PREFLIGHT_PHASE_SELECTED: ${{ needs.code_paths.outputs.typecheck == 'true' }} PREFLIGHT_PRIOR_SUCCESS: ${{ job.status == 'success' }} ORCA_UNIT_SELECTION_MODE: ${{ vars.ORCA_UNIT_SELECTION_MODE || 'shadow' }} - # Set the repository variable to '5' to roll back full PR shards. - ORCA_UNIT_FULL_SHARD_COUNT: ${{ vars.ORCA_UNIT_FULL_SHARD_COUNT || '10' }} + # Five shards use fewer runner minutes; the repository variable can still request ten. + ORCA_UNIT_FULL_SHARD_COUNT: ${{ vars.ORCA_UNIT_FULL_SHARD_COUNT || '5' }} run: | if [ "$PREFLIGHT_PHASE_SELECTED" != true ] || [ "$PREFLIGHT_PRIOR_SUCCESS" != true ]; then exit 0; fi node config/scripts/ci-unit-plan.mjs diff --git a/config/scripts/ci-unit-selection.mjs b/config/scripts/ci-unit-selection.mjs index 0d2bbe68c29..5a71c5f87fe 100644 --- a/config/scripts/ci-unit-selection.mjs +++ b/config/scripts/ci-unit-selection.mjs @@ -35,7 +35,7 @@ export function selectUnitFiles(files, changed, graphInput) { // the account's slots and made the unit matrix 68% of daily slot demand. Against the checked-in // baseline, five shards each carry 24.7 test-minutes over four workers plus ~2.6 minutes of fixed // setup, so ~8.8 minutes -- less than the 10.5-minute p95 queue the oversharding was causing. -// Full PR workflows request ten; daily callers and selected drafts retain five. +// Full PR workflows and daily callers use five; selected drafts may use fewer. export const FULL_SHARD_COUNT = 5 export function planUnitSelection({ diff --git a/config/scripts/mobile-web-app-preview-arm-driver.mjs b/config/scripts/mobile-web-app-preview-arm-driver.mjs index 6ab78058755..5cc5b98f249 100644 --- a/config/scripts/mobile-web-app-preview-arm-driver.mjs +++ b/config/scripts/mobile-web-app-preview-arm-driver.mjs @@ -186,7 +186,10 @@ export async function openPreviewArm( if (act) { // Recorded, never swallowed: a click that never landed and a click that produced no // navigation are the same empty counter, and only one of them is the product's doing. - await act({ page, frame: previewFrame(page) }).catch((error) => { + if (!artifactFrame || artifactFrame.isDetached()) { + throw new Error('The loaded preview frame is missing before its action') + } + await act({ page, frame: artifactFrame }).catch((error) => { actError = String(error).split('\n')[0] }) } diff --git a/config/scripts/pr-preflight-gates.test.mjs b/config/scripts/pr-preflight-gates.test.mjs index 443457a426a..56b7926a693 100644 --- a/config/scripts/pr-preflight-gates.test.mjs +++ b/config/scripts/pr-preflight-gates.test.mjs @@ -32,7 +32,7 @@ it('shares one setup and runs the unchanged compiler after static checks finish' 'node config/scripts/ci-unit-plan.mjs' ]) expect(plan.env.ORCA_UNIT_SELECTION_MODE).toContain('vars.ORCA_UNIT_SELECTION_MODE') - expect(plan.env.ORCA_UNIT_FULL_SHARD_COUNT).toBe("${{ vars.ORCA_UNIT_FULL_SHARD_COUNT || '10' }}") + expect(plan.env.ORCA_UNIT_FULL_SHARD_COUNT).toBe("${{ vars.ORCA_UNIT_FULL_SHARD_COUNT || '5' }}") expect(steps.indexOf(plan)).toBeLessThan(steps.indexOf(compiler)) expect(steps.indexOf(compiler)).toBeGreaterThan( steps.findIndex((step) => step.wait?.includes('localization-extraction')) diff --git a/src/main/pi/prefill-extension-source.test.ts b/src/main/pi/prefill-extension-source.test.ts deleted file mode 100644 index 9e36edd69bf..00000000000 --- a/src/main/pi/prefill-extension-source.test.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { describe, expect, it } from 'vitest' -import { getPiPrefillExtensionSource } from './prefill-extension-source' - -describe('getPiPrefillExtensionSource', () => { - it('accepts OMP session_start events without a reason field', () => { - const source = getPiPrefillExtensionSource('omp') - expect(source).toContain('process.env.ORCA_OMP_PREFILL') - expect(source).not.toContain("event.reason !== 'startup'") - }) - - it('keeps Pi startup reason filtering', () => { - expect(getPiPrefillExtensionSource('pi')).toContain("event.reason !== 'startup'") - }) -}) diff --git a/src/renderer/src/lazy-use-ref-ratchet.test.ts b/src/renderer/src/lazy-use-ref-ratchet.test.ts deleted file mode 100644 index c0b23821bcb..00000000000 --- a/src/renderer/src/lazy-use-ref-ratchet.test.ts +++ /dev/null @@ -1,130 +0,0 @@ -import { readFileSync, readdirSync } from 'node:fs' -import path from 'node:path' -import { describe, expect, it } from 'vitest' - -/** - * `useRef(create())` evaluates its argument on EVERY render and discards every result after the - * first, so any real work there is pure waste. The lazy form keeps the same value with none of the - * churn: - * - * const ref = useRef(undefined!) - * ref.current ??= create() - * - * Use a `useState` lazy initializer instead when the seed can legitimately be null/undefined, or - * an explicit `seededRef` guard when both are true. - */ -const RENDERER_ROOT = import.meta.dirname - -function collectSourceFiles(dir: string, out: string[] = []): string[] { - for (const entry of readdirSync(dir, { withFileTypes: true })) { - const full = path.join(dir, entry.name) - if (entry.isDirectory()) { - if (entry.name === 'node_modules' || entry.name === 'dist') { - continue - } - collectSourceFiles(full, out) - continue - } - if (!/\.tsx?$/.test(entry.name) || /\.(test|spec)\.tsx?$/.test(entry.name)) { - continue - } - out.push(full) - } - return out -} - -/** Reads the balanced argument text of the `useRef(...)` starting at `from`. */ -function readUseRefArgument(source: string, from: number): { arg: string; end: number } | null { - let i = from - while (source[i] === ' ') { - i++ - } - if (source[i] === '<') { - let depth = 0 - while (i < source.length) { - if (source[i] === '<') { - depth++ - } else if (source[i] === '>') { - depth-- - if (depth === 0) { - i++ - break - } - } - i++ - } - } - while (source[i] === ' ') { - i++ - } - if (source[i] !== '(') { - return null - } - const argStart = i + 1 - let depth = 0 - while (i < source.length) { - if (source[i] === '(') { - depth++ - } else if (source[i] === ')') { - depth-- - if (depth === 0) { - return { arg: source.slice(argStart, i).trim(), end: i + 1 } - } - } - i++ - } - return null -} - -// Allowed because none of these is work that a render repeats for nothing: -// - an empty collection literal, which the repo keeps in the direct form -// - `undefined!`, the lazy-seed marker -// - a function literal, which is the ref's payload rather than its initialization -// - a primitive coercion of an already-computed value -const ALLOWED_ARGUMENT = new RegExp( - [ - '^new (Map|Set|WeakMap|WeakSet)(<[\\s\\S]*>)?\\(\\)$', - '^undefined!$', - '^(async )?\\([\\s\\S]*?\\)\\s*(:[^=]*)?=>[\\s\\S]*$', - '^(Boolean|Number|String)\\([\\s\\S]*\\)$', - '^[A-Za-z_$][\\w$.?\\[\\]\'"]*$' - ].join('|') -) - -function findNonLazyUseRefs(file: string): string[] { - const source = readFileSync(file, 'utf8') - const findings: string[] = [] - let index = 0 - while ((index = source.indexOf('useRef', index)) !== -1) { - const start = index - index += 'useRef'.length - if (/[\w$.]/.test(source[start - 1] ?? '')) { - continue - } - const parsed = readUseRefArgument(source, index) - if (!parsed) { - continue - } - index = parsed.end - const arg = parsed.arg - if (arg === '' || ALLOWED_ARGUMENT.test(arg)) { - continue - } - // Only a call or constructor invocation actually burns work per render. - if (!/\(/.test(arg) && !/\bnew\b/.test(arg)) { - continue - } - const line = source.slice(0, start).split('\n').length - findings.push( - `${path.relative(RENDERER_ROOT, file)}:${line} useRef(${arg.replace(/\s+/g, ' ').slice(0, 90)})` - ) - } - return findings -} - -describe('renderer useRef initializers', () => { - it('never does work in the useRef argument', () => { - const findings = collectSourceFiles(RENDERER_ROOT).flatMap(findNonLazyUseRefs) - expect(findings).toEqual([]) - }) -})