@backstage/plugin-scaffolder-backend 4.1.0-next.0 → 4.1.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.
Files changed (41) hide show
  1. package/CHANGELOG.md +23 -11
  2. package/README.md +0 -23
  3. package/config.schema.json +7 -63
  4. package/dist/ScaffolderPlugin.cjs.js +9 -2
  5. package/dist/ScaffolderPlugin.cjs.js.map +1 -1
  6. package/dist/actions/createDryRunTemplateAction.cjs.js +0 -2
  7. package/dist/actions/createDryRunTemplateAction.cjs.js.map +1 -1
  8. package/dist/index.d.ts +4 -0
  9. package/dist/scaffolder/actions/builtin/fetch/assertScmUserCredentials.cjs.js +34 -0
  10. package/dist/scaffolder/actions/builtin/fetch/assertScmUserCredentials.cjs.js.map +1 -0
  11. package/dist/scaffolder/actions/builtin/fetch/plain.cjs.js +9 -1
  12. package/dist/scaffolder/actions/builtin/fetch/plain.cjs.js.map +1 -1
  13. package/dist/scaffolder/actions/builtin/fetch/plainFile.cjs.js +9 -1
  14. package/dist/scaffolder/actions/builtin/fetch/plainFile.cjs.js.map +1 -1
  15. package/dist/scaffolder/actions/builtin/fetch/template.cjs.js +8 -0
  16. package/dist/scaffolder/actions/builtin/fetch/template.cjs.js.map +1 -1
  17. package/dist/scaffolder/actions/builtin/fetch/templateFile.cjs.js +8 -0
  18. package/dist/scaffolder/actions/builtin/fetch/templateFile.cjs.js.map +1 -1
  19. package/dist/scaffolder/tasks/DatabaseTaskStore.cjs.js +53 -78
  20. package/dist/scaffolder/tasks/DatabaseTaskStore.cjs.js.map +1 -1
  21. package/dist/scaffolder/tasks/DatabaseWorkspaceProvider.cjs.js +23 -0
  22. package/dist/scaffolder/tasks/DatabaseWorkspaceProvider.cjs.js.map +1 -0
  23. package/dist/scaffolder/tasks/NunjucksWorkflowRunner.cjs.js +130 -91
  24. package/dist/scaffolder/tasks/NunjucksWorkflowRunner.cjs.js.map +1 -1
  25. package/dist/scaffolder/tasks/StorageTaskBroker.cjs.js +29 -53
  26. package/dist/scaffolder/tasks/StorageTaskBroker.cjs.js.map +1 -1
  27. package/dist/scaffolder/tasks/WorkspaceService.cjs.js +18 -26
  28. package/dist/scaffolder/tasks/WorkspaceService.cjs.js.map +1 -1
  29. package/dist/scaffolder/tasks/logger.cjs.js +101 -7
  30. package/dist/scaffolder/tasks/logger.cjs.js.map +1 -1
  31. package/dist/scaffolder/tasks/taskRecoveryHelper.cjs.js +0 -4
  32. package/dist/scaffolder/tasks/taskRecoveryHelper.cjs.js.map +1 -1
  33. package/dist/schema/openapi/generated/router.cjs.js +6 -6
  34. package/dist/schema/openapi/generated/router.cjs.js.map +1 -1
  35. package/dist/service/router.cjs.js +22 -9
  36. package/dist/service/router.cjs.js.map +1 -1
  37. package/dist/service/rules.cjs.js +12 -0
  38. package/dist/service/rules.cjs.js.map +1 -1
  39. package/dist/util/checkPermissions.cjs.js +3 -0
  40. package/dist/util/checkPermissions.cjs.js.map +1 -1
  41. package/package.json +20 -20
@@ -3,11 +3,12 @@
3
3
  var errors = require('@backstage/errors');
4
4
  var fs = require('fs-extra');
5
5
  var jsonschema = require('jsonschema');
6
+ var lodash = require('lodash');
6
7
  var path = require('node:path');
7
8
  var nunjitsu = require('nunjitsu');
8
9
  var winston = require('winston');
10
+ var v3 = require('zod/v3');
9
11
  var helper = require('./helper.cjs.js');
10
- var taskRecoveryHelper = require('./taskRecoveryHelper.cjs.js');
11
12
  var pluginPermissionCommon = require('@backstage/plugin-permission-common');
12
13
  var pluginPermissionNode = require('@backstage/plugin-permission-node');
13
14
  var alpha = require('@backstage/plugin-scaffolder-common/alpha');
@@ -70,7 +71,7 @@ const createStepLogger = ({
70
71
  ),
71
72
  transports: [new logger.BackstageLoggerTransport(rootLogger, task, step.id)]
72
73
  });
73
- taskLogger.addRedactions(Object.values(redactions ?? {}));
74
+ taskLogger.addRedactions(redactions ?? []);
74
75
  return { taskLogger };
75
76
  };
76
77
  function collectSecretRedactions(withSecrets, withoutSecrets) {
@@ -84,9 +85,19 @@ function collectSecretRedactions(withSecrets, withoutSecrets) {
84
85
  );
85
86
  }
86
87
  if (withSecrets && typeof withSecrets === "object") {
87
- const other = withoutSecrets && typeof withoutSecrets === "object" ? withoutSecrets : {};
88
+ const otherEntries = withoutSecrets && typeof withoutSecrets === "object" ? Object.entries(withoutSecrets) : [];
88
89
  return Object.entries(withSecrets).flatMap(
89
- ([key, val]) => collectSecretRedactions(val, other[key])
90
+ ([key, value], index) => {
91
+ const otherEntry = otherEntries[index];
92
+ if (!otherEntry) {
93
+ return [key, ...extractStringValues(value)];
94
+ }
95
+ const [otherKey, otherValue] = otherEntry;
96
+ return [
97
+ ...key !== otherKey ? [key] : [],
98
+ ...collectSecretRedactions(value, otherValue)
99
+ ];
100
+ }
90
101
  );
91
102
  }
92
103
  return [];
