Merge pull request #1726 from github/koesie10/new-variant-analysis-statuses
Use new variant analysis statuses
This commit is contained in:
@@ -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": [
|
||||
{
|
||||
|
||||
@@ -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": [
|
||||
{
|
||||
|
||||
@@ -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": [
|
||||
{
|
||||
|
||||
@@ -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 =
|
||||
|
||||
@@ -56,6 +56,7 @@ export function isFinalVariantAnalysisStatus(status: VariantAnalysisStatus): boo
|
||||
|
||||
export enum VariantAnalysisFailureReason {
|
||||
NoReposQueried = 'noReposQueried',
|
||||
ActionsWorkflowRunFailed = 'actionsWorkflowRunFailed',
|
||||
InternalError = 'internalError',
|
||||
}
|
||||
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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') {
|
||||
return VariantAnalysisStatus.InProgress;
|
||||
} else if (failureReason !== undefined) {
|
||||
return VariantAnalysisStatus.Failed;
|
||||
} else {
|
||||
function processApiStatus(status: ApiVariantAnalysisStatus): VariantAnalysisStatus {
|
||||
if (status === 'succeeded') {
|
||||
return VariantAnalysisStatus.Succeeded;
|
||||
} else if (status === 'in_progress') {
|
||||
return VariantAnalysisStatus.InProgress;
|
||||
} else if (status === 'failed') {
|
||||
return VariantAnalysisStatus.Failed;
|
||||
} else if (status === 'cancelled') {
|
||||
return VariantAnalysisStatus.Canceled;
|
||||
} else {
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -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<typeof FailureReasonAlert>;
|
||||
|
||||
const Template: ComponentStory<typeof FailureReasonAlert> = (args) => (
|
||||
<FailureReasonAlert {...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,
|
||||
};
|
||||
@@ -1,30 +1,12 @@
|
||||
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 getTitle = (failureReason: VariantAnalysisFailureReason): string => {
|
||||
switch (failureReason) {
|
||||
case VariantAnalysisFailureReason.NoReposQueried:
|
||||
return 'No repositories to analyze';
|
||||
case VariantAnalysisFailureReason.InternalError:
|
||||
return 'Something unexpected happened';
|
||||
}
|
||||
};
|
||||
|
||||
const getMessage = (failureReason: VariantAnalysisFailureReason): string => {
|
||||
switch (failureReason) {
|
||||
case VariantAnalysisFailureReason.NoReposQueried:
|
||||
return 'No repositories available after processing. No repositories were analyzed.';
|
||||
case VariantAnalysisFailureReason.InternalError:
|
||||
return 'An internal error occurred while running this variant analysis. Please try again later.';
|
||||
}
|
||||
};
|
||||
|
||||
const openLogs = () => {
|
||||
@@ -33,16 +15,36 @@ const 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): 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. <VSCodeLink onClick={openLogs}>Check logs</VSCodeLink> and try running this query again.</>;
|
||||
case VariantAnalysisFailureReason.InternalError:
|
||||
return 'An internal error occurred while running this variant analysis. Please try again later.';
|
||||
}
|
||||
};
|
||||
|
||||
export const FailureReasonAlert = ({
|
||||
failureReason,
|
||||
showLogsButton,
|
||||
}: Props) => {
|
||||
return (
|
||||
<Alert
|
||||
type="error"
|
||||
title={getTitle(failureReason)}
|
||||
message={getMessage(failureReason)}
|
||||
actions={showLogsButton && <VSCodeButton appearance="secondary" onClick={openLogs}>View logs</VSCodeButton>}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -65,7 +65,7 @@ export const VariantAnalysisOutcomePanels = ({
|
||||
/>
|
||||
)}
|
||||
{variantAnalysis.status === VariantAnalysisStatus.Failed && variantAnalysis.failureReason && (
|
||||
<FailureReasonAlert failureReason={variantAnalysis.failureReason} showLogsButton={!!variantAnalysis.actionsWorkflowRunId} />
|
||||
<FailureReasonAlert failureReason={variantAnalysis.failureReason} />
|
||||
)}
|
||||
{overLimitRepositoryCount > 0 && (
|
||||
<Alert
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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', () => {
|
||||
|
||||
Reference in New Issue
Block a user