@backstage/plugin-scaffolder-backend 0.17.3 → 0.18.0-next.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +41 -0
- package/dist/index.cjs.js +73 -297
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +11 -83
- package/migrations/20210120143715_init.js +1 -1
- package/package.json +10 -12
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,46 @@
|
|
|
1
1
|
# @backstage/plugin-scaffolder-backend
|
|
2
2
|
|
|
3
|
+
## 0.18.0-next.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
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.13.0-next.0
|
|
39
|
+
- @backstage/plugin-catalog-backend@0.24.0-next.0
|
|
40
|
+
- @backstage/plugin-scaffolder-common@0.3.0-next.0
|
|
41
|
+
- @backstage/catalog-model@0.13.0-next.0
|
|
42
|
+
- @backstage/catalog-client@0.9.0-next.0
|
|
43
|
+
|
|
3
44
|
## 0.17.3
|
|
4
45
|
|
|
5
46
|
### Patch Changes
|
package/dist/index.cjs.js
CHANGED
|
@@ -12,7 +12,6 @@ var path = require('path');
|
|
|
12
12
|
var globby = require('globby');
|
|
13
13
|
var isbinaryfile = require('isbinaryfile');
|
|
14
14
|
var vm2 = require('vm2');
|
|
15
|
-
var pluginScaffolderBackendModuleCookiecutter = require('@backstage/plugin-scaffolder-backend-module-cookiecutter');
|
|
16
15
|
var child_process = require('child_process');
|
|
17
16
|
var stream = require('stream');
|
|
18
17
|
var azureDevopsNodeApi = require('azure-devops-node-api');
|
|
@@ -25,10 +24,9 @@ var webhooks = require('@octokit/webhooks');
|
|
|
25
24
|
var uuid = require('uuid');
|
|
26
25
|
var luxon = require('luxon');
|
|
27
26
|
var ObservableImpl = require('zen-observable');
|
|
28
|
-
var Handlebars = require('handlebars');
|
|
29
27
|
var winston = require('winston');
|
|
30
|
-
var jsonschema = require('jsonschema');
|
|
31
28
|
var nunjucks = require('nunjucks');
|
|
29
|
+
var jsonschema = require('jsonschema');
|
|
32
30
|
var express = require('express');
|
|
33
31
|
var Router = require('express-promise-router');
|
|
34
32
|
var os = require('os');
|
|
@@ -61,7 +59,6 @@ var path__default = /*#__PURE__*/_interopDefaultLegacy(path);
|
|
|
61
59
|
var globby__default = /*#__PURE__*/_interopDefaultLegacy(globby);
|
|
62
60
|
var fetch__default = /*#__PURE__*/_interopDefaultLegacy(fetch);
|
|
63
61
|
var ObservableImpl__default = /*#__PURE__*/_interopDefaultLegacy(ObservableImpl);
|
|
64
|
-
var Handlebars__namespace = /*#__PURE__*/_interopNamespace(Handlebars);
|
|
65
62
|
var winston__namespace = /*#__PURE__*/_interopNamespace(winston);
|
|
66
63
|
var nunjucks__default = /*#__PURE__*/_interopDefaultLegacy(nunjucks);
|
|
67
64
|
var express__default = /*#__PURE__*/_interopDefaultLegacy(express);
|
|
@@ -691,7 +688,6 @@ const executeShellCommand = async (options) => {
|
|
|
691
688
|
});
|
|
692
689
|
});
|
|
693
690
|
};
|
|
694
|
-
const runCommand = executeShellCommand;
|
|
695
691
|
async function initRepoAndPush({
|
|
696
692
|
dir,
|
|
697
693
|
remoteUrl,
|
|
@@ -1272,6 +1268,26 @@ function createPublishGithubAction(options) {
|
|
|
1272
1268
|
type: "string",
|
|
1273
1269
|
description: `Sets the default branch on the repository. The default value is 'master'`
|
|
1274
1270
|
},
|
|
1271
|
+
deleteBranchOnMerge: {
|
|
1272
|
+
title: "Delete Branch On Merge",
|
|
1273
|
+
type: "boolean",
|
|
1274
|
+
description: `Delete the branch after merging the PR. The default value is 'false'`
|
|
1275
|
+
},
|
|
1276
|
+
allowMergeCommit: {
|
|
1277
|
+
title: "Allow Merge Commits",
|
|
1278
|
+
type: "boolean",
|
|
1279
|
+
description: `Allow merge commits. The default value is 'true'`
|
|
1280
|
+
},
|
|
1281
|
+
allowSquashMerge: {
|
|
1282
|
+
title: "Allow Squash Merges",
|
|
1283
|
+
type: "boolean",
|
|
1284
|
+
description: `Allow squash merges. The default value is 'true'`
|
|
1285
|
+
},
|
|
1286
|
+
allowRebaseMerge: {
|
|
1287
|
+
title: "Allow Rebase Merges",
|
|
1288
|
+
type: "boolean",
|
|
1289
|
+
description: `Allow rebase merges. The default value is 'true'`
|
|
1290
|
+
},
|
|
1275
1291
|
sourcePath: {
|
|
1276
1292
|
title: "Source Path",
|
|
1277
1293
|
description: "Path within the workspace that will be used as the repository root. If omitted, the entire workspace will be published as the repository.",
|
|
@@ -1333,6 +1349,10 @@ function createPublishGithubAction(options) {
|
|
|
1333
1349
|
requireCodeOwnerReviews = false,
|
|
1334
1350
|
repoVisibility = "private",
|
|
1335
1351
|
defaultBranch = "master",
|
|
1352
|
+
deleteBranchOnMerge = false,
|
|
1353
|
+
allowMergeCommit = true,
|
|
1354
|
+
allowSquashMerge = true,
|
|
1355
|
+
allowRebaseMerge = true,
|
|
1336
1356
|
collaborators,
|
|
1337
1357
|
topics,
|
|
1338
1358
|
token: providedToken
|
|
@@ -1356,11 +1376,19 @@ function createPublishGithubAction(options) {
|
|
|
1356
1376
|
org: owner,
|
|
1357
1377
|
private: repoVisibility === "private",
|
|
1358
1378
|
visibility: repoVisibility,
|
|
1359
|
-
description
|
|
1379
|
+
description,
|
|
1380
|
+
delete_branch_on_merge: deleteBranchOnMerge,
|
|
1381
|
+
allow_merge_commit: allowMergeCommit,
|
|
1382
|
+
allow_squash_merge: allowSquashMerge,
|
|
1383
|
+
allow_rebase_merge: allowRebaseMerge
|
|
1360
1384
|
}) : client.rest.repos.createForAuthenticatedUser({
|
|
1361
1385
|
name: repo,
|
|
1362
1386
|
private: repoVisibility === "private",
|
|
1363
|
-
description
|
|
1387
|
+
description,
|
|
1388
|
+
delete_branch_on_merge: deleteBranchOnMerge,
|
|
1389
|
+
allow_merge_commit: allowMergeCommit,
|
|
1390
|
+
allow_squash_merge: allowSquashMerge,
|
|
1391
|
+
allow_rebase_merge: allowRebaseMerge
|
|
1364
1392
|
});
|
|
1365
1393
|
const { data: newRepo } = await repoCreationPromise;
|
|
1366
1394
|
if (access == null ? void 0 : access.startsWith(`${owner}/`)) {
|
|
@@ -2010,49 +2038,10 @@ function createGithubWebhookAction(options) {
|
|
|
2010
2038
|
});
|
|
2011
2039
|
}
|
|
2012
2040
|
|
|
2013
|
-
class OctokitProvider {
|
|
2014
|
-
constructor(integrations, githubCredentialsProvider) {
|
|
2015
|
-
this.integrations = integrations;
|
|
2016
|
-
this.githubCredentialsProvider = githubCredentialsProvider || integration.DefaultGithubCredentialsProvider.fromIntegrations(this.integrations);
|
|
2017
|
-
}
|
|
2018
|
-
async getOctokit(repoUrl, options) {
|
|
2019
|
-
var _a;
|
|
2020
|
-
const { owner, repo, host } = parseRepoUrl(repoUrl, this.integrations);
|
|
2021
|
-
if (!owner) {
|
|
2022
|
-
throw new errors.InputError(`No owner provided for repo ${repoUrl}`);
|
|
2023
|
-
}
|
|
2024
|
-
const integrationConfig = (_a = this.integrations.github.byHost(host)) == null ? void 0 : _a.config;
|
|
2025
|
-
if (!integrationConfig) {
|
|
2026
|
-
throw new errors.InputError(`No integration for host ${host}`);
|
|
2027
|
-
}
|
|
2028
|
-
if (options == null ? void 0 : options.token) {
|
|
2029
|
-
const client2 = new octokit.Octokit({
|
|
2030
|
-
auth: options.token,
|
|
2031
|
-
baseUrl: integrationConfig.apiBaseUrl,
|
|
2032
|
-
previews: ["nebula-preview"]
|
|
2033
|
-
});
|
|
2034
|
-
return { client: client2, token: options.token, owner, repo };
|
|
2035
|
-
}
|
|
2036
|
-
const { token } = await this.githubCredentialsProvider.getCredentials({
|
|
2037
|
-
url: `https://${host}/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}`
|
|
2038
|
-
});
|
|
2039
|
-
if (!token) {
|
|
2040
|
-
throw new errors.InputError(`No token available for host: ${host}, with owner ${owner}, and repo ${repo}`);
|
|
2041
|
-
}
|
|
2042
|
-
const client = new octokit.Octokit({
|
|
2043
|
-
auth: token,
|
|
2044
|
-
baseUrl: integrationConfig.apiBaseUrl,
|
|
2045
|
-
previews: ["nebula-preview"]
|
|
2046
|
-
});
|
|
2047
|
-
return { client, token, owner, repo };
|
|
2048
|
-
}
|
|
2049
|
-
}
|
|
2050
|
-
|
|
2051
2041
|
const createBuiltinActions = (options) => {
|
|
2052
2042
|
const {
|
|
2053
2043
|
reader,
|
|
2054
2044
|
integrations,
|
|
2055
|
-
containerRunner,
|
|
2056
2045
|
catalogClient,
|
|
2057
2046
|
config,
|
|
2058
2047
|
additionalTemplateFilters
|
|
@@ -2106,16 +2095,6 @@ const createBuiltinActions = (options) => {
|
|
|
2106
2095
|
githubCredentialsProvider
|
|
2107
2096
|
})
|
|
2108
2097
|
];
|
|
2109
|
-
if (containerRunner) {
|
|
2110
|
-
backendCommon.getRootLogger().warn(`[DEPRECATED] The fetch:cookiecutter action will be removed part of the default scaffolder actions in later versions.
|
|
2111
|
-
You can install the package seperately and remove the containerRunner from the createBuiltInActions to remove this warning,
|
|
2112
|
-
or you can migrate to using fetch:template https://backstage.io/docs/features/software-templates/builtin-actions#migrating-from-fetchcookiecutter-to-fetchtemplate`);
|
|
2113
|
-
actions.push(pluginScaffolderBackendModuleCookiecutter.createFetchCookiecutterAction({
|
|
2114
|
-
reader,
|
|
2115
|
-
integrations,
|
|
2116
|
-
containerRunner
|
|
2117
|
-
}));
|
|
2118
|
-
}
|
|
2119
2098
|
return actions;
|
|
2120
2099
|
};
|
|
2121
2100
|
|
|
@@ -2223,7 +2202,7 @@ class DatabaseTaskStore {
|
|
|
2223
2202
|
}
|
|
2224
2203
|
}
|
|
2225
2204
|
async listStaleTasks({ timeoutS }) {
|
|
2226
|
-
const rawRows = await this.db("tasks").where("status", "processing").andWhere("last_heartbeat_at", "<=", this.db.client.config.client
|
|
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', ?, ?)`, [
|
|
2227
2206
|
`-${timeoutS}`,
|
|
2228
2207
|
this.db.fn.now()
|
|
2229
2208
|
]));
|
|
@@ -2450,182 +2429,6 @@ function isTruthy(value) {
|
|
|
2450
2429
|
return lodash.isArray(value) ? value.length > 0 : !!value;
|
|
2451
2430
|
}
|
|
2452
2431
|
|
|
2453
|
-
const isValidTaskSpec$1 = (taskSpec) => taskSpec.apiVersion === "backstage.io/v1beta2";
|
|
2454
|
-
class HandlebarsWorkflowRunner {
|
|
2455
|
-
constructor(options) {
|
|
2456
|
-
this.options = options;
|
|
2457
|
-
this.handlebars = Handlebars__namespace.create();
|
|
2458
|
-
this.handlebars.registerHelper("parseRepoUrl", (repoUrl) => {
|
|
2459
|
-
return JSON.stringify(parseRepoUrl(repoUrl, this.options.integrations));
|
|
2460
|
-
});
|
|
2461
|
-
this.handlebars.registerHelper("projectSlug", (repoUrl) => {
|
|
2462
|
-
const { owner, repo } = parseRepoUrl(repoUrl, this.options.integrations);
|
|
2463
|
-
return `${owner}/${repo}`;
|
|
2464
|
-
});
|
|
2465
|
-
this.handlebars.registerHelper("json", (obj) => JSON.stringify(obj));
|
|
2466
|
-
this.handlebars.registerHelper("not", (value) => !isTruthy(value));
|
|
2467
|
-
this.handlebars.registerHelper("eq", (a, b) => a === b);
|
|
2468
|
-
}
|
|
2469
|
-
async execute(task) {
|
|
2470
|
-
var _a, _b;
|
|
2471
|
-
if (!isValidTaskSpec$1(task.spec)) {
|
|
2472
|
-
throw new errors.InputError(`Task spec is not a valid v1beta2 task spec`);
|
|
2473
|
-
}
|
|
2474
|
-
const { actionRegistry } = this.options;
|
|
2475
|
-
const workspacePath = path__default["default"].join(this.options.workingDirectory, await task.getWorkspaceName());
|
|
2476
|
-
try {
|
|
2477
|
-
await fs__default["default"].ensureDir(workspacePath);
|
|
2478
|
-
await task.emitLog(`Starting up task with ${task.spec.steps.length} steps`);
|
|
2479
|
-
const templateCtx = { parameters: task.spec.values, steps: {} };
|
|
2480
|
-
for (const step of task.spec.steps) {
|
|
2481
|
-
const metadata = { stepId: step.id };
|
|
2482
|
-
try {
|
|
2483
|
-
const taskLogger = winston__namespace.createLogger({
|
|
2484
|
-
level: process.env.LOG_LEVEL || "info",
|
|
2485
|
-
format: winston__namespace.format.combine(winston__namespace.format.colorize(), winston__namespace.format.timestamp(), winston__namespace.format.simple()),
|
|
2486
|
-
defaultMeta: {}
|
|
2487
|
-
});
|
|
2488
|
-
const stream$1 = new stream.PassThrough();
|
|
2489
|
-
stream$1.on("data", async (data) => {
|
|
2490
|
-
const message = data.toString().trim();
|
|
2491
|
-
if ((message == null ? void 0 : message.length) > 1) {
|
|
2492
|
-
await task.emitLog(message, metadata);
|
|
2493
|
-
}
|
|
2494
|
-
});
|
|
2495
|
-
taskLogger.add(new winston__namespace.transports.Stream({ stream: stream$1 }));
|
|
2496
|
-
if (step.if !== void 0) {
|
|
2497
|
-
let skip = !step.if;
|
|
2498
|
-
if (typeof step.if === "string") {
|
|
2499
|
-
const condition = JSON.parse(JSON.stringify(step.if), (_key, value) => {
|
|
2500
|
-
if (typeof value === "string") {
|
|
2501
|
-
const templated = this.handlebars.compile(value, {
|
|
2502
|
-
noEscape: true,
|
|
2503
|
-
data: false,
|
|
2504
|
-
preventIndent: true
|
|
2505
|
-
})(templateCtx);
|
|
2506
|
-
if (templated === "") {
|
|
2507
|
-
return void 0;
|
|
2508
|
-
}
|
|
2509
|
-
try {
|
|
2510
|
-
return JSON.parse(templated);
|
|
2511
|
-
} catch {
|
|
2512
|
-
return templated;
|
|
2513
|
-
}
|
|
2514
|
-
}
|
|
2515
|
-
return value;
|
|
2516
|
-
});
|
|
2517
|
-
skip = !isTruthy(condition);
|
|
2518
|
-
}
|
|
2519
|
-
if (skip) {
|
|
2520
|
-
await task.emitLog(`Skipped step ${step.name}`, {
|
|
2521
|
-
...metadata,
|
|
2522
|
-
status: "skipped"
|
|
2523
|
-
});
|
|
2524
|
-
continue;
|
|
2525
|
-
}
|
|
2526
|
-
}
|
|
2527
|
-
await task.emitLog(`Beginning step ${step.name}`, {
|
|
2528
|
-
...metadata,
|
|
2529
|
-
status: "processing"
|
|
2530
|
-
});
|
|
2531
|
-
const action = actionRegistry.get(step.action);
|
|
2532
|
-
if (!action) {
|
|
2533
|
-
throw new Error(`Action '${step.action}' does not exist`);
|
|
2534
|
-
}
|
|
2535
|
-
const input = step.input && JSON.parse(JSON.stringify(step.input), (_key, value) => {
|
|
2536
|
-
if (typeof value === "string") {
|
|
2537
|
-
const templated = this.handlebars.compile(value, {
|
|
2538
|
-
noEscape: true,
|
|
2539
|
-
data: false,
|
|
2540
|
-
preventIndent: true
|
|
2541
|
-
})(templateCtx);
|
|
2542
|
-
if (templated.startsWith('"') && templated.endsWith('"') || templated.startsWith("{") && templated.endsWith("}") || templated.startsWith("[") && templated.endsWith("]")) {
|
|
2543
|
-
try {
|
|
2544
|
-
return JSON.parse(templated);
|
|
2545
|
-
} catch {
|
|
2546
|
-
return templated;
|
|
2547
|
-
}
|
|
2548
|
-
}
|
|
2549
|
-
return templated;
|
|
2550
|
-
}
|
|
2551
|
-
return value;
|
|
2552
|
-
});
|
|
2553
|
-
if ((_a = action.schema) == null ? void 0 : _a.input) {
|
|
2554
|
-
const validateResult = jsonschema.validate(input, action.schema.input);
|
|
2555
|
-
if (!validateResult.valid) {
|
|
2556
|
-
const errors$1 = validateResult.errors.join(", ");
|
|
2557
|
-
throw new errors.InputError(`Invalid input passed to action ${action.id}, ${errors$1}`);
|
|
2558
|
-
}
|
|
2559
|
-
}
|
|
2560
|
-
const stepOutputs = {};
|
|
2561
|
-
const tmpDirs = new Array();
|
|
2562
|
-
this.options.logger.debug(`Running ${action.id} with input`, {
|
|
2563
|
-
input: JSON.stringify(input, null, 2)
|
|
2564
|
-
});
|
|
2565
|
-
await action.handler({
|
|
2566
|
-
baseUrl: task.spec.baseUrl,
|
|
2567
|
-
logger: taskLogger,
|
|
2568
|
-
logStream: stream$1,
|
|
2569
|
-
input,
|
|
2570
|
-
secrets: (_b = task.secrets) != null ? _b : {},
|
|
2571
|
-
workspacePath,
|
|
2572
|
-
async createTemporaryDirectory() {
|
|
2573
|
-
const tmpDir = await fs__default["default"].mkdtemp(`${workspacePath}_step-${step.id}-`);
|
|
2574
|
-
tmpDirs.push(tmpDir);
|
|
2575
|
-
return tmpDir;
|
|
2576
|
-
},
|
|
2577
|
-
output(name, value) {
|
|
2578
|
-
stepOutputs[name] = value;
|
|
2579
|
-
},
|
|
2580
|
-
metadata: task.spec.metadata,
|
|
2581
|
-
templateInfo: task.spec.templateInfo
|
|
2582
|
-
});
|
|
2583
|
-
for (const tmpDir of tmpDirs) {
|
|
2584
|
-
await fs__default["default"].remove(tmpDir);
|
|
2585
|
-
}
|
|
2586
|
-
templateCtx.steps[step.id] = { output: stepOutputs };
|
|
2587
|
-
await task.emitLog(`Finished step ${step.name}`, {
|
|
2588
|
-
...metadata,
|
|
2589
|
-
status: "completed"
|
|
2590
|
-
});
|
|
2591
|
-
} catch (error) {
|
|
2592
|
-
await task.emitLog(String(error.stack), {
|
|
2593
|
-
...metadata,
|
|
2594
|
-
status: "failed"
|
|
2595
|
-
});
|
|
2596
|
-
throw error;
|
|
2597
|
-
}
|
|
2598
|
-
}
|
|
2599
|
-
const output = JSON.parse(JSON.stringify(task.spec.output), (_key, value) => {
|
|
2600
|
-
if (typeof value === "string") {
|
|
2601
|
-
const templated = this.handlebars.compile(value, {
|
|
2602
|
-
noEscape: true,
|
|
2603
|
-
data: false,
|
|
2604
|
-
preventIndent: true
|
|
2605
|
-
})(templateCtx);
|
|
2606
|
-
if (templated === "") {
|
|
2607
|
-
return void 0;
|
|
2608
|
-
}
|
|
2609
|
-
if (templated.startsWith('"') && templated.endsWith('"') || templated.startsWith("{") && templated.endsWith("}") || templated.startsWith("[") && templated.endsWith("]")) {
|
|
2610
|
-
try {
|
|
2611
|
-
return JSON.parse(templated);
|
|
2612
|
-
} catch {
|
|
2613
|
-
return templated;
|
|
2614
|
-
}
|
|
2615
|
-
}
|
|
2616
|
-
return templated;
|
|
2617
|
-
}
|
|
2618
|
-
return value;
|
|
2619
|
-
});
|
|
2620
|
-
return { output };
|
|
2621
|
-
} finally {
|
|
2622
|
-
if (workspacePath) {
|
|
2623
|
-
await fs__default["default"].remove(workspacePath);
|
|
2624
|
-
}
|
|
2625
|
-
}
|
|
2626
|
-
}
|
|
2627
|
-
}
|
|
2628
|
-
|
|
2629
2432
|
const isValidTaskSpec = (taskSpec) => {
|
|
2630
2433
|
return taskSpec.apiVersion === "scaffolder.backstage.io/v1beta3";
|
|
2631
2434
|
};
|
|
@@ -2739,7 +2542,6 @@ class NunjucksWorkflowRunner {
|
|
|
2739
2542
|
const tmpDirs = new Array();
|
|
2740
2543
|
const stepOutput = {};
|
|
2741
2544
|
await action.handler({
|
|
2742
|
-
baseUrl: task.spec.baseUrl,
|
|
2743
2545
|
input,
|
|
2744
2546
|
secrets: (_d = task.secrets) != null ? _d : {},
|
|
2745
2547
|
logger: taskLogger,
|
|
@@ -2753,7 +2555,6 @@ class NunjucksWorkflowRunner {
|
|
|
2753
2555
|
output(name, value) {
|
|
2754
2556
|
stepOutput[name] = value;
|
|
2755
2557
|
},
|
|
2756
|
-
metadata: task.spec.metadata,
|
|
2757
2558
|
templateInfo: task.spec.templateInfo
|
|
2758
2559
|
});
|
|
2759
2560
|
for (const tmpDir of tmpDirs) {
|
|
@@ -2795,12 +2596,6 @@ class TaskWorker {
|
|
|
2795
2596
|
workingDirectory,
|
|
2796
2597
|
additionalTemplateFilters
|
|
2797
2598
|
} = options;
|
|
2798
|
-
const legacyWorkflowRunner = new HandlebarsWorkflowRunner({
|
|
2799
|
-
logger,
|
|
2800
|
-
actionRegistry,
|
|
2801
|
-
integrations,
|
|
2802
|
-
workingDirectory
|
|
2803
|
-
});
|
|
2804
2599
|
const workflowRunner = new NunjucksWorkflowRunner({
|
|
2805
2600
|
actionRegistry,
|
|
2806
2601
|
integrations,
|
|
@@ -2810,7 +2605,7 @@ class TaskWorker {
|
|
|
2810
2605
|
});
|
|
2811
2606
|
return new TaskWorker({
|
|
2812
2607
|
taskBroker,
|
|
2813
|
-
runners: {
|
|
2608
|
+
runners: { workflowRunner }
|
|
2814
2609
|
});
|
|
2815
2610
|
}
|
|
2816
2611
|
start() {
|
|
@@ -2823,7 +2618,10 @@ class TaskWorker {
|
|
|
2823
2618
|
}
|
|
2824
2619
|
async runOneTask(task) {
|
|
2825
2620
|
try {
|
|
2826
|
-
|
|
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);
|
|
2827
2625
|
await task.complete("completed", { output });
|
|
2828
2626
|
} catch (error) {
|
|
2829
2627
|
errors.assertError(error);
|
|
@@ -2882,7 +2680,7 @@ async function findTemplate(options) {
|
|
|
2882
2680
|
}
|
|
2883
2681
|
|
|
2884
2682
|
function isSupportedTemplate(entity) {
|
|
2885
|
-
return entity.apiVersion === "
|
|
2683
|
+
return entity.apiVersion === "scaffolder.backstage.io/v1beta3";
|
|
2886
2684
|
}
|
|
2887
2685
|
async function createRouter(options) {
|
|
2888
2686
|
const router = Router__default["default"]();
|
|
@@ -2894,7 +2692,6 @@ async function createRouter(options) {
|
|
|
2894
2692
|
database,
|
|
2895
2693
|
catalogClient,
|
|
2896
2694
|
actions,
|
|
2897
|
-
containerRunner,
|
|
2898
2695
|
taskWorkers,
|
|
2899
2696
|
additionalTemplateFilters
|
|
2900
2697
|
} = options;
|
|
@@ -2926,7 +2723,6 @@ async function createRouter(options) {
|
|
|
2926
2723
|
const actionsToRegister = Array.isArray(actions) ? actions : createBuiltinActions({
|
|
2927
2724
|
integrations,
|
|
2928
2725
|
catalogClient,
|
|
2929
|
-
containerRunner,
|
|
2930
2726
|
reader,
|
|
2931
2727
|
config,
|
|
2932
2728
|
additionalTemplateFilters
|
|
@@ -2966,7 +2762,7 @@ async function createRouter(options) {
|
|
|
2966
2762
|
});
|
|
2967
2763
|
res.json(actionsList);
|
|
2968
2764
|
}).post("/v2/tasks", async (req, res) => {
|
|
2969
|
-
var _a, _b, _c
|
|
2765
|
+
var _a, _b, _c;
|
|
2970
2766
|
const templateRef = req.body.templateRef;
|
|
2971
2767
|
const { kind, namespace, name } = catalogModel.parseEntityRef(templateRef, {
|
|
2972
2768
|
defaultKind: "template"
|
|
@@ -2978,52 +2774,38 @@ async function createRouter(options) {
|
|
|
2978
2774
|
entityRef: { kind, namespace, name },
|
|
2979
2775
|
token: getBearerToken(req.headers.authorization)
|
|
2980
2776
|
});
|
|
2981
|
-
|
|
2982
|
-
if (isSupportedTemplate(template)) {
|
|
2983
|
-
if (template.apiVersion === "backstage.io/v1beta2") {
|
|
2984
|
-
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`);
|
|
2985
|
-
}
|
|
2986
|
-
for (const parameters of [(_a = template.spec.parameters) != null ? _a : []].flat()) {
|
|
2987
|
-
const result2 = jsonschema.validate(values, parameters);
|
|
2988
|
-
if (!result2.valid) {
|
|
2989
|
-
res.status(400).json({ errors: result2.errors });
|
|
2990
|
-
return;
|
|
2991
|
-
}
|
|
2992
|
-
}
|
|
2993
|
-
const baseUrl = getEntityBaseUrl(template);
|
|
2994
|
-
const baseTaskSpec = {
|
|
2995
|
-
baseUrl,
|
|
2996
|
-
steps: template.spec.steps.map((step, index) => {
|
|
2997
|
-
var _a2, _b2;
|
|
2998
|
-
return {
|
|
2999
|
-
...step,
|
|
3000
|
-
id: (_a2 = step.id) != null ? _a2 : `step-${index + 1}`,
|
|
3001
|
-
name: (_b2 = step.name) != null ? _b2 : step.action
|
|
3002
|
-
};
|
|
3003
|
-
}),
|
|
3004
|
-
output: (_b = template.spec.output) != null ? _b : {},
|
|
3005
|
-
metadata: { name: (_c = template.metadata) == null ? void 0 : _c.name },
|
|
3006
|
-
templateInfo: {
|
|
3007
|
-
entityRef: catalogModel.stringifyEntityRef({
|
|
3008
|
-
kind,
|
|
3009
|
-
namespace,
|
|
3010
|
-
name: (_d = template.metadata) == null ? void 0 : _d.name
|
|
3011
|
-
}),
|
|
3012
|
-
baseUrl
|
|
3013
|
-
}
|
|
3014
|
-
};
|
|
3015
|
-
taskSpec = template.apiVersion === "backstage.io/v1beta2" ? {
|
|
3016
|
-
...baseTaskSpec,
|
|
3017
|
-
apiVersion: template.apiVersion,
|
|
3018
|
-
values
|
|
3019
|
-
} : {
|
|
3020
|
-
...baseTaskSpec,
|
|
3021
|
-
apiVersion: template.apiVersion,
|
|
3022
|
-
parameters: values
|
|
3023
|
-
};
|
|
3024
|
-
} else {
|
|
2777
|
+
if (!isSupportedTemplate(template)) {
|
|
3025
2778
|
throw new errors.InputError(`Unsupported apiVersion field in schema entity, ${template.apiVersion}`);
|
|
3026
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
|
+
};
|
|
3027
2809
|
const result = await taskBroker.dispatch({
|
|
3028
2810
|
spec: taskSpec,
|
|
3029
2811
|
secrets: {
|
|
@@ -3154,12 +2936,7 @@ class ScaffolderEntitiesProcessor {
|
|
|
3154
2936
|
}
|
|
3155
2937
|
}
|
|
3156
2938
|
|
|
3157
|
-
Object.defineProperty(exports, 'createFetchCookiecutterAction', {
|
|
3158
|
-
enumerable: true,
|
|
3159
|
-
get: function () { return pluginScaffolderBackendModuleCookiecutter.createFetchCookiecutterAction; }
|
|
3160
|
-
});
|
|
3161
2939
|
exports.DatabaseTaskStore = DatabaseTaskStore;
|
|
3162
|
-
exports.OctokitProvider = OctokitProvider;
|
|
3163
2940
|
exports.ScaffolderEntitiesProcessor = ScaffolderEntitiesProcessor;
|
|
3164
2941
|
exports.TaskManager = TaskManager;
|
|
3165
2942
|
exports.TaskWorker = TaskWorker;
|
|
@@ -3185,5 +2962,4 @@ exports.createRouter = createRouter;
|
|
|
3185
2962
|
exports.createTemplateAction = createTemplateAction;
|
|
3186
2963
|
exports.executeShellCommand = executeShellCommand;
|
|
3187
2964
|
exports.fetchContents = fetchContents;
|
|
3188
|
-
exports.runCommand = runCommand;
|
|
3189
2965
|
//# sourceMappingURL=index.cjs.js.map
|