Merge pull request #3569 from github/robertbrignull/ghec_dr_mode

Detect when the github-enterprise.uri setting is set
This commit is contained in:
Robert
2024-04-17 11:06:26 +01:00
committed by GitHub
6 changed files with 219 additions and 4 deletions

View File

@@ -4,7 +4,7 @@ import type {
ConfigurationScope,
Event,
} from "vscode";
import { ConfigurationTarget, EventEmitter, workspace } from "vscode";
import { ConfigurationTarget, EventEmitter, workspace, Uri } from "vscode";
import type { DistributionManager } from "./codeql-cli/distribution";
import { extLogger } from "./common/logging/vscode";
import { ONE_DAY_IN_MS } from "./common/time";
@@ -14,6 +14,7 @@ import {
SortKey,
} from "./variant-analysis/shared/variant-analysis-filter-sort";
import { substituteConfigVariables } from "./common/config-template";
import { getErrorMessage } from "./common/helpers-pure";
export const ALL_SETTINGS: Setting[] = [];
@@ -69,6 +70,52 @@ export const VSCODE_SAVE_BEFORE_START_SETTING = new Setting(
VSCODE_DEBUG_SETTING,
);
const VSCODE_GITHUB_ENTERPRISE_SETTING = new Setting(
"github-enterprise",
undefined,
);
export const VSCODE_GITHUB_ENTERPRISE_URI_SETTING = new Setting(
"uri",
VSCODE_GITHUB_ENTERPRISE_SETTING,
);
/**
* Get the value of the `github-enterprise.uri` setting, parsed as a URI.
* If the value is not set or cannot be parsed, return `undefined`.
*/
export function getEnterpriseUri(): Uri | undefined {
const config = VSCODE_GITHUB_ENTERPRISE_URI_SETTING.getValue<string>();
if (config) {
try {
let uri = Uri.parse(config, true);
if (uri.scheme === "http") {
uri = uri.with({ scheme: "https" });
}
return uri;
} catch (e) {
void extLogger.log(
`Failed to parse the GitHub Enterprise URI: ${getErrorMessage(e)}`,
);
}
}
return undefined;
}
/**
* Is the GitHub Enterprise URI set?
*/
export function hasEnterpriseUri(): boolean {
return getEnterpriseUri() !== undefined;
}
/**
* Is the GitHub Enterprise URI set to something that looks like GHEC-DR?
*/
export function hasGhecDrUri(): boolean {
const uri = getEnterpriseUri();
return uri !== undefined && uri.authority.toLowerCase().endsWith(".ghe.com");
}
const ROOT_SETTING = new Setting("codeQL");
// Telemetry configuration
@@ -576,6 +623,11 @@ export function getVariantAnalysisDefaultResultsSort(): SortKey {
*/
const ACTION_BRANCH = new Setting("actionBranch", VARIANT_ANALYSIS_SETTING);
export const VARIANT_ANALYSIS_ENABLE_GHEC_DR = new Setting(
"enableGhecDr",
VARIANT_ANALYSIS_SETTING,
);
export function getActionBranch(): string {
return ACTION_BRANCH.getValue<string>() || "main";
}

View File

@@ -0,0 +1,18 @@
import {
VARIANT_ANALYSIS_ENABLE_GHEC_DR,
hasEnterpriseUri,
hasGhecDrUri,
} from "../config";
/**
* Determines whether MRVA should be enabled or not for the current GitHub host.
* This is based on the `github-enterprise.uri` setting.
*/
export function isVariantAnalysisEnabledForGitHubHost(): boolean {
return (
// MRVA is always enabled on github.com
!hasEnterpriseUri() ||
// MRVA can be enabled on GHEC-DR using a feature flag
(hasGhecDrUri() && !!VARIANT_ANALYSIS_ENABLE_GHEC_DR.getValue<boolean>())
);
}

View File

@@ -97,6 +97,8 @@ import { getOnDiskWorkspaceFolders } from "../common/vscode/workspace-folders";
import { findVariantAnalysisQlPackRoot } from "./ql";
import { resolveCodeScanningQueryPack } from "./code-scanning-pack";
import { isSarifResultsQueryKind } from "../common/query-metadata";
import { isVariantAnalysisEnabledForGitHubHost } from "./ghec-dr";
import { getEnterpriseUri } from "../config";
const maxRetryCount = 3;
@@ -327,6 +329,12 @@ export class VariantAnalysisManager
token: CancellationToken,
openViewAfterSubmission = true,
): Promise<number | undefined> {
if (!isVariantAnalysisEnabledForGitHubHost()) {
throw new Error(
`Multi-repository variant analysis is not enabled for ${getEnterpriseUri()}`,
);
}
await saveBeforeStart();
progress({

View File

@@ -1,6 +1,15 @@
import { CancellationTokenSource, commands, window, Uri } from "vscode";
import {
CancellationTokenSource,
commands,
window,
Uri,
ConfigurationTarget,
} from "vscode";
import { extLogger } from "../../../../src/common/logging/vscode";
import { setRemoteControllerRepo } from "../../../../src/config";
import {
VSCODE_GITHUB_ENTERPRISE_URI_SETTING,
setRemoteControllerRepo,
} from "../../../../src/config";
import * as ghApiClient from "../../../../src/variant-analysis/gh-api/gh-api-client";
import { isAbsolute, join } from "path";
@@ -99,6 +108,32 @@ describe("Variant Analysis Manager", () => {
await setRemoteControllerRepo("github/vscode-codeql");
});
it("fails if MRVA is not supported for this GHE URI", async () => {
await VSCODE_GITHUB_ENTERPRISE_URI_SETTING.updateValue(
"https://github.example.com",
ConfigurationTarget.Global,
);
const qlPackDetails: QlPackDetails = {
queryFiles: [getFileOrDir("data-remote-qlpack/in-pack.ql")],
qlPackRootPath: getFileOrDir("data-remote-qlpack"),
qlPackFilePath: getFileOrDir("data-remote-qlpack/qlpack.yml"),
language: QueryLanguage.Javascript,
};
await expect(
variantAnalysisManager.runVariantAnalysis(
qlPackDetails,
progress,
cancellationTokenSource.token,
),
).rejects.toThrow(
new Error(
"Multi-repository variant analysis is not enabled for https://github.example.com/",
),
);
});
it("should run a variant analysis that is part of a qlpack", async () => {
const filePath = getFileOrDir("data-remote-qlpack/in-pack.ql");
const qlPackRootPath = getFileOrDir("data-remote-qlpack");

View File

@@ -1,10 +1,14 @@
import { workspace } from "vscode";
import { ConfigurationTarget, workspace } from "vscode";
import type { ConfigListener } from "../../../src/config";
import {
CliConfigListener,
QueryHistoryConfigListener,
QueryServerConfigListener,
VSCODE_GITHUB_ENTERPRISE_URI_SETTING,
getEnterpriseUri,
hasEnterpriseUri,
hasGhecDrUri,
} from "../../../src/config";
import { vscodeGetConfigurationMock } from "../test-config";
@@ -126,3 +130,49 @@ describe("config listeners", () => {
return new Promise((resolve) => setTimeout(resolve, ms));
}
});
describe("enterprise URI", () => {
it("detects no enterprise URI when config value is not set", async () => {
expect(getEnterpriseUri()).toBeUndefined();
expect(hasEnterpriseUri()).toBe(false);
expect(hasGhecDrUri()).toBe(false);
});
it("detects no enterprise URI when config value is set to an invalid value", async () => {
await VSCODE_GITHUB_ENTERPRISE_URI_SETTING.updateValue(
"invalid-uri",
ConfigurationTarget.Global,
);
expect(getEnterpriseUri()).toBeUndefined();
expect(hasEnterpriseUri()).toBe(false);
expect(hasGhecDrUri()).toBe(false);
});
it("detects an enterprise URI when config value is set to a GHES URI", async () => {
await VSCODE_GITHUB_ENTERPRISE_URI_SETTING.updateValue(
"https://github.example.com",
ConfigurationTarget.Global,
);
expect(getEnterpriseUri()?.toString()).toBe("https://github.example.com/");
expect(hasEnterpriseUri()).toBe(true);
expect(hasGhecDrUri()).toBe(false);
});
it("detects a GHEC-DR URI when config value is set to a GHEC-DR URI", async () => {
await VSCODE_GITHUB_ENTERPRISE_URI_SETTING.updateValue(
"https://example.ghe.com",
ConfigurationTarget.Global,
);
expect(getEnterpriseUri()?.toString()).toBe("https://example.ghe.com/");
expect(hasEnterpriseUri()).toBe(true);
expect(hasGhecDrUri()).toBe(true);
});
it("Upgrades HTTP URIs to HTTPS", async () => {
await VSCODE_GITHUB_ENTERPRISE_URI_SETTING.updateValue(
"http://example.ghe.com",
ConfigurationTarget.Global,
);
expect(getEnterpriseUri()?.toString()).toBe("https://example.ghe.com/");
});
});

View File

@@ -0,0 +1,52 @@
import { ConfigurationTarget } from "vscode";
import {
VARIANT_ANALYSIS_ENABLE_GHEC_DR,
VSCODE_GITHUB_ENTERPRISE_URI_SETTING,
} from "../../../../src/config";
import { isVariantAnalysisEnabledForGitHubHost } from "../../../../src/variant-analysis/ghec-dr";
describe("checkVariantAnalysisEnabled", () => {
it("returns cleanly when no enterprise URI is set", async () => {
expect(isVariantAnalysisEnabledForGitHubHost()).toBe(true);
});
it("returns false when GHES enterprise URI is set and variant analysis feature flag is not set", async () => {
await VSCODE_GITHUB_ENTERPRISE_URI_SETTING.updateValue(
"https://github.example.com",
ConfigurationTarget.Global,
);
expect(isVariantAnalysisEnabledForGitHubHost()).toBe(false);
});
it("returns false when GHES enterprise URI is set and variant analysis feature flag is set", async () => {
await VSCODE_GITHUB_ENTERPRISE_URI_SETTING.updateValue(
"https://github.example.com",
ConfigurationTarget.Global,
);
await VARIANT_ANALYSIS_ENABLE_GHEC_DR.updateValue(
"true",
ConfigurationTarget.Global,
);
expect(isVariantAnalysisEnabledForGitHubHost()).toBe(false);
});
it("returns false when GHEC-DR URI is set and variant analysis feature flag is not set", async () => {
await VSCODE_GITHUB_ENTERPRISE_URI_SETTING.updateValue(
"https://example.ghe.com",
ConfigurationTarget.Global,
);
expect(isVariantAnalysisEnabledForGitHubHost()).toBe(false);
});
it("returns true when GHEC-DR URI is set and variant analysis feature flag is set", async () => {
await VSCODE_GITHUB_ENTERPRISE_URI_SETTING.updateValue(
"https://example.ghe.com",
ConfigurationTarget.Global,
);
await VARIANT_ANALYSIS_ENABLE_GHEC_DR.updateValue(
"true",
ConfigurationTarget.Global,
);
expect(isVariantAnalysisEnabledForGitHubHost()).toBe(true);
});
});