fix: stop showing update modal when required version isn't in store yet#39884
fix: stop showing update modal when required version isn't in store yet#39884gauthierpetetin merged 16 commits intomainfrom
Conversation
- Replace isUpdateAvailable with pendingExtensionVersion in AppStateController - Set pending version from runtime.onUpdateAvailable(details.version) in background - Clear pending version in onUpdate when update is applied - Update getShowUpdateModal: show only when pending > current and current < minimum - Add E2E test for 'pending not newer than current' and fix update-modal confirm wait - Update fixtures, types, and JSDoc Co-authored-by: Cursor <cursoragent@cursor.com>
|
CLA Signature Action: All authors have signed the CLA. You may need to manually re-run the blocking PR check if it doesn't pass in a few minutes. |
✨ Files requiring CODEOWNER review ✨🕵️ @MetaMask/extension-privacy-reviewers (1 files, +1 -1)
🧪 @MetaMask/qa (1 files, +1 -1)
|
Co-authored-by: Cursor <cursoragent@cursor.com>
Builds ready [a242d0d]
UI Startup Metrics (1370 ± 103 ms)
📊 Page Load Benchmark ResultsCurrent Commit: 📄 Localhost MetaMask Test DappSamples: 100 Summary
📈 Detailed Results
Bundle size diffs
|
pendingExtensionVersion was set to string '0.0.0' but maskObject() only accepts true, false, or sub-mask objects. That caused a throw when Sentry attached state to traces, preventing the trace from being sent and failing the Traces E2E tests. Use true so the value is included. Co-authored-by: Cursor <cursoragent@cursor.com>
Builds ready [377c3d0]
UI Startup Metrics (1461 ± 99 ms)
📊 Page Load Benchmark ResultsCurrent Commit: 📄 Localhost MetaMask Test DappSamples: 100 Summary
📈 Detailed Results
Bundle size diffs
|
Revert to delay(3000) + waitUntilXWindowHandles(1) to mitigate webdriver disconnect race when tab is closed and re-opened after confirming the update. Co-authored-by: Cursor <cursoragent@cursor.com>
Builds ready [044603b]
UI Startup Metrics (1405 ± 99 ms)
📊 Page Load Benchmark ResultsCurrent Commit: 📄 Localhost MetaMask Test DappSamples: 100 Summary
📈 Detailed Results
Bundle size diffs
|
State logs E2E expects the type map to match downloaded state; when no update is pending the value is null, so the reference type is set to "null" to match. Co-authored-by: Cursor <cursoragent@cursor.com>
Builds ready [f49316b]
UI Startup Metrics (1389 ± 109 ms)
📊 Page Load Benchmark ResultsCurrent Commit: 📄 Localhost MetaMask Test DappSamples: 100 Summary
📈 Detailed Results
Bundle size diffs
|
| /** | ||
| * Determines whether the update modal should be shown. | ||
| * | ||
| * Logic: |
There was a problem hiding this comment.
Nit: would be nice to append some unit tests to reflect the logic
There was a problem hiding this comment.
Yes, they're now added in this commit: 04fc190
Co-authored-by: Cursor <cursoragent@cursor.com>
…l-pending-version
Builds ready [a158b3f]
UI Startup Metrics (1405 ± 108 ms)
📊 Page Load Benchmark ResultsCurrent Commit: 📄 Localhost MetaMask Test DappSamples: 100 Summary
📈 Detailed Results
Bundle size diffs
|
hjetpoluru
left a comment
There was a problem hiding this comment.
QA related files are lgtm.
davidmurdoch
left a comment
There was a problem hiding this comment.
approved with one comment. if you do "fix" this issue now (which isn't really an issue!) ping me and I'll give a quick second approval.
ui/selectors/selectors.js
Outdated
| semver.coerce(remoteFeatureFlags.extensionUpdatePromptMinimumVersion), | ||
| ); | ||
| const isExtensionOutdated = | ||
|
|
There was a problem hiding this comment.
This might be an existing "issue", and maybe not even worth fixing.
I was wondering if we need to be concerned with "pre-release" versions?
For prereleases we technically support the ability to have public releases versions like:
10.2.3.111
10.2.3.112
10.2.3.113
yarn webpack --type beta --releaseVersion 2 would output something like 10.2.3.112 (beta has an id of 11, and when releaseVersion is 2 it will generate a 4th segment in the version number equal to 112)
Since semver.coerce lops off the last segment here (since it isn't valid semver) we wouldn't be able to show the update prompt when the installed version of 10.2.3.111 and the update version is 10.2.3.112, since semver.gt(pendingVersionValid, extensionCurrentVersion) will return false.
Again, not a serious concern, since we don't currently do this. Just thought I'd mention it here since I thought about it and you're in here editing this code already :-)
There was a problem hiding this comment.
Good idea, here's a commit to handle it: a4fbd64
- Add versionToComparable() and isExtensionVersionNewer() for 3- and 4-segment versions - Use new comparison in getShowUpdateModal so beta builds (e.g. 10.2.3.111 -> 10.2.3.112) show update prompt - Add unit tests for four-segment version comparison Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
28fe4a4
Builds ready [0bc37b2]
UI Startup Metrics (1560 ± 114 ms)
📊 Page Load Benchmark ResultsCurrent Commit: 📄 Localhost MetaMask Test DappSamples: 100 Summary
📈 Detailed Results
Bundle size diffs
|
Description
Replaces the update-modal’s
isUpdateAvailableboolean withpendingExtensionVersion(string | null). When the browser reports an available update viaruntime.onUpdateAvailable, we store the pending version and only show the force-upgrade modal when:This avoids prompting users when the store doesn’t yet offer a version that satisfies the minimum (e.g. Firefox publishing lag) and keeps a single source of truth (pending version implies “update available”).
Changelog
CHANGELOG entry: Adjusts update modal logic to use the pending extension version and only show when a newer version is available.
Related issues
Fixes: #39570
Manual testing steps
yarn start).controller.appStateController.setPendingExtensionVersion('99.0.0')and ensure remote feature flags setextensionUpdatePromptMinimumVersionabove current version; open the extension UI and confirm the update modal appears.setPendingExtensionVersion(version)(same as current version) and confirm the update modal does not appear.To set remote feature flags, you can add the following in .manifest-overrides.json
and the following line in .metamaskrc:
Screenshots/Recordings
N/A – No UI changes to the modal itself; behavior change is when it is shown/hidden.
Pre-merge author checklist
Pre-merge reviewer checklist
Note
Medium Risk
Changes the logic that determines when the forced update modal appears and introduces custom version parsing/comparison (including 4-segment versions), which could affect upgrade prompting behavior across browsers.
Overview
Updates the force-upgrade/update-modal flow to track a specific pending store version instead of a boolean flag.
runtime.onUpdateAvailablenow storesdetails.versioninAppStateController.pendingExtensionVersion, and this value is cleared on successful update install viaonUpdate.getShowUpdateModalis rewritten to only show when a newer pending version exists and the current version is below the remote minimum, with added comparison support for four-segment build versions (e.g.10.2.3.111). Types, Sentry masks/state snapshots, mocks, and E2E/unit tests are updated accordingly (including a new test ensuring the modal doesn’t show when the pending version isn’t newer than current).Written by Cursor Bugbot for commit 0bc37b2. This will update automatically on new commits. Configure here.