Files
vscode/build/lib/preLaunch.ts
Robo 4b6f5e55bb chore: bump electron@42.5.0 (#321629)
* chore: bump electron@42.4.0

* chore: apply temp dir workaround for short paths

* chore: use 24.15.x for CI node

* chore: update nodejs build

* chore: bump electron@42.5.0

* fix: unblock playwright install on node 24.17

Node 24.16+ made Readable pause()/resume() a no-op on destroyed streams
which makes yauzl 2.x / extract-zip 2.x and older playwright extraction
hang forever.

- extensions/copilot: add "yauzl": "^3.3.1" override (was missed by #318682)
  so electron and @vscode/vsce no longer resolve the broken yauzl 2.10, fixing the
  hung `npm ci` in the Copilot and Extract chat-lib pipelines.
- extensions/copilot: bump electron ^39.8.5 -> ^42.5.0 so its install
  script uses the native @electron-internal/extract-zip instead of extract-zip.
- bump @playwright/test ^1.56.1 -> ^1.61.1 so `playwright install`
  uses the fixed extractor, unblocking the "Download Electron and
  Playwright" step in all electron test pipelines.

* chore: update build

* agentHost: fix macOS sandbox smoke sentinel parsing

On macOS CI, the AgentHost sandbox smoke test resolves the shell to
/bin/sh, which uses the sentinel-based completion path. In that path, the
parser could consume the echoed sentinel command text
(`<<<COPILOT_SENTINEL_..._EXIT_$?>>>`) before the real numeric marker
arrived, causing a false `Exit code: -1` failure even though the command
later completed successfully.

Harden the sentinel parser to ignore echoed/non-numeric sentinel text
and use the latest complete numeric marker instead. Also force the
macOS AgentHost sandbox smoke test to use /bin/sh and assert that in the
suite log so local runs exercise the same path as CI.

Adds a regression test for echoed sentinel command text.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* chore: update screenshot baseline after playwright bump

* chore: bump distro

* chore: fix typecheck

* chore: bump distro

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-29 13:53:48 +00:00

82 lines
2.7 KiB
TypeScript

/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import path from 'path';
import { spawn } from 'child_process';
import { promises as fs } from 'fs';
const npm = process.platform === 'win32' ? 'npm.cmd' : 'npm';
const rootDir = path.resolve(import.meta.dirname, '..', '..');
function runProcess(command: string, args: ReadonlyArray<string> = []) {
return new Promise<void>((resolve, reject) => {
const child = spawn(command, args, { cwd: rootDir, stdio: 'inherit', env: process.env, shell: process.platform === 'win32' });
child.on('exit', err => !err ? resolve() : process.exit(err ?? 1));
child.on('error', reject);
});
}
async function exists(subdir: string) {
try {
await fs.stat(path.join(rootDir, subdir));
return true;
} catch {
return false;
}
}
async function ensureNodeModules() {
if (!(await exists('node_modules'))) {
await runProcess(npm, ['ci']);
}
}
async function getElectron() {
// `npm run electron` deletes and re-downloads `.build/electron` on every
// invocation. When preLaunch runs repeatedly (e.g. once per integration test
// section) this is both wasteful and a source of flaky failures on Windows,
// where the just-exited Electron process can still hold file locks while the
// directory is being removed and re-extracted. Skip the refresh when the
// already-present Electron matches the expected version; any detection
// failure falls back to a (re)download to preserve the previous behavior.
if (await isExpectedElectronInstalled()) {
return;
}
await runProcess(npm, ['run', 'electron']);
}
async function isExpectedElectronInstalled(): Promise<boolean> {
try {
const { getElectronVersion } = await import('./util.ts');
const { electronVersion } = getElectronVersion();
const installedVersion = (await fs.readFile(path.join(rootDir, '.build', 'electron', 'version'), 'utf8')).trim().replace(/^v/, '');
return installedVersion === electronVersion;
} catch {
return false;
}
}
async function ensureCompiled() {
if (!(await exists('out'))) {
await runProcess(npm, ['run', 'compile']);
}
}
async function main() {
await ensureNodeModules();
await getElectron();
await ensureCompiled();
// Can't require this until after dependencies are installed
const { getBuiltInExtensions } = await import('./builtInExtensions.ts');
await getBuiltInExtensions();
}
if (import.meta.main) {
main().catch(err => {
console.error(err);
process.exit(1);
});
}