From fe898d6b39a3aeb530220166fcfa90e61862801e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Josh=20Goldberg=20=E2=9C=A8?= Date: Thu, 14 May 2026 08:27:29 -0400 Subject: [PATCH 1/4] chore: merged Jest changedSince testing into main PR Jest job --- .github/workflows/frontend-optional.yml | 100 +++--------------------- .github/workflows/frontend.yml | 30 +++++++ 2 files changed, 42 insertions(+), 88 deletions(-) diff --git a/.github/workflows/frontend-optional.yml b/.github/workflows/frontend-optional.yml index 2d626c4efb8c25..2434c71a59ddb7 100644 --- a/.github/workflows/frontend-optional.yml +++ b/.github/workflows/frontend-optional.yml @@ -25,11 +25,8 @@ jobs: testable_rules_changed: ${{ steps.changes.outputs.testable_rules_changed }} typecheckable_rules_changed: ${{ steps.changes.outputs.typecheckable_rules_changed }} frontend_all: ${{ steps.changes.outputs.frontend_all }} - merge_base: ${{ steps.merge_base.outputs.merge_base }} steps: - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - with: - fetch-depth: 100 - name: Check for frontend file changes uses: dorny/paths-filter@0bc4621a3135347011ad047f9ecf449bf72ce2bd # v3.0.0 @@ -39,95 +36,22 @@ jobs: filters: .github/file-filters.yml list-files: shell - # On PRs, HEAD is the merge commit; its parents (HEAD^1, HEAD^2) are base and head. - # Merge base of those two is what Jest --changedSince needs. - # If merge base can't be computed or non-frontend files changed, output is empty - # and the optional Jest job will be skipped entirely. - - name: Get merge base for changedSince - id: merge_base - run: | - MERGE_BASE=$(git merge-base HEAD^1 HEAD^2 2>/dev/null) || true - if [ -n "$MERGE_BASE" ]; then - CHANGED=$(git diff --name-only "$MERGE_BASE" HEAD^2) - if echo "$CHANGED" | grep -qvE '^static/'; then - echo "Non-frontend file changed — skipping optional Jest" - MERGE_BASE="" - else - echo "Merge base: $MERGE_BASE (Jest will use --changedSince)" - fi - else - echo "Could not compute merge base — skipping optional Jest" - fi - echo "merge_base=${MERGE_BASE:-}" >> "$GITHUB_OUTPUT" - - # This job intentionally mirrors `frontend-jest-tests` in frontend.yml. - # Our intent is to try it out for a few weeks and see if it's stable. - frontend-jest-tests-changed-only: - if: >- - needs.files-changed.outputs.merge_base != '' && - (needs.files-changed.outputs.testable_rules_changed == 'true' || needs.files-changed.outputs.testable_modified == 'true') - needs: [files-changed] - name: Jest - # If you change the runs-on image, you must also change the runner in jest-balance.yml - # so that the balancer runs in the same environment as the tests. + typescript-native: + if: needs.files-changed.outputs.frontend_all == 'true' + needs: files-changed + name: '@typescript/native-preview' runs-on: ubuntu-24.04 - timeout-minutes: 30 - strategy: - # This helps not having to run multiple jobs because one fails, thus, reducing resource usage - # and reducing the risk that one of many runs would turn red again (read: intermittent tests) - fail-fast: false - matrix: - # XXX: When updating this, make sure you also update CI_NODE_TOTAL. - instance: [0, 1, 2, 3] - + continue-on-error: true steps: - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - name: Checkout sentry - with: - # PRs need history so we can compute merge base for Jest --changedSince. - # 100 is an arbitrary depth that will get most reasonable PRs' commits. - fetch-depth: ${{ github.event_name == 'pull_request' && '100' || '1' }} - uses: ./.github/actions/setup-node-pnpm - - name: jest transform cache - uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0 - with: - path: | - .cache/jest - ~/.cache/swc - key: jest-cache-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml', 'jest.config.ts') }}-${{ matrix.instance }} - restore-keys: | - jest-cache-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml', 'jest.config.ts') }}- - jest-cache-${{ runner.os }}- - - - name: Download jest-balance.json - id: download-artifact - uses: dawidd6/action-download-artifact@ac66b43f0e6a346234dd65d4d0c8fbb31cb316e5 # v11 - with: - workflow: 38531594 # jest-balancer.yml - workflow_conclusion: success # The conclusion of the workflow we're looking for - branch: master # The branch we're looking for - name: jest-balance.json # Artifact name - name_is_regexp: false - path: tests/js/test-balancer/ # Directory where to extract artifact(s), defaults to the current directory - search_artifacts: true # Search for the last workflow run whose stored the artifact we're looking for - if_no_artifact_found: warn # Can be one of: "fail", "warn", "ignore" + - name: setup matchers + run: | + echo "::remove-matcher owner=masters::" + echo "::add-matcher::.github/tsc.json" - - name: jest - env: - GITHUB_PR_SHA: ${{ github.event.pull_request.head.sha || github.sha }} - GITHUB_PR_REF: ${{ github.event.pull_request.head.ref || github.ref }} - # XXX: CI_NODE_TOTAL must be hardcoded to the length of strategy.matrix.instance. - # Otherwise, if there are other things in the matrix, using strategy.job-total - # wouldn't be correct. - CI_NODE_TOTAL: 4 - CI_NODE_INDEX: ${{ matrix.instance }} - # Disable testing-library from printing out any of of the DOM to - # stdout. No one actually looks through this in CI, they're just - # going to run it locally. - # - # This quiets up the logs quite a bit. - DEBUG_PRINT_LIMIT: 0 - MERGE_BASE: ${{ needs.files-changed.outputs.merge_base }} - run: pnpm run test-ci --forceExit + - name: tsgo + id: tsgo + run: pnpm run typecheck diff --git a/.github/workflows/frontend.yml b/.github/workflows/frontend.yml index d908150d27b95d..07ecc71fd538d1 100644 --- a/.github/workflows/frontend.yml +++ b/.github/workflows/frontend.yml @@ -28,8 +28,11 @@ jobs: testable_rules_changed: ${{ steps.changes.outputs.testable_rules_changed }} typecheckable_rules_changed: ${{ steps.changes.outputs.typecheckable_rules_changed }} frontend_all: ${{ steps.changes.outputs.frontend_all }} + merge_base: ${{ steps.merge_base.outputs.merge_base }} steps: - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + with: + fetch-depth: 100 - name: Check for frontend file changes uses: dorny/paths-filter@0bc4621a3135347011ad047f9ecf449bf72ce2bd # v3.0.0 @@ -39,6 +42,27 @@ jobs: filters: .github/file-filters.yml list-files: shell + # On PRs, HEAD is the merge commit; its parents (HEAD^1, HEAD^2) are base and head. + # Merge base of those two is what Jest --changedSince needs. + # If merge base can't be computed or non-frontend files changed, output is empty + # and the Jest job will run the full test suite instead. + - name: Get merge base for changedSince + id: merge_base + run: | + MERGE_BASE=$(git merge-base HEAD^1 HEAD^2 2>/dev/null) || true + if [ -n "$MERGE_BASE" ]; then + CHANGED=$(git diff --name-only "$MERGE_BASE" HEAD^2) + if echo "$CHANGED" | grep -qvE '^static/'; then + echo "Non-frontend file changed — running full Jest suite" + MERGE_BASE="" + else + echo "Merge base: $MERGE_BASE (Jest will use --changedSince)" + fi + else + echo "Could not compute merge base — running full Jest suite" + fi + echo "merge_base=${MERGE_BASE:-}" >> "$GITHUB_OUTPUT" + typescript: if: needs.files-changed.outputs.frontend_all == 'true' needs: files-changed @@ -128,6 +152,9 @@ jobs: steps: - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 name: Checkout sentry + with: + # PRs need history so Jest can resolve --changedSince from local Git history. + fetch-depth: ${{ github.event_name == 'pull_request' && '100' || '1' }} - uses: ./.github/actions/setup-node-pnpm @@ -173,6 +200,9 @@ jobs: # When the "Frontend: Rerun Flaky Tests" label is on the PR, # tests wrapped with it.isKnownFlake() run 50x to validate fixes. RERUN_KNOWN_FLAKY_TESTS: "${{ contains(github.event.pull_request.labels.*.name, 'Frontend: Rerun Flaky Tests') }}" + # When set, Jest uses --changedSince to run only tests affected by this PR. + # Empty on master or when non-frontend files changed (falls back to full suite). + MERGE_BASE: ${{ needs.files-changed.outputs.merge_base }} run: pnpm run test-ci --forceExit form-field-registry: From 2c9a0aaba2db3ee61e2c1f44b77d0155191b6576 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Josh=20Goldberg=20=E2=9C=A8?= Date: Thu, 14 May 2026 11:00:28 -0400 Subject: [PATCH 2/4] fix(ci): skip merge base computation on master push Prevents MERGE_BASE from being set when a merge commit lands on master, which would cause jest --changedSince to fail in the shallow-cloned jest job. --- .github/workflows/frontend.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/frontend.yml b/.github/workflows/frontend.yml index 07ecc71fd538d1..932e9a9f76e106 100644 --- a/.github/workflows/frontend.yml +++ b/.github/workflows/frontend.yml @@ -48,6 +48,7 @@ jobs: # and the Jest job will run the full test suite instead. - name: Get merge base for changedSince id: merge_base + if: github.event_name == 'pull_request' run: | MERGE_BASE=$(git merge-base HEAD^1 HEAD^2 2>/dev/null) || true if [ -n "$MERGE_BASE" ]; then From 8b4dbaa8177831b38e59a8969c10440e57446929 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Josh=20Goldberg=20=E2=9C=A8?= Date: Thu, 14 May 2026 12:20:33 -0400 Subject: [PATCH 3/4] Remove orphaned job outputs --- .github/workflows/frontend-optional.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/frontend-optional.yml b/.github/workflows/frontend-optional.yml index 2434c71a59ddb7..9c25cdefb9045e 100644 --- a/.github/workflows/frontend-optional.yml +++ b/.github/workflows/frontend-optional.yml @@ -21,9 +21,6 @@ jobs: timeout-minutes: 3 # Map a step output to a job output outputs: - testable_modified: ${{ steps.changes.outputs.testable_modified }} - testable_rules_changed: ${{ steps.changes.outputs.testable_rules_changed }} - typecheckable_rules_changed: ${{ steps.changes.outputs.typecheckable_rules_changed }} frontend_all: ${{ steps.changes.outputs.frontend_all }} steps: - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 From dac3ecf7405390b5eb278874b1dcc5a27830cf1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Josh=20Goldberg=20=E2=9C=A8?= Date: Thu, 14 May 2026 12:34:32 -0400 Subject: [PATCH 4/4] oh hey no more frontend-optional.yml --- .github/workflows/frontend-optional.yml | 54 ------------------------- 1 file changed, 54 deletions(-) delete mode 100644 .github/workflows/frontend-optional.yml diff --git a/.github/workflows/frontend-optional.yml b/.github/workflows/frontend-optional.yml deleted file mode 100644 index 9c25cdefb9045e..00000000000000 --- a/.github/workflows/frontend-optional.yml +++ /dev/null @@ -1,54 +0,0 @@ -name: '[NOT REQUIRED] frontend (optional)' - -on: - pull_request: - -# Cancel in progress workflows on pull_requests. -# https://docs.github.com/en/actions/using-jobs/using-concurrency#example-using-a-fallback-value -concurrency: - group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} - cancel-in-progress: true - -# hack for https://github.com/actions/cache/issues/810#issuecomment-1222550359 -env: - SEGMENT_DOWNLOAD_TIMEOUT_MINS: 3 - NODE_OPTIONS: '--max-old-space-size=5120' - -jobs: - files-changed: - name: detect what files changed - runs-on: ubuntu-24.04 - timeout-minutes: 3 - # Map a step output to a job output - outputs: - frontend_all: ${{ steps.changes.outputs.frontend_all }} - steps: - - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - - - name: Check for frontend file changes - uses: dorny/paths-filter@0bc4621a3135347011ad047f9ecf449bf72ce2bd # v3.0.0 - id: changes - with: - token: ${{ github.token }} - filters: .github/file-filters.yml - list-files: shell - - typescript-native: - if: needs.files-changed.outputs.frontend_all == 'true' - needs: files-changed - name: '@typescript/native-preview' - runs-on: ubuntu-24.04 - continue-on-error: true - steps: - - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - - - uses: ./.github/actions/setup-node-pnpm - - - name: setup matchers - run: | - echo "::remove-matcher owner=masters::" - echo "::add-matcher::.github/tsc.json" - - - name: tsgo - id: tsgo - run: pnpm run typecheck