Skip to content

Commit 8521541

Browse files
committed
[ci] Improve parallelism of yarn test
This PR adds parallelism similar to our existing circleci setup for running yarn tests with the various test params. It does this by sharding tests into `$SHARD_COUNT` number of groups, then spawning a job for each of them and using jest's built in `--shard` option. Effectively this means that the job will spawn an additional (where `n` is the number of test params) `n * $SHARD_COUNT` number of jobs to run tests in parallel for a total of `n + (n * $SHARD_COUNT)` jobs. This does mean the GitHub UI at the bottom of each PR gets longer and unfortunately it's not sorted in any way as far as I can tell. But if something goes wrong it should still be easy to find out what the problem is. The PR also changes the `ci` argument for jest-cli to be an enum instead so the tests use all available workers in GitHub actions. This will have to live around for a bit until we can fully migrate off of circleci. ghstack-source-id: 08f2d16353aeca7cd15655d5ce2b7963a12507a7 Pull Request resolved: #30033
1 parent 28c1336 commit 8521541

File tree

5 files changed

+81
-45
lines changed

5 files changed

+81
-45
lines changed

Diff for: .circleci/config.yml

+3-3
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,7 @@ jobs:
281281
at: .
282282
- setup_node_modules
283283
- run: ./scripts/circleci/download_devtools_regression_build.js << parameters.version >> --replaceBuild
284-
- run: node ./scripts/jest/jest-cli.js --build --project devtools --release-channel=experimental --reactVersion << parameters.version >> --ci
284+
- run: node ./scripts/jest/jest-cli.js --build --project devtools --release-channel=experimental --reactVersion << parameters.version >> --ci=circleci
285285

286286
run_devtools_e2e_tests_for_versions:
287287
docker: *docker
@@ -368,7 +368,7 @@ jobs:
368368
steps:
369369
- checkout
370370
- setup_node_modules
371-
- run: yarn test <<parameters.args>> --ci
371+
- run: yarn test <<parameters.args>> --ci=circleci
372372

373373
yarn_test_build:
374374
docker: *docker
@@ -382,7 +382,7 @@ jobs:
382382
- attach_workspace:
383383
at: .
384384
- setup_node_modules
385-
- run: yarn test --build <<parameters.args>> --ci
385+
- run: yarn test --build <<parameters.args>> --ci=circleci
386386

387387
RELEASE_CHANNEL_stable_yarn_test_dom_fixtures:
388388
docker: *docker

Diff for: .github/workflows/fuzz_tests.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -28,5 +28,5 @@ jobs:
2828
shell: bash
2929
- name: Run fuzz tests
3030
run: |-
31-
FUZZ_TEST_SEED=$RANDOM yarn test fuzz --ci
32-
FUZZ_TEST_SEED=$RANDOM yarn test --prod fuzz --ci
31+
FUZZ_TEST_SEED=$RANDOM yarn test fuzz --ci=github
32+
FUZZ_TEST_SEED=$RANDOM yarn test --prod fuzz --ci=github

Diff for: .github/workflows/runtime_test.yml

+57-27
Original file line numberDiff line numberDiff line change
@@ -7,37 +7,67 @@ on:
77
paths-ignore:
88
- 'compiler/**'
99

