@backstage/plugin-scaffolder-backend 1.19.0-next.2 → 1.19.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,56 @@
1
1
  # @backstage/plugin-scaffolder-backend
2
2
 
3
+ ## 1.19.1
4
+
5
+ ### Patch Changes
6
+
7
+ - 25a0c75a99bd: Fix issue with Circular JSON dependencies in templating
8
+
9
+ ## 1.19.0
10
+
11
+ ### Minor Changes
12
+
13
+ - f3ab9cfcb7: Made shut down stale tasks configurable.
14
+
15
+ There are two properties exposed:
16
+
17
+ - `scaffolder.processingInterval` - sets the processing interval for staled tasks.
18
+ - `scaffolder.taskTimeoutJanitorFrequency` - sets the task's heartbeat timeout, when to consider a task to be staled.
19
+
20
+ - 7d5a921114: Allow using `globby`'s negative matching with `copyWithoutTemplating`/`copyWithoutRender`. This allows including an entire subdirectory while excluding a single file so that it will still be templated instead of needing to list every other file and ensure the list is updated when new files are added.
21
+ - 5e4127c18e: Allow setting `update: true` in `publish:github:pull-request` scaffolder action
22
+
23
+ ### Patch Changes
24
+
25
+ - 0920fd02ac: Add examples for `github:environment:create` scaffolder action & improve related tests
26
+ - ae30a9ae8c: Added description for publish:gerrit scaffolder actions
27
+ - 013611b42e: `knex` has been bumped to major version 3 and `better-sqlite3` to major version 9, which deprecate node 16 support.
28
+ - 23f72b2cba: Refactoring the runner to generate minimally informative task log per iteration and properly validate iterated actions.
29
+ - 8613ba3928: Switched to using `"exports"` field for `/alpha` subpath export.
30
+ - 99d4936f6c: Add examples for `github:webhook` scaffolder action & improve related tests
31
+ - 2be3922eb8: Add examples for `github:deployKey:create` scaffolder action & improve related tests
32
+ - 76d07da66a: Make it possible to define control buttons text (Back, Create, Review) per template
33
+ - f8727ad228: Add examples for `publish:github:pull-request` scaffolder action & improve related tests
34
+ - Updated dependencies
35
+ - @backstage/plugin-catalog-backend@1.15.0
36
+ - @backstage/plugin-catalog-node@1.5.0
37
+ - @backstage/plugin-scaffolder-common@1.4.3
38
+ - @backstage/integration@1.7.2
39
+ - @backstage/backend-common@0.19.9
40
+ - @backstage/backend-plugin-api@0.6.7
41
+ - @backstage/backend-tasks@0.5.12
42
+ - @backstage/catalog-client@1.4.6
43
+ - @backstage/plugin-permission-common@0.7.10
44
+ - @backstage/plugin-scaffolder-node@0.2.8
45
+ - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.4
46
+ - @backstage/catalog-model@1.4.3
47
+ - @backstage/config@1.1.1
48
+ - @backstage/errors@1.2.3
49
+ - @backstage/types@1.1.1
50
+ - @backstage/plugin-auth-node@0.4.1
51
+ - @backstage/plugin-catalog-common@1.0.18
52
+ - @backstage/plugin-permission-node@0.7.18
53
+
3
54
  ## 1.19.0-next.2
4
55
 
5
56
  ### Patch Changes
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backstage/plugin-scaffolder-backend",
3
- "version": "1.19.0-next.2",
3
+ "version": "1.19.1",
4
4
  "main": "../dist/alpha.cjs.js",
5
5
  "types": "../dist/alpha.d.ts"
6
6
  }
package/config.d.ts CHANGED
@@ -14,6 +14,8 @@
14
14
  * limitations under the License.
15
15
  */
16
16
 
