Skip to content

[eas-build-job][build-tools] Replace eas-cli npm dist-tags with cli-versions.json - #4147

Open
douglowder wants to merge 2 commits into
mainfrom
doug/eng-25633-create-a-non-npm-source-for-latest-eas-build-and-related-cli
Open

[eas-build-job][build-tools] Replace eas-cli npm dist-tags with cli-versions.json#4147
douglowder wants to merge 2 commits into
mainfrom
doug/eng-25633-create-a-non-npm-source-for-latest-eas-build-and-related-cli

Conversation

@douglowder

Copy link
Copy Markdown
Contributor

Why

Add cli-versions.json as the source of truth for the staging/production eas-cli versions, to remove the dependency on NPM tags to determine the correct version used in workflow jobs.

How

Adding new function fetchEasCliVersionsAsync in the eas-build-job package. This reads the file from main on GitHub; build-tools uses it to build the eas-cli@ npx argument and falls back to the latest-eas-build* dist-tags on any failure. The release workflow now bumps cli-versions.json in the release commit and no longer posts the manual npm dist-tag reminder.

Test Plan

New unit tests added.

@linear-code

linear-code Bot commented Aug 4, 2026

Copy link
Copy Markdown

ENG-25633

Copy link
Copy Markdown
Contributor Author

This stack of pull requests is managed by Graphite. Learn more about stacking.

@douglowder douglowder added the no changelog PR that doesn't require a changelog entry label Aug 4, 2026
@codecov

codecov Bot commented Aug 4, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 62.46%. Comparing base (a3a1d84) to head (e917d8b).

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4147      +/-   ##
==========================================
+ Coverage   62.43%   62.46%   +0.03%     
==========================================
  Files        1009     1009              
  Lines       45737    45771      +34     
  Branches     9622     9627       +5     
==========================================
+ Hits        28550    28584      +34     
  Misses      15726    15726              
  Partials     1461     1461              

☔ View full report in Codecov by Harness.
📢 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.

@douglowder

Copy link
Copy Markdown
Contributor Author

@claude review once

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Code review skipped — your organization's overage spend limit has been reached.

Code review is billed via overage credits. To resume reviews, an organization admin can raise the monthly limit at claude.ai/admin-settings/claude-code.

Once credits are available, comment @claude review on this pull request to trigger a review.

Comment thread packages/build-tools/src/utils/easCli.ts Outdated
Comment thread packages/eas-build-job/src/common.ts
Comment thread cli-versions.json
Comment thread .github/workflows/release.yml Outdated
Comment thread packages/eas-build-job/src/common.ts Outdated
Comment thread packages/build-tools/src/utils/easCli.ts
@douglowder
douglowder requested a review from szdziedzic August 4, 2026 19:08
douglowder and others added 2 commits August 4, 2026 16:10
…ersions.json

Add cli-versions.json as the source of truth for the staging/production
eas-cli versions. eas-build-job gains fetchEasCliVersionsAsync, which reads
the file from main on GitHub; build-tools uses it to build the eas-cli@<version>
npx argument and falls back to the latest-eas-build* dist-tags on any failure.
The release workflow now bumps cli-versions.json in the release commit and no
longer posts the manual npm dist-tag reminder.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Set the initial cli-versions.json values to 21.5.0, the current version
  published as latest on npm.
- Verify in the release workflow that eas-cli@latest on npm matches the version
  just published; fail the release if the publish did not take effect.
- Bump only STAGING from the release workflow. PRODUCTION is now bumped by a
  separate, manually-triggered "Promote eas-cli to production" workflow, which
  verifies the version exists on npm before updating cli-versions.json.
- Remove the obsolete move-eas-build-tag workflow (dist-tags are no longer the
  source of truth and it could not run from CI).
- Validate STAGING and PRODUCTION as semver in the cli-versions.json schema.
- Time out the cli-versions.json fetch after 10s via AbortController, surfaced
  as EasCliVersionsFetchTimeoutError.
