@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@backstage/plugin-scaffolder': patch
|
||||
---
|
||||
|
||||
Preserve time execution for a non-running task
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
'@backstage/plugin-scaffolder-common': patch
|
||||
'@backstage/plugin-scaffolder-react': patch
|
||||
---
|
||||
|
||||
Make it possible to define control buttons text (Back, Create, Review) per template
|
||||
@@ -21,11 +21,6 @@ import { rest } from 'msw';
|
||||
import { setupServer } from 'msw/node';
|
||||
import { ScaffolderClient } from './api';
|
||||
import { EventSourcePolyfill } from 'event-source-polyfill';
|
||||
import {
|
||||
SerializedTask,
|
||||
SerializedTaskEvent,
|
||||
} from '@backstage/plugin-scaffolder-node';
|
||||
import { ScaffolderStep } from '@backstage/plugin-scaffolder-react';
|
||||
|
||||
const MockedEventSource = EventSourcePolyfill as jest.MockedClass<
|
||||
typeof EventSourcePolyfill
|
||||
|
||||
@@ -38,13 +38,10 @@ import {
|
||||
ScaffolderDryRunOptions,
|
||||
ScaffolderDryRunResponse,
|
||||
TemplateParameterSchema,
|
||||
ScaffolderStep,
|
||||
} from '@backstage/plugin-scaffolder-react';
|
||||
import { TaskStep } from '@backstage/plugin-scaffolder-common';
|
||||
|
||||
import queryString from 'qs';
|
||||
import { EventSourcePolyfill } from 'event-source-polyfill';
|
||||
import { SerializedTaskEvent } from '@backstage/plugin-scaffolder-node';
|
||||
|
||||
/**
|
||||
* An API to interact with the scaffolder backend.
|
||||
@@ -173,62 +170,14 @@ export class ScaffolderClient implements ScaffolderApi {
|
||||
|
||||
async getTask(taskId: string): Promise<ScaffolderTask> {
|
||||
const baseUrl = await this.discoveryApi.getBaseUrl('scaffolder');
|
||||
const taskUrl = `${baseUrl}/v2/tasks/${encodeURIComponent(taskId)}`;
|
||||
const url = `${baseUrl}/v2/tasks/${encodeURIComponent(taskId)}`;
|
||||
|
||||
const taskEventsUrl = `${baseUrl}/v2/tasks/${encodeURIComponent(
|
||||
taskId,
|
||||
)}/events`;
|
||||
|
||||
const taskResponse = await this.fetchApi.fetch(taskUrl);
|
||||
if (!taskResponse.ok) {
|
||||
throw await ResponseError.fromResponse(taskResponse);
|
||||
const response = await this.fetchApi.fetch(url);
|
||||
if (!response.ok) {
|
||||
throw await ResponseError.fromResponse(response);
|
||||
}
|
||||
|
||||
const taskEventsResponse = await this.fetchApi.fetch(taskEventsUrl);
|
||||
if (!taskEventsResponse.ok) {
|
||||
throw await ResponseError.fromResponse(taskEventsResponse);
|
||||
}
|
||||
|
||||
const task = (await taskResponse.json()) as ScaffolderTask;
|
||||
const taskEvents =
|
||||
(await taskEventsResponse.json()) as SerializedTaskEvent[];
|
||||
|
||||
const stepIdToTimestamps = taskEvents
|
||||
.filter(event => event.type === 'log')
|
||||
.reduce((acc, event) => {
|
||||
const stepId = event.body.stepId as string;
|
||||
if (stepId) {
|
||||
acc.set(stepId, [...(acc.get(stepId) ?? []), event.createdAt]);
|
||||
}
|
||||
return acc;
|
||||
}, new Map<string, string[]>());
|
||||
|
||||
const toStartedAt = (stepId: string) => {
|
||||
const timestamps = stepIdToTimestamps.get(stepId);
|
||||
return timestamps ? timestamps[0] : undefined;
|
||||
};
|
||||
|
||||
const toEndedAt = (stepId: string) => {
|
||||
const timestamps = stepIdToTimestamps.get(stepId);
|
||||
return timestamps ? timestamps[timestamps.length - 1] : undefined;
|
||||
};
|
||||
|
||||
const enrichedTask = {
|
||||
...task,
|
||||
spec: {
|
||||
...task.spec,
|
||||
steps: task.spec.steps.map(
|
||||
step =>
|
||||
({
|
||||
...step,
|
||||
startedAt: toStartedAt(step.id),
|
||||
endedAt: toEndedAt(step.id),
|
||||
} as TaskStep & ScaffolderStep),
|
||||
),
|
||||
},
|
||||
};
|
||||
|
||||
return enrichedTask as ScaffolderTask;
|
||||
return await response.json();
|
||||
}
|
||||
|
||||
streamLogs(options: ScaffolderStreamLogsOptions): Observable<LogEvent> {
|
||||
|
||||
Reference in New Issue
Block a user