fix(perps): when opening perps quickly after wallet open, the app display $0 for 24h volume and OI #4062
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
| # Compares BrowserStack app profiling for a failed performance scenario against | |
| # the last green baseline on main, then posts a diff comment on the PR. | |
| # | |
| # Automatic: run-performance-e2e.yml posts this for failed PR scenarios. | |
| # | |
| # Manual trigger via bot command on a PR: | |
| # @metamaskbot app-profiling-check --test "Cold Start Login" --platform Android --device "Google Pixel 8 Pro+14.0" --run 123456789 | |
| # @metamaskbot app-profiling-check --all --run 123456789 | |
| # | |
| # Or manually via Actions tab with workflow_dispatch. | |
| # | |
| # NOTE: issue_comment always runs from the default branch (main). | |
| # To use the workflow version from the PR branch, the issue_comment handler | |
| # dispatches a workflow_dispatch event on the PR branch, then exits. | |
| name: App Profiling Check | |
| on: | |
| issue_comment: | |
| types: | |
| - created | |
| workflow_dispatch: | |
| inputs: | |
| pr_number: | |
| description: 'PR number to comment on' | |
| required: true | |
| type: string | |
| current_run_id: | |
| description: 'Performance workflow run id that produced aggregated-reports' | |
| required: true | |
| type: string | |
| test_name: | |
| description: 'Scenario name to compare (leave empty when compare_all=true)' | |
| required: false | |
| type: string | |
| default: '' | |
| platform: | |
| description: 'Platform (Android / iOS)' | |
| required: false | |
| type: string | |
| default: '' | |
| device: | |
| description: 'Device key as Name+OSVersion' | |
| required: false | |
| type: string | |
| default: '' | |
| compare_all: | |
| description: 'Compare all failed scenarios from the current run summary' | |
| required: false | |
| type: boolean | |
| default: false | |
| baseline_branch: | |
| description: 'Branch used to find the last green baseline' | |
| required: false | |
| type: string | |
| default: main | |
| jobs: | |
| # ── issue_comment dispatcher ────────────────────────────────────────── | |
| dispatch: | |
| name: Dispatch to PR branch | |
| if: >- | |
| ${{ | |
| github.event_name == 'issue_comment' && | |
| github.event.issue.pull_request && | |
| startsWith(github.event.comment.body, '@metamaskbot app-profiling-check') | |
| }} | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 5 | |
| permissions: | |
| actions: write | |
| contents: read | |
| pull-requests: write | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: React to the comment | |
| continue-on-error: true | |
| run: | | |
| gh api \ | |
| --method POST \ | |
| -H "Accept: application/vnd.github+json" \ | |
| "/repos/${{ github.repository }}/issues/comments/${{ github.event.comment.id }}/reactions" \ | |
| -f content='+1' | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Get PR details | |
| id: pr | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| PR_NUMBER: ${{ github.event.issue.number }} | |
| run: | | |
| set -euo pipefail | |
| IS_FORK=$(gh pr view "${PR_NUMBER}" --json isCrossRepository --jq '.isCrossRepository') | |
| BRANCH=$(gh pr view "${PR_NUMBER}" --json headRefName --jq '.headRefName') | |
| { | |
| echo "PR_NUMBER=${PR_NUMBER}" | |
| echo "IS_FORK=${IS_FORK}" | |
| echo "BRANCH=${BRANCH}" | |
| } >> "$GITHUB_OUTPUT" | |
| - name: Parse bot command | |
| id: parse | |
| if: steps.pr.outputs.IS_FORK == 'false' | |
| env: | |
| COMMENT_BODY: ${{ github.event.comment.body }} | |
| run: | | |
| set -euo pipefail | |
| # Defaults | |
| TEST_NAME="" | |
| PLATFORM="" | |
| DEVICE="" | |
| RUN_ID="" | |
| COMPARE_ALL=false | |
| # --all | |
| if echo "$COMMENT_BODY" | grep -Eq -- '(^|[[:space:]])--all([[:space:]]|$)'; then | |
| COMPARE_ALL=true | |
| fi | |
| # --run <id> (digits only) | |
| if RUN_MATCH=$(echo "$COMMENT_BODY" | grep -Eo -- '--run[[:space:]]+[0-9]+' | head -n1); then | |
| RUN_ID=$(echo "$RUN_MATCH" | awk '{print $2}') | |
| fi | |
| # --platform <value> | |
| if PLATFORM_MATCH=$(echo "$COMMENT_BODY" | grep -Eo -- '--platform[[:space:]]+[^[:space:]]+' | head -n1); then | |
| PLATFORM=$(echo "$PLATFORM_MATCH" | awk '{print $2}') | |
| fi | |
| # --device "..." or --device ... | |
| if DEVICE_MATCH=$(echo "$COMMENT_BODY" | grep -Eo -- '--device[[:space:]]+"[^"]+"' | head -n1); then | |
| DEVICE=$(echo "$DEVICE_MATCH" | sed -E 's/^--device[[:space:]]*"//; s/"$//') | |
| elif DEVICE_MATCH=$(echo "$COMMENT_BODY" | grep -Eo -- '--device[[:space:]]+[^[:space:]]+' | head -n1); then | |
| DEVICE=$(echo "$DEVICE_MATCH" | awk '{print $2}') | |
| fi | |
| # --test "..." or --test ... | |
| if TEST_MATCH=$(echo "$COMMENT_BODY" | grep -Eo -- '--test[[:space:]]+"[^"]+"' | head -n1); then | |
| TEST_NAME=$(echo "$TEST_MATCH" | sed -E 's/^--test[[:space:]]*"//; s/"$//') | |
| elif TEST_MATCH=$(echo "$COMMENT_BODY" | grep -Eo -- '--test[[:space:]]+[^[:space:]]+' | head -n1); then | |
| TEST_NAME=$(echo "$TEST_MATCH" | awk '{print $2}') | |
| fi | |
| if [ -z "$RUN_ID" ]; then | |
| echo "::error::Missing --run <workflow_run_id> in app-profiling-check command" | |
| exit 1 | |
| fi | |
| if [ "$COMPARE_ALL" != "true" ] && [ -z "$TEST_NAME" ]; then | |
| echo "::error::Provide --test \"Scenario name\" or --all" | |
| exit 1 | |
| fi | |
| # Use delimited output form so user-controlled values cannot break | |
| # GITHUB_OUTPUT or inject extra keys. Random delimiter avoids collisions | |
| # if the value itself contains the literal word EOF. | |
| OUTPUT_DELIMITER="ghadelim_$(openssl rand -hex 16)" | |
| { | |
| echo "TEST_NAME<<${OUTPUT_DELIMITER}" | |
| printf '%s\n' "$TEST_NAME" | |
| echo "${OUTPUT_DELIMITER}" | |
| echo "PLATFORM<<${OUTPUT_DELIMITER}" | |
| printf '%s\n' "$PLATFORM" | |
| echo "${OUTPUT_DELIMITER}" | |
| echo "DEVICE<<${OUTPUT_DELIMITER}" | |
| printf '%s\n' "$DEVICE" | |
| echo "${OUTPUT_DELIMITER}" | |
| echo "RUN_ID<<${OUTPUT_DELIMITER}" | |
| printf '%s\n' "$RUN_ID" | |
| echo "${OUTPUT_DELIMITER}" | |
| echo "COMPARE_ALL<<${OUTPUT_DELIMITER}" | |
| printf '%s\n' "$COMPARE_ALL" | |
| echo "${OUTPUT_DELIMITER}" | |
| } >> "$GITHUB_OUTPUT" | |
| - name: Dispatch workflow on PR branch | |
| if: steps.pr.outputs.IS_FORK == 'false' | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| PR_NUMBER: ${{ steps.pr.outputs.PR_NUMBER }} | |
| BRANCH: ${{ steps.pr.outputs.BRANCH }} | |
| RUN_ID: ${{ steps.parse.outputs.RUN_ID }} | |
| COMPARE_ALL: ${{ steps.parse.outputs.COMPARE_ALL }} | |
| TEST_NAME: ${{ steps.parse.outputs.TEST_NAME }} | |
| PLATFORM: ${{ steps.parse.outputs.PLATFORM }} | |
| DEVICE: ${{ steps.parse.outputs.DEVICE }} | |
| SERVER_URL: ${{ github.server_url }} | |
| REPO: ${{ github.repository }} | |
| run: | | |
| set -euo pipefail | |
| # Pass comment-derived values only via env (never expression | |
| # interpolation inside this script body) to avoid shell injection | |
| # from --test/--device/--platform text. | |
| ACTIONS_URL="${SERVER_URL}/${REPO}/actions/workflows/app-profiling-check.yml" | |
| ARGS=( | |
| gh workflow run "App Profiling Check" | |
| --ref "${BRANCH}" | |
| -f "pr_number=${PR_NUMBER}" | |
| -f "current_run_id=${RUN_ID}" | |
| -f "compare_all=${COMPARE_ALL}" | |
| -f "baseline_branch=main" | |
| ) | |
| if [ -n "${TEST_NAME}" ]; then | |
| ARGS+=(-f "test_name=${TEST_NAME}") | |
| fi | |
| if [ -n "${PLATFORM}" ]; then | |
| ARGS+=(-f "platform=${PLATFORM}") | |
| fi | |
| if [ -n "${DEVICE}" ]; then | |
| ARGS+=(-f "device=${DEVICE}") | |
| fi | |
| "${ARGS[@]}" | |
| gh pr comment "${PR_NUMBER}" --body "🔬 **App profiling check started** for run \`${RUN_ID}\`. [View workflow runs](${ACTIONS_URL})" | |
| # ── workflow_dispatch: actual diff ──────────────────────────────────── | |
| check: | |
| name: Diff app profiling | |
| if: ${{ github.event_name == 'workflow_dispatch' }} | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 20 | |
| permissions: | |
| actions: read | |
| contents: read | |
| pull-requests: write | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version-file: '.nvmrc' | |
| - name: Run app profiling diff | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| GITHUB_REPOSITORY: ${{ github.repository }} | |
| PR_NUMBER: ${{ inputs.pr_number }} | |
| CURRENT_RUN_ID: ${{ inputs.current_run_id }} | |
| TEST_NAME: ${{ inputs.test_name }} | |
| PLATFORM: ${{ inputs.platform }} | |
| DEVICE: ${{ inputs.device }} | |
| COMPARE_ALL: ${{ inputs.compare_all }} | |
| BASELINE_BRANCH: ${{ inputs.baseline_branch }} | |
| run: | | |
| set -euo pipefail | |
| ARGS=( | |
| node tests/scripts/diff-app-profiling.mjs | |
| --pr "${PR_NUMBER}" | |
| --run "${CURRENT_RUN_ID}" | |
| --baseline-branch "${BASELINE_BRANCH:-main}" | |
| ) | |
| if [ "${COMPARE_ALL}" = "true" ]; then | |
| ARGS+=(--all) | |
| else | |
| if [ -z "${TEST_NAME}" ]; then | |
| echo "::error::test_name is required when compare_all is false" | |
| exit 1 | |
| fi | |
| ARGS+=(--test "${TEST_NAME}") | |
| fi | |
| if [ -n "${PLATFORM}" ]; then | |
| ARGS+=(--platform "${PLATFORM}") | |
| fi | |
| if [ -n "${DEVICE}" ]; then | |
| ARGS+=(--device "${DEVICE}") | |
| fi | |
| "${ARGS[@]}" |