@backstage/plugin-scaffolder-node 0.1.6-next.2 → 0.2.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/CHANGELOG.md CHANGED
@@ -1,5 +1,27 @@
1
1
  # @backstage/plugin-scaffolder-node
2
2
 
3
+ ## 0.2.0
4
+
5
+ ### Minor Changes
6
+
7
+ - e514aac3eac0: Introduce `each` property on action steps, allowing them to be ran repeatedly.
8
+
9
+ ### Patch Changes
10
+
11
+ - 12a8c94eda8d: Add package repository and homepage metadata
12
+ - e07a4914f621: Added several new types that were moved from `@backstage/plugin-scaffolder-backend`.
13
+ - 349611126ae2: Added two new alpha extension points, `scaffolderTaskBrokerExtensionPoint` and `scaffolderTemplatingExtensionPoint`.
14
+ - 0b1d775be05b: Export `TemplateExample` from the `createTemplateAction` type.
15
+ - d3b31a791eb1: Deprecated `executeShellCommand`, `RunCommandOptions`, and `fetchContents` from `@backstage/plugin-scaffolder-backend`, since they are useful for Scaffolder modules (who should not be importing from the plugin package itself). You should now import these from `@backstage/plugin-scaffolder-backend-node` instead. `RunCommandOptions` was renamed in the Node package as `ExecuteShellCommandOptions`, for consistency.
16
+ - Updated dependencies
17
+ - @backstage/backend-common@0.19.2
18
+ - @backstage/backend-plugin-api@0.6.0
19
+ - @backstage/integration@1.6.0
20
+ - @backstage/plugin-scaffolder-common@1.4.0
21
+ - @backstage/catalog-model@1.4.1
22
+ - @backstage/errors@1.2.1
23
+ - @backstage/types@1.1.0
24
+
3
25
  ## 0.1.6-next.2
4
26
 
5
27
  ### Patch Changes
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backstage/plugin-scaffolder-node",
3
- "version": "0.1.6-next.2",
3
+ "version": "0.2.0",
4
4
  "main": "../dist/index.cjs.js",
5
5
  "types": "../dist/index.alpha.d.ts"
6
6
  }
@@ -8,10 +8,17 @@
8
8
 
9
9
  import { ExtensionPoint } from '@backstage/backend-plugin-api';
10
10
  import { JsonObject } from '@backstage/types';
11
+ import { JsonValue } from '@backstage/types';
11
12
  import { Logger } from 'winston';
13
+ import { Observable } from '@backstage/types';
12
14
  import { Schema } from 'jsonschema';
13
15
  import { ScmIntegrations } from '@backstage/integration';
14
16
  import { SpawnOptionsWithoutStdio } from 'child_process';
17
+ import { TaskBroker as TaskBroker_2 } from '@backstage/plugin-scaffolder-node';
18
+ import { TaskSpec } from '@backstage/plugin-scaffolder-common';
19
+ import { TemplateAction as TemplateAction_2 } from '@backstage/plugin-scaffolder-node';
20
+ import { TemplateFilter as TemplateFilter_2 } from '@backstage/plugin-scaffolder-node';
21
+ import { TemplateGlobal as TemplateGlobal_2 } from '@backstage/plugin-scaffolder-node';
15
22
  import { TemplateInfo } from '@backstage/plugin-scaffolder-common';
16
23
  import { UrlReader } from '@backstage/backend-common';
17
24
  import { UserEntity } from '@backstage/catalog-model';
@@ -56,6 +63,10 @@ export declare type ActionContext<TActionInput extends JsonObject, TActionOutput
56
63
  * Implement the signal to make your custom step abortable https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal
57
64
  */
58
65
  signal?: AbortSignal;
66
+ /**
67
+ * Optional value of each invocation
68
+ */
69
+ each?: JsonObject;
59
70
  };
60
71
 
61
72
  /**
@@ -122,7 +133,7 @@ export declare function fetchFile(options: {
122
133
  * @alpha
123
134
  */
124
135
  export declare interface ScaffolderActionsExtensionPoint {
125
- addActions(...actions: TemplateAction<any, any>[]): void;
136
+ addActions(...actions: TemplateAction_2<any, any>[]): void;
126
137
  }
127
138
 
128
139
  /**
@@ -132,6 +143,145 @@ export declare interface ScaffolderActionsExtensionPoint {
132
143
  */
133
144
  export declare const scaffolderActionsExtensionPoint: ExtensionPoint<ScaffolderActionsExtensionPoint>;
134
145
 
