Merge pull request #2068 from github/koesie10/remove-run-remote-query

Remove code to start a remote query run
This commit is contained in:
Koen Vlaswinkel
2023-02-13 15:46:10 +01:00
committed by GitHub
6 changed files with 9 additions and 293 deletions

View File

@@ -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.",

View File

@@ -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,
};
}

View File

@@ -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> {

View File

@@ -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,
};
}

View File

@@ -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();

View File

@@ -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({});