diff --git a/.circleci/config.yml b/.circleci/config.yml index 60bb80eaf449..61493189a8b6 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1426,14 +1426,6 @@ jobs: - store_artifacts: path: development/ts-migration-dashboard/build/final destination: ts-migration-dashboard - - run: - name: Set branch parent commit env var - command: | - echo "export PARENT_COMMIT=$(git merge-base origin/HEAD HEAD)" >> $BASH_ENV - source $BASH_ENV - - run: - name: build:announce - command: ./development/metamaskbot-build-announce.js job-publish-release: executor: node-browsers-small diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index ee29c54e94ac..2b64d6379825 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -64,6 +64,15 @@ jobs: name: Wait for CircleCI workflow status uses: ./.github/workflows/wait-for-circleci-workflow-status.yml + publish-prerelease: + name: Publish prerelease + if: ${{ github.event_name == 'pull_request' }} + needs: + - wait-for-circleci-workflow-status + uses: ./.github/workflows/publish-prerelease.yml + secrets: + PR_COMMENT_TOKEN: ${{ secrets.PR_COMMENT_TOKEN }} + all-jobs-completed: name: All jobs completed runs-on: ubuntu-latest diff --git a/.github/workflows/publish-prerelease.yml b/.github/workflows/publish-prerelease.yml new file mode 100644 index 000000000000..9b4e460d546a --- /dev/null +++ b/.github/workflows/publish-prerelease.yml @@ -0,0 +1,72 @@ +name: Publish prerelease + +on: + workflow_call: + secrets: + PR_COMMENT_TOKEN: + required: true + +jobs: + publish-prerelease: + name: Publish prerelease + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 # This is needed to get merge base to calculate bundle size diff + + - name: Setup environment + uses: metamask/github-tools/.github/actions/setup-environment@main + + - name: Get merge base commit hash + id: get-merge-base + env: + BASE_REF: ${{ github.event.pull_request.base.ref }} + run: | + merge_base="$(git merge-base "origin/${BASE_REF}" HEAD)" + echo "Merge base is '${merge_base}'" + echo "MERGE_BASE=${merge_base}" >> "$GITHUB_OUTPUT" + + - name: Get CircleCI job details + id: get-circleci-job-details + env: + REPOSITORY: ${{ github.repository }} + BRANCH: ${{ github.head_ref }} + HEAD_COMMIT_HASH: ${{ github.event.pull_request.head.sha }} + run: | + pipeline_id=$(curl --silent "https://circleci.com/api/v2/project/gh/$OWNER/$REPOSITORY/pipeline?branch=$BRANCH" | jq -r ".items | map(select(.vcs.revision == \"${HEAD_COMMIT_HASH}\" )) | first | .id") + workflow_id=$(curl --silent "https://circleci.com/api/v2/pipeline/$pipeline_id/workflow" | jq -r ".items[0].id") + job_details=$(curl --silent "https://circleci.com/api/v2/workflow/$workflow_id/job" | jq -r '.items[] | select(.name == "job-publish-prerelease")') + build_num=$(echo "$job_details" | jq -r '.job_number') + + echo 'CIRCLE_BUILD_NUM='"$build_num" >> "$GITHUB_OUTPUT" + job_id=$(echo "$job_details" | jq -r '.id') + echo 'CIRCLE_WORKFLOW_JOB_ID='"$job_id" >> "$GITHUB_OUTPUT" + + echo "Getting artifacts from pipeline '${pipeline_id}', workflow '${workflow_id}', build number '${build_num}', job ID '${job_id}'" + + - name: Get CircleCI job artifacts + env: + CIRCLE_WORKFLOW_JOB_ID: ${{ steps.get-circleci-job-details.outputs.CIRCLE_WORKFLOW_JOB_ID }} + run: | + mkdir -p "test-artifacts/chrome/benchmark" + curl --silent --location "https://output.circle-artifacts.com/output/job/${CIRCLE_WORKFLOW_JOB_ID}/artifacts/0/test-artifacts/chrome/benchmark/pageload.json" > "test-artifacts/chrome/benchmark/pageload.json" + + bundle_size=$(curl --silent --location "https://output.circle-artifacts.com/output/job/${CIRCLE_WORKFLOW_JOB_ID}/artifacts/0/test-artifacts/chrome/bundle_size.json") + mkdir -p "test-artifacts/chrome" + echo "${bundle_size}" > "test-artifacts/chrome/bundle_size.json" + + stories=$(curl --silent --location "https://output.circle-artifacts.com/output/job/${CIRCLE_WORKFLOW_JOB_ID}/artifacts/0/storybook/stories.json") + mkdir "storybook-build" + echo "${stories}" > "storybook-build/stories.json" + + - name: Publish prerelease + env: + PR_COMMENT_TOKEN: ${{ secrets.PR_COMMENT_TOKEN }} + PR_NUMBER: ${{ github.event.pull_request.number }} + HEAD_COMMIT_HASH: ${{ github.event.pull_request.head.sha }} + MERGE_BASE_COMMIT_HASH: ${{ steps.get-merge-base.outputs.MERGE_BASE }} + CIRCLE_BUILD_NUM: ${{ steps.get-circleci-job-details.outputs.CIRCLE_BUILD_NUM }} + CIRCLE_WORKFLOW_JOB_ID: ${{ steps.get-circleci-job-details.outputs.CIRCLE_WORKFLOW_JOB_ID }} + run: ./development/metamaskbot-build-announce.js diff --git a/development/highlights/index.js b/development/highlights/index.js index 2616d602633e..9efd3073d031 100644 --- a/development/highlights/index.js +++ b/development/highlights/index.js @@ -9,7 +9,7 @@ async function getHighlights({ artifactBase }) { // here we assume the PR base branch ("target") is `main` in lieu of doing // a query against the github api which requires an access token // see https://discuss.circleci.com/t/how-to-retrieve-a-pull-requests-base-branch-name-github/36911 - const changedFiles = await getChangedFiles({ target: 'main' }); + const changedFiles = await getChangedFiles({ target: 'origin/main' }); console.log(`detected changed files vs main:`); for (const filename of changedFiles) { console.log(` ${filename}`); diff --git a/development/metamaskbot-build-announce.js b/development/metamaskbot-build-announce.js index f85d64faa887..d449c8ce7259 100755 --- a/development/metamaskbot-build-announce.js +++ b/development/metamaskbot-build-announce.js @@ -5,7 +5,6 @@ const path = require('path'); // Fetch is part of node js in future versions, thus triggering no-shadow // eslint-disable-next-line no-shadow const fetch = require('node-fetch'); -const glob = require('fast-glob'); const VERSION = require('../package.json').version; const { getHighlights } = require('./highlights'); @@ -38,29 +37,41 @@ function getPercentageChange(from, to) { return parseFloat(((to - from) / Math.abs(from)) * 100).toFixed(2); } +/** + * Check whether an artifact exists, + * + * @param {string} url - The URL of the artifact to check. + * @returns True if the artifact exists, false if it doesn't + */ +async function artifactExists(url) { + // Using a regular GET request here rather than HEAD because for some reason CircleCI always + // returns 404 for HEAD requests. + const response = await fetch(url); + return response.ok; +} + async function start() { const { - GITHUB_COMMENT_TOKEN, - CIRCLE_PULL_REQUEST, - CIRCLE_SHA1, + PR_COMMENT_TOKEN, + PR_NUMBER, + HEAD_COMMIT_HASH, + MERGE_BASE_COMMIT_HASH, CIRCLE_BUILD_NUM, CIRCLE_WORKFLOW_JOB_ID, - PARENT_COMMIT, } = process.env; - console.log('CIRCLE_PULL_REQUEST', CIRCLE_PULL_REQUEST); - console.log('CIRCLE_SHA1', CIRCLE_SHA1); + console.log('PR_NUMBER', PR_NUMBER); + console.log('HEAD_COMMIT_HASH', HEAD_COMMIT_HASH); + console.log('MERGE_BASE_COMMIT_HASH', MERGE_BASE_COMMIT_HASH); console.log('CIRCLE_BUILD_NUM', CIRCLE_BUILD_NUM); console.log('CIRCLE_WORKFLOW_JOB_ID', CIRCLE_WORKFLOW_JOB_ID); - console.log('PARENT_COMMIT', PARENT_COMMIT); - if (!CIRCLE_PULL_REQUEST) { - console.warn(`No pull request detected for commit "${CIRCLE_SHA1}"`); + if (!PR_NUMBER) { + console.warn(`No pull request detected for commit "${HEAD_COMMIT_HASH}"`); return; } - const CIRCLE_PR_NUMBER = CIRCLE_PULL_REQUEST.split('/').pop(); - const SHORT_SHA1 = CIRCLE_SHA1.slice(0, 7); + const SHORT_SHA1 = HEAD_COMMIT_HASH.slice(0, 7); const BUILD_LINK_BASE = `https://output.circle-artifacts.com/output/job/${CIRCLE_WORKFLOW_JOB_ID}/artifacts/0`; // build the github comment content @@ -112,30 +123,30 @@ async function start() { // links to bundle browser builds const bundles = {}; - const fileType = '.html'; const sourceMapRoot = '/build-artifacts/source-map-explorer/'; - const bundleFiles = await glob(`.${sourceMapRoot}*${fileType}`); - - bundleFiles.forEach((bundleFile) => { - const fileName = bundleFile.split(sourceMapRoot)[1]; - const bundleName = fileName.split(fileType)[0]; - const url = `${BUILD_LINK_BASE}${sourceMapRoot}${fileName}`; - let fileRoot = bundleName; - let fileIndex = bundleName.match(/-[0-9]{1,}$/u)?.index; - - if (fileIndex) { - fileRoot = bundleName.slice(0, fileIndex); - fileIndex = bundleName.slice(fileIndex + 1, bundleName.length); - } - - const link = `${fileIndex || fileRoot}`; + const fileRoots = [ + 'background', + 'common', + 'ui', + 'content-script', + 'offscreen', + ]; - if (fileRoot in bundles) { + for (const fileRoot of fileRoots) { + bundles[fileRoot] = []; + let fileIndex = 0; + let url = `${BUILD_LINK_BASE}${sourceMapRoot}${fileRoot}-${fileIndex}.html`; + console.log(`Verifying ${url}`); + while (await artifactExists(url)) { + const link = `${fileIndex}`; bundles[fileRoot].push(link); - } else { - bundles[fileRoot] = [link]; + + fileIndex += 1; + url = `${BUILD_LINK_BASE}${sourceMapRoot}${fileRoot}-${fileIndex}.html`; + console.log(`Verifying ${url}`); } - }); + console.log(`Not found: ${url}`); + } const bundleMarkup = `