Skip to content

Commit 2f414a1

Browse files
committed
Merge branch 'main' into mikesposito/update-message-manager
2 parents 5c2d13d + 5d08c9b commit 2f414a1

File tree

1,132 files changed

+53525
-15307
lines changed

Some content is hidden

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

1,132 files changed

+53525
-15307
lines changed

.github/CODEOWNERS

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -99,20 +99,21 @@ app/scripts/constants/snaps.ts @MetaMask/core-platform
9999
# Co-owned by Confirmations and Snaps
100100
ui/components/app/metamask-template-renderer @MetaMask/confirmations @MetaMask/core-platform
101101

102-
# Wallet UX
103-
ui/components/app/whats-new-popup @MetaMask/wallet-ux
104-
ui/css @MetaMask/wallet-ux
105-
ui/pages/home @MetaMask/wallet-ux
106-
ui/components/multichain/ @MetaMask/wallet-ux
107-
108-
# Co-owned by accounts and wallet-ux
109-
ui/components/multichain/multi-srp/ @MetaMask/accounts-engineers @MetaMask/wallet-ux
110-
ui/components/multichain/account-picker/ @MetaMask/accounts-engineers @MetaMask/wallet-ux
111-
ui/components/multichain/account-details/ @MetaMask/accounts-engineers @MetaMask/wallet-ux
112-
ui/components/multichain/account-overview/ @MetaMask/accounts-engineers @MetaMask/wallet-ux
113-
ui/components/multichain/account-list-item/ @MetaMask/accounts-engineers @MetaMask/wallet-ux
114-
ui/components/multichain/account-list-menu/ @MetaMask/accounts-engineers @MetaMask/wallet-ux
115-
ui/components/multichain/account-list-item-menu/ @MetaMask/accounts-engineers @MetaMask/wallet-ux
102+
# Core Extension UX
103+
ui/components/app/whats-new-popup @MetaMask/core-extension-ux
104+
ui/css @MetaMask/core-extension-ux
105+
ui/pages/home @MetaMask/core-extension-ux
106+
ui/pages/core @MetaMask/core-extension-ux
107+
ui/components/multichain/ @MetaMask/core-extension-ux
108+
109+
# Co-owned by accounts and core-extension-ux
110+
ui/components/multichain/multi-srp/ @MetaMask/accounts-engineers @MetaMask/core-extension-ux
111+
ui/components/multichain/account-picker/ @MetaMask/accounts-engineers @MetaMask/core-extension-ux
112+
ui/components/multichain/account-details/ @MetaMask/accounts-engineers @MetaMask/core-extension-ux
113+
ui/components/multichain/account-overview/ @MetaMask/accounts-engineers @MetaMask/core-extension-ux
114+
ui/components/multichain/account-list-item/ @MetaMask/accounts-engineers @MetaMask/core-extension-ux
115+
ui/components/multichain/account-list-menu/ @MetaMask/accounts-engineers @MetaMask/core-extension-ux
116+
ui/components/multichain/account-list-item-menu/ @MetaMask/accounts-engineers @MetaMask/core-extension-ux
116117

117118
# Web3Auth / Onboarding
118119
ui/pages/onboarding-flow @MetaMask/web3auth
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
name: 'Page load benchmark comment'
2+
description: 'Download benchmark results, create directory structure, and comment on PR'
3+
inputs:
4+
head-commit-hash:
5+
description: 'The head commit hash to pass to the benchmark comment script'
6+
required: true
7+
pr-comment-token:
8+
description: 'GitHub token for commenting on PR'
9+
required: true
10+
runs:
11+
using: 'composite'
12+
steps:
13+
- name: Download page load benchmark results
14+
uses: actions/download-artifact@v4
15+
with:
16+
name: benchmark-results
17+
18+
- name: Create expected page load benchmark results directory structure
19+
shell: bash
20+
run: |
21+
mkdir -p test-artifacts/benchmarks
22+
mv benchmark-results.json test-artifacts/benchmarks/benchmark-results.json
23+
24+
- name: Page load benchmark compare and comment
25+
shell: bash
26+
run: yarn tsx development/page-load-benchmark-pr-comment.ts
27+
env:
28+
PR_COMMENT_TOKEN: ${{ inputs.pr-comment-token }}
29+
OWNER: ${{ github.repository_owner }}
30+
REPOSITORY: ${{ github.event.repository.name }}
31+
PR_NUMBER: ${{ github.event.pull_request.number }}
32+
HEAD_COMMIT_HASH: ${{ inputs.head-commit-hash }}