- Report cli-versions.json fetch failures to Sentry before falling back to the
  npm dist-tags, with a distinct message for the timeout failure mode.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@brentvatne
brentvatne force-pushed the doug/eng-25633-create-a-non-npm-source-for-latest-eas-build-and-related-cli branch from 0697859 to e917d8b Compare August 4, 2026 23:11
@brentvatne brentvatne added the ai-review Commits pushed to PRs with this label be automatically reviewed. label Aug 4, 2026
@github-actions

github-actions Bot commented Aug 4, 2026

Copy link
Copy Markdown

⏩ The changelog entry check has been skipped since the "no changelog" label is present.

@github-actions

github-actions Bot commented Aug 4, 2026

Copy link
Copy Markdown

🤖 AI code review

Decision: Approve with comments

Overall PR risk: Medium. The change modifies an existing shared path: EAS Build now resolves the eas-cli version by fetching cli-versions.json from GitHub on every build, instead of reading npm dist-tags, and it keeps the dist-tags only as a fallback. The release and promotion CI workflows also change to write cli-versions.json instead of moving npm tags. Verified findings show plausible breakage: every build gains network latency on its hot path before falling back, the new promote workflow can let a non-semver value through and silently pin builds to a stale fallback version since the dist-tag updater was removed, Sentry alerting for this new recoverable failure uses an inconsistent severity level, and no CHANGELOG entry documents the behavior change. None of the findings are critical or security-exploitable; the code keeps a working fallback path, so rollback stays straightforward.

