@backstage/plugin-scaffolder-backend 0.0.0-nightly-202202022734 → 0.0.0-nightly-20220206022752
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 +63 -9
- package/dist/index.cjs.js +190 -67
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +34 -21
- package/package.json +13 -13
package/dist/index.cjs.js
CHANGED
|
@@ -17,7 +17,7 @@ var child_process = require('child_process');
|
|
|
17
17
|
var stream = require('stream');
|
|
18
18
|
var azureDevopsNodeApi = require('azure-devops-node-api');
|
|
19
19
|
var fetch = require('node-fetch');
|
|
20
|
-
var
|
|
20
|
+
var octokit = require('octokit');
|
|
21
21
|
var lodash = require('lodash');
|
|
22
22
|
var octokitPluginCreatePullRequest = require('octokit-plugin-create-pull-request');
|
|
23
23
|
var node = require('@gitbeaker/node');
|
|
@@ -119,6 +119,7 @@ function createCatalogRegisterAction(options) {
|
|
|
119
119
|
}
|
|
120
120
|
},
|
|
121
121
|
async handler(ctx) {
|
|
122
|
+
var _a, _b;
|
|
122
123
|
const { input } = ctx;
|
|
123
124
|
let catalogInfoUrl;
|
|
124
125
|
if ("catalogInfoUrl" in input) {
|
|
@@ -138,13 +139,13 @@ function createCatalogRegisterAction(options) {
|
|
|
138
139
|
await catalogClient.addLocation({
|
|
139
140
|
type: "url",
|
|
140
141
|
target: catalogInfoUrl
|
|
141
|
-
}, ctx.
|
|
142
|
+
}, ((_a = ctx.secrets) == null ? void 0 : _a.backstageToken) ? { token: ctx.secrets.backstageToken } : {});
|
|
142
143
|
try {
|
|
143
144
|
const result = await catalogClient.addLocation({
|
|
144
145
|
dryRun: true,
|
|
145
146
|
type: "url",
|
|
146
147
|
target: catalogInfoUrl
|
|
147
|
-
}, ctx.
|
|
148
|
+
}, ((_b = ctx.secrets) == null ? void 0 : _b.backstageToken) ? { token: ctx.secrets.backstageToken } : {});
|
|
148
149
|
if (result.entities.length > 0) {
|
|
149
150
|
const { entities } = result;
|
|
150
151
|
let entity;
|
|
@@ -360,6 +361,12 @@ const { render, renderCompat } = (() => {
|
|
|
360
361
|
});
|
|
361
362
|
}
|
|
362
363
|
|
|
364
|
+
if (typeof additionalTemplateFilters !== 'undefined') {
|
|
365
|
+
for (const [filterName, filterFn] of Object.entries(additionalTemplateFilters)) {
|
|
366
|
+
env.addFilter(filterName, (...args) => JSON.parse(filterFn(...args)));
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
|
|
363
370
|
let uninstallCompat = undefined;
|
|
364
371
|
|
|
365
372
|
function render(str, values) {
|
|
@@ -392,12 +399,16 @@ const { render, renderCompat } = (() => {
|
|
|
392
399
|
`;
|
|
393
400
|
class SecureTemplater {
|
|
394
401
|
static async loadRenderer(options = {}) {
|
|
395
|
-
const { parseRepoUrl, cookiecutterCompat } = options;
|
|
396
|
-
|
|
402
|
+
const { parseRepoUrl, cookiecutterCompat, additionalTemplateFilters } = options;
|
|
403
|
+
const sandbox = {};
|
|
397
404
|
if (parseRepoUrl) {
|
|
398
|
-
sandbox =
|
|
399
|
-
|
|
400
|
-
|
|
405
|
+
sandbox.parseRepoUrl = (url) => JSON.stringify(parseRepoUrl(url));
|
|
406
|
+
}
|
|
407
|
+
if (additionalTemplateFilters) {
|
|
408
|
+
sandbox.additionalTemplateFilters = Object.fromEntries(Object.entries(additionalTemplateFilters).filter(([_, filterFunction]) => !!filterFunction).map(([filterName, filterFunction]) => [
|
|
409
|
+
filterName,
|
|
410
|
+
(...args) => JSON.stringify(filterFunction(...args))
|
|
411
|
+
]));
|
|
401
412
|
}
|
|
402
413
|
const vm = new vm2.VM({ sandbox });
|
|
403
414
|
const nunjucksSource = await fs__default["default"].readFile(backendCommon.resolvePackagePath("@backstage/plugin-scaffolder-backend", "assets/nunjucks.js.txt"), "utf-8");
|
|
@@ -418,7 +429,7 @@ class SecureTemplater {
|
|
|
418
429
|
}
|
|
419
430
|
|
|
420
431
|
function createFetchTemplateAction(options) {
|
|
421
|
-
const { reader, integrations } = options;
|
|
432
|
+
const { reader, integrations, additionalTemplateFilters } = options;
|
|
422
433
|
return createTemplateAction({
|
|
423
434
|
id: "fetch:template",
|
|
424
435
|
description: "Downloads a skeleton, templates variables into file and directory names and content, and places the result in the workspace, or optionally in a subdirectory specified by the 'targetPath' input option.",
|
|
@@ -509,7 +520,8 @@ function createFetchTemplateAction(options) {
|
|
|
509
520
|
};
|
|
510
521
|
ctx.logger.info(`Processing ${allEntriesInTemplate.length} template files/directories with input values`, ctx.input.values);
|
|
511
522
|
const renderTemplate = await SecureTemplater.loadRenderer({
|
|
512
|
-
cookiecutterCompat: ctx.input.cookiecutterCompat
|
|
523
|
+
cookiecutterCompat: ctx.input.cookiecutterCompat,
|
|
524
|
+
additionalTemplateFilters
|
|
513
525
|
});
|
|
514
526
|
for (const location of allEntriesInTemplate) {
|
|
515
527
|
let renderFilename;
|
|
@@ -729,7 +741,7 @@ const enableBranchProtectionOnDefaultRepoBranch = async ({
|
|
|
729
741
|
}) => {
|
|
730
742
|
const tryOnce = async () => {
|
|
731
743
|
try {
|
|
732
|
-
await client.repos.updateBranchProtection({
|
|
744
|
+
await client.rest.repos.updateBranchProtection({
|
|
733
745
|
mediaType: {
|
|
734
746
|
previews: ["luke-cage-preview"]
|
|
735
747
|
},
|
|
@@ -842,8 +854,14 @@ function createPublishAzureAction(options) {
|
|
|
842
854
|
description: `Sets the default branch on the repository. The default value is 'master'`
|
|
843
855
|
},
|
|
844
856
|
sourcePath: {
|
|
845
|
-
title: "Path
|
|
857
|
+
title: "Source Path",
|
|
858
|
+
description: "Path within the workspace that will be used as the repository root. If omitted, the entire workspace will be published as the repository.",
|
|
846
859
|
type: "string"
|
|
860
|
+
},
|
|
861
|
+
token: {
|
|
862
|
+
title: "Authentication Token",
|
|
863
|
+
type: "string",
|
|
864
|
+
description: "The token to use for authorization to Azure"
|
|
847
865
|
}
|
|
848
866
|
}
|
|
849
867
|
},
|
|
@@ -862,6 +880,7 @@ function createPublishAzureAction(options) {
|
|
|
862
880
|
}
|
|
863
881
|
},
|
|
864
882
|
async handler(ctx) {
|
|
883
|
+
var _a;
|
|
865
884
|
const { repoUrl, defaultBranch = "master" } = ctx.input;
|
|
866
885
|
const { owner, repo, host, organization } = parseRepoUrl(repoUrl, integrations);
|
|
867
886
|
if (!organization) {
|
|
@@ -871,10 +890,11 @@ function createPublishAzureAction(options) {
|
|
|
871
890
|
if (!integrationConfig) {
|
|
872
891
|
throw new errors.InputError(`No matching integration configuration for host ${host}, please check your integrations config`);
|
|
873
892
|
}
|
|
874
|
-
if (!integrationConfig.config.token) {
|
|
893
|
+
if (!integrationConfig.config.token && !ctx.input.token) {
|
|
875
894
|
throw new errors.InputError(`No token provided for Azure Integration ${host}`);
|
|
876
895
|
}
|
|
877
|
-
const
|
|
896
|
+
const token = (_a = ctx.input.token) != null ? _a : integrationConfig.config.token;
|
|
897
|
+
const authHandler = azureDevopsNodeApi.getPersonalAccessTokenHandler(token);
|
|
878
898
|
const webApi = new azureDevopsNodeApi.WebApi(`https://${host}/${organization}`, authHandler);
|
|
879
899
|
const client = await webApi.getGitApi();
|
|
880
900
|
const createOptions = { name: repo };
|
|
@@ -898,7 +918,7 @@ function createPublishAzureAction(options) {
|
|
|
898
918
|
defaultBranch,
|
|
899
919
|
auth: {
|
|
900
920
|
username: "notempty",
|
|
901
|
-
password:
|
|
921
|
+
password: token
|
|
902
922
|
},
|
|
903
923
|
logger: ctx.logger,
|
|
904
924
|
commitMessage: config.getOptionalString("scaffolder.defaultCommitMessage"),
|
|
@@ -1044,12 +1064,19 @@ function createPublishBitbucketAction(options) {
|
|
|
1044
1064
|
description: `Sets the default branch on the repository. The default value is 'master'`
|
|
1045
1065
|
},
|
|
1046
1066
|
sourcePath: {
|
|
1047
|
-
title: "Path
|
|
1067
|
+
title: "Source Path",
|
|
1068
|
+
description: "Path within the workspace that will be used as the repository root. If omitted, the entire workspace will be published as the repository.",
|
|
1048
1069
|
type: "string"
|
|
1049
1070
|
},
|
|
1050
1071
|
enableLFS: {
|
|
1051
|
-
title: "Enable LFS
|
|
1072
|
+
title: "Enable LFS?",
|
|
1073
|
+
description: "Enable LFS for the repository. Only available for hosted Bitbucket.",
|
|
1052
1074
|
type: "boolean"
|
|
1075
|
+
},
|
|
1076
|
+
token: {
|
|
1077
|
+
title: "Authentication Token",
|
|
1078
|
+
type: "string",
|
|
1079
|
+
description: "The token to use for authorization to BitBucket"
|
|
1053
1080
|
}
|
|
1054
1081
|
}
|
|
1055
1082
|
},
|
|
@@ -1089,7 +1116,7 @@ function createPublishBitbucketAction(options) {
|
|
|
1089
1116
|
if (!integrationConfig) {
|
|
1090
1117
|
throw new errors.InputError(`No matching integration configuration for host ${host}, please check your integrations config`);
|
|
1091
1118
|
}
|
|
1092
|
-
const authorization = getAuthorizationHeader(integrationConfig.config);
|
|
1119
|
+
const authorization = getAuthorizationHeader(ctx.input.token ? { host: integrationConfig.config.host, token: ctx.input.token } : integrationConfig.config);
|
|
1093
1120
|
const apiBaseUrl = integrationConfig.config.apiBaseUrl;
|
|
1094
1121
|
const createMethod = host === "bitbucket.org" ? createBitbucketCloudRepository : createBitbucketServerRepository;
|
|
1095
1122
|
const { remoteUrl, repoContentsUrl } = await createMethod({
|
|
@@ -1106,13 +1133,22 @@ function createPublishBitbucketAction(options) {
|
|
|
1106
1133
|
name: config.getOptionalString("scaffolder.defaultAuthor.name"),
|
|
1107
1134
|
email: config.getOptionalString("scaffolder.defaultAuthor.email")
|
|
1108
1135
|
};
|
|
1136
|
+
let auth;
|
|
1137
|
+
if (ctx.input.token) {
|
|
1138
|
+
auth = {
|
|
1139
|
+
username: "x-token-auth",
|
|
1140
|
+
password: ctx.input.token
|
|
1141
|
+
};
|
|
1142
|
+
} else {
|
|
1143
|
+
auth = {
|
|
1144
|
+
username: integrationConfig.config.username ? integrationConfig.config.username : "x-token-auth",
|
|
1145
|
+
password: integrationConfig.config.appPassword ? integrationConfig.config.appPassword : (_a = integrationConfig.config.token) != null ? _a : ""
|
|
1146
|
+
};
|
|
1147
|
+
}
|
|
1109
1148
|
await initRepoAndPush({
|
|
1110
1149
|
dir: getRepoSourceDirectory(ctx.workspacePath, ctx.input.sourcePath),
|
|
1111
1150
|
remoteUrl,
|
|
1112
|
-
auth
|
|
1113
|
-
username: integrationConfig.config.username ? integrationConfig.config.username : "x-token-auth",
|
|
1114
|
-
password: integrationConfig.config.appPassword ? integrationConfig.config.appPassword : (_a = integrationConfig.config.token) != null ? _a : ""
|
|
1115
|
-
},
|
|
1151
|
+
auth,
|
|
1116
1152
|
defaultBranch,
|
|
1117
1153
|
logger: ctx.logger,
|
|
1118
1154
|
commitMessage: config.getOptionalString("scaffolder.defaultCommitMessage"),
|
|
@@ -1160,7 +1196,7 @@ class OctokitProvider {
|
|
|
1160
1196
|
this.integrations = integrations;
|
|
1161
1197
|
this.githubCredentialsProvider = githubCredentialsProvider || integration.DefaultGithubCredentialsProvider.fromIntegrations(this.integrations);
|
|
1162
1198
|
}
|
|
1163
|
-
async getOctokit(repoUrl) {
|
|
1199
|
+
async getOctokit(repoUrl, options) {
|
|
1164
1200
|
var _a;
|
|
1165
1201
|
const { owner, repo, host } = parseRepoUrl(repoUrl, this.integrations);
|
|
1166
1202
|
if (!owner) {
|
|
@@ -1170,13 +1206,21 @@ class OctokitProvider {
|
|
|
1170
1206
|
if (!integrationConfig) {
|
|
1171
1207
|
throw new errors.InputError(`No integration for host ${host}`);
|
|
1172
1208
|
}
|
|
1209
|
+
if (options == null ? void 0 : options.token) {
|
|
1210
|
+
const client2 = new octokit.Octokit({
|
|
1211
|
+
auth: options.token,
|
|
1212
|
+
baseUrl: integrationConfig.apiBaseUrl,
|
|
1213
|
+
previews: ["nebula-preview"]
|
|
1214
|
+
});
|
|
1215
|
+
return { client: client2, token: options.token, owner, repo };
|
|
1216
|
+
}
|
|
1173
1217
|
const { token } = await this.githubCredentialsProvider.getCredentials({
|
|
1174
1218
|
url: `https://${host}/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}`
|
|
1175
1219
|
});
|
|
1176
1220
|
if (!token) {
|
|
1177
1221
|
throw new errors.InputError(`No token available for host: ${host}, with owner ${owner}, and repo ${repo}`);
|
|
1178
1222
|
}
|
|
1179
|
-
const client = new
|
|
1223
|
+
const client = new octokit.Octokit({
|
|
1180
1224
|
auth: token,
|
|
1181
1225
|
baseUrl: integrationConfig.apiBaseUrl,
|
|
1182
1226
|
previews: ["nebula-preview"]
|
|
@@ -1211,7 +1255,8 @@ function createPublishGithubAction(options) {
|
|
|
1211
1255
|
type: "string"
|
|
1212
1256
|
},
|
|
1213
1257
|
requireCodeOwnerReviews: {
|
|
1214
|
-
title: "Require
|
|
1258
|
+
title: "Require CODEOWNER Reviews?",
|
|
1259
|
+
description: "Require an approved review in PR including files with a designated Code Owner",
|
|
1215
1260
|
type: "boolean"
|
|
1216
1261
|
},
|
|
1217
1262
|
repoVisibility: {
|
|
@@ -1225,7 +1270,8 @@ function createPublishGithubAction(options) {
|
|
|
1225
1270
|
description: `Sets the default branch on the repository. The default value is 'master'`
|
|
1226
1271
|
},
|
|
1227
1272
|
sourcePath: {
|
|
1228
|
-
title: "Path
|
|
1273
|
+
title: "Source Path",
|
|
1274
|
+
description: "Path within the workspace that will be used as the repository root. If omitted, the entire workspace will be published as the repository.",
|
|
1229
1275
|
type: "string"
|
|
1230
1276
|
},
|
|
1231
1277
|
collaborators: {
|
|
@@ -1248,6 +1294,11 @@ function createPublishGithubAction(options) {
|
|
|
1248
1294
|
}
|
|
1249
1295
|
}
|
|
1250
1296
|
},
|
|
1297
|
+
token: {
|
|
1298
|
+
title: "Authentication Token",
|
|
1299
|
+
type: "string",
|
|
1300
|
+
description: "The token to use for authorization to GitHub"
|
|
1301
|
+
},
|
|
1251
1302
|
topics: {
|
|
1252
1303
|
title: "Topics",
|
|
1253
1304
|
type: "array",
|
|
@@ -1280,19 +1331,20 @@ function createPublishGithubAction(options) {
|
|
|
1280
1331
|
repoVisibility = "private",
|
|
1281
1332
|
defaultBranch = "master",
|
|
1282
1333
|
collaborators,
|
|
1283
|
-
topics
|
|
1334
|
+
topics,
|
|
1335
|
+
token: providedToken
|
|
1284
1336
|
} = ctx.input;
|
|
1285
|
-
const { client, token, owner, repo } = await octokitProvider.getOctokit(repoUrl);
|
|
1286
|
-
const user = await client.users.getByUsername({
|
|
1337
|
+
const { client, token, owner, repo } = await octokitProvider.getOctokit(repoUrl, { token: providedToken });
|
|
1338
|
+
const user = await client.rest.users.getByUsername({
|
|
1287
1339
|
username: owner
|
|
1288
1340
|
});
|
|
1289
|
-
const repoCreationPromise = user.data.type === "Organization" ? client.repos.createInOrg({
|
|
1341
|
+
const repoCreationPromise = user.data.type === "Organization" ? client.rest.repos.createInOrg({
|
|
1290
1342
|
name: repo,
|
|
1291
1343
|
org: owner,
|
|
1292
1344
|
private: repoVisibility === "private",
|
|
1293
1345
|
visibility: repoVisibility,
|
|
1294
1346
|
description
|
|
1295
|
-
}) : client.repos.createForAuthenticatedUser({
|
|
1347
|
+
}) : client.rest.repos.createForAuthenticatedUser({
|
|
1296
1348
|
name: repo,
|
|
1297
1349
|
private: repoVisibility === "private",
|
|
1298
1350
|
description
|
|
@@ -1300,7 +1352,7 @@ function createPublishGithubAction(options) {
|
|
|
1300
1352
|
const { data: newRepo } = await repoCreationPromise;
|
|
1301
1353
|
if (access == null ? void 0 : access.startsWith(`${owner}/`)) {
|
|
1302
1354
|
const [, team] = access.split("/");
|
|
1303
|
-
await client.teams.addOrUpdateRepoPermissionsInOrg({
|
|
1355
|
+
await client.rest.teams.addOrUpdateRepoPermissionsInOrg({
|
|
1304
1356
|
org: owner,
|
|
1305
1357
|
team_slug: team,
|
|
1306
1358
|
owner,
|
|
@@ -1308,7 +1360,7 @@ function createPublishGithubAction(options) {
|
|
|
1308
1360
|
permission: "admin"
|
|
1309
1361
|
});
|
|
1310
1362
|
} else if (access && access !== owner) {
|
|
1311
|
-
await client.repos.addCollaborator({
|
|
1363
|
+
await client.rest.repos.addCollaborator({
|
|
1312
1364
|
owner,
|
|
1313
1365
|
repo,
|
|
1314
1366
|
username: access,
|
|
@@ -1321,7 +1373,7 @@ function createPublishGithubAction(options) {
|
|
|
1321
1373
|
username: team_slug
|
|
1322
1374
|
} of collaborators) {
|
|
1323
1375
|
try {
|
|
1324
|
-
await client.teams.addOrUpdateRepoPermissionsInOrg({
|
|
1376
|
+
await client.rest.teams.addOrUpdateRepoPermissionsInOrg({
|
|
1325
1377
|
org: owner,
|
|
1326
1378
|
team_slug,
|
|
1327
1379
|
owner,
|
|
@@ -1336,7 +1388,7 @@ function createPublishGithubAction(options) {
|
|
|
1336
1388
|
}
|
|
1337
1389
|
if (topics) {
|
|
1338
1390
|
try {
|
|
1339
|
-
await client.repos.replaceAllTopics({
|
|
1391
|
+
await client.rest.repos.replaceAllTopics({
|
|
1340
1392
|
owner,
|
|
1341
1393
|
repo,
|
|
1342
1394
|
names: topics.map((t) => t.toLowerCase())
|
|
@@ -1390,13 +1442,21 @@ const defaultClientFactory = async ({
|
|
|
1390
1442
|
githubCredentialsProvider,
|
|
1391
1443
|
owner,
|
|
1392
1444
|
repo,
|
|
1393
|
-
host = "github.com"
|
|
1445
|
+
host = "github.com",
|
|
1446
|
+
token: providedToken
|
|
1394
1447
|
}) => {
|
|
1395
1448
|
var _a;
|
|
1396
1449
|
const integrationConfig = (_a = integrations.github.byHost(host)) == null ? void 0 : _a.config;
|
|
1450
|
+
const OctokitPR = octokit.Octokit.plugin(octokitPluginCreatePullRequest.createPullRequest);
|
|
1397
1451
|
if (!integrationConfig) {
|
|
1398
1452
|
throw new errors.InputError(`No integration for host ${host}`);
|
|
1399
1453
|
}
|
|
1454
|
+
if (providedToken) {
|
|
1455
|
+
return new OctokitPR({
|
|
1456
|
+
auth: providedToken,
|
|
1457
|
+
baseUrl: integrationConfig.apiBaseUrl
|
|
1458
|
+
});
|
|
1459
|
+
}
|
|
1400
1460
|
const credentialsProvider = githubCredentialsProvider || integration.SingleInstanceGithubCredentialsProvider.create(integrationConfig);
|
|
1401
1461
|
const { token } = await credentialsProvider.getCredentials({
|
|
1402
1462
|
url: `https://${host}/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}`
|
|
@@ -1404,7 +1464,6 @@ const defaultClientFactory = async ({
|
|
|
1404
1464
|
if (!token) {
|
|
1405
1465
|
throw new errors.InputError(`No token available for host: ${host}, with owner ${owner}, and repo ${repo}`);
|
|
1406
1466
|
}
|
|
1407
|
-
const OctokitPR = rest.Octokit.plugin(octokitPluginCreatePullRequest.createPullRequest);
|
|
1408
1467
|
return new OctokitPR({
|
|
1409
1468
|
auth: token,
|
|
1410
1469
|
baseUrl: integrationConfig.apiBaseUrl
|
|
@@ -1451,6 +1510,11 @@ const createPublishGithubPullRequestAction = ({
|
|
|
1451
1510
|
type: "string",
|
|
1452
1511
|
title: "Repository Subdirectory",
|
|
1453
1512
|
description: "Subdirectory of repository to apply changes to"
|
|
1513
|
+
},
|
|
1514
|
+
token: {
|
|
1515
|
+
title: "Authentication Token",
|
|
1516
|
+
type: "string",
|
|
1517
|
+
description: "The token to use for authorization to GitHub"
|
|
1454
1518
|
}
|
|
1455
1519
|
}
|
|
1456
1520
|
},
|
|
@@ -1473,7 +1537,8 @@ const createPublishGithubPullRequestAction = ({
|
|
|
1473
1537
|
title,
|
|
1474
1538
|
description,
|
|
1475
1539
|
targetPath,
|
|
1476
|
-
sourcePath
|
|
1540
|
+
sourcePath,
|
|
1541
|
+
token: providedToken
|
|
1477
1542
|
} = ctx.input;
|
|
1478
1543
|
const { owner, repo, host } = parseRepoUrl(repoUrl, integrations);
|
|
1479
1544
|
if (!owner) {
|
|
@@ -1484,7 +1549,8 @@ const createPublishGithubPullRequestAction = ({
|
|
|
1484
1549
|
githubCredentialsProvider,
|
|
1485
1550
|
host,
|
|
1486
1551
|
owner,
|
|
1487
|
-
repo
|
|
1552
|
+
repo,
|
|
1553
|
+
token: providedToken
|
|
1488
1554
|
});
|
|
1489
1555
|
const fileRoot = sourcePath ? backendCommon.resolveSafeChildPath(ctx.workspacePath, sourcePath) : ctx.workspacePath;
|
|
1490
1556
|
const localFilePaths = await globby__default["default"](["./**", "./**/.*", "!.git"], {
|
|
@@ -1558,8 +1624,14 @@ function createPublishGitlabAction(options) {
|
|
|
1558
1624
|
description: `Sets the default branch on the repository. The default value is 'master'`
|
|
1559
1625
|
},
|
|
1560
1626
|
sourcePath: {
|
|
1561
|
-
title: "Path
|
|
1627
|
+
title: "Source Path",
|
|
1628
|
+
description: "Path within the workspace that will be used as the repository root. If omitted, the entire workspace will be published as the repository.",
|
|
1562
1629
|
type: "string"
|
|
1630
|
+
},
|
|
1631
|
+
token: {
|
|
1632
|
+
title: "Authentication Token",
|
|
1633
|
+
type: "string",
|
|
1634
|
+
description: "The token to use for authorization to GitLab"
|
|
1563
1635
|
}
|
|
1564
1636
|
}
|
|
1565
1637
|
},
|
|
@@ -1591,12 +1663,14 @@ function createPublishGitlabAction(options) {
|
|
|
1591
1663
|
if (!integrationConfig) {
|
|
1592
1664
|
throw new errors.InputError(`No matching integration configuration for host ${host}, please check your integrations config`);
|
|
1593
1665
|
}
|
|
1594
|
-
if (!integrationConfig.config.token) {
|
|
1666
|
+
if (!integrationConfig.config.token && !ctx.input.token) {
|
|
1595
1667
|
throw new errors.InputError(`No token available for host ${host}`);
|
|
1596
1668
|
}
|
|
1669
|
+
const token = ctx.input.token || integrationConfig.config.token;
|
|
1670
|
+
const tokenType = ctx.input.token ? "oauthToken" : "token";
|
|
1597
1671
|
const client = new node.Gitlab({
|
|
1598
1672
|
host: integrationConfig.config.baseUrl,
|
|
1599
|
-
|
|
1673
|
+
[tokenType]: token
|
|
1600
1674
|
});
|
|
1601
1675
|
let { id: targetNamespace } = await client.Namespaces.show(owner);
|
|
1602
1676
|
if (!targetNamespace) {
|
|
@@ -1620,7 +1694,7 @@ function createPublishGitlabAction(options) {
|
|
|
1620
1694
|
defaultBranch,
|
|
1621
1695
|
auth: {
|
|
1622
1696
|
username: "oauth2",
|
|
1623
|
-
password:
|
|
1697
|
+
password: token
|
|
1624
1698
|
},
|
|
1625
1699
|
logger: ctx.logger,
|
|
1626
1700
|
commitMessage: config.getOptionalString("scaffolder.defaultCommitMessage"),
|
|
@@ -1670,6 +1744,11 @@ const createPublishGitlabMergeRequestAction = (options) => {
|
|
|
1670
1744
|
type: "string",
|
|
1671
1745
|
title: "Repository Subdirectory",
|
|
1672
1746
|
description: "Subdirectory of repository to apply changes to"
|
|
1747
|
+
},
|
|
1748
|
+
token: {
|
|
1749
|
+
title: "Authentication Token",
|
|
1750
|
+
type: "string",
|
|
1751
|
+
description: "The token to use for authorization to GitLab"
|
|
1673
1752
|
}
|
|
1674
1753
|
}
|
|
1675
1754
|
},
|
|
@@ -1689,6 +1768,7 @@ const createPublishGitlabMergeRequestAction = (options) => {
|
|
|
1689
1768
|
}
|
|
1690
1769
|
},
|
|
1691
1770
|
async handler(ctx) {
|
|
1771
|
+
var _a;
|
|
1692
1772
|
const repoUrl = ctx.input.repoUrl;
|
|
1693
1773
|
const { host } = parseRepoUrl(repoUrl, integrations);
|
|
1694
1774
|
const integrationConfig = integrations.gitlab.byHost(host);
|
|
@@ -1697,12 +1777,14 @@ const createPublishGitlabMergeRequestAction = (options) => {
|
|
|
1697
1777
|
if (!integrationConfig) {
|
|
1698
1778
|
throw new errors.InputError(`No matching integration configuration for host ${host}, please check your integrations config`);
|
|
1699
1779
|
}
|
|
1700
|
-
if (!integrationConfig.config.token) {
|
|
1780
|
+
if (!integrationConfig.config.token && !ctx.input.token) {
|
|
1701
1781
|
throw new errors.InputError(`No token available for host ${host}`);
|
|
1702
1782
|
}
|
|
1783
|
+
const token = (_a = ctx.input.token) != null ? _a : integrationConfig.config.token;
|
|
1784
|
+
const tokenType = ctx.input.token ? "oauthToken" : "token";
|
|
1703
1785
|
const api = new node.Gitlab({
|
|
1704
1786
|
host: integrationConfig.config.baseUrl,
|
|
1705
|
-
|
|
1787
|
+
[tokenType]: token
|
|
1706
1788
|
});
|
|
1707
1789
|
const fileRoot = ctx.workspacePath;
|
|
1708
1790
|
const localFilePaths = await globby__default["default"]([`${ctx.input.targetPath}/**`], {
|
|
@@ -1771,19 +1853,36 @@ function createGithubActionsDispatchAction(options) {
|
|
|
1771
1853
|
title: "Branch or Tag name",
|
|
1772
1854
|
description: "The git branch or tag name used to dispatch the workflow",
|
|
1773
1855
|
type: "string"
|
|
1856
|
+
},
|
|
1857
|
+
workflowInputs: {
|
|
1858
|
+
title: "Workflow Inputs",
|
|
1859
|
+
description: "Inputs keys and values to send to GitHub Action configured on the workflow file. The maximum number of properties is 10. ",
|
|
1860
|
+
type: "object"
|
|
1861
|
+
},
|
|
1862
|
+
token: {
|
|
1863
|
+
title: "Authentication Token",
|
|
1864
|
+
type: "string",
|
|
1865
|
+
description: "The GITHUB_TOKEN to use for authorization to GitHub"
|
|
1774
1866
|
}
|
|
1775
1867
|
}
|
|
1776
1868
|
}
|
|
1777
1869
|
},
|
|
1778
1870
|
async handler(ctx) {
|
|
1779
|
-
const {
|
|
1871
|
+
const {
|
|
1872
|
+
repoUrl,
|
|
1873
|
+
workflowId,
|
|
1874
|
+
branchOrTagName,
|
|
1875
|
+
workflowInputs,
|
|
1876
|
+
token: providedToken
|
|
1877
|
+
} = ctx.input;
|
|
1780
1878
|
ctx.logger.info(`Dispatching workflow ${workflowId} for repo ${repoUrl} on ${branchOrTagName}`);
|
|
1781
|
-
const { client, owner, repo } = await octokitProvider.getOctokit(repoUrl);
|
|
1879
|
+
const { client, owner, repo } = await octokitProvider.getOctokit(repoUrl, { token: providedToken });
|
|
1782
1880
|
await client.rest.actions.createWorkflowDispatch({
|
|
1783
1881
|
owner,
|
|
1784
1882
|
repo,
|
|
1785
1883
|
workflow_id: workflowId,
|
|
1786
|
-
ref: branchOrTagName
|
|
1884
|
+
ref: branchOrTagName,
|
|
1885
|
+
inputs: workflowInputs
|
|
1787
1886
|
});
|
|
1788
1887
|
ctx.logger.info(`Workflow ${workflowId} dispatched successfully`);
|
|
1789
1888
|
}
|
|
@@ -1851,6 +1950,11 @@ function createGithubWebhookAction(options) {
|
|
|
1851
1950
|
title: "Insecure SSL",
|
|
1852
1951
|
type: "boolean",
|
|
1853
1952
|
description: `Determines whether the SSL certificate of the host for url will be verified when delivering payloads. Default 'false'`
|
|
1953
|
+
},
|
|
1954
|
+
token: {
|
|
1955
|
+
title: "Authentication Token",
|
|
1956
|
+
type: "string",
|
|
1957
|
+
description: "The GITHUB_TOKEN to use for authorization to GitHub"
|
|
1854
1958
|
}
|
|
1855
1959
|
}
|
|
1856
1960
|
}
|
|
@@ -1863,13 +1967,14 @@ function createGithubWebhookAction(options) {
|
|
|
1863
1967
|
events = ["push"],
|
|
1864
1968
|
active = true,
|
|
1865
1969
|
contentType = "form",
|
|
1866
|
-
insecureSsl = false
|
|
1970
|
+
insecureSsl = false,
|
|
1971
|
+
token: providedToken
|
|
1867
1972
|
} = ctx.input;
|
|
1868
1973
|
ctx.logger.info(`Creating webhook ${webhookUrl} for repo ${repoUrl}`);
|
|
1869
|
-
const { client, owner, repo } = await octokitProvider.getOctokit(repoUrl);
|
|
1974
|
+
const { client, owner, repo } = await octokitProvider.getOctokit(repoUrl, { token: providedToken });
|
|
1870
1975
|
try {
|
|
1871
1976
|
const insecure_ssl = insecureSsl ? "1" : "0";
|
|
1872
|
-
await client.repos.createWebhook({
|
|
1977
|
+
await client.rest.repos.createWebhook({
|
|
1873
1978
|
owner,
|
|
1874
1979
|
repo,
|
|
1875
1980
|
config: {
|
|
@@ -1891,7 +1996,14 @@ function createGithubWebhookAction(options) {
|
|
|
1891
1996
|
}
|
|
1892
1997
|
|
|
1893
1998
|
const createBuiltinActions = (options) => {
|
|
1894
|
-
const {
|
|
1999
|
+
const {
|
|
2000
|
+
reader,
|
|
2001
|
+
integrations,
|
|
2002
|
+
containerRunner,
|
|
2003
|
+
catalogClient,
|
|
2004
|
+
config,
|
|
2005
|
+
additionalTemplateFilters
|
|
2006
|
+
} = options;
|
|
1895
2007
|
const githubCredentialsProvider = integration.DefaultGithubCredentialsProvider.fromIntegrations(integrations);
|
|
1896
2008
|
const actions = [
|
|
1897
2009
|
createFetchPlainAction({
|
|
@@ -1900,7 +2012,8 @@ const createBuiltinActions = (options) => {
|
|
|
1900
2012
|
}),
|
|
1901
2013
|
createFetchTemplateAction({
|
|
1902
2014
|
integrations,
|
|
1903
|
-
reader
|
|
2015
|
+
reader,
|
|
2016
|
+
additionalTemplateFilters
|
|
1904
2017
|
}),
|
|
1905
2018
|
createPublishGithubAction({
|
|
1906
2019
|
integrations,
|
|
@@ -2023,7 +2136,8 @@ class DatabaseTaskStore {
|
|
|
2023
2136
|
}
|
|
2024
2137
|
const updateCount = await tx("tasks").where({ id: task.id, status: "open" }).update({
|
|
2025
2138
|
status: "processing",
|
|
2026
|
-
last_heartbeat_at: this.db.fn.now()
|
|
2139
|
+
last_heartbeat_at: this.db.fn.now(),
|
|
2140
|
+
secrets: null
|
|
2027
2141
|
});
|
|
2028
2142
|
if (updateCount < 1) {
|
|
2029
2143
|
return void 0;
|
|
@@ -2087,8 +2201,7 @@ class DatabaseTaskStore {
|
|
|
2087
2201
|
id: taskId,
|
|
2088
2202
|
status: oldStatus
|
|
2089
2203
|
}).update({
|
|
2090
|
-
status
|
|
2091
|
-
secrets: null
|
|
2204
|
+
status
|
|
2092
2205
|
});
|
|
2093
2206
|
if (updateCount !== 1) {
|
|
2094
2207
|
throw new errors.ConflictError(`Failed to update status to '${status}' for taskId ${taskId}`);
|
|
@@ -2301,7 +2414,7 @@ class HandlebarsWorkflowRunner {
|
|
|
2301
2414
|
this.handlebars.registerHelper("eq", (a, b) => a === b);
|
|
2302
2415
|
}
|
|
2303
2416
|
async execute(task) {
|
|
2304
|
-
var _a, _b;
|
|
2417
|
+
var _a, _b, _c;
|
|
2305
2418
|
if (!isValidTaskSpec$1(task.spec)) {
|
|
2306
2419
|
throw new errors.InputError(`Task spec is not a valid v1beta2 task spec`);
|
|
2307
2420
|
}
|
|
@@ -2405,6 +2518,7 @@ class HandlebarsWorkflowRunner {
|
|
|
2405
2518
|
logStream: stream$1,
|
|
2406
2519
|
input,
|
|
2407
2520
|
token: (_b = task.secrets) == null ? void 0 : _b.token,
|
|
2521
|
+
secrets: (_c = task.secrets) != null ? _c : {},
|
|
2408
2522
|
workspacePath,
|
|
2409
2523
|
async createTemporaryDirectory() {
|
|
2410
2524
|
const tmpDir = await fs__default["default"].mkdtemp(`${workspacePath}_step-${step.id}-`);
|
|
@@ -2530,7 +2644,7 @@ class NunjucksWorkflowRunner {
|
|
|
2530
2644
|
});
|
|
2531
2645
|
}
|
|
2532
2646
|
async execute(task) {
|
|
2533
|
-
var _a, _b, _c;
|
|
2647
|
+
var _a, _b, _c, _d, _e;
|
|
2534
2648
|
if (!isValidTaskSpec(task.spec)) {
|
|
2535
2649
|
throw new errors.InputError("Wrong template version executed with the workflow engine");
|
|
2536
2650
|
}
|
|
@@ -2539,7 +2653,8 @@ class NunjucksWorkflowRunner {
|
|
|
2539
2653
|
const renderTemplate = await SecureTemplater.loadRenderer({
|
|
2540
2654
|
parseRepoUrl(url) {
|
|
2541
2655
|
return parseRepoUrl(url, integrations);
|
|
2542
|
-
}
|
|
2656
|
+
},
|
|
2657
|
+
additionalTemplateFilters: this.options.additionalTemplateFilters
|
|
2543
2658
|
});
|
|
2544
2659
|
try {
|
|
2545
2660
|
await fs__default["default"].ensureDir(workspacePath);
|
|
@@ -2563,8 +2678,8 @@ class NunjucksWorkflowRunner {
|
|
|
2563
2678
|
});
|
|
2564
2679
|
const action = this.options.actionRegistry.get(step.action);
|
|
2565
2680
|
const { taskLogger, streamLogger } = createStepLogger({ task, step });
|
|
2566
|
-
const input = (
|
|
2567
|
-
if ((
|
|
2681
|
+
const input = (_b = step.input && this.render(step.input, { ...context, secrets: (_a = task.secrets) != null ? _a : {} }, renderTemplate)) != null ? _b : {};
|
|
2682
|
+
if ((_c = action.schema) == null ? void 0 : _c.input) {
|
|
2568
2683
|
const validateResult = jsonschema.validate(input, action.schema.input);
|
|
2569
2684
|
if (!validateResult.valid) {
|
|
2570
2685
|
const errors$1 = validateResult.errors.join(", ");
|
|
@@ -2579,7 +2694,8 @@ class NunjucksWorkflowRunner {
|
|
|
2579
2694
|
await action.handler({
|
|
2580
2695
|
baseUrl: task.spec.baseUrl,
|
|
2581
2696
|
input,
|
|
2582
|
-
token: (
|
|
2697
|
+
token: (_d = task.secrets) == null ? void 0 : _d.token,
|
|
2698
|
+
secrets: (_e = task.secrets) != null ? _e : {},
|
|
2583
2699
|
logger: taskLogger,
|
|
2584
2700
|
logStream: streamLogger,
|
|
2585
2701
|
workspacePath,
|
|
@@ -2629,7 +2745,8 @@ class TaskWorker {
|
|
|
2629
2745
|
logger,
|
|
2630
2746
|
actionRegistry,
|
|
2631
2747
|
integrations,
|
|
2632
|
-
workingDirectory
|
|
2748
|
+
workingDirectory,
|
|
2749
|
+
additionalTemplateFilters
|
|
2633
2750
|
} = options;
|
|
2634
2751
|
const legacyWorkflowRunner = new HandlebarsWorkflowRunner({
|
|
2635
2752
|
logger,
|
|
@@ -2641,7 +2758,8 @@ class TaskWorker {
|
|
|
2641
2758
|
actionRegistry,
|
|
2642
2759
|
integrations,
|
|
2643
2760
|
logger,
|
|
2644
|
-
workingDirectory
|
|
2761
|
+
workingDirectory,
|
|
2762
|
+
additionalTemplateFilters
|
|
2645
2763
|
});
|
|
2646
2764
|
return new TaskWorker({
|
|
2647
2765
|
taskBroker,
|
|
@@ -2738,7 +2856,8 @@ async function createRouter(options) {
|
|
|
2738
2856
|
catalogClient,
|
|
2739
2857
|
actions,
|
|
2740
2858
|
containerRunner,
|
|
2741
|
-
taskWorkers
|
|
2859
|
+
taskWorkers,
|
|
2860
|
+
additionalTemplateFilters
|
|
2742
2861
|
} = options;
|
|
2743
2862
|
const logger = parentLogger.child({ plugin: "scaffolder" });
|
|
2744
2863
|
const workingDirectory = await getWorkingDirectory(config, logger);
|
|
@@ -2761,7 +2880,8 @@ async function createRouter(options) {
|
|
|
2761
2880
|
actionRegistry,
|
|
2762
2881
|
integrations,
|
|
2763
2882
|
logger,
|
|
2764
|
-
workingDirectory
|
|
2883
|
+
workingDirectory,
|
|
2884
|
+
additionalTemplateFilters
|
|
2765
2885
|
});
|
|
2766
2886
|
workers.push(worker);
|
|
2767
2887
|
}
|
|
@@ -2770,7 +2890,8 @@ async function createRouter(options) {
|
|
|
2770
2890
|
catalogClient,
|
|
2771
2891
|
containerRunner,
|
|
2772
2892
|
reader,
|
|
2773
|
-
config
|
|
2893
|
+
config,
|
|
2894
|
+
additionalTemplateFilters
|
|
2774
2895
|
});
|
|
2775
2896
|
actionsToRegister.forEach((action) => actionRegistry.register(action));
|
|
2776
2897
|
workers.forEach((worker) => worker.start());
|
|
@@ -2861,6 +2982,8 @@ async function createRouter(options) {
|
|
|
2861
2982
|
throw new errors.InputError(`Unsupported apiVersion field in schema entity, ${template.apiVersion}`);
|
|
2862
2983
|
}
|
|
2863
2984
|
const result = await taskBroker.dispatch(taskSpec, {
|
|
2985
|
+
...req.body.secrets,
|
|
2986
|
+
backstageToken: token,
|
|
2864
2987
|
token
|
|
2865
2988
|
});
|
|
2866
2989
|
res.status(201).json({ id: result.taskId });
|