Summary
@mergifyio/vitest@0.3.0 (latest) breaks every test run in CI once the quarantine/flaky runner activates. MergifyReporter._configureRunner resolves the runner as dist/runner.js, but the package only ships dist/runner.mjs and dist/runner.cjs — there is no runner.js. Under Vitest 4.x this throws ERR_MODULE_NOT_FOUND and aborts the entire suite.
Root cause
_configureRunner builds the runner path with a hardcoded "runner.js":
// dist/index.mjs:116
const mergifyRunner = resolve(
typeof __dirname !== "undefined" ? __dirname : dirname(fileURLToPath(import.meta.url)),
"runner.js"
);
if (!vitest.config.runner) vitest.config.runner = mergifyRunner;
// dist/index.cjs:120
const mergifyRunner = (0, node_path.resolve)(/* … */, "runner.js");
But the build emits runner.mjs / runner.cjs (and the package exports map exposes them via ./runner → import: dist/runner.mjs, require: dist/runner.cjs). So the resolved absolute path …/dist/runner.js does not exist.
$ ls node_modules/@mergifyio/vitest/dist
index.cjs index.mjs runner.cjs runner.mjs … # no runner.js
Reproduction
- Vitest
4.1.8, @mergifyio/vitest@0.3.0, ESM vite.config.ts registering new MergifyReporter().
- In CI (
isInCI() true) with MERGIFY_TOKEN set and a non-empty quarantine list (so _configureRunner runs), every test errors:
Error: Cannot find module '…/node_modules/.pnpm/@mergifyio+vitest@0.3.0…/dist/runner.js'
imported from …/vitest/dist/module-evaluator.js
{ code: 'ERR_MODULE_NOT_FOUND', url: 'file://…/dist/runner.js' }
It passes locally only because the reporter is gated on isInCI().
Suggested fix
Resolve the runner via the package's own ./runner export (so the correct .mjs/.cjs is chosen per build), e.g.:
const mergifyRunner = fileURLToPath(import.meta.resolve("@mergifyio/vitest/runner"));
or emit the runner with the same extension the entry resolves (runner.mjs from index.mjs, runner.cjs from index.cjs).
Workaround (for others hitting this)
Pre-pin the runner in your Vitest config so the reporter's broken assignment is skipped:
import { fileURLToPath } from "node:url";
const mergifyRunner = fileURLToPath(import.meta.resolve("@mergifyio/vitest/runner"));
export default defineConfig({
test: {
runner: mergifyRunner,
reporters: ["default", new MergifyReporter()],
},
});
Thanks for the plugin! Happy to test a patch.
Summary
@mergifyio/vitest@0.3.0(latest) breaks every test run in CI once the quarantine/flaky runner activates.MergifyReporter._configureRunnerresolves the runner asdist/runner.js, but the package only shipsdist/runner.mjsanddist/runner.cjs— there is norunner.js. Under Vitest 4.x this throwsERR_MODULE_NOT_FOUNDand aborts the entire suite.Root cause
_configureRunnerbuilds the runner path with a hardcoded"runner.js":But the build emits
runner.mjs/runner.cjs(and the packageexportsmap exposes them via./runner→import: dist/runner.mjs,require: dist/runner.cjs). So the resolved absolute path…/dist/runner.jsdoes not exist.Reproduction
4.1.8,@mergifyio/vitest@0.3.0, ESMvite.config.tsregisteringnew MergifyReporter().isInCI()true) withMERGIFY_TOKENset and a non-empty quarantine list (so_configureRunnerruns), every test errors:It passes locally only because the reporter is gated on
isInCI().Suggested fix
Resolve the runner via the package's own
./runnerexport (so the correct.mjs/.cjsis chosen per build), e.g.:or emit the runner with the same extension the entry resolves (
runner.mjsfromindex.mjs,runner.cjsfromindex.cjs).Workaround (for others hitting this)
Pre-pin the runner in your Vitest config so the reporter's broken assignment is skipped:
Thanks for the plugin! Happy to test a patch.