Main #11
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Main | |
| on: | |
| push: | |
| branches: | |
| - main | |
| - stable | |
| - release/* | |
| - trigger-ci-* | |
| pull_request: | |
| types: | |
| - opened | |
| - reopened | |
| - synchronize | |
| branches-ignore: | |
| - stable | |
| merge_group: | |
| schedule: | |
| # Run the full suite "overnight," once every hour from 2:00am UTC until 5:59am UTC. | |
| # This helps with "Top 10 failed tests on the metamask-extension repository main branch," | |
| # especially the Monday morning list, which is otherwise usually a fake empty. | |
| - cron: '0 2-6 * * *' | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref == 'refs/heads/main' && github.sha || github.ref }} | |
| cancel-in-progress: ${{ !(contains(github.ref, 'refs/heads/main') || contains(github.ref, 'refs/heads/stable')) }} | |
| env: | |
| # For a `pull_request` event, the branch is `github.head_ref``. | |
| # For a `push` event, the branch is `github.ref_name`. | |
| BRANCH: ${{ github.head_ref || github.ref_name }} | |
| # For a `pull_request` event, the fork is `github.event.pull_request.head.repo.fork`. | |
| # For a `push` event, the fork is `github.event.repository.fork`. | |
| IS_FORK: ${{ github.event.pull_request.head.repo.fork || github.event.repository.fork }} | |
| # For a `pull_request` event, the head commit hash is `github.event.pull_request.head.sha`. | |
| # For a `push` event, the head commit hash is `github.sha`. | |
| HEAD_COMMIT_HASH: ${{ github.event.pull_request.head.sha || github.sha }} | |
| permissions: | |
| contents: write # required for releases | |
| id-token: write # required for s3 uploads | |
| jobs: | |
| get-requirements: | |
| name: Get workflow and job requirements | |
| uses: ./.github/workflows/get-requirements.yml | |
| locales-changed-only: | |
| name: Locales changed only checks | |
| needs: | |
| - get-requirements | |
| if: ${{ needs.get-requirements.outputs.needs-locales == 'true' }} | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 30 | |
| steps: | |
| - name: Checkout and setup environment | |
| uses: MetaMask/action-checkout-and-setup@v3 | |
| with: | |
| is-high-risk-environment: false | |
| skip-allow-scripts: true | |
| - name: lint:prettier (for json,md,mdx,yml files) | |
| run: yarn lint:prettier | |
| - name: Verify locales | |
| run: yarn verify-locales --quiet | |
| prep-deps: | |
| name: Prepare dependencies | |
| if: ${{ needs.get-requirements.outputs.skip-everything != 'true' }} | |
| runs-on: ubuntu-latest | |
| needs: | |
| - get-requirements | |
| timeout-minutes: 30 | |
| steps: | |
| - name: Checkout and setup environment | |
| uses: MetaMask/action-checkout-and-setup@v3 | |
| id: checkout-and-setup | |
| with: | |
| is-high-risk-environment: false | |
| cache-node-modules: true | |
| skip-allow-scripts: true | |
| # Need to cache `.metamask` folder for the anvil binary | |
| - name: Cache .metamask folder | |
| if: ${{ steps.checkout-and-setup.outputs.node-modules-cache-hit != 'true' }} | |
| uses: actions/cache/save@v5 | |
| with: | |
| path: .metamask | |
| key: .metamask-${{ hashFiles('yarn.lock') }} | |
| lint-workflows: | |
| name: Lint workflows | |
| if: ${{ needs.get-requirements.outputs.skip-everything != 'true' }} | |
| needs: | |
| - get-requirements | |
| uses: MetaMask/github-tools/.github/workflows/lint-workflows.yml@v1 | |
| test-lint: | |
| name: Test lint | |
| if: ${{ needs.get-requirements.outputs.needs-lint == 'true' }} | |
| needs: | |
| - prep-deps | |
| - get-requirements | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 30 | |
| steps: | |
| - name: Checkout and setup environment | |
| uses: MetaMask/action-checkout-and-setup@v3 | |
| with: | |
| is-high-risk-environment: false | |
| skip-allow-scripts: true | |
| - name: Lint | |
| run: yarn lint | |
| - name: Verify locales | |
| run: yarn verify-locales --quiet | |
| - name: Check circular dependencies | |
| run: yarn circular-deps:check | |
| repository-health-checks: | |
| needs: | |
| - get-requirements | |
| - prep-deps | |
| if: ${{ needs.get-requirements.outputs.skip-everything != 'true' }} | |
| uses: ./.github/workflows/repository-health-checks.yml | |
| test-storybook: | |
| name: Test storybook | |
| needs: | |
| - get-requirements | |
| - prep-deps | |
| if: ${{ needs.get-requirements.outputs.skip-everything != 'true' }} | |
| uses: ./.github/workflows/test-storybook.yml | |
| validate-lavamoat-policies: | |
| needs: | |
| - get-requirements | |
| - prep-deps | |
| if: ${{ needs.get-requirements.outputs.skip-everything != 'true' }} | |
| uses: ./.github/workflows/validate-lavamoat-policies.yml | |
| build-dist-browserify: | |
| needs: | |
| - get-requirements | |
| if: ${{ needs.get-requirements.outputs.skip-everything != 'true' }} | |
| uses: ./.github/workflows/run-build.yml | |
| with: | |
| build-name: build-dist-browserify | |
| build-command: ${{ (github.head_ref || github.ref_name) == 'stable' && 'yarn build prod' || 'yarn build dist' }} | |
| builds-from-run: ${{ needs.get-requirements.outputs.builds-from-run }} | |
| secrets: inherit | |
| build-dist-mv2-browserify: | |
| needs: | |
| - get-requirements | |
| if: ${{ needs.get-requirements.outputs.skip-everything != 'true' }} | |
| uses: ./.github/workflows/run-build.yml | |
| with: | |
| build-name: build-dist-mv2-browserify | |
| build-command: ${{ (github.head_ref || github.ref_name) == 'stable' && 'yarn build prod' || 'yarn build dist' }} | |
| mozilla-lint: true | |
| enable-mv3: false | |
| builds-from-run: ${{ needs.get-requirements.outputs.builds-from-run }} | |
| secrets: inherit | |
| build-beta-browserify: | |
| needs: | |
| - get-requirements | |
| if: ${{ needs.get-requirements.outputs.skip-everything != 'true' }} | |
| uses: ./.github/workflows/run-build.yml | |
| with: | |
| build-name: build-beta-browserify | |
| build-command: yarn build --build-type beta dist | |
| builds-from-run: ${{ needs.get-requirements.outputs.builds-from-run }} | |
| secrets: inherit | |
| build-beta-mv2-browserify: | |
| needs: | |
| - get-requirements | |
| if: ${{ needs.get-requirements.outputs.skip-everything != 'true' }} | |
| uses: ./.github/workflows/run-build.yml | |
| with: | |
| build-name: build-beta-mv2-browserify | |
| build-command: yarn build --build-type beta dist | |
| mozilla-lint: false # Disabled as it is failing for some reason | |
| enable-mv3: false | |
| builds-from-run: ${{ needs.get-requirements.outputs.builds-from-run }} | |
| secrets: inherit | |
| build-flask-browserify: | |
| needs: | |
| - get-requirements | |
| if: ${{ needs.get-requirements.outputs.skip-everything != 'true' }} | |
| uses: ./.github/workflows/run-build.yml | |
| with: | |
| build-name: build-flask-browserify | |
| build-command: ${{ (github.head_ref || github.ref_name) == 'stable' && 'yarn build --build-type flask prod' || 'yarn build --build-type flask dist' }} | |
| builds-from-run: ${{ needs.get-requirements.outputs.builds-from-run }} | |
| secrets: inherit | |
| build-flask-mv2-browserify: | |
| needs: | |
| - get-requirements | |
| if: ${{ needs.get-requirements.outputs.skip-everything != 'true' }} | |
| uses: ./.github/workflows/run-build.yml | |
| with: | |
| build-name: build-flask-mv2-browserify | |
| build-command: ${{ (github.head_ref || github.ref_name) == 'stable' && 'yarn build --build-type flask prod' || 'yarn build --build-type flask dist' }} | |
| mozilla-lint: true | |
| enable-mv3: false | |
| builds-from-run: ${{ needs.get-requirements.outputs.builds-from-run }} | |
| secrets: inherit | |
| build-test-browserify: | |
| needs: | |
| - get-requirements | |
| if: ${{ needs.get-requirements.outputs.skip-everything != 'true' }} | |
| uses: ./.github/workflows/run-build.yml | |
| with: | |
| build-name: build-test-browserify | |
| build-command: yarn build:test | |
| builds-from-run: ${{ needs.get-requirements.outputs.builds-from-run }} | |
| secrets: inherit | |
| build-test-mv2-browserify: | |
| needs: | |
| - get-requirements | |
| if: ${{ needs.get-requirements.outputs.skip-everything != 'true' }} | |
| uses: ./.github/workflows/run-build.yml | |
| with: | |
| build-name: build-test-mv2-browserify | |
| build-command: yarn build:test:mv2 | |
| mozilla-lint: false # Disabled as it is failing for some reason | |
| enable-mv3: false | |
| builds-from-run: ${{ needs.get-requirements.outputs.builds-from-run }} | |
| secrets: inherit | |
| build-test-flask-browserify: | |
| needs: | |
| - get-requirements | |
| if: ${{ needs.get-requirements.outputs.skip-everything != 'true' }} | |
| uses: ./.github/workflows/run-build.yml | |
| with: | |
| build-name: build-test-flask-browserify | |
| build-command: yarn build:test:flask | |
| builds-from-run: ${{ needs.get-requirements.outputs.builds-from-run }} | |
| secrets: inherit | |
| build-test-flask-mv2-browserify: | |
| needs: | |
| - get-requirements | |
| if: ${{ needs.get-requirements.outputs.skip-everything != 'true' }} | |
| uses: ./.github/workflows/run-build.yml | |
| with: | |
| build-name: build-test-flask-mv2-browserify | |
| build-command: yarn build:test:flask:mv2 | |
| mozilla-lint: false # Disabled as it is failing for some reason | |
| enable-mv3: false | |
| builds-from-run: ${{ needs.get-requirements.outputs.builds-from-run }} | |
| secrets: inherit | |
| build-test-webpack: | |
| needs: | |
| - get-requirements | |
| if: ${{ needs.get-requirements.outputs.skip-everything != 'true' }} | |
| uses: ./.github/workflows/run-build.yml | |
| with: | |
| build-name: build-test-webpack | |
| build-command: yarn build:test:webpack | |
| validate-source-maps: false # Disabled as webpack outputs are not supported by validate-source-maps | |
| builds-from-run: ${{ needs.get-requirements.outputs.builds-from-run }} | |
| secrets: inherit | |
| build-test-mv2-webpack: | |
| needs: | |
| - get-requirements | |
| if: ${{ needs.get-requirements.outputs.skip-everything != 'true' }} | |
| uses: ./.github/workflows/run-build.yml | |
| with: | |
| build-name: build-test-mv2-webpack | |
| build-command: yarn build:test:webpack:mv2 | |
| validate-source-maps: false # Disabled as webpack outputs are not supported by validate-source-maps | |
| builds-from-run: ${{ needs.get-requirements.outputs.builds-from-run }} | |
| secrets: inherit | |
| run-benchmarks: | |
| if: ${{ needs.get-requirements.outputs.needs-benchmarks == 'true' }} | |
| uses: ./.github/workflows/run-benchmarks.yml | |
| needs: | |
| - get-requirements | |
| - prep-deps | |
| - build-test-browserify | |
| - build-test-mv2-browserify | |
| - build-test-webpack | |
| - build-test-mv2-webpack | |
| with: | |
| builds-from-run: ${{ needs.get-requirements.outputs.builds-from-run }} | |
| secrets: | |
| INFURA_PROJECT_ID: ${{ secrets.INFURA_PROJECT_ID }} | |
| TEST_SRP_2: ${{ secrets.TEST_SRP_2 }} | |
| run-tests: | |
| name: Run tests | |
| needs: | |
| - get-requirements | |
| - prep-deps | |
| if: ${{ needs.get-requirements.outputs.needs-unit-and-integration == 'true' }} | |
| uses: ./.github/workflows/run-tests.yml | |
| sonarcloud: | |
| name: SonarCloud | |
| needs: | |
| - run-tests | |
| if: >- | |
| ${{ | |
| !cancelled() && | |
| (github.event_name == 'pull_request' || (github.event_name == 'push' && github.ref_name == 'main')) && | |
| needs.run-tests.result == 'success' && | |
| !(github.event.pull_request.head.repo.fork || github.event.repository.fork) | |
| }} | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 30 | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| - name: Download coverage artifact | |
| uses: actions/download-artifact@v7 | |
| with: | |
| name: lcov.info | |
| path: coverage | |
| - name: SonarCloud Scan | |
| # This is SonarSource/sonarqube-scan-action@v7.0.0 | |
| uses: SonarSource/sonarqube-scan-action@a31c9398be7ace6bbfaf30c0bd5d415f843d45e9 | |
| env: | |
| SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} | |
| bundle-size: | |
| needs: | |
| - get-requirements | |
| - build-dist-browserify | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 30 | |
| env: | |
| EXTENSION_BUNDLESIZE_STATS_TOKEN: ${{ secrets.EXTENSION_BUNDLESIZE_STATS_TOKEN }} | |
| SELENIUM_BROWSER: chrome | |
| steps: | |
| - name: Checkout and setup environment | |
| uses: MetaMask/action-checkout-and-setup@v3 | |
| with: | |
| is-high-risk-environment: false | |
| skip-allow-scripts: true | |
| - name: Download artifact 'build-dist-browserify' | |
| uses: actions/download-artifact@v7 | |
| with: | |
| name: build-dist-browserify | |
| github-token: ${{ secrets.GITHUB_TOKEN }} # This is required when downloading artifacts from a different repository or from a different workflow run. | |
| run-id: ${{ needs.get-requirements.outputs.builds-from-run }} # Download from whatever run the get-requirements job said. | |
| - name: Measure bundle size | |
| run: yarn tsx test/e2e/mv3-perf-stats/bundle-size.ts --out test-artifacts/chrome | |
| - name: Record bundle size at commit | |
| if: ${{ env.BRANCH == 'main' && env.IS_FORK == 'false'}} | |
| run: ./.github/scripts/bundle-stats-commit.sh | |
| - name: Upload 'bundle-size' to S3 | |
| if: ${{ vars.AWS_REGION && vars.AWS_IAM_ROLE && vars.AWS_S3_BUCKET }} | |
| uses: MetaMask/github-tools/.github/actions/upload-s3@v1 | |
| with: | |
| aws-region: ${{ vars.AWS_REGION }} | |
| role-to-assume: ${{ vars.AWS_IAM_ROLE }} | |
| s3-bucket: ${{ vars.AWS_S3_BUCKET }}/${{ github.event.repository.name }}/${{ github.run_id }}/bundle-size | |
| path: test-artifacts/chrome | |
| page-load-benchmark: | |
| needs: | |
| - get-requirements | |
| - build-test-browserify | |
| if: ${{ needs.get-requirements.outputs.needs-benchmarks == 'true' }} | |
| uses: ./.github/workflows/page-load-benchmark.yml | |
| secrets: | |
| EXTENSION_BENCHMARK_STATS_TOKEN: ${{ secrets.EXTENSION_BENCHMARK_STATS_TOKEN }} | |
| with: | |
| browser-loads: 10 | |
| page-loads: 10 | |
| builds-from-run: ${{ needs.get-requirements.outputs.builds-from-run }} | |
| prep-e2e: | |
| needs: | |
| - get-requirements | |
| - prep-deps | |
| if: ${{ needs.get-requirements.outputs.needs-e2e == 'true' }} | |
| uses: ./.github/workflows/prep-e2e.yml | |
| e2e-chrome: | |
| needs: | |
| - get-requirements | |
| - prep-e2e | |
| - build-test-browserify | |
| - build-test-webpack | |
| - build-dist-browserify | |
| - build-test-flask-browserify | |
| uses: ./.github/workflows/e2e-chrome.yml | |
| # Without this `if`, when builds-from-run is activated, the build jobs are considered skipped, and the downstream E2E tests won't run | |
| if: ${{ !cancelled() && needs.get-requirements.outputs.needs-e2e == 'true' && !contains(needs.*.result, 'failure') }} | |
| with: | |
| builds-from-run: ${{ needs.get-requirements.outputs.builds-from-run }} | |
| secrets: inherit | |
| e2e-firefox: | |
| needs: | |
| - get-requirements | |
| - prep-e2e | |
| - build-dist-mv2-browserify | |
| - build-test-mv2-browserify | |
| - build-test-mv2-webpack | |
| - build-test-flask-mv2-browserify | |
| uses: ./.github/workflows/e2e-firefox.yml | |
| # Without this `if`, when builds-from-run is activated, the build jobs are considered skipped, and the downstream E2E tests won't run | |
| if: ${{ !cancelled() && needs.get-requirements.outputs.needs-e2e == 'true' && !contains(needs.*.result, 'failure') }} | |
| with: | |
| builds-from-run: ${{ needs.get-requirements.outputs.builds-from-run }} | |
| secrets: | |
| INFURA_PROJECT_ID: ${{ secrets.INFURA_PROJECT_ID }} | |
| build-storybook: | |
| name: Build storybook | |
| if: ${{ needs.get-requirements.outputs.skip-everything != 'true' }} | |
| needs: | |
| - get-requirements | |
| uses: ./.github/workflows/build-storybook.yml | |
| secrets: | |
| STORYBOOK_TOKEN: ${{ secrets.STORYBOOK_TOKEN }} | |
| build-ts-migration-dashboard: | |
| name: Build ts migration dashboard | |
| if: ${{ github.event_name != 'merge_group' && needs.get-requirements.outputs.skip-everything != 'true' }} | |
| needs: | |
| - get-requirements | |
| uses: ./.github/workflows/build-ts-migration-dashboard.yml | |
| secrets: | |
| TS_MIGRATION_DASHBOARD_TOKEN: ${{ secrets.TS_MIGRATION_DASHBOARD_TOKEN }} | |
| build-source-map-explorer: | |
| needs: | |
| - get-requirements | |
| - prep-deps | |
| - build-dist-browserify | |
| if: ${{ needs.get-requirements.outputs.skip-everything != 'true' && github.event_name != 'merge_group' }} | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 30 | |
| steps: | |
| - name: Checkout and setup environment | |
| uses: MetaMask/action-checkout-and-setup@v3 | |
| with: | |
| is-high-risk-environment: false | |
| skip-allow-scripts: true | |
| - name: Download artifact 'build-dist-browserify' | |
| uses: actions/download-artifact@v7 | |
| with: | |
| name: build-dist-browserify | |
| github-token: ${{ secrets.GITHUB_TOKEN }} # This is required when downloading artifacts from a different repository or from a different workflow run. | |
| run-id: ${{ needs.get-requirements.outputs.builds-from-run }} # Download from whatever run the get-requirements job said. | |
| - run: ./development/source-map-explorer.sh | |
| - name: Upload 'source-map-explorer' to S3 | |
| if: ${{ vars.AWS_REGION && vars.AWS_IAM_ROLE && vars.AWS_S3_BUCKET }} | |
| uses: MetaMask/github-tools/.github/actions/upload-s3@v1 | |
| with: | |
| aws-region: ${{ vars.AWS_REGION }} | |
| role-to-assume: ${{ vars.AWS_IAM_ROLE }} | |
| s3-bucket: ${{ vars.AWS_S3_BUCKET }}/${{ github.event.repository.name }}/${{ github.run_id }}/source-map-explorer | |
| path: build-artifacts/source-map-explorer | |
| build-lavamoat-viz: | |
| needs: | |
| - get-requirements | |
| - prep-deps | |
| - build-dist-browserify | |
| if: ${{ needs.get-requirements.outputs.skip-everything != 'true' }} | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 30 | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| INFURA_PROJECT_ID: ${{ secrets.INFURA_PROJECT_ID }} | |
| GOOGLE_PROD_CLIENT_ID: 00000000000 | |
| APPLE_PROD_CLIENT_ID: 00000000000 | |
| GOOGLE_BETA_CLIENT_ID: 00000000000 | |
| APPLE_BETA_CLIENT_ID: 00000000000 | |
| GOOGLE_EXPERIMENTAL_CLIENT_ID: 00000000000 | |
| APPLE_EXPERIMENTAL_CLIENT_ID: 00000000000 | |
| GOOGLE_FLASK_CLIENT_ID: 00000000000 | |
| APPLE_FLASK_CLIENT_ID: 00000000000 | |
| outputs: | |
| lavamoat-policy-changed: ${{ steps.lavamoat-policy-changed.outputs.lavamoat-policy-changed }} | |
| steps: | |
| - name: Checkout and setup environment | |
| uses: MetaMask/action-checkout-and-setup@v3 | |
| with: | |
| is-high-risk-environment: false | |
| skip-allow-scripts: true | |
| - name: Download changed-files artifact | |
| if: ${{ env.BRANCH != 'main' }} | |
| id: download-changed-files | |
| continue-on-error: true | |
| uses: actions/download-artifact@v7 | |
| with: | |
| name: changed-files | |
| path: ./changed-files/ | |
| # if the changed-files artifact does not exist, we get the diff | |
| - run: yarn tsx .github/scripts/git-diff-default-branch.ts | |
| if: ${{ steps.download-changed-files.outcome == 'failure' }} | |
| - name: See if lavamoat policy files have changed | |
| id: lavamoat-policy-changed | |
| run: | | |
| # if 'changed-files/changed-files.json' exists, check if it contains any files named policy.json or policy-override.json | |
| if [ -f "changed-files/changed-files.json" ]; then | |
| if grep -q -e 'policy.json' -e 'policy-override.json' changed-files/changed-files.json; then | |
| echo "Lavamoat policy file changes detected." | |
| echo "lavamoat-policy-changed=true" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "No Lavamoat policy file changes detected." | |
| echo "lavamoat-policy-changed=false" >> "$GITHUB_OUTPUT" | |
| fi | |
| else | |
| echo "Cannot find 'changed-files.json', assuming that Lavamoat policy files have changed." | |
| echo "lavamoat-policy-changed=true" >> "$GITHUB_OUTPUT" | |
| fi | |
| - name: Download artifact 'build-dist-browserify' | |
| if: ${{ steps.lavamoat-policy-changed.outputs.lavamoat-policy-changed == 'true' }} | |
| uses: actions/download-artifact@v7 | |
| with: | |
| name: build-dist-browserify | |
| github-token: ${{ secrets.GITHUB_TOKEN }} # This is required when downloading artifacts from a different repository or from a different workflow run. | |
| run-id: ${{ needs.get-requirements.outputs.builds-from-run }} # Download from whatever run the get-requirements job said. | |
| - run: ./.github/scripts/create-lavamoat-viz.sh | |
| if: ${{ steps.lavamoat-policy-changed.outputs.lavamoat-policy-changed == 'true' }} | |
| - name: Upload 'build-viz' to S3 | |
| if: ${{ steps.lavamoat-policy-changed.outputs.lavamoat-policy-changed == 'true' && vars.AWS_REGION && vars.AWS_IAM_ROLE && vars.AWS_S3_BUCKET }} | |
| uses: MetaMask/github-tools/.github/actions/upload-s3@v1 | |
| with: | |
| aws-region: ${{ vars.AWS_REGION }} | |
| role-to-assume: ${{ vars.AWS_IAM_ROLE }} | |
| s3-bucket: ${{ vars.AWS_S3_BUCKET }}/${{ github.event.repository.name }}/${{ github.run_id }}/lavamoat-viz | |
| path: build-artifacts/build-viz | |
| publish-prerelease: | |
| name: Publish prerelease | |
| # publish-prerelease when releases are enabled. | |
| # | |
| # This job is sequenced after *all* jobs in `needs`, including benchmarks. | |
| # | |
| # Requirements: | |
| # - For most jobs: result must be `success` or `skipped` (supports the builds-from-run shortcut). | |
| # - For benchmark jobs: result can be anything (failure does not block prerelease), | |
| if: >- | |
| ${{ | |
| !cancelled() && | |
| needs.get-requirements.outputs.needs-releases == 'true' && | |
| contains(fromJson('["success","skipped"]'), needs.build-dist-browserify.result) && | |
| contains(fromJson('["success","skipped"]'), needs.build-dist-mv2-browserify.result) && | |
| contains(fromJson('["success","skipped"]'), needs.build-beta-browserify.result) && | |
| contains(fromJson('["success","skipped"]'), needs.build-beta-mv2-browserify.result) && | |
| contains(fromJson('["success","skipped"]'), needs.build-flask-browserify.result) && | |
| contains(fromJson('["success","skipped"]'), needs.build-flask-mv2-browserify.result) && | |
| contains(fromJson('["success","skipped"]'), needs.build-test-browserify.result) && | |
| contains(fromJson('["success","skipped"]'), needs.build-test-mv2-browserify.result) && | |
| contains(fromJson('["success","skipped"]'), needs.build-test-flask-browserify.result) && | |
| contains(fromJson('["success","skipped"]'), needs.build-test-flask-mv2-browserify.result) && | |
| contains(fromJson('["success","skipped"]'), needs.bundle-size.result) && | |
| contains(fromJson('["success","skipped"]'), needs.build-storybook.result) && | |
| contains(fromJson('["success","skipped"]'), needs.build-ts-migration-dashboard.result) && | |
| contains(fromJson('["success","skipped"]'), needs.build-source-map-explorer.result) && | |
| contains(fromJson('["success","skipped"]'), needs.build-lavamoat-viz.result) | |
| }} | |
| needs: | |
| - get-requirements | |
| - build-dist-browserify | |
| - build-dist-mv2-browserify | |
| - build-beta-browserify | |
| - build-beta-mv2-browserify | |
| - build-flask-browserify | |
| - build-flask-mv2-browserify | |
| - build-test-browserify | |
| - build-test-mv2-browserify | |
| - build-test-flask-browserify | |
| - build-test-flask-mv2-browserify | |
| - run-benchmarks | |
| - page-load-benchmark | |
| - bundle-size | |
| - build-storybook | |
| - build-ts-migration-dashboard | |
| - build-source-map-explorer | |
| - build-lavamoat-viz | |
| uses: ./.github/workflows/publish-prerelease.yml | |
| with: | |
| lavamoat-policy-changed: ${{ needs.build-lavamoat-viz.outputs.lavamoat-policy-changed == 'true' }} | |
| post-new-builds: ${{ needs.get-requirements.outputs.builds-from-run == github.run_id }} | |
| secrets: inherit | |
| trigger-regression-validation: | |
| name: Trigger Regression Validation | |
| # Only run for release branches, not forks | |
| if: ${{ (startsWith(github.head_ref || github.ref_name, 'release/') && !(github.event.pull_request.head.repo.fork || github.event.repository.fork)) }} | |
| needs: | |
| - build-dist-browserify | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 5 | |
| environment: release-branch | |
| steps: | |
| - name: Trigger regression validation in external repo | |
| env: | |
| DISPATCH_TOKEN: ${{ secrets.METAMASK_REGRESSION_TRIGGER_TEST }} | |
| RUN_ID: ${{ github.run_id }} | |
| run: | | |
| # Extract version from branch name (e.g., release/12.5.0 -> 12.5.0) | |
| # Use BRANCH env var which correctly handles both push and pull_request events | |
| VERSION="${BRANCH#release/}" | |
| echo "Triggering regression validation..." | |
| echo "Run ID: $RUN_ID" | |
| echo "Branch: $BRANCH" | |
| echo "Version: $VERSION" | |
| echo "Commit SHA: $HEAD_COMMIT_HASH" | |
| curl -X POST \ | |
| -H "Accept: application/vnd.github.v3+json" \ | |
| -H "Authorization: token $DISPATCH_TOKEN" \ | |
| https://api.github.com/repos/MetaMask/extension-regression-validation-poc/dispatches \ | |
| -d '{ | |
| "event_type": "release_pr_updated", | |
| "client_payload": { | |
| "run_id": "'"$RUN_ID"'", | |
| "version": "'"$VERSION"'", | |
| "branch": "'"$BRANCH"'", | |
| "commit_sha": "'"$HEAD_COMMIT_HASH"'" | |
| } | |
| }' | |
| echo "Regression validation triggered successfully" | |
| all-jobs-pass: | |
| name: All jobs pass | |
| if: ${{ !cancelled() }} | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 2 | |
| # We list every job we want to validate in `needs`, because `needs` only contains results for jobs explicitly | |
| # named here. A failing job can cause downstream jobs to be `skipped`, which can hide the true failure unless | |
| # the upstream job is also included. | |
| # | |
| # For instance, if prep-e2e fails, e2e-chrome and e2e-firefox are skipped, so we need the direct result of prep-e2e. | |
| # | |
| # Jobs intentionally excluded: | |
| # - Publish jobs (not required for CI pass) | |
| # - Jobs that depend on all-jobs-pass (e.g., log-merge-group-failure) cannot be included here | |
| needs: | |
| - get-requirements | |
| - locales-changed-only | |
| - prep-deps | |
| - lint-workflows | |
| - test-lint | |
| - repository-health-checks | |
| - test-storybook | |
| - validate-lavamoat-policies | |
| - build-dist-browserify | |
| - build-dist-mv2-browserify | |
| - build-beta-browserify | |
| - build-beta-mv2-browserify | |
| - build-flask-browserify | |
| - build-flask-mv2-browserify | |
| - build-test-browserify | |
| - build-test-mv2-browserify | |
| - build-test-flask-browserify | |
| - build-test-flask-mv2-browserify | |
| - build-test-webpack | |
| - build-test-mv2-webpack | |
| - run-benchmarks | |
| - run-tests | |
| - bundle-size | |
| - page-load-benchmark | |
| - prep-e2e | |
| - e2e-chrome | |
| - e2e-firefox | |
| - build-storybook | |
| - build-ts-migration-dashboard | |
| - build-source-map-explorer | |
| - build-lavamoat-viz | |
| - trigger-regression-validation | |
| steps: | |
| - name: Check that all jobs have passed | |
| env: | |
| NEEDS_JSON: ${{ toJson(needs) }} # This is required for the the job_result lookup and the job_id loop | |
| BUILDS_FROM_RUN: ${{ needs.get-requirements.outputs.builds-from-run }} | |
| RUN_ID: ${{ github.run_id }} | |
| run: | | |
| # Function to ensure a job's result is either 'success' or 'skipped' | |
| requireJobSuccessOrSkipped() { | |
| local job_id="$1" | |
| local job_result="$2" | |
| if [[ -z "$job_result" ]]; then | |
| echo "Could not determine result for job: $job_id" | |
| exit 1 | |
| fi | |
| if [[ "$job_result" != "skipped" && "$job_result" != "success" ]]; then | |
| echo "$job_id did not succeed (result: $job_result)" | |
| exit 1 | |
| fi | |
| } | |
| # Loop through each job in the needs array to ensure it succeeded or was skipped | |
| while IFS=$'\t' read -r job_id job_result; do | |
| # job_result is effectively `needs[$job_id].result` | |
| requireJobSuccessOrSkipped "$job_id" "$job_result" | |
| done < <( | |
| jq -r 'to_entries[] | [.key, (.value.result // "")] | @tsv' <<<"$NEEDS_JSON" | |
| ) | |
| # # Check if the builds-from-run output is the current run ID | |
| if [[ "$BUILDS_FROM_RUN" != "$RUN_ID" ]]; then | |
| echo "Builds were used from a different GHA run: $BUILDS_FROM_RUN" | |
| echo "Right now you can use this feature to test and iterate faster, but to merge a PR, you have to disable it." | |
| exit 1 | |
| fi | |
| echo "All required jobs either passed or were skipped" | |
| - name: Log merge group failure | |
| if: ${{ github.event_name == 'merge_group' && failure() && !github.event.repository.fork }} | |
| uses: MetaMask/github-tools/.github/actions/log-merge-group-failure@v1 | |
| with: | |
| google-application-credentials: ${{ secrets.GOOGLE_APPLICATION_CREDENTIALS }} | |
| google-service-account: ${{ secrets.GOOGLE_SERVICE_ACCOUNT }} | |
| spreadsheet-id: ${{ secrets.GOOGLE_MERGE_QUEUE_SPREADSHEET_ID }} | |
| sheet-name: ${{ secrets.GOOGLE_MERGE_QUEUE_SHEET_NAME }} | |
| publish-release: | |
| name: Publish release | |
| if: ${{ !cancelled() && needs.all-jobs-pass.result == 'success' && github.event_name == 'push' && github.ref_name == 'stable' && needs.get-requirements.outputs.needs-releases == 'true' }} | |
| needs: | |
| - get-requirements | |
| - all-jobs-pass | |
| uses: ./.github/workflows/publish-release.yml | |
| secrets: inherit |