Skip to content

Commit ba1bc15

Browse files
authored
Merge pull request #30314 from MetaMask/Version-v12.13.0
Version v12.13.0
2 parents dc47374 + 8de0364 commit ba1bc15

File tree

1,186 files changed

+19917
-50556
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,186 files changed

+19917
-50556
lines changed

.circleci/config.yml

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -321,12 +321,15 @@ jobs:
321321
- run:
322322
name: Save Yarn version
323323
command: yarn --version > /tmp/YARN_VERSION
324+
- run:
325+
name: Save Foundry version
326+
command: node -e "process.stdout.write(require('./package.json').foundryup.version)" > /tmp/FOUNDRY_VERSION
324327
- restore_cache:
325328
keys:
326329
# First try to get the specific cache for the checksum of the yarn.lock file.
327330
# This cache key lookup will fail if the lock file is modified and a cache
328331
# has not yet been persisted for the new checksum.
329-
- dependency-cache-{{ checksum "/tmp/YARN_VERSION" }}-{{ checksum "yarn.lock" }}
332+
- dependency-cache-{{ checksum "/tmp/YARN_VERSION" }}-{{ checksum "yarn.lock" }}-{{ checksum "/tmp/FOUNDRY_VERSION" }}
330333
# To prevent having to do a full install of every node_module when
331334
# dependencies change, restore from the last known cache of any
332335
# branch/checksum with the same Yarn version, the install step will remove
@@ -338,12 +341,14 @@ jobs:
338341
name: Install dependencies
339342
command: yarn --immutable
340343
- save_cache:
341-
key: dependency-cache-{{ checksum "/tmp/YARN_VERSION" }}-{{ checksum "yarn.lock" }}
344+
key: dependency-cache-{{ checksum "/tmp/YARN_VERSION" }}-{{ checksum "yarn.lock" }}-{{ checksum "/tmp/FOUNDRY_VERSION" }}
342345
paths:
343346
- .yarn/cache
347+
- .metamask/cache # should match yarn's relative location
344348
- persist_to_workspace:
345349
root: .
346350
paths:
351+
- .metamask/cache # ensures anvil is installed
347352
- node_modules
348353
- build-artifacts
349354

@@ -364,6 +369,9 @@ jobs:
364369
root: .
365370
paths:
366371
- changed-files
372+
- store_artifacts:
373+
path: changed-files
374+
destination: changed-files
367375

368376
validate-locales-only:
369377
executor: node-browsers-small

