Skip to content

Add custom-server support for variant analysis through companion extension support - #4636

Open
nicolaswill wants to merge 5 commits into
github:mainfrom
nicolaswill:nicolaswill-add-customer-extension
Open

nicolaswill wants to merge 5 commits into
github:mainfrom
nicolaswill:nicolaswill-add-customer-extension

Conversation

@nicolaswill

Copy link
Copy Markdown

This PR adds a configurable server for multi-repository variant analysis (MRVA). Submission, polling, task retrieval, and cancellation go through variant-analysis-api.ts, which selects GitHub or the configured endpoint.

Purpose:
To unblock GitHub Expert-Services-guided customer use of multi-repo variant analysis on GitHub Enterprise Server using existing tooling, in a stable, extensible way without breaking any existing logic.

Implementation:

  • A companion extension supplies getVariantAnalysisServerToken(serverUrl) and can implement openVariantAnalysisLogs(serverUrl, analysisId). This lets the companion handle sign-in, token refresh, and log presentation while CodeQL keeps the existing analysis UI. The server must implement the existing variant-analysis REST contract.
  • Adds hidden user settings, codeQL.variantAnalysis.serverUrl and codeQL.variantAnalysis.serverTokenProvider. Workspace values are ignored. Custom endpoints must use HTTPS; redirects are rejected. Custom submissions use controller repository ID 0, bypassing controller-repository setup.
  • Requests a companion-provided bearer token before each server request, with a combined 30-second limit for provider activation and token acquisition. The companion owns token refresh. GitHub credentials are not used for custom-server API requests.
  • Persists the originating server URL with each run and rejects API operations when the current configuration differs. Custom runs support cancellation without an Actions workflow ID. Optional log support is discovered asynchronously so history and results can render immediately.
  • Allows results without a commit SHA or source-location prefix. File links use the supplied repository URL and fall back to HEAD when the SHA is missing; unavailable repository URLs produce plain-text locations.
  • Retains local Markdown export for custom runs and blocks gist export. Adds regression coverage for routing, configuration isolation, persistence, cancellation, logs, and result handling.
  • Without a custom server configured, analysis requests continue to use GitHub. The settings are internal and unsupported, with the server and companion contracts documented in docs/variant-analysis-custom-server.md. This PR does not include either implementation.
  • Only one endpoint is active at a time. Managing a saved run from another endpoint requires restoring its configuration; managing a saved GitHub run requires removing the custom-server setting. Artifact URLs must work without an authorization header. Source links still assume /blob/{revision}, and canary autofix still retrieves source through GitHub.

Adds hidden, user/machine-scoped settings that send variant analysis
requests to a self-hosted server implementing the GitHub variant analysis
REST endpoints, authenticated with a bearer token supplied by a named
companion extension. GitHub sign-in, the github-enterprise.uri setting
and database downloads are unaffected. Internal and unsupported; see
docs/variant-analysis-custom-server.md.

Also tolerates repository tasks without a database commit SHA or source
location prefix, and implements inspect() in the vscode-tests config mock.
Persist the originating custom server with each run and reject requests when the configured endpoint changes. Reject redirects and endpoint query strings or fragments, and derive export and log availability from the saved run.

Share submission mapping across transports, use the existing settings abstraction for global-only reads, and reject malformed successful JSON responses while allowing empty cancellation responses. Consolidate VS Code-dependent regression cases into the no-workspace suite.
@nicolaswill
nicolaswill requested a review from a team as a code owner November 3, 2026 11:31
Copilot AI auto review requested due to automatic review settings November 3, 2026 11:31
Comment on lines +140 to +146
response: {
status: response.status,
url,
headers: {},
data,
retryCount: 0,
},
: "";
throw new RequestError(
`Variant analysis server request failed: ${method} ${path}: ${response.status} ${response.statusText}${describeErrorBody(data)}${authenticationMessage}`,
response.status,
? ` Re-authenticate using the token provider '${server.tokenProviderExtensionId}' and retry.`
: "";
throw new RequestError(
`Variant analysis server request failed: ${method} ${path}: ${response.status} ${response.statusText}${describeErrorBody(data)}${authenticationMessage}`,
Authorization: `Bearer ${token}`,
...(body === undefined ? {} : { "Content-Type": "application/json" }),
},
body: body === undefined ? undefined : JSON.stringify(body),
return requestVariantAnalysisServer<T>(server, method, path, body);
}
const octokit = await credentials.getOctokit();
return (await octokit.request<T>({ method, url: path, data: body })).data;

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Unresolved critical issues can misroute query-pack uploads, allow writes or deletion outside analysis storage, and mix or expose results through cross-server ID collisions.

