Skip to content

[eas-build] - lockfile preflight checks to eas build command#3434

Open
AbbanMustafa wants to merge 7 commits intomainfrom
eas-build-valid-lock
Open

[eas-build] - lockfile preflight checks to eas build command#3434
AbbanMustafa wants to merge 7 commits intomainfrom
eas-build-valid-lock

Conversation

@AbbanMustafa
Copy link
Contributor

@AbbanMustafa AbbanMustafa commented Feb 26, 2026

Why

Our new build error logging has highlighted that nearly ~3k builds fail every week on the install_dependencies phase. These are typically from out of sync lockfiles or peer dependency conflicts. These can be avoided by providing a set of preflight checks that ensure the dependency installation is valid before queueing up to build. Quicker feedback is a much better experience for the user, and helps us from running wasteful builds.

Screenshot 2026-03-02 at 3 31 17 PM Screenshot 2026-03-02 at 3 29 40 PM

How

  • Add lockfile preflight checks that run before uploading to the EAS builder, catching common install_dependencies failures instantly on the client
  • Define a module-level flag (lockfileChecked) so the validation only runs once, even when building for both iOS and Android in the same command. Same
    pattern as the existing sdkVersionChecked and metroConfigValidated flags.
  • Supports npm, yarn, pnpm, and bun (text lockfile); binary bun.lockb gracefully skips parse-dependent checks

The set of checks to be made:

  ┌─────┬──────────────────────────────┬──────────┬──────────────────────────────────────────────────────────────────────────────────┐
  │  #  │            Check             │ Severity │                                   Description                                    │
  ├─────┼──────────────────────────────┼──────────┼──────────────────────────────────────────────────────────────────────────────────┤
  │ 1   │ Lockfile existence           │ Error    │ No lockfile detected at all                                                      │
  ├─────┼──────────────────────────────┼──────────┼──────────────────────────────────────────────────────────────────────────────────┤
  │ 2   │ Lockfile missing for manager │ Error    │ e.g. npm detected but no package-lock.json (checks workspace root for monorepos) │
  ├─────┼──────────────────────────────┼──────────┼──────────────────────────────────────────────────────────────────────────────────┤
  │ 3   │ Lockfile ignored by VCS      │ Error    │ Lockfile exists but is gitignored/easignored — won't be uploaded                 │
  ├─────┼──────────────────────────────┼──────────┼──────────────────────────────────────────────────────────────────────────────────┤
  │ 4   │ Conflicting lockfiles        │ Error    │ Lockfiles from multiple managers (bun's two variants treated as same manager)    │
  ├─────┼──────────────────────────────┼──────────┼──────────────────────────────────────────────────────────────────────────────────┤
  │ 5   │ Lockfile out of sync         │ Error    │ Locked versions don't satisfy package.json specifiers                            │
  ├─────┼──────────────────────────────┼──────────┼──────────────────────────────────────────────────────────────────────────────────┤
  │ 6   │ Peer dependency conflicts    │ Error    │ Direct dependencies have unsatisfied peer requirements (skips optional peers)    │
  └─────┴──────────────────────────────┴──────────┴──────────────────────────────────────────────────────────────────────────────────┘

Test Plan

Example of how a build would fail before: https://expo.dev/accounts/mustafaexpo/projects/wander/builds/c596e1ac-f8ba-4af4-9840-fe1492837ef7

After:
Screenshot 2026-03-02 at 3 51 20 PM

Validated each scenario fails locally without queueing a build and with a helpful error log to provide the resolution step to the user.

eas build
✔ Incremented versionCode from 30 to 31.
Lockfile is out of sync with package.json:
  react: package.json requires 19.0.4, but lockfile has 19.0.0
Run "bun install" to update your lockfile, then commit the changes.
✔ Incremented versionCode from 34 to 35.
Conflicting lockfiles detected from multiple package managers: bun, npm.
Having lockfiles from multiple package managers can cause install failures on the EAS builder. Remove the lockfiles you do not need and commit the change.
✔ Incremented versionCode from 37 to 38.
No lockfile found in the project directory.
A lockfile is required to ensure deterministic dependency installation on the EAS builder.
Run your package manager's install command (e.g. "npm install") to generate one, then commit it to version control.
✔ Incremented versionCode from 42 to 43.
Peer dependency conflicts detected:
  react-dom@19.0.0 requires peer react@"^19.1.0", but react@19.0.0 is installed
Update the conflicting packages to compatible versions, then run "bun install" and commit the changes.

@codecov
Copy link

codecov bot commented Feb 26, 2026

Codecov Report

❌ Patch coverage is 84.03756% with 34 lines in your changes missing coverage. Please review.
✅ Project coverage is 52.98%. Comparing base (62ab329) to head (b862a05).
⚠️ Report is 3 commits behind head on main.

Files with missing lines Patch % Lines
packages/eas-cli/src/build/validateLockfile.ts 85.10% 31 Missing ⚠️
packages/eas-cli/src/build/runBuildAndSubmit.ts 40.00% 3 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3434      +/-   ##
==========================================
+ Coverage   52.78%   52.98%   +0.20%     
==========================================
  Files         809      810       +1     
  Lines       34048    34260     +212     
  Branches     7075     7139      +64     
==========================================
+ Hits        17969    18148     +179     
- Misses      15998    16031      +33     
  Partials       81       81              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions
Copy link

github-actions bot commented Mar 2, 2026

✅ Thank you for adding the changelog entry!

@AbbanMustafa AbbanMustafa marked this pull request as ready for review March 2, 2026 22:25
@github-actions
Copy link

github-actions bot commented Mar 2, 2026

Subscribed to pull request

File Patterns Mentions
**/* @douglowder
packages/eas-cli/src/build/** @sjchmiela

Generated by CodeMention

env,
});

if (!lockfileChecked) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@AbbanMustafa this is a great PR! I do think that we should provide a way for customers to opt out of this check, in case they have an unusual configuration that is really valid for them, but might not pass these checks. Maybe something like EAS_BUILD_SKIP_LOCKFILE_CHECK.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thank you! yes I agree an opt out would be nice


const LOCKFILE_BY_MANAGER: Record<string, LockfileInfo> = {
npm: { filename: NPM_LOCK_FILE, managerName: 'npm' },
yarn: { filename: YARN_LOCK_FILE, managerName: 'Yarn' },
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Curious as to why managerName is capitalized for yarn and bun....

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, in reading through this, it occurred to me that it might be good to package all this code for reuse, in case it's needed elsewhere. I also noticed that there are open source packages for this, e.g. https://github.com/snyk/nodejs-lockfile-parser

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.

2 participants