Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DRAFT] ci: prep builds #30720

Open
wants to merge 48 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
d65e37d
ci: prep builds
makemesteaks Mar 4, 2025
01904bc
ci: add infura key
makemesteaks Mar 4, 2025
cf3a423
ci: add prep build flask and flask mv2, test master prepbuild
makemesteaks Mar 4, 2025
71548b8
ci: add missing keys
makemesteaks Mar 4, 2025
699ac04
ci: add remaining jobs
makemesteaks Mar 4, 2025
a87ee36
ci: test
makemesteaks Mar 4, 2025
cd4adef
ci: test ci prep build
makemesteaks Mar 4, 2025
4a27fc0
ci: comment to test
makemesteaks Mar 4, 2025
8090e6b
ci: dummy prod keys
makemesteaks Mar 4, 2025
1ecc382
ci: dummy flask keys
makemesteaks Mar 4, 2025
885aaf1
ci: missing migrating vars from circleci
makemesteaks Mar 4, 2025
cbf6191
ci: remove for now
makemesteaks Mar 4, 2025
5f9c625
ci: test vars
makemesteaks Mar 5, 2025
0fea6f5
ci: add real vars
makemesteaks Mar 5, 2025
7708a25
ci: test prod now
makemesteaks Mar 5, 2025
806cff1
ci: typo
makemesteaks Mar 5, 2025
5267957
ci: prep builds are working
makemesteaks Mar 5, 2025
4348e1f
ci: test e2e chrome webpack
makemesteaks Mar 5, 2025
61e8975
ci: run
makemesteaks Mar 5, 2025
a487869
ci: changed files script to gha
makemesteaks Mar 5, 2025
331a872
ci: pass token
makemesteaks Mar 5, 2025
c906dbe
ci: just warning
makemesteaks Mar 5, 2025
dda2899
ci: permission to run
makemesteaks Mar 5, 2025
2717008
ci: test e2e with updated chrome, and specific job for GHA
makemesteaks Mar 5, 2025
e04fa64
ci: pin chrome
makemesteaks Mar 5, 2025
1122ac3
ci: setup chrome path
makemesteaks Mar 5, 2025
f253931
ci: no sandbox
makemesteaks Mar 5, 2025
b6efae7
fixing sandbox
HowardBraham Mar 6, 2025
22a0b80
ci: add anvil
makemesteaks Mar 6, 2025
14c263d
ci: add anvil debug commands
makemesteaks Mar 6, 2025
7e12822
ci: simplify anvil
makemesteaks Mar 6, 2025
26ce0db
ci: permissions are not preserved
makemesteaks Mar 6, 2025
dc22abd
ci: remove duplicate foundry install test
makemesteaks Mar 6, 2025
8c05e3a
ci: try new docker image for e2e tests
makemesteaks Mar 6, 2025
4c6355b
ci: draft testing root
makemesteaks Mar 6, 2025
738bc0e
ci: sandbox gha
makemesteaks Mar 6, 2025
35dbd85
ci: install before cache
makemesteaks Mar 6, 2025
4be0921
ci: bad place
makemesteaks Mar 6, 2025
eb0ba85
ci: test just once
makemesteaks Mar 6, 2025
f5788c3
ci: xvfb and anvil
HowardBraham Mar 7, 2025
3d87238
fix: timeout
itsyoboieltr Mar 7, 2025
f6303c8
ci: updating chrome to work with benchmarks
makemesteaks Mar 7, 2025
4103edf
ci: typo
makemesteaks Mar 7, 2025
5a21082
ci: move foundry after checkout
makemesteaks Mar 7, 2025
0f52fd3
test
itsyoboieltr Mar 7, 2025
8c42f97
test 2
itsyoboieltr Mar 7, 2025
6ef5c38
ci: test-e2e-chrome
makemesteaks Mar 7, 2025
6e0012f
ci: added more e2e
makemesteaks Mar 8, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
171 changes: 171 additions & 0 deletions .github/scripts/git-diff-default-branch.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
import { exec as execCallback } from 'child_process';
import fs from 'fs';
import path from 'path';
import { promisify } from 'util';
import { context } from '@actions/github';
import * as core from '@actions/core';