17
+ import { HumanDuration } from '@backstage/types';
18
+
17
19
  export interface Config {
18
20
  /** Configuration options for the scaffolder plugin */
19
21
  scaffolder?: {
@@ -37,5 +39,21 @@ export interface Config {
37
39
  * Set to 0 to disable task workers altogether.
38
40
  */
39
41
  concurrentTasksLimit?: number;
42
+
43
+ /**
44
+ * Makes sure to auto-expire and clean up things that time out or for other reasons should not be left lingering.
45
+ *
46
+ * By default, the frequency is every 5 minutes.
47
+ */
48
+ taskTimeoutJanitorFrequency?: HumanDuration;
49
+
50
+ /**
51
+ * Sets the task's heartbeat timeout, when to consider a task to be staled.
52
+ *
53
+ * Once task is considered to be staled, the scheduler will shut it down on the next cycle.
54
+ *
55
+ * Default value is 24 hours.
56
+ */
57
+ taskTimeout?: HumanDuration;
40
58
  };
41
59
  }
package/dist/alpha.cjs.js CHANGED
@@ -4,7 +4,7 @@ Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var alpha = require('@backstage/plugin-scaffolder-common/alpha');
6
6
  var pluginPermissionNode = require('@backstage/plugin-permission-node');
7
- var router = require('./cjs/router-04ab6217.cjs.js');
7
+ var router = require('./cjs/router-68c854a3.cjs.js');
8
8
  var backendPluginApi = require('@backstage/backend-plugin-api');
9
9
  var backendCommon = require('@backstage/backend-common');
10
10
  var integration = require('@backstage/integration');
@@ -34,6 +34,7 @@ require('@gitbeaker/node');
34
34
  require('@octokit/webhooks');
35
35
  require('zen-observable');
36
36
  require('p-queue');
37
+ require('@backstage/config');
37
38
  require('@backstage/plugin-scaffolder-common');
38
39
  require('express');
39
40
  require('express-promise-router');
@@ -1 +1 @@
1
- {"version":3,"file":"alpha.cjs.js","sources":["../src/service/conditionExports.ts","../src/ScaffolderPlugin.ts"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n RESOURCE_TYPE_SCAFFOLDER_TEMPLATE,\n RESOURCE_TYPE_SCAFFOLDER_ACTION,\n} from '@backstage/plugin-scaffolder-common/alpha';\nimport { createConditionExports } from '@backstage/plugin-permission-node';\nimport { scaffolderTemplateRules, scaffolderActionRules } from './rules';\n\nconst templateConditionExports = createConditionExports({\n pluginId: 'scaffolder',\n resourceType: RESOURCE_TYPE_SCAFFOLDER_TEMPLATE,\n rules: scaffolderTemplateRules,\n});\n\nconst actionsConditionExports = createConditionExports({\n pluginId: 'scaffolder',\n resourceType: RESOURCE_TYPE_SCAFFOLDER_ACTION,\n rules: scaffolderActionRules,\n});\n\n/**\n * `createScaffolderTemplateConditionalDecision` can be used when authoring policies to\n * create conditional decisions. It requires a permission of type\n * `ResourcePermission<'scaffolder-template'>` to be passed as the first parameter.\n * It's recommended that you use the provided `isResourcePermission` and\n * `isPermission` helper methods to narrow the type of the permission passed to\n * the handle method as shown below.\n *\n * ```\n * // MyAuthorizationPolicy.ts\n * ...\n * import { createScaffolderPolicyDecision } from '@backstage/plugin-scaffolder-backend';\n * import { RESOURCE_TYPE_SCAFFOLDER_TEMPLATE } from '@backstage/plugin-scaffolder-common';\n *\n * class MyAuthorizationPolicy implements PermissionPolicy {\n * async handle(request, user) {\n * ...\n *\n * if (isResourcePermission(request.permission, RESOURCE_TYPE_SCAFFOLDER_TEMPLATE)) {\n * return createScaffolderConditionalDecision(\n * request.permission,\n * { anyOf: [...insert conditions here...] }\n * );\n * }\n *\n * ...\n * }\n *\n * ```\n *\n * @alpha\n */\nexport const createScaffolderTemplateConditionalDecision =\n templateConditionExports.createConditionalDecision;\n\n/**\n * These conditions are used when creating conditional decisions for scaffolder\n * templates that are returned by authorization policies.\n *\n * @alpha\n */\nexport const scaffolderTemplateConditions = templateConditionExports.conditions;\n\n/**\n * @alpha\n */\nexport const createScaffolderActionConditionalDecision =\n actionsConditionExports.createConditionalDecision;\n\n/**\n *\n * These conditions are used when creating conditional decisions for scaffolder\n * actions that are returned by authorization policies.\n *\n * @alpha\n */\nexport const scaffolderActionConditions = actionsConditionExports.conditions;\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n createBackendPlugin,\n coreServices,\n} from '@backstage/backend-plugin-api';\nimport { loggerToWinstonLogger } from '@backstage/backend-common';\nimport { ScmIntegrations } from '@backstage/integration';\nimport { catalogServiceRef } from '@backstage/plugin-catalog-node/alpha';\nimport {\n TaskBroker,\n TemplateAction,\n TemplateFilter,\n TemplateGlobal,\n} from '@backstage/plugin-scaffolder-node';\nimport {\n scaffolderActionsExtensionPoint,\n scaffolderTaskBrokerExtensionPoint,\n scaffolderTemplatingExtensionPoint,\n} from '@backstage/plugin-scaffolder-node/alpha';\nimport { createBuiltinActions } from './scaffolder';\nimport { createRouter } from './service/router';\n\n/**\n * Scaffolder plugin\n *\n * @alpha\n */\nexport const scaffolderPlugin = createBackendPlugin({\n pluginId: 'scaffolder',\n register(env) {\n const addedActions = new Array<TemplateAction<any, any>>();\n env.registerExtensionPoint(scaffolderActionsExtensionPoint, {\n addActions(...newActions: TemplateAction<any>[]) {\n addedActions.push(...newActions);\n },\n });\n\n let taskBroker: TaskBroker | undefined;\n env.registerExtensionPoint(scaffolderTaskBrokerExtensionPoint, {\n setTaskBroker(newTaskBroker) {\n if (taskBroker) {\n throw new Error('Task broker may only be set once');\n }\n taskBroker = newTaskBroker;\n },\n });\n\n const additionalTemplateFilters: Record<string, TemplateFilter> = {};\n const additionalTemplateGlobals: Record<string, TemplateGlobal> = {};\n env.registerExtensionPoint(scaffolderTemplatingExtensionPoint, {\n addTemplateFilters(newFilters) {\n Object.assign(additionalTemplateFilters, newFilters);\n },\n addTemplateGlobals(newGlobals) {\n Object.assign(additionalTemplateGlobals, newGlobals);\n },\n });\n\n env.registerInit({\n deps: {\n logger: coreServices.logger,\n config: coreServices.rootConfig,\n reader: coreServices.urlReader,\n permissions: coreServices.permissions,\n database: coreServices.database,\n httpRouter: coreServices.httpRouter,\n catalogClient: catalogServiceRef,\n },\n async init({\n logger,\n config,\n reader,\n database,\n httpRouter,\n catalogClient,\n permissions,\n }) {\n const log = loggerToWinstonLogger(logger);\n\n const actions = [\n ...addedActions,\n ...createBuiltinActions({\n integrations: ScmIntegrations.fromConfig(config),\n catalogClient,\n reader,\n config,\n additionalTemplateFilters,\n additionalTemplateGlobals,\n }),\n ];\n\n const actionIds = actions.map(action => action.id).join(', ');\n log.info(\n `Starting scaffolder with the following actions enabled ${actionIds}`,\n );\n\n const router = await createRouter({\n logger: log,\n config,\n database,\n catalogClient,\n reader,\n actions,\n taskBroker,\n additionalTemplateFilters,\n additionalTemplateGlobals,\n permissions,\n });\n httpRouter.use(router);\n },\n });\n },\n});\n"],"names":["createConditionExports","RESOURCE_TYPE_SCAFFOLDER_TEMPLATE","scaffolderTemplateRules","RESOURCE_TYPE_SCAFFOLDER_ACTION","scaffolderActionRules","createBackendPlugin","scaffolderActionsExtensionPoint","scaffolderTaskBrokerExtensionPoint","scaffolderTemplatingExtensionPoint","coreServices","catalogServiceRef","loggerToWinstonLogger","createBuiltinActions","ScmIntegrations","router","createRouter"],"mappings":"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"}
1
+ {"version":3,"file":"alpha.cjs.js","sources":["../src/service/conditionExports.ts","../src/ScaffolderPlugin.ts"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n RESOURCE_TYPE_SCAFFOLDER_TEMPLATE,\n RESOURCE_TYPE_SCAFFOLDER_ACTION,\n} from '@backstage/plugin-scaffolder-common/alpha';\nimport { createConditionExports } from '@backstage/plugin-permission-node';\nimport { scaffolderTemplateRules, scaffolderActionRules } from './rules';\n\nconst templateConditionExports = createConditionExports({\n pluginId: 'scaffolder',\n resourceType: RESOURCE_TYPE_SCAFFOLDER_TEMPLATE,\n rules: scaffolderTemplateRules,\n});\n\nconst actionsConditionExports = createConditionExports({\n pluginId: 'scaffolder',\n resourceType: RESOURCE_TYPE_SCAFFOLDER_ACTION,\n rules: scaffolderActionRules,\n});\n\n/**\n * `createScaffolderTemplateConditionalDecision` can be used when authoring policies to\n * create conditional decisions. It requires a permission of type\n * `ResourcePermission<'scaffolder-template'>` to be passed as the first parameter.\n * It's recommended that you use the provided `isResourcePermission` and\n * `isPermission` helper methods to narrow the type of the permission passed to\n * the handle method as shown below.\n *\n * ```\n * // MyAuthorizationPolicy.ts\n * ...\n * import { createScaffolderPolicyDecision } from '@backstage/plugin-scaffolder-backend';\n * import { RESOURCE_TYPE_SCAFFOLDER_TEMPLATE } from '@backstage/plugin-scaffolder-common';\n *\n * class MyAuthorizationPolicy implements PermissionPolicy {\n * async handle(request, user) {\n * ...\n *\n * if (isResourcePermission(request.permission, RESOURCE_TYPE_SCAFFOLDER_TEMPLATE)) {\n * return createScaffolderConditionalDecision(\n * request.permission,\n * { anyOf: [...insert conditions here...] }\n * );\n * }\n *\n * ...\n * }\n *\n * ```\n *\n * @alpha\n */\nexport const createScaffolderTemplateConditionalDecision =\n templateConditionExports.createConditionalDecision;\n\n/**\n * These conditions are used when creating conditional decisions for scaffolder\n * templates that are returned by authorization policies.\n *\n * @alpha\n */\nexport const scaffolderTemplateConditions = templateConditionExports.conditions;\n\n/**\n * @alpha\n */\nexport const createScaffolderActionConditionalDecision =\n actionsConditionExports.createConditionalDecision;\n\n/**\n *\n * These conditions are used when creating conditional decisions for scaffolder\n * actions that are returned by authorization policies.\n *\n * @alpha\n */\nexport const scaffolderActionConditions = actionsConditionExports.conditions;\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n createBackendPlugin,\n coreServices,\n} from '@backstage/backend-plugin-api';\nimport { loggerToWinstonLogger } from '@backstage/backend-common';\nimport { ScmIntegrations } from '@backstage/integration';\nimport { catalogServiceRef } from '@backstage/plugin-catalog-node/alpha';\nimport {\n TaskBroker,\n TemplateAction,\n TemplateFilter,\n TemplateGlobal,\n} from '@backstage/plugin-scaffolder-node';\nimport {\n scaffolderActionsExtensionPoint,\n scaffolderTaskBrokerExtensionPoint,\n scaffolderTemplatingExtensionPoint,\n} from '@backstage/plugin-scaffolder-node/alpha';\nimport { createBuiltinActions } from './scaffolder';\nimport { createRouter } from './service/router';\n\n/**\n * Scaffolder plugin\n *\n * @alpha\n */\nexport const scaffolderPlugin = createBackendPlugin({\n pluginId: 'scaffolder',\n register(env) {\n const addedActions = new Array<TemplateAction<any, any>>();\n env.registerExtensionPoint(scaffolderActionsExtensionPoint, {\n addActions(...newActions: TemplateAction<any>[]) {\n addedActions.push(...newActions);\n },\n });\n\n let taskBroker: TaskBroker | undefined;\n env.registerExtensionPoint(scaffolderTaskBrokerExtensionPoint, {\n setTaskBroker(newTaskBroker) {\n if (taskBroker) {\n throw new Error('Task broker may only be set once');\n }\n taskBroker = newTaskBroker;\n },\n });\n\n const additionalTemplateFilters: Record<string, TemplateFilter> = {};\n const additionalTemplateGlobals: Record<string, TemplateGlobal> = {};\n env.registerExtensionPoint(scaffolderTemplatingExtensionPoint, {\n addTemplateFilters(newFilters) {\n Object.assign(additionalTemplateFilters, newFilters);\n },\n addTemplateGlobals(newGlobals) {\n Object.assign(additionalTemplateGlobals, newGlobals);\n },\n });\n\n env.registerInit({\n deps: {\n logger: coreServices.logger,\n config: coreServices.rootConfig,\n reader: coreServices.urlReader,\n permissions: coreServices.permissions,\n database: coreServices.database,\n httpRouter: coreServices.httpRouter,\n catalogClient: catalogServiceRef,\n },\n async init({\n logger,\n config,\n reader,\n database,\n httpRouter,\n catalogClient,\n permissions,\n }) {\n const log = loggerToWinstonLogger(logger);\n\n const actions = [\n ...addedActions,\n ...createBuiltinActions({\n integrations: ScmIntegrations.fromConfig(config),\n catalogClient,\n reader,\n config,\n additionalTemplateFilters,\n additionalTemplateGlobals,\n }),\n ];\n\n const actionIds = actions.map(action => action.id).join(', ');\n log.info(\n `Starting scaffolder with the following actions enabled ${actionIds}`,\n );\n\n const router = await createRouter({\n logger: log,\n config,\n database,\n catalogClient,\n reader,\n actions,\n taskBroker,\n additionalTemplateFilters,\n additionalTemplateGlobals,\n permissions,\n });\n httpRouter.use(router);\n },\n });\n },\n});\n"],"names":["createConditionExports","RESOURCE_TYPE_SCAFFOLDER_TEMPLATE","scaffolderTemplateRules","RESOURCE_TYPE_SCAFFOLDER_ACTION","scaffolderActionRules","createBackendPlugin","scaffolderActionsExtensionPoint","scaffolderTaskBrokerExtensionPoint","scaffolderTemplatingExtensionPoint","coreServices","catalogServiceRef","loggerToWinstonLogger","createBuiltinActions","ScmIntegrations","router","createRouter"],"mappings":"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"}
@@ -1,6 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var catalogModel = require('@backstage/catalog-model');
4
+ var config = require('@backstage/config');
4
5
  var errors = require('@backstage/errors');
5
6
  var integration = require('@backstage/integration');
6
7
  var pluginScaffolderCommon = require('@backstage/plugin-scaffolder-common');
@@ -1110,17 +1111,13 @@ function createFetchTemplateAction(options) {
1110
1111
  followSymbolicLinks: false
1111
1112
  });
