diff --git a/plugins/scaffolder-backend/api-report.md b/plugins/scaffolder-backend/api-report.md index 467887dfc5..742834a4df 100644 --- a/plugins/scaffolder-backend/api-report.md +++ b/plugins/scaffolder-backend/api-report.md @@ -9,6 +9,7 @@ import * as bitbucket from '@backstage/plugin-scaffolder-backend-module-bitbucke import * as bitbucketCloud from '@backstage/plugin-scaffolder-backend-module-bitbucket-cloud'; import * as bitbucketServer from '@backstage/plugin-scaffolder-backend-module-bitbucket-server'; import { CatalogApi } from '@backstage/catalog-client'; +import { CheckpointRecord } from '@backstage/plugin-scaffolder-node'; import { Config } from '@backstage/config'; import { Duration } from 'luxon'; import { executeShellCommand as executeShellCommand_2 } from '@backstage/plugin-scaffolder-node'; @@ -47,6 +48,7 @@ import { TaskRecovery } from '@backstage/plugin-scaffolder-common'; import { TaskSecrets as TaskSecrets_2 } from '@backstage/plugin-scaffolder-node'; import { TaskSpec } from '@backstage/plugin-scaffolder-common'; import { TaskSpecV1beta3 } from '@backstage/plugin-scaffolder-common'; +import { TaskState } from '@backstage/plugin-scaffolder-node'; import { TaskStatus as TaskStatus_2 } from '@backstage/plugin-scaffolder-node'; import { TemplateAction as TemplateAction_2 } from '@backstage/plugin-scaffolder-node'; import { TemplateActionOptions } from '@backstage/plugin-scaffolder-node'; @@ -359,6 +361,7 @@ export interface CurrentClaimedTask { createdBy?: string; secrets?: TaskSecrets_2; spec: TaskSpec; + state?: TaskState; taskId: string; } @@ -403,6 +406,10 @@ export class DatabaseTaskStore implements TaskStore { tasks: SerializedTask_2[]; }>; // (undocumented) + listCheckpoints({ taskId }: { taskId: string }): Promise<{ + state: TaskState; + }>; + // (undocumented) listEvents(options: TaskStoreListEventsOptions): Promise<{ events: SerializedTaskEvent_2[]; }>; @@ -418,6 +425,8 @@ export class DatabaseTaskStore implements TaskStore { ids: string[]; }>; // (undocumented) + saveCheckpoint(options: TaskStoreStateOptions): Promise; + // (undocumented) shutdownTask(options: TaskStoreShutDownTaskOptions): Promise; } @@ -519,11 +528,20 @@ export class TaskManager implements TaskContext { // (undocumented) emitLog(message: string, logMetadata?: JsonObject): Promise; // (undocumented) + getCheckpoints?(): Promise< + | { + state: TaskState; + } + | undefined + >; + // (undocumented) getWorkspaceName(): Promise; // (undocumented) get secrets(): TaskSecrets_2 | undefined; // (undocumented) get spec(): TaskSpecV1beta3; + // (undocumented) + updateCheckpoint?(options: CheckpointRecord): Promise; } // @public @deprecated (undocumented) @@ -559,6 +577,10 @@ export interface TaskStore { tasks: SerializedTask[]; }>; // (undocumented) + listCheckpoints?({ taskId }: { taskId: string }): Promise<{ + state: TaskState; + }>; + // (undocumented) listEvents(options: TaskStoreListEventsOptions): Promise<{ events: SerializedTaskEvent[]; }>; @@ -573,6 +595,8 @@ export interface TaskStore { ids: string[]; }>; // (undocumented) + saveCheckpoint?(options: TaskStoreStateOptions): Promise; + // (undocumented) shutdownTask?(options: TaskStoreShutDownTaskOptions): Promise; } @@ -610,6 +634,12 @@ export type TaskStoreShutDownTaskOptions = { taskId: string; }; +// @public +export type TaskStoreStateOptions = { + taskId: string; + state?: TaskState; +}; + // @public export class TaskWorker { // (undocumented) diff --git a/plugins/scaffolder-backend/src/scaffolder/tasks/StorageTaskBroker.ts b/plugins/scaffolder-backend/src/scaffolder/tasks/StorageTaskBroker.ts index d7fe1be6af..6e01141dab 100644 --- a/plugins/scaffolder-backend/src/scaffolder/tasks/StorageTaskBroker.ts +++ b/plugins/scaffolder-backend/src/scaffolder/tasks/StorageTaskBroker.ts @@ -100,11 +100,11 @@ export class TaskManager implements TaskContext { } async updateCheckpoint?(options: CheckpointRecord): Promise { - // drop the key + const { key, ...value } = options; if (this.task.state) { - this.task.state[options.key] = { ...options }; + this.task.state[key] = value; } else { - this.task.state = { [options.key]: options }; + this.task.state = { [key]: value }; } await this.storage.saveCheckpoint?.({ taskId: this.task.taskId, diff --git a/plugins/scaffolder-backend/src/scaffolder/tasks/index.ts b/plugins/scaffolder-backend/src/scaffolder/tasks/index.ts index 9d231d7e7c..2da812e869 100644 --- a/plugins/scaffolder-backend/src/scaffolder/tasks/index.ts +++ b/plugins/scaffolder-backend/src/scaffolder/tasks/index.ts @@ -25,6 +25,7 @@ export type { TaskStoreEmitOptions, TaskStoreListEventsOptions, TaskStoreShutDownTaskOptions, + TaskStoreStateOptions, SerializedTask, SerializedTaskEvent, TaskStatus, diff --git a/plugins/scaffolder-backend/src/scaffolder/tasks/types.ts b/plugins/scaffolder-backend/src/scaffolder/tasks/types.ts index 54c0f19782..e30de5db94 100644 --- a/plugins/scaffolder-backend/src/scaffolder/tasks/types.ts +++ b/plugins/scaffolder-backend/src/scaffolder/tasks/types.ts @@ -113,6 +113,11 @@ export type TaskStoreEmitOptions = { body: TBody; }; +/** + * TaskStoreStateOptions + * + * @public + */ export type TaskStoreStateOptions = { taskId: string; state?: TaskState; diff --git a/plugins/scaffolder-node/api-report.md b/plugins/scaffolder-node/api-report.md index fec2205462..d3bc9d8500 100644 --- a/plugins/scaffolder-node/api-report.md +++ b/plugins/scaffolder-node/api-report.md @@ -30,6 +30,10 @@ export type ActionContext< secrets?: TaskSecrets; workspacePath: string; input: TActionInput; + checkpoint?( + key: string, + fn: () => Promise, + ): Promise; output( name: keyof TActionOutput, value: TActionOutput[keyof TActionOutput], @@ -60,6 +64,19 @@ export function addFiles(options: { logger?: Logger | undefined; }): Promise; +// @public +export type CheckpointRecord = + | { + key: string; + status: 'success'; + value: JsonValue; + } + | { + key: string; + status: 'failed'; + reason: string; + }; + // @public (undocumented) export function cloneRepo(options: { url: string; @@ -345,6 +362,13 @@ export interface TaskContext { // (undocumented) emitLog(message: string, logMetadata?: JsonObject): Promise; // (undocumented) + getCheckpoints?(): Promise< + | { + state: TaskState; + } + | undefined + >; + // (undocumented) getWorkspaceName(): Promise; // (undocumented) isDryRun?: boolean; @@ -352,6 +376,10 @@ export interface TaskContext { secrets?: TaskSecrets; // (undocumented) spec: TaskSpec; + // (undocumented) + state?: TaskState; + // (undocumented) + updateCheckpoint?(options: CheckpointRecord): Promise; } // @public @@ -362,6 +390,19 @@ export type TaskSecrets = Record & { backstageToken?: string; }; +// @public +export type TaskState = { + [key: string]: + | { + status: 'failed'; + reason: string; + } + | { + status: 'success'; + value: JsonValue; + }; +}; + // @public export type TaskStatus = | 'cancelled' diff --git a/plugins/scaffolder-node/src/actions/types.ts b/plugins/scaffolder-node/src/actions/types.ts index 5abeb29a2b..678d6f87d7 100644 --- a/plugins/scaffolder-node/src/actions/types.ts +++ b/plugins/scaffolder-node/src/actions/types.ts @@ -35,7 +35,7 @@ export type ActionContext< secrets?: TaskSecrets; workspacePath: string; input: TActionInput; - checkpoint( + checkpoint?( key: string, fn: () => Promise, ): Promise; diff --git a/plugins/scaffolder-node/src/tasks/types.ts b/plugins/scaffolder-node/src/tasks/types.ts index b2bff61e03..a7fbf4ac76 100644 --- a/plugins/scaffolder-node/src/tasks/types.ts +++ b/plugins/scaffolder-node/src/tasks/types.ts @@ -27,7 +27,7 @@ export type TaskSecrets = Record & { }; /** - * The record passed to {@link TaskBroker.updateCheckpoint?} + * The record passed to TaskBroker for updating a checkpoint. * Parameters to store the result of the executed checkpoint * * @public @@ -45,7 +45,7 @@ export type CheckpointRecord = }; /** - * TaskState + * The state of all task's checkpoints * * @public */