Skip to content

Commit 0193bbd

Browse files
authored
release: 7.77.0 (#29883)
# 🚀 v7.77.0 Testing & Release Quality Process Hi Team, As part of our new **MetaMask Release Quality Process**, here’s a quick overview of the key processes, testing strategies, and milestones to ensure a smooth and high-quality deployment. --- ## 📋 Key Processes ### Testing Strategy - **Developer Teams:** Conduct regression and exploratory testing for your functional areas, including automated and manual tests for critical workflows. - **QA Team:** Focus on exploratory testing across the wallet, prioritize high-impact areas, and triage any Sentry errors found during testing. - **Customer Success Team:** Validate new functionalities and provide feedback to support release monitoring. ### GitHub Signoff - Each team must **sign off on the Release Candidate (RC)** via GitHub by the end of the validation timeline (**Tuesday EOD PT**). - Ensure all tests outlined in the Testing Plan are executed, and any identified issues are addressed. ### Issue Resolution - **Resolve all Release Blockers** (Sev0 and Sev1) by **Tuesday EOD PT**. - For unresolved blockers, PRs may be reverted, or feature flags disabled to maintain release quality and timelines. ### Cherry-Picking Criteria - Only **critical fixes** meeting outlined criteria will be cherry-picked. - Developers must ensure these fixes are thoroughly reviewed, tested, and merged by **Tuesday EOD PT**. --- ## 🗓️ Timeline and Milestones 1. **Today (Friday):** Begin Release Candidate validation. 2. **Tuesday EOD PT:** Finalize RC with all fixes and cherry-picks. 3. **Wednesday:** Buffer day for final checks. 4. **Thursday:** Submit release to app stores and begin rollout to 1% of users. 5. **Monday:** Scale deployment to 10%. 6. **Tuesday:** Full rollout to 100%. --- ## ✅ Signoff Checklist Each team is responsible for signing off via GitHub. Use the checkbox below to track signoff completion: # Team sign-off checklist - [x] Accounts - [x] Assets - [x] BE Trade - [x] Bots Team - [x] Card - [x] Confirmations - [x] Core Extension UX - [x] Delegation - [x] Design System - [x] Earn - [x] Mobile Platform - [x] Mobile UX - [x] Money Movement - [x] Networks - [x] Onboarding - [x] Perps - [x] Predict - [x] Rewards - [x] Social & AI - [x] Swaps and Bridge - [x] Transactions - [x] Wallet Integrations This process is a major step forward in ensuring release stability and quality. Let’s stay aligned and make this release a success! 🚀 Feel free to reach out if you have questions or need clarification. Many thanks in advance # Reference - Testing plan sheet - https://docs.google.com/spreadsheets/d/1tsoodlAlyvEUpkkcNcbZ4PM9HuC9cEM80RZeoVv5OCQ/edit?gid=404070372#gid=404070372
2 parents 9ac14e3 + 3930a44 commit 0193bbd

1,453 files changed

Lines changed: 81227 additions & 35289 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.eslintrc.js

Lines changed: 234 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,136 @@
11
/* eslint-disable import-x/no-commonjs */
2+
3+
/**
4+
* Files still allowed to import deprecated `app/util/number/index.js` during
5+
* the BN.js → BigInt migration. Kept in one array so the default import-fence
6+
* override can exclude them while the follow-up override below re-applies only
7+
* the expo-haptics / perps restrictions (see comments on those overrides).
8+
*/
9+
const utilNumberImportBurndownFiles = [
10+
'app/component-library/components-temp/CustomSpendCap/CustomInput/CustomInput.tsx',
11+
'app/component-library/components-temp/CustomSpendCap/CustomSpendCap.tsx',
12+
'app/component-library/components-temp/Price/AggregatedPercentage/AggregatedPercentage.tsx',
13+
'app/component-library/components-temp/Price/AggregatedPercentage/utils.ts',
14+
'app/components/UI/AccountInfoCard/index.js',
15+
'app/components/UI/AssetOverview/Price/Price.advanced.tsx',
16+
'app/components/UI/AssetOverview/Price/Price.legacy.tsx',
17+
'app/components/UI/AssetOverview/utils/marketDetails.ts',
18+
'app/components/UI/Bridge/components/QuoteSelectorView/QuoteRow.tsx',
19+
'app/components/UI/Bridge/components/QuoteSelectorView/index.tsx',
20+
'app/components/UI/Bridge/hooks/useBridgeQuoteData/index.ts',
21+
'app/components/UI/Bridge/hooks/useFormattedBalanceWithThreshold/index.ts',
22+
'app/components/UI/Bridge/hooks/useHasSufficientGas/index.ts',
23+
'app/components/UI/Bridge/hooks/useInsufficientBalance/index.ts',
24+
'app/components/UI/Bridge/hooks/useTokenBalanceInUsd/index.ts',
25+
'app/components/UI/Bridge/hooks/useTokensWithBalance/index.ts',
26+
'app/components/UI/Bridge/utils/exchange-rates.ts',
27+
'app/components/UI/Bridge/utils/formatNetworkFee.test.ts',
28+
'app/components/UI/Bridge/utils/formatNetworkFee.ts',
29+
'app/components/UI/Bridge/utils/transaction-history.ts',
30+
'app/components/UI/Card/hooks/useAssetBalances.tsx',
31+
'app/components/UI/Card/hooks/useCardDelegation.test.ts',
32+
'app/components/UI/Card/hooks/useCardDelegation.ts',
33+
'app/components/UI/Card/hooks/useNeedsGasFaucet.ts',
34+
'app/components/UI/Card/sdk/CardSDK.ts',
35+
'app/components/UI/CollectibleOverview/index.js',
36+
'app/components/UI/Earn/Views/EarnInputView/EarnInputView.test.tsx',
37+
'app/components/UI/Earn/Views/EarnLendingDepositConfirmationView/components/Erc20TokenHero/index.tsx',
38+
'app/components/UI/Earn/Views/EarnLendingDepositConfirmationView/index.tsx',
39+
'app/components/UI/Earn/Views/EarnLendingWithdrawalConfirmationView/index.tsx',
40+
'app/components/UI/Earn/Views/EarnWithdrawInputView/EarnWithdrawInputView.tsx',
41+
'app/components/UI/Earn/components/EarnLendingBalance/index.tsx',
42+
'app/components/UI/Earn/components/Earnings/EarningsHistory/EarningsHistory.utils.ts',
43+
'app/components/UI/Earn/components/InputDisplay/InputDisplay.test.tsx',
44+
'app/components/UI/Earn/hooks/useEarnGasFee.ts',
45+
'app/components/UI/Earn/hooks/useEarnInput.ts',
46+
'app/components/UI/Earn/hooks/useEarnings.ts',
47+
'app/components/UI/Earn/hooks/useInput.ts',
48+
'app/components/UI/Earn/hooks/useMultichainInputHandlers.ts',
49+
'app/components/UI/Earn/hooks/useMusdBalance.ts',
50+
'app/components/UI/Earn/hooks/useMusdCtaVisibility.ts',
51+
'app/components/UI/Earn/utils/number.ts',
52+
'app/components/UI/Earn/utils/token/index.ts',
53+
'app/components/UI/Earn/utils/tron.ts',
54+
'app/components/UI/HardwareWallet/AccountDetails/index.tsx',
55+
'app/components/UI/Money/constants/activityStyles.ts',
56+
'app/components/UI/Money/hooks/useMoneyAccountBalance.ts',
57+
'app/components/UI/Money/utils/moneyActivityFiat.ts',
58+
'app/components/UI/MultichainBridgeTransactionListItem/MultichainBridgeTransactionListItem.tsx',
59+
'app/components/UI/Notification/TransactionNotification/index.js',
60+
'app/components/UI/Ramp/Aggregator/Views/BuildQuote/BuildQuote.test.tsx',
61+
'app/components/UI/Ramp/Aggregator/Views/BuildQuote/BuildQuote.tsx',
62+
'app/components/UI/Ramp/Aggregator/Views/OrdersList/OrdersList.tsx',
63+
'app/components/UI/Ramp/Aggregator/Views/SendTransaction/SendTransaction.tsx',
64+
'app/components/UI/Ramp/Aggregator/components/OrderDetails.tsx',
65+
'app/components/UI/Ramp/Aggregator/components/OrderListItem/OrderListItem.tsx',
66+
'app/components/UI/Ramp/Aggregator/components/Quote/Quote.tsx',
67+
'app/components/UI/Ramp/Aggregator/hooks/useBalance.test.ts',
68+
'app/components/UI/Ramp/Aggregator/hooks/useBalance.ts',
69+
'app/components/UI/Ramp/Aggregator/hooks/useERC20GasLimitEstimation.ts',
70+
'app/components/UI/Ramp/Aggregator/hooks/useHandleSuccessfulOrder.ts',
71+
'app/components/UI/Ramp/Aggregator/hooks/useIntentAmount.ts',
72+
'app/components/UI/Ramp/Aggregator/utils/index.ts',
73+
'app/components/UI/Ramp/Deposit/utils/index.ts',
74+
'app/components/UI/Ramp/utils/getOrderAmount.ts',
75+
'app/components/UI/Ramp/utils/v2OrderToast.ts',
76+
'app/components/UI/Stake/components/StakingBalance/StakingBanners/ClaimBanner/ClaimBanner.tsx',
77+
'app/components/UI/Stake/components/StakingConfirmation/TokenValueStack/TokenValueStack.test.tsx',
78+
'app/components/UI/Stake/components/StakingConfirmation/TokenValueStack/TokenValueStack.tsx',
79+
'app/components/UI/Stake/components/StakingConfirmation/YouReceiveCard/YouReceiveCard.test.tsx',
80+
'app/components/UI/Stake/components/StakingConfirmation/YouReceiveCard/YouReceiveCard.tsx',
81+
'app/components/UI/Stake/hooks/useBalance.ts',
82+
'app/components/UI/Tokens/util/deriveBalanceFromAssetMarketDetails.test.ts',
83+
'app/components/UI/Tokens/util/deriveBalanceFromAssetMarketDetails.ts',
84+
'app/components/UI/TransactionElement/utils-gas.js',
85+
'app/components/UI/TransactionElement/utils.js',
86+
'app/components/UI/UrlAutocomplete/Result.tsx',
87+
'app/components/Views/AssetDetails/index.tsx',
88+
'app/components/Views/DetectedTokens/components/Token.tsx',
89+
'app/components/Views/GasEducationCarousel/index.js',
90+
'app/components/Views/NetworksManagement/NetworkDetailsView/hooks/useNetworkValidation.ts',
91+
'app/components/Views/SocialLeaderboard/TraderPositionView/components/QuickBuyBottomSheet/useQuickBuyBottomSheet.ts',
92+
'app/components/Views/SocialLeaderboard/TraderPositionView/components/QuickBuyBottomSheet/useQuickBuyQuotes.ts',
93+
'app/components/Views/SocialLeaderboard/utils/formatters.ts',
94+
'app/components/Views/UnifiedTransactionsView/useUnifiedTxActions.test.ts',
95+
'app/components/Views/confirmations/components/gas/max-base-fee-input/max-base-fee-input.tsx',
96+
'app/components/Views/confirmations/components/gas/priority-fee-input/priority-fee-input.tsx',
97+
'app/components/Views/confirmations/components/info/typed-sign-v3v4/simulation/components/native-value-display/native-value-display.tsx',
98+
'app/components/Views/confirmations/components/info/typed-sign-v3v4/simulation/components/value-display/value-display.tsx',
99+
'app/components/Views/confirmations/components/transactions/custom-amount/custom-amount.tsx',
100+
'app/components/Views/confirmations/context/send-context/utils.ts',
101+
'app/components/Views/confirmations/external/staking/hooks/useStakingDetails.ts',
102+
'app/components/Views/confirmations/hooks/earn/useCustomAmount.tsx',
103+
'app/components/Views/confirmations/hooks/gas/useCancelSpeedupGas/useCancelSpeedupGas.ts',
104+
'app/components/Views/confirmations/hooks/send/useBalance.ts',
105+
'app/components/Views/confirmations/hooks/send/useCurrencyConversions.ts',
106+
'app/components/Views/confirmations/hooks/send/usePercentageAmount.ts',
107+
'app/components/Views/confirmations/hooks/useTokenAmount.ts',
108+
'app/components/Views/confirmations/legacy/components/CustomNonceModal/index.js',
109+
'app/components/Views/confirmations/legacy/components/WatchAssetRequest/index.js',
110+
'app/components/Views/confirmations/utils/send.ts',
111+
'app/components/hooks/useAddressBalance/useAddressBalance.ts',
112+
'app/components/hooks/useGetFormattedTokensPerChain.tsx',
113+
'app/components/hooks/useGetTotalFiatBalanceCrossChains.tsx',
114+
'app/core/Engine/Engine.ts',
115+
'app/core/Engine/controllers/gas-fee-controller/gas-fee-controller-init.test.ts',
116+
'app/core/GasPolling/GasPolling.ts',
117+
'app/core/NotificationManager.js',
118+
'app/selectors/assets/assets-list.ts',
119+
'app/selectors/earnController/earn/index.ts',
120+
'app/selectors/multichain/evm.ts',
121+
// `app/util/**` importers of `./number` or `../number` (resolves to `index.js`);
122+
// same burndown contract as feature files — remove when migrated to
123+
// `../number/bigint` (or `./number/bigint` from `app/util/`).
124+
'app/util/confirm-tx.js',
125+
'app/util/conversions.js',
126+
'app/util/confirmation/gas.ts',
127+
'app/util/confirmation/transactions.ts',
128+
'app/util/custom-gas/index.js',
129+
'app/util/networks/index.js',
130+
'app/util/transactions/index.js',
131+
'app/util/transactions/index.test.ts',
132+
];
133+
2134
module.exports = {
3135
root: true,
4136
parser: '@typescript-eslint/parser',
@@ -42,6 +174,11 @@ module.exports = {
42174
'interface',
43175
],
44176
'@typescript-eslint/no-explicit-any': 'error',
177+
// Surface JSDoc @deprecated annotations at every use-site (warn for now;
178+
// ratchet to 'error' once the BN.js → BigInt migration is complete).
179+
// Pairs with the `import-x/no-restricted-paths` fence on
180+
// `app/util/number/index.js` in the app import-fence override below.
181+
'@typescript-eslint/no-deprecated': 'warn',
45182
// Under discussion
46183
'@typescript-eslint/no-duplicate-enum-values': 'off',
47184
'@typescript-eslint/no-shadow': [
@@ -248,6 +385,33 @@ module.exports = {
248385
],
249386
},
250387
},
388+
{
389+
files: ['**/*.test.{js,ts,tsx,jsx}', '**/*.spec.{js,ts,tsx,jsx}'],
390+
plugins: ['jest'],
391+
rules: {
392+
// Prevent new file-based snapshots. Inline snapshots (toMatchInlineSnapshot)
393+
// are still allowed as they keep assertions co-located with the test.
394+
'jest/no-restricted-matchers': [
395+
'error',
396+
{
397+
toMatchSnapshot:
398+
'Use toMatchInlineSnapshot() or an explicit assertion instead. File-based snapshots are being phased out.',
399+
},
400+
],
401+
},
402+
},
403+
{
404+
// Matches CODEOWNERS `**/snaps/**` and `**/Snaps/**` (@MetaMask/core-platform).
405+
// ESLint cannot read CODEOWNERS.
406+
files: [
407+
'**/snaps/**/*.{test,spec}.{js,ts,tsx,jsx}',
408+
'**/Snaps/**/*.{test,spec}.{js,ts,tsx,jsx}',
409+
],
410+
plugins: ['jest'],
411+
rules: {
412+
'jest/no-restricted-matchers': 'off',
413+
},
414+
},
251415
// ── Perps controller Core-alignment override ──
252416
// Enforces the same ESLint rules that Core's @metamask/eslint-config
253417
// applies to packages/perps-controller so that code written in mobile
@@ -466,11 +630,78 @@ module.exports = {
466630
},
467631
},
468632
{
469-
files: ['app/**/*.{ts,tsx}'],
633+
// Default app import fences (expo-haptics, perps, deprecated util/number/index.js).
634+
// `excludedFiles` applies to the whole override — listing burn-down paths
635+
// here would incorrectly skip expo/perps for those files, so burn-down is
636+
// excluded from *this* block only and picked up by the next override.
637+
files: ['app/**/*.{ts,tsx,js,jsx}'],
470638
excludedFiles: [
471-
'app/controllers/perps/**/*.{ts,tsx}',
472-
'app/util/haptics/**/*.{ts,tsx}',
639+
// Perps controller is exempt from importing itself.
640+
'app/controllers/perps/**/*.{ts,tsx,js,jsx}',
641+
// Designated expo-haptics wrapper — only this tree may import expo-haptics.
642+
'app/util/haptics/**/*.{ts,tsx,js,jsx}',
643+
// Legacy number utils + parity tests.
644+
'app/util/number/**',
645+
// BN.js → BigInt burn-down: still allowed util/number imports; see next override.
646+
...utilNumberImportBurndownFiles,
473647
],
648+
rules: {
649+
'no-restricted-imports': [
650+
'error',
651+
{
652+
paths: [
653+
{
654+
name: 'expo-haptics',
655+
message:
656+
'Import from app/util/haptics instead of expo-haptics directly.',
657+
},
658+
],
659+
patterns: [
660+
{
661+
group: ['**/controllers/perps', '**/controllers/perps/**'],
662+
message:
663+
'Use @metamask/perps-controller instead of relative imports into app/controllers/perps/.',
664+
},
665+
{
666+
group: ['expo-haptics/*'],
667+
message:
668+
'Import from app/util/haptics instead of expo-haptics directly.',
669+
},
670+
],
671+
},
672+
],
673+
// Fences the deprecated `app/util/number/index.js` module. We use
674+
// `import-x/no-restricted-paths` (not `no-restricted-imports`) because
675+
// it resolves each import to its absolute file, which means a single
676+
// entry catches every spelling that lands on `index.js` — bare
677+
// (`from '../util/number'`), explicit (`'../util/number/index'`),
678+
// and explicit-with-extension. Sibling modules like `bigint`,
679+
// `bignumber`, and `subscriptNotation` resolve to different files
680+
// and are unaffected, so no negation list is needed. Inherits the
681+
// burn-down allowlist from this override's `excludedFiles`; the
682+
// burn-down override below intentionally does not re-declare this
683+
// rule, so allow-listed files remain exempt.
684+
'import-x/no-restricted-paths': [
685+
'error',
686+
{
687+
zones: [
688+
{
689+
target: 'app',
690+
from: 'app/util/number/index.js',
691+
message:
692+
'app/util/number/index.js is deprecated. Import the BigInt-based replacement from app/util/number/bigint instead. See app/util/number/bigint-migration-reference.test.ts for migration patterns.',
693+
},
694+
],
695+
},
696+
],
697+
},
698+
},
699+
{
700+
// Re-apply expo-haptics + perps only for burn-down files. A second
701+
// override is required because ESLint replaces `no-restricted-imports`
702+
// when the same rule is set again — we cannot use one override with only
703+
// `excludedFiles` for util/number without silently dropping other fences.
704+
files: utilNumberImportBurndownFiles,
474705
rules: {
475706
'no-restricted-imports': [
476707
'error',

.github/CODEOWNERS

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ app/core/Engine/README.md @MetaMask/mobile-pla
4343
app/core/Engine/types.ts @MetaMask/mobile-platform
4444
app/core/Engine/controllers/remote-feature-flag-controller/ @MetaMask/mobile-platform
4545
app/core/DeeplinkManager @MetaMask/mobile-platform
46+
# Deprecated BN.js helpers. Gated to discourage adding new exports; consumers
47+
# should migrate to app/util/number/bigint. See .eslintrc.js for the import
48+
# fence and bigint-migration-reference.test.ts for migration patterns.
49+
app/util/number/index.js @MetaMask/mobile-platform
4650
scripts/build.sh @MetaMask/mobile-platform
4751
fingerprint.config.js @MetaMask/mobile-platform
4852
builds.yml @MetaMask/mobile-platform
@@ -154,7 +158,12 @@ app/components/UI/TemplateRenderer @MetaMask/confirmations @MetaMask/core-plat
154158
app/components/UI/Stake @MetaMask/earn
155159
app/core/Engine/controllers/earn-controller @MetaMask/earn
156160
app/core/Engine/messengers/earn-controller-messenger @MetaMask/earn
161+
app/core/Engine/controllers/chomp-api-service-init* @MetaMask/earn
162+
app/core/Engine/controllers/money-account-upgrade-controller-init* @MetaMask/earn
163+
app/core/Engine/messengers/chomp-api-service-messenger* @MetaMask/earn
164+
app/core/Engine/messengers/money-account-upgrade-controller-messenger* @MetaMask/earn
157165
app/selectors/earnController @MetaMask/earn
166+
app/selectors/featureFlagController/chompApi/ @MetaMask/earn
158167
**/Earn/** @MetaMask/earn
159168
**/earn/** @MetaMask/earn
160169
**/Money/** @MetaMask/earn
@@ -334,6 +343,7 @@ tests/tools/ @MetaMask/qa
334343
tests/websocket/ @MetaMask/qa
335344

336345
# QA Team - CI
346+
.github/guidelines/E2E_DECISION_TREE.md @MetaMask/qa
337347
.github/actions/smart-e2e-selection/ @MetaMask/qa
338348
.github/workflows/ai-pr-risk-analysis.yml @MetaMask/qa
339349
.github/workflows/auto-label-not-ready-for-e2e.yml @MetaMask/qa
@@ -353,6 +363,7 @@ tests/websocket/ @MetaMask/qa
353363
.github/workflows/run-performance-e2e.yml @MetaMask/qa
354364
.github/workflows/run-performance-e2e-experimental.yml @MetaMask/qa
355365
.github/workflows/run-performance-e2e-release.yml @MetaMask/qa
366+
.github/workflows/run-system-tests.yml @MetaMask/qa
356367
.github/scripts/e2e-*.mjs @MetaMask/qa
357368
.github/scripts/collect-qa-stats.mjs @MetaMask/qa
358369
.github/scripts/generate-regression-slack-summary.mjs @MetaMask/qa

.github/actionlint.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@ self-hosted-runner:
1515
- "ghcr.io/cirruslabs/ubuntu-runner-amd64:24.04-lg"
1616
- "ghcr.io/cirruslabs/ubuntu-runner-amd64:24.04-xl"
1717
- "low-priority"
18+
# Namespace runner profile labels (INFRA-3592). Format: namespace-profile-<profile-name>.
19+
- "namespace-profile-metamask-ci-linux"
20+
- "namespace-profile-metamask-android-build"
21+
- "namespace-profile-metamask-ios-build"
22+
- "namespace-profile-metamask-ios-e2e"
1823

1924
# Configuration variables in array of strings defined in your repository or
2025
# organization. `null` means disabling configuration variables check.

0 commit comments

Comments
 (0)