@red-hat-developer-hub/backstage-plugin-bulk-import-backend 6.2.0 → 6.4.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.
Files changed (56) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/README.md +28 -0
  3. package/config.d.ts +9 -1
  4. package/dist/catalog/catalogHttpClient.cjs.js +3 -0
  5. package/dist/catalog/catalogHttpClient.cjs.js.map +1 -1
  6. package/dist/catalog/catalogInfoGenerator.cjs.js +1 -0
  7. package/dist/catalog/catalogInfoGenerator.cjs.js.map +1 -1
  8. package/dist/database/migration.cjs.js +20 -0
  9. package/dist/database/migration.cjs.js.map +1 -0
  10. package/dist/database/repositoryDao.cjs.js +117 -0
  11. package/dist/database/repositoryDao.cjs.js.map +1 -0
  12. package/dist/generated/openapidocument.cjs.js +366 -38
  13. package/dist/generated/openapidocument.cjs.js.map +1 -1
  14. package/dist/github/githubApiService.cjs.js +222 -95
  15. package/dist/github/githubApiService.cjs.js.map +1 -1
  16. package/dist/github/utils/orgUtils.cjs.js +2 -0
  17. package/dist/github/utils/orgUtils.cjs.js.map +1 -1
  18. package/dist/github/utils/prUtils.cjs.js +3 -0
  19. package/dist/github/utils/prUtils.cjs.js.map +1 -1
  20. package/dist/github/utils/repoUtils.cjs.js +1 -38
  21. package/dist/github/utils/repoUtils.cjs.js.map +1 -1
  22. package/dist/github/utils/utils.cjs.js +29 -18
  23. package/dist/github/utils/utils.cjs.js.map +1 -1
  24. package/dist/gitlab/GitlabAppManager.cjs.js +54 -0
  25. package/dist/gitlab/GitlabAppManager.cjs.js.map +1 -0
  26. package/dist/gitlab/gitlabApiService.cjs.js +660 -0
  27. package/dist/gitlab/gitlabApiService.cjs.js.map +1 -0
  28. package/dist/gitlab/utils/glUtils.cjs.js +15 -0
  29. package/dist/gitlab/utils/glUtils.cjs.js.map +1 -0
  30. package/dist/gitlab/utils/orgUtils.cjs.js +72 -0
  31. package/dist/gitlab/utils/orgUtils.cjs.js.map +1 -0
  32. package/dist/gitlab/utils/prUtils.cjs.js +73 -0
  33. package/dist/gitlab/utils/prUtils.cjs.js.map +1 -0
  34. package/dist/gitlab/utils/repoUtils.cjs.js +200 -0
  35. package/dist/gitlab/utils/repoUtils.cjs.js.map +1 -0
  36. package/dist/gitlab/utils/utils.cjs.js +131 -0
  37. package/dist/gitlab/utils/utils.cjs.js.map +1 -0
  38. package/dist/helpers/utils.cjs.js +58 -0
  39. package/dist/helpers/utils.cjs.js.map +1 -1
  40. package/dist/index.d.ts +2 -1
  41. package/dist/plugin.cjs.js +6 -3
  42. package/dist/plugin.cjs.js.map +1 -1
  43. package/dist/service/handlers/import/bulkImports.cjs.js +216 -34
  44. package/dist/service/handlers/import/bulkImports.cjs.js.map +1 -1
  45. package/dist/service/handlers/import/execute-template.cjs.js +264 -0
  46. package/dist/service/handlers/import/execute-template.cjs.js.map +1 -0
  47. package/dist/service/handlers/import/importStatus.cjs.js +5 -8
  48. package/dist/service/handlers/import/importStatus.cjs.js.map +1 -1
  49. package/dist/service/handlers/organization/organizations.cjs.js +2 -2
  50. package/dist/service/handlers/organization/organizations.cjs.js.map +1 -1
  51. package/dist/service/handlers/repository/repositories.cjs.js +5 -2
  52. package/dist/service/handlers/repository/repositories.cjs.js.map +1 -1
  53. package/dist/service/router.cjs.js +199 -34
  54. package/dist/service/router.cjs.js.map +1 -1
  55. package/migrations/20250808122501_migrations.js +53 -0
  56. package/package.json +17 -11
@@ -1 +1 @@
1
- {"version":3,"file":"orgUtils.cjs.js","sources":["../../../src/github/utils/orgUtils.ts"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\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 type { LoggerService } from '@backstage/backend-plugin-api';\nimport type {\n GithubCredentials,\n GithubIntegrationConfig,\n} from '@backstage/integration';\n\nimport { Octokit } from '@octokit/rest';\n\nimport { logErrorIfNeeded, paginateArray } from '../../helpers';\nimport {\n DefaultPageNumber,\n DefaultPageSize,\n} from '../../service/handlers/handlers';\nimport type { CustomGithubCredentialsProvider } from '../GithubAppManager';\nimport type { GithubFetchError, GithubOrganization } from '../types';\nimport { computeTotalCountFromGitHubToken, handleError } from './utils';\n\nexport async function getAllAppOrgs(\n githubCredentialsProvider: CustomGithubCredentialsProvider,\n ghConfig: GithubIntegrationConfig,\n credentialAccountLogin?: string,\n) {\n const result = new Map<string, GithubOrganization>();\n const resp = await githubCredentialsProvider.getAllAppInstallations(ghConfig);\n for (const installation of resp ?? []) {\n if (\n !(\n installation.account &&\n installation.target_type?.toLowerCase() === 'organization'\n )\n ) {\n continue;\n }\n const acc = installation.account!;\n if (credentialAccountLogin !== acc.login) {\n continue;\n }\n result.set(acc.url, {\n id: acc.id,\n description: acc.description ?? undefined,\n name: acc.login,\n url: acc.html_url,\n html_url: acc.html_url,\n repos_url: acc.repos_url,\n events_url: acc.events_url,\n });\n }\n return result;\n}\n\nexport async function addGithubAppOrgs(\n deps: {\n logger: LoggerService;\n githubCredentialsProvider: CustomGithubCredentialsProvider;\n },\n octokit: Octokit,\n ghConfig: GithubIntegrationConfig,\n params: {\n credentialAccountLogin: string | undefined;\n search: string | undefined;\n orgs: Map<string, GithubOrganization>;\n errors: Map<number, GithubFetchError>;\n },\n): Promise<{ totalCount?: number }> {\n const credentialAccountLogin = params.credentialAccountLogin;\n const search = params.search;\n const orgs = params.orgs;\n const errors = params.errors;\n let totalCount = 0;\n try {\n const resp = await getAllAppOrgs(\n deps.githubCredentialsProvider,\n ghConfig,\n credentialAccountLogin,\n );\n for (const [orgUrl, ghOrg] of resp) {\n if (search && !ghOrg.name.toLowerCase().includes(search.toLowerCase())) {\n continue;\n }\n const orgData = await octokit.request(\n orgUrl.replace('/users/', '/orgs/'),\n );\n orgs.set(ghOrg.name, {\n ...ghOrg,\n public_repos: orgData?.data?.public_repos,\n total_private_repos: orgData?.data?.total_private_repos,\n owned_private_repos: orgData?.data?.owned_private_repos,\n });\n totalCount++;\n }\n } catch (err: any) {\n logErrorIfNeeded(\n deps.logger,\n `Fetching organizations with access token for github app`,\n err,\n );\n errors.set(-1, err.message);\n }\n return { totalCount };\n}\n\nexport async function addGithubTokenOrgs(\n deps: {\n logger: LoggerService;\n },\n octokit: Octokit,\n credential: GithubCredentials,\n params: {\n search: string | undefined;\n orgs: Map<string, GithubOrganization>;\n errors: Map<number, GithubFetchError>;\n pageNumber: number;\n pageSize: number;\n },\n): Promise<{ totalCount?: number }> {\n const search = params.search;\n const orgs = params.orgs;\n const errors = params.errors;\n const pageNumber = params.pageNumber ?? DefaultPageNumber;\n const pageSize = params.pageSize ?? DefaultPageSize;\n\n let totalCount: number | undefined;\n try {\n let matchingOrgs;\n if (search) {\n // Initial idea was to leverage octokit.rest.search.users({q: `${search} type:org`}),\n // but this searches across all of GitHub, not only the orgs accessible by the current creds.\n // That's why we are searching in everything, hoping the list of organizations to not be that big in size\n const resp = await octokit.paginate(\n octokit.rest.orgs.listForAuthenticatedUser,\n {\n sort: 'full_name',\n direction: 'asc',\n },\n );\n const allMatchingOrgs =\n resp?.filter(org =>\n org.login.toLowerCase().includes(search.toLowerCase()),\n ) ?? [];\n const matchingOrgsPage = paginateArray(\n allMatchingOrgs,\n pageNumber,\n pageSize,\n );\n matchingOrgs = matchingOrgsPage.result;\n totalCount = matchingOrgsPage.totalCount;\n } else {\n /**\n * The listForAuthenticatedUser endpoint will grab all the repositories the github token has explicit access to.\n * These would include repositories they own, repositories where they are a collaborator,\n * and repositories that they can access through an organization membership.\n */\n const resp = await octokit.rest.orgs.listForAuthenticatedUser({\n page: pageNumber,\n per_page: pageSize,\n sort: 'full_name',\n direction: 'asc',\n });\n matchingOrgs = resp?.data ?? [];\n\n totalCount = await computeTotalCountFromGitHubToken(\n deps,\n async (lastPageNumber: number) =>\n octokit.orgs\n .listForAuthenticatedUser({\n page: lastPageNumber,\n per_page: 100,\n })\n .then(lastPageResp => lastPageResp.data.length),\n 'orgs.listForAuthenticatedUser',\n resp?.data?.length,\n resp?.headers?.link,\n );\n }\n\n for (const org of matchingOrgs) {\n const orgData = await octokit.request(org.url);\n const ghOrg: GithubOrganization = {\n id: org.id,\n name: org.login,\n description: org.description ?? undefined,\n url: orgData?.data?.html_url ?? org.url,\n repos_url: org.repos_url,\n hooks_url: org.hooks_url,\n issues_url: org.issues_url,\n members_url: org.members_url,\n public_members_url: org.public_members_url,\n avatar_url: org.avatar_url,\n public_repos: orgData?.data?.public_repos,\n total_private_repos: orgData?.data?.total_private_repos,\n owned_private_repos: orgData?.data?.owned_private_repos,\n };\n orgs.set(org.login, ghOrg);\n }\n } catch (err) {\n handleError(\n { logger: deps.logger },\n 'Fetching orgs with token from token',\n credential,\n errors,\n err,\n );\n }\n return { totalCount };\n}\n"],"names":["logErrorIfNeeded","DefaultPageNumber","DefaultPageSize","paginateArray","computeTotalCountFromGitHubToken","handleError"],"mappings":"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"}
1
+ {"version":3,"file":"orgUtils.cjs.js","sources":["../../../src/github/utils/orgUtils.ts"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\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 type { LoggerService } from '@backstage/backend-plugin-api';\nimport type {\n GithubCredentials,\n GithubIntegrationConfig,\n} from '@backstage/integration';\n\nimport { Octokit } from '@octokit/rest';\n\nimport { logErrorIfNeeded, paginateArray } from '../../helpers';\nimport {\n DefaultPageNumber,\n DefaultPageSize,\n} from '../../service/handlers/handlers';\nimport type { CustomGithubCredentialsProvider } from '../GithubAppManager';\nimport type { GithubFetchError, GithubOrganization } from '../types';\nimport { computeTotalCountFromGitHubToken, handleError } from './utils';\n\nexport async function getAllAppOrgs(\n githubCredentialsProvider: CustomGithubCredentialsProvider,\n ghConfig: GithubIntegrationConfig,\n credentialAccountLogin?: string,\n) {\n const result = new Map<string, GithubOrganization>();\n const resp = await githubCredentialsProvider.getAllAppInstallations(ghConfig);\n for (const installation of resp ?? []) {\n if (\n !(\n installation.account &&\n installation.target_type?.toLowerCase() === 'organization'\n )\n ) {\n continue;\n }\n const acc = installation.account!;\n if (credentialAccountLogin !== acc.login) {\n continue;\n }\n result.set(acc.url, {\n id: acc.id,\n description: acc.description ?? undefined,\n name: acc.login,\n url: acc.html_url,\n html_url: acc.html_url,\n repos_url: acc.repos_url,\n events_url: acc.events_url,\n });\n }\n return result;\n}\n\nexport async function addGithubAppOrgs(\n deps: {\n logger: LoggerService;\n githubCredentialsProvider: CustomGithubCredentialsProvider;\n },\n octokit: Octokit,\n ghConfig: GithubIntegrationConfig,\n params: {\n credentialAccountLogin: string | undefined;\n search: string | undefined;\n orgs: Map<string, GithubOrganization>;\n errors: Map<number, GithubFetchError>;\n },\n): Promise<{ totalCount?: number }> {\n const credentialAccountLogin = params.credentialAccountLogin;\n const search = params.search;\n const orgs = params.orgs;\n const errors = params.errors;\n let totalCount = 0;\n try {\n const resp = await getAllAppOrgs(\n deps.githubCredentialsProvider,\n ghConfig,\n credentialAccountLogin,\n );\n for (const [orgUrl, ghOrg] of resp) {\n if (search && !ghOrg.name.toLowerCase().includes(search.toLowerCase())) {\n continue;\n }\n const orgData = await octokit.request(\n orgUrl.replace('/users/', '/orgs/'),\n );\n orgs.set(ghOrg.name, {\n ...ghOrg,\n public_repos: orgData?.data?.public_repos,\n total_private_repos: orgData?.data?.total_private_repos,\n owned_private_repos: orgData?.data?.owned_private_repos,\n });\n totalCount++;\n }\n } catch (err: any) {\n logErrorIfNeeded(\n deps.logger,\n `Fetching organizations with access token for github app`,\n err,\n );\n errors.set(-1, err.message);\n }\n return { totalCount };\n}\n\nexport async function addGithubTokenOrgs(\n deps: {\n logger: LoggerService;\n },\n octokit: Octokit,\n credential: GithubCredentials,\n params: {\n search: string | undefined;\n orgs: Map<string, GithubOrganization>;\n errors: Map<number, GithubFetchError>;\n pageNumber: number;\n pageSize: number;\n },\n): Promise<{ totalCount?: number }> {\n const search = params.search;\n const orgs = params.orgs;\n const errors = params.errors;\n const pageNumber = params.pageNumber ?? DefaultPageNumber;\n const pageSize = params.pageSize ?? DefaultPageSize;\n\n let totalCount: number | undefined;\n try {\n let matchingOrgs;\n if (search) {\n // Initial idea was to leverage octokit.rest.search.users({q: `${search} type:org`}),\n // but this searches across all of GitHub, not only the orgs accessible by the current creds.\n // That's why we are searching in everything, hoping the list of organizations to not be that big in size\n const resp = await octokit.paginate(\n octokit.rest.orgs.listForAuthenticatedUser,\n {\n sort: 'full_name',\n direction: 'asc',\n },\n );\n const allMatchingOrgs =\n resp?.filter(org =>\n org.login.toLowerCase().includes(search.toLowerCase()),\n ) ?? [];\n const matchingOrgsPage = paginateArray(\n allMatchingOrgs,\n pageNumber,\n pageSize,\n );\n matchingOrgs = matchingOrgsPage.result;\n totalCount = matchingOrgsPage.totalCount;\n } else {\n /**\n * The listForAuthenticatedUser endpoint will grab all the repositories the github token has explicit access to.\n * These would include repositories they own, repositories where they are a collaborator,\n * and repositories that they can access through an organization membership.\n */\n const resp = await octokit.rest.orgs.listForAuthenticatedUser({\n page: pageNumber,\n per_page: pageSize,\n sort: 'full_name',\n direction: 'asc',\n });\n matchingOrgs = resp?.data ?? [];\n\n totalCount = await computeTotalCountFromGitHubToken(\n deps,\n async (lastPageNumber: number) =>\n octokit.orgs\n .listForAuthenticatedUser({\n page: lastPageNumber,\n per_page: 100,\n })\n .then(lastPageResp => lastPageResp.data.length),\n 'orgs.listForAuthenticatedUser',\n resp?.data?.length,\n resp?.headers?.link,\n );\n }\n\n for (const org of matchingOrgs) {\n const orgData = await octokit.request(org.url);\n const ghOrg: GithubOrganization = {\n id: org.id,\n name: org.login,\n description: org.description ?? undefined,\n url: orgData?.data?.html_url ?? org.url,\n repos_url: org.repos_url,\n hooks_url: org.hooks_url,\n issues_url: org.issues_url,\n members_url: org.members_url,\n public_members_url: org.public_members_url,\n avatar_url: org.avatar_url,\n public_repos: orgData?.data?.public_repos,\n total_private_repos: orgData?.data?.total_private_repos,\n owned_private_repos: orgData?.data?.owned_private_repos,\n };\n orgs.set(org.login, ghOrg);\n }\n } catch (err) {\n handleError(\n { logger: deps.logger },\n 'Fetching orgs with token from token',\n credential,\n errors,\n err,\n );\n }\n return { totalCount };\n}\n"],"names":["logErrorIfNeeded","DefaultPageNumber","DefaultPageSize","paginateArray","computeTotalCountFromGitHubToken","handleError"],"mappings":"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"}
@@ -6,6 +6,8 @@ require('@backstage/plugin-permission-common');
6
6
  require('@red-hat-developer-hub/backstage-plugin-bulk-import-common');
7
7
  require('just-kebab-case');
8
8
  var loggingUtils = require('../../helpers/loggingUtils.cjs.js');
9
+ require('@backstage/catalog-model');
10
+ require('git-url-parse');
9
11
 
10
12
  async function findOpenPRForBranch(logger, config, octo, owner, repo, branchName, withCatalogInfoContent = false) {
11
13
  try {
@@ -83,4 +85,5 @@ async function closePRWithComment(octo, owner, repo, prNum, comment) {
83
85
 
84
86
  exports.closePRWithComment = closePRWithComment;
85
87
  exports.findOpenPRForBranch = findOpenPRForBranch;
88
+ exports.getCatalogInfoContentFromPR = getCatalogInfoContentFromPR;
86
89
  //# sourceMappingURL=prUtils.cjs.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"prUtils.cjs.js","sources":["../../../src/github/utils/prUtils.ts"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\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 type { LoggerService } from '@backstage/backend-plugin-api';\nimport type { Config } from '@backstage/config';\n\nimport { Octokit } from '@octokit/rest';\n\nimport { getCatalogFilename } from '../../catalog/catalogUtils';\nimport { logErrorIfNeeded } from '../../helpers';\n\nexport async function findOpenPRForBranch(\n logger: LoggerService,\n config: Config,\n octo: Octokit,\n owner: string,\n repo: string,\n branchName: string,\n withCatalogInfoContent: boolean = false,\n): Promise<{\n prNum?: number;\n prUrl?: string;\n prTitle?: string;\n prBody?: string;\n prCatalogInfoContent?: string;\n lastUpdate?: string;\n}> {\n try {\n const response = await octo.rest.pulls.list({\n owner: owner,\n repo: repo,\n state: 'open',\n });\n for (const pull of response.data) {\n if (pull.head.ref === branchName) {\n return {\n prNum: pull.number,\n prUrl: pull.html_url,\n prTitle: pull.title,\n prBody: pull.body ?? undefined,\n prCatalogInfoContent: withCatalogInfoContent\n ? await getCatalogInfoContentFromPR(\n logger,\n config,\n octo,\n owner,\n repo,\n pull.number,\n pull.head.sha,\n )\n : undefined,\n lastUpdate: pull.updated_at,\n };\n }\n }\n } catch (error) {\n logErrorIfNeeded(logger, 'Error fetching pull requests', error);\n }\n return {};\n}\n\nasync function getCatalogInfoContentFromPR(\n logger: LoggerService,\n config: Config,\n octo: Octokit,\n owner: string,\n repo: string,\n prNumber: number,\n prHeadSha: string,\n): Promise<string | undefined> {\n try {\n const filePath = getCatalogFilename(config);\n const fileContentResponse = await octo.rest.repos.getContent({\n owner,\n repo,\n path: filePath,\n ref: prHeadSha,\n });\n if (!fileContentResponse.data) {\n return undefined;\n }\n if (!('content' in fileContentResponse.data)) {\n return undefined;\n }\n return Buffer.from(fileContentResponse.data.content, 'base64').toString(\n 'utf-8',\n );\n } catch (error: any) {\n logErrorIfNeeded(\n logger,\n `Error fetching catalog-info content from PR ${prNumber}`,\n error,\n );\n return undefined;\n }\n}\n\nexport async function closePRWithComment(\n octo: Octokit,\n owner: string,\n repo: string,\n prNum: number,\n comment: string,\n) {\n await octo.rest.issues.createComment({\n owner,\n repo,\n issue_number: prNum,\n body: comment,\n });\n await octo.rest.pulls.update({\n owner,\n repo,\n pull_number: prNum,\n state: 'closed',\n });\n}\n"],"names":["logErrorIfNeeded","getCatalogFilename"],"mappings":";;;;;;;;;AAwBsB,eAAA,mBAAA,CACpB,QACA,MACA,EAAA,IAAA,EACA,OACA,IACA,EAAA,UAAA,EACA,yBAAkC,KAQjC,EAAA;AACD,EAAI,IAAA;AACF,IAAA,MAAM,QAAW,GAAA,MAAM,IAAK,CAAA,IAAA,CAAK,MAAM,IAAK,CAAA;AAAA,MAC1C,KAAA;AAAA,MACA,IAAA;AAAA,MACA,KAAO,EAAA;AAAA,KACR,CAAA;AACD,IAAW,KAAA,MAAA,IAAA,IAAQ,SAAS,IAAM,EAAA;AAChC,MAAI,IAAA,IAAA,CAAK,IAAK,CAAA,GAAA,KAAQ,UAAY,EAAA;AAChC,QAAO,OAAA;AAAA,UACL,OAAO,IAAK,CAAA,MAAA;AAAA,UACZ,OAAO,IAAK,CAAA,QAAA;AAAA,UACZ,SAAS,IAAK,CAAA,KAAA;AAAA,UACd,MAAA,EAAQ,KAAK,IAAQ,IAAA,KAAA,CAAA;AAAA,UACrB,oBAAA,EAAsB,yBAClB,MAAM,2BAAA;AAAA,YACJ,MAAA;AAAA,YACA,MAAA;AAAA,YACA,IAAA;AAAA,YACA,KAAA;AAAA,YACA,IAAA;AAAA,YACA,IAAK,CAAA,MAAA;AAAA,YACL,KAAK,IAAK,CAAA;AAAA,WAEZ,GAAA,KAAA,CAAA;AAAA,UACJ,YAAY,IAAK,CAAA;AAAA,SACnB;AAAA;AACF;AACF,WACO,KAAO,EAAA;AACd,IAAiBA,6BAAA,CAAA,MAAA,EAAQ,gCAAgC,KAAK,CAAA;AAAA;AAEhE,EAAA,OAAO,EAAC;AACV;AAEA,eAAe,4BACb,MACA,EAAA,MAAA,EACA,MACA,KACA,EAAA,IAAA,EACA,UACA,SAC6B,EAAA;AAC7B,EAAI,IAAA;AACF,IAAM,MAAA,QAAA,GAAWC,gCAAmB,MAAM,CAAA;AAC1C,IAAA,MAAM,mBAAsB,GAAA,MAAM,IAAK,CAAA,IAAA,CAAK,MAAM,UAAW,CAAA;AAAA,MAC3D,KAAA;AAAA,MACA,IAAA;AAAA,MACA,IAAM,EAAA,QAAA;AAAA,MACN,GAAK,EAAA;AAAA,KACN,CAAA;AACD,IAAI,IAAA,CAAC,oBAAoB,IAAM,EAAA;AAC7B,MAAO,OAAA,KAAA,CAAA;AAAA;AAET,IAAI,IAAA,EAAE,SAAa,IAAA,mBAAA,CAAoB,IAAO,CAAA,EAAA;AAC5C,MAAO,OAAA,KAAA,CAAA;AAAA;AAET,IAAA,OAAO,OAAO,IAAK,CAAA,mBAAA,CAAoB,IAAK,CAAA,OAAA,EAAS,QAAQ,CAAE,CAAA,QAAA;AAAA,MAC7D;AAAA,KACF;AAAA,WACO,KAAY,EAAA;AACnB,IAAAD,6BAAA;AAAA,MACE,MAAA;AAAA,MACA,+CAA+C,QAAQ,CAAA,CAAA;AAAA,MACvD;AAAA,KACF;AACA,IAAO,OAAA,SAAA;AAAA;AAEX;AAEA,eAAsB,kBACpB,CAAA,IAAA,EACA,KACA,EAAA,IAAA,EACA,OACA,OACA,EAAA;AACA,EAAM,MAAA,IAAA,CAAK,IAAK,CAAA,MAAA,CAAO,aAAc,CAAA;AAAA,IACnC,KAAA;AAAA,IACA,IAAA;AAAA,IACA,YAAc,EAAA,KAAA;AAAA,IACd,IAAM,EAAA;AAAA,GACP,CAAA;AACD,EAAM,MAAA,IAAA,CAAK,IAAK,CAAA,KAAA,CAAM,MAAO,CAAA;AAAA,IAC3B,KAAA;AAAA,IACA,IAAA;AAAA,IACA,WAAa,EAAA,KAAA;AAAA,IACb,KAAO,EAAA;AAAA,GACR,CAAA;AACH;;;;;"}
1
+ {"version":3,"file":"prUtils.cjs.js","sources":["../../../src/github/utils/prUtils.ts"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\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 type { LoggerService } from '@backstage/backend-plugin-api';\nimport type { Config } from '@backstage/config';\n\nimport { Octokit } from '@octokit/rest';\n\nimport { getCatalogFilename } from '../../catalog/catalogUtils';\nimport { logErrorIfNeeded } from '../../helpers';\n\nexport async function findOpenPRForBranch(\n logger: LoggerService,\n config: Config,\n octo: Octokit,\n owner: string,\n repo: string,\n branchName: string,\n withCatalogInfoContent: boolean = false,\n): Promise<{\n prNum?: number;\n prUrl?: string;\n prTitle?: string;\n prBody?: string;\n prCatalogInfoContent?: string;\n lastUpdate?: string;\n}> {\n try {\n const response = await octo.rest.pulls.list({\n owner: owner,\n repo: repo,\n state: 'open',\n });\n for (const pull of response.data) {\n if (pull.head.ref === branchName) {\n return {\n prNum: pull.number,\n prUrl: pull.html_url,\n prTitle: pull.title,\n prBody: pull.body ?? undefined,\n prCatalogInfoContent: withCatalogInfoContent\n ? await getCatalogInfoContentFromPR(\n logger,\n config,\n octo,\n owner,\n repo,\n pull.number,\n pull.head.sha,\n )\n : undefined,\n lastUpdate: pull.updated_at,\n };\n }\n }\n } catch (error) {\n logErrorIfNeeded(logger, 'Error fetching pull requests', error);\n }\n return {};\n}\n\nexport async function getCatalogInfoContentFromPR(\n logger: LoggerService,\n config: Config,\n octo: Octokit,\n owner: string,\n repo: string,\n prNumber: number,\n prHeadSha: string,\n): Promise<string | undefined> {\n try {\n const filePath = getCatalogFilename(config);\n const fileContentResponse = await octo.rest.repos.getContent({\n owner,\n repo,\n path: filePath,\n ref: prHeadSha,\n });\n if (!fileContentResponse.data) {\n return undefined;\n }\n if (!('content' in fileContentResponse.data)) {\n return undefined;\n }\n return Buffer.from(fileContentResponse.data.content, 'base64').toString(\n 'utf-8',\n );\n } catch (error: any) {\n logErrorIfNeeded(\n logger,\n `Error fetching catalog-info content from PR ${prNumber}`,\n error,\n );\n return undefined;\n }\n}\n\nexport async function closePRWithComment(\n octo: Octokit,\n owner: string,\n repo: string,\n prNum: number,\n comment: string,\n) {\n await octo.rest.issues.createComment({\n owner,\n repo,\n issue_number: prNum,\n body: comment,\n });\n await octo.rest.pulls.update({\n owner,\n repo,\n pull_number: prNum,\n state: 'closed',\n });\n}\n"],"names":["logErrorIfNeeded","getCatalogFilename"],"mappings":";;;;;;;;;;;AAwBsB,eAAA,mBAAA,CACpB,QACA,MACA,EAAA,IAAA,EACA,OACA,IACA,EAAA,UAAA,EACA,yBAAkC,KAQjC,EAAA;AACD,EAAI,IAAA;AACF,IAAA,MAAM,QAAW,GAAA,MAAM,IAAK,CAAA,IAAA,CAAK,MAAM,IAAK,CAAA;AAAA,MAC1C,KAAA;AAAA,MACA,IAAA;AAAA,MACA,KAAO,EAAA;AAAA,KACR,CAAA;AACD,IAAW,KAAA,MAAA,IAAA,IAAQ,SAAS,IAAM,EAAA;AAChC,MAAI,IAAA,IAAA,CAAK,IAAK,CAAA,GAAA,KAAQ,UAAY,EAAA;AAChC,QAAO,OAAA;AAAA,UACL,OAAO,IAAK,CAAA,MAAA;AAAA,UACZ,OAAO,IAAK,CAAA,QAAA;AAAA,UACZ,SAAS,IAAK,CAAA,KAAA;AAAA,UACd,MAAA,EAAQ,KAAK,IAAQ,IAAA,KAAA,CAAA;AAAA,UACrB,oBAAA,EAAsB,yBAClB,MAAM,2BAAA;AAAA,YACJ,MAAA;AAAA,YACA,MAAA;AAAA,YACA,IAAA;AAAA,YACA,KAAA;AAAA,YACA,IAAA;AAAA,YACA,IAAK,CAAA,MAAA;AAAA,YACL,KAAK,IAAK,CAAA;AAAA,WAEZ,GAAA,KAAA,CAAA;AAAA,UACJ,YAAY,IAAK,CAAA;AAAA,SACnB;AAAA;AACF;AACF,WACO,KAAO,EAAA;AACd,IAAiBA,6BAAA,CAAA,MAAA,EAAQ,gCAAgC,KAAK,CAAA;AAAA;AAEhE,EAAA,OAAO,EAAC;AACV;AAEA,eAAsB,4BACpB,MACA,EAAA,MAAA,EACA,MACA,KACA,EAAA,IAAA,EACA,UACA,SAC6B,EAAA;AAC7B,EAAI,IAAA;AACF,IAAM,MAAA,QAAA,GAAWC,gCAAmB,MAAM,CAAA;AAC1C,IAAA,MAAM,mBAAsB,GAAA,MAAM,IAAK,CAAA,IAAA,CAAK,MAAM,UAAW,CAAA;AAAA,MAC3D,KAAA;AAAA,MACA,IAAA;AAAA,MACA,IAAM,EAAA,QAAA;AAAA,MACN,GAAK,EAAA;AAAA,KACN,CAAA;AACD,IAAI,IAAA,CAAC,oBAAoB,IAAM,EAAA;AAC7B,MAAO,OAAA,KAAA,CAAA;AAAA;AAET,IAAI,IAAA,EAAE,SAAa,IAAA,mBAAA,CAAoB,IAAO,CAAA,EAAA;AAC5C,MAAO,OAAA,KAAA,CAAA;AAAA;AAET,IAAA,OAAO,OAAO,IAAK,CAAA,mBAAA,CAAoB,IAAK,CAAA,OAAA,EAAS,QAAQ,CAAE,CAAA,QAAA;AAAA,MAC7D;AAAA,KACF;AAAA,WACO,KAAY,EAAA;AACnB,IAAAD,6BAAA;AAAA,MACE,MAAA;AAAA,MACA,+CAA+C,QAAQ,CAAA,CAAA;AAAA,MACvD;AAAA,KACF;AACA,IAAO,OAAA,SAAA;AAAA;AAEX;AAEA,eAAsB,kBACpB,CAAA,IAAA,EACA,KACA,EAAA,IAAA,EACA,OACA,OACA,EAAA;AACA,EAAM,MAAA,IAAA,CAAK,IAAK,CAAA,MAAA,CAAO,aAAc,CAAA;AAAA,IACnC,KAAA;AAAA,IACA,IAAA;AAAA,IACA,YAAc,EAAA,KAAA;AAAA,IACd,IAAM,EAAA;AAAA,GACP,CAAA;AACD,EAAM,MAAA,IAAA,CAAK,IAAK,CAAA,KAAA,CAAM,MAAO,CAAA;AAAA,IAC3B,KAAA;AAAA,IACA,IAAA;AAAA,IACA,WAAa,EAAA,KAAA;AAAA,IACb,KAAO,EAAA;AAAA,GACR,CAAA;AACH;;;;;;"}
@@ -7,6 +7,7 @@ require('@backstage/plugin-permission-common');
7
7
  require('@red-hat-developer-hub/backstage-plugin-bulk-import-common');
8
8
  require('just-kebab-case');
9
9
  var loggingUtils = require('../../helpers/loggingUtils.cjs.js');
10
+ require('@backstage/catalog-model');
10
11
  var handlers = require('../../service/handlers/handlers.cjs.js');
11
12
  var orgUtils = require('./orgUtils.cjs.js');
12
13
  var utils = require('./utils.cjs.js');
@@ -260,48 +261,10 @@ async function fileExistsInDefaultBranch(logger, octo, owner, repo, fileName, de
260
261
  return undefined;
261
262
  }
262
263
  }
263
- async function createOrUpdateFileInBranch(octo, owner, repo, branchName, fileName, fileContent) {
264
- try {
265
- const { data: existingFile } = await octo.rest.repos.getContent({
266
- owner,
267
- repo,
268
- path: fileName,
269
- ref: branchName
270
- });
271
- if (Array.isArray(existingFile) || !("sha" in existingFile)) {
272
- throw new Error(
273
- `The content at path ${fileName} is not a file or the response from GitHub does not contain the 'sha' property.`
274
- );
275
- }
276
- await octo.rest.repos.createOrUpdateFileContents({
277
- owner,
278
- repo,
279
- path: fileName,
280
- message: `Add ${fileName} config file`,
281
- content: btoa(fileContent),
282
- sha: existingFile.sha,
283
- branch: branchName
284
- });
285
- } catch (error) {
286
- if (error.status === 404) {
287
- await octo.rest.repos.createOrUpdateFileContents({
288
- owner,
289
- repo,
290
- path: fileName,
291
- message: `Add ${fileName} config file`,
292
- content: btoa(fileContent),
293
- branch: branchName
294
- });
295
- } else {
296
- throw error;
297
- }
298
- }
299
- }
300
264
 
301
265
  exports.addGithubAppRepositories = addGithubAppRepositories;
302
266
  exports.addGithubTokenOrgRepositories = addGithubTokenOrgRepositories;
303
267
  exports.addGithubTokenRepositories = addGithubTokenRepositories;
304
- exports.createOrUpdateFileInBranch = createOrUpdateFileInBranch;
305
268
  exports.fileExistsInDefaultBranch = fileExistsInDefaultBranch;
306
269
  exports.searchRepos = searchRepos;
307
270
  exports.validateAndBuildRepoData = validateAndBuildRepoData;
@@ -1 +1 @@
1
- {"version":3,"file":"repoUtils.cjs.js","sources":["../../../src/github/utils/repoUtils.ts"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\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 type { LoggerService } from '@backstage/backend-plugin-api';\nimport type { Config } from '@backstage/config';\nimport type {\n GithubCredentials,\n GithubIntegrationConfig,\n ScmIntegrations,\n} from '@backstage/integration';\n\nimport { Octokit } from '@octokit/rest';\nimport gitUrlParse from 'git-url-parse';\n\nimport { getBranchName } from '../../catalog/catalogUtils';\nimport { logErrorIfNeeded } from '../../helpers';\nimport {\n DefaultPageNumber,\n DefaultPageSize,\n} from '../../service/handlers/handlers';\nimport type { CustomGithubCredentialsProvider } from '../GithubAppManager';\nimport type {\n ExtendedGithubCredentials,\n GithubAppCredentials,\n GithubFetchError,\n GithubRepository,\n} from '../types';\nimport { getAllAppOrgs } from './orgUtils';\nimport {\n computeTotalCountFromGitHubToken,\n createCredentialError,\n handleError,\n} from './utils';\n\nexport type ValidatedRepo = {\n ghConfig: GithubIntegrationConfig;\n credentials: ExtendedGithubCredentials[];\n owner: string;\n repo: string;\n branchName: string;\n};\n\nexport async function validateAndBuildRepoData(\n githubCredentialsProvider: CustomGithubCredentialsProvider,\n integrations: ScmIntegrations,\n config: Config,\n input: {\n repoUrl: string;\n },\n): Promise<ValidatedRepo> {\n const ghConfig = integrations.github.byUrl(input.repoUrl)?.config;\n if (!ghConfig) {\n throw new Error(`Could not find GH integration from ${input.repoUrl}`);\n }\n\n const gitUrl = gitUrlParse(input.repoUrl);\n const owner = gitUrl.organization;\n const repo = gitUrl.name;\n\n const credentials = await githubCredentialsProvider.getAllCredentials({\n host: ghConfig.host,\n });\n if (credentials.length === 0) {\n throw new Error(`No credentials for GH integration`);\n }\n\n const branchName = getBranchName(config);\n return { ghConfig, owner, repo, credentials, branchName };\n}\n\nexport async function searchRepos(\n octokit: Octokit,\n ghSearchQuery: string,\n pageNumber: number = DefaultPageNumber,\n pageSize: number = DefaultPageSize,\n): Promise<{ totalCount?: number; repositories: GithubRepository[] }> {\n const repoSearchResp = await octokit.rest.search.repos({\n q: ghSearchQuery,\n order: 'asc',\n page: pageNumber,\n per_page: pageSize,\n });\n return {\n totalCount: repoSearchResp?.data?.total_count,\n repositories:\n repoSearchResp?.data?.items?.map(repo => {\n return {\n name: repo.name,\n full_name: repo.full_name,\n url: repo.url,\n html_url: repo.html_url,\n default_branch: repo.default_branch,\n updated_at: repo.updated_at,\n };\n }) ?? [],\n };\n}\n\n/**\n * Adds the repositories accessible by the provided github app to the provided repositories Map<string, GithubRepository>\n * If any errors occurs, adds them to the provided errors Map<number, GithubFetchError>\n */\nexport async function addGithubAppRepositories(\n deps: {\n logger: LoggerService;\n githubCredentialsProvider: CustomGithubCredentialsProvider;\n },\n octokit: Octokit,\n credential: GithubAppCredentials,\n ghConfig: GithubIntegrationConfig,\n repositories: Map<string, GithubRepository>,\n errors: Map<number, GithubFetchError>,\n reqParams?: {\n search?: string;\n pageNumber?: number;\n pageSize?: number;\n },\n): Promise<{ totalCount?: number }> {\n const search = reqParams?.search;\n const pageNumber = reqParams?.pageNumber ?? DefaultPageNumber;\n const pageSize = reqParams?.pageSize ?? DefaultPageSize;\n let totalCount: number | undefined;\n try {\n if (search) {\n const allOrgsMap = await getAllAppOrgs(\n deps.githubCredentialsProvider,\n ghConfig,\n credential.accountLogin,\n );\n const orgSearch: string[] = [];\n for (const [_orgUrl, ghOrg] of allOrgsMap) {\n orgSearch.push(`org:${ghOrg.name}`);\n }\n const query = `${search} in:name ${orgSearch.join(' ')}`;\n const searchResp = await searchRepos(\n octokit,\n query,\n pageNumber,\n pageSize,\n );\n totalCount = searchResp.totalCount;\n searchResp.repositories.forEach(repo =>\n repositories.set(repo.full_name, repo),\n );\n } else {\n const resp = await octokit.apps.listReposAccessibleToInstallation({\n page: pageNumber,\n per_page: pageSize,\n });\n const repos = resp?.data?.repositories ?? resp?.data;\n repos?.forEach(repo => {\n repositories.set(repo.full_name, {\n name: repo.name,\n full_name: repo.full_name,\n url: repo.url,\n html_url: repo.html_url,\n default_branch: repo.default_branch,\n updated_at: repo.updated_at,\n });\n });\n totalCount = resp?.data?.total_count;\n }\n } catch (err: any) {\n logErrorIfNeeded(\n deps.logger,\n `Fetching repositories with access token for github app ${credential.appId}`,\n err,\n );\n const credentialError = createCredentialError(credential, err as Error);\n if (credentialError) {\n errors.set(credential.appId, credentialError);\n }\n }\n return { totalCount };\n}\n\n/**\n * Adds the user or organization repositories accessible by the github token to the provided repositories Map<string, GithubRepository> if they're owned by the specified owner\n * If any errors occurs, adds them to the provided errors Map<number, GithubFetchError>\n */\nexport async function addGithubTokenRepositories(\n deps: {\n logger: LoggerService;\n },\n octokit: Octokit,\n credential: GithubCredentials,\n repositories: Map<string, GithubRepository>,\n errors: Map<number, GithubFetchError>,\n reqParams?: {\n search?: string;\n pageNumber?: number;\n pageSize?: number;\n },\n): Promise<{ totalCount?: number }> {\n const search = reqParams?.search;\n const pageNumber = reqParams?.pageNumber ?? DefaultPageNumber;\n const pageSize = reqParams?.pageSize ?? DefaultPageSize;\n let totalCount: number | undefined;\n try {\n if (search) {\n // Get currently authenticated user\n const username = (await octokit.rest.users.getAuthenticated())?.data\n ?.login;\n let query = `${search} in:name user:${username}`;\n\n const allOrgsResp = await octokit.paginate(\n octokit.rest.orgs.listForAuthenticatedUser,\n {\n sort: 'full_name',\n direction: 'asc',\n },\n );\n const orgSearch: string[] = [];\n allOrgsResp?.forEach(org => orgSearch.push(`org:${org.login}`));\n if (orgSearch.length > 0) {\n query += ` ${orgSearch.join(' ')}`;\n }\n\n const searchResp = await searchRepos(\n octokit,\n query,\n pageNumber,\n pageSize,\n );\n totalCount = searchResp.totalCount;\n searchResp.repositories.forEach(repo =>\n repositories.set(repo.full_name, repo),\n );\n } else {\n /**\n * The listForAuthenticatedUser endpoint will grab all the repositories the github token has explicit access to.\n * These would include repositories they own, repositories where they are a collaborator,\n * and repositories that they can access through an organization membership.\n */\n const resp = await octokit.rest.repos.listForAuthenticatedUser({\n page: pageNumber,\n per_page: pageSize,\n sort: 'full_name',\n direction: 'asc',\n });\n resp?.data?.forEach(repo => {\n repositories.set(repo.full_name, {\n name: repo.name,\n full_name: repo.full_name,\n url: repo.url,\n html_url: repo.html_url,\n default_branch: repo.default_branch,\n updated_at: repo.updated_at,\n });\n });\n\n totalCount = await computeTotalCountFromGitHubToken(\n deps,\n async (lastPageNumber: number) =>\n octokit.repos\n .listForAuthenticatedUser({\n page: lastPageNumber,\n per_page: 100,\n })\n .then(lastPageResp => lastPageResp.data.length),\n 'repos.listForAuthenticatedUser',\n resp?.data?.length,\n resp?.headers?.link,\n );\n }\n } catch (err) {\n handleError(\n deps,\n 'Fetching repositories with token from token',\n credential,\n errors,\n err,\n );\n }\n return { totalCount };\n}\n\nexport async function addGithubTokenOrgRepositories(\n deps: {\n logger: LoggerService;\n },\n octokit: Octokit,\n credential: GithubCredentials,\n org: string,\n repositories: Map<string, GithubRepository>,\n errors: Map<number, GithubFetchError>,\n reqParams?: {\n search?: string;\n pageNumber?: number;\n pageSize?: number;\n },\n): Promise<{ totalCount?: number }> {\n const search = reqParams?.search;\n const pageNumber = reqParams?.pageNumber ?? DefaultPageNumber;\n const pageSize = reqParams?.pageSize ?? DefaultPageSize;\n let totalCount: number | undefined;\n try {\n if (search) {\n const query = `${search} in:name org:${org}`;\n const searchResp = await searchRepos(\n octokit,\n query,\n pageNumber,\n pageSize,\n );\n totalCount = searchResp.totalCount;\n searchResp.repositories.forEach(repo =>\n repositories.set(repo.full_name, repo),\n );\n } else {\n /**\n * The listForAuthenticatedUser endpoint will grab all the repositories the github token has explicit access to.\n * These would include repositories they own, repositories where they are a collaborator,\n * and repositories that they can access through an organization membership.\n */\n const resp = await octokit.rest.repos.listForOrg({\n org,\n page: pageNumber,\n per_page: pageSize,\n sort: 'full_name',\n direction: 'asc',\n });\n resp?.data?.forEach(repo => {\n const githubRepo: GithubRepository = {\n name: repo.name,\n full_name: repo.full_name,\n url: repo.url,\n html_url: repo.html_url,\n default_branch: repo.default_branch ?? 'main',\n updated_at: repo.updated_at,\n };\n repositories.set(githubRepo.full_name, githubRepo);\n });\n\n totalCount = await computeTotalCountFromGitHubToken(\n deps,\n async (lastPageNumber: number) =>\n octokit.repos\n .listForOrg({\n org,\n page: lastPageNumber,\n per_page: 100,\n })\n .then(lastPageResp => lastPageResp.data.length),\n 'repos.listForOrg',\n resp?.data?.length,\n resp?.headers?.link,\n );\n }\n } catch (err) {\n handleError(\n deps,\n 'Fetching org repositories with token from token',\n credential,\n errors,\n err,\n );\n }\n return { totalCount };\n}\n\nexport async function fileExistsInDefaultBranch(\n logger: LoggerService,\n octo: Octokit,\n owner: string,\n repo: string,\n fileName: string,\n defaultBranch: string = 'main',\n) {\n try {\n await octo.rest.repos.getContent({\n owner,\n repo,\n path: fileName,\n ref: defaultBranch,\n });\n return true;\n } catch (error: any) {\n if (error.status === 404) {\n return false;\n }\n logger.debug(\n `Unable to determine if a file named ${fileName} already exists in repo ${repo}: ${error}`,\n );\n return undefined;\n }\n}\n\nexport async function createOrUpdateFileInBranch(\n octo: Octokit,\n owner: string,\n repo: string,\n branchName: string,\n fileName: string,\n fileContent: string,\n): Promise<void> {\n try {\n const { data: existingFile } = await octo.rest.repos.getContent({\n owner: owner,\n repo: repo,\n path: fileName,\n ref: branchName,\n });\n // Response can either be a directory (array of files) or a single file element. In this case, we ensure it has the sha property to update it.\n if (Array.isArray(existingFile) || !('sha' in existingFile)) {\n throw new Error(\n `The content at path ${fileName} is not a file or the response from GitHub does not contain the 'sha' property.`,\n );\n }\n // If the file already exists, update it\n await octo.rest.repos.createOrUpdateFileContents({\n owner,\n repo,\n path: fileName,\n message: `Add ${fileName} config file`,\n content: btoa(fileContent),\n sha: existingFile.sha,\n branch: branchName,\n });\n } catch (error: any) {\n if (error.status === 404) {\n // If the file does not exist, create it\n await octo.rest.repos.createOrUpdateFileContents({\n owner,\n repo,\n path: fileName,\n message: `Add ${fileName} config file`,\n content: btoa(fileContent),\n branch: branchName,\n });\n } else {\n throw error;\n }\n }\n}\n"],"names":["gitUrlParse","getBranchName","DefaultPageNumber","DefaultPageSize","getAllAppOrgs","logErrorIfNeeded","createCredentialError","computeTotalCountFromGitHubToken","handleError"],"mappings":"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"}
1
+ {"version":3,"file":"repoUtils.cjs.js","sources":["../../../src/github/utils/repoUtils.ts"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\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 type { LoggerService } from '@backstage/backend-plugin-api';\nimport type { Config } from '@backstage/config';\nimport type {\n GithubCredentials,\n GithubIntegrationConfig,\n ScmIntegrations,\n} from '@backstage/integration';\n\nimport { Octokit } from '@octokit/rest';\nimport gitUrlParse from 'git-url-parse';\n\nimport { getBranchName } from '../../catalog/catalogUtils';\nimport { logErrorIfNeeded } from '../../helpers';\nimport {\n DefaultPageNumber,\n DefaultPageSize,\n} from '../../service/handlers/handlers';\nimport type { CustomGithubCredentialsProvider } from '../GithubAppManager';\nimport type {\n ExtendedGithubCredentials,\n GithubAppCredentials,\n GithubFetchError,\n GithubRepository,\n} from '../types';\nimport { getAllAppOrgs } from './orgUtils';\nimport {\n computeTotalCountFromGitHubToken,\n createCredentialError,\n handleError,\n} from './utils';\n\nexport type ValidatedRepo = {\n ghConfig: GithubIntegrationConfig;\n credentials: ExtendedGithubCredentials[];\n owner: string;\n repo: string;\n branchName: string;\n};\n\nexport async function validateAndBuildRepoData(\n githubCredentialsProvider: CustomGithubCredentialsProvider,\n integrations: ScmIntegrations,\n config: Config,\n input: {\n repoUrl: string;\n },\n): Promise<ValidatedRepo> {\n const ghConfig = integrations.github.byUrl(input.repoUrl)?.config;\n if (!ghConfig) {\n throw new Error(`Could not find GH integration from ${input.repoUrl}`);\n }\n\n const gitUrl = gitUrlParse(input.repoUrl);\n const owner = gitUrl.organization;\n const repo = gitUrl.name;\n\n const credentials = await githubCredentialsProvider.getAllCredentials({\n host: ghConfig.host,\n });\n if (credentials.length === 0) {\n throw new Error(`No credentials for GH integration`);\n }\n\n const branchName = getBranchName(config);\n return { ghConfig, owner, repo, credentials, branchName };\n}\n\nexport async function searchRepos(\n octokit: Octokit,\n ghSearchQuery: string,\n pageNumber: number = DefaultPageNumber,\n pageSize: number = DefaultPageSize,\n): Promise<{ totalCount?: number; repositories: GithubRepository[] }> {\n const repoSearchResp = await octokit.rest.search.repos({\n q: ghSearchQuery,\n order: 'asc',\n page: pageNumber,\n per_page: pageSize,\n });\n return {\n totalCount: repoSearchResp?.data?.total_count,\n repositories:\n repoSearchResp?.data?.items?.map(repo => {\n return {\n name: repo.name,\n full_name: repo.full_name,\n url: repo.url,\n html_url: repo.html_url,\n default_branch: repo.default_branch,\n updated_at: repo.updated_at,\n };\n }) ?? [],\n };\n}\n\n/**\n * Adds the repositories accessible by the provided github app to the provided repositories Map<string, GithubRepository>\n * If any errors occurs, adds them to the provided errors Map<number, GithubFetchError>\n */\nexport async function addGithubAppRepositories(\n deps: {\n logger: LoggerService;\n githubCredentialsProvider: CustomGithubCredentialsProvider;\n },\n octokit: Octokit,\n credential: GithubAppCredentials,\n ghConfig: GithubIntegrationConfig,\n repositories: Map<string, GithubRepository>,\n errors: Map<number, GithubFetchError>,\n reqParams?: {\n search?: string;\n pageNumber?: number;\n pageSize?: number;\n },\n): Promise<{ totalCount?: number }> {\n const search = reqParams?.search;\n const pageNumber = reqParams?.pageNumber ?? DefaultPageNumber;\n const pageSize = reqParams?.pageSize ?? DefaultPageSize;\n let totalCount: number | undefined;\n try {\n if (search) {\n const allOrgsMap = await getAllAppOrgs(\n deps.githubCredentialsProvider,\n ghConfig,\n credential.accountLogin,\n );\n const orgSearch: string[] = [];\n for (const [_orgUrl, ghOrg] of allOrgsMap) {\n orgSearch.push(`org:${ghOrg.name}`);\n }\n const query = `${search} in:name ${orgSearch.join(' ')}`;\n const searchResp = await searchRepos(\n octokit,\n query,\n pageNumber,\n pageSize,\n );\n totalCount = searchResp.totalCount;\n searchResp.repositories.forEach(repo =>\n repositories.set(repo.full_name, repo),\n );\n } else {\n const resp = await octokit.apps.listReposAccessibleToInstallation({\n page: pageNumber,\n per_page: pageSize,\n });\n const repos = resp?.data?.repositories ?? resp?.data;\n repos?.forEach(repo => {\n repositories.set(repo.full_name, {\n name: repo.name,\n full_name: repo.full_name,\n url: repo.url,\n html_url: repo.html_url,\n default_branch: repo.default_branch,\n updated_at: repo.updated_at,\n });\n });\n totalCount = resp?.data?.total_count;\n }\n } catch (err: any) {\n logErrorIfNeeded(\n deps.logger,\n `Fetching repositories with access token for github app ${credential.appId}`,\n err,\n );\n const credentialError = createCredentialError(credential, err as Error);\n if (credentialError) {\n errors.set(credential.appId, credentialError);\n }\n }\n return { totalCount };\n}\n\n/**\n * Adds the user or organization repositories accessible by the github token to the provided repositories Map<string, GithubRepository> if they're owned by the specified owner\n * If any errors occurs, adds them to the provided errors Map<number, GithubFetchError>\n */\nexport async function addGithubTokenRepositories(\n deps: {\n logger: LoggerService;\n },\n octokit: Octokit,\n credential: GithubCredentials,\n repositories: Map<string, GithubRepository>,\n errors: Map<number, GithubFetchError>,\n reqParams?: {\n search?: string;\n pageNumber?: number;\n pageSize?: number;\n },\n): Promise<{ totalCount?: number }> {\n const search = reqParams?.search;\n const pageNumber = reqParams?.pageNumber ?? DefaultPageNumber;\n const pageSize = reqParams?.pageSize ?? DefaultPageSize;\n let totalCount: number | undefined;\n try {\n if (search) {\n // Get currently authenticated user\n const username = (await octokit.rest.users.getAuthenticated())?.data\n ?.login;\n let query = `${search} in:name user:${username}`;\n\n const allOrgsResp = await octokit.paginate(\n octokit.rest.orgs.listForAuthenticatedUser,\n {\n sort: 'full_name',\n direction: 'asc',\n },\n );\n const orgSearch: string[] = [];\n allOrgsResp?.forEach(org => orgSearch.push(`org:${org.login}`));\n if (orgSearch.length > 0) {\n query += ` ${orgSearch.join(' ')}`;\n }\n\n const searchResp = await searchRepos(\n octokit,\n query,\n pageNumber,\n pageSize,\n );\n totalCount = searchResp.totalCount;\n searchResp.repositories.forEach(repo =>\n repositories.set(repo.full_name, repo),\n );\n } else {\n /**\n * The listForAuthenticatedUser endpoint will grab all the repositories the github token has explicit access to.\n * These would include repositories they own, repositories where they are a collaborator,\n * and repositories that they can access through an organization membership.\n */\n const resp = await octokit.rest.repos.listForAuthenticatedUser({\n page: pageNumber,\n per_page: pageSize,\n sort: 'full_name',\n direction: 'asc',\n });\n resp?.data?.forEach(repo => {\n repositories.set(repo.full_name, {\n name: repo.name,\n full_name: repo.full_name,\n url: repo.url,\n html_url: repo.html_url,\n default_branch: repo.default_branch,\n updated_at: repo.updated_at,\n });\n });\n\n totalCount = await computeTotalCountFromGitHubToken(\n deps,\n async (lastPageNumber: number) =>\n octokit.repos\n .listForAuthenticatedUser({\n page: lastPageNumber,\n per_page: 100,\n })\n .then(lastPageResp => lastPageResp.data.length),\n 'repos.listForAuthenticatedUser',\n resp?.data?.length,\n resp?.headers?.link,\n );\n }\n } catch (err) {\n handleError(\n deps,\n 'Fetching repositories with token from token',\n credential,\n errors,\n err,\n );\n }\n return { totalCount };\n}\n\nexport async function addGithubTokenOrgRepositories(\n deps: {\n logger: LoggerService;\n },\n octokit: Octokit,\n credential: GithubCredentials,\n org: string,\n repositories: Map<string, GithubRepository>,\n errors: Map<number, GithubFetchError>,\n reqParams?: {\n search?: string;\n pageNumber?: number;\n pageSize?: number;\n },\n): Promise<{ totalCount?: number }> {\n const search = reqParams?.search;\n const pageNumber = reqParams?.pageNumber ?? DefaultPageNumber;\n const pageSize = reqParams?.pageSize ?? DefaultPageSize;\n let totalCount: number | undefined;\n try {\n if (search) {\n const query = `${search} in:name org:${org}`;\n const searchResp = await searchRepos(\n octokit,\n query,\n pageNumber,\n pageSize,\n );\n totalCount = searchResp.totalCount;\n searchResp.repositories.forEach(repo =>\n repositories.set(repo.full_name, repo),\n );\n } else {\n /**\n * The listForAuthenticatedUser endpoint will grab all the repositories the github token has explicit access to.\n * These would include repositories they own, repositories where they are a collaborator,\n * and repositories that they can access through an organization membership.\n */\n const resp = await octokit.rest.repos.listForOrg({\n org,\n page: pageNumber,\n per_page: pageSize,\n sort: 'full_name',\n direction: 'asc',\n });\n resp?.data?.forEach(repo => {\n const githubRepo: GithubRepository = {\n name: repo.name,\n full_name: repo.full_name,\n url: repo.url,\n html_url: repo.html_url,\n default_branch: repo.default_branch ?? 'main',\n updated_at: repo.updated_at,\n };\n repositories.set(githubRepo.full_name, githubRepo);\n });\n\n totalCount = await computeTotalCountFromGitHubToken(\n deps,\n async (lastPageNumber: number) =>\n octokit.repos\n .listForOrg({\n org,\n page: lastPageNumber,\n per_page: 100,\n })\n .then(lastPageResp => lastPageResp.data.length),\n 'repos.listForOrg',\n resp?.data?.length,\n resp?.headers?.link,\n );\n }\n } catch (err) {\n handleError(\n deps,\n 'Fetching org repositories with token from token',\n credential,\n errors,\n err,\n );\n }\n return { totalCount };\n}\n\nexport async function fileExistsInDefaultBranch(\n logger: LoggerService,\n octo: Octokit,\n owner: string,\n repo: string,\n fileName: string,\n defaultBranch: string = 'main',\n) {\n try {\n await octo.rest.repos.getContent({\n owner,\n repo,\n path: fileName,\n ref: defaultBranch,\n });\n return true;\n } catch (error: any) {\n if (error.status === 404) {\n return false;\n }\n logger.debug(\n `Unable to determine if a file named ${fileName} already exists in repo ${repo}: ${error}`,\n );\n return undefined;\n }\n}\n\nexport async function createOrUpdateFileInBranch(\n octo: Octokit,\n owner: string,\n repo: string,\n branchName: string,\n fileName: string,\n fileContent: string,\n): Promise<void> {\n try {\n const { data: existingFile } = await octo.rest.repos.getContent({\n owner: owner,\n repo: repo,\n path: fileName,\n ref: branchName,\n });\n // Response can either be a directory (array of files) or a single file element. In this case, we ensure it has the sha property to update it.\n if (Array.isArray(existingFile) || !('sha' in existingFile)) {\n throw new Error(\n `The content at path ${fileName} is not a file or the response from GitHub does not contain the 'sha' property.`,\n );\n }\n // If the file already exists, update it\n await octo.rest.repos.createOrUpdateFileContents({\n owner,\n repo,\n path: fileName,\n message: `Add ${fileName} config file`,\n content: btoa(fileContent),\n sha: existingFile.sha,\n branch: branchName,\n });\n } catch (error: any) {\n if (error.status === 404) {\n // If the file does not exist, create it\n await octo.rest.repos.createOrUpdateFileContents({\n owner,\n repo,\n path: fileName,\n message: `Add ${fileName} config file`,\n content: btoa(fileContent),\n branch: branchName,\n });\n } else {\n throw error;\n }\n }\n}\n"],"names":["gitUrlParse","getBranchName","DefaultPageNumber","DefaultPageSize","getAllAppOrgs","logErrorIfNeeded","createCredentialError","computeTotalCountFromGitHubToken","handleError"],"mappings":"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"}
@@ -6,6 +6,7 @@ require('@backstage/plugin-permission-common');
6
6
  require('@red-hat-developer-hub/backstage-plugin-bulk-import-common');
7
7
  require('just-kebab-case');
8
8
  var loggingUtils = require('../../helpers/loggingUtils.cjs.js');
9
+ require('@backstage/catalog-model');
9
10
  var types = require('../types.cjs.js');
10
11
  var ghUtils = require('./ghUtils.cjs.js');
11
12
  var repoUtils = require('./repoUtils.cjs.js');
@@ -172,34 +173,44 @@ async function fetchFromAllIntegrations(deps, integrations, params) {
172
173
  dataErrs.forEach((err, idx) => aggregatedErrors.set(idx, err));
173
174
  return { data, errors: aggregatedErrors };
174
175
  }
175
- function computeTotalCount(data, countList, pageSize) {
176
- let totalCount = countList.reduce(
177
- (accumulator, currentValue) => accumulator + currentValue,
178
- 0
179
- );
180
- if (totalCount < pageSize) {
181
- totalCount = data.length;
176
+ async function fetchFromMatchedIntegration(deps, integrations, repoUrl, fetcher) {
177
+ const gitUrl = gitUrlParse__default.default(repoUrl);
178
+ const errors = /* @__PURE__ */ new Map();
179
+ const ghConfig = integrations.github.byUrl(repoUrl)?.config;
180
+ if (!ghConfig) {
181
+ throw new Error(
182
+ `No GitHub integration config found for repo ${repoUrl}. Please add a configuration entry under 'integrations.github'`
183
+ );
182
184
  }
183
- return totalCount;
184
- }
185
- function extractLocationOwnerMap(locationUrls) {
186
- const locationGitOwnerMap = /* @__PURE__ */ new Map();
187
- for (const locationUrl of locationUrls) {
188
- const split = locationUrl.split("/blob/");
189
- if (split.length < 2) {
185
+ const credentials = await getCredentialsForConfig(
186
+ deps.githubCredentialsProvider,
187
+ ghConfig
188
+ );
189
+ for (const credential of credentials) {
190
+ const octokit = ghUtils.buildOcto(
191
+ {
192
+ logger: deps.logger,
193
+ cache: deps.cache
194
+ },
195
+ { credential, errors, owner: gitUrl.owner },
196
+ ghConfig.apiBaseUrl
197
+ );
198
+ if (!octokit) {
190
199
  continue;
191
200
  }
192
- locationGitOwnerMap.set(locationUrl, gitUrlParse__default.default(split[0]).owner);
201
+ const data = await fetcher(octokit, gitUrl);
202
+ if (data) {
203
+ return { data, errors: Array.from(errors.values()) };
204
+ }
193
205
  }
194
- return locationGitOwnerMap;
206
+ return { errors: Array.from(errors.values()) };
195
207
  }
196
208
 
197
- exports.computeTotalCount = computeTotalCount;
198
209
  exports.computeTotalCountFromGitHubToken = computeTotalCountFromGitHubToken;
199
210
  exports.createCredentialError = createCredentialError;
200
211
  exports.executeFunctionOnFirstSuccessfulIntegration = executeFunctionOnFirstSuccessfulIntegration;
201
- exports.extractLocationOwnerMap = extractLocationOwnerMap;
202
212
  exports.fetchFromAllIntegrations = fetchFromAllIntegrations;
213
+ exports.fetchFromMatchedIntegration = fetchFromMatchedIntegration;
203
214
  exports.getCredentialsForConfig = getCredentialsForConfig;
204
215
  exports.getCredentialsFromIntegrations = getCredentialsFromIntegrations;
205
216
  exports.handleError = handleError;
@@ -1 +1 @@
1
- {"version":3,"file":"utils.cjs.js","sources":["../../../src/github/utils/utils.ts"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\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 type {\n CacheService,\n LoggerService,\n} from '@backstage/backend-plugin-api';\nimport type { Config } from '@backstage/config';\nimport {\n ScmIntegrations,\n type GithubIntegrationConfig,\n} from '@backstage/integration';\n\nimport { Octokit } from '@octokit/rest';\nimport gitUrlParse from 'git-url-parse';\n\nimport { logErrorIfNeeded } from '../../helpers';\nimport type { CustomGithubCredentialsProvider } from '../GithubAppManager';\nimport {\n isGithubAppCredential,\n type ExtendedGithubCredentials,\n type GithubFetchError,\n} from '../types';\nimport { buildOcto } from './ghUtils';\nimport { validateAndBuildRepoData, ValidatedRepo } from './repoUtils';\n\n/**\n * Creates the GithubFetchError to be stored in the returned errors array of the returned GithubRepositoryResponse object\n */\nexport function createCredentialError(\n credential: ExtendedGithubCredentials,\n err?: Error,\n): GithubFetchError | undefined {\n if (err) {\n if (isGithubAppCredential(credential)) {\n return {\n appId: credential.appId,\n type: 'app',\n error: {\n name: err.name,\n message: err.message,\n },\n };\n }\n return {\n type: 'token',\n error: {\n name: err.name,\n message: err.message,\n },\n };\n }\n if ('error' in credential) {\n return {\n appId: credential.appId,\n type: 'app',\n error: {\n name: credential.error.name,\n message: credential.error.message,\n },\n };\n }\n return undefined;\n}\n\nexport function verifyAndGetIntegrations(\n deps: {\n logger: LoggerService;\n },\n\n integrations: ScmIntegrations,\n) {\n const ghConfigs = integrations.github.list().map(ghInt => ghInt.config);\n if (ghConfigs.length === 0) {\n deps.logger.debug(\n 'No GitHub Integration in config => returning an empty list of repositories.',\n );\n throw new Error(\n \"Looks like there is no GitHub Integration in config. Please add a configuration entry under 'integrations.github\",\n );\n }\n return ghConfigs;\n}\n\nexport async function getCredentialsFromIntegrations(\n githubCredentialsProvider: CustomGithubCredentialsProvider,\n ghConfigs: GithubIntegrationConfig[],\n) {\n const credentialsByConfig = new Map<\n GithubIntegrationConfig,\n ExtendedGithubCredentials[]\n >();\n for (const ghConfig of ghConfigs) {\n const creds = await getCredentialsForConfig(\n githubCredentialsProvider,\n ghConfig,\n );\n credentialsByConfig.set(ghConfig, creds);\n }\n return credentialsByConfig;\n}\n\nexport async function getCredentialsForConfig(\n githubCredentialsProvider: CustomGithubCredentialsProvider,\n ghConfig: GithubIntegrationConfig,\n) {\n return await githubCredentialsProvider.getAllCredentials({\n host: ghConfig.host,\n });\n}\n\nexport async function extractConfigAndCreds(\n githubCredentialsProvider: CustomGithubCredentialsProvider,\n integrations: ScmIntegrations,\n input: {\n repoUrl: string;\n defaultBranch?: string;\n },\n) {\n const ghConfig = integrations.github.byUrl(input.repoUrl)?.config;\n if (!ghConfig) {\n throw new Error(`Could not find GH integration from ${input.repoUrl}`);\n }\n\n const credentials = await githubCredentialsProvider.getAllCredentials({\n host: ghConfig.host,\n });\n if (credentials.length === 0) {\n throw new Error(`No credentials for GH integration`);\n }\n\n const gitUrl = gitUrlParse(input.repoUrl);\n return { ghConfig, credentials, gitUrl };\n}\n\nexport function handleError(\n deps: {\n logger: LoggerService;\n },\n desc: string,\n credential: ExtendedGithubCredentials,\n errors: Map<number, GithubFetchError>,\n err: any,\n) {\n logErrorIfNeeded(deps.logger, `${desc} failed`, err);\n const credentialError = createCredentialError(credential, err as Error);\n if (credentialError) {\n errors.set(-1, credentialError);\n }\n}\n\nexport async function computeTotalCountFromGitHubToken(\n deps: {\n logger: LoggerService;\n },\n lastPageDataLengthProviderFn: (lastPageNumber: number) => Promise<number>,\n ghApiName: string,\n pageSize?: number,\n linkHeader?: string,\n): Promise<number | undefined> {\n // There is no direct way to get the total count of repositories other than using octokit.paginate,\n // but will make us retrieve all pages, thus increasing our response time.\n // Workaround here is to analyze the headers, and get the link to the last page.\n if (!linkHeader) {\n deps.logger.debug(\n `No link header found in response from ${ghApiName} GH endpoint => returning current page size`,\n );\n return pageSize;\n }\n const lastPageLink = linkHeader\n .split(',')\n .find(s => s.includes('rel=\"last\"'));\n if (!lastPageLink) {\n deps.logger.debug(\n `No rel='last' link found in response headers from ${ghApiName} GH endpoint => returning current page size`,\n );\n return pageSize;\n }\n const match = lastPageLink.match(/page=(\\d+)/);\n if (!match || match.length < 2) {\n deps.logger.debug(\n `Unable to extract page number from rel='last' link found in response headers from ${ghApiName} GH endpoint => returning current page size`,\n );\n return pageSize;\n }\n\n const lastPageNumber = parseInt(match[1], 10);\n // Fetch the last page to count its items, as it might contain fewer than the requested size\n const lastPageDataLength = await lastPageDataLengthProviderFn(lastPageNumber);\n return pageSize\n ? (lastPageNumber - 1) * pageSize + lastPageDataLength\n : undefined;\n}\n\nexport async function executeFunctionOnFirstSuccessfulIntegration<T>(\n deps: {\n logger: LoggerService;\n cache: CacheService;\n config: Config;\n githubCredentialsProvider: CustomGithubCredentialsProvider;\n },\n integrations: ScmIntegrations,\n params: {\n repoUrl: string;\n fn: (\n validatedRepo: ValidatedRepo,\n octo: Octokit,\n ) => Promise<{ successful: boolean; result?: T }>;\n },\n) {\n const validatedRepo = await validateAndBuildRepoData(\n deps.githubCredentialsProvider,\n integrations,\n deps.config,\n params,\n );\n for (const credential of validatedRepo.credentials) {\n const octo = buildOcto(\n {\n logger: deps.logger,\n cache: deps.cache,\n },\n { credential, owner: validatedRepo.owner },\n validatedRepo.ghConfig.apiBaseUrl,\n );\n if (!octo) {\n continue;\n }\n const res = await params.fn(validatedRepo, octo);\n if (!res.successful) {\n continue;\n }\n return res.result;\n }\n return undefined;\n}\n\nexport async function fetchFromAllIntegrations<T>(\n deps: {\n logger: LoggerService;\n cache: CacheService;\n githubCredentialsProvider: CustomGithubCredentialsProvider;\n },\n integrations: ScmIntegrations,\n params: {\n dataFetcher: (\n octo: Octokit,\n credential: ExtendedGithubCredentials,\n ghConfig: GithubIntegrationConfig,\n ) => Promise<{\n stopFetchingData?: boolean;\n result?: T;\n errors?: GithubFetchError[];\n }>;\n },\n) {\n const ghConfigs = verifyAndGetIntegrations(deps, integrations);\n\n const credentialsByConfig = await getCredentialsFromIntegrations(\n deps.githubCredentialsProvider,\n ghConfigs,\n );\n const errors = new Map<number, GithubFetchError>();\n const data: T[] = [];\n const dataErrs: GithubFetchError[] = [];\n let stopFetchingData: boolean | undefined = false;\n for (const [ghConfig, credentials] of credentialsByConfig) {\n if (stopFetchingData) {\n break;\n }\n deps.logger.debug(\n `Got ${credentials.length} credential(s) for ${ghConfig.host}`,\n );\n for (const credential of credentials) {\n const octokit = buildOcto(\n deps,\n { credential, errors },\n ghConfig.apiBaseUrl,\n );\n if (!octokit) {\n continue;\n }\n const res = await params.dataFetcher(octokit, credential, ghConfig);\n res.errors?.forEach(err => dataErrs.push(err));\n\n if (res.result) {\n data.push(res.result);\n }\n\n stopFetchingData = res.stopFetchingData;\n }\n }\n\n const aggregatedErrors = new Map<number, GithubFetchError>();\n errors.forEach((err, num) => aggregatedErrors.set(num, err));\n dataErrs.forEach((err, idx) => aggregatedErrors.set(idx, err));\n\n return { data, errors: aggregatedErrors };\n}\n\nexport function computeTotalCount<T>(\n data: T[],\n countList: number[],\n pageSize: number,\n) {\n let totalCount = countList.reduce(\n (accumulator, currentValue) => accumulator + currentValue,\n 0,\n );\n if (totalCount < pageSize) {\n totalCount = data.length;\n }\n return totalCount;\n}\n\nexport function extractLocationOwnerMap(locationUrls: string[]) {\n const locationGitOwnerMap = new Map<string, string>();\n for (const locationUrl of locationUrls) {\n const split = locationUrl.split('/blob/');\n if (split.length < 2) {\n continue;\n }\n locationGitOwnerMap.set(locationUrl, gitUrlParse(split[0]).owner);\n }\n return locationGitOwnerMap;\n}\n"],"names":["isGithubAppCredential","logErrorIfNeeded","validateAndBuildRepoData","buildOcto","gitUrlParse"],"mappings":"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"}
1
+ {"version":3,"file":"utils.cjs.js","sources":["../../../src/github/utils/utils.ts"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\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 type {\n CacheService,\n LoggerService,\n} from '@backstage/backend-plugin-api';\nimport type { Config } from '@backstage/config';\nimport {\n ScmIntegrations,\n type GithubIntegrationConfig,\n} from '@backstage/integration';\n\nimport { Octokit } from '@octokit/rest';\nimport gitUrlParse from 'git-url-parse';\n\nimport { logErrorIfNeeded } from '../../helpers';\nimport type { CustomGithubCredentialsProvider } from '../GithubAppManager';\nimport {\n isGithubAppCredential,\n type ExtendedGithubCredentials,\n type GithubFetchError,\n} from '../types';\nimport { buildOcto } from './ghUtils';\nimport { validateAndBuildRepoData, ValidatedRepo } from './repoUtils';\n\n/**\n * Creates the GithubFetchError to be stored in the returned errors array of the returned GithubRepositoryResponse object\n */\nexport function createCredentialError(\n credential: ExtendedGithubCredentials,\n err?: Error,\n): GithubFetchError | undefined {\n if (err) {\n if (isGithubAppCredential(credential)) {\n return {\n appId: credential.appId,\n type: 'app',\n error: {\n name: err.name,\n message: err.message,\n },\n };\n }\n return {\n type: 'token',\n error: {\n name: err.name,\n message: err.message,\n },\n };\n }\n if ('error' in credential) {\n return {\n appId: credential.appId,\n type: 'app',\n error: {\n name: credential.error.name,\n message: credential.error.message,\n },\n };\n }\n return undefined;\n}\n\nexport function verifyAndGetIntegrations(\n deps: {\n logger: LoggerService;\n },\n\n integrations: ScmIntegrations,\n) {\n const ghConfigs = integrations.github.list().map(ghInt => ghInt.config);\n if (ghConfigs.length === 0) {\n deps.logger.debug(\n 'No GitHub Integration in config => returning an empty list of repositories.',\n );\n throw new Error(\n \"Looks like there is no GitHub Integration in config. Please add a configuration entry under 'integrations.github\",\n );\n }\n return ghConfigs;\n}\n\nexport async function getCredentialsFromIntegrations(\n githubCredentialsProvider: CustomGithubCredentialsProvider,\n ghConfigs: GithubIntegrationConfig[],\n) {\n const credentialsByConfig = new Map<\n GithubIntegrationConfig,\n ExtendedGithubCredentials[]\n >();\n for (const ghConfig of ghConfigs) {\n const creds = await getCredentialsForConfig(\n githubCredentialsProvider,\n ghConfig,\n );\n credentialsByConfig.set(ghConfig, creds);\n }\n return credentialsByConfig;\n}\n\nexport async function getCredentialsForConfig(\n githubCredentialsProvider: CustomGithubCredentialsProvider,\n ghConfig: GithubIntegrationConfig,\n) {\n return await githubCredentialsProvider.getAllCredentials({\n host: ghConfig.host,\n });\n}\n\nexport async function extractConfigAndCreds(\n githubCredentialsProvider: CustomGithubCredentialsProvider,\n integrations: ScmIntegrations,\n input: {\n repoUrl: string;\n defaultBranch?: string;\n },\n) {\n const ghConfig = integrations.github.byUrl(input.repoUrl)?.config;\n if (!ghConfig) {\n throw new Error(`Could not find GH integration from ${input.repoUrl}`);\n }\n\n const credentials = await githubCredentialsProvider.getAllCredentials({\n host: ghConfig.host,\n });\n if (credentials.length === 0) {\n throw new Error(`No credentials for GH integration`);\n }\n\n const gitUrl = gitUrlParse(input.repoUrl);\n return { ghConfig, credentials, gitUrl };\n}\n\nexport function handleError(\n deps: {\n logger: LoggerService;\n },\n desc: string,\n credential: ExtendedGithubCredentials,\n errors: Map<number, GithubFetchError>,\n err: any,\n) {\n logErrorIfNeeded(deps.logger, `${desc} failed`, err);\n const credentialError = createCredentialError(credential, err as Error);\n if (credentialError) {\n errors.set(-1, credentialError);\n }\n}\n\nexport async function computeTotalCountFromGitHubToken(\n deps: {\n logger: LoggerService;\n },\n lastPageDataLengthProviderFn: (lastPageNumber: number) => Promise<number>,\n ghApiName: string,\n pageSize?: number,\n linkHeader?: string,\n): Promise<number | undefined> {\n // There is no direct way to get the total count of repositories other than using octokit.paginate,\n // but will make us retrieve all pages, thus increasing our response time.\n // Workaround here is to analyze the headers, and get the link to the last page.\n if (!linkHeader) {\n deps.logger.debug(\n `No link header found in response from ${ghApiName} GH endpoint => returning current page size`,\n );\n return pageSize;\n }\n const lastPageLink = linkHeader\n .split(',')\n .find(s => s.includes('rel=\"last\"'));\n if (!lastPageLink) {\n deps.logger.debug(\n `No rel='last' link found in response headers from ${ghApiName} GH endpoint => returning current page size`,\n );\n return pageSize;\n }\n const match = lastPageLink.match(/page=(\\d+)/);\n if (!match || match.length < 2) {\n deps.logger.debug(\n `Unable to extract page number from rel='last' link found in response headers from ${ghApiName} GH endpoint => returning current page size`,\n );\n return pageSize;\n }\n\n const lastPageNumber = parseInt(match[1], 10);\n // Fetch the last page to count its items, as it might contain fewer than the requested size\n const lastPageDataLength = await lastPageDataLengthProviderFn(lastPageNumber);\n return pageSize\n ? (lastPageNumber - 1) * pageSize + lastPageDataLength\n : undefined;\n}\n\nexport async function executeFunctionOnFirstSuccessfulIntegration<T>(\n deps: {\n logger: LoggerService;\n cache: CacheService;\n config: Config;\n githubCredentialsProvider: CustomGithubCredentialsProvider;\n },\n integrations: ScmIntegrations,\n params: {\n repoUrl: string;\n fn: (\n validatedRepo: ValidatedRepo,\n octo: Octokit,\n ) => Promise<{ successful: boolean; result?: T }>;\n },\n) {\n const validatedRepo = await validateAndBuildRepoData(\n deps.githubCredentialsProvider,\n integrations,\n deps.config,\n params,\n );\n for (const credential of validatedRepo.credentials) {\n const octo = buildOcto(\n {\n logger: deps.logger,\n cache: deps.cache,\n },\n { credential, owner: validatedRepo.owner },\n validatedRepo.ghConfig.apiBaseUrl,\n );\n if (!octo) {\n continue;\n }\n const res = await params.fn(validatedRepo, octo);\n if (!res.successful) {\n continue;\n }\n return res.result;\n }\n return undefined;\n}\n\nexport async function fetchFromAllIntegrations<T>(\n deps: {\n logger: LoggerService;\n cache: CacheService;\n githubCredentialsProvider: CustomGithubCredentialsProvider;\n },\n integrations: ScmIntegrations,\n params: {\n dataFetcher: (\n octo: Octokit,\n credential: ExtendedGithubCredentials,\n ghConfig: GithubIntegrationConfig,\n ) => Promise<{\n stopFetchingData?: boolean;\n result?: T;\n errors?: GithubFetchError[];\n }>;\n },\n) {\n const ghConfigs = verifyAndGetIntegrations(deps, integrations);\n\n const credentialsByConfig = await getCredentialsFromIntegrations(\n deps.githubCredentialsProvider,\n ghConfigs,\n );\n const errors = new Map<number, GithubFetchError>();\n const data: T[] = [];\n const dataErrs: GithubFetchError[] = [];\n let stopFetchingData: boolean | undefined = false;\n for (const [ghConfig, credentials] of credentialsByConfig) {\n if (stopFetchingData) {\n break;\n }\n deps.logger.debug(\n `Got ${credentials.length} credential(s) for ${ghConfig.host}`,\n );\n for (const credential of credentials) {\n const octokit = buildOcto(\n deps,\n { credential, errors },\n ghConfig.apiBaseUrl,\n );\n if (!octokit) {\n continue;\n }\n const res = await params.dataFetcher(octokit, credential, ghConfig);\n res.errors?.forEach(err => dataErrs.push(err));\n\n if (res.result) {\n data.push(res.result);\n }\n\n stopFetchingData = res.stopFetchingData;\n }\n }\n\n const aggregatedErrors = new Map<number, GithubFetchError>();\n errors.forEach((err, num) => aggregatedErrors.set(num, err));\n dataErrs.forEach((err, idx) => aggregatedErrors.set(idx, err));\n\n return { data, errors: aggregatedErrors };\n}\n\nexport async function fetchFromMatchedIntegration<T>(\n deps: {\n logger: LoggerService;\n cache: CacheService;\n githubCredentialsProvider: CustomGithubCredentialsProvider;\n },\n integrations: ScmIntegrations,\n repoUrl: string,\n fetcher: (\n octokit: Octokit,\n gitUrl: gitUrlParse.GitUrl,\n ) => Promise<T | undefined>,\n): Promise<{ data?: T; errors: GithubFetchError[] }> {\n const gitUrl = gitUrlParse(repoUrl);\n const errors = new Map<number, GithubFetchError>();\n\n const ghConfig = integrations.github.byUrl(repoUrl)?.config;\n if (!ghConfig) {\n throw new Error(\n `No GitHub integration config found for repo ${repoUrl}. Please add a configuration entry under 'integrations.github'`,\n );\n }\n\n const credentials = await getCredentialsForConfig(\n deps.githubCredentialsProvider,\n ghConfig,\n );\n\n for (const credential of credentials) {\n const octokit = buildOcto(\n {\n logger: deps.logger,\n cache: deps.cache,\n },\n { credential, errors, owner: gitUrl.owner },\n ghConfig.apiBaseUrl,\n );\n if (!octokit) {\n continue;\n }\n const data = await fetcher(octokit, gitUrl);\n if (data) {\n return { data, errors: Array.from(errors.values()) };\n }\n }\n\n return { errors: Array.from(errors.values()) };\n}\n"],"names":["isGithubAppCredential","logErrorIfNeeded","validateAndBuildRepoData","buildOcto","gitUrlParse"],"mappings":"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"}
@@ -0,0 +1,54 @@
1
+ 'use strict';
2
+
3
+ class CustomSingleInstanceGitlabCredentialsProvider {
4
+ constructor(token) {
5
+ this.token = token;
6
+ }
7
+ static create = (config) => {
8
+ return new CustomSingleInstanceGitlabCredentialsProvider(config.token);
9
+ };
10
+ async getAllCredentials(_opts) {
11
+ const credentials = [];
12
+ if (this.token) {
13
+ credentials.push({
14
+ headers: { Authorization: `Bearer ${this.token}` },
15
+ token: this.token
16
+ });
17
+ }
18
+ return credentials;
19
+ }
20
+ getCredentials(_opts) {
21
+ throw new Error("Method not implemented.");
22
+ }
23
+ }
24
+ class CustomGitlabCredentialsProvider {
25
+ constructor(providers) {
26
+ this.providers = providers;
27
+ }
28
+ static fromIntegrations(integrations) {
29
+ const credentialsProviders = /* @__PURE__ */ new Map();
30
+ integrations.gitlab.list().forEach((integration) => {
31
+ const credtialsProvider = CustomSingleInstanceGitlabCredentialsProvider.create(
32
+ integration.config
33
+ );
34
+ credentialsProviders.set(integration.config.host, credtialsProvider);
35
+ });
36
+ return new CustomGitlabCredentialsProvider(credentialsProviders);
37
+ }
38
+ async getAllCredentials(opts) {
39
+ const provider = this.providers.get(opts.host);
40
+ if (!provider) {
41
+ throw new Error(
42
+ `There is no GitLab integration that matches ${opts.host}. Please add a configuration for an integration.`
43
+ );
44
+ }
45
+ return provider.getAllCredentials(opts);
46
+ }
47
+ getCredentials(_opts) {
48
+ throw new Error("Method not implemented.");
49
+ }
50
+ }
51
+
52
+ exports.CustomGitlabCredentialsProvider = CustomGitlabCredentialsProvider;
53
+ exports.CustomSingleInstanceGitlabCredentialsProvider = CustomSingleInstanceGitlabCredentialsProvider;
54
+ //# sourceMappingURL=GitlabAppManager.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GitlabAppManager.cjs.js","sources":["../../src/gitlab/GitlabAppManager.ts"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\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 */\nimport type {\n GitlabCredentials,\n GitLabIntegrationConfig,\n ScmIntegrationRegistry,\n} from '@backstage/integration';\n\nimport {\n ExtendedGitlabCredentials,\n ExtendedGitlabCredentialsProvider,\n} from './types';\n\n// For reference\n// https://github.com/backstage/backstage/blob/master/packages/integration/src/gitlab/SingleInstanceGitlabCredentialsProvider.ts\n\nexport class CustomSingleInstanceGitlabCredentialsProvider\n implements ExtendedGitlabCredentialsProvider\n{\n static readonly create: (\n config: GitLabIntegrationConfig,\n ) => ExtendedGitlabCredentialsProvider = config => {\n return new CustomSingleInstanceGitlabCredentialsProvider(config.token);\n };\n\n private constructor(private readonly token?: string) {}\n async getAllCredentials(_opts: {\n host: string;\n }): Promise<ExtendedGitlabCredentials[]> {\n const credentials: ExtendedGitlabCredentials[] = [];\n if (this.token) {\n credentials.push({\n headers: { Authorization: `Bearer ${this.token}` },\n token: this.token,\n });\n }\n return credentials;\n }\n getCredentials(_opts: { url: string }): Promise<GitlabCredentials> {\n throw new Error('Method not implemented.');\n }\n}\n\nexport class CustomGitlabCredentialsProvider\n implements ExtendedGitlabCredentialsProvider\n{\n static fromIntegrations(integrations: ScmIntegrationRegistry) {\n const credentialsProviders: Map<string, ExtendedGitlabCredentialsProvider> =\n new Map<string, ExtendedGitlabCredentialsProvider>();\n\n integrations.gitlab.list().forEach(integration => {\n const credtialsProvider =\n CustomSingleInstanceGitlabCredentialsProvider.create(\n integration.config,\n );\n credentialsProviders.set(integration.config.host, credtialsProvider);\n });\n\n return new CustomGitlabCredentialsProvider(credentialsProviders);\n }\n\n private constructor(\n private readonly providers: Map<string, ExtendedGitlabCredentialsProvider>,\n ) {}\n async getAllCredentials(opts: {\n host: string;\n }): Promise<ExtendedGitlabCredentials[]> {\n const provider = this.providers.get(opts.host);\n\n if (!provider) {\n throw new Error(\n `There is no GitLab integration that matches ${opts.host}. Please add a configuration for an integration.`,\n );\n }\n return provider.getAllCredentials(opts);\n }\n getCredentials(_opts: { url: string }): Promise<GitlabCredentials> {\n throw new Error('Method not implemented.');\n }\n}\n"],"names":[],"mappings":";;AA6BO,MAAM,6CAEb,CAAA;AAAA,EAOU,YAA6B,KAAgB,EAAA;AAAhB,IAAA,IAAA,CAAA,KAAA,GAAA,KAAA;AAAA;AAAiB,EANtD,OAAgB,SAEyB,CAAU,MAAA,KAAA;AACjD,IAAO,OAAA,IAAI,6CAA8C,CAAA,MAAA,CAAO,KAAK,CAAA;AAAA,GACvE;AAAA,EAGA,MAAM,kBAAkB,KAEiB,EAAA;AACvC,IAAA,MAAM,cAA2C,EAAC;AAClD,IAAA,IAAI,KAAK,KAAO,EAAA;AACd,MAAA,WAAA,CAAY,IAAK,CAAA;AAAA,QACf,SAAS,EAAE,aAAA,EAAe,CAAU,OAAA,EAAA,IAAA,CAAK,KAAK,CAAG,CAAA,EAAA;AAAA,QACjD,OAAO,IAAK,CAAA;AAAA,OACb,CAAA;AAAA;AAEH,IAAO,OAAA,WAAA;AAAA;AACT,EACA,eAAe,KAAoD,EAAA;AACjE,IAAM,MAAA,IAAI,MAAM,yBAAyB,CAAA;AAAA;AAE7C;AAEO,MAAM,+BAEb,CAAA;AAAA,EAgBU,YACW,SACjB,EAAA;AADiB,IAAA,IAAA,CAAA,SAAA,GAAA,SAAA;AAAA;AAChB,EAjBH,OAAO,iBAAiB,YAAsC,EAAA;AAC5D,IAAM,MAAA,oBAAA,uBACA,GAA+C,EAAA;AAErD,IAAA,YAAA,CAAa,MAAO,CAAA,IAAA,EAAO,CAAA,OAAA,CAAQ,CAAe,WAAA,KAAA;AAChD,MAAA,MAAM,oBACJ,6CAA8C,CAAA,MAAA;AAAA,QAC5C,WAAY,CAAA;AAAA,OACd;AACF,MAAA,oBAAA,CAAqB,GAAI,CAAA,WAAA,CAAY,MAAO,CAAA,IAAA,EAAM,iBAAiB,CAAA;AAAA,KACpE,CAAA;AAED,IAAO,OAAA,IAAI,gCAAgC,oBAAoB,CAAA;AAAA;AACjE,EAKA,MAAM,kBAAkB,IAEiB,EAAA;AACvC,IAAA,MAAM,QAAW,GAAA,IAAA,CAAK,SAAU,CAAA,GAAA,CAAI,KAAK,IAAI,CAAA;AAE7C,IAAA,IAAI,CAAC,QAAU,EAAA;AACb,MAAA,MAAM,IAAI,KAAA;AAAA,QACR,CAAA,4CAAA,EAA+C,KAAK,IAAI,CAAA,gDAAA;AAAA,OAC1D;AAAA;AAEF,IAAO,OAAA,QAAA,CAAS,kBAAkB,IAAI,CAAA;AAAA;AACxC,EACA,eAAe,KAAoD,EAAA;AACjE,IAAM,MAAA,IAAI,MAAM,yBAAyB,CAAA;AAAA;AAE7C;;;;;"}