Files
vscode/.github/actions/detect-agent-host-e2e-changes/detect.ts
T
roblourensandCopilot 280a9749f7 [Perf] agentHost: isolate E2E storage on tmpfs (#340215)
* agentHost: trace flaky test phases (Written by Copilot)

Correlate restore, provider initialization, and database queue phases without changing deadlines, assertions, storage, or lifecycle ordering. Retain compact operation timings from successful hosts and sample Linux worker pressure outside the host processes. Add opt-in focused Linux replay and worker controls for measured CI comparisons.

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

* agentHost: isolate E2E storage (Written by Copilot)

Run Linux CI replay on a private executable tmpfs while retaining required disk-backed persistence and lifecycle coverage. Keep real SQLite files, durability settings, close/reopen, deletion, and host restarts unchanged. Add same-worker alternating storage experiments, mount diagnostics, and cleanup regression coverage.

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

* agentHost: isolate tmpfs outside checkout (Written by Copilot)

Keep provider test workspaces outside the repository so ancestor instruction discovery cannot inject checkout AGENTS.md into strict replay. Allocate a unique /tmp mount and remove only that owned directory after unmounting. Preserve wrapper failure and cleanup coverage.

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

* agentHost: document storage isolation (Written by Copilot)

Capture verified test-authoring guidance for instruction-safe temporary roots and separate RAM-backed semantics from required disk-backed lifecycle coverage.

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

* tests: organize storage runners (Written by Copilot)

Keep Agent Host E2E runners, coverage, and Windows launch support under test/integration/agentHost. Share the scoped tmpfs wrapper with built-in Git extension tests, retaining required disk-backed commit, worktree, and symlink coverage and separate test reports. Update integration entrypoints and CI change detection, and cover both-pass failure propagation.

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

* agentHost: narrow E2E storage scope (Written by Copilot)

Remove the Git extension adoption, production timing instrumentation, and experimental flaky-pipeline controls. Keep storage tooling scoped to Agent Host E2E, require detached-worktree archive/restart/deletion coverage on disk, and fail on filesystem probe errors. Remove the out-of-scope review findings rather than carrying unrelated changes.

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

* agentHost: fix relocated startup test (Written by Copilot)

Update the Agent Host E2E startup fixture to copy and launch test/integration/agentHost tooling. Select disk mode explicitly so the Electron-preparation regression remains independent of CI tmpfs defaults.

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

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-10-07 08:03:12 -07:00

98 lines
3.0 KiB
TypeScript

/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
interface IChangedFile {
readonly filename: string;
readonly previous_filename?: string;
}
interface IListFilesParameters {
readonly owner: string;
readonly repo: string;
readonly pull_number: number;
readonly per_page: number;
}
interface IGitHub {
readonly paginate: (method: object, parameters: IListFilesParameters) => Promise<readonly IChangedFile[]>;
readonly rest: { readonly pulls: { readonly listFiles: object } };
}
interface IContext {
readonly repo: { readonly owner: string; readonly repo: string };
readonly issue: { readonly number: number };
readonly payload: { readonly pull_request?: { readonly changed_files?: number } };
}
interface ICore {
info(message: string): void;
warning(message: string): void;
setOutput(name: string, value: string): void;
}
const exactPaths = new Set([
'.nvmrc',
'.npmrc',
'package.json',
'package-lock.json',
'product.json',
'scripts/test-integration.sh',
'scripts/test-integration.bat',
'scripts/test.sh',
'scripts/test.bat',
'src/vs/nls.ts',
]);
const pathPrefixes = [
'.github/actions/detect-agent-host-e2e-changes/',
'.github/workflows/pr',
'build/',
'src/bootstrap',
'src/tsconfig',
'src/vs/base/',
'src/vs/platform/',
'test/unit/electron/',
'test/integration/agentHost/',
];
function affectsAgentHostE2E(path: string): boolean {
if (path.endsWith('.md')) {
return false;
}
return exactPaths.has(path) || pathPrefixes.some(prefix => path.startsWith(prefix));
}
export async function detectAgentHostE2EChanges(github: IGitHub, context: IContext, core: ICore): Promise<void> {
let files: readonly IChangedFile[];
try {
files = await github.paginate(github.rest.pulls.listFiles, {
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: context.issue.number,
per_page: 100,
});
} catch (error) {
const message = error instanceof Error ? error.message : String(error);
core.warning(`Unable to list pull request files; running Agent Host E2E tests. ${message}`);
core.setOutput('affected', 'true');
return;
}
const paths = files.flatMap(file =>
file.previous_filename ? [file.filename, file.previous_filename] : [file.filename]);
const expectedFileCount = context.payload.pull_request?.changed_files;
const incomplete = typeof expectedFileCount === 'number' && files.length < expectedFileCount;
const affected = incomplete || paths.some(affectsAgentHostE2E);
if (incomplete) {
core.warning(`GitHub returned ${files.length} of ${expectedFileCount} changed files; running Agent Host E2E tests.`);
} else {
core.info(affected
? 'Agent Host E2E tests may be affected.'
: 'No changes can affect Agent Host E2E tests.');
}
core.setOutput('affected', affected ? 'true' : 'false');
}