mirror of
https://github.com/stablyai/orca.git
synced 2026-10-31 00:57:45 +00:00
ci: avoid mobile runs for desktop test-only changes (#29138)
This commit is contained in:
@@ -24,6 +24,7 @@ on:
|
||||
- 'src/main/runtime/orca-runtime.ts'
|
||||
- 'src/main/runtime/agent-session-*.ts'
|
||||
- 'src/main/native-chat/agent-session-wire/**'
|
||||
- 'src/main/runtime/structured-attention-original-delivery.test-fixture.ts'
|
||||
# Why: this job holds the only checks that load the Fastfile, so edits to
|
||||
# it or to the release workflow it guards must re-run them.
|
||||
- '.github/workflows/mobile.yml'
|
||||
@@ -38,6 +39,16 @@ on:
|
||||
- 'config/scripts/pr-code-change-scope.mjs'
|
||||
- 'config/scripts/pr-package-test-paths.mjs'
|
||||
- 'config/scripts/pr-layout-oracle-route.mjs'
|
||||
# Desktop suites do not feed mobile; keep fixtures and test/toolchain config inputs.
|
||||
- '!src/shared/**/*.test.[jt]s'
|
||||
- '!src/shared/**/*.test.[jt]sx'
|
||||
- '!src/shared/**/*.test.[cm][jt]s'
|
||||
- '!src/packages/process-host/**/*.test.[jt]s'
|
||||
- '!src/packages/process-host/**/*.test.[jt]sx'
|
||||
- '!src/packages/process-host/**/*.test.[cm][jt]s'
|
||||
- '!src/main/**/*.test.[jt]s'
|
||||
- '!src/main/**/*.test.[jt]sx'
|
||||
- '!src/main/**/*.test.[cm][jt]s'
|
||||
# Why main too: two pull requests can each pass against their own base and disagree once both
|
||||
# land, and `verify` never runs on main. The same source paths as above, less the CI inputs only
|
||||
# `verify` reads.
|
||||
@@ -57,10 +68,21 @@ on:
|
||||
- 'src/main/runtime/orca-runtime.ts'
|
||||
- 'src/main/runtime/agent-session-*.ts'
|
||||
- 'src/main/native-chat/agent-session-wire/**'
|
||||
- 'src/main/runtime/structured-attention-original-delivery.test-fixture.ts'
|
||||
- '.github/workflows/mobile.yml'
|
||||
- 'config/mobile-ci.vitest.config.mjs'
|
||||
- 'config/scripts/run-mobile-ci-tests.mjs'
|
||||
- 'config/.bun-version'
|
||||
# Desktop suites do not feed mobile; keep fixtures and test/toolchain config inputs.
|
||||
- '!src/shared/**/*.test.[jt]s'
|
||||
- '!src/shared/**/*.test.[jt]sx'
|
||||
- '!src/shared/**/*.test.[cm][jt]s'
|
||||
- '!src/packages/process-host/**/*.test.[jt]s'
|
||||
- '!src/packages/process-host/**/*.test.[jt]sx'
|
||||
- '!src/packages/process-host/**/*.test.[cm][jt]s'
|
||||
- '!src/main/**/*.test.[jt]s'
|
||||
- '!src/main/**/*.test.[jt]sx'
|
||||
- '!src/main/**/*.test.[cm][jt]s'
|
||||
|
||||
concurrency:
|
||||
# Per commit on main, not per branch. GitHub cancels any PENDING run in a group when a new one
|
||||
|
||||
@@ -15,6 +15,23 @@ const NON_TEST_FILES = new Set([
|
||||
'config/scripts/mobile-release-check-scope.test.mjs'
|
||||
])
|
||||
|
||||
const DESKTOP_SUITE_PREFIXES = [
|
||||
'src/shared/',
|
||||
'src/packages/process-host/',
|
||||
'src/main/agent-launch/',
|
||||
'src/main/runtime/rpc/',
|
||||
'src/main/runtime/runtime-rpc/',
|
||||
'src/main/runtime/agent-session-',
|
||||
'src/main/native-chat/agent-session-wire/'
|
||||
]
|
||||
|
||||
function isDesktopSuite(file) {
|
||||
return (
|
||||
DESKTOP_SUITE_PREFIXES.some((prefix) => file.startsWith(prefix)) &&
|
||||
/\.test\.(?:[cm]?[jt]s|[jt]sx)$/.test(file)
|
||||
)
|
||||
}
|
||||
|
||||
export function shouldRunMobileTests(files) {
|
||||
return (
|
||||
files.length === 0 ||
|
||||
@@ -23,6 +40,7 @@ export function shouldRunMobileTests(files) {
|
||||
file.split('/').includes('..') ||
|
||||
(!isDocsOnlyPath(file) &&
|
||||
!NON_TEST_FILES.has(file) &&
|
||||
!isDesktopSuite(file) &&
|
||||
!file.startsWith('mobile/docs/') &&
|
||||
!file.startsWith('mobile/fastlane/'))
|
||||
)
|
||||
|
||||
@@ -4,6 +4,15 @@ import { parse } from 'yaml'
|
||||
import { expect, it } from 'vitest'
|
||||
import { shouldRunMobileTests } from './mobile-test-change-scope.mjs'
|
||||
|
||||
function workflowIncludes(paths, files) {
|
||||
return files.some((file) =>
|
||||
paths.reduce((included, pattern) => {
|
||||
const excluded = pattern.startsWith('!')
|
||||
return matchesGlob(file, excluded ? pattern.slice(1) : pattern) ? !excluded : included
|
||||
}, false)
|
||||
)
|
||||
}
|
||||
|
||||
it.each([
|
||||
'docs/ci.md',
|
||||
'mobile/docs/release.md',
|
||||
@@ -54,16 +63,85 @@ it('runs Mobile Checks for shared modules, process-host tooling and the root loc
|
||||
'src/shared/any/module.ts',
|
||||
'src/packages/process-host/src/run-process.ts',
|
||||
'src/packages/process-host/package.json',
|
||||
'src/main/runtime/structured-attention-original-delivery.test-fixture.ts',
|
||||
'pnpm-lock.yaml'
|
||||
]) {
|
||||
expect(paths.some((pattern) => matchesGlob(file, pattern))).toBe(true)
|
||||
expect(workflowIncludes(paths, [file])).toBe(true)
|
||||
}
|
||||
expect(
|
||||
paths.some((pattern) => matchesGlob('src/packages/unrelated/src/index.ts', pattern))
|
||||
).toBe(false)
|
||||
expect(workflowIncludes(paths, ['src/packages/unrelated/src/index.ts'])).toBe(false)
|
||||
}
|
||||
})
|
||||
|
||||
it('honors ordered exclusions and later re-inclusion when matching workflow paths', () => {
|
||||
const paths = ['src/**', '!src/**/*.test.ts', 'src/retained.test.ts']
|
||||
expect(workflowIncludes(paths, ['src/removed.test.ts'])).toBe(false)
|
||||
expect(workflowIncludes(paths, ['src/retained.test.ts'])).toBe(true)
|
||||
})
|
||||
|
||||
it.each([
|
||||
'src/shared/model-id-label.test.ts',
|
||||
'src/shared/nested/view.test.tsx',
|
||||
'src/shared/nested/module.test.js',
|
||||
'src/shared/nested/view.test.jsx',
|
||||
'src/shared/nested/module.test.cjs',
|
||||
'src/shared/nested/module.test.mjs',
|
||||
'src/shared/nested/module.test.cts',
|
||||
'src/shared/nested/module.test.mts',
|
||||
'src/packages/process-host/src/run-process.test.ts',
|
||||
'src/main/agent-launch/dispatch.test.ts',
|
||||
'src/main/runtime/rpc/dispatcher.test.ts',
|
||||
'src/main/runtime/runtime-rpc/server.test.ts',
|
||||
'src/main/runtime/agent-session-store.test.ts',
|
||||
'src/main/native-chat/agent-session-wire/history.test.ts'
|
||||
])('skips desktop suites on PRs and main, including removal: %s', (file) => {
|
||||
const workflow = parse(
|
||||
readFileSync(new URL('../../.github/workflows/mobile.yml', import.meta.url), 'utf8')
|
||||
)
|
||||
expect(shouldRunMobileTests([file])).toBe(false)
|
||||
expect(shouldRunMobileTests([file, 'mobile/docs/ci.md'])).toBe(false)
|
||||
for (const paths of [workflow.on.pull_request.paths, workflow.on.push.paths]) {
|
||||
expect(workflowIncludes(paths, [file])).toBe(false)
|
||||
expect(workflowIncludes(paths, [file, 'src/shared/changed.ts'])).toBe(true)
|
||||
expect(workflowIncludes(paths, [file, 'mobile/src/changed.test.ts'])).toBe(true)
|
||||
// A rename is represented by the removed and added names, so moving a suite into source runs.
|
||||
expect(workflowIncludes(paths, [file, file.replace('.test.', '.')])).toBe(true)
|
||||
}
|
||||
expect(shouldRunMobileTests([file, 'src/shared/changed.ts'])).toBe(true)
|
||||
expect(shouldRunMobileTests([file, file.replace('.test.', '.')])).toBe(true)
|
||||
})
|
||||
|
||||
it.each([
|
||||
'mobile/src/changed.test.ts',
|
||||
'mobile/src/changed.test.tsx',
|
||||
'src/shared/project-section-parity.test-fixture.ts',
|
||||
'src/shared/fixtures/recording.json',
|
||||
'src/main/runtime/rpc/methods/agent-launch.test-fixture.ts',
|
||||
'src/main/runtime/agent-session-record-store-test-harness.ts',
|
||||
'src/packages/process-host/tsconfig.test.json',
|
||||
'src/packages/process-host/vitest.config.ts',
|
||||
'src/packages/process-host/package.json',
|
||||
'pnpm-lock.yaml',
|
||||
'mobile/pnpm-lock.yaml',
|
||||
'config/mobile-ci.vitest.config.mjs',
|
||||
'config/scripts/run-mobile-ci-tests.mjs',
|
||||
'config/.bun-version',
|
||||
'.github/workflows/mobile.yml'
|
||||
])('retains mobile suites, shared fixtures and toolchain inputs: %s', (file) => {
|
||||
const workflow = parse(
|
||||
readFileSync(new URL('../../.github/workflows/mobile.yml', import.meta.url), 'utf8')
|
||||
)
|
||||
expect(shouldRunMobileTests([file])).toBe(true)
|
||||
for (const paths of [workflow.on.pull_request.paths, workflow.on.push.paths]) {
|
||||
expect(workflowIncludes(paths, [file])).toBe(true)
|
||||
}
|
||||
})
|
||||
|
||||
it('retains unknown suite paths and noncanonical traversal evidence', () => {
|
||||
expect(shouldRunMobileTests(['unknown/module.test.ts'])).toBe(true)
|
||||
expect(shouldRunMobileTests(['src/unknown/module.test.ts'])).toBe(true)
|
||||
expect(shouldRunMobileTests(['src/shared/../main/module.test.ts'])).toBe(true)
|
||||
})
|
||||
|
||||
it('skips only tests, after successful detection, and retains all other mobile gates', () => {
|
||||
const workflow = parse(
|
||||
readFileSync(new URL('../../.github/workflows/mobile.yml', import.meta.url), 'utf8')
|
||||
|
||||
Reference in New Issue
Block a user