Skip to content

Commit ac644d6

Browse files
committed
[ci] Improve parallelism of yarn test
Changes the `ci` argument to be an enum instead so the tests use all available workers in GitHub actions. - When `ci === 'github'` also increase maxConcurrency to 10 - Increase timeout of ReactMultiChildText-test.js - Chunk test files ghstack-source-id: 6c9b2f8344fd7159a73acf7c199f56c0b48ab6a4 Pull Request resolved: #30033
1 parent 6b54293 commit ac644d6

File tree

4 files changed

+99
-41
lines changed

4 files changed

+99
-41
lines changed

Diff for: .circleci/config.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -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

Diff for: .github/workflows/runtime_test.yml

+79-27
Original file line numberDiff line numberDiff line change
@@ -8,36 +8,86 @@ on:
88
- 'compiler/**'
99

1010
jobs:
11-
test:
12-
name: yarn test
11+
# Define the various test parameters and parallelism for this workflow
12+
build_test_params:
13+
name: Build test params
1314
runs-on: ubuntu-latest
15+
outputs:
16+
params: ${{ steps.define-params.outputs.result }}
17+
# How many chunks to group tests into
18+
parallelism: 5
19+
steps:
20+
- uses: actions/github-script@v7
21+
id: define-params
22+
with:
23+
script: |
24+
return [
25+
"-r=stable --env=development",
26+
"-r=stable --env=production",
27+
"-r=experimental --env=development",
28+
"-r=experimental --env=production",
29+
"-r=www-classic --env=development --variant=false",
30+
"-r=www-classic --env=production --variant=false",
31+
"-r=www-classic --env=development --variant=true",
32+
"-r=www-classic --env=production --variant=true",
33+
"-r=www-modern --env=development --variant=false",
34+
"-r=www-modern --env=production --variant=false",
35+
"-r=www-modern --env=development --variant=true",
36+
"-r=www-modern --env=production --variant=true",
37+
"-r=xplat --env=development --variant=false",
38+
"-r=xplat --env=development --variant=true",
39+
"-r=xplat --env=production --variant=false",
40+
"-r=xplat --env=production --variant=true",
41+
// TODO: Test more persistent configurations?
42+
"-r=stable --env=development --persistent",
43+
"-r=experimental --env=development --persistent"
44+
];
45+
46+
# Chunk tests into groups for parallelism
47+
chunk_tests:
48+
name: Chunk tests
49+
runs-on: ubuntu-latest
50+
needs: build_test_params
51+
strategy:
52+
matrix:
53+
params: ${{ fromJSON(needs.build_test_params.outputs.params) }}
1454
continue-on-error: true
55+
outputs:
56+
chunks: ${{ steps.chunks.outputs.chunks }}
57+
chunk_ids: ${{ steps.chunk_ids.outputs.chunk_ids }}
58+
steps:
59+
- uses: actions/checkout@v4
60+
- uses: actions/setup-node@v4
61+
with:
62+
node-version: 18.x
63+
cache: "yarn"
64+
cache-dependency-path: yarn.lock
65+
- name: Restore cached node_modules
66+
uses: actions/cache@v4
67+
id: node_modules
68+
with:
69+
path: "**/node_modules"
70+
key: ${{ runner.arch }}-${{ runner.os }}-modules-${{ hashFiles('yarn.lock') }}
71+
- run: yarn install --frozen-lockfile
72+
- id: chunks
73+
name: Set chunks
74+
run: echo "chunks=$(yarn --silent test ${{ matrix.params }} --listTests --json --ci=github | jq -cM '[_nwise(length / ${{ needs.build_test_params.outputs.parallelism }} | ceil)]')" >> $GITHUB_OUTPUT
75+
- id: chunk_ids
76+
name: Set chunk IDs
77+
run: echo "chunk_ids=$(echo $CHUNKS | jq -cM 'to_entries | map(.key)')" >> $GITHUB_OUTPUT
78+
env:
79+
CHUNKS: ${{ steps.chunks.outputs.chunks }}
80+
81+
# Spawn a job for each set of test param and number of chunks
82+
test:
83+
name: yarn test ${{ matrix.params }} (Chunk ${{ matrix.chunk_ids }})
84+
runs-on: ubuntu-latest
85+
needs: [build_test_params, chunk_tests]
1586
strategy:
1687
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-
]
88+
params: ${{ fromJSON(needs.build_test_params.outputs.params) }}
89+
chunk_ids: ${{ fromJSON(needs.chunk_tests.outputs.chunk_ids) }}
90+
continue-on-error: true
4191
steps:
4292
- uses: actions/checkout@v4
4393
- uses: actions/setup-node@v4
@@ -52,4 +102,6 @@ jobs:
52102
path: "**/node_modules"
53103
key: ${{ runner.arch }}-${{ runner.os }}-modules-${{ hashFiles('yarn.lock') }}
54104
- run: yarn install --frozen-lockfile
55-
- run: yarn test ${{ matrix.params }} --ci
105+
- run: echo $CHUNKS | jq '.[${{ matrix.chunk_ids }}] | .[] | @text' | xargs yarn test ${{ matrix.params }} --ci=github
106+
env:
107+
CHUNKS: ${{ needs.chunk_tests.outputs.chunks }}

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 --workerThreads=true');
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)