10+
env:
11+
# Number of workers (one per shard) to spawn
12+
SHARD_COUNT: 5
13+
1014
jobs:
15+
# Define the various test parameters and parallelism for this workflow
16+
build_test_params:
17+
name: Build test params
18+
runs-on: ubuntu-latest
19+
outputs:
20+
params: ${{ steps.define-params.outputs.result }}
21+
shard_id: ${{ steps.define-shards.outputs.result }}
22+
steps:
23+
- uses: actions/github-script@v7
24+
id: define-shards
25+
with:
26+
script: |
27+
function range(from, to) {
28+
const arr = [];
29+
for (let n = from; n <= to; n++) {
30+
arr.push(n);
31+
}
32+
return arr;
33+
}
34+
return range(1, process.env.SHARD_COUNT);
35+
- uses: actions/github-script@v7
36+
id: define-params
37+
with:
38+
script: |
39+
return [
40+
"-r=stable --env=development",
41+
"-r=stable --env=production",
42+
"-r=experimental --env=development",
43+
"-r=experimental --env=production",
44+
"-r=www-classic --env=development --variant=false",
45+
"-r=www-classic --env=production --variant=false",
46+
"-r=www-classic --env=development --variant=true",
47+
"-r=www-classic --env=production --variant=true",
48+
"-r=www-modern --env=development --variant=false",
49+
"-r=www-modern --env=production --variant=false",
50+
"-r=www-modern --env=development --variant=true",
51+
"-r=www-modern --env=production --variant=true",
52+
"-r=xplat --env=development --variant=false",
53+
"-r=xplat --env=development --variant=true",
54+
"-r=xplat --env=production --variant=false",
55+
"-r=xplat --env=production --variant=true",
56+
// TODO: Test more persistent configurations?
57+
"-r=stable --env=development --persistent",
58+
"-r=experimental --env=development --persistent"
59+
];
60+
61+
# Spawn a job for each shard for a given set of test params
1162
test:
12-
name: yarn test
63+
name: yarn test ${{ matrix.params }} (Shard ${{ matrix.shard_id }})
1364
runs-on: ubuntu-latest
14-
continue-on-error: true
65+
needs: build_test_params
1566
strategy:
1667
matrix:
17-
# Intentionally passing these as strings instead of creating a
18-
# separate parameter per CLI argument, since it's easier to
19-
# control/see which combinations we want to run.
20-
params: [
21-
"-r=stable --env=development",
22-
"-r=stable --env=production",
23-
"-r=experimental --env=development",
24-
"-r=experimental --env=production",
25-
"-r=www-classic --env=development --variant=false",
26-
"-r=www-classic --env=production --variant=false",
27-
"-r=www-classic --env=development --variant=true",
28-
"-r=www-classic --env=production --variant=true",
29-
"-r=www-modern --env=development --variant=false",
30-
"-r=www-modern --env=production --variant=false",
31-
"-r=www-modern --env=development --variant=true",
32-
"-r=www-modern --env=production --variant=true",
33-
"-r=xplat --env=development --variant=false",
34-
"-r=xplat --env=development --variant=true",
35-
"-r=xplat --env=production --variant=false",
36-
"-r=xplat --env=production --variant=true",
37-
# TODO: Test more persistent configurations?
38-
"-r=stable --env=development --persistent",
39-
"-r=experimental --env=development --persistent"
40-
]
68+
params: ${{ fromJSON(needs.build_test_params.outputs.params) }}
69+
shard_id: ${{ fromJSON(needs.build_test_params.outputs.shard_id) }}
70+
continue-on-error: true
4171
steps:
4272
- uses: actions/checkout@v4
4373
- uses: actions/setup-node@v4
@@ -52,4 +82,4 @@ jobs:
5282
path: "**/node_modules"
5383
key: ${{ runner.arch }}-${{ runner.os }}-modules-${{ hashFiles('yarn.lock') }}
5484
- run: yarn install --frozen-lockfile
55-
- run: yarn test ${{ matrix.params }} --ci
85+
- run: yarn test ${{ matrix.params }} --ci=github --shard=${{ matrix.shard_id }}/${{ env.SHARD_COUNT }}

Diff for: packages/react-dom/src/__tests__/ReactMultiChildText-test.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ const expectChildren = function (container, children) {
7777
* faster to render and update.
7878
*/
7979
describe('ReactMultiChildText', () => {
80-
jest.setTimeout(20000);
80+
jest.setTimeout(30000);
8181

8282
it('should correctly handle all possible children for render and update', async () => {
8383
await expect(async () => {

Diff for: scripts/jest/jest-cli.js

+18-12
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,8 @@ const argv = yargs
9191
ci: {
9292
describe: 'Run tests in CI',
9393
requiresArg: false,
94-
type: 'boolean',
95-
default: false,
94+
type: 'choices',
95+
choices: ['circleci', 'github'],
9696
},
9797
compactConsole: {
9898
alias: 'c',
@@ -309,10 +309,14 @@ function getCommandArgs() {
309309
}
310310

311311
// CI Environments have limited workers.
312-
if (argv.ci) {
312+
if (argv.ci === 'circleci') {
313313
args.push('--maxWorkers=2');
314314
}
315315

316+
if (argv.ci === 'github') {
317+
args.push('--maxConcurrency=10');
318+
}
319+
316320
// Push the remaining args onto the command.
317321
// This will send args like `--watch` to Jest.
318322
args.push(...argv._);
@@ -364,16 +368,18 @@ function main() {
364368
const envars = getEnvars();
365369
const env = Object.entries(envars).map(([k, v]) => `${k}=${v}`);
366370

367-
// Print the full command we're actually running.
368-
const command = `$ ${env.join(' ')} node ${args.join(' ')}`;
369-
console.log(chalk.dim(command));
371+
if (argv.ci !== 'github') {
372+
// Print the full command we're actually running.
373+
const command = `$ ${env.join(' ')} node ${args.join(' ')}`;
374+
console.log(chalk.dim(command));
370375

371-
// Print the release channel and project we're running for quick confirmation.
372-
console.log(
373-
chalk.blue(
374-
`\nRunning tests for ${argv.project} (${argv.releaseChannel})...`
375-
)
376-
);
376+
// Print the release channel and project we're running for quick confirmation.
377+
console.log(
378+
chalk.blue(
379+
`\nRunning tests for ${argv.project} (${argv.releaseChannel})...`
380+
)
381+
);
382+
}
377383

378384
// Print a message that the debugger is starting just
379385
// for some extra feedback when running the debugger.

0 commit comments

Comments
 (0)