Loading src/desktop/commands/job_actions.test.ts +3 −2 Original line number Diff line number Diff line import vscode from 'vscode'; import { getGitLabService } from '../gitlab/get_gitlab_service'; import { job, projectInRepository } from '../test_utils/entities'; import { GitLabService } from '../gitlab/gitlab_service'; import { JobItemModel } from '../tree_view/items/job_item_model'; import { createFakePartial } from '../../common/test_utils/create_fake_partial'; import { currentBranchRefresher } from '../current_branch_refresher'; import { cancelJob, executeJob, retryJob } from './job_actions'; jest.mock('../gitlab/get_gitlab_service'); jest.mock('../current_branch_refresher'); describe('retryOrCancelJobItemModel', () => { const mockActions: Record<string, 'canceled' | 'pending'> = { Loading @@ -23,7 +24,7 @@ describe('retryOrCancelJobItemModel', () => { const model = new JobItemModel(projectInRepository, job); beforeEach(() => { (vscode.window.withProgress as jest.Mock).mockImplementation((_, task) => task()); jest.mocked(currentBranchRefresher.refresh).mockResolvedValue(undefined); jest.mocked(getGitLabService).mockReturnValue(gitlabService); }); Loading src/desktop/commands/job_actions.ts +4 −4 Original line number Diff line number Diff line import * as vscode from 'vscode'; import { USER_COMMANDS } from '../command_names'; import { getGitLabService } from '../gitlab/get_gitlab_service'; import { JobItemModel } from '../tree_view/items/job_item_model'; import { currentBranchDataProvider } from '../tree_view/current_branch_data_provider'; import { currentBranchRefresher } from '../current_branch_refresher'; async function retryOrCancelJobItemModel( action: 'retry' | 'cancel' | 'play', Loading @@ -9,9 +9,9 @@ async function retryOrCancelJobItemModel( ): Promise<RestJob | undefined> { const { job, projectInRepository } = item; const gitlabService = getGitLabService(projectInRepository); return vscode.window.withProgress({ location: { viewId: 'currentBranchInfo' } }, async () => { return currentBranchDataProvider.withMarkedAsBusy('job', job.id, async () => { const result = await gitlabService.cancelOrRetryJob(action, projectInRepository.project, job); if (result) await vscode.commands.executeCommand(USER_COMMANDS.REFRESH_SIDEBAR); if (result) await currentBranchRefresher.refresh(); return result; }); } Loading src/desktop/commands/pipeline_actions.test.ts +3 −2 Original line number Diff line number Diff line import vscode from 'vscode'; import { createFakePartial } from '../../common/test_utils/create_fake_partial'; import { getGitLabService } from '../gitlab/get_gitlab_service'; import { GitLabService } from '../gitlab/gitlab_service'; import { job, pipeline, projectInRepository } from '../test_utils/entities'; import { PipelineItemModel } from '../tree_view/items/pipeline_item_model'; import { currentBranchRefresher } from '../current_branch_refresher'; import { cancelPipeline, retryPipeline } from './pipeline_actions'; jest.mock('../gitlab/get_gitlab_service'); jest.mock('../current_branch_refresher'); describe('retryOrCancelPipeline', () => { const item = new PipelineItemModel(projectInRepository, pipeline, [job]); Loading @@ -15,7 +16,7 @@ describe('retryOrCancelPipeline', () => { }); beforeEach(() => { (vscode.window.withProgress as jest.Mock).mockImplementation((_, task) => task()); jest.mocked(currentBranchRefresher.refresh).mockResolvedValue(undefined); jest.mocked(getGitLabService).mockReturnValue(gitLabService); }); Loading src/desktop/commands/pipeline_actions.ts +4 −4 Original line number Diff line number Diff line import * as vscode from 'vscode'; import { USER_COMMANDS } from '../command_names'; import { getGitLabService } from '../gitlab/get_gitlab_service'; import { ProjectInRepositoryProvider } from '../gitlab/new_project'; import { PipelineProvider } from '../tree_view/items/pipeline_provider'; import { PipelineItemModel } from '../tree_view/items/pipeline_item_model'; import { currentBranchDataProvider } from '../tree_view/current_branch_data_provider'; import { currentBranchRefresher } from '../current_branch_refresher'; async function retryOrCancelPipeline( action: 'retry' | 'cancel', Loading @@ -11,13 +11,13 @@ async function retryOrCancelPipeline( ): Promise<RestPipeline | undefined> { const { pipeline, projectInRepository } = provider; const gitlabService = getGitLabService(projectInRepository); return vscode.window.withProgress({ location: { viewId: 'currentBranchInfo' } }, async () => { return currentBranchDataProvider.withMarkedAsBusy('pipeline', pipeline.id, async () => { const result = await gitlabService.cancelOrRetryPipeline( action, projectInRepository.project, pipeline, ); if (result) await vscode.commands.executeCommand(USER_COMMANDS.REFRESH_SIDEBAR); if (result) await currentBranchRefresher.refresh(); return result; }); } Loading src/desktop/gitlab/ci_status_metadata.ts +25 −6 Original line number Diff line number Diff line Loading @@ -13,6 +13,7 @@ export interface CiStatusMetadata { } type IconName = | 'sync~spin' | 'pass' | 'play' | 'debug-pause' Loading @@ -31,8 +32,10 @@ const errorColor = 'testing.iconErrored'; const inProgressColor = 'debugIcon.pauseForeground'; const grayColor = 'testing.iconSkipped'; const icon = (name: IconName, color: string) => new vscode.ThemeIcon(name, new vscode.ThemeColor(color)); const icon = (name: IconName, color?: string) => new vscode.ThemeIcon(name, color ? new vscode.ThemeColor(color) : undefined); const syncingIcon = icon('sync~spin'); const STATUS_METADATA: Record<string, CiStatusMetadata> = { manual: { Loading Loading @@ -125,7 +128,7 @@ const STATUS_METADATA: Record<string, CiStatusMetadata> = { }, canceling: { name: 'Cancelling', icon: icon('circle-slash', grayColor), icon: icon('circle-slash'), priority: 10, contextAction: 'retryable', illustration: { Loading Loading @@ -170,7 +173,7 @@ const ERASED: Partial<CiStatusMetadata> = { }, }; export const getJobMetadata = (job: RestJob): CiStatusMetadata => { export const getJobMetadata = (job: RestJob, isBusy: boolean = false): CiStatusMetadata => { let data: CiStatusMetadata; if (job.status === 'failed' && job.allow_failure) { data = FAILED_ALLOWED; Loading @@ -178,11 +181,27 @@ export const getJobMetadata = (job: RestJob): CiStatusMetadata => { data = STATUS_METADATA[job.status] || UNKNOWN_STATUS; } if (isBusy && data.contextAction === 'cancellable') { data = STATUS_METADATA.canceling; } else if (isBusy) { data = { ...data, icon: syncingIcon }; } if (job.erased_at) { data = { ...data, ...ERASED }; } return { ...COMMON, ...data }; }; export const getPipelineMetadata = (pipeline: RestPipeline): CiStatusMetadata => STATUS_METADATA[pipeline.status] || UNKNOWN_STATUS; export const getPipelineMetadata = ( pipeline: RestPipeline, isBusy: boolean = false, ): CiStatusMetadata => { let data = STATUS_METADATA[pipeline.status] || UNKNOWN_STATUS; if (isBusy && data.contextAction === 'cancellable') { data = STATUS_METADATA.canceling; } else if (isBusy) { data = { ...data, icon: syncingIcon }; } return data; }; Loading
src/desktop/commands/job_actions.test.ts +3 −2 Original line number Diff line number Diff line import vscode from 'vscode'; import { getGitLabService } from '../gitlab/get_gitlab_service'; import { job, projectInRepository } from '../test_utils/entities'; import { GitLabService } from '../gitlab/gitlab_service'; import { JobItemModel } from '../tree_view/items/job_item_model'; import { createFakePartial } from '../../common/test_utils/create_fake_partial'; import { currentBranchRefresher } from '../current_branch_refresher'; import { cancelJob, executeJob, retryJob } from './job_actions'; jest.mock('../gitlab/get_gitlab_service'); jest.mock('../current_branch_refresher'); describe('retryOrCancelJobItemModel', () => { const mockActions: Record<string, 'canceled' | 'pending'> = { Loading @@ -23,7 +24,7 @@ describe('retryOrCancelJobItemModel', () => { const model = new JobItemModel(projectInRepository, job); beforeEach(() => { (vscode.window.withProgress as jest.Mock).mockImplementation((_, task) => task()); jest.mocked(currentBranchRefresher.refresh).mockResolvedValue(undefined); jest.mocked(getGitLabService).mockReturnValue(gitlabService); }); Loading
src/desktop/commands/job_actions.ts +4 −4 Original line number Diff line number Diff line import * as vscode from 'vscode'; import { USER_COMMANDS } from '../command_names'; import { getGitLabService } from '../gitlab/get_gitlab_service'; import { JobItemModel } from '../tree_view/items/job_item_model'; import { currentBranchDataProvider } from '../tree_view/current_branch_data_provider'; import { currentBranchRefresher } from '../current_branch_refresher'; async function retryOrCancelJobItemModel( action: 'retry' | 'cancel' | 'play', Loading @@ -9,9 +9,9 @@ async function retryOrCancelJobItemModel( ): Promise<RestJob | undefined> { const { job, projectInRepository } = item; const gitlabService = getGitLabService(projectInRepository); return vscode.window.withProgress({ location: { viewId: 'currentBranchInfo' } }, async () => { return currentBranchDataProvider.withMarkedAsBusy('job', job.id, async () => { const result = await gitlabService.cancelOrRetryJob(action, projectInRepository.project, job); if (result) await vscode.commands.executeCommand(USER_COMMANDS.REFRESH_SIDEBAR); if (result) await currentBranchRefresher.refresh(); return result; }); } Loading
src/desktop/commands/pipeline_actions.test.ts +3 −2 Original line number Diff line number Diff line import vscode from 'vscode'; import { createFakePartial } from '../../common/test_utils/create_fake_partial'; import { getGitLabService } from '../gitlab/get_gitlab_service'; import { GitLabService } from '../gitlab/gitlab_service'; import { job, pipeline, projectInRepository } from '../test_utils/entities'; import { PipelineItemModel } from '../tree_view/items/pipeline_item_model'; import { currentBranchRefresher } from '../current_branch_refresher'; import { cancelPipeline, retryPipeline } from './pipeline_actions'; jest.mock('../gitlab/get_gitlab_service'); jest.mock('../current_branch_refresher'); describe('retryOrCancelPipeline', () => { const item = new PipelineItemModel(projectInRepository, pipeline, [job]); Loading @@ -15,7 +16,7 @@ describe('retryOrCancelPipeline', () => { }); beforeEach(() => { (vscode.window.withProgress as jest.Mock).mockImplementation((_, task) => task()); jest.mocked(currentBranchRefresher.refresh).mockResolvedValue(undefined); jest.mocked(getGitLabService).mockReturnValue(gitLabService); }); Loading
src/desktop/commands/pipeline_actions.ts +4 −4 Original line number Diff line number Diff line import * as vscode from 'vscode'; import { USER_COMMANDS } from '../command_names'; import { getGitLabService } from '../gitlab/get_gitlab_service'; import { ProjectInRepositoryProvider } from '../gitlab/new_project'; import { PipelineProvider } from '../tree_view/items/pipeline_provider'; import { PipelineItemModel } from '../tree_view/items/pipeline_item_model'; import { currentBranchDataProvider } from '../tree_view/current_branch_data_provider'; import { currentBranchRefresher } from '../current_branch_refresher'; async function retryOrCancelPipeline( action: 'retry' | 'cancel', Loading @@ -11,13 +11,13 @@ async function retryOrCancelPipeline( ): Promise<RestPipeline | undefined> { const { pipeline, projectInRepository } = provider; const gitlabService = getGitLabService(projectInRepository); return vscode.window.withProgress({ location: { viewId: 'currentBranchInfo' } }, async () => { return currentBranchDataProvider.withMarkedAsBusy('pipeline', pipeline.id, async () => { const result = await gitlabService.cancelOrRetryPipeline( action, projectInRepository.project, pipeline, ); if (result) await vscode.commands.executeCommand(USER_COMMANDS.REFRESH_SIDEBAR); if (result) await currentBranchRefresher.refresh(); return result; }); } Loading
src/desktop/gitlab/ci_status_metadata.ts +25 −6 Original line number Diff line number Diff line Loading @@ -13,6 +13,7 @@ export interface CiStatusMetadata { } type IconName = | 'sync~spin' | 'pass' | 'play' | 'debug-pause' Loading @@ -31,8 +32,10 @@ const errorColor = 'testing.iconErrored'; const inProgressColor = 'debugIcon.pauseForeground'; const grayColor = 'testing.iconSkipped'; const icon = (name: IconName, color: string) => new vscode.ThemeIcon(name, new vscode.ThemeColor(color)); const icon = (name: IconName, color?: string) => new vscode.ThemeIcon(name, color ? new vscode.ThemeColor(color) : undefined); const syncingIcon = icon('sync~spin'); const STATUS_METADATA: Record<string, CiStatusMetadata> = { manual: { Loading Loading @@ -125,7 +128,7 @@ const STATUS_METADATA: Record<string, CiStatusMetadata> = { }, canceling: { name: 'Cancelling', icon: icon('circle-slash', grayColor), icon: icon('circle-slash'), priority: 10, contextAction: 'retryable', illustration: { Loading Loading @@ -170,7 +173,7 @@ const ERASED: Partial<CiStatusMetadata> = { }, }; export const getJobMetadata = (job: RestJob): CiStatusMetadata => { export const getJobMetadata = (job: RestJob, isBusy: boolean = false): CiStatusMetadata => { let data: CiStatusMetadata; if (job.status === 'failed' && job.allow_failure) { data = FAILED_ALLOWED; Loading @@ -178,11 +181,27 @@ export const getJobMetadata = (job: RestJob): CiStatusMetadata => { data = STATUS_METADATA[job.status] || UNKNOWN_STATUS; } if (isBusy && data.contextAction === 'cancellable') { data = STATUS_METADATA.canceling; } else if (isBusy) { data = { ...data, icon: syncingIcon }; } if (job.erased_at) { data = { ...data, ...ERASED }; } return { ...COMMON, ...data }; }; export const getPipelineMetadata = (pipeline: RestPipeline): CiStatusMetadata => STATUS_METADATA[pipeline.status] || UNKNOWN_STATUS; export const getPipelineMetadata = ( pipeline: RestPipeline, isBusy: boolean = false, ): CiStatusMetadata => { let data = STATUS_METADATA[pipeline.status] || UNKNOWN_STATUS; if (isBusy && data.contextAction === 'cancellable') { data = STATUS_METADATA.canceling; } else if (isBusy) { data = { ...data, icon: syncingIcon }; } return data; };