@backstage/plugin-scaffolder-backend 0.16.1 → 0.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -3,11 +3,10 @@ import { ScmIntegrations, ScmIntegrationRegistry, GithubCredentialsProvider } fr
3
3
  import { CatalogApi } from '@backstage/catalog-client';
4
4
  import { Logger } from 'winston';
5
5
  import { Writable } from 'stream';
6
- import { JsonValue, JsonObject } from '@backstage/types';
6
+ import { JsonValue, JsonObject, Observable } from '@backstage/types';
7
7
  import { Schema } from 'jsonschema';
8
- import { TaskSpec, TemplateMetadata } from '@backstage/plugin-scaffolder-common';
9
- export { TaskSpec, TaskSpecV1beta2, TaskSpecV1beta3, TemplateMetadata } from '@backstage/plugin-scaffolder-common';
10
- import { Entity, LocationSpec } from '@backstage/catalog-model';
8
+ import { TaskSpec, TemplateMetadata, TemplateInfo } from '@backstage/plugin-scaffolder-common';
9
+ import { Entity } from '@backstage/catalog-model';
11
10
  import { UrlReader, ContainerRunner, PluginDatabaseManager } from '@backstage/backend-common';
12
11
  import { Config } from '@backstage/config';
13
12
  import { createPullRequest } from 'octokit-plugin-create-pull-request';
@@ -16,7 +15,7 @@ export { createFetchCookiecutterAction } from '@backstage/plugin-scaffolder-back
16
15
  import { SpawnOptionsWithoutStdio } from 'child_process';
17
16
  import { Knex } from 'knex';
18
17
  import express from 'express';
19
- import { CatalogProcessor, CatalogProcessorEmit } from '@backstage/plugin-catalog-backend';
18
+ import { CatalogProcessor, LocationSpec, CatalogProcessorEmit } from '@backstage/plugin-catalog-backend';
20
19
 
