@backstage/plugin-scaffolder-backend-module-github 0.2.8-next.2 → 0.2.9-next.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 CHANGED
@@ -1,5 +1,31 @@
1
1
  # @backstage/plugin-scaffolder-backend-module-github
2
2
 
3
+ ## 0.2.9-next.0
4
+
5
+ ### Patch Changes
6
+
7
+ - f145a04: Added handling for dry run to githubPullRequest and githubWebhook and added tests for this functionality
8
+ - Updated dependencies
9
+ - @backstage/backend-common@0.22.1-next.0
10
+ - @backstage/backend-plugin-api@0.6.19-next.0
11
+ - @backstage/plugin-scaffolder-node@0.4.5-next.0
12
+ - @backstage/config@1.2.0
13
+ - @backstage/errors@1.2.4
14
+ - @backstage/integration@1.11.0
15
+
16
+ ## 0.2.8
17
+
18
+ ### Patch Changes
19
+
20
+ - 5d99272: Update local development dependencies.
21
+ - d229dc4: Move path utilities from `backend-common` to the `backend-plugin-api` package.
22
+ - 52ab241: Adding support to change the default commit author for `publish:github:pull-request`
23
+ - Updated dependencies
24
+ - @backstage/backend-common@0.22.0
25
+ - @backstage/backend-plugin-api@0.6.18
26
+ - @backstage/plugin-scaffolder-node@0.4.4
27
+ - @backstage/integration@1.11.0
28
+
3
29
  ## 0.2.8-next.2
4
30
 
5
31
  ### Patch Changes
package/dist/index.cjs.js CHANGED
@@ -10,7 +10,6 @@ var Sodium = require('libsodium-wrappers');
10
10
  var yaml = require('yaml');
11
11
  var webhooks = require('@octokit/webhooks');
12
12
  var path = require('path');
13
- var backendCommon = require('@backstage/backend-common');
14
13
  var octokitPluginCreatePullRequest = require('octokit-plugin-create-pull-request');
15
14
  var backendPluginApi = require('@backstage/backend-plugin-api');
16
15
  var alpha = require('@backstage/plugin-scaffolder-node/alpha');
@@ -58,7 +57,7 @@ const enableBranchProtectionOnDefaultRepoBranch = async ({
58
57
  strict: requireBranchesToBeUpToDate,
59
58
  contexts: requiredStatusCheckContexts
60
59
  },
61
- restrictions: restrictions != null ? restrictions : null,
60
+ restrictions: restrictions ?? null,
62
61
  enforce_admins: enforceAdmins,
63
62
  required_pull_request_reviews: {
64
63
  required_approving_review_count: requiredApprovingReviewCount,
@@ -104,7 +103,6 @@ function entityRefToName(name) {
104
103
 
105
104
  const DEFAULT_TIMEOUT_MS = 6e4;
106
105
  async function getOctokitOptions(options) {
107
- var _a;
108
106
  const { integrations, credentialsProvider, repoUrl, token } = options;
109
107
  const { owner, repo, host } = pluginScaffolderNode.parseRepoUrl(repoUrl, integrations);
110
108
  const requestOptions = {
@@ -114,7 +112,7 @@ async function getOctokitOptions(options) {
114
112
  if (!owner) {
115
113
  throw new errors.InputError(`No owner provided for repo ${repoUrl}`);
116
114
  }
117
- const integrationConfig = (_a = integrations.github.byHost(host)) == null ? void 0 : _a.config;
115
+ const integrationConfig = integrations.github.byHost(host)?.config;
118
116
  if (!integrationConfig) {
119
117
  throw new errors.InputError(`No integration for host ${host}`);
120
118
  }
@@ -126,7 +124,7 @@ async function getOctokitOptions(options) {
126
124
  request: requestOptions
127
125
  };
128
126
  }
129
- const githubCredentialsProvider = credentialsProvider != null ? credentialsProvider : integration.DefaultGithubCredentialsProvider.fromIntegrations(integrations);
127
+ const githubCredentialsProvider = credentialsProvider ?? integration.DefaultGithubCredentialsProvider.fromIntegrations(integrations);
130
128
  const { token: credentialProviderToken } = await githubCredentialsProvider.getCredentials({
131
129
  url: `https://${host}/${encodeURIComponent(owner)}/${encodeURIComponent(
132
130
  repo
@@ -147,7 +145,7 @@ async function createGithubRepoWithCollaboratorsAndTopics(client, repo, owner, r
147
145
  const user = await client.rest.users.getByUsername({
148
146
  username: owner
149
147
  });
150
- if (access == null ? void 0 : access.startsWith(`${owner}/`)) {
148
+ if (access?.startsWith(`${owner}/`)) {
151
149
  await validateAccessTeam(client, access);
152
150
  }
153
151
  const repoCreationPromise = user.data.type === "Organization" ? client.rest.repos.createInOrg({
@@ -198,7 +196,7 @@ async function createGithubRepoWithCollaboratorsAndTopics(client, repo, owner, r
198
196
  `Failed to create the ${user.data.type} repository ${owner}/${repo}, ${e.message}`
199
197
  );
200
198
  }
201
- if (access == null ? void 0 : access.startsWith(`${owner}/`)) {
199
+ if (access?.startsWith(`${owner}/`)) {
202
200
  const [, team] = access.split("/");
203
201
  await client.rest.teams.addOrUpdateRepoPermissionsInOrg({
204
202
  org: owner,
@@ -255,7 +253,7 @@ async function createGithubRepoWithCollaboratorsAndTopics(client, repo, owner, r
255
253
  logger.warn(`Skipping topics ${topics.join(" ")}, ${e.message}`);
256
254
  }
257
255
  }
258
- for (const [key, value] of Object.entries(repoVariables != null ? repoVariables : {})) {
256
+ for (const [key, value] of Object.entries(repoVariables ?? {})) {
259
257
  await client.rest.actions.createRepoVariable({
260
258
  owner,
261
259
  repo,
@@ -1319,6 +1317,7 @@ function createGithubWebhookAction(options) {
1319
1317
  id: "github:webhook",
1320
1318
  description: "Creates webhook for a repository on GitHub.",
1321
1319
  examples: examples$5,
1320
+ supportsDryRun: true,
1322
1321
  schema: {
1323
1322
  input: {
1324
1323
  type: "object",
@@ -1406,6 +1405,10 @@ function createGithubWebhookAction(options) {
1406
1405
  token: providedToken
1407
1406
  })
1408
1407
  );
1408
+ if (ctx.isDryRun) {
1409
+ ctx.logger.info(`Dry run complete`);
1410
+ return;
1411
+ }
1409
1412
  try {
1410
1413
  const insecure_ssl = insecureSsl ? "1" : "0";
1411
1414
  await client.rest.repos.createWebhook({
@@ -1734,7 +1737,7 @@ function createGithubEnvironmentAction(options) {
1734
1737
  owner,
1735
1738
  repo,
1736
1739
  environment_name: name,
1737
- deployment_branch_policy: deploymentBranchPolicy != null ? deploymentBranchPolicy : null
1740
+ deployment_branch_policy: deploymentBranchPolicy ?? null
1738
1741
  });
1739
1742
  if (customBranchPolicyNames) {
1740
1743
  for (const item of customBranchPolicyNames) {
@@ -1746,7 +1749,7 @@ function createGithubEnvironmentAction(options) {
1746
1749
  });
1747
1750
  }
1748
1751
  }
1749
- for (const [key, value] of Object.entries(environmentVariables != null ? environmentVariables : {})) {
1752
+ for (const [key, value] of Object.entries(environmentVariables ?? {})) {
1750
1753
  await client.rest.actions.createEnvironmentVariable({
1751
1754
  repository_id: repository.data.id,
1752
1755
  environment_name: name,
@@ -1949,6 +1952,65 @@ const examples$2 = [
1949
1952
  ]
1950
1953
  })
1951
1954
  },
1955
+ {
1956
+ description: "Create a pull request with a git author name and email",
1957
+ example: yaml__default.default.stringify({
1958
+ steps: [
1959
+ {
1960
+ action: "publish:github:pull-request",
1961
+ name: "Create a pull reuqest",
1962
+ input: {
1963
+ repoUrl: "github.com?repo=repo&owner=owner",
1964
+ branchName: "new-app",
1965
+ title: "Create my new app",
1966
+ description: "This PR is really good",
1967
+ gitAuthorName: "Foo Bar",
1968
+ gitAuthorEmail: "foo@bar.example"
1969
+ }
1970
+ }
1971
+ ]
1972
+ })
1973
+ },
1974
+ {
1975
+ description: "Create a pull request with a git author name",
1976
+ example: yaml__default.default.stringify({
1977
+ steps: [
1978
+ {
1979
+ action: "publish:github:pull-request",
1980
+ name: "Create a pull reuqest",
1981
+ input: {
1982
+ repoUrl: "github.com?repo=repo&owner=owner",
1983
+ branchName: "new-app",
1984
+ title: "Create my new app",
1985
+ description: "This PR is really good",
1986
+ // gitAuthorEmail will be 'scaffolder@backstage.io'
1987
+ // once one author attribute has been set we need to set both
1988
+ gitAuthorName: "Foo Bar"
1989
+ }
1990
+ }
1991
+ ]
1992
+ })
1993
+ },
1994
+ {
1995
+ description: "Create a pull request with a git author email",
1996
+ example: yaml__default.default.stringify({
1997
+ steps: [
1998
+ {
1999
+ action: "publish:github:pull-request",
2000
+ name: "Create a pull reuqest",
2001
+ input: {
2002
+ repoUrl: "github.com?repo=repo&owner=owner",
2003
+ branchName: "new-app",
2004
+ title: "Create my new app",
2005
+ description: "This PR is really good",
2006
+ // gitAuthorName will be 'Scaffolder'
2007
+ // once one author attribute has been set we need to set both
2008
+ gitAuthorEmail: "foo@bar.example"
2009
+ }
2010
+ }
2011
+ ]
2012
+ })
2013
+ },
1952
2014
  {
1953
2015
  description: "Create a pull request with all parameters",
1954
2016
  example: yaml__default.default.stringify({
@@ -1968,7 +2030,9 @@ const examples$2 = [
1968
2030
  token: "gph_YourGitHubToken",
1969
2031
  reviewers: ["foobar"],
1970
2032
  teamReviewers: ["team-foo"],
1971
- commitMessage: "Commit for foo changes"
2033
+ commitMessage: "Commit for foo changes",
2034
+ gitAuthorName: "Foo Bar",
2035
+ gitAuthorEmail: "foo@bar.example"
1972
2036
  }
1973
2037
  }
1974
2038
  ]
@@ -2005,11 +2069,13 @@ const createPublishGithubPullRequestAction = (options) => {
2005
2069
  const {
2006
2070
  integrations,
2007
2071
  githubCredentialsProvider,
2008
- clientFactory = defaultClientFactory
2072
+ clientFactory = defaultClientFactory,
2073
+ config
2009
2074
  } = options;
2010
2075
  return pluginScaffolderNode.createTemplateAction({
2011
2076
  id: "publish:github:pull-request",
2012
2077
  examples: examples$2,
2078
+ supportsDryRun: true,
2013
2079
  schema: {
2014
2080
  input: {
2015
2081
  required: ["repoUrl", "title", "description", "branchName"],
@@ -2090,6 +2156,16 @@ const createPublishGithubPullRequestAction = (options) => {
2090
2156
  type: "boolean",
2091
2157
  title: "Force Fork",
2092
2158
  description: "Create pull request from a fork"
2159
+ },
2160
+ gitAuthorName: {
2161
+ type: "string",
2162
+ title: "Default Author Name",
2163
+ description: "Sets the default author name for the commit. The default value is the authenticated user or 'Scaffolder'"
2164
+ },
2165
+ gitAuthorEmail: {
2166
+ type: "string",
2167
+ title: "Default Author Email",
2168
+ description: "Sets the default author email for the commit. The default value is the authenticated user or 'scaffolder@backstage.io'"
2093
2169
  }
2094
2170
  }
2095
2171
  },
@@ -2129,7 +2205,9 @@ const createPublishGithubPullRequestAction = (options) => {
2129
2205
  teamReviewers,
2130
2206
  commitMessage,
2131
2207
  update,
2132
- forceFork
2208
+ forceFork,
2209
+ gitAuthorEmail,
2210
+ gitAuthorName
2133
2211
  } = ctx.input;
2134
2212
  const { owner, repo, host } = pluginScaffolderNode.parseRepoUrl(repoUrl, integrations);
2135
2213
  if (!owner) {
@@ -2145,7 +2223,7 @@ const createPublishGithubPullRequestAction = (options) => {
2145
2223
  repo,
2146
2224
  token: providedToken
2147
2225
  });
2148
- const fileRoot = sourcePath ? backendCommon.resolveSafeChildPath(ctx.workspacePath, sourcePath) : ctx.workspacePath;
2226
+ const fileRoot = sourcePath ? backendPluginApi.resolveSafeChildPath(ctx.workspacePath, sourcePath) : ctx.workspacePath;
2149
2227
  const directoryContents = await pluginScaffolderNode.serializeDirectoryContents(fileRoot, {
2150
2228
  gitignore: true
2151
2229
  });
@@ -2176,6 +2254,14 @@ const createPublishGithubPullRequestAction = (options) => {
2176
2254
  }
2177
2255
  ])
2178
2256
  );
2257
+ if (ctx.isDryRun) {
2258
+ ctx.logger.info(`Performing dry run of creating pull request`);
2259
+ ctx.output("targetBranchName", branchName);
2260
+ ctx.output("remoteUrl", repoUrl);
2261
+ ctx.output("pullRequestNumber", 43);
2262
+ ctx.logger.info(`Dry run complete`);
2263
+ return;
2264
+ }
2179
2265
  try {
2180
2266
  const createOptions = {
2181
2267
  owner,
@@ -2184,7 +2270,7 @@ const createPublishGithubPullRequestAction = (options) => {
2184
2270
  changes: [
2185
2271
  {
2186
2272
  files,
2187
- commit: commitMessage != null ? commitMessage : title
2273
+ commit: commitMessage ?? config?.getOptionalString("scaffolder.defaultCommitMessage") ?? title
2188
2274
  }
2189
2275
  ],
2190
2276
  body: description,
@@ -2193,6 +2279,29 @@ const createPublishGithubPullRequestAction = (options) => {
2193
2279
  update,
2194
2280
  forceFork
2195
2281
  };
2282
+ const gitAuthorInfo = {
2283
+ name: gitAuthorName ?? config?.getOptionalString("scaffolder.defaultAuthor.name"),
2284
+ email: gitAuthorEmail ?? config?.getOptionalString("scaffolder.defaultAuthor.email")
2285
+ };
2286
+ if (gitAuthorInfo.name || gitAuthorInfo.email) {
2287
+ if (Array.isArray(createOptions.changes)) {
2288
+ createOptions.changes = createOptions.changes.map((change) => ({
2289
+ ...change,
2290
+ author: {
2291
+ name: gitAuthorInfo.name || "Scaffolder",
2292
+ email: gitAuthorInfo.email || "scaffolder@backstage.io"
2293
+ }
2294
+ }));
2295
+ } else {
2296
+ createOptions.changes = {
2297
+ ...createOptions.changes,
2298
+ author: {
2299
+ name: gitAuthorInfo.name || "Scaffolder",
2300
+ email: gitAuthorInfo.email || "scaffolder@backstage.io"
2301
+ }
2302
+ };
2303
+ }
2304
+ }
2196
2305
  if (targetBranchName) {
2197
2306
  createOptions.base = targetBranchName;
2198
2307
  }
@@ -2221,7 +2330,6 @@ const createPublishGithubPullRequestAction = (options) => {
2221
2330
  }
2222
2331
  });
2223
2332
  async function requestReviewersOnPullRequest(pr, reviewers, teamReviewers, client, logger) {
2224
- var _a, _b, _c, _d;
2225
2333
  try {
2226
2334
  const result = await client.rest.pulls.requestReviewers({
2227
2335
  owner: pr.owner,
@@ -2230,8 +2338,8 @@ const createPublishGithubPullRequestAction = (options) => {
2230
2338
  reviewers,
2231
2339
  team_reviewers: teamReviewers ? [...new Set(teamReviewers)] : void 0
2232
2340
  });
2233
- const addedUsers = (_b = (_a = result.data.requested_reviewers) == null ? void 0 : _a.join(", ")) != null ? _b : "";
2234
- const addedTeams = (_d = (_c = result.data.requested_teams) == null ? void 0 : _c.join(", ")) != null ? _d : "";
2341
+ const addedUsers = result.data.requested_reviewers?.join(", ") ?? "";
2342
+ const addedTeams = result.data.requested_teams?.join(", ") ?? "";
2235
2343
  logger.info(
2236
2344
  `Added users [${addedUsers}] and teams [${addedTeams}] as reviewers to Pull request ${pr.number}`
2237
2345
  );
@@ -2456,7 +2564,7 @@ function createPublishGithubAction(options) {
2456
2564
  dismissStaleReviews,
2457
2565
  requiredCommitSigning
2458
2566
  );
2459
- ctx.output("commitHash", commitResult == null ? void 0 : commitResult.commitHash);
2567
+ ctx.output("commitHash", commitResult?.commitHash);
2460
2568
  ctx.output("remoteUrl", remoteUrl);
2461
2569
  ctx.output("repoContentsUrl", repoContentsUrl);
2462
2570
  }
@@ -2596,7 +2704,8 @@ const githubModule = backendPluginApi.createBackendModule({
2596
2704
  }),
2597
2705
  createPublishGithubPullRequestAction({
2598
2706
  integrations,
2599
- githubCredentialsProvider
2707
+ githubCredentialsProvider,
2708
+ config
2600
2709
  })
2601
2710
  );
2602
2711
  }