const exec = promisify(execCallback);

// Get PR number from GitHub Actions environment variables
const PR_NUMBER = context.payload.pull_request?.number;

const GITHUB_DEFAULT_BRANCH = 'main';
const SOURCE_BRANCH = PR_NUMBER ? `refs/pull/${PR_NUMBER}/head` : '';

const CHANGED_FILES_DIR = 'changed-files';

type PRInfo = {
base: {
ref: string;
};
body: string;
labels: { name: string }[];
};

/**
* Get JSON info about the given pull request using Octokit
*
* @returns PR information from GitHub
*/
async function getPrInfo(): Promise<PRInfo | null> {
if (!PR_NUMBER) {
return null;
}

const { owner, repo } = context.repo;

const response = await fetch(
`https://api.github.com/repos/${owner}/${repo}/pulls/${PR_NUMBER}`,
{
headers: {
'Authorization': `token ${process.env.GITHUB_TOKEN}`,
'Accept': 'application/vnd.github.v3+json'
}
}
);

return await response.json();
}

/**
* Fetches the git repository with a specified depth.
*
* @param depth - The depth to use for the fetch command.
* @returns True if the fetch is successful, otherwise false.
*/
async function fetchWithDepth(depth: number): Promise<boolean> {
try {
await exec(`git fetch --depth ${depth} origin "${GITHUB_DEFAULT_BRANCH}"`);
if (SOURCE_BRANCH) {
await exec(
`git fetch --depth ${depth} origin "${SOURCE_BRANCH}:${SOURCE_BRANCH}"`,
);
}
return true;
} catch (error: unknown) {
core.warning(`Failed to fetch with depth ${depth}:`, error);
return false;
}
}

/**
* Attempts to fetch the necessary commits until the merge base is found.
* It tries different fetch depths and performs a full fetch if needed.
*
* @throws If an unexpected error occurs during the execution of git commands.
*/
async function fetchUntilMergeBaseFound() {
const depths = [1, 10, 100];
for (const depth of depths) {
core.info(`Attempting git diff with depth ${depth}...`);
await fetchWithDepth(depth);

try {
await exec(`git merge-base origin/${GITHUB_DEFAULT_BRANCH} HEAD`);
return;
} catch (error: unknown) {
if (error instanceof Error && 'code' in error) {
core.warning(
`Error 'no merge base' encountered with depth ${depth}. Incrementing depth...`,
);
} else {
throw error;
}
}
}
await exec(`git fetch --unshallow origin "${GITHUB_DEFAULT_BRANCH}"`);
}

/**
* Performs a git diff command to get the list of files changed between the current branch and the origin.
* It first ensures that the necessary commits are fetched until the merge base is found.
*
* @returns The output of the git diff command, listing the file paths with status (A, M, D).
* @throws If unable to get the diff after fetching the merge base or if an unexpected error occurs.
*/
async function gitDiff(): Promise<string> {
await fetchUntilMergeBaseFound();
const { stdout: diffResult } = await exec(
`git diff --name-status "origin/${GITHUB_DEFAULT_BRANCH}...${SOURCE_BRANCH || 'HEAD'}"`
);
if (!diffResult) {
throw new Error('Unable to get diff after full checkout.');
}
return diffResult;
}

function writePrBodyAndInfoToFile(prInfo: PRInfo) {
const prBodyPath = path.resolve(CHANGED_FILES_DIR, 'pr-body.txt');
const labels = prInfo.labels.map(label => label.name).join(', ');
const updatedPrBody = `PR labels: {${labels}}\nPR base: {${prInfo.base.ref}}\n${prInfo.body.trim()}`;
fs.writeFileSync(prBodyPath, updatedPrBody);

Check warning

Code scanning / CodeQL

Network data written to file Medium

Write to file system depends on
Untrusted data
.
core.info(`PR body and info saved to ${prBodyPath}`);
}