146
+ /**
147
+ * Extension point for replacing the scaffolder task broker.
148
+ *
149
+ * @alpha
150
+ */
151
+ export declare interface ScaffolderTaskBrokerExtensionPoint {
152
+ setTaskBroker(taskBroker: TaskBroker_2): void;
153
+ }
154
+
155
+ /**
156
+ * Extension point for replacing the scaffolder task broker.
157
+ *
158
+ * @alpha
159
+ */
160
+ export declare const scaffolderTaskBrokerExtensionPoint: ExtensionPoint<ScaffolderTaskBrokerExtensionPoint>;
161
+
162
+ /**
163
+ * Extension point for adding template filters and globals.
164
+ *
165
+ * @alpha
166
+ */
167
+ export declare interface ScaffolderTemplatingExtensionPoint {
168
+ addTemplateFilters(filters: Record<string, TemplateFilter_2>): void;
169
+ addTemplateGlobals(filters: Record<string, TemplateGlobal_2>): void;
170
+ }
171
+
172
+ /**
173
+ * Extension point for adding template filters and globals.
174
+ *
175
+ * @alpha
176
+ */
177
+ export declare const scaffolderTemplatingExtensionPoint: ExtensionPoint<ScaffolderTemplatingExtensionPoint>;
178
+
179
+ /**
180
+ * SerializedTask
181
+ *
182
+ * @public
183
+ */
184
+ export declare type SerializedTask = {
185
+ id: string;
186
+ spec: TaskSpec;
187
+ status: TaskStatus;
188
+ createdAt: string;
189
+ lastHeartbeatAt?: string;
190
+ createdBy?: string;
191
+ secrets?: TaskSecrets;
192
+ };
193
+
194
+ /**
195
+ * SerializedTaskEvent
196
+ *
197
+ * @public
198
+ */
199
+ export declare type SerializedTaskEvent = {
200
+ id: number;
201
+ taskId: string;
202
+ body: JsonObject;
203
+ type: TaskEventType;
204
+ createdAt: string;
205
+ };
206
+
207
+ /**
208
+ * TaskBroker
209
+ *
210
+ * @public
211
+ */
212
+ export declare interface TaskBroker {
213
+ cancel?(taskId: string): Promise<void>;
214
+ claim(): Promise<TaskContext>;
215
+ dispatch(options: TaskBrokerDispatchOptions): Promise<TaskBrokerDispatchResult>;
216
+ vacuumTasks(options: {
217
+ timeoutS: number;
218
+ }): Promise<void>;
219
+ event$(options: {
220
+ taskId: string;
221
+ after: number | undefined;
222
+ }): Observable<{
223
+ events: SerializedTaskEvent[];
224
+ }>;
225
+ get(taskId: string): Promise<SerializedTask>;
226
+ list?(options?: {
227
+ createdBy?: string;
228
+ }): Promise<{
229
+ tasks: SerializedTask[];
230
+ }>;
231
+ }
232
+
233
+ /**
234
+ * The options passed to {@link TaskBroker.dispatch}
235
+ * Currently a spec and optional secrets
236
+ *
237
+ * @public
238
+ */
239
+ export declare type TaskBrokerDispatchOptions = {
240
+ spec: TaskSpec;
241
+ secrets?: TaskSecrets;
242
+ createdBy?: string;
243
+ };
244
+
245
+ /**
246
+ * The result of {@link TaskBroker.dispatch}
247
+ *
248
+ * @public
249
+ */
250
+ export declare type TaskBrokerDispatchResult = {
251
+ taskId: string;
252
+ };
253
+
254
+ /**
255
+ * The state of a completed task.
256
+ *
257
+ * @public
258
+ */
259
+ export declare type TaskCompletionState = 'failed' | 'completed';
260
+
261
+ /**
262
+ * Task
263
+ *
264
+ * @public
265
+ */
266
+ export declare interface TaskContext {
267
+ cancelSignal: AbortSignal;
268
+ spec: TaskSpec;
269
+ secrets?: TaskSecrets;
270
+ createdBy?: string;
271
+ done: boolean;
272
+ isDryRun?: boolean;
273
+ complete(result: TaskCompletionState, metadata?: JsonObject): Promise<void>;
274
+ emitLog(message: string, logMetadata?: JsonObject): Promise<void>;
275
+ getWorkspaceName(): Promise<string>;
276
+ }
277
+
278
+ /**
279
+ * TaskEventType
280
+ *
281
+ * @public
282
+ */
283
+ export declare type TaskEventType = 'completion' | 'log' | 'cancelled';
284
+
135
285
  /**
136
286
  * TaskSecrets
137
287
  *
@@ -141,6 +291,13 @@ export declare type TaskSecrets = Record<string, string> & {
141
291
  backstageToken?: string;
142
292
  };
143
293
 
294
+ /**
295
+ * The status of each step of the Task
296
+ *
297
+ * @public
298
+ */
299
+ export declare type TaskStatus = 'cancelled' | 'completed' | 'failed' | 'open' | 'processing';
300
+
144
301
  /** @public */
145
302
  export declare type TemplateAction<TActionInput extends JsonObject = JsonObject, TActionOutput extends JsonObject = JsonObject> = {
146
303
  id: string;
@@ -176,4 +333,10 @@ export declare type TemplateExample = {
176
333
  example: string;
177
334
  };
178
335
 
336
+ /** @public */
337
+ export declare type TemplateFilter = (...args: JsonValue[]) => JsonValue | undefined;
338
+
339
+ /** @public */
340
+ export declare type TemplateGlobal = ((...args: JsonValue[]) => JsonValue | undefined) | JsonValue;
341
+
179
342
  export { }
@@ -8,10 +8,17 @@
8
8
 
9
9
  import { ExtensionPoint } from '@backstage/backend-plugin-api';
10
10
  import { JsonObject } from '@backstage/types';
11
+ import { JsonValue } from '@backstage/types';
11
12
  import { Logger } from 'winston';
13
+ import { Observable } from '@backstage/types';
12
14
  import { Schema } from 'jsonschema';
13
15
  import { ScmIntegrations } from '@backstage/integration';
14
16
  import { SpawnOptionsWithoutStdio } from 'child_process';
17
+ import { TaskBroker as TaskBroker_2 } from '@backstage/plugin-scaffolder-node';
18
+ import { TaskSpec } from '@backstage/plugin-scaffolder-common';
19
+ import { TemplateAction as TemplateAction_2 } from '@backstage/plugin-scaffolder-node';
20
+ import { TemplateFilter as TemplateFilter_2 } from '@backstage/plugin-scaffolder-node';
21
+ import { TemplateGlobal as TemplateGlobal_2 } from '@backstage/plugin-scaffolder-node';
15
22
  import { TemplateInfo } from '@backstage/plugin-scaffolder-common';
16
23
  import { UrlReader } from '@backstage/backend-common';
17
24
  import { UserEntity } from '@backstage/catalog-model';
@@ -56,6 +63,10 @@ export declare type ActionContext<TActionInput extends JsonObject, TActionOutput
56
63
  * Implement the signal to make your custom step abortable https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal
57
64
  */
58
65
  signal?: AbortSignal;
66
+ /**
67
+ * Optional value of each invocation
68
+ */
69
+ each?: JsonObject;
59
70
  };
