Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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": [
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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": [
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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": [
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ export function isFinalVariantAnalysisStatus(status: VariantAnalysisStatus): boo

export enum VariantAnalysisFailureReason {
NoReposQueried = 'noReposQueried',
ActionsWorkflowRunFailed = 'actionsWorkflowRunFailed',
InternalError = 'internalError',
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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;
}

Expand All @@ -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(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -188,20 +188,26 @@ 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;
}
}

export function processFailureReason(failureReason: ApiVariantAnalysisFailureReason): VariantAnalysisFailureReason {
switch (failureReason) {
case 'no_repos_queried':
return VariantAnalysisFailureReason.NoReposQueried;
case 'actions_workflow_run_failed':
return VariantAnalysisFailureReason.ActionsWorkflowRunFailed;
case 'internal_error':
return VariantAnalysisFailureReason.InternalError;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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,
};
Original file line number Diff line number Diff line change
@@ -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. <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.';
}
};

const openLogs = () => {
vscode.postMessage({
t: 'openLogs',
});
};

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>}
/>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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');
});
Expand Down Expand Up @@ -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);
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Original file line number Diff line number Diff line change
Expand Up @@ -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', () => {
Expand Down