.github/e2e-filter-rules.yml

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# Filter rules for determining E2E test requirements
2+
# Used with dorny/paths-filter action
3+
#
4+
# Each filter creates two outputs:
5+
# - {filter_name}: 'true'/'false' if any changed files match any filter rules
6+
# - {filter_name}_count: number of matching files
7+
#
8+
# STRATEGY: Use separate filters to detect different file types non E2E related.
9+
# Conservative approach - add only files that safely allow skipping E2E tests.
10+
11+
# DOCUMENTATION FILES
12+
documentation_files: &documentation_files
13+
- '**/*.{md,mdx,txt}'
14+
- 'docs/**/*'
15+
- 'test/manual-scenarios/**/*'
16+
- 'LICENSE'
17+
18+
# LOW LEVEL TEST FILES
19+
test_files: &test_files
20+
- '**/*.test.{js,ts,tsx,jsx}'
21+
- '**/*.stories.*'
22+
- '**/*.snap'
23+
- 'test/jest/**/*'
24+
- 'test/unit-global/**/*'
25+
- 'test/lib/**/*'
26+
- 'test/stub/**/*'
27+
- 'test/integration/**/*'
28+
29+
# CONFIG FILES
30+
config_files: &config_files
31+
- '.eslint*'
32+
- 'eslint.config.js'
33+
- 'prettier.config.js'
34+
- 'stylelint.config.js'
35+
- 'tailwind.config.js'
36+
- 'sonar-project.properties'
37+
- 'codecov.yml'
38+
39+
# DEVELOPMENT TOOLS
40+
dev_tools: &dev_tools
41+
- 'development/fitness-functions/**/*'
42+
- 'development/ts-migration-dashboard/**/*'
43+
- 'development/generate-attributions/**/*'
44+
45+
# ALL FILTERED FILES - non E2E related files
46+
non_e2e_related_files:
47+
- *documentation_files
48+
- *test_files
49+
- *config_files
50+
- *dev_tools
51+
52+
# ALL CHANGED FILES
53+
all_changes:
54+
- '**'

.github/guidelines/LABELING_GUIDELINES.md

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,38 +2,41 @@
22

33
To maintain a consistent and efficient development workflow, we have set specific label guidelines for all pull requests (PRs). Please ensure you adhere to the following instructions:
44

5-
### Mandatory team labels:
5+
## Mandatory team label (automated)
66

77
- **Internal Developers**: Every PR raised by an internal developer must include a label prefixed with `team-` (e.g., `team-extension-ux`, `team-extension-platform`, etc.). This indicates the respective internal team responsible for the PR.
88

99
- **External Contributors**: PRs submitted by contributors who are not part of the organization will be automatically labeled with `external-contributor`.
1010

11-
It's essential to ensure that PRs have the appropriate labels before they are considered for merging.
11+
## Mandatory checklog entry or label (manual addition)
1212

13-
### Mandatory release version labels:
13+
The releases changelog generation is based on PR's changelog entries.
14+
The check can be bypassed when necessary, either by setting the changelog entry to "null" or by adding following label:
1415

15-
- **release-x.y.z**: This label is automatically added to a PR and its linked issues upon the PR's merge. The `x.y.z` in the label represents the version in which the changes from the PR will be included. This label is auto-generated by a [GitHub action](../workflows/add-release-label.yml), which determines the version by incrementing the minor version number from the most recent release. Manual intervention is only required in specific cases. For instance, if a merged PR is cherry-picked into a release branch, typically done to address Release Candidate (RC) bugs, the label would need to be manually updated to reflect the correct version.
16-
- **regression-prod-x.y.z**: This label is automatically added to a bug report issue at the time of its creation. The `x.y.z` in the label represents the version in which the bug first appeared. This label is auto-generated by a [GitHub action](../workflows/check-template-and-add-labels.yml), which determines the `x.y.z` value based on the version information provided in the bug report issue form. Manual intervention is only necessary under certain circumstances. For example, if a user submits a bug report and specifies the version they are currently using, but the bug was actually introduced in a prior version, the label would need to be manually updated to accurately reflect the version where the bug originated.
17-
- **regression-RC-x.y.z**: This label is manually added to a bug report issue by release engineers when a bug is found during release regerssion testing phase. The `x.y.z` in the label represents the release candidate (RC) version in which the bug's been discovered.
16+
- **no-changelog**: PR's changes do not need to be included in the changelog.
17+
18+
## Optional labels (manual addition)
19+
20+
Any label can be manually added on demand depending on the PR's content. For instance, the label **QA passed** will indicate that a thorough manual testing has been performed and the PR is ready to be merged. In addition, following labels have some specific use cases.
1821

