mirror of
https://github.com/stablyai/orca.git
synced 2026-10-30 16:47:34 +00:00
* feat(wsl): bridge sh/dash/ash panes report their folder (OSC 7) at every prompt bash, zsh, fish and nushell panes already tell the terminal daemon their folder; a bridge pane whose login shell is sh, dash or busybox ash did not, so restores fell back to the starting folder. dash has no rcfile flag or prompt hook, but an interactive sh reads $ENV after ~/.profile, and dash 0.5.8+ (plus ash and bash-as-sh) expand $(...) in PS1. The bridge now points ENV at a new sh/env file in the published wrapper tree, saving the user's own ENV. That file hands ENV back to the user's value (so children see theirs), sources it, and inside WSL only prefixes PS1 with the report. A root containing $, ` or \ is skipped, since the shell expands ENV's value. A non-interactive sh -c never reads ENV, and a missing file (Orca updated away or uninstalled) is silently ignored by dash, ash and bash. * fix(wsl): sh ENV hook survives quotes in the user's ENV and keeps prompt width - The user's ENV is expanded through a here-document, so a value with a quote, $ or space no longer breaks startup with a syntax error. - bash-as-sh and busybox ash (fancy prompt) get the report inside \[ \] so its invisible bytes don't count toward the prompt width; dash has no line editor to miscount and would print \[ literally, so it stays bare. - Tests: a user ENV of `$HOME/u "q" sp/env`, a user PS1 with $, a quote and a backslash, and reports read through the daemon's WSL parser. - CI: edits to the sh hook and the bridge launch trigger the shell contracts job (its prefix list moves to its own module, keeping the scope script under its line limit), and the sh and fish WSL pty tests leave the unit shards. * ci: check out the shell-contract prefix module in the change detector The detector job sparse-checks-out a fixed file list; the new pr-shell-contract-prefixes.mjs that pr-code-change-scope.mjs imports was missing from it, so the job failed with ERR_MODULE_NOT_FOUND. A contract test now walks the scope script's local imports and requires each in that list. * ci: list the shell-contract prefix module wherever the scope script's modules are listed Two config-script suites copy pr-code-change-scope.mjs and its sibling modules into a fixture repo; without the new pr-shell-contract-prefixes.mjs the copied script failed to load, and the detector fell back to running everything. Also lists it with the scope script's other modules in the mobile workflow trigger and the mobile non-test file set.
363 lines
14 KiB
YAML
363 lines
14 KiB
YAML
name: Mobile Checks
|
||
|
||
on:
|
||
pull_request:
|
||
types:
|
||
- opened
|
||
- synchronize
|
||
- reopened
|
||
- ready_for_review
|
||
- converted_to_draft
|
||
paths:
|
||
- 'mobile/**'
|
||
# Route shared edits to mobile’s imports/RPC recordings/typecheck; root lockfile changes affect those modules’ root-resolved packages.
|
||
- '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/**'
|
||
- 'src/main/runtime/structured-attention-original-delivery.test-fixture.ts'
|
||
# Rerun the only Fastfile-loading checks for release-workflow/Fastfile edits.
|
||
- '.github/workflows/mobile.yml'
|
||
- 'config/mobile-ci.vitest.config.mjs'
|
||
- 'config/scripts/run-mobile-ci-tests.mjs'
|
||
# Mobile typechecks run through the root compiler selection.
|
||
- 'config/scripts/run-typecheck-projects-in-parallel.mjs'
|
||
- 'config/scripts/tsrs-typecheck-compiler.mjs'
|
||
- 'config/scripts/pinned-bun-executable.mjs'
|
||
- 'config/oxlint-code-quality-native-plugins.json'
|
||
- 'config/.bun-version'
|
||
- '.github/actions/install-node-dependencies/**'
|
||
- '.github/actions/setup-pnpm/**'
|
||
- '.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'
|
||
- 'config/scripts/pr-package-test-paths.mjs'
|
||
- 'config/scripts/pr-layout-oracle-route.mjs'
|
||
- 'config/scripts/pr-shell-contract-prefixes.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'
|
||
# Check matching source inputs on main too: independently passing PRs can conflict after merge, and verify is PR-only.
|
||
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/**'
|
||
- '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/scripts/run-typecheck-projects-in-parallel.mjs'
|
||
- 'config/scripts/tsrs-typecheck-compiler.mjs'
|
||
- 'config/scripts/pinned-bun-executable.mjs'
|
||
- 'config/.bun-version'
|
||
- '.github/actions/install-node-dependencies/**'
|
||
- '.github/actions/setup-pnpm/**'
|
||
# 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:
|
||
# Key main concurrency by commit: GitHub replaces pending runs even with cancel-in-progress:false, hiding middle-merge regressions.
|
||
group: mobile-${{ github.event.pull_request.number || github.sha }}
|
||
cancel-in-progress: true
|
||
|
||
permissions:
|
||
contents: read
|
||
|
||
jobs:
|
||
verify:
|
||
name: Mobile verify
|
||
if: github.event_name == 'pull_request' && github.event.pull_request.draft != true
|
||
# Use ARM for pure Vitest; no x86 native toolchain is needed and Gemfile.lock’s ruby platform supports frozen install.
|
||
runs-on: ubuntu-24.04-arm
|
||
|
||
env:
|
||
# Freeze bundler to reject Gemfile drift before release jobs resolve different fastlane versions.
|
||
BUNDLE_FROZEN: 'true'
|
||
ORCA_MOBILE_TYPECHECK_COMPILER: 'bun'
|
||
|
||
defaults:
|
||
run:
|
||
working-directory: mobile
|
||
|
||
steps:
|
||
- name: Checkout
|
||
uses: actions/checkout@v6
|
||
with:
|
||
fetch-depth: 2
|
||
|
||
- uses: ./.github/actions/install-node-dependencies
|
||
with:
|
||
cache-pnpm-store: 'false'
|
||
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
|
||
|
||
- name: Setup Ruby
|
||
id: ruby-setup
|
||
background: true
|
||
if: steps.ruby-scope.outputs.should_run != 'false'
|
||
uses: ruby/setup-ruby@v1
|
||
with:
|
||
ruby-version: '3.3'
|
||
working-directory: mobile
|
||
|
||
- name: Install dependencies
|
||
run: pnpm install --frozen-lockfile
|
||
|
||
- wait: ruby-setup
|
||
|
||
# ruby/setup-ruby's bundler-cache saves on every miss; the platform warmup saves this key on main.
|
||
- name: Resolve fastlane bundle cache
|
||
id: ruby-bundle
|
||
if: steps.ruby-scope.outputs.should_run != 'false'
|
||
env:
|
||
GEMFILE_HASH: ${{ hashFiles('mobile/Gemfile', 'mobile/Gemfile.lock') }}
|
||
run: |
|
||
. /etc/os-release
|
||
printf 'key=mobile-bundle-v1-%s-%s-%s-%s\n' "$ID-$VERSION_ID" "$(ruby -e 'print RUBY_PLATFORM')" "$(ruby -e 'print RbConfig::CONFIG["ruby_version"]')" "$GEMFILE_HASH" >> "$GITHUB_OUTPUT"
|
||
|
||
- name: Restore fastlane bundle
|
||
if: steps.ruby-scope.outputs.should_run != 'false'
|
||
uses: actions/cache/restore@v5
|
||
with:
|
||
path: mobile/vendor/bundle
|
||
key: ${{ steps.ruby-bundle.outputs.key }}
|
||
|
||
# Installing proves the release’s pinned fastlane still resolves before a release needs it.
|
||
- name: Install fastlane
|
||
id: ruby-tools
|
||
background: true
|
||
if: steps.ruby-scope.outputs.should_run != 'false'
|
||
run: |
|
||
bundle config set --local path "$PWD/vendor/bundle"
|
||
bundle config set --local deployment true
|
||
bundle install --jobs 4
|
||
|
||
# Check mobile import cycles after Expo deps install; pre-install pr.yml cannot load its tsconfig.
|
||
- name: Lint mobile imports with mobile dependencies installed
|
||
working-directory: .
|
||
run: node node_modules/oxlint/bin/oxlint --config config/oxlint-code-quality-native-plugins.json mobile --deny-warnings
|
||
|
||
# Call installed tools so pnpm's dependency refresh cannot race between checks.
|
||
- name: Typecheck
|
||
id: production-types
|
||
background: true
|
||
run: node ../config/scripts/run-typecheck-projects-in-parallel.mjs --compiler=bun --bun-threads=2 --project=mobile/tsconfig.json
|
||
|
||
# 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)
|
||
id: test-types
|
||
background: true
|
||
run: node scripts/check-tests-typecheck-ratchet.mjs
|
||
|
||
# Run bridged recording corpus unconditionally: reject growing/unclassified divergence and changed verdicts among 103 C1 goldens. Share worker time instead of a separate skippable env-gated step.
|
||
- 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: Setup Bun for tests
|
||
if: steps.test-scope.outputs.should_run != 'false'
|
||
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0
|
||
with:
|
||
bun-version-file: config/.bun-version
|
||
no-cache: true
|
||
|
||
- name: Test
|
||
if: steps.test-scope.outputs.should_run != 'false'
|
||
env:
|
||
ORCA_BACKGROUND_LAUNCH: '1'
|
||
run: node ../config/scripts/run-mobile-ci-tests.mjs
|
||
|
||
# All checks read the completed install; compilers need not hold up test workers.
|
||
- wait: [production-types, test-types, ruby-tools]
|
||
|
||
# Decode hash-addressed golden behavior changes for review, including after failed tests; advisory only.
|
||
- 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
|
||
|
||
# Load/list Fastfile lanes without Apple credentials/network to catch syntax/require/constants before release; ios-distribute failed six days without this guard.
|
||
- 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: Smoke-check CocoaPods
|
||
if: steps.ruby-scope.outputs.should_run != 'false'
|
||
run: bundle exec pod --version
|
||
|
||
- name: Lint
|
||
run: pnpm lint
|
||
|
||
- name: Check formatting
|
||
run: pnpm format:check
|
||
|
||
# Reports, never gates: flags in the job summary when a pull request changes the Expo fingerprint,
|
||
# i.e. dev clients need a native rebuild. Only mobile's install, without scripts: the fingerprint
|
||
# hashes project sources and dependency paths, never installed package contents.
|
||
native-fingerprint:
|
||
name: Mobile native fingerprint
|
||
if: github.event_name == 'pull_request' && github.event.pull_request.draft != true
|
||
runs-on: ubuntu-24.04
|
||
timeout-minutes: 15
|
||
continue-on-error: true
|
||
|
||
defaults:
|
||
run:
|
||
working-directory: mobile
|
||
|
||
steps:
|
||
- name: Checkout
|
||
uses: actions/checkout@v6
|
||
with:
|
||
fetch-depth: 2
|
||
persist-credentials: false
|
||
|
||
- uses: actions/setup-node@v6
|
||
with:
|
||
node-version-file: package.json
|
||
package-manager-cache: false
|
||
|
||
- name: Setup pnpm
|
||
uses: ./.github/actions/setup-pnpm
|
||
|
||
# The base commit may predate the fingerprint tools, so run the head's copy against both.
|
||
- name: Compare native fingerprint with the base
|
||
shell: bash
|
||
run: |
|
||
set -euo pipefail
|
||
tools="$RUNNER_TEMP/native-fingerprint"
|
||
mkdir -p "$tools"
|
||
cp scripts/native-client.mjs scripts/native-build-cache.cjs "$tools/"
|
||
pnpm install --frozen-lockfile --ignore-scripts
|
||
node "$tools/native-client.mjs" fingerprint --project . --out "$tools/head.json"
|
||
git checkout --quiet --detach HEAD^1
|
||
pnpm install --frozen-lockfile --ignore-scripts
|
||
node "$tools/native-client.mjs" fingerprint --project . --out "$tools/base.json"
|
||
node "$tools/native-client.mjs" compare "$tools/base.json" "$tools/head.json" \
|
||
--project . --summary "$GITHUB_STEP_SUMMARY"
|
||
|
||
main-tests:
|
||
name: Mobile tests on main
|
||
env:
|
||
ORCA_MOBILE_TYPECHECK_COMPILER: 'bun'
|
||
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
|
||
|
||
# Restoring the 650 MB store took longer than downloading these packages.
|
||
- uses: ./.github/actions/install-node-dependencies
|
||
with:
|
||
cache-pnpm-store: 'false'
|
||
cache-dependency-path: |
|
||
pnpm-lock.yaml
|
||
mobile/pnpm-lock.yaml
|
||
|
||
- name: Install dependencies
|
||
run: pnpm install --frozen-lockfile
|
||
|
||
- name: Typecheck
|
||
id: production-types
|
||
background: true
|
||
run: node ../config/scripts/run-typecheck-projects-in-parallel.mjs --compiler=bun --bun-threads=2 --project=mobile/tsconfig.json
|
||
|
||
- name: Typecheck tests (ratchet)
|
||
id: test-types
|
||
background: true
|
||
run: node scripts/check-tests-typecheck-ratchet.mjs
|
||
|
||
# Run all golden consumers, including mutant/page-bridge suites; failures name the recording and rpc:record command.
|
||
- name: Setup Bun for tests
|
||
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0
|
||
with:
|
||
bun-version-file: config/.bun-version
|
||
no-cache: true
|
||
|
||
- name: Test
|
||
env:
|
||
ORCA_BACKGROUND_LAUNCH: '1'
|
||
run: node ../config/scripts/run-mobile-ci-tests.mjs
|
||
|
||
- wait: [production-types, test-types]
|