Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .github/workflows/nodejs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@ on:
jobs:
Job:
name: Node.js
uses: node-modules/github-actions/.github/workflows/node-test.yml@master
uses: node-modules/github-actions/.github/workflows/node-test-parallel.yml@test-parallel
Comment thread
fengmk2 marked this conversation as resolved.
Outdated
with:
os: 'ubuntu-latest, macos-latest, windows-latest'
version: '18.19.0, 18, 20, 22, 23'
parallel: 4
action_ref: 'test-parallel'
secrets:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"@types/mocha": "^10.0.10",
"@types/supertest": "^6.0.2",
"c8": "^10.0.0",
"ci-parallel-vars": "^1.0.1",
"detect-port": "^2.0.0",
"egg-ts-helper": "^3.0.0",
"globby": "^11.1.0",
Expand Down
17 changes: 16 additions & 1 deletion src/commands/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import { Args, Flags } from '@oclif/core';
import globby from 'globby';
import { importResolve, detectType, EggType } from '@eggjs/utils';
import { getChangedFilesForRoots } from 'jest-changed-files';
// @ts-expect-error no types
import ciParallelVars from 'ci-parallel-vars';
import { BaseCommand } from '../baseCommand.js';

const debug = debuglog('@eggjs/bin/commands/test');
Expand Down Expand Up @@ -166,14 +168,27 @@ export default class Test<T extends typeof Test> extends BaseCommand<T> {
pattern = pattern.concat([ '!test/fixtures', '!test/node_modules' ]);

// expand glob and skip node_modules and fixtures
const files = globby.sync(pattern, { cwd: flags.base });
let files = globby.sync(pattern, { cwd: flags.base });
files.sort();

if (files.length === 0) {
console.log('No test files found with pattern %o', pattern);
return;
}

// split up test files in parallel CI jobs
if (ciParallelVars) {
const { index: currentIndex, total: totalRuns } = ciParallelVars as { index: number, total: number };
const fileCount = files.length;
const each = Math.floor(fileCount / totalRuns);
const remainder = fileCount % totalRuns;
const offset = Math.min(currentIndex, remainder) + (currentIndex * each);
const currentFileCount = each + (currentIndex < remainder ? 1 : 0);
files = files.slice(offset, offset + currentFileCount);
console.log('# Split test files in parallel CI jobs: %d/%d, files: %d/%d',
currentIndex + 1, totalRuns, files.length, fileCount);
}
Comment thread
fengmk2 marked this conversation as resolved.

// auto add setup file as the first test file
const setupFile = path.join(flags.base, `test/.setup.${ext}`);
try {
Expand Down
18 changes: 18 additions & 0 deletions test/commands/test.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,24 @@ describe('test/commands/test.test.ts', () => {
.end();
});

it('should work on split test files in parallel CI jobs', () => {
return coffee.fork(eggBin, [ 'test' ], {
cwd,
env: {
CI_NODE_INDEX: '2',
CI_NODE_TOTAL: '3',
},
})
// .debug()
.expect('stdout', /# Split test files in parallel CI jobs: 3\/3, files: 1\/4/)
.expect('stdout', /should success/)
.expect('stdout', /no-timeouts\.test\.js/)
.notExpect('stdout', /a\.test\.js/)
.expect('stdout', /1 passing \(/)
.expect('code', 0)
.end();
});

it('should success with some files', async () => {
await coffee.fork(eggBin, [ 'test', 'test/a.test.js' ], { cwd })
// .debug()
Expand Down