From d711d80cfb2ee69adc724a2e9a0b3af8f32dd080 Mon Sep 17 00:00:00 2001 From: Koen Vlaswinkel Date: Tue, 8 Nov 2022 13:13:51 +0100 Subject: [PATCH 1/2] Use new variant analysis statuses The `status` on the variant analysis has changed to have `succeeded`, `failed` and `cancelled` instead of `completed`. --- .../27-getVariantAnalysis.json | 2 +- .../51-getVariantAnalysis.json | 2 +- .../query-failure/15-getVariantAnalysis.json | 2 +- .../remote-queries/gh-api/variant-analysis.ts | 5 ++++- .../remote-queries/shared/variant-analysis.ts | 1 + .../remote-queries/variant-analysis-monitor.ts | 6 +++--- .../remote-queries/variant-analysis-processor.ts | 16 +++++++++++----- .../variant-analysis-monitor.test.ts | 4 ++-- .../gh-api/variant-analysis-api-response.ts | 2 +- .../variant-analysis-processor.test.ts | 2 +- 10 files changed, 26 insertions(+), 16 deletions(-) diff --git a/extensions/ql-vscode/src/mocks/scenarios/problem-query-success/27-getVariantAnalysis.json b/extensions/ql-vscode/src/mocks/scenarios/problem-query-success/27-getVariantAnalysis.json index 9ba45d1da0d..824c4b2ed32 100644 --- a/extensions/ql-vscode/src/mocks/scenarios/problem-query-success/27-getVariantAnalysis.json +++ b/extensions/ql-vscode/src/mocks/scenarios/problem-query-success/27-getVariantAnalysis.json @@ -98,7 +98,7 @@ "created_at": "2022-10-26T12:45:12Z", "updated_at": "2022-10-26T12:45:15Z", "actions_workflow_run_id": 3329095282, - "status": "completed", + "status": "succeeded", "completed_at": "2022-10-26T12:48:17Z", "scanned_repositories": [ { diff --git a/extensions/ql-vscode/src/mocks/scenarios/problem-query-warnings/51-getVariantAnalysis.json b/extensions/ql-vscode/src/mocks/scenarios/problem-query-warnings/51-getVariantAnalysis.json index 3a6f10fb586..93b8ea8aa5a 100644 --- a/extensions/ql-vscode/src/mocks/scenarios/problem-query-warnings/51-getVariantAnalysis.json +++ b/extensions/ql-vscode/src/mocks/scenarios/problem-query-warnings/51-getVariantAnalysis.json @@ -98,7 +98,7 @@ "created_at": "2022-10-27T07:42:59Z", "updated_at": "2022-10-27T07:43:02Z", "actions_workflow_run_id": 3335462873, - "status": "completed", + "status": "succeeded", "completed_at": "2022-10-27T08:18:47Z", "scanned_repositories": [ { diff --git a/extensions/ql-vscode/src/mocks/scenarios/query-failure/15-getVariantAnalysis.json b/extensions/ql-vscode/src/mocks/scenarios/query-failure/15-getVariantAnalysis.json index 91730f98b8b..f44c6f421e7 100644 --- a/extensions/ql-vscode/src/mocks/scenarios/query-failure/15-getVariantAnalysis.json +++ b/extensions/ql-vscode/src/mocks/scenarios/query-failure/15-getVariantAnalysis.json @@ -98,7 +98,7 @@ "created_at": "2022-10-27T12:00:27Z", "updated_at": "2022-10-27T12:00:30Z", "actions_workflow_run_id": 3337181325, - "status": "completed", + "status": "succeeded", "completed_at": "2022-10-27T12:04:03Z", "scanned_repositories": [ { diff --git a/extensions/ql-vscode/src/remote-queries/gh-api/variant-analysis.ts b/extensions/ql-vscode/src/remote-queries/gh-api/variant-analysis.ts index 9efe8200a85..a501cfb86a2 100644 --- a/extensions/ql-vscode/src/remote-queries/gh-api/variant-analysis.ts +++ b/extensions/ql-vscode/src/remote-queries/gh-api/variant-analysis.ts @@ -35,10 +35,13 @@ export interface VariantAnalysis { export type VariantAnalysisStatus = | 'in_progress' - | 'completed'; + | 'succeeded' + | 'failed' + | 'cancelled'; export type VariantAnalysisFailureReason = | 'no_repos_queried' + | 'actions_workflow_run_failed' | 'internal_error'; export type VariantAnalysisRepoStatus = diff --git a/extensions/ql-vscode/src/remote-queries/shared/variant-analysis.ts b/extensions/ql-vscode/src/remote-queries/shared/variant-analysis.ts index 29ef410efa0..8c120f72a84 100644 --- a/extensions/ql-vscode/src/remote-queries/shared/variant-analysis.ts +++ b/extensions/ql-vscode/src/remote-queries/shared/variant-analysis.ts @@ -56,6 +56,7 @@ export function isFinalVariantAnalysisStatus(status: VariantAnalysisStatus): boo export enum VariantAnalysisFailureReason { NoReposQueried = 'noReposQueried', + ActionsWorkflowRunFailed = 'actionsWorkflowRunFailed', InternalError = 'internalError', } diff --git a/extensions/ql-vscode/src/remote-queries/variant-analysis-monitor.ts b/extensions/ql-vscode/src/remote-queries/variant-analysis-monitor.ts index 86d8f47c007..a644097d3ff 100644 --- a/extensions/ql-vscode/src/remote-queries/variant-analysis-monitor.ts +++ b/extensions/ql-vscode/src/remote-queries/variant-analysis-monitor.ts @@ -4,8 +4,8 @@ import * as ghApiClient from './gh-api/gh-api-client'; import { isFinalVariantAnalysisStatus, + repoHasDownloadableArtifact, VariantAnalysis, - VariantAnalysisRepoStatus, VariantAnalysisScannedRepository } from './shared/variant-analysis'; import { VariantAnalysisMonitorResult } from './shared/variant-analysis-monitor-result'; @@ -61,7 +61,7 @@ export class VariantAnalysisMonitor extends DisposableObject { const downloadedRepos = this.downloadVariantAnalysisResults(variantAnalysis, scannedReposDownloaded); scannedReposDownloaded.push(...downloadedRepos); - if (isFinalVariantAnalysisStatus(variantAnalysis.status) || variantAnalysis.failureReason) { + if (isFinalVariantAnalysisStatus(variantAnalysis.status)) { break; } @@ -82,7 +82,7 @@ export class VariantAnalysisMonitor extends DisposableObject { scannedRepo: VariantAnalysisScannedRepository, alreadyDownloaded: number[] ): boolean { - return !alreadyDownloaded.includes(scannedRepo.repository.id) && scannedRepo.analysisStatus === VariantAnalysisRepoStatus.Succeeded; + return !alreadyDownloaded.includes(scannedRepo.repository.id) && repoHasDownloadableArtifact(scannedRepo); } private getReposToDownload( diff --git a/extensions/ql-vscode/src/remote-queries/variant-analysis-processor.ts b/extensions/ql-vscode/src/remote-queries/variant-analysis-processor.ts index 339448891e3..5da32395100 100644 --- a/extensions/ql-vscode/src/remote-queries/variant-analysis-processor.ts +++ b/extensions/ql-vscode/src/remote-queries/variant-analysis-processor.ts @@ -64,7 +64,7 @@ export function processUpdatedVariantAnalysis( executionStartTime: previousVariantAnalysis.executionStartTime, createdAt: response.created_at, updatedAt: response.updated_at, - status: processApiStatus(response.status, response.failure_reason), + status: processApiStatus(response.status), completedAt: response.completed_at, actionsWorkflowRunId: response.actions_workflow_run_id, scannedRepos: scannedRepos, @@ -188,13 +188,17 @@ function processApiRepoStatus(analysisStatus: ApiVariantAnalysisRepoStatus): Var } } -function processApiStatus(status: ApiVariantAnalysisStatus, failureReason: string | undefined): VariantAnalysisStatus { - if (status === 'in_progress') { +function processApiStatus(status: ApiVariantAnalysisStatus): VariantAnalysisStatus { + if (status === 'succeeded') { + return VariantAnalysisStatus.Succeeded; + } else if (status === 'in_progress') { return VariantAnalysisStatus.InProgress; - } else if (failureReason !== undefined) { + } else if (status === 'failed') { return VariantAnalysisStatus.Failed; + } else if (status === 'cancelled') { + return VariantAnalysisStatus.Canceled; } else { - return VariantAnalysisStatus.Succeeded; + return VariantAnalysisStatus.InProgress; } } @@ -202,6 +206,8 @@ export function processFailureReason(failureReason: ApiVariantAnalysisFailureRea switch (failureReason) { case 'no_repos_queried': return VariantAnalysisFailureReason.NoReposQueried; + case 'actions_workflow_run_failed': + return VariantAnalysisFailureReason.ActionsWorkflowRunFailed; case 'internal_error': return VariantAnalysisFailureReason.InternalError; } diff --git a/extensions/ql-vscode/src/vscode-tests/cli-integration/remote-queries/variant-analysis-monitor.test.ts b/extensions/ql-vscode/src/vscode-tests/cli-integration/remote-queries/variant-analysis-monitor.test.ts index 71355ca251a..dc0aa13a3c8 100644 --- a/extensions/ql-vscode/src/vscode-tests/cli-integration/remote-queries/variant-analysis-monitor.test.ts +++ b/extensions/ql-vscode/src/vscode-tests/cli-integration/remote-queries/variant-analysis-monitor.test.ts @@ -125,7 +125,7 @@ describe('Variant Analysis Monitor', async function() { describe('when there are successfully scanned repos', async () => { beforeEach(async function() { scannedRepos = createMockScannedRepos(['pending', 'pending', 'in_progress', 'in_progress', 'succeeded', 'succeeded', 'succeeded']); - mockApiResponse = createMockApiResponse('completed', scannedRepos); + mockApiResponse = createMockApiResponse('succeeded', scannedRepos); mockGetVariantAnalysis = sandbox.stub(ghApiClient, 'getVariantAnalysis').resolves(mockApiResponse); succeededRepos = scannedRepos.filter(r => r.analysis_status === 'succeeded'); }); @@ -190,7 +190,7 @@ describe('Variant Analysis Monitor', async function() { describe('when there are no repos to scan', async () => { beforeEach(async function() { scannedRepos = []; - mockApiResponse = createMockApiResponse('completed', scannedRepos); + mockApiResponse = createMockApiResponse('succeeded', scannedRepos); mockGetVariantAnalysis = sandbox.stub(ghApiClient, 'getVariantAnalysis').resolves(mockApiResponse); }); diff --git a/extensions/ql-vscode/src/vscode-tests/factories/remote-queries/gh-api/variant-analysis-api-response.ts b/extensions/ql-vscode/src/vscode-tests/factories/remote-queries/gh-api/variant-analysis-api-response.ts index 8bdae9cf2ac..093bf76c82a 100644 --- a/extensions/ql-vscode/src/vscode-tests/factories/remote-queries/gh-api/variant-analysis-api-response.ts +++ b/extensions/ql-vscode/src/vscode-tests/factories/remote-queries/gh-api/variant-analysis-api-response.ts @@ -43,7 +43,7 @@ export function createFailedMockApiResponse( scannedRepos: VariantAnalysisScannedRepository[] = createMockScannedRepos(), skippedRepos: VariantAnalysisSkippedRepositories = createMockSkippedRepos(), ): VariantAnalysisApiResponse { - const variantAnalysis = createMockApiResponse('completed', scannedRepos, skippedRepos); + const variantAnalysis = createMockApiResponse('failed', scannedRepos, skippedRepos); variantAnalysis.failure_reason = 'internal_error'; return variantAnalysis; } diff --git a/extensions/ql-vscode/test/pure-tests/remote-queries/variant-analysis-processor.test.ts b/extensions/ql-vscode/test/pure-tests/remote-queries/variant-analysis-processor.test.ts index 90e2d841881..b60306e7a16 100644 --- a/extensions/ql-vscode/test/pure-tests/remote-queries/variant-analysis-processor.test.ts +++ b/extensions/ql-vscode/test/pure-tests/remote-queries/variant-analysis-processor.test.ts @@ -31,7 +31,7 @@ import { describe(processVariantAnalysis.name, function() { const scannedRepos = createMockScannedRepos(); const skippedRepos = createMockSkippedRepos(); - const mockApiResponse = createMockApiResponse('completed', scannedRepos, skippedRepos); + const mockApiResponse = createMockApiResponse('succeeded', scannedRepos, skippedRepos); const mockSubmission = createMockSubmission(); it('should process an API response and return a variant analysis', () => { From a80ace53344c6f9ad83c82869985d883b2c37f9b Mon Sep 17 00:00:00 2001 From: Koen Vlaswinkel Date: Thu, 10 Nov 2022 15:07:58 +0100 Subject: [PATCH 2/2] Add alert message for failed Actions workflow This also changes the failure reason alert component to remove the logs button since it's not used by any failure reason. Instead, a link is added into the message for a failed Actions workflow using which the Actions workflow run may be opened. --- .../FailureReasonAlert.stories.tsx | 29 +++++++++++++++++++ .../variant-analysis/FailureReasonAlert.tsx | 24 ++++++++------- .../VariantAnalysisOutcomePanels.tsx | 2 +- 3 files changed, 43 insertions(+), 12 deletions(-) create mode 100644 extensions/ql-vscode/src/stories/variant-analysis/FailureReasonAlert.stories.tsx diff --git a/extensions/ql-vscode/src/stories/variant-analysis/FailureReasonAlert.stories.tsx b/extensions/ql-vscode/src/stories/variant-analysis/FailureReasonAlert.stories.tsx new file mode 100644 index 00000000000..5df6037667e --- /dev/null +++ b/extensions/ql-vscode/src/stories/variant-analysis/FailureReasonAlert.stories.tsx @@ -0,0 +1,29 @@ +import React from 'react'; + +import { ComponentMeta, ComponentStory } from '@storybook/react'; +import { VariantAnalysisFailureReason } from '../../remote-queries/shared/variant-analysis'; +import { FailureReasonAlert } from '../../view/variant-analysis/FailureReasonAlert'; + +export default { + title: 'Variant Analysis/Failure reason alert', + component: FailureReasonAlert, +} as ComponentMeta; + +const Template: ComponentStory = (args) => ( + +); + +export const NoReposQueried = Template.bind({}); +NoReposQueried.args = { + failureReason: VariantAnalysisFailureReason.NoReposQueried, +}; + +export const ActionsWorkflowRunFailed = Template.bind({}); +ActionsWorkflowRunFailed.args = { + failureReason: VariantAnalysisFailureReason.ActionsWorkflowRunFailed, +}; + +export const InternalError = Template.bind({}); +InternalError.args = { + failureReason: VariantAnalysisFailureReason.InternalError, +}; diff --git a/extensions/ql-vscode/src/view/variant-analysis/FailureReasonAlert.tsx b/extensions/ql-vscode/src/view/variant-analysis/FailureReasonAlert.tsx index f3a7c179fa3..e04fce503bd 100644 --- a/extensions/ql-vscode/src/view/variant-analysis/FailureReasonAlert.tsx +++ b/extensions/ql-vscode/src/view/variant-analysis/FailureReasonAlert.tsx @@ -1,48 +1,50 @@ import * as React from 'react'; -import { VSCodeButton } from '@vscode/webview-ui-toolkit/react'; +import { ReactNode } from 'react'; +import { VSCodeLink } from '@vscode/webview-ui-toolkit/react'; import { Alert } from '../common'; import { vscode } from '../vscode-api'; import { VariantAnalysisFailureReason } from '../../remote-queries/shared/variant-analysis'; type Props = { failureReason: VariantAnalysisFailureReason; - showLogsButton: boolean; +}; + +const openLogs = () => { + vscode.postMessage({ + t: 'openLogs', + }); }; const getTitle = (failureReason: VariantAnalysisFailureReason): string => { switch (failureReason) { case VariantAnalysisFailureReason.NoReposQueried: return 'No repositories to analyze'; + case VariantAnalysisFailureReason.ActionsWorkflowRunFailed: + return 'GitHub Actions workflow run failed'; case VariantAnalysisFailureReason.InternalError: return 'Something unexpected happened'; } }; -const getMessage = (failureReason: VariantAnalysisFailureReason): string => { +const getMessage = (failureReason: VariantAnalysisFailureReason): ReactNode => { switch (failureReason) { case VariantAnalysisFailureReason.NoReposQueried: return 'No repositories available after processing. No repositories were analyzed.'; + case VariantAnalysisFailureReason.ActionsWorkflowRunFailed: + return <>The GitHub Actions workflow run has failed. Check logs and try running this query again.; case VariantAnalysisFailureReason.InternalError: return 'An internal error occurred while running this variant analysis. Please try again later.'; } }; -const openLogs = () => { - vscode.postMessage({ - t: 'openLogs', - }); -}; - export const FailureReasonAlert = ({ failureReason, - showLogsButton, }: Props) => { return ( View logs} /> ); }; diff --git a/extensions/ql-vscode/src/view/variant-analysis/VariantAnalysisOutcomePanels.tsx b/extensions/ql-vscode/src/view/variant-analysis/VariantAnalysisOutcomePanels.tsx index 7ae34883990..5f480610567 100644 --- a/extensions/ql-vscode/src/view/variant-analysis/VariantAnalysisOutcomePanels.tsx +++ b/extensions/ql-vscode/src/view/variant-analysis/VariantAnalysisOutcomePanels.tsx @@ -65,7 +65,7 @@ export const VariantAnalysisOutcomePanels = ({ /> )} {variantAnalysis.status === VariantAnalysisStatus.Failed && variantAnalysis.failureReason && ( - + )} {overLimitRepositoryCount > 0 && (