@backstage/plugin-scaffolder-backend 3.3.0 → 3.4.0-next.2
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 +55 -5
- package/dist/ScaffolderPlugin.cjs.js +6 -3
- package/dist/ScaffolderPlugin.cjs.js.map +1 -1
- package/dist/actions/createExecuteTemplateAction.cjs.js +52 -0
- package/dist/actions/createExecuteTemplateAction.cjs.js.map +1 -0
- package/dist/actions/index.cjs.js +2 -0
- package/dist/actions/index.cjs.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/lib/templating/filters/createDefaultFilters.cjs.js +6 -6
- package/dist/lib/templating/filters/createDefaultFilters.cjs.js.map +1 -1
- package/dist/scaffolder/actions/TemplateActionRegistry.cjs.js +0 -1
- package/dist/scaffolder/actions/TemplateActionRegistry.cjs.js.map +1 -1
- package/dist/scaffolder/dryrun/createDryRunner.cjs.js.map +1 -1
- package/dist/scaffolder/tasks/NunjucksWorkflowRunner.cjs.js +13 -14
- package/dist/scaffolder/tasks/NunjucksWorkflowRunner.cjs.js.map +1 -1
- package/dist/scaffolder/tasks/TaskWorker.cjs.js +7 -5
- package/dist/scaffolder/tasks/TaskWorker.cjs.js.map +1 -1
- package/dist/service/helpers.cjs.js +3 -3
- package/dist/service/helpers.cjs.js.map +1 -1
- package/dist/service/router.cjs.js +4 -1
- package/dist/service/router.cjs.js.map +1 -1
- package/package.json +20 -21
package/CHANGELOG.md
CHANGED
|
@@ -1,15 +1,65 @@
|
|
|
1
1
|
# @backstage/plugin-scaffolder-backend
|
|
2
2
|
|
|
3
|
-
## 3.
|
|
3
|
+
## 3.4.0-next.2
|
|
4
4
|
|
|
5
5
|
### Minor Changes
|
|
6
6
|
|
|
7
|
-
-
|
|
7
|
+
- 5af48e7: Migrated permission registration to use the `PermissionsRegistryService` instead of the deprecated `createPermissionIntegrationRouter`. This fixes an issue where scaffolder permissions were not visible to RBAC plugins because the `actionsRegistryServiceRef` dependency caused an empty permissions metadata router to shadow the scaffolder's actual permission metadata. The old `createPermissionIntegrationRouter` path is retained as a fallback for standalone `createRouter` usage.
|
|
8
8
|
|
|
9
9
|
### Patch Changes
|
|
10
10
|
|
|
11
|
+
- 482ceed: Migrated from `assertError` to `toError` for error handling.
|
|
12
|
+
- 961e274: Migrated OpenTelemetry metrics to use the `MetricsService` from `@backstage/backend-plugin-api/alpha` instead of the raw `@opentelemetry/api` meter.
|
|
11
13
|
- Updated dependencies
|
|
12
|
-
- @backstage/
|
|
14
|
+
- @backstage/errors@1.3.0-next.0
|
|
15
|
+
- @backstage/plugin-catalog-node@2.2.0-next.2
|
|
16
|
+
- @backstage/plugin-scaffolder-node@0.13.2-next.2
|
|
17
|
+
- @backstage/integration@2.0.1-next.0
|
|
18
|
+
- @backstage/backend-openapi-utils@0.6.8-next.2
|
|
19
|
+
- @backstage/backend-plugin-api@1.9.0-next.2
|
|
20
|
+
- @backstage/catalog-model@1.7.8-next.0
|
|
21
|
+
- @backstage/config@1.3.7-next.0
|
|
22
|
+
- @backstage/plugin-events-node@0.4.21-next.2
|
|
23
|
+
- @backstage/plugin-permission-common@0.9.8-next.0
|
|
24
|
+
- @backstage/plugin-permission-node@0.10.12-next.2
|
|
25
|
+
- @backstage/plugin-scaffolder-common@2.0.1-next.0
|
|
26
|
+
|
|
27
|
+
## 3.3.0-next.1
|
|
28
|
+
|
|
29
|
+
### Minor Changes
|
|
30
|
+
|
|
31
|
+
- 309b712: Added a new `execute-template` actions registry action that executes a scaffolder template with provided input values and returns a task ID for tracking progress.
|
|
32
|
+
|
|
33
|
+
### Patch Changes
|
|
34
|
+
|
|
35
|
+
- 4559806: Removed unnecessary empty `examples` array from actions bridged via the actions registry.
|
|
36
|
+
- Updated dependencies
|
|
37
|
+
- @backstage/backend-plugin-api@1.9.0-next.1
|
|
38
|
+
- @backstage/backend-openapi-utils@0.6.8-next.1
|
|
39
|
+
- @backstage/plugin-catalog-node@2.1.1-next.1
|
|
40
|
+
- @backstage/plugin-events-node@0.4.21-next.1
|
|
41
|
+
- @backstage/plugin-permission-node@0.10.12-next.1
|
|
42
|
+
- @backstage/plugin-scaffolder-node@0.13.1-next.1
|
|
43
|
+
|
|
44
|
+
## 3.2.1-next.0
|
|
45
|
+
|
|
46
|
+
### Patch Changes
|
|
47
|
+
|
|
48
|
+
- 79453c0: Updated dependency `wait-for-expect` to `^4.0.0`.
|
|
49
|
+
- Updated dependencies
|
|
50
|
+
- @backstage/backend-plugin-api@1.8.1-next.0
|
|
51
|
+
- @backstage/plugin-permission-node@0.10.12-next.0
|
|
52
|
+
- @backstage/backend-openapi-utils@0.6.8-next.0
|
|
53
|
+
- @backstage/plugin-catalog-node@2.1.1-next.0
|
|
54
|
+
- @backstage/plugin-events-node@0.4.21-next.0
|
|
55
|
+
- @backstage/plugin-scaffolder-node@0.13.1-next.0
|
|
56
|
+
- @backstage/catalog-model@1.7.7
|
|
57
|
+
- @backstage/config@1.3.6
|
|
58
|
+
- @backstage/errors@1.2.7
|
|
59
|
+
- @backstage/integration@2.0.0
|
|
60
|
+
- @backstage/types@1.2.2
|
|
61
|
+
- @backstage/plugin-permission-common@0.9.7
|
|
62
|
+
- @backstage/plugin-scaffolder-common@2.0.0
|
|
13
63
|
|
|
14
64
|
## 3.2.0
|
|
15
65
|
|
|
@@ -5625,7 +5675,7 @@
|
|
|
5625
5675
|
- `step`: The name of the step that was run
|
|
5626
5676
|
- `result`: A string describing whether the task ran successfully, failed, or was skipped
|
|
5627
5677
|
|
|
5628
|
-
You can find a guide for running Prometheus metrics here: https://github.com/backstage/backstage/blob/
|
|
5678
|
+
You can find a guide for running Prometheus metrics here: https://github.com/backstage/backstage/blob/384b7bac2e/contrib/docs/tutorials/prometheus-metrics.md
|
|
5629
5679
|
|
|
5630
5680
|
- 5921b5ce49: - The GitLab Project ID for the `publish:gitlab:merge-request` action is now passed through the query parameter `project` in the `repoUrl`. It still allows people to not use the `projectid` and use the `repoUrl` with the `owner` and `repo` query parameters instead. This makes it easier to publish to repositories instead of writing the full path to the project.
|
|
5631
5681
|
- 5025d2e8b6: Adds the ability to pass (an optional) array of strings that will be applied to the newly scaffolded repository as topic labels.
|
|
@@ -5718,7 +5768,7 @@
|
|
|
5718
5768
|
- `step`: The name of the step that was run
|
|
5719
5769
|
- `result`: A string describing whether the task ran successfully, failed, or was skipped
|
|
5720
5770
|
|
|
5721
|
-
You can find a guide for running Prometheus metrics here: https://github.com/backstage/backstage/blob/
|
|
5771
|
+
You can find a guide for running Prometheus metrics here: https://github.com/backstage/backstage/blob/384b7bac2e/contrib/docs/tutorials/prometheus-metrics.md
|
|
5722
5772
|
|
|
5723
5773
|
### Patch Changes
|
|
5724
5774
|
|
|
@@ -102,7 +102,8 @@ const scaffolderPlugin = backendPluginApi.createBackendPlugin({
|
|
|
102
102
|
events: pluginEventsNode.eventsServiceRef,
|
|
103
103
|
actionsRegistry: alpha$1.actionsServiceRef,
|
|
104
104
|
actionsRegistryService: alpha$1.actionsRegistryServiceRef,
|
|
105
|
-
scaffolderService: pluginScaffolderNode.scaffolderServiceRef
|
|
105
|
+
scaffolderService: pluginScaffolderNode.scaffolderServiceRef,
|
|
106
|
+
metrics: alpha$1.metricsServiceRef
|
|
106
107
|
},
|
|
107
108
|
async init({
|
|
108
109
|
logger,
|
|
@@ -120,7 +121,8 @@ const scaffolderPlugin = backendPluginApi.createBackendPlugin({
|
|
|
120
121
|
auditor,
|
|
121
122
|
actionsRegistry,
|
|
122
123
|
actionsRegistryService,
|
|
123
|
-
scaffolderService
|
|
124
|
+
scaffolderService,
|
|
125
|
+
metrics
|
|
124
126
|
}) {
|
|
125
127
|
const log$1 = loggerToWinstonLogger.loggerToWinstonLogger(logger);
|
|
126
128
|
const integrations = integration.ScmIntegrations.fromConfig(config);
|
|
@@ -191,7 +193,8 @@ const scaffolderPlugin = backendPluginApi.createBackendPlugin({
|
|
|
191
193
|
additionalWorkspaceProviders,
|
|
192
194
|
events,
|
|
193
195
|
auditor,
|
|
194
|
-
actionsRegistry
|
|
196
|
+
actionsRegistry,
|
|
197
|
+
metrics
|
|
195
198
|
});
|
|
196
199
|
httpRouter.use(router$1);
|
|
197
200
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ScaffolderPlugin.cjs.js","sources":["../src/ScaffolderPlugin.ts"],"sourcesContent":["/*\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 {\n coreServices,\n createBackendPlugin,\n} from '@backstage/backend-plugin-api';\nimport { ScmIntegrations } from '@backstage/integration';\nimport { catalogServiceRef } from '@backstage/plugin-catalog-node';\nimport { eventsServiceRef } from '@backstage/plugin-events-node';\nimport {\n scaffolderActionsExtensionPoint,\n scaffolderServiceRef,\n TaskBroker,\n TemplateAction,\n} from '@backstage/plugin-scaffolder-node';\nimport {\n AutocompleteHandler,\n CreatedTemplateFilter,\n CreatedTemplateGlobal,\n createTemplateFilter,\n createTemplateGlobalFunction,\n createTemplateGlobalValue,\n scaffolderAutocompleteExtensionPoint,\n scaffolderTaskBrokerExtensionPoint,\n scaffolderTemplatingExtensionPoint,\n scaffolderWorkspaceProviderExtensionPoint,\n WorkspaceProvider,\n} from '@backstage/plugin-scaffolder-node/alpha';\nimport {\n createCatalogRegisterAction,\n createCatalogWriteAction,\n createDebugLogAction,\n createFetchCatalogEntityAction,\n createFetchPlainAction,\n createFetchPlainFileAction,\n createFetchTemplateAction,\n createFetchTemplateFileAction,\n createFilesystemDeleteAction,\n createFilesystemReadDirAction,\n createFilesystemRenameAction,\n createWaitAction,\n} from './scaffolder';\nimport { createRouter } from './service/router';\nimport { loggerToWinstonLogger } from './util/loggerToWinstonLogger';\nimport {\n convertFiltersToRecord,\n convertGlobalsToRecord,\n} from './util/templating';\nimport {\n actionsServiceRef,\n actionsRegistryServiceRef,\n} from '@backstage/backend-plugin-api/alpha';\nimport { createScaffolderActions } from './actions';\n\n/**\n * Scaffolder plugin\n *\n * @public\n */\nexport const scaffolderPlugin = createBackendPlugin({\n pluginId: 'scaffolder',\n register(env) {\n const addedActions = new Array<TemplateAction<any, any>>();\n env.registerExtensionPoint(scaffolderActionsExtensionPoint, {\n addActions(...newActions: TemplateAction<any>[]) {\n addedActions.push(...newActions);\n },\n });\n\n let taskBroker: TaskBroker | undefined;\n env.registerExtensionPoint(scaffolderTaskBrokerExtensionPoint, {\n setTaskBroker(newTaskBroker) {\n if (taskBroker) {\n throw new Error('Task broker may only be set once');\n }\n taskBroker = newTaskBroker;\n },\n });\n\n const additionalTemplateFilters: CreatedTemplateFilter<any, any>[] = [];\n const additionalTemplateGlobals: CreatedTemplateGlobal[] = [];\n\n env.registerExtensionPoint(scaffolderTemplatingExtensionPoint, {\n addTemplateFilters(newFilters) {\n additionalTemplateFilters.push(\n ...(Array.isArray(newFilters)\n ? newFilters\n : Object.entries(newFilters).map(([id, filter]) =>\n createTemplateFilter({\n id,\n filter,\n }),\n )),\n );\n },\n addTemplateGlobals(newGlobals) {\n additionalTemplateGlobals.push(\n ...(Array.isArray(newGlobals)\n ? newGlobals\n : Object.entries(newGlobals).map(([id, global]) =>\n typeof global === 'function'\n ? createTemplateGlobalFunction({ id, fn: global })\n : createTemplateGlobalValue({ id, value: global }),\n )),\n );\n },\n });\n\n const autocompleteHandlers: Record<string, AutocompleteHandler> = {};\n env.registerExtensionPoint(scaffolderAutocompleteExtensionPoint, {\n addAutocompleteProvider(provider) {\n autocompleteHandlers[provider.id] = provider.handler;\n },\n });\n\n const additionalWorkspaceProviders: Record<string, WorkspaceProvider> = {};\n env.registerExtensionPoint(scaffolderWorkspaceProviderExtensionPoint, {\n addProviders(provider) {\n Object.assign(additionalWorkspaceProviders, provider);\n },\n });\n\n env.registerInit({\n deps: {\n logger: coreServices.logger,\n config: coreServices.rootConfig,\n lifecycle: coreServices.rootLifecycle,\n reader: coreServices.urlReader,\n permissions: coreServices.permissions,\n permissionsRegistry: coreServices.permissionsRegistry,\n database: coreServices.database,\n auth: coreServices.auth,\n httpRouter: coreServices.httpRouter,\n httpAuth: coreServices.httpAuth,\n auditor: coreServices.auditor,\n catalog: catalogServiceRef,\n events: eventsServiceRef,\n actionsRegistry: actionsServiceRef,\n actionsRegistryService: actionsRegistryServiceRef,\n scaffolderService: scaffolderServiceRef,\n },\n async init({\n logger,\n config,\n lifecycle,\n reader,\n database,\n auth,\n httpRouter,\n httpAuth,\n catalog,\n permissions,\n permissionsRegistry,\n events,\n auditor,\n actionsRegistry,\n actionsRegistryService,\n scaffolderService,\n }) {\n const log = loggerToWinstonLogger(logger);\n const integrations = ScmIntegrations.fromConfig(config);\n\n const templateExtensions = {\n additionalTemplateFilters: convertFiltersToRecord(\n additionalTemplateFilters,\n ),\n additionalTemplateGlobals: convertGlobalsToRecord(\n additionalTemplateGlobals,\n ),\n };\n const actions = [\n // actions provided from other modules\n ...addedActions,\n\n // built-in actions for the scaffolder\n createFetchPlainAction({\n reader,\n integrations,\n }),\n createFetchPlainFileAction({\n reader,\n integrations,\n }),\n createFetchTemplateAction({\n integrations,\n reader,\n ...templateExtensions,\n }),\n createFetchTemplateFileAction({\n integrations,\n reader,\n ...templateExtensions,\n }),\n createDebugLogAction(),\n createWaitAction(),\n // todo(blam): maybe these should be a -catalog module?\n createCatalogRegisterAction({ catalog, integrations }),\n createFetchCatalogEntityAction({ catalog }),\n createCatalogWriteAction(),\n createFilesystemDeleteAction(),\n createFilesystemRenameAction(),\n createFilesystemReadDirAction(),\n ];\n\n const actionIds = actions.map(action => action.id).join(', ');\n\n log.info(\n `Starting scaffolder with the following actions enabled ${actionIds}`,\n );\n\n createScaffolderActions({\n actionsRegistry: actionsRegistryService,\n scaffolderService,\n auth,\n });\n\n const router = await createRouter({\n logger,\n config,\n database,\n catalog,\n lifecycle,\n actions,\n taskBroker,\n additionalTemplateFilters,\n additionalTemplateGlobals,\n auth,\n httpAuth,\n permissions,\n permissionsRegistry,\n autocompleteHandlers,\n additionalWorkspaceProviders,\n events,\n auditor,\n actionsRegistry,\n });\n httpRouter.use(router);\n },\n });\n },\n});\n"],"names":["createBackendPlugin","scaffolderActionsExtensionPoint","scaffolderTaskBrokerExtensionPoint","scaffolderTemplatingExtensionPoint","createTemplateFilter","createTemplateGlobalFunction","createTemplateGlobalValue","scaffolderAutocompleteExtensionPoint","scaffolderWorkspaceProviderExtensionPoint","coreServices","catalogServiceRef","eventsServiceRef","actionsServiceRef","actionsRegistryServiceRef","scaffolderServiceRef","log","loggerToWinstonLogger","ScmIntegrations","convertFiltersToRecord","convertGlobalsToRecord","createFetchPlainAction","createFetchPlainFileAction","createFetchTemplateAction","createFetchTemplateFileAction","createDebugLogAction","createWaitAction","createCatalogRegisterAction","createFetchCatalogEntityAction","createCatalogWriteAction","createFilesystemDeleteAction","createFilesystemRenameAction","createFilesystemReadDirAction","createScaffolderActions","router","createRouter"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ScaffolderPlugin.cjs.js","sources":["../src/ScaffolderPlugin.ts"],"sourcesContent":["/*\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 {\n coreServices,\n createBackendPlugin,\n} from '@backstage/backend-plugin-api';\nimport { ScmIntegrations } from '@backstage/integration';\nimport { catalogServiceRef } from '@backstage/plugin-catalog-node';\nimport { eventsServiceRef } from '@backstage/plugin-events-node';\nimport {\n scaffolderActionsExtensionPoint,\n scaffolderServiceRef,\n TaskBroker,\n TemplateAction,\n} from '@backstage/plugin-scaffolder-node';\nimport {\n AutocompleteHandler,\n CreatedTemplateFilter,\n CreatedTemplateGlobal,\n createTemplateFilter,\n createTemplateGlobalFunction,\n createTemplateGlobalValue,\n scaffolderAutocompleteExtensionPoint,\n scaffolderTaskBrokerExtensionPoint,\n scaffolderTemplatingExtensionPoint,\n scaffolderWorkspaceProviderExtensionPoint,\n WorkspaceProvider,\n} from '@backstage/plugin-scaffolder-node/alpha';\nimport {\n createCatalogRegisterAction,\n createCatalogWriteAction,\n createDebugLogAction,\n createFetchCatalogEntityAction,\n createFetchPlainAction,\n createFetchPlainFileAction,\n createFetchTemplateAction,\n createFetchTemplateFileAction,\n createFilesystemDeleteAction,\n createFilesystemReadDirAction,\n createFilesystemRenameAction,\n createWaitAction,\n} from './scaffolder';\nimport { createRouter } from './service/router';\nimport { loggerToWinstonLogger } from './util/loggerToWinstonLogger';\nimport {\n convertFiltersToRecord,\n convertGlobalsToRecord,\n} from './util/templating';\nimport {\n actionsServiceRef,\n actionsRegistryServiceRef,\n metricsServiceRef,\n} from '@backstage/backend-plugin-api/alpha';\nimport { createScaffolderActions } from './actions';\n\n/**\n * Scaffolder plugin\n *\n * @public\n */\nexport const scaffolderPlugin = createBackendPlugin({\n pluginId: 'scaffolder',\n register(env) {\n const addedActions = new Array<TemplateAction<any, any>>();\n env.registerExtensionPoint(scaffolderActionsExtensionPoint, {\n addActions(...newActions: TemplateAction<any>[]) {\n addedActions.push(...newActions);\n },\n });\n\n let taskBroker: TaskBroker | undefined;\n env.registerExtensionPoint(scaffolderTaskBrokerExtensionPoint, {\n setTaskBroker(newTaskBroker) {\n if (taskBroker) {\n throw new Error('Task broker may only be set once');\n }\n taskBroker = newTaskBroker;\n },\n });\n\n const additionalTemplateFilters: CreatedTemplateFilter<any, any>[] = [];\n const additionalTemplateGlobals: CreatedTemplateGlobal[] = [];\n\n env.registerExtensionPoint(scaffolderTemplatingExtensionPoint, {\n addTemplateFilters(newFilters) {\n additionalTemplateFilters.push(\n ...(Array.isArray(newFilters)\n ? newFilters\n : Object.entries(newFilters).map(([id, filter]) =>\n createTemplateFilter({\n id,\n filter,\n }),\n )),\n );\n },\n addTemplateGlobals(newGlobals) {\n additionalTemplateGlobals.push(\n ...(Array.isArray(newGlobals)\n ? newGlobals\n : Object.entries(newGlobals).map(([id, global]) =>\n typeof global === 'function'\n ? createTemplateGlobalFunction({ id, fn: global })\n : createTemplateGlobalValue({ id, value: global }),\n )),\n );\n },\n });\n\n const autocompleteHandlers: Record<string, AutocompleteHandler> = {};\n env.registerExtensionPoint(scaffolderAutocompleteExtensionPoint, {\n addAutocompleteProvider(provider) {\n autocompleteHandlers[provider.id] = provider.handler;\n },\n });\n\n const additionalWorkspaceProviders: Record<string, WorkspaceProvider> = {};\n env.registerExtensionPoint(scaffolderWorkspaceProviderExtensionPoint, {\n addProviders(provider) {\n Object.assign(additionalWorkspaceProviders, provider);\n },\n });\n\n env.registerInit({\n deps: {\n logger: coreServices.logger,\n config: coreServices.rootConfig,\n lifecycle: coreServices.rootLifecycle,\n reader: coreServices.urlReader,\n permissions: coreServices.permissions,\n permissionsRegistry: coreServices.permissionsRegistry,\n database: coreServices.database,\n auth: coreServices.auth,\n httpRouter: coreServices.httpRouter,\n httpAuth: coreServices.httpAuth,\n auditor: coreServices.auditor,\n catalog: catalogServiceRef,\n events: eventsServiceRef,\n actionsRegistry: actionsServiceRef,\n actionsRegistryService: actionsRegistryServiceRef,\n scaffolderService: scaffolderServiceRef,\n metrics: metricsServiceRef,\n },\n async init({\n logger,\n config,\n lifecycle,\n reader,\n database,\n auth,\n httpRouter,\n httpAuth,\n catalog,\n permissions,\n permissionsRegistry,\n events,\n auditor,\n actionsRegistry,\n actionsRegistryService,\n scaffolderService,\n metrics,\n }) {\n const log = loggerToWinstonLogger(logger);\n const integrations = ScmIntegrations.fromConfig(config);\n\n const templateExtensions = {\n additionalTemplateFilters: convertFiltersToRecord(\n additionalTemplateFilters,\n ),\n additionalTemplateGlobals: convertGlobalsToRecord(\n additionalTemplateGlobals,\n ),\n };\n const actions = [\n // actions provided from other modules\n ...addedActions,\n\n // built-in actions for the scaffolder\n createFetchPlainAction({\n reader,\n integrations,\n }),\n createFetchPlainFileAction({\n reader,\n integrations,\n }),\n createFetchTemplateAction({\n integrations,\n reader,\n ...templateExtensions,\n }),\n createFetchTemplateFileAction({\n integrations,\n reader,\n ...templateExtensions,\n }),\n createDebugLogAction(),\n createWaitAction(),\n // todo(blam): maybe these should be a -catalog module?\n createCatalogRegisterAction({ catalog, integrations }),\n createFetchCatalogEntityAction({ catalog }),\n createCatalogWriteAction(),\n createFilesystemDeleteAction(),\n createFilesystemRenameAction(),\n createFilesystemReadDirAction(),\n ];\n\n const actionIds = actions.map(action => action.id).join(', ');\n\n log.info(\n `Starting scaffolder with the following actions enabled ${actionIds}`,\n );\n\n createScaffolderActions({\n actionsRegistry: actionsRegistryService,\n scaffolderService,\n auth,\n });\n\n const router = await createRouter({\n logger,\n config,\n database,\n catalog,\n lifecycle,\n actions,\n taskBroker,\n additionalTemplateFilters,\n additionalTemplateGlobals,\n auth,\n httpAuth,\n permissions,\n permissionsRegistry,\n autocompleteHandlers,\n additionalWorkspaceProviders,\n events,\n auditor,\n actionsRegistry,\n metrics,\n });\n httpRouter.use(router);\n },\n });\n },\n});\n"],"names":["createBackendPlugin","scaffolderActionsExtensionPoint","scaffolderTaskBrokerExtensionPoint","scaffolderTemplatingExtensionPoint","createTemplateFilter","createTemplateGlobalFunction","createTemplateGlobalValue","scaffolderAutocompleteExtensionPoint","scaffolderWorkspaceProviderExtensionPoint","coreServices","catalogServiceRef","eventsServiceRef","actionsServiceRef","actionsRegistryServiceRef","scaffolderServiceRef","metricsServiceRef","log","loggerToWinstonLogger","ScmIntegrations","convertFiltersToRecord","convertGlobalsToRecord","createFetchPlainAction","createFetchPlainFileAction","createFetchTemplateAction","createFetchTemplateFileAction","createDebugLogAction","createWaitAction","createCatalogRegisterAction","createFetchCatalogEntityAction","createCatalogWriteAction","createFilesystemDeleteAction","createFilesystemRenameAction","createFilesystemReadDirAction","createScaffolderActions","router","createRouter"],"mappings":"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"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const createExecuteTemplateAction = ({
|
|
4
|
+
actionsRegistry,
|
|
5
|
+
scaffolderService
|
|
6
|
+
}) => {
|
|
7
|
+
actionsRegistry.register({
|
|
8
|
+
name: "execute-template",
|
|
9
|
+
title: "Execute Scaffolder Template",
|
|
10
|
+
attributes: {
|
|
11
|
+
destructive: true,
|
|
12
|
+
readOnly: false,
|
|
13
|
+
idempotent: false
|
|
14
|
+
},
|
|
15
|
+
description: `Executes a Scaffolder template with its template ref and input parameter values.
|
|
16
|
+
The template is run using the credentials provided to this action, and respects any RBAC permissions associated with those credentials.
|
|
17
|
+
Returns a taskId that can be used to track execution progress.
|
|
18
|
+
Use the catalog.get-catalog-entity action to fetch the Template entity and discover its parameter schema and secrets definition before calling this action.`,
|
|
19
|
+
schema: {
|
|
20
|
+
input: (z) => z.object({
|
|
21
|
+
templateRef: z.string().describe(
|
|
22
|
+
'The template entity reference to execute, e.g. "template:default/my-template"'
|
|
23
|
+
),
|
|
24
|
+
values: z.record(z.unknown()).describe(
|
|
25
|
+
"Input parameter values required by the template. Use catalog.get-catalog-entity to discover the required parameters for the template."
|
|
26
|
+
),
|
|
27
|
+
secrets: z.record(z.string()).optional().describe(
|
|
28
|
+
"Optional secrets to pass to the template execution. Use catalog.get-catalog-entity to discover the secrets definition on the Template entity."
|
|
29
|
+
)
|
|
30
|
+
}),
|
|
31
|
+
output: (z) => z.object({
|
|
32
|
+
taskId: z.string().describe(
|
|
33
|
+
"The task ID for the scaffolder execution. Use this to track progress or retrieve logs."
|
|
34
|
+
)
|
|
35
|
+
})
|
|
36
|
+
},
|
|
37
|
+
action: async ({ input, credentials }) => {
|
|
38
|
+
const { taskId } = await scaffolderService.scaffold(
|
|
39
|
+
{
|
|
40
|
+
templateRef: input.templateRef,
|
|
41
|
+
values: input.values,
|
|
42
|
+
...input.secrets && { secrets: input.secrets }
|
|
43
|
+
},
|
|
44
|
+
{ credentials }
|
|
45
|
+
);
|
|
46
|
+
return { output: { taskId } };
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
exports.createExecuteTemplateAction = createExecuteTemplateAction;
|
|
52
|
+
//# sourceMappingURL=createExecuteTemplateAction.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createExecuteTemplateAction.cjs.js","sources":["../../src/actions/createExecuteTemplateAction.ts"],"sourcesContent":["/*\n * Copyright 2026 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 */\nimport { ActionsRegistryService } from '@backstage/backend-plugin-api/alpha';\nimport { ScaffolderService } from '@backstage/plugin-scaffolder-node';\nimport { JsonValue } from '@backstage/types';\n\nexport const createExecuteTemplateAction = ({\n actionsRegistry,\n scaffolderService,\n}: {\n actionsRegistry: ActionsRegistryService;\n scaffolderService: ScaffolderService;\n}) => {\n actionsRegistry.register({\n name: 'execute-template',\n title: 'Execute Scaffolder Template',\n attributes: {\n destructive: true,\n readOnly: false,\n idempotent: false,\n },\n description: `Executes a Scaffolder template with its template ref and input parameter values.\nThe template is run using the credentials provided to this action, and respects any RBAC permissions associated with those credentials.\nReturns a taskId that can be used to track execution progress.\nUse the catalog.get-catalog-entity action to fetch the Template entity and discover its parameter schema and secrets definition before calling this action.`,\n schema: {\n input: z =>\n z.object({\n templateRef: z\n .string()\n .describe(\n 'The template entity reference to execute, e.g. \"template:default/my-template\"',\n ),\n values: z\n .record(z.unknown())\n .describe(\n 'Input parameter values required by the template. Use catalog.get-catalog-entity to discover the required parameters for the template.',\n ),\n secrets: z\n .record(z.string())\n .optional()\n .describe(\n 'Optional secrets to pass to the template execution. Use catalog.get-catalog-entity to discover the secrets definition on the Template entity.',\n ),\n }),\n output: z =>\n z.object({\n taskId: z\n .string()\n .describe(\n 'The task ID for the scaffolder execution. Use this to track progress or retrieve logs.',\n ),\n }),\n },\n action: async ({ input, credentials }) => {\n const { taskId } = await scaffolderService.scaffold(\n {\n templateRef: input.templateRef,\n values: input.values as Record<string, JsonValue>,\n ...(input.secrets && { secrets: input.secrets }),\n },\n { credentials },\n );\n\n return { output: { taskId } };\n },\n });\n};\n"],"names":[],"mappings":";;AAmBO,MAAM,8BAA8B,CAAC;AAAA,EAC1C,eAAA;AAAA,EACA;AACF,CAAA,KAGM;AACJ,EAAA,eAAA,CAAgB,QAAA,CAAS;AAAA,IACvB,IAAA,EAAM,kBAAA;AAAA,IACN,KAAA,EAAO,6BAAA;AAAA,IACP,UAAA,EAAY;AAAA,MACV,WAAA,EAAa,IAAA;AAAA,MACb,QAAA,EAAU,KAAA;AAAA,MACV,UAAA,EAAY;AAAA,KACd;AAAA,IACA,WAAA,EAAa,CAAA;AAAA;AAAA;AAAA,2JAAA,CAAA;AAAA,IAIb,MAAA,EAAQ;AAAA,MACN,KAAA,EAAO,CAAA,CAAA,KACL,CAAA,CAAE,MAAA,CAAO;AAAA,QACP,WAAA,EAAa,CAAA,CACV,MAAA,EAAO,CACP,QAAA;AAAA,UACC;AAAA,SACF;AAAA,QACF,QAAQ,CAAA,CACL,MAAA,CAAO,CAAA,CAAE,OAAA,EAAS,CAAA,CAClB,QAAA;AAAA,UACC;AAAA,SACF;AAAA,QACF,OAAA,EAAS,EACN,MAAA,CAAO,CAAA,CAAE,QAAQ,CAAA,CACjB,UAAS,CACT,QAAA;AAAA,UACC;AAAA;AACF,OACH,CAAA;AAAA,MACH,MAAA,EAAQ,CAAA,CAAA,KACN,CAAA,CAAE,MAAA,CAAO;AAAA,QACP,MAAA,EAAQ,CAAA,CACL,MAAA,EAAO,CACP,QAAA;AAAA,UACC;AAAA;AACF,OACH;AAAA,KACL;AAAA,IACA,MAAA,EAAQ,OAAO,EAAE,KAAA,EAAO,aAAY,KAAM;AACxC,MAAA,MAAM,EAAE,MAAA,EAAO,GAAI,MAAM,iBAAA,CAAkB,QAAA;AAAA,QACzC;AAAA,UACE,aAAa,KAAA,CAAM,WAAA;AAAA,UACnB,QAAQ,KAAA,CAAM,MAAA;AAAA,UACd,GAAI,KAAA,CAAM,OAAA,IAAW,EAAE,OAAA,EAAS,MAAM,OAAA;AAAQ,SAChD;AAAA,QACA,EAAE,WAAA;AAAY,OAChB;AAEA,MAAA,OAAO,EAAE,MAAA,EAAQ,EAAE,MAAA,EAAO,EAAE;AAAA,IAC9B;AAAA,GACD,CAAA;AACH;;;;"}
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
var listScaffolderTasksAction = require('./listScaffolderTasksAction.cjs.js');
|
|
4
4
|
var createDryRunTemplateAction = require('./createDryRunTemplateAction.cjs.js');
|
|
5
5
|
var createListScaffolderActionsAction = require('./createListScaffolderActionsAction.cjs.js');
|
|
6
|
+
var createExecuteTemplateAction = require('./createExecuteTemplateAction.cjs.js');
|
|
6
7
|
var createGetScaffolderTaskLogsAction = require('./createGetScaffolderTaskLogsAction.cjs.js');
|
|
7
8
|
|
|
8
9
|
const createScaffolderActions = (options) => {
|
|
@@ -13,6 +14,7 @@ const createScaffolderActions = (options) => {
|
|
|
13
14
|
});
|
|
14
15
|
createDryRunTemplateAction.createDryRunTemplateAction(options);
|
|
15
16
|
createListScaffolderActionsAction.createListScaffolderActionsAction(options);
|
|
17
|
+
createExecuteTemplateAction.createExecuteTemplateAction(options);
|
|
16
18
|
createGetScaffolderTaskLogsAction.createGetScaffolderTaskLogsAction(options);
|
|
17
19
|
};
|
|
18
20
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs.js","sources":["../../src/actions/index.ts"],"sourcesContent":["/*\n * Copyright 2026 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 */\nimport { ActionsRegistryService } from '@backstage/backend-plugin-api/alpha';\nimport { AuthService } from '@backstage/backend-plugin-api';\nimport { createListScaffolderTasksAction } from './listScaffolderTasksAction';\nimport { ScaffolderService } from '@backstage/plugin-scaffolder-node';\nimport { createDryRunTemplateAction } from './createDryRunTemplateAction';\nimport { createListScaffolderActionsAction } from './createListScaffolderActionsAction';\nimport { createGetScaffolderTaskLogsAction } from './createGetScaffolderTaskLogsAction';\n\nexport const createScaffolderActions = (options: {\n actionsRegistry: ActionsRegistryService;\n scaffolderService: ScaffolderService;\n auth: AuthService;\n}) => {\n createListScaffolderTasksAction({\n actionsRegistry: options.actionsRegistry,\n auth: options.auth,\n scaffolderService: options.scaffolderService,\n });\n createDryRunTemplateAction(options);\n createListScaffolderActionsAction(options);\n createGetScaffolderTaskLogsAction(options);\n};\n"],"names":["createListScaffolderTasksAction","createDryRunTemplateAction","createListScaffolderActionsAction","createGetScaffolderTaskLogsAction"],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.cjs.js","sources":["../../src/actions/index.ts"],"sourcesContent":["/*\n * Copyright 2026 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 */\nimport { ActionsRegistryService } from '@backstage/backend-plugin-api/alpha';\nimport { AuthService } from '@backstage/backend-plugin-api';\nimport { createListScaffolderTasksAction } from './listScaffolderTasksAction';\nimport { ScaffolderService } from '@backstage/plugin-scaffolder-node';\nimport { createDryRunTemplateAction } from './createDryRunTemplateAction';\nimport { createListScaffolderActionsAction } from './createListScaffolderActionsAction';\nimport { createExecuteTemplateAction } from './createExecuteTemplateAction';\nimport { createGetScaffolderTaskLogsAction } from './createGetScaffolderTaskLogsAction';\n\nexport const createScaffolderActions = (options: {\n actionsRegistry: ActionsRegistryService;\n scaffolderService: ScaffolderService;\n auth: AuthService;\n}) => {\n createListScaffolderTasksAction({\n actionsRegistry: options.actionsRegistry,\n auth: options.auth,\n scaffolderService: options.scaffolderService,\n });\n createDryRunTemplateAction(options);\n createListScaffolderActionsAction(options);\n createExecuteTemplateAction(options);\n createGetScaffolderTaskLogsAction(options);\n};\n"],"names":["createListScaffolderTasksAction","createDryRunTemplateAction","createListScaffolderActionsAction","createExecuteTemplateAction","createGetScaffolderTaskLogsAction"],"mappings":";;;;;;;;AAwBO,MAAM,uBAAA,GAA0B,CAAC,OAAA,KAIlC;AACJ,EAAAA,yDAAA,CAAgC;AAAA,IAC9B,iBAAiB,OAAA,CAAQ,eAAA;AAAA,IACzB,MAAM,OAAA,CAAQ,IAAA;AAAA,IACd,mBAAmB,OAAA,CAAQ;AAAA,GAC5B,CAAA;AACD,EAAAC,qDAAA,CAA2B,OAAO,CAAA;AAClC,EAAAC,mEAAA,CAAkC,OAAO,CAAA;AACzC,EAAAC,uDAAA,CAA4B,OAAO,CAAA;AACnC,EAAAC,mEAAA,CAAkC,OAAO,CAAA;AAC3C;;;;"}
|
package/dist/index.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ import { HumanDuration } from '@backstage/types';
|
|
|
8
8
|
import { Duration } from 'luxon';
|
|
9
9
|
import { PermissionRule } from '@backstage/plugin-permission-node';
|
|
10
10
|
import { TemplateEntityStepV1beta3, TemplateParametersV1beta3 } from '@backstage/plugin-scaffolder-common';
|
|
11
|
-
import {
|
|
11
|
+
import { RESOURCE_TYPE_SCAFFOLDER_ACTION, RESOURCE_TYPE_SCAFFOLDER_TEMPLATE } from '@backstage/plugin-scaffolder-common/alpha';
|
|
12
12
|
import { PermissionRuleParams } from '@backstage/plugin-permission-common';
|
|
13
13
|
|
|
14
14
|
/**
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var filter = require('./parseRepoUrl/filter.cjs.js');
|
|
4
|
-
var filter
|
|
5
|
-
var filter$
|
|
3
|
+
var filter$2 = require('./parseRepoUrl/filter.cjs.js');
|
|
4
|
+
var filter = require('./parseEntityRef/filter.cjs.js');
|
|
5
|
+
var filter$1 = require('./pick/filter.cjs.js');
|
|
6
6
|
var filter$3 = require('./projectSlug/filter.cjs.js');
|
|
7
7
|
|
|
8
8
|
const createDefaultFilters = (options) => [
|
|
9
|
-
filter.createParseRepoUrl(options.integrations),
|
|
10
|
-
filter
|
|
11
|
-
filter$
|
|
9
|
+
filter$2.createParseRepoUrl(options.integrations),
|
|
10
|
+
filter.parseEntityRef,
|
|
11
|
+
filter$1.pick,
|
|
12
12
|
filter$3.createProjectSlug(options.integrations)
|
|
13
13
|
];
|
|
14
14
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createDefaultFilters.cjs.js","sources":["../../../../src/lib/templating/filters/createDefaultFilters.ts"],"sourcesContent":["/*\n * Copyright 2025 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 */\nimport { ScmIntegrations } from '@backstage/integration';\nimport { createParseRepoUrl } from './parseRepoUrl';\nimport { parseEntityRef } from './parseEntityRef';\nimport { pick } from './pick';\nimport { createProjectSlug } from './projectSlug';\n\nexport const createDefaultFilters = (options: {\n integrations: ScmIntegrations;\n}) => [\n createParseRepoUrl(options.integrations),\n parseEntityRef,\n pick,\n createProjectSlug(options.integrations),\n];\n"],"names":["createParseRepoUrl","parseEntityRef","pick","createProjectSlug"],"mappings":";;;;;;;AAqBO,MAAM,oBAAA,GAAuB,CAAC,OAAA,KAE/B;AAAA,EACJA,
|
|
1
|
+
{"version":3,"file":"createDefaultFilters.cjs.js","sources":["../../../../src/lib/templating/filters/createDefaultFilters.ts"],"sourcesContent":["/*\n * Copyright 2025 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 */\nimport { ScmIntegrations } from '@backstage/integration';\nimport { createParseRepoUrl } from './parseRepoUrl';\nimport { parseEntityRef } from './parseEntityRef';\nimport { pick } from './pick';\nimport { createProjectSlug } from './projectSlug';\n\nexport const createDefaultFilters = (options: {\n integrations: ScmIntegrations;\n}) => [\n createParseRepoUrl(options.integrations),\n parseEntityRef,\n pick,\n createProjectSlug(options.integrations),\n];\n"],"names":["createParseRepoUrl","parseEntityRef","pick","createProjectSlug"],"mappings":";;;;;;;AAqBO,MAAM,oBAAA,GAAuB,CAAC,OAAA,KAE/B;AAAA,EACJA,2BAAA,CAAmB,QAAQ,YAAY,CAAA;AAAA,EACvCC,qBAAA;AAAA,EACAC,aAAA;AAAA,EACAC,0BAAA,CAAkB,QAAQ,YAAY;AACxC;;;;"}
|
|
@@ -41,7 +41,6 @@ class DefaultTemplateActionRegistry {
|
|
|
41
41
|
ret.set(action.id, {
|
|
42
42
|
id: action.id,
|
|
43
43
|
description: action.description,
|
|
44
|
-
examples: [],
|
|
45
44
|
supportsDryRun: action.attributes?.readOnly === true && action.attributes?.destructive === false,
|
|
46
45
|
handler: async (ctx) => {
|
|
47
46
|
const { output } = await this.actionsRegistry.invoke({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TemplateActionRegistry.cjs.js","sources":["../../../src/scaffolder/actions/TemplateActionRegistry.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 { ConflictError, NotFoundError } from '@backstage/errors';\nimport { TemplateAction } from '@backstage/plugin-scaffolder-node';\nimport { ActionsService } from '@backstage/backend-plugin-api/alpha';\nimport {\n BackstageCredentials,\n LoggerService,\n} from '@backstage/backend-plugin-api';\nimport { isPlainObject } from 'lodash';\nimport { Schema } from 'jsonschema';\nimport { JsonObject } from '@backstage/types';\n\n/**\n * @internal\n */\nexport interface TemplateActionRegistry {\n register(action: TemplateAction<any, any, any>): void;\n get(\n actionId: string,\n options: { credentials: BackstageCredentials },\n ): Promise<TemplateAction<any, any, any>>;\n list(options: {\n credentials: BackstageCredentials;\n }): Promise<Map<string, TemplateAction<any, any, any>>>;\n}\n\n/**\n * Registry of all registered template actions.\n */\nexport class DefaultTemplateActionRegistry implements TemplateActionRegistry {\n private readonly actions = new Map<string, TemplateAction>();\n\n constructor(\n private readonly actionsRegistry: ActionsService,\n private readonly logger: LoggerService,\n ) {}\n\n register(action: TemplateAction<any, any, any>) {\n if (this.actions.has(action.id)) {\n throw new ConflictError(\n `Template action with ID '${action.id}' has already been registered`,\n );\n }\n\n this.actions.set(action.id, action);\n }\n\n async get(\n actionId: string,\n options: { credentials: BackstageCredentials },\n ): Promise<TemplateAction<any, any, any>> {\n const action = (await this.list(options)).get(actionId);\n if (!action) {\n throw new NotFoundError(\n `Template action with ID '${actionId}' is not registered. See https://backstage.io/docs/features/software-templates/builtin-actions/ on how to add a new action module.`,\n );\n }\n return action;\n }\n\n async list(options: {\n credentials: BackstageCredentials;\n }): Promise<Map<string, TemplateAction<any, any, any>>> {\n const ret = new Map(this.actions);\n\n const { actions } = await this.actionsRegistry.list({\n credentials: options.credentials,\n });\n\n for (const action of actions) {\n if (ret.has(action.id)) {\n this.logger.warn(\n `Template action with ID '${action.id}' has already been registered, skipping action provided by actions service`,\n );\n continue;\n }\n\n ret.set(action.id, {\n id: action.id,\n description: action.description,\n
|
|
1
|
+
{"version":3,"file":"TemplateActionRegistry.cjs.js","sources":["../../../src/scaffolder/actions/TemplateActionRegistry.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 { ConflictError, NotFoundError } from '@backstage/errors';\nimport { TemplateAction } from '@backstage/plugin-scaffolder-node';\nimport { ActionsService } from '@backstage/backend-plugin-api/alpha';\nimport {\n BackstageCredentials,\n LoggerService,\n} from '@backstage/backend-plugin-api';\nimport { isPlainObject } from 'lodash';\nimport { Schema } from 'jsonschema';\nimport { JsonObject } from '@backstage/types';\n\n/**\n * @internal\n */\nexport interface TemplateActionRegistry {\n register(action: TemplateAction<any, any, any>): void;\n get(\n actionId: string,\n options: { credentials: BackstageCredentials },\n ): Promise<TemplateAction<any, any, any>>;\n list(options: {\n credentials: BackstageCredentials;\n }): Promise<Map<string, TemplateAction<any, any, any>>>;\n}\n\n/**\n * Registry of all registered template actions.\n */\nexport class DefaultTemplateActionRegistry implements TemplateActionRegistry {\n private readonly actions = new Map<string, TemplateAction>();\n\n constructor(\n private readonly actionsRegistry: ActionsService,\n private readonly logger: LoggerService,\n ) {}\n\n register(action: TemplateAction<any, any, any>) {\n if (this.actions.has(action.id)) {\n throw new ConflictError(\n `Template action with ID '${action.id}' has already been registered`,\n );\n }\n\n this.actions.set(action.id, action);\n }\n\n async get(\n actionId: string,\n options: { credentials: BackstageCredentials },\n ): Promise<TemplateAction<any, any, any>> {\n const action = (await this.list(options)).get(actionId);\n if (!action) {\n throw new NotFoundError(\n `Template action with ID '${actionId}' is not registered. See https://backstage.io/docs/features/software-templates/builtin-actions/ on how to add a new action module.`,\n );\n }\n return action;\n }\n\n async list(options: {\n credentials: BackstageCredentials;\n }): Promise<Map<string, TemplateAction<any, any, any>>> {\n const ret = new Map(this.actions);\n\n const { actions } = await this.actionsRegistry.list({\n credentials: options.credentials,\n });\n\n for (const action of actions) {\n if (ret.has(action.id)) {\n this.logger.warn(\n `Template action with ID '${action.id}' has already been registered, skipping action provided by actions service`,\n );\n continue;\n }\n\n ret.set(action.id, {\n id: action.id,\n description: action.description,\n supportsDryRun:\n action.attributes?.readOnly === true &&\n action.attributes?.destructive === false,\n handler: async ctx => {\n const { output } = await this.actionsRegistry.invoke({\n id: action.id,\n input: ctx.input,\n credentials: await ctx.getInitiatorCredentials(),\n });\n\n if (isPlainObject(output)) {\n for (const [key, value] of Object.entries(output as JsonObject)) {\n ctx.output(key as keyof typeof output, value);\n }\n }\n },\n schema: {\n input: action.schema.input as Schema,\n output: action.schema.output as Schema,\n },\n });\n }\n return ret;\n }\n}\n"],"names":["ConflictError","NotFoundError","isPlainObject"],"mappings":";;;;;AA4CO,MAAM,6BAAA,CAAgE;AAAA,EAG3E,WAAA,CACmB,iBACA,MAAA,EACjB;AAFiB,IAAA,IAAA,CAAA,eAAA,GAAA,eAAA;AACA,IAAA,IAAA,CAAA,MAAA,GAAA,MAAA;AAAA,EAChB;AAAA,EALc,OAAA,uBAAc,GAAA,EAA4B;AAAA,EAO3D,SAAS,MAAA,EAAuC;AAC9C,IAAA,IAAI,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAI,MAAA,CAAO,EAAE,CAAA,EAAG;AAC/B,MAAA,MAAM,IAAIA,oBAAA;AAAA,QACR,CAAA,yBAAA,EAA4B,OAAO,EAAE,CAAA,6BAAA;AAAA,OACvC;AAAA,IACF;AAEA,IAAA,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAI,MAAA,CAAO,EAAA,EAAI,MAAM,CAAA;AAAA,EACpC;AAAA,EAEA,MAAM,GAAA,CACJ,QAAA,EACA,OAAA,EACwC;AACxC,IAAA,MAAM,UAAU,MAAM,IAAA,CAAK,KAAK,OAAO,CAAA,EAAG,IAAI,QAAQ,CAAA;AACtD,IAAA,IAAI,CAAC,MAAA,EAAQ;AACX,MAAA,MAAM,IAAIC,oBAAA;AAAA,QACR,4BAA4B,QAAQ,CAAA,kIAAA;AAAA,OACtC;AAAA,IACF;AACA,IAAA,OAAO,MAAA;AAAA,EACT;AAAA,EAEA,MAAM,KAAK,OAAA,EAE6C;AACtD,IAAA,MAAM,GAAA,GAAM,IAAI,GAAA,CAAI,IAAA,CAAK,OAAO,CAAA;AAEhC,IAAA,MAAM,EAAE,OAAA,EAAQ,GAAI,MAAM,IAAA,CAAK,gBAAgB,IAAA,CAAK;AAAA,MAClD,aAAa,OAAA,CAAQ;AAAA,KACtB,CAAA;AAED,IAAA,KAAA,MAAW,UAAU,OAAA,EAAS;AAC5B,MAAA,IAAI,GAAA,CAAI,GAAA,CAAI,MAAA,CAAO,EAAE,CAAA,EAAG;AACtB,QAAA,IAAA,CAAK,MAAA,CAAO,IAAA;AAAA,UACV,CAAA,yBAAA,EAA4B,OAAO,EAAE,CAAA,0EAAA;AAAA,SACvC;AACA,QAAA;AAAA,MACF;AAEA,MAAA,GAAA,CAAI,GAAA,CAAI,OAAO,EAAA,EAAI;AAAA,QACjB,IAAI,MAAA,CAAO,EAAA;AAAA,QACX,aAAa,MAAA,CAAO,WAAA;AAAA,QACpB,gBACE,MAAA,CAAO,UAAA,EAAY,aAAa,IAAA,IAChC,MAAA,CAAO,YAAY,WAAA,KAAgB,KAAA;AAAA,QACrC,OAAA,EAAS,OAAM,GAAA,KAAO;AACpB,UAAA,MAAM,EAAE,MAAA,EAAO,GAAI,MAAM,IAAA,CAAK,gBAAgB,MAAA,CAAO;AAAA,YACnD,IAAI,MAAA,CAAO,EAAA;AAAA,YACX,OAAO,GAAA,CAAI,KAAA;AAAA,YACX,WAAA,EAAa,MAAM,GAAA,CAAI,uBAAA;AAAwB,WAChD,CAAA;AAED,UAAA,IAAIC,oBAAA,CAAc,MAAM,CAAA,EAAG;AACzB,YAAA,KAAA,MAAW,CAAC,GAAA,EAAK,KAAK,KAAK,MAAA,CAAO,OAAA,CAAQ,MAAoB,CAAA,EAAG;AAC/D,cAAA,GAAA,CAAI,MAAA,CAAO,KAA4B,KAAK,CAAA;AAAA,YAC9C;AAAA,UACF;AAAA,QACF,CAAA;AAAA,QACA,MAAA,EAAQ;AAAA,UACN,KAAA,EAAO,OAAO,MAAA,CAAO,KAAA;AAAA,UACrB,MAAA,EAAQ,OAAO,MAAA,CAAO;AAAA;AACxB,OACD,CAAA;AAAA,IACH;AACA,IAAA,OAAO,GAAA;AAAA,EACT;AACF;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createDryRunner.cjs.js","sources":["../../../src/scaffolder/dryrun/createDryRunner.ts"],"sourcesContent":["/*\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 {\n AuditorService,\n BackstageCredentials,\n LoggerService,\n} from '@backstage/backend-plugin-api';\nimport type { UserEntity } from '@backstage/catalog-model';\nimport { Config } from '@backstage/config';\nimport { ScmIntegrations } from '@backstage/integration';\nimport { PermissionEvaluator } from '@backstage/plugin-permission-common';\nimport {\n ScaffolderTaskStatus,\n TaskSpec,\n TemplateInfo,\n} from '@backstage/plugin-scaffolder-common';\nimport {\n createTemplateAction,\n deserializeDirectoryContents,\n SerializedFile,\n serializeDirectoryContents,\n TaskSecrets,\n TemplateFilter,\n TemplateGlobal,\n} from '@backstage/plugin-scaffolder-node';\nimport { JsonObject } from '@backstage/types';\nimport fs from 'fs-extra';\nimport path from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { v4 as uuid } from 'uuid';\nimport { NunjucksWorkflowRunner } from '../tasks/NunjucksWorkflowRunner';\nimport { DecoratedActionsRegistry } from './DecoratedActionsRegistry';\nimport { TemplateActionRegistry } from '../actions';\n\ninterface DryRunInput {\n spec: TaskSpec;\n templateInfo: TemplateInfo;\n secrets?: TaskSecrets;\n directoryContents: SerializedFile[];\n credentials: BackstageCredentials;\n user?: {\n entity?: UserEntity;\n ref?: string;\n };\n}\n\ninterface DryRunResult {\n log: Array<{\n body: {\n message: string;\n stepId?: string;\n status?: ScaffolderTaskStatus;\n };\n }>;\n directoryContents: SerializedFile[];\n output: JsonObject;\n}\n\n/** @internal */\nexport type TemplateTesterCreateOptions = {\n logger: LoggerService;\n auditor?: AuditorService;\n integrations: ScmIntegrations;\n actionRegistry: TemplateActionRegistry;\n workingDirectory: string;\n additionalTemplateFilters?: Record<string, TemplateFilter>;\n additionalTemplateGlobals?: Record<string, TemplateGlobal>;\n permissions?: PermissionEvaluator;\n config?: Config;\n};\n\n/**\n * Executes a dry-run of the provided template.\n *\n * The provided content will be extracted into a temporary directory\n * which is then use as the base for any relative file fetch paths.\n *\n * @internal\n */\nexport function createDryRunner(options: TemplateTesterCreateOptions) {\n return async function dryRun(input: DryRunInput): Promise<DryRunResult> {\n let contentPromise;\n\n const workflowRunner = new NunjucksWorkflowRunner({\n ...options,\n actionRegistry: new DecoratedActionsRegistry(options.actionRegistry, [\n createTemplateAction({\n id: 'dry-run:extract',\n supportsDryRun: true,\n async handler(ctx) {\n contentPromise = serializeDirectoryContents(ctx.workspacePath);\n await contentPromise.catch(() => {});\n },\n }),\n ]),\n config: options.config,\n });\n\n // Extracting contentsPath and dryRunId from the baseUrl\n const baseUrl = input.templateInfo.baseUrl;\n if (!baseUrl) {\n throw new Error('baseUrl is required');\n }\n const basePath = fileURLToPath(new URL(baseUrl));\n const contentsPath = path.dirname(basePath);\n const dryRunId = uuid();\n\n const log = new Array<{\n body: {\n message: string;\n stepId?: string;\n status?: ScaffolderTaskStatus;\n };\n }>();\n\n try {\n await deserializeDirectoryContents(contentsPath, input.directoryContents);\n\n const abortSignal = new AbortController().signal;\n const result = await workflowRunner.execute({\n taskId: dryRunId,\n spec: {\n ...input.spec,\n steps: [\n ...input.spec.steps,\n {\n id: dryRunId,\n name: 'dry-run:extract',\n action: 'dry-run:extract',\n },\n ],\n templateInfo: input.templateInfo,\n },\n secrets: input.secrets,\n getInitiatorCredentials: () => Promise.resolve(input.credentials),\n // No need to update this at the end of the run, so just hard-code it\n done: false,\n isDryRun: true,\n getWorkspaceName: async () => `dry-run-${dryRunId}`,\n cancelSignal: abortSignal,\n async emitLog(message: string, logMetadata?: JsonObject) {\n if (logMetadata?.stepId === dryRunId) {\n return;\n }\n log.push({\n body: {\n ...logMetadata,\n message,\n },\n });\n },\n complete: async () => {\n throw new Error('Not implemented');\n },\n });\n\n if (!contentPromise) {\n throw new Error('Content extraction step was skipped');\n }\n const directoryContents = await contentPromise;\n\n return {\n log,\n directoryContents,\n output: result.output,\n };\n } finally {\n await fs.remove(contentsPath);\n }\n };\n}\n"],"names":["NunjucksWorkflowRunner","DecoratedActionsRegistry","createTemplateAction","serializeDirectoryContents","fileURLToPath","path","uuid","deserializeDirectoryContents","fs"],"mappings":";;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"createDryRunner.cjs.js","sources":["../../../src/scaffolder/dryrun/createDryRunner.ts"],"sourcesContent":["/*\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 {\n AuditorService,\n BackstageCredentials,\n LoggerService,\n} from '@backstage/backend-plugin-api';\nimport type { MetricsService } from '@backstage/backend-plugin-api/alpha';\nimport type { UserEntity } from '@backstage/catalog-model';\nimport { Config } from '@backstage/config';\nimport { ScmIntegrations } from '@backstage/integration';\nimport { PermissionEvaluator } from '@backstage/plugin-permission-common';\nimport {\n ScaffolderTaskStatus,\n TaskSpec,\n TemplateInfo,\n} from '@backstage/plugin-scaffolder-common';\nimport {\n createTemplateAction,\n deserializeDirectoryContents,\n SerializedFile,\n serializeDirectoryContents,\n TaskSecrets,\n TemplateFilter,\n TemplateGlobal,\n} from '@backstage/plugin-scaffolder-node';\nimport { JsonObject } from '@backstage/types';\nimport fs from 'fs-extra';\nimport path from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { v4 as uuid } from 'uuid';\nimport { NunjucksWorkflowRunner } from '../tasks/NunjucksWorkflowRunner';\nimport { DecoratedActionsRegistry } from './DecoratedActionsRegistry';\nimport { TemplateActionRegistry } from '../actions';\n\ninterface DryRunInput {\n spec: TaskSpec;\n templateInfo: TemplateInfo;\n secrets?: TaskSecrets;\n directoryContents: SerializedFile[];\n credentials: BackstageCredentials;\n user?: {\n entity?: UserEntity;\n ref?: string;\n };\n}\n\ninterface DryRunResult {\n log: Array<{\n body: {\n message: string;\n stepId?: string;\n status?: ScaffolderTaskStatus;\n };\n }>;\n directoryContents: SerializedFile[];\n output: JsonObject;\n}\n\n/** @internal */\nexport type TemplateTesterCreateOptions = {\n logger: LoggerService;\n auditor?: AuditorService;\n integrations: ScmIntegrations;\n actionRegistry: TemplateActionRegistry;\n workingDirectory: string;\n additionalTemplateFilters?: Record<string, TemplateFilter>;\n additionalTemplateGlobals?: Record<string, TemplateGlobal>;\n permissions?: PermissionEvaluator;\n config?: Config;\n metrics: MetricsService;\n};\n\n/**\n * Executes a dry-run of the provided template.\n *\n * The provided content will be extracted into a temporary directory\n * which is then use as the base for any relative file fetch paths.\n *\n * @internal\n */\nexport function createDryRunner(options: TemplateTesterCreateOptions) {\n return async function dryRun(input: DryRunInput): Promise<DryRunResult> {\n let contentPromise;\n\n const workflowRunner = new NunjucksWorkflowRunner({\n ...options,\n actionRegistry: new DecoratedActionsRegistry(options.actionRegistry, [\n createTemplateAction({\n id: 'dry-run:extract',\n supportsDryRun: true,\n async handler(ctx) {\n contentPromise = serializeDirectoryContents(ctx.workspacePath);\n await contentPromise.catch(() => {});\n },\n }),\n ]),\n config: options.config,\n });\n\n // Extracting contentsPath and dryRunId from the baseUrl\n const baseUrl = input.templateInfo.baseUrl;\n if (!baseUrl) {\n throw new Error('baseUrl is required');\n }\n const basePath = fileURLToPath(new URL(baseUrl));\n const contentsPath = path.dirname(basePath);\n const dryRunId = uuid();\n\n const log = new Array<{\n body: {\n message: string;\n stepId?: string;\n status?: ScaffolderTaskStatus;\n };\n }>();\n\n try {\n await deserializeDirectoryContents(contentsPath, input.directoryContents);\n\n const abortSignal = new AbortController().signal;\n const result = await workflowRunner.execute({\n taskId: dryRunId,\n spec: {\n ...input.spec,\n steps: [\n ...input.spec.steps,\n {\n id: dryRunId,\n name: 'dry-run:extract',\n action: 'dry-run:extract',\n },\n ],\n templateInfo: input.templateInfo,\n },\n secrets: input.secrets,\n getInitiatorCredentials: () => Promise.resolve(input.credentials),\n // No need to update this at the end of the run, so just hard-code it\n done: false,\n isDryRun: true,\n getWorkspaceName: async () => `dry-run-${dryRunId}`,\n cancelSignal: abortSignal,\n async emitLog(message: string, logMetadata?: JsonObject) {\n if (logMetadata?.stepId === dryRunId) {\n return;\n }\n log.push({\n body: {\n ...logMetadata,\n message,\n },\n });\n },\n complete: async () => {\n throw new Error('Not implemented');\n },\n });\n\n if (!contentPromise) {\n throw new Error('Content extraction step was skipped');\n }\n const directoryContents = await contentPromise;\n\n return {\n log,\n directoryContents,\n output: result.output,\n };\n } finally {\n await fs.remove(contentsPath);\n }\n };\n}\n"],"names":["NunjucksWorkflowRunner","DecoratedActionsRegistry","createTemplateAction","serializeDirectoryContents","fileURLToPath","path","uuid","deserializeDirectoryContents","fs"],"mappings":"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"}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var errors = require('@backstage/errors');
|
|
4
|
-
var api = require('@opentelemetry/api');
|
|
5
4
|
var fs = require('fs-extra');
|
|
6
5
|
var jsonschema = require('jsonschema');
|
|
7
6
|
var nunjucks = require('nunjucks');
|
|
@@ -100,6 +99,7 @@ class NunjucksWorkflowRunner {
|
|
|
100
99
|
defaultTemplateFilters;
|
|
101
100
|
options;
|
|
102
101
|
environment = { parameters: {}, secrets: {} };
|
|
102
|
+
tracker;
|
|
103
103
|
constructor(options) {
|
|
104
104
|
this.options = options;
|
|
105
105
|
this.defaultTemplateFilters = templating.convertFiltersToRecord(
|
|
@@ -107,8 +107,8 @@ class NunjucksWorkflowRunner {
|
|
|
107
107
|
integrations: this.options.integrations
|
|
108
108
|
})
|
|
109
109
|
);
|
|
110
|
+
this.tracker = scaffoldingTracker(options.metrics);
|
|
110
111
|
}
|
|
111
|
-
tracker = scaffoldingTracker();
|
|
112
112
|
async getEnvironmentConfig() {
|
|
113
113
|
if (this.options.config) {
|
|
114
114
|
const defaultEnvironment$1 = defaultEnvironment.resolveDefaultEnvironment(this.options.config);
|
|
@@ -485,7 +485,7 @@ class NunjucksWorkflowRunner {
|
|
|
485
485
|
}
|
|
486
486
|
}
|
|
487
487
|
}
|
|
488
|
-
function scaffoldingTracker() {
|
|
488
|
+
function scaffoldingTracker(metrics$1) {
|
|
489
489
|
const promTaskCount = metrics.createCounterMetric({
|
|
490
490
|
name: "scaffolder_task_count",
|
|
491
491
|
help: "Count of task runs",
|
|
@@ -506,20 +506,19 @@ function scaffoldingTracker() {
|
|
|
506
506
|
help: "Duration of a step runs",
|
|
507
507
|
labelNames: ["template", "step", "result"]
|
|
508
508
|
});
|
|
509
|
-
const
|
|
510
|
-
|
|
511
|
-
description: "Count of task runs"
|
|
509
|
+
const taskCount = metrics$1.createCounter("scaffolder.task.count", {
|
|
510
|
+
description: "Total number of scaffolder tasks executed"
|
|
512
511
|
});
|
|
513
|
-
const taskDuration =
|
|
514
|
-
description: "
|
|
515
|
-
unit: "
|
|
512
|
+
const taskDuration = metrics$1.createHistogram("scaffolder.task.duration", {
|
|
513
|
+
description: "Time taken to complete a scaffolder task end-to-end",
|
|
514
|
+
unit: "s"
|
|
516
515
|
});
|
|
517
|
-
const stepCount =
|
|
518
|
-
description: "
|
|
516
|
+
const stepCount = metrics$1.createCounter("scaffolder.step.count", {
|
|
517
|
+
description: "Total number of individual scaffolder action steps executed"
|
|
519
518
|
});
|
|
520
|
-
const stepDuration =
|
|
521
|
-
description: "
|
|
522
|
-
unit: "
|
|
519
|
+
const stepDuration = metrics$1.createHistogram("scaffolder.step.duration", {
|
|
520
|
+
description: "Time taken to complete a single scaffolder action step",
|
|
521
|
+
unit: "s"
|
|
523
522
|
});
|
|
524
523
|
async function taskStart(task) {
|
|
525
524
|
await task.emitLog(`Starting up task with ${task.spec.steps.length} steps`);
|