|
25 | 25 | testable_rules_changed: ${{ steps.changes.outputs.testable_rules_changed }} |
26 | 26 | typecheckable_rules_changed: ${{ steps.changes.outputs.typecheckable_rules_changed }} |
27 | 27 | frontend_all: ${{ steps.changes.outputs.frontend_all }} |
| 28 | + merge_base: ${{ steps.merge_base.outputs.merge_base }} |
28 | 29 | steps: |
29 | 30 | - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 |
| 31 | + with: |
| 32 | + fetch-depth: 100 |
30 | 33 |
|
31 | 34 | - name: Check for frontend file changes |
32 | 35 | uses: dorny/paths-filter@0bc4621a3135347011ad047f9ecf449bf72ce2bd # v3.0.0 |
|
36 | 39 | filters: .github/file-filters.yml |
37 | 40 | list-files: shell |
38 | 41 |
|
| 42 | + # On PRs, HEAD is the merge commit; its parents (HEAD^1, HEAD^2) are base and head. |
| 43 | + # Merge base of those two is what Jest --changedSince needs. |
| 44 | + # If merge base can't be computed or non-frontend files changed, output is empty |
| 45 | + # and the optional Jest job will be skipped entirely. |
| 46 | + - name: Get merge base for changedSince |
| 47 | + id: merge_base |
| 48 | + run: | |
| 49 | + MERGE_BASE=$(git merge-base HEAD^1 HEAD^2 2>/dev/null) || true |
| 50 | + if [ -n "$MERGE_BASE" ]; then |
| 51 | + CHANGED=$(git diff --name-only "$MERGE_BASE" HEAD^2) |
| 52 | + if echo "$CHANGED" | grep -qvE '^static/'; then |
| 53 | + echo "Non-frontend file changed — skipping optional Jest" |
| 54 | + MERGE_BASE="" |
| 55 | + else |
| 56 | + echo "Merge base: $MERGE_BASE (Jest will use --changedSince)" |
| 57 | + fi |
| 58 | + else |
| 59 | + echo "Could not compute merge base — skipping optional Jest" |
| 60 | + fi |
| 61 | + echo "merge_base=${MERGE_BASE:-}" >> "$GITHUB_OUTPUT" |
| 62 | +
|
| 63 | + # This job intentionally mirrors `frontend-jest-tests` in frontend.yml. |
| 64 | + # Our intent is to try it out for a few weeks and see if it's stable. |
| 65 | + frontend-jest-tests-changed-only: |
| 66 | + if: >- |
| 67 | + needs.files-changed.outputs.merge_base != '' && |
| 68 | + (needs.files-changed.outputs.testable_rules_changed == 'true' || needs.files-changed.outputs.testable_modified == 'true') |
| 69 | + needs: [files-changed] |
| 70 | + name: Jest |
| 71 | + # If you change the runs-on image, you must also change the runner in jest-balance.yml |
| 72 | + # so that the balancer runs in the same environment as the tests. |
| 73 | + runs-on: ubuntu-24.04 |
| 74 | + timeout-minutes: 30 |
| 75 | + strategy: |
| 76 | + # This helps not having to run multiple jobs because one fails, thus, reducing resource usage |
| 77 | + # and reducing the risk that one of many runs would turn red again (read: intermittent tests) |
| 78 | + fail-fast: false |
| 79 | + matrix: |
| 80 | + # XXX: When updating this, make sure you also update CI_NODE_TOTAL. |
| 81 | + instance: [0, 1, 2, 3] |
| 82 | + |
| 83 | + steps: |
| 84 | + - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 |
| 85 | + name: Checkout sentry |
| 86 | + with: |
| 87 | + # PRs need history so we can compute merge base for Jest --changedSince. |
| 88 | + # 100 is an arbitrary depth that will get most reasonable PRs' commits. |
| 89 | + fetch-depth: ${{ github.event_name == 'pull_request' && '100' || '1' }} |
| 90 | + |
| 91 | + - uses: ./.github/actions/setup-node-pnpm |
| 92 | + |
| 93 | + - name: Download jest-balance.json |
| 94 | + id: download-artifact |
| 95 | + uses: dawidd6/action-download-artifact@ac66b43f0e6a346234dd65d4d0c8fbb31cb316e5 # v11 |
| 96 | + with: |
| 97 | + workflow: 38531594 # jest-balancer.yml |
| 98 | + workflow_conclusion: success # The conclusion of the workflow we're looking for |
| 99 | + branch: master # The branch we're looking for |
| 100 | + name: jest-balance.json # Artifact name |
| 101 | + name_is_regexp: false |
| 102 | + path: tests/js/test-balancer/ # Directory where to extract artifact(s), defaults to the current directory |
| 103 | + search_artifacts: true # Search for the last workflow run whose stored the artifact we're looking for |
| 104 | + if_no_artifact_found: warn # Can be one of: "fail", "warn", "ignore" |
| 105 | + |
| 106 | + - name: jest |
| 107 | + env: |
| 108 | + GITHUB_PR_SHA: ${{ github.event.pull_request.head.sha || github.sha }} |
| 109 | + GITHUB_PR_REF: ${{ github.event.pull_request.head.ref || github.ref }} |
| 110 | + # XXX: CI_NODE_TOTAL must be hardcoded to the length of strategy.matrix.instance. |
| 111 | + # Otherwise, if there are other things in the matrix, using strategy.job-total |
| 112 | + # wouldn't be correct. |
| 113 | + CI_NODE_TOTAL: 4 |
| 114 | + CI_NODE_INDEX: ${{ matrix.instance }} |
| 115 | + # Disable testing-library from printing out any of of the DOM to |
| 116 | + # stdout. No one actually looks through this in CI, they're just |
| 117 | + # going to run it locally. |
| 118 | + # |
| 119 | + # This quiets up the logs quite a bit. |
| 120 | + DEBUG_PRINT_LIMIT: 0 |
| 121 | + MERGE_BASE: ${{ needs.files-changed.outputs.merge_base }} |
| 122 | + run: pnpm run test-ci --forceExit |
| 123 | + |
39 | 124 | typescript-native: |
40 | 125 | if: needs.files-changed.outputs.frontend_all == 'true' |
41 | 126 | needs: files-changed |
|
0 commit comments