Scale ERC-8056 token amounts by the token's UI multiplier #4442
Workflow file for this run
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: Checks | |
| on: | |
| workflow_call: | |
| workflow_dispatch: | |
| pull_request: | |
| types: [ opened, synchronize, unlabeled, ready_for_review ] | |
| paths-ignore: | |
| - '.github/ISSUE_TEMPLATE/**' | |
| - '.husky/**' | |
| - '.vscode/**' | |
| - '.agents/**' | |
| - '.cursor/**' | |
| - 'deploy/**' | |
| - 'docs/**' | |
| - 'public/**' | |
| # concurrency: | |
| # group: ${{ github.workflow }}__${{ github.job }}__${{ github.ref }} | |
| # cancel-in-progress: true | |
| permissions: | |
| contents: read | |
| pull-requests: write | |
| # pnpm deps: rely on actions/setup-node cache: pnpm (content-addressable store, keyed on | |
| # pnpm-lock.yaml). Always run pnpm install --frozen-lockfile in each job — with a warm store | |
| # it is mostly linking. Caching only the repo-root node_modules tarball omits workspace | |
| # package node_modules symlinks and breaks tsc/vite in toolkit and deploy/tools/* packages. | |
| jobs: | |
| code_quality: | |
| name: Code quality | |
| runs-on: ubuntu-latest | |
| # Draft PRs are skipped (spec-first workflow opens PRs as drafts early); checks run on | |
| # ready_for_review, and workflow_dispatch always allows a manual run on any PR. | |
| if: ${{ github.event.pull_request.draft != true && !contains(github.event.pull_request.labels.*.name, 'skip checks') && !(github.event.action == 'unlabeled' && github.event.label.name != 'skip checks') }} | |
| steps: | |
| - name: Checkout repo | |
| uses: actions/checkout@v4 | |
| - name: Install pnpm | |
| uses: pnpm/action-setup@v6 | |
| with: | |
| version: 12.4.1 | |
| cache: true | |
| - name: Setup node | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: 24.21.0 | |
| cache: 'pnpm' | |
| - name: Install dependencies | |
| run: pnpm install --frozen-lockfile | |
| - parallel: | |
| - name: Run ESLint | |
| run: pnpm lint:eslint | |
| - name: Compile TypeScript | |
| run: pnpm lint:tsc | |
| - name: Check licenses | |
| run: pnpm lint:license:check | |
| - name: Check spelling | |
| run: pnpm lint:cspell --no-progress | |
| - name: Check agent doc references resolve | |
| run: pnpm lint:doc-links | |
| - name: Check preset lists are in sync with registry | |
| run: pnpm presets:lint | |
| toolkit_build_check: | |
| name: Toolkit build check | |
| needs: [ code_quality ] | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout repo | |
| uses: actions/checkout@v4 | |
| - name: Install pnpm | |
| uses: pnpm/action-setup@v6 | |
| with: | |
| version: 12.4.1 | |
| cache: true | |
| - name: Setup node | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: 24.21.0 | |
| cache: 'pnpm' | |
| - name: Install project dependencies | |
| run: pnpm install --frozen-lockfile | |
| - parallel: | |
| - name: Type check the package | |
| run: pnpm --filter @blockscout/ui-toolkit typecheck | |
| - name: Build the package | |
| run: pnpm --filter @blockscout/ui-toolkit build | |
| - name: Verify build output | |
| run: | | |
| cd ./src/toolkit/package | |
| if [ ! -d "dist" ]; then | |
| echo "Build failed: dist directory not found" | |
| exit 1 | |
| fi | |
| if [ ! -f "dist/index.js" ]; then | |
| echo "Build failed: dist/index.js not found" | |
| exit 1 | |
| fi | |
| if [ ! -f "dist/index.d.ts" ]; then | |
| echo "Build failed: dist/index.d.ts not found" | |
| exit 1 | |
| fi | |
| envs_validation: | |
| name: ENV variables validation | |
| runs-on: ubuntu-latest | |
| needs: [ code_quality ] | |
| steps: | |
| - name: Checkout repo | |
| uses: actions/checkout@v4 | |
| - name: Install pnpm | |
| uses: pnpm/action-setup@v6 | |
| with: | |
| version: 12.4.1 | |
| cache: true | |
| - name: Setup node | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: 24.21.0 | |
| cache: 'pnpm' | |
| - name: Install dependencies | |
| run: pnpm install --frozen-lockfile | |
| - name: Run validation tests | |
| run: pnpm --filter envs-validator test | |
| vitest_tests: | |
| name: Unit tests | |
| needs: [ code_quality, envs_validation ] | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout repo | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Install pnpm | |
| uses: pnpm/action-setup@v6 | |
| with: | |
| version: 12.4.1 | |
| cache: true | |
| - name: Setup node | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: 24.21.0 | |
| cache: 'pnpm' | |
| - name: Install dependencies | |
| run: pnpm install --frozen-lockfile | |
| - name: Run Vitest | |
| run: pnpm test:vitest ${{ github.event_name == 'pull_request' && '--changed=origin/main --coverage --coverage.provider=v8 --coverage.reporter=json' || '' }} --passWithNoTests | |
| - name: Cognitive complexity & CRAP gate | |
| if: ${{ github.event_name == 'pull_request' }} | |
| run: pnpm test:code-complexity --changed=origin/main --coverage-file coverage/coverage-final.json | |
| - name: React Doctor gate | |
| if: ${{ github.event_name == 'pull_request' }} | |
| run: pnpm lint:react-doctor --scope changed --base origin/main --no-color | |
| mutation_tests: | |
| name: Mutation testing gate | |
| needs: [ vitest_tests ] | |
| runs-on: ubuntu-latest | |
| if: github.event_name == 'pull_request' | |
| # Outside the run's own 15-min wall-clock budget (tools/mutation-testing/config.ts), leaving room | |
| # for checkout and install so that expiring the budget still reaches the truncation report rather | |
| # than being killed mid-write. A normal PR gets nowhere near either bound. | |
| timeout-minutes: 20 | |
| steps: | |
| - name: Checkout repo | |
| uses: actions/checkout@v4 | |
| with: | |
| # The diff is resolved through the merge-base with origin/main, which a shallow clone lacks. | |
| fetch-depth: 0 | |
| - name: Install pnpm | |
| uses: pnpm/action-setup@v6 | |
| with: | |
| version: 12.4.1 | |
| cache: true | |
| - name: Setup node | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: 24.21.0 | |
| cache: 'pnpm' | |
| - name: Install dependencies | |
| run: pnpm install --frozen-lockfile | |
| - name: Mutation testing gate | |
| run: pnpm test:mutation-testing --changed=origin/main | |
| pw_changes: | |
| name: Check for Playwright-relevant changes | |
| runs-on: ubuntu-latest | |
| needs: [ code_quality, envs_validation ] | |
| if: github.event_name == 'pull_request' | |
| outputs: | |
| has_changes: ${{ steps.diff.outputs.has_changes }} | |
| steps: | |
| - name: Checkout repo | |
| uses: actions/checkout@v4 | |
| with: | |
| # The diff is resolved through the merge-base with origin/main, which a shallow clone lacks. | |
| fetch-depth: 0 | |
| - name: Diff watched paths against the merge-base | |
| id: diff | |
| # No dependency install here on purpose: the gate is one git command, so a PR that touches | |
| # nothing Playwright cares about skips the whole matrix in seconds. | |
| # The path list is paired with FORCE_FULL_PATHS in tools/playwright/config.ts (the tool's | |
| # "run the whole suite" triggers); it is a superset of that list plus src/, where the tests | |
| # and everything they import live. Keep the two in sync. | |
| run: | | |
| base=$(git merge-base origin/main HEAD) | |
| changed=$(git diff --name-only "$base" -- src playwright playwright-ct.config.ts pnpm-lock.yaml) | |
| if [ -n "$changed" ]; then | |
| echo "Changed files under the watched paths:" | |
| echo "$changed" | |
| echo "has_changes=true" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "No changes under the watched paths; the Playwright matrix will be skipped." | |
| echo "has_changes=false" >> "$GITHUB_OUTPUT" | |
| fi | |
| pw_tests: | |
| name: 'Playwright tests / ${{ matrix.name }}' | |
| needs: [ code_quality, envs_validation, pw_changes ] | |
| # The gate only runs on pull requests; a skipped gate (workflow_call from pre-release, manual | |
| # dispatch) means a full run. | |
| if: | | |
| always() && | |
| needs.code_quality.result == 'success' && | |
| needs.envs_validation.result == 'success' && | |
| (needs.pw_changes.result == 'skipped' || (needs.pw_changes.result == 'success' && needs.pw_changes.outputs.has_changes == 'true')) | |
| runs-on: ubuntu-latest | |
| container: | |
| image: mcr.microsoft.com/playwright:v1.57.0-noble | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - name: default-1 | |
| project: default | |
| shard: 1/3 | |
| - name: default-2 | |
| project: default | |
| shard: 2/3 | |
| - name: default-3 | |
| project: default | |
| shard: 3/3 | |
| - name: mobile | |
| project: mobile | |
| - name: dark-color-mode | |
| project: dark-color-mode | |
| steps: | |
| - name: Checkout repo | |
| uses: actions/checkout@v4 | |
| with: | |
| # --changed resolves the merge-base with origin/main, which a shallow clone lacks. | |
| fetch-depth: 0 | |
| - name: Install pnpm | |
| uses: pnpm/action-setup@v6 | |
| with: | |
| version: 12.4.1 | |
| - name: Setup node | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: 24.21.0 | |
| cache: 'pnpm' | |
| - name: Install dependencies | |
| run: pnpm install --frozen-lockfile | |
| - name: Trust the checkout inside the container | |
| # actions/checkout registers the workspace as a safe.directory in the global git config of the | |
| # HOME it ran under (/github/home); the run step below sets HOME=/root, where git finds no such | |
| # entry and refuses the repo ("dubious ownership") when --changed resolves the merge-base. | |
| run: git config --global --add safe.directory "$GITHUB_WORKSPACE" | |
| env: | |
| HOME: /root | |
| - name: Run PlayWright | |
| run: pnpm test:pw ${{ github.event_name == 'pull_request' && '--changed' || '' }} --project=${{ matrix.project }} ${{ matrix.shard && format('--shard={0}', matrix.shard) || '' }} --pass-with-no-tests | |
| env: | |
| HOME: /root | |
| - name: Upload blob report to GitHub Actions Artifacts | |
| if: ${{ !cancelled() }} | |
| uses: actions/upload-artifact@v5 | |
| with: | |
| name: blob-report-${{ matrix.name }} | |
| path: blob-report | |
| retention-days: 1 | |
| pw_report: | |
| name: Generate Playwright report | |
| # Merge reports after pw_tests job, even if some shards have failed | |
| if: ${{ !cancelled() }} | |
| runs-on: ubuntu-latest | |
| needs: [ pw_tests ] | |
| steps: | |
| - name: Download blob reports from GitHub Actions Artifacts | |
| id: download-reports | |
| uses: actions/download-artifact@v5 | |
| continue-on-error: true | |
| with: | |
| path: ${{ runner.temp }}/all-blob-reports | |
| pattern: blob-report-* | |
| merge-multiple: true | |
| - name: Check for downloaded reports | |
| id: check-reports | |
| run: | | |
| if [ -d "$RUNNER_TEMP/all-blob-reports" ] && [ -n "$(ls -A "$RUNNER_TEMP/all-blob-reports" 2>/dev/null)" ]; then | |
| echo "has_reports=true" >> $GITHUB_OUTPUT | |
| else | |
| echo "has_reports=false" >> $GITHUB_OUTPUT | |
| fi | |
| - name: Checkout repo | |
| if: steps.check-reports.outputs.has_reports == 'true' | |
| uses: actions/checkout@v4 | |
| - name: Install pnpm | |
| if: steps.check-reports.outputs.has_reports == 'true' | |
| uses: pnpm/action-setup@v6 | |
| with: | |
| version: 12.4.1 | |
| cache: true | |
| - name: Setup node | |
| if: steps.check-reports.outputs.has_reports == 'true' | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: 24.21.0 | |
| cache: 'pnpm' | |
| - name: Install dependencies | |
| if: steps.check-reports.outputs.has_reports == 'true' | |
| run: pnpm install --frozen-lockfile | |
| - name: Merge into HTML Report | |
| if: steps.check-reports.outputs.has_reports == 'true' | |
| run: npx playwright merge-reports --reporter html "$RUNNER_TEMP/all-blob-reports" | |
| - name: Upload HTML report artifact | |
| # Upload HTML report to GitHub Actions Artifacts only for pull requests from forks | |
| if: steps.check-reports.outputs.has_reports == 'true' && (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository) | |
| uses: actions/upload-artifact@v5 | |
| with: | |
| name: playwright-html-report | |
| path: playwright-report | |
| retention-days: 7 | |
| - name: Configure AWS credentials | |
| if: steps.check-reports.outputs.has_reports == 'true' && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository) | |
| uses: aws-actions/configure-aws-credentials@v1 | |
| with: | |
| aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} | |
| aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} | |
| aws-region: ${{ vars.AWS_REGION }} | |
| - name: Upload HTML report to S3 | |
| # Upload HTML report to S3 only for pull requests from the main repository or for non-pull requests events | |
| if: steps.check-reports.outputs.has_reports == 'true' && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository) | |
| run: | | |
| export "SHORT_SHA=`echo ${GITHUB_SHA} | cut -c1-8`" | |
| aws s3 cp playwright-report/ s3://${{ vars.AWS_BUCKET_NAME }}/report-${SHORT_SHA} --recursive | |
| echo "PLAYWRIGHT_URL=https://${{ vars.AWS_BUCKET_NAME }}.s3.${{ vars.AWS_REGION }}.amazonaws.com/report-${SHORT_SHA}/index.html" >> "$GITHUB_ENV" | |
| - name: Add link to job summary | |
| if: steps.check-reports.outputs.has_reports == 'true' | |
| run: | | |
| echo "### Playwright report" >> $GITHUB_STEP_SUMMARY | |
| if [ -n "${{ env.PLAYWRIGHT_URL }}" ]; then | |
| echo "[View report (S3)](${{ env.PLAYWRIGHT_URL }})" >> $GITHUB_STEP_SUMMARY | |
| else | |
| echo "Download the **playwright-html-report** artifact below to view the report (open \`index.html\` in a browser)." >> $GITHUB_STEP_SUMMARY | |
| fi | |
| echo "[Read about ducks](https://animalkingdom.org/animals/ducks/)" >> $GITHUB_STEP_SUMMARY |