@backstage/plugin-scaffolder-backend 1.10.0-next.1 → 1.10.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 +213 -0
- package/alpha/package.json +1 -1
- package/dist/index.alpha.d.ts +40 -1
- package/dist/index.beta.d.ts +39 -0
- package/dist/index.cjs.js +376 -86
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +39 -0
- package/package.json +14 -14
package/dist/index.cjs.js
CHANGED
|
@@ -4,8 +4,8 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
4
4
|
|
|
5
5
|
var errors = require('@backstage/errors');
|
|
6
6
|
var catalogModel = require('@backstage/catalog-model');
|
|
7
|
-
var fs = require('fs-extra');
|
|
8
7
|
var yaml = require('yaml');
|
|
8
|
+
var fs = require('fs-extra');
|
|
9
9
|
var backendCommon = require('@backstage/backend-common');
|
|
10
10
|
var integration = require('@backstage/integration');
|
|
11
11
|
var path = require('path');
|
|
@@ -62,8 +62,9 @@ function _interopNamespace(e) {
|
|
|
62
62
|
return Object.freeze(n);
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
-
var
|
|
65
|
+
var yaml__default = /*#__PURE__*/_interopDefaultLegacy(yaml);
|
|
66
66
|
var yaml__namespace = /*#__PURE__*/_interopNamespace(yaml);
|
|
67
|
+
var fs__default = /*#__PURE__*/_interopDefaultLegacy(fs);
|
|
67
68
|
var path__default = /*#__PURE__*/_interopDefaultLegacy(path);
|
|
68
69
|
var globby__default = /*#__PURE__*/_interopDefaultLegacy(globby);
|
|
69
70
|
var fetch__default = /*#__PURE__*/_interopDefaultLegacy(fetch);
|
|
@@ -81,11 +82,30 @@ const createTemplateAction = (templateAction) => {
|
|
|
81
82
|
return templateAction;
|
|
82
83
|
};
|
|
83
84
|
|
|
85
|
+
const id$3 = "catalog:register";
|
|
86
|
+
const examples$3 = [
|
|
87
|
+
{
|
|
88
|
+
description: "Register with the catalog",
|
|
89
|
+
example: yaml__default["default"].stringify({
|
|
90
|
+
steps: [
|
|
91
|
+
{
|
|
92
|
+
action: id$3,
|
|
93
|
+
id: "register-with-catalog",
|
|
94
|
+
name: "Register with the catalog",
|
|
95
|
+
input: {
|
|
96
|
+
catalogInfoUrl: "http://github.com/backstage/backstage/blob/master/catalog-info.yaml"
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
]
|
|
100
|
+
})
|
|
101
|
+
}
|
|
102
|
+
];
|
|
84
103
|
function createCatalogRegisterAction(options) {
|
|
85
104
|
const { catalogClient, integrations } = options;
|
|
86
105
|
return createTemplateAction({
|
|
87
|
-
id:
|
|
106
|
+
id: id$3,
|
|
88
107
|
description: "Registers entities from a catalog descriptor file in the workspace into the software catalog.",
|
|
108
|
+
examples: examples$3,
|
|
89
109
|
schema: {
|
|
90
110
|
input: {
|
|
91
111
|
oneOf: [
|
|
@@ -203,10 +223,41 @@ function createCatalogRegisterAction(options) {
|
|
|
203
223
|
});
|
|
204
224
|
}
|
|
205
225
|
|
|
226
|
+
const id$2 = "catalog:write";
|
|
227
|
+
const examples$2 = [
|
|
228
|
+
{
|
|
229
|
+
description: "Write a catalog yaml file",
|
|
230
|
+
example: yaml__namespace.stringify({
|
|
231
|
+
steps: [
|
|
232
|
+
{
|
|
233
|
+
action: id$2,
|
|
234
|
+
id: "create-catalog-info-file",
|
|
235
|
+
name: "Create catalog file",
|
|
236
|
+
input: {
|
|
237
|
+
entity: {
|
|
238
|
+
apiVersion: "backstage.io/v1alpha1",
|
|
239
|
+
kind: "Component",
|
|
240
|
+
metadata: {
|
|
241
|
+
name: "test",
|
|
242
|
+
annotations: {}
|
|
243
|
+
},
|
|
244
|
+
spec: {
|
|
245
|
+
type: "service",
|
|
246
|
+
lifecycle: "production",
|
|
247
|
+
owner: "default/owner"
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
]
|
|
253
|
+
})
|
|
254
|
+
}
|
|
255
|
+
];
|
|
206
256
|
function createCatalogWriteAction() {
|
|
207
257
|
return createTemplateAction({
|
|
208
|
-
id:
|
|
258
|
+
id: id$2,
|
|
209
259
|
description: "Writes the catalog-info.yaml for your template",
|
|
260
|
+
examples: examples$2,
|
|
210
261
|
schema: {
|
|
211
262
|
input: {
|
|
212
263
|
type: "object",
|
|
@@ -237,10 +288,114 @@ function createCatalogWriteAction() {
|
|
|
237
288
|
});
|
|
238
289
|
}
|
|
239
290
|
|
|
291
|
+
const id$1 = "catalog:fetch";
|
|
292
|
+
const examples$1 = [
|
|
293
|
+
{
|
|
294
|
+
description: "Fetch entity by reference",
|
|
295
|
+
example: yaml__default["default"].stringify({
|
|
296
|
+
steps: [
|
|
297
|
+
{
|
|
298
|
+
action: id$1,
|
|
299
|
+
id: "fetch",
|
|
300
|
+
name: "Fetch catalog entity",
|
|
301
|
+
input: {
|
|
302
|
+
entityRef: "component:default/name"
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
]
|
|
306
|
+
})
|
|
307
|
+
}
|
|
308
|
+
];
|
|
309
|
+
function createFetchCatalogEntityAction(options) {
|
|
310
|
+
const { catalogClient } = options;
|
|
311
|
+
return createTemplateAction({
|
|
312
|
+
id: id$1,
|
|
313
|
+
description: "Returns entity from the catalog by entity reference",
|
|
314
|
+
examples: examples$1,
|
|
315
|
+
schema: {
|
|
316
|
+
input: {
|
|
317
|
+
required: ["entityRef"],
|
|
318
|
+
type: "object",
|
|
319
|
+
properties: {
|
|
320
|
+
entityRef: {
|
|
321
|
+
type: "string",
|
|
322
|
+
title: "Entity reference",
|
|
323
|
+
description: "Entity reference of the entity to get"
|
|
324
|
+
},
|
|
325
|
+
optional: {
|
|
326
|
+
title: "Optional",
|
|
327
|
+
description: "Permit the entity to optionally exist. Default: false",
|
|
328
|
+
type: "boolean"
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
},
|
|
332
|
+
output: {
|
|
333
|
+
type: "object",
|
|
334
|
+
properties: {
|
|
335
|
+
entity: {
|
|
336
|
+
title: "Entity found by the entity reference",
|
|
337
|
+
type: "object",
|
|
338
|
+
description: "Object containing same values used in the Entity schema."
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
},
|
|
343
|
+
async handler(ctx) {
|
|
344
|
+
var _a;
|
|
345
|
+
const { entityRef, optional } = ctx.input;
|
|
346
|
+
let entity;
|
|
347
|
+
try {
|
|
348
|
+
entity = await catalogClient.getEntityByRef(entityRef, {
|
|
349
|
+
token: (_a = ctx.secrets) == null ? void 0 : _a.backstageToken
|
|
350
|
+
});
|
|
351
|
+
} catch (e) {
|
|
352
|
+
if (!optional) {
|
|
353
|
+
throw e;
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
ctx.output("entity", entity != null ? entity : null);
|
|
357
|
+
}
|
|
358
|
+
});
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
const id = "debug:log";
|
|
362
|
+
const examples = [
|
|
363
|
+
{
|
|
364
|
+
description: "Write a debug message",
|
|
365
|
+
example: yaml__default["default"].stringify({
|
|
366
|
+
steps: [
|
|
367
|
+
{
|
|
368
|
+
action: id,
|
|
369
|
+
id: "write-debug-line",
|
|
370
|
+
name: 'Write "Hello Backstage!" log line',
|
|
371
|
+
input: {
|
|
372
|
+
message: "Hello Backstage!"
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
]
|
|
376
|
+
})
|
|
377
|
+
},
|
|
378
|
+
{
|
|
379
|
+
description: "List the workspace directory",
|
|
380
|
+
example: yaml__default["default"].stringify({
|
|
381
|
+
steps: [
|
|
382
|
+
{
|
|
383
|
+
action: id,
|
|
384
|
+
id: "write-workspace-directory",
|
|
385
|
+
name: "List the workspace directory",
|
|
386
|
+
input: {
|
|
387
|
+
listWorkspace: true
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
]
|
|
391
|
+
})
|
|
392
|
+
}
|
|
393
|
+
];
|
|
240
394
|
function createDebugLogAction() {
|
|
241
395
|
return createTemplateAction({
|
|
242
|
-
id
|
|
396
|
+
id,
|
|
243
397
|
description: "Writes a message into the log or lists all files in the workspace.",
|
|
398
|
+
examples,
|
|
244
399
|
schema: {
|
|
245
400
|
input: {
|
|
246
401
|
type: "object",
|
|
@@ -327,7 +482,7 @@ function createFetchPlainAction(options) {
|
|
|
327
482
|
const { reader, integrations } = options;
|
|
328
483
|
return createTemplateAction({
|
|
329
484
|
id: "fetch:plain",
|
|
330
|
-
description: "Downloads content and places it in the workspace, or optionally in a subdirectory specified by the
|
|
485
|
+
description: "Downloads content and places it in the workspace, or optionally in a subdirectory specified by the `targetPath` input option.",
|
|
331
486
|
schema: {
|
|
332
487
|
input: {
|
|
333
488
|
type: "object",
|
|
@@ -512,7 +667,7 @@ function createFetchTemplateAction(options) {
|
|
|
512
667
|
} = options;
|
|
513
668
|
return createTemplateAction({
|
|
514
669
|
id: "fetch:template",
|
|
515
|
-
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
|
|
670
|
+
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.",
|
|
516
671
|
schema: {
|
|
517
672
|
input: {
|
|
518
673
|
type: "object",
|
|
@@ -996,17 +1151,27 @@ const enableBranchProtectionOnDefaultRepoBranch = async ({
|
|
|
996
1151
|
logger,
|
|
997
1152
|
requireCodeOwnerReviews,
|
|
998
1153
|
bypassPullRequestAllowances,
|
|
1154
|
+
requiredApprovingReviewCount,
|
|
1155
|
+
restrictions,
|
|
999
1156
|
requiredStatusCheckContexts = [],
|
|
1000
1157
|
requireBranchesToBeUpToDate = true,
|
|
1001
1158
|
requiredConversationResolution = false,
|
|
1002
1159
|
defaultBranch = "master",
|
|
1003
1160
|
enforceAdmins = true,
|
|
1004
|
-
dismissStaleReviews = false
|
|
1161
|
+
dismissStaleReviews = false,
|
|
1162
|
+
requiredCommitSigning = false
|
|
1005
1163
|
}) => {
|
|
1006
1164
|
const tryOnce = async () => {
|
|
1007
1165
|
try {
|
|
1008
1166
|
await client.rest.repos.updateBranchProtection({
|
|
1009
1167
|
mediaType: {
|
|
1168
|
+
/**
|
|
1169
|
+
* 👇 we need this preview because allowing a custom
|
|
1170
|
+
* reviewer count on branch protection is a preview
|
|
1171
|
+
* feature
|
|
1172
|
+
*
|
|
1173
|
+
* More here: https://docs.github.com/en/rest/overview/api-previews#require-multiple-approving-reviews
|
|
1174
|
+
*/
|
|
1010
1175
|
previews: ["luke-cage-preview"]
|
|
1011
1176
|
},
|
|
1012
1177
|
owner,
|
|
@@ -1016,16 +1181,23 @@ const enableBranchProtectionOnDefaultRepoBranch = async ({
|
|
|
1016
1181
|
strict: requireBranchesToBeUpToDate,
|
|
1017
1182
|
contexts: requiredStatusCheckContexts
|
|
1018
1183
|
},
|
|
1019
|
-
restrictions: null,
|
|
1184
|
+
restrictions: restrictions != null ? restrictions : null,
|
|
1020
1185
|
enforce_admins: enforceAdmins,
|
|
1021
1186
|
required_pull_request_reviews: {
|
|
1022
|
-
required_approving_review_count:
|
|
1187
|
+
required_approving_review_count: requiredApprovingReviewCount,
|
|
1023
1188
|
require_code_owner_reviews: requireCodeOwnerReviews,
|
|
1024
1189
|
bypass_pull_request_allowances: bypassPullRequestAllowances,
|
|
1025
1190
|
dismiss_stale_reviews: dismissStaleReviews
|
|
1026
1191
|
},
|
|
1027
1192
|
required_conversation_resolution: requiredConversationResolution
|
|
1028
1193
|
});
|
|
1194
|
+
if (requiredCommitSigning) {
|
|
1195
|
+
await client.rest.repos.createCommitSignatureProtection({
|
|
1196
|
+
owner,
|
|
1197
|
+
repo: repoName,
|
|
1198
|
+
branch: defaultBranch
|
|
1199
|
+
});
|
|
1200
|
+
}
|
|
1029
1201
|
} catch (e) {
|
|
1030
1202
|
errors.assertError(e);
|
|
1031
1203
|
if (e.message.includes(
|
|
@@ -1056,6 +1228,7 @@ async function getOctokitOptions(options) {
|
|
|
1056
1228
|
const { integrations, credentialsProvider, repoUrl, token } = options;
|
|
1057
1229
|
const { owner, repo, host } = parseRepoUrl(repoUrl, integrations);
|
|
1058
1230
|
const requestOptions = {
|
|
1231
|
+
// set timeout to 60 seconds
|
|
1059
1232
|
timeout: DEFAULT_TIMEOUT_MS
|
|
1060
1233
|
};
|
|
1061
1234
|
if (!owner) {
|
|
@@ -1200,7 +1373,7 @@ async function createGithubRepoWithCollaboratorsAndTopics(client, repo, owner, r
|
|
|
1200
1373
|
}
|
|
1201
1374
|
return newRepo;
|
|
1202
1375
|
}
|
|
1203
|
-
async function initRepoPushAndProtect(remoteUrl, password, workspacePath, sourcePath, defaultBranch, protectDefaultBranch, protectEnforceAdmins, owner, client, repo, requireCodeOwnerReviews, bypassPullRequestAllowances, requiredStatusCheckContexts, requireBranchesToBeUpToDate, requiredConversationResolution, config, logger, gitCommitMessage, gitAuthorName, gitAuthorEmail, dismissStaleReviews) {
|
|
1376
|
+
async function initRepoPushAndProtect(remoteUrl, password, workspacePath, sourcePath, defaultBranch, protectDefaultBranch, protectEnforceAdmins, owner, client, repo, requireCodeOwnerReviews, bypassPullRequestAllowances, requiredApprovingReviewCount, restrictions, requiredStatusCheckContexts, requireBranchesToBeUpToDate, requiredConversationResolution, config, logger, gitCommitMessage, gitAuthorName, gitAuthorEmail, dismissStaleReviews, requiredCommitSigning) {
|
|
1204
1377
|
const gitAuthorInfo = {
|
|
1205
1378
|
name: gitAuthorName ? gitAuthorName : config.getOptionalString("scaffolder.defaultAuthor.name"),
|
|
1206
1379
|
email: gitAuthorEmail ? gitAuthorEmail : config.getOptionalString("scaffolder.defaultAuthor.email")
|
|
@@ -1227,12 +1400,15 @@ async function initRepoPushAndProtect(remoteUrl, password, workspacePath, source
|
|
|
1227
1400
|
logger,
|
|
1228
1401
|
defaultBranch,
|
|
1229
1402
|
bypassPullRequestAllowances,
|
|
1403
|
+
requiredApprovingReviewCount,
|
|
1404
|
+
restrictions,
|
|
1230
1405
|
requireCodeOwnerReviews,
|
|
1231
1406
|
requiredStatusCheckContexts,
|
|
1232
1407
|
requireBranchesToBeUpToDate,
|
|
1233
1408
|
requiredConversationResolution,
|
|
1234
1409
|
enforceAdmins: protectEnforceAdmins,
|
|
1235
|
-
dismissStaleReviews
|
|
1410
|
+
dismissStaleReviews,
|
|
1411
|
+
requiredCommitSigning
|
|
1236
1412
|
});
|
|
1237
1413
|
} catch (e) {
|
|
1238
1414
|
errors.assertError(e);
|
|
@@ -1590,6 +1766,42 @@ const sourcePath = {
|
|
|
1590
1766
|
description: "Path within the workspace that will be used as the repository root. If omitted, the entire workspace will be published as the repository.",
|
|
1591
1767
|
type: "string"
|
|
1592
1768
|
};
|
|
1769
|
+
const requiredApprovingReviewCount = {
|
|
1770
|
+
title: "Required approving review count",
|
|
1771
|
+
type: "number",
|
|
1772
|
+
description: `Specify the number of reviewers required to approve pull requests. Use a number between 1 and 6 or 0 to not require reviewers. Defaults to 1.`
|
|
1773
|
+
};
|
|
1774
|
+
const restrictions = {
|
|
1775
|
+
title: "Restrict who can push to the protected branch",
|
|
1776
|
+
description: "Restrict who can push to the protected branch. User, app, and team restrictions are only available for organization-owned repositories.",
|
|
1777
|
+
type: "object",
|
|
1778
|
+
additionalProperties: false,
|
|
1779
|
+
properties: {
|
|
1780
|
+
apps: {
|
|
1781
|
+
type: "array",
|
|
1782
|
+
items: {
|
|
1783
|
+
type: "string"
|
|
1784
|
+
}
|
|
1785
|
+
},
|
|
1786
|
+
users: {
|
|
1787
|
+
type: "array",
|
|
1788
|
+
items: {
|
|
1789
|
+
type: "string"
|
|
1790
|
+
}
|
|
1791
|
+
},
|
|
1792
|
+
teams: {
|
|
1793
|
+
type: "array",
|
|
1794
|
+
items: {
|
|
1795
|
+
type: "string"
|
|
1796
|
+
}
|
|
1797
|
+
}
|
|
1798
|
+
}
|
|
1799
|
+
};
|
|
1800
|
+
const requiredCommitSigning = {
|
|
1801
|
+
title: "Require commit signing",
|
|
1802
|
+
type: "boolean",
|
|
1803
|
+
description: `Require commit signing so that you must sign commits on this branch.`
|
|
1804
|
+
};
|
|
1593
1805
|
|
|
1594
1806
|
const remoteUrl = {
|
|
1595
1807
|
title: "A URL to the repository with the provider",
|
|
@@ -1616,6 +1828,8 @@ function createGithubRepoCreateAction(options) {
|
|
|
1616
1828
|
access: access,
|
|
1617
1829
|
requireCodeOwnerReviews: requireCodeOwnerReviews,
|
|
1618
1830
|
bypassPullRequestAllowances: bypassPullRequestAllowances,
|
|
1831
|
+
requiredApprovingReviewCount: requiredApprovingReviewCount,
|
|
1832
|
+
restrictions: restrictions,
|
|
1619
1833
|
requiredStatusCheckContexts: requiredStatusCheckContexts,
|
|
1620
1834
|
requireBranchesToBeUpToDate: requireBranchesToBeUpToDate,
|
|
1621
1835
|
requiredConversationResolution: requiredConversationResolution,
|
|
@@ -1632,7 +1846,8 @@ function createGithubRepoCreateAction(options) {
|
|
|
1632
1846
|
hasWiki: hasWiki,
|
|
1633
1847
|
hasIssues: hasIssues,
|
|
1634
1848
|
token: token,
|
|
1635
|
-
topics: topics
|
|
1849
|
+
topics: topics,
|
|
1850
|
+
requiredCommitSigning: requiredCommitSigning
|
|
1636
1851
|
}
|
|
1637
1852
|
},
|
|
1638
1853
|
output: {
|
|
@@ -1717,6 +1932,8 @@ function createGithubRepoPushAction(options) {
|
|
|
1717
1932
|
dismissStaleReviews: dismissStaleReviews,
|
|
1718
1933
|
requiredStatusCheckContexts: requiredStatusCheckContexts,
|
|
1719
1934
|
bypassPullRequestAllowances: bypassPullRequestAllowances,
|
|
1935
|
+
requiredApprovingReviewCount: requiredApprovingReviewCount,
|
|
1936
|
+
restrictions: restrictions,
|
|
1720
1937
|
requireBranchesToBeUpToDate: requireBranchesToBeUpToDate,
|
|
1721
1938
|
requiredConversationResolution: requiredConversationResolution,
|
|
1722
1939
|
defaultBranch: defaultBranch,
|
|
@@ -1726,7 +1943,8 @@ function createGithubRepoPushAction(options) {
|
|
|
1726
1943
|
gitAuthorName: gitAuthorName,
|
|
1727
1944
|
gitAuthorEmail: gitAuthorEmail,
|
|
1728
1945
|
sourcePath: sourcePath,
|
|
1729
|
-
token: token
|
|
1946
|
+
token: token,
|
|
1947
|
+
requiredCommitSigning: requiredCommitSigning
|
|
1730
1948
|
}
|
|
1731
1949
|
},
|
|
1732
1950
|
output: {
|
|
@@ -1749,10 +1967,13 @@ function createGithubRepoPushAction(options) {
|
|
|
1749
1967
|
requireCodeOwnerReviews = false,
|
|
1750
1968
|
dismissStaleReviews = false,
|
|
1751
1969
|
bypassPullRequestAllowances,
|
|
1970
|
+
requiredApprovingReviewCount = 1,
|
|
1971
|
+
restrictions,
|
|
1752
1972
|
requiredStatusCheckContexts = [],
|
|
1753
1973
|
requireBranchesToBeUpToDate = true,
|
|
1754
1974
|
requiredConversationResolution = false,
|
|
1755
|
-
token: providedToken
|
|
1975
|
+
token: providedToken,
|
|
1976
|
+
requiredCommitSigning = false
|
|
1756
1977
|
} = ctx.input;
|
|
1757
1978
|
const { owner, repo } = parseRepoUrl(repoUrl, integrations);
|
|
1758
1979
|
if (!owner) {
|
|
@@ -1781,6 +2002,8 @@ function createGithubRepoPushAction(options) {
|
|
|
1781
2002
|
repo,
|
|
1782
2003
|
requireCodeOwnerReviews,
|
|
1783
2004
|
bypassPullRequestAllowances,
|
|
2005
|
+
requiredApprovingReviewCount,
|
|
2006
|
+
restrictions,
|
|
1784
2007
|
requiredStatusCheckContexts,
|
|
1785
2008
|
requireBranchesToBeUpToDate,
|
|
1786
2009
|
requiredConversationResolution,
|
|
@@ -1789,7 +2012,8 @@ function createGithubRepoPushAction(options) {
|
|
|
1789
2012
|
gitCommitMessage,
|
|
1790
2013
|
gitAuthorName,
|
|
1791
2014
|
gitAuthorEmail,
|
|
1792
|
-
dismissStaleReviews
|
|
2015
|
+
dismissStaleReviews,
|
|
2016
|
+
requiredCommitSigning
|
|
1793
2017
|
);
|
|
1794
2018
|
ctx.output("remoteUrl", remoteUrl);
|
|
1795
2019
|
ctx.output("repoContentsUrl", repoContentsUrl);
|
|
@@ -2641,6 +2865,21 @@ function createPublishBitbucketServerAction(options) {
|
|
|
2641
2865
|
title: "Authentication Token",
|
|
2642
2866
|
type: "string",
|
|
2643
2867
|
description: "The token to use for authorization to BitBucket Server"
|
|
2868
|
+
},
|
|
2869
|
+
gitCommitMessage: {
|
|
2870
|
+
title: "Git Commit Message",
|
|
2871
|
+
type: "string",
|
|
2872
|
+
description: `Sets the commit message on the repository. The default value is 'initial commit'`
|
|
2873
|
+
},
|
|
2874
|
+
gitAuthorName: {
|
|
2875
|
+
title: "Author Name",
|
|
2876
|
+
type: "string",
|
|
2877
|
+
description: `Sets the author name for the commit. The default value is 'Scaffolder'`
|
|
2878
|
+
},
|
|
2879
|
+
gitAuthorEmail: {
|
|
2880
|
+
title: "Author Email",
|
|
2881
|
+
type: "string",
|
|
2882
|
+
description: `Sets the author email for the commit.`
|
|
2644
2883
|
}
|
|
2645
2884
|
}
|
|
2646
2885
|
},
|
|
@@ -2665,7 +2904,10 @@ function createPublishBitbucketServerAction(options) {
|
|
|
2665
2904
|
description,
|
|
2666
2905
|
defaultBranch = "master",
|
|
2667
2906
|
repoVisibility = "private",
|
|
2668
|
-
enableLFS = false
|
|
2907
|
+
enableLFS = false,
|
|
2908
|
+
gitCommitMessage = "initial commit",
|
|
2909
|
+
gitAuthorName,
|
|
2910
|
+
gitAuthorEmail
|
|
2669
2911
|
} = ctx.input;
|
|
2670
2912
|
const { project, repo, host } = parseRepoUrl(repoUrl, integrations);
|
|
2671
2913
|
if (!project) {
|
|
@@ -2702,8 +2944,8 @@ function createPublishBitbucketServerAction(options) {
|
|
|
2702
2944
|
apiBaseUrl
|
|
2703
2945
|
});
|
|
2704
2946
|
const gitAuthorInfo = {
|
|
2705
|
-
name: config.getOptionalString("scaffolder.defaultAuthor.name"),
|
|
2706
|
-
email: config.getOptionalString("scaffolder.defaultAuthor.email")
|
|
2947
|
+
name: gitAuthorName ? gitAuthorName : config.getOptionalString("scaffolder.defaultAuthor.name"),
|
|
2948
|
+
email: gitAuthorEmail ? gitAuthorEmail : config.getOptionalString("scaffolder.defaultAuthor.email")
|
|
2707
2949
|
};
|
|
2708
2950
|
const auth = authConfig.token ? {
|
|
2709
2951
|
token
|
|
@@ -2717,9 +2959,7 @@ function createPublishBitbucketServerAction(options) {
|
|
|
2717
2959
|
auth,
|
|
2718
2960
|
defaultBranch,
|
|
2719
2961
|
logger: ctx.logger,
|
|
2720
|
-
commitMessage: config.getOptionalString(
|
|
2721
|
-
"scaffolder.defaultCommitMessage"
|
|
2722
|
-
),
|
|
2962
|
+
commitMessage: gitCommitMessage ? gitCommitMessage : config.getOptionalString("scaffolder.defaultCommitMessage"),
|
|
2723
2963
|
gitAuthorInfo
|
|
2724
2964
|
});
|
|
2725
2965
|
if (enableLFS) {
|
|
@@ -3002,6 +3242,8 @@ function createPublishGithubAction(options) {
|
|
|
3002
3242
|
homepage: homepage,
|
|
3003
3243
|
access: access,
|
|
3004
3244
|
bypassPullRequestAllowances: bypassPullRequestAllowances,
|
|
3245
|
+
requiredApprovingReviewCount: requiredApprovingReviewCount,
|
|
3246
|
+
restrictions: restrictions,
|
|
3005
3247
|
requireCodeOwnerReviews: requireCodeOwnerReviews,
|
|
3006
3248
|
dismissStaleReviews: dismissStaleReviews,
|
|
3007
3249
|
requiredStatusCheckContexts: requiredStatusCheckContexts,
|
|
@@ -3027,7 +3269,8 @@ function createPublishGithubAction(options) {
|
|
|
3027
3269
|
hasWiki: hasWiki,
|
|
3028
3270
|
hasIssues: hasIssues,
|
|
3029
3271
|
token: token,
|
|
3030
|
-
topics: topics
|
|
3272
|
+
topics: topics,
|
|
3273
|
+
requiredCommitSigning: requiredCommitSigning
|
|
3031
3274
|
}
|
|
3032
3275
|
},
|
|
3033
3276
|
output: {
|
|
@@ -3047,6 +3290,8 @@ function createPublishGithubAction(options) {
|
|
|
3047
3290
|
requireCodeOwnerReviews = false,
|
|
3048
3291
|
dismissStaleReviews = false,
|
|
3049
3292
|
bypassPullRequestAllowances,
|
|
3293
|
+
requiredApprovingReviewCount = 1,
|
|
3294
|
+
restrictions,
|
|
3050
3295
|
requiredStatusCheckContexts = [],
|
|
3051
3296
|
requireBranchesToBeUpToDate = true,
|
|
3052
3297
|
requiredConversationResolution = false,
|
|
@@ -3069,7 +3314,8 @@ function createPublishGithubAction(options) {
|
|
|
3069
3314
|
hasWiki = void 0,
|
|
3070
3315
|
hasIssues = void 0,
|
|
3071
3316
|
topics,
|
|
3072
|
-
token: providedToken
|
|
3317
|
+
token: providedToken,
|
|
3318
|
+
requiredCommitSigning = false
|
|
3073
3319
|
} = ctx.input;
|
|
3074
3320
|
const octokitOptions = await getOctokitOptions({
|
|
3075
3321
|
integrations,
|
|
@@ -3119,6 +3365,8 @@ function createPublishGithubAction(options) {
|
|
|
3119
3365
|
repo,
|
|
3120
3366
|
requireCodeOwnerReviews,
|
|
3121
3367
|
bypassPullRequestAllowances,
|
|
3368
|
+
requiredApprovingReviewCount,
|
|
3369
|
+
restrictions,
|
|
3122
3370
|
requiredStatusCheckContexts,
|
|
3123
3371
|
requireBranchesToBeUpToDate,
|
|
3124
3372
|
requiredConversationResolution,
|
|
@@ -3127,7 +3375,8 @@ function createPublishGithubAction(options) {
|
|
|
3127
3375
|
gitCommitMessage,
|
|
3128
3376
|
gitAuthorName,
|
|
3129
3377
|
gitAuthorEmail,
|
|
3130
|
-
dismissStaleReviews
|
|
3378
|
+
dismissStaleReviews,
|
|
3379
|
+
requiredCommitSigning
|
|
3131
3380
|
);
|
|
3132
3381
|
ctx.output("remoteUrl", remoteUrl);
|
|
3133
3382
|
ctx.output("repoContentsUrl", repoContentsUrl);
|
|
@@ -3155,6 +3404,8 @@ async function serializeDirectoryContents(sourcePath, options) {
|
|
|
3155
3404
|
dot: true,
|
|
3156
3405
|
gitignore: options == null ? void 0 : options.gitignore,
|
|
3157
3406
|
followSymbolicLinks: false,
|
|
3407
|
+
// In order to pick up 'broken' symlinks, we oxymoronically request files AND folders yet we filter out folders
|
|
3408
|
+
// This is because broken symlinks aren't classed as files so we need to glob everything
|
|
3158
3409
|
onlyFiles: false,
|
|
3159
3410
|
objectMode: true,
|
|
3160
3411
|
stats: true
|
|
@@ -3352,7 +3603,16 @@ const createPublishGithubPullRequestAction = ({
|
|
|
3352
3603
|
directoryContents.map((file) => [
|
|
3353
3604
|
targetPath ? path__default["default"].posix.join(targetPath, file.path) : file.path,
|
|
3354
3605
|
{
|
|
3606
|
+
// See the properties of tree items
|
|
3607
|
+
// in https://docs.github.com/en/rest/reference/git#trees
|
|
3355
3608
|
mode: determineFileMode(file),
|
|
3609
|
+
// Always use base64 encoding where possible to avoid doubling a binary file in size
|
|
3610
|
+
// due to interpreting a binary file as utf-8 and sending github
|
|
3611
|
+
// the utf-8 encoded content. Symlinks are kept as utf-8 to avoid them
|
|
3612
|
+
// being formatted as a series of scrambled characters
|
|
3613
|
+
//
|
|
3614
|
+
// For example, the original gradle-wrapper.jar is 57.8k in https://github.com/kennethzfeng/pull-request-test/pull/5/files.
|
|
3615
|
+
// Its size could be doubled to 98.3K (See https://github.com/kennethzfeng/pull-request-test/pull/4/files)
|
|
3356
3616
|
encoding: determineFileEncoding(file),
|
|
3357
3617
|
content: file.content.toString(determineFileEncoding(file))
|
|
3358
3618
|
}
|
|
@@ -3589,6 +3849,7 @@ const createPublishGitlabMergeRequestAction = (options) => {
|
|
|
3589
3849
|
title: "Repository Location",
|
|
3590
3850
|
description: `Accepts the format 'gitlab.com/group_name/project_name' where 'project_name' is the repository name and 'group_name' is a group or username`
|
|
3591
3851
|
},
|
|
3852
|
+
/** @deprecated projectID is passed as query parameters in the repoUrl */
|
|
3592
3853
|
projectid: {
|
|
3593
3854
|
type: "string",
|
|
3594
3855
|
title: "projectid",
|
|
@@ -3826,6 +4087,7 @@ const createBuiltinActions = (options) => {
|
|
|
3826
4087
|
}),
|
|
3827
4088
|
createDebugLogAction(),
|
|
3828
4089
|
createCatalogRegisterAction({ catalogClient, integrations }),
|
|
4090
|
+
createFetchCatalogEntityAction({ catalogClient }),
|
|
3829
4091
|
createCatalogWriteAction(),
|
|
3830
4092
|
createFilesystemDeleteAction(),
|
|
3831
4093
|
createFilesystemRenameAction(),
|
|
@@ -3990,6 +4252,7 @@ class DatabaseTaskStore {
|
|
|
3990
4252
|
const updateCount = await tx("tasks").where({ id: task.id, status: "open" }).update({
|
|
3991
4253
|
status: "processing",
|
|
3992
4254
|
last_heartbeat_at: this.db.fn.now(),
|
|
4255
|
+
// remove the secrets when moving moving to processing state.
|
|
3993
4256
|
secrets: null
|
|
3994
4257
|
});
|
|
3995
4258
|
if (updateCount < 1) {
|
|
@@ -4140,6 +4403,7 @@ class DatabaseTaskStore {
|
|
|
4140
4403
|
}
|
|
4141
4404
|
|
|
4142
4405
|
class TaskManager {
|
|
4406
|
+
// Runs heartbeat internally
|
|
4143
4407
|
constructor(task, storage, logger) {
|
|
4144
4408
|
this.task = task;
|
|
4145
4409
|
this.storage = storage;
|
|
@@ -4223,6 +4487,9 @@ class StorageTaskBroker {
|
|
|
4223
4487
|
}
|
|
4224
4488
|
return await this.storage.list({ createdBy: options == null ? void 0 : options.createdBy });
|
|
4225
4489
|
}
|
|
4490
|
+
/**
|
|
4491
|
+
* {@inheritdoc TaskBroker.claim}
|
|
4492
|
+
*/
|
|
4226
4493
|
async claim() {
|
|
4227
4494
|
for (; ; ) {
|
|
4228
4495
|
const pendingTask = await this.storage.claimTask();
|
|
@@ -4241,6 +4508,9 @@ class StorageTaskBroker {
|
|
|
4241
4508
|
await this.waitForDispatch();
|
|
4242
4509
|
}
|
|
4243
4510
|
}
|
|
4511
|
+
/**
|
|
4512
|
+
* {@inheritdoc TaskBroker.dispatch}
|
|
4513
|
+
*/
|
|
4244
4514
|
async dispatch(options) {
|
|
4245
4515
|
const taskRow = await this.storage.createTask(options);
|
|
4246
4516
|
this.signalDispatch();
|
|
@@ -4248,9 +4518,15 @@ class StorageTaskBroker {
|
|
|
4248
4518
|
taskId: taskRow.taskId
|
|
4249
4519
|
};
|
|
4250
4520
|
}
|
|
4521
|
+
/**
|
|
4522
|
+
* {@inheritdoc TaskBroker.get}
|
|
4523
|
+
*/
|
|
4251
4524
|
async get(taskId) {
|
|
4252
4525
|
return this.storage.getTask(taskId);
|
|
4253
4526
|
}
|
|
4527
|
+
/**
|
|
4528
|
+
* {@inheritdoc TaskBroker.event$}
|
|
4529
|
+
*/
|
|
4254
4530
|
event$(options) {
|
|
4255
4531
|
return new ObservableImpl__default["default"]((observer) => {
|
|
4256
4532
|
const { taskId } = options;
|
|
@@ -4272,6 +4548,9 @@ class StorageTaskBroker {
|
|
|
4272
4548
|
};
|
|
4273
4549
|
});
|
|
4274
4550
|
}
|
|
4551
|
+
/**
|
|
4552
|
+
* {@inheritdoc TaskBroker.vacuumTasks}
|
|
4553
|
+
*/
|
|
4275
4554
|
async vacuumTasks(options) {
|
|
4276
4555
|
const { tasks } = await this.storage.listStaleTasks(options);
|
|
4277
4556
|
await Promise.all(
|
|
@@ -4441,6 +4720,10 @@ class NunjucksWorkflowRunner {
|
|
|
4441
4720
|
);
|
|
4442
4721
|
const { integrations } = this.options;
|
|
4443
4722
|
const renderTemplate = await SecureTemplater.loadRenderer({
|
|
4723
|
+
// TODO(blam): let's work out how we can deprecate this.
|
|
4724
|
+
// We shouldn't really need to be exposing these now we can deal with
|
|
4725
|
+
// objects in the params block.
|
|
4726
|
+
// Maybe we can expose a new RepoUrlPicker with secrets for V3 that provides an object already.
|
|
4444
4727
|
parseRepoUrl(url) {
|
|
4445
4728
|
return parseRepoUrl(url, integrations);
|
|
4446
4729
|
},
|
|
@@ -4693,6 +4976,7 @@ class TaskWorker {
|
|
|
4693
4976
|
workingDirectory,
|
|
4694
4977
|
additionalTemplateFilters,
|
|
4695
4978
|
concurrentTasksLimit = 10,
|
|
4979
|
+
// from 1 to Infinity
|
|
4696
4980
|
additionalTemplateGlobals
|
|
4697
4981
|
} = options;
|
|
4698
4982
|
const workflowRunner = new NunjucksWorkflowRunner({
|
|
@@ -4809,6 +5093,7 @@ function createDryRunner(options) {
|
|
|
4809
5093
|
}
|
|
4810
5094
|
},
|
|
4811
5095
|
secrets: input.secrets,
|
|
5096
|
+
// No need to update this at the end of the run, so just hard-code it
|
|
4812
5097
|
done: false,
|
|
4813
5098
|
isDryRun: true,
|
|
4814
5099
|
getWorkspaceName: async () => `dry-run-${dryRunId}`,
|
|
@@ -4963,6 +5248,7 @@ async function createRouter(options) {
|
|
|
4963
5248
|
await scheduler.scheduleTask({
|
|
4964
5249
|
id: "close_stale_tasks",
|
|
4965
5250
|
frequency: { cron: "*/5 * * * *" },
|
|
5251
|
+
// every 5 minutes, also supports Duration
|
|
4966
5252
|
timeout: { minutes: 15 },
|
|
4967
5253
|
fn: async () => {
|
|
4968
5254
|
const { tasks } = await databaseTaskStore.listStaleTasks({
|
|
@@ -5051,6 +5337,7 @@ async function createRouter(options) {
|
|
|
5051
5337
|
return {
|
|
5052
5338
|
id: action.id,
|
|
5053
5339
|
description: action.description,
|
|
5340
|
+
examples: action.examples,
|
|
5054
5341
|
schema: action.schema
|
|
5055
5342
|
};
|
|
5056
5343
|
});
|
|
@@ -5377,71 +5664,73 @@ _actions = new WeakMap();
|
|
|
5377
5664
|
const scaffolderActionsExtensionPoint = backendPluginApi.createExtensionPoint({
|
|
5378
5665
|
id: "scaffolder.actions"
|
|
5379
5666
|
});
|
|
5380
|
-
const scaffolderPlugin = backendPluginApi.createBackendPlugin(
|
|
5381
|
-
|
|
5382
|
-
|
|
5383
|
-
|
|
5384
|
-
|
|
5385
|
-
|
|
5386
|
-
|
|
5387
|
-
|
|
5388
|
-
|
|
5389
|
-
|
|
5390
|
-
|
|
5391
|
-
|
|
5392
|
-
|
|
5393
|
-
|
|
5394
|
-
|
|
5395
|
-
|
|
5396
|
-
|
|
5397
|
-
|
|
5398
|
-
|
|
5399
|
-
|
|
5400
|
-
|
|
5401
|
-
|
|
5402
|
-
|
|
5403
|
-
|
|
5404
|
-
|
|
5405
|
-
|
|
5406
|
-
|
|
5407
|
-
|
|
5408
|
-
|
|
5409
|
-
|
|
5410
|
-
|
|
5411
|
-
|
|
5412
|
-
|
|
5413
|
-
|
|
5414
|
-
|
|
5415
|
-
|
|
5416
|
-
|
|
5667
|
+
const scaffolderPlugin = backendPluginApi.createBackendPlugin(
|
|
5668
|
+
(options) => ({
|
|
5669
|
+
id: "scaffolder",
|
|
5670
|
+
register(env) {
|
|
5671
|
+
const actionsExtensions = new ScaffolderActionsExtensionPointImpl();
|
|
5672
|
+
env.registerExtensionPoint(
|
|
5673
|
+
scaffolderActionsExtensionPoint,
|
|
5674
|
+
actionsExtensions
|
|
5675
|
+
);
|
|
5676
|
+
env.registerInit({
|
|
5677
|
+
deps: {
|
|
5678
|
+
logger: backendPluginApi.coreServices.logger,
|
|
5679
|
+
config: backendPluginApi.coreServices.config,
|
|
5680
|
+
reader: backendPluginApi.coreServices.urlReader,
|
|
5681
|
+
permissions: backendPluginApi.coreServices.permissions,
|
|
5682
|
+
database: backendPluginApi.coreServices.database,
|
|
5683
|
+
httpRouter: backendPluginApi.coreServices.httpRouter,
|
|
5684
|
+
catalogClient: pluginCatalogNode.catalogServiceRef
|
|
5685
|
+
},
|
|
5686
|
+
async init({
|
|
5687
|
+
logger,
|
|
5688
|
+
config,
|
|
5689
|
+
reader,
|
|
5690
|
+
database,
|
|
5691
|
+
httpRouter,
|
|
5692
|
+
catalogClient
|
|
5693
|
+
}) {
|
|
5694
|
+
const {
|
|
5695
|
+
additionalTemplateFilters,
|
|
5696
|
+
taskBroker,
|
|
5697
|
+
taskWorkers,
|
|
5698
|
+
additionalTemplateGlobals
|
|
5699
|
+
} = options;
|
|
5700
|
+
const log = backendCommon.loggerToWinstonLogger(logger);
|
|
5701
|
+
const actions = options.actions || [
|
|
5702
|
+
...actionsExtensions.actions,
|
|
5703
|
+
...createBuiltinActions({
|
|
5704
|
+
integrations: integration.ScmIntegrations.fromConfig(config),
|
|
5705
|
+
catalogClient,
|
|
5706
|
+
reader,
|
|
5707
|
+
config,
|
|
5708
|
+
additionalTemplateFilters,
|
|
5709
|
+
additionalTemplateGlobals
|
|
5710
|
+
})
|
|
5711
|
+
];
|
|
5712
|
+
const actionIds = actions.map((action) => action.id).join(", ");
|
|
5713
|
+
log.info(
|
|
5714
|
+
`Starting scaffolder with the following actions enabled ${actionIds}`
|
|
5715
|
+
);
|
|
5716
|
+
const router = await createRouter({
|
|
5717
|
+
logger: log,
|
|
5718
|
+
config,
|
|
5719
|
+
database,
|
|
5417
5720
|
catalogClient,
|
|
5418
5721
|
reader,
|
|
5419
|
-
|
|
5722
|
+
actions,
|
|
5723
|
+
taskBroker,
|
|
5724
|
+
taskWorkers,
|
|
5420
5725
|
additionalTemplateFilters,
|
|
5421
5726
|
additionalTemplateGlobals
|
|
5422
|
-
})
|
|
5423
|
-
|
|
5424
|
-
|
|
5425
|
-
|
|
5426
|
-
|
|
5427
|
-
|
|
5428
|
-
|
|
5429
|
-
logger: log,
|
|
5430
|
-
config,
|
|
5431
|
-
database,
|
|
5432
|
-
catalogClient,
|
|
5433
|
-
reader,
|
|
5434
|
-
actions,
|
|
5435
|
-
taskBroker,
|
|
5436
|
-
taskWorkers,
|
|
5437
|
-
additionalTemplateFilters,
|
|
5438
|
-
additionalTemplateGlobals
|
|
5439
|
-
});
|
|
5440
|
-
httpRouter.use(router);
|
|
5441
|
-
}
|
|
5442
|
-
});
|
|
5443
|
-
}
|
|
5444
|
-
});
|
|
5727
|
+
});
|
|
5728
|
+
httpRouter.use(router);
|
|
5729
|
+
}
|
|
5730
|
+
});
|
|
5731
|
+
}
|
|
5732
|
+
})
|
|
5733
|
+
);
|
|
5445
5734
|
|
|
5446
5735
|
exports.DatabaseTaskStore = DatabaseTaskStore;
|
|
5447
5736
|
exports.ScaffolderEntitiesProcessor = ScaffolderEntitiesProcessor;
|
|
@@ -5452,6 +5741,7 @@ exports.createBuiltinActions = createBuiltinActions;
|
|
|
5452
5741
|
exports.createCatalogRegisterAction = createCatalogRegisterAction;
|
|
5453
5742
|
exports.createCatalogWriteAction = createCatalogWriteAction;
|
|
5454
5743
|
exports.createDebugLogAction = createDebugLogAction;
|
|
5744
|
+
exports.createFetchCatalogEntityAction = createFetchCatalogEntityAction;
|
|
5455
5745
|
exports.createFetchPlainAction = createFetchPlainAction;
|
|
5456
5746
|
exports.createFetchTemplateAction = createFetchTemplateAction;
|
|
5457
5747
|
exports.createFilesystemDeleteAction = createFilesystemDeleteAction;
|