@backstage/plugin-scaffolder-backend 0.15.23-next.1 → 0.15.23

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 CHANGED
@@ -1,5 +1,17 @@
1
1
  # @backstage/plugin-scaffolder-backend
2
2
 
3
+ ## 0.15.23
4
+
5
+ ### Patch Changes
6
+
7
+ - 2e0dbb0e50: Migrate from deprecated package @octokit/rest to octokit
8
+ - c95df1631e: Added support for templating secrets into actions input, and also added an extra `token` input argument to all publishers to provide a token that would override the `integrations.config`.
9
+ You can find more information over at [Writing Templates](https://backstage.io/docs/features/software-templates/writing-templates#using-the-users-oauth-token)
10
+ - Updated dependencies
11
+ - @backstage/plugin-catalog-backend@0.21.2
12
+ - @backstage/backend-common@0.10.6
13
+ - @backstage/plugin-scaffolder-backend-module-cookiecutter@0.1.10
14
+
3
15
  ## 0.15.23-next.1
4
16
 
5
17
  ### Patch Changes
package/dist/index.cjs.js CHANGED
@@ -854,8 +854,14 @@ function createPublishAzureAction(options) {
854
854
  description: `Sets the default branch on the repository. The default value is 'master'`
855
855
  },
856
856
  sourcePath: {
857
- title: "Path within the workspace that will be used as the repository root. If omitted, the entire workspace will be published as the repository.",
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.",
858
859
  type: "string"
860
+ },
861
+ token: {
862
+ title: "Authentication Token",
863
+ type: "string",
864
+ description: "The token to use for authorization to Azure"
859
865
  }
860
866
  }
861
867
  },
@@ -874,6 +880,7 @@ function createPublishAzureAction(options) {
874
880
  }
875
881
  },
876
882
  async handler(ctx) {
883
+ var _a;
877
884
  const { repoUrl, defaultBranch = "master" } = ctx.input;
878
885
  const { owner, repo, host, organization } = parseRepoUrl(repoUrl, integrations);
879
886
  if (!organization) {
@@ -883,10 +890,11 @@ function createPublishAzureAction(options) {
883
890
  if (!integrationConfig) {
884
891
  throw new errors.InputError(`No matching integration configuration for host ${host}, please check your integrations config`);
885
892
  }
886
- if (!integrationConfig.config.token) {
893
+ if (!integrationConfig.config.token && !ctx.input.token) {
887
894
  throw new errors.InputError(`No token provided for Azure Integration ${host}`);
888
895
  }
889
- const authHandler = azureDevopsNodeApi.getPersonalAccessTokenHandler(integrationConfig.config.token);
896
+ const token = (_a = ctx.input.token) != null ? _a : integrationConfig.config.token;
897
+ const authHandler = azureDevopsNodeApi.getPersonalAccessTokenHandler(token);
890
898
  const webApi = new azureDevopsNodeApi.WebApi(`https://${host}/${organization}`, authHandler);
891
899
  const client = await webApi.getGitApi();
892
900
  const createOptions = { name: repo };
@@ -910,7 +918,7 @@ function createPublishAzureAction(options) {
910
918
  defaultBranch,
911
919
  auth: {
912
920
  username: "notempty",
913
- password: integrationConfig.config.token
921
+ password: token
914
922
  },
915
923
  logger: ctx.logger,
916
924
  commitMessage: config.getOptionalString("scaffolder.defaultCommitMessage"),
@@ -1056,12 +1064,19 @@ function createPublishBitbucketAction(options) {
1056
1064
  description: `Sets the default branch on the repository. The default value is 'master'`
1057
1065
  },
1058
1066
  sourcePath: {
1059
- title: "Path within the workspace that will be used as the repository root. If omitted, the entire workspace will be published as the repository.",
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.",
1060
1069
  type: "string"
1061
1070
  },
1062
1071
  enableLFS: {
1063
- title: "Enable LFS for the repository. Only available for hosted Bitbucket.",
1072
+ title: "Enable LFS?",
1073
+ description: "Enable LFS for the repository. Only available for hosted Bitbucket.",
1064
1074
  type: "boolean"
1075
+ },
1076
+ token: {
1077
+ title: "Authentication Token",
1078
+ type: "string",
1079
+ description: "The token to use for authorization to BitBucket"
1065
1080
  }
1066
1081
  }
1067
1082
  },
@@ -1101,7 +1116,7 @@ function createPublishBitbucketAction(options) {
1101
1116
  if (!integrationConfig) {
1102
1117
  throw new errors.InputError(`No matching integration configuration for host ${host}, please check your integrations config`);
1103
1118
  }
1104
- const authorization = getAuthorizationHeader(integrationConfig.config);
1119
+ const authorization = getAuthorizationHeader(ctx.input.token ? { host: integrationConfig.config.host, token: ctx.input.token } : integrationConfig.config);
1105
1120
  const apiBaseUrl = integrationConfig.config.apiBaseUrl;
1106
1121
  const createMethod = host === "bitbucket.org" ? createBitbucketCloudRepository : createBitbucketServerRepository;
1107
1122
  const { remoteUrl, repoContentsUrl } = await createMethod({
@@ -1118,13 +1133,22 @@ function createPublishBitbucketAction(options) {
1118
1133
  name: config.getOptionalString("scaffolder.defaultAuthor.name"),
1119
1134
  email: config.getOptionalString("scaffolder.defaultAuthor.email")
1120
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
+ }
1121
1148
  await initRepoAndPush({
1122
1149
  dir: getRepoSourceDirectory(ctx.workspacePath, ctx.input.sourcePath),
1123
1150
  remoteUrl,
1124
- auth: {
1125
- username: integrationConfig.config.username ? integrationConfig.config.username : "x-token-auth",
1126
- password: integrationConfig.config.appPassword ? integrationConfig.config.appPassword : (_a = integrationConfig.config.token) != null ? _a : ""
1127
- },
1151
+ auth,
1128
1152
  defaultBranch,
1129
1153
  logger: ctx.logger,
1130
1154
  commitMessage: config.getOptionalString("scaffolder.defaultCommitMessage"),
@@ -1172,7 +1196,7 @@ class OctokitProvider {
1172
1196
  this.integrations = integrations;
1173
1197
  this.githubCredentialsProvider = githubCredentialsProvider || integration.DefaultGithubCredentialsProvider.fromIntegrations(this.integrations);
1174
1198
  }
1175
- async getOctokit(repoUrl) {
1199
+ async getOctokit(repoUrl, options) {
1176
1200
  var _a;
1177
1201
  const { owner, repo, host } = parseRepoUrl(repoUrl, this.integrations);
1178
1202
  if (!owner) {
@@ -1182,6 +1206,14 @@ class OctokitProvider {
1182
1206
  if (!integrationConfig) {
1183
1207
  throw new errors.InputError(`No integration for host ${host}`);
1184
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
+ }
1185
1217
  const { token } = await this.githubCredentialsProvider.getCredentials({
1186
1218
  url: `https://${host}/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}`
1187
1219
  });
@@ -1223,7 +1255,8 @@ function createPublishGithubAction(options) {
1223
1255
  type: "string"
1224
1256
  },
1225
1257
  requireCodeOwnerReviews: {
1226
- title: "Require an approved review in PR including files with a designated Code Owner",
1258
+ title: "Require CODEOWNER Reviews?",
1259
+ description: "Require an approved review in PR including files with a designated Code Owner",
1227
1260
  type: "boolean"
1228
1261
  },
1229
1262
  repoVisibility: {
@@ -1237,7 +1270,8 @@ function createPublishGithubAction(options) {
1237
1270
  description: `Sets the default branch on the repository. The default value is 'master'`
1238
1271
  },
1239
1272
  sourcePath: {
1240
- title: "Path within the workspace that will be used as the repository root. If omitted, the entire workspace will be published as the repository.",
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.",
1241
1275
  type: "string"
1242
1276
  },
1243
1277
  collaborators: {
@@ -1260,6 +1294,11 @@ function createPublishGithubAction(options) {
1260
1294
  }
1261
1295
  }
1262
1296
  },
1297
+ token: {
1298
+ title: "Authentication Token",
1299
+ type: "string",
1300
+ description: "The token to use for authorization to GitHub"
1301
+ },
1263
1302
  topics: {
1264
1303
  title: "Topics",
1265
1304
  type: "array",
@@ -1292,9 +1331,10 @@ function createPublishGithubAction(options) {
1292
1331
  repoVisibility = "private",
1293
1332
  defaultBranch = "master",
1294
1333
  collaborators,
1295
- topics
1334
+ topics,
1335
+ token: providedToken
1296
1336
  } = ctx.input;
1297
- const { client, token, owner, repo } = await octokitProvider.getOctokit(repoUrl);
1337
+ const { client, token, owner, repo } = await octokitProvider.getOctokit(repoUrl, { token: providedToken });
1298
1338
  const user = await client.rest.users.getByUsername({
1299
1339
  username: owner
1300
1340
  });
@@ -1402,13 +1442,21 @@ const defaultClientFactory = async ({
1402
1442
  githubCredentialsProvider,
1403
1443
  owner,
1404
1444
  repo,
1405
- host = "github.com"
1445
+ host = "github.com",
1446
+ token: providedToken
1406
1447
  }) => {
1407
1448
  var _a;
1408
1449
  const integrationConfig = (_a = integrations.github.byHost(host)) == null ? void 0 : _a.config;
1450
+ const OctokitPR = octokit.Octokit.plugin(octokitPluginCreatePullRequest.createPullRequest);
1409
1451
  if (!integrationConfig) {
1410
1452
  throw new errors.InputError(`No integration for host ${host}`);
1411
1453
  }
1454
+ if (providedToken) {
1455
+ return new OctokitPR({
1456
+ auth: providedToken,
1457
+ baseUrl: integrationConfig.apiBaseUrl
1458
+ });
1459
+ }
1412
1460
  const credentialsProvider = githubCredentialsProvider || integration.SingleInstanceGithubCredentialsProvider.create(integrationConfig);
1413
1461
  const { token } = await credentialsProvider.getCredentials({
1414
1462
  url: `https://${host}/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}`
@@ -1416,7 +1464,6 @@ const defaultClientFactory = async ({
1416
1464
  if (!token) {
1417
1465
  throw new errors.InputError(`No token available for host: ${host}, with owner ${owner}, and repo ${repo}`);
1418
1466
  }
1419
- const OctokitPR = octokit.Octokit.plugin(octokitPluginCreatePullRequest.createPullRequest);
1420
1467
  return new OctokitPR({
1421
1468
  auth: token,
1422
1469
  baseUrl: integrationConfig.apiBaseUrl
@@ -1463,6 +1510,11 @@ const createPublishGithubPullRequestAction = ({
1463
1510
  type: "string",
1464
1511
  title: "Repository Subdirectory",
1465
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"
1466
1518
  }
1467
1519
  }
1468
1520
  },
@@ -1485,7 +1537,8 @@ const createPublishGithubPullRequestAction = ({
1485
1537
  title,
1486
1538
  description,
1487
1539
  targetPath,
1488
- sourcePath
1540
+ sourcePath,
1541
+ token: providedToken
1489
1542
  } = ctx.input;
1490
1543
  const { owner, repo, host } = parseRepoUrl(repoUrl, integrations);
1491
1544
  if (!owner) {
@@ -1496,7 +1549,8 @@ const createPublishGithubPullRequestAction = ({
1496
1549
  githubCredentialsProvider,
1497
1550
  host,
1498
1551
  owner,
1499
- repo
1552
+ repo,
1553
+ token: providedToken
1500
1554
  });
1501
1555
  const fileRoot = sourcePath ? backendCommon.resolveSafeChildPath(ctx.workspacePath, sourcePath) : ctx.workspacePath;
1502
1556
  const localFilePaths = await globby__default["default"](["./**", "./**/.*", "!.git"], {
@@ -1570,8 +1624,14 @@ function createPublishGitlabAction(options) {
1570
1624
  description: `Sets the default branch on the repository. The default value is 'master'`
1571
1625
  },
1572
1626
  sourcePath: {
1573
- title: "Path within the workspace that will be used as the repository root. If omitted, the entire workspace will be published as the repository.",
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.",
1574
1629
  type: "string"
1630
+ },
1631
+ token: {
1632
+ title: "Authentication Token",
1633
+ type: "string",
1634
+ description: "The token to use for authorization to GitLab"
1575
1635
  }
1576
1636
  }
1577
1637
  },
@@ -1603,12 +1663,13 @@ function createPublishGitlabAction(options) {
1603
1663
  if (!integrationConfig) {
1604
1664
  throw new errors.InputError(`No matching integration configuration for host ${host}, please check your integrations config`);
1605
1665
  }
1606
- if (!integrationConfig.config.token) {
1666
+ if (!integrationConfig.config.token && !ctx.input.token) {
1607
1667
  throw new errors.InputError(`No token available for host ${host}`);
1608
1668
  }
1669
+ const token = ctx.input.token || integrationConfig.config.token;
1609
1670
  const client = new node.Gitlab({
1610
1671
  host: integrationConfig.config.baseUrl,
1611
- token: integrationConfig.config.token
1672
+ token
1612
1673
  });
1613
1674
  let { id: targetNamespace } = await client.Namespaces.show(owner);
1614
1675
  if (!targetNamespace) {
@@ -1632,7 +1693,7 @@ function createPublishGitlabAction(options) {
1632
1693
  defaultBranch,
1633
1694
  auth: {
1634
1695
  username: "oauth2",
1635
- password: integrationConfig.config.token
1696
+ password: token
1636
1697
  },
1637
1698
  logger: ctx.logger,
1638
1699
  commitMessage: config.getOptionalString("scaffolder.defaultCommitMessage"),
@@ -1682,6 +1743,11 @@ const createPublishGitlabMergeRequestAction = (options) => {
1682
1743
  type: "string",
1683
1744
  title: "Repository Subdirectory",
1684
1745
  description: "Subdirectory of repository to apply changes to"
1746
+ },
1747
+ token: {
1748
+ title: "Authentication Token",
1749
+ type: "string",
1750
+ description: "The token to use for authorization to GitLab"
1685
1751
  }
1686
1752
  }
1687
1753
  },
@@ -1701,6 +1767,7 @@ const createPublishGitlabMergeRequestAction = (options) => {
1701
1767
  }
1702
1768
  },
1703
1769
  async handler(ctx) {
1770
+ var _a;
1704
1771
  const repoUrl = ctx.input.repoUrl;
1705
1772
  const { host } = parseRepoUrl(repoUrl, integrations);
1706
1773
  const integrationConfig = integrations.gitlab.byHost(host);
@@ -1709,12 +1776,13 @@ const createPublishGitlabMergeRequestAction = (options) => {
1709
1776
  if (!integrationConfig) {
1710
1777
  throw new errors.InputError(`No matching integration configuration for host ${host}, please check your integrations config`);
1711
1778
  }
1712
- if (!integrationConfig.config.token) {
1779
+ if (!integrationConfig.config.token && !ctx.input.token) {
1713
1780
  throw new errors.InputError(`No token available for host ${host}`);
1714
1781
  }
1782
+ const token = (_a = ctx.input.token) != null ? _a : integrationConfig.config.token;
1715
1783
  const api = new node.Gitlab({
1716
1784
  host: integrationConfig.config.baseUrl,
1717
- token: integrationConfig.config.token
1785
+ token
1718
1786
  });
1719
1787
  const fileRoot = ctx.workspacePath;
1720
1788
  const localFilePaths = await globby__default["default"]([`${ctx.input.targetPath}/**`], {
@@ -1788,14 +1856,25 @@ function createGithubActionsDispatchAction(options) {
1788
1856
  title: "Workflow Inputs",
1789
1857
  description: "Inputs keys and values to send to GitHub Action configured on the workflow file. The maximum number of properties is 10. ",
1790
1858
  type: "object"
1859
+ },
1860
+ token: {
1861
+ title: "Authentication Token",
1862
+ type: "string",
1863
+ description: "The GITHUB_TOKEN to use for authorization to GitHub"
1791
1864
  }
1792
1865
  }
1793
1866
  }
1794
1867
  },
1795
1868
  async handler(ctx) {
1796
- const { repoUrl, workflowId, branchOrTagName, workflowInputs } = ctx.input;
1869
+ const {
1870
+ repoUrl,
1871
+ workflowId,
1872
+ branchOrTagName,
1873
+ workflowInputs,
1874
+ token: providedToken
1875
+ } = ctx.input;
1797
1876
  ctx.logger.info(`Dispatching workflow ${workflowId} for repo ${repoUrl} on ${branchOrTagName}`);
1798
- const { client, owner, repo } = await octokitProvider.getOctokit(repoUrl);
1877
+ const { client, owner, repo } = await octokitProvider.getOctokit(repoUrl, { token: providedToken });
1799
1878
  await client.rest.actions.createWorkflowDispatch({
1800
1879
  owner,
1801
1880
  repo,
@@ -1869,6 +1948,11 @@ function createGithubWebhookAction(options) {
1869
1948
  title: "Insecure SSL",
1870
1949
  type: "boolean",
1871
1950
  description: `Determines whether the SSL certificate of the host for url will be verified when delivering payloads. Default 'false'`
1951
+ },
1952
+ token: {
1953
+ title: "Authentication Token",
1954
+ type: "string",
1955
+ description: "The GITHUB_TOKEN to use for authorization to GitHub"
1872
1956
  }
1873
1957
  }
1874
1958
  }
@@ -1881,10 +1965,11 @@ function createGithubWebhookAction(options) {
1881
1965
  events = ["push"],
1882
1966
  active = true,
1883
1967
  contentType = "form",
1884
- insecureSsl = false
1968
+ insecureSsl = false,
1969
+ token: providedToken
1885
1970
  } = ctx.input;
1886
1971
  ctx.logger.info(`Creating webhook ${webhookUrl} for repo ${repoUrl}`);
1887
- const { client, owner, repo } = await octokitProvider.getOctokit(repoUrl);
1972
+ const { client, owner, repo } = await octokitProvider.getOctokit(repoUrl, { token: providedToken });
1888
1973
  try {
1889
1974
  const insecure_ssl = insecureSsl ? "1" : "0";
1890
1975
  await client.rest.repos.createWebhook({
@@ -2557,7 +2642,7 @@ class NunjucksWorkflowRunner {
2557
2642
  });
2558
2643
  }
2559
2644
  async execute(task) {
2560
- var _a, _b, _c, _d;
2645
+ var _a, _b, _c, _d, _e;
2561
2646
  if (!isValidTaskSpec(task.spec)) {
2562
2647
  throw new errors.InputError("Wrong template version executed with the workflow engine");
2563
2648
  }
@@ -2591,8 +2676,8 @@ class NunjucksWorkflowRunner {
2591
2676
  });
2592
2677
  const action = this.options.actionRegistry.get(step.action);
2593
2678
  const { taskLogger, streamLogger } = createStepLogger({ task, step });
2594
- const input = (_a = step.input && this.render(step.input, context, renderTemplate)) != null ? _a : {};
2595
- if ((_b = action.schema) == null ? void 0 : _b.input) {
2679
+ const input = (_b = step.input && this.render(step.input, { ...context, secrets: (_a = task.secrets) != null ? _a : {} }, renderTemplate)) != null ? _b : {};
2680
+ if ((_c = action.schema) == null ? void 0 : _c.input) {
2596
2681
  const validateResult = jsonschema.validate(input, action.schema.input);
2597
2682
  if (!validateResult.valid) {
2598
2683
  const errors$1 = validateResult.errors.join(", ");
@@ -2607,8 +2692,8 @@ class NunjucksWorkflowRunner {
2607
2692
  await action.handler({
2608
2693
  baseUrl: task.spec.baseUrl,
2609
2694
  input,
2610
- token: (_c = task.secrets) == null ? void 0 : _c.token,
2611
- secrets: (_d = task.secrets) != null ? _d : {},
2695
+ token: (_d = task.secrets) == null ? void 0 : _d.token,
2696
+ secrets: (_e = task.secrets) != null ? _e : {},
2612
2697
  logger: taskLogger,
2613
2698
  logStream: streamLogger,
2614
2699
  workspacePath,