60
71
 
61
72
  /**
@@ -120,6 +131,120 @@ export declare function fetchFile(options: {
120
131
 
121
132
  /* Excluded from this release type: scaffolderActionsExtensionPoint */
122
133
 
134
+ /* Excluded from this release type: ScaffolderTaskBrokerExtensionPoint */
135
+
136
+ /* Excluded from this release type: scaffolderTaskBrokerExtensionPoint */
137
+
138
+ /* Excluded from this release type: ScaffolderTemplatingExtensionPoint */
139
+
140
+ /* Excluded from this release type: scaffolderTemplatingExtensionPoint */
141
+
142
+ /**
143
+ * SerializedTask
144
+ *
145
+ * @public
146
+ */
147
+ export declare type SerializedTask = {
148
+ id: string;
149
+ spec: TaskSpec;
150
+ status: TaskStatus;
151
+ createdAt: string;
152
+ lastHeartbeatAt?: string;
153
+ createdBy?: string;
154
+ secrets?: TaskSecrets;
155
+ };
156
+
157
+ /**
158
+ * SerializedTaskEvent
159
+ *
160
+ * @public
161
+ */
162
+ export declare type SerializedTaskEvent = {
163
+ id: number;
164
+ taskId: string;
165
+ body: JsonObject;
166
+ type: TaskEventType;
167
+ createdAt: string;
168
+ };
169
+
170
+ /**
171
+ * TaskBroker
172
+ *
173
+ * @public
174
+ */
175
+ export declare interface TaskBroker {
176
+ cancel?(taskId: string): Promise<void>;
177
+ claim(): Promise<TaskContext>;
178
+ dispatch(options: TaskBrokerDispatchOptions): Promise<TaskBrokerDispatchResult>;
179
+ vacuumTasks(options: {
180
+ timeoutS: number;
181
+ }): Promise<void>;
182
+ event$(options: {
183
+ taskId: string;
184
+ after: number | undefined;
185
+ }): Observable<{
186
+ events: SerializedTaskEvent[];
187
+ }>;
188
+ get(taskId: string): Promise<SerializedTask>;
189
+ list?(options?: {
190
+ createdBy?: string;
191
+ }): Promise<{
192
+ tasks: SerializedTask[];
193
+ }>;
194
+ }
195
+
196
+ /**
197
+ * The options passed to {@link TaskBroker.dispatch}
198
+ * Currently a spec and optional secrets
199
+ *
200
+ * @public
201
+ */
202
+ export declare type TaskBrokerDispatchOptions = {
203
+ spec: TaskSpec;
204
+ secrets?: TaskSecrets;
205
+ createdBy?: string;
206
+ };
207
+
208
+ /**
209
+ * The result of {@link TaskBroker.dispatch}
210
+ *
211
+ * @public
212
+ */
213
+ export declare type TaskBrokerDispatchResult = {
214
+ taskId: string;
215
+ };
216
+
217
+ /**
218
+ * The state of a completed task.
219
+ *
220
+ * @public
221
+ */
222
+ export declare type TaskCompletionState = 'failed' | 'completed';
223
+
224
+ /**
225
+ * Task
226
+ *
227
+ * @public
228
+ */
229
+ export declare interface TaskContext {
230
+ cancelSignal: AbortSignal;
231
+ spec: TaskSpec;
232
+ secrets?: TaskSecrets;
233
+ createdBy?: string;
234
+ done: boolean;
235
+ isDryRun?: boolean;
236
+ complete(result: TaskCompletionState, metadata?: JsonObject): Promise<void>;
237
+ emitLog(message: string, logMetadata?: JsonObject): Promise<void>;
238
+ getWorkspaceName(): Promise<string>;
239
+ }
240
+
241
+ /**
242
+ * TaskEventType
243
+ *
244
+ * @public
245
+ */
246
+ export declare type TaskEventType = 'completion' | 'log' | 'cancelled';
247
+
123
248
  /**
124
249
  * TaskSecrets
125
250
  *
@@ -129,6 +254,13 @@ export declare type TaskSecrets = Record<string, string> & {
129
254
  backstageToken?: string;
130
255
  };
131
256
 
257
+ /**
258
+ * The status of each step of the Task
259
+ *
260
+ * @public
261
+ */
262
+ export declare type TaskStatus = 'cancelled' | 'completed' | 'failed' | 'open' | 'processing';
263
+
132
264
  /** @public */
