Skip to content

Commit 0b2ce7a

Browse files
committed
MRVA: Display available results, even if some jobs are cancelled
1 parent dac7881 commit 0b2ce7a

2 files changed

Lines changed: 53 additions & 25 deletions

File tree

extensions/ql-vscode/src/remote-queries/gh-actions-api-client.ts

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,10 @@ export async function getRemoteQueryIndex(
4242
const artifactsUrlPath = `/repos/${owner}/${repoName}/actions/artifacts`;
4343

4444
const artifactList = await listWorkflowRunArtifacts(credentials, owner, repoName, workflowRunId);
45-
const resultIndexArtifactId = getArtifactIDfromName('result-index', workflowUri, artifactList);
45+
const resultIndexArtifactId = tryGetArtifactIDfromName('result-index', artifactList);
46+
if (!resultIndexArtifactId) {
47+
return undefined;
48+
}
4649
const resultIndex = await getResultIndex(credentials, owner, repoName, resultIndexArtifactId);
4750

4851
const successes = resultIndex?.successes.map(item => {
@@ -223,15 +226,29 @@ function getArtifactIDfromName(
223226
workflowUri: string,
224227
artifacts: Array<{ id: number, name: string }>
225228
): number {
226-
const artifact = artifacts.find(a => a.name === artifactName);
229+
const artifactId = tryGetArtifactIDfromName(artifactName, artifacts);
227230

228-
if (!artifact) {
231+
if (!artifactId) {
229232
const errorMessage =
230233
`Could not find artifact with name ${artifactName} in workflow ${workflowUri}.
231234
Please check whether the workflow run has successfully completed.`;
232235
throw Error(errorMessage);
233236
}
234237

238+
return artifactId;
239+
}
240+
241+
/**
242+
* @param artifactName The artifact name, as a string.
243+
* @param artifacts An array of artifact details (from the "list workflow run artifacts" API response).
244+
* @returns The artifact ID corresponding to the given artifact name, if it exists.
245+
*/
246+
function tryGetArtifactIDfromName(
247+
artifactName: string,
248+
artifacts: Array<{ id: number, name: string }>
249+
): number | undefined {
250+
const artifact = artifacts.find(a => a.name === artifactName);
251+
235252
return artifact?.id;
236253
}
237254

extensions/ql-vscode/src/remote-queries/remote-queries-manager.ts

Lines changed: 33 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -131,40 +131,21 @@ export class RemoteQueriesManager extends DisposableObject {
131131
const executionEndTime = Date.now();
132132

133133
if (queryWorkflowResult.status === 'CompletedSuccessfully') {
134-
const resultIndex = await getRemoteQueryIndex(credentials, queryItem.remoteQuery);
135-
queryItem.completed = true;
136-
if (resultIndex) {
137-
queryItem.status = QueryStatus.Completed;
138-
const queryResult = this.mapQueryResult(executionEndTime, resultIndex, queryItem.queryId);
139-
140-
await this.storeJsonFile(queryItem, 'query-result.json', queryResult);
141-
142-
// Kick off auto-download of results in the background.
143-
void commands.executeCommand('codeQL.autoDownloadRemoteQueryResults', queryResult);
144-
145-
// Ask if the user wants to open the results in the background.
146-
void this.askToOpenResults(queryItem.remoteQuery, queryResult).then(
147-
noop,
148-
err => {
149-
void showAndLogErrorMessage(err);
150-
}
151-
);
152-
} else {
153-
void showAndLogErrorMessage(`There was an issue retrieving the result for the query ${queryItem.remoteQuery.queryName}`);
154-
queryItem.status = QueryStatus.Failed;
155-
}
134+
await this.downloadAvailableResults(queryItem, credentials, executionEndTime);
156135
} else if (queryWorkflowResult.status === 'CompletedUnsuccessfully') {
157136
if (queryWorkflowResult.error?.includes('cancelled')) {
158137
// workflow was cancelled on the server
159138
queryItem.failureReason = 'Cancelled';
160139
queryItem.status = QueryStatus.Failed;
140+
await this.downloadAvailableResults(queryItem, credentials, executionEndTime);
161141
void showAndLogInformationMessage('Variant analysis was cancelled');
162142
} else {
163143
queryItem.failureReason = queryWorkflowResult.error;
164144
queryItem.status = QueryStatus.Failed;
165145
void showAndLogErrorMessage(`Variant analysis execution failed. Error: ${queryWorkflowResult.error}`);
166146
}
167147
} else if (queryWorkflowResult.status === 'Cancelled') {
148+
// workflow was cancelled from within VS Code
168149
queryItem.failureReason = 'Cancelled';
169150
queryItem.status = QueryStatus.Failed;
170151
void showAndLogErrorMessage('Variant analysis was cancelled');
@@ -282,4 +263,34 @@ export class RemoteQueriesManager extends DisposableObject {
282263
const filePath = path.join(this.storagePath, queryItem.queryId);
283264
return await fs.pathExists(filePath);
284265
}
266+
267+
/**
268+
* Checks whether there's a result index artifact available for the given query.
269+
* If so, set the query status to `Completed` and auto-download the results.
270+
*/
271+
private async downloadAvailableResults(queryItem: RemoteQueryHistoryItem, credentials: Credentials, executionEndTime: number): Promise<void> {
272+
const resultIndex = await getRemoteQueryIndex(credentials, queryItem.remoteQuery);
273+
if (resultIndex) {
274+
queryItem.completed = true;
275+
queryItem.status = QueryStatus.Completed;
276+
queryItem.failureReason = undefined;
277+
const queryResult = this.mapQueryResult(executionEndTime, resultIndex, queryItem.queryId);
278+
279+
await this.storeJsonFile(queryItem, 'query-result.json', queryResult);
280+
281+
// Kick off auto-download of results in the background.
282+
void commands.executeCommand('codeQL.autoDownloadRemoteQueryResults', queryResult);
283+
284+
// Ask if the user wants to open the results in the background.
285+
void this.askToOpenResults(queryItem.remoteQuery, queryResult).then(
286+
noop,
287+
err => {
288+
void showAndLogErrorMessage(err);
289+
}
290+
);
291+
} else {
292+
void showAndLogErrorMessage(`There was an issue retrieving the result for the query ${queryItem.remoteQuery.queryName}`);
293+
queryItem.status = QueryStatus.Failed;
294+
}
295+
}
285296
}

0 commit comments

Comments
 (0)