19-
### Optional labels:
22+
### Bypass Quality Gates
2023

21-
- **regression-main**: This label can manually be added to a bug report issue at the time of its creation if the bug is present on the development branch, i.e., `main`, but is not yet released in production.
22-
- **feature-branch-bug**: This label can manually be added to a bug report issue at the time of its creation if the bug is present on a feature branch, i.e., before merging to `main`.
23-
- **needs-qa**: If the PR includes a new features, complex testing steps, or large refactors, this label must be added to indicated PR requires a full manual QA prior being merged and added to a release.
24+
Using any of these labels should be exceptional in case of CI friction and urgencies. Please use them reasonably and verify new changes and regressions manually.
2425

25-
### Labels prohibited when PR needs to be merged:
26+
- **skip-e2e-quality-gate**: This label will disable the default test retries for E2E test files modified in the PR. Useful when making large refactors or when changes don't pose flakiness risk.
2627

27-
Any PR that includes one of the following labels can not be merged:
28+
### Block merge if any is present
2829

2930
- **needs-qa**: The PR requires a full manual QA prior to being merged and added to a release.
30-
- **QA'd but questions**: The PR has been checked by QA, but there are pending questions or clarifications needed on minor issues that were found.
31-
- **issues-found**: The PR has been checked by QA or other reviewers, and appeared to include issues that need to be addressed.
3231
- **need-ux-ds-review**: The PR requires a review from the User Experience or Design System teams.
3332
- **blocked**: There are unresolved dependencies or other issues blocking the progress of this PR.
3433
- **stale**: The PR has not had recent activity in the last 90 days. It will be closed in 7 days.
3534
- **DO-NOT-MERGE**: The PR should not be merged under any circumstances.
3635

36+
## Release version label (automated)
37+
38+
- **release-x.y.z**: This label is automatically added to a PR and its linked issues upon the PR's merge. The `x.y.z` in the label represents the version in which the changes from the PR will be included. This label is auto-generated by a [GitHub action](../workflows/add-release-label.yml), which determines the version by incrementing the minor version number from the most recent release. Manual intervention is only required in specific cases. For instance, if a merged PR is cherry-picked into a release branch, typically done to address Release Candidate (RC) bugs, the label would need to be manually updated to reflect the correct version.
39+
3740
To maintain code quality and project integrity, it's crucial to respect these label guidelines. Please ensure you review and update labels appropriately throughout the PR lifecycle.
3841

3942
Thank you for your cooperation!