133
265
  export declare type TemplateAction<TActionInput extends JsonObject = JsonObject, TActionOutput extends JsonObject = JsonObject> = {
134
266
  id: string;
@@ -164,4 +296,10 @@ export declare type TemplateExample = {
164
296
  example: string;
165
297
  };
166
298
 
299
+ /** @public */
300
+ export declare type TemplateFilter = (...args: JsonValue[]) => JsonValue | undefined;
301
+
302
+ /** @public */
303
+ export declare type TemplateGlobal = ((...args: JsonValue[]) => JsonValue | undefined) | JsonValue;
304
+
167
305
  export { }
package/dist/index.cjs.js CHANGED
@@ -119,10 +119,18 @@ function getReadUrl(fetchUrl, baseUrl, integrations) {
119
119
  const scaffolderActionsExtensionPoint = backendPluginApi.createExtensionPoint({
120
120
  id: "scaffolder.actions"
121
121
  });
122
+ const scaffolderTaskBrokerExtensionPoint = backendPluginApi.createExtensionPoint({
123
+ id: "scaffolder.taskBroker"
124
+ });
125
+ const scaffolderTemplatingExtensionPoint = backendPluginApi.createExtensionPoint({
126
+ id: "scaffolder.templating"
127
+ });
122
128
 
123
129
  exports.createTemplateAction = createTemplateAction;
124
130
  exports.executeShellCommand = executeShellCommand;
125
131
  exports.fetchContents = fetchContents;
126
132
  exports.fetchFile = fetchFile;
127
133
  exports.scaffolderActionsExtensionPoint = scaffolderActionsExtensionPoint;
134
+ exports.scaffolderTaskBrokerExtensionPoint = scaffolderTaskBrokerExtensionPoint;
135
+ exports.scaffolderTemplatingExtensionPoint = scaffolderTemplatingExtensionPoint;
128
136
  //# sourceMappingURL=index.cjs.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs.js","sources":["../src/actions/createTemplateAction.ts","../src/actions/executeShellCommand.ts","../src/actions/fetch.ts","../src/extensions.ts"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ActionContext, TemplateAction } from './types';\nimport { z } from 'zod';\nimport { Schema } from 'jsonschema';\nimport zodToJsonSchema from 'zod-to-json-schema';\nimport { JsonObject } from '@backstage/types';\n\n/** @public */\nexport type TemplateExample = {\n description: string;\n example: string;\n};\n\n/** @public */\nexport type TemplateActionOptions<\n TActionInput extends JsonObject = {},\n TActionOutput extends JsonObject = {},\n TInputSchema extends Schema | z.ZodType = {},\n TOutputSchema extends Schema | z.ZodType = {},\n> = {\n id: string;\n description?: string;\n examples?: TemplateExample[];\n supportsDryRun?: boolean;\n schema?: {\n input?: TInputSchema;\n output?: TOutputSchema;\n };\n handler: (ctx: ActionContext<TActionInput, TActionOutput>) => Promise<void>;\n};\n\n/**\n * This function is used to create new template actions to get type safety.\n * Will convert zod schemas to json schemas for use throughout the system.\n * @public\n */\nexport const createTemplateAction = <\n TInputParams extends JsonObject = JsonObject,\n TOutputParams extends JsonObject = JsonObject,\n TInputSchema extends Schema | z.ZodType = {},\n TOutputSchema extends Schema | z.ZodType = {},\n TActionInput extends JsonObject = TInputSchema extends z.ZodType<\n any,\n any,\n infer IReturn\n >\n ? IReturn\n : TInputParams,\n TActionOutput extends JsonObject = TOutputSchema extends z.ZodType<\n any,\n any,\n infer IReturn\n >\n ? IReturn\n : TOutputParams,\n>(\n action: TemplateActionOptions<\n TActionInput,\n TActionOutput,\n TInputSchema,\n TOutputSchema\n >,\n): TemplateAction<TActionInput, TActionOutput> => {\n const inputSchema =\n action.schema?.input && 'safeParseAsync' in action.schema.input\n ? zodToJsonSchema(action.schema.input)\n : action.schema?.input;\n\n const outputSchema =\n action.schema?.output && 'safeParseAsync' in action.schema.output\n ? zodToJsonSchema(action.schema.output)\n : action.schema?.output;\n\n return {\n ...action,\n schema: {\n ...action.schema,\n input: inputSchema,\n output: outputSchema,\n },\n };\n};\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { spawn, SpawnOptionsWithoutStdio } from 'child_process';\nimport { PassThrough, Writable } from 'stream';\n\n/**\n * Options for {@link executeShellCommand}.\n *\n * @public\n */\nexport type ExecuteShellCommandOptions = {\n /** command to run */\n command: string;\n /** arguments to pass the command */\n args: string[];\n /** options to pass to spawn */\n options?: SpawnOptionsWithoutStdio;\n /** stream to capture stdout and stderr output */\n logStream?: Writable;\n};\n\n/**\n * Run a command in a sub-process, normally a shell command.\n *\n * @public\n */\nexport async function executeShellCommand(\n options: ExecuteShellCommandOptions,\n): Promise<void> {\n const {\n command,\n args,\n options: spawnOptions,\n logStream = new PassThrough(),\n } = options;\n\n await new Promise<void>((resolve, reject) => {\n const process = spawn(command, args, spawnOptions);\n\n process.stdout.on('data', stream => {\n logStream.write(stream);\n });\n\n process.stderr.on('data', stream => {\n logStream.write(stream);\n });\n\n process.on('error', error => {\n return reject(error);\n });\n\n process.on('close', code => {\n if (code !== 0) {\n return reject(\n new Error(`Command ${command} failed, exit code: ${code}`),\n );\n }\n return resolve();\n });\n });\n}\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { resolveSafeChildPath, UrlReader } from '@backstage/backend-common';\nimport { InputError } from '@backstage/errors';\nimport { ScmIntegrations } from '@backstage/integration';\nimport fs from 'fs-extra';\nimport path from 'path';\n\n/**\n * A helper function that reads the contents of a directory from the given URL.\n * Can be used in your own actions, and also used behind fetch:template and fetch:plain\n *\n * @public\n */\nexport async function fetchContents(options: {\n reader: UrlReader;\n integrations: ScmIntegrations;\n baseUrl?: string;\n fetchUrl?: string;\n outputPath: string;\n}) {\n const { reader, integrations, baseUrl, fetchUrl = '.', outputPath } = options;\n\n const fetchUrlIsAbsolute = isFetchUrlAbsolute(fetchUrl);\n\n // We handle both file locations and url ones\n if (!fetchUrlIsAbsolute && baseUrl?.startsWith('file://')) {\n const basePath = baseUrl.slice('file://'.length);\n const srcDir = resolveSafeChildPath(path.dirname(basePath), fetchUrl);\n await fs.copy(srcDir, outputPath);\n } else {\n const readUrl = getReadUrl(fetchUrl, baseUrl, integrations);\n\n const res = await reader.readTree(readUrl);\n await fs.ensureDir(outputPath);\n await res.dir({ targetDir: outputPath });\n }\n}\n\n/**\n * A helper function that reads the content of a single file from the given URL.\n * Can be used in your own actions, and also used behind `fetch:plain:file`\n *\n * @public\n */\nexport async function fetchFile(options: {\n reader: UrlReader;\n integrations: ScmIntegrations;\n baseUrl?: string;\n fetchUrl?: string;\n outputPath: string;\n}) {\n const { reader, integrations, baseUrl, fetchUrl = '.', outputPath } = options;\n\n const fetchUrlIsAbsolute = isFetchUrlAbsolute(fetchUrl);\n\n // We handle both file locations and url ones\n if (!fetchUrlIsAbsolute && baseUrl?.startsWith('file://')) {\n const basePath = baseUrl.slice('file://'.length);\n const src = resolveSafeChildPath(path.dirname(basePath), fetchUrl);\n await fs.copyFile(src, outputPath);\n } else {\n const readUrl = getReadUrl(fetchUrl, baseUrl, integrations);\n\n const res = await reader.readUrl(readUrl);\n await fs.ensureDir(path.dirname(outputPath));\n const buffer = await res.buffer();\n await fs.outputFile(outputPath, buffer.toString());\n }\n}\n\nfunction isFetchUrlAbsolute(fetchUrl: string) {\n let fetchUrlIsAbsolute = false;\n try {\n // eslint-disable-next-line no-new\n new URL(fetchUrl);\n fetchUrlIsAbsolute = true;\n } catch {\n /* ignored */\n }\n return fetchUrlIsAbsolute;\n}\n\nfunction getReadUrl(\n fetchUrl: string,\n baseUrl: string | undefined,\n integrations: ScmIntegrations,\n) {\n if (isFetchUrlAbsolute(fetchUrl)) {\n return fetchUrl;\n } else if (baseUrl) {\n const integration = integrations.byUrl(baseUrl);\n if (!integration) {\n throw new InputError(`No integration found for location ${baseUrl}`);\n }\n\n return integration.resolveUrl({\n url: fetchUrl,\n base: baseUrl,\n });\n }\n throw new InputError(\n `Failed to fetch, template location could not be determined and the fetch URL is relative, ${fetchUrl}`,\n );\n}\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { createExtensionPoint } from '@backstage/backend-plugin-api';\nimport { TemplateAction } from './actions';\n\n/**\n * Extension point for managing scaffolder actions.\n *\n * @alpha\n */\nexport interface ScaffolderActionsExtensionPoint {\n addActions(...actions: TemplateAction<any, any>[]): void;\n}\n\n/**\n * Extension point for managing scaffolder actions.\n *\n * @alpha\n */\nexport const scaffolderActionsExtensionPoint =\n createExtensionPoint<ScaffolderActionsExtensionPoint>({\n id: 'scaffolder.actions',\n });\n"],"names":["zodToJsonSchema","PassThrough","spawn","resolveSafeChildPath","path","fs","InputError","createExtensionPoint"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs.js","sources":["../src/actions/createTemplateAction.ts","../src/actions/executeShellCommand.ts","../src/actions/fetch.ts","../src/extensions.ts"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ActionContext, TemplateAction } from './types';\nimport { z } from 'zod';\nimport { Schema } from 'jsonschema';\nimport zodToJsonSchema from 'zod-to-json-schema';\nimport { JsonObject } from '@backstage/types';\n\n/** @public */\nexport type TemplateExample = {\n description: string;\n example: string;\n};\n\n/** @public */\nexport type TemplateActionOptions<\n TActionInput extends JsonObject = {},\n TActionOutput extends JsonObject = {},\n TInputSchema extends Schema | z.ZodType = {},\n TOutputSchema extends Schema | z.ZodType = {},\n> = {\n id: string;\n description?: string;\n examples?: TemplateExample[];\n supportsDryRun?: boolean;\n schema?: {\n input?: TInputSchema;\n output?: TOutputSchema;\n };\n handler: (ctx: ActionContext<TActionInput, TActionOutput>) => Promise<void>;\n};\n\n/**\n * This function is used to create new template actions to get type safety.\n * Will convert zod schemas to json schemas for use throughout the system.\n * @public\n */\nexport const createTemplateAction = <\n TInputParams extends JsonObject = JsonObject,\n TOutputParams extends JsonObject = JsonObject,\n TInputSchema extends Schema | z.ZodType = {},\n TOutputSchema extends Schema | z.ZodType = {},\n TActionInput extends JsonObject = TInputSchema extends z.ZodType<\n any,\n any,\n infer IReturn\n >\n ? IReturn\n : TInputParams,\n TActionOutput extends JsonObject = TOutputSchema extends z.ZodType<\n any,\n any,\n infer IReturn\n >\n ? IReturn\n : TOutputParams,\n>(\n action: TemplateActionOptions<\n TActionInput,\n TActionOutput,\n TInputSchema,\n TOutputSchema\n >,\n): TemplateAction<TActionInput, TActionOutput> => {\n const inputSchema =\n action.schema?.input && 'safeParseAsync' in action.schema.input\n ? zodToJsonSchema(action.schema.input)\n : action.schema?.input;\n\n const outputSchema =\n action.schema?.output && 'safeParseAsync' in action.schema.output\n ? zodToJsonSchema(action.schema.output)\n : action.schema?.output;\n\n return {\n ...action,\n schema: {\n ...action.schema,\n input: inputSchema,\n output: outputSchema,\n },\n };\n};\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { spawn, SpawnOptionsWithoutStdio } from 'child_process';\nimport { PassThrough, Writable } from 'stream';\n\n/**\n * Options for {@link executeShellCommand}.\n *\n * @public\n */\nexport type ExecuteShellCommandOptions = {\n /** command to run */\n command: string;\n /** arguments to pass the command */\n args: string[];\n /** options to pass to spawn */\n options?: SpawnOptionsWithoutStdio;\n /** stream to capture stdout and stderr output */\n logStream?: Writable;\n};\n\n/**\n * Run a command in a sub-process, normally a shell command.\n *\n * @public\n */\nexport async function executeShellCommand(\n options: ExecuteShellCommandOptions,\n): Promise<void> {\n const {\n command,\n args,\n options: spawnOptions,\n logStream = new PassThrough(),\n } = options;\n\n await new Promise<void>((resolve, reject) => {\n const process = spawn(command, args, spawnOptions);\n\n process.stdout.on('data', stream => {\n logStream.write(stream);\n });\n\n process.stderr.on('data', stream => {\n logStream.write(stream);\n });\n\n process.on('error', error => {\n return reject(error);\n });\n\n process.on('close', code => {\n if (code !== 0) {\n return reject(\n new Error(`Command ${command} failed, exit code: ${code}`),\n );\n }\n return resolve();\n });\n });\n}\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { resolveSafeChildPath, UrlReader } from '@backstage/backend-common';\nimport { InputError } from '@backstage/errors';\nimport { ScmIntegrations } from '@backstage/integration';\nimport fs from 'fs-extra';\nimport path from 'path';\n\n/**\n * A helper function that reads the contents of a directory from the given URL.\n * Can be used in your own actions, and also used behind fetch:template and fetch:plain\n *\n * @public\n */\nexport async function fetchContents(options: {\n reader: UrlReader;\n integrations: ScmIntegrations;\n baseUrl?: string;\n fetchUrl?: string;\n outputPath: string;\n}) {\n const { reader, integrations, baseUrl, fetchUrl = '.', outputPath } = options;\n\n const fetchUrlIsAbsolute = isFetchUrlAbsolute(fetchUrl);\n\n // We handle both file locations and url ones\n if (!fetchUrlIsAbsolute && baseUrl?.startsWith('file://')) {\n const basePath = baseUrl.slice('file://'.length);\n const srcDir = resolveSafeChildPath(path.dirname(basePath), fetchUrl);\n await fs.copy(srcDir, outputPath);\n } else {\n const readUrl = getReadUrl(fetchUrl, baseUrl, integrations);\n\n const res = await reader.readTree(readUrl);\n await fs.ensureDir(outputPath);\n await res.dir({ targetDir: outputPath });\n }\n}\n\n/**\n * A helper function that reads the content of a single file from the given URL.\n * Can be used in your own actions, and also used behind `fetch:plain:file`\n *\n * @public\n */\nexport async function fetchFile(options: {\n reader: UrlReader;\n integrations: ScmIntegrations;\n baseUrl?: string;\n fetchUrl?: string;\n outputPath: string;\n}) {\n const { reader, integrations, baseUrl, fetchUrl = '.', outputPath } = options;\n\n const fetchUrlIsAbsolute = isFetchUrlAbsolute(fetchUrl);\n\n // We handle both file locations and url ones\n if (!fetchUrlIsAbsolute && baseUrl?.startsWith('file://')) {\n const basePath = baseUrl.slice('file://'.length);\n const src = resolveSafeChildPath(path.dirname(basePath), fetchUrl);\n await fs.copyFile(src, outputPath);\n } else {\n const readUrl = getReadUrl(fetchUrl, baseUrl, integrations);\n\n const res = await reader.readUrl(readUrl);\n await fs.ensureDir(path.dirname(outputPath));\n const buffer = await res.buffer();\n await fs.outputFile(outputPath, buffer.toString());\n }\n}\n\nfunction isFetchUrlAbsolute(fetchUrl: string) {\n let fetchUrlIsAbsolute = false;\n try {\n // eslint-disable-next-line no-new\n new URL(fetchUrl);\n fetchUrlIsAbsolute = true;\n } catch {\n /* ignored */\n }\n return fetchUrlIsAbsolute;\n}\n\nfunction getReadUrl(\n fetchUrl: string,\n baseUrl: string | undefined,\n integrations: ScmIntegrations,\n) {\n if (isFetchUrlAbsolute(fetchUrl)) {\n return fetchUrl;\n } else if (baseUrl) {\n const integration = integrations.byUrl(baseUrl);\n if (!integration) {\n throw new InputError(`No integration found for location ${baseUrl}`);\n }\n\n return integration.resolveUrl({\n url: fetchUrl,\n base: baseUrl,\n });\n }\n throw new InputError(\n `Failed to fetch, template location could not be determined and the fetch URL is relative, ${fetchUrl}`,\n );\n}\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { createExtensionPoint } from '@backstage/backend-plugin-api';\nimport {\n TemplateAction,\n TemplateFilter,\n TemplateGlobal,\n TaskBroker,\n} from '@backstage/plugin-scaffolder-node';\n\n/**\n * Extension point for managing scaffolder actions.\n *\n * @alpha\n */\nexport interface ScaffolderActionsExtensionPoint {\n addActions(...actions: TemplateAction<any, any>[]): void;\n}\n\n/**\n * Extension point for managing scaffolder actions.\n *\n * @alpha\n */\nexport const scaffolderActionsExtensionPoint =\n createExtensionPoint<ScaffolderActionsExtensionPoint>({\n id: 'scaffolder.actions',\n });\n\n/**\n * Extension point for replacing the scaffolder task broker.\n *\n * @alpha\n */\nexport interface ScaffolderTaskBrokerExtensionPoint {\n setTaskBroker(taskBroker: TaskBroker): void;\n}\n\n/**\n * Extension point for replacing the scaffolder task broker.\n *\n * @alpha\n */\nexport const scaffolderTaskBrokerExtensionPoint =\n createExtensionPoint<ScaffolderTaskBrokerExtensionPoint>({\n id: 'scaffolder.taskBroker',\n });\n\n/**\n * Extension point for adding template filters and globals.\n *\n * @alpha\n */\nexport interface ScaffolderTemplatingExtensionPoint {\n addTemplateFilters(filters: Record<string, TemplateFilter>): void;\n addTemplateGlobals(filters: Record<string, TemplateGlobal>): void;\n}\n\n/**\n * Extension point for adding template filters and globals.\n *\n * @alpha\n */\nexport const scaffolderTemplatingExtensionPoint =\n createExtensionPoint<ScaffolderTemplatingExtensionPoint>({\n id: 'scaffolder.templating',\n });\n"],"names":["zodToJsonSchema","PassThrough","spawn","resolveSafeChildPath","path","fs","InputError","createExtensionPoint"],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -8,10 +8,17 @@
8
8
 
9
9
  import { ExtensionPoint } from '@backstage/backend-plugin-api';
10
10
  import { JsonObject } from '@backstage/types';
11
+ import { JsonValue } from '@backstage/types';
11
12
  import { Logger } from 'winston';
13
+ import { Observable } from '@backstage/types';
12
14
  import { Schema } from 'jsonschema';
13
15
  import { ScmIntegrations } from '@backstage/integration';
14
16
  import { SpawnOptionsWithoutStdio } from 'child_process';
17
+ import { TaskBroker as TaskBroker_2 } from '@backstage/plugin-scaffolder-node';
18
+ import { TaskSpec } from '@backstage/plugin-scaffolder-common';
19
+ import { TemplateAction as TemplateAction_2 } from '@backstage/plugin-scaffolder-node';
20
+ import { TemplateFilter as TemplateFilter_2 } from '@backstage/plugin-scaffolder-node';
21
+ import { TemplateGlobal as TemplateGlobal_2 } from '@backstage/plugin-scaffolder-node';
15
22
  import { TemplateInfo } from '@backstage/plugin-scaffolder-common';
16
23
  import { UrlReader } from '@backstage/backend-common';
17
24
  import { UserEntity } from '@backstage/catalog-model';
@@ -56,6 +63,10 @@ export declare type ActionContext<TActionInput extends JsonObject, TActionOutput
56
63
  * Implement the signal to make your custom step abortable https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal
57
64
  */
58
65
  signal?: AbortSignal;
66
+ /**
67
+ * Optional value of each invocation
68
+ */
69
+ each?: JsonObject;
59
70
  };
60
71
 
61
72
  /**
@@ -120,6 +131,120 @@ export declare function fetchFile(options: {
120
131
 
121
132
  /* Excluded from this release type: scaffolderActionsExtensionPoint */
122
133
 
134
+ /* Excluded from this release type: ScaffolderTaskBrokerExtensionPoint */
135
+
136
+ /* Excluded from this release type: scaffolderTaskBrokerExtensionPoint */
137
+
138
+ /* Excluded from this release type: ScaffolderTemplatingExtensionPoint */
139
+
140
+ /* Excluded from this release type: scaffolderTemplatingExtensionPoint */
141
+
142
+ /**
143
+ * SerializedTask
144
+ *
145
+ * @public
146
+ */
147
+ export declare type SerializedTask = {
148
+ id: string;
149
+ spec: TaskSpec;
150
+ status: TaskStatus;
151
+ createdAt: string;
152
+ lastHeartbeatAt?: string;
153
+ createdBy?: string;
154
+ secrets?: TaskSecrets;
155
+ };
156
+
157
+ /**
158
+ * SerializedTaskEvent
159
+ *
160
+ * @public
161
+ */
162
+ export declare type SerializedTaskEvent = {
163
+ id: number;
164
+ taskId: string;
165
+ body: JsonObject;
166
+ type: TaskEventType;
167
+ createdAt: string;
168
+ };
169
+
170
+ /**
171
+ * TaskBroker
172
+ *
173
+ * @public
174
+ */
175
+ export declare interface TaskBroker {
176
+ cancel?(taskId: string): Promise<void>;
177
+ claim(): Promise<TaskContext>;
178
+ dispatch(options: TaskBrokerDispatchOptions): Promise<TaskBrokerDispatchResult>;
179
+ vacuumTasks(options: {
180
+ timeoutS: number;
181
+ }): Promise<void>;
182
+ event$(options: {
183
+ taskId: string;
184
+ after: number | undefined;
185
+ }): Observable<{
186
+ events: SerializedTaskEvent[];
187
+ }>;
188
+ get(taskId: string): Promise<SerializedTask>;
189
+ list?(options?: {
190
+ createdBy?: string;
191
+ }): Promise<{
192
+ tasks: SerializedTask[];
193
+ }>;
194
+ }
195
+
196
+ /**
197
+ * The options passed to {@link TaskBroker.dispatch}
198
+ * Currently a spec and optional secrets
199
+ *
200
+ * @public
201
+ */
202
+ export declare type TaskBrokerDispatchOptions = {
203
+ spec: TaskSpec;
204
+ secrets?: TaskSecrets;
205
+ createdBy?: string;
206
+ };
207
+
208
+ /**
209
+ * The result of {@link TaskBroker.dispatch}
210
+ *
211
+ * @public
212
+ */
213
+ export declare type TaskBrokerDispatchResult = {
214
+ taskId: string;
215
+ };
216
+
217
+ /**
218
+ * The state of a completed task.
219
+ *
220
+ * @public
221
+ */
222
+ export declare type TaskCompletionState = 'failed' | 'completed';
223
+
224
+ /**
225
+ * Task
226
+ *
227
+ * @public
228
+ */
229
+ export declare interface TaskContext {
230
+ cancelSignal: AbortSignal;
231
+ spec: TaskSpec;
232
+ secrets?: TaskSecrets;
233
+ createdBy?: string;
234
+ done: boolean;
235
+ isDryRun?: boolean;
236
+ complete(result: TaskCompletionState, metadata?: JsonObject): Promise<void>;
237
+ emitLog(message: string, logMetadata?: JsonObject): Promise<void>;
238
+ getWorkspaceName(): Promise<string>;
239
+ }
240
+
241
+ /**
242
+ * TaskEventType
243
+ *
244
+ * @public
245
+ */
246
+ export declare type TaskEventType = 'completion' | 'log' | 'cancelled';
247
+
123
248
  /**
124
249
  * TaskSecrets
125
250
  *
@@ -129,6 +254,13 @@ export declare type TaskSecrets = Record<string, string> & {
129
254
  backstageToken?: string;
130
255
  };
131
256
 
257
+ /**
258
+ * The status of each step of the Task
259
+ *
260
+ * @public
261
+ */
262
+ export declare type TaskStatus = 'cancelled' | 'completed' | 'failed' | 'open' | 'processing';
263
+
132
264
  /** @public */
133
265
  export declare type TemplateAction<TActionInput extends JsonObject = JsonObject, TActionOutput extends JsonObject = JsonObject> = {
134
266
  id: string;
@@ -164,4 +296,10 @@ export declare type TemplateExample = {
164
296
  example: string;
165
297
  };
166
298
 
299
+ /** @public */
300
+ export declare type TemplateFilter = (...args: JsonValue[]) => JsonValue | undefined;
301
+
302
+ /** @public */
303
+ export declare type TemplateGlobal = ((...args: JsonValue[]) => JsonValue | undefined) | JsonValue;
304
+
167
305
  export { }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@backstage/plugin-scaffolder-node",
3
3
  "description": "The plugin-scaffolder-node module for @backstage/plugin-scaffolder-backend",
4
- "version": "0.1.6-next.2",
4
+ "version": "0.2.0",
5
5
  "main": "dist/index.cjs.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "license": "Apache-2.0",
@@ -30,12 +30,12 @@
30
30
  "postpack": "backstage-cli package postpack"
31
31
  },
32
32
  "dependencies": {
33
- "@backstage/backend-common": "^0.19.2-next.2",
34
- "@backstage/backend-plugin-api": "^0.6.0-next.2",
33
+ "@backstage/backend-common": "^0.19.2",
34
+ "@backstage/backend-plugin-api": "^0.6.0",
35
35
  "@backstage/catalog-model": "^1.4.1",
36
36
  "@backstage/errors": "^1.2.1",
37
- "@backstage/integration": "^1.5.1",
38
- "@backstage/plugin-scaffolder-common": "^1.3.2",
37
+ "@backstage/integration": "^1.6.0",
38
+ "@backstage/plugin-scaffolder-common": "^1.4.0",
39
39
  "@backstage/types": "^1.1.0",
40
40
  "fs-extra": "10.1.0",
41
41
  "jsonschema": "^1.2.6",
@@ -44,7 +44,7 @@
44
44
  "zod-to-json-schema": "^3.20.4"
45
45
  },
46
46
  "devDependencies": {
47
- "@backstage/cli": "^0.22.10-next.1",
47
+ "@backstage/cli": "^0.22.10",
48
48
  "@backstage/config": "^1.0.8"
49
49
  },
50
50
  "files": [