Skip to content

Commit cb64ba0

Browse files
authored
Merge branch 'main' into chore/navigation-typing-phase-3-shells-wallet-settings
2 parents f9fa421 + 3552457 commit cb64ba0

192 files changed

Lines changed: 12953 additions & 5212 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: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -93,15 +93,12 @@ const utilNumberImportBurndownFiles = [
9393
'app/components/UI/Stake/hooks/useBalance.ts',
9494
'app/components/UI/Tokens/util/deriveBalanceFromAssetMarketDetails.test.ts',
9595
'app/components/UI/Tokens/util/deriveBalanceFromAssetMarketDetails.ts',
96-
'app/components/UI/TransactionElement/utils-gas.js',
97-
'app/components/UI/TransactionElement/utils.js',
9896
'app/components/UI/UrlAutocomplete/Result.tsx',
9997
'app/components/Views/GasEducationCarousel/index.js',
10098
'app/components/Views/NetworksManagement/NetworkDetailsView/hooks/useNetworkValidation.ts',
10199
'app/components/Views/SocialLeaderboard/TraderPositionView/components/QuickBuyBottomSheet/useQuickBuyBottomSheet.ts',
102100
'app/components/Views/SocialLeaderboard/TraderPositionView/components/QuickBuyBottomSheet/useQuickBuyQuotes.ts',
103101
'app/components/Views/SocialLeaderboard/utils/formatters.ts',
104-
'app/components/Views/UnifiedTransactionsView/useUnifiedTxActions.test.ts',
105102
'app/components/Views/confirmations/components/gas/max-base-fee-input/max-base-fee-input.tsx',
106103
'app/components/Views/confirmations/components/gas/priority-fee-input/priority-fee-input.tsx',
107104
'app/components/Views/confirmations/components/info/typed-sign-v3v4/simulation/components/native-value-display/native-value-display.tsx',
@@ -133,10 +130,9 @@ const utilNumberImportBurndownFiles = [
133130
// `../number/bigint` (or `./number/bigint` from `app/util/`).
134131
'app/util/confirm-tx.js',
135132
'app/util/conversions.js',
136-
'app/util/confirmation/gas.ts',
133+
137134
'app/util/confirmation/transactions.ts',
138135
'app/util/custom-gas/index.js',
139-
'app/util/networks/index.js',
140136
'app/util/transactions/index.js',
141137
'app/util/transactions/index.test.ts',
142138
];

.github/guidelines/E2E_DECISION_TREE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ When a PR only changes E2E/performance test files (and other ignorable files), C
3232

3333
The native build fingerprint for test-only PRs is computed from **`main` HEAD** (not the PR merge tree) so the lookup key matches completed `ci.yml` runs on `main`. Reuse tries GitHub Actions artifacts first, then the Cirrus `main` APK cache on Android.
3434

35-
If `main` has new native-changing commits but its CI build has not finished yet, reuse lookup may miss — CI logs a warning and **falls back to a fresh native build** instead of failing the workflow. Performance E2E on test-only PRs resolves BrowserStack apps by `custom_id` prefix `MetaMask-Android-*-main-*` so only uploads from `main` are reused (not other branches or PRs).
35+
If `main` has new native-changing commits but its CI build has not finished yet, reuse lookup may miss — CI logs a warning and **falls back to a fresh native build** instead of failing the workflow. Performance E2E on test-only PRs resolves BrowserStack apps via stable main `custom_id`s (`MetaMask-Android-*-main`) first, then legacy `…-main-<run_id>` IDs; if none are found it **falls back to a fresh dual Android upload** instead of failing.
3636

3737
This applies when all changed files match `e2e_test_files` or `e2e_ignorable` filters in `.github/rules/filter-rules.yml`, with at least one E2E test file changed, and no E2E-relevant workflow files were modified.
3838

.github/scripts/browserstack-app-validation.cjs

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,24 @@
66
/** BrowserStack app URLs use the bs:// scheme with an opaque app hash. */
77
const BROWSERSTACK_APP_URL_PATTERN = /^bs:\/\/[A-Za-z0-9]+$/;
88

9+
/**
10+
* custom_id format after MMQA-1667:
11+
* - Stable per branch: MetaMask-Android-With-SRP-<branchSlug>
12+
* - Legacy with run id: MetaMask-Android-With-SRP-<branchSlug>-<runId>
13+
* Slug must include at least one letter so pure-numeric pre-MMQA IDs are rejected.
14+
*/
915
const WITH_SRP_CUSTOM_ID_PATTERN =
10-
/^MetaMask-Android-With-SRP-[A-Za-z0-9._-]+-\d+$/;
16+
/^MetaMask-Android-With-SRP-(?=.*[A-Za-z])[A-Za-z0-9._-]+$/;
1117
const WITHOUT_SRP_CUSTOM_ID_PATTERN =
12-
/^MetaMask-Android-Without-SRP-[A-Za-z0-9._-]+-\d+$/;
18+
/^MetaMask-Android-Without-SRP-(?=.*[A-Za-z])[A-Za-z0-9._-]+$/;
1319

1420
const MAIN_BRANCH_BROWSERSTACK_SLUG = 'main';
15-
const MAIN_WITH_SRP_CUSTOM_ID_PREFIX = `MetaMask-Android-With-SRP-${MAIN_BRANCH_BROWSERSTACK_SLUG}-`;
16-
const MAIN_WITHOUT_SRP_CUSTOM_ID_PREFIX = `MetaMask-Android-Without-SRP-${MAIN_BRANCH_BROWSERSTACK_SLUG}-`;
21+
/** Stable custom_id used for main uploads (overwritten on each main upload). */
22+
const MAIN_WITH_SRP_CUSTOM_ID = `MetaMask-Android-With-SRP-${MAIN_BRANCH_BROWSERSTACK_SLUG}`;
23+
const MAIN_WITHOUT_SRP_CUSTOM_ID = `MetaMask-Android-Without-SRP-${MAIN_BRANCH_BROWSERSTACK_SLUG}`;
24+
/** Prefix for older main uploads that still embed github.run_id. */
25+
const MAIN_WITH_SRP_CUSTOM_ID_PREFIX = `${MAIN_WITH_SRP_CUSTOM_ID}-`;
26+
const MAIN_WITHOUT_SRP_CUSTOM_ID_PREFIX = `${MAIN_WITHOUT_SRP_CUSTOM_ID}-`;
1727

1828
/**
1929
* @param {unknown} value
@@ -50,6 +60,30 @@ function assertBrowserStackCustomId(value, kind) {
5060
return assertMatchesPattern(value, pattern, `${kind} custom_id`);
5161
}
5262

63+
/**
64+
* @param {unknown} customId
65+
* @param {'with-srp' | 'without-srp'} kind
66+
* @returns {boolean}
67+
*/
68+
function isMainBranchBrowserStackCustomId(customId, kind) {
69+
if (typeof customId !== 'string') {
70+
return false;
71+
}
72+
const stable =
73+
kind === 'with-srp' ? MAIN_WITH_SRP_CUSTOM_ID : MAIN_WITHOUT_SRP_CUSTOM_ID;
74+
const legacyPrefix =
75+
kind === 'with-srp'
76+
? MAIN_WITH_SRP_CUSTOM_ID_PREFIX
77+
: MAIN_WITHOUT_SRP_CUSTOM_ID_PREFIX;
78+
if (customId === stable) {
79+
return true;
80+
}
81+
return (
82+
customId.startsWith(legacyPrefix) &&
83+
/^\d+$/.test(customId.slice(legacyPrefix.length))
84+
);
85+
}
86+
5387
/**
5488
* @param {string} path
5589
* @param {Record<string, string>} outputs
@@ -70,9 +104,12 @@ module.exports = {
70104
WITH_SRP_CUSTOM_ID_PATTERN,
71105
WITHOUT_SRP_CUSTOM_ID_PATTERN,
72106
MAIN_BRANCH_BROWSERSTACK_SLUG,
107+
MAIN_WITH_SRP_CUSTOM_ID,
108+
MAIN_WITHOUT_SRP_CUSTOM_ID,
73109
MAIN_WITH_SRP_CUSTOM_ID_PREFIX,
74110
MAIN_WITHOUT_SRP_CUSTOM_ID_PREFIX,
75111
assertBrowserStackAppUrl,
76112
assertBrowserStackCustomId,
113+
isMainBranchBrowserStackCustomId,
77114
writeGithubOutputs,
78115
};

.github/scripts/browserstack-app-validation.test.ts

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import path from 'node:path';
55
const {
66
assertBrowserStackAppUrl,
77
assertBrowserStackCustomId,
8+
isMainBranchBrowserStackCustomId,
89
writeGithubOutputs,
910
} = require('./browserstack-app-validation.cjs');
1011

@@ -24,7 +25,10 @@ describe('browserstack-app-validation', () => {
2425
).toThrow('Invalid test');
2526
});
2627

27-
it('accepts expected custom_id formats with branch slug', () => {
28+
it('accepts stable and run-scoped custom_id formats with branch slug', () => {
29+
expect(
30+
assertBrowserStackCustomId('MetaMask-Android-With-SRP-main', 'with-srp'),
31+
).toBe('MetaMask-Android-With-SRP-main');
2832
expect(
2933
assertBrowserStackCustomId(
3034
'MetaMask-Android-With-SRP-main-123',
@@ -45,14 +49,42 @@ describe('browserstack-app-validation', () => {
4549
).toBe('MetaMask-Android-With-SRP-feature_x-789');
4650
});
4751

48-
it('rejects legacy custom_id formats without branch slug', () => {
52+
it('rejects legacy custom_id formats without a letterful branch slug', () => {
4953
expect(() =>
5054
assertBrowserStackCustomId('MetaMask-Android-With-SRP-123', 'with-srp'),
5155
).toThrow('Invalid with-srp custom_id');
5256
});
5357

58+
it('detects main-branch custom_ids only', () => {
59+
expect(
60+
isMainBranchBrowserStackCustomId(
61+
'MetaMask-Android-With-SRP-main',
62+
'with-srp',
63+
),
64+
).toBe(true);
65+
expect(
66+
isMainBranchBrowserStackCustomId(
67+
'MetaMask-Android-With-SRP-main-999',
68+
'with-srp',
69+
),
70+
).toBe(true);
71+
expect(
72+
isMainBranchBrowserStackCustomId(
73+
'MetaMask-Android-With-SRP-feature_x',
74+
'with-srp',
75+
),
76+
).toBe(false);
77+
expect(
78+
isMainBranchBrowserStackCustomId(
79+
'MetaMask-Android-With-SRP-maintenance-1',
80+
'with-srp',
81+
),
82+
).toBe(false);
83+
});
84+
5485
it('writes only validated single-line GitHub outputs', () => {
55-
const outputPath = path.join(os.tmpdir(), `gh-output-${Date.now()}.txt`);
86+
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'gh-output-'));
87+
const outputPath = path.join(tempDir, 'gh-output-test.txt');
5688
writeGithubOutputs(outputPath, {
5789
found: 'true',
5890
'with-srp-browserstack-url': 'bs://abc123',
@@ -61,6 +93,6 @@ describe('browserstack-app-validation', () => {
6193
expect(fs.readFileSync(outputPath, 'utf8')).toBe(
6294
'found=true\nwith-srp-browserstack-url=bs://abc123\n',
6395
);
64-
fs.unlinkSync(outputPath);
96+
fs.rmSync(tempDir, { recursive: true, force: true });
6597
});
6698
});

0 commit comments

Comments
 (0)