/**
* Main run function, stores the output of git diff and the body of the matching PR to a file.
*
* @returns Returns a promise that resolves when the git diff output and PR body is successfully stored.
*/
async function storeGitDiffOutputAndPrBody() {
try {
// Create the directory
fs.mkdirSync(CHANGED_FILES_DIR, { recursive: true });

core.info(`Determining whether to run git diff...`);
if (!PR_NUMBER) {
core.info('Not a PR, skipping git diff');
return;
}

const prInfo = await getPrInfo();

const baseRef = prInfo?.base.ref;
if (!baseRef) {
core.info('Not a PR, skipping git diff');
return;
}
// We perform git diff even if the PR base is not main or skip-e2e-quality-gate label is applied
// because we rely on the git diff results for other jobs
core.info('Attempting to get git diff...');
const diffOutput = await gitDiff();
core.info(diffOutput);

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

writePrBodyAndInfoToFile(prInfo);

core.info('success', 'true');
} catch (error: any) {
core.setFailed(`Failed to process git diff: ${error.message}`);
}
}

// If main module (i.e. this is the TS file that was run directly)
if (require.main === module) {
storeGitDiffOutputAndPrBody();
}
29 changes: 29 additions & 0 deletions .github/scripts/test-run-e2e-timeout-minutes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { filterE2eChangedFiles, readChangedAndNewFilesWithStatus, getChangedAndNewFiles } from '../../test/e2e/changedFilesUtil';

function computeTimeout(): number {
let timeout: number;

// Use the GitHub Action provided timeout if it exists
if (process.env.TIMEOUT) {
timeout = parseInt(process.env.TIMEOUT, 10);
} else {
// Calculate timeout based on changed files:
// Read the changed/new files and filter for e2e tests
const changedAndNewFilesWithStatus = readChangedAndNewFilesWithStatus();
const changedAndNewFiles = getChangedAndNewFiles(changedAndNewFilesWithStatus);
const changedOrNewTests = filterE2eChangedFiles(changedAndNewFiles);

// Base timeout of 20 minutes plus 3 minutes per changed file, capped at 30 minutes
timeout = Math.min(20 + changedOrNewTests.length * 3, 30);
}

// Optionally, adjust timeout for merge queue scenarios.
// For example, if the branch reference starts with 'refs/heads/gh-readonly-queue', add 10 minutes.
if (process.env.GITHUB_REF?.startsWith('refs/heads/gh-readonly-queue')) {
timeout += 10;
}

return timeout;
}

console.log(computeTimeout());
28 changes: 28 additions & 0 deletions .github/scripts/test-run-e2e.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#!/usr/bin/env bash

set -e
set -u
set -o pipefail

# Skip running e2e tests if the HEAD commit is tagged correctly
if git show --format='%B' --no-patch "$GITHUB_SHA" | grep --fixed-strings --quiet '[skip e2e]'
then
printf '%s\n' "$GITHUB_SHA contains the tag '[skip e2e]' so e2e tests will not run"
exit 1
fi

TIMEOUT_MINUTES=$(yarn tsx .github/scripts/test-run-e2e-timeout-minutes.ts)
echo "TIMEOUT_MINUTES: $TIMEOUT_MINUTES"

# Run the actual test command from the parameters
timeout "${TIMEOUT_MINUTES}"m "$@" --retries 1

# Error code 124 means the command timed out
if [ $? -eq 124 ]
then
echo 'Timeout error, deleting the test results'
rm -rf test/test-results/e2e
exit 124
fi

exit 0
2 changes: 1 addition & 1 deletion .github/scripts/validate-e2e-page-object-usage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
async function verifyE2ePageObjectsUsage(fileStatus: 'M' | 'A' | 'both') {
let e2eFiles: string[];

if (process.env.GITHUB_ACTIONS) {
if (process.env.GITHUB_ACTION) {
// Running in Github Actions
const branch = process.env.BRANCH || '';
const headCommitHash = process.env.HEAD_COMMIT_HASH || '';
Expand Down
Loading
Loading