Skip to content

Commit 50f490e

Browse files
authored
Merge branch 'main' into SOL-225-disable-buttons-for-solana
2 parents 86e77a8 + 6ad6037 commit 50f490e

File tree

78 files changed

+1272
-383
lines changed

Some content is hidden

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

78 files changed

+1272
-383
lines changed

.circleci/config.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@ version: 2.1
33
executors:
44
node-browsers-small:
55
docker:
6-
- image: cimg/node:22.13-browsers
6+
- image: cimg/node:22.14-browsers
77
resource_class: small
88
environment:
99
NODE_OPTIONS: --max_old_space_size=2048
1010
node-browsers-medium:
1111
docker:
12-
- image: cimg/node:22.13-browsers
12+
- image: cimg/node:22.14-browsers
1313
resource_class: medium
1414
environment:
1515
NODE_OPTIONS: --max_old_space_size=3072
@@ -21,7 +21,7 @@ executors:
2121
NODE_OPTIONS: --max_old_space_size=6144
2222
node-browsers-medium-plus:
2323
docker:
24-
- image: cimg/node:22.13-browsers
24+
- image: cimg/node:22.14-browsers
2525
resource_class: medium+
2626
environment:
2727
NODE_OPTIONS: --max_old_space_size=4096

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

Lines changed: 30 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,15 @@
1-
import { exec as execCallback } from 'child_process';
21
import fs from 'fs';
32
import path from 'path';
4-
import { promisify } from 'util';
5-
import { context } from '@actions/github';
3+
import { context, getOctokit } from '@actions/github';
64
import * as core from '@actions/core';
75

8-
const exec = promisify(execCallback);
9-
106
// Get PR number from GitHub Actions environment variables
117
const PR_NUMBER = context.payload.pull_request?.number;
128

13-
const GITHUB_DEFAULT_BRANCH = 'main';
14-
const SOURCE_BRANCH = PR_NUMBER ? `refs/pull/${PR_NUMBER}/head` : '';
15-
169
const CHANGED_FILES_DIR = 'changed-files';
1710