.circleci/scripts/git-diff-default-branch.ts

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -91,24 +91,26 @@ async function fetchUntilMergeBaseFound() {
9191
* Performs a git diff command to get the list of files changed between the current branch and the origin.
9292
* It first ensures that the necessary commits are fetched until the merge base is found.
9393
*
94-
* @returns The output of the git diff command, listing the changed files.
94+
* @returns The output of the git diff command, listing the file paths with status (A, M, D).
9595
* @throws If unable to get the diff after fetching the merge base or if an unexpected error occurs.
9696
*/
9797
async function gitDiff(): Promise<string> {
9898
await fetchUntilMergeBaseFound();
9999
const { stdout: diffResult } = await exec(
100-
`git diff --name-only "origin/HEAD...${SOURCE_BRANCH}"`,
100+
`git diff --name-status "origin/HEAD...${SOURCE_BRANCH}"`,
101101
);
102102
if (!diffResult) {
103103
throw new Error('Unable to get diff after full checkout.');
104104
}
105105
return diffResult;
106106
}
107107

108-
function writePrBodyToFile(prBody: string) {
108+
function writePrBodyAndInfoToFile(prInfo: PRInfo) {
109109
const prBodyPath = path.resolve(CHANGED_FILES_DIR, 'pr-body.txt');
110-
fs.writeFileSync(prBodyPath, prBody.trim());
111-
console.log(`PR body saved to ${prBodyPath}`);
110+
const labels = prInfo.labels.map(label => label.name).join(', ');
111+
const updatedPrBody = `PR labels: {${labels}}\nPR base: {${prInfo.base.ref}}\n${prInfo.body.trim()}`;
112+
fs.writeFileSync(prBodyPath, updatedPrBody);
113+
console.log(`PR body and info saved to ${prBodyPath}`);
112114
}
113115

114116
/**
@@ -135,17 +137,9 @@ async function storeGitDiffOutputAndPrBody() {
135137
if (!baseRef) {
136138
console.log('Not a PR, skipping git diff');
137139
return;
138-
} else if (baseRef !== GITHUB_DEFAULT_BRANCH) {
139-
console.log(`This is for a PR targeting '${baseRef}', skipping git diff`);
140-
writePrBodyToFile(prInfo.body);
141-
return;
142-
} else if (
143-
prInfo.labels.some((label) => label.name === 'skip-e2e-quality-gate')
144-
) {
145-
console.log('PR has the skip-e2e-quality-gate label, skipping git diff');
146-
return;
147140
}
148-
141+
// We perform git diff even if the PR base is not main or skip-e2e-quality-gate label is applied
142+
// because we rely on the git diff results for other jobs
149143
console.log('Attempting to get git diff...');
150144
const diffOutput = await gitDiff();
151145
console.log(diffOutput);
@@ -155,7 +149,7 @@ async function storeGitDiffOutputAndPrBody() {
155149
fs.writeFileSync(outputPath, diffOutput.trim());
156150
console.log(`Git diff results saved to ${outputPath}`);
157151

158-
writePrBodyToFile(prInfo.body);
152+
writePrBodyAndInfoToFile(prInfo);
159153

160154
process.exit(0);
161155
} catch (error: any) {

.circleci/scripts/test-run-e2e-timeout-minutes.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
import { fetchManifestFlagsFromPRAndGit } from '../../development/lib/get-manifest-flag';
2-
import { filterE2eChangedFiles } from '../../test/e2e/changedFilesUtil';
2+
import { filterE2eChangedFiles, readChangedAndNewFilesWithStatus, getChangedAndNewFiles } from '../../test/e2e/changedFilesUtil';
33

44
fetchManifestFlagsFromPRAndGit().then((manifestFlags) => {
55
let timeout;
66

77
if (manifestFlags.circleci?.timeoutMinutes) {
88
timeout = manifestFlags.circleci?.timeoutMinutes;
99
} else {
10-
const changedOrNewTests = filterE2eChangedFiles();
10+
const changedAndNewFilesWithStatus = readChangedAndNewFilesWithStatus();
11+
const changedAndNewFiles = getChangedAndNewFiles(changedAndNewFilesWithStatus);
12+
const changedOrNewTests = filterE2eChangedFiles(changedAndNewFiles);
1113

1214
// 20 minutes, plus 3 minutes for every changed file, up to a maximum of 30 minutes
1315
timeout = Math.min(20 + changedOrNewTests.length * 3, 30);

.circleci/scripts/validate-locales-only.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
1-
const { readChangedFiles } = require('../../test/e2e/changedFilesUtil.js');
1+
const { readChangedAndNewFilesWithStatus, getChangedAndNewFiles } = require('../../test/e2e/changedFilesUtil.js');
22

33
/**
44
* Verifies that all changed files are in the /_locales/ directory.
55
* Fails the build if any changed files are outside of the /_locales/ directory.
66
* Fails if no changed files are detected.
77
*/
88
function validateLocalesOnlyChangedFiles() {
9-
const changedFiles = readChangedFiles();
9+
const changedAndNewFilesWithStatus = readChangedAndNewFilesWithStatus();
10+
const changedFiles = getChangedAndNewFiles(changedAndNewFilesWithStatus);
1011
if (!changedFiles || changedFiles.length === 0) {
1112
console.error('Failure: No changed files detected.');
1213
process.exit(1);

.depcheckrc.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ ignores:
4040
- 'wait-on'
4141
- 'tsx' # used in .devcontainer
4242
- 'prettier-eslint' # used by the Prettier ESLint VSCode extension
43+
- 'tar' # used by foundryup.ts
44+
- 'minipass' # used by foundryup.ts
4345
# storybook
4446
- '@storybook/cli'
4547
- '@storybook/core'
@@ -65,7 +67,7 @@ ignores:
6567
- 'html-bundler-webpack-plugin' # build tool
6668
- 'postcss-loader' # build tool
6769
- '@swc/helpers' # build tool
68-
- browserslist # build tool
70+
- 'browserslist' # build tool
6971
- 'buffer' # polyfill
7072
- 'crypto-browserify' # polyfill
7173
- 'process' # polyfill

.devcontainer/download-builds.ts

Lines changed: 9 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
import { execSync } from 'child_process';
22
import util from 'util';
3-
3+
import {
4+
getJobsByWorkflowId,
5+
getPipelineId,
6+
getWorkflowId,
7+
} from '../.github/scripts/shared/circle-artifacts';
48
const exec = util.promisify(require('node:child_process').exec);
59

610
function getGitBranch() {
@@ -10,34 +14,10 @@ function getGitBranch() {
1014
return gitOutput.match(branchRegex)?.groups?.branch || 'main';
1115
}
1216

13-
async function getCircleJobs(branch: string) {
14-
let response = await fetch(
15-
`https://circleci.com/api/v2/project/gh/MetaMask/metamask-extension/pipeline?branch=${branch}`,
16-
);
17-
18-
const pipelineId = (await response.json()).items[0].id;
19-
20-
console.log('pipelineId:', pipelineId);
21-
22-
response = await fetch(
23-
`https://circleci.com/api/v2/pipeline/${pipelineId}/workflow`,
24-
);
25-
26-
const workflowId = (await response.json()).items[0].id;
27-
28-
console.log('workflowId:', workflowId);
29-
30-
response = await fetch(
31-
`https://circleci.com/api/v2/workflow/${workflowId}/job`,
32-
);
33-
34-
const jobs = (await response.json()).items;
35-
36-
return jobs;
37-
}
38-
3917
async function getBuilds(branch: string, jobNames: string[]) {
40-
const jobs = await getCircleJobs(branch);
18+
const pipelineId = await getPipelineId(branch);
19+
const workflowId = await getWorkflowId(pipelineId);
20+
const jobs = await getJobsByWorkflowId(workflowId);
4121
let builds = [] as any[];
4222

4323
for (const jobName of jobNames) {
@@ -137,7 +117,7 @@ function unzipBuilds(folder: 'builds' | 'builds-test', versionNumber: string) {
137117
}
138118

139119
async function main(jobNames: string[]) {
140-
const branch = getGitBranch();
120+
const branch = process.env.CIRCLE_BRANCH || getGitBranch();
141121

142122
const builds = await getBuilds(branch, jobNames);
143123

.eslintrc.js

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,54 @@ module.exports = {
280280
},
281281
},
282282
},
283+
284+
/**
285+
* TypeScript React-specific code
286+
*
287+
* Similar to above, but marks a majority of errors to warnings.
288+
* TODO - combine rulesets and resolve errors
289+
*/
290+
{
291+
files: ['ui/**/*.ts', 'ui/**/*.tsx'],
292+
extends: ['plugin:react/recommended', 'plugin:react-hooks/recommended'],
293+
parserOptions: {
294+
ecmaFeatures: {
295+
jsx: true,
296+
},
297+
},
298+
plugins: ['react'],
299+
rules: {
300+
'react/no-unused-prop-types': 'warn',
301+
'react/no-unused-state': 'warn',
302+
'react/jsx-boolean-value': 'warn',
303+
'react/jsx-curly-brace-presence': [
304+
'warn',
305+
{
306+
props: 'never',
307+
children: 'never',
308+
},
309+
],
310+
'react/no-deprecated': 'warn',
311+
'react/default-props-match-prop-types': 'warn',
312+
'react/jsx-no-duplicate-props': 'warn',
313+
'react/display-name': 'off',
314+
'react/no-unescaped-entities': 'warn',
315+
'react/prop-types': 'off',
316+
'react/no-children-prop': 'off',
317+
'react/jsx-key': 'warn', // TODO - increase this into 'error' level
318+
'react-hooks/rules-of-hooks': 'warn', // TODO - increase this into 'error' level
319+
},
320+
settings: {
321+
react: {
322+
// If this is set to 'detect', ESLint will import React in order to
323+
// find its version. Because we run ESLint in the build system under
324+
// LavaMoat, this means that detecting the React version requires a
325+
// LavaMoat policy for all of React, in the build system. That's a
326+
// no-go, so we grab it from React's package.json.
327+
version: reactVersion,
328+
},
329+
},
330+
},
283331
/**
284332
* Mocha tests
285333
*

.github/CODEOWNERS

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,11 @@ offscreen/scripts/offscreen.ts @MetaMask/snaps-devs
4444
# make all such communication opt IN versus opt OUT.
4545
privacy-snapshot.json @MetaMask/extension-privacy-reviewers
4646

47+
48+
# A machine-generated file that tracks circular dependencies in the codebase.
49+
# It is updated using yarn circular-deps:update
50+
development/circular-deps.jsonc @MetaMask/extension-security-team @HowardBraham @dbrans
51+
4752
# The CODEOWNERS file constitutes an agreement amongst organization
4853
# admins and maintainers to restrict approval capabilities to a subset
4954
# of contributors. Modifications to this file result in a modification of

0 commit comments

Comments
 (0)