@backstage/plugin-scaffolder-backend 0.17.3 → 1.0.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 +105 -0
- package/dist/index.cjs.js +145 -294
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +69 -83
- package/migrations/20210120143715_init.js +1 -1
- package/package.json +14 -16
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}/`)) {
|
|
@@ -1525,6 +1553,11 @@ const createPublishGithubPullRequestAction = ({
|
|
|
1525
1553
|
type: "string",
|
|
1526
1554
|
title: "Pull Request URL",
|
|
1527
1555
|
description: "Link to the pull request in Github"
|
|
1556
|
+
},
|
|
1557
|
+
pullRequestNumber: {
|
|
1558
|
+
type: "number",
|
|
1559
|
+
title: "Pull Request Number",
|
|
1560
|
+
description: "The pull request number"
|
|
1528
1561
|
}
|
|
1529
1562
|
}
|
|
1530
1563
|
}
|
|
@@ -1591,6 +1624,7 @@ const createPublishGithubPullRequestAction = ({
|
|
|
1591
1624
|
throw new GithubResponseError("null response from Github");
|
|
1592
1625
|
}
|
|
1593
1626
|
ctx.output("remoteUrl", response.data.html_url);
|
|
1627
|
+
ctx.output("pullRequestNumber", response.data.number);
|
|
1594
1628
|
} catch (e) {
|
|
1595
1629
|
throw new GithubResponseError("Pull request creation failed", e);
|
|
1596
1630
|
}
|
|
@@ -2010,49 +2044,74 @@ function createGithubWebhookAction(options) {
|
|
|
2010
2044
|
});
|
|
2011
2045
|
}
|
|
2012
2046
|
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2047
|
+
function createGithubIssuesLabelAction(options) {
|
|
2048
|
+
const { integrations, githubCredentialsProvider } = options;
|
|
2049
|
+
return createTemplateAction({
|
|
2050
|
+
id: "github:issues:label",
|
|
2051
|
+
description: "Adds labels to a pull request or issue on GitHub.",
|
|
2052
|
+
schema: {
|
|
2053
|
+
input: {
|
|
2054
|
+
type: "object",
|
|
2055
|
+
required: ["repoUrl", "number", "labels"],
|
|
2056
|
+
properties: {
|
|
2057
|
+
repoUrl: {
|
|
2058
|
+
title: "Repository Location",
|
|
2059
|
+
description: `Accepts the format 'github.com?repo=reponame&owner=owner' where 'reponame' is the repository name and 'owner' is an organization or username`,
|
|
2060
|
+
type: "string"
|
|
2061
|
+
},
|
|
2062
|
+
number: {
|
|
2063
|
+
title: "Pull Request or issue number",
|
|
2064
|
+
description: "The pull request or issue number to add labels to",
|
|
2065
|
+
type: "number"
|
|
2066
|
+
},
|
|
2067
|
+
labels: {
|
|
2068
|
+
title: "Labels",
|
|
2069
|
+
description: "The labels to add to the pull request or issue",
|
|
2070
|
+
type: "array",
|
|
2071
|
+
items: {
|
|
2072
|
+
type: "string"
|
|
2073
|
+
}
|
|
2074
|
+
},
|
|
2075
|
+
token: {
|
|
2076
|
+
title: "Authentication Token",
|
|
2077
|
+
type: "string",
|
|
2078
|
+
description: "The GITHUB_TOKEN to use for authorization to GitHub"
|
|
2079
|
+
}
|
|
2080
|
+
}
|
|
2081
|
+
}
|
|
2082
|
+
},
|
|
2083
|
+
async handler(ctx) {
|
|
2084
|
+
const { repoUrl, number, labels, token: providedToken } = ctx.input;
|
|
2085
|
+
const { owner, repo } = parseRepoUrl(repoUrl, integrations);
|
|
2086
|
+
ctx.logger.info(`Adding labels to ${number} issue on repo ${repo}`);
|
|
2087
|
+
if (!owner) {
|
|
2088
|
+
throw new errors.InputError("Invalid repository owner provided in repoUrl");
|
|
2089
|
+
}
|
|
2090
|
+
const client = new octokit.Octokit(await getOctokitOptions({
|
|
2091
|
+
integrations,
|
|
2092
|
+
credentialsProvider: githubCredentialsProvider,
|
|
2093
|
+
repoUrl,
|
|
2094
|
+
token: providedToken
|
|
2095
|
+
}));
|
|
2096
|
+
try {
|
|
2097
|
+
await client.rest.issues.addLabels({
|
|
2098
|
+
owner,
|
|
2099
|
+
repo,
|
|
2100
|
+
issue_number: number,
|
|
2101
|
+
labels
|
|
2102
|
+
});
|
|
2103
|
+
} catch (e) {
|
|
2104
|
+
errors.assertError(e);
|
|
2105
|
+
ctx.logger.warn(`Failed: adding labels to issue: '${number}' on repo: '${repo}', ${e.message}`);
|
|
2106
|
+
}
|
|
2041
2107
|
}
|
|
2042
|
-
|
|
2043
|
-
auth: token,
|
|
2044
|
-
baseUrl: integrationConfig.apiBaseUrl,
|
|
2045
|
-
previews: ["nebula-preview"]
|
|
2046
|
-
});
|
|
2047
|
-
return { client, token, owner, repo };
|
|
2048
|
-
}
|
|
2108
|
+
});
|
|
2049
2109
|
}
|
|
2050
2110
|
|
|
2051
2111
|
const createBuiltinActions = (options) => {
|
|
2052
2112
|
const {
|
|
2053
2113
|
reader,
|
|
2054
2114
|
integrations,
|
|
2055
|
-
containerRunner,
|
|
2056
2115
|
catalogClient,
|
|
2057
2116
|
config,
|
|
2058
2117
|
additionalTemplateFilters
|
|
@@ -2104,18 +2163,12 @@ const createBuiltinActions = (options) => {
|
|
|
2104
2163
|
createGithubWebhookAction({
|
|
2105
2164
|
integrations,
|
|
2106
2165
|
githubCredentialsProvider
|
|
2166
|
+
}),
|
|
2167
|
+
createGithubIssuesLabelAction({
|
|
2168
|
+
integrations,
|
|
2169
|
+
githubCredentialsProvider
|
|
2107
2170
|
})
|
|
2108
2171
|
];
|
|
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
2172
|
return actions;
|
|
2120
2173
|
};
|
|
2121
2174
|
|
|
@@ -2223,7 +2276,7 @@ class DatabaseTaskStore {
|
|
|
2223
2276
|
}
|
|
2224
2277
|
}
|
|
2225
2278
|
async listStaleTasks({ timeoutS }) {
|
|
2226
|
-
const rawRows = await this.db("tasks").where("status", "processing").andWhere("last_heartbeat_at", "<=", this.db.client.config.client
|
|
2279
|
+
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
2280
|
`-${timeoutS}`,
|
|
2228
2281
|
this.db.fn.now()
|
|
2229
2282
|
]));
|
|
@@ -2450,182 +2503,6 @@ function isTruthy(value) {
|
|
|
2450
2503
|
return lodash.isArray(value) ? value.length > 0 : !!value;
|
|
2451
2504
|
}
|
|
2452
2505
|
|
|
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
2506
|
const isValidTaskSpec = (taskSpec) => {
|
|
2630
2507
|
return taskSpec.apiVersion === "scaffolder.backstage.io/v1beta3";
|
|
2631
2508
|
};
|
|
@@ -2739,7 +2616,6 @@ class NunjucksWorkflowRunner {
|
|
|
2739
2616
|
const tmpDirs = new Array();
|
|
2740
2617
|
const stepOutput = {};
|
|
2741
2618
|
await action.handler({
|
|
2742
|
-
baseUrl: task.spec.baseUrl,
|
|
2743
2619
|
input,
|
|
2744
2620
|
secrets: (_d = task.secrets) != null ? _d : {},
|
|
2745
2621
|
logger: taskLogger,
|
|
@@ -2753,7 +2629,6 @@ class NunjucksWorkflowRunner {
|
|
|
2753
2629
|
output(name, value) {
|
|
2754
2630
|
stepOutput[name] = value;
|
|
2755
2631
|
},
|
|
2756
|
-
metadata: task.spec.metadata,
|
|
2757
2632
|
templateInfo: task.spec.templateInfo
|
|
2758
2633
|
});
|
|
2759
2634
|
for (const tmpDir of tmpDirs) {
|
|
@@ -2795,12 +2670,6 @@ class TaskWorker {
|
|
|
2795
2670
|
workingDirectory,
|
|
2796
2671
|
additionalTemplateFilters
|
|
2797
2672
|
} = options;
|
|
2798
|
-
const legacyWorkflowRunner = new HandlebarsWorkflowRunner({
|
|
2799
|
-
logger,
|
|
2800
|
-
actionRegistry,
|
|
2801
|
-
integrations,
|
|
2802
|
-
workingDirectory
|
|
2803
|
-
});
|
|
2804
2673
|
const workflowRunner = new NunjucksWorkflowRunner({
|
|
2805
2674
|
actionRegistry,
|
|
2806
2675
|
integrations,
|
|
@@ -2810,7 +2679,7 @@ class TaskWorker {
|
|
|
2810
2679
|
});
|
|
2811
2680
|
return new TaskWorker({
|
|
2812
2681
|
taskBroker,
|
|
2813
|
-
runners: {
|
|
2682
|
+
runners: { workflowRunner }
|
|
2814
2683
|
});
|
|
2815
2684
|
}
|
|
2816
2685
|
start() {
|
|
@@ -2823,7 +2692,10 @@ class TaskWorker {
|
|
|
2823
2692
|
}
|
|
2824
2693
|
async runOneTask(task) {
|
|
2825
2694
|
try {
|
|
2826
|
-
|
|
2695
|
+
if (task.spec.apiVersion !== "scaffolder.backstage.io/v1beta3") {
|
|
2696
|
+
throw new Error(`Unsupported Template apiVersion ${task.spec.apiVersion}`);
|
|
2697
|
+
}
|
|
2698
|
+
const { output } = await this.options.runners.workflowRunner.execute(task);
|
|
2827
2699
|
await task.complete("completed", { output });
|
|
2828
2700
|
} catch (error) {
|
|
2829
2701
|
errors.assertError(error);
|
|
@@ -2882,7 +2754,7 @@ async function findTemplate(options) {
|
|
|
2882
2754
|
}
|
|
2883
2755
|
|
|
2884
2756
|
function isSupportedTemplate(entity) {
|
|
2885
|
-
return entity.apiVersion === "
|
|
2757
|
+
return entity.apiVersion === "scaffolder.backstage.io/v1beta3";
|
|
2886
2758
|
}
|
|
2887
2759
|
async function createRouter(options) {
|
|
2888
2760
|
const router = Router__default["default"]();
|
|
@@ -2894,7 +2766,6 @@ async function createRouter(options) {
|
|
|
2894
2766
|
database,
|
|
2895
2767
|
catalogClient,
|
|
2896
2768
|
actions,
|
|
2897
|
-
containerRunner,
|
|
2898
2769
|
taskWorkers,
|
|
2899
2770
|
additionalTemplateFilters
|
|
2900
2771
|
} = options;
|
|
@@ -2926,7 +2797,6 @@ async function createRouter(options) {
|
|
|
2926
2797
|
const actionsToRegister = Array.isArray(actions) ? actions : createBuiltinActions({
|
|
2927
2798
|
integrations,
|
|
2928
2799
|
catalogClient,
|
|
2929
|
-
containerRunner,
|
|
2930
2800
|
reader,
|
|
2931
2801
|
config,
|
|
2932
2802
|
additionalTemplateFilters
|
|
@@ -2966,7 +2836,7 @@ async function createRouter(options) {
|
|
|
2966
2836
|
});
|
|
2967
2837
|
res.json(actionsList);
|
|
2968
2838
|
}).post("/v2/tasks", async (req, res) => {
|
|
2969
|
-
var _a, _b, _c
|
|
2839
|
+
var _a, _b, _c;
|
|
2970
2840
|
const templateRef = req.body.templateRef;
|
|
2971
2841
|
const { kind, namespace, name } = catalogModel.parseEntityRef(templateRef, {
|
|
2972
2842
|
defaultKind: "template"
|
|
@@ -2978,52 +2848,38 @@ async function createRouter(options) {
|
|
|
2978
2848
|
entityRef: { kind, namespace, name },
|
|
2979
2849
|
token: getBearerToken(req.headers.authorization)
|
|
2980
2850
|
});
|
|
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 {
|
|
2851
|
+
if (!isSupportedTemplate(template)) {
|
|
3025
2852
|
throw new errors.InputError(`Unsupported apiVersion field in schema entity, ${template.apiVersion}`);
|
|
3026
2853
|
}
|
|
2854
|
+
for (const parameters of [(_a = template.spec.parameters) != null ? _a : []].flat()) {
|
|
2855
|
+
const result2 = jsonschema.validate(values, parameters);
|
|
2856
|
+
if (!result2.valid) {
|
|
2857
|
+
res.status(400).json({ errors: result2.errors });
|
|
2858
|
+
return;
|
|
2859
|
+
}
|
|
2860
|
+
}
|
|
2861
|
+
const baseUrl = getEntityBaseUrl(template);
|
|
2862
|
+
const taskSpec = {
|
|
2863
|
+
apiVersion: template.apiVersion,
|
|
2864
|
+
steps: template.spec.steps.map((step, index) => {
|
|
2865
|
+
var _a2, _b2;
|
|
2866
|
+
return {
|
|
2867
|
+
...step,
|
|
2868
|
+
id: (_a2 = step.id) != null ? _a2 : `step-${index + 1}`,
|
|
2869
|
+
name: (_b2 = step.name) != null ? _b2 : step.action
|
|
2870
|
+
};
|
|
2871
|
+
}),
|
|
2872
|
+
output: (_b = template.spec.output) != null ? _b : {},
|
|
2873
|
+
parameters: values,
|
|
2874
|
+
templateInfo: {
|
|
2875
|
+
entityRef: catalogModel.stringifyEntityRef({
|
|
2876
|
+
kind,
|
|
2877
|
+
namespace,
|
|
2878
|
+
name: (_c = template.metadata) == null ? void 0 : _c.name
|
|
2879
|
+
}),
|
|
2880
|
+
baseUrl
|
|
2881
|
+
}
|
|
2882
|
+
};
|
|
3027
2883
|
const result = await taskBroker.dispatch({
|
|
3028
2884
|
spec: taskSpec,
|
|
3029
2885
|
secrets: {
|
|
@@ -3154,12 +3010,7 @@ class ScaffolderEntitiesProcessor {
|
|
|
3154
3010
|
}
|
|
3155
3011
|
}
|
|
3156
3012
|
|
|
3157
|
-
Object.defineProperty(exports, 'createFetchCookiecutterAction', {
|
|
3158
|
-
enumerable: true,
|
|
3159
|
-
get: function () { return pluginScaffolderBackendModuleCookiecutter.createFetchCookiecutterAction; }
|
|
3160
|
-
});
|
|
3161
3013
|
exports.DatabaseTaskStore = DatabaseTaskStore;
|
|
3162
|
-
exports.OctokitProvider = OctokitProvider;
|
|
3163
3014
|
exports.ScaffolderEntitiesProcessor = ScaffolderEntitiesProcessor;
|
|
3164
3015
|
exports.TaskManager = TaskManager;
|
|
3165
3016
|
exports.TaskWorker = TaskWorker;
|
|
@@ -3173,6 +3024,7 @@ exports.createFetchTemplateAction = createFetchTemplateAction;
|
|
|
3173
3024
|
exports.createFilesystemDeleteAction = createFilesystemDeleteAction;
|
|
3174
3025
|
exports.createFilesystemRenameAction = createFilesystemRenameAction;
|
|
3175
3026
|
exports.createGithubActionsDispatchAction = createGithubActionsDispatchAction;
|
|
3027
|
+
exports.createGithubIssuesLabelAction = createGithubIssuesLabelAction;
|
|
3176
3028
|
exports.createGithubWebhookAction = createGithubWebhookAction;
|
|
3177
3029
|
exports.createPublishAzureAction = createPublishAzureAction;
|
|
3178
3030
|
exports.createPublishBitbucketAction = createPublishBitbucketAction;
|
|
@@ -3185,5 +3037,4 @@ exports.createRouter = createRouter;
|
|
|
3185
3037
|
exports.createTemplateAction = createTemplateAction;
|
|
3186
3038
|
exports.executeShellCommand = executeShellCommand;
|
|
3187
3039
|
exports.fetchContents = fetchContents;
|
|
3188
|
-
exports.runCommand = runCommand;
|
|
3189
3040
|
//# sourceMappingURL=index.cjs.js.map
|