11+
const octokit = getOctokit(process.env.GITHUB_TOKEN || '');
12+
1813
type PRInfo = {
1914
base: {
2015
ref: string;
@@ -35,86 +30,36 @@ async function getPrInfo(): Promise<PRInfo | null> {
3530

3631
const { owner, repo } = context.repo;
3732

38-
const response = await fetch(
39-
`https://api.github.com/repos/${owner}/${repo}/pulls/${PR_NUMBER}`,
40-
{
41-
headers: {
42-
Authorization: `token ${process.env.GITHUB_TOKEN}`,
43-
Accept: 'application/vnd.github.v3+json',
44-
},
45-
},
46-
);
47-
48-
return await response.json();
49-
}
50-
51-
/**
52-
* Fetches the git repository with a specified depth.
53-
*
54-
* @param depth - The depth to use for the fetch command.
55-
* @returns True if the fetch is successful, otherwise false.
56-
*/
57-
async function fetchWithDepth(depth: number): Promise<boolean> {
58-
try {
59-
await exec(`git fetch --depth ${depth} origin "${GITHUB_DEFAULT_BRANCH}"`);
60-
if (SOURCE_BRANCH) {
61-
await exec(
62-
`git fetch --depth ${depth} origin "${SOURCE_BRANCH}:${SOURCE_BRANCH}"`,
63-
);
64-
}
65-
return true;
66-
} catch (error) {
67-
core.warning(`Failed to fetch with depth ${depth}:`, error);
68-
return false;
69-
}
33+
return (
34+
await octokit.request(`GET /repos/${owner}/${repo}/pulls/${PR_NUMBER}`)
35+
).data;
7036
}
7137

7238
/**
73-
* Attempts to fetch the necessary commits until the merge base is found.
74-
* It tries different fetch depths and performs a full fetch if needed.
39+
* Get the list of files changed in the pull request using GraphQL
7540
*
76-
* @throws If an unexpected error occurs during the execution of git commands.
41+
* @returns List of files changed in the PR
7742
*/
78-
async function fetchUntilMergeBaseFound() {
79-
const depths = [1, 10, 100];
80-
for (const depth of depths) {
81-
core.info(`Attempting git diff with depth ${depth}...`);
82-
await fetchWithDepth(depth);
83-
84-
try {
85-
await exec(`git merge-base origin/${GITHUB_DEFAULT_BRANCH} HEAD`);
86-
return;
87-
} catch (error: unknown) {
88-
if (error instanceof Error && 'code' in error) {
89-
core.warning(
90-
`Error 'no merge base' encountered with depth ${depth}. Incrementing depth...`,
91-
);
92-
} else {
93-
throw error;
94-
}
95-
}
96-
}
97-
await exec(`git fetch --unshallow origin "${GITHUB_DEFAULT_BRANCH}"`);
98-
}
43+
async function getPrFilesChanged() {
44+
const { owner, repo } = context.repo;
9945

100-
/**
101-
* Performs a git diff command to get the list of files changed between the current branch and the origin.
102-
* It first ensures that the necessary commits are fetched until the merge base is found.
103-
*
104-
* @returns The output of the git diff command, listing the file paths with status (A, M, D).
105-
* @throws If unable to get the diff after fetching the merge base or if an unexpected error occurs.
106-
*/
107-
async function gitDiff(): Promise<string> {
108-
await fetchUntilMergeBaseFound();
109-
const { stdout: diffResult } = await exec(
110-
`git diff --name-status "origin/${GITHUB_DEFAULT_BRANCH}...${
111-
SOURCE_BRANCH || 'HEAD'
112-
}"`,
113-
);
114-
if (!diffResult) {
115-
throw new Error('Unable to get diff after full checkout.');
116-
}
117-
return diffResult;
46+
const response = await octokit.graphql({
47+
query: `
48+
{
49+
repository(owner: "${owner}", name: "${repo}") {
50+
pullRequest(number: ${PR_NUMBER}) {
51+
files(first: 100) {
52+
nodes {
53+
changeType
54+
path,
55+
}
56+
}
57+
}
58+
}
59+
}`,
60+
});
61+
62+
return response.repository.pullRequest.files.nodes;
11863
}
11964

12065
function writePrBodyAndInfoToFile(prInfo: PRInfo) {
@@ -153,12 +98,12 @@ async function storeGitDiffOutputAndPrBody() {
15398
// We perform git diff even if the PR base is not main or skip-e2e-quality-gate label is applied
15499
// because we rely on the git diff results for other jobs
155100
core.info('Attempting to get git diff...');
156-
const diffOutput = await gitDiff();
101+
const diffOutput = JSON.stringify(await getPrFilesChanged());
157102
core.info(diffOutput);
158103

159104
// Store the output of git diff
160-
const outputPath = path.resolve(CHANGED_FILES_DIR, 'changed-files.txt');
161-
fs.writeFileSync(outputPath, diffOutput.trim());
105+
const outputPath = path.resolve(CHANGED_FILES_DIR, 'changed-files.json');
106+
fs.writeFileSync(outputPath, diffOutput);
162107
core.info(`Git diff results saved to ${outputPath}`);
163108

164109
writePrBodyAndInfoToFile(prInfo);
Lines changed: 72 additions & 123 deletions
Original file line numberDiff line numberDiff line change
@@ -1,131 +1,80 @@
1+
import * as core from '@actions/core';
12
import fs from 'fs';
2-
import { execSync } from 'child_process';
33
import { filterE2eChangedFiles } from '../../test/e2e/changedFilesUtil';
4-
import {
5-
downloadArtifact,
6-
getArtifactUrl,
7-
readFileContent,
8-
sleep,
9-
} from './shared/circle-artifacts';
10-
11-
async function verifyE2ePageObjectsUsage(fileStatus: 'M' | 'A' | 'both') {
12-
let e2eFiles: string[];
13-
14-
if (process.env.GITHUB_ACTIONS) {
15-
// Running in Github Actions
16-
const branch = process.env.BRANCH || '';
17-
const headCommitHash = process.env.HEAD_COMMIT_HASH || '';
18-
const artifactName = 'changed-files.txt';
19-
const artifactPath = 'changed-files';
20-
const jobName = 'get-changed-files-with-git-diff';
21-
22-
let attempts = 0;
23-
const maxAttempts = 3;
24-
let changedFilesContent = '';
25-
26-
// Small buffer to ensure the job id is accessible in circle ci
27-
// once we have that job migrated into github actions, we can just add a dependency rule
28-
await sleep(180);
29-
30-
while (attempts < maxAttempts) {
31-
try {
32-
console.log(`Attempt ${attempts + 1}/${maxAttempts}`);
33-
34-
const outputDir = `${artifactPath}/changed-files.txt`;
35-
const changedFilesArtifactUrl = await getArtifactUrl(branch, headCommitHash, jobName, artifactName);
36-
37-
await downloadArtifact(changedFilesArtifactUrl, outputDir);
38-
39-
changedFilesContent = readFileContent(outputDir);
40-
41-
if (changedFilesContent) {
42-
console.log('Artifact downloaded and read successfully.');
43-
break;
44-
}
45-
} catch (error) {
46-
console.error(`Error fetching artifact: ${error.message}`);
47-
}
48-
49-
attempts++;
50-
if (attempts < maxAttempts) {
51-
console.log(`Retrying in 15 seconds... (${attempts}/${maxAttempts})`);
52-
await sleep(15);
53-
}
54-
}
55-
56-
if (!changedFilesContent) {
57-
console.error('No artifacts found for changed files. Exiting with failure.');
58-
process.exit(1);
59-
}
60-
61-
// Parse the changed and new files with status
62-
const changedAndNewFilePathsWithStatus = changedFilesContent.split('\n').filter(line => line.trim() !== '').map(line => {
63-
const [status, filePath] = line.split('\t');
64-
return { status, filePath };
65-
});
66-
67-
// Filter files based on the provided fileStatus
68-
const filteredFiles = changedAndNewFilePathsWithStatus.filter(file => {
69-
if (fileStatus === 'both') {
70-
return file.status === 'A' || file.status === 'M';
71-
}
72-
return file.status === fileStatus;
73-
}).map(file => file.filePath);
74-
75-
e2eFiles = filterE2eChangedFiles(filteredFiles);
76-
console.log('Filtered E2E files:', e2eFiles);
77-
} else {
78-
// Running locally
79-
console.log('Running locally, performing git diff against main branch...');
80-
const diffOutput = execSync('git diff --name-status main...HEAD').toString().trim();
81-
const changedFiles = diffOutput.split('\n').filter(line => line.trim() !== '').map(line => {
82-
const [status, filePath] = line.split('\t');
83-
return { status, filePath };
84-
});
85-
86-
// Filter files based on the provided fileStatus
87-
const filteredFiles = changedFiles.filter(file => {
88-
if (fileStatus === 'both') {
89-
return file.status === 'A' || file.status === 'M';
90-
}
91-
return file.status === fileStatus;
92-
}).map(file => file.filePath);
93-
94-
e2eFiles = filterE2eChangedFiles(filteredFiles);
95-
console.log('Filtered E2E files:', e2eFiles);
4+
import { readFileContent } from './shared/circle-artifacts';
5+
6+
async function verifyE2ePageObjectsUsage(
7+
changeType: 'MODIFIED' | 'ADDED' | 'BOTH',
8+
) {
9+
let e2eFiles: string[];
10+
11+
const artifactName = 'changed-files.json';
12+
const artifactDir = 'changed-files';
13+
const artifactPath = `${artifactDir}/${artifactName}`;
14+
15+
let changedFilesContent;
16+
17+
try {
18+
changedFilesContent = JSON.parse(fs.readFileSync(artifactPath, 'utf-8'));
19+
} catch (error) {
20+
console.error('No artifacts found for changed files.');
21+
process.exit(0);
22+
}
23+
24+
// Filter files based on the provided changeType
25+
const filteredFiles = changedFilesContent
26+
.filter((file) => {
27+
if (changeType === 'BOTH') {
28+
return file.changeType === 'MODIFIED' || file.changeType === 'ADDED';
29+
}
30+
return file.changeType === changeType;
31+
})
32+
.map((file) => file.path);
33+
34+
e2eFiles = filterE2eChangedFiles(filteredFiles);
35+
console.log('Filtered E2E files:', e2eFiles);
36+
37+
if (e2eFiles.length === 0) {
38+
console.log('No E2E files to validate. Exiting successfully.');
39+
process.exit(0);
40+
}
41+
42+
let hasErrors = false;
43+
44+
// Check each E2E file for page object usage
45+
for (const file of e2eFiles) {
46+
try {
47+
const content = fs.readFileSync(file, 'utf8');
48+
// Check for the presence of page object imports
49+
const usesPageObjectModel = content.includes('./page-objects/');
50+
51+
if (!usesPageObjectModel) {
52+
core.error(
53+
`\x1b[31m You need to use Page Object Model in ${file}\x1b[0m`,
54+
);
55+
hasErrors = true;
56+
}
57+
} catch (error) {
58+
if (error.code === 'ENOENT') {
59+
console.warn(`File not found: ${file}`);
60+
continue; // Skip this file because it was deleted, so no need to validate
61+
} else {
62+
throw error; // Re-throw if it's a different error
63+
}
9664
}
65+
}
9766

98-
if (e2eFiles.length === 0) {
99-
console.log('No E2E files to validate. Exiting successfully.');
100-
process.exit(0);
101-
}
102-
103-
// Check each E2E file for page object usage
104-
for (const file of e2eFiles) {
105-
try {
106-
const content = fs.readFileSync(file, 'utf8');
107-
// Check for the presence of page object imports
108-
const usesPageObjectModel = content.includes('./page-objects/');
109-
110-
if (!usesPageObjectModel) {
111-
console.error(`\x1b[31mFailure: You need to use Page Object Model in ${file}\x1b[0m`);
112-
process.exit(1);
113-
}
114-
} catch (error) {
115-
if (error.code === 'ENOENT') {
116-
console.warn(`File not found: ${file}`);
117-
continue; // Skip this file because it was deleted, so no need to validate
118-
} else {
119-
throw error; // Re-throw if it's a different error
120-
}
121-
}
122-
}
67+
if (hasErrors) {
68+
process.exit(1);
69+
}
12370

124-
console.log("\x1b[32mSuccess: All the new or modified E2E files use the Page Object Model.\x1b[0m");
71+
console.log(
72+
'\x1b[32mSuccess: All the new or modified E2E files use the Page Object Model.\x1b[0m',
73+
);
12574
}
12675

12776
// Run the verification for new files only
128-
verifyE2ePageObjectsUsage('A').catch((error) => {
129-
console.error('Not all the new e2e files use the Page Object Model', error);
130-
process.exit(1);
131-
});
77+
verifyE2ePageObjectsUsage('ADDED').catch((error) => {
78+
console.error('Not all the new e2e files use the Page Object Model', error);
79+
process.exit(1);
80+
});

.github/workflows/add-release-label.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ jobs:
1313
if: github.event.pull_request.merged == true
1414
steps:
1515
- name: Checkout and setup environment
16-
uses: metamask/github-tools/.github/actions/checkout-and-setup@1299bb1de0c6974ae6d0a32c7e8897fe168239ac
16+
uses: MetaMask/action-checkout-and-setup@v1
1717
with:
1818
is-high-risk-environment: false
1919
fetch-depth: 0 # This is needed to checkout all branches

.github/workflows/build-beta.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ jobs:
4242
4343
- name: Checkout and setup high risk environment
4444
if: ${{ steps.needs-beta-build.outputs.NEEDS_BETA_BUILD == 'true' }}
45-
uses: metamask/github-tools/.github/actions/checkout-and-setup@1299bb1de0c6974ae6d0a32c7e8897fe168239ac
45+
uses: MetaMask/action-checkout-and-setup@v1
4646
with:
4747
is-high-risk-environment: true
4848
ref: ${{ github.event.pull_request.head.sha || github.sha }}

0 commit comments

Comments
 (0)