mirror of
https://github.com/stablyai/orca.git
synced 2026-10-31 17:17:38 +00:00
Extract subprocess execution and process contracts into @orca/process-host with explicit public entry points, independent checks, and one Node 18 compatible CommonJS runtime. Migrate application consumers and integrate package builds, dependency selection, import enforcement, and runtime resource staging. Preserve daemon startup ownership and profile isolation, and qualify development rebuild recovery and concurrent output publication. Remove unnecessary aliases, test forwarding exports, and a duplicate output scan. Validation: full typechecks, changed-code quality, package and artifact checks, native Windows builds/types plus 306 runtime tests, and independent native reviews. Matched full E2E controls on original main and unchanged reviewed head both pass all 17 applicable tests (nine skips). Earlier intermittent E2E failures are documented in the PR; no assertions were weakened. The final combined-tree audit preserves both branches with no import-boundary violations.
224 lines
8.9 KiB
YAML
224 lines
8.9 KiB
YAML
name: Mobile Checks
|
|
|
|
on:
|
|
pull_request:
|
|
types:
|
|
- opened
|
|
- synchronize
|
|
- reopened
|
|
paths:
|
|
- 'mobile/**'
|
|
# Why all of src/shared: mobile imports hundreds of its modules, directly and through the RPC
|
|
# recordings and the host params check, so any shared edit can move a golden or break mobile's
|
|
# typecheck. Why the root lockfile: those modules resolve their packages from the root install.
|
|
- 'src/shared/**'
|
|
# Mobile's Node RPC recording tools import this package.
|
|
- 'src/packages/process-host/**'
|
|
- 'pnpm-lock.yaml'
|
|
# Mobile launch contracts exercise the real host dispatcher and durable receipt store.
|
|
- 'src/main/agent-launch/**'
|
|
- 'src/main/runtime/rpc/**'
|
|
- 'src/main/runtime/runtime-rpc/**'
|
|
- 'src/main/runtime/runtime-rpc.ts'
|
|
- 'src/main/runtime/device-registry.ts'
|
|
- 'src/main/runtime/orca-runtime.ts'
|
|
- 'src/main/runtime/agent-session-*.ts'
|
|
- 'src/main/native-chat/agent-session-wire/**'
|
|
# 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'
|
|
- '.github/actions/install-node-dependencies/**'
|
|
- '.github/actions/restore-pnpm-verification/**'
|
|
- '.github/workflows/mobile-ios-release.yml'
|
|
- 'config/scripts/mobile-release-check-scope*'
|
|
- 'config/scripts/mobile-test-change-scope*'
|
|
- 'config/scripts/pr-code-change-scope.mjs'
|
|
# 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.
|
|
push:
|
|
branches:
|
|
- main
|
|
paths:
|
|
- 'mobile/**'
|
|
- 'src/shared/**'
|
|
- 'src/packages/process-host/**'
|
|
- 'pnpm-lock.yaml'
|
|
- 'src/main/agent-launch/**'
|
|
- 'src/main/runtime/rpc/**'
|
|
- 'src/main/runtime/runtime-rpc/**'
|
|
- 'src/main/runtime/runtime-rpc.ts'
|
|
- 'src/main/runtime/device-registry.ts'
|
|
- 'src/main/runtime/orca-runtime.ts'
|
|
- 'src/main/runtime/agent-session-*.ts'
|
|
- 'src/main/native-chat/agent-session-wire/**'
|
|
- '.github/workflows/mobile.yml'
|
|
|
|
concurrency:
|
|
# Per commit on main, not per branch. GitHub cancels any PENDING run in a group when a new one
|
|
# queues, whatever `cancel-in-progress` says, so one shared main group drops the middle merge of
|
|
# three -- and a merge that breaks main there is exactly what `main-tests` checks for.
|
|
group: mobile-${{ github.event.pull_request.number || github.sha }}
|
|
cancel-in-progress: true
|
|
|
|
jobs:
|
|
verify:
|
|
if: github.event_name == 'pull_request'
|
|
# Why ARM: 209s of this job is Vitest and nothing here needs x86: no Android SDK, emulator, gradle,
|
|
# Hermes or Watchman, no docker, and no artifacts. The Gemfile.lock lists the generic `ruby`
|
|
# platform, so frozen bundler installs without an aarch64-linux entry.
|
|
runs-on: ubuntu-24.04-arm
|
|
|
|
env:
|
|
# Why: an unfrozen bundler silently re-resolves when Gemfile.lock drifts
|
|
# from the Gemfile, which is how the release jobs could land on different
|
|
# fastlane versions in the first place. Fail here instead.
|
|
BUNDLE_FROZEN: 'true'
|
|
|
|
defaults:
|
|
run:
|
|
working-directory: mobile
|
|
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@v6
|
|
with:
|
|
fetch-depth: 2
|
|
|
|
- uses: ./.github/actions/install-node-dependencies
|
|
with:
|
|
cache-dependency-path: |
|
|
pnpm-lock.yaml
|
|
mobile/pnpm-lock.yaml
|
|
|
|
- name: Detect Ruby release inputs
|
|
id: ruby-scope
|
|
shell: bash
|
|
working-directory: .
|
|
run: |
|
|
# Keep deletions when release files move into an application directory.
|
|
if ! git diff --name-only --no-renames -z HEAD^1 HEAD > "$RUNNER_TEMP/mobile-release-changes"; then
|
|
echo 'should_run=true' >> "$GITHUB_OUTPUT"
|
|
elif ! node config/scripts/mobile-release-check-scope.mjs "$RUNNER_TEMP/mobile-release-changes"; then
|
|
echo 'should_run=true' >> "$GITHUB_OUTPUT"
|
|
fi
|
|
|
|
# bundler-cache installs mobile/Gemfile.lock, so this job is also what
|
|
# proves the pinned fastlane the release workflow depends on still
|
|
# resolves — before a release run finds out.
|
|
- name: Setup Ruby and fastlane
|
|
if: steps.ruby-scope.outputs.should_run != 'false'
|
|
uses: ruby/setup-ruby@v1
|
|
with:
|
|
ruby-version: '3.3'
|
|
bundler-cache: true
|
|
working-directory: mobile
|
|
|
|
- name: Install dependencies
|
|
run: pnpm install --frozen-lockfile
|
|
|
|
# Call installed tools so pnpm's dependency refresh cannot race between checks.
|
|
- name: Typecheck
|
|
id: production-types
|
|
background: true
|
|
run: node node_modules/typescript/bin/tsc --noEmit
|
|
|
|
# Why a ratchet and not the raw typecheck: mobile/tsconfig.json excludes test files, so until
|
|
# tsconfig.test.json existed nothing checked them, and at introduction 127 of the 632 had
|
|
# drifted. This fails when a test file that checks today stops checking, when a test leaves
|
|
# the program, and on @ts-nocheck; the baseline may only shrink.
|
|
- name: Typecheck tests (ratchet)
|
|
run: node scripts/check-tests-typecheck-ratchet.mjs
|
|
|
|
- wait: production-types
|
|
|
|
# This includes the bridged replay of the whole recording corpus, which used to be a second
|
|
# step of its own behind RPC_FOUNDATION_BRIDGE=1. A gate nobody can forget to set is the point:
|
|
# it fails when a divergence class grows, when a divergence lands in no class at all, or when
|
|
# one of the 103 goldens inside the C1 page closure changes the verdict it is pinned to. It is
|
|
# ~3 min of test time on its own, and Vitest runs it on a worker beside the rest of the suite,
|
|
# so folding it in costs a fraction of that in wall time and one step less to skip.
|
|
- name: Detect mobile test inputs
|
|
id: test-scope
|
|
shell: bash
|
|
working-directory: .
|
|
run: |
|
|
if ! git diff --name-only --no-renames -z HEAD^1 HEAD > "$RUNNER_TEMP/mobile-test-changes"; then
|
|
echo 'should_run=true' >> "$GITHUB_OUTPUT"
|
|
elif ! node config/scripts/mobile-test-change-scope.mjs "$RUNNER_TEMP/mobile-test-changes"; then
|
|
echo 'should_run=true' >> "$GITHUB_OUTPUT"
|
|
fi
|
|
|
|
- name: Test
|
|
if: steps.test-scope.outputs.should_run != 'false'
|
|
env:
|
|
ORCA_BACKGROUND_LAUNCH: '1'
|
|
run: pnpm test
|
|
|
|
# Reports, never gates: the goldens are content-addressed JSON, so their raw diff is hashes.
|
|
# This decodes which recorded behaviour the pull request moves into the job summary, and runs
|
|
# after a red Test too, when a reviewer most wants it.
|
|
- name: Summarize RPC recording changes
|
|
if: ${{ !cancelled() }}
|
|
continue-on-error: true
|
|
run: pnpm run rpc:diff HEAD^1 --summary "$GITHUB_STEP_SUMMARY"
|
|
|
|
- name: Test iOS release version resolution
|
|
if: steps.ruby-scope.outputs.should_run != 'false'
|
|
run: ruby fastlane/ios_release_version_test.rb
|
|
|
|
- name: Test TestFlight lane arguments
|
|
if: steps.ruby-scope.outputs.should_run != 'false'
|
|
run: ruby fastlane/fastfile_testflight_arguments_test.rb
|
|
|
|
# Why: nothing else in CI loads the Fastfile, so a syntax error, a broken
|
|
# require, or an undefined constant only surfaces mid-release — the
|
|
# ios-distribute job failed every run for six days that way. `lanes` just
|
|
# loads and lists, so it needs no App Store Connect credentials and makes
|
|
# no network calls to Apple.
|
|
- name: Smoke-check the Fastfile
|
|
if: steps.ruby-scope.outputs.should_run != 'false'
|
|
env:
|
|
FASTLANE_SKIP_UPDATE_CHECK: '1'
|
|
FASTLANE_OPT_OUT_USAGE: '1'
|
|
run: bundle exec fastlane lanes
|
|
|
|
- name: Lint
|
|
run: pnpm lint
|
|
|
|
- name: Check formatting
|
|
run: pnpm format:check
|
|
|
|
main-tests:
|
|
name: Mobile tests on main
|
|
if: github.event_name == 'push'
|
|
# Why ARM: the same pure-Node Vitest run `verify` makes on a pull request.
|
|
runs-on: ubuntu-24.04-arm
|
|
|
|
defaults:
|
|
run:
|
|
working-directory: mobile
|
|
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@v6
|
|
with:
|
|
persist-credentials: false
|
|
|
|
- uses: ./.github/actions/install-node-dependencies
|
|
with:
|
|
cache-dependency-path: |
|
|
pnpm-lock.yaml
|
|
mobile/pnpm-lock.yaml
|
|
|
|
- name: Install dependencies
|
|
run: pnpm install --frozen-lockfile
|
|
|
|
# The whole suite, not only the recordings: the mutant and page-bridge suites read the goldens
|
|
# too. A red run here names each golden and the `rpc:record` command; the author of the merge
|
|
# that turned it red re-records in a follow-up.
|
|
- name: Test
|
|
env:
|
|
ORCA_BACKGROUND_LAUNCH: '1'
|
|
run: pnpm test
|