Merge pull request #2068 from github/koesie10/remove-run-remote-query
Remove code to start a remote query run
This commit is contained in:
@@ -38,7 +38,6 @@ import {
|
||||
CliConfigListener,
|
||||
DistributionConfigListener,
|
||||
isCanary,
|
||||
isVariantAnalysisLiveResultsEnabled,
|
||||
joinOrderWarningThreshold,
|
||||
MAX_QUERIES,
|
||||
QueryHistoryConfigListener,
|
||||
@@ -1112,19 +1111,11 @@ async function activateWithInstalledDistribution(
|
||||
message: "Getting credentials",
|
||||
});
|
||||
|
||||
if (isVariantAnalysisLiveResultsEnabled()) {
|
||||
await variantAnalysisManager.runVariantAnalysis(
|
||||
uri || window.activeTextEditor?.document.uri,
|
||||
progress,
|
||||
token,
|
||||
);
|
||||
} else {
|
||||
await rqm.runRemoteQuery(
|
||||
uri || window.activeTextEditor?.document.uri,
|
||||
progress,
|
||||
token,
|
||||
);
|
||||
}
|
||||
await variantAnalysisManager.runVariantAnalysis(
|
||||
uri || window.activeTextEditor?.document.uri,
|
||||
progress,
|
||||
token,
|
||||
);
|
||||
} else {
|
||||
throw new Error(
|
||||
"Variant analysis requires the CodeQL Canary version to run.",
|
||||
|
||||
@@ -1,154 +0,0 @@
|
||||
import { EOL } from "os";
|
||||
import { Credentials } from "../common/authentication";
|
||||
import { RepositorySelection } from "./repository-selection";
|
||||
import { Repository } from "./shared/repository";
|
||||
import { RemoteQueriesResponse } from "./gh-api/remote-queries";
|
||||
import { submitRemoteQueries } from "./gh-api/gh-api-client";
|
||||
import {
|
||||
showAndLogErrorMessage,
|
||||
showAndLogExceptionWithTelemetry,
|
||||
showAndLogInformationMessage,
|
||||
} from "../helpers";
|
||||
import { asError, getErrorMessage } from "../pure/helpers-pure";
|
||||
import { pluralize } from "../pure/word";
|
||||
import { redactableError } from "../pure/errors";
|
||||
|
||||
export async function runRemoteQueriesApiRequest(
|
||||
credentials: Credentials,
|
||||
ref: string,
|
||||
language: string,
|
||||
repoSelection: RepositorySelection,
|
||||
controllerRepo: Repository,
|
||||
queryPackBase64: string,
|
||||
): Promise<void | RemoteQueriesResponse> {
|
||||
try {
|
||||
const response = await submitRemoteQueries(credentials, {
|
||||
ref,
|
||||
language,
|
||||
repositories: repoSelection.repositories,
|
||||
repositoryLists: repoSelection.repositoryLists,
|
||||
repositoryOwners: repoSelection.owners,
|
||||
queryPack: queryPackBase64,
|
||||
controllerRepoId: controllerRepo.id,
|
||||
});
|
||||
const { popupMessage, logMessage } = parseResponse(
|
||||
controllerRepo,
|
||||
response,
|
||||
);
|
||||
void showAndLogInformationMessage(popupMessage, {
|
||||
fullMessage: logMessage,
|
||||
});
|
||||
return response;
|
||||
} catch (error: any) {
|
||||
if (error.status === 404) {
|
||||
void showAndLogErrorMessage(
|
||||
`Controller repository was not found. Please make sure it's a valid repo name.${eol}`,
|
||||
);
|
||||
} else {
|
||||
void showAndLogExceptionWithTelemetry(
|
||||
redactableError(
|
||||
asError(error),
|
||||
)`Error submitting remote queries request: ${getErrorMessage(error)}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const eol = EOL;
|
||||
const eol2 = EOL + EOL;
|
||||
|
||||
// exported for testing only
|
||||
export function parseResponse(
|
||||
controllerRepo: Repository,
|
||||
response: RemoteQueriesResponse,
|
||||
) {
|
||||
const repositoriesQueried = response.repositories_queried;
|
||||
const repositoryCount = repositoriesQueried.length;
|
||||
|
||||
const popupMessage = `Successfully scheduled runs on ${pluralize(
|
||||
repositoryCount,
|
||||
"repository",
|
||||
"repositories",
|
||||
)}. [Click here to see the progress](https://github.com/${
|
||||
controllerRepo.fullName
|
||||
}/actions/runs/${response.workflow_run_id}).${
|
||||
response.errors
|
||||
? `${eol2}Some repositories could not be scheduled. See extension log for details.`
|
||||
: ""
|
||||
}`;
|
||||
|
||||
let logMessage = `Successfully scheduled runs on ${pluralize(
|
||||
repositoryCount,
|
||||
"repository",
|
||||
"repositories",
|
||||
)}. See https://github.com/${controllerRepo.fullName}/actions/runs/${
|
||||
response.workflow_run_id
|
||||
}.`;
|
||||
logMessage += `${eol2}Repositories queried:${eol}${repositoriesQueried.join(
|
||||
", ",
|
||||
)}`;
|
||||
if (response.errors) {
|
||||
const {
|
||||
invalid_repositories,
|
||||
repositories_without_database,
|
||||
private_repositories,
|
||||
cutoff_repositories,
|
||||
cutoff_repositories_count,
|
||||
} = response.errors;
|
||||
logMessage += `${eol2}Some repositories could not be scheduled.`;
|
||||
if (invalid_repositories?.length) {
|
||||
logMessage += `${eol2}${pluralize(
|
||||
invalid_repositories.length,
|
||||
"repository",
|
||||
"repositories",
|
||||
)} invalid and could not be found:${eol}${invalid_repositories.join(
|
||||
", ",
|
||||
)}`;
|
||||
}
|
||||
if (repositories_without_database?.length) {
|
||||
logMessage += `${eol2}${pluralize(
|
||||
repositories_without_database.length,
|
||||
"repository",
|
||||
"repositories",
|
||||
)} did not have a CodeQL database available:${eol}${repositories_without_database.join(
|
||||
", ",
|
||||
)}`;
|
||||
logMessage += `${eol}For each public repository that has not yet been added to the database service, we will try to create a database next time the store is updated.`;
|
||||
}
|
||||
if (private_repositories?.length) {
|
||||
logMessage += `${eol2}${pluralize(
|
||||
private_repositories.length,
|
||||
"repository",
|
||||
"repositories",
|
||||
)} not public:${eol}${private_repositories.join(", ")}`;
|
||||
logMessage += `${eol}When using a public controller repository, only public repositories can be queried.`;
|
||||
}
|
||||
if (cutoff_repositories_count) {
|
||||
logMessage += `${eol2}${pluralize(
|
||||
cutoff_repositories_count,
|
||||
"repository",
|
||||
"repositories",
|
||||
)} over the limit for a single request`;
|
||||
if (cutoff_repositories) {
|
||||
logMessage += `:${eol}${cutoff_repositories.join(", ")}`;
|
||||
if (cutoff_repositories_count !== cutoff_repositories.length) {
|
||||
const moreRepositories =
|
||||
cutoff_repositories_count - cutoff_repositories.length;
|
||||
logMessage += `${eol}...${eol}And another ${pluralize(
|
||||
moreRepositories,
|
||||
"repository",
|
||||
"repositories",
|
||||
)}.`;
|
||||
}
|
||||
} else {
|
||||
logMessage += ".";
|
||||
}
|
||||
logMessage += `${eol}Repositories were selected based on how recently they had been updated.`;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
popupMessage,
|
||||
logMessage,
|
||||
};
|
||||
}
|
||||
@@ -1,29 +1,24 @@
|
||||
import {
|
||||
CancellationToken,
|
||||
commands,
|
||||
env,
|
||||
EventEmitter,
|
||||
ExtensionContext,
|
||||
Uri,
|
||||
env,
|
||||
} from "vscode";
|
||||
import { nanoid } from "nanoid";
|
||||
import { join } from "path";
|
||||
import { writeFile, readFile, remove, pathExists } from "fs-extra";
|
||||
import { pathExists, readFile, remove, writeFile } from "fs-extra";
|
||||
import { EOL } from "os";
|
||||
|
||||
import { CodeQLCliServer } from "../cli";
|
||||
import { ProgressCallback } from "../commandRunner";
|
||||
import {
|
||||
createTimestampFile,
|
||||
showAndLogErrorMessage,
|
||||
showAndLogExceptionWithTelemetry,
|
||||
showAndLogInformationMessage,
|
||||
showInformationMessageWithAction,
|
||||
} from "../helpers";
|
||||
import { Logger } from "../common";
|
||||
import { prepareRemoteQueryRun } from "./run-remote-query";
|
||||
import { RemoteQueriesView } from "./remote-queries-view";
|
||||
import { buildRemoteQueryEntity, RemoteQuery } from "./remote-query";
|
||||
import { RemoteQuery } from "./remote-query";
|
||||
import { RemoteQueriesMonitor } from "./remote-queries-monitor";
|
||||
import {
|
||||
getRemoteQueryIndex,
|
||||
@@ -41,7 +36,6 @@ import { asError, assertNever, getErrorMessage } from "../pure/helpers-pure";
|
||||
import { QueryStatus } from "../query-status";
|
||||
import { DisposableObject } from "../pure/disposable-object";
|
||||
import { AnalysisResults } from "./shared/analysis-result";
|
||||
import { runRemoteQueriesApiRequest } from "./remote-queries-api";
|
||||
import { App } from "../common/app";
|
||||
import { redactableError } from "../pure/errors";
|
||||
|
||||
@@ -85,7 +79,7 @@ export class RemoteQueriesManager extends DisposableObject {
|
||||
constructor(
|
||||
ctx: ExtensionContext,
|
||||
private readonly app: App,
|
||||
private readonly cliServer: CodeQLCliServer,
|
||||
cliServer: CodeQLCliServer,
|
||||
private readonly storagePath: string,
|
||||
logger: Logger,
|
||||
) {
|
||||
@@ -167,62 +161,6 @@ export class RemoteQueriesManager extends DisposableObject {
|
||||
}
|
||||
}
|
||||
|
||||
public async runRemoteQuery(
|
||||
uri: Uri | undefined,
|
||||
progress: ProgressCallback,
|
||||
token: CancellationToken,
|
||||
): Promise<void> {
|
||||
const {
|
||||
actionBranch,
|
||||
base64Pack,
|
||||
repoSelection,
|
||||
queryFile,
|
||||
queryMetadata,
|
||||
controllerRepo,
|
||||
queryStartTime,
|
||||
language,
|
||||
} = await prepareRemoteQueryRun(
|
||||
this.cliServer,
|
||||
this.app.credentials,
|
||||
uri,
|
||||
progress,
|
||||
token,
|
||||
);
|
||||
|
||||
const apiResponse = await runRemoteQueriesApiRequest(
|
||||
this.app.credentials,
|
||||
actionBranch,
|
||||
language,
|
||||
repoSelection,
|
||||
controllerRepo,
|
||||
base64Pack,
|
||||
);
|
||||
|
||||
if (!apiResponse) {
|
||||
return;
|
||||
}
|
||||
|
||||
const workflowRunId = apiResponse.workflow_run_id;
|
||||
const repositoryCount = apiResponse.repositories_queried.length;
|
||||
const query = await buildRemoteQueryEntity(
|
||||
queryFile,
|
||||
queryMetadata,
|
||||
controllerRepo,
|
||||
queryStartTime,
|
||||
workflowRunId,
|
||||
language,
|
||||
repositoryCount,
|
||||
);
|
||||
|
||||
const queryId = this.createQueryId();
|
||||
|
||||
await this.prepareStorageDirectory(queryId);
|
||||
await this.storeJsonFile(queryId, "query.json", query);
|
||||
|
||||
this.remoteQueryAddedEventEmitter.fire({ queryId, query });
|
||||
void commands.executeCommand("codeQL.monitorRemoteQuery", queryId, query);
|
||||
}
|
||||
|
||||
public async monitorRemoteQuery(
|
||||
queryId: string,
|
||||
remoteQuery: RemoteQuery,
|
||||
@@ -389,25 +327,6 @@ export class RemoteQueriesManager extends DisposableObject {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a unique id for this query, suitable for determining the storage location for the downloaded query artifacts.
|
||||
* @returns A unique id for this query.
|
||||
*/
|
||||
private createQueryId(): string {
|
||||
return nanoid();
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares a directory for storing analysis results for a single query run.
|
||||
* This directory contains a timestamp file, which will be
|
||||
* used by the query history manager to determine when the directory
|
||||
* should be deleted.
|
||||
*
|
||||
*/
|
||||
private async prepareStorageDirectory(queryId: string): Promise<void> {
|
||||
await createTimestampFile(join(this.storagePath, queryId));
|
||||
}
|
||||
|
||||
private async getRemoteQueryResult(
|
||||
queryId: string,
|
||||
): Promise<RemoteQueryResult> {
|
||||
|
||||
@@ -1,8 +1,4 @@
|
||||
import { readFile } from "fs-extra";
|
||||
import { Repository as RemoteRepository } from "./repository";
|
||||
import { QueryMetadata } from "../pure/interface-types";
|
||||
import { getQueryName } from "./run-remote-query";
|
||||
import { Repository } from "./shared/repository";
|
||||
|
||||
export interface RemoteQuery {
|
||||
queryName: string;
|
||||
@@ -14,31 +10,3 @@ export interface RemoteQuery {
|
||||
actionsWorkflowRunId: number;
|
||||
repositoryCount: number;
|
||||
}
|
||||
|
||||
export async function buildRemoteQueryEntity(
|
||||
queryFilePath: string,
|
||||
queryMetadata: QueryMetadata | undefined,
|
||||
controllerRepo: Repository,
|
||||
queryStartTime: number,
|
||||
workflowRunId: number,
|
||||
language: string,
|
||||
repositoryCount: number,
|
||||
): Promise<RemoteQuery> {
|
||||
const queryName = getQueryName(queryMetadata, queryFilePath);
|
||||
const queryText = await readFile(queryFilePath, "utf8");
|
||||
const [owner, name] = controllerRepo.fullName.split("/");
|
||||
|
||||
return {
|
||||
queryName,
|
||||
queryFilePath,
|
||||
queryText,
|
||||
language,
|
||||
controllerRepository: {
|
||||
owner,
|
||||
name,
|
||||
},
|
||||
executionStartTime: queryStartTime,
|
||||
actionsWorkflowRunId: workflowRunId,
|
||||
repositoryCount,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -78,9 +78,6 @@ describe("Variant Analysis Manager", () => {
|
||||
|
||||
beforeEach(async () => {
|
||||
jest.spyOn(extLogger, "log").mockResolvedValue(undefined);
|
||||
jest
|
||||
.spyOn(config, "isVariantAnalysisLiveResultsEnabled")
|
||||
.mockReturnValue(false);
|
||||
|
||||
cancellationTokenSource = new CancellationTokenSource();
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { CancellationTokenSource, commands, extensions } from "vscode";
|
||||
import { CodeQLExtensionInterface } from "../../../../src/extension";
|
||||
import * as config from "../../../../src/config";
|
||||
|
||||
import * as ghApiClient from "../../../../src/remote-queries/gh-api/gh-api-client";
|
||||
import { VariantAnalysisMonitor } from "../../../../src/remote-queries/variant-analysis-monitor";
|
||||
@@ -46,10 +45,6 @@ describe("Variant Analysis Monitor", () => {
|
||||
const onVariantAnalysisChangeSpy = jest.fn();
|
||||
|
||||
beforeEach(async () => {
|
||||
jest
|
||||
.spyOn(config, "isVariantAnalysisLiveResultsEnabled")
|
||||
.mockReturnValue(false);
|
||||
|
||||
cancellationTokenSource = new CancellationTokenSource();
|
||||
|
||||
variantAnalysis = createMockVariantAnalysis({});
|
||||
|
||||
Reference in New Issue
Block a user