Merge pull request #1032 from github/remote-query-submission-result
Expose remote query submission result
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
import { RemoteQuery } from './remote-query';
|
||||
|
||||
export interface RemoteQuerySubmissionResult {
|
||||
queryDirPath?: string;
|
||||
query?: RemoteQuery;
|
||||
}
|
||||
10
extensions/ql-vscode/src/remote-queries/remote-query.ts
Normal file
10
extensions/ql-vscode/src/remote-queries/remote-query.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { Repository } from './repository';
|
||||
|
||||
export interface RemoteQuery {
|
||||
queryName: string;
|
||||
queryFilePath: string;
|
||||
controllerRepository: Repository;
|
||||
repositories: Repository[];
|
||||
executionStartTime: Date;
|
||||
actionsWorkflowRunId: number;
|
||||
}
|
||||
4
extensions/ql-vscode/src/remote-queries/repository.ts
Normal file
4
extensions/ql-vscode/src/remote-queries/repository.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
export interface Repository {
|
||||
owner: string;
|
||||
name: string;
|
||||
}
|
||||
@@ -12,6 +12,8 @@ import { tmpDir } from '../run-queries';
|
||||
import { ProgressCallback, UserCancellationException } from '../commandRunner';
|
||||
import { OctokitResponse } from '@octokit/types/dist-types';
|
||||
import * as unzipper from 'unzipper';
|
||||
import { RemoteQuery } from './remote-query';
|
||||
import { RemoteQuerySubmissionResult } from './remote-query-submission-result';
|
||||
|
||||
interface Config {
|
||||
repositories: string[];
|
||||
@@ -216,7 +218,7 @@ export async function runRemoteQuery(
|
||||
dryRun: boolean,
|
||||
progress: ProgressCallback,
|
||||
token: CancellationToken
|
||||
): Promise<void | string> {
|
||||
): Promise<void | RemoteQuerySubmissionResult> {
|
||||
if (!(await cliServer.cliConstraints.supportsRemoteQueries())) {
|
||||
throw new Error(`Remote queries are not supported by this version of CodeQL. Please upgrade to v${cli.CliVersionConstraint.CLI_VERSION_REMOTE_QUERIES
|
||||
} or later.`);
|
||||
@@ -320,13 +322,20 @@ export async function runRemoteQuery(
|
||||
message: 'Sending request'
|
||||
});
|
||||
|
||||
await runRemoteQueriesApiRequest(credentials, ref, language, repositories, owner, repo, base64Pack, dryRun);
|
||||
const workflowRunId = await runRemoteQueriesApiRequest(credentials, ref, language, repositories, owner, repo, base64Pack, dryRun);
|
||||
const queryStartTime = new Date();
|
||||
|
||||
if (dryRun) {
|
||||
return remoteQueryDir.path;
|
||||
return { queryDirPath: remoteQueryDir.path };
|
||||
} else {
|
||||
if (!workflowRunId) {
|
||||
return;
|
||||
}
|
||||
|
||||
const remoteQuery = buildRemoteQueryEntity(repositories, queryFile, owner, repo, queryStartTime, workflowRunId);
|
||||
|
||||
// don't return the path because it has been deleted
|
||||
return;
|
||||
return { query: remoteQuery };
|
||||
}
|
||||
|
||||
} finally {
|
||||
@@ -348,7 +357,7 @@ async function runRemoteQueriesApiRequest(
|
||||
repo: string,
|
||||
queryPackBase64: string,
|
||||
dryRun = false
|
||||
): Promise<void> {
|
||||
): Promise<void | number> {
|
||||
if (dryRun) {
|
||||
void showAndLogInformationMessage('[DRY RUN] Would have sent request. See extension log for the payload.');
|
||||
void logger.log(JSON.stringify({ ref, language, repositories, owner, repo, queryPackBase64: queryPackBase64.substring(0, 100) + '... ' + queryPackBase64.length + ' bytes' }));
|
||||
@@ -372,8 +381,9 @@ async function runRemoteQueriesApiRequest(
|
||||
);
|
||||
const workflowRunId = response.data.workflow_run_id;
|
||||
void showAndLogInformationMessage(`Successfully scheduled runs. [Click here to see the progress](https://github.com/${owner}/${repo}/actions/runs/${workflowRunId}).`);
|
||||
return workflowRunId;
|
||||
} catch (error) {
|
||||
await attemptRerun(error, credentials, ref, language, repositories, owner, repo, queryPackBase64, dryRun);
|
||||
return await attemptRerun(error, credentials, ref, language, repositories, owner, repo, queryPackBase64, dryRun);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -411,7 +421,7 @@ export async function attemptRerun(
|
||||
if (rerunQuery) {
|
||||
const validRepositories = repositories.filter(r => !invalidRepos.includes(r) && !reposWithoutDbUploads.includes(r));
|
||||
void logger.log(`Rerunning query on set of valid repositories: ${JSON.stringify(validRepositories)}`);
|
||||
await runRemoteQueriesApiRequest(credentials, ref, language, validRepositories, owner, repo, queryPackBase64, dryRun);
|
||||
return await runRemoteQueriesApiRequest(credentials, ref, language, validRepositories, owner, repo, queryPackBase64, dryRun);
|
||||
}
|
||||
} else {
|
||||
void showAndLogErrorMessage(error);
|
||||
@@ -556,3 +566,32 @@ export async function getResultIndex(
|
||||
throw new Error(`Invalid result index file: ${error}`);
|
||||
}
|
||||
}
|
||||
|
||||
function buildRemoteQueryEntity(
|
||||
repositories: string[],
|
||||
queryFilePath: string,
|
||||
controllerRepoOwner: string,
|
||||
controllerRepoName: string,
|
||||
queryStartTime: Date,
|
||||
workflowRunId: number
|
||||
): RemoteQuery {
|
||||
// For now, just use the file name as the query name.
|
||||
const queryName = path.basename(queryFilePath);
|
||||
|
||||
const queryRepos = repositories.map(r => {
|
||||
const [owner, repo] = r.split('/');
|
||||
return { owner: owner, name: repo };
|
||||
});
|
||||
|
||||
return {
|
||||
queryName,
|
||||
queryFilePath,
|
||||
controllerRepository: {
|
||||
owner: controllerRepoOwner,
|
||||
name: controllerRepoName,
|
||||
},
|
||||
repositories: queryRepos,
|
||||
executionStartTime: queryStartTime,
|
||||
actionsWorkflowRunId: workflowRunId
|
||||
};
|
||||
}
|
||||
|
||||
@@ -68,7 +68,9 @@ describe('Remote queries', function() {
|
||||
it('should run a remote query that is part of a qlpack', async () => {
|
||||
const fileUri = getFile('data-remote-qlpack/in-pack.ql');
|
||||
|
||||
const queryPackRootDir = (await runRemoteQuery(cli, credentials, fileUri, true, progress, token))!;
|
||||
const querySubmissionResult = await runRemoteQuery(cli, credentials, fileUri, true, progress, token);
|
||||
expect(querySubmissionResult).to.be.ok;
|
||||
const queryPackRootDir = querySubmissionResult!.queryDirPath!;
|
||||
printDirectoryContents(queryPackRootDir);
|
||||
|
||||
// to retrieve the list of repositories
|
||||
@@ -117,7 +119,9 @@ describe('Remote queries', function() {
|
||||
it('should run a remote query that is not part of a qlpack', async () => {
|
||||
const fileUri = getFile('data-remote-no-qlpack/in-pack.ql');
|
||||
|
||||
const queryPackRootDir = (await runRemoteQuery(cli, credentials, fileUri, true, progress, token))!;
|
||||
const querySubmissionResult = await runRemoteQuery(cli, credentials, fileUri, true, progress, token);
|
||||
expect(querySubmissionResult).to.be.ok;
|
||||
const queryPackRootDir = querySubmissionResult!.queryDirPath!;
|
||||
|
||||
// to retrieve the list of repositories
|
||||
// and a second time to ask for the language
|
||||
@@ -172,7 +176,9 @@ describe('Remote queries', function() {
|
||||
it('should run a remote query that is nested inside a qlpack', async () => {
|
||||
const fileUri = getFile('data-remote-qlpack-nested/subfolder/in-pack.ql');
|
||||
|
||||
const queryPackRootDir = (await runRemoteQuery(cli, credentials, fileUri, true, progress, token))!;
|
||||
const querySubmissionResult = await runRemoteQuery(cli, credentials, fileUri, true, progress, token);
|
||||
expect(querySubmissionResult).to.be.ok;
|
||||
const queryPackRootDir = querySubmissionResult!.queryDirPath!;
|
||||
|
||||
// to retrieve the list of repositories
|
||||
expect(showQuickPickSpy).to.have.been.calledOnce;
|
||||
|
||||
Reference in New Issue
Block a user