@backstage/plugin-scaffolder-backend 0.0.0-nightly-20220307022304 → 0.0.0-nightly-20220310022859

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,9 +1,66 @@
1
1
  # @backstage/plugin-scaffolder-backend
2
2
 
3
- ## 0.0.0-nightly-20220307022304
3
+ ## 0.0.0-nightly-20220310022859
4
4
 
5
5
  ### Minor Changes
6
6
 
7
+ - 310e905998: The following deprecations are now breaking and have been removed:
8
+
9
+ - **BREAKING**: Support for `backstage.io/v1beta2` Software Templates has been removed. Please migrate your legacy templates to the new `scaffolder.backstage.io/v1beta3` `apiVersion` by following the [migration guide](https://backstage.io/docs/features/software-templates/migrating-from-v1beta2-to-v1beta3)
10
+
11
+ - **BREAKING**: Removed the deprecated `TemplateMetadata`. Please use `TemplateInfo` instead.
12
+
13
+ - **BREAKING**: Removed the deprecated `context.baseUrl`. It's now available on `context.templateInfo.baseUrl`.
14
+
15
+ - **BREAKING**: Removed the deprecated `DispatchResult`, use `TaskBrokerDispatchResult` instead.
16
+
17
+ - **BREAKING**: Removed the deprecated `runCommand`, use `executeShellCommond` instead.
18
+
19
+ - **BREAKING**: Removed the deprecated `Status` in favour of `TaskStatus` instead.
20
+
21
+ - **BREAKING**: Removed the deprecated `TaskState` in favour of `CurrentClaimedTask` instead.
22
+
23
+ - f9c7bdd899: **BREAKING**:
24
+
25
+ - Removed the `createFetchCookiecutterAction` export, please use the `@backstage/plugin-scaffolder-backend-module-cookiecutter` package explicitly (see [its README](https://github.com/backstage/backstage/tree/master/plugins/scaffolder-backend-module-cookiecutter) for installation instructions).
26
+ - Removed the `containerRunner` argument from the types `RouterOptions` (as used by `createRouter`) and `CreateBuiltInActionsOptions` (as used by `createBuiltinActions`).
27
+
28
+ - 5afbd16d43: **BREAKING**: Removed the previously deprecated `OctokitProvider` class.
29
+
30
+ ### Patch Changes
31
+
32
+ - ab7cd7d70e: Do some groundwork for supporting the `better-sqlite3` driver, to maybe eventually replace `@vscode/sqlite3` (#9912)
33
+ - 8122e27717: Updating documentation for supporting `apiVersion: scaffolder.backstage.io/v1beta3`
34
+ - e0a69ba49f: build(deps): bump `fs-extra` from 9.1.0 to 10.0.1
35
+ - 3c2bc73901: Use `setupRequestMockHandlers` from `@backstage/backend-test-utils`
36
+ - 458d16869c: Allow passing more repo configuration for `publish:github` action
37
+ - Updated dependencies
38
+ - @backstage/backend-common@0.0.0-nightly-20220310022859
39
+ - @backstage/plugin-catalog-backend@0.0.0-nightly-20220310022859
40
+ - @backstage/plugin-scaffolder-common@0.0.0-nightly-20220310022859
41
+ - @backstage/catalog-model@0.0.0-nightly-20220310022859
42
+ - @backstage/catalog-client@0.0.0-nightly-20220310022859
43
+
44
+ ## 0.18.0-next.0
45
+
46
+ ### Minor Changes
47
+
48
+ - 310e905998: The following deprecations are now breaking and have been removed:
49
+
50
+ - **BREAKING**: Support for `backstage.io/v1beta2` Software Templates has been removed. Please migrate your legacy templates to the new `scaffolder.backstage.io/v1beta3` `apiVersion` by following the [migration guide](https://backstage.io/docs/features/software-templates/migrating-from-v1beta2-to-v1beta3)
51
+
52
+ - **BREAKING**: Removed the deprecated `TemplateMetadata`. Please use `TemplateInfo` instead.
53
+
54
+ - **BREAKING**: Removed the deprecated `context.baseUrl`. It's now available on `context.templateInfo.baseUrl`.
55
+
56
+ - **BREAKING**: Removed the deprecated `DispatchResult`, use `TaskBrokerDispatchResult` instead.
57
+
58
+ - **BREAKING**: Removed the deprecated `runCommand`, use `executeShellCommond` instead.
59
+
60
+ - **BREAKING**: Removed the deprecated `Status` in favour of `TaskStatus` instead.
61
+
62
+ - **BREAKING**: Removed the deprecated `TaskState` in favour of `CurrentClaimedTask` instead.
63
+
7
64
  - f9c7bdd899: **BREAKING**:
8
65
 
9
66
  - Removed the `createFetchCookiecutterAction` export, please use the `@backstage/plugin-scaffolder-backend-module-cookiecutter` package explicitly (see [its README](https://github.com/backstage/backstage/tree/master/plugins/scaffolder-backend-module-cookiecutter) for installation instructions).
@@ -13,13 +70,17 @@
13
70
 
14
71
  ### Patch Changes
15
72
 
73
+ - ab7cd7d70e: Do some groundwork for supporting the `better-sqlite3` driver, to maybe eventually replace `@vscode/sqlite3` (#9912)
74
+ - 8122e27717: Updating documentation for supporting `apiVersion: scaffolder.backstage.io/v1beta3`
75
+ - e0a69ba49f: build(deps): bump `fs-extra` from 9.1.0 to 10.0.1
76
+ - 3c2bc73901: Use `setupRequestMockHandlers` from `@backstage/backend-test-utils`
16
77
  - 458d16869c: Allow passing more repo configuration for `publish:github` action
17
78
  - Updated dependencies
18
- - @backstage/plugin-catalog-backend@0.0.0-nightly-20220307022304
19
- - @backstage/catalog-model@0.0.0-nightly-20220307022304
20
- - @backstage/backend-common@0.0.0-nightly-20220307022304
21
- - @backstage/catalog-client@0.0.0-nightly-20220307022304
22
- - @backstage/plugin-scaffolder-common@0.0.0-nightly-20220307022304
79
+ - @backstage/backend-common@0.13.0-next.0
80
+ - @backstage/plugin-catalog-backend@0.24.0-next.0
81
+ - @backstage/plugin-scaffolder-common@0.3.0-next.0
82
+ - @backstage/catalog-model@0.13.0-next.0
83
+ - @backstage/catalog-client@0.9.0-next.0
23
84
 
24
85
  ## 0.17.3
25
86
 
package/dist/index.cjs.js CHANGED
@@ -24,10 +24,9 @@ var webhooks = require('@octokit/webhooks');
24
24
  var uuid = require('uuid');
25
25
  var luxon = require('luxon');
26
26
  var ObservableImpl = require('zen-observable');
27
- var Handlebars = require('handlebars');
28
27
  var winston = require('winston');
29
- var jsonschema = require('jsonschema');
30
28
  var nunjucks = require('nunjucks');
29
+ var jsonschema = require('jsonschema');
31
30
  var express = require('express');
32
31
  var Router = require('express-promise-router');
33
32
  var os = require('os');
@@ -60,7 +59,6 @@ var path__default = /*#__PURE__*/_interopDefaultLegacy(path);
60
59
  var globby__default = /*#__PURE__*/_interopDefaultLegacy(globby);
61
60
  var fetch__default = /*#__PURE__*/_interopDefaultLegacy(fetch);
62
61
  var ObservableImpl__default = /*#__PURE__*/_interopDefaultLegacy(ObservableImpl);
63
- var Handlebars__namespace = /*#__PURE__*/_interopNamespace(Handlebars);
64
62
  var winston__namespace = /*#__PURE__*/_interopNamespace(winston);
65
63
  var nunjucks__default = /*#__PURE__*/_interopDefaultLegacy(nunjucks);
66
64
  var express__default = /*#__PURE__*/_interopDefaultLegacy(express);
@@ -690,7 +688,6 @@ const executeShellCommand = async (options) => {
690
688
  });
691
689
  });
692
690
  };
693
- const runCommand = executeShellCommand;
694
691
  async function initRepoAndPush({
695
692
  dir,
696
693
  remoteUrl,
@@ -2205,7 +2202,7 @@ class DatabaseTaskStore {
2205
2202
  }
2206
2203
  }
2207
2204
  async listStaleTasks({ timeoutS }) {
2208
- const rawRows = await this.db("tasks").where("status", "processing").andWhere("last_heartbeat_at", "<=", this.db.client.config.client === "sqlite3" ? this.db.raw(`datetime('now', ?)`, [`-${timeoutS} seconds`]) : this.db.raw(`dateadd('second', ?, ?)`, [
2205
+ const rawRows = await this.db("tasks").where("status", "processing").andWhere("last_heartbeat_at", "<=", this.db.client.config.client.includes("sqlite3") ? this.db.raw(`datetime('now', ?)`, [`-${timeoutS} seconds`]) : this.db.raw(`dateadd('second', ?, ?)`, [
2209
2206
  `-${timeoutS}`,
2210
2207
  this.db.fn.now()
2211
2208
  ]));
@@ -2432,182 +2429,6 @@ function isTruthy(value) {
2432
2429
  return lodash.isArray(value) ? value.length > 0 : !!value;
2433
2430
  }
2434
2431
 
2435
- const isValidTaskSpec$1 = (taskSpec) => taskSpec.apiVersion === "backstage.io/v1beta2";
2436
- class HandlebarsWorkflowRunner {
2437
- constructor(options) {
2438
- this.options = options;
2439
- this.handlebars = Handlebars__namespace.create();
2440
- this.handlebars.registerHelper("parseRepoUrl", (repoUrl) => {
2441
- return JSON.stringify(parseRepoUrl(repoUrl, this.options.integrations));
2442
- });
2443
- this.handlebars.registerHelper("projectSlug", (repoUrl) => {
2444
- const { owner, repo } = parseRepoUrl(repoUrl, this.options.integrations);
2445
- return `${owner}/${repo}`;
2446
- });
2447
- this.handlebars.registerHelper("json", (obj) => JSON.stringify(obj));
2448
- this.handlebars.registerHelper("not", (value) => !isTruthy(value));
2449
- this.handlebars.registerHelper("eq", (a, b) => a === b);
2450
- }
2451
- async execute(task) {
2452
- var _a, _b;
2453
- if (!isValidTaskSpec$1(task.spec)) {
2454
- throw new errors.InputError(`Task spec is not a valid v1beta2 task spec`);
2455
- }
2456
- const { actionRegistry } = this.options;
2457
- const workspacePath = path__default["default"].join(this.options.workingDirectory, await task.getWorkspaceName());
2458
- try {
2459
- await fs__default["default"].ensureDir(workspacePath);
2460
- await task.emitLog(`Starting up task with ${task.spec.steps.length} steps`);
2461
- const templateCtx = { parameters: task.spec.values, steps: {} };
2462
- for (const step of task.spec.steps) {
2463
- const metadata = { stepId: step.id };
2464
- try {
2465
- const taskLogger = winston__namespace.createLogger({
2466
- level: process.env.LOG_LEVEL || "info",
2467
- format: winston__namespace.format.combine(winston__namespace.format.colorize(), winston__namespace.format.timestamp(), winston__namespace.format.simple()),
2468
- defaultMeta: {}
2469
- });
2470
- const stream$1 = new stream.PassThrough();
2471
- stream$1.on("data", async (data) => {
2472
- const message = data.toString().trim();
2473
- if ((message == null ? void 0 : message.length) > 1) {
2474
- await task.emitLog(message, metadata);
2475
- }
2476
- });
2477
- taskLogger.add(new winston__namespace.transports.Stream({ stream: stream$1 }));
2478
- if (step.if !== void 0) {
2479
- let skip = !step.if;
2480
- if (typeof step.if === "string") {
2481
- const condition = JSON.parse(JSON.stringify(step.if), (_key, value) => {
2482
- if (typeof value === "string") {
2483
- const templated = this.handlebars.compile(value, {
2484
- noEscape: true,
2485
- data: false,
2486
- preventIndent: true
2487
- })(templateCtx);
2488
- if (templated === "") {
2489
- return void 0;
2490
- }
2491
- try {
2492
- return JSON.parse(templated);
2493
- } catch {
2494
- return templated;
2495
- }
2496
- }
2497
- return value;
2498
- });
2499
- skip = !isTruthy(condition);
2500
- }
2501
- if (skip) {
2502
- await task.emitLog(`Skipped step ${step.name}`, {
2503
- ...metadata,
2504
- status: "skipped"
2505
- });
2506
- continue;
2507
- }
2508
- }
2509
- await task.emitLog(`Beginning step ${step.name}`, {
2510
- ...metadata,
2511
- status: "processing"
2512
- });
2513
- const action = actionRegistry.get(step.action);
2514
- if (!action) {
2515
- throw new Error(`Action '${step.action}' does not exist`);
2516
- }
2517
- const input = step.input && JSON.parse(JSON.stringify(step.input), (_key, value) => {
2518
- if (typeof value === "string") {
2519
- const templated = this.handlebars.compile(value, {
2520
- noEscape: true,
2521
- data: false,
2522
- preventIndent: true
2523
- })(templateCtx);
2524
- if (templated.startsWith('"') && templated.endsWith('"') || templated.startsWith("{") && templated.endsWith("}") || templated.startsWith("[") && templated.endsWith("]")) {
2525
- try {
2526
- return JSON.parse(templated);
2527
- } catch {
2528
- return templated;
2529
- }
2530
- }
2531
- return templated;
2532
- }
2533
- return value;
2534
- });
2535
- if ((_a = action.schema) == null ? void 0 : _a.input) {
2536
- const validateResult = jsonschema.validate(input, action.schema.input);
2537
- if (!validateResult.valid) {
2538
- const errors$1 = validateResult.errors.join(", ");
2539
- throw new errors.InputError(`Invalid input passed to action ${action.id}, ${errors$1}`);
2540
- }
2541
- }
2542
- const stepOutputs = {};
2543
- const tmpDirs = new Array();
2544
- this.options.logger.debug(`Running ${action.id} with input`, {
2545
- input: JSON.stringify(input, null, 2)
2546
- });
2547
- await action.handler({
2548
- baseUrl: task.spec.baseUrl,
2549
- logger: taskLogger,
2550
- logStream: stream$1,
2551
- input,
2552
- secrets: (_b = task.secrets) != null ? _b : {},
2553
- workspacePath,
2554
- async createTemporaryDirectory() {
2555
- const tmpDir = await fs__default["default"].mkdtemp(`${workspacePath}_step-${step.id}-`);
2556
- tmpDirs.push(tmpDir);
2557
- return tmpDir;
2558
- },
2559
- output(name, value) {
2560
- stepOutputs[name] = value;
2561
- },
2562
- metadata: task.spec.metadata,
2563
- templateInfo: task.spec.templateInfo
2564
- });
2565
- for (const tmpDir of tmpDirs) {
2566
- await fs__default["default"].remove(tmpDir);
2567
- }
2568
- templateCtx.steps[step.id] = { output: stepOutputs };
2569
- await task.emitLog(`Finished step ${step.name}`, {
2570
- ...metadata,
2571
- status: "completed"
2572
- });
2573
- } catch (error) {
2574
- await task.emitLog(String(error.stack), {
2575
- ...metadata,
2576
- status: "failed"
2577
- });
2578
- throw error;
2579
- }
2580
- }
2581
- const output = JSON.parse(JSON.stringify(task.spec.output), (_key, value) => {
2582
- if (typeof value === "string") {
2583
- const templated = this.handlebars.compile(value, {
2584
- noEscape: true,
2585
- data: false,
2586
- preventIndent: true
2587
- })(templateCtx);
2588
- if (templated === "") {
2589
- return void 0;
2590
- }
2591
- if (templated.startsWith('"') && templated.endsWith('"') || templated.startsWith("{") && templated.endsWith("}") || templated.startsWith("[") && templated.endsWith("]")) {
2592
- try {
2593
- return JSON.parse(templated);
2594
- } catch {
2595
- return templated;
2596
- }
2597
- }
2598
- return templated;
2599
- }
2600
- return value;
2601
- });
2602
- return { output };
2603
- } finally {
2604
- if (workspacePath) {
2605
- await fs__default["default"].remove(workspacePath);
2606
- }
2607
- }
2608
- }
2609
- }
2610
-
2611
2432
  const isValidTaskSpec = (taskSpec) => {
2612
2433
  return taskSpec.apiVersion === "scaffolder.backstage.io/v1beta3";
2613
2434
  };
@@ -2721,7 +2542,6 @@ class NunjucksWorkflowRunner {
2721
2542
  const tmpDirs = new Array();
2722
2543
  const stepOutput = {};
2723
2544
  await action.handler({
2724
- baseUrl: task.spec.baseUrl,
2725
2545
  input,
2726
2546
  secrets: (_d = task.secrets) != null ? _d : {},
2727
2547
  logger: taskLogger,
@@ -2735,7 +2555,6 @@ class NunjucksWorkflowRunner {
2735
2555
  output(name, value) {
2736
2556
  stepOutput[name] = value;
2737
2557
  },
2738
- metadata: task.spec.metadata,
2739
2558
  templateInfo: task.spec.templateInfo
2740
2559
  });
2741
2560
  for (const tmpDir of tmpDirs) {
@@ -2777,12 +2596,6 @@ class TaskWorker {
2777
2596
  workingDirectory,
2778
2597
  additionalTemplateFilters
2779
2598
  } = options;
2780
- const legacyWorkflowRunner = new HandlebarsWorkflowRunner({
2781
- logger,
2782
- actionRegistry,
2783
- integrations,
2784
- workingDirectory
2785
- });
2786
2599
  const workflowRunner = new NunjucksWorkflowRunner({
2787
2600
  actionRegistry,
2788
2601
  integrations,
@@ -2792,7 +2605,7 @@ class TaskWorker {
2792
2605
  });
2793
2606
  return new TaskWorker({
2794
2607
  taskBroker,
2795
- runners: { legacyWorkflowRunner, workflowRunner }
2608
+ runners: { workflowRunner }
2796
2609
  });
2797
2610
  }
2798
2611
  start() {
@@ -2805,7 +2618,10 @@ class TaskWorker {
2805
2618
  }
2806
2619
  async runOneTask(task) {
2807
2620
  try {
2808
- const { output } = task.spec.apiVersion === "scaffolder.backstage.io/v1beta3" ? await this.options.runners.workflowRunner.execute(task) : await this.options.runners.legacyWorkflowRunner.execute(task);
2621
+ if (task.spec.apiVersion !== "scaffolder.backstage.io/v1beta3") {
2622
+ throw new Error(`Unsupported Template apiVersion ${task.spec.apiVersion}`);
2623
+ }
2624
+ const { output } = await this.options.runners.workflowRunner.execute(task);
2809
2625
  await task.complete("completed", { output });
2810
2626
  } catch (error) {
2811
2627
  errors.assertError(error);
@@ -2864,7 +2680,7 @@ async function findTemplate(options) {
2864
2680
  }
2865
2681
 
2866
2682
  function isSupportedTemplate(entity) {
2867
- return entity.apiVersion === "backstage.io/v1beta2" || entity.apiVersion === "scaffolder.backstage.io/v1beta3";
2683
+ return entity.apiVersion === "scaffolder.backstage.io/v1beta3";
2868
2684
  }
2869
2685
  async function createRouter(options) {
2870
2686
  const router = Router__default["default"]();
@@ -2946,7 +2762,7 @@ async function createRouter(options) {
2946
2762
  });
2947
2763
  res.json(actionsList);
2948
2764
  }).post("/v2/tasks", async (req, res) => {
2949
- var _a, _b, _c, _d;
2765
+ var _a, _b, _c;
2950
2766
  const templateRef = req.body.templateRef;
2951
2767
  const { kind, namespace, name } = catalogModel.parseEntityRef(templateRef, {
2952
2768
  defaultKind: "template"
@@ -2958,52 +2774,38 @@ async function createRouter(options) {
2958
2774
  entityRef: { kind, namespace, name },
2959
2775
  token: getBearerToken(req.headers.authorization)
2960
2776
  });
2961
- let taskSpec;
2962
- if (isSupportedTemplate(template)) {
2963
- if (template.apiVersion === "backstage.io/v1beta2") {
2964
- logger.warn(`Scaffolding ${catalogModel.stringifyEntityRef(template)} with deprecated apiVersion ${template.apiVersion}. Please migrate the template to backstage.io/v1beta3. https://backstage.io/docs/features/software-templates/migrating-from-v1beta2-to-v1beta3`);
2965
- }
2966
- for (const parameters of [(_a = template.spec.parameters) != null ? _a : []].flat()) {
2967
- const result2 = jsonschema.validate(values, parameters);
2968
- if (!result2.valid) {
2969
- res.status(400).json({ errors: result2.errors });
2970
- return;
2971
- }
2972
- }
2973
- const baseUrl = getEntityBaseUrl(template);
2974
- const baseTaskSpec = {
2975
- baseUrl,
2976
- steps: template.spec.steps.map((step, index) => {
2977
- var _a2, _b2;
2978
- return {
2979
- ...step,
2980
- id: (_a2 = step.id) != null ? _a2 : `step-${index + 1}`,
2981
- name: (_b2 = step.name) != null ? _b2 : step.action
2982
- };
2983
- }),
2984
- output: (_b = template.spec.output) != null ? _b : {},
2985
- metadata: { name: (_c = template.metadata) == null ? void 0 : _c.name },
2986
- templateInfo: {
2987
- entityRef: catalogModel.stringifyEntityRef({
2988
- kind,
2989
- namespace,
2990
- name: (_d = template.metadata) == null ? void 0 : _d.name
2991
- }),
2992
- baseUrl
2993
- }
2994
- };
2995
- taskSpec = template.apiVersion === "backstage.io/v1beta2" ? {
2996
- ...baseTaskSpec,
2997
- apiVersion: template.apiVersion,
2998
- values
2999
- } : {
3000
- ...baseTaskSpec,
3001
- apiVersion: template.apiVersion,
3002
- parameters: values
3003
- };
3004
- } else {
2777
+ if (!isSupportedTemplate(template)) {
3005
2778
  throw new errors.InputError(`Unsupported apiVersion field in schema entity, ${template.apiVersion}`);
3006
2779
  }
2780
+ for (const parameters of [(_a = template.spec.parameters) != null ? _a : []].flat()) {
2781
+ const result2 = jsonschema.validate(values, parameters);
2782
+ if (!result2.valid) {
2783
+ res.status(400).json({ errors: result2.errors });
2784
+ return;
2785
+ }
2786
+ }
2787
+ const baseUrl = getEntityBaseUrl(template);
2788
+ const taskSpec = {
2789
+ apiVersion: template.apiVersion,
2790
+ steps: template.spec.steps.map((step, index) => {
2791
+ var _a2, _b2;
2792
+ return {
2793
+ ...step,
2794
+ id: (_a2 = step.id) != null ? _a2 : `step-${index + 1}`,
2795
+ name: (_b2 = step.name) != null ? _b2 : step.action
2796
+ };
2797
+ }),
2798
+ output: (_b = template.spec.output) != null ? _b : {},
2799
+ parameters: values,
2800
+ templateInfo: {
2801
+ entityRef: catalogModel.stringifyEntityRef({
2802
+ kind,
2803
+ namespace,
2804
+ name: (_c = template.metadata) == null ? void 0 : _c.name
2805
+ }),
2806
+ baseUrl
2807
+ }
2808
+ };
3007
2809
  const result = await taskBroker.dispatch({
3008
2810
  spec: taskSpec,
3009
2811
  secrets: {
@@ -3160,5 +2962,4 @@ exports.createRouter = createRouter;
3160
2962
  exports.createTemplateAction = createTemplateAction;
3161
2963
  exports.executeShellCommand = executeShellCommand;
3162
2964
  exports.fetchContents = fetchContents;
3163
- exports.runCommand = runCommand;
3164
2965
  //# sourceMappingURL=index.cjs.js.map