21
20
  declare function createCatalogRegisterAction(options: {
22
21
  catalogClient: CatalogApi;
@@ -38,17 +37,31 @@ declare function createCatalogWriteAction(): TemplateAction<{
38
37
  declare type TemplateFilter = (...args: JsonValue[]) => JsonValue | undefined;
39
38
 
40
39
  /**
41
- * Status
40
+ * The status of each step of the Task
42
41
  *
43
42
  * @public
44
43
  */
45
- declare type Status = 'open' | 'processing' | 'failed' | 'cancelled' | 'completed';
44
+ declare type TaskStatus = 'open' | 'processing' | 'failed' | 'cancelled' | 'completed';
46
45
  /**
47
- * CompletedTaskState
46
+ * The status of each step of the Task
48
47
  *
49
48
  * @public
49
+ * @deprecated use TaskStatus instead
50
50
  */
51
- declare type CompletedTaskState = 'failed' | 'completed';
51
+ declare type Status = TaskStatus;
52
+ /**
53
+ * The state of a completed task.
54
+ *
55
+ * @public
56
+ */
57
+ declare type TaskCompletionState = 'failed' | 'completed';
58
+ /**
59
+ * The state of a completed task.
60
+ *
61
+ * @public
62
+ * @deprecated use TaskCompletionState instead
63
+ */
64
+ declare type CompletedTaskState = TaskCompletionState;
52
65
  /**
53
66
  * SerializedTask
54
67
  *
@@ -57,7 +70,7 @@ declare type CompletedTaskState = 'failed' | 'completed';
57
70
  declare type SerializedTask = {
58
71
  id: string;
59
72
  spec: TaskSpec;
60
- status: Status;
73
+ status: TaskStatus;
61
74
  createdAt: string;
62
75
  lastHeartbeatAt?: string;
63
76
  secrets?: TaskSecrets;
@@ -89,13 +102,30 @@ declare type TaskSecrets = Record<string, string> & {
89
102
  backstageToken?: string;
90
103
  };
91
104
  /**
92
- * DispatchResult
105
+ * The result of {@link TaskBroker.dispatch}
93
106
  *
94
107
  * @public
95
108
  */
96
- declare type DispatchResult = {
109
+ declare type TaskBrokerDispatchResult = {
97
110
  taskId: string;
98
111
  };
112
+ /**
113
+ * The options passed to {@link TaskBroker.dispatch}
114
+ * Currently a spec and optional secrets
115
+ *
116
+ * @public
117
+ */
118
+ declare type TaskBrokerDispatchOptions = {
119
+ spec: TaskSpec;
120
+ secrets?: TaskSecrets;
121
+ };
122
+ /**
123
+ * DispatchResult
124
+ *
125
+ * @public
126
+ * @deprecated use TaskBrokerDispatchResult instead
127
+ */
128
+ declare type DispatchResult = TaskBrokerDispatchResult;
99
129
  /**
100
130
  * Task
101
131
  *
@@ -105,8 +135,8 @@ interface TaskContext {
105
135
  spec: TaskSpec;
106
136
  secrets?: TaskSecrets;
107
137
  done: boolean;
108
- emitLog(message: string, metadata?: JsonValue): Promise<void>;
109
- complete(result: CompletedTaskState, metadata?: JsonValue): Promise<void>;
138
+ emitLog(message: string, logMetadata?: JsonObject): Promise<void>;
139
+ complete(result: TaskCompletionState, metadata?: JsonObject): Promise<void>;
110
140
  getWorkspaceName(): Promise<string>;
111
141
  }
112
142
  /**
@@ -116,18 +146,16 @@ interface TaskContext {
116
146
  */
117
147
  interface TaskBroker {
118
148
  claim(): Promise<TaskContext>;
119
- dispatch(spec: TaskSpec, secrets?: TaskSecrets): Promise<DispatchResult>;
120
- vacuumTasks(timeoutS: {
149
+ dispatch(options: TaskBrokerDispatchOptions): Promise<TaskBrokerDispatchResult>;
150
+ vacuumTasks(options: {
121
151
  timeoutS: number;
122
152
  }): Promise<void>;
123
- observe(options: {
153
+ event$(options: {
124
154
  taskId: string;
125
155
  after: number | undefined;
126
- }, callback: (error: Error | undefined, result: {
156
+ }): Observable<{
127
157
  events: SerializedTaskEvent[];
128
- }) => void): {
129
- unsubscribe: () => void;
130
- };
158
+ }>;
131
159
  get(taskId: string): Promise<SerializedTask>;
132
160
  }
133
161
  /**
@@ -135,9 +163,9 @@ interface TaskBroker {
135
163
  *
136
164
  * @public
137
165
  */
138
- declare type TaskStoreEmitOptions = {
166
+ declare type TaskStoreEmitOptions<TBody = JsonObject> = {
139
167
  taskId: string;
140
- body: JsonObject;
168
+ body: TBody;
141
169
  };
142
170
  /**
143
171
  * TaskStoreListEventsOptions
@@ -148,20 +176,33 @@ declare type TaskStoreListEventsOptions = {
148
176
  taskId: string;
149
177
  after?: number | undefined;
150
178
  };
179
+ /**
180
+ * The options passed to {@link TaskStore.createTask}
181
+ * @public
182
+ */
183
+ declare type TaskStoreCreateTaskOptions = {
184
+ spec: TaskSpec;
185
+ secrets?: TaskSecrets;
186
+ };
187
+ /**
188
+ * The response from {@link TaskStore.createTask}
189
+ * @public
190
+ */
191
+ declare type TaskStoreCreateTaskResult = {
192
+ taskId: string;
193
+ };
151
194
  /**
152
195
  * TaskStore
153
196
  *
154
197
  * @public
155
198
  */
156
199
  interface TaskStore {
157
- createTask(task: TaskSpec, secrets?: TaskSecrets): Promise<{
158
- taskId: string;
159
- }>;
200
+ createTask(options: TaskStoreCreateTaskOptions): Promise<TaskStoreCreateTaskResult>;
160
201
  getTask(taskId: string): Promise<SerializedTask>;
161
202
  claimTask(): Promise<SerializedTask | undefined>;
162
203
  completeTask(options: {
163
204
  taskId: string;
164
- status: Status;
205
+ status: TaskStatus;
165
206
  eventBody: JsonObject;
166
207
  }): Promise<void>;
167
208
  heartbeatTask(taskId: string): Promise<void>;
@@ -181,6 +222,7 @@ interface TaskStore {
181
222
  declare type ActionContext<Input extends JsonObject> = {
182
223
  /**
183
224
  * Base URL for the location of the task spec, typically the url of the source entity file.
225
+ * @deprecated please use templateInfo.baseUrl instead
184
226
  */
185
227
  baseUrl?: string;
186
228
  logger: Logger;
@@ -193,7 +235,11 @@ declare type ActionContext<Input extends JsonObject> = {
193
235
  * Creates a temporary directory for use by the action, which is then cleaned up automatically.
194
236
  */
195
237
  createTemporaryDirectory(): Promise<string>;
238
+ /**
239
+ * @deprecated please use templateInfo instead
240
+ */
196
241
  metadata?: TemplateMetadata;
242
+ templateInfo?: TemplateInfo;
197
243
  };
198
244
  declare type TemplateAction<Input extends JsonObject> = {
199
245
  id: string;
@@ -205,14 +251,27 @@ declare type TemplateAction<Input extends JsonObject> = {
205
251
  handler: (ctx: ActionContext<Input>) => Promise<void>;
206
252
  };
207
253
 
208
- declare const createBuiltinActions: (options: {
254
+ /**
255
+ * The options passed to {@link createBuiltinActions}
256
+ * @public
257
+ */
258
+ interface CreateBuiltInActionsOptions {
209
259
  reader: UrlReader;
210
260
  integrations: ScmIntegrations;
211
261
  catalogClient: CatalogApi;
262
+ /** @deprecated when the cookiecutter action is removed this won't be necessary */
212
263
  containerRunner?: ContainerRunner;
213
264
  config: Config;
214
265
  additionalTemplateFilters?: Record<string, TemplateFilter>;
215
- }) => TemplateAction<JsonObject>[];
266
+ }
267
+ /**
268
+ * A function to generate create a list of default actions that the scaffolder provides.
269
+ * Is called internally in the default setup, but can be used when adding your own actions or overriding the default ones
270
+ *
271
+ * @public
272
+ * @returns A list of actions that can be used in the scaffolder
273
+ */
274
+ declare const createBuiltinActions: (options: CreateBuiltInActionsOptions) => TemplateAction<JsonObject>[];
216
275
 
217
276
  /**
218
277
  * This task is useful for local development and testing of both the scaffolder
@@ -244,11 +303,17 @@ declare function createFetchTemplateAction(options: {
244
303
  cookiecutterCompat?: boolean | undefined;
245
304
  }>;
246
305
 
306
+ /**
307
+ * A helper function that reads the contents of a directory from the given URL.
308
+ * Can be used in your own actions, and also used behind fetch:template and fetch:plain
309
+ *
310
+ * @public
311
+ */
247
312
  declare function fetchContents({ reader, integrations, baseUrl, fetchUrl, outputPath, }: {
248
313
  reader: UrlReader;
249
314
  integrations: ScmIntegrations;
250
315
  baseUrl?: string;
251
- fetchUrl?: JsonValue;
316
+ fetchUrl?: string;
252
317
  outputPath: string;
253
318
  }): Promise<void>;
254
319
 
@@ -410,6 +475,9 @@ declare type OctokitIntegration = {
410
475
  /**
411
476
  * OctokitProvider provides Octokit client based on ScmIntegrationsRegistry configuration.
412
477
  * OctokitProvider supports GitHub credentials caching out of the box.
478
+ *
479
+ * @deprecated we are no longer providing a way from the scaffolder to generate octokit instances.
480
+ * Implement your own if you're using this method from an external package, or use the internal `getOctokitOptions` function instead
413
481
  */
414
482
  declare class OctokitProvider {
415
483
  private readonly integrations;
@@ -419,6 +487,9 @@ declare class OctokitProvider {
419
487
  * gets standard Octokit client based on repository URL.
420
488
  *
421
489
  * @param repoUrl - Repository URL
490
+ *
491
+ * @deprecated we are no longer providing a way from the scaffolder to generate octokit instances.
492
+ * Implement your own if you're using this method from an external package, or use the internal `getOctokitOptions` function instead
422
493
  */
423
494
  getOctokit(repoUrl: string, options?: {
424
495
  token?: string;
@@ -437,8 +508,16 @@ declare type RunCommandOptions = {
437
508
  };
438
509
  /**
439
510
  * Run a command in a sub-process, normally a shell command.
511
+ *
512
+ * @public
440
513
  */
441
- declare const runCommand: ({ command, args, logStream, options, }: RunCommandOptions) => Promise<void>;
514
+ declare const executeShellCommand: (options: RunCommandOptions) => Promise<void>;
515
+ /**
516
+ * Run a command in a sub-process, normally a shell command.
517
+ * @public
518
+ * @deprecated use {@link executeShellCommand} instead
519
+ */
520
+ declare const runCommand: (options: RunCommandOptions) => Promise<void>;
442
521
 
443
522
  declare class TemplateActionRegistry {
444
523
  private readonly actions;
@@ -465,11 +544,9 @@ declare type DatabaseTaskStoreOptions = {
465
544
  declare class DatabaseTaskStore implements TaskStore {
466
545
  private readonly db;
467
546
  static create(options: DatabaseTaskStoreOptions): Promise<DatabaseTaskStore>;
468
- constructor(options: DatabaseTaskStoreOptions);
547
+ private constructor();
469
548
  getTask(taskId: string): Promise<SerializedTask>;
470
- createTask(spec: TaskSpec, secrets?: TaskSecrets): Promise<{
471
- taskId: string;
472
- }>;
549
+ createTask(options: TaskStoreCreateTaskOptions): Promise<TaskStoreCreateTaskResult>;
473
550
  claimTask(): Promise<SerializedTask | undefined>;
474
551
  heartbeatTask(taskId: string): Promise<void>;
475
552
  listStaleTasks({ timeoutS }: {
@@ -481,10 +558,12 @@ declare class DatabaseTaskStore implements TaskStore {
481
558
  }>;
482
559
  completeTask({ taskId, status, eventBody, }: {
483
560
  taskId: string;
484
- status: Status;
561
+ status: TaskStatus;
485
562
  eventBody: JsonObject;
486
563
  }): Promise<void>;
487
- emitLogEvent({ taskId, body }: TaskStoreEmitOptions): Promise<void>;
564
+ emitLogEvent(options: TaskStoreEmitOptions<{
565
+ message: string;
566
+ } & JsonObject>): Promise<void>;
488
567
  listEvents({ taskId, after, }: TaskStoreListEventsOptions): Promise<{
489
568
  events: SerializedTaskEvent[];
490
569
  }>;
@@ -496,31 +575,38 @@ declare class DatabaseTaskStore implements TaskStore {
496
575
  * @public
497
576
  */
498
577
  declare class TaskManager implements TaskContext {
499
- private readonly state;
578
+ private readonly task;
500
579
  private readonly storage;
501
580
  private readonly logger;
502
581
  private isDone;
503
582
  private heartbeatTimeoutId?;
504
- static create(state: TaskState, storage: TaskStore, logger: Logger): TaskManager;
583
+ static create(task: CurrentClaimedTask, storage: TaskStore, logger: Logger): TaskManager;
505
584
  private constructor();
506
585
  get spec(): TaskSpec;
507
586
  get secrets(): TaskSecrets | undefined;
508
587
  getWorkspaceName(): Promise<string>;
509
588
  get done(): boolean;
510
- emitLog(message: string, metadata?: JsonObject): Promise<void>;
511
- complete(result: CompletedTaskState, metadata?: JsonObject): Promise<void>;
589
+ emitLog(message: string, logMetadata?: JsonObject): Promise<void>;
590
+ complete(result: TaskCompletionState, metadata?: JsonObject): Promise<void>;
512
591
  private startTimeout;
513
592
  }
514
593
  /**
515
- * TaskState
594
+ * Stores the state of the current claimed task passed to the TaskContext
516
595
  *
517
596
  * @public
518
597
  */
519
- interface TaskState {
598
+ interface CurrentClaimedTask {
520
599
  spec: TaskSpec;
521
600
  taskId: string;
522
601
  secrets?: TaskSecrets;
523
602
  }
603
+ /**
604
+ * TaskState
605
+ *
606
+ * @public
607
+ * @deprecated use CurrentClaimedTask instead
608
+ */
609
+ declare type TaskState = CurrentClaimedTask;
524
610
 
525
611
  /**
526
612
  * CreateWorkerOptions
@@ -569,9 +655,10 @@ declare function createRouter(options: RouterOptions): Promise<express.Router>;
569
655
 
570
656
  /** @public */
571
657
  declare class ScaffolderEntitiesProcessor implements CatalogProcessor {
658
+ getProcessorName(): string;
572
659
  private readonly validators;
573
660
  validateEntityKind(entity: Entity): Promise<boolean>;
574
661
  postProcessEntity(entity: Entity, _location: LocationSpec, emit: CatalogProcessorEmit): Promise<Entity>;
575
662
  }
576
663
 
577
- export { ActionContext, CompletedTaskState, CreateWorkerOptions, DatabaseTaskStore, DispatchResult, OctokitProvider, RouterOptions, ScaffolderEntitiesProcessor, SerializedTask, SerializedTaskEvent, Status, TaskBroker, TaskContext, TaskEventType, TaskManager, TaskSecrets, TaskState, TaskStore, TaskStoreEmitOptions, TaskStoreListEventsOptions, TaskWorker, TemplateAction, TemplateActionRegistry, TemplateFilter, createBuiltinActions, createCatalogRegisterAction, createCatalogWriteAction, createDebugLogAction, createFetchPlainAction, createFetchTemplateAction, createFilesystemDeleteAction, createFilesystemRenameAction, createGithubActionsDispatchAction, createGithubWebhookAction, createPublishAzureAction, createPublishBitbucketAction, createPublishFileAction, createPublishGithubAction, createPublishGithubPullRequestAction, createPublishGitlabAction, createPublishGitlabMergeRequestAction, createRouter, createTemplateAction, fetchContents, runCommand };
664
+ export { ActionContext, CompletedTaskState, CreateBuiltInActionsOptions, CreateWorkerOptions, CurrentClaimedTask, DatabaseTaskStore, DispatchResult, OctokitProvider, RouterOptions, ScaffolderEntitiesProcessor, SerializedTask, SerializedTaskEvent, Status, TaskBroker, TaskBrokerDispatchOptions, TaskBrokerDispatchResult, TaskCompletionState, TaskContext, TaskEventType, TaskManager, TaskSecrets, TaskState, TaskStatus, TaskStore, TaskStoreCreateTaskOptions, TaskStoreCreateTaskResult, TaskStoreEmitOptions, TaskStoreListEventsOptions, TaskWorker, TemplateAction, TemplateActionRegistry, TemplateFilter, createBuiltinActions, createCatalogRegisterAction, createCatalogWriteAction, createDebugLogAction, createFetchPlainAction, createFetchTemplateAction, createFilesystemDeleteAction, createFilesystemRenameAction, createGithubActionsDispatchAction, createGithubWebhookAction, createPublishAzureAction, createPublishBitbucketAction, createPublishFileAction, createPublishGithubAction, createPublishGithubPullRequestAction, createPublishGitlabAction, createPublishGitlabMergeRequestAction, createRouter, createTemplateAction, executeShellCommand, fetchContents, runCommand };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@backstage/plugin-scaffolder-backend",
3
3
  "description": "The Backstage backend plugin that helps you create new things",
4
- "version": "0.16.1",
4
+ "version": "0.17.0",
5
5
  "main": "dist/index.cjs.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "license": "Apache-2.0",
@@ -34,15 +34,15 @@
34
34
  "build:assets": "node scripts/build-nunjucks.js"
35
35
  },
36
36
  "dependencies": {
37
- "@backstage/backend-common": "^0.10.9",
38
- "@backstage/catalog-client": "^0.7.1",
39
- "@backstage/catalog-model": "^0.10.1",
37
+ "@backstage/backend-common": "^0.11.0",
38
+ "@backstage/catalog-client": "^0.7.2",
39
+ "@backstage/catalog-model": "^0.11.0",
40
40
  "@backstage/config": "^0.1.15",
41
41
  "@backstage/errors": "^0.2.2",
42
- "@backstage/integration": "^0.7.4",
43
- "@backstage/plugin-catalog-backend": "^0.21.5",
44
- "@backstage/plugin-scaffolder-backend-module-cookiecutter": "^0.2.1",
45
- "@backstage/plugin-scaffolder-common": "^0.2.1",
42
+ "@backstage/integration": "^0.7.5",
43
+ "@backstage/plugin-catalog-backend": "^0.22.0",
44
+ "@backstage/plugin-scaffolder-backend-module-cookiecutter": "^0.2.2",
45
+ "@backstage/plugin-scaffolder-common": "^0.2.2",
46
46
  "@backstage/types": "^0.1.3",
47
47
  "@gitbeaker/core": "^34.6.0",
48
48
  "@gitbeaker/node": "^35.1.0",
@@ -72,17 +72,19 @@
72
72
  "uuid": "^8.2.0",
73
73
  "vm2": "^3.9.6",
74
74
  "winston": "^3.2.1",
75
- "yaml": "^1.10.0"
75
+ "yaml": "^1.10.0",
76
+ "zen-observable": "^0.8.15"
76
77
  },
77
78
  "devDependencies": {
78
- "@backstage/cli": "^0.14.0",
79
- "@backstage/test-utils": "^0.2.5",
79
+ "@backstage/cli": "^0.14.1",
80
+ "@backstage/test-utils": "^0.2.6",
80
81
  "@types/command-exists": "^1.2.0",
81
82
  "@types/fs-extra": "^9.0.1",
82
83
  "@types/git-url-parse": "^9.0.0",
83
84
  "@types/mock-fs": "^4.13.0",
84
85
  "@types/nunjucks": "^3.1.4",
85
86
  "@types/supertest": "^2.0.8",
87
+ "@types/zen-observable": "^0.8.0",
86
88
  "esbuild": "^0.14.1",
87
89
  "jest-when": "^3.1.0",
88
90
  "mock-fs": "^5.1.0",
@@ -97,5 +99,5 @@
97
99
  "assets"
98
100
  ],
99
101
  "configSchema": "config.d.ts",
100
- "gitHead": "e244b348c473700e7d5e5fbcef38bd9f9fd1d0ba"
102
+ "gitHead": "a15da6ea1e3e8adc37be98be064071c8b5279b4a"
101
103
  }