Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin' into merge-master-into-v12.5.0
Browse files Browse the repository at this point in the history
  • Loading branch information
hjetpoluru committed Oct 11, 2024
2 parents 0736532 + 05dda70 commit 12215b9
Show file tree
Hide file tree
Showing 738 changed files with 26,435 additions and 13,540 deletions.
14 changes: 5 additions & 9 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -118,11 +118,9 @@ workflows:
- prep-deps
- get-changed-files-with-git-diff:
filters:
branches:
ignore:
- master
requires:
- prep-deps
branches:
ignore:
- master
- test-deps-audit:
requires:
- prep-deps
Expand Down Expand Up @@ -360,11 +358,10 @@ workflows:
value: << pipeline.git.branch >>
jobs:
- prep-deps
- get-changed-files-with-git-diff:
requires:
- prep-deps
- get-changed-files-with-git-diff
- validate-locales-only:
requires:
- prep-deps
- get-changed-files-with-git-diff
- test-lint:
requires:
Expand Down Expand Up @@ -501,7 +498,6 @@ jobs:
- run: sudo corepack enable
- attach_workspace:
at: .
- gh/install
- run:
name: Get changed files with git diff
command: npx tsx .circleci/scripts/git-diff-develop.ts
Expand Down
101 changes: 64 additions & 37 deletions .circleci/scripts/git-diff-develop.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,42 @@
import { hasProperty } from '@metamask/utils';
import { exec as execCallback } from 'child_process';
import fs from 'fs';
import path from 'path';
import { promisify } from 'util';

const exec = promisify(execCallback);

// The CIRCLE_PR_NUMBER variable is only available on forked Pull Requests
const PR_NUMBER =
process.env.CIRCLE_PR_NUMBER ||
process.env.CIRCLE_PULL_REQUEST?.split('/').pop();

const MAIN_BRANCH = 'develop';
const SOURCE_BRANCH = `refs/pull/${PR_NUMBER}/head`;

const CHANGED_FILES_DIR = 'changed-files';

type PRInfo = {
base: {
ref: string;
};
body: string;
};

