Skip to content

Commit 02f4be1

Browse files
authored
test(vscode): keep E2E fixture installs under the release-age gate (#56)
The dependency-recovery E2E tests failed on main whenever a transitive third-party dependency of a fixture was younger than pnpm's minimumReleaseAge: setupFixtures.mjs resolved the lockfile with minimumReleaseAge=0, and the tests' frozen re-install in a tmpdir copy ran under pnpm 11's default policy, which re-verifies lockfile entries. - Every E2E fixture now has a committed, settings-only pnpm-workspace.yaml that makes it its own workspace root and exempts the Rstack family via minimumReleaseAgeExclude. The file takes effect at install time like the root one, and travels with the tmpdir copy, so both installs share one policy. Nothing is generated at setup. - setupFixtures.mjs drops --ignore-workspace (pnpm ignores the file's settings under it) and --config.minimumReleaseAge=0. - Add @rspack/* to the root exclude list; the fixture files repeat the root list verbatim. - Both recovery tests install through a shared e2e/pnpmInstall.ts helper that includes pnpm's stdout and stderr in the error when the install fails; pnpm 11 prints its errors to stdout.
1 parent ca374a3 commit 02f4be1

13 files changed

Lines changed: 134 additions & 39 deletions

File tree

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# E2E fixture install config; rationale in packages/vscode/e2e/setupFixtures.mjs.
2+
minimumReleaseAgeExclude:
3+
- rstack
4+
- '@rslint/core'
5+
- '@rstest/core'
6+
- '@rsbuild/core'
7+
- '@rslib/core'
8+
- '@rstackjs/*'
9+
- rsbuild-plugin-dts
10+
- '@rspack/*'
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# E2E fixture install config; rationale in packages/vscode/e2e/setupFixtures.mjs.
2+
minimumReleaseAgeExclude:
3+
- rstack
4+
- '@rslint/core'
5+
- '@rstest/core'
6+
- '@rsbuild/core'
7+
- '@rslib/core'
8+
- '@rstackjs/*'
9+
- rsbuild-plugin-dts
10+
- '@rspack/*'
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# E2E fixture install config; rationale in packages/vscode/e2e/setupFixtures.mjs.
2+
minimumReleaseAgeExclude:
3+
- rstack
4+
- '@rslint/core'
5+
- '@rstest/core'
6+
- '@rsbuild/core'
7+
- '@rslib/core'
8+
- '@rstackjs/*'
9+
- rsbuild-plugin-dts
10+
- '@rspack/*'
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# E2E fixture install config; rationale in packages/vscode/e2e/setupFixtures.mjs.
2+
minimumReleaseAgeExclude:
3+
- rstack
4+
- '@rslint/core'
5+
- '@rstest/core'
6+
- '@rsbuild/core'
7+
- '@rslib/core'
8+
- '@rstackjs/*'
9+
- rsbuild-plugin-dts
10+
- '@rspack/*'
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# E2E fixture install config; rationale in packages/vscode/e2e/setupFixtures.mjs.
2+
minimumReleaseAgeExclude:
3+
- rstack
4+
- '@rslint/core'
5+
- '@rstest/core'
6+
- '@rsbuild/core'
7+
- '@rslib/core'
8+
- '@rstackjs/*'
9+
- rsbuild-plugin-dts
10+
- '@rspack/*'
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# E2E fixture install config; rationale in packages/vscode/e2e/setupFixtures.mjs.
2+
minimumReleaseAgeExclude:
3+
- rstack
4+
- '@rslint/core'
5+
- '@rstest/core'
6+
- '@rsbuild/core'
7+
- '@rslib/core'
8+
- '@rstackjs/*'
9+
- rsbuild-plugin-dts
10+
- '@rspack/*'

‎packages/vscode/e2e/lint/suite-dependency-recovery/dependency-recovery.test.ts‎

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,12 @@
11
import * as assert from 'node:assert';
2-
import { execFile as execFileCallback } from 'node:child_process';
32
import fs from 'node:fs';
43
import path from 'node:path';
5-
import { promisify } from 'node:util';
64
import * as vscode from 'vscode';
5+
import { pnpmInstallFrozen } from '../../pnpmInstall';
76
import type { StackState } from '../../../src/types';
87
import { waitForRslintDiagnostics } from '../utils/diagnostics';
98
import { extensionExports } from '../utils/extension';
109

11-
const execFile = promisify(execFileCallback);
12-
1310
function lintExports(): {
1411
getFolderStates(): ReadonlyMap<string, StackState>;
1512
} {
@@ -61,17 +58,7 @@ suite('Rslint dependency polling recovery', function () {
6158
const beforeContents = fs.readFileSync(lockfile);
6259
const beforeMtime = fs.statSync(lockfile).mtimeMs;
6360

64-
await execFile(
65-
'pnpm',
66-
['install', '--frozen-lockfile', '--ignore-scripts'],
67-
{
68-
cwd: root,
69-
timeout: 90_000,
70-
// Match setupFixtures.mjs/run.mjs: Windows needs a shell for pnpm's
71-
// .cmd shim. All arguments are fixed safe tokens; cwd is not interpolated.
72-
shell: process.platform === 'win32',
73-
},
74-
);
61+
await pnpmInstallFrozen(root);
7562

7663
assert.deepStrictEqual(
7764
fs.readFileSync(lockfile),

‎packages/vscode/e2e/pnpmInstall.ts‎

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { execFile as execFileCallback } from 'node:child_process';
2+
import { promisify } from 'node:util';
3+
4+
const execFile = promisify(execFileCallback);
5+
6+
/**
7+
* Runs `pnpm install --frozen-lockfile --ignore-scripts` in `cwd`. pnpm 11
8+
* prints install errors (e.g. ERR_PNPM_MINIMUM_RELEASE_AGE_VIOLATION) to
9+
* stdout, while execFile's error message carries only stderr, so a failure
10+
* rethrows with both streams appended.
11+
*/
12+
export async function pnpmInstallFrozen(cwd: string): Promise<void> {
13+
try {
14+
await execFile(
15+
'pnpm',
16+
['install', '--frozen-lockfile', '--ignore-scripts'],
17+
{
18+
cwd,
19+
timeout: 90_000,
20+
// Windows needs a shell for pnpm's .cmd shim; the arguments are fixed
21+
// safe tokens and cwd is not interpolated.
22+
shell: process.platform === 'win32',
23+
},
24+
);
25+
} catch (error) {
26+
const { stdout = '', stderr = '' } = error as {
27+
stdout?: string;
28+
stderr?: string;
29+
};
30+
throw new Error(`${(error as Error).message}\n${stdout}${stderr}`, {
31+
cause: error,
32+
});
33+
}
34+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# E2E fixture install config; rationale in packages/vscode/e2e/setupFixtures.mjs.
2+
minimumReleaseAgeExclude:
3+
- rstack
4+
- '@rslint/core'
5+
- '@rstest/core'
6+
- '@rsbuild/core'
7+
- '@rslib/core'
8+
- '@rstackjs/*'
9+
- rsbuild-plugin-dts
10+
- '@rspack/*'
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# E2E fixture install config; rationale in packages/vscode/e2e/setupFixtures.mjs.
2+
minimumReleaseAgeExclude:
3+
- rstack
4+
- '@rslint/core'
5+
- '@rstest/core'
6+
- '@rsbuild/core'
7+
- '@rslib/core'
8+
- '@rstackjs/*'
9+
- rsbuild-plugin-dts
10+
- '@rspack/*'

0 commit comments

Comments
 (0)