feat(orcad): ship the mobile web page so phones paired to orcad get it (#29882)

* feat(orcad): ship the mobile web page so phones paired to orcad get it

orcad never carried out/mobile-web, so it did not advertise
mobileWeb.bundle.v1 and phones paired directly to an orcad server fell
back to the app's built-in native screens.

The built page now ships in every orcad package at out/mobile-web, the
path getBundledMobileWebBundleRoot already probes under the install
root. Its manifest is a fixed artifact; its content-addressed assets
join the hashed artifact list from that manifest, as one shared copy in
the template's common files. build-orcad fails when the page is missing
or stale, and CI lanes that build orcad now build the page first.

* ci(orcad): check out mobile/ for the Windows host template build

* refactor(orcad): copy the page tree whole and build it once per CI run

The guard already refuses unlisted files, so staging copies the
bundle directory as native-chat-visuals is copied. The shipped template
takes the page the qualification lanes tested, the e2e build artifact
carries it, and the PR smoke builds it through install-mobile-dependencies
behind its own scope step. Drops tests that duplicated the guard's own.

* fix(orcad): refuse a template page asset name that escapes the slot
This commit is contained in:
Jinwoo Hong
2026-10-16 19:29:41 -07:00
committed by GitHub
parent 0013011409
commit 776c791554
31 changed files with 505 additions and 72 deletions
+46 -4
View File
@@ -191,6 +191,7 @@ jobs:
if: runner.os == 'Windows'
with:
arches: ${{ (inputs.build_template && matrix.os == 'windows-2022') && 'x64 arm64' || (runner.arch == 'ARM64' && 'arm64' || 'x64') }}
- uses: ./.github/actions/build-mobile-web-bundle
- run: pnpm build:orcad
env:
ORCA_REUSE_PREPARED_WINDOWS_SECURITY: ${{ github.event_name == 'pull_request' && runner.os == 'Windows' && steps.dependencies.outcome == 'success' }}
@@ -297,14 +298,40 @@ jobs:
# A rerun attempt re-uploads under the same name, which v4 otherwise refuses.
overwrite: true
# The container lanes take the page from here: it is platform-independent, and building it needs
# mobile/node_modules, which those images never install.
mobile_web_bundle:
needs: changes
if: >-
${{ !cancelled() && needs.changes.outputs.should_run != 'false' &&
needs.changes.outputs.qualification != 'false' &&
(github.event_name != 'pull_request' || github.event.pull_request.draft != true) }}
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v6
with:
ref: ${{ inputs.ref }}
persist-credentials: false
- uses: ./.github/actions/install-node-dependencies
- uses: ./.github/actions/build-mobile-web-bundle
- uses: actions/upload-artifact@v7
with:
name: orcad-mobile-web-bundle
path: out/mobile-web/
if-no-files-found: error
retention-days: 1
overwrite: true
linux_glibc_floor:
needs: [changes, persistence]
needs: [changes, persistence, mobile_web_bundle]
concurrency:
group: node-server-linux_glibc_floor-${{ matrix.os }}-${{ github.event_name == 'push' && !inputs.build_template && inputs.ref == '' && github.ref || github.run_id }}
cancel-in-progress: ${{ github.event_name == 'push' && !inputs.build_template && inputs.ref == '' }}
# A failed smoke already blocks qualification; missing scope still selects every platform.
if: >-
${{ !cancelled() && needs.persistence.result == 'success' &&
needs.mobile_web_bundle.result == 'success' &&
needs.changes.outputs.should_run != 'false' &&
needs.changes.outputs.qualification != 'false' }}
strategy:
@@ -353,6 +380,10 @@ jobs:
pnpm build:orcad-prebuilds
pnpm build:orcad-prebuilds --require-slots "$(node config/scripts/build-orcad-prebuilds.mjs --print-slot)"
pnpm build:orcad-prebuilds --smoke
- uses: actions/download-artifact@v8
with:
name: orcad-mobile-web-bundle
path: out/mobile-web
- run: pnpm build:orcad
- run: pnpm test:node-server --artifact
- name: Keep this runner's glibc 2.28 slot for the desktop template
@@ -423,13 +454,14 @@ jobs:
overwrite: true
linux_musl:
needs: [changes, persistence]
needs: [changes, persistence, mobile_web_bundle]
concurrency:
group: node-server-linux_musl-${{ matrix.os }}-${{ github.event_name == 'push' && !inputs.build_template && inputs.ref == '' && github.ref || github.run_id }}
cancel-in-progress: ${{ github.event_name == 'push' && !inputs.build_template && inputs.ref == '' }}
# A failed smoke already blocks qualification; missing scope still selects every platform.
if: >-
${{ !cancelled() && needs.persistence.result == 'success' &&
needs.mobile_web_bundle.result == 'success' &&
needs.changes.outputs.should_run != 'false' &&
needs.changes.outputs.qualification != 'false' }}
strategy:
@@ -449,6 +481,10 @@ jobs:
id: pnpm-verification
with:
container-toolchain: 'true'
- uses: actions/download-artifact@v8
with:
name: orcad-mobile-web-bundle
path: out/mobile-web
- name: Verify native Alpine artifact and persistence
env:
VERIFICATION_CACHE_PATH: ${{ steps.pnpm-verification.outputs.path }}
@@ -483,10 +519,11 @@ jobs:
# Design D2: the desktop ships every target's addons, merged from the lanes that qualified them.
desktop_template:
needs: [persistence, linux_glibc_floor, linux_glibc217_compat, linux_musl]
needs: [persistence, mobile_web_bundle, linux_glibc_floor, linux_glibc217_compat, linux_musl]
if: >-
${{ !cancelled() && inputs.build_template &&
needs.persistence.result == 'success' && needs.linux_glibc_floor.result == 'success' &&
needs.persistence.result == 'success' && needs.mobile_web_bundle.result == 'success' &&
needs.linux_glibc_floor.result == 'success' &&
needs.linux_glibc217_compat.result == 'success' && needs.linux_musl.result == 'success' }}
runs-on: ubuntu-latest
timeout-minutes: 30
@@ -523,6 +560,11 @@ jobs:
node config/scripts/merge-orcad-prebuilds.mjs "$RUNNER_TEMP"/orcad-prebuild-lanes/*
pnpm build:orcad-prebuilds --require-slots
pnpm build:orcad-prebuilds --require-slots linux-x64-glibc217
# The page the qualification lanes tested, not a rebuild.
- uses: actions/download-artifact@v8
with:
name: orcad-mobile-web-bundle
path: out/mobile-web
- run: pnpm build:orcad-template
- name: Report the template size
shell: bash