🟡 Warning (4)

  • Unconditional network fetch added to every build's hot pathpackages/build-tools/src/utils/easCli.ts:51 (correctness) · id:2c17a6843008
    Confidence: High — the code and call sites directly show this.
    Impact if shipped: Medium — every EAS Build job gains new network latency and an external dependency on a path that used to be instant.
    Suggested remediation: Only fetch versions when they will actually be used, e.g. move the fetch inside the staging/production branches and the development fallback branch, after the probeEasdAsync() check fails.

    Evidence and reasoning

    resolveEasCommandPrefixAndEnvAsync now calls resolveEasCliVersionsAsync() (a fetch to raw.githubusercontent.com with up to a 10-second timeout) before it checks process.env.ENVIRONMENT. This function runs on every real build, since runEasBuildInternalAsync and resolveEnvFromBuildProfileAsync in packages/build-tools/src/common/easBuildInternal.ts call it for each build job on EAS Build worker infrastructure.

    Before this change, resolving the command prefix was a pure, instant operation (reading a static enum). Now it always waits on an external HTTP call to GitHub, even in the development branch where, if probeEasdAsync() returns true, the fetched versions value is never used at all. In the worst case (GitHub raw content slow or unreachable), every single build is delayed by close to 10 seconds before falling back to the npm dist-tags, and the fallback path also fires a Sentry event on every affected build.

  • Promote workflow accepts npm ranges and dist-tags, but build-tools requires exact semver.github/workflows/promote-eas-cli-production.yml:35 (correctness) · id:78663391717d
    Confidence: High — the check and the consumer schema are both in this diff and disagree.
    Impact if shipped: Medium — one bad promote input makes every build worker fall back to the npm dist-tags, which this PR stops updating.
    Suggested remediation: Validate the resolved version as exact semver before you write it. For example, run npx semver "$PRODUCTION_VERSION" (or npm view "eas-cli@$PRODUCTION_VERSION" version and compare the output to the input) and fail the job when the value is a range or a dist-tag.

    Evidence and reasoning

    The only validation of the operator input is npm pack --dry-run "eas-cli@$PRODUCTION_VERSION". npm resolves ranges and dist-tags here, so values like 21.6 or latest-eas-build pass the check. The workflow then writes that value into cli-versions.json and pushes it to main.

    The consumer is strict. packages/eas-build-job/src/common.ts:415 requires semver.valid(value) !== null for both keys, and EasCliVersionsZ.parse fails the whole object. So an invalid PRODUCTION value also breaks STAGING resolution.

    After the parse fails, resolveEasCliVersionsAsync in packages/build-tools/src/utils/easCli.ts:19 reports to Sentry and returns EasCliNpmTags. This PR deletes move-eas-build-tag.yml and removes the dist-tag steps and the Slack reminder from release.yml. Nothing updates latest-eas-build or latest-eas-build-staging anymore. The fallback therefore pins builds to a stale eas-cli version, and the only signal is a Sentry error.

    The release path is safe because it uses the exact git tag version. Only the promote path accepts free-form input.

  • Sentry level 'error' breaks the 'warning' convention for recoverable fetch failurespackages/build-tools/src/utils/easCli.ts:28 (quality) · id:ac30fcaef5cd
    Confidence: High — many sibling call sites in this package use level: 'warning' for the same kind of recoverable, fallback-covered failure.
    Impact if shipped: Medium — this failure path can fire on ordinary network flakiness and will alert at error severity where the established pattern treats it as a warning.
    Suggested remediation: Use level: 'warning' for both branches, matching RuntimeSettings.loadAsync and other fallback-covered fetch failures in this package.

    Evidence and reasoning

    resolveEasCliVersionsAsync catches any fetch failure (including a 10s timeout) and falls back to the latest-eas-build* npm dist-tags, so the build still proceeds. This matches the shape of RuntimeSettings.loadAsync in packages/build-tools/src/runtimeSettings.ts, which fetches an external JSON config with a timeout and reports fetch failures with level: 'warning' because a safe fallback exists. The same pattern appears in remoteDeviceRunSession.ts (Sentry.capture('Could not fetch Cloudflare TURN ICE servers', error, { level: 'warning' })) and installDependencies.ts. The new code in easCli.ts instead reports both the generic fetch failure and the timeout-specific failure at level: 'error', even though both cases already recover automatically. This is inconsistent with how the rest of the package classifies recoverable, fallback-covered errors and can cause disproportionate Sentry noise for a self-healing condition (e.g. a transient GitHub raw-content outage).

  • No CHANGELOG.md entry for the new cli-versions.json resolution behaviorpackages/eas-build-job/src/common.ts:443 (quality) · id:be791c198332
    Confidence: Medium — the repo's established process is to add a ## main entry per user-facing PR, and none was added here.
    Impact if shipped: Medium — matches the house anchor for a missing or malformed CHANGELOG entry, which breaks release-note automation for this behavior change.
    Suggested remediation: Add a [build-tools][eas-build-job] entry under ### 🎉 New features or ### 🧹 Chores in the ## main section of CHANGELOG.md describing the switch from npm dist-tags to cli-versions.json.

    Evidence and reasoning

    CHANGELOG.md already has a pending ## main section with manually added entries for comparable build-tools behavior changes, e.g. [build-tools] Pin the default agent-device version for remote sessions instead of installing latest and [build-tools] Install ffmpeg when it is missing so Argent screen recording works. This PR changes how EAS Build resolves the eas-cli version for staging/production builds (new fetchEasCliVersionsAsync, cli-versions.json, dist-tag fallback), which is the same category of build-behavior change as those existing entries. No corresponding [build-tools] or [eas-build-job] entry was added to the ## main section for this change.


This review is advisory — it never blocks a merge and never auto-approves.

@szdziedzic szdziedzic left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM overall! Thanks for crafting this! 🙏

Should we also update RELEASING.md?

Do we want to automatically kick system tests off as a part of release workflow and make this promote-eas-cli-production.yml flow automatically start once they pass as a follow up?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ai-review Commits pushed to PRs with this label be automatically reviewed. no changelog PR that doesn't require a changelog entry

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants