Skip to content

feat(app-expo): Windows-friendly Android dev scripts + environment doctor - #691

Open
k6G52m4Dz75W wants to merge 9 commits into
codedogQBY:mainfrom
k6G52m4Dz75W:feat/windows-android-onboarding
Open

feat(app-expo): Windows-friendly Android dev scripts + environment doctor#691
k6G52m4Dz75W wants to merge 9 commits into
codedogQBY:mainfrom
k6G52m4Dz75W:feat/windows-android-onboarding

Conversation

@k6G52m4Dz75W

Copy link
Copy Markdown
Contributor

Summary

On Windows, every expo:* npm script failed with
'APP_VARIANT' 不是内部或外部命令 because the scripts used Unix-style
APP_VARIANT=development pnpm ... env assignment, which cmd/PowerShell do not
support. This PR makes the mobile dev scripts work cross-platform and adds a
doctor script so Windows contributors can verify their Android toolchain in one
command.

Changes

  • cross-env: prefix all APP_VARIANT=... scripts (start, start:clear,
    android:dev, ios:*, eas:build:*) with cross-env (added as a
    devDependency) so they run in Windows PowerShell/cmd and keep working on
    macOS/Linux/CI.
  • scripts/check-android-env.ps1: a PowerShell doctor that checks
    Node/pnpm, JDK 17+, the Android SDK (platform-tools, platforms, build-tools,
    accepted licenses) and an emulator AVD / connected device. Prints [ OK ] /
    [FAIL] per item with concrete fix steps and exits non-zero on failure.
  • pnpm expo:doctor:android: new npm script + root alias to run the check.
  • Docs: added a "Windows: Android development setup" section to
    README.md / README_CN.md (JDK, Android Studio, SDK components, AVD, env
    vars, then pnpm expo:doctor:androidpnpm expo:start + pnpm expo:android).

Example output

ReadAny - Android dev environment check

[ OK ] Node.js
[ OK ] pnpm
[FAIL] JDK (JAVA_HOME=)
       > JAVA_HOME is not set. Install JDK 17/21 and set JAVA_HOME (...).
[ OK ] Android SDK (C:\Users\...\Android\Sdk)
[ OK ] platform-tools (adb)
[ OK ] Android SDK Platform (API 35+)
[ OK ] Android SDK Build-Tools
[ OK ] SDK licenses accepted
[FAIL] Android device/emulator connected
       > Start an emulator (Device Manager) or connect a device with USB debugging enabled.
[ OK ] Emulator AVD configured

8 passed, 2 failed

@k6G52m4Dz75W
k6G52m4Dz75W changed the base branch from main to refactor/sync-unified-storage August 25, 2026 14:42
@k6G52m4Dz75W
k6G52m4Dz75W changed the base branch from refactor/sync-unified-storage to main August 25, 2026 14:42
The npm scripts used Unix-style APP_VARIANT=development cmd env assignment,
which fails on Windows cmd/PowerShell ('APP_VARIANT' is not recognized). Prefix
them with cross-env (added as devDependency) so pnpm start / pnpm android
work cross-platform.
… doctor

- npm scripts used Unix-style APP_VARIANT=... which fails on Windows
  cmd/PowerShell. Prefix with cross-env (new devDependency) so pnpm
  expo:start / expo:android work cross-platform.
- Add scripts/check-android-env.ps1: a doctor that verifies Node/pnpm, JDK
  17+, Android SDK (platform-tools, platforms, build-tools, licenses) and an
  emulator/device, printing concrete fix steps and exiting non-zero on failure.
- Wire pnpm expo:doctor:android (app-expo doctor:android + root alias).
- Document the Windows Android setup in README.md / README_CN.md.
…'t swallow it

Under Continue=SilentlyContinue, PowerShell drops the
NativeCommandError records produced by 2>&1, so java -version came back empty
and the doctor reported "Could not read the JDK version". Merge java's stderr
at the OS level with cmd /c ... 2>&1 instead.
@k6G52m4Dz75W
k6G52m4Dz75W force-pushed the feat/windows-android-onboarding branch from f96fd8a to 14af9c2 Compare September 12, 2026 11:13
- JDK check: enforce the full Gradle 8.13 range (17-21) — the old
  $major -ge 17 silently passed JDK 22+ while the hint text claimed
  they were too new; normalize legacy 1.8.0_x version strings (they
  parsed as 'JDK 1'); split the hint for too-old vs too-new.
- SDK check: do not report PASS on the default-folder fallback alone.
  Gradle resolves the SDK from ANDROID_HOME/ANDROID_SDK_ROOT or
  android/local.properties — a bare default path is exactly the 'SDK
  location not found' trap, so it now WARNs with the fix steps.
- Device/AVD checks: honor the documented 'AVD or connected device'
  semantics — each half degrades to WARN when the other is satisfied,
  so a clean setup with the emulator not yet running no longer fails
  the whole doctor.
- Node check: parse node -v and enforce the documented 18+ minimum
  instead of just checking the command exists.
- cross-env: pin ^7.0.3 — v10 requires Node >=20 while the project
  documents Node 18; v7 fully covers the env-var prefix use case.
…view)

The WARN flag was passed to Write-Result while Ok stayed true, so the
elseif branch never ran and a default-path fallback still printed a
green pass — silently violating the very rule the comment stated.
Pass Ok as (found AND env-sourced) so the three states are distinct:
env-sourced = OK, default-path only = WARN, missing = FAIL. Also tint
the summary yellow when only warnings remain. Verified by running the
doctor with ANDROID_HOME cleared (WARN branch fires, exit stays 0).
- Node check: use an explicit if instead of -and chaining — PowerShell's
  -and does not short-circuit, so a failed node -v match would still
  evaluate [int]$Matches[1] against whatever the JDK regex left behind.
- SDK WARN hint: point at the actual fix (set ANDROID_HOME / pin
  sdk.dir) instead of telling the user to install Android Studio they
  already have; the install guidance stays for the true FAIL case.

Verified: normal env (10 passed), cleared env (WARN branch fires,
exit 0), and the JDK 25 too-new branch resolves ok=False.
Round-3 review found the SDK WARN still exited 0 without any verified
alternative: android/local.properties was cited as a possible fallback
but never read (android/ is generated, nothing writes sdk.dir for a
fresh clone). Now the doctor actually reads it — a pinned sdk.dir
pointing at an existing SDK passes (un-escaping the properties format:
doubled backslashes, \: for the drive colon); a bare default-path
fallback with no env var and no pin is a FAIL, since Gradle would fail
with 'SDK location not found' anyway; an env var pointing at a missing
folder gets its own hint instead of the generic install text.

Also correct the Node-check comment: PowerShell's -and DOES
short-circuit, so the previous chained form was correct — the explicit
if is a clarity choice, not a fix (round-3 review caught my wrong
language claim).

Verified on this machine across the full matrix: env-sourced PASS,
default-path-no-pin FAIL (exit 1), pinned sdk.dir without env PASS
(real Gradle escape format), and env-pointing-at-nothing via the
branch-specific hint.
The check ran java -version and looked no further, so a JAVA_HOME
pointing at a JRE passed the doctor while Gradle fails on the missing
compiler (JRE installs ship bin\java.exe without bin\javac.exe).
Require bin\javac.exe next to it, with a hint that names the JRE-vs-JDK
distinction.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant