Compare commits

...
Author SHA1 Message Date
Keith KurakandClaude Opus 5.5 222744d084 Add changelog entry
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
2026-09-24 11:00:56 -04:00
Keith KurakandClaude Opus 5.5 23317618e9 [build-tools] Run expo doctor when expo is a devDependency
The RUN_EXPO_DOCTOR phase only checked `dependencies.expo`, so projects
that list `expo` under `devDependencies` (common in some monorepo and
template setups) silently skipped the step. Check both fields, matching
autolinking and the other expo lookups in build-tools.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
2026-09-24 11:00:37 -04:00
4 changed files with 44 additions and 1 deletions

No files matched your search

+1
View File
@@ -18,6 +18,7 @@ This is the log of notable changes to EAS CLI and related packages.
### 🐛 Bug fixes
- [build-tools] Run `expo doctor` during builds when `expo` is listed in `devDependencies`, not only `dependencies`. ([#4469](https://github.com/expo/eas-cli/pull/4469) by [@keith-kurak](https://github.com/keith-kurak))
- [eas-cli] Exclude time waiting for simulator concurrency from the session startup timeout and show queue progress. ([#4411](https://github.com/expo/eas-cli/pull/4411) by [@szdziedzic](https://github.com/szdziedzic))
- [eas-cli] List `eas simulator` only once in `eas --help`. The `sim` shorthand is now a hidden alias, so it still runs but no longer duplicates the entry. ([#4457](https://github.com/expo/eas-cli/pull/4457) by [@krystofwoldrich](https://github.com/krystofwoldrich))
- [eas-cli] Fix `eas account:view` printing `Role: undefined` for the new Release Manager role. ([#4300](https://github.com/expo/eas-cli/pull/4300) by [@byronkarlen](https://github.com/byronkarlen))
+5 -1
View File
@@ -26,6 +26,7 @@ import { setUpNpmrcAsync } from '../utils/npmrc';
import {
getPackageVersionFromPackageJson,
isAtLeastNpm7Async,
isPackageInPackageJson,
shouldUseFrozenLockfile,
} from '../utils/packageManager';
import { getParentAndDescendantProcessPidsAsync } from '../utils/processes';
@@ -176,7 +177,10 @@ export async function setupAsync<TJob extends BuildJob>(
// Read fresh: a before_install_node_modules hook may have added or removed
// the expo dependency.
const hasExpoPackage = !!readPackageJson(ctx.getReactNativeProjectDirectory()).dependencies?.expo;
const hasExpoPackage = isPackageInPackageJson({
packageJson: readPackageJson(ctx.getReactNativeProjectDirectory()),
packageName: 'expo',
});
if (!ctx.env.EAS_BUILD_DISABLE_EXPO_DOCTOR_STEP && hasExpoPackage) {
await ctx.runBuildPhase(BuildPhase.RUN_EXPO_DOCTOR, async () => {
try {
@@ -9,6 +9,7 @@ import {
PackageManager,
findPackagerRootDir,
getPackageVersionFromPackageJson,
isPackageInPackageJson,
resolveConfiguredPackageManager,
resolveFallbackPackageManager,
resolveOverridePackageManager,
@@ -480,3 +481,22 @@ describe(shouldUseFrozenLockfile, () => {
).toBe(false);
});
});
describe(isPackageInPackageJson, () => {
const CASES = [
[{ dependencies: { expo: '~54.0.0' } }, 'expo', true],
[{ devDependencies: { expo: '~54.0.0' } }, 'expo', true],
[{ dependencies: { expo: 'catalog:' } }, 'expo', true],
[{ devDependencies: { expo: 'workspace:*' } }, 'expo', true],
[{ dependencies: { 'react-native': '0.81.0' } }, 'expo', false],
[{}, 'expo', false],
[null, 'expo', false],
['not-a-package-json', 'expo', false],
] as const;
for (const [packageJson, packageName, expected] of CASES) {
it(`returns ${expected} for ${JSON.stringify(packageJson)}`, () => {
expect(isPackageInPackageJson({ packageJson, packageName })).toBe(expected);
});
}
});
@@ -197,6 +197,24 @@ const PackageJsonZ = z.object({
devDependencies: z.record(z.string(), z.string()).optional(),
});
export function isPackageInPackageJson({
packageJson,
packageName,
}: {
packageJson: unknown;
packageName: string;
}): boolean {
const parsedPackageJson = PackageJsonZ.safeParse(packageJson);
if (!parsedPackageJson.success) {
return false;
}
return !!(
parsedPackageJson.data.dependencies?.[packageName] ??
parsedPackageJson.data.devDependencies?.[packageName]
);
}
export function getPackageVersionFromPackageJson({
packageJson,
packageName,