@backstage/plugin-scaffolder-backend-module-github 0.9.10-next.0 → 0.9.10

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,16 @@
1
1
  # @backstage/plugin-scaffolder-backend-module-github
2
2
 
3
+ ## 0.9.10
4
+
5
+ ### Patch Changes
6
+
7
+ - 464ebc2: Added a fallback for `publish:github` and `github:repo:push` actions that retries via the GitHub GraphQL API when the git push fails with a connection-level error (`ECONNRESET` or `ECONNREFUSED`, checked on both `error.code` and `error.cause.code`). The git smart HTTP protocol sends binary pack data in a POST request which can be blocked by network proxies that perform deep packet inspection. The GraphQL fallback uses standard JSON requests which are not affected.
8
+ - Updated dependencies
9
+ - @backstage/plugin-scaffolder-node@0.13.4
10
+ - @backstage/integration@2.0.3
11
+ - @backstage/backend-plugin-api@1.9.2
12
+ - @backstage/plugin-catalog-node@2.2.2
13
+
3
14
  ## 0.9.10-next.0
4
15
 
5
16
  ### Patch Changes
@@ -1,6 +1,8 @@
1
1
  'use strict';
2
2
 
3
+ var backendPluginApi = require('@backstage/backend-plugin-api');
3
4
  var errors = require('@backstage/errors');
5
+ var node_fs = require('node:fs');
4
6
  var pluginScaffolderNode = require('@backstage/plugin-scaffolder-node');
5
7
  var Sodium = require('libsodium-wrappers');
6
8
  var gitHelpers = require('./gitHelpers.cjs.js');
@@ -181,18 +183,41 @@ async function initRepoPushAndProtect(remoteUrl, password, workspacePath, source
181
183
  email: gitAuthorEmail ? gitAuthorEmail : config.getOptionalString("scaffolder.defaultAuthor.email")
182
184
  };
183
185
  const commitMessage = getGitCommitMessage(gitCommitMessage, config) || "initial commit";
184
- const commitResult = await pluginScaffolderNode.initRepoAndPush({
185
- dir: pluginScaffolderNode.getRepoSourceDirectory(workspacePath, sourcePath),
186
- remoteUrl,
187
- defaultBranch,
188
- auth: {
189
- username: "x-access-token",
190
- password
191
- },
192
- logger,
193
- commitMessage,
194
- gitAuthorInfo
195
- });
186
+ let commitResult;
187
+ try {
188
+ commitResult = await pluginScaffolderNode.initRepoAndPush({
189
+ dir: pluginScaffolderNode.getRepoSourceDirectory(workspacePath, sourcePath),
190
+ remoteUrl,
191
+ defaultBranch,
192
+ auth: {
193
+ username: "x-access-token",
194
+ password
195
+ },
196
+ logger,
197
+ commitMessage,
198
+ gitAuthorInfo
199
+ });
200
+ } catch (error) {
201
+ const code = error.code;
202
+ const causeCode = error.cause?.code;
203
+ const isConnectionError = code === "ECONNRESET" || code === "ECONNREFUSED" || causeCode === "ECONNRESET" || causeCode === "ECONNREFUSED";
204
+ if (isConnectionError) {
205
+ logger.warn(
206
+ `Git push failed with ${code ?? causeCode}, retrying via GitHub API. This can happen when a network proxy blocks the binary payload in the git smart HTTP protocol.`
207
+ );
208
+ commitResult = await pushFilesViaGitHubApi({
209
+ dir: pluginScaffolderNode.getRepoSourceDirectory(workspacePath, sourcePath),
210
+ owner,
211
+ repo,
212
+ client,
213
+ defaultBranch,
214
+ commitMessage,
215
+ logger
216
+ });
217
+ } else {
218
+ throw error;
219
+ }
220
+ }
196
221
  if (protectDefaultBranch) {
197
222
  try {
198
223
  await gitHelpers.enableBranchProtectionOnDefaultRepoBranch({
@@ -222,6 +247,149 @@ async function initRepoPushAndProtect(remoteUrl, password, workspacePath, source
222
247
  }
223
248
  return { commitHash: commitResult.commitHash };
224
249
  }
250
+ async function collectFilesFromDir(dirPath, basePath = "", rootPath) {
251
+ const root = rootPath ?? dirPath;
252
+ const entries = await node_fs.promises.readdir(dirPath, {
253
+ withFileTypes: true
254
+ });
255
+ const results = [];
256
+ for (const entry of entries) {
257
+ const fullPath = backendPluginApi.resolveSafeChildPath(
258
+ root,
259
+ basePath ? `${basePath}/${entry.name}` : entry.name
260
+ );
261
+ const relativePath = basePath ? `${basePath}/${entry.name}` : entry.name;
262
+ if (entry.name === ".git") {
263
+ continue;
264
+ }
265
+ if (entry.isSymbolicLink()) {
266
+ continue;
267
+ }
268
+ if (entry.isDirectory()) {
269
+ results.push(
270
+ ...await collectFilesFromDir(fullPath, relativePath, root)
271
+ );
272
+ } else if (entry.isFile()) {
273
+ results.push({
274
+ filePath: relativePath,
275
+ content: await node_fs.promises.readFile(fullPath)
276
+ });
277
+ }
278
+ }
279
+ return results;
280
+ }
281
+ const CREATE_COMMIT_ON_BRANCH_MUTATION = `
282
+ mutation CreateCommitOnBranch($input: CreateCommitOnBranchInput!) {
283
+ createCommitOnBranch(input: $input) {
284
+ commit {
285
+ oid
286
+ }
287
+ }
288
+ }
289
+ `;
290
+ async function pushFilesViaGitHubApi(input) {
291
+ const { dir, owner, repo, client, defaultBranch, commitMessage, logger } = input;
292
+ const files = await collectFilesFromDir(dir);
293
+ logger.info(
294
+ `Collected ${files.length} files for push via GraphQL to ${owner}/${repo}#${defaultBranch}`
295
+ );
296
+ if (files.length === 0) {
297
+ throw new Error(
298
+ "GraphQL API fallback found no files to push. The workspace directory may be empty."
299
+ );
300
+ }
301
+ const totalRawBytes = files.reduce((sum, f) => sum + f.content.length, 0);
302
+ const estimatedPayload = Math.ceil(totalRawBytes * (4 / 3)) + files.length * 1024;
303
+ const MAX_PAYLOAD_BYTES = 30 * 1024 * 1024;
304
+ if (estimatedPayload > MAX_PAYLOAD_BYTES) {
305
+ throw new Error(
306
+ `GraphQL API fallback payload too large (${(totalRawBytes / 1024 / 1024).toFixed(1)} MB raw, ~${(estimatedPayload / 1024 / 1024).toFixed(1)} MB encoded). Consider reducing template size or resolving the network issue preventing git push.`
307
+ );
308
+ }
309
+ let headOid;
310
+ let needsCleanup = false;
311
+ try {
312
+ const { data: ref } = await client.rest.git.getRef({
313
+ owner,
314
+ repo,
315
+ ref: `heads/${defaultBranch}`
316
+ });
317
+ headOid = ref.object.sha;
318
+ } catch (refError) {
319
+ const status = refError.status;
320
+ if (status !== 404 && status !== 409) {
321
+ throw refError;
322
+ }
323
+ if (status === 404) {
324
+ const { data: repoData } = await client.rest.repos.get({ owner, repo });
325
+ if (repoData.size > 0) {
326
+ throw new Error(
327
+ `Branch '${defaultBranch}' not found in ${owner}/${repo}. The repository exists and its default branch is '${repoData.default_branch}'.`
328
+ );
329
+ }
330
+ }
331
+ logger.info(
332
+ `No existing HEAD found for ${owner}/${repo}#${defaultBranch} (status ${status}), initializing repository`
333
+ );
334
+ const { data: init } = await client.rest.repos.createOrUpdateFileContents({
335
+ owner,
336
+ repo,
337
+ path: ".gitkeep",
338
+ message: "initialize repository",
339
+ content: "",
340
+ branch: defaultBranch
341
+ });
342
+ headOid = init.commit.sha;
343
+ needsCleanup = true;
344
+ }
345
+ const additions = files.map((file) => ({
346
+ path: file.filePath,
347
+ contents: file.content.toString("base64")
348
+ }));
349
+ const fileChanges = {
350
+ additions
351
+ };
352
+ if (needsCleanup) {
353
+ fileChanges.deletions = [{ path: ".gitkeep" }];
354
+ }
355
+ const commitInput = {
356
+ branch: {
357
+ repositoryNameWithOwner: `${owner}/${repo}`,
358
+ branchName: defaultBranch
359
+ },
360
+ message: { headline: commitMessage },
361
+ fileChanges,
362
+ expectedHeadOid: headOid
363
+ };
364
+ let result;
365
+ try {
366
+ result = await client.graphql(CREATE_COMMIT_ON_BRANCH_MUTATION, {
367
+ input: commitInput
368
+ });
369
+ } catch (commitError) {
370
+ const msg = String(commitError.message ?? "");
371
+ if (!msg.includes("expectedHeadOid")) {
372
+ throw commitError;
373
+ }
374
+ logger.warn(
375
+ `HEAD OID of ${owner}/${repo}#${defaultBranch} changed since read, retrying GraphQL commit once`
376
+ );
377
+ const { data: freshRef } = await client.rest.git.getRef({
378
+ owner,
379
+ repo,
380
+ ref: `heads/${defaultBranch}`
381
+ });
382
+ commitInput.expectedHeadOid = freshRef.object.sha;
383
+ result = await client.graphql(CREATE_COMMIT_ON_BRANCH_MUTATION, {
384
+ input: commitInput
385
+ });
386
+ }
387
+ const commitHash = result.createCommitOnBranch.commit.oid;
388
+ logger.info(
389
+ `Pushed ${files.length} files to ${owner}/${repo}#${defaultBranch} via GitHub GraphQL API (${commitHash})`
390
+ );
391
+ return { commitHash };
392
+ }
225
393
  function extractCollaboratorName(collaborator) {
226
394
  if ("username" in collaborator) {
227
395
  return collaborator.username;
@@ -1 +1 @@
1
- {"version":3,"file":"helpers.cjs.js","sources":["../../src/actions/helpers.ts"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Config } from '@backstage/config';\nimport { NotFoundError, toError } from '@backstage/errors';\nimport { Octokit } from 'octokit';\n\nimport {\n getRepoSourceDirectory,\n initRepoAndPush,\n} from '@backstage/plugin-scaffolder-node';\n\nimport Sodium from 'libsodium-wrappers';\nimport {\n enableBranchProtectionOnDefaultRepoBranch,\n entityRefToName,\n} from './gitHelpers';\nimport { LoggerService } from '@backstage/backend-plugin-api';\n\nexport async function createGithubRepoWithCollaboratorsAndTopics(\n client: Octokit,\n repo: string,\n owner: string,\n repoVisibility: 'private' | 'internal' | 'public' | undefined,\n description: string | undefined,\n homepage: string | undefined,\n deleteBranchOnMerge: boolean,\n allowMergeCommit: boolean,\n allowSquashMerge: boolean,\n squashMergeCommitTitle: 'PR_TITLE' | 'COMMIT_OR_PR_TITLE' | undefined,\n squashMergeCommitMessage: 'PR_BODY' | 'COMMIT_MESSAGES' | 'BLANK' | undefined,\n allowRebaseMerge: boolean,\n allowAutoMerge: boolean,\n allowUpdateBranch: boolean,\n access: string | undefined,\n collaborators:\n | (\n | {\n user: string;\n access: string;\n }\n | {\n team: string;\n access: string;\n }\n | {\n /** @deprecated This field is deprecated in favor of team */\n username: string;\n access: 'pull' | 'push' | 'admin' | 'maintain' | 'triage';\n }\n )[]\n | undefined,\n hasProjects: boolean | undefined,\n hasWiki: boolean | undefined,\n hasIssues: boolean | undefined,\n topics: string[] | undefined,\n repoVariables: { [key: string]: string } | undefined,\n secrets: { [key: string]: string } | undefined,\n oidcCustomization:\n | {\n useDefault: boolean;\n includeClaimKeys?: string[];\n }\n | undefined,\n customProperties: { [key: string]: string | string[] } | undefined,\n subscribe: boolean | undefined,\n logger: LoggerService,\n autoInit?: boolean | undefined,\n workflowAccess?: 'none' | 'organization' | 'user',\n) {\n const user = await client.rest.users.getByUsername({\n username: owner,\n });\n\n if (access?.startsWith(`${owner}/`)) {\n await validateAccessTeam(client, access);\n }\n\n const baseRepoParams = {\n allow_auto_merge: allowAutoMerge,\n allow_merge_commit: allowMergeCommit,\n allow_rebase_merge: allowRebaseMerge,\n allow_squash_merge: allowSquashMerge,\n allow_update_branch: allowUpdateBranch,\n auto_init: autoInit,\n delete_branch_on_merge: deleteBranchOnMerge,\n description,\n has_issues: hasIssues,\n has_projects: hasProjects,\n has_wiki: hasWiki,\n homepage,\n name: repo,\n private: repoVisibility === 'private',\n squash_merge_commit_message: squashMergeCommitMessage,\n squash_merge_commit_title: squashMergeCommitTitle,\n };\n const repoCreationPromise =\n user.data.type === 'Organization'\n ? client.rest.repos.createInOrg({\n ...baseRepoParams,\n // Custom properties only available on org repos\n custom_properties: customProperties,\n org: owner,\n // @ts-ignore https://github.com/octokit/types.ts/issues/522\n visibility: repoVisibility,\n })\n : client.rest.repos.createForAuthenticatedUser(baseRepoParams);\n\n let newRepo;\n\n try {\n newRepo = (await repoCreationPromise).data;\n } catch (e) {\n if (toError(e).message === 'Resource not accessible by integration') {\n logger.warn(\n `The GitHub app or token provided may not have the required permissions to create the ${user.data.type} repository ${owner}/${repo}.`,\n );\n }\n throw new Error(\n `Failed to create the ${user.data.type} repository ${owner}/${repo}, ${\n toError(e).message\n }`,\n );\n }\n\n if (access?.startsWith(`${owner}/`)) {\n const [, team] = access.split('/');\n await client.rest.teams.addOrUpdateRepoPermissionsInOrg({\n org: owner,\n team_slug: team,\n owner,\n repo,\n permission: 'admin',\n });\n // No need to add access if it's the person who owns the personal account\n } else if (access && access !== owner) {\n await client.rest.repos.addCollaborator({\n owner,\n repo,\n username: access,\n permission: 'admin',\n });\n }\n\n if (collaborators) {\n for (const collaborator of collaborators) {\n try {\n if ('user' in collaborator) {\n await client.rest.repos.addCollaborator({\n owner,\n repo,\n username: entityRefToName(collaborator.user),\n permission: collaborator.access,\n });\n } else if ('team' in collaborator) {\n await client.rest.teams.addOrUpdateRepoPermissionsInOrg({\n org: owner,\n team_slug: entityRefToName(collaborator.team),\n owner,\n repo,\n permission: collaborator.access,\n });\n }\n } catch (e) {\n const name = extractCollaboratorName(collaborator);\n logger.warn(\n `Skipping ${collaborator.access} access for ${name}, ${\n toError(e).message\n }`,\n );\n }\n }\n }\n\n if (topics) {\n try {\n await client.rest.repos.replaceAllTopics({\n owner,\n repo,\n names: topics.map(t => t.toLowerCase()),\n });\n } catch (e) {\n logger.warn(`Skipping topics ${topics.join(' ')}, ${toError(e).message}`);\n }\n }\n\n for (const [key, value] of Object.entries(repoVariables ?? {})) {\n await client.rest.actions.createRepoVariable({\n owner,\n repo,\n name: key,\n value: value,\n });\n }\n\n if (secrets) {\n const publicKeyResponse = await client.rest.actions.getRepoPublicKey({\n owner,\n repo,\n });\n\n await Sodium.ready;\n const binaryKey = Sodium.from_base64(\n publicKeyResponse.data.key,\n Sodium.base64_variants.ORIGINAL,\n );\n for (const [key, value] of Object.entries(secrets)) {\n const binarySecret = Sodium.from_string(value);\n const encryptedBinarySecret = Sodium.crypto_box_seal(\n binarySecret,\n binaryKey,\n );\n const encryptedBase64Secret = Sodium.to_base64(\n encryptedBinarySecret,\n Sodium.base64_variants.ORIGINAL,\n );\n\n await client.rest.actions.createOrUpdateRepoSecret({\n owner,\n repo,\n secret_name: key,\n encrypted_value: encryptedBase64Secret,\n key_id: publicKeyResponse.data.key_id,\n });\n }\n }\n\n if (oidcCustomization) {\n await client.request(\n 'PUT /repos/{owner}/{repo}/actions/oidc/customization/sub',\n {\n owner,\n repo,\n use_default: oidcCustomization.useDefault,\n include_claim_keys: oidcCustomization.includeClaimKeys,\n },\n );\n }\n\n if (subscribe) {\n await client.rest.activity.setRepoSubscription({\n subscribed: true,\n ignored: false,\n owner,\n repo,\n });\n }\n\n if (workflowAccess) {\n await client.rest.actions.setWorkflowAccessToRepository({\n access_level: workflowAccess,\n owner,\n repo,\n });\n }\n\n return newRepo;\n}\n\nexport async function initRepoPushAndProtect(\n remoteUrl: string,\n password: string,\n workspacePath: string,\n sourcePath: string | undefined,\n defaultBranch: string,\n protectDefaultBranch: boolean,\n enforceAdmins: boolean,\n owner: string,\n client: Octokit,\n repo: string,\n requireCodeOwnerReviews: boolean,\n bypassPullRequestAllowances:\n | {\n users?: string[];\n teams?: string[];\n apps?: string[];\n }\n | undefined,\n requiredApprovingReviewCount: number,\n restrictions:\n | {\n users: string[];\n teams: string[];\n apps?: string[];\n }\n | undefined,\n requiredStatusCheckContexts: string[],\n requireBranchesToBeUpToDate: boolean,\n requiredConversationResolution: boolean,\n requireLastPushApproval: boolean,\n config: Config,\n logger: any,\n gitCommitMessage?: string,\n gitAuthorName?: string,\n gitAuthorEmail?: string,\n dismissStaleReviews?: boolean,\n requiredCommitSigning?: boolean,\n requiredLinearHistory?: boolean,\n): Promise<{ commitHash: string }> {\n const gitAuthorInfo = {\n name: gitAuthorName\n ? gitAuthorName\n : config.getOptionalString('scaffolder.defaultAuthor.name'),\n email: gitAuthorEmail\n ? gitAuthorEmail\n : config.getOptionalString('scaffolder.defaultAuthor.email'),\n };\n\n const commitMessage =\n getGitCommitMessage(gitCommitMessage, config) || 'initial commit';\n\n const commitResult = await initRepoAndPush({\n dir: getRepoSourceDirectory(workspacePath, sourcePath),\n remoteUrl,\n defaultBranch,\n auth: {\n username: 'x-access-token',\n password,\n },\n logger,\n commitMessage,\n gitAuthorInfo,\n });\n\n if (protectDefaultBranch) {\n try {\n await enableBranchProtectionOnDefaultRepoBranch({\n owner,\n client,\n repoName: repo,\n logger,\n defaultBranch,\n bypassPullRequestAllowances,\n requiredApprovingReviewCount,\n restrictions,\n requireCodeOwnerReviews,\n requiredStatusCheckContexts,\n requireBranchesToBeUpToDate,\n requiredConversationResolution,\n requireLastPushApproval,\n enforceAdmins,\n dismissStaleReviews,\n requiredCommitSigning,\n requiredLinearHistory,\n });\n } catch (e) {\n logger.warn(\n `Skipping: default branch protection on '${repo}', ${\n toError(e).message\n }`,\n );\n }\n }\n\n return { commitHash: commitResult.commitHash };\n}\n\nfunction extractCollaboratorName(\n collaborator: { user: string } | { team: string } | { username: string },\n) {\n if ('username' in collaborator) {\n return collaborator.username;\n }\n if ('user' in collaborator) {\n return collaborator.user;\n }\n return collaborator.team;\n}\n\nasync function validateAccessTeam(client: Octokit, access: string) {\n const [org, team_slug] = access.split('/');\n try {\n // Below rule disabled because of a 'getByName' check for a different library\n // incorrectly triggers here.\n // eslint-disable-next-line testing-library/no-await-sync-queries\n await client.rest.teams.getByName({\n org,\n team_slug,\n });\n } catch (e) {\n if (e.response.data.message === 'Not Found') {\n const message = `Received 'Not Found' from the API; one of org:\n ${org} or team: ${team_slug} was not found within GitHub.`;\n throw new NotFoundError(message);\n }\n }\n}\n\nexport function getGitCommitMessage(\n gitCommitMessage: string | undefined,\n config: Config,\n): string | undefined {\n return gitCommitMessage\n ? gitCommitMessage\n : config.getOptionalString('scaffolder.defaultCommitMessage');\n}\n"],"names":["toError","entityRefToName","Sodium","initRepoAndPush","getRepoSourceDirectory","enableBranchProtectionOnDefaultRepoBranch","NotFoundError"],"mappings":"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"}
1
+ {"version":3,"file":"helpers.cjs.js","sources":["../../src/actions/helpers.ts"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { resolveSafeChildPath } from '@backstage/backend-plugin-api';\nimport { Config } from '@backstage/config';\nimport { NotFoundError, toError } from '@backstage/errors';\nimport { Octokit } from 'octokit';\nimport { promises as fsPromises, Dirent } from 'node:fs';\n\nimport {\n getRepoSourceDirectory,\n initRepoAndPush,\n} from '@backstage/plugin-scaffolder-node';\n\nimport Sodium from 'libsodium-wrappers';\nimport {\n enableBranchProtectionOnDefaultRepoBranch,\n entityRefToName,\n} from './gitHelpers';\nimport { LoggerService } from '@backstage/backend-plugin-api';\n\nexport async function createGithubRepoWithCollaboratorsAndTopics(\n client: Octokit,\n repo: string,\n owner: string,\n repoVisibility: 'private' | 'internal' | 'public' | undefined,\n description: string | undefined,\n homepage: string | undefined,\n deleteBranchOnMerge: boolean,\n allowMergeCommit: boolean,\n allowSquashMerge: boolean,\n squashMergeCommitTitle: 'PR_TITLE' | 'COMMIT_OR_PR_TITLE' | undefined,\n squashMergeCommitMessage: 'PR_BODY' | 'COMMIT_MESSAGES' | 'BLANK' | undefined,\n allowRebaseMerge: boolean,\n allowAutoMerge: boolean,\n allowUpdateBranch: boolean,\n access: string | undefined,\n collaborators:\n | (\n | {\n user: string;\n access: string;\n }\n | {\n team: string;\n access: string;\n }\n | {\n /** @deprecated This field is deprecated in favor of team */\n username: string;\n access: 'pull' | 'push' | 'admin' | 'maintain' | 'triage';\n }\n )[]\n | undefined,\n hasProjects: boolean | undefined,\n hasWiki: boolean | undefined,\n hasIssues: boolean | undefined,\n topics: string[] | undefined,\n repoVariables: { [key: string]: string } | undefined,\n secrets: { [key: string]: string } | undefined,\n oidcCustomization:\n | {\n useDefault: boolean;\n includeClaimKeys?: string[];\n }\n | undefined,\n customProperties: { [key: string]: string | string[] } | undefined,\n subscribe: boolean | undefined,\n logger: LoggerService,\n autoInit?: boolean | undefined,\n workflowAccess?: 'none' | 'organization' | 'user',\n) {\n const user = await client.rest.users.getByUsername({\n username: owner,\n });\n\n if (access?.startsWith(`${owner}/`)) {\n await validateAccessTeam(client, access);\n }\n\n const baseRepoParams = {\n allow_auto_merge: allowAutoMerge,\n allow_merge_commit: allowMergeCommit,\n allow_rebase_merge: allowRebaseMerge,\n allow_squash_merge: allowSquashMerge,\n allow_update_branch: allowUpdateBranch,\n auto_init: autoInit,\n delete_branch_on_merge: deleteBranchOnMerge,\n description,\n has_issues: hasIssues,\n has_projects: hasProjects,\n has_wiki: hasWiki,\n homepage,\n name: repo,\n private: repoVisibility === 'private',\n squash_merge_commit_message: squashMergeCommitMessage,\n squash_merge_commit_title: squashMergeCommitTitle,\n };\n const repoCreationPromise =\n user.data.type === 'Organization'\n ? client.rest.repos.createInOrg({\n ...baseRepoParams,\n // Custom properties only available on org repos\n custom_properties: customProperties,\n org: owner,\n // @ts-ignore https://github.com/octokit/types.ts/issues/522\n visibility: repoVisibility,\n })\n : client.rest.repos.createForAuthenticatedUser(baseRepoParams);\n\n let newRepo;\n\n try {\n newRepo = (await repoCreationPromise).data;\n } catch (e) {\n if (toError(e).message === 'Resource not accessible by integration') {\n logger.warn(\n `The GitHub app or token provided may not have the required permissions to create the ${user.data.type} repository ${owner}/${repo}.`,\n );\n }\n throw new Error(\n `Failed to create the ${user.data.type} repository ${owner}/${repo}, ${\n toError(e).message\n }`,\n );\n }\n\n if (access?.startsWith(`${owner}/`)) {\n const [, team] = access.split('/');\n await client.rest.teams.addOrUpdateRepoPermissionsInOrg({\n org: owner,\n team_slug: team,\n owner,\n repo,\n permission: 'admin',\n });\n // No need to add access if it's the person who owns the personal account\n } else if (access && access !== owner) {\n await client.rest.repos.addCollaborator({\n owner,\n repo,\n username: access,\n permission: 'admin',\n });\n }\n\n if (collaborators) {\n for (const collaborator of collaborators) {\n try {\n if ('user' in collaborator) {\n await client.rest.repos.addCollaborator({\n owner,\n repo,\n username: entityRefToName(collaborator.user),\n permission: collaborator.access,\n });\n } else if ('team' in collaborator) {\n await client.rest.teams.addOrUpdateRepoPermissionsInOrg({\n org: owner,\n team_slug: entityRefToName(collaborator.team),\n owner,\n repo,\n permission: collaborator.access,\n });\n }\n } catch (e) {\n const name = extractCollaboratorName(collaborator);\n logger.warn(\n `Skipping ${collaborator.access} access for ${name}, ${\n toError(e).message\n }`,\n );\n }\n }\n }\n\n if (topics) {\n try {\n await client.rest.repos.replaceAllTopics({\n owner,\n repo,\n names: topics.map(t => t.toLowerCase()),\n });\n } catch (e) {\n logger.warn(`Skipping topics ${topics.join(' ')}, ${toError(e).message}`);\n }\n }\n\n for (const [key, value] of Object.entries(repoVariables ?? {})) {\n await client.rest.actions.createRepoVariable({\n owner,\n repo,\n name: key,\n value: value,\n });\n }\n\n if (secrets) {\n const publicKeyResponse = await client.rest.actions.getRepoPublicKey({\n owner,\n repo,\n });\n\n await Sodium.ready;\n const binaryKey = Sodium.from_base64(\n publicKeyResponse.data.key,\n Sodium.base64_variants.ORIGINAL,\n );\n for (const [key, value] of Object.entries(secrets)) {\n const binarySecret = Sodium.from_string(value);\n const encryptedBinarySecret = Sodium.crypto_box_seal(\n binarySecret,\n binaryKey,\n );\n const encryptedBase64Secret = Sodium.to_base64(\n encryptedBinarySecret,\n Sodium.base64_variants.ORIGINAL,\n );\n\n await client.rest.actions.createOrUpdateRepoSecret({\n owner,\n repo,\n secret_name: key,\n encrypted_value: encryptedBase64Secret,\n key_id: publicKeyResponse.data.key_id,\n });\n }\n }\n\n if (oidcCustomization) {\n await client.request(\n 'PUT /repos/{owner}/{repo}/actions/oidc/customization/sub',\n {\n owner,\n repo,\n use_default: oidcCustomization.useDefault,\n include_claim_keys: oidcCustomization.includeClaimKeys,\n },\n );\n }\n\n if (subscribe) {\n await client.rest.activity.setRepoSubscription({\n subscribed: true,\n ignored: false,\n owner,\n repo,\n });\n }\n\n if (workflowAccess) {\n await client.rest.actions.setWorkflowAccessToRepository({\n access_level: workflowAccess,\n owner,\n repo,\n });\n }\n\n return newRepo;\n}\n\nexport async function initRepoPushAndProtect(\n remoteUrl: string,\n password: string,\n workspacePath: string,\n sourcePath: string | undefined,\n defaultBranch: string,\n protectDefaultBranch: boolean,\n enforceAdmins: boolean,\n owner: string,\n client: Octokit,\n repo: string,\n requireCodeOwnerReviews: boolean,\n bypassPullRequestAllowances:\n | {\n users?: string[];\n teams?: string[];\n apps?: string[];\n }\n | undefined,\n requiredApprovingReviewCount: number,\n restrictions:\n | {\n users: string[];\n teams: string[];\n apps?: string[];\n }\n | undefined,\n requiredStatusCheckContexts: string[],\n requireBranchesToBeUpToDate: boolean,\n requiredConversationResolution: boolean,\n requireLastPushApproval: boolean,\n config: Config,\n logger: any,\n gitCommitMessage?: string,\n gitAuthorName?: string,\n gitAuthorEmail?: string,\n dismissStaleReviews?: boolean,\n requiredCommitSigning?: boolean,\n requiredLinearHistory?: boolean,\n): Promise<{ commitHash: string }> {\n const gitAuthorInfo = {\n name: gitAuthorName\n ? gitAuthorName\n : config.getOptionalString('scaffolder.defaultAuthor.name'),\n email: gitAuthorEmail\n ? gitAuthorEmail\n : config.getOptionalString('scaffolder.defaultAuthor.email'),\n };\n\n const commitMessage =\n getGitCommitMessage(gitCommitMessage, config) || 'initial commit';\n\n let commitResult: { commitHash: string };\n\n try {\n commitResult = await initRepoAndPush({\n dir: getRepoSourceDirectory(workspacePath, sourcePath),\n remoteUrl,\n defaultBranch,\n auth: {\n username: 'x-access-token',\n password,\n },\n logger,\n commitMessage,\n gitAuthorInfo,\n });\n } catch (error) {\n const code = (error as NodeJS.ErrnoException).code;\n const causeCode = (\n (error as NodeJS.ErrnoException).cause as\n | NodeJS.ErrnoException\n | undefined\n )?.code;\n const isConnectionError =\n code === 'ECONNRESET' ||\n code === 'ECONNREFUSED' ||\n causeCode === 'ECONNRESET' ||\n causeCode === 'ECONNREFUSED';\n if (isConnectionError) {\n logger.warn(\n `Git push failed with ${code ?? causeCode}, retrying via GitHub API. ` +\n 'This can happen when a network proxy blocks the binary payload ' +\n 'in the git smart HTTP protocol.',\n );\n commitResult = await pushFilesViaGitHubApi({\n dir: getRepoSourceDirectory(workspacePath, sourcePath),\n owner,\n repo,\n client,\n defaultBranch,\n commitMessage,\n logger,\n });\n } else {\n throw error;\n }\n }\n\n if (protectDefaultBranch) {\n try {\n await enableBranchProtectionOnDefaultRepoBranch({\n owner,\n client,\n repoName: repo,\n logger,\n defaultBranch,\n bypassPullRequestAllowances,\n requiredApprovingReviewCount,\n restrictions,\n requireCodeOwnerReviews,\n requiredStatusCheckContexts,\n requireBranchesToBeUpToDate,\n requiredConversationResolution,\n requireLastPushApproval,\n enforceAdmins,\n dismissStaleReviews,\n requiredCommitSigning,\n requiredLinearHistory,\n });\n } catch (e) {\n logger.warn(\n `Skipping: default branch protection on '${repo}', ${\n toError(e).message\n }`,\n );\n }\n }\n\n return { commitHash: commitResult.commitHash };\n}\n\nasync function collectFilesFromDir(\n dirPath: string,\n basePath: string = '',\n rootPath?: string,\n): Promise<{ filePath: string; content: Buffer }[]> {\n const root = rootPath ?? dirPath;\n const entries: Dirent[] = await fsPromises.readdir(dirPath, {\n withFileTypes: true,\n });\n const results: { filePath: string; content: Buffer }[] = [];\n for (const entry of entries) {\n const fullPath = resolveSafeChildPath(\n root,\n basePath ? `${basePath}/${entry.name}` : entry.name,\n );\n const relativePath = basePath ? `${basePath}/${entry.name}` : entry.name;\n if (entry.name === '.git') {\n continue;\n }\n if (entry.isSymbolicLink()) {\n continue;\n }\n if (entry.isDirectory()) {\n results.push(\n ...(await collectFilesFromDir(fullPath, relativePath, root)),\n );\n } else if (entry.isFile()) {\n results.push({\n filePath: relativePath,\n content: await fsPromises.readFile(fullPath),\n });\n }\n }\n return results;\n}\n\nconst CREATE_COMMIT_ON_BRANCH_MUTATION = `\n mutation CreateCommitOnBranch($input: CreateCommitOnBranchInput!) {\n createCommitOnBranch(input: $input) {\n commit {\n oid\n }\n }\n }\n`;\n\nasync function pushFilesViaGitHubApi(input: {\n dir: string;\n owner: string;\n repo: string;\n client: Octokit;\n defaultBranch: string;\n commitMessage: string;\n logger: LoggerService;\n}): Promise<{ commitHash: string }> {\n const { dir, owner, repo, client, defaultBranch, commitMessage, logger } =\n input;\n\n const files = await collectFilesFromDir(dir);\n logger.info(\n `Collected ${files.length} files for push via GraphQL to ${owner}/${repo}#${defaultBranch}`,\n );\n\n if (files.length === 0) {\n throw new Error(\n 'GraphQL API fallback found no files to push. ' +\n 'The workspace directory may be empty.',\n );\n }\n\n const totalRawBytes = files.reduce((sum, f) => sum + f.content.length, 0);\n // base64 expands content by ~4/3; add 1 KB per file for JSON overhead\n const estimatedPayload =\n Math.ceil(totalRawBytes * (4 / 3)) + files.length * 1024;\n const MAX_PAYLOAD_BYTES = 30 * 1024 * 1024; // 30 MB after encoding\n if (estimatedPayload > MAX_PAYLOAD_BYTES) {\n throw new Error(\n `GraphQL API fallback payload too large ` +\n `(${(totalRawBytes / 1024 / 1024).toFixed(1)} MB raw, ` +\n `~${(estimatedPayload / 1024 / 1024).toFixed(1)} MB encoded). ` +\n 'Consider reducing template size or resolving the network issue preventing git push.',\n );\n }\n\n let headOid: string;\n let needsCleanup = false;\n try {\n const { data: ref } = await client.rest.git.getRef({\n owner,\n repo,\n ref: `heads/${defaultBranch}`,\n });\n headOid = ref.object.sha;\n } catch (refError: unknown) {\n const status = (refError as { status?: number }).status;\n if (status !== 404 && status !== 409) {\n throw refError;\n }\n if (status === 404) {\n const { data: repoData } = await client.rest.repos.get({ owner, repo });\n if (repoData.size > 0) {\n throw new Error(\n `Branch '${defaultBranch}' not found in ${owner}/${repo}. ` +\n `The repository exists and its default branch is '${repoData.default_branch}'.`,\n );\n }\n }\n logger.info(\n `No existing HEAD found for ${owner}/${repo}#${defaultBranch} ` +\n `(status ${status}), initializing repository`,\n );\n const { data: init } = await client.rest.repos.createOrUpdateFileContents({\n owner,\n repo,\n path: '.gitkeep',\n message: 'initialize repository',\n content: '',\n branch: defaultBranch,\n });\n headOid = init.commit.sha!;\n needsCleanup = true;\n }\n\n const additions = files.map(file => ({\n path: file.filePath,\n contents: file.content.toString('base64'),\n }));\n\n const fileChanges: {\n additions: typeof additions;\n deletions?: { path: string }[];\n } = {\n additions,\n };\n if (needsCleanup) {\n fileChanges.deletions = [{ path: '.gitkeep' }];\n }\n\n const commitInput = {\n branch: {\n repositoryNameWithOwner: `${owner}/${repo}`,\n branchName: defaultBranch,\n },\n message: { headline: commitMessage },\n fileChanges,\n expectedHeadOid: headOid,\n };\n\n let result: { createCommitOnBranch: { commit: { oid: string } } };\n try {\n result = await client.graphql(CREATE_COMMIT_ON_BRANCH_MUTATION, {\n input: commitInput,\n });\n } catch (commitError: unknown) {\n const msg = String((commitError as Error).message ?? '');\n if (!msg.includes('expectedHeadOid')) {\n throw commitError;\n }\n logger.warn(\n `HEAD OID of ${owner}/${repo}#${defaultBranch} changed since read, retrying GraphQL commit once`,\n );\n const { data: freshRef } = await client.rest.git.getRef({\n owner,\n repo,\n ref: `heads/${defaultBranch}`,\n });\n commitInput.expectedHeadOid = freshRef.object.sha;\n result = await client.graphql(CREATE_COMMIT_ON_BRANCH_MUTATION, {\n input: commitInput,\n });\n }\n\n const commitHash = result.createCommitOnBranch.commit.oid;\n logger.info(\n `Pushed ${files.length} files to ${owner}/${repo}#${defaultBranch} via GitHub GraphQL API (${commitHash})`,\n );\n return { commitHash };\n}\n\nfunction extractCollaboratorName(\n collaborator: { user: string } | { team: string } | { username: string },\n) {\n if ('username' in collaborator) {\n return collaborator.username;\n }\n if ('user' in collaborator) {\n return collaborator.user;\n }\n return collaborator.team;\n}\n\nasync function validateAccessTeam(client: Octokit, access: string) {\n const [org, team_slug] = access.split('/');\n try {\n // Below rule disabled because of a 'getByName' check for a different library\n // incorrectly triggers here.\n // eslint-disable-next-line testing-library/no-await-sync-queries\n await client.rest.teams.getByName({\n org,\n team_slug,\n });\n } catch (e) {\n if (e.response.data.message === 'Not Found') {\n const message = `Received 'Not Found' from the API; one of org:\n ${org} or team: ${team_slug} was not found within GitHub.`;\n throw new NotFoundError(message);\n }\n }\n}\n\nexport function getGitCommitMessage(\n gitCommitMessage: string | undefined,\n config: Config,\n): string | undefined {\n return gitCommitMessage\n ? gitCommitMessage\n : config.getOptionalString('scaffolder.defaultCommitMessage');\n}\n"],"names":["toError","entityRefToName","Sodium","initRepoAndPush","getRepoSourceDirectory","enableBranchProtectionOnDefaultRepoBranch","fsPromises","resolveSafeChildPath","NotFoundError"],"mappings":";;;;;;;;;;;;;AAkCA,eAAsB,0CAAA,CACpB,MAAA,EACA,IAAA,EACA,KAAA,EACA,cAAA,EACA,WAAA,EACA,QAAA,EACA,mBAAA,EACA,gBAAA,EACA,gBAAA,EACA,sBAAA,EACA,wBAAA,EACA,gBAAA,EACA,cAAA,EACA,iBAAA,EACA,MAAA,EACA,aAAA,EAiBA,WAAA,EACA,OAAA,EACA,SAAA,EACA,MAAA,EACA,aAAA,EACA,OAAA,EACA,iBAAA,EAMA,gBAAA,EACA,SAAA,EACA,MAAA,EACA,QAAA,EACA,cAAA,EACA;AACA,EAAA,MAAM,IAAA,GAAO,MAAM,MAAA,CAAO,IAAA,CAAK,MAAM,aAAA,CAAc;AAAA,IACjD,QAAA,EAAU;AAAA,GACX,CAAA;AAED,EAAA,IAAI,MAAA,EAAQ,UAAA,CAAW,CAAA,EAAG,KAAK,GAAG,CAAA,EAAG;AACnC,IAAA,MAAM,kBAAA,CAAmB,QAAQ,MAAM,CAAA;AAAA,EACzC;AAEA,EAAA,MAAM,cAAA,GAAiB;AAAA,IACrB,gBAAA,EAAkB,cAAA;AAAA,IAClB,kBAAA,EAAoB,gBAAA;AAAA,IACpB,kBAAA,EAAoB,gBAAA;AAAA,IACpB,kBAAA,EAAoB,gBAAA;AAAA,IACpB,mBAAA,EAAqB,iBAAA;AAAA,IACrB,SAAA,EAAW,QAAA;AAAA,IACX,sBAAA,EAAwB,mBAAA;AAAA,IACxB,WAAA;AAAA,IACA,UAAA,EAAY,SAAA;AAAA,IACZ,YAAA,EAAc,WAAA;AAAA,IACd,QAAA,EAAU,OAAA;AAAA,IACV,QAAA;AAAA,IACA,IAAA,EAAM,IAAA;AAAA,IACN,SAAS,cAAA,KAAmB,SAAA;AAAA,IAC5B,2BAAA,EAA6B,wBAAA;AAAA,IAC7B,yBAAA,EAA2B;AAAA,GAC7B;AACA,EAAA,MAAM,mBAAA,GACJ,KAAK,IAAA,CAAK,IAAA,KAAS,iBACf,MAAA,CAAO,IAAA,CAAK,MAAM,WAAA,CAAY;AAAA,IAC5B,GAAG,cAAA;AAAA;AAAA,IAEH,iBAAA,EAAmB,gBAAA;AAAA,IACnB,GAAA,EAAK,KAAA;AAAA;AAAA,IAEL,UAAA,EAAY;AAAA,GACb,CAAA,GACD,MAAA,CAAO,IAAA,CAAK,KAAA,CAAM,2BAA2B,cAAc,CAAA;AAEjE,EAAA,IAAI,OAAA;AAEJ,EAAA,IAAI;AACF,IAAA,OAAA,GAAA,CAAW,MAAM,mBAAA,EAAqB,IAAA;AAAA,EACxC,SAAS,CAAA,EAAG;AACV,IAAA,IAAIA,cAAA,CAAQ,CAAC,CAAA,CAAE,OAAA,KAAY,wCAAA,EAA0C;AACnE,MAAA,MAAA,CAAO,IAAA;AAAA,QACL,wFAAwF,IAAA,CAAK,IAAA,CAAK,IAAI,CAAA,YAAA,EAAe,KAAK,IAAI,IAAI,CAAA,CAAA;AAAA,OACpI;AAAA,IACF;AACA,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,CAAA,qBAAA,EAAwB,IAAA,CAAK,IAAA,CAAK,IAAI,CAAA,YAAA,EAAe,KAAK,CAAA,CAAA,EAAI,IAAI,CAAA,EAAA,EAChEA,cAAA,CAAQ,CAAC,CAAA,CAAE,OACb,CAAA;AAAA,KACF;AAAA,EACF;AAEA,EAAA,IAAI,MAAA,EAAQ,UAAA,CAAW,CAAA,EAAG,KAAK,GAAG,CAAA,EAAG;AACnC,IAAA,MAAM,GAAG,IAAI,CAAA,GAAI,MAAA,CAAO,MAAM,GAAG,CAAA;AACjC,IAAA,MAAM,MAAA,CAAO,IAAA,CAAK,KAAA,CAAM,+BAAA,CAAgC;AAAA,MACtD,GAAA,EAAK,KAAA;AAAA,MACL,SAAA,EAAW,IAAA;AAAA,MACX,KAAA;AAAA,MACA,IAAA;AAAA,MACA,UAAA,EAAY;AAAA,KACb,CAAA;AAAA,EAEH,CAAA,MAAA,IAAW,MAAA,IAAU,MAAA,KAAW,KAAA,EAAO;AACrC,IAAA,MAAM,MAAA,CAAO,IAAA,CAAK,KAAA,CAAM,eAAA,CAAgB;AAAA,MACtC,KAAA;AAAA,MACA,IAAA;AAAA,MACA,QAAA,EAAU,MAAA;AAAA,MACV,UAAA,EAAY;AAAA,KACb,CAAA;AAAA,EACH;AAEA,EAAA,IAAI,aAAA,EAAe;AACjB,IAAA,KAAA,MAAW,gBAAgB,aAAA,EAAe;AACxC,MAAA,IAAI;AACF,QAAA,IAAI,UAAU,YAAA,EAAc;AAC1B,UAAA,MAAM,MAAA,CAAO,IAAA,CAAK,KAAA,CAAM,eAAA,CAAgB;AAAA,YACtC,KAAA;AAAA,YACA,IAAA;AAAA,YACA,QAAA,EAAUC,0BAAA,CAAgB,YAAA,CAAa,IAAI,CAAA;AAAA,YAC3C,YAAY,YAAA,CAAa;AAAA,WAC1B,CAAA;AAAA,QACH,CAAA,MAAA,IAAW,UAAU,YAAA,EAAc;AACjC,UAAA,MAAM,MAAA,CAAO,IAAA,CAAK,KAAA,CAAM,+BAAA,CAAgC;AAAA,YACtD,GAAA,EAAK,KAAA;AAAA,YACL,SAAA,EAAWA,0BAAA,CAAgB,YAAA,CAAa,IAAI,CAAA;AAAA,YAC5C,KAAA;AAAA,YACA,IAAA;AAAA,YACA,YAAY,YAAA,CAAa;AAAA,WAC1B,CAAA;AAAA,QACH;AAAA,MACF,SAAS,CAAA,EAAG;AACV,QAAA,MAAM,IAAA,GAAO,wBAAwB,YAAY,CAAA;AACjD,QAAA,MAAA,CAAO,IAAA;AAAA,UACL,CAAA,SAAA,EAAY,aAAa,MAAM,CAAA,YAAA,EAAe,IAAI,CAAA,EAAA,EAChDD,cAAA,CAAQ,CAAC,CAAA,CAAE,OACb,CAAA;AAAA,SACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,EAAA,IAAI,MAAA,EAAQ;AACV,IAAA,IAAI;AACF,MAAA,MAAM,MAAA,CAAO,IAAA,CAAK,KAAA,CAAM,gBAAA,CAAiB;AAAA,QACvC,KAAA;AAAA,QACA,IAAA;AAAA,QACA,OAAO,MAAA,CAAO,GAAA,CAAI,CAAA,CAAA,KAAK,CAAA,CAAE,aAAa;AAAA,OACvC,CAAA;AAAA,IACH,SAAS,CAAA,EAAG;AACV,MAAA,MAAA,CAAO,IAAA,CAAK,CAAA,gBAAA,EAAmB,MAAA,CAAO,IAAA,CAAK,GAAG,CAAC,CAAA,EAAA,EAAKA,cAAA,CAAQ,CAAC,CAAA,CAAE,OAAO,CAAA,CAAE,CAAA;AAAA,IAC1E;AAAA,EACF;AAEA,EAAA,KAAA,MAAW,CAAC,KAAK,KAAK,CAAA,IAAK,OAAO,OAAA,CAAQ,aAAA,IAAiB,EAAE,CAAA,EAAG;AAC9D,IAAA,MAAM,MAAA,CAAO,IAAA,CAAK,OAAA,CAAQ,kBAAA,CAAmB;AAAA,MAC3C,KAAA;AAAA,MACA,IAAA;AAAA,MACA,IAAA,EAAM,GAAA;AAAA,MACN;AAAA,KACD,CAAA;AAAA,EACH;AAEA,EAAA,IAAI,OAAA,EAAS;AACX,IAAA,MAAM,iBAAA,GAAoB,MAAM,MAAA,CAAO,IAAA,CAAK,QAAQ,gBAAA,CAAiB;AAAA,MACnE,KAAA;AAAA,MACA;AAAA,KACD,CAAA;AAED,IAAA,MAAME,uBAAA,CAAO,KAAA;AACb,IAAA,MAAM,YAAYA,uBAAA,CAAO,WAAA;AAAA,MACvB,kBAAkB,IAAA,CAAK,GAAA;AAAA,MACvBA,wBAAO,eAAA,CAAgB;AAAA,KACzB;AACA,IAAA,KAAA,MAAW,CAAC,GAAA,EAAK,KAAK,KAAK,MAAA,CAAO,OAAA,CAAQ,OAAO,CAAA,EAAG;AAClD,MAAA,MAAM,YAAA,GAAeA,uBAAA,CAAO,WAAA,CAAY,KAAK,CAAA;AAC7C,MAAA,MAAM,wBAAwBA,uBAAA,CAAO,eAAA;AAAA,QACnC,YAAA;AAAA,QACA;AAAA,OACF;AACA,MAAA,MAAM,wBAAwBA,uBAAA,CAAO,SAAA;AAAA,QACnC,qBAAA;AAAA,QACAA,wBAAO,eAAA,CAAgB;AAAA,OACzB;AAEA,MAAA,MAAM,MAAA,CAAO,IAAA,CAAK,OAAA,CAAQ,wBAAA,CAAyB;AAAA,QACjD,KAAA;AAAA,QACA,IAAA;AAAA,QACA,WAAA,EAAa,GAAA;AAAA,QACb,eAAA,EAAiB,qBAAA;AAAA,QACjB,MAAA,EAAQ,kBAAkB,IAAA,CAAK;AAAA,OAChC,CAAA;AAAA,IACH;AAAA,EACF;AAEA,EAAA,IAAI,iBAAA,EAAmB;AACrB,IAAA,MAAM,MAAA,CAAO,OAAA;AAAA,MACX,0DAAA;AAAA,MACA;AAAA,QACE,KAAA;AAAA,QACA,IAAA;AAAA,QACA,aAAa,iBAAA,CAAkB,UAAA;AAAA,QAC/B,oBAAoB,iBAAA,CAAkB;AAAA;AACxC,KACF;AAAA,EACF;AAEA,EAAA,IAAI,SAAA,EAAW;AACb,IAAA,MAAM,MAAA,CAAO,IAAA,CAAK,QAAA,CAAS,mBAAA,CAAoB;AAAA,MAC7C,UAAA,EAAY,IAAA;AAAA,MACZ,OAAA,EAAS,KAAA;AAAA,MACT,KAAA;AAAA,MACA;AAAA,KACD,CAAA;AAAA,EACH;AAEA,EAAA,IAAI,cAAA,EAAgB;AAClB,IAAA,MAAM,MAAA,CAAO,IAAA,CAAK,OAAA,CAAQ,6BAAA,CAA8B;AAAA,MACtD,YAAA,EAAc,cAAA;AAAA,MACd,KAAA;AAAA,MACA;AAAA,KACD,CAAA;AAAA,EACH;AAEA,EAAA,OAAO,OAAA;AACT;AAEA,eAAsB,sBAAA,CACpB,SAAA,EACA,QAAA,EACA,aAAA,EACA,UAAA,EACA,aAAA,EACA,oBAAA,EACA,aAAA,EACA,KAAA,EACA,MAAA,EACA,IAAA,EACA,uBAAA,EACA,2BAAA,EAOA,8BACA,YAAA,EAOA,2BAAA,EACA,2BAAA,EACA,8BAAA,EACA,uBAAA,EACA,MAAA,EACA,MAAA,EACA,gBAAA,EACA,aAAA,EACA,cAAA,EACA,mBAAA,EACA,qBAAA,EACA,qBAAA,EACiC;AACjC,EAAA,MAAM,aAAA,GAAgB;AAAA,IACpB,IAAA,EAAM,aAAA,GACF,aAAA,GACA,MAAA,CAAO,kBAAkB,+BAA+B,CAAA;AAAA,IAC5D,KAAA,EAAO,cAAA,GACH,cAAA,GACA,MAAA,CAAO,kBAAkB,gCAAgC;AAAA,GAC/D;AAEA,EAAA,MAAM,aAAA,GACJ,mBAAA,CAAoB,gBAAA,EAAkB,MAAM,CAAA,IAAK,gBAAA;AAEnD,EAAA,IAAI,YAAA;AAEJ,EAAA,IAAI;AACF,IAAA,YAAA,GAAe,MAAMC,oCAAA,CAAgB;AAAA,MACnC,GAAA,EAAKC,2CAAA,CAAuB,aAAA,EAAe,UAAU,CAAA;AAAA,MACrD,SAAA;AAAA,MACA,aAAA;AAAA,MACA,IAAA,EAAM;AAAA,QACJ,QAAA,EAAU,gBAAA;AAAA,QACV;AAAA,OACF;AAAA,MACA,MAAA;AAAA,MACA,aAAA;AAAA,MACA;AAAA,KACD,CAAA;AAAA,EACH,SAAS,KAAA,EAAO;AACd,IAAA,MAAM,OAAQ,KAAA,CAAgC,IAAA;AAC9C,IAAA,MAAM,SAAA,GACH,MAAgC,KAAA,EAGhC,IAAA;AACH,IAAA,MAAM,oBACJ,IAAA,KAAS,YAAA,IACT,SAAS,cAAA,IACT,SAAA,KAAc,gBACd,SAAA,KAAc,cAAA;AAChB,IAAA,IAAI,iBAAA,EAAmB;AACrB,MAAA,MAAA,CAAO,IAAA;AAAA,QACL,CAAA,qBAAA,EAAwB,QAAQ,SAAS,CAAA,yHAAA;AAAA,OAG3C;AACA,MAAA,YAAA,GAAe,MAAM,qBAAA,CAAsB;AAAA,QACzC,GAAA,EAAKA,2CAAA,CAAuB,aAAA,EAAe,UAAU,CAAA;AAAA,QACrD,KAAA;AAAA,QACA,IAAA;AAAA,QACA,MAAA;AAAA,QACA,aAAA;AAAA,QACA,aAAA;AAAA,QACA;AAAA,OACD,CAAA;AAAA,IACH,CAAA,MAAO;AACL,MAAA,MAAM,KAAA;AAAA,IACR;AAAA,EACF;AAEA,EAAA,IAAI,oBAAA,EAAsB;AACxB,IAAA,IAAI;AACF,MAAA,MAAMC,oDAAA,CAA0C;AAAA,QAC9C,KAAA;AAAA,QACA,MAAA;AAAA,QACA,QAAA,EAAU,IAAA;AAAA,QACV,MAAA;AAAA,QACA,aAAA;AAAA,QACA,2BAAA;AAAA,QACA,4BAAA;AAAA,QACA,YAAA;AAAA,QACA,uBAAA;AAAA,QACA,2BAAA;AAAA,QACA,2BAAA;AAAA,QACA,8BAAA;AAAA,QACA,uBAAA;AAAA,QACA,aAAA;AAAA,QACA,mBAAA;AAAA,QACA,qBAAA;AAAA,QACA;AAAA,OACD,CAAA;AAAA,IACH,SAAS,CAAA,EAAG;AACV,MAAA,MAAA,CAAO,IAAA;AAAA,QACL,2CAA2C,IAAI,CAAA,GAAA,EAC7CL,cAAA,CAAQ,CAAC,EAAE,OACb,CAAA;AAAA,OACF;AAAA,IACF;AAAA,EACF;AAEA,EAAA,OAAO,EAAE,UAAA,EAAY,YAAA,CAAa,UAAA,EAAW;AAC/C;AAEA,eAAe,mBAAA,CACb,OAAA,EACA,QAAA,GAAmB,EAAA,EACnB,QAAA,EACkD;AAClD,EAAA,MAAM,OAAO,QAAA,IAAY,OAAA;AACzB,EAAA,MAAM,OAAA,GAAoB,MAAMM,gBAAA,CAAW,OAAA,CAAQ,OAAA,EAAS;AAAA,IAC1D,aAAA,EAAe;AAAA,GAChB,CAAA;AACD,EAAA,MAAM,UAAmD,EAAC;AAC1D,EAAA,KAAA,MAAW,SAAS,OAAA,EAAS;AAC3B,IAAA,MAAM,QAAA,GAAWC,qCAAA;AAAA,MACf,IAAA;AAAA,MACA,WAAW,CAAA,EAAG,QAAQ,IAAI,KAAA,CAAM,IAAI,KAAK,KAAA,CAAM;AAAA,KACjD;AACA,IAAA,MAAM,YAAA,GAAe,WAAW,CAAA,EAAG,QAAQ,IAAI,KAAA,CAAM,IAAI,KAAK,KAAA,CAAM,IAAA;AACpE,IAAA,IAAI,KAAA,CAAM,SAAS,MAAA,EAAQ;AACzB,MAAA;AAAA,IACF;AACA,IAAA,IAAI,KAAA,CAAM,gBAAe,EAAG;AAC1B,MAAA;AAAA,IACF;AACA,IAAA,IAAI,KAAA,CAAM,aAAY,EAAG;AACvB,MAAA,OAAA,CAAQ,IAAA;AAAA,QACN,GAAI,MAAM,mBAAA,CAAoB,QAAA,EAAU,cAAc,IAAI;AAAA,OAC5D;AAAA,IACF,CAAA,MAAA,IAAW,KAAA,CAAM,MAAA,EAAO,EAAG;AACzB,MAAA,OAAA,CAAQ,IAAA,CAAK;AAAA,QACX,QAAA,EAAU,YAAA;AAAA,QACV,OAAA,EAAS,MAAMD,gBAAA,CAAW,QAAA,CAAS,QAAQ;AAAA,OAC5C,CAAA;AAAA,IACH;AAAA,EACF;AACA,EAAA,OAAO,OAAA;AACT;AAEA,MAAM,gCAAA,GAAmC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AAUzC,eAAe,sBAAsB,KAAA,EAQD;AAClC,EAAA,MAAM,EAAE,KAAK,KAAA,EAAO,IAAA,EAAM,QAAQ,aAAA,EAAe,aAAA,EAAe,QAAO,GACrE,KAAA;AAEF,EAAA,MAAM,KAAA,GAAQ,MAAM,mBAAA,CAAoB,GAAG,CAAA;AAC3C,EAAA,MAAA,CAAO,IAAA;AAAA,IACL,CAAA,UAAA,EAAa,MAAM,MAAM,CAAA,+BAAA,EAAkC,KAAK,CAAA,CAAA,EAAI,IAAI,IAAI,aAAa,CAAA;AAAA,GAC3F;AAEA,EAAA,IAAI,KAAA,CAAM,WAAW,CAAA,EAAG;AACtB,IAAA,MAAM,IAAI,KAAA;AAAA,MACR;AAAA,KAEF;AAAA,EACF;AAEA,EAAA,MAAM,aAAA,GAAgB,KAAA,CAAM,MAAA,CAAO,CAAC,GAAA,EAAK,MAAM,GAAA,GAAM,CAAA,CAAE,OAAA,CAAQ,MAAA,EAAQ,CAAC,CAAA;AAExE,EAAA,MAAM,gBAAA,GACJ,KAAK,IAAA,CAAK,aAAA,IAAiB,IAAI,CAAA,CAAE,CAAA,GAAI,MAAM,MAAA,GAAS,IAAA;AACtD,EAAA,MAAM,iBAAA,GAAoB,KAAK,IAAA,GAAO,IAAA;AACtC,EAAA,IAAI,mBAAmB,iBAAA,EAAmB;AACxC,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,CAAA,wCAAA,EAAA,CACO,aAAA,GAAgB,IAAA,GAAO,IAAA,EAAM,OAAA,CAAQ,CAAC,CAAC,CAAA,UAAA,EAAA,CACvC,gBAAA,GAAmB,IAAA,GAAO,IAAA,EAAM,OAAA,CAAQ,CAAC,CAAC,CAAA,iGAAA;AAAA,KAEnD;AAAA,EACF;AAEA,EAAA,IAAI,OAAA;AACJ,EAAA,IAAI,YAAA,GAAe,KAAA;AACnB,EAAA,IAAI;AACF,IAAA,MAAM,EAAE,MAAM,GAAA,EAAI,GAAI,MAAM,MAAA,CAAO,IAAA,CAAK,IAAI,MAAA,CAAO;AAAA,MACjD,KAAA;AAAA,MACA,IAAA;AAAA,MACA,GAAA,EAAK,SAAS,aAAa,CAAA;AAAA,KAC5B,CAAA;AACD,IAAA,OAAA,GAAU,IAAI,MAAA,CAAO,GAAA;AAAA,EACvB,SAAS,QAAA,EAAmB;AAC1B,IAAA,MAAM,SAAU,QAAA,CAAiC,MAAA;AACjD,IAAA,IAAI,MAAA,KAAW,GAAA,IAAO,MAAA,KAAW,GAAA,EAAK;AACpC,MAAA,MAAM,QAAA;AAAA,IACR;AACA,IAAA,IAAI,WAAW,GAAA,EAAK;AAClB,MAAA,MAAM,EAAE,IAAA,EAAM,QAAA,EAAS,GAAI,MAAM,MAAA,CAAO,IAAA,CAAK,KAAA,CAAM,GAAA,CAAI,EAAE,KAAA,EAAO,IAAA,EAAM,CAAA;AACtE,MAAA,IAAI,QAAA,CAAS,OAAO,CAAA,EAAG;AACrB,QAAA,MAAM,IAAI,KAAA;AAAA,UACR,CAAA,QAAA,EAAW,aAAa,CAAA,eAAA,EAAkB,KAAK,IAAI,IAAI,CAAA,mDAAA,EACD,SAAS,cAAc,CAAA,EAAA;AAAA,SAC/E;AAAA,MACF;AAAA,IACF;AACA,IAAA,MAAA,CAAO,IAAA;AAAA,MACL,8BAA8B,KAAK,CAAA,CAAA,EAAI,IAAI,CAAA,CAAA,EAAI,aAAa,YAC/C,MAAM,CAAA,0BAAA;AAAA,KACrB;AACA,IAAA,MAAM,EAAE,MAAM,IAAA,EAAK,GAAI,MAAM,MAAA,CAAO,IAAA,CAAK,MAAM,0BAAA,CAA2B;AAAA,MACxE,KAAA;AAAA,MACA,IAAA;AAAA,MACA,IAAA,EAAM,UAAA;AAAA,MACN,OAAA,EAAS,uBAAA;AAAA,MACT,OAAA,EAAS,EAAA;AAAA,MACT,MAAA,EAAQ;AAAA,KACT,CAAA;AACD,IAAA,OAAA,GAAU,KAAK,MAAA,CAAO,GAAA;AACtB,IAAA,YAAA,GAAe,IAAA;AAAA,EACjB;AAEA,EAAA,MAAM,SAAA,GAAY,KAAA,CAAM,GAAA,CAAI,CAAA,IAAA,MAAS;AAAA,IACnC,MAAM,IAAA,CAAK,QAAA;AAAA,IACX,QAAA,EAAU,IAAA,CAAK,OAAA,CAAQ,QAAA,CAAS,QAAQ;AAAA,GAC1C,CAAE,CAAA;AAEF,EAAA,MAAM,WAAA,GAGF;AAAA,IACF;AAAA,GACF;AACA,EAAA,IAAI,YAAA,EAAc;AAChB,IAAA,WAAA,CAAY,SAAA,GAAY,CAAC,EAAE,IAAA,EAAM,YAAY,CAAA;AAAA,EAC/C;AAEA,EAAA,MAAM,WAAA,GAAc;AAAA,IAClB,MAAA,EAAQ;AAAA,MACN,uBAAA,EAAyB,CAAA,EAAG,KAAK,CAAA,CAAA,EAAI,IAAI,CAAA,CAAA;AAAA,MACzC,UAAA,EAAY;AAAA,KACd;AAAA,IACA,OAAA,EAAS,EAAE,QAAA,EAAU,aAAA,EAAc;AAAA,IACnC,WAAA;AAAA,IACA,eAAA,EAAiB;AAAA,GACnB;AAEA,EAAA,IAAI,MAAA;AACJ,EAAA,IAAI;AACF,IAAA,MAAA,GAAS,MAAM,MAAA,CAAO,OAAA,CAAQ,gCAAA,EAAkC;AAAA,MAC9D,KAAA,EAAO;AAAA,KACR,CAAA;AAAA,EACH,SAAS,WAAA,EAAsB;AAC7B,IAAA,MAAM,GAAA,GAAM,MAAA,CAAQ,WAAA,CAAsB,OAAA,IAAW,EAAE,CAAA;AACvD,IAAA,IAAI,CAAC,GAAA,CAAI,QAAA,CAAS,iBAAiB,CAAA,EAAG;AACpC,MAAA,MAAM,WAAA;AAAA,IACR;AACA,IAAA,MAAA,CAAO,IAAA;AAAA,MACL,CAAA,YAAA,EAAe,KAAK,CAAA,CAAA,EAAI,IAAI,IAAI,aAAa,CAAA,iDAAA;AAAA,KAC/C;AACA,IAAA,MAAM,EAAE,MAAM,QAAA,EAAS,GAAI,MAAM,MAAA,CAAO,IAAA,CAAK,IAAI,MAAA,CAAO;AAAA,MACtD,KAAA;AAAA,MACA,IAAA;AAAA,MACA,GAAA,EAAK,SAAS,aAAa,CAAA;AAAA,KAC5B,CAAA;AACD,IAAA,WAAA,CAAY,eAAA,GAAkB,SAAS,MAAA,CAAO,GAAA;AAC9C,IAAA,MAAA,GAAS,MAAM,MAAA,CAAO,OAAA,CAAQ,gCAAA,EAAkC;AAAA,MAC9D,KAAA,EAAO;AAAA,KACR,CAAA;AAAA,EACH;AAEA,EAAA,MAAM,UAAA,GAAa,MAAA,CAAO,oBAAA,CAAqB,MAAA,CAAO,GAAA;AACtD,EAAA,MAAA,CAAO,IAAA;AAAA,IACL,CAAA,OAAA,EAAU,KAAA,CAAM,MAAM,CAAA,UAAA,EAAa,KAAK,IAAI,IAAI,CAAA,CAAA,EAAI,aAAa,CAAA,yBAAA,EAA4B,UAAU,CAAA,CAAA;AAAA,GACzG;AACA,EAAA,OAAO,EAAE,UAAA,EAAW;AACtB;AAEA,SAAS,wBACP,YAAA,EACA;AACA,EAAA,IAAI,cAAc,YAAA,EAAc;AAC9B,IAAA,OAAO,YAAA,CAAa,QAAA;AAAA,EACtB;AACA,EAAA,IAAI,UAAU,YAAA,EAAc;AAC1B,IAAA,OAAO,YAAA,CAAa,IAAA;AAAA,EACtB;AACA,EAAA,OAAO,YAAA,CAAa,IAAA;AACtB;AAEA,eAAe,kBAAA,CAAmB,QAAiB,MAAA,EAAgB;AACjE,EAAA,MAAM,CAAC,GAAA,EAAK,SAAS,CAAA,GAAI,MAAA,CAAO,MAAM,GAAG,CAAA;AACzC,EAAA,IAAI;AAIF,IAAA,MAAM,MAAA,CAAO,IAAA,CAAK,KAAA,CAAM,SAAA,CAAU;AAAA,MAChC,GAAA;AAAA,MACA;AAAA,KACD,CAAA;AAAA,EACH,SAAS,CAAA,EAAG;AACV,IAAA,IAAI,CAAA,CAAE,QAAA,CAAS,IAAA,CAAK,OAAA,KAAY,WAAA,EAAa;AAC3C,MAAA,MAAM,OAAA,GAAU,CAAA;AAAA,QAAA,EACZ,GAAG,aAAa,SAAS,CAAA,6BAAA,CAAA;AAC7B,MAAA,MAAM,IAAIE,qBAAc,OAAO,CAAA;AAAA,IACjC;AAAA,EACF;AACF;AAEO,SAAS,mBAAA,CACd,kBACA,MAAA,EACoB;AACpB,EAAA,OAAO,gBAAA,GACH,gBAAA,GACA,MAAA,CAAO,iBAAA,CAAkB,iCAAiC,CAAA;AAChE;;;;;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backstage/plugin-scaffolder-backend-module-github",
3
- "version": "0.9.10-next.0",
3
+ "version": "0.9.10",
4
4
  "description": "The github module for @backstage/plugin-scaffolder-backend",
5
5
  "backstage": {
6
6
  "role": "backend-plugin-module",
@@ -50,14 +50,14 @@
50
50
  "test": "backstage-cli package test"
51
51
  },
52
52
  "dependencies": {
53
- "@backstage/backend-plugin-api": "1.9.2-next.0",
54
- "@backstage/catalog-model": "1.9.0",
55
- "@backstage/config": "1.3.8",
56
- "@backstage/errors": "1.3.1",
57
- "@backstage/integration": "2.0.3-next.0",
58
- "@backstage/plugin-catalog-node": "2.2.2-next.0",
59
- "@backstage/plugin-scaffolder-node": "0.13.4-next.0",
60
- "@backstage/types": "1.2.2",
53
+ "@backstage/backend-plugin-api": "^1.9.2",
54
+ "@backstage/catalog-model": "^1.9.0",
55
+ "@backstage/config": "^1.3.8",
56
+ "@backstage/errors": "^1.3.1",
57
+ "@backstage/integration": "^2.0.3",
58
+ "@backstage/plugin-catalog-node": "^2.2.2",
59
+ "@backstage/plugin-scaffolder-node": "^0.13.4",
60
+ "@backstage/types": "^1.2.2",
61
61
  "@octokit/core": "^5.0.0",
62
62
  "@octokit/plugin-retry": "^6.0.0",
63
63
  "@octokit/webhooks": "^10.9.2",
@@ -68,9 +68,9 @@
68
68
  "zod": "^3.25.76 || ^4.0.0"
69
69
  },
70
70
  "devDependencies": {
71
- "@backstage/backend-test-utils": "1.11.4-next.0",
72
- "@backstage/cli": "0.36.3-next.0",
73
- "@backstage/plugin-scaffolder-node-test-utils": "0.3.12-next.0",
71
+ "@backstage/backend-test-utils": "^1.11.4",
72
+ "@backstage/cli": "^0.36.3",
73
+ "@backstage/plugin-scaffolder-node-test-utils": "^0.3.12",
74
74
  "@types/libsodium-wrappers": "^0.8.0",
75
75
  "fs-extra": "^11.2.0",
76
76
  "jsonschema": "^1.2.6"