@@ -105,12 +116,47 @@ function extractStringValues(obj) {
105
116
  const isActionAuthorized = pluginPermissionNode.createConditionAuthorizer(
106
117
  Object.values(rules.scaffolderActionRules)
107
118
  );
119
+ const stringPathConditionSchema = v3.z.object({
120
+ rule: v3.z.literal("HAS_STRING_PROPERTY"),
121
+ params: v3.z.object({
122
+ key: v3.z.string().refine((key) => lodash.toPath(key).join(".") === "path"),
123
+ value: v3.z.string()
124
+ })
125
+ });
126
+ const numericGroupPathSchema = v3.z.number().or(v3.z.string().regex(/^\d+$/u));
127
+ function getStringPathConditions(criteria) {
128
+ switch (true) {
129
+ case pluginPermissionNode.isAndCriteria(criteria):
130
+ return criteria.allOf.flatMap(getStringPathConditions);
131
+ case pluginPermissionNode.isOrCriteria(criteria):
132
+ return criteria.anyOf.flatMap(getStringPathConditions);
133
+ case pluginPermissionNode.isNotCriteria(criteria):
134
+ return getStringPathConditions(criteria.not);
135
+ default: {
136
+ const condition = stringPathConditionSchema.safeParse(criteria);
137
+ return condition.success ? [condition.data.params.value] : [];
138
+ }
139
+ }
140
+ }
141
+ function isActionInputAuthorized(decision, action, input) {
142
+ if (!isActionAuthorized(decision, { action, input })) {
143
+ return false;
144
+ }
145
+ if (decision.result !== pluginPermissionCommon.AuthorizeResult.CONDITIONAL || !action.split(":").includes("group") || !numericGroupPathSchema.safeParse(input.path).success) {
146
+ return true;
147
+ }
148
+ return getStringPathConditions(decision.conditions).every(
149
+ (candidatePath) => isActionAuthorized(decision, {
150
+ action,
151
+ input: { ...input, path: candidatePath }
152
+ })
153
+ );
154
+ }
108
155
  class NunjucksWorkflowRunner {
109
156
  defaultTemplateCapabilities;
110
157
  options;
111
158
  environment = { parameters: {}, secrets: {} };
112
159
  tracker;
113
- recoveryEnabled;
114
160
  constructor(options) {
115
161
  this.options = options;
116
162
  this.defaultTemplateCapabilities = templating.collectTemplateCapabilities({
@@ -121,7 +167,6 @@ class NunjucksWorkflowRunner {
121
167
  )
122
168
  });
123
169
  this.tracker = scaffoldingTracker(options.metrics);
124
- this.recoveryEnabled = taskRecoveryHelper.isTaskRecoveryEnabled(options.config);
125
170
  }
126
171
  async getEnvironmentConfig() {
127
172
  if (this.options.config) {
@@ -150,7 +195,15 @@ class NunjucksWorkflowRunner {
150
195
  }
151
196
  async executeStep(task, step, context, preparedContext, templateRenderer, taskTrack, workspacePath, decision) {
152
197
  const stepTrack = await this.tracker.stepStart(task, step);
153
- let workspaceSerializationAttempted = false;
198
+ const { taskLogger } = createStepLogger({
199
+ task,
200
+ step,
201
+ rootLogger: this.options.logger,
202
+ redactions: [
203
+ ...Object.values(task.secrets ?? {}),
204
+ ...Object.values(this.environment?.secrets ?? {})
205
+ ]
206
+ });
154
207
  if (task.cancelSignal.aborted) {
155
208
  throw new Error(
156
209
  `Step ${step.id} (${step.name}) of task ${task.taskId} has been cancelled.`
@@ -164,15 +217,6 @@ class NunjucksWorkflowRunner {
164
217
  const action = await this.options.actionRegistry.get(step.action, {
165
218
  credentials: await task.getInitiatorCredentials()
166
219
  });
167
- const { taskLogger } = createStepLogger({
168
- task,
169
- step,
170
- rootLogger: this.options.logger,
171
- redactions: {
172
- ...task.secrets,
173
- ...this.environment?.secrets
174
- }
175
- });
176
220
  if (task.isDryRun) {
177
221
  const redactedSecrets = Object.fromEntries(
178
222
  Object.entries(task.secrets ?? {}).map((secret) => [secret[0], "***"])
@@ -226,38 +270,91 @@ class NunjucksWorkflowRunner {
226
270
  ["secrets"],
227
271
  preIterationContext.secrets
228
272
  );
229
- const hasEach = step.each !== void 0;
230
- const resolvedEach = hasEach ? this.render(step.each, preparedPreIterationContext, templateRenderer) : void 0;
231
- if (hasEach && resolvedEach === void 0) {
273
+ const hasSecrets = Object.keys(task.secrets ?? {}).length > 0 || Object.keys(this.environment?.secrets ?? {}).length > 0;
274
+ const preparedPreIterationContextNoSecrets = preparedPreIterationContext.withValue(["secrets"], {}).withValue(["environment", "secrets"], {});
275
+ const resolvedEach = step.each && this.render(step.each, preparedPreIterationContext, templateRenderer);
276
+ if (step.each && !resolvedEach) {
232
277
  throw new errors.InputError(
233
278
  `Invalid value on action ${action.id}.each parameter, "${step.each}" cannot be resolved to a value`
234
279
  );
235
280
  }
236
- if (hasEach && (resolvedEach === null || typeof resolvedEach !== "object")) {
237
- throw new errors.InputError(
238
- `Invalid value on action ${action.id}.each parameter, must resolve to an array or object`
239
- );
281
+ let eachWithoutSecretsEntries;
282
+ if (step.each && resolvedEach && hasSecrets) {
283
+ try {
284
+ const eachWithoutSecrets = this.render(
285
+ step.each,
286
+ preparedPreIterationContextNoSecrets,
287
+ templateRenderer
288
+ );
289
+ eachWithoutSecretsEntries = Array.isArray(resolvedEach) && Array.isArray(eachWithoutSecrets) ? Object.keys(resolvedEach).map(
290
+ (key) => [key, eachWithoutSecrets[Number(key)]]
291
+ ) : Object.entries(eachWithoutSecrets);
292
+ taskLogger.addRedactions(
293
+ collectSecretRedactions(
294
+ Object.entries(resolvedEach),
295
+ eachWithoutSecretsEntries
296
+ )
297
+ );
298
+ } catch {
299
+ taskLogger.addRedactions(extractStringValues(resolvedEach));
300
+ }
240
301
  }
241
- const iterations = (resolvedEach ? Object.entries(resolvedEach).map(([key, value]) => ({
242
- each: { key, value }
243
- })) : [{}]).map((i) => {
302
+ const iterations = (resolvedEach ? Object.entries(resolvedEach).map(([key, value], index) => {
303
+ const eachWithoutSecrets = eachWithoutSecretsEntries?.[index];
304
+ return {
305
+ each: { key, value },
306
+ eachWithoutSecrets: eachWithoutSecrets ? {
307
+ key: eachWithoutSecrets[0],
308
+ value: eachWithoutSecrets[1]
309
+ } : {}
310
+ };
311
+ }) : [{}]).map((i) => {
244
312
  const preparedFullContext = "each" in i ? preparedPreIterationContext.withValue(
245
313
  ["each"],
246
314
  i.each
247
315
  ) : preparedPreIterationContext;
316
+ const preparedContextNoSecrets = "each" in i ? preparedPreIterationContextNoSecrets.withValue(
317
+ ["each"],
318
+ i.eachWithoutSecrets
319
+ ) : preparedPreIterationContextNoSecrets;
248
320
  const shouldRun = !("each" in i) || !step.if || helper.isTruthy(this.render(step.if, preparedFullContext, templateRenderer));
249
321
  return {
250
322
  ...i,
251
323
  preparedContext: preparedFullContext,
324
+ preparedContextNoSecrets,
252
325
  shouldRun,
253
326
  // Secrets are only passed when templating the input to actions for security reasons
254
327
  input: step.input ? this.render(step.input, preparedFullContext, templateRenderer) : {}
255
328
  };
256
329
  });
257
330
  for (const iteration of iterations) {
331
+ if (hasSecrets && iteration.each) {
332
+ taskLogger.addRedactions(
333
+ collectSecretRedactions(
334
+ iteration.each,
335
+ iteration.eachWithoutSecrets
336
+ )
337
+ );
338
+ }
258
339
  if (!iteration.shouldRun) {
259
340
  continue;
260
341
  }
342
+ if (step.input) {
343
+ if (hasSecrets) {
344
+ try {
345
+ const inputWithoutSecrets = this.render(
346
+ step.input,
347
+ iteration.preparedContextNoSecrets,
348
+ templateRenderer
349
+ );
350
+ taskLogger.addRedactions(
351
+ collectSecretRedactions(iteration.input, inputWithoutSecrets)
352
+ );
353
+ } catch {
354
+ taskLogger.addRedactions(extractStringValues(iteration.input));
355
+ }
356
+ }
357
+ }
261
358
  const actionId = `${action.id}${iteration.each ? `[${iteration.each.key}]` : ""}`;
262
359
  if (action.schema?.input) {
263
360
  const validateResult = jsonschema.validate(
@@ -271,16 +368,9 @@ class NunjucksWorkflowRunner {
271
368
  );
272
369
  }
273
370
  }
274
- if (!isActionAuthorized(decision, {
275
- action: action.id,
276
- input: iteration.input
277
- })) {
371
+ if (!isActionInputAuthorized(decision, action.id, iteration.input)) {
278
372
  throw new errors.NotAllowedError(
279
- `Unauthorized action: ${actionId}. The action is not allowed. Input: ${JSON.stringify(
280
- iteration.input,
281
- null,
282
- 2
283
- )}`
373
+ `Unauthorized action: ${action.id}. The action is not allowed.`
284
374
  );
285
375
  }
286
376
  }
@@ -307,24 +397,6 @@ class NunjucksWorkflowRunner {
307
397
  )}`
308
398
  );
309
399
  }
310
- if (step.input) {
311
- const hasSecrets = Object.keys(task.secrets ?? {}).length > 0 || Object.keys(this.environment?.secrets ?? {}).length > 0;
312
- if (hasSecrets) {
313
- try {
314
- const preparedContextNoSecrets = iteration.preparedContext.withValue(["secrets"], {}).withValue(["environment", "secrets"], {});
315
- const inputWithoutSecrets = this.render(
316
- step.input,
317
- preparedContextNoSecrets,
318
- templateRenderer
319
- );
320
- taskLogger.addRedactions(
321
- collectSecretRedactions(iteration.input, inputWithoutSecrets)
322
- );
323
- } catch {
324
- taskLogger.addRedactions(extractStringValues(iteration.input));
325
- }
326
- }
327
- }
328
400
  await action.handler({
329
401
  input: iteration.input,
330
402
  task: {
@@ -352,7 +424,7 @@ class NunjucksWorkflowRunner {
352
424
  await task.updateCheckpoint?.({
353
425
  key,
354
426
  status: "failed",
355
- reason: errors.stringifyError(err)
427
+ reason: errors.stringifyError(taskLogger.redactError(err))
356
428
  });
357
429
  } catch (persistenceError) {
358
430
  throw new AggregateError(
@@ -413,25 +485,15 @@ class NunjucksWorkflowRunner {
413
485
  `Step ${step.id} (${step.name}) of task ${task.taskId} has been cancelled.`
414
486
  );
415
487
  }
416
- workspaceSerializationAttempted = true;
417
- await task.serializeWorkspace?.({ path: workspacePath });
418
- if (this.recoveryEnabled) {
419
- await task.updateStepState?.({
420
- stepId: step.id,
421
- status: "completed",
422
- output: stepOutput
423
- });
424
- }
425
488
  await stepTrack.markSuccessful();
426
489
  return updatedPreparedContext;
427
- } catch (err) {
490
+ } catch (cause) {
491
+ const err = taskLogger.redactError(cause);
428
492
  await taskTrack.markFailed(step, err);
429
493
  await stepTrack.markFailed();
430
494
  throw err;
431
495
  } finally {
432
- if (!workspaceSerializationAttempted) {
433
- await task.serializeWorkspace?.({ path: workspacePath });
434
- }
496
+ await task.serializeWorkspace?.({ path: workspacePath });
435
497
  }
436
498
  }
437
499
  async execute(task) {
@@ -489,33 +551,9 @@ class NunjucksWorkflowRunner {
489
551
  [{ permission: alpha.actionExecutePermission }],
490
552
  { credentials: await task.getInitiatorCredentials() }
491
553
  ) : [{ result: pluginPermissionCommon.AuthorizeResult.ALLOW }];
492
- const prevTaskState = this.recoveryEnabled ? await task.getTaskState?.() : void 0;
493
- const recoveredTaskState = prevTaskState?.state;
494
- const savedSteps = recoveredTaskState?.steps ?? {};
495
- const completedStepIds = Object.keys(savedSteps).filter(
496
- (id) => savedSteps[id]?.status === "completed"
497
- );
498
- if (completedStepIds.length > 0) {
499
- await task.emitLog(
500
- `Task recovered - resuming from last known good state. ${completedStepIds.length} step(s) already completed.`
501
- );
502
- }
503
554
  let firstError;
504
555
  const allErrors = [];
505
556
  for (const step of task.spec.steps) {
506
- const savedStepState = savedSteps[step.id];
507
- if (savedStepState?.status === "completed") {
508
- context.steps[step.id] = { output: savedStepState.output };
509
- preparedContext = preparedContext.withValue(
510
- ["steps", step.id],
511
- context.steps[step.id]
512
- );
513
- await task.emitLog(
514
- `Skipping step ${step.id} because it was already completed in a previous run`,
515
- { stepId: step.id, status: "completed" }
516
- );
517
- continue;
518
- }
519
557
  if (taskState.failed) {
520
558
  if (typeof step.if !== "string") {
521
559
  await task.emitLog(
@@ -585,6 +623,7 @@ ${error.stack}`,
585
623
  output.text = helper.filterConditionalItems(output.text);
586
624
  }
587
625
  await taskTrack.markSuccessful();
626
+ await task.cleanWorkspace?.();
588
627
  return { output };
589
628
  } finally {
590
629
  if (workspacePath) {
@@ -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';\n\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 fs from 'fs-extra';\nimport { validate as validateJsonSchema } from 'jsonschema';\nimport path from 'node:path';\nimport {\n createTemplateRenderer,\n PreparedTemplateContext,\n TemplateCapabilities,\n TemplateContext as NunjitsuTemplateContext,\n TemplateRenderer,\n TemplateValue as NunjitsuTemplateValue,\n} from 'nunjitsu';\nimport * as winston from 'winston';\nimport { TemplateActionRegistry } from '../actions/TemplateActionRegistry';\nimport {\n filterConditionalItems,\n generateExampleOutput,\n isTruthy,\n} from './helper';\nimport { isTaskRecoveryEnabled } from './taskRecoveryHelper';\nimport {\n TaskTrackType,\n TaskState,\n WorkflowResponse,\n WorkflowRunner,\n} from './types';\n\nimport type {\n AuditorService,\n LoggerService,\n PermissionsService,\n} from '@backstage/backend-plugin-api';\nimport type { MetricsService } from '@backstage/backend-plugin-api/alpha';\nimport { UserEntity } from '@backstage/catalog-model';\nimport { Config } from '@backstage/config';\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 TaskSecrets,\n TemplateAction,\n} from '@backstage/plugin-scaffolder-node';\nimport {\n CheckpointContext,\n CheckpointState,\n} from '@backstage/plugin-scaffolder-node/alpha';\nimport { resolveDefaultEnvironment } from '../../lib/defaultEnvironment';\nimport { createDefaultFilters } from '../../lib/templating/filters/createDefaultFilters';\nimport { scaffolderActionRules } from '../../service/rules';\nimport { createCounterMetric, createHistogramMetric } from '../../util/metrics';\nimport {\n collectTemplateCapabilities,\n convertFiltersToRecord,\n} from '../../util/templating';\nimport { BackstageLoggerTransport, WinstonLogger } from './logger';\n\ntype NunjucksWorkflowRunnerOptions = {\n workingDirectory: string;\n actionRegistry: TemplateActionRegistry;\n integrations: ScmIntegrations;\n logger: LoggerService;\n auditor?: AuditorService;\n templateCapabilities?: TemplateCapabilities;\n permissions?: PermissionsService;\n config?: Config;\n metrics: MetricsService;\n};\n\ntype TemplateContext = {\n parameters: JsonObject;\n environment: 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\nfunction stringifyEachLogValue(value: unknown): string {\n if (Array.isArray(value)) {\n return value\n .map(item =>\n item === null || item === undefined ? '' : stringifyEachLogValue(item),\n )\n .join(',');\n }\n if (value !== null && typeof value === 'object') {\n return '[object Object]';\n }\n return String(value);\n}\n\nconst createStepLogger = ({\n task,\n step,\n rootLogger,\n redactions,\n}: {\n task: TaskContext;\n step: TaskStep;\n rootLogger: LoggerService;\n redactions?: Record<string, string>;\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(redactions ?? {}));\n\n return { taskLogger };\n};\n\n/**\n * Recursively compares two rendered objects and returns string values from\n * `withSecrets` that differ from their counterpart in `withoutSecrets`.\n * These are values that were influenced by secret interpolation and should\n * be added as log redactions.\n */\nfunction collectSecretRedactions(\n withSecrets: unknown,\n withoutSecrets: unknown,\n): string[] {\n if (typeof withSecrets === 'string') {\n return withSecrets !== withoutSecrets ? [withSecrets] : [];\n }\n if (Array.isArray(withSecrets)) {\n const other = Array.isArray(withoutSecrets) ? withoutSecrets : [];\n return withSecrets.flatMap((val, i) =>\n collectSecretRedactions(val, other[i]),\n );\n }\n if (withSecrets && typeof withSecrets === 'object') {\n const other =\n withoutSecrets && typeof withoutSecrets === 'object'\n ? (withoutSecrets as Record<string, unknown>)\n : {};\n return Object.entries(withSecrets as Record<string, unknown>).flatMap(\n ([key, val]) => collectSecretRedactions(val, other[key]),\n );\n }\n return [];\n}\n\n/**\n * Extracts all string values from a nested object structure.\n * Used as a fallback when the comparison render fails.\n */\nfunction extractStringValues(obj: unknown): string[] {\n if (typeof obj === 'string') return [obj];\n if (Array.isArray(obj)) return obj.flatMap(extractStringValues);\n if (obj && typeof obj === 'object') {\n return Object.entries(obj).flatMap(([key, val]) => [\n key,\n ...extractStringValues(val),\n ]);\n }\n return [];\n}\n\nconst isActionAuthorized = createConditionAuthorizer(\n Object.values(scaffolderActionRules),\n);\n\nexport class NunjucksWorkflowRunner implements WorkflowRunner {\n private readonly defaultTemplateCapabilities: TemplateCapabilities;\n private readonly options: NunjucksWorkflowRunnerOptions;\n private environment: {\n parameters: JsonObject;\n secrets?: Record<string, string>;\n } = { parameters: {}, secrets: {} };\n\n private readonly tracker: ReturnType<typeof scaffoldingTracker>;\n private readonly recoveryEnabled: boolean;\n\n constructor(options: NunjucksWorkflowRunnerOptions) {\n this.options = options;\n this.defaultTemplateCapabilities = collectTemplateCapabilities({\n filters: convertFiltersToRecord(\n createDefaultFilters({\n integrations: this.options.integrations,\n }),\n ),\n });\n this.tracker = scaffoldingTracker(options.metrics);\n this.recoveryEnabled = isTaskRecoveryEnabled(options.config);\n }\n\n async getEnvironmentConfig(): Promise<{\n parameters: JsonObject;\n secrets?: TaskSecrets;\n }> {\n if (this.options.config) {\n const defaultEnvironment = resolveDefaultEnvironment(this.options.config);\n return {\n parameters: defaultEnvironment.parameters,\n secrets: defaultEnvironment.secrets,\n };\n }\n\n return {\n parameters: {},\n secrets: {},\n };\n }\n\n private render<T>(\n input: T,\n context: PreparedTemplateContext,\n templateRenderer: TemplateRenderer,\n ): T {\n return JSON.parse(JSON.stringify(input), (_key, value) => {\n try {\n if (typeof value === 'string') {\n return templateRenderer.renderValue(value, context);\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 preparedContext: PreparedTemplateContext,\n templateRenderer: TemplateRenderer,\n taskTrack: TaskTrackType,\n workspacePath: string,\n decision: PolicyDecision,\n ) {\n const stepTrack = await this.tracker.stepStart(task, step);\n let workspaceSerializationAttempted = false;\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 step.each === undefined &&\n !isTruthy(this.render(step.if, preparedContext, templateRenderer)))\n ) {\n await stepTrack.skipFalsy();\n return preparedContext;\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 redactions: {\n ...task.secrets,\n ...this.environment?.secrets,\n },\n });\n\n if (task.isDryRun) {\n const redactedSecrets = Object.fromEntries(\n Object.entries(task.secrets ?? {}).map(secret => [secret[0], '***']),\n );\n\n const redactedEnvironmentSecrets = Object.fromEntries(\n Object.entries(this.environment?.secrets ?? {}).map(secret => [\n secret[0],\n '***',\n ]),\n );\n const dryRunContext = preparedContext\n .withValue(['environment'], {\n parameters: this.environment?.parameters || {},\n secrets: redactedEnvironmentSecrets,\n } as NunjitsuTemplateValue)\n .withValue(['secrets'], redactedSecrets);\n const debugInput =\n (step.input &&\n this.render(step.input, dryRunContext, templateRenderer)) ??\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 preparedContext.withValue(\n ['steps', step.id],\n context.steps[step.id] as unknown as NunjitsuTemplateValue,\n );\n }\n }\n\n const preIterationContext = {\n ...context,\n environment: {\n parameters: this.environment?.parameters ?? {},\n secrets: task.isDryRun ? {} : this.environment?.secrets ?? {},\n },\n secrets: task.secrets ?? {},\n };\n const preparedPreIterationContext = preparedContext\n .withValue(\n ['environment'],\n preIterationContext.environment as NunjitsuTemplateValue,\n )\n .withValue(\n ['secrets'],\n preIterationContext.secrets as NunjitsuTemplateValue,\n );\n\n const hasEach = step.each !== undefined;\n const resolvedEach = hasEach\n ? this.render(step.each, preparedPreIterationContext, templateRenderer)\n : undefined;\n\n if (hasEach && resolvedEach === undefined) {\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 if (\n hasEach &&\n (resolvedEach === null || typeof resolvedEach !== 'object')\n ) {\n throw new InputError(\n `Invalid value on action ${action.id}.each parameter, must resolve to an array or object`,\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 const preparedFullContext =\n 'each' in i\n ? preparedPreIterationContext.withValue(\n ['each'],\n i.each as NunjitsuTemplateValue,\n )\n : preparedPreIterationContext;\n // Evaluate if condition once per iteration, only when using 'each'\n const shouldRun =\n !('each' in i) ||\n !step.if ||\n isTruthy(this.render(step.if, preparedFullContext, templateRenderer));\n\n return {\n ...i,\n preparedContext: preparedFullContext,\n shouldRun,\n // Secrets are only passed when templating the input to actions for security reasons\n input: step.input\n ? this.render(step.input, preparedFullContext, templateRenderer)\n : {},\n };\n });\n for (const iteration of iterations) {\n if (!iteration.shouldRun) {\n // No need to check schema or authorization for iterations that will not run\n continue;\n }\n\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 if (!iteration.shouldRun) {\n taskLogger.info(\n `Skipping step each: ${JSON.stringify(\n iteration.each,\n (key, value) => (key ? stringifyEachLogValue(value) : value),\n 0,\n )}`,\n );\n continue;\n }\n taskLogger.info(\n `Running step each: ${JSON.stringify(\n iteration.each,\n (key, value) => (key ? stringifyEachLogValue(value) : value),\n 0,\n )}`,\n );\n }\n\n // Redact any rendered values that were influenced by secrets.\n // Re-render the input without secrets and diff against the real render\n // to find values that changed due to secret interpolation.\n if (step.input) {\n const hasSecrets =\n Object.keys(task.secrets ?? {}).length > 0 ||\n Object.keys(this.environment?.secrets ?? {}).length > 0;\n\n if (hasSecrets) {\n try {\n const preparedContextNoSecrets = iteration.preparedContext\n .withValue(['secrets'], {})\n .withValue(['environment', 'secrets'], {});\n const inputWithoutSecrets = this.render(\n step.input,\n preparedContextNoSecrets,\n templateRenderer,\n );\n taskLogger.addRedactions(\n collectSecretRedactions(iteration.input, inputWithoutSecrets),\n );\n } catch {\n taskLogger.addRedactions(extractStringValues(iteration.input));\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 let value: T;\n\n try {\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 value = prevValue !== undefined ? prevValue : await fn();\n } catch (err) {\n try {\n await task.updateCheckpoint?.({\n key,\n status: 'failed',\n reason: stringifyError(err),\n });\n } catch (persistenceError) {\n throw new AggregateError(\n [err, persistenceError],\n `Checkpoint '${checkpointKey}' failed and its failure state could not be persisted`,\n );\n }\n throw err;\n }\n\n if (prevValue === undefined) {\n await task.updateCheckpoint?.({\n key,\n status: 'success',\n value: value ?? {},\n });\n }\n return value;\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 const updatedPreparedContext = preparedContext.withValue(\n ['steps', step.id],\n context.steps[step.id] as unknown as NunjitsuTemplateValue,\n );\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 workspaceSerializationAttempted = true;\n await task.serializeWorkspace?.({ path: workspacePath });\n\n // Persist step state so a recovered task can resume from here. Only done\n // when recovery is enabled to keep the default retry lifecycle unchanged.\n if (this.recoveryEnabled) {\n await task.updateStepState?.({\n stepId: step.id,\n status: 'completed',\n output: stepOutput,\n });\n }\n\n await stepTrack.markSuccessful();\n return updatedPreparedContext;\n } catch (err) {\n await taskTrack.markFailed(step, err);\n await stepTrack.markFailed();\n throw err;\n } finally {\n if (!workspaceSerializationAttempted) {\n await task.serializeWorkspace?.({ path: workspacePath });\n }\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 { templateCapabilities } = this.options;\n\n this.environment = await this.getEnvironmentConfig();\n\n // Track whether any step has failed, used by status check functions\n const taskState = { failed: false };\n\n // Track whether a status check global (always/failure) was invoked during rendering\n const statusCheckInvoked = { value: false };\n\n const templateRenderer = createTemplateRenderer({\n allowRegexExecution: true,\n filters: {\n ...this.defaultTemplateCapabilities.filters,\n ...templateCapabilities?.filters,\n },\n globals: {\n ...templateCapabilities?.globals,\n always: () => {\n statusCheckInvoked.value = true;\n return true;\n },\n failure: () => {\n statusCheckInvoked.value = true;\n return taskState.failed;\n },\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 environment: {\n parameters: this.environment?.parameters || {},\n secrets: {},\n },\n steps: {},\n user: task.spec.user,\n context: {\n task: {\n id: taskId,\n },\n },\n };\n let preparedContext = templateRenderer.prepareContext(\n context as unknown as NunjitsuTemplateContext,\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 // Only resume from persisted step state when recovery is enabled.\n // Otherwise ignore any saved state so retries always re-run every step,\n // matching the behavior when recovery is disabled.\n const prevTaskState = this.recoveryEnabled\n ? await task.getTaskState?.()\n : undefined;\n const recoveredTaskState = prevTaskState?.state as TaskState | undefined;\n const savedSteps = recoveredTaskState?.steps ?? {};\n const completedStepIds = Object.keys(savedSteps).filter(\n id => savedSteps[id]?.status === 'completed',\n );\n if (completedStepIds.length > 0) {\n await task.emitLog(\n `Task recovered - resuming from last known good state. ${completedStepIds.length} step(s) already completed.`,\n );\n }\n\n let firstError: Error | undefined;\n const allErrors: Array<{ step: TaskStep; error: Error }> = [];\n\n for (const step of task.spec.steps) {\n const savedStepState = savedSteps[step.id];\n if (savedStepState?.status === 'completed') {\n context.steps[step.id] = { output: savedStepState.output };\n preparedContext = preparedContext.withValue(\n ['steps', step.id],\n context.steps[step.id] as unknown as NunjitsuTemplateValue,\n );\n // Re-emit the completion status event for the skipped step so the\n // frontend, which reconstructs step status from log events, does not\n // show a recovered step as stuck in `processing`. This also covers\n // the crash window between persisting the step state and emitting the\n // original completion event.\n await task.emitLog(\n `Skipping step ${step.id} because it was already completed in a previous run`,\n { stepId: step.id, status: 'completed' },\n );\n continue;\n }\n\n // If a previous step failed, only run steps whose `if` condition\n // invokes a status check global (${{ always() }} or ${{ failure() }})\n if (taskState.failed) {\n if (typeof step.if !== 'string') {\n await task.emitLog(\n `Skipping step ${step.id} because a previous step failed`,\n { stepId: step.id, status: 'skipped' },\n );\n continue;\n }\n\n // Render the if condition to detect status check function usage\n statusCheckInvoked.value = false;\n this.render(step.if, preparedContext, templateRenderer);\n\n if (!statusCheckInvoked.value) {\n await task.emitLog(\n `Skipping step ${step.id} because a previous step failed`,\n { stepId: step.id, status: 'skipped' },\n );\n continue;\n }\n }\n\n try {\n preparedContext = await this.executeStep(\n task,\n step,\n context,\n preparedContext,\n templateRenderer,\n taskTrack,\n workspacePath,\n decision,\n );\n } catch (err) {\n const error = err as Error;\n allErrors.push({ step, error });\n\n if (!firstError) {\n firstError = error;\n } else {\n // Log subsequent errors to preserve debugging information\n this.options.logger.error(\n `Additional error in step ${step.id} (${step.name}): ${error.message}`,\n error,\n );\n await task.emitLog(\n `Additional error occurred: ${error.message}\\n${error.stack}`,\n { stepId: step.id, status: 'failed' },\n );\n }\n taskState.failed = true;\n }\n }\n\n if (firstError) {\n // If there were multiple errors, add context to the first error\n if (allErrors.length > 1) {\n const additionalErrorSummary = allErrors\n .slice(1)\n .map(({ step }) => `${step.id} (${step.name})`)\n .join(', ');\n this.options.logger.warn(\n `Task failed with ${allErrors.length} errors. First error from step ${allErrors[0].step.id}. Additional failures in: ${additionalErrorSummary}`,\n );\n }\n throw firstError;\n }\n\n const output = this.render(\n task.spec.output,\n preparedContext,\n templateRenderer,\n );\n\n // Filter output links and text items based on their `if` condition\n if (Array.isArray(output?.links)) {\n output.links = filterConditionalItems(output.links);\n }\n if (Array.isArray(output?.text)) {\n output.text = filterConditionalItems(output.text);\n }\n\n await taskTrack.markSuccessful();\n\n return { output };\n } finally {\n if (workspacePath) {\n await fs.remove(workspacePath);\n }\n }\n }\n}\n\nfunction scaffoldingTracker(metrics: MetricsService) {\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 promStepCount = 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 taskCount = metrics.createCounter('scaffolder.task.count', {\n description: 'Total number of scaffolder tasks executed',\n });\n\n const taskDuration = metrics.createHistogram('scaffolder.task.duration', {\n description: 'Time taken to complete a scaffolder task end-to-end',\n unit: 's',\n });\n\n const stepCount = metrics.createCounter('scaffolder.step.count', {\n description: 'Total number of individual scaffolder action steps executed',\n });\n\n const stepDuration = metrics.createHistogram('scaffolder.step.duration', {\n description: 'Time taken to complete a single scaffolder action step',\n unit: 's',\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 promStepCount.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 promStepCount.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 promStepCount.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","collectTemplateCapabilities","convertFiltersToRecord","createDefaultFilters","isTaskRecoveryEnabled","defaultEnvironment","resolveDefaultEnvironment","isTruthy","generateExampleOutput","InputError","validateJsonSchema","errors","NotAllowedError","stringifyError","fs","path","createTemplateRenderer","actionExecutePermission","AuthorizeResult","filterConditionalItems","metrics","createCounterMetric","createHistogramMetric"],"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 fs from 'fs-extra';\nimport { validate as validateJsonSchema } from 'jsonschema';\nimport { toPath } from 'lodash';\nimport path from 'node:path';\nimport {\n createTemplateRenderer,\n PreparedTemplateContext,\n TemplateCapabilities,\n TemplateContext as NunjitsuTemplateContext,\n TemplateRenderer,\n TemplateValue as NunjitsuTemplateValue,\n} from 'nunjitsu';\nimport * as winston from 'winston';\nimport { z } from 'zod/v3';\nimport { TemplateActionRegistry } from '../actions/TemplateActionRegistry';\nimport {\n filterConditionalItems,\n generateExampleOutput,\n isTruthy,\n} from './helper';\nimport { TaskTrackType, WorkflowResponse, WorkflowRunner } from './types';\n\nimport type {\n AuditorService,\n LoggerService,\n PermissionsService,\n} from '@backstage/backend-plugin-api';\nimport type { MetricsService } from '@backstage/backend-plugin-api/alpha';\nimport { UserEntity } from '@backstage/catalog-model';\nimport { Config } from '@backstage/config';\nimport {\n AuthorizeResult,\n type PermissionCondition,\n type PermissionCriteria,\n PolicyDecision,\n} from '@backstage/plugin-permission-common';\nimport {\n createConditionAuthorizer,\n isAndCriteria,\n isNotCriteria,\n isOrCriteria,\n} from '@backstage/plugin-permission-node';\nimport { actionExecutePermission } from '@backstage/plugin-scaffolder-common/alpha';\nimport {\n TaskContext,\n TaskSecrets,\n TemplateAction,\n} from '@backstage/plugin-scaffolder-node';\nimport {\n CheckpointContext,\n CheckpointState,\n} from '@backstage/plugin-scaffolder-node/alpha';\nimport { resolveDefaultEnvironment } from '../../lib/defaultEnvironment';\nimport { createDefaultFilters } from '../../lib/templating/filters/createDefaultFilters';\nimport { scaffolderActionRules } from '../../service/rules';\nimport { createCounterMetric, createHistogramMetric } from '../../util/metrics';\nimport {\n collectTemplateCapabilities,\n convertFiltersToRecord,\n} from '../../util/templating';\nimport { BackstageLoggerTransport, WinstonLogger } from './logger';\n\ntype NunjucksWorkflowRunnerOptions = {\n workingDirectory: string;\n actionRegistry: TemplateActionRegistry;\n integrations: ScmIntegrations;\n logger: LoggerService;\n auditor?: AuditorService;\n templateCapabilities?: TemplateCapabilities;\n permissions?: PermissionsService;\n config?: Config;\n metrics: MetricsService;\n};\n\ntype TemplateContext = {\n parameters: JsonObject;\n environment: 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\nfunction stringifyEachLogValue(value: unknown): string {\n if (Array.isArray(value)) {\n return value\n .map(item =>\n item === null || item === undefined ? '' : stringifyEachLogValue(item),\n )\n .join(',');\n }\n if (value !== null && typeof value === 'object') {\n return '[object Object]';\n }\n return String(value);\n}\n\nconst createStepLogger = ({\n task,\n step,\n rootLogger,\n redactions,\n}: {\n task: TaskContext;\n step: TaskStep;\n rootLogger: LoggerService;\n redactions?: Iterable<string>;\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(redactions ?? []);\n\n return { taskLogger };\n};\n\n/**\n * Recursively compares two rendered objects and returns string keys and values\n * from `withSecrets` that differ from their counterpart in `withoutSecrets`.\n * These were influenced by secret interpolation and should be added as log\n * redactions.\n */\nfunction collectSecretRedactions(\n withSecrets: unknown,\n withoutSecrets: unknown,\n): string[] {\n if (typeof withSecrets === 'string') {\n return withSecrets !== withoutSecrets ? [withSecrets] : [];\n }\n if (Array.isArray(withSecrets)) {\n const other = Array.isArray(withoutSecrets) ? withoutSecrets : [];\n return withSecrets.flatMap((val, i) =>\n collectSecretRedactions(val, other[i]),\n );\n }\n if (withSecrets && typeof withSecrets === 'object') {\n const otherEntries =\n withoutSecrets && typeof withoutSecrets === 'object'\n ? Object.entries(withoutSecrets as Record<string, unknown>)\n : [];\n return Object.entries(withSecrets as Record<string, unknown>).flatMap(\n ([key, value], index) => {\n const otherEntry = otherEntries[index];\n if (!otherEntry) {\n return [key, ...extractStringValues(value)];\n }\n const [otherKey, otherValue] = otherEntry;\n return [\n ...(key !== otherKey ? [key] : []),\n ...collectSecretRedactions(value, otherValue),\n ];\n },\n );\n }\n return [];\n}\n\n/**\n * Extracts all string values from a nested object structure.\n * Used as a fallback when the comparison render fails.\n */\nfunction extractStringValues(obj: unknown): string[] {\n if (typeof obj === 'string') return [obj];\n if (Array.isArray(obj)) return obj.flatMap(extractStringValues);\n if (obj && typeof obj === 'object') {\n return Object.entries(obj).flatMap(([key, val]) => [\n key,\n ...extractStringValues(val),\n ]);\n }\n return [];\n}\n\nconst isActionAuthorized = createConditionAuthorizer(\n Object.values(scaffolderActionRules),\n);\n\nconst stringPathConditionSchema = z.object({\n rule: z.literal('HAS_STRING_PROPERTY'),\n params: z.object({\n key: z.string().refine(key => toPath(key).join('.') === 'path'),\n value: z.string(),\n }),\n});\n\nconst numericGroupPathSchema = z.number().or(z.string().regex(/^\\d+$/u));\n\nfunction getStringPathConditions(\n criteria: PermissionCriteria<PermissionCondition>,\n): Array<string> {\n switch (true) {\n case isAndCriteria(criteria):\n return criteria.allOf.flatMap(getStringPathConditions);\n case isOrCriteria(criteria):\n return criteria.anyOf.flatMap(getStringPathConditions);\n case isNotCriteria(criteria):\n return getStringPathConditions(criteria.not);\n default: {\n const condition = stringPathConditionSchema.safeParse(criteria);\n return condition.success ? [condition.data.params.value] : [];\n }\n }\n}\n\nfunction isActionInputAuthorized(\n decision: PolicyDecision,\n action: string,\n input: JsonObject,\n): boolean {\n if (!isActionAuthorized(decision, { action, input })) {\n return false;\n }\n\n if (\n decision.result !== AuthorizeResult.CONDITIONAL ||\n !action.split(':').includes('group') ||\n !numericGroupPathSchema.safeParse(input.path).success\n ) {\n return true;\n }\n\n return getStringPathConditions(decision.conditions).every(candidatePath =>\n isActionAuthorized(decision, {\n action,\n input: { ...input, path: candidatePath },\n }),\n );\n}\n\nexport class NunjucksWorkflowRunner implements WorkflowRunner {\n private readonly defaultTemplateCapabilities: TemplateCapabilities;\n private readonly options: NunjucksWorkflowRunnerOptions;\n private environment: {\n parameters: JsonObject;\n secrets?: Record<string, string>;\n } = { parameters: {}, secrets: {} };\n\n private readonly tracker: ReturnType<typeof scaffoldingTracker>;\n\n constructor(options: NunjucksWorkflowRunnerOptions) {\n this.options = options;\n this.defaultTemplateCapabilities = collectTemplateCapabilities({\n filters: convertFiltersToRecord(\n createDefaultFilters({\n integrations: this.options.integrations,\n }),\n ),\n });\n this.tracker = scaffoldingTracker(options.metrics);\n }\n\n async getEnvironmentConfig(): Promise<{\n parameters: JsonObject;\n secrets?: TaskSecrets;\n }> {\n if (this.options.config) {\n const defaultEnvironment = resolveDefaultEnvironment(this.options.config);\n return {\n parameters: defaultEnvironment.parameters,\n secrets: defaultEnvironment.secrets,\n };\n }\n\n return {\n parameters: {},\n secrets: {},\n };\n }\n\n private render<T>(\n input: T,\n context: PreparedTemplateContext,\n templateRenderer: TemplateRenderer,\n ): T {\n return JSON.parse(JSON.stringify(input), (_key, value) => {\n try {\n if (typeof value === 'string') {\n return templateRenderer.renderValue(value, context);\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 preparedContext: PreparedTemplateContext,\n templateRenderer: TemplateRenderer,\n taskTrack: TaskTrackType,\n workspacePath: string,\n decision: PolicyDecision,\n ) {\n const stepTrack = await this.tracker.stepStart(task, step);\n const { taskLogger } = createStepLogger({\n task,\n step,\n rootLogger: this.options.logger,\n redactions: [\n ...Object.values(task.secrets ?? {}),\n ...Object.values(this.environment?.secrets ?? {}),\n ],\n });\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 step.each === undefined &&\n !isTruthy(this.render(step.if, preparedContext, templateRenderer)))\n ) {\n await stepTrack.skipFalsy();\n return preparedContext;\n }\n const action: TemplateAction<JsonObject> =\n await this.options.actionRegistry.get(step.action, {\n credentials: await task.getInitiatorCredentials(),\n });\n\n if (task.isDryRun) {\n const redactedSecrets = Object.fromEntries(\n Object.entries(task.secrets ?? {}).map(secret => [secret[0], '***']),\n );\n\n const redactedEnvironmentSecrets = Object.fromEntries(\n Object.entries(this.environment?.secrets ?? {}).map(secret => [\n secret[0],\n '***',\n ]),\n );\n const dryRunContext = preparedContext\n .withValue(['environment'], {\n parameters: this.environment?.parameters || {},\n secrets: redactedEnvironmentSecrets,\n } as NunjitsuTemplateValue)\n .withValue(['secrets'], redactedSecrets);\n const debugInput =\n (step.input &&\n this.render(step.input, dryRunContext, templateRenderer)) ??\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 preparedContext.withValue(\n ['steps', step.id],\n context.steps[step.id] as unknown as NunjitsuTemplateValue,\n );\n }\n }\n\n const preIterationContext = {\n ...context,\n environment: {\n parameters: this.environment?.parameters ?? {},\n secrets: task.isDryRun ? {} : this.environment?.secrets ?? {},\n },\n secrets: task.secrets ?? {},\n };\n const preparedPreIterationContext = preparedContext\n .withValue(\n ['environment'],\n preIterationContext.environment as NunjitsuTemplateValue,\n )\n .withValue(\n ['secrets'],\n preIterationContext.secrets as NunjitsuTemplateValue,\n );\n const hasSecrets =\n Object.keys(task.secrets ?? {}).length > 0 ||\n Object.keys(this.environment?.secrets ?? {}).length > 0;\n const preparedPreIterationContextNoSecrets = preparedPreIterationContext\n .withValue(['secrets'], {})\n .withValue(['environment', 'secrets'], {});\n\n const resolvedEach =\n step.each &&\n this.render(step.each, preparedPreIterationContext, templateRenderer);\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 // Discover secret-derived iteration values before logging or executing\n // any iteration. The iteration value is already resolved by the time it\n // is added to each iteration's context, so input-only comparison cannot\n // identify it as secret-derived.\n let eachWithoutSecretsEntries: [string, unknown][] | undefined;\n if (step.each && resolvedEach && hasSecrets) {\n try {\n const eachWithoutSecrets = this.render(\n step.each,\n preparedPreIterationContextNoSecrets,\n templateRenderer,\n );\n eachWithoutSecretsEntries =\n Array.isArray(resolvedEach) && Array.isArray(eachWithoutSecrets)\n ? Object.keys(resolvedEach).map(\n key =>\n [key, eachWithoutSecrets[Number(key)]] as [string, unknown],\n )\n : Object.entries(eachWithoutSecrets);\n taskLogger.addRedactions(\n collectSecretRedactions(\n Object.entries(resolvedEach),\n eachWithoutSecretsEntries,\n ),\n );\n } catch {\n taskLogger.addRedactions(extractStringValues(resolvedEach));\n }\n }\n\n const iterations = (\n resolvedEach\n ? Object.entries(resolvedEach).map(([key, value], index) => {\n const eachWithoutSecrets = eachWithoutSecretsEntries?.[index];\n return {\n each: { key, value },\n eachWithoutSecrets: eachWithoutSecrets\n ? {\n key: eachWithoutSecrets[0],\n value: eachWithoutSecrets[1],\n }\n : {},\n };\n })\n : [{}]\n ).map(i => {\n const preparedFullContext =\n 'each' in i\n ? preparedPreIterationContext.withValue(\n ['each'],\n i.each as NunjitsuTemplateValue,\n )\n : preparedPreIterationContext;\n const preparedContextNoSecrets =\n 'each' in i\n ? preparedPreIterationContextNoSecrets.withValue(\n ['each'],\n i.eachWithoutSecrets as NunjitsuTemplateValue,\n )\n : preparedPreIterationContextNoSecrets;\n // Evaluate if condition once per iteration, only when using 'each'\n const shouldRun =\n !('each' in i) ||\n !step.if ||\n isTruthy(this.render(step.if, preparedFullContext, templateRenderer));\n\n return {\n ...i,\n preparedContext: preparedFullContext,\n preparedContextNoSecrets,\n shouldRun,\n // Secrets are only passed when templating the input to actions for security reasons\n input: step.input\n ? this.render(step.input, preparedFullContext, templateRenderer)\n : {},\n };\n });\n for (const iteration of iterations) {\n if (hasSecrets && iteration.each) {\n taskLogger.addRedactions(\n collectSecretRedactions(\n iteration.each,\n iteration.eachWithoutSecrets,\n ),\n );\n }\n if (!iteration.shouldRun) {\n // No need to check schema or authorization for iterations that will not run\n continue;\n }\n\n // Redact any rendered values that were influenced by secrets.\n // Re-render the input without secrets and diff against the real render\n // to find values that changed due to secret interpolation.\n if (step.input) {\n if (hasSecrets) {\n try {\n const inputWithoutSecrets = this.render(\n step.input,\n iteration.preparedContextNoSecrets,\n templateRenderer,\n );\n taskLogger.addRedactions(\n collectSecretRedactions(iteration.input, inputWithoutSecrets),\n );\n } catch {\n taskLogger.addRedactions(extractStringValues(iteration.input));\n }\n }\n }\n\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 (!isActionInputAuthorized(decision, action.id, iteration.input)) {\n throw new NotAllowedError(\n `Unauthorized action: ${action.id}. The action is not allowed.`,\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 if (!iteration.shouldRun) {\n taskLogger.info(\n `Skipping step each: ${JSON.stringify(\n iteration.each,\n (key, value) => (key ? stringifyEachLogValue(value) : value),\n 0,\n )}`,\n );\n continue;\n }\n taskLogger.info(\n `Running step each: ${JSON.stringify(\n iteration.each,\n (key, value) => (key ? stringifyEachLogValue(value) : value),\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 let value: T;\n\n try {\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 value = prevValue !== undefined ? prevValue : await fn();\n } catch (err) {\n try {\n await task.updateCheckpoint?.({\n key,\n status: 'failed',\n reason: stringifyError(taskLogger.redactError(err)),\n });\n } catch (persistenceError) {\n throw new AggregateError(\n [err, persistenceError],\n `Checkpoint '${checkpointKey}' failed and its failure state could not be persisted`,\n );\n }\n throw err;\n }\n\n if (prevValue === undefined) {\n await task.updateCheckpoint?.({\n key,\n status: 'success',\n value: value ?? {},\n });\n }\n return value;\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 const updatedPreparedContext = preparedContext.withValue(\n ['steps', step.id],\n context.steps[step.id] as unknown as NunjitsuTemplateValue,\n );\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 return updatedPreparedContext;\n } catch (cause) {\n const err = taskLogger.redactError(cause);\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 { templateCapabilities } = this.options;\n\n this.environment = await this.getEnvironmentConfig();\n\n // Track whether any step has failed, used by status check functions\n const taskState = { failed: false };\n\n // Track whether a status check global (always/failure) was invoked during rendering\n const statusCheckInvoked = { value: false };\n\n const templateRenderer = createTemplateRenderer({\n allowRegexExecution: true,\n filters: {\n ...this.defaultTemplateCapabilities.filters,\n ...templateCapabilities?.filters,\n },\n globals: {\n ...templateCapabilities?.globals,\n always: () => {\n statusCheckInvoked.value = true;\n return true;\n },\n failure: () => {\n statusCheckInvoked.value = true;\n return taskState.failed;\n },\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 environment: {\n parameters: this.environment?.parameters || {},\n secrets: {},\n },\n steps: {},\n user: task.spec.user,\n context: {\n task: {\n id: taskId,\n },\n },\n };\n let preparedContext = templateRenderer.prepareContext(\n context as unknown as NunjitsuTemplateContext,\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 let firstError: Error | undefined;\n const allErrors: Array<{ step: TaskStep; error: Error }> = [];\n\n for (const step of task.spec.steps) {\n // If a previous step failed, only run steps whose `if` condition\n // invokes a status check global (${{ always() }} or ${{ failure() }})\n if (taskState.failed) {\n if (typeof step.if !== 'string') {\n await task.emitLog(\n `Skipping step ${step.id} because a previous step failed`,\n { stepId: step.id, status: 'skipped' },\n );\n continue;\n }\n\n // Render the if condition to detect status check function usage\n statusCheckInvoked.value = false;\n this.render(step.if, preparedContext, templateRenderer);\n\n if (!statusCheckInvoked.value) {\n await task.emitLog(\n `Skipping step ${step.id} because a previous step failed`,\n { stepId: step.id, status: 'skipped' },\n );\n continue;\n }\n }\n\n try {\n preparedContext = await this.executeStep(\n task,\n step,\n context,\n preparedContext,\n templateRenderer,\n taskTrack,\n workspacePath,\n decision,\n );\n } catch (err) {\n const error = err as Error;\n allErrors.push({ step, error });\n\n if (!firstError) {\n firstError = error;\n } else {\n // Log subsequent errors to preserve debugging information\n this.options.logger.error(\n `Additional error in step ${step.id} (${step.name}): ${error.message}`,\n error,\n );\n await task.emitLog(\n `Additional error occurred: ${error.message}\\n${error.stack}`,\n { stepId: step.id, status: 'failed' },\n );\n }\n taskState.failed = true;\n }\n }\n\n if (firstError) {\n // If there were multiple errors, add context to the first error\n if (allErrors.length > 1) {\n const additionalErrorSummary = allErrors\n .slice(1)\n .map(({ step }) => `${step.id} (${step.name})`)\n .join(', ');\n this.options.logger.warn(\n `Task failed with ${allErrors.length} errors. First error from step ${allErrors[0].step.id}. Additional failures in: ${additionalErrorSummary}`,\n );\n }\n throw firstError;\n }\n\n const output = this.render(\n task.spec.output,\n preparedContext,\n templateRenderer,\n );\n\n // Filter output links and text items based on their `if` condition\n if (Array.isArray(output?.links)) {\n output.links = filterConditionalItems(output.links);\n }\n if (Array.isArray(output?.text)) {\n output.text = filterConditionalItems(output.text);\n }\n\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(metrics: MetricsService) {\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 promStepCount = 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 taskCount = metrics.createCounter('scaffolder.task.count', {\n description: 'Total number of scaffolder tasks executed',\n });\n\n const taskDuration = metrics.createHistogram('scaffolder.task.duration', {\n description: 'Time taken to complete a scaffolder task end-to-end',\n unit: 's',\n });\n\n const stepCount = metrics.createCounter('scaffolder.step.count', {\n description: 'Total number of individual scaffolder action steps executed',\n });\n\n const stepDuration = metrics.createHistogram('scaffolder.step.duration', {\n description: 'Time taken to complete a single scaffolder action step',\n unit: 's',\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 promStepCount.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 promStepCount.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 promStepCount.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","z","toPath","isAndCriteria","isOrCriteria","isNotCriteria","AuthorizeResult","collectTemplateCapabilities","convertFiltersToRecord","createDefaultFilters","defaultEnvironment","resolveDefaultEnvironment","isTruthy","generateExampleOutput","InputError","validateJsonSchema","errors","NotAllowedError","stringifyError","fs","path","createTemplateRenderer","actionExecutePermission","filterConditionalItems","metrics","createCounterMetric","createHistogramMetric"],"mappings":"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"}