/**
* Get the target branch for the given pull request.
* Get JSON info about the given pull request
*
* @returns The name of the branch targeted by the PR.
* @returns JSON info from GitHub
*/
async function getBaseRef(): Promise<string | null> {
if (!process.env.CIRCLE_PULL_REQUEST) {
async function getPrInfo(): Promise<PRInfo | null> {
if (!PR_NUMBER) {
return null;
}

// We're referencing the CIRCLE_PULL_REQUEST environment variable within the script rather than
// passing it in because this makes it easier to use Bash parameter expansion to extract the
// PR number from the URL.
const result = await exec(`gh pr view --json baseRefName "\${CIRCLE_PULL_REQUEST##*/}" --jq '.baseRefName'`);
const baseRef = result.stdout.trim();
return baseRef;
return await (
await fetch(
`https://api.github.com/repos/${process.env.CIRCLE_PROJECT_USERNAME}/${process.env.CIRCLE_PROJECT_REPONAME}/pulls/${PR_NUMBER}`,
)
).json();
}

/**
Expand All @@ -34,8 +47,10 @@ async function getBaseRef(): Promise<string | null> {
*/
async function fetchWithDepth(depth: number): Promise<boolean> {
try {
await exec(`git fetch --depth ${depth} origin develop`);
await exec(`git fetch --depth ${depth} origin ${process.env.CIRCLE_BRANCH}`);
await exec(`git fetch --depth ${depth} origin "${MAIN_BRANCH}"`);
await exec(
`git fetch --depth ${depth} origin "${SOURCE_BRANCH}:${SOURCE_BRANCH}"`,
);
return true;
} catch (error: unknown) {
console.error(`Failed to fetch with depth ${depth}:`, error);
Expand All @@ -59,18 +74,16 @@ async function fetchUntilMergeBaseFound() {
await exec(`git merge-base origin/HEAD HEAD`);
return;
} catch (error: unknown) {
if (
error instanceof Error &&
hasProperty(error, 'code') &&
error.code === 1
) {
console.error(`Error 'no merge base' encountered with depth ${depth}. Incrementing depth...`);
if (error instanceof Error && 'code' in error) {
console.error(
`Error 'no merge base' encountered with depth ${depth}. Incrementing depth...`,
);
} else {
throw error;
}
}
}
await exec(`git fetch --unshallow origin develop`);
await exec(`git fetch --unshallow origin "${MAIN_BRANCH}"`);
}

/**
Expand All @@ -82,55 +95,69 @@ async function fetchUntilMergeBaseFound() {
*/
async function gitDiff(): Promise<string> {
await fetchUntilMergeBaseFound();
const { stdout: diffResult } = await exec(`git diff --name-only origin/HEAD...${process.env.CIRCLE_BRANCH}`);
const { stdout: diffResult } = await exec(
`git diff --name-only "origin/HEAD...${SOURCE_BRANCH}"`,
);
if (!diffResult) {
throw new Error('Unable to get diff after full checkout.');
throw new Error('Unable to get diff after full checkout.');
}
return diffResult;
}

function writePrBodyToFile(prBody: string) {
const prBodyPath = path.resolve(CHANGED_FILES_DIR, 'pr-body.txt');
fs.writeFileSync(prBodyPath, prBody.trim());
console.log(`PR body saved to ${prBodyPath}`);
}

/**
* Stores the output of git diff to a file.
* 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 is successfully stored.
* @returns Returns a promise that resolves when the git diff output and PR body is successfully stored.
*/
async function storeGitDiffOutput() {
async function storeGitDiffOutputAndPrBody() {
try {
// Create the directory
// This is done first because our CirleCI config requires that this directory is present,
// even if we want to skip this step.
const outputDir = 'changed-files';
fs.mkdirSync(outputDir, { recursive: true });
fs.mkdirSync(CHANGED_FILES_DIR, { recursive: true });

console.log(`Determining whether this run is for a PR targetting ${MAIN_BRANCH}`)
if (!process.env.CIRCLE_PULL_REQUEST) {
console.log("Not a PR, skipping git diff");
console.log(
`Determining whether this run is for a PR targeting ${MAIN_BRANCH}`,
);
if (!PR_NUMBER) {
console.log('Not a PR, skipping git diff');
return;
}

const baseRef = await getBaseRef();
if (baseRef === null) {
console.log("Not a PR, skipping git diff");
const prInfo = await getPrInfo();

const baseRef = prInfo?.base.ref;
if (!baseRef) {
console.log('Not a PR, skipping git diff');
return;
} else if (baseRef !== MAIN_BRANCH) {
console.log(`This is for a PR targeting '${baseRef}', skipping git diff`);
writePrBodyToFile(prInfo.body);
return;
}

console.log("Attempting to get git diff...");
console.log('Attempting to get git diff...');
const diffOutput = await gitDiff();
console.log(diffOutput);

// Store the output of git diff
const outputPath = path.resolve(outputDir, 'changed-files.txt');
const outputPath = path.resolve(CHANGED_FILES_DIR, 'changed-files.txt');
fs.writeFileSync(outputPath, diffOutput.trim());

console.log(`Git diff results saved to ${outputPath}`);

writePrBodyToFile(prInfo.body);

process.exit(0);
} catch (error: any) {
console.error('An error occurred:', error.message);
process.exit(1);
}
}

storeGitDiffOutput();
storeGitDiffOutputAndPrBody();
26 changes: 24 additions & 2 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,15 @@ name: Main

on:
push:
branches: [develop, master]
branches:
- develop
- master
pull_request:
types:
- opened
- reopened
- synchronize
merge_group:

jobs:
check-workflows:
Expand All @@ -21,11 +28,25 @@ jobs:
run: ${{ steps.download-actionlint.outputs.executable }} -color
shell: bash

run-tests:
name: Run tests
uses: ./.github/workflows/run-tests.yml

sonarcloud:
name: SonarCloud
uses: ./.github/workflows/sonarcloud.yml
secrets:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
needs:
- run-tests

all-jobs-completed:
name: All jobs completed
runs-on: ubuntu-latest
needs:
- check-workflows
- run-tests
- sonarcloud
outputs:
PASSED: ${{ steps.set-output.outputs.PASSED }}
steps:
Expand All @@ -37,7 +58,8 @@ jobs:
name: All jobs pass
if: ${{ always() }}
runs-on: ubuntu-latest
needs: all-jobs-completed
needs:
- all-jobs-completed
steps:
- name: Check that all jobs have passed
run: |
Expand Down
67 changes: 30 additions & 37 deletions .github/workflows/run-tests.yml
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
name: Run tests

on:
push:
branches:
- develop
- master
pull_request:
types:
- opened
- reopened
- synchronize
workflow_call:
outputs:
current-coverage:
description: Current coverage
value: ${{ jobs.report-coverage.outputs.current-coverage }}
stored-coverage:
description: Stored coverage
value: ${{ jobs.report-coverage.outputs.stored-coverage }}

jobs:
test-unit:
Expand Down Expand Up @@ -78,18 +77,19 @@ jobs:
name: coverage-integration
path: coverage/integration/coverage-integration.json

sonarcloud:
name: SonarCloud
report-coverage:
name: Report coverage
runs-on: ubuntu-latest
needs:
- test-unit
- test-webpack
- test-integration
outputs:
current-coverage: ${{ steps.get-current-coverage.outputs.CURRENT_COVERAGE }}
stored-coverage: ${{ steps.get-stored-coverage.outputs.STORED_COVERAGE }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0 # Shallow clones should be disabled for better relevancy of analysis

- name: Setup environment
uses: metamask/github-tools/.github/actions/setup-environment@main
Expand All @@ -108,35 +108,28 @@ jobs:
name: lcov.info
path: coverage/lcov.info

- name: Get Sonar coverage
id: get-sonar-coverage
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
- name: Get current coverage
id: get-current-coverage
run: |
current_coverage=$(yarn nyc report --reporter=text-summary | grep 'Lines' | awk '{gsub(/%/, ""); print int($3)}')
echo "The current coverage is $current_coverage%."
echo 'CURRENT_COVERAGE='"$current_coverage" >> "$GITHUB_OUTPUT"
- name: Get stored coverage
id: get-stored-coverage
run: |
projectKey=$(grep 'sonar.projectKey=' sonar-project.properties | cut -d'=' -f2)
sonar_coverage=$(curl --silent --header "Authorization: Bearer $SONAR_TOKEN" "https://sonarcloud.io/api/measures/component?component=$projectKey&metricKeys=coverage" | jq -r '.component.measures[0].value // 0')
echo "The Sonar coverage of $projectKey is $sonar_coverage%."
echo 'SONAR_COVERAGE='"$sonar_coverage" >> "$GITHUB_OUTPUT"
stored_coverage=$(jq ".coverage" coverage.json)
echo "The stored coverage is $stored_coverage%."
echo 'STORED_COVERAGE='"$stored_coverage" >> "$GITHUB_OUTPUT"
- name: Validate test coverage
env:
SONAR_COVERAGE: ${{ steps.get-sonar-coverage.outputs.SONAR_COVERAGE }}
CURRENT_COVERAGE: ${{ steps.get-current-coverage.outputs.CURRENT_COVERAGE }}
STORED_COVERAGE: ${{ steps.get-stored-coverage.outputs.STORED_COVERAGE }}
run: |
coverage=$(yarn nyc report --reporter=text-summary | grep 'Lines' | awk '{gsub(/%/, ""); print $3}')
if [ -z "$coverage" ]; then
echo "::error::Could not retrieve test coverage."
exit 1
fi
if (( $(echo "$coverage < $SONAR_COVERAGE" | bc -l) )); then
echo "::error::Quality gate failed for test coverage. Current test coverage is $coverage%, please increase coverage to at least $SONAR_COVERAGE%."
if (( $(echo "$CURRENT_COVERAGE < $STORED_COVERAGE" | bc -l) )); then
echo "::error::Quality gate failed for test coverage. Current coverage is $CURRENT_COVERAGE%, please increase coverage to at least $STORED_COVERAGE%."
exit 1
else
echo "Test coverage is $coverage%. Quality gate passed."
echo "The current coverage is $CURRENT_COVERAGE%, stored coverage is $STORED_COVERAGE%. Quality gate passed."
fi
- name: SonarCloud Scan
# This is SonarSource/[email protected]
uses: SonarSource/sonarcloud-github-action@4b4d7634dab97dcee0b75763a54a6dc92a9e6bc1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
30 changes: 30 additions & 0 deletions .github/workflows/sonarcloud.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: SonarCloud

on:
workflow_call:
secrets:
SONAR_TOKEN:
required: true

jobs:
sonarcloud:
name: SonarCloud
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0 # Shallow clones should be disabled for better relevancy of analysis

- name: Download artifacts
uses: actions/download-artifact@v4
with:
name: lcov.info
path: coverage

- name: SonarCloud Scan
# This is SonarSource/[email protected]
uses: SonarSource/sonarcloud-github-action@4b4d7634dab97dcee0b75763a54a6dc92a9e6bc1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
Loading

0 comments on commit 12215b9

Please sign in to comment.