Cancelling the running task (executing of a scaffolder template)
Signed-off-by: Bogdan Nechyporenko <bnechyporenko@bol.com>
This commit is contained in:
@@ -24,10 +24,11 @@ import { TemplateParameterSchema } from '../types';
|
||||
* @public
|
||||
*/
|
||||
export type ScaffolderTaskStatus =
|
||||
| 'cancelled'
|
||||
| 'completed'
|
||||
| 'failed'
|
||||
| 'open'
|
||||
| 'processing'
|
||||
| 'failed'
|
||||
| 'completed'
|
||||
| 'skipped';
|
||||
|
||||
/**
|
||||
@@ -96,7 +97,7 @@ export type ScaffolderTaskOutput = {
|
||||
* @public
|
||||
*/
|
||||
export type LogEvent = {
|
||||
type: 'log' | 'completion';
|
||||
type: 'log' | 'completion' | 'cancelled';
|
||||
body: {
|
||||
message: string;
|
||||
stepId?: string;
|
||||
@@ -196,6 +197,13 @@ export interface ScaffolderApi {
|
||||
|
||||
getTask(taskId: string): Promise<ScaffolderTask>;
|
||||
|
||||
/**
|
||||
* Sends a signal to a task broker to cancel the running task by taskId.
|
||||
*
|
||||
* @param taskId - the id of the task
|
||||
*/
|
||||
cancelTask(taskId: string): Promise<void>;
|
||||
|
||||
listTasks?(options: {
|
||||
filterByOwnership: 'owned' | 'all';
|
||||
}): Promise<{ tasks: ScaffolderTask[] }>;
|
||||
|
||||
@@ -44,6 +44,7 @@ export type ScaffolderStep = {
|
||||
* @public
|
||||
*/
|
||||
export type TaskStream = {
|
||||
cancelled: boolean;
|
||||
loading: boolean;
|
||||
error?: Error;
|
||||
stepLogs: { [stepId in string]: string[] };
|
||||
@@ -66,6 +67,7 @@ type ReducerLogEntry = {
|
||||
|
||||
type ReducerAction =
|
||||
| { type: 'INIT'; data: ScaffolderTask }
|
||||
| { type: 'CANCELLED' }
|
||||
| { type: 'LOGS'; data: ReducerLogEntry[] }
|
||||
| { type: 'COMPLETED'; data: ReducerLogEntry }
|
||||
| { type: 'ERROR'; data: Error };
|
||||
@@ -111,7 +113,7 @@ function reducer(draft: TaskStream, action: ReducerAction) {
|
||||
}
|
||||
|
||||
if (
|
||||
['cancelled', 'failed', 'completed'].includes(currentStep.status)
|
||||
['cancelled', 'completed', 'failed'].includes(currentStep.status)
|
||||
) {
|
||||
currentStep.endedAt = entry.createdAt;
|
||||
}
|
||||
@@ -131,6 +133,11 @@ function reducer(draft: TaskStream, action: ReducerAction) {
|
||||
return;
|
||||
}
|
||||
|
||||
case 'CANCELLED': {
|
||||
draft.cancelled = true;
|
||||
return;
|
||||
}
|
||||
|
||||
case 'ERROR': {
|
||||
draft.error = action.data;
|
||||
draft.loading = false;
|
||||
@@ -151,6 +158,7 @@ function reducer(draft: TaskStream, action: ReducerAction) {
|
||||
export const useTaskEventStream = (taskId: string): TaskStream => {
|
||||
const scaffolderApi = useApi(scaffolderApiRef);
|
||||
const [state, dispatch] = useImmerReducer(reducer, {
|
||||
cancelled: false,
|
||||
loading: true,
|
||||
completed: false,
|
||||
stepLogs: {} as { [stepId in string]: string[] },
|
||||
@@ -196,6 +204,9 @@ export const useTaskEventStream = (taskId: string): TaskStream => {
|
||||
switch (event.type) {
|
||||
case 'log':
|
||||
return collectedLogEvents.push(event);
|
||||
case 'cancelled':
|
||||
dispatch({ type: 'CANCELLED' });
|
||||
return undefined;
|
||||
case 'completion':
|
||||
emitLogs();
|
||||
dispatch({ type: 'COMPLETED', data: event });
|
||||
|
||||
@@ -24,10 +24,10 @@ import { act, fireEvent } from '@testing-library/react';
|
||||
import React from 'react';
|
||||
import { Workflow } from './Workflow';
|
||||
import { analyticsApiRef } from '@backstage/core-plugin-api';
|
||||
import { ScaffolderApi } from '../../../api/types';
|
||||
import { scaffolderApiRef } from '../../../api/ref';
|
||||
import { ScaffolderApi, scaffolderApiRef } from '../../../api';
|
||||
|
||||
const scaffolderApiMock: jest.Mocked<ScaffolderApi> = {
|
||||
cancelTask: jest.fn(),
|
||||
scaffold: jest.fn(),
|
||||
getTemplateParameterSchema: jest.fn(),
|
||||
getIntegrationsList: jest.fn(),
|
||||
|
||||
Reference in New Issue
Block a user