.github/scripts/check-pr-has-required-labels.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,6 @@ async function main(): Promise<void> {
4242

4343
const preventMergeLabels = [
4444
'needs-qa',
45-
"QA'd but questions",
46-
'issues-found',
4745
'need-ux-ds-review',
4846
'blocked',
4947
'stale',

.github/scripts/check-template-and-add-labels.ts

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ async function main(): Promise<void> {
140140
}
141141
// Add area-Sentry label to the bug report issue
142142
await addAreaSentryLabelToIssue(octokit, labelable);
143+
await checkAndRemoveNeedsTriageIfFullyLabeled(octokit, labelable);
143144
process.exit(0); // Stop the process and exit with a success status code
144145
}
145146

@@ -165,18 +166,22 @@ async function main(): Promise<void> {
165166
if (context.payload.action === 'opened') {
166167
await addNeedsTriageLabelToIssue(octokit, labelable);
167168
}
169+
await checkAndRemoveNeedsTriageIfFullyLabeled(octokit, labelable);
170+
168171
} else {
169172
const errorMessage =
170173
"Issue body does not match any of expected templates ('general-issue.yml' or 'bug-report.yml').\n\nMake sure issue's body includes all section titles.\n\nSections titles are listed here: https://github.com/MetaMask/metamask-extension/blob/main/.github/scripts/shared/template.ts#L14-L37";
171174
console.log(errorMessage);
172175

173-
// Add label to indicate issue doesn't match any template
176+
// Add label to indicate issue does not match any template
174177
await addLabelToLabelable(octokit, labelable, invalidIssueTemplateLabel);
178+
await checkAndRemoveNeedsTriageIfFullyLabeled(octokit, labelable);
175179

176180
// Github action shall fail in case issue body doesn't match any template
177181
core.setFailed(errorMessage);
178182
process.exit(1);
179183
}
184+
180185
} else if (labelable.type === LabelableType.PullRequest) {
181186
if (templateType === TemplateType.PullRequest) {
182187
console.log("PR matches 'pull-request-template.md' template.");
@@ -429,3 +434,36 @@ function hasChangelogEntry(body: string): boolean {
429434
console.log(`Changelog entry found: ${entry}`);
430435
return true; // allow any non-empty value, including "null"
431436
}
437+
438+
// This function checks if issue has both team and severity labels and removes needs-triage label if present
439+
async function checkAndRemoveNeedsTriageIfFullyLabeled(
440+
octokit: InstanceType<typeof GitHub>,
441+
issue: Labelable,
442+
): Promise<void> {
443+
let hasTeamLabel = false;
444+
let hasSeverityLabel = false;
445+
446+
for (const label of issue.labels || []) {
447+
// Check for team labels
448+
if (
449+
label.name.startsWith('team-') ||
450+
label.name === externalContributorLabel.name
451+
) {
452+
console.log(`Issue contains a team label: ${label.name}`);
453+
hasTeamLabel = true;
454+
}
455+
// Check for severity labels (Sev0-urgent, Sev1-high, etc.)
456+
if (/^Sev\d-\w+$/.test(label.name)) {
457+
console.log(`Issue contains a severity label: ${label.name}`);
458+
hasSeverityLabel = true;
459+
}
460+
}
461+
462+
// If both team and severity labels are present, remove needs-triage label
463+
if (hasTeamLabel && hasSeverityLabel) {
464+
console.log(
465+
'Both team and severity labels found. Removing needs-triage label if present...',
466+
);
467+
await removeLabelFromLabelableIfPresent(octokit, issue, needsTriageLabel);
468+
}
469+
}

.github/scripts/create-bug-report-issue.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ async function main(): Promise<void> {
103103
process.exit(1);
104104
}
105105

106-
const issueBody = `**What is this bug report issue for?**\n\n1. This issue is used to track release dates on this [Github Project board](https://github.com/orgs/MetaMask/projects/${projectNumber}/views/${projectViewNumber}), which content then gets pulled into our metrics system.\n\n2. This issue is also used by our Zapier automations, to determine if automated notifications shall be sent on Slack for release \`${releaseVersion}\`. Notifications will only be sent as long as this issue is open.\n\n**Who created and/or closed this issue?**\n\n- This issue was automatically created by a GitHub action upon the creation of the release branch \`Version-v${releaseVersion}\`, indicating the release was cut.\n\n- This issue gets automatically closed by another GitHub action, once the release branch \`Version-v${releaseVersion}\` or \`release/${releaseVersion}\` merges into \`main\`, indicating the release is prepared for store submission.`;
106+
const issueBody = `**What is this bug report issue for?**\n\n1. This issue is used to track release dates on this [Github Project board](https://github.com/orgs/MetaMask/projects/${projectNumber}/views/${projectViewNumber}), which content then gets pulled into our metrics system.\n\n2. This issue is also used by our Zapier automations, to determine if automated notifications shall be sent on Slack for release \`${releaseVersion}\`. Notifications will only be sent as long as this issue is open.\n\n**Who created and/or closed this issue?**\n\n- This issue was automatically created by a GitHub action upon the creation of the release branch \`release/${releaseVersion}\`, indicating the release was cut.\n\n- This issue gets automatically closed by another GitHub action, once the release branch \`release/${releaseVersion}\` merges into \`stable\`, indicating the release is prepared for store submission.`;
107107
const issueId = await createIssue(octokit, repoOwner, planningRepoName, issueTitle, issueBody, [regressionLabelTestingId, typeBugLabelId, teamLabelId]);
108108

109109
// Retrieve project, in order to obtain its ID

.github/scripts/extract-semver.sh

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#!/bin/bash
2+
3+
set -euo pipefail
4+
5+
ref_name="${GITHUB_REF#refs/heads/}"
6+
7+
# Extract semver based on prefix
8+
if [[ "$ref_name" == Version-v* ]]; then
9+
semver="${ref_name#Version-v}"
10+
elif [[ "$ref_name" == release/* ]]; then
11+
semver="${ref_name#release/}"
12+
else
13+
echo "Error: Branch name must be Version-vX.Y.Z or release/X.Y.Z where X, Y, Z are numbers. Got: $ref_name" >&2
14+
exit 1
15+
fi
16+
17+
# Validate semver format X.Y.Z where X, Y, Z are numbers
18+
if ! [[ "$semver" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
19+
echo "Error: Invalid semver in branch name: $ref_name (extracted: $semver; must be numeric X.Y.Z)" >&2
20+
exit 1
21+
fi
22+
23+
echo " semver-version: ${semver}"
24+
echo "semver=${semver}" >> "$GITHUB_OUTPUT"
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
#!/bin/bash
2+
3+
set -euo pipefail
4+
5+
# Ensure SEMVER is provided via environment and assign
6+
semver="${SEMVER:?SEMVER environment variable must be set}"
7+
8+
patch="${semver##*.}"
9+
if [ "$patch" -gt 0 ]; then
10+
previous_ref="null"
11+
echo "Hotfix detected (patch=$patch > 0): setting previous-version-ref to 'null' (string)."
12+
echo "previous_ref=${previous_ref}" >> "$GITHUB_OUTPUT"
13+
exit 0
14+
fi
15+
16+
# Function to paginate and collect refs for a prefix
17+
fetch_matching_refs() {
18+
local prefix="$1"
19+
local temp_file
20+
temp_file="$(mktemp)"
21+
local page=1
22+
echo "Fetching branches matching $prefix* (paginated)..." >&2
23+
while :; do
24+
echo "Fetching page $page for $prefix..." >&2
25+
local resp
26+
resp="$(mktemp)"
27+
url="https://api.github.com/repos/${GITHUB_REPOSITORY}/git/matching-refs/heads/${prefix}?per_page=100&page=${page}"
28+
curl -sS -H "Authorization: token $GITHUB_TOKEN" -H "Accept: application/vnd.github.v3+json" "$url" -o "$resp"
29+
30+
cat "$resp" >> "$temp_file"
31+
32+
local count
33+
count=$(jq length "$resp")
34+
if [ "$count" -lt 100 ]; then
35+
break
36+
fi
37+
page=$((page + 1))
38+
if [ "$page" -gt 100 ]; then
39+
echo "Error: Exceeded maximum pagination limit (100 pages) while fetching refs for prefix '$prefix'. This may indicate too many matching branches or an API issue." >&2
40+
exit 1
41+
fi
42+
done
43+
echo "$temp_file"
44+
}
45+
46+
# Fetch for each prefix
47+
version_v_file=$(fetch_matching_refs "Version-v")
48+
release_file=$(fetch_matching_refs "release/")
49+
50+
# Combine and process: extract {name, semver} for matches, sort desc by semver
51+
jq -s 'add | [ .[] | .ref | ltrimstr("refs/heads/") as $name | select($name | test("^Version-v[0-9]+\\.[0-9]+\\.[0-9]+$") or test("^release/[0-9]+\\.[0-9]+\\.[0-9]+$")) | {name: $name, semver: (if $name | test("^Version-v") then $name | ltrimstr("Version-v") else $name | ltrimstr("release/") end) } ] | sort_by( .semver | split(".") | map(tonumber) ) | reverse' "$version_v_file" "$release_file" > all_versions.json
52+
53+
# Filter to those with semver strictly lower than current and non-hotfix (patch==0)
54+
jq --arg semver "$semver" '[ .[] | select( .semver as $v | $semver | split(".") as $c | $v | split(".") as $p | ( ($p[0] | tonumber) < ($c[0] | tonumber) or (($p[0] | tonumber) == ($c[0] | tonumber) and (($p[1] | tonumber) < ($c[1] | tonumber) or (($p[1] | tonumber) == ($c[1] | tonumber) and ($p[2] | tonumber) < ($c[2] | tonumber)))) ) and (($p[2] | tonumber) == 0) ) ]' all_versions.json > filtered_versions.json
55+
56+
# Select the highest lower: first in filtered list. If none found, fail.
57+
if [ "$(jq length filtered_versions.json)" -eq 0 ]; then
58+
echo "Error: No lower non-hotfix versions found; cannot determine previous-version-ref." >&2
59+
echo "This likely indicates a missing prior minor release branch (e.g., Version-vX.(Y-1).0 or release/X.(Y-1).0)." >&2
60+
exit 1
61+
else
62+
highest_lower="$(jq -r '.[0].semver' filtered_versions.json)"
63+
previous_ref="$(jq -r '.[0].name' filtered_versions.json)"
64+
echo "Selected highest lower non-hotfix version: ${highest_lower} (branch: ${previous_ref})"
65+
echo "previous_ref=${previous_ref}" >> "$GITHUB_OUTPUT"
66+
fi

0 commit comments

Comments
 (0)