@backstage/plugin-scaffolder-backend 4.1.0-next.0 → 4.2.0-next.1
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 +28 -0
- package/config.schema.json +4 -0
- package/dist/ScaffolderPlugin.cjs.js +9 -2
- package/dist/ScaffolderPlugin.cjs.js.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/scaffolder/actions/builtin/fetch/assertScmUserCredentials.cjs.js +34 -0
- package/dist/scaffolder/actions/builtin/fetch/assertScmUserCredentials.cjs.js.map +1 -0
- package/dist/scaffolder/actions/builtin/fetch/plain.cjs.js +9 -1
- package/dist/scaffolder/actions/builtin/fetch/plain.cjs.js.map +1 -1
- package/dist/scaffolder/actions/builtin/fetch/plainFile.cjs.js +9 -1
- package/dist/scaffolder/actions/builtin/fetch/plainFile.cjs.js.map +1 -1
- package/dist/scaffolder/actions/builtin/fetch/template.cjs.js +8 -0
- package/dist/scaffolder/actions/builtin/fetch/template.cjs.js.map +1 -1
- package/dist/scaffolder/actions/builtin/fetch/templateFile.cjs.js +8 -0
- package/dist/scaffolder/actions/builtin/fetch/templateFile.cjs.js.map +1 -1
- package/dist/scaffolder/tasks/DatabaseTaskStore.cjs.js +17 -18
- package/dist/scaffolder/tasks/DatabaseTaskStore.cjs.js.map +1 -1
- package/dist/scaffolder/tasks/NunjucksWorkflowRunner.cjs.js +131 -52
- package/dist/scaffolder/tasks/NunjucksWorkflowRunner.cjs.js.map +1 -1
- package/dist/scaffolder/tasks/TaskWorker.cjs.js +14 -4
- package/dist/scaffolder/tasks/TaskWorker.cjs.js.map +1 -1
- package/dist/scaffolder/tasks/logger.cjs.js +101 -7
- package/dist/scaffolder/tasks/logger.cjs.js.map +1 -1
- package/dist/schema/openapi/generated/router.cjs.js +6 -6
- package/dist/schema/openapi/generated/router.cjs.js.map +1 -1
- package/dist/service/router.cjs.js +20 -4
- package/dist/service/router.cjs.js.map +1 -1
- package/dist/service/rules.cjs.js +12 -0
- package/dist/service/rules.cjs.js.map +1 -1
- package/dist/util/checkPermissions.cjs.js +3 -0
- package/dist/util/checkPermissions.cjs.js.map +1 -1
- package/package.json +13 -13
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,33 @@
|
|
|
1
1
|
# @backstage/plugin-scaffolder-backend
|
|
2
2
|
|
|
3
|
+
## 4.2.0-next.1
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- bbba6b5: Added the `scaffolder.requireScmUserCredentials` configuration option to require user-provided credentials for supported SCM mutation and fetch actions.
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- 7fba55a: Removed user entity references from scaffolder task count metrics to avoid exposing user identities and creating high-cardinality metric labels.
|
|
12
|
+
- b1256aa: Respect task read permission decisions when listing scaffolder tasks.
|
|
13
|
+
- 15fa029: Restrict task list ordering to supported fields.
|
|
14
|
+
- be0a75a: Exclude internal task data from task responses.
|
|
15
|
+
- f389dd2: Improve denied scaffolder action error handling.
|
|
16
|
+
- 2eebeb7: Ensure task failure details use the configured log redactions.
|
|
17
|
+
- 84ebbb9: Fixed log redaction for transformed secret values used to iterate Scaffolder steps.
|
|
18
|
+
- b4172dd: Restrict task retries to terminal states.
|
|
19
|
+
- ee9c48d: Fixed matching of action input values in scaffolder permission policies.
|
|
20
|
+
- 79f0b91: Fixed the scaffolder task worker silently giving up after a transient failure. A single error while picking up a task, such as a dropped database connection, would stop the backend from running any further software templates for the rest of its lifetime. New tasks stayed queued indefinitely with no error shown to the user and no failing health check, and the only way to recover was to restart the backend. Picking up tasks is now retried instead.
|
|
21
|
+
- Updated dependencies
|
|
22
|
+
- @backstage/plugin-scaffolder-common@2.3.0-next.1
|
|
23
|
+
- @backstage/integration@2.1.2-next.0
|
|
24
|
+
- @backstage/backend-openapi-utils@0.7.2-next.0
|
|
25
|
+
- @backstage/plugin-permission-node@0.11.4-next.0
|
|
26
|
+
- @backstage/plugin-scaffolder-node@0.13.7-next.1
|
|
27
|
+
- @backstage/backend-plugin-api@1.10.1-next.0
|
|
28
|
+
- @backstage/plugin-catalog-node@2.2.5-next.0
|
|
29
|
+
- @backstage/plugin-events-node@0.4.26-next.0
|
|
30
|
+
|
|
3
31
|
## 4.1.0-next.0
|
|
4
32
|
|
|
5
33
|
### Minor Changes
|
package/config.schema.json
CHANGED
|
@@ -86,6 +86,10 @@
|
|
|
86
86
|
"description": "Task recovery configuration",
|
|
87
87
|
"visibility": "backend"
|
|
88
88
|
},
|
|
89
|
+
"requireScmUserCredentials": {
|
|
90
|
+
"type": "boolean",
|
|
91
|
+
"description": "Requires supported SCM actions to only operate with credentials explicitly provided by the signed-in user.\n\nDefaults to false."
|
|
92
|
+
},
|
|
89
93
|
"EXPERIMENTAL_gracefulShutdown": {
|
|
90
94
|
"type": "boolean",
|
|
91
95
|
"description": "Tries to wait for tasks to finish during SIGTERM before shutting down the TaskWorker."
|
|
@@ -128,6 +128,9 @@ const scaffolderPlugin = backendPluginApi.createBackendPlugin({
|
|
|
128
128
|
}) {
|
|
129
129
|
const log$1 = loggerToWinstonLogger.loggerToWinstonLogger(logger);
|
|
130
130
|
const integrations = integration.ScmIntegrations.fromConfig(config);
|
|
131
|
+
const requireScmUserCredentials = config.getOptionalBoolean(
|
|
132
|
+
"scaffolder.requireScmUserCredentials"
|
|
133
|
+
);
|
|
131
134
|
const templateExtensions = {
|
|
132
135
|
additionalTemplateFilters: templating.convertFiltersToRecord(
|
|
133
136
|
additionalTemplateFilters
|
|
@@ -142,20 +145,24 @@ const scaffolderPlugin = backendPluginApi.createBackendPlugin({
|
|
|
142
145
|
// built-in actions for the scaffolder
|
|
143
146
|
plain.createFetchPlainAction({
|
|
144
147
|
reader,
|
|
145
|
-
integrations
|
|
148
|
+
integrations,
|
|
149
|
+
requireScmUserCredentials
|
|
146
150
|
}),
|
|
147
151
|
plainFile.createFetchPlainFileAction({
|
|
148
152
|
reader,
|
|
149
|
-
integrations
|
|
153
|
+
integrations,
|
|
154
|
+
requireScmUserCredentials
|
|
150
155
|
}),
|
|
151
156
|
template.createFetchTemplateAction({
|
|
152
157
|
integrations,
|
|
153
158
|
reader,
|
|
159
|
+
requireScmUserCredentials,
|
|
154
160
|
...templateExtensions
|
|
155
161
|
}),
|
|
156
162
|
templateFile.createFetchTemplateFileAction({
|
|
157
163
|
integrations,
|
|
158
164
|
reader,
|
|
165
|
+
requireScmUserCredentials,
|
|
159
166
|
...templateExtensions
|
|
160
167
|
}),
|
|
161
168
|
log.createDebugLogAction(),
|
|
@@ -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 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 scheduler: coreServices.scheduler,\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 scheduler,\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 scheduler,\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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"}
|
|
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 scheduler: coreServices.scheduler,\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 scheduler,\n metrics,\n }) {\n const log = loggerToWinstonLogger(logger);\n const integrations = ScmIntegrations.fromConfig(config);\n const requireScmUserCredentials = config.getOptionalBoolean(\n 'scaffolder.requireScmUserCredentials',\n );\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 requireScmUserCredentials,\n }),\n createFetchPlainFileAction({\n reader,\n integrations,\n requireScmUserCredentials,\n }),\n createFetchTemplateAction({\n integrations,\n reader,\n requireScmUserCredentials,\n ...templateExtensions,\n }),\n createFetchTemplateFileAction({\n integrations,\n reader,\n requireScmUserCredentials,\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 scheduler,\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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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -117,6 +117,7 @@ declare function createWaitAction(options?: {
|
|
|
117
117
|
declare function createFetchPlainAction(options: {
|
|
118
118
|
reader: UrlReaderService;
|
|
119
119
|
integrations: ScmIntegrations;
|
|
120
|
+
requireScmUserCredentials?: boolean;
|
|
120
121
|
}): _backstage_plugin_scaffolder_node.TemplateAction<{
|
|
121
122
|
url: string;
|
|
122
123
|
targetPath?: string | undefined;
|
|
@@ -132,6 +133,7 @@ declare function createFetchPlainAction(options: {
|
|
|
132
133
|
declare function createFetchPlainFileAction(options: {
|
|
133
134
|
reader: UrlReaderService;
|
|
134
135
|
integrations: ScmIntegrations;
|
|
136
|
+
requireScmUserCredentials?: boolean;
|
|
135
137
|
}): _backstage_plugin_scaffolder_node.TemplateAction<{
|
|
136
138
|
url: string;
|
|
137
139
|
targetPath: string;
|
|
@@ -150,6 +152,7 @@ declare function createFetchPlainFileAction(options: {
|
|
|
150
152
|
declare function createFetchTemplateAction(options: {
|
|
151
153
|
reader: UrlReaderService;
|
|
152
154
|
integrations: ScmIntegrations;
|
|
155
|
+
requireScmUserCredentials?: boolean;
|
|
153
156
|
additionalTemplateFilters?: Record<string, TemplateFilter>;
|
|
154
157
|
additionalTemplateGlobals?: Record<string, TemplateGlobal>;
|
|
155
158
|
}): _backstage_plugin_scaffolder_node.TemplateAction<{
|
|
@@ -177,6 +180,7 @@ declare function createFetchTemplateAction(options: {
|
|
|
177
180
|
declare function createFetchTemplateFileAction(options: {
|
|
178
181
|
reader: UrlReaderService;
|
|
179
182
|
integrations: ScmIntegrations;
|
|
183
|
+
requireScmUserCredentials?: boolean;
|
|
180
184
|
additionalTemplateFilters?: Record<string, TemplateFilter>;
|
|
181
185
|
additionalTemplateGlobals?: Record<string, TemplateGlobal>;
|
|
182
186
|
}): _backstage_plugin_scaffolder_node.TemplateAction<{
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var errors = require('@backstage/errors');
|
|
4
|
+
|
|
5
|
+
const USER_TOKEN_SUPPORTED_INTEGRATION_TYPES = /* @__PURE__ */ new Set(["github", "gitlab"]);
|
|
6
|
+
function assertScmUserCredentials(options) {
|
|
7
|
+
const { integrations, requireScmUserCredentials, url, baseUrl, token } = options;
|
|
8
|
+
if (!requireScmUserCredentials || token) {
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
let sourceUrl;
|
|
12
|
+
try {
|
|
13
|
+
sourceUrl = new URL(url);
|
|
14
|
+
} catch {
|
|
15
|
+
if (baseUrl) {
|
|
16
|
+
try {
|
|
17
|
+
sourceUrl = new URL(baseUrl);
|
|
18
|
+
} catch {
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
if (!sourceUrl) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
const integration = integrations.byUrl(sourceUrl);
|
|
26
|
+
if (integration && USER_TOKEN_SUPPORTED_INTEGRATION_TYPES.has(integration.type)) {
|
|
27
|
+
throw new errors.InputError(
|
|
28
|
+
`No user credentials provided for host ${sourceUrl.host}, but scaffolder.requireScmUserCredentials is enabled`
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
exports.assertScmUserCredentials = assertScmUserCredentials;
|
|
34
|
+
//# sourceMappingURL=assertScmUserCredentials.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"assertScmUserCredentials.cjs.js","sources":["../../../../../src/scaffolder/actions/builtin/fetch/assertScmUserCredentials.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 */\n\nimport { InputError } from '@backstage/errors';\nimport { ScmIntegrations } from '@backstage/integration';\n\nconst USER_TOKEN_SUPPORTED_INTEGRATION_TYPES = new Set(['github', 'gitlab']);\n\nexport function assertScmUserCredentials(options: {\n integrations: ScmIntegrations;\n requireScmUserCredentials?: boolean;\n url: string;\n baseUrl?: string;\n token?: string;\n}) {\n const { integrations, requireScmUserCredentials, url, baseUrl, token } =\n options;\n\n if (!requireScmUserCredentials || token) {\n return;\n }\n\n let sourceUrl: URL | undefined;\n try {\n sourceUrl = new URL(url);\n } catch {\n if (baseUrl) {\n try {\n sourceUrl = new URL(baseUrl);\n } catch {\n // Invalid URLs are reported by the fetch helpers.\n }\n }\n }\n\n if (!sourceUrl) {\n return;\n }\n\n const integration = integrations.byUrl(sourceUrl);\n if (\n integration &&\n USER_TOKEN_SUPPORTED_INTEGRATION_TYPES.has(integration.type)\n ) {\n throw new InputError(\n `No user credentials provided for host ${sourceUrl.host}, but scaffolder.requireScmUserCredentials is enabled`,\n );\n }\n}\n"],"names":["InputError"],"mappings":";;;;AAmBA,MAAM,yDAAyC,IAAI,GAAA,CAAI,CAAC,QAAA,EAAU,QAAQ,CAAC,CAAA;AAEpE,SAAS,yBAAyB,OAAA,EAMtC;AACD,EAAA,MAAM,EAAE,YAAA,EAAc,yBAAA,EAA2B,GAAA,EAAK,OAAA,EAAS,OAAM,GACnE,OAAA;AAEF,EAAA,IAAI,CAAC,6BAA6B,KAAA,EAAO;AACvC,IAAA;AAAA,EACF;AAEA,EAAA,IAAI,SAAA;AACJ,EAAA,IAAI;AACF,IAAA,SAAA,GAAY,IAAI,IAAI,GAAG,CAAA;AAAA,EACzB,CAAA,CAAA,MAAQ;AACN,IAAA,IAAI,OAAA,EAAS;AACX,MAAA,IAAI;AACF,QAAA,SAAA,GAAY,IAAI,IAAI,OAAO,CAAA;AAAA,MAC7B,CAAA,CAAA,MAAQ;AAAA,MAER;AAAA,IACF;AAAA,EACF;AAEA,EAAA,IAAI,CAAC,SAAA,EAAW;AACd,IAAA;AAAA,EACF;AAEA,EAAA,MAAM,WAAA,GAAc,YAAA,CAAa,KAAA,CAAM,SAAS,CAAA;AAChD,EAAA,IACE,WAAA,IACA,sCAAA,CAAuC,GAAA,CAAI,WAAA,CAAY,IAAI,CAAA,EAC3D;AACA,IAAA,MAAM,IAAIA,iBAAA;AAAA,MACR,CAAA,sCAAA,EAAyC,UAAU,IAAI,CAAA,qDAAA;AAAA,KACzD;AAAA,EACF;AACF;;;;"}
|
|
@@ -2,11 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
var backendPluginApi = require('@backstage/backend-plugin-api');
|
|
4
4
|
var plain_examples = require('./plain.examples.cjs.js');
|
|
5
|
+
var assertScmUserCredentials = require('./assertScmUserCredentials.cjs.js');
|
|
5
6
|
var pluginScaffolderNode = require('@backstage/plugin-scaffolder-node');
|
|
6
7
|
|
|
7
8
|
const ACTION_ID = "fetch:plain";
|
|
8
9
|
function createFetchPlainAction(options) {
|
|
9
|
-
const { reader, integrations } = options;
|
|
10
|
+
const { reader, integrations, requireScmUserCredentials } = options;
|
|
10
11
|
return pluginScaffolderNode.createTemplateAction({
|
|
11
12
|
id: ACTION_ID,
|
|
12
13
|
examples: plain_examples.examples,
|
|
@@ -29,6 +30,13 @@ function createFetchPlainAction(options) {
|
|
|
29
30
|
ctx.logger.info("Fetching plain content from remote URL");
|
|
30
31
|
const targetPath = ctx.input.targetPath ?? "./";
|
|
31
32
|
const outputPath = backendPluginApi.resolveSafeChildPath(ctx.workspacePath, targetPath);
|
|
33
|
+
assertScmUserCredentials.assertScmUserCredentials({
|
|
34
|
+
integrations,
|
|
35
|
+
requireScmUserCredentials,
|
|
36
|
+
url: ctx.input.url,
|
|
37
|
+
baseUrl: ctx.templateInfo?.baseUrl,
|
|
38
|
+
token: ctx.input.token
|
|
39
|
+
});
|
|
32
40
|
await pluginScaffolderNode.fetchContents({
|
|
33
41
|
reader,
|
|
34
42
|
integrations,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plain.cjs.js","sources":["../../../../../src/scaffolder/actions/builtin/fetch/plain.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 {\n resolveSafeChildPath,\n UrlReaderService,\n} from '@backstage/backend-plugin-api';\nimport { ScmIntegrations } from '@backstage/integration';\nimport { examples } from './plain.examples';\n\nimport {\n createTemplateAction,\n fetchContents,\n} from '@backstage/plugin-scaffolder-node';\n\nexport const ACTION_ID = 'fetch:plain';\n\n/**\n * Downloads content and places it in the workspace, or optionally\n * in a subdirectory specified by the 'targetPath' input option.\n * @public\n */\nexport function createFetchPlainAction(options: {\n reader: UrlReaderService;\n integrations: ScmIntegrations;\n}) {\n const { reader, integrations } = options;\n\n return createTemplateAction({\n id: ACTION_ID,\n examples,\n description:\n 'Downloads content and places it in the workspace, or optionally in a subdirectory specified by the `targetPath` input option.',\n schema: {\n input: {\n url: z =>\n z.string({\n description:\n 'Relative path or absolute URL pointing to the directory tree to fetch',\n }),\n targetPath: z =>\n z\n .string({\n description:\n 'Target path within the working directory to download the contents to.',\n })\n .optional(),\n token: z =>\n z\n .string({\n description:\n 'An optional token to use for authentication when reading the resources.',\n })\n .optional(),\n },\n },\n supportsDryRun: true,\n async handler(ctx) {\n ctx.logger.info('Fetching plain content from remote URL');\n\n // Finally move the template result into the task workspace\n const targetPath = ctx.input.targetPath ?? './';\n const outputPath = resolveSafeChildPath(ctx.workspacePath, targetPath);\n\n await fetchContents({\n reader,\n integrations,\n baseUrl: ctx.templateInfo?.baseUrl,\n fetchUrl: ctx.input.url,\n outputPath,\n token: ctx.input.token,\n });\n },\n });\n}\n"],"names":["createTemplateAction","examples","resolveSafeChildPath","fetchContents"],"mappings":"
|
|
1
|
+
{"version":3,"file":"plain.cjs.js","sources":["../../../../../src/scaffolder/actions/builtin/fetch/plain.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 {\n resolveSafeChildPath,\n UrlReaderService,\n} from '@backstage/backend-plugin-api';\nimport { ScmIntegrations } from '@backstage/integration';\nimport { examples } from './plain.examples';\nimport { assertScmUserCredentials } from './assertScmUserCredentials';\n\nimport {\n createTemplateAction,\n fetchContents,\n} from '@backstage/plugin-scaffolder-node';\n\nexport const ACTION_ID = 'fetch:plain';\n\n/**\n * Downloads content and places it in the workspace, or optionally\n * in a subdirectory specified by the 'targetPath' input option.\n * @public\n */\nexport function createFetchPlainAction(options: {\n reader: UrlReaderService;\n integrations: ScmIntegrations;\n requireScmUserCredentials?: boolean;\n}) {\n const { reader, integrations, requireScmUserCredentials } = options;\n\n return createTemplateAction({\n id: ACTION_ID,\n examples,\n description:\n 'Downloads content and places it in the workspace, or optionally in a subdirectory specified by the `targetPath` input option.',\n schema: {\n input: {\n url: z =>\n z.string({\n description:\n 'Relative path or absolute URL pointing to the directory tree to fetch',\n }),\n targetPath: z =>\n z\n .string({\n description:\n 'Target path within the working directory to download the contents to.',\n })\n .optional(),\n token: z =>\n z\n .string({\n description:\n 'An optional token to use for authentication when reading the resources.',\n })\n .optional(),\n },\n },\n supportsDryRun: true,\n async handler(ctx) {\n ctx.logger.info('Fetching plain content from remote URL');\n\n // Finally move the template result into the task workspace\n const targetPath = ctx.input.targetPath ?? './';\n const outputPath = resolveSafeChildPath(ctx.workspacePath, targetPath);\n\n assertScmUserCredentials({\n integrations,\n requireScmUserCredentials,\n url: ctx.input.url,\n baseUrl: ctx.templateInfo?.baseUrl,\n token: ctx.input.token,\n });\n\n await fetchContents({\n reader,\n integrations,\n baseUrl: ctx.templateInfo?.baseUrl,\n fetchUrl: ctx.input.url,\n outputPath,\n token: ctx.input.token,\n });\n },\n });\n}\n"],"names":["createTemplateAction","examples","resolveSafeChildPath","assertScmUserCredentials","fetchContents"],"mappings":";;;;;;;AA6BO,MAAM,SAAA,GAAY;AAOlB,SAAS,uBAAuB,OAAA,EAIpC;AACD,EAAA,MAAM,EAAE,MAAA,EAAQ,YAAA,EAAc,yBAAA,EAA0B,GAAI,OAAA;AAE5D,EAAA,OAAOA,yCAAA,CAAqB;AAAA,IAC1B,EAAA,EAAI,SAAA;AAAA,cACJC,uBAAA;AAAA,IACA,WAAA,EACE,+HAAA;AAAA,IACF,MAAA,EAAQ;AAAA,MACN,KAAA,EAAO;AAAA,QACL,GAAA,EAAK,CAAA,CAAA,KACH,CAAA,CAAE,MAAA,CAAO;AAAA,UACP,WAAA,EACE;AAAA,SACH,CAAA;AAAA,QACH,UAAA,EAAY,CAAA,CAAA,KACV,CAAA,CACG,MAAA,CAAO;AAAA,UACN,WAAA,EACE;AAAA,SACH,EACA,QAAA,EAAS;AAAA,QACd,KAAA,EAAO,CAAA,CAAA,KACL,CAAA,CACG,MAAA,CAAO;AAAA,UACN,WAAA,EACE;AAAA,SACH,EACA,QAAA;AAAS;AAChB,KACF;AAAA,IACA,cAAA,EAAgB,IAAA;AAAA,IAChB,MAAM,QAAQ,GAAA,EAAK;AACjB,MAAA,GAAA,CAAI,MAAA,CAAO,KAAK,wCAAwC,CAAA;AAGxD,MAAA,MAAM,UAAA,GAAa,GAAA,CAAI,KAAA,CAAM,UAAA,IAAc,IAAA;AAC3C,MAAA,MAAM,UAAA,GAAaC,qCAAA,CAAqB,GAAA,CAAI,aAAA,EAAe,UAAU,CAAA;AAErE,MAAAC,iDAAA,CAAyB;AAAA,QACvB,YAAA;AAAA,QACA,yBAAA;AAAA,QACA,GAAA,EAAK,IAAI,KAAA,CAAM,GAAA;AAAA,QACf,OAAA,EAAS,IAAI,YAAA,EAAc,OAAA;AAAA,QAC3B,KAAA,EAAO,IAAI,KAAA,CAAM;AAAA,OAClB,CAAA;AAED,MAAA,MAAMC,kCAAA,CAAc;AAAA,QAClB,MAAA;AAAA,QACA,YAAA;AAAA,QACA,OAAA,EAAS,IAAI,YAAA,EAAc,OAAA;AAAA,QAC3B,QAAA,EAAU,IAAI,KAAA,CAAM,GAAA;AAAA,QACpB,UAAA;AAAA,QACA,KAAA,EAAO,IAAI,KAAA,CAAM;AAAA,OAClB,CAAA;AAAA,IACH;AAAA,GACD,CAAA;AACH;;;;;"}
|
|
@@ -2,10 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
var backendPluginApi = require('@backstage/backend-plugin-api');
|
|
4
4
|
var plainFile_examples = require('./plainFile.examples.cjs.js');
|
|
5
|
+
var assertScmUserCredentials = require('./assertScmUserCredentials.cjs.js');
|
|
5
6
|
var pluginScaffolderNode = require('@backstage/plugin-scaffolder-node');
|
|
6
7
|
|
|
7
8
|
function createFetchPlainFileAction(options) {
|
|
8
|
-
const { reader, integrations } = options;
|
|
9
|
+
const { reader, integrations, requireScmUserCredentials } = options;
|
|
9
10
|
return pluginScaffolderNode.createTemplateAction({
|
|
10
11
|
id: "fetch:plain:file",
|
|
11
12
|
description: "Downloads single file and places it in the workspace.",
|
|
@@ -30,6 +31,13 @@ function createFetchPlainFileAction(options) {
|
|
|
30
31
|
ctx.workspacePath,
|
|
31
32
|
ctx.input.targetPath
|
|
32
33
|
);
|
|
34
|
+
assertScmUserCredentials.assertScmUserCredentials({
|
|
35
|
+
integrations,
|
|
36
|
+
requireScmUserCredentials,
|
|
37
|
+
url: ctx.input.url,
|
|
38
|
+
baseUrl: ctx.templateInfo?.baseUrl,
|
|
39
|
+
token: ctx.input.token
|
|
40
|
+
});
|
|
33
41
|
await pluginScaffolderNode.fetchFile({
|
|
34
42
|
reader,
|
|
35
43
|
integrations,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plainFile.cjs.js","sources":["../../../../../src/scaffolder/actions/builtin/fetch/plainFile.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 {\n resolveSafeChildPath,\n UrlReaderService,\n} from '@backstage/backend-plugin-api';\nimport { ScmIntegrations } from '@backstage/integration';\nimport { examples } from './plainFile.examples';\n\nimport {\n createTemplateAction,\n fetchFile,\n} from '@backstage/plugin-scaffolder-node';\n\n/**\n * Downloads a single file and places it in the workspace.\n * @public\n */\nexport function createFetchPlainFileAction(options: {\n reader: UrlReaderService;\n integrations: ScmIntegrations;\n}) {\n const { reader, integrations } = options;\n\n return createTemplateAction({\n id: 'fetch:plain:file',\n description: 'Downloads single file and places it in the workspace.',\n examples,\n schema: {\n input: {\n url: z =>\n z.string({\n description:\n 'Relative path or absolute URL pointing to the single file to fetch.',\n }),\n targetPath: z =>\n z.string({\n description:\n 'Target path within the working directory to download the file as.',\n }),\n token: z =>\n z\n .string({\n description:\n 'An optional token to use for authentication when reading the resources.',\n })\n .optional(),\n },\n },\n supportsDryRun: true,\n async handler(ctx) {\n ctx.logger.info('Fetching plain content from remote URL');\n\n // Finally move the template result into the task workspace\n const outputPath = resolveSafeChildPath(\n ctx.workspacePath,\n ctx.input.targetPath,\n );\n\n await fetchFile({\n reader,\n integrations,\n baseUrl: ctx.templateInfo?.baseUrl,\n fetchUrl: ctx.input.url,\n outputPath,\n token: ctx.input.token,\n });\n },\n });\n}\n"],"names":["createTemplateAction","examples","resolveSafeChildPath","fetchFile"],"mappings":"
|
|
1
|
+
{"version":3,"file":"plainFile.cjs.js","sources":["../../../../../src/scaffolder/actions/builtin/fetch/plainFile.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 {\n resolveSafeChildPath,\n UrlReaderService,\n} from '@backstage/backend-plugin-api';\nimport { ScmIntegrations } from '@backstage/integration';\nimport { examples } from './plainFile.examples';\nimport { assertScmUserCredentials } from './assertScmUserCredentials';\n\nimport {\n createTemplateAction,\n fetchFile,\n} from '@backstage/plugin-scaffolder-node';\n\n/**\n * Downloads a single file and places it in the workspace.\n * @public\n */\nexport function createFetchPlainFileAction(options: {\n reader: UrlReaderService;\n integrations: ScmIntegrations;\n requireScmUserCredentials?: boolean;\n}) {\n const { reader, integrations, requireScmUserCredentials } = options;\n\n return createTemplateAction({\n id: 'fetch:plain:file',\n description: 'Downloads single file and places it in the workspace.',\n examples,\n schema: {\n input: {\n url: z =>\n z.string({\n description:\n 'Relative path or absolute URL pointing to the single file to fetch.',\n }),\n targetPath: z =>\n z.string({\n description:\n 'Target path within the working directory to download the file as.',\n }),\n token: z =>\n z\n .string({\n description:\n 'An optional token to use for authentication when reading the resources.',\n })\n .optional(),\n },\n },\n supportsDryRun: true,\n async handler(ctx) {\n ctx.logger.info('Fetching plain content from remote URL');\n\n // Finally move the template result into the task workspace\n const outputPath = resolveSafeChildPath(\n ctx.workspacePath,\n ctx.input.targetPath,\n );\n\n assertScmUserCredentials({\n integrations,\n requireScmUserCredentials,\n url: ctx.input.url,\n baseUrl: ctx.templateInfo?.baseUrl,\n token: ctx.input.token,\n });\n\n await fetchFile({\n reader,\n integrations,\n baseUrl: ctx.templateInfo?.baseUrl,\n fetchUrl: ctx.input.url,\n outputPath,\n token: ctx.input.token,\n });\n },\n });\n}\n"],"names":["createTemplateAction","examples","resolveSafeChildPath","assertScmUserCredentials","fetchFile"],"mappings":";;;;;;;AAiCO,SAAS,2BAA2B,OAAA,EAIxC;AACD,EAAA,MAAM,EAAE,MAAA,EAAQ,YAAA,EAAc,yBAAA,EAA0B,GAAI,OAAA;AAE5D,EAAA,OAAOA,yCAAA,CAAqB;AAAA,IAC1B,EAAA,EAAI,kBAAA;AAAA,IACJ,WAAA,EAAa,uDAAA;AAAA,cACbC,2BAAA;AAAA,IACA,MAAA,EAAQ;AAAA,MACN,KAAA,EAAO;AAAA,QACL,GAAA,EAAK,CAAA,CAAA,KACH,CAAA,CAAE,MAAA,CAAO;AAAA,UACP,WAAA,EACE;AAAA,SACH,CAAA;AAAA,QACH,UAAA,EAAY,CAAA,CAAA,KACV,CAAA,CAAE,MAAA,CAAO;AAAA,UACP,WAAA,EACE;AAAA,SACH,CAAA;AAAA,QACH,KAAA,EAAO,CAAA,CAAA,KACL,CAAA,CACG,MAAA,CAAO;AAAA,UACN,WAAA,EACE;AAAA,SACH,EACA,QAAA;AAAS;AAChB,KACF;AAAA,IACA,cAAA,EAAgB,IAAA;AAAA,IAChB,MAAM,QAAQ,GAAA,EAAK;AACjB,MAAA,GAAA,CAAI,MAAA,CAAO,KAAK,wCAAwC,CAAA;AAGxD,MAAA,MAAM,UAAA,GAAaC,qCAAA;AAAA,QACjB,GAAA,CAAI,aAAA;AAAA,QACJ,IAAI,KAAA,CAAM;AAAA,OACZ;AAEA,MAAAC,iDAAA,CAAyB;AAAA,QACvB,YAAA;AAAA,QACA,yBAAA;AAAA,QACA,GAAA,EAAK,IAAI,KAAA,CAAM,GAAA;AAAA,QACf,OAAA,EAAS,IAAI,YAAA,EAAc,OAAA;AAAA,QAC3B,KAAA,EAAO,IAAI,KAAA,CAAM;AAAA,OAClB,CAAA;AAED,MAAA,MAAMC,8BAAA,CAAU;AAAA,QACd,MAAA;AAAA,QACA,YAAA;AAAA,QACA,OAAA,EAAS,IAAI,YAAA,EAAc,OAAA;AAAA,QAC3B,QAAA,EAAU,IAAI,KAAA,CAAM,GAAA;AAAA,QACpB,UAAA;AAAA,QACA,KAAA,EAAO,IAAI,KAAA,CAAM;AAAA,OAClB,CAAA;AAAA,IACH;AAAA,GACD,CAAA;AACH;;;;"}
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
var backendPluginApi = require('@backstage/backend-plugin-api');
|
|
4
4
|
var pluginScaffolderNode = require('@backstage/plugin-scaffolder-node');
|
|
5
5
|
var template_examples = require('./template.examples.cjs.js');
|
|
6
|
+
var assertScmUserCredentials = require('./assertScmUserCredentials.cjs.js');
|
|
6
7
|
var templateActionHandler = require('./templateActionHandler.cjs.js');
|
|
7
8
|
|
|
8
9
|
function createFetchTemplateAction(options) {
|
|
@@ -53,6 +54,13 @@ function createFetchTemplateAction(options) {
|
|
|
53
54
|
ctx,
|
|
54
55
|
resolveTemplate: async () => {
|
|
55
56
|
ctx.logger.info("Fetching template content from remote URL");
|
|
57
|
+
assertScmUserCredentials.assertScmUserCredentials({
|
|
58
|
+
integrations: options.integrations,
|
|
59
|
+
requireScmUserCredentials: options.requireScmUserCredentials,
|
|
60
|
+
url: ctx.input.url,
|
|
61
|
+
baseUrl: ctx.templateInfo?.baseUrl,
|
|
62
|
+
token: ctx.input.token
|
|
63
|
+
});
|
|
56
64
|
const workDir = await ctx.createTemporaryDirectory();
|
|
57
65
|
const templateDir = backendPluginApi.resolveSafeChildPath(workDir, "template");
|
|
58
66
|
await pluginScaffolderNode.fetchContents({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"template.cjs.js","sources":["../../../../../src/scaffolder/actions/builtin/fetch/template.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 {\n resolveSafeChildPath,\n UrlReaderService,\n} from '@backstage/backend-plugin-api';\nimport { ScmIntegrations } from '@backstage/integration';\nimport {\n createTemplateAction,\n fetchContents,\n TemplateFilter,\n TemplateGlobal,\n} from '@backstage/plugin-scaffolder-node';\nimport { examples } from './template.examples';\nimport {\n collectActionTemplateCapabilities,\n createTemplateActionHandler,\n} from './templateActionHandler';\n\n/**\n * Downloads a skeleton, templates variables into file and directory names and content.\n * Then places the result in the workspace, or optionally in a subdirectory\n * specified by the 'targetPath' input option.\n *\n * @public\n */\nexport function createFetchTemplateAction(options: {\n reader: UrlReaderService;\n integrations: ScmIntegrations;\n additionalTemplateFilters?: Record<string, TemplateFilter>;\n additionalTemplateGlobals?: Record<string, TemplateGlobal>;\n}) {\n const templateCapabilities = collectActionTemplateCapabilities(options);\n\n return createTemplateAction({\n id: 'fetch:template',\n description:\n 'Downloads a skeleton, templates variables into file and directory names and content, and places the result in the workspace, or optionally in a subdirectory specified by the `targetPath` input option.',\n examples,\n schema: {\n input: {\n url: z =>\n z.string({\n description:\n 'Relative path or absolute URL pointing to the directory tree to fetch',\n }),\n targetPath: z =>\n z\n .string({\n description:\n 'Target path within the working directory to download the contents to. Defaults to the working directory root.',\n })\n .optional(),\n values: z =>\n z\n .record(z.any(), {\n description: 'Values to pass on to the templating engine',\n })\n .optional(),\n copyWithoutRender: z =>\n z\n .array(z.string(), {\n description:\n 'An array of glob patterns. Any files or directories which match are copied without being processed as templates.',\n })\n .optional(),\n copyWithoutTemplating: z =>\n z\n .array(z.string(), {\n description:\n 'An array of glob patterns. Contents of matched files or directories are copied without being processed, but paths are subject to rendering.',\n })\n .optional(),\n cookiecutterCompat: z =>\n z\n .boolean({\n description:\n 'Enable features to maximise compatibility with templates built for fetch:cookiecutter',\n })\n .optional(),\n templateFileExtension: z =>\n z\n .union([z.string(), z.boolean()], {\n description:\n 'If set, only files with the given extension will be templated. If set to `true`, the default extension `.njk` is used.',\n })\n .optional(),\n replace: z =>\n z\n .boolean({\n description:\n 'If set, replace files in targetPath instead of skipping existing ones.',\n })\n .optional(),\n trimBlocks: z =>\n z\n .boolean({\n description:\n 'If set, the first newline after a block is removed (block, not variable tag).',\n })\n .optional(),\n lstripBlocks: z =>\n z\n .boolean({\n description:\n 'If set, leading spaces and tabs are stripped from the start of a line to a block.',\n })\n .optional(),\n token: z =>\n z\n .string({\n description:\n 'An optional token to use for authentication when reading the resources.',\n })\n .optional(),\n },\n },\n supportsDryRun: true,\n handler: ctx =>\n createTemplateActionHandler({\n ctx,\n resolveTemplate: async () => {\n ctx.logger.info('Fetching template content from remote URL');\n\n const workDir = await ctx.createTemporaryDirectory();\n const templateDir = resolveSafeChildPath(workDir, 'template');\n\n await fetchContents({\n baseUrl: ctx.templateInfo?.baseUrl,\n fetchUrl: ctx.input.url,\n outputPath: templateDir,\n token: ctx.input.token,\n ...options,\n });\n\n return templateDir;\n },\n ...options,\n templateCapabilities,\n }),\n });\n}\n"],"names":["collectActionTemplateCapabilities","createTemplateAction","examples","createTemplateActionHandler","resolveSafeChildPath","fetchContents"],"mappings":"
|
|
1
|
+
{"version":3,"file":"template.cjs.js","sources":["../../../../../src/scaffolder/actions/builtin/fetch/template.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 {\n resolveSafeChildPath,\n UrlReaderService,\n} from '@backstage/backend-plugin-api';\nimport { ScmIntegrations } from '@backstage/integration';\nimport {\n createTemplateAction,\n fetchContents,\n TemplateFilter,\n TemplateGlobal,\n} from '@backstage/plugin-scaffolder-node';\nimport { examples } from './template.examples';\nimport { assertScmUserCredentials } from './assertScmUserCredentials';\nimport {\n collectActionTemplateCapabilities,\n createTemplateActionHandler,\n} from './templateActionHandler';\n\n/**\n * Downloads a skeleton, templates variables into file and directory names and content.\n * Then places the result in the workspace, or optionally in a subdirectory\n * specified by the 'targetPath' input option.\n *\n * @public\n */\nexport function createFetchTemplateAction(options: {\n reader: UrlReaderService;\n integrations: ScmIntegrations;\n requireScmUserCredentials?: boolean;\n additionalTemplateFilters?: Record<string, TemplateFilter>;\n additionalTemplateGlobals?: Record<string, TemplateGlobal>;\n}) {\n const templateCapabilities = collectActionTemplateCapabilities(options);\n\n return createTemplateAction({\n id: 'fetch:template',\n description:\n 'Downloads a skeleton, templates variables into file and directory names and content, and places the result in the workspace, or optionally in a subdirectory specified by the `targetPath` input option.',\n examples,\n schema: {\n input: {\n url: z =>\n z.string({\n description:\n 'Relative path or absolute URL pointing to the directory tree to fetch',\n }),\n targetPath: z =>\n z\n .string({\n description:\n 'Target path within the working directory to download the contents to. Defaults to the working directory root.',\n })\n .optional(),\n values: z =>\n z\n .record(z.any(), {\n description: 'Values to pass on to the templating engine',\n })\n .optional(),\n copyWithoutRender: z =>\n z\n .array(z.string(), {\n description:\n 'An array of glob patterns. Any files or directories which match are copied without being processed as templates.',\n })\n .optional(),\n copyWithoutTemplating: z =>\n z\n .array(z.string(), {\n description:\n 'An array of glob patterns. Contents of matched files or directories are copied without being processed, but paths are subject to rendering.',\n })\n .optional(),\n cookiecutterCompat: z =>\n z\n .boolean({\n description:\n 'Enable features to maximise compatibility with templates built for fetch:cookiecutter',\n })\n .optional(),\n templateFileExtension: z =>\n z\n .union([z.string(), z.boolean()], {\n description:\n 'If set, only files with the given extension will be templated. If set to `true`, the default extension `.njk` is used.',\n })\n .optional(),\n replace: z =>\n z\n .boolean({\n description:\n 'If set, replace files in targetPath instead of skipping existing ones.',\n })\n .optional(),\n trimBlocks: z =>\n z\n .boolean({\n description:\n 'If set, the first newline after a block is removed (block, not variable tag).',\n })\n .optional(),\n lstripBlocks: z =>\n z\n .boolean({\n description:\n 'If set, leading spaces and tabs are stripped from the start of a line to a block.',\n })\n .optional(),\n token: z =>\n z\n .string({\n description:\n 'An optional token to use for authentication when reading the resources.',\n })\n .optional(),\n },\n },\n supportsDryRun: true,\n handler: ctx =>\n createTemplateActionHandler({\n ctx,\n resolveTemplate: async () => {\n ctx.logger.info('Fetching template content from remote URL');\n\n assertScmUserCredentials({\n integrations: options.integrations,\n requireScmUserCredentials: options.requireScmUserCredentials,\n url: ctx.input.url,\n baseUrl: ctx.templateInfo?.baseUrl,\n token: ctx.input.token,\n });\n\n const workDir = await ctx.createTemporaryDirectory();\n const templateDir = resolveSafeChildPath(workDir, 'template');\n\n await fetchContents({\n baseUrl: ctx.templateInfo?.baseUrl,\n fetchUrl: ctx.input.url,\n outputPath: templateDir,\n token: ctx.input.token,\n ...options,\n });\n\n return templateDir;\n },\n ...options,\n templateCapabilities,\n }),\n });\n}\n"],"names":["collectActionTemplateCapabilities","createTemplateAction","examples","createTemplateActionHandler","assertScmUserCredentials","resolveSafeChildPath","fetchContents"],"mappings":"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"}
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
var pluginScaffolderNode = require('@backstage/plugin-scaffolder-node');
|
|
4
4
|
var path = require('node:path');
|
|
5
5
|
var templateFile_examples = require('./templateFile.examples.cjs.js');
|
|
6
|
+
var assertScmUserCredentials = require('./assertScmUserCredentials.cjs.js');
|
|
6
7
|
var templateFileActionHandler = require('./templateFileActionHandler.cjs.js');
|
|
7
8
|
var templateActionHandler = require('./templateActionHandler.cjs.js');
|
|
8
9
|
|
|
@@ -49,6 +50,13 @@ function createFetchTemplateFileAction(options) {
|
|
|
49
50
|
ctx,
|
|
50
51
|
resolveTemplateFile: async () => {
|
|
51
52
|
ctx.logger.info("Fetching template file content from remote URL");
|
|
53
|
+
assertScmUserCredentials.assertScmUserCredentials({
|
|
54
|
+
integrations: options.integrations,
|
|
55
|
+
requireScmUserCredentials: options.requireScmUserCredentials,
|
|
56
|
+
url: ctx.input.url,
|
|
57
|
+
baseUrl: ctx.templateInfo?.baseUrl,
|
|
58
|
+
token: ctx.input.token
|
|
59
|
+
});
|
|
52
60
|
const workDir = await ctx.createTemporaryDirectory();
|
|
53
61
|
const tmpFilePath = path__default.default.join(workDir, "tmp");
|
|
54
62
|
await pluginScaffolderNode.fetchFile({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"templateFile.cjs.js","sources":["../../../../../src/scaffolder/actions/builtin/fetch/templateFile.ts"],"sourcesContent":["/*\n * Copyright 2024 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 { UrlReaderService } from '@backstage/backend-plugin-api';\nimport { ScmIntegrations } from '@backstage/integration';\nimport {\n createTemplateAction,\n fetchFile,\n TemplateFilter,\n TemplateGlobal,\n} from '@backstage/plugin-scaffolder-node';\nimport path from 'node:path';\nimport { examples } from './templateFile.examples';\nimport { createTemplateFileActionHandler } from './templateFileActionHandler';\nimport { collectActionTemplateCapabilities } from './templateActionHandler';\n\n/**\n * Downloads a single file and templates variables into file.\n * Then places the result in the workspace, or optionally in a subdirectory\n * specified by the 'targetPath' input option.\n * @public\n */\nexport function createFetchTemplateFileAction(options: {\n reader: UrlReaderService;\n integrations: ScmIntegrations;\n additionalTemplateFilters?: Record<string, TemplateFilter>;\n additionalTemplateGlobals?: Record<string, TemplateGlobal>;\n}) {\n const templateCapabilities = collectActionTemplateCapabilities(options);\n\n return createTemplateAction({\n id: 'fetch:template:file',\n description: 'Downloads single file and places it in the workspace.',\n examples,\n schema: {\n input: {\n url: z =>\n z.string({\n description:\n 'Relative path or absolute URL pointing to the single file to fetch.',\n }),\n targetPath: z =>\n z.string({\n description:\n 'Target path within the working directory to download the file as.',\n }),\n values: z =>\n z\n .record(z.any(), {\n description: 'Values to pass on to the templating engine',\n })\n .optional(),\n cookiecutterCompat: z =>\n z\n .boolean({\n description:\n 'Enable features to maximise compatibility with templates built for fetch:cookiecutter',\n })\n .optional(),\n replace: z =>\n z\n .boolean({\n description:\n 'If set, replace file in targetPath instead of overwriting existing one.',\n })\n .optional(),\n trimBlocks: z =>\n z\n .boolean({\n description:\n 'If set, the first newline after a block is removed (block, not variable tag).',\n })\n .optional(),\n lstripBlocks: z =>\n z\n .boolean({\n description:\n 'If set, leading spaces and tabs are stripped from the start of a line to a block.',\n })\n .optional(),\n token: z =>\n z\n .string({\n description:\n 'An optional token to use for authentication when reading the resources.',\n })\n .optional(),\n },\n },\n supportsDryRun: true,\n handler: ctx =>\n createTemplateFileActionHandler({\n ctx,\n resolveTemplateFile: async () => {\n ctx.logger.info('Fetching template file content from remote URL');\n\n const workDir = await ctx.createTemporaryDirectory();\n // Write to a tmp file, render the template, then copy to workspace.\n const tmpFilePath = path.join(workDir, 'tmp');\n\n await fetchFile({\n baseUrl: ctx.templateInfo?.baseUrl,\n fetchUrl: ctx.input.url,\n outputPath: tmpFilePath,\n token: ctx.input.token,\n ...options,\n });\n return tmpFilePath;\n },\n ...options,\n templateCapabilities,\n }),\n });\n}\n"],"names":["collectActionTemplateCapabilities","createTemplateAction","examples","createTemplateFileActionHandler","path","fetchFile"],"mappings":"
|
|
1
|
+
{"version":3,"file":"templateFile.cjs.js","sources":["../../../../../src/scaffolder/actions/builtin/fetch/templateFile.ts"],"sourcesContent":["/*\n * Copyright 2024 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 { UrlReaderService } from '@backstage/backend-plugin-api';\nimport { ScmIntegrations } from '@backstage/integration';\nimport {\n createTemplateAction,\n fetchFile,\n TemplateFilter,\n TemplateGlobal,\n} from '@backstage/plugin-scaffolder-node';\nimport path from 'node:path';\nimport { examples } from './templateFile.examples';\nimport { assertScmUserCredentials } from './assertScmUserCredentials';\nimport { createTemplateFileActionHandler } from './templateFileActionHandler';\nimport { collectActionTemplateCapabilities } from './templateActionHandler';\n\n/**\n * Downloads a single file and templates variables into file.\n * Then places the result in the workspace, or optionally in a subdirectory\n * specified by the 'targetPath' input option.\n * @public\n */\nexport function createFetchTemplateFileAction(options: {\n reader: UrlReaderService;\n integrations: ScmIntegrations;\n requireScmUserCredentials?: boolean;\n additionalTemplateFilters?: Record<string, TemplateFilter>;\n additionalTemplateGlobals?: Record<string, TemplateGlobal>;\n}) {\n const templateCapabilities = collectActionTemplateCapabilities(options);\n\n return createTemplateAction({\n id: 'fetch:template:file',\n description: 'Downloads single file and places it in the workspace.',\n examples,\n schema: {\n input: {\n url: z =>\n z.string({\n description:\n 'Relative path or absolute URL pointing to the single file to fetch.',\n }),\n targetPath: z =>\n z.string({\n description:\n 'Target path within the working directory to download the file as.',\n }),\n values: z =>\n z\n .record(z.any(), {\n description: 'Values to pass on to the templating engine',\n })\n .optional(),\n cookiecutterCompat: z =>\n z\n .boolean({\n description:\n 'Enable features to maximise compatibility with templates built for fetch:cookiecutter',\n })\n .optional(),\n replace: z =>\n z\n .boolean({\n description:\n 'If set, replace file in targetPath instead of overwriting existing one.',\n })\n .optional(),\n trimBlocks: z =>\n z\n .boolean({\n description:\n 'If set, the first newline after a block is removed (block, not variable tag).',\n })\n .optional(),\n lstripBlocks: z =>\n z\n .boolean({\n description:\n 'If set, leading spaces and tabs are stripped from the start of a line to a block.',\n })\n .optional(),\n token: z =>\n z\n .string({\n description:\n 'An optional token to use for authentication when reading the resources.',\n })\n .optional(),\n },\n },\n supportsDryRun: true,\n handler: ctx =>\n createTemplateFileActionHandler({\n ctx,\n resolveTemplateFile: async () => {\n ctx.logger.info('Fetching template file content from remote URL');\n\n assertScmUserCredentials({\n integrations: options.integrations,\n requireScmUserCredentials: options.requireScmUserCredentials,\n url: ctx.input.url,\n baseUrl: ctx.templateInfo?.baseUrl,\n token: ctx.input.token,\n });\n\n const workDir = await ctx.createTemporaryDirectory();\n // Write to a tmp file, render the template, then copy to workspace.\n const tmpFilePath = path.join(workDir, 'tmp');\n\n await fetchFile({\n baseUrl: ctx.templateInfo?.baseUrl,\n fetchUrl: ctx.input.url,\n outputPath: tmpFilePath,\n token: ctx.input.token,\n ...options,\n });\n return tmpFilePath;\n },\n ...options,\n templateCapabilities,\n }),\n });\n}\n"],"names":["collectActionTemplateCapabilities","createTemplateAction","examples","createTemplateFileActionHandler","assertScmUserCredentials","path","fetchFile"],"mappings":";;;;;;;;;;;;;AAoCO,SAAS,8BAA8B,OAAA,EAM3C;AACD,EAAA,MAAM,oBAAA,GAAuBA,wDAAkC,OAAO,CAAA;AAEtE,EAAA,OAAOC,yCAAA,CAAqB;AAAA,IAC1B,EAAA,EAAI,qBAAA;AAAA,IACJ,WAAA,EAAa,uDAAA;AAAA,cACbC,8BAAA;AAAA,IACA,MAAA,EAAQ;AAAA,MACN,KAAA,EAAO;AAAA,QACL,GAAA,EAAK,CAAA,CAAA,KACH,CAAA,CAAE,MAAA,CAAO;AAAA,UACP,WAAA,EACE;AAAA,SACH,CAAA;AAAA,QACH,UAAA,EAAY,CAAA,CAAA,KACV,CAAA,CAAE,MAAA,CAAO;AAAA,UACP,WAAA,EACE;AAAA,SACH,CAAA;AAAA,QACH,QAAQ,CAAA,CAAA,KACN,CAAA,CACG,MAAA,CAAO,CAAA,CAAE,KAAI,EAAG;AAAA,UACf,WAAA,EAAa;AAAA,SACd,EACA,QAAA,EAAS;AAAA,QACd,kBAAA,EAAoB,CAAA,CAAA,KAClB,CAAA,CACG,OAAA,CAAQ;AAAA,UACP,WAAA,EACE;AAAA,SACH,EACA,QAAA,EAAS;AAAA,QACd,OAAA,EAAS,CAAA,CAAA,KACP,CAAA,CACG,OAAA,CAAQ;AAAA,UACP,WAAA,EACE;AAAA,SACH,EACA,QAAA,EAAS;AAAA,QACd,UAAA,EAAY,CAAA,CAAA,KACV,CAAA,CACG,OAAA,CAAQ;AAAA,UACP,WAAA,EACE;AAAA,SACH,EACA,QAAA,EAAS;AAAA,QACd,YAAA,EAAc,CAAA,CAAA,KACZ,CAAA,CACG,OAAA,CAAQ;AAAA,UACP,WAAA,EACE;AAAA,SACH,EACA,QAAA,EAAS;AAAA,QACd,KAAA,EAAO,CAAA,CAAA,KACL,CAAA,CACG,MAAA,CAAO;AAAA,UACN,WAAA,EACE;AAAA,SACH,EACA,QAAA;AAAS;AAChB,KACF;AAAA,IACA,cAAA,EAAgB,IAAA;AAAA,IAChB,OAAA,EAAS,SACPC,yDAAA,CAAgC;AAAA,MAC9B,GAAA;AAAA,MACA,qBAAqB,YAAY;AAC/B,QAAA,GAAA,CAAI,MAAA,CAAO,KAAK,gDAAgD,CAAA;AAEhE,QAAAC,iDAAA,CAAyB;AAAA,UACvB,cAAc,OAAA,CAAQ,YAAA;AAAA,UACtB,2BAA2B,OAAA,CAAQ,yBAAA;AAAA,UACnC,GAAA,EAAK,IAAI,KAAA,CAAM,GAAA;AAAA,UACf,OAAA,EAAS,IAAI,YAAA,EAAc,OAAA;AAAA,UAC3B,KAAA,EAAO,IAAI,KAAA,CAAM;AAAA,SAClB,CAAA;AAED,QAAA,MAAM,OAAA,GAAU,MAAM,GAAA,CAAI,wBAAA,EAAyB;AAEnD,QAAA,MAAM,WAAA,GAAcC,qBAAA,CAAK,IAAA,CAAK,OAAA,EAAS,KAAK,CAAA;AAE5C,QAAA,MAAMC,8BAAA,CAAU;AAAA,UACd,OAAA,EAAS,IAAI,YAAA,EAAc,OAAA;AAAA,UAC3B,QAAA,EAAU,IAAI,KAAA,CAAM,GAAA;AAAA,UACpB,UAAA,EAAY,WAAA;AAAA,UACZ,KAAA,EAAO,IAAI,KAAA,CAAM,KAAA;AAAA,UACjB,GAAG;AAAA,SACJ,CAAA;AACD,QAAA,OAAO,WAAA;AAAA,MACT,CAAA;AAAA,MACA,GAAG,OAAA;AAAA,MACH;AAAA,KACD;AAAA,GACJ,CAAA;AACH;;;;"}
|
|
@@ -487,25 +487,24 @@ class DatabaseTaskStore {
|
|
|
487
487
|
async retryTask(options) {
|
|
488
488
|
const { secrets, taskId } = options;
|
|
489
489
|
await this.db.transaction(async (tx) => {
|
|
490
|
-
const
|
|
491
|
-
{
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
);
|
|
498
|
-
for (const { id, spec } of result) {
|
|
499
|
-
const taskSpec = JSON.parse(spec);
|
|
500
|
-
await tx("task_events").where("task_id", id).andWhere((q) => q.whereIn("event_type", ["cancelled", "completion"])).del();
|
|
501
|
-
await tx("task_events").insert({
|
|
502
|
-
task_id: id,
|
|
503
|
-
event_type: "recovered",
|
|
504
|
-
body: JSON.stringify({
|
|
505
|
-
recoverStrategy: taskSpec.EXPERIMENTAL_recovery?.EXPERIMENTAL_strategy ?? "none"
|
|
506
|
-
})
|
|
507
|
-
});
|
|
490
|
+
const updateCount = await tx("tasks").where("id", taskId).whereIn("status", ["cancelled", "completed", "failed", "skipped"]).update({
|
|
491
|
+
...secrets && { secrets: JSON.stringify(secrets) },
|
|
492
|
+
status: "open",
|
|
493
|
+
last_heartbeat_at: this.db.fn.now()
|
|
494
|
+
});
|
|
495
|
+
if (Number(updateCount) !== 1) {
|
|
496
|
+
throw new errors.ConflictError(`Task with taskId ${taskId} cannot be retried`);
|
|
508
497
|
}
|
|
498
|
+
const [task] = await tx("tasks").where("id", taskId).select("id", "spec");
|
|
499
|
+
const taskSpec = JSON.parse(task.spec);
|
|
500
|
+
await tx("task_events").where("task_id", task.id).andWhere((q) => q.whereIn("event_type", ["cancelled", "completion"])).del();
|
|
501
|
+
await tx("task_events").insert({
|
|
502
|
+
task_id: task.id,
|
|
503
|
+
event_type: "recovered",
|
|
504
|
+
body: JSON.stringify({
|
|
505
|
+
recoverStrategy: taskSpec.EXPERIMENTAL_recovery?.EXPERIMENTAL_strategy ?? "none"
|
|
506
|
+
})
|
|
507
|
+
});
|
|
509
508
|
});
|
|
510
509
|
}
|
|
511
510
|
async recoverTasks(options) {
|