@backstage/plugin-scaffolder-backend 0.15.2 → 0.15.6
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 +48 -0
- package/dist/index.cjs.js +150 -51
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +29 -1
- package/package.json +14 -12
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,53 @@
|
|
|
1
1
|
# @backstage/plugin-scaffolder-backend
|
|
2
2
|
|
|
3
|
+
## 0.15.6
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies
|
|
8
|
+
- @backstage/integration@0.6.5
|
|
9
|
+
- @backstage/catalog-client@0.4.0
|
|
10
|
+
- @backstage/catalog-model@0.9.3
|
|
11
|
+
- @backstage/backend-common@0.9.4
|
|
12
|
+
- @backstage/config@0.1.10
|
|
13
|
+
|
|
14
|
+
## 0.15.5
|
|
15
|
+
|
|
16
|
+
### Patch Changes
|
|
17
|
+
|
|
18
|
+
- 618143c3c7: Action needed: If you are using the templates located at https://github.com/backstage/backstage/tree/master/ in your Backstage app directly using the URL via the `app-config.yaml`, you should copy over the templates inside your org and import from there. The templates have now been moved to https://github.com/backstage/software-templates. See https://github.com/backstage/backstage/issues/6415 for explanation.
|
|
19
|
+
- cfade02127: Change hardcoded branch `master` to \$defaultBranch in GitLab provider
|
|
20
|
+
- 96fef17a18: Upgrade git-parse-url to v11.6.0
|
|
21
|
+
- Updated dependencies
|
|
22
|
+
- @backstage/backend-common@0.9.3
|
|
23
|
+
- @backstage/integration@0.6.4
|
|
24
|
+
|
|
25
|
+
## 0.15.4
|
|
26
|
+
|
|
27
|
+
### Patch Changes
|
|
28
|
+
|
|
29
|
+
- 04aad2dab: Fix issue #7021 scaffolder action fetch:template preserves templates file permissions
|
|
30
|
+
- 21ccd4997: GitHub Webhook action in Scaffolder Backend has been improved to validate event names against Octokit Webhook event names list.
|
|
31
|
+
- Updated dependencies
|
|
32
|
+
- @backstage/catalog-client@0.3.19
|
|
33
|
+
- @backstage/catalog-model@0.9.2
|
|
34
|
+
- @backstage/errors@0.1.2
|
|
35
|
+
- @backstage/config@0.1.9
|
|
36
|
+
- @backstage/backend-common@0.9.2
|
|
37
|
+
|
|
38
|
+
## 0.15.3
|
|
39
|
+
|
|
40
|
+
### Patch Changes
|
|
41
|
+
|
|
42
|
+
- 3f9dd1759: GitHub create repository webhook action: `github:webhook` for Backstage plugin Scaffolder has been added.
|
|
43
|
+
- 774b08a5c: GitHubWebhook Action can be created with a default webhook secret. This allows getting secret from environment variable as an alternative to get it from context.
|
|
44
|
+
- 536f4d844: Updated dependencies
|
|
45
|
+
- 0b92a1e74: refactor: extract common Octokit related code and use it in actions: `publish:github`, `github:actions:dispatch`, `github:webhook`.
|
|
46
|
+
- Updated dependencies
|
|
47
|
+
- @backstage/integration@0.6.3
|
|
48
|
+
- @backstage/catalog-model@0.9.1
|
|
49
|
+
- @backstage/backend-common@0.9.1
|
|
50
|
+
|
|
3
51
|
## 0.15.2
|
|
4
52
|
|
|
5
53
|
### Patch Changes
|
package/dist/index.cjs.js
CHANGED
|
@@ -21,6 +21,7 @@ var rest = require('@octokit/rest');
|
|
|
21
21
|
var lodash = require('lodash');
|
|
22
22
|
var octokitPluginCreatePullRequest = require('octokit-plugin-create-pull-request');
|
|
23
23
|
var node = require('@gitbeaker/node');
|
|
24
|
+
var webhooks = require('@octokit/webhooks');
|
|
24
25
|
var express = require('express');
|
|
25
26
|
var Router = require('express-promise-router');
|
|
26
27
|
var jsonschema = require('jsonschema');
|
|
@@ -418,9 +419,10 @@ function createFetchTemplateAction(options) {
|
|
|
418
419
|
ctx.logger.info(`Copying binary file ${location} to template output path.`);
|
|
419
420
|
await fs__default['default'].copy(inputFilePath, outputPath);
|
|
420
421
|
} else {
|
|
421
|
-
|
|
422
|
+
const statsObj = await fs__default['default'].stat(inputFilePath);
|
|
423
|
+
ctx.logger.info(`Writing file ${location} to template output path with mode ${statsObj.mode}.`);
|
|
422
424
|
const inputFileContents = await fs__default['default'].readFile(inputFilePath, "utf-8");
|
|
423
|
-
await fs__default['default'].outputFile(outputPath, renderContents ? templater.renderString(inputFileContents, context) : inputFileContents);
|
|
425
|
+
await fs__default['default'].outputFile(outputPath, renderContents ? templater.renderString(inputFileContents, context) : inputFileContents, {mode: statsObj.mode});
|
|
424
426
|
}
|
|
425
427
|
}
|
|
426
428
|
}
|
|
@@ -1018,12 +1020,46 @@ function createPublishFileAction() {
|
|
|
1018
1020
|
});
|
|
1019
1021
|
}
|
|
1020
1022
|
|
|
1023
|
+
class OctokitProvider {
|
|
1024
|
+
constructor(integrations) {
|
|
1025
|
+
this.integrations = integrations;
|
|
1026
|
+
this.credentialsProviders = new Map(integrations.github.list().map((integration$1) => {
|
|
1027
|
+
const provider = integration.GithubCredentialsProvider.create(integration$1.config);
|
|
1028
|
+
return [integration$1.config.host, provider];
|
|
1029
|
+
}));
|
|
1030
|
+
}
|
|
1031
|
+
async getOctokit(repoUrl) {
|
|
1032
|
+
var _a;
|
|
1033
|
+
const {owner, repo, host} = parseRepoUrl(repoUrl, this.integrations);
|
|
1034
|
+
if (!owner) {
|
|
1035
|
+
throw new errors.InputError(`No owner provided for repo ${repoUrl}`);
|
|
1036
|
+
}
|
|
1037
|
+
const integrationConfig = (_a = this.integrations.github.byHost(host)) == null ? void 0 : _a.config;
|
|
1038
|
+
if (!integrationConfig) {
|
|
1039
|
+
throw new errors.InputError(`No integration for host ${host}`);
|
|
1040
|
+
}
|
|
1041
|
+
const credentialsProvider = this.credentialsProviders.get(host);
|
|
1042
|
+
if (!credentialsProvider) {
|
|
1043
|
+
throw new errors.InputError(`No matching credentials for host ${host}, please check your integrations config`);
|
|
1044
|
+
}
|
|
1045
|
+
const {token} = await credentialsProvider.getCredentials({
|
|
1046
|
+
url: `https://${host}/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}`
|
|
1047
|
+
});
|
|
1048
|
+
if (!token) {
|
|
1049
|
+
throw new errors.InputError(`No token available for host: ${host}, with owner ${owner}, and repo ${repo}`);
|
|
1050
|
+
}
|
|
1051
|
+
const client = new rest.Octokit({
|
|
1052
|
+
auth: token,
|
|
1053
|
+
baseUrl: integrationConfig.apiBaseUrl,
|
|
1054
|
+
previews: ["nebula-preview"]
|
|
1055
|
+
});
|
|
1056
|
+
return {client, token, owner, repo};
|
|
1057
|
+
}
|
|
1058
|
+
}
|
|
1059
|
+
|
|
1021
1060
|
function createPublishGithubAction(options) {
|
|
1022
1061
|
const {integrations, config} = options;
|
|
1023
|
-
const
|
|
1024
|
-
const provider = integration.GithubCredentialsProvider.create(integration$1.config);
|
|
1025
|
-
return [integration$1.config.host, provider];
|
|
1026
|
-
}));
|
|
1062
|
+
const octokitProvider = new OctokitProvider(integrations);
|
|
1027
1063
|
return createTemplateAction({
|
|
1028
1064
|
id: "publish:github",
|
|
1029
1065
|
description: "Initializes a git repository of contents in workspace and publishes it to GitHub.",
|
|
@@ -1118,26 +1154,7 @@ function createPublishGithubAction(options) {
|
|
|
1118
1154
|
collaborators,
|
|
1119
1155
|
topics
|
|
1120
1156
|
} = ctx.input;
|
|
1121
|
-
const {owner, repo
|
|
1122
|
-
if (!owner) {
|
|
1123
|
-
throw new errors.InputError(`No owner provided for host: ${host}, and repo ${repo}`);
|
|
1124
|
-
}
|
|
1125
|
-
const credentialsProvider = credentialsProviders.get(host);
|
|
1126
|
-
const integrationConfig = integrations.github.byHost(host);
|
|
1127
|
-
if (!credentialsProvider || !integrationConfig) {
|
|
1128
|
-
throw new errors.InputError(`No matching integration configuration for host ${host}, please check your integrations config`);
|
|
1129
|
-
}
|
|
1130
|
-
const {token} = await credentialsProvider.getCredentials({
|
|
1131
|
-
url: `https://${host}/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}`
|
|
1132
|
-
});
|
|
1133
|
-
if (!token) {
|
|
1134
|
-
throw new errors.InputError(`No token available for host: ${host}, with owner ${owner}, and repo ${repo}`);
|
|
1135
|
-
}
|
|
1136
|
-
const client = new rest.Octokit({
|
|
1137
|
-
auth: token,
|
|
1138
|
-
baseUrl: integrationConfig.config.apiBaseUrl,
|
|
1139
|
-
previews: ["nebula-preview"]
|
|
1140
|
-
});
|
|
1157
|
+
const {client, token, owner, repo} = await octokitProvider.getOctokit(repoUrl);
|
|
1141
1158
|
const user = await client.users.getByUsername({
|
|
1142
1159
|
username: owner
|
|
1143
1160
|
});
|
|
@@ -1445,7 +1462,7 @@ function createPublishGitlabAction(options) {
|
|
|
1445
1462
|
visibility: repoVisibility
|
|
1446
1463
|
});
|
|
1447
1464
|
const remoteUrl = http_url_to_repo.replace(/\.git$/, "");
|
|
1448
|
-
const repoContentsUrl = `${remoteUrl}/-/blob
|
|
1465
|
+
const repoContentsUrl = `${remoteUrl}/-/blob/${defaultBranch}`;
|
|
1449
1466
|
const gitAuthorInfo = {
|
|
1450
1467
|
name: config.getOptionalString("scaffolder.defaultAuthor.name"),
|
|
1451
1468
|
email: config.getOptionalString("scaffolder.defaultAuthor.email")
|
|
@@ -1470,10 +1487,7 @@ function createPublishGitlabAction(options) {
|
|
|
1470
1487
|
|
|
1471
1488
|
function createGithubActionsDispatchAction(options) {
|
|
1472
1489
|
const {integrations} = options;
|
|
1473
|
-
const
|
|
1474
|
-
const provider = integration.GithubCredentialsProvider.create(integration$1.config);
|
|
1475
|
-
return [integration$1.config.host, provider];
|
|
1476
|
-
}));
|
|
1490
|
+
const octokitProvider = new OctokitProvider(integrations);
|
|
1477
1491
|
return createTemplateAction({
|
|
1478
1492
|
id: "github:actions:dispatch",
|
|
1479
1493
|
description: "Dispatches a GitHub Action workflow for a given branch or tag",
|
|
@@ -1502,27 +1516,8 @@ function createGithubActionsDispatchAction(options) {
|
|
|
1502
1516
|
},
|
|
1503
1517
|
async handler(ctx) {
|
|
1504
1518
|
const {repoUrl, workflowId, branchOrTagName} = ctx.input;
|
|
1505
|
-
const {owner, repo, host} = parseRepoUrl(repoUrl, integrations);
|
|
1506
|
-
if (!owner) {
|
|
1507
|
-
throw new errors.InputError(`No owner provided for host: ${host}, and repo ${repo}`);
|
|
1508
|
-
}
|
|
1509
1519
|
ctx.logger.info(`Dispatching workflow ${workflowId} for repo ${repoUrl} on ${branchOrTagName}`);
|
|
1510
|
-
const
|
|
1511
|
-
const integrationConfig = integrations.github.byHost(host);
|
|
1512
|
-
if (!credentialsProvider || !integrationConfig) {
|
|
1513
|
-
throw new errors.InputError(`No matching integration configuration for host ${host}, please check your integrations config`);
|
|
1514
|
-
}
|
|
1515
|
-
const {token} = await credentialsProvider.getCredentials({
|
|
1516
|
-
url: `https://${host}/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}`
|
|
1517
|
-
});
|
|
1518
|
-
if (!token) {
|
|
1519
|
-
throw new errors.InputError(`No token available for host: ${host}, with owner ${owner}, and repo ${repo}`);
|
|
1520
|
-
}
|
|
1521
|
-
const client = new rest.Octokit({
|
|
1522
|
-
auth: token,
|
|
1523
|
-
baseUrl: integrationConfig.config.apiBaseUrl,
|
|
1524
|
-
previews: ["nebula-preview"]
|
|
1525
|
-
});
|
|
1520
|
+
const {client, owner, repo} = await octokitProvider.getOctokit(repoUrl);
|
|
1526
1521
|
await client.rest.actions.createWorkflowDispatch({
|
|
1527
1522
|
owner,
|
|
1528
1523
|
repo,
|
|
@@ -1534,6 +1529,105 @@ function createGithubActionsDispatchAction(options) {
|
|
|
1534
1529
|
});
|
|
1535
1530
|
}
|
|
1536
1531
|
|
|
1532
|
+
function createGithubWebhookAction(options) {
|
|
1533
|
+
const {integrations, defaultWebhookSecret} = options;
|
|
1534
|
+
const octokitProvider = new OctokitProvider(integrations);
|
|
1535
|
+
const eventNames = webhooks.emitterEventNames.filter((event) => !event.includes("."));
|
|
1536
|
+
return createTemplateAction({
|
|
1537
|
+
id: "github:webhook",
|
|
1538
|
+
description: "Creates webhook for a repository on GitHub.",
|
|
1539
|
+
schema: {
|
|
1540
|
+
input: {
|
|
1541
|
+
type: "object",
|
|
1542
|
+
required: ["repoUrl", "webhookUrl"],
|
|
1543
|
+
properties: {
|
|
1544
|
+
repoUrl: {
|
|
1545
|
+
title: "Repository Location",
|
|
1546
|
+
description: `Accepts the format 'github.com?repo=reponame&owner=owner' where 'reponame' is the new repository name and 'owner' is an organization or username`,
|
|
1547
|
+
type: "string"
|
|
1548
|
+
},
|
|
1549
|
+
webhookUrl: {
|
|
1550
|
+
title: "Webhook URL",
|
|
1551
|
+
description: "The URL to which the payloads will be delivered",
|
|
1552
|
+
type: "string"
|
|
1553
|
+
},
|
|
1554
|
+
webhookSecret: {
|
|
1555
|
+
title: "Webhook Secret",
|
|
1556
|
+
description: "Webhook secret value. The default can be provided internally in action creation",
|
|
1557
|
+
type: "string"
|
|
1558
|
+
},
|
|
1559
|
+
events: {
|
|
1560
|
+
title: "Triggering Events",
|
|
1561
|
+
description: "Determines what events the hook is triggered for. Default: push",
|
|
1562
|
+
type: "array",
|
|
1563
|
+
oneOf: [
|
|
1564
|
+
{
|
|
1565
|
+
items: {
|
|
1566
|
+
type: "string",
|
|
1567
|
+
enum: eventNames
|
|
1568
|
+
}
|
|
1569
|
+
},
|
|
1570
|
+
{
|
|
1571
|
+
items: {
|
|
1572
|
+
type: "string",
|
|
1573
|
+
const: "*"
|
|
1574
|
+
}
|
|
1575
|
+
}
|
|
1576
|
+
]
|
|
1577
|
+
},
|
|
1578
|
+
active: {
|
|
1579
|
+
title: "Active",
|
|
1580
|
+
type: "boolean",
|
|
1581
|
+
description: `Determines if notifications are sent when the webhook is triggered. Default: true`
|
|
1582
|
+
},
|
|
1583
|
+
contentType: {
|
|
1584
|
+
title: "Content Type",
|
|
1585
|
+
type: "string",
|
|
1586
|
+
enum: ["form", "json"],
|
|
1587
|
+
description: `The media type used to serialize the payloads. The default is 'form'`
|
|
1588
|
+
},
|
|
1589
|
+
insecureSsl: {
|
|
1590
|
+
title: "Insecure SSL",
|
|
1591
|
+
type: "boolean",
|
|
1592
|
+
description: `Determines whether the SSL certificate of the host for url will be verified when delivering payloads. Default 'false'`
|
|
1593
|
+
}
|
|
1594
|
+
}
|
|
1595
|
+
}
|
|
1596
|
+
},
|
|
1597
|
+
async handler(ctx) {
|
|
1598
|
+
const {
|
|
1599
|
+
repoUrl,
|
|
1600
|
+
webhookUrl,
|
|
1601
|
+
webhookSecret = defaultWebhookSecret,
|
|
1602
|
+
events = ["push"],
|
|
1603
|
+
active = true,
|
|
1604
|
+
contentType = "form",
|
|
1605
|
+
insecureSsl = false
|
|
1606
|
+
} = ctx.input;
|
|
1607
|
+
ctx.logger.info(`Creating webhook ${webhookUrl} for repo ${repoUrl}`);
|
|
1608
|
+
const {client, owner, repo} = await octokitProvider.getOctokit(repoUrl);
|
|
1609
|
+
try {
|
|
1610
|
+
const insecure_ssl = insecureSsl ? "1" : "0";
|
|
1611
|
+
await client.repos.createWebhook({
|
|
1612
|
+
owner,
|
|
1613
|
+
repo,
|
|
1614
|
+
config: {
|
|
1615
|
+
url: webhookUrl,
|
|
1616
|
+
content_type: contentType,
|
|
1617
|
+
secret: webhookSecret,
|
|
1618
|
+
insecure_ssl
|
|
1619
|
+
},
|
|
1620
|
+
events,
|
|
1621
|
+
active
|
|
1622
|
+
});
|
|
1623
|
+
ctx.logger.info(`Webhook '${webhookUrl}' created successfully`);
|
|
1624
|
+
} catch (e) {
|
|
1625
|
+
ctx.logger.warn(`Failed: create webhook '${webhookUrl}' on repo: '${repo}', ${e.message}`);
|
|
1626
|
+
}
|
|
1627
|
+
}
|
|
1628
|
+
});
|
|
1629
|
+
}
|
|
1630
|
+
|
|
1537
1631
|
const createBuiltinActions = (options) => {
|
|
1538
1632
|
const {reader, integrations, containerRunner, catalogClient, config} = options;
|
|
1539
1633
|
return [
|
|
@@ -1576,6 +1670,9 @@ const createBuiltinActions = (options) => {
|
|
|
1576
1670
|
createFilesystemRenameAction(),
|
|
1577
1671
|
createGithubActionsDispatchAction({
|
|
1578
1672
|
integrations
|
|
1673
|
+
}),
|
|
1674
|
+
createGithubWebhookAction({
|
|
1675
|
+
integrations
|
|
1579
1676
|
})
|
|
1580
1677
|
];
|
|
1581
1678
|
};
|
|
@@ -2324,6 +2421,7 @@ Object.defineProperty(exports, 'createFetchCookiecutterAction', {
|
|
|
2324
2421
|
}
|
|
2325
2422
|
});
|
|
2326
2423
|
exports.CatalogEntityClient = CatalogEntityClient;
|
|
2424
|
+
exports.OctokitProvider = OctokitProvider;
|
|
2327
2425
|
exports.TemplateActionRegistry = TemplateActionRegistry;
|
|
2328
2426
|
exports.createBuiltinActions = createBuiltinActions;
|
|
2329
2427
|
exports.createCatalogRegisterAction = createCatalogRegisterAction;
|
|
@@ -2334,6 +2432,7 @@ exports.createFetchTemplateAction = createFetchTemplateAction;
|
|
|
2334
2432
|
exports.createFilesystemDeleteAction = createFilesystemDeleteAction;
|
|
2335
2433
|
exports.createFilesystemRenameAction = createFilesystemRenameAction;
|
|
2336
2434
|
exports.createGithubActionsDispatchAction = createGithubActionsDispatchAction;
|
|
2435
|
+
exports.createGithubWebhookAction = createGithubWebhookAction;
|
|
2337
2436
|
exports.createPublishAzureAction = createPublishAzureAction;
|
|
2338
2437
|
exports.createPublishBitbucketAction = createPublishBitbucketAction;
|
|
2339
2438
|
exports.createPublishFileAction = createPublishFileAction;
|