MRVA: Include more info in query history label (#1427)

Co-authored-by: Elena Tanasoiu <elenatanasoiu@github.com>
This commit is contained in:
Shati Patel
2022-07-15 13:58:45 +01:00
committed by GitHub
parent ffe1704ac0
commit f992679e94
5 changed files with 40 additions and 18 deletions

View File

@@ -65,12 +65,14 @@ export class HistoryItemLabelProvider {
}
private getRemoteInterpolateReplacements(item: RemoteQueryHistoryItem): InterpolateReplacements {
const numRepositoriesQueried = item.remoteQuery.numRepositoriesQueried;
const numRepositoriesLabel = `${numRepositoriesQueried} ${numRepositoriesQueried === 1 ? 'repository' : 'repositories'}`;
return {
t: new Date(item.remoteQuery.executionStartTime).toLocaleString(env.language),
q: item.remoteQuery.queryName,
q: `${item.remoteQuery.queryName} (${item.remoteQuery.language})`,
// There is no database name for remote queries. Instead use the controller repository name.
d: `${item.remoteQuery.controllerRepository.owner}/${item.remoteQuery.controllerRepository.name}`,
// Return the number of repositories queried if available. Otherwise, use the controller repository name.
d: numRepositoriesQueried ? numRepositoriesLabel : `${item.remoteQuery.controllerRepository.owner}/${item.remoteQuery.controllerRepository.name}`,
// There is no synchronous way to get the results count.
r: '',

View File

@@ -41,6 +41,7 @@ export interface UpdatedQueryStatusEvent {
queryId: string;
status: QueryStatus;
failureReason?: string;
numRepositoriesQueried?: number;
}
export class RemoteQueriesManager extends DisposableObject {
@@ -314,9 +315,13 @@ export class RemoteQueriesManager extends DisposableObject {
): Promise<void> {
const resultIndex = await getRemoteQueryIndex(credentials, remoteQuery);
if (resultIndex) {
this.remoteQueryStatusUpdateEventEmitter.fire({ queryId, status: QueryStatus.Completed });
const metadata = await this.getRepositoriesMetadata(resultIndex, credentials);
const queryResult = this.mapQueryResult(executionEndTime, resultIndex, queryId, metadata);
this.remoteQueryStatusUpdateEventEmitter.fire({
queryId,
status: QueryStatus.Completed,
numRepositoriesQueried: queryResult.analysisSummaries.length,
});
await this.storeJsonFile(queryId, 'query-result.json', queryResult);

View File

@@ -8,4 +8,5 @@ export interface RemoteQuery {
controllerRepository: Repository;
executionStartTime: number; // Use number here since it needs to be serialized and desserialized.
actionsWorkflowRunId: number;
numRepositoriesQueried: number;
}

View File

@@ -258,17 +258,19 @@ export async function runRemoteQuery(
});
const actionBranch = getActionBranch();
const workflowRunId = await runRemoteQueriesApiRequest(credentials, actionBranch, language, repoSelection, owner, repo, base64Pack, dryRun);
const apiResponse = await runRemoteQueriesApiRequest(credentials, actionBranch, language, repoSelection, owner, repo, base64Pack, dryRun);
const queryStartTime = Date.now();
const queryMetadata = await tryGetQueryMetadata(cliServer, queryFile);
if (dryRun) {
return { queryDirPath: remoteQueryDir.path };
} else {
if (!workflowRunId) {
if (!apiResponse) {
return;
}
const workflowRunId = apiResponse.workflow_run_id;
const numRepositoriesQueried = apiResponse.repositories_queried.length;
const remoteQuery = await buildRemoteQueryEntity(
queryFile,
queryMetadata,
@@ -276,7 +278,8 @@ export async function runRemoteQuery(
repo,
queryStartTime,
workflowRunId,
language);
language,
numRepositoriesQueried);
// don't return the path because it has been deleted
return { query: remoteQuery };
@@ -301,7 +304,7 @@ async function runRemoteQueriesApiRequest(
repo: string,
queryPackBase64: string,
dryRun = false
): Promise<void | number> {
): Promise<void | QueriesResponse> {
const data = {
ref,
language,
@@ -336,7 +339,7 @@ async function runRemoteQueriesApiRequest(
);
const { popupMessage, logMessage } = parseResponse(owner, repo, response.data);
void showAndLogInformationMessage(popupMessage, { fullMessage: logMessage });
return response.data.workflow_run_id;
return response.data;
} catch (error: any) {
if (error.status === 404) {
void showAndLogErrorMessage(`Controller repository was not found. Please make sure it's a valid repo name.${eol}`);
@@ -432,7 +435,8 @@ async function buildRemoteQueryEntity(
controllerRepoName: string,
queryStartTime: number,
workflowRunId: number,
language: string
language: string,
numRepositoriesQueried: number
): Promise<RemoteQuery> {
// The query name is either the name as specified in the query metadata, or the file name.
const queryName = queryMetadata?.name ?? path.basename(queryFilePath);
@@ -449,6 +453,7 @@ async function buildRemoteQueryEntity(
name: controllerRepoName,
},
executionStartTime: queryStartTime,
actionsWorkflowRunId: workflowRunId
actionsWorkflowRunId: workflowRunId,
numRepositoriesQueried: numRepositoriesQueried,
};
}

View File

@@ -89,23 +89,30 @@ describe('HistoryItemLabelProvider', () => {
expect(labelProvider.getLabel(fqi)).to.eq('xxx');
fqi.userSpecifiedLabel = '%t %q %d %s %%';
expect(labelProvider.getLabel(fqi)).to.eq(`${dateStr} query-name github/vscode-codeql-integration-tests in progress %`);
expect(labelProvider.getLabel(fqi)).to.eq(`${dateStr} query-name (javascript) github/vscode-codeql-integration-tests in progress %`);
fqi.userSpecifiedLabel = '%t %q %d %s %%::%t %q %d %s %%';
expect(labelProvider.getLabel(fqi)).to.eq(`${dateStr} query-name github/vscode-codeql-integration-tests in progress %::${dateStr} query-name github/vscode-codeql-integration-tests in progress %`);
expect(labelProvider.getLabel(fqi)).to.eq(`${dateStr} query-name (javascript) github/vscode-codeql-integration-tests in progress %::${dateStr} query-name (javascript) github/vscode-codeql-integration-tests in progress %`);
});
it('should interpolate query when not user specified', () => {
const fqi = createMockRemoteQueryInfo();
expect(labelProvider.getLabel(fqi)).to.eq('xxx query-name xxx');
expect(labelProvider.getLabel(fqi)).to.eq('xxx query-name (javascript) xxx');
config.format = '%t %q %d %s %f %r %%';
expect(labelProvider.getLabel(fqi)).to.eq(`${dateStr} query-name github/vscode-codeql-integration-tests in progress query-file.ql %`);
expect(labelProvider.getLabel(fqi)).to.eq(`${dateStr} query-name (javascript) github/vscode-codeql-integration-tests in progress query-file.ql %`);
config.format = '%t %q %d %s %f %r %%::%t %q %d %s %f %r %%';
expect(labelProvider.getLabel(fqi)).to.eq(`${dateStr} query-name github/vscode-codeql-integration-tests in progress query-file.ql %::${dateStr} query-name github/vscode-codeql-integration-tests in progress query-file.ql %`);
expect(labelProvider.getLabel(fqi)).to.eq(`${dateStr} query-name (javascript) github/vscode-codeql-integration-tests in progress query-file.ql %::${dateStr} query-name (javascript) github/vscode-codeql-integration-tests in progress query-file.ql %`);
});
it('should use number of repositories instead of controller repo if available', () => {
const fqi = createMockRemoteQueryInfo(undefined, 2);
config.format = '%t %q %d %s %f %r %%';
expect(labelProvider.getLabel(fqi)).to.eq(`${dateStr} query-name (javascript) 2 repositories in progress query-file.ql %`);
});
it('should get query short label', () => {
@@ -119,7 +126,7 @@ describe('HistoryItemLabelProvider', () => {
expect(labelProvider.getShortLabel(fqi)).to.eq('query-name');
});
function createMockRemoteQueryInfo(userSpecifiedLabel?: string) {
function createMockRemoteQueryInfo(userSpecifiedLabel?: string, numRepositoriesQueried?: number) {
return {
t: 'remote',
userSpecifiedLabel,
@@ -130,7 +137,9 @@ describe('HistoryItemLabelProvider', () => {
controllerRepository: {
owner: 'github',
name: 'vscode-codeql-integration-tests'
}
},
language: 'javascript',
numRepositoriesQueried,
},
status: 'in progress',
} as unknown as RemoteQueryHistoryItem;