mirror of
https://github.com/n8n-io/n8n.git
synced 2026-06-03 18:27:09 +02:00
ci: Build tsc deps and surface vitest stderr in grind workflow (#31543)
Co-authored-by: n8n-cat-bot[bot] <n8n-cat-bot[bot]@users.noreply.github.com> Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
790a8da6af
commit
0cb26bdea9
29
.github/scripts/grind-changed-tests.mjs
vendored
29
.github/scripts/grind-changed-tests.mjs
vendored
|
|
@ -112,12 +112,14 @@ for (const file of files) {
|
|||
}
|
||||
}
|
||||
|
||||
const stderr = res.stderr ?? '';
|
||||
|
||||
if (!parsed) {
|
||||
rows.push({ file, status: 'no-result' });
|
||||
rows.push({ file, status: 'no-result', stderr });
|
||||
continue;
|
||||
}
|
||||
|
||||
rows.push({ file, status: 'ran', passed: parsed.passed, total: parsed.total });
|
||||
rows.push({ file, status: 'ran', passed: parsed.passed, total: parsed.total, stderr });
|
||||
}
|
||||
|
||||
// --- Render markdown ---
|
||||
|
|
@ -131,6 +133,28 @@ const renderRow = ({ file, status, passed, total }) => {
|
|||
return `| \`${file}\` | ${fraction} ⚠️ flaky |`;
|
||||
};
|
||||
|
||||
const STDERR_EXCERPT_LINES = 20;
|
||||
|
||||
const renderDiagnostic = ({ file, stderr }) => {
|
||||
const lines = stderr.split('\n');
|
||||
const truncated = lines.length > STDERR_EXCERPT_LINES;
|
||||
const excerpt = lines.slice(0, STDERR_EXCERPT_LINES).join('\n');
|
||||
const trailer = truncated ? `\n... (${lines.length - STDERR_EXCERPT_LINES} more lines)` : '';
|
||||
return [
|
||||
`<details><summary><code>${file}</code> — first failure stderr</summary>`,
|
||||
'',
|
||||
'```',
|
||||
excerpt + trailer,
|
||||
'```',
|
||||
'',
|
||||
'</details>',
|
||||
].join('\n');
|
||||
};
|
||||
|
||||
const diagnostics = rows
|
||||
.filter((r) => r.stderr && r.stderr.trim() && (r.status === 'no-result' || (r.status === 'ran' && r.passed < r.total)))
|
||||
.map(renderDiagnostic);
|
||||
|
||||
const body = [
|
||||
'<!-- grind-results -->',
|
||||
'## Grind results — pre-merge flake detection (N=' + n + ')',
|
||||
|
|
@ -139,6 +163,7 @@ const body = [
|
|||
'|---|---|',
|
||||
...rows.map(renderRow),
|
||||
'',
|
||||
...(diagnostics.length ? ['### First-failure diagnostics', '', ...diagnostics, ''] : []),
|
||||
'_Spawn-per-iteration mode. Catches post-teardown async flakes that `vitest --repeat` misses. See [DEVP-198](https://linear.app/n8n/issue/DEVP-198) for design notes._',
|
||||
'',
|
||||
].join('\n');
|
||||
|
|
|
|||
6
.github/workflows/grind-changed-tests.yml
vendored
6
.github/workflows/grind-changed-tests.yml
vendored
|
|
@ -33,7 +33,11 @@ jobs:
|
|||
- name: Setup Node.js
|
||||
uses: ./.github/actions/setup-nodejs
|
||||
with:
|
||||
build-command: ''
|
||||
# Build editor-ui's dependencies (e.g. @n8n/api-types) but not
|
||||
# editor-ui itself — Vitest transforms editor-ui sources on the fly,
|
||||
# while tsc-built deps must exist on disk for import resolution.
|
||||
# Turbo cache makes this near-instant on subsequent runs.
|
||||
build-command: 'pnpm --filter=n8n-editor-ui^... build'
|
||||
|
||||
- name: Install .github/scripts dependencies
|
||||
run: pnpm install --frozen-lockfile --dir ./.github/scripts --ignore-workspace
|
||||
|
|
|
|||
|
|
@ -98,12 +98,22 @@ const runnerArgs =
|
|||
: ['jest', fileRelToPkg, '--colors=false'];
|
||||
|
||||
let passed = 0;
|
||||
let firstFailureLogged = false;
|
||||
for (let i = 0; i < n; i++) {
|
||||
const res = spawnSync('pnpm', runnerArgs, {
|
||||
cwd: pkgRoot,
|
||||
stdio: values.json ? ['ignore', 'ignore', 'ignore'] : ['ignore', 'inherit', 'inherit'],
|
||||
stdio: values.json ? ['ignore', 'ignore', 'pipe'] : ['ignore', 'inherit', 'inherit'],
|
||||
encoding: 'utf8',
|
||||
});
|
||||
if (res.status === 0) passed++;
|
||||
if (res.status === 0) {
|
||||
passed++;
|
||||
} else if (values.json && !firstFailureLogged) {
|
||||
// Without this, JSON-mode invocations (used in CI) swallow every
|
||||
// vitest error message and leave authors with no diagnostic trail.
|
||||
firstFailureLogged = true;
|
||||
process.stderr.write(`\n[grind] first failing iteration for ${fileRelToPkg}:\n`);
|
||||
if (res.stderr) process.stderr.write(res.stderr);
|
||||
}
|
||||
if (!values.json) process.stdout.write(res.status === 0 ? '.' : 'F');
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user