1112
1113
  const nonTemplatedEntries = new Set(
1113
- (await Promise.all(
1114
- (copyOnlyPatterns || []).map(
1115
- (pattern) => globby__default["default"](pattern, {
1116
- cwd: templateDir,
1117
- dot: true,
1118
- onlyFiles: false,
1119
- markDirectories: true,
1120
- followSymbolicLinks: false
1121
- })
1122
- )
1123
- )).flat()
1114
+ await globby__default["default"](copyOnlyPatterns || [], {
1115
+ cwd: templateDir,
1116
+ dot: true,
1117
+ onlyFiles: false,
1118
+ markDirectories: true,
1119
+ followSymbolicLinks: false
1120
+ })
1124
1121
  );
1125
1122
  const { cookiecutterCompat, values } = ctx.input;
1126
1123
  const context = {
@@ -7128,7 +7125,7 @@ class NunjucksWorkflowRunner {
7128
7125
  });
7129
7126
  }
7130
7127
  async executeStep(task, step, context, renderTemplate, taskTrack, workspacePath, decision) {
7131
- var _a, _b, _c, _d, _e, _f, _g, _h, _i;
7128
+ var _a, _b, _c, _d, _e;
7132
7129
  const stepTrack = await this.tracker.stepStart(task, step);
7133
7130
  if (task.cancelSignal.aborted) {
7134
7131
  throw new Error(`Step ${step.name} has been cancelled.`);
@@ -7178,59 +7175,64 @@ class NunjucksWorkflowRunner {
7178
7175
  return;
7179
7176
  }
7180
7177
  }
7181
- const input = (_e = step.input && this.render(
7182
- step.input,
7183
- { ...context, secrets: (_d = task.secrets) != null ? _d : {} },
7184
- renderTemplate
7185
- )) != null ? _e : {};
7186
- if ((_f = action.schema) == null ? void 0 : _f.input) {
7187
- const validateResult = jsonschema.validate(input, action.schema.input);
7188
- if (!validateResult.valid) {
7189
- const errors$1 = validateResult.errors.join(", ");
7190
- throw new errors.InputError(
7191
- `Invalid input passed to action ${action.id}, ${errors$1}`
7178
+ const iterations = (step.each ? Object.entries(this.render(step.each, context, renderTemplate)).map(
7179
+ ([key, value]) => ({
7180
+ each: { key, value }
7181
+ })
7182
+ ) : [{}]).map((i) => {
7183
+ var _a2;
7184
+ return {
7185
+ ...i,
7186
+ // Secrets are only passed when templating the input to actions for security reasons
7187
+ input: step.input ? this.render(
7188
+ step.input,
7189
+ { ...context, secrets: (_a2 = task.secrets) != null ? _a2 : {}, ...i },
7190
+ renderTemplate
7191
+ ) : {}
7192
+ };
7193
+ });
7194
+ for (const iteration of iterations) {
7195
+ const actionId = `${action.id}${iteration.each ? `[${iteration.each.key}]` : ""}`;
7196
+ if ((_d = action.schema) == null ? void 0 : _d.input) {
7197
+ const validateResult = jsonschema.validate(
7198
+ iteration.input,
7199
+ action.schema.input
7200
+ );
7201
+ if (!validateResult.valid) {
7202
+ const errors$1 = validateResult.errors.join(", ");
7203
+ throw new errors.InputError(
7204
+ `Invalid input passed to action ${actionId}, ${errors$1}`
7205
+ );
7206
+ }
7207
+ }
7208
+ if (!isActionAuthorized(decision, {
7209
+ action: action.id,
7210
+ input: iteration.input
7211
+ })) {
7212
+ throw new errors.NotAllowedError(
7213
+ `Unauthorized action: ${actionId}. The action is not allowed. Input: ${JSON.stringify(
7214
+ iteration.input,
7215
+ null,
7216
+ 2
7217
+ )}`
7192
7218
  );
7193
7219
  }
7194
- }
7195
- if (!isActionAuthorized(decision, { action: action.id, input })) {
7196
- throw new errors.NotAllowedError(
7197
- `Unauthorized action: ${action.id}. The action is not allowed. Input: ${JSON.stringify(
7198
- input,
7199
- null,
7200
- 2
7201
- )}`
7202
- );
7203
7220
  }
7204
7221
  const tmpDirs = new Array();
7205
7222
  const stepOutput = {};
7206
- const iterations = new Array();
7207
- if (step.each) {
7208
- const each = await this.render(step.each, context, renderTemplate);
7209
- iterations.push(
7210
- ...Object.keys(each).map((key) => {
7211
- return { key, value: each[key] };
7212
- })
7213
- );
7214
- } else {
7215
- iterations.push({});
7216
- }
7217
- let actionInput = input;
7218
7223
  for (const iteration of iterations) {
7219
- if (step.each) {
7220
- taskLogger.info(`Running step each: ${iteration}`);
7221
- const iterationContext = {
7222
- ...context,
7223
- each: iteration
7224
- };
7225
- actionInput = (_h = step.input && this.render(
7226
- step.input,
7227
- { ...iterationContext, secrets: (_g = task.secrets) != null ? _g : {} },
7228
- renderTemplate
7229
- )) != null ? _h : {};
7224
+ if (iteration.each) {
7225
+ taskLogger.info(
7226
+ `Running step each: ${JSON.stringify(
7227
+ iteration.each,
7228
+ (k, v) => k ? v.toString() : v,
7229
+ 0
7230
+ )}`
7231
+ );
7230
7232
  }
7231
7233
  await action.handler({
7232
- input: actionInput,
7233
- secrets: (_i = task.secrets) != null ? _i : {},
7234
+ input: iteration.input,
7235
+ secrets: (_e = task.secrets) != null ? _e : {},
7234
7236
  logger: taskLogger,
7235
7237
  logStream: streamLogger,
7236
7238
  workspacePath,
@@ -7734,6 +7736,12 @@ function buildDefaultIdentityClient(options) {
7734
7736
  }
7735
7737
  };
7736
7738
  }
7739
+ const readDuration = (config$1, key, defaultValue) => {
7740
+ if (config$1.has(key)) {
7741
+ return config.readDurationFromConfig(config$1, { key });
7742
+ }
7743
+ return defaultValue;
7744
+ };
7737
7745
  async function createRouter(options) {
7738
7746
  var _a;
7739
7747
  const router = Router__default["default"]();
@@ -7764,12 +7772,21 @@ async function createRouter(options) {
7764
7772
  if (scheduler && databaseTaskStore.listStaleTasks) {
7765
7773
  await scheduler.scheduleTask({
7766
7774
  id: "close_stale_tasks",
7767
- frequency: { cron: "*/5 * * * *" },
7768
- // every 5 minutes, also supports Duration
7775
+ frequency: readDuration(
7776
+ config,
7777
+ "scaffolder.taskTimeoutJanitorFrequency",
7778
+ {
7779
+ minutes: 5
7780
+ }
7781
+ ),
7769
7782
  timeout: { minutes: 15 },
7770
7783
  fn: async () => {
7771
7784
  const { tasks } = await databaseTaskStore.listStaleTasks({
7772
- timeoutS: 86400
7785
+ timeoutS: luxon.Duration.fromObject(
7786
+ readDuration(config, "scaffolder.taskTimeout", {
7787
+ hours: 24
7788
+ })
7789
+ ).as("seconds")
7773
7790
  });
7774
7791
  for (const task of tasks) {
7775
7792
  await databaseTaskStore.shutdownTask(task);
@@ -8171,4 +8188,4 @@ exports.createRouter = createRouter;
8171
8188
  exports.createWaitAction = createWaitAction;
8172
8189
  exports.scaffolderActionRules = scaffolderActionRules;
8173
8190
  exports.scaffolderTemplateRules = scaffolderTemplateRules;
8174
- //# sourceMappingURL=router-04ab6217.cjs.js.map
8191
+ //# sourceMappingURL=router-68c854a3.cjs.js.map