8 open issues
What changed in this PR

Adds internal custom-server integration for multi-repository variant analysis, aimed at GitHub Enterprise Server deployments while reusing CodeQL’s existing history and results UI.

Changes:

  • Routes analysis operations to GitHub or a custom HTTPS endpoint using companion-provided authentication.
  • Persists server origins and repository URLs, and adapts logs, cancellation, source links, and exports for custom runs.
  • Documents the internal contracts and adds configuration, lifecycle, persistence, and rendering coverage.
File Description
extensions/​ql-vscode/​test/​vscode-tests/​test-config.ts Supports configuration inspection in tests.
extensions/​ql-vscode/​test/​vscode-tests/​no-workspace/​variant-analysis/​variant-analysis-api.test.ts Covers routing, authentication, logs, configuration isolation, and errors.
extensions/​ql-vscode/​test/​vscode-tests/​no-workspace/​variant-analysis/​gh-api-client.test.ts Exercises GitHub requests through the routing API.
extensions/​ql-vscode/​test/​vscode-tests/​no-workspace/​query-history/​store/​query-history-store.test.ts Tests persistence of server origins and repository URLs.
extensions/​ql-vscode/​test/​vscode-tests/​no-workspace/​query-history/​query-history-manager.test.ts Covers delegated logs and cancellation during removal.
extensions/​ql-vscode/​test/​vscode-tests/​no-workspace/​query-history/​history-tree-data-provider.test.ts Tests capability-based history actions.
extensions/​ql-vscode/​test/​vscode-tests/​cli-integration/​variant-analysis/​variant-analysis-manager.test.ts Updates submission mocks for the routing API.
extensions/​ql-vscode/​test/​vscode-tests/​activated-extension/​variant-analysis/​variant-analysis-results-manager.test.ts Covers custom repository links and plain-text fallbacks.
extensions/​ql-vscode/​test/​vscode-tests/​activated-extension/​variant-analysis/​variant-analysis-monitor.test.ts Updates polling mocks and cancellation-status coverage.
extensions/​ql-vscode/​test/​vscode-tests/​activated-extension/​variant-analysis/​variant-analysis-manager.test.ts Adds custom-server lifecycle, logs, and cancellation coverage.
extensions/​ql-vscode/​test/​unit-tests/​variant-analysis/​variant-analysis-mapper.test.ts Tests origin and source-URL preservation.
extensions/​ql-vscode/​test/​unit-tests/​variant-analysis/​markdown-generation.test.ts Tests Markdown locations without repository links.
extensions/​ql-vscode/​test/​unit-tests/​common/​bqrs-utils.test.ts Covers raw-result links with optional prefixes.
extensions/​ql-vscode/​src/​view/​variant-analysis/​VariantAnalysisStatusStats.tsx Uses server-neutral log-link wording.
extensions/​ql-vscode/​src/​view/​variant-analysis/​VariantAnalysisOutcomePanels.tsx Passes server and log capabilities to failure alerts.
extensions/​ql-vscode/​src/​view/​variant-analysis/​VariantAnalysis.tsx Renders custom runs without workflow IDs.
extensions/​ql-vscode/​src/​view/​variant-analysis/​RawResultsTable.tsx Accepts missing file-link prefixes.
extensions/​ql-vscode/​src/​view/​variant-analysis/​RawResultRow.tsx Propagates optional file-link prefixes.
extensions/​ql-vscode/​src/​view/​variant-analysis/​RawResultCell.tsx Supports cells without repository links.
extensions/​ql-vscode/​src/​view/​variant-analysis/​FailureReasonAlert.tsx Adapts failure messages and log actions for custom runs.
extensions/​ql-vscode/​src/​view/​variant-analysis/​__tests__/​VariantAnalysisStatusStats.spec.tsx Updates log-label expectations.
extensions/​ql-vscode/​src/​view/​variant-analysis/​__tests__/​VariantAnalysisStats.spec.tsx Updates log-action interaction coverage.
extensions/​ql-vscode/​src/​view/​variant-analysis/​__tests__/​VariantAnalysisOutcomePanels.spec.tsx Covers custom-server failure alerts and logs.
extensions/​ql-vscode/​src/​view/​variant-analysis/​__tests__/​VariantAnalysis.spec.tsx Tests rendering without workflow IDs.
extensions/​ql-vscode/​src/​view/​variant-analysis/​__tests__/​AnalyzedRepoItemContent.spec.tsx Tests plain-text locations without links.
extensions/​ql-vscode/​src/​view/​model-alerts/​ModelAlerts.tsx Uses shared log-capability checks.
extensions/​ql-vscode/​src/​view/​common/​FileCodeSnippet/​FileCodeSnippet.tsx Renders unlinked file titles as text.
extensions/​ql-vscode/​src/​view/​common/​FileCodeSnippet/​CodeSnippetMessage.tsx Renders unlinked message locations as text.
extensions/​ql-vscode/​src/​variant-analysis/​variant-analysis-view.ts Refreshes views after asynchronous log discovery.
extensions/​ql-vscode/​src/​variant-analysis/​variant-analysis-results-manager.ts Builds source links from repository URLs with revision fallbacks.
extensions/​ql-vscode/​src/​variant-analysis/​variant-analysis-monitor.ts Polls using the run’s originating server.
extensions/​ql-vscode/​src/​variant-analysis/​variant-analysis-mapper.ts Maps submissions and preserves server metadata.
extensions/​ql-vscode/​src/​variant-analysis/​variant-analysis-manager.ts Integrates custom routing, result loading, cancellation, and logs.
extensions/​ql-vscode/​src/​variant-analysis/​variant-analysis-api.ts Centralizes routing, origin checks, logs, and gist restrictions.
extensions/​ql-vscode/​src/​variant-analysis/​shared/​variant-analysis.ts Adds server-origin and runtime log-capability fields.
extensions/​ql-vscode/​src/​variant-analysis/​shared/​repository.ts Adds optional repository URLs.
extensions/​ql-vscode/​src/​variant-analysis/​shared/​analysis-result.ts Makes file-link prefixes optional.
extensions/​ql-vscode/​src/​variant-analysis/​sarif-processing.ts Propagates optional links through interpreted results.
extensions/​ql-vscode/​src/​variant-analysis/​run-remote-query.ts Bypasses controller-repository lookup for custom servers.
extensions/​ql-vscode/​src/​variant-analysis/​repo-tasks-store/​repo-tasks-dto.ts Adds repository URLs to stored task data.
extensions/​ql-vscode/​src/​variant-analysis/​repo-tasks-store/​repo-tasks-dto-mapper.ts Saves repository URLs with tasks.
extensions/​ql-vscode/​src/​variant-analysis/​repo-tasks-store/​repo-tasks-domain-mapper.ts Restores repository URLs from stored tasks.
extensions/​ql-vscode/​src/​variant-analysis/​markdown-generation.ts Emits plain-text locations when links are unavailable.
extensions/​ql-vscode/​src/​variant-analysis/​ghec-dr.ts Enables variant analysis with a configured custom server.
extensions/​ql-vscode/​src/​variant-analysis/​gh-api/​variant-analysis-server-client.ts Adds companion activation, token timeouts, and HTTPS requests.
extensions/​ql-vscode/​src/​variant-analysis/​gh-api/​repository.ts Accepts repository URLs in API responses.
extensions/​ql-vscode/​src/​variant-analysis/​gh-api/​gh-api-client.ts Moves analysis operations into the routing API.
extensions/​ql-vscode/​src/​variant-analysis/​export-results.ts Restricts custom runs to local Markdown export.
extensions/​ql-vscode/​src/​variant-analysis/​bqrs-processing.ts Accepts raw results without file-link prefixes.
extensions/​ql-vscode/​src/​query-history/​store/​query-history-variant-analysis-dto.ts Adds persisted origins and repository URLs.
extensions/​ql-vscode/​src/​query-history/​store/​query-history-variant-analysis-dto-mapper.ts Restores custom-server metadata from history.
extensions/​ql-vscode/​src/​query-history/​store/​query-history-variant-analysis-domain-mapper.ts Saves custom-server metadata to history.
extensions/​ql-vscode/​src/​query-history/​query-history-manager.ts Delegates logs and offers server cancellation during removal.
extensions/​ql-vscode/​src/​query-history/​history-tree-data-provider.ts Selects history actions using log capabilities.
extensions/​ql-vscode/​src/​model-editor/​model-alerts/​model-alerts-view.ts Refreshes model-alert log capabilities asynchronously.
extensions/​ql-vscode/​src/​extension.ts Registers log-capability configuration watching.
extensions/​ql-vscode/​src/​databases/​ui/​db-panel.ts Guards GitHub-opening actions in custom-server mode.
extensions/​ql-vscode/​src/​config.ts Reads hidden global settings and validates server URLs.
extensions/​ql-vscode/​src/​common/​location-link-utils.ts Omits remote references when link prefixes are unavailable.
extensions/​ql-vscode/​src/​common/​bqrs-utils.ts Omits raw-result links without a repository prefix.
extensions/​ql-vscode/​package.json Updates history actions and custom-server UI conditions.
docs/​variant-analysis-custom-server.md Documents settings, companion hooks, behavior, and server contracts.

Review effort: Max (auto)

Comment on lines +647 to +648
const value = setting.getGlobalValue<string>();
return typeof value === "string" && value.trim() ? value.trim() : undefined;
throw new Error("Variant analysis server returned an empty response.");
}

return data as T;
this.getVariantAnalysisStorageLocation(variantAnalysisId),
repositoryFullName,
options,
{ ...options, serverUrl: variantAnalysis.serverUrl },
"view": "codeQLVariantAnalysisRepositories",
"contents": "Set up a controller repository to start using variant analysis. [Learn more](https://codeql.github.com/docs/codeql-for-visual-studio-code/running-codeql-queries-at-scale-with-mrva#controller-repository) about controller repositories. \n[Set up controller repository](command:codeQLVariantAnalysisRepositories.setupControllerRepository)",
"when": "!config.codeQL.variantAnalysis.controllerRepo"
"when": "!config.codeQL.variantAnalysis.controllerRepo && !config.codeQL.variantAnalysis.serverUrl"
Comment on lines +675 to +676
url.search ||
url.hash
Comment on lines +625 to +628
const shouldCancel = await showInformationMessageWithAction(
"Removing this query from history will not stop the variant analysis running on the server.",
"Cancel variant analysis",
);
if (!run.serverUrl) {
return run.actionsWorkflowRunId !== undefined;
}
const server = getVariantAnalysisServerConfig();
if (
variantAnalysis === undefined ||
(variantAnalysis.status === VariantAnalysisStatus.InProgress &&
!variantAnalysis.serverUrl &&

@cklin cklin left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a very large PR, and it is in everyone's interest that the PR is as easy to review as possible. Given that this is an unsupported feature, a key focus of the review is that existing behavior remains unchanged.

To facilitate timely review, please restructure the PR into a series of self-contained commits, with each commit clearly labeled as being in one of the following four categories:

  1. Refactoring: The commit completely preserves existing behavior. For example, the commit extracts new functions, or moves functions from one file to another. Commits in this category should make it apparent that all behavior remain unchanged.
  2. Switching to custom-server support: The commit adds new behavior based on the hidden user settings (or based on consequences of those hidden user settings). There should be very few such commits, and they should be very small. Commits in this category should make it apparent that existing supported behavior (i.e., when the hidden settings are absent) remains unchanged.
  3. Adding custom-server support: The commit changes behavior, but the behavior change can only affect custom-server support. Commits in this category should make it apparent that code changes affect only custom-server support, for example, because it changes code paths that are used only by custom-server support.
  4. Non-production-code changes: The commit does not change production code. For example, it only adds documentation or tests.

Please reach out when the restructuring is done. Thanks!

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants