@backstage/plugin-scaffolder-backend 3.0.0 → 3.0.1-next.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,37 @@
1
1
  # @backstage/plugin-scaffolder-backend
2
2
 
3
+ ## 3.0.1-next.0
4
+
5
+ ### Patch Changes
6
+
7
+ - 05f60e1: Refactored constructor parameter properties to explicit property declarations for compatibility with TypeScript's `erasableSyntaxOnly` setting. This internal refactoring maintains all existing functionality while ensuring TypeScript compilation compatibility.
8
+ - Updated dependencies
9
+ - @backstage/backend-defaults@0.13.1-next.0
10
+ - @backstage/plugin-events-node@0.4.17-next.0
11
+ - @backstage/plugin-bitbucket-cloud-common@0.3.4-next.0
12
+ - @backstage/plugin-auth-node@0.6.9-next.0
13
+ - @backstage/config@1.3.6-next.0
14
+ - @backstage/catalog-model@1.7.6-next.0
15
+ - @backstage/integration@1.18.2-next.0
16
+ - @backstage/plugin-scaffolder-node@0.12.1-next.0
17
+ - @backstage/plugin-permission-node@0.10.6-next.0
18
+ - @backstage/backend-openapi-utils@0.6.3-next.0
19
+ - @backstage/backend-plugin-api@1.4.5-next.0
20
+ - @backstage/errors@1.2.7
21
+ - @backstage/types@1.2.2
22
+ - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.14-next.0
23
+ - @backstage/plugin-catalog-node@1.19.2-next.0
24
+ - @backstage/plugin-permission-common@0.9.3-next.0
25
+ - @backstage/plugin-scaffolder-backend-module-azure@0.2.15-next.0
26
+ - @backstage/plugin-scaffolder-backend-module-bitbucket@0.3.16-next.0
27
+ - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.15-next.0
28
+ - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.15-next.0
29
+ - @backstage/plugin-scaffolder-backend-module-gerrit@0.2.15-next.0
30
+ - @backstage/plugin-scaffolder-backend-module-gitea@0.2.15-next.0
31
+ - @backstage/plugin-scaffolder-backend-module-github@0.9.2-next.0
32
+ - @backstage/plugin-scaffolder-backend-module-gitlab@0.9.7-next.0
33
+ - @backstage/plugin-scaffolder-common@1.7.3-next.0
34
+
3
35
  ## 3.0.0
4
36
 
5
37
  ### Major Changes
@@ -1,13 +1,14 @@
1
1
  'use strict';
2
2
 
3
3
  class DecoratedActionsRegistry {
4
+ innerActions = /* @__PURE__ */ new Map();
5
+ innerRegistry;
4
6
  constructor(innerRegistry, extraActions) {
5
7
  this.innerRegistry = innerRegistry;
6
8
  for (const action of extraActions) {
7
9
  this.innerActions.set(action.id, action);
8
10
  }
9
11
  }
10
- innerActions = /* @__PURE__ */ new Map();
11
12
  async get(actionId, options) {
12
13
  try {
13
14
  return await this.innerRegistry.get(actionId, options);
@@ -1 +1 @@
1
- {"version":3,"file":"DecoratedActionsRegistry.cjs.js","sources":["../../../src/scaffolder/dryrun/DecoratedActionsRegistry.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 { TemplateAction } from '@backstage/plugin-scaffolder-node';\nimport { TemplateActionRegistry } from '../actions';\nimport { BackstageCredentials } from '@backstage/backend-plugin-api';\n\n/** @internal */\nexport class DecoratedActionsRegistry implements TemplateActionRegistry {\n private readonly innerActions: Map<string, TemplateAction> = new Map();\n\n constructor(\n private readonly innerRegistry: TemplateActionRegistry,\n extraActions: Array<TemplateAction>,\n ) {\n for (const action of extraActions) {\n this.innerActions.set(action.id, action);\n }\n }\n\n async get(\n actionId: string,\n options: { credentials: BackstageCredentials },\n ): Promise<TemplateAction> {\n try {\n return await this.innerRegistry.get(actionId, options);\n } catch (e) {\n if (!this.innerActions.has(actionId)) {\n throw e;\n }\n return this.innerActions.get(actionId)!;\n }\n }\n\n async list(options: {\n credentials: BackstageCredentials;\n }): Promise<Map<string, TemplateAction<any, any, any>>> {\n const inner = await this.innerRegistry.list(options);\n return new Map<string, TemplateAction<any, any, any>>([\n ...inner,\n ...this.innerActions,\n ]);\n }\n\n register(action: TemplateAction<any, any, any>): void {\n this.innerRegistry.register(action);\n }\n}\n"],"names":[],"mappings":";;AAqBO,MAAM,wBAAA,CAA2D;AAAA,EAGtE,WAAA,CACmB,eACjB,YAAA,EACA;AAFiB,IAAA,IAAA,CAAA,aAAA,GAAA,aAAA;AAGjB,IAAA,KAAA,MAAW,UAAU,YAAA,EAAc;AACjC,MAAA,IAAA,CAAK,YAAA,CAAa,GAAA,CAAI,MAAA,CAAO,EAAA,EAAI,MAAM,CAAA;AAAA,IACzC;AAAA,EACF;AAAA,EATiB,YAAA,uBAAgD,GAAA,EAAI;AAAA,EAWrE,MAAM,GAAA,CACJ,QAAA,EACA,OAAA,EACyB;AACzB,IAAA,IAAI;AACF,MAAA,OAAO,MAAM,IAAA,CAAK,aAAA,CAAc,GAAA,CAAI,UAAU,OAAO,CAAA;AAAA,IACvD,SAAS,CAAA,EAAG;AACV,MAAA,IAAI,CAAC,IAAA,CAAK,YAAA,CAAa,GAAA,CAAI,QAAQ,CAAA,EAAG;AACpC,QAAA,MAAM,CAAA;AAAA,MACR;AACA,MAAA,OAAO,IAAA,CAAK,YAAA,CAAa,GAAA,CAAI,QAAQ,CAAA;AAAA,IACvC;AAAA,EACF;AAAA,EAEA,MAAM,KAAK,OAAA,EAE6C;AACtD,IAAA,MAAM,KAAA,GAAQ,MAAM,IAAA,CAAK,aAAA,CAAc,KAAK,OAAO,CAAA;AACnD,IAAA,OAAO,IAAI,GAAA,CAA2C;AAAA,MACpD,GAAG,KAAA;AAAA,MACH,GAAG,IAAA,CAAK;AAAA,KACT,CAAA;AAAA,EACH;AAAA,EAEA,SAAS,MAAA,EAA6C;AACpD,IAAA,IAAA,CAAK,aAAA,CAAc,SAAS,MAAM,CAAA;AAAA,EACpC;AACF;;;;"}
1
+ {"version":3,"file":"DecoratedActionsRegistry.cjs.js","sources":["../../../src/scaffolder/dryrun/DecoratedActionsRegistry.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 { TemplateAction } from '@backstage/plugin-scaffolder-node';\nimport { TemplateActionRegistry } from '../actions';\nimport { BackstageCredentials } from '@backstage/backend-plugin-api';\n\n/** @internal */\nexport class DecoratedActionsRegistry implements TemplateActionRegistry {\n private readonly innerActions: Map<string, TemplateAction> = new Map();\n private readonly innerRegistry: TemplateActionRegistry;\n\n constructor(\n innerRegistry: TemplateActionRegistry,\n extraActions: Array<TemplateAction>,\n ) {\n this.innerRegistry = innerRegistry;\n for (const action of extraActions) {\n this.innerActions.set(action.id, action);\n }\n }\n\n async get(\n actionId: string,\n options: { credentials: BackstageCredentials },\n ): Promise<TemplateAction> {\n try {\n return await this.innerRegistry.get(actionId, options);\n } catch (e) {\n if (!this.innerActions.has(actionId)) {\n throw e;\n }\n return this.innerActions.get(actionId)!;\n }\n }\n\n async list(options: {\n credentials: BackstageCredentials;\n }): Promise<Map<string, TemplateAction<any, any, any>>> {\n const inner = await this.innerRegistry.list(options);\n return new Map<string, TemplateAction<any, any, any>>([\n ...inner,\n ...this.innerActions,\n ]);\n }\n\n register(action: TemplateAction<any, any, any>): void {\n this.innerRegistry.register(action);\n }\n}\n"],"names":[],"mappings":";;AAqBO,MAAM,wBAAA,CAA2D;AAAA,EACrD,YAAA,uBAAgD,GAAA,EAAI;AAAA,EACpD,aAAA;AAAA,EAEjB,WAAA,CACE,eACA,YAAA,EACA;AACA,IAAA,IAAA,CAAK,aAAA,GAAgB,aAAA;AACrB,IAAA,KAAA,MAAW,UAAU,YAAA,EAAc;AACjC,MAAA,IAAA,CAAK,YAAA,CAAa,GAAA,CAAI,MAAA,CAAO,EAAA,EAAI,MAAM,CAAA;AAAA,IACzC;AAAA,EACF;AAAA,EAEA,MAAM,GAAA,CACJ,QAAA,EACA,OAAA,EACyB;AACzB,IAAA,IAAI;AACF,MAAA,OAAO,MAAM,IAAA,CAAK,aAAA,CAAc,GAAA,CAAI,UAAU,OAAO,CAAA;AAAA,IACvD,SAAS,CAAA,EAAG;AACV,MAAA,IAAI,CAAC,IAAA,CAAK,YAAA,CAAa,GAAA,CAAI,QAAQ,CAAA,EAAG;AACpC,QAAA,MAAM,CAAA;AAAA,MACR;AACA,MAAA,OAAO,IAAA,CAAK,YAAA,CAAa,GAAA,CAAI,QAAQ,CAAA;AAAA,IACvC;AAAA,EACF;AAAA,EAEA,MAAM,KAAK,OAAA,EAE6C;AACtD,IAAA,MAAM,KAAA,GAAQ,MAAM,IAAA,CAAK,aAAA,CAAc,KAAK,OAAO,CAAA;AACnD,IAAA,OAAO,IAAI,GAAA,CAA2C;AAAA,MACpD,GAAG,KAAA;AAAA,MACH,GAAG,IAAA,CAAK;AAAA,KACT,CAAA;AAAA,EACH;AAAA,EAEA,SAAS,MAAA,EAA6C;AACpD,IAAA,IAAA,CAAK,aAAA,CAAc,SAAS,MAAM,CAAA;AAAA,EACpC;AACF;;;;"}
@@ -1,12 +1,13 @@
1
1
  'use strict';
2
2
 
3
3
  class DatabaseWorkspaceProvider {
4
- constructor(storage) {
5
- this.storage = storage;
6
- }
4
+ storage;
7
5
  static create(storage) {
8
6
  return new DatabaseWorkspaceProvider(storage);
9
7
  }
8
+ constructor(storage) {
9
+ this.storage = storage;
10
+ }
10
11
  async serializeWorkspace(options) {
11
12
  await this.storage.serializeWorkspace?.(options);
12
13
  }
@@ -1 +1 @@
1
- {"version":3,"file":"DatabaseWorkspaceProvider.cjs.js","sources":["../../../src/scaffolder/tasks/DatabaseWorkspaceProvider.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 { TaskStore } from './types';\n\nimport { WorkspaceProvider } from '@backstage/plugin-scaffolder-node/alpha';\n\nexport class DatabaseWorkspaceProvider implements WorkspaceProvider {\n static create(storage: TaskStore) {\n return new DatabaseWorkspaceProvider(storage);\n }\n\n private constructor(private readonly storage: TaskStore) {}\n\n public async serializeWorkspace(options: {\n path: string;\n taskId: string;\n }): Promise<void> {\n await this.storage.serializeWorkspace?.(options);\n }\n\n public async rehydrateWorkspace(options: {\n taskId: string;\n targetPath: string;\n }): Promise<void> {\n return this.storage.rehydrateWorkspace?.(options);\n }\n\n public async cleanWorkspace(options: { taskId: string }): Promise<void> {\n return this.storage.cleanWorkspace?.(options);\n }\n}\n"],"names":[],"mappings":";;AAoBO,MAAM,yBAAA,CAAuD;AAAA,EAK1D,YAA6B,OAAA,EAAoB;AAApB,IAAA,IAAA,CAAA,OAAA,GAAA,OAAA;AAAA,EAAqB;AAAA,EAJ1D,OAAO,OAAO,OAAA,EAAoB;AAChC,IAAA,OAAO,IAAI,0BAA0B,OAAO,CAAA;AAAA,EAC9C;AAAA,EAIA,MAAa,mBAAmB,OAAA,EAGd;AAChB,IAAA,MAAM,IAAA,CAAK,OAAA,CAAQ,kBAAA,GAAqB,OAAO,CAAA;AAAA,EACjD;AAAA,EAEA,MAAa,mBAAmB,OAAA,EAGd;AAChB,IAAA,OAAO,IAAA,CAAK,OAAA,CAAQ,kBAAA,GAAqB,OAAO,CAAA;AAAA,EAClD;AAAA,EAEA,MAAa,eAAe,OAAA,EAA4C;AACtE,IAAA,OAAO,IAAA,CAAK,OAAA,CAAQ,cAAA,GAAiB,OAAO,CAAA;AAAA,EAC9C;AACF;;;;"}
1
+ {"version":3,"file":"DatabaseWorkspaceProvider.cjs.js","sources":["../../../src/scaffolder/tasks/DatabaseWorkspaceProvider.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 { TaskStore } from './types';\n\nimport { WorkspaceProvider } from '@backstage/plugin-scaffolder-node/alpha';\n\nexport class DatabaseWorkspaceProvider implements WorkspaceProvider {\n private readonly storage: TaskStore;\n\n static create(storage: TaskStore) {\n return new DatabaseWorkspaceProvider(storage);\n }\n\n private constructor(storage: TaskStore) {\n this.storage = storage;\n }\n\n public async serializeWorkspace(options: {\n path: string;\n taskId: string;\n }): Promise<void> {\n await this.storage.serializeWorkspace?.(options);\n }\n\n public async rehydrateWorkspace(options: {\n taskId: string;\n targetPath: string;\n }): Promise<void> {\n return this.storage.rehydrateWorkspace?.(options);\n }\n\n public async cleanWorkspace(options: { taskId: string }): Promise<void> {\n return this.storage.cleanWorkspace?.(options);\n }\n}\n"],"names":[],"mappings":";;AAoBO,MAAM,yBAAA,CAAuD;AAAA,EACjD,OAAA;AAAA,EAEjB,OAAO,OAAO,OAAA,EAAoB;AAChC,IAAA,OAAO,IAAI,0BAA0B,OAAO,CAAA;AAAA,EAC9C;AAAA,EAEQ,YAAY,OAAA,EAAoB;AACtC,IAAA,IAAA,CAAK,OAAA,GAAU,OAAA;AAAA,EACjB;AAAA,EAEA,MAAa,mBAAmB,OAAA,EAGd;AAChB,IAAA,MAAM,IAAA,CAAK,OAAA,CAAQ,kBAAA,GAAqB,OAAO,CAAA;AAAA,EACjD;AAAA,EAEA,MAAa,mBAAmB,OAAA,EAGd;AAChB,IAAA,OAAO,IAAA,CAAK,OAAA,CAAQ,kBAAA,GAAqB,OAAO,CAAA;AAAA,EAClD;AAAA,EAEA,MAAa,eAAe,OAAA,EAA4C;AACtE,IAAA,OAAO,IAAA,CAAK,OAAA,CAAQ,cAAA,GAAiB,OAAO,CAAA;AAAA,EAC9C;AACF;;;;"}
@@ -66,6 +66,8 @@ const isActionAuthorized = pluginPermissionNode.createConditionAuthorizer(
66
66
  Object.values(rules.scaffolderActionRules)
67
67
  );
68
68
  class NunjucksWorkflowRunner {
69
+ defaultTemplateFilters;
70
+ options;
69
71
  constructor(options) {
70
72
  this.options = options;
71
73
  this.defaultTemplateFilters = templating.convertFiltersToRecord(
@@ -74,7 +76,6 @@ class NunjucksWorkflowRunner {
74
76
  })
75
77
  );
76
78
  }
77
- defaultTemplateFilters;
78
79
  tracker = scaffoldingTracker();
79
80
  isSingleTemplateString(input) {
80
81
  const { parser, nodes } = nunjucks__default.default;
@@ -1 +1 @@
1
- {"version":3,"file":"NunjucksWorkflowRunner.cjs.js","sources":["../../../src/scaffolder/tasks/NunjucksWorkflowRunner.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 { InputError, NotAllowedError, stringifyError } from '@backstage/errors';\nimport { ScmIntegrations } from '@backstage/integration';\nimport {\n TaskRecovery,\n TaskSpec,\n TaskSpecV1beta3,\n TaskStep,\n} from '@backstage/plugin-scaffolder-common';\nimport { JsonArray, JsonObject, JsonValue } from '@backstage/types';\nimport { metrics } from '@opentelemetry/api';\nimport fs from 'fs-extra';\nimport { validate as validateJsonSchema } from 'jsonschema';\nimport nunjucks from 'nunjucks';\nimport path from 'path';\nimport * as winston from 'winston';\nimport {\n SecureTemplater,\n SecureTemplateRenderer,\n} from '../../lib/templating/SecureTemplater';\nimport { TemplateActionRegistry } from '../actions/TemplateActionRegistry';\nimport { generateExampleOutput, isTruthy } from './helper';\nimport { TaskTrackType, WorkflowResponse, WorkflowRunner } from './types';\n\nimport type {\n AuditorService,\n LoggerService,\n PermissionsService,\n} from '@backstage/backend-plugin-api';\nimport { UserEntity } from '@backstage/catalog-model';\nimport {\n AuthorizeResult,\n PolicyDecision,\n} from '@backstage/plugin-permission-common';\nimport { createConditionAuthorizer } from '@backstage/plugin-permission-node';\nimport { actionExecutePermission } from '@backstage/plugin-scaffolder-common/alpha';\nimport {\n TaskContext,\n TemplateAction,\n TemplateFilter,\n TemplateGlobal,\n} from '@backstage/plugin-scaffolder-node';\nimport { createDefaultFilters } from '../../lib/templating/filters/createDefaultFilters';\nimport { scaffolderActionRules } from '../../service/rules';\nimport { createCounterMetric, createHistogramMetric } from '../../util/metrics';\nimport { BackstageLoggerTransport, WinstonLogger } from './logger';\nimport { convertFiltersToRecord } from '../../util/templating';\nimport {\n CheckpointContext,\n CheckpointState,\n} from '@backstage/plugin-scaffolder-node/alpha';\n\ntype NunjucksWorkflowRunnerOptions = {\n workingDirectory: string;\n actionRegistry: TemplateActionRegistry;\n integrations: ScmIntegrations;\n logger: LoggerService;\n auditor?: AuditorService;\n additionalTemplateFilters?: Record<string, TemplateFilter>;\n additionalTemplateGlobals?: Record<string, TemplateGlobal>;\n permissions?: PermissionsService;\n};\n\ntype TemplateContext = {\n parameters: JsonObject;\n EXPERIMENTAL_recovery?: TaskRecovery;\n steps: {\n [stepName: string]: { output: { [outputName: string]: JsonValue } };\n };\n secrets?: Record<string, string>;\n user?: {\n entity?: UserEntity;\n ref?: string;\n };\n each?: JsonValue;\n context: {\n task: {\n id: string;\n };\n };\n};\n\nconst isValidTaskSpec = (taskSpec: TaskSpec): taskSpec is TaskSpecV1beta3 => {\n return taskSpec.apiVersion === 'scaffolder.backstage.io/v1beta3';\n};\n\nconst createStepLogger = ({\n task,\n step,\n rootLogger,\n}: {\n task: TaskContext;\n step: TaskStep;\n rootLogger: LoggerService;\n}) => {\n const taskLogger = WinstonLogger.create({\n level: process.env.LOG_LEVEL || 'info',\n format: winston.format.combine(\n winston.format.colorize(),\n winston.format.simple(),\n ),\n transports: [new BackstageLoggerTransport(rootLogger, task, step.id)],\n });\n\n taskLogger.addRedactions(Object.values(task.secrets ?? {}));\n\n return { taskLogger };\n};\n\nconst isActionAuthorized = createConditionAuthorizer(\n Object.values(scaffolderActionRules),\n);\n\nexport class NunjucksWorkflowRunner implements WorkflowRunner {\n private readonly defaultTemplateFilters: Record<string, TemplateFilter>;\n\n constructor(private readonly options: NunjucksWorkflowRunnerOptions) {\n this.defaultTemplateFilters = convertFiltersToRecord(\n createDefaultFilters({\n integrations: this.options.integrations,\n }),\n );\n }\n\n private readonly tracker = scaffoldingTracker();\n\n private isSingleTemplateString(input: string) {\n const { parser, nodes } = nunjucks as unknown as {\n parser: {\n parse(\n template: string,\n ctx: object,\n options: nunjucks.ConfigureOptions,\n ): { children: { children?: unknown[] }[] };\n };\n nodes: { TemplateData: Function };\n };\n\n const parsed = parser.parse(\n input,\n {},\n {\n autoescape: false,\n tags: {\n variableStart: '${{',\n variableEnd: '}}',\n },\n },\n );\n\n return (\n parsed.children.length === 1 &&\n !(parsed.children[0]?.children?.[0] instanceof nodes.TemplateData)\n );\n }\n\n private render<T>(\n input: T,\n context: TemplateContext,\n renderTemplate: SecureTemplateRenderer,\n ): T {\n return JSON.parse(JSON.stringify(input), (_key, value) => {\n try {\n if (typeof value === 'string') {\n try {\n if (this.isSingleTemplateString(value)) {\n // Lets convert ${{ parameters.bob }} to ${{ (parameters.bob) | dump }} so we can keep the input type\n const wrappedDumped = value.replace(\n /\\${{(.+)}}/g,\n '${{ ( $1 ) | dump }}',\n );\n\n // Run the templating\n const templated = renderTemplate(wrappedDumped, context);\n\n // If there's an empty string returned, then it's undefined\n if (templated === '') {\n return undefined;\n }\n\n // Reparse the dumped string\n return JSON.parse(templated);\n }\n } catch (ex) {\n this.options.logger.error(\n `Failed to parse template string: ${value} with error ${ex.message}`,\n );\n }\n\n // Fallback to default behaviour\n const templated = renderTemplate(value, context);\n\n if (templated === '') {\n return undefined;\n }\n\n return templated;\n }\n } catch {\n return value;\n }\n return value;\n });\n }\n\n async executeStep(\n task: TaskContext,\n step: TaskStep,\n context: TemplateContext,\n renderTemplate: (template: string, values: unknown) => string,\n taskTrack: TaskTrackType,\n workspacePath: string,\n decision: PolicyDecision,\n ) {\n const stepTrack = await this.tracker.stepStart(task, step);\n\n if (task.cancelSignal.aborted) {\n throw new Error(\n `Step ${step.id} (${step.name}) of task ${task.taskId} has been cancelled.`,\n );\n }\n\n try {\n if (\n step.if === false ||\n (typeof step.if === 'string' &&\n !isTruthy(this.render(step.if, context, renderTemplate)))\n ) {\n await stepTrack.skipFalsy();\n return;\n }\n const action: TemplateAction<JsonObject> =\n await this.options.actionRegistry.get(step.action, {\n credentials: await task.getInitiatorCredentials(),\n });\n const { taskLogger } = createStepLogger({\n task,\n step,\n rootLogger: this.options.logger,\n });\n\n if (task.isDryRun) {\n const redactedSecrets = Object.fromEntries(\n Object.entries(task.secrets ?? {}).map(secret => [secret[0], '***']),\n );\n const debugInput =\n (step.input &&\n this.render(\n step.input,\n {\n ...context,\n secrets: redactedSecrets,\n },\n renderTemplate,\n )) ??\n {};\n taskLogger.info(\n `Running ${\n action.id\n } in dry-run mode with inputs (secrets redacted): ${JSON.stringify(\n debugInput,\n undefined,\n 2,\n )}`,\n );\n if (!action.supportsDryRun) {\n await taskTrack.skipDryRun(step, action);\n const outputSchema = action.schema?.output;\n if (outputSchema) {\n context.steps[step.id] = {\n output: generateExampleOutput(outputSchema) as {\n [name in string]: JsonValue;\n },\n };\n } else {\n context.steps[step.id] = { output: {} };\n }\n return;\n }\n }\n\n const resolvedEach =\n step.each &&\n this.render(\n step.each,\n { ...context, secrets: task.secrets ?? {} },\n renderTemplate,\n );\n\n if (step.each && !resolvedEach) {\n throw new InputError(\n `Invalid value on action ${action.id}.each parameter, \"${step.each}\" cannot be resolved to a value`,\n );\n }\n\n const iterations = (\n resolvedEach\n ? Object.entries(resolvedEach).map(([key, value]) => ({\n each: { key, value },\n }))\n : [{}]\n ).map(i => ({\n ...i,\n // Secrets are only passed when templating the input to actions for security reasons\n input: step.input\n ? this.render(\n step.input,\n { ...context, secrets: task.secrets ?? {}, ...i },\n renderTemplate,\n )\n : {},\n }));\n for (const iteration of iterations) {\n const actionId = `${action.id}${\n iteration.each ? `[${iteration.each.key}]` : ''\n }`;\n\n if (action.schema?.input) {\n const validateResult = validateJsonSchema(\n iteration.input,\n action.schema.input,\n );\n if (!validateResult.valid) {\n const errors = validateResult.errors.join(', ');\n throw new InputError(\n `Invalid input passed to action ${actionId}, ${errors}`,\n );\n }\n }\n if (\n !isActionAuthorized(decision, {\n action: action.id,\n input: iteration.input,\n })\n ) {\n throw new NotAllowedError(\n `Unauthorized action: ${actionId}. The action is not allowed. Input: ${JSON.stringify(\n iteration.input,\n null,\n 2,\n )}`,\n );\n }\n }\n const tmpDirs = new Array<string>();\n const stepOutput: { [outputName: string]: JsonValue } = {};\n const prevTaskState = await task.getTaskState?.();\n\n for (const iteration of iterations) {\n if (iteration.each) {\n taskLogger.info(\n `Running step each: ${JSON.stringify(\n iteration.each,\n (k, v) => (k ? v.toString() : v),\n 0,\n )}`,\n );\n }\n\n await action.handler({\n input: iteration.input,\n task: {\n id: await task.getWorkspaceName(),\n },\n secrets: task.secrets ?? {},\n logger: taskLogger,\n workspacePath,\n async checkpoint<T extends JsonValue | void>(\n opts: CheckpointContext<T>,\n ) {\n const { key: checkpointKey, fn } = opts;\n const key = `v1.task.checkpoint.${step.id}.${checkpointKey}`;\n\n try {\n let prevValue: T | undefined;\n\n if (prevTaskState) {\n const prevState = (\n prevTaskState.state?.checkpoints as CheckpointState\n )?.[key];\n\n if (prevState && prevState.status === 'success') {\n prevValue = prevState.value as T;\n }\n }\n\n const value = prevValue ? prevValue : await fn();\n\n if (!prevValue) {\n task.updateCheckpoint?.({\n key,\n status: 'success',\n value: value ?? {},\n });\n }\n return value;\n } catch (err) {\n task.updateCheckpoint?.({\n key,\n status: 'failed',\n reason: stringifyError(err),\n });\n throw err;\n } finally {\n await task.serializeWorkspace?.({ path: workspacePath });\n }\n },\n createTemporaryDirectory: async () => {\n const tmpDir = await fs.mkdtemp(\n `${workspacePath}_step-${step.id}-`,\n );\n tmpDirs.push(tmpDir);\n return tmpDir;\n },\n output(name: string, value: JsonValue) {\n if (step.each) {\n stepOutput[name] = stepOutput[name] || [];\n (stepOutput[name] as JsonArray).push(value);\n } else {\n stepOutput[name] = value;\n }\n },\n templateInfo: task.spec.templateInfo,\n user: task.spec.user,\n isDryRun: task.isDryRun,\n signal: task.cancelSignal,\n getInitiatorCredentials: () => task.getInitiatorCredentials(),\n step: {\n id: step.id,\n name: step.name,\n },\n });\n }\n\n // Remove all temporary directories that were created when executing the action\n for (const tmpDir of tmpDirs) {\n await fs.remove(tmpDir);\n }\n\n context.steps[step.id] = { output: stepOutput };\n\n if (task.cancelSignal.aborted) {\n throw new Error(\n `Step ${step.id} (${step.name}) of task ${task.taskId} has been cancelled.`,\n );\n }\n\n await stepTrack.markSuccessful();\n } catch (err) {\n await taskTrack.markFailed(step, err);\n await stepTrack.markFailed();\n throw err;\n } finally {\n await task.serializeWorkspace?.({ path: workspacePath });\n }\n }\n\n async execute(task: TaskContext): Promise<WorkflowResponse> {\n if (!isValidTaskSpec(task.spec)) {\n throw new InputError(\n 'Wrong template version executed with the workflow engine',\n );\n }\n const taskId = await task.getWorkspaceName();\n\n const workspacePath = path.join(this.options.workingDirectory, taskId);\n\n const { additionalTemplateFilters, additionalTemplateGlobals } =\n this.options;\n\n const renderTemplate = await SecureTemplater.loadRenderer({\n templateFilters: {\n ...this.defaultTemplateFilters,\n ...additionalTemplateFilters,\n },\n templateGlobals: additionalTemplateGlobals,\n });\n\n try {\n await task.rehydrateWorkspace?.({ taskId, targetPath: workspacePath });\n\n const taskTrack = await this.tracker.taskStart(task);\n await fs.ensureDir(workspacePath);\n\n const context: TemplateContext = {\n parameters: task.spec.parameters,\n steps: {},\n user: task.spec.user,\n context: {\n task: {\n id: taskId,\n },\n },\n };\n\n const [decision]: PolicyDecision[] =\n this.options.permissions && task.spec.steps.length\n ? await this.options.permissions.authorizeConditional(\n [{ permission: actionExecutePermission }],\n { credentials: await task.getInitiatorCredentials() },\n )\n : [{ result: AuthorizeResult.ALLOW }];\n\n for (const step of task.spec.steps) {\n await this.executeStep(\n task,\n step,\n context,\n renderTemplate,\n taskTrack,\n workspacePath,\n decision,\n );\n }\n\n const output = this.render(task.spec.output, context, renderTemplate);\n await taskTrack.markSuccessful();\n await task.cleanWorkspace?.();\n\n return { output };\n } finally {\n if (workspacePath) {\n await fs.remove(workspacePath);\n }\n }\n }\n}\n\nfunction scaffoldingTracker() {\n // prom-client metrics are deprecated in favour of OpenTelemetry metrics.\n const promTaskCount = createCounterMetric({\n name: 'scaffolder_task_count',\n help: 'Count of task runs',\n labelNames: ['template', 'user', 'result'],\n });\n const promTaskDuration = createHistogramMetric({\n name: 'scaffolder_task_duration',\n help: 'Duration of a task run',\n labelNames: ['template', 'result'],\n });\n const promtStepCount = createCounterMetric({\n name: 'scaffolder_step_count',\n help: 'Count of step runs',\n labelNames: ['template', 'step', 'result'],\n });\n const promStepDuration = createHistogramMetric({\n name: 'scaffolder_step_duration',\n help: 'Duration of a step runs',\n labelNames: ['template', 'step', 'result'],\n });\n\n const meter = metrics.getMeter('default');\n const taskCount = meter.createCounter('scaffolder.task.count', {\n description: 'Count of task runs',\n });\n\n const taskDuration = meter.createHistogram('scaffolder.task.duration', {\n description: 'Duration of a task run',\n unit: 'seconds',\n });\n\n const stepCount = meter.createCounter('scaffolder.step.count', {\n description: 'Count of step runs',\n });\n\n const stepDuration = meter.createHistogram('scaffolder.step.duration', {\n description: 'Duration of a step runs',\n unit: 'seconds',\n });\n\n async function taskStart(task: TaskContext) {\n await task.emitLog(`Starting up task with ${task.spec.steps.length} steps`);\n const template = task.spec.templateInfo?.entityRef || '';\n const user = task.spec.user?.ref || '';\n\n const startTime = process.hrtime();\n const taskTimer = promTaskDuration.startTimer({\n template,\n });\n\n function endTime() {\n const delta = process.hrtime(startTime);\n return delta[0] + delta[1] / 1e9;\n }\n\n async function skipDryRun(\n step: TaskStep,\n action: TemplateAction<JsonObject>,\n ) {\n task.emitLog(`Skipping because ${action.id} does not support dry-run`, {\n stepId: step.id,\n status: 'skipped',\n });\n }\n\n async function markSuccessful() {\n promTaskCount.inc({\n template,\n user,\n result: 'ok',\n });\n taskTimer({ result: 'ok' });\n\n taskCount.add(1, { template, user, result: 'ok' });\n taskDuration.record(endTime(), {\n template,\n result: 'ok',\n });\n }\n\n async function markFailed(step: TaskStep, err: Error) {\n await task.emitLog(String(err.stack), {\n stepId: step.id,\n status: 'failed',\n });\n promTaskCount.inc({\n template,\n user,\n result: 'failed',\n });\n taskTimer({ result: 'failed' });\n\n taskCount.add(1, { template, user, result: 'failed' });\n taskDuration.record(endTime(), {\n template,\n result: 'failed',\n });\n }\n\n async function markCancelled(step: TaskStep) {\n await task.emitLog(`Step ${step.id} has been cancelled.`, {\n stepId: step.id,\n status: 'cancelled',\n });\n promTaskCount.inc({\n template,\n user,\n result: 'cancelled',\n });\n taskTimer({ result: 'cancelled' });\n\n taskCount.add(1, { template, user, result: 'cancelled' });\n taskDuration.record(endTime(), {\n template,\n result: 'cancelled',\n });\n }\n\n return {\n skipDryRun,\n markCancelled,\n markSuccessful,\n markFailed,\n };\n }\n\n async function stepStart(task: TaskContext, step: TaskStep) {\n await task.emitLog(`Beginning step ${step.name}`, {\n stepId: step.id,\n status: 'processing',\n });\n const template = task.spec.templateInfo?.entityRef || '';\n\n const startTime = process.hrtime();\n const stepTimer = promStepDuration.startTimer({\n template,\n step: step.name,\n });\n\n function endTime() {\n const delta = process.hrtime(startTime);\n return delta[0] + delta[1] / 1e9;\n }\n\n async function markSuccessful() {\n await task.emitLog(`Finished step ${step.name}`, {\n stepId: step.id,\n status: 'completed',\n });\n promtStepCount.inc({\n template,\n step: step.name,\n result: 'ok',\n });\n stepTimer({ result: 'ok' });\n\n stepCount.add(1, { template, step: step.name, result: 'ok' });\n stepDuration.record(endTime(), {\n template,\n step: step.name,\n result: 'ok',\n });\n }\n\n async function markCancelled() {\n promtStepCount.inc({\n template,\n step: step.name,\n result: 'cancelled',\n });\n stepTimer({ result: 'cancelled' });\n\n stepCount.add(1, { template, step: step.name, result: 'cancelled' });\n stepDuration.record(endTime(), {\n template,\n step: step.name,\n result: 'cancelled',\n });\n }\n\n async function markFailed() {\n promtStepCount.inc({\n template,\n step: step.name,\n result: 'failed',\n });\n stepTimer({ result: 'failed' });\n\n stepCount.add(1, { template, step: step.name, result: 'failed' });\n stepDuration.record(endTime(), {\n template,\n step: step.name,\n result: 'failed',\n });\n }\n\n async function skipFalsy() {\n await task.emitLog(\n `Skipping step ${step.id} because its if condition was false`,\n { stepId: step.id, status: 'skipped' },\n );\n stepTimer({ result: 'skipped' });\n\n stepCount.add(1, { template, step: step.name, result: 'skipped' });\n stepDuration.record(endTime(), {\n template,\n step: step.name,\n result: 'skipped',\n });\n }\n\n return {\n markCancelled,\n markFailed,\n markSuccessful,\n skipFalsy,\n };\n }\n\n return {\n taskStart,\n stepStart,\n };\n}\n"],"names":["WinstonLogger","winston","BackstageLoggerTransport","createConditionAuthorizer","scaffolderActionRules","convertFiltersToRecord","createDefaultFilters","nunjucks","templated","isTruthy","generateExampleOutput","InputError","validateJsonSchema","errors","NotAllowedError","stringifyError","fs","path","SecureTemplater","actionExecutePermission","AuthorizeResult","createCounterMetric","createHistogramMetric","metrics"],"mappings":"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"}
1
+ {"version":3,"file":"NunjucksWorkflowRunner.cjs.js","sources":["../../../src/scaffolder/tasks/NunjucksWorkflowRunner.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 { InputError, NotAllowedError, stringifyError } from '@backstage/errors';\nimport { ScmIntegrations } from '@backstage/integration';\nimport {\n TaskRecovery,\n TaskSpec,\n TaskSpecV1beta3,\n TaskStep,\n} from '@backstage/plugin-scaffolder-common';\nimport { JsonArray, JsonObject, JsonValue } from '@backstage/types';\nimport { metrics } from '@opentelemetry/api';\nimport fs from 'fs-extra';\nimport { validate as validateJsonSchema } from 'jsonschema';\nimport nunjucks from 'nunjucks';\nimport path from 'path';\nimport * as winston from 'winston';\nimport {\n SecureTemplater,\n SecureTemplateRenderer,\n} from '../../lib/templating/SecureTemplater';\nimport { TemplateActionRegistry } from '../actions/TemplateActionRegistry';\nimport { generateExampleOutput, isTruthy } from './helper';\nimport { TaskTrackType, WorkflowResponse, WorkflowRunner } from './types';\n\nimport type {\n AuditorService,\n LoggerService,\n PermissionsService,\n} from '@backstage/backend-plugin-api';\nimport { UserEntity } from '@backstage/catalog-model';\nimport {\n AuthorizeResult,\n PolicyDecision,\n} from '@backstage/plugin-permission-common';\nimport { createConditionAuthorizer } from '@backstage/plugin-permission-node';\nimport { actionExecutePermission } from '@backstage/plugin-scaffolder-common/alpha';\nimport {\n TaskContext,\n TemplateAction,\n TemplateFilter,\n TemplateGlobal,\n} from '@backstage/plugin-scaffolder-node';\nimport { createDefaultFilters } from '../../lib/templating/filters/createDefaultFilters';\nimport { scaffolderActionRules } from '../../service/rules';\nimport { createCounterMetric, createHistogramMetric } from '../../util/metrics';\nimport { BackstageLoggerTransport, WinstonLogger } from './logger';\nimport { convertFiltersToRecord } from '../../util/templating';\nimport {\n CheckpointContext,\n CheckpointState,\n} from '@backstage/plugin-scaffolder-node/alpha';\n\ntype NunjucksWorkflowRunnerOptions = {\n workingDirectory: string;\n actionRegistry: TemplateActionRegistry;\n integrations: ScmIntegrations;\n logger: LoggerService;\n auditor?: AuditorService;\n additionalTemplateFilters?: Record<string, TemplateFilter>;\n additionalTemplateGlobals?: Record<string, TemplateGlobal>;\n permissions?: PermissionsService;\n};\n\ntype TemplateContext = {\n parameters: JsonObject;\n EXPERIMENTAL_recovery?: TaskRecovery;\n steps: {\n [stepName: string]: { output: { [outputName: string]: JsonValue } };\n };\n secrets?: Record<string, string>;\n user?: {\n entity?: UserEntity;\n ref?: string;\n };\n each?: JsonValue;\n context: {\n task: {\n id: string;\n };\n };\n};\n\nconst isValidTaskSpec = (taskSpec: TaskSpec): taskSpec is TaskSpecV1beta3 => {\n return taskSpec.apiVersion === 'scaffolder.backstage.io/v1beta3';\n};\n\nconst createStepLogger = ({\n task,\n step,\n rootLogger,\n}: {\n task: TaskContext;\n step: TaskStep;\n rootLogger: LoggerService;\n}) => {\n const taskLogger = WinstonLogger.create({\n level: process.env.LOG_LEVEL || 'info',\n format: winston.format.combine(\n winston.format.colorize(),\n winston.format.simple(),\n ),\n transports: [new BackstageLoggerTransport(rootLogger, task, step.id)],\n });\n\n taskLogger.addRedactions(Object.values(task.secrets ?? {}));\n\n return { taskLogger };\n};\n\nconst isActionAuthorized = createConditionAuthorizer(\n Object.values(scaffolderActionRules),\n);\n\nexport class NunjucksWorkflowRunner implements WorkflowRunner {\n private readonly defaultTemplateFilters: Record<string, TemplateFilter>;\n private readonly options: NunjucksWorkflowRunnerOptions;\n\n constructor(options: NunjucksWorkflowRunnerOptions) {\n this.options = options;\n this.defaultTemplateFilters = convertFiltersToRecord(\n createDefaultFilters({\n integrations: this.options.integrations,\n }),\n );\n }\n\n private readonly tracker = scaffoldingTracker();\n\n private isSingleTemplateString(input: string) {\n const { parser, nodes } = nunjucks as unknown as {\n parser: {\n parse(\n template: string,\n ctx: object,\n options: nunjucks.ConfigureOptions,\n ): { children: { children?: unknown[] }[] };\n };\n nodes: { TemplateData: Function };\n };\n\n const parsed = parser.parse(\n input,\n {},\n {\n autoescape: false,\n tags: {\n variableStart: '${{',\n variableEnd: '}}',\n },\n },\n );\n\n return (\n parsed.children.length === 1 &&\n !(parsed.children[0]?.children?.[0] instanceof nodes.TemplateData)\n );\n }\n\n private render<T>(\n input: T,\n context: TemplateContext,\n renderTemplate: SecureTemplateRenderer,\n ): T {\n return JSON.parse(JSON.stringify(input), (_key, value) => {\n try {\n if (typeof value === 'string') {\n try {\n if (this.isSingleTemplateString(value)) {\n // Lets convert ${{ parameters.bob }} to ${{ (parameters.bob) | dump }} so we can keep the input type\n const wrappedDumped = value.replace(\n /\\${{(.+)}}/g,\n '${{ ( $1 ) | dump }}',\n );\n\n // Run the templating\n const templated = renderTemplate(wrappedDumped, context);\n\n // If there's an empty string returned, then it's undefined\n if (templated === '') {\n return undefined;\n }\n\n // Reparse the dumped string\n return JSON.parse(templated);\n }\n } catch (ex) {\n this.options.logger.error(\n `Failed to parse template string: ${value} with error ${ex.message}`,\n );\n }\n\n // Fallback to default behaviour\n const templated = renderTemplate(value, context);\n\n if (templated === '') {\n return undefined;\n }\n\n return templated;\n }\n } catch {\n return value;\n }\n return value;\n });\n }\n\n async executeStep(\n task: TaskContext,\n step: TaskStep,\n context: TemplateContext,\n renderTemplate: (template: string, values: unknown) => string,\n taskTrack: TaskTrackType,\n workspacePath: string,\n decision: PolicyDecision,\n ) {\n const stepTrack = await this.tracker.stepStart(task, step);\n\n if (task.cancelSignal.aborted) {\n throw new Error(\n `Step ${step.id} (${step.name}) of task ${task.taskId} has been cancelled.`,\n );\n }\n\n try {\n if (\n step.if === false ||\n (typeof step.if === 'string' &&\n !isTruthy(this.render(step.if, context, renderTemplate)))\n ) {\n await stepTrack.skipFalsy();\n return;\n }\n const action: TemplateAction<JsonObject> =\n await this.options.actionRegistry.get(step.action, {\n credentials: await task.getInitiatorCredentials(),\n });\n const { taskLogger } = createStepLogger({\n task,\n step,\n rootLogger: this.options.logger,\n });\n\n if (task.isDryRun) {\n const redactedSecrets = Object.fromEntries(\n Object.entries(task.secrets ?? {}).map(secret => [secret[0], '***']),\n );\n const debugInput =\n (step.input &&\n this.render(\n step.input,\n {\n ...context,\n secrets: redactedSecrets,\n },\n renderTemplate,\n )) ??\n {};\n taskLogger.info(\n `Running ${\n action.id\n } in dry-run mode with inputs (secrets redacted): ${JSON.stringify(\n debugInput,\n undefined,\n 2,\n )}`,\n );\n if (!action.supportsDryRun) {\n await taskTrack.skipDryRun(step, action);\n const outputSchema = action.schema?.output;\n if (outputSchema) {\n context.steps[step.id] = {\n output: generateExampleOutput(outputSchema) as {\n [name in string]: JsonValue;\n },\n };\n } else {\n context.steps[step.id] = { output: {} };\n }\n return;\n }\n }\n\n const resolvedEach =\n step.each &&\n this.render(\n step.each,\n { ...context, secrets: task.secrets ?? {} },\n renderTemplate,\n );\n\n if (step.each && !resolvedEach) {\n throw new InputError(\n `Invalid value on action ${action.id}.each parameter, \"${step.each}\" cannot be resolved to a value`,\n );\n }\n\n const iterations = (\n resolvedEach\n ? Object.entries(resolvedEach).map(([key, value]) => ({\n each: { key, value },\n }))\n : [{}]\n ).map(i => ({\n ...i,\n // Secrets are only passed when templating the input to actions for security reasons\n input: step.input\n ? this.render(\n step.input,\n { ...context, secrets: task.secrets ?? {}, ...i },\n renderTemplate,\n )\n : {},\n }));\n for (const iteration of iterations) {\n const actionId = `${action.id}${\n iteration.each ? `[${iteration.each.key}]` : ''\n }`;\n\n if (action.schema?.input) {\n const validateResult = validateJsonSchema(\n iteration.input,\n action.schema.input,\n );\n if (!validateResult.valid) {\n const errors = validateResult.errors.join(', ');\n throw new InputError(\n `Invalid input passed to action ${actionId}, ${errors}`,\n );\n }\n }\n if (\n !isActionAuthorized(decision, {\n action: action.id,\n input: iteration.input,\n })\n ) {\n throw new NotAllowedError(\n `Unauthorized action: ${actionId}. The action is not allowed. Input: ${JSON.stringify(\n iteration.input,\n null,\n 2,\n )}`,\n );\n }\n }\n const tmpDirs = new Array<string>();\n const stepOutput: { [outputName: string]: JsonValue } = {};\n const prevTaskState = await task.getTaskState?.();\n\n for (const iteration of iterations) {\n if (iteration.each) {\n taskLogger.info(\n `Running step each: ${JSON.stringify(\n iteration.each,\n (k, v) => (k ? v.toString() : v),\n 0,\n )}`,\n );\n }\n\n await action.handler({\n input: iteration.input,\n task: {\n id: await task.getWorkspaceName(),\n },\n secrets: task.secrets ?? {},\n logger: taskLogger,\n workspacePath,\n async checkpoint<T extends JsonValue | void>(\n opts: CheckpointContext<T>,\n ) {\n const { key: checkpointKey, fn } = opts;\n const key = `v1.task.checkpoint.${step.id}.${checkpointKey}`;\n\n try {\n let prevValue: T | undefined;\n\n if (prevTaskState) {\n const prevState = (\n prevTaskState.state?.checkpoints as CheckpointState\n )?.[key];\n\n if (prevState && prevState.status === 'success') {\n prevValue = prevState.value as T;\n }\n }\n\n const value = prevValue ? prevValue : await fn();\n\n if (!prevValue) {\n task.updateCheckpoint?.({\n key,\n status: 'success',\n value: value ?? {},\n });\n }\n return value;\n } catch (err) {\n task.updateCheckpoint?.({\n key,\n status: 'failed',\n reason: stringifyError(err),\n });\n throw err;\n } finally {\n await task.serializeWorkspace?.({ path: workspacePath });\n }\n },\n createTemporaryDirectory: async () => {\n const tmpDir = await fs.mkdtemp(\n `${workspacePath}_step-${step.id}-`,\n );\n tmpDirs.push(tmpDir);\n return tmpDir;\n },\n output(name: string, value: JsonValue) {\n if (step.each) {\n stepOutput[name] = stepOutput[name] || [];\n (stepOutput[name] as JsonArray).push(value);\n } else {\n stepOutput[name] = value;\n }\n },\n templateInfo: task.spec.templateInfo,\n user: task.spec.user,\n isDryRun: task.isDryRun,\n signal: task.cancelSignal,\n getInitiatorCredentials: () => task.getInitiatorCredentials(),\n step: {\n id: step.id,\n name: step.name,\n },\n });\n }\n\n // Remove all temporary directories that were created when executing the action\n for (const tmpDir of tmpDirs) {\n await fs.remove(tmpDir);\n }\n\n context.steps[step.id] = { output: stepOutput };\n\n if (task.cancelSignal.aborted) {\n throw new Error(\n `Step ${step.id} (${step.name}) of task ${task.taskId} has been cancelled.`,\n );\n }\n\n await stepTrack.markSuccessful();\n } catch (err) {\n await taskTrack.markFailed(step, err);\n await stepTrack.markFailed();\n throw err;\n } finally {\n await task.serializeWorkspace?.({ path: workspacePath });\n }\n }\n\n async execute(task: TaskContext): Promise<WorkflowResponse> {\n if (!isValidTaskSpec(task.spec)) {\n throw new InputError(\n 'Wrong template version executed with the workflow engine',\n );\n }\n const taskId = await task.getWorkspaceName();\n\n const workspacePath = path.join(this.options.workingDirectory, taskId);\n\n const { additionalTemplateFilters, additionalTemplateGlobals } =\n this.options;\n\n const renderTemplate = await SecureTemplater.loadRenderer({\n templateFilters: {\n ...this.defaultTemplateFilters,\n ...additionalTemplateFilters,\n },\n templateGlobals: additionalTemplateGlobals,\n });\n\n try {\n await task.rehydrateWorkspace?.({ taskId, targetPath: workspacePath });\n\n const taskTrack = await this.tracker.taskStart(task);\n await fs.ensureDir(workspacePath);\n\n const context: TemplateContext = {\n parameters: task.spec.parameters,\n steps: {},\n user: task.spec.user,\n context: {\n task: {\n id: taskId,\n },\n },\n };\n\n const [decision]: PolicyDecision[] =\n this.options.permissions && task.spec.steps.length\n ? await this.options.permissions.authorizeConditional(\n [{ permission: actionExecutePermission }],\n { credentials: await task.getInitiatorCredentials() },\n )\n : [{ result: AuthorizeResult.ALLOW }];\n\n for (const step of task.spec.steps) {\n await this.executeStep(\n task,\n step,\n context,\n renderTemplate,\n taskTrack,\n workspacePath,\n decision,\n );\n }\n\n const output = this.render(task.spec.output, context, renderTemplate);\n await taskTrack.markSuccessful();\n await task.cleanWorkspace?.();\n\n return { output };\n } finally {\n if (workspacePath) {\n await fs.remove(workspacePath);\n }\n }\n }\n}\n\nfunction scaffoldingTracker() {\n // prom-client metrics are deprecated in favour of OpenTelemetry metrics.\n const promTaskCount = createCounterMetric({\n name: 'scaffolder_task_count',\n help: 'Count of task runs',\n labelNames: ['template', 'user', 'result'],\n });\n const promTaskDuration = createHistogramMetric({\n name: 'scaffolder_task_duration',\n help: 'Duration of a task run',\n labelNames: ['template', 'result'],\n });\n const promtStepCount = createCounterMetric({\n name: 'scaffolder_step_count',\n help: 'Count of step runs',\n labelNames: ['template', 'step', 'result'],\n });\n const promStepDuration = createHistogramMetric({\n name: 'scaffolder_step_duration',\n help: 'Duration of a step runs',\n labelNames: ['template', 'step', 'result'],\n });\n\n const meter = metrics.getMeter('default');\n const taskCount = meter.createCounter('scaffolder.task.count', {\n description: 'Count of task runs',\n });\n\n const taskDuration = meter.createHistogram('scaffolder.task.duration', {\n description: 'Duration of a task run',\n unit: 'seconds',\n });\n\n const stepCount = meter.createCounter('scaffolder.step.count', {\n description: 'Count of step runs',\n });\n\n const stepDuration = meter.createHistogram('scaffolder.step.duration', {\n description: 'Duration of a step runs',\n unit: 'seconds',\n });\n\n async function taskStart(task: TaskContext) {\n await task.emitLog(`Starting up task with ${task.spec.steps.length} steps`);\n const template = task.spec.templateInfo?.entityRef || '';\n const user = task.spec.user?.ref || '';\n\n const startTime = process.hrtime();\n const taskTimer = promTaskDuration.startTimer({\n template,\n });\n\n function endTime() {\n const delta = process.hrtime(startTime);\n return delta[0] + delta[1] / 1e9;\n }\n\n async function skipDryRun(\n step: TaskStep,\n action: TemplateAction<JsonObject>,\n ) {\n task.emitLog(`Skipping because ${action.id} does not support dry-run`, {\n stepId: step.id,\n status: 'skipped',\n });\n }\n\n async function markSuccessful() {\n promTaskCount.inc({\n template,\n user,\n result: 'ok',\n });\n taskTimer({ result: 'ok' });\n\n taskCount.add(1, { template, user, result: 'ok' });\n taskDuration.record(endTime(), {\n template,\n result: 'ok',\n });\n }\n\n async function markFailed(step: TaskStep, err: Error) {\n await task.emitLog(String(err.stack), {\n stepId: step.id,\n status: 'failed',\n });\n promTaskCount.inc({\n template,\n user,\n result: 'failed',\n });\n taskTimer({ result: 'failed' });\n\n taskCount.add(1, { template, user, result: 'failed' });\n taskDuration.record(endTime(), {\n template,\n result: 'failed',\n });\n }\n\n async function markCancelled(step: TaskStep) {\n await task.emitLog(`Step ${step.id} has been cancelled.`, {\n stepId: step.id,\n status: 'cancelled',\n });\n promTaskCount.inc({\n template,\n user,\n result: 'cancelled',\n });\n taskTimer({ result: 'cancelled' });\n\n taskCount.add(1, { template, user, result: 'cancelled' });\n taskDuration.record(endTime(), {\n template,\n result: 'cancelled',\n });\n }\n\n return {\n skipDryRun,\n markCancelled,\n markSuccessful,\n markFailed,\n };\n }\n\n async function stepStart(task: TaskContext, step: TaskStep) {\n await task.emitLog(`Beginning step ${step.name}`, {\n stepId: step.id,\n status: 'processing',\n });\n const template = task.spec.templateInfo?.entityRef || '';\n\n const startTime = process.hrtime();\n const stepTimer = promStepDuration.startTimer({\n template,\n step: step.name,\n });\n\n function endTime() {\n const delta = process.hrtime(startTime);\n return delta[0] + delta[1] / 1e9;\n }\n\n async function markSuccessful() {\n await task.emitLog(`Finished step ${step.name}`, {\n stepId: step.id,\n status: 'completed',\n });\n promtStepCount.inc({\n template,\n step: step.name,\n result: 'ok',\n });\n stepTimer({ result: 'ok' });\n\n stepCount.add(1, { template, step: step.name, result: 'ok' });\n stepDuration.record(endTime(), {\n template,\n step: step.name,\n result: 'ok',\n });\n }\n\n async function markCancelled() {\n promtStepCount.inc({\n template,\n step: step.name,\n result: 'cancelled',\n });\n stepTimer({ result: 'cancelled' });\n\n stepCount.add(1, { template, step: step.name, result: 'cancelled' });\n stepDuration.record(endTime(), {\n template,\n step: step.name,\n result: 'cancelled',\n });\n }\n\n async function markFailed() {\n promtStepCount.inc({\n template,\n step: step.name,\n result: 'failed',\n });\n stepTimer({ result: 'failed' });\n\n stepCount.add(1, { template, step: step.name, result: 'failed' });\n stepDuration.record(endTime(), {\n template,\n step: step.name,\n result: 'failed',\n });\n }\n\n async function skipFalsy() {\n await task.emitLog(\n `Skipping step ${step.id} because its if condition was false`,\n { stepId: step.id, status: 'skipped' },\n );\n stepTimer({ result: 'skipped' });\n\n stepCount.add(1, { template, step: step.name, result: 'skipped' });\n stepDuration.record(endTime(), {\n template,\n step: step.name,\n result: 'skipped',\n });\n }\n\n return {\n markCancelled,\n markFailed,\n markSuccessful,\n skipFalsy,\n };\n }\n\n return {\n taskStart,\n stepStart,\n };\n}\n"],"names":["WinstonLogger","winston","BackstageLoggerTransport","createConditionAuthorizer","scaffolderActionRules","convertFiltersToRecord","createDefaultFilters","nunjucks","templated","isTruthy","generateExampleOutput","InputError","validateJsonSchema","errors","NotAllowedError","stringifyError","fs","path","SecureTemplater","actionExecutePermission","AuthorizeResult","createCounterMetric","createHistogramMetric","metrics"],"mappings":"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"}
@@ -10,15 +10,6 @@ function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'defau
10
10
  var ObservableImpl__default = /*#__PURE__*/_interopDefaultCompat(ObservableImpl);
11
11
 
12
12
  class TaskManager {
13
- // Runs heartbeat internally
14
- constructor(task, storage, signal, logger, workspaceService, auth) {
15
- this.task = task;
16
- this.storage = storage;
17
- this.signal = signal;
18
- this.logger = logger;
19
- this.workspaceService = workspaceService;
20
- this.auth = auth;
21
- }
22
13
  isDone = false;
23
14
  heartbeatTimeoutId;
24
15
  static create(task, storage, abortSignal, logger, auth, config, additionalWorkspaceProviders) {
@@ -39,6 +30,21 @@ class TaskManager {
39
30
  agent.startTimeout();
40
31
  return agent;
41
32
  }
33
+ task;
34
+ storage;
35
+ signal;
36
+ logger;
37
+ workspaceService;
38
+ auth;
39
+ // Runs heartbeat internally
40
+ constructor(task, storage, signal, logger, workspaceService, auth) {
41
+ this.task = task;
42
+ this.storage = storage;
43
+ this.signal = signal;
44
+ this.logger = logger;
45
+ this.workspaceService = workspaceService;
46
+ this.auth = auth;
47
+ }
42
48
  get taskId() {
43
49
  return this.task.taskId;
44
50
  }
@@ -132,6 +138,12 @@ class TaskManager {
132
138
  }
133
139
  }
134
140
  class StorageTaskBroker {
141
+ storage;
142
+ logger;
143
+ config;
144
+ auth;
145
+ additionalWorkspaceProviders;
146
+ auditor;
135
147
  constructor(storage, logger, config, auth, additionalWorkspaceProviders, auditor) {
136
148
  this.storage = storage;
137
149
  this.logger = logger;
@@ -1 +1 @@
1
- {"version":3,"file":"StorageTaskBroker.cjs.js","sources":["../../../src/scaffolder/tasks/StorageTaskBroker.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 AuditorService,\n AuthService,\n BackstageCredentials,\n LoggerService,\n} from '@backstage/backend-plugin-api';\nimport { Config } from '@backstage/config';\nimport { TaskSpec } from '@backstage/plugin-scaffolder-common';\nimport {\n SerializedTask,\n SerializedTaskEvent,\n TaskBroker,\n TaskBrokerDispatchOptions,\n TaskCompletionState,\n TaskContext,\n TaskFilters,\n TaskSecrets,\n TaskStatus,\n} from '@backstage/plugin-scaffolder-node';\nimport {\n CheckpointState,\n WorkspaceProvider,\n UpdateTaskCheckpointOptions,\n} from '@backstage/plugin-scaffolder-node/alpha';\nimport { JsonObject, Observable, createDeferred } from '@backstage/types';\nimport ObservableImpl from 'zen-observable';\nimport { DefaultWorkspaceService, WorkspaceService } from './WorkspaceService';\nimport { readDuration } from './helper';\nimport { InternalTaskSecrets, TaskStore } from './types';\nimport { PermissionCriteria } from '@backstage/plugin-permission-common';\n\ntype TaskState = {\n checkpoints: CheckpointState;\n};\n/**\n * TaskManager\n */\nexport class TaskManager implements TaskContext {\n private isDone = false;\n\n private heartbeatTimeoutId?: ReturnType<typeof setInterval>;\n\n static create(\n task: CurrentClaimedTask,\n storage: TaskStore,\n abortSignal: AbortSignal,\n logger: LoggerService,\n auth?: AuthService,\n config?: Config,\n additionalWorkspaceProviders?: Record<string, WorkspaceProvider>,\n ) {\n const workspaceService = DefaultWorkspaceService.create(\n task,\n storage,\n additionalWorkspaceProviders,\n config,\n );\n\n const agent = new TaskManager(\n task,\n storage,\n abortSignal,\n logger,\n workspaceService,\n auth,\n );\n agent.startTimeout();\n return agent;\n }\n\n // Runs heartbeat internally\n private constructor(\n private readonly task: CurrentClaimedTask,\n private readonly storage: TaskStore,\n private readonly signal: AbortSignal,\n private readonly logger: LoggerService,\n private readonly workspaceService: WorkspaceService,\n private readonly auth?: AuthService,\n ) {}\n\n get taskId() {\n return this.task.taskId;\n }\n\n get spec() {\n return this.task.spec;\n }\n\n get cancelSignal() {\n return this.signal;\n }\n\n get secrets() {\n return this.task.secrets;\n }\n\n get createdBy() {\n return this.task.createdBy;\n }\n\n async getWorkspaceName() {\n return this.task.taskId;\n }\n\n async rehydrateWorkspace?(options: {\n taskId: string;\n targetPath: string;\n }): Promise<void> {\n await this.workspaceService.rehydrateWorkspace(options);\n }\n\n get done() {\n return this.isDone;\n }\n\n async emitLog(message: string, logMetadata?: JsonObject): Promise<void> {\n await this.storage.emitLogEvent({\n taskId: this.task.taskId,\n body: { message, ...logMetadata },\n });\n }\n\n async getTaskState?(): Promise<\n | {\n state?: JsonObject;\n }\n | undefined\n > {\n return this.storage.getTaskState?.({ taskId: this.task.taskId });\n }\n\n async updateCheckpoint?(options: UpdateTaskCheckpointOptions): Promise<void> {\n const { key, ...value } = options;\n\n if (this.task.state) {\n (this.task.state as TaskState).checkpoints[key] = value;\n } else {\n this.task.state = { checkpoints: { [key]: value } };\n }\n await this.storage.saveTaskState?.({\n taskId: this.task.taskId,\n state: this.task.state,\n });\n }\n\n async serializeWorkspace?(options: { path: string }): Promise<void> {\n await this.workspaceService.serializeWorkspace(options);\n }\n\n async cleanWorkspace?(): Promise<void> {\n await this.workspaceService.cleanWorkspace();\n }\n\n async complete(\n result: TaskCompletionState,\n metadata?: JsonObject,\n ): Promise<void> {\n await this.storage.completeTask({\n taskId: this.task.taskId,\n status: result === 'failed' ? 'failed' : 'completed',\n eventBody: {\n message: `Run completed with status: ${result}`,\n ...metadata,\n },\n });\n this.isDone = true;\n if (this.heartbeatTimeoutId) {\n clearTimeout(this.heartbeatTimeoutId);\n }\n }\n\n private startTimeout() {\n this.heartbeatTimeoutId = setTimeout(async () => {\n try {\n await this.storage.heartbeatTask(this.task.taskId);\n this.startTimeout();\n } catch (error) {\n this.isDone = true;\n\n this.logger.error(\n `Heartbeat for task ${this.task.taskId} failed`,\n error,\n );\n }\n }, 1000);\n }\n\n async getInitiatorCredentials(): Promise<BackstageCredentials> {\n const secrets = this.task.secrets as InternalTaskSecrets;\n\n if (secrets && secrets.__initiatorCredentials) {\n return JSON.parse(secrets.__initiatorCredentials);\n }\n if (!this.auth) {\n throw new Error(\n 'Failed to create none credentials in scaffolder task. The TaskManager has not been initialized with an auth service implementation',\n );\n }\n return this.auth.getNoneCredentials();\n }\n}\n\n/**\n * Stores the state of the current claimed task passed to the TaskContext\n *\n * @public\n */\nexport interface CurrentClaimedTask {\n /**\n * The TaskSpec of the current claimed task.\n */\n spec: TaskSpec;\n /**\n * The uuid of the current claimed task.\n */\n taskId: string;\n /**\n * The secrets that are stored with the task.\n */\n secrets?: TaskSecrets;\n /**\n * The state of checkpoints of the task.\n */\n state?: JsonObject;\n /**\n * The creator of the task.\n */\n createdBy?: string;\n /**\n * The workspace of the task.\n */\n workspace?: Promise<Buffer>;\n}\n\nexport class StorageTaskBroker implements TaskBroker {\n constructor(\n private readonly storage: TaskStore,\n private readonly logger: LoggerService,\n private readonly config?: Config,\n private readonly auth?: AuthService,\n private readonly additionalWorkspaceProviders?: Record<\n string,\n WorkspaceProvider\n >,\n private readonly auditor?: AuditorService,\n ) {}\n\n async list(options?: {\n createdBy?: string;\n status?: TaskStatus;\n filters?: {\n createdBy?: string | string[];\n status?: TaskStatus | TaskStatus[];\n };\n pagination?: {\n limit?: number;\n offset?: number;\n };\n order?: { order: 'asc' | 'desc'; field: string }[];\n permissionFilters?: PermissionCriteria<TaskFilters>;\n }): Promise<{ tasks: SerializedTask[]; totalTasks?: number }> {\n if (!this.storage.list) {\n throw new Error(\n 'TaskStore does not implement the list method. Please implement the list method to be able to list tasks',\n );\n }\n return await this.storage.list(options ?? {});\n }\n\n private deferredDispatch = createDeferred();\n\n private async registerCancellable(\n taskId: string,\n abortController: AbortController,\n ) {\n let shouldUnsubscribe = false;\n const subscription = this.event$({ taskId, after: undefined }).subscribe({\n error: _ => {\n subscription.unsubscribe();\n },\n next: ({ events }) => {\n for (const event of events) {\n if (event.type === 'cancelled') {\n abortController.abort();\n shouldUnsubscribe = true;\n }\n\n if (event.type === 'completion' && !event.isTaskRecoverable) {\n shouldUnsubscribe = true;\n }\n }\n if (shouldUnsubscribe) {\n subscription.unsubscribe();\n }\n },\n });\n }\n\n public async recoverTasks(): Promise<void> {\n const enabled =\n this.config?.getOptionalBoolean('scaffolder.EXPERIMENTAL_recoverTasks') ??\n false;\n\n if (enabled) {\n const defaultTimeout = { seconds: 30 };\n const timeout = readDuration(\n this.config,\n 'scaffolder.EXPERIMENTAL_recoverTasksTimeout',\n defaultTimeout,\n );\n const { ids: recoveredTaskIds } = (await this.storage.recoverTasks?.({\n timeout,\n })) ?? { ids: [] };\n if (recoveredTaskIds.length > 0) {\n this.signalDispatch();\n }\n }\n }\n\n /**\n * {@inheritdoc TaskBroker.claim}\n */\n async claim(): Promise<TaskContext> {\n for (;;) {\n const pendingTask = await this.storage.claimTask();\n if (pendingTask) {\n const abortController = new AbortController();\n await this.registerCancellable(pendingTask.id, abortController);\n return TaskManager.create(\n {\n taskId: pendingTask.id,\n spec: pendingTask.spec,\n secrets: pendingTask.secrets,\n createdBy: pendingTask.createdBy,\n state: pendingTask.state,\n },\n this.storage,\n abortController.signal,\n this.logger,\n this.auth,\n this.config,\n this.additionalWorkspaceProviders,\n );\n }\n\n await this.waitForDispatch();\n }\n }\n\n /**\n * {@inheritdoc TaskBroker.dispatch}\n */\n async dispatch(\n options: TaskBrokerDispatchOptions,\n ): Promise<{ taskId: string }> {\n const taskRow = await this.storage.createTask(options);\n this.signalDispatch();\n return {\n taskId: taskRow.taskId,\n };\n }\n\n /**\n * {@inheritdoc TaskBroker.get}\n */\n async get(taskId: string): Promise<SerializedTask> {\n return this.storage.getTask(taskId);\n }\n\n /**\n * {@inheritdoc TaskBroker.event$}\n */\n event$(options: {\n taskId: string;\n after?: number;\n }): Observable<{ events: SerializedTaskEvent[] }> {\n return new ObservableImpl(observer => {\n const { taskId } = options;\n\n let after = options.after;\n let cancelled = false;\n\n (async () => {\n const task = await this.storage.getTask(taskId);\n const isTaskRecoverable =\n task.spec.EXPERIMENTAL_recovery?.EXPERIMENTAL_strategy ===\n 'startOver';\n\n while (!cancelled) {\n const result = await this.storage.listEvents({\n isTaskRecoverable,\n taskId,\n after,\n });\n const { events } = result;\n if (events.length) {\n after = events[events.length - 1].id;\n observer.next(result);\n }\n\n await new Promise(resolve => setTimeout(resolve, 1000));\n }\n })();\n\n return () => {\n cancelled = true;\n };\n });\n }\n\n /**\n * {@inheritdoc TaskBroker.vacuumTasks}\n */\n async vacuumTasks(options: { timeoutS: number }): Promise<void> {\n const { tasks } = await this.storage.listStaleTasks(options);\n await Promise.all(\n tasks.map(async task => {\n const auditorEvent = await this.auditor?.createEvent({\n eventId: 'task',\n severityLevel: 'medium',\n meta: {\n actionType: 'stale-cancel',\n taskId: task.taskId,\n },\n });\n try {\n await this.storage.completeTask({\n taskId: task.taskId,\n status: 'failed',\n eventBody: {\n message:\n 'The task was cancelled because the task worker lost connection to the task broker',\n },\n });\n await auditorEvent?.success();\n } catch (error) {\n this.logger.warn(`Failed to cancel task '${task.taskId}', ${error}`);\n await auditorEvent?.fail({ error: error });\n }\n }),\n );\n }\n\n private waitForDispatch() {\n return this.deferredDispatch;\n }\n\n private signalDispatch() {\n this.deferredDispatch.resolve();\n this.deferredDispatch = createDeferred();\n }\n\n async cancel(taskId: string) {\n const { events } = await this.storage.listEvents({ taskId });\n const currentStepId =\n events.length > 0\n ? events\n .filter(({ body }) => body?.stepId)\n .reduce((prev, curr) => (prev.id > curr.id ? prev : curr)).body\n .stepId\n : 0;\n\n await this.storage.cancelTask?.({\n taskId,\n body: {\n message: `Step ${currentStepId} has been cancelled.`,\n stepId: currentStepId,\n status: 'cancelled',\n },\n });\n }\n\n async retry(options: {\n secrets?: TaskSecrets;\n taskId: string;\n }): Promise<void> {\n await this.storage.retryTask?.(options);\n this.signalDispatch();\n }\n}\n"],"names":["DefaultWorkspaceService","createDeferred","readDuration","ObservableImpl"],"mappings":"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"}
1
+ {"version":3,"file":"StorageTaskBroker.cjs.js","sources":["../../../src/scaffolder/tasks/StorageTaskBroker.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 AuditorService,\n AuthService,\n BackstageCredentials,\n LoggerService,\n} from '@backstage/backend-plugin-api';\nimport { Config } from '@backstage/config';\nimport { TaskSpec } from '@backstage/plugin-scaffolder-common';\nimport {\n SerializedTask,\n SerializedTaskEvent,\n TaskBroker,\n TaskBrokerDispatchOptions,\n TaskCompletionState,\n TaskContext,\n TaskFilters,\n TaskSecrets,\n TaskStatus,\n} from '@backstage/plugin-scaffolder-node';\nimport {\n CheckpointState,\n WorkspaceProvider,\n UpdateTaskCheckpointOptions,\n} from '@backstage/plugin-scaffolder-node/alpha';\nimport { JsonObject, Observable, createDeferred } from '@backstage/types';\nimport ObservableImpl from 'zen-observable';\nimport { DefaultWorkspaceService, WorkspaceService } from './WorkspaceService';\nimport { readDuration } from './helper';\nimport { InternalTaskSecrets, TaskStore } from './types';\nimport { PermissionCriteria } from '@backstage/plugin-permission-common';\n\ntype TaskState = {\n checkpoints: CheckpointState;\n};\n/**\n * TaskManager\n */\nexport class TaskManager implements TaskContext {\n private isDone = false;\n\n private heartbeatTimeoutId?: ReturnType<typeof setInterval>;\n\n static create(\n task: CurrentClaimedTask,\n storage: TaskStore,\n abortSignal: AbortSignal,\n logger: LoggerService,\n auth?: AuthService,\n config?: Config,\n additionalWorkspaceProviders?: Record<string, WorkspaceProvider>,\n ) {\n const workspaceService = DefaultWorkspaceService.create(\n task,\n storage,\n additionalWorkspaceProviders,\n config,\n );\n\n const agent = new TaskManager(\n task,\n storage,\n abortSignal,\n logger,\n workspaceService,\n auth,\n );\n agent.startTimeout();\n return agent;\n }\n\n private readonly task: CurrentClaimedTask;\n private readonly storage: TaskStore;\n private readonly signal: AbortSignal;\n private readonly logger: LoggerService;\n private readonly workspaceService: WorkspaceService;\n private readonly auth?: AuthService;\n\n // Runs heartbeat internally\n private constructor(\n task: CurrentClaimedTask,\n storage: TaskStore,\n signal: AbortSignal,\n logger: LoggerService,\n workspaceService: WorkspaceService,\n auth?: AuthService,\n ) {\n this.task = task;\n this.storage = storage;\n this.signal = signal;\n this.logger = logger;\n this.workspaceService = workspaceService;\n this.auth = auth;\n }\n\n get taskId() {\n return this.task.taskId;\n }\n\n get spec() {\n return this.task.spec;\n }\n\n get cancelSignal() {\n return this.signal;\n }\n\n get secrets() {\n return this.task.secrets;\n }\n\n get createdBy() {\n return this.task.createdBy;\n }\n\n async getWorkspaceName() {\n return this.task.taskId;\n }\n\n async rehydrateWorkspace?(options: {\n taskId: string;\n targetPath: string;\n }): Promise<void> {\n await this.workspaceService.rehydrateWorkspace(options);\n }\n\n get done() {\n return this.isDone;\n }\n\n async emitLog(message: string, logMetadata?: JsonObject): Promise<void> {\n await this.storage.emitLogEvent({\n taskId: this.task.taskId,\n body: { message, ...logMetadata },\n });\n }\n\n async getTaskState?(): Promise<\n | {\n state?: JsonObject;\n }\n | undefined\n > {\n return this.storage.getTaskState?.({ taskId: this.task.taskId });\n }\n\n async updateCheckpoint?(options: UpdateTaskCheckpointOptions): Promise<void> {\n const { key, ...value } = options;\n\n if (this.task.state) {\n (this.task.state as TaskState).checkpoints[key] = value;\n } else {\n this.task.state = { checkpoints: { [key]: value } };\n }\n await this.storage.saveTaskState?.({\n taskId: this.task.taskId,\n state: this.task.state,\n });\n }\n\n async serializeWorkspace?(options: { path: string }): Promise<void> {\n await this.workspaceService.serializeWorkspace(options);\n }\n\n async cleanWorkspace?(): Promise<void> {\n await this.workspaceService.cleanWorkspace();\n }\n\n async complete(\n result: TaskCompletionState,\n metadata?: JsonObject,\n ): Promise<void> {\n await this.storage.completeTask({\n taskId: this.task.taskId,\n status: result === 'failed' ? 'failed' : 'completed',\n eventBody: {\n message: `Run completed with status: ${result}`,\n ...metadata,\n },\n });\n this.isDone = true;\n if (this.heartbeatTimeoutId) {\n clearTimeout(this.heartbeatTimeoutId);\n }\n }\n\n private startTimeout() {\n this.heartbeatTimeoutId = setTimeout(async () => {\n try {\n await this.storage.heartbeatTask(this.task.taskId);\n this.startTimeout();\n } catch (error) {\n this.isDone = true;\n\n this.logger.error(\n `Heartbeat for task ${this.task.taskId} failed`,\n error,\n );\n }\n }, 1000);\n }\n\n async getInitiatorCredentials(): Promise<BackstageCredentials> {\n const secrets = this.task.secrets as InternalTaskSecrets;\n\n if (secrets && secrets.__initiatorCredentials) {\n return JSON.parse(secrets.__initiatorCredentials);\n }\n if (!this.auth) {\n throw new Error(\n 'Failed to create none credentials in scaffolder task. The TaskManager has not been initialized with an auth service implementation',\n );\n }\n return this.auth.getNoneCredentials();\n }\n}\n\n/**\n * Stores the state of the current claimed task passed to the TaskContext\n *\n * @public\n */\nexport interface CurrentClaimedTask {\n /**\n * The TaskSpec of the current claimed task.\n */\n spec: TaskSpec;\n /**\n * The uuid of the current claimed task.\n */\n taskId: string;\n /**\n * The secrets that are stored with the task.\n */\n secrets?: TaskSecrets;\n /**\n * The state of checkpoints of the task.\n */\n state?: JsonObject;\n /**\n * The creator of the task.\n */\n createdBy?: string;\n /**\n * The workspace of the task.\n */\n workspace?: Promise<Buffer>;\n}\n\nexport class StorageTaskBroker implements TaskBroker {\n private readonly storage: TaskStore;\n private readonly logger: LoggerService;\n private readonly config?: Config;\n private readonly auth?: AuthService;\n private readonly additionalWorkspaceProviders?: Record<\n string,\n WorkspaceProvider\n >;\n private readonly auditor?: AuditorService;\n\n constructor(\n storage: TaskStore,\n logger: LoggerService,\n config?: Config,\n auth?: AuthService,\n additionalWorkspaceProviders?: Record<string, WorkspaceProvider>,\n auditor?: AuditorService,\n ) {\n this.storage = storage;\n this.logger = logger;\n this.config = config;\n this.auth = auth;\n this.additionalWorkspaceProviders = additionalWorkspaceProviders;\n this.auditor = auditor;\n }\n\n async list(options?: {\n createdBy?: string;\n status?: TaskStatus;\n filters?: {\n createdBy?: string | string[];\n status?: TaskStatus | TaskStatus[];\n };\n pagination?: {\n limit?: number;\n offset?: number;\n };\n order?: { order: 'asc' | 'desc'; field: string }[];\n permissionFilters?: PermissionCriteria<TaskFilters>;\n }): Promise<{ tasks: SerializedTask[]; totalTasks?: number }> {\n if (!this.storage.list) {\n throw new Error(\n 'TaskStore does not implement the list method. Please implement the list method to be able to list tasks',\n );\n }\n return await this.storage.list(options ?? {});\n }\n\n private deferredDispatch = createDeferred();\n\n private async registerCancellable(\n taskId: string,\n abortController: AbortController,\n ) {\n let shouldUnsubscribe = false;\n const subscription = this.event$({ taskId, after: undefined }).subscribe({\n error: _ => {\n subscription.unsubscribe();\n },\n next: ({ events }) => {\n for (const event of events) {\n if (event.type === 'cancelled') {\n abortController.abort();\n shouldUnsubscribe = true;\n }\n\n if (event.type === 'completion' && !event.isTaskRecoverable) {\n shouldUnsubscribe = true;\n }\n }\n if (shouldUnsubscribe) {\n subscription.unsubscribe();\n }\n },\n });\n }\n\n public async recoverTasks(): Promise<void> {\n const enabled =\n this.config?.getOptionalBoolean('scaffolder.EXPERIMENTAL_recoverTasks') ??\n false;\n\n if (enabled) {\n const defaultTimeout = { seconds: 30 };\n const timeout = readDuration(\n this.config,\n 'scaffolder.EXPERIMENTAL_recoverTasksTimeout',\n defaultTimeout,\n );\n const { ids: recoveredTaskIds } = (await this.storage.recoverTasks?.({\n timeout,\n })) ?? { ids: [] };\n if (recoveredTaskIds.length > 0) {\n this.signalDispatch();\n }\n }\n }\n\n /**\n * {@inheritdoc TaskBroker.claim}\n */\n async claim(): Promise<TaskContext> {\n for (;;) {\n const pendingTask = await this.storage.claimTask();\n if (pendingTask) {\n const abortController = new AbortController();\n await this.registerCancellable(pendingTask.id, abortController);\n return TaskManager.create(\n {\n taskId: pendingTask.id,\n spec: pendingTask.spec,\n secrets: pendingTask.secrets,\n createdBy: pendingTask.createdBy,\n state: pendingTask.state,\n },\n this.storage,\n abortController.signal,\n this.logger,\n this.auth,\n this.config,\n this.additionalWorkspaceProviders,\n );\n }\n\n await this.waitForDispatch();\n }\n }\n\n /**\n * {@inheritdoc TaskBroker.dispatch}\n */\n async dispatch(\n options: TaskBrokerDispatchOptions,\n ): Promise<{ taskId: string }> {\n const taskRow = await this.storage.createTask(options);\n this.signalDispatch();\n return {\n taskId: taskRow.taskId,\n };\n }\n\n /**\n * {@inheritdoc TaskBroker.get}\n */\n async get(taskId: string): Promise<SerializedTask> {\n return this.storage.getTask(taskId);\n }\n\n /**\n * {@inheritdoc TaskBroker.event$}\n */\n event$(options: {\n taskId: string;\n after?: number;\n }): Observable<{ events: SerializedTaskEvent[] }> {\n return new ObservableImpl(observer => {\n const { taskId } = options;\n\n let after = options.after;\n let cancelled = false;\n\n (async () => {\n const task = await this.storage.getTask(taskId);\n const isTaskRecoverable =\n task.spec.EXPERIMENTAL_recovery?.EXPERIMENTAL_strategy ===\n 'startOver';\n\n while (!cancelled) {\n const result = await this.storage.listEvents({\n isTaskRecoverable,\n taskId,\n after,\n });\n const { events } = result;\n if (events.length) {\n after = events[events.length - 1].id;\n observer.next(result);\n }\n\n await new Promise(resolve => setTimeout(resolve, 1000));\n }\n })();\n\n return () => {\n cancelled = true;\n };\n });\n }\n\n /**\n * {@inheritdoc TaskBroker.vacuumTasks}\n */\n async vacuumTasks(options: { timeoutS: number }): Promise<void> {\n const { tasks } = await this.storage.listStaleTasks(options);\n await Promise.all(\n tasks.map(async task => {\n const auditorEvent = await this.auditor?.createEvent({\n eventId: 'task',\n severityLevel: 'medium',\n meta: {\n actionType: 'stale-cancel',\n taskId: task.taskId,\n },\n });\n try {\n await this.storage.completeTask({\n taskId: task.taskId,\n status: 'failed',\n eventBody: {\n message:\n 'The task was cancelled because the task worker lost connection to the task broker',\n },\n });\n await auditorEvent?.success();\n } catch (error) {\n this.logger.warn(`Failed to cancel task '${task.taskId}', ${error}`);\n await auditorEvent?.fail({ error: error });\n }\n }),\n );\n }\n\n private waitForDispatch() {\n return this.deferredDispatch;\n }\n\n private signalDispatch() {\n this.deferredDispatch.resolve();\n this.deferredDispatch = createDeferred();\n }\n\n async cancel(taskId: string) {\n const { events } = await this.storage.listEvents({ taskId });\n const currentStepId =\n events.length > 0\n ? events\n .filter(({ body }) => body?.stepId)\n .reduce((prev, curr) => (prev.id > curr.id ? prev : curr)).body\n .stepId\n : 0;\n\n await this.storage.cancelTask?.({\n taskId,\n body: {\n message: `Step ${currentStepId} has been cancelled.`,\n stepId: currentStepId,\n status: 'cancelled',\n },\n });\n }\n\n async retry(options: {\n secrets?: TaskSecrets;\n taskId: string;\n }): Promise<void> {\n await this.storage.retryTask?.(options);\n this.signalDispatch();\n }\n}\n"],"names":["DefaultWorkspaceService","createDeferred","readDuration","ObservableImpl"],"mappings":"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"}
@@ -11,6 +11,12 @@ var PQueue__default = /*#__PURE__*/_interopDefaultCompat(PQueue);
11
11
 
12
12
  const DEFAULT_TASK_PARAMETER_MAX_LENGTH = 256;
13
13
  class TaskWorker {
14
+ taskQueue;
15
+ logger;
16
+ auditor;
17
+ parameterAuditTransform;
18
+ stopWorkers;
19
+ options;
14
20
  constructor(options) {
15
21
  this.options = options;
16
22
  this.stopWorkers = false;
@@ -21,11 +27,6 @@ class TaskWorker {
21
27
  });
22
28
  this.parameterAuditTransform = options.parameterAuditTransform;
23
29
  }
24
- taskQueue;
25
- logger;
26
- auditor;
27
- parameterAuditTransform;
28
- stopWorkers;
29
30
  static async create(options) {
30
31
  const {
31
32
  taskBroker,
@@ -1 +1 @@
1
- {"version":3,"file":"TaskWorker.cjs.js","sources":["../../../src/scaffolder/tasks/TaskWorker.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 { AuditorService, LoggerService } from '@backstage/backend-plugin-api';\nimport { assertError, InputError, stringifyError } from '@backstage/errors';\nimport { ScmIntegrations } from '@backstage/integration';\nimport { PermissionEvaluator } from '@backstage/plugin-permission-common';\nimport {\n TaskBroker,\n TaskContext,\n TemplateFilter,\n TemplateGlobal,\n} from '@backstage/plugin-scaffolder-node';\nimport PQueue from 'p-queue';\nimport { TemplateActionRegistry } from '../actions/TemplateActionRegistry';\nimport { NunjucksWorkflowRunner } from './NunjucksWorkflowRunner';\nimport { WorkflowRunner } from './types';\nimport { setTimeout } from 'timers/promises';\nimport { JsonObject } from '@backstage/types';\nimport { Config } from '@backstage/config';\n\nconst DEFAULT_TASK_PARAMETER_MAX_LENGTH = 256;\n\n/**\n * TaskWorkerOptions\n */\nexport type TaskWorkerOptions = {\n taskBroker: TaskBroker;\n runners: {\n workflowRunner: WorkflowRunner;\n };\n concurrentTasksLimit: number;\n permissions?: PermissionEvaluator;\n logger?: LoggerService;\n auditor?: AuditorService;\n config?: Config;\n gracefulShutdown?: boolean;\n};\n\n/**\n * CreateWorkerOptions\n */\nexport type CreateWorkerOptions = {\n taskBroker: TaskBroker;\n actionRegistry: TemplateActionRegistry;\n integrations: ScmIntegrations;\n workingDirectory: string;\n logger: LoggerService;\n auditor?: AuditorService;\n config?: Config;\n additionalTemplateFilters?: Record<string, TemplateFilter>;\n /**\n * The number of tasks that can be executed at the same time by the worker\n * @defaultValue 10\n * @example\n * ```\n * {\n * concurrentTasksLimit: 1,\n * // OR\n * concurrentTasksLimit: Infinity\n * }\n * ```\n */\n concurrentTasksLimit?: number;\n additionalTemplateGlobals?: Record<string, TemplateGlobal>;\n permissions?: PermissionEvaluator;\n gracefulShutdown?: boolean;\n};\n\n/**\n * TaskWorker\n */\nexport class TaskWorker {\n private taskQueue: PQueue;\n private logger: LoggerService | undefined;\n private auditor: AuditorService | undefined;\n private parameterAuditTransform: ParameterAuditTransform;\n private stopWorkers: boolean;\n\n private constructor(\n private readonly options: TaskWorkerOptions & {\n parameterAuditTransform: ParameterAuditTransform;\n },\n ) {\n this.stopWorkers = false;\n this.logger = options.logger;\n this.auditor = options.auditor;\n this.taskQueue = new PQueue({\n concurrency: options.concurrentTasksLimit,\n });\n this.parameterAuditTransform = options.parameterAuditTransform;\n }\n\n static async create(options: CreateWorkerOptions): Promise<TaskWorker> {\n const {\n taskBroker,\n logger,\n auditor,\n config,\n actionRegistry,\n integrations,\n workingDirectory,\n additionalTemplateFilters,\n concurrentTasksLimit = 10, // from 1 to Infinity\n additionalTemplateGlobals,\n permissions,\n gracefulShutdown,\n } = options;\n\n const workflowRunner = new NunjucksWorkflowRunner({\n actionRegistry,\n integrations,\n logger,\n auditor,\n workingDirectory,\n additionalTemplateFilters,\n additionalTemplateGlobals,\n permissions,\n });\n\n return new TaskWorker({\n taskBroker: taskBroker,\n runners: { workflowRunner },\n concurrentTasksLimit,\n permissions,\n auditor,\n config,\n gracefulShutdown,\n parameterAuditTransform: createParameterTruncator(config),\n });\n }\n\n async recoverTasks() {\n try {\n await this.options.taskBroker.recoverTasks?.();\n } catch (err) {\n this.logger?.error(stringifyError(err));\n }\n }\n\n start() {\n (async () => {\n while (!this.stopWorkers) {\n await setTimeout(10000);\n await this.recoverTasks();\n }\n })();\n (async () => {\n while (!this.stopWorkers) {\n await this.onReadyToClaimTask();\n if (!this.stopWorkers) {\n const task = await this.options.taskBroker.claim();\n void this.taskQueue.add(() => this.runOneTask(task));\n }\n }\n })();\n }\n\n async stop() {\n this.stopWorkers = true;\n if (this.options?.gracefulShutdown) {\n while (this.taskQueue.size > 0) {\n await setTimeout(1000);\n }\n }\n }\n\n protected onReadyToClaimTask(): Promise<void> {\n if (this.taskQueue.pending < this.options.concurrentTasksLimit) {\n return Promise.resolve();\n }\n return new Promise(resolve => {\n // \"next\" event emits when a task completes\n // https://github.com/sindresorhus/p-queue#next\n this.taskQueue.once('next', () => {\n resolve();\n });\n });\n }\n\n async runOneTask(task: TaskContext) {\n const auditorEvent = await this.auditor?.createEvent({\n eventId: 'task',\n severityLevel: 'medium',\n meta: {\n actionType: 'execution',\n createdBy: task.createdBy,\n taskId: task.taskId,\n taskParameters: this.parameterAuditTransform(task.spec.parameters),\n templateRef: task.spec.templateInfo?.entityRef,\n },\n });\n\n try {\n if (task.spec.apiVersion !== 'scaffolder.backstage.io/v1beta3') {\n throw new Error(\n `Unsupported Template apiVersion ${task.spec.apiVersion}`,\n );\n }\n\n const { output } = await this.options.runners.workflowRunner.execute(\n task,\n );\n\n await task.complete('completed', { output });\n await auditorEvent?.success();\n } catch (error) {\n assertError(error);\n await auditorEvent?.fail({\n error,\n });\n await task.complete('failed', {\n error: { name: error.name, message: error.message },\n });\n }\n }\n}\n\ntype ParameterAuditTransform = (parameters: JsonObject) => JsonObject;\n\n/**\n * Truncates task parameters for audit logging using the configured max length.\n * @internal\n */\nexport function createParameterTruncator(\n config?: Config,\n): ParameterAuditTransform {\n const maxLength =\n config?.getOptionalNumber('scaffolder.auditor.taskParameterMaxLength') ??\n DEFAULT_TASK_PARAMETER_MAX_LENGTH;\n\n if (!Number.isSafeInteger(maxLength) || maxLength < -1) {\n throw new InputError(\n `Invalid configuration for 'scaffolder.auditor.taskParameterMaxLength', got ${maxLength}. Must be a positive integer or -1 to disable truncation.`,\n );\n }\n\n if (maxLength === -1) {\n return (parameters: JsonObject) => parameters;\n }\n\n return (parameters: JsonObject) => {\n function truncate(value: unknown): unknown {\n if (typeof value === 'string') {\n if (value.length > maxLength) {\n return value.slice(0, maxLength).concat('...<truncated>');\n }\n return value;\n }\n if (Array.isArray(value)) {\n return value.map(truncate);\n }\n if (value && typeof value === 'object') {\n const result: Record<string, unknown> = {};\n for (const k in value as object) {\n if (Object.hasOwn(value, k)) {\n result[k] = truncate((value as any)[k]);\n }\n }\n return result;\n }\n return value;\n }\n\n return truncate(parameters) as JsonObject;\n };\n}\n"],"names":["PQueue","NunjucksWorkflowRunner","stringifyError","setTimeout","assertError","InputError"],"mappings":"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"}
1
+ {"version":3,"file":"TaskWorker.cjs.js","sources":["../../../src/scaffolder/tasks/TaskWorker.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 { AuditorService, LoggerService } from '@backstage/backend-plugin-api';\nimport { assertError, InputError, stringifyError } from '@backstage/errors';\nimport { ScmIntegrations } from '@backstage/integration';\nimport { PermissionEvaluator } from '@backstage/plugin-permission-common';\nimport {\n TaskBroker,\n TaskContext,\n TemplateFilter,\n TemplateGlobal,\n} from '@backstage/plugin-scaffolder-node';\nimport PQueue from 'p-queue';\nimport { TemplateActionRegistry } from '../actions/TemplateActionRegistry';\nimport { NunjucksWorkflowRunner } from './NunjucksWorkflowRunner';\nimport { WorkflowRunner } from './types';\nimport { setTimeout } from 'timers/promises';\nimport { JsonObject } from '@backstage/types';\nimport { Config } from '@backstage/config';\n\nconst DEFAULT_TASK_PARAMETER_MAX_LENGTH = 256;\n\n/**\n * TaskWorkerOptions\n */\nexport type TaskWorkerOptions = {\n taskBroker: TaskBroker;\n runners: {\n workflowRunner: WorkflowRunner;\n };\n concurrentTasksLimit: number;\n permissions?: PermissionEvaluator;\n logger?: LoggerService;\n auditor?: AuditorService;\n config?: Config;\n gracefulShutdown?: boolean;\n};\n\n/**\n * CreateWorkerOptions\n */\nexport type CreateWorkerOptions = {\n taskBroker: TaskBroker;\n actionRegistry: TemplateActionRegistry;\n integrations: ScmIntegrations;\n workingDirectory: string;\n logger: LoggerService;\n auditor?: AuditorService;\n config?: Config;\n additionalTemplateFilters?: Record<string, TemplateFilter>;\n /**\n * The number of tasks that can be executed at the same time by the worker\n * @defaultValue 10\n * @example\n * ```\n * {\n * concurrentTasksLimit: 1,\n * // OR\n * concurrentTasksLimit: Infinity\n * }\n * ```\n */\n concurrentTasksLimit?: number;\n additionalTemplateGlobals?: Record<string, TemplateGlobal>;\n permissions?: PermissionEvaluator;\n gracefulShutdown?: boolean;\n};\n\n/**\n * TaskWorker\n */\nexport class TaskWorker {\n private taskQueue: PQueue;\n private logger: LoggerService | undefined;\n private auditor: AuditorService | undefined;\n private parameterAuditTransform: ParameterAuditTransform;\n private stopWorkers: boolean;\n\n private readonly options: TaskWorkerOptions & {\n parameterAuditTransform: ParameterAuditTransform;\n };\n\n private constructor(\n options: TaskWorkerOptions & {\n parameterAuditTransform: ParameterAuditTransform;\n },\n ) {\n this.options = options;\n this.stopWorkers = false;\n this.logger = options.logger;\n this.auditor = options.auditor;\n this.taskQueue = new PQueue({\n concurrency: options.concurrentTasksLimit,\n });\n this.parameterAuditTransform = options.parameterAuditTransform;\n }\n\n static async create(options: CreateWorkerOptions): Promise<TaskWorker> {\n const {\n taskBroker,\n logger,\n auditor,\n config,\n actionRegistry,\n integrations,\n workingDirectory,\n additionalTemplateFilters,\n concurrentTasksLimit = 10, // from 1 to Infinity\n additionalTemplateGlobals,\n permissions,\n gracefulShutdown,\n } = options;\n\n const workflowRunner = new NunjucksWorkflowRunner({\n actionRegistry,\n integrations,\n logger,\n auditor,\n workingDirectory,\n additionalTemplateFilters,\n additionalTemplateGlobals,\n permissions,\n });\n\n return new TaskWorker({\n taskBroker: taskBroker,\n runners: { workflowRunner },\n concurrentTasksLimit,\n permissions,\n auditor,\n config,\n gracefulShutdown,\n parameterAuditTransform: createParameterTruncator(config),\n });\n }\n\n async recoverTasks() {\n try {\n await this.options.taskBroker.recoverTasks?.();\n } catch (err) {\n this.logger?.error(stringifyError(err));\n }\n }\n\n start() {\n (async () => {\n while (!this.stopWorkers) {\n await setTimeout(10000);\n await this.recoverTasks();\n }\n })();\n (async () => {\n while (!this.stopWorkers) {\n await this.onReadyToClaimTask();\n if (!this.stopWorkers) {\n const task = await this.options.taskBroker.claim();\n void this.taskQueue.add(() => this.runOneTask(task));\n }\n }\n })();\n }\n\n async stop() {\n this.stopWorkers = true;\n if (this.options?.gracefulShutdown) {\n while (this.taskQueue.size > 0) {\n await setTimeout(1000);\n }\n }\n }\n\n protected onReadyToClaimTask(): Promise<void> {\n if (this.taskQueue.pending < this.options.concurrentTasksLimit) {\n return Promise.resolve();\n }\n return new Promise(resolve => {\n // \"next\" event emits when a task completes\n // https://github.com/sindresorhus/p-queue#next\n this.taskQueue.once('next', () => {\n resolve();\n });\n });\n }\n\n async runOneTask(task: TaskContext) {\n const auditorEvent = await this.auditor?.createEvent({\n eventId: 'task',\n severityLevel: 'medium',\n meta: {\n actionType: 'execution',\n createdBy: task.createdBy,\n taskId: task.taskId,\n taskParameters: this.parameterAuditTransform(task.spec.parameters),\n templateRef: task.spec.templateInfo?.entityRef,\n },\n });\n\n try {\n if (task.spec.apiVersion !== 'scaffolder.backstage.io/v1beta3') {\n throw new Error(\n `Unsupported Template apiVersion ${task.spec.apiVersion}`,\n );\n }\n\n const { output } = await this.options.runners.workflowRunner.execute(\n task,\n );\n\n await task.complete('completed', { output });\n await auditorEvent?.success();\n } catch (error) {\n assertError(error);\n await auditorEvent?.fail({\n error,\n });\n await task.complete('failed', {\n error: { name: error.name, message: error.message },\n });\n }\n }\n}\n\ntype ParameterAuditTransform = (parameters: JsonObject) => JsonObject;\n\n/**\n * Truncates task parameters for audit logging using the configured max length.\n * @internal\n */\nexport function createParameterTruncator(\n config?: Config,\n): ParameterAuditTransform {\n const maxLength =\n config?.getOptionalNumber('scaffolder.auditor.taskParameterMaxLength') ??\n DEFAULT_TASK_PARAMETER_MAX_LENGTH;\n\n if (!Number.isSafeInteger(maxLength) || maxLength < -1) {\n throw new InputError(\n `Invalid configuration for 'scaffolder.auditor.taskParameterMaxLength', got ${maxLength}. Must be a positive integer or -1 to disable truncation.`,\n );\n }\n\n if (maxLength === -1) {\n return (parameters: JsonObject) => parameters;\n }\n\n return (parameters: JsonObject) => {\n function truncate(value: unknown): unknown {\n if (typeof value === 'string') {\n if (value.length > maxLength) {\n return value.slice(0, maxLength).concat('...<truncated>');\n }\n return value;\n }\n if (Array.isArray(value)) {\n return value.map(truncate);\n }\n if (value && typeof value === 'object') {\n const result: Record<string, unknown> = {};\n for (const k in value as object) {\n if (Object.hasOwn(value, k)) {\n result[k] = truncate((value as any)[k]);\n }\n }\n return result;\n }\n return value;\n }\n\n return truncate(parameters) as JsonObject;\n };\n}\n"],"names":["PQueue","NunjucksWorkflowRunner","stringifyError","setTimeout","assertError","InputError"],"mappings":"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"}
@@ -8,11 +8,6 @@ function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'defau
8
8
  var fs__default = /*#__PURE__*/_interopDefaultCompat(fs);
9
9
 
10
10
  class DefaultWorkspaceService {
11
- constructor(task, workspaceProvider, config) {
12
- this.task = task;
13
- this.workspaceProvider = workspaceProvider;
14
- this.config = config;
15
- }
16
11
  static create(task, storage, additionalWorkspaceProviders, config) {
17
12
  const workspaceProviderName = config?.getOptionalString(
18
13
  "scaffolder.EXPERIMENTAL_workspaceSerializationProvider"
@@ -20,6 +15,14 @@ class DefaultWorkspaceService {
20
15
  const workspaceProvider = additionalWorkspaceProviders?.[workspaceProviderName] ?? DatabaseWorkspaceProvider.DatabaseWorkspaceProvider.create(storage);
21
16
  return new DefaultWorkspaceService(task, workspaceProvider, config);
22
17
  }
18
+ task;
19
+ workspaceProvider;
20
+ config;
21
+ constructor(task, workspaceProvider, config) {
22
+ this.task = task;
23
+ this.workspaceProvider = workspaceProvider;
24
+ this.config = config;
25
+ }
23
26
  async serializeWorkspace(options) {
24
27
  if (this.isWorkspaceSerializationEnabled()) {
25
28
  await this.workspaceProvider.serializeWorkspace({
@@ -1 +1 @@
1
- {"version":3,"file":"WorkspaceService.cjs.js","sources":["../../../src/scaffolder/tasks/WorkspaceService.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 { Config } from '@backstage/config';\nimport { CurrentClaimedTask } from './StorageTaskBroker';\nimport { WorkspaceProvider } from '@backstage/plugin-scaffolder-node/alpha';\nimport { DatabaseWorkspaceProvider } from './DatabaseWorkspaceProvider';\nimport { TaskStore } from './types';\nimport fs from 'fs-extra';\n\nexport interface WorkspaceService {\n serializeWorkspace(options: { path: string }): Promise<void>;\n\n cleanWorkspace(): Promise<void>;\n\n rehydrateWorkspace(options: {\n taskId: string;\n targetPath: string;\n }): Promise<void>;\n}\n\nexport class DefaultWorkspaceService implements WorkspaceService {\n static create(\n task: CurrentClaimedTask,\n storage: TaskStore,\n additionalWorkspaceProviders?: Record<string, WorkspaceProvider>,\n config?: Config,\n ) {\n const workspaceProviderName =\n config?.getOptionalString(\n 'scaffolder.EXPERIMENTAL_workspaceSerializationProvider',\n ) ?? 'database';\n const workspaceProvider =\n additionalWorkspaceProviders?.[workspaceProviderName] ??\n DatabaseWorkspaceProvider.create(storage);\n return new DefaultWorkspaceService(task, workspaceProvider, config);\n }\n\n private constructor(\n private readonly task: CurrentClaimedTask,\n private readonly workspaceProvider: WorkspaceProvider,\n private readonly config?: Config,\n ) {}\n\n public async serializeWorkspace(options: { path: string }): Promise<void> {\n if (this.isWorkspaceSerializationEnabled()) {\n await this.workspaceProvider.serializeWorkspace({\n path: options.path,\n taskId: this.task.taskId,\n });\n }\n }\n\n public async cleanWorkspace(): Promise<void> {\n if (this.isWorkspaceSerializationEnabled()) {\n await this.workspaceProvider.cleanWorkspace({ taskId: this.task.taskId });\n }\n }\n\n public async rehydrateWorkspace(options: {\n taskId: string;\n targetPath: string;\n }): Promise<void> {\n if (this.isWorkspaceSerializationEnabled()) {\n await fs.mkdirp(options.targetPath);\n await this.workspaceProvider.rehydrateWorkspace(options);\n }\n }\n\n private isWorkspaceSerializationEnabled(): boolean {\n return (\n this.config?.getOptionalBoolean(\n 'scaffolder.EXPERIMENTAL_workspaceSerialization',\n ) ?? false\n );\n }\n}\n"],"names":["DatabaseWorkspaceProvider","fs"],"mappings":";;;;;;;;;AAkCO,MAAM,uBAAA,CAAoD;AAAA,EAiBvD,WAAA,CACW,IAAA,EACA,iBAAA,EACA,MAAA,EACjB;AAHiB,IAAA,IAAA,CAAA,IAAA,GAAA,IAAA;AACA,IAAA,IAAA,CAAA,iBAAA,GAAA,iBAAA;AACA,IAAA,IAAA,CAAA,MAAA,GAAA,MAAA;AAAA,EAChB;AAAA,EApBH,OAAO,MAAA,CACL,IAAA,EACA,OAAA,EACA,8BACA,MAAA,EACA;AACA,IAAA,MAAM,wBACJ,MAAA,EAAQ,iBAAA;AAAA,MACN;AAAA,KACF,IAAK,UAAA;AACP,IAAA,MAAM,oBACJ,4BAAA,GAA+B,qBAAqB,CAAA,IACpDA,mDAAA,CAA0B,OAAO,OAAO,CAAA;AAC1C,IAAA,OAAO,IAAI,uBAAA,CAAwB,IAAA,EAAM,iBAAA,EAAmB,MAAM,CAAA;AAAA,EACpE;AAAA,EAQA,MAAa,mBAAmB,OAAA,EAA0C;AACxE,IAAA,IAAI,IAAA,CAAK,iCAAgC,EAAG;AAC1C,MAAA,MAAM,IAAA,CAAK,kBAAkB,kBAAA,CAAmB;AAAA,QAC9C,MAAM,OAAA,CAAQ,IAAA;AAAA,QACd,MAAA,EAAQ,KAAK,IAAA,CAAK;AAAA,OACnB,CAAA;AAAA,IACH;AAAA,EACF;AAAA,EAEA,MAAa,cAAA,GAAgC;AAC3C,IAAA,IAAI,IAAA,CAAK,iCAAgC,EAAG;AAC1C,MAAA,MAAM,IAAA,CAAK,kBAAkB,cAAA,CAAe,EAAE,QAAQ,IAAA,CAAK,IAAA,CAAK,QAAQ,CAAA;AAAA,IAC1E;AAAA,EACF;AAAA,EAEA,MAAa,mBAAmB,OAAA,EAGd;AAChB,IAAA,IAAI,IAAA,CAAK,iCAAgC,EAAG;AAC1C,MAAA,MAAMC,mBAAA,CAAG,MAAA,CAAO,OAAA,CAAQ,UAAU,CAAA;AAClC,MAAA,MAAM,IAAA,CAAK,iBAAA,CAAkB,kBAAA,CAAmB,OAAO,CAAA;AAAA,IACzD;AAAA,EACF;AAAA,EAEQ,+BAAA,GAA2C;AACjD,IAAA,OACE,KAAK,MAAA,EAAQ,kBAAA;AAAA,MACX;AAAA,KACF,IAAK,KAAA;AAAA,EAET;AACF;;;;"}
1
+ {"version":3,"file":"WorkspaceService.cjs.js","sources":["../../../src/scaffolder/tasks/WorkspaceService.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 { Config } from '@backstage/config';\nimport { CurrentClaimedTask } from './StorageTaskBroker';\nimport { WorkspaceProvider } from '@backstage/plugin-scaffolder-node/alpha';\nimport { DatabaseWorkspaceProvider } from './DatabaseWorkspaceProvider';\nimport { TaskStore } from './types';\nimport fs from 'fs-extra';\n\nexport interface WorkspaceService {\n serializeWorkspace(options: { path: string }): Promise<void>;\n\n cleanWorkspace(): Promise<void>;\n\n rehydrateWorkspace(options: {\n taskId: string;\n targetPath: string;\n }): Promise<void>;\n}\n\nexport class DefaultWorkspaceService implements WorkspaceService {\n static create(\n task: CurrentClaimedTask,\n storage: TaskStore,\n additionalWorkspaceProviders?: Record<string, WorkspaceProvider>,\n config?: Config,\n ) {\n const workspaceProviderName =\n config?.getOptionalString(\n 'scaffolder.EXPERIMENTAL_workspaceSerializationProvider',\n ) ?? 'database';\n const workspaceProvider =\n additionalWorkspaceProviders?.[workspaceProviderName] ??\n DatabaseWorkspaceProvider.create(storage);\n return new DefaultWorkspaceService(task, workspaceProvider, config);\n }\n\n private readonly task: CurrentClaimedTask;\n private readonly workspaceProvider: WorkspaceProvider;\n private readonly config?: Config;\n\n private constructor(\n task: CurrentClaimedTask,\n workspaceProvider: WorkspaceProvider,\n config?: Config,\n ) {\n this.task = task;\n this.workspaceProvider = workspaceProvider;\n this.config = config;\n }\n\n public async serializeWorkspace(options: { path: string }): Promise<void> {\n if (this.isWorkspaceSerializationEnabled()) {\n await this.workspaceProvider.serializeWorkspace({\n path: options.path,\n taskId: this.task.taskId,\n });\n }\n }\n\n public async cleanWorkspace(): Promise<void> {\n if (this.isWorkspaceSerializationEnabled()) {\n await this.workspaceProvider.cleanWorkspace({ taskId: this.task.taskId });\n }\n }\n\n public async rehydrateWorkspace(options: {\n taskId: string;\n targetPath: string;\n }): Promise<void> {\n if (this.isWorkspaceSerializationEnabled()) {\n await fs.mkdirp(options.targetPath);\n await this.workspaceProvider.rehydrateWorkspace(options);\n }\n }\n\n private isWorkspaceSerializationEnabled(): boolean {\n return (\n this.config?.getOptionalBoolean(\n 'scaffolder.EXPERIMENTAL_workspaceSerialization',\n ) ?? false\n );\n }\n}\n"],"names":["DatabaseWorkspaceProvider","fs"],"mappings":";;;;;;;;;AAkCO,MAAM,uBAAA,CAAoD;AAAA,EAC/D,OAAO,MAAA,CACL,IAAA,EACA,OAAA,EACA,8BACA,MAAA,EACA;AACA,IAAA,MAAM,wBACJ,MAAA,EAAQ,iBAAA;AAAA,MACN;AAAA,KACF,IAAK,UAAA;AACP,IAAA,MAAM,oBACJ,4BAAA,GAA+B,qBAAqB,CAAA,IACpDA,mDAAA,CAA0B,OAAO,OAAO,CAAA;AAC1C,IAAA,OAAO,IAAI,uBAAA,CAAwB,IAAA,EAAM,iBAAA,EAAmB,MAAM,CAAA;AAAA,EACpE;AAAA,EAEiB,IAAA;AAAA,EACA,iBAAA;AAAA,EACA,MAAA;AAAA,EAET,WAAA,CACN,IAAA,EACA,iBAAA,EACA,MAAA,EACA;AACA,IAAA,IAAA,CAAK,IAAA,GAAO,IAAA;AACZ,IAAA,IAAA,CAAK,iBAAA,GAAoB,iBAAA;AACzB,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AAAA,EAChB;AAAA,EAEA,MAAa,mBAAmB,OAAA,EAA0C;AACxE,IAAA,IAAI,IAAA,CAAK,iCAAgC,EAAG;AAC1C,MAAA,MAAM,IAAA,CAAK,kBAAkB,kBAAA,CAAmB;AAAA,QAC9C,MAAM,OAAA,CAAQ,IAAA;AAAA,QACd,MAAA,EAAQ,KAAK,IAAA,CAAK;AAAA,OACnB,CAAA;AAAA,IACH;AAAA,EACF;AAAA,EAEA,MAAa,cAAA,GAAgC;AAC3C,IAAA,IAAI,IAAA,CAAK,iCAAgC,EAAG;AAC1C,MAAA,MAAM,IAAA,CAAK,kBAAkB,cAAA,CAAe,EAAE,QAAQ,IAAA,CAAK,IAAA,CAAK,QAAQ,CAAA;AAAA,IAC1E;AAAA,EACF;AAAA,EAEA,MAAa,mBAAmB,OAAA,EAGd;AAChB,IAAA,IAAI,IAAA,CAAK,iCAAgC,EAAG;AAC1C,MAAA,MAAMC,mBAAA,CAAG,MAAA,CAAO,OAAA,CAAQ,UAAU,CAAA;AAClC,MAAA,MAAM,IAAA,CAAK,iBAAA,CAAkB,kBAAA,CAAmB,OAAO,CAAA;AAAA,IACzD;AAAA,EACF;AAAA,EAEQ,+BAAA,GAA2C;AACjD,IAAA,OACE,KAAK,MAAA,EAAQ,kBAAA;AAAA,MACX;AAAA,KACF,IAAK,KAAA;AAAA,EAET;AACF;;;;"}
@@ -12,6 +12,9 @@ const escapeRegExp = (text) => {
12
12
  return text.replace(/[.*+?^${}(\)|[\]\\]/g, "\\$&");
13
13
  };
14
14
  class BackstageLoggerTransport extends Transport__default.default {
15
+ backstageLogger;
16
+ taskContext;
17
+ stepId;
15
18
  constructor(backstageLogger, taskContext, stepId, opts) {
16
19
  super(opts);
17
20
  this.backstageLogger = backstageLogger;
@@ -1 +1 @@
1
- {"version":3,"file":"logger.cjs.js","sources":["../../../src/scaffolder/tasks/logger.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 */\nimport {\n LoggerService,\n RootLoggerService,\n} from '@backstage/backend-plugin-api';\nimport { JsonObject } from '@backstage/types';\nimport { Format, TransformableInfo } from 'logform';\nimport Transport, { TransportStreamOptions } from 'winston-transport';\nimport { Logger, format, createLogger, transports } from 'winston';\nimport { LEVEL, MESSAGE, SPLAT } from 'triple-beam';\nimport { TaskContext } from '@backstage/plugin-scaffolder-node';\nimport _ from 'lodash';\n\n/**\n * Escapes a given string to be used inside a RegExp.\n *\n * Taken from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions\n */\nconst escapeRegExp = (text: string) => {\n return text.replace(/[.*+?^${}(\\)|[\\]\\\\]/g, '\\\\$&');\n};\n\ninterface WinstonLoggerOptions {\n meta?: JsonObject;\n level: string;\n format: Format;\n transports: Transport[];\n}\n\n// This is a workaround for being able to preserve the log format of the root logger.\n// Will revisit all of this implementation once we can break the router to use only `LoggerService`.\nexport class BackstageLoggerTransport extends Transport {\n constructor(\n private readonly backstageLogger: LoggerService,\n private readonly taskContext: TaskContext,\n private readonly stepId: string,\n opts?: TransportStreamOptions,\n ) {\n super(opts);\n }\n\n log(info: TransformableInfo, callback: VoidFunction) {\n if (typeof info !== 'object' || info === null) {\n callback();\n return;\n }\n\n const message = info[MESSAGE];\n const level = info[LEVEL];\n\n switch (level) {\n case 'error':\n this.backstageLogger.error(String(message));\n break;\n case 'warn':\n this.backstageLogger.warn(String(message));\n break;\n case 'info':\n this.backstageLogger.info(String(message));\n break;\n case 'debug':\n this.backstageLogger.debug(String(message));\n break;\n default:\n this.backstageLogger.info(String(message));\n }\n\n this.taskContext.emitLog(message, { stepId: this.stepId });\n callback();\n }\n}\n\nexport class WinstonLogger implements RootLoggerService {\n #winston: Logger;\n #addRedactions?: (redactions: Iterable<string>) => void;\n\n /**\n * Creates a {@link WinstonLogger} instance.\n */\n static create(options: WinstonLoggerOptions): WinstonLogger {\n const redacter = WinstonLogger.redacter();\n\n let logger = createLogger({\n level: options.level,\n format: format.combine(options.format, redacter.format),\n transports: options.transports ?? new transports.Console(),\n });\n\n if (options.meta) {\n logger = logger.child(options.meta);\n }\n\n return new WinstonLogger(logger, redacter.add);\n }\n\n /**\n * Creates a winston log formatter for redacting secrets.\n */\n static redacter(): {\n format: Format;\n add: (redactions: Iterable<string>) => void;\n } {\n const redactionSet = new Set<string>();\n\n let redactionPattern: RegExp | undefined = undefined;\n\n return {\n format: format((obj: TransformableInfo) => {\n if (!redactionPattern || !obj) {\n return obj;\n }\n\n obj[MESSAGE] = obj[MESSAGE]?.replace?.(redactionPattern, '***');\n\n return obj;\n })(),\n add(newRedactions) {\n let added = 0;\n for (const redactionToTrim of newRedactions) {\n // Skip null or undefined values\n if (redactionToTrim === null || redactionToTrim === undefined) {\n continue;\n }\n // Trimming the string ensures that we don't accdentally get extra\n // newlines or other whitespace interfering with the redaction; this\n // can happen for example when using string literals in yaml\n const redaction = redactionToTrim.trim();\n // Exclude secrets that are empty or just one character in length. These\n // typically mean that you are running local dev or tests, or using the\n // --lax flag which sets things to just 'x'.\n if (redaction.length <= 1) {\n continue;\n }\n if (!redactionSet.has(redaction)) {\n redactionSet.add(redaction);\n added += 1;\n }\n }\n if (added > 0) {\n const redactions = Array.from(redactionSet)\n .map(r => escapeRegExp(r))\n .join('|');\n redactionPattern = new RegExp(`(${redactions})`, 'g');\n }\n },\n };\n }\n\n /**\n * Creates a pretty printed winston log formatter.\n */\n static colorFormat(): Format {\n const colorizer = format.colorize();\n\n return format.combine(\n format.timestamp(),\n format.colorize({\n colors: {\n timestamp: 'dim',\n prefix: 'blue',\n field: 'cyan',\n debug: 'grey',\n },\n }),\n format.printf((info: TransformableInfo) => {\n const { timestamp, plugin, service } = info;\n const message = info[MESSAGE];\n const level = info[LEVEL];\n const fields = info[SPLAT];\n const prefix = plugin || service;\n const timestampColor = colorizer.colorize('timestamp', timestamp);\n const prefixColor = colorizer.colorize('prefix', prefix);\n\n const extraFields = Object.entries(fields)\n .map(\n ([key, value]) =>\n `${colorizer.colorize('field', `${key}`)}=${value}`,\n )\n .join(' ');\n\n return `${timestampColor} ${prefixColor} ${level} ${message} ${extraFields}`;\n }),\n );\n }\n\n private constructor(\n winston: Logger,\n addRedactions?: (redactions: Iterable<string>) => void,\n ) {\n this.#winston = winston;\n this.#addRedactions = addRedactions;\n }\n\n error(message: string, meta?: JsonObject): void {\n this.#winston.error(message, meta);\n }\n\n warn(message: string, meta?: JsonObject): void {\n this.#winston.warn(message, meta);\n }\n\n info(message: string, meta?: JsonObject): void {\n this.#winston.info(message, meta);\n }\n\n debug(message: string, meta?: JsonObject): void {\n this.#winston.debug(message, meta);\n }\n\n child(meta: JsonObject): LoggerService {\n return new WinstonLogger(this.#winston.child(meta));\n }\n\n addRedactions(redactions: Iterable<string>) {\n this.#addRedactions?.(redactions);\n }\n}\n"],"names":["Transport","MESSAGE","LEVEL","createLogger","format","transports","SPLAT"],"mappings":"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"}
1
+ {"version":3,"file":"logger.cjs.js","sources":["../../../src/scaffolder/tasks/logger.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 */\nimport {\n LoggerService,\n RootLoggerService,\n} from '@backstage/backend-plugin-api';\nimport { JsonObject } from '@backstage/types';\nimport { Format, TransformableInfo } from 'logform';\nimport Transport, { TransportStreamOptions } from 'winston-transport';\nimport { Logger, format, createLogger, transports } from 'winston';\nimport { LEVEL, MESSAGE, SPLAT } from 'triple-beam';\nimport { TaskContext } from '@backstage/plugin-scaffolder-node';\nimport _ from 'lodash';\n\n/**\n * Escapes a given string to be used inside a RegExp.\n *\n * Taken from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions\n */\nconst escapeRegExp = (text: string) => {\n return text.replace(/[.*+?^${}(\\)|[\\]\\\\]/g, '\\\\$&');\n};\n\ninterface WinstonLoggerOptions {\n meta?: JsonObject;\n level: string;\n format: Format;\n transports: Transport[];\n}\n\n// This is a workaround for being able to preserve the log format of the root logger.\n// Will revisit all of this implementation once we can break the router to use only `LoggerService`.\nexport class BackstageLoggerTransport extends Transport {\n private readonly backstageLogger: LoggerService;\n private readonly taskContext: TaskContext;\n private readonly stepId: string;\n\n constructor(\n backstageLogger: LoggerService,\n taskContext: TaskContext,\n stepId: string,\n opts?: TransportStreamOptions,\n ) {\n super(opts);\n this.backstageLogger = backstageLogger;\n this.taskContext = taskContext;\n this.stepId = stepId;\n }\n\n log(info: TransformableInfo, callback: VoidFunction) {\n if (typeof info !== 'object' || info === null) {\n callback();\n return;\n }\n\n const message = info[MESSAGE];\n const level = info[LEVEL];\n\n switch (level) {\n case 'error':\n this.backstageLogger.error(String(message));\n break;\n case 'warn':\n this.backstageLogger.warn(String(message));\n break;\n case 'info':\n this.backstageLogger.info(String(message));\n break;\n case 'debug':\n this.backstageLogger.debug(String(message));\n break;\n default:\n this.backstageLogger.info(String(message));\n }\n\n this.taskContext.emitLog(message, { stepId: this.stepId });\n callback();\n }\n}\n\nexport class WinstonLogger implements RootLoggerService {\n #winston: Logger;\n #addRedactions?: (redactions: Iterable<string>) => void;\n\n /**\n * Creates a {@link WinstonLogger} instance.\n */\n static create(options: WinstonLoggerOptions): WinstonLogger {\n const redacter = WinstonLogger.redacter();\n\n let logger = createLogger({\n level: options.level,\n format: format.combine(options.format, redacter.format),\n transports: options.transports ?? new transports.Console(),\n });\n\n if (options.meta) {\n logger = logger.child(options.meta);\n }\n\n return new WinstonLogger(logger, redacter.add);\n }\n\n /**\n * Creates a winston log formatter for redacting secrets.\n */\n static redacter(): {\n format: Format;\n add: (redactions: Iterable<string>) => void;\n } {\n const redactionSet = new Set<string>();\n\n let redactionPattern: RegExp | undefined = undefined;\n\n return {\n format: format((obj: TransformableInfo) => {\n if (!redactionPattern || !obj) {\n return obj;\n }\n\n obj[MESSAGE] = obj[MESSAGE]?.replace?.(redactionPattern, '***');\n\n return obj;\n })(),\n add(newRedactions) {\n let added = 0;\n for (const redactionToTrim of newRedactions) {\n // Skip null or undefined values\n if (redactionToTrim === null || redactionToTrim === undefined) {\n continue;\n }\n // Trimming the string ensures that we don't accdentally get extra\n // newlines or other whitespace interfering with the redaction; this\n // can happen for example when using string literals in yaml\n const redaction = redactionToTrim.trim();\n // Exclude secrets that are empty or just one character in length. These\n // typically mean that you are running local dev or tests, or using the\n // --lax flag which sets things to just 'x'.\n if (redaction.length <= 1) {\n continue;\n }\n if (!redactionSet.has(redaction)) {\n redactionSet.add(redaction);\n added += 1;\n }\n }\n if (added > 0) {\n const redactions = Array.from(redactionSet)\n .map(r => escapeRegExp(r))\n .join('|');\n redactionPattern = new RegExp(`(${redactions})`, 'g');\n }\n },\n };\n }\n\n /**\n * Creates a pretty printed winston log formatter.\n */\n static colorFormat(): Format {\n const colorizer = format.colorize();\n\n return format.combine(\n format.timestamp(),\n format.colorize({\n colors: {\n timestamp: 'dim',\n prefix: 'blue',\n field: 'cyan',\n debug: 'grey',\n },\n }),\n format.printf((info: TransformableInfo) => {\n const { timestamp, plugin, service } = info;\n const message = info[MESSAGE];\n const level = info[LEVEL];\n const fields = info[SPLAT];\n const prefix = plugin || service;\n const timestampColor = colorizer.colorize('timestamp', timestamp);\n const prefixColor = colorizer.colorize('prefix', prefix);\n\n const extraFields = Object.entries(fields)\n .map(\n ([key, value]) =>\n `${colorizer.colorize('field', `${key}`)}=${value}`,\n )\n .join(' ');\n\n return `${timestampColor} ${prefixColor} ${level} ${message} ${extraFields}`;\n }),\n );\n }\n\n private constructor(\n winston: Logger,\n addRedactions?: (redactions: Iterable<string>) => void,\n ) {\n this.#winston = winston;\n this.#addRedactions = addRedactions;\n }\n\n error(message: string, meta?: JsonObject): void {\n this.#winston.error(message, meta);\n }\n\n warn(message: string, meta?: JsonObject): void {\n this.#winston.warn(message, meta);\n }\n\n info(message: string, meta?: JsonObject): void {\n this.#winston.info(message, meta);\n }\n\n debug(message: string, meta?: JsonObject): void {\n this.#winston.debug(message, meta);\n }\n\n child(meta: JsonObject): LoggerService {\n return new WinstonLogger(this.#winston.child(meta));\n }\n\n addRedactions(redactions: Iterable<string>) {\n this.#addRedactions?.(redactions);\n }\n}\n"],"names":["Transport","MESSAGE","LEVEL","createLogger","format","transports","SPLAT"],"mappings":"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"}
@@ -8,6 +8,7 @@ function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'defau
8
8
  var Transport__default = /*#__PURE__*/_interopDefaultCompat(Transport);
9
9
 
10
10
  class BackstageLoggerTransport extends Transport__default.default {
11
+ backstageLogger;
11
12
  constructor(backstageLogger, opts) {
12
13
  super(opts);
13
14
  this.backstageLogger = backstageLogger;
@@ -1 +1 @@
1
- {"version":3,"file":"loggerToWinstonLogger.cjs.js","sources":["../../src/util/loggerToWinstonLogger.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 { LoggerService } from '@backstage/backend-plugin-api';\nimport { JsonObject } from '@backstage/types';\nimport { Logger as WinstonLogger, createLogger } from 'winston';\nimport Transport, { TransportStreamOptions } from 'winston-transport';\n\nclass BackstageLoggerTransport extends Transport {\n constructor(\n private readonly backstageLogger: LoggerService,\n opts?: TransportStreamOptions,\n ) {\n super(opts);\n }\n\n log(info: unknown, callback: VoidFunction) {\n if (typeof info !== 'object' || info === null) {\n callback();\n return;\n }\n const { level, message, ...meta } = info as JsonObject;\n switch (level) {\n case 'error':\n this.backstageLogger.error(String(message), meta);\n break;\n case 'warn':\n this.backstageLogger.warn(String(message), meta);\n break;\n case 'info':\n this.backstageLogger.info(String(message), meta);\n break;\n case 'debug':\n this.backstageLogger.debug(String(message), meta);\n break;\n default:\n this.backstageLogger.info(String(message), meta);\n }\n callback();\n }\n}\n\n/**\n * A helper function to convert a Backstage LoggerService to a Winston Logger.\n * @internal\n */\nexport function loggerToWinstonLogger(\n logger: LoggerService,\n opts?: TransportStreamOptions,\n): WinstonLogger {\n return createLogger({\n transports: [new BackstageLoggerTransport(logger, opts)],\n });\n}\n"],"names":["Transport","createLogger"],"mappings":";;;;;;;;;AAqBA,MAAM,iCAAiCA,0BAAA,CAAU;AAAA,EAC/C,WAAA,CACmB,iBACjB,IAAA,EACA;AACA,IAAA,KAAA,CAAM,IAAI,CAAA;AAHO,IAAA,IAAA,CAAA,eAAA,GAAA,eAAA;AAAA,EAInB;AAAA,EAEA,GAAA,CAAI,MAAe,QAAA,EAAwB;AACzC,IAAA,IAAI,OAAO,IAAA,KAAS,QAAA,IAAY,IAAA,KAAS,IAAA,EAAM;AAC7C,MAAA,QAAA,EAAS;AACT,MAAA;AAAA,IACF;AACA,IAAA,MAAM,EAAE,KAAA,EAAO,OAAA,EAAS,GAAG,MAAK,GAAI,IAAA;AACpC,IAAA,QAAQ,KAAA;AAAO,MACb,KAAK,OAAA;AACH,QAAA,IAAA,CAAK,eAAA,CAAgB,KAAA,CAAM,MAAA,CAAO,OAAO,GAAG,IAAI,CAAA;AAChD,QAAA;AAAA,MACF,KAAK,MAAA;AACH,QAAA,IAAA,CAAK,eAAA,CAAgB,IAAA,CAAK,MAAA,CAAO,OAAO,GAAG,IAAI,CAAA;AAC/C,QAAA;AAAA,MACF,KAAK,MAAA;AACH,QAAA,IAAA,CAAK,eAAA,CAAgB,IAAA,CAAK,MAAA,CAAO,OAAO,GAAG,IAAI,CAAA;AAC/C,QAAA;AAAA,MACF,KAAK,OAAA;AACH,QAAA,IAAA,CAAK,eAAA,CAAgB,KAAA,CAAM,MAAA,CAAO,OAAO,GAAG,IAAI,CAAA;AAChD,QAAA;AAAA,MACF;AACE,QAAA,IAAA,CAAK,eAAA,CAAgB,IAAA,CAAK,MAAA,CAAO,OAAO,GAAG,IAAI,CAAA;AAAA;AAEnD,IAAA,QAAA,EAAS;AAAA,EACX;AACF;AAMO,SAAS,qBAAA,CACd,QACA,IAAA,EACe;AACf,EAAA,OAAOC,oBAAA,CAAa;AAAA,IAClB,YAAY,CAAC,IAAI,wBAAA,CAAyB,MAAA,EAAQ,IAAI,CAAC;AAAA,GACxD,CAAA;AACH;;;;"}
1
+ {"version":3,"file":"loggerToWinstonLogger.cjs.js","sources":["../../src/util/loggerToWinstonLogger.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 { LoggerService } from '@backstage/backend-plugin-api';\nimport { JsonObject } from '@backstage/types';\nimport { Logger as WinstonLogger, createLogger } from 'winston';\nimport Transport, { TransportStreamOptions } from 'winston-transport';\n\nclass BackstageLoggerTransport extends Transport {\n private readonly backstageLogger: LoggerService;\n\n constructor(backstageLogger: LoggerService, opts?: TransportStreamOptions) {\n super(opts);\n this.backstageLogger = backstageLogger;\n }\n\n log(info: unknown, callback: VoidFunction) {\n if (typeof info !== 'object' || info === null) {\n callback();\n return;\n }\n const { level, message, ...meta } = info as JsonObject;\n switch (level) {\n case 'error':\n this.backstageLogger.error(String(message), meta);\n break;\n case 'warn':\n this.backstageLogger.warn(String(message), meta);\n break;\n case 'info':\n this.backstageLogger.info(String(message), meta);\n break;\n case 'debug':\n this.backstageLogger.debug(String(message), meta);\n break;\n default:\n this.backstageLogger.info(String(message), meta);\n }\n callback();\n }\n}\n\n/**\n * A helper function to convert a Backstage LoggerService to a Winston Logger.\n * @internal\n */\nexport function loggerToWinstonLogger(\n logger: LoggerService,\n opts?: TransportStreamOptions,\n): WinstonLogger {\n return createLogger({\n transports: [new BackstageLoggerTransport(logger, opts)],\n });\n}\n"],"names":["Transport","createLogger"],"mappings":";;;;;;;;;AAqBA,MAAM,iCAAiCA,0BAAA,CAAU;AAAA,EAC9B,eAAA;AAAA,EAEjB,WAAA,CAAY,iBAAgC,IAAA,EAA+B;AACzE,IAAA,KAAA,CAAM,IAAI,CAAA;AACV,IAAA,IAAA,CAAK,eAAA,GAAkB,eAAA;AAAA,EACzB;AAAA,EAEA,GAAA,CAAI,MAAe,QAAA,EAAwB;AACzC,IAAA,IAAI,OAAO,IAAA,KAAS,QAAA,IAAY,IAAA,KAAS,IAAA,EAAM;AAC7C,MAAA,QAAA,EAAS;AACT,MAAA;AAAA,IACF;AACA,IAAA,MAAM,EAAE,KAAA,EAAO,OAAA,EAAS,GAAG,MAAK,GAAI,IAAA;AACpC,IAAA,QAAQ,KAAA;AAAO,MACb,KAAK,OAAA;AACH,QAAA,IAAA,CAAK,eAAA,CAAgB,KAAA,CAAM,MAAA,CAAO,OAAO,GAAG,IAAI,CAAA;AAChD,QAAA;AAAA,MACF,KAAK,MAAA;AACH,QAAA,IAAA,CAAK,eAAA,CAAgB,IAAA,CAAK,MAAA,CAAO,OAAO,GAAG,IAAI,CAAA;AAC/C,QAAA;AAAA,MACF,KAAK,MAAA;AACH,QAAA,IAAA,CAAK,eAAA,CAAgB,IAAA,CAAK,MAAA,CAAO,OAAO,GAAG,IAAI,CAAA;AAC/C,QAAA;AAAA,MACF,KAAK,OAAA;AACH,QAAA,IAAA,CAAK,eAAA,CAAgB,KAAA,CAAM,MAAA,CAAO,OAAO,GAAG,IAAI,CAAA;AAChD,QAAA;AAAA,MACF;AACE,QAAA,IAAA,CAAK,eAAA,CAAgB,IAAA,CAAK,MAAA,CAAO,OAAO,GAAG,IAAI,CAAA;AAAA;AAEnD,IAAA,QAAA,EAAS;AAAA,EACX;AACF;AAMO,SAAS,qBAAA,CACd,QACA,IAAA,EACe;AACf,EAAA,OAAOC,oBAAA,CAAa;AAAA,IAClB,YAAY,CAAC,IAAI,wBAAA,CAAyB,MAAA,EAAQ,IAAI,CAAC;AAAA,GACxD,CAAA;AACH;;;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backstage/plugin-scaffolder-backend",
3
- "version": "3.0.0",
3
+ "version": "3.0.1-next.0",
4
4
  "description": "The Backstage backend plugin that helps you create new things",
5
5
  "backstage": {
6
6
  "role": "backend-plugin",
@@ -74,31 +74,31 @@
74
74
  "test": "backstage-cli package test"
75
75
  },
76
76
  "dependencies": {
77
- "@backstage/backend-defaults": "^0.13.0",
78
- "@backstage/backend-openapi-utils": "^0.6.2",
79
- "@backstage/backend-plugin-api": "^1.4.4",
80
- "@backstage/catalog-model": "^1.7.5",
81
- "@backstage/config": "^1.3.5",
82
- "@backstage/errors": "^1.2.7",
83
- "@backstage/integration": "^1.18.1",
84
- "@backstage/plugin-auth-node": "^0.6.8",
85
- "@backstage/plugin-bitbucket-cloud-common": "^0.3.3",
86
- "@backstage/plugin-catalog-backend-module-scaffolder-entity-model": "^0.2.13",
87
- "@backstage/plugin-catalog-node": "^1.19.1",
88
- "@backstage/plugin-events-node": "^0.4.16",
89
- "@backstage/plugin-permission-common": "^0.9.2",
90
- "@backstage/plugin-permission-node": "^0.10.5",
91
- "@backstage/plugin-scaffolder-backend-module-azure": "^0.2.14",
92
- "@backstage/plugin-scaffolder-backend-module-bitbucket": "^0.3.15",
93
- "@backstage/plugin-scaffolder-backend-module-bitbucket-cloud": "^0.2.14",
94
- "@backstage/plugin-scaffolder-backend-module-bitbucket-server": "^0.2.14",
95
- "@backstage/plugin-scaffolder-backend-module-gerrit": "^0.2.14",
96
- "@backstage/plugin-scaffolder-backend-module-gitea": "^0.2.14",
97
- "@backstage/plugin-scaffolder-backend-module-github": "^0.9.1",
98
- "@backstage/plugin-scaffolder-backend-module-gitlab": "^0.9.6",
99
- "@backstage/plugin-scaffolder-common": "^1.7.2",
100
- "@backstage/plugin-scaffolder-node": "^0.12.0",
101
- "@backstage/types": "^1.2.2",
77
+ "@backstage/backend-defaults": "0.13.1-next.0",
78
+ "@backstage/backend-openapi-utils": "0.6.3-next.0",
79
+ "@backstage/backend-plugin-api": "1.4.5-next.0",
80
+ "@backstage/catalog-model": "1.7.6-next.0",
81
+ "@backstage/config": "1.3.6-next.0",
82
+ "@backstage/errors": "1.2.7",
83
+ "@backstage/integration": "1.18.2-next.0",
84
+ "@backstage/plugin-auth-node": "0.6.9-next.0",
85
+ "@backstage/plugin-bitbucket-cloud-common": "0.3.4-next.0",
86
+ "@backstage/plugin-catalog-backend-module-scaffolder-entity-model": "0.2.14-next.0",
87
+ "@backstage/plugin-catalog-node": "1.19.2-next.0",
88
+ "@backstage/plugin-events-node": "0.4.17-next.0",
89
+ "@backstage/plugin-permission-common": "0.9.3-next.0",
90
+ "@backstage/plugin-permission-node": "0.10.6-next.0",
91
+ "@backstage/plugin-scaffolder-backend-module-azure": "0.2.15-next.0",
92
+ "@backstage/plugin-scaffolder-backend-module-bitbucket": "0.3.16-next.0",
93
+ "@backstage/plugin-scaffolder-backend-module-bitbucket-cloud": "0.2.15-next.0",
94
+ "@backstage/plugin-scaffolder-backend-module-bitbucket-server": "0.2.15-next.0",
95
+ "@backstage/plugin-scaffolder-backend-module-gerrit": "0.2.15-next.0",
96
+ "@backstage/plugin-scaffolder-backend-module-gitea": "0.2.15-next.0",
97
+ "@backstage/plugin-scaffolder-backend-module-github": "0.9.2-next.0",
98
+ "@backstage/plugin-scaffolder-backend-module-gitlab": "0.9.7-next.0",
99
+ "@backstage/plugin-scaffolder-common": "1.7.3-next.0",
100
+ "@backstage/plugin-scaffolder-node": "0.12.1-next.0",
101
+ "@backstage/types": "1.2.2",
102
102
  "@opentelemetry/api": "^1.9.0",
103
103
  "@types/luxon": "^3.0.0",
104
104
  "concat-stream": "^2.0.0",
@@ -127,12 +127,12 @@
127
127
  "zod-to-json-schema": "^3.20.4"
128
128
  },
129
129
  "devDependencies": {
130
- "@backstage/backend-app-api": "^1.2.8",
131
- "@backstage/backend-defaults": "^0.13.0",
132
- "@backstage/backend-test-utils": "^1.9.1",
133
- "@backstage/cli": "^0.34.4",
134
- "@backstage/plugin-scaffolder-node-test-utils": "^0.3.4",
135
- "@backstage/repo-tools": "^0.15.3",
130
+ "@backstage/backend-app-api": "1.2.9-next.0",
131
+ "@backstage/backend-defaults": "0.13.1-next.0",
132
+ "@backstage/backend-test-utils": "1.10.0-next.0",
133
+ "@backstage/cli": "0.34.5-next.0",
134
+ "@backstage/plugin-scaffolder-node-test-utils": "0.3.5-next.0",
135
+ "@backstage/repo-tools": "0.15.4-next.0",
136
136
  "@types/express": "^4.17.6",
137
137
  "@types/fs-extra": "^11.0.0",
138
138
  "@types/nunjucks": "^3.1.4",