@red-hat-developer-hub/backstage-plugin-bulk-import-backend 7.2.0 → 7.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +51 -0
- package/README.md +41 -4
- package/dist/database/repositoryDao.cjs.js +6 -0
- package/dist/database/repositoryDao.cjs.js.map +1 -1
- package/dist/generated/openapidocument.cjs.js +89 -0
- package/dist/generated/openapidocument.cjs.js.map +1 -1
- package/dist/github/GithubAppManager.cjs.js +3 -0
- package/dist/github/GithubAppManager.cjs.js.map +1 -1
- package/dist/github/githubApiService.cjs.js +140 -144
- package/dist/github/githubApiService.cjs.js.map +1 -1
- package/dist/github/types.cjs.js.map +1 -1
- package/dist/github/utils/ghUtils.cjs.js +3 -3
- package/dist/github/utils/ghUtils.cjs.js.map +1 -1
- package/dist/github/utils/repoUtils.cjs.js +53 -99
- package/dist/github/utils/repoUtils.cjs.js.map +1 -1
- package/dist/gitlab/GitlabAppManager.cjs.js +2 -0
- package/dist/gitlab/GitlabAppManager.cjs.js.map +1 -1
- package/dist/gitlab/gitlabApiService.cjs.js +65 -8
- package/dist/gitlab/gitlabApiService.cjs.js.map +1 -1
- package/dist/gitlab/utils/glUtils.cjs.js +1 -1
- package/dist/gitlab/utils/glUtils.cjs.js.map +1 -1
- package/dist/gitlab/utils/repoUtils.cjs.js +32 -57
- package/dist/gitlab/utils/repoUtils.cjs.js.map +1 -1
- package/dist/service/handlers/import/bulkImports.cjs.js +14 -6
- package/dist/service/handlers/import/bulkImports.cjs.js.map +1 -1
- package/dist/service/handlers/import/importStatus.cjs.js.map +1 -1
- package/dist/service/handlers/organization/organizations.cjs.js +2 -2
- package/dist/service/handlers/organization/organizations.cjs.js.map +1 -1
- package/dist/service/handlers/repository/repositories.cjs.js +41 -6
- package/dist/service/handlers/repository/repositories.cjs.js.map +1 -1
- package/dist/service/handlers/scm/scm.cjs.js +16 -0
- package/dist/service/handlers/scm/scm.cjs.js.map +1 -0
- package/dist/service/router.cjs.js +81 -9
- package/dist/service/router.cjs.js.map +1 -1
- package/package.json +16 -16
|
@@ -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 AppInstallationRepositories,\n AuthenticatedUserRepositoryList,\n ExtendedGithubCredentials,\n GithubAppCredentials,\n GithubFetchError,\n GithubRepository,\n} from '../types';\nimport {\n computeTotalCountFromGitHubToken,\n createCredentialError,\n handleError,\n} from './utils';\n\nconst GITHUB_REST_API_MAX_PAGE_SIZE = 100;\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 repositories: Map<string, GithubRepository>,\n errors: Map<number, GithubFetchError>,\n reqParams?: {\n search?: string;\n },\n): Promise<{ totalCount?: number }> {\n const lowercaseSearch = reqParams?.search?.toLocaleLowerCase();\n let totalCount: number | undefined;\n\n try {\n const { repositories: allRepositories } =\n await listAllRepositoriesAccessibleToInstallation(octokit);\n\n const filteredRepositories = lowercaseSearch\n ? allRepositories.filter(repo =>\n repo.name.toLocaleLowerCase().includes(lowercaseSearch),\n )\n : allRepositories;\n\n filteredRepositories.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 = filteredRepositories.length;\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 },\n): Promise<{ totalCount?: number }> {\n const lowercaseSearch = reqParams?.search?.toLocaleLowerCase();\n let totalCount: number | undefined;\n\n try {\n const allRepositories =\n await listAllRepositoriesForAuthenticatedUser(octokit);\n\n const filteredRepositories = lowercaseSearch\n ? allRepositories.filter(repo =>\n repo.name.toLocaleLowerCase().includes(lowercaseSearch),\n )\n : allRepositories;\n\n filteredRepositories.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 = filteredRepositories.length;\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\nasync function listAllRepositoriesForAuthenticatedUser(\n octokit: Octokit,\n): Promise<AuthenticatedUserRepositoryList> {\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 return await octokit.paginate(octokit.rest.repos.listForAuthenticatedUser, {\n per_page: GITHUB_REST_API_MAX_PAGE_SIZE,\n sort: 'full_name',\n direction: 'asc',\n });\n}\n\nasync function listAllRepositoriesAccessibleToInstallation(\n octokit: Octokit,\n): Promise<AppInstallationRepositories> {\n /**\n * The octokit pagination smartly extracts data from the response.\n * Here, repositories array is extracted from the original listReposAccessibleToInstallation.\n */\n const repositories = await octokit.paginate(\n octokit.rest.apps.listReposAccessibleToInstallation,\n {\n per_page: GITHUB_REST_API_MAX_PAGE_SIZE,\n },\n );\n\n return {\n repositories,\n total_count: repositories.length,\n repository_selection: repositories.repository_selection ?? 'all',\n };\n}\n"],"names":["gitUrlParse","getBranchName","DefaultPageNumber","DefaultPageSize","logErrorIfNeeded","createCredentialError","handleError","computeTotalCountFromGitHubToken"],"mappings":"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"}
|
|
@@ -4,6 +4,7 @@ class CustomSingleInstanceGitlabCredentialsProvider {
|
|
|
4
4
|
constructor(token) {
|
|
5
5
|
this.token = token;
|
|
6
6
|
}
|
|
7
|
+
token;
|
|
7
8
|
static create = (config) => {
|
|
8
9
|
return new CustomSingleInstanceGitlabCredentialsProvider(config.token);
|
|
9
10
|
};
|
|
@@ -25,6 +26,7 @@ class CustomGitlabCredentialsProvider {
|
|
|
25
26
|
constructor(providers) {
|
|
26
27
|
this.providers = providers;
|
|
27
28
|
}
|
|
29
|
+
providers;
|
|
28
30
|
static fromIntegrations(integrations) {
|
|
29
31
|
const credentialsProviders = /* @__PURE__ */ new Map();
|
|
30
32
|
integrations.gitlab.list().forEach((integration) => {
|
|
@@ -1 +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 implements ExtendedGitlabCredentialsProvider {\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 implements ExtendedGitlabCredentialsProvider {\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,6CAAA,CAA2F;AAAA,EAO9F,YAA6B,KAAA,EAAgB;AAAhB,IAAA,IAAA,CAAA,KAAA,GAAA,KAAA;AAAA,EAAiB;AAAA,
|
|
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 implements ExtendedGitlabCredentialsProvider {\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 implements ExtendedGitlabCredentialsProvider {\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,6CAAA,CAA2F;AAAA,EAO9F,YAA6B,KAAA,EAAgB;AAAhB,IAAA,IAAA,CAAA,KAAA,GAAA,KAAA;AAAA,EAAiB;AAAA,EAAjB,KAAA;AAAA,EANrC,OAAgB,SAEyB,CAAA,MAAA,KAAU;AACjD,IAAA,OAAO,IAAI,6CAAA,CAA8C,MAAA,CAAO,KAAK,CAAA;AAAA,EACvE,CAAA;AAAA,EAGA,MAAM,kBAAkB,KAAA,EAEiB;AACvC,IAAA,MAAM,cAA2C,EAAC;AAClD,IAAA,IAAI,KAAK,KAAA,EAAO;AACd,MAAA,WAAA,CAAY,IAAA,CAAK;AAAA,QACf,SAAS,EAAE,aAAA,EAAe,CAAA,OAAA,EAAU,IAAA,CAAK,KAAK,CAAA,CAAA,EAAG;AAAA,QACjD,OAAO,IAAA,CAAK;AAAA,OACb,CAAA;AAAA,IACH;AACA,IAAA,OAAO,WAAA;AAAA,EACT;AAAA,EACA,eAAe,KAAA,EAAoD;AACjE,IAAA,MAAM,IAAI,MAAM,yBAAyB,CAAA;AAAA,EAC3C;AACF;AAEO,MAAM,+BAAA,CAA6E;AAAA,EAgBhF,YACW,SAAA,EACjB;AADiB,IAAA,IAAA,CAAA,SAAA,GAAA,SAAA;AAAA,EAChB;AAAA,EADgB,SAAA;AAAA,EAhBnB,OAAO,iBAAiB,YAAA,EAAsC;AAC5D,IAAA,MAAM,oBAAA,uBACA,GAAA,EAA+C;AAErD,IAAA,YAAA,CAAa,MAAA,CAAO,IAAA,EAAK,CAAE,OAAA,CAAQ,CAAA,WAAA,KAAe;AAChD,MAAA,MAAM,oBACJ,6CAAA,CAA8C,MAAA;AAAA,QAC5C,WAAA,CAAY;AAAA,OACd;AACF,MAAA,oBAAA,CAAqB,GAAA,CAAI,WAAA,CAAY,MAAA,CAAO,IAAA,EAAM,iBAAiB,CAAA;AAAA,IACrE,CAAC,CAAA;AAED,IAAA,OAAO,IAAI,gCAAgC,oBAAoB,CAAA;AAAA,EACjE;AAAA,EAKA,MAAM,kBAAkB,IAAA,EAEiB;AACvC,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,KAAK,IAAI,CAAA;AAE7C,IAAA,IAAI,CAAC,QAAA,EAAU;AACb,MAAA,MAAM,IAAI,KAAA;AAAA,QACR,CAAA,4CAAA,EAA+C,KAAK,IAAI,CAAA,gDAAA;AAAA,OAC1D;AAAA,IACF;AACA,IAAA,OAAO,QAAA,CAAS,kBAAkB,IAAI,CAAA;AAAA,EACxC;AAAA,EACA,eAAe,KAAA,EAAoD;AACjE,IAAA,MAAM,IAAI,MAAM,yBAAyB,CAAA;AAAA,EAC3C;AACF;;;;;"}
|
|
@@ -26,7 +26,7 @@ class GitlabApiService {
|
|
|
26
26
|
integrations;
|
|
27
27
|
gitlabCredentialsProvider;
|
|
28
28
|
config;
|
|
29
|
-
// Cache for storing ETags (used for efficient caching of unchanged data returned by
|
|
29
|
+
// Cache for storing ETags (used for efficient caching of unchanged data returned by GitLab)
|
|
30
30
|
cache;
|
|
31
31
|
constructor(logger, config, cacheService) {
|
|
32
32
|
this.logger = logger;
|
|
@@ -90,7 +90,7 @@ class GitlabApiService {
|
|
|
90
90
|
errors: []
|
|
91
91
|
};
|
|
92
92
|
}
|
|
93
|
-
async getOrganizationsFromIntegrations(
|
|
93
|
+
async getOrganizationsFromIntegrations(pageNumber = handlers.DefaultPageNumber, pageSize = handlers.DefaultPageSize, search) {
|
|
94
94
|
const groups = /* @__PURE__ */ new Map();
|
|
95
95
|
const result = await utils.fetchFromAllIntegrations(
|
|
96
96
|
{
|
|
@@ -134,8 +134,48 @@ class GitlabApiService {
|
|
|
134
134
|
totalCount
|
|
135
135
|
};
|
|
136
136
|
}
|
|
137
|
-
async
|
|
137
|
+
async fetchUserTokenGitlabIntegrationRepositories(userTokens, fetcher) {
|
|
138
|
+
const allErrors = [];
|
|
139
|
+
let totalCount;
|
|
140
|
+
const glConfigs = this.integrations.gitlab.list().map((i) => i.config);
|
|
141
|
+
for (const glConfig of glConfigs) {
|
|
142
|
+
const normalizedBase = glConfig.baseUrl.replace(/\/$/, "");
|
|
143
|
+
const token = userTokens[normalizedBase] ?? userTokens[`https://${glConfig.host}`];
|
|
144
|
+
if (!token) {
|
|
145
|
+
continue;
|
|
146
|
+
}
|
|
147
|
+
const userCredential = { token };
|
|
148
|
+
const userGitlab = glUtils.buildGitlab(
|
|
149
|
+
{ logger: this.logger, cache: this.cache },
|
|
150
|
+
{ credential: userCredential },
|
|
151
|
+
glConfig.baseUrl
|
|
152
|
+
// NOTE: baseUrl, NOT apiBaseUrl (Gitlab constructor takes the base, not /api/v4)
|
|
153
|
+
);
|
|
154
|
+
const dataFetchErrors = /* @__PURE__ */ new Map();
|
|
155
|
+
const result = await fetcher(userGitlab, userCredential, dataFetchErrors);
|
|
156
|
+
totalCount = (totalCount ?? 0) + (result.totalCount ?? 0);
|
|
157
|
+
dataFetchErrors.forEach((err) => allErrors.push(err));
|
|
158
|
+
}
|
|
159
|
+
return { errors: allErrors, totalCount };
|
|
160
|
+
}
|
|
161
|
+
async getOrgRepositoriesFromIntegrations(orgName, search, pageNumber = handlers.DefaultPageNumber, pageSize = handlers.DefaultPageSize, userTokens) {
|
|
138
162
|
const orgRepositories = /* @__PURE__ */ new Map();
|
|
163
|
+
if (userTokens && Object.keys(userTokens).length > 0) {
|
|
164
|
+
const { errors: allErrors, totalCount: totalCount2 } = await this.fetchUserTokenGitlabIntegrationRepositories(
|
|
165
|
+
userTokens,
|
|
166
|
+
(userGitlab, userCredential, dataFetchErrors) => repoUtils.addGitlabTokenOrgRepositories(
|
|
167
|
+
{ logger: this.logger },
|
|
168
|
+
userGitlab,
|
|
169
|
+
userCredential,
|
|
170
|
+
orgName,
|
|
171
|
+
orgRepositories,
|
|
172
|
+
dataFetchErrors,
|
|
173
|
+
{ search, pageNumber, pageSize }
|
|
174
|
+
)
|
|
175
|
+
);
|
|
176
|
+
const repoList2 = Array.from(orgRepositories.values());
|
|
177
|
+
return { repositories: repoList2, errors: allErrors, totalCount: totalCount2 };
|
|
178
|
+
}
|
|
139
179
|
const result = await utils.fetchFromAllIntegrations(
|
|
140
180
|
{
|
|
141
181
|
logger: this.logger,
|
|
@@ -185,8 +225,23 @@ class GitlabApiService {
|
|
|
185
225
|
* - a list of unique repositories the gitlab integrations have access to
|
|
186
226
|
* - a list of errors encountered by each token (if any exist)
|
|
187
227
|
*/
|
|
188
|
-
async getRepositoriesFromIntegrations(search,
|
|
228
|
+
async getRepositoriesFromIntegrations(search, userTokens) {
|
|
189
229
|
const repositories = /* @__PURE__ */ new Map();
|
|
230
|
+
if (userTokens && Object.keys(userTokens).length > 0) {
|
|
231
|
+
const { errors: allErrors, totalCount: totalCount2 } = await this.fetchUserTokenGitlabIntegrationRepositories(
|
|
232
|
+
userTokens,
|
|
233
|
+
(userGitlab, userCredential, dataFetchErrors) => repoUtils.addGitlabTokenRepositories(
|
|
234
|
+
{ logger: this.logger },
|
|
235
|
+
userGitlab,
|
|
236
|
+
userCredential,
|
|
237
|
+
repositories,
|
|
238
|
+
dataFetchErrors,
|
|
239
|
+
{ search }
|
|
240
|
+
)
|
|
241
|
+
);
|
|
242
|
+
const repoList2 = Array.from(repositories.values());
|
|
243
|
+
return { repositories: repoList2, errors: allErrors, totalCount: totalCount2 };
|
|
244
|
+
}
|
|
190
245
|
const result = await utils.fetchFromAllIntegrations(
|
|
191
246
|
{
|
|
192
247
|
logger: this.logger,
|
|
@@ -206,9 +261,7 @@ class GitlabApiService {
|
|
|
206
261
|
repositories,
|
|
207
262
|
dataFetchErrors,
|
|
208
263
|
{
|
|
209
|
-
search
|
|
210
|
-
pageNumber,
|
|
211
|
-
pageSize
|
|
264
|
+
search
|
|
212
265
|
}
|
|
213
266
|
);
|
|
214
267
|
this.logger.debug(
|
|
@@ -222,7 +275,11 @@ class GitlabApiService {
|
|
|
222
275
|
}
|
|
223
276
|
);
|
|
224
277
|
const repoList = Array.from(repositories.values());
|
|
225
|
-
const totalCount = utils$1.computeTotalCount(
|
|
278
|
+
const totalCount = utils$1.computeTotalCount(
|
|
279
|
+
repoList,
|
|
280
|
+
result.data,
|
|
281
|
+
handlers.DefaultPageSize
|
|
282
|
+
);
|
|
226
283
|
return {
|
|
227
284
|
repositories: repoList,
|
|
228
285
|
errors: Array.from(result.errors?.values() ?? []),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gitlabApiService.cjs.js","sources":["../../src/gitlab/gitlabApiService.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 DefaultGitlabCredentialsProvider,\n GitLabIntegrationConfig,\n ScmIntegrations,\n} from '@backstage/integration';\n\nimport { Gitlab } from '@gitbeaker/rest';\nimport gitUrlParse from 'git-url-parse';\n\nimport { getBranchName, getCatalogFilename } from '../catalog/catalogUtils';\nimport {\n computeTotalCount,\n extractLocationOwnerMap,\n logErrorIfNeeded,\n} from '../helpers';\nimport {\n DefaultPageNumber,\n DefaultPageSize,\n} from '../service/handlers/handlers';\nimport { CustomGitlabCredentialsProvider } from './GitlabAppManager';\nimport {\n ExtendedGitlabCredentials,\n GitlabFetchError,\n GitlabOrganization,\n GitlabOrganizationResponse,\n GitlabRepository,\n GitlabRepositoryResponse,\n} from './types';\nimport { buildGitlab } from './utils/glUtils';\nimport { addGitlabTokenGroups } from './utils/orgUtils';\nimport { closePRWithComment, findOpenPRForBranch } from './utils/prUtils';\nimport {\n addGitlabTokenOrgRepositories,\n addGitlabTokenRepositories,\n createOrUpdateFileInBranch,\n fileExistsInDefaultBranch,\n ValidatedRepo,\n} from './utils/repoUtils';\nimport {\n executeFunctionOnFirstSuccessfulIntegration,\n fetchFromAllIntegrations,\n getCredentialsForConfig,\n} from './utils/utils';\n\nexport class GitlabApiService {\n private readonly logger: LoggerService;\n private readonly integrations: ScmIntegrations;\n private readonly gitlabCredentialsProvider: CustomGitlabCredentialsProvider;\n private readonly config: Config;\n // Cache for storing ETags (used for efficient caching of unchanged data returned by GitHub)\n private readonly cache: CacheService;\n constructor(\n logger: LoggerService,\n config: Config,\n cacheService: CacheService,\n ) {\n this.logger = logger;\n this.config = config;\n this.integrations = ScmIntegrations.fromConfig(config);\n this.gitlabCredentialsProvider =\n CustomGitlabCredentialsProvider.fromIntegrations(this.integrations);\n this.cache = cacheService;\n }\n\n async getCredentials(repoUrl: string): Promise<{ token: string }> {\n const provider = DefaultGitlabCredentialsProvider.fromIntegrations(\n this.integrations,\n );\n const creds = await provider.getCredentials({\n url: repoUrl,\n });\n if (!creds || !creds.token) {\n throw new Error(`Token not configured for 'gitlab' provider`);\n }\n return {\n token: creds.token,\n };\n }\n\n async getRepositoryFromIntegrations(repoUrl: string): Promise<{\n repository?: GitlabRepository;\n errors?: GitlabFetchError[];\n }> {\n const gitUrl = gitUrlParse(repoUrl);\n\n const glConfig = this.integrations.gitlab.byUrl(repoUrl)?.config;\n if (!glConfig) {\n throw new Error(\n `No Gitlab integration config found for repo ${repoUrl}. Please add a configuration entry under 'integrations.gitlab`,\n );\n }\n\n const credentials = await getCredentialsForConfig(\n this.gitlabCredentialsProvider,\n glConfig,\n );\n let repository: GitlabRepository | undefined = undefined;\n for (const credential of credentials) {\n const glKit = buildGitlab(\n {\n logger: this.logger,\n cache: this.cache,\n },\n { credential, owner: gitUrl.owner },\n glConfig.baseUrl,\n );\n const repo = await glKit.Projects.show(`${gitUrl.owner}/${gitUrl.name}`);\n if (!repo) {\n continue;\n }\n repository = {\n name: repo.name,\n full_name: repo.path_with_namespace,\n url: repo._links.self,\n html_url: repo.web_url,\n default_branch: repo.default_branch,\n updated_at: repo.updated_at,\n };\n break;\n }\n\n return {\n repository,\n errors: [],\n };\n }\n\n async getOrganizationsFromIntegrations(\n search?: string,\n pageNumber: number = DefaultPageNumber,\n pageSize: number = DefaultPageSize,\n ): Promise<GitlabOrganizationResponse> {\n const groups = new Map<string, GitlabOrganization>();\n const result = await fetchFromAllIntegrations(\n {\n logger: this.logger,\n cache: this.cache,\n gitlabCredentialsProvider: this.gitlabCredentialsProvider,\n },\n this.integrations,\n {\n dataFetcher: async (\n glApi: InstanceType<typeof Gitlab<false>>,\n credential: ExtendedGitlabCredentials,\n glConfig: GitLabIntegrationConfig,\n ) => {\n const dataFetchErrors = new Map<number, GitlabFetchError>();\n const resp = await addGitlabTokenGroups(\n {\n logger: this.logger,\n },\n glApi,\n credential,\n {\n search,\n groups,\n pageNumber,\n pageSize,\n errors: dataFetchErrors,\n },\n );\n this.logger.debug(\n `Got ${resp.totalCount} groups(s) for ${glConfig.host}`,\n );\n return {\n result: resp.totalCount ?? 0,\n errors: Array.from(dataFetchErrors.values()),\n };\n },\n },\n );\n\n const groupList = Array.from(groups.values());\n const totalCount = computeTotalCount(groupList, result.data, pageSize);\n return {\n organizations: groupList,\n errors: Array.from(result.errors?.values() ?? []),\n totalCount,\n };\n }\n\n async getOrgRepositoriesFromIntegrations(\n orgName: string,\n search?: string,\n pageNumber: number = DefaultPageNumber,\n pageSize: number = DefaultPageSize,\n ): Promise<GitlabRepositoryResponse> {\n const orgRepositories = new Map<string, GitlabRepository>();\n const result = await fetchFromAllIntegrations(\n {\n logger: this.logger,\n cache: this.cache,\n gitlabCredentialsProvider: this.gitlabCredentialsProvider,\n },\n this.integrations,\n {\n dataFetcher: async (\n glApi: InstanceType<typeof Gitlab<false>>,\n credential: ExtendedGitlabCredentials,\n glConfig: GitLabIntegrationConfig,\n ) => {\n const dataFetchErrors = new Map<number, GitlabFetchError>();\n const resp = await addGitlabTokenOrgRepositories(\n {\n logger: this.logger,\n },\n glApi,\n credential,\n orgName,\n orgRepositories,\n dataFetchErrors,\n {\n search,\n pageNumber,\n pageSize,\n },\n );\n this.logger.debug(\n `Got ${resp.totalCount} org repo(s) for ${glConfig.host}`,\n );\n return {\n stopFetchingData: true,\n result: resp.totalCount ?? 0,\n errors: Array.from(dataFetchErrors.values()),\n };\n },\n },\n );\n\n const repoList = Array.from(orgRepositories.values());\n const totalCount = computeTotalCount(repoList, result.data, pageSize);\n return {\n repositories: repoList,\n errors: Array.from(result.errors?.values() ?? []),\n totalCount,\n };\n }\n\n /**\n * Returns GitlabRepositoryResponse containing:\n * - a list of unique repositories the gitlab integrations have access to\n * - a list of errors encountered by each token (if any exist)\n */\n async getRepositoriesFromIntegrations(\n search?: string,\n pageNumber: number = DefaultPageNumber,\n pageSize: number = DefaultPageSize,\n ): Promise<GitlabRepositoryResponse> {\n const repositories = new Map<string, GitlabRepository>();\n const result = await fetchFromAllIntegrations(\n {\n logger: this.logger,\n cache: this.cache,\n gitlabCredentialsProvider: this.gitlabCredentialsProvider,\n },\n this.integrations,\n {\n dataFetcher: async (\n glApi: InstanceType<typeof Gitlab<false>>,\n credential: ExtendedGitlabCredentials,\n glConfig: GitLabIntegrationConfig,\n ) => {\n const dataFetchErrors = new Map<number, GitlabFetchError>();\n const resp = await addGitlabTokenRepositories(\n {\n logger: this.logger,\n },\n glApi,\n credential,\n repositories,\n dataFetchErrors,\n {\n search,\n pageNumber,\n pageSize,\n },\n );\n this.logger.debug(\n `Got ${resp.totalCount} repo(s) for ${glConfig.host}`,\n );\n return {\n result: resp.totalCount ?? 0,\n errors: Array.from(dataFetchErrors.values()),\n };\n },\n },\n );\n\n const repoList = Array.from(repositories.values());\n const totalCount = computeTotalCount(repoList, result.data, pageSize);\n return {\n repositories: repoList,\n errors: Array.from(result.errors?.values() ?? []),\n totalCount,\n };\n }\n\n async filterLocationsAccessibleFromIntegrations(\n locationUrls: string[],\n ): Promise<string[]> {\n const locationGitOwnerMap = extractLocationOwnerMap(locationUrls);\n\n const allAccessibleTokenOrgs = new Set<string>();\n const allAccessibleUsernames = new Set<string>();\n await fetchFromAllIntegrations(\n {\n logger: this.logger,\n cache: this.cache,\n gitlabCredentialsProvider: this.gitlabCredentialsProvider,\n },\n this.integrations,\n {\n dataFetcher: async (gitlab: InstanceType<typeof Gitlab<false>>) => {\n // find authenticated gitlab owner...\n try {\n const username = (await gitlab.Users.showCurrentUser()).username;\n if (username) {\n allAccessibleUsernames.add(username);\n }\n } catch (err) {\n logErrorIfNeeded(\n this.logger,\n 'failed to fetch gitlab current user',\n err,\n );\n }\n\n // ... along with orgs accessible from the token auth\n try {\n const allGroups = await gitlab.Groups.all<false, 'offset'>({\n allAvailable: false,\n });\n allGroups\n .map(org => org.path)\n ?.forEach((orgName: string) =>\n allAccessibleTokenOrgs.add(orgName),\n );\n } catch (err) {\n logErrorIfNeeded(this.logger, 'failed to fetch gitlab groups', err);\n }\n\n return {};\n },\n },\n );\n\n return locationUrls.filter(loc => {\n if (!locationGitOwnerMap.has(loc)) {\n return false;\n }\n const owner = locationGitOwnerMap.get(loc)!;\n return (\n allAccessibleTokenOrgs.has(owner) || allAccessibleUsernames.has(owner)\n );\n });\n }\n\n async findImportOpenPr(\n logger: LoggerService,\n input: {\n repoUrl: string;\n includeCatalogInfoContent?: boolean;\n },\n ): Promise<{\n prNum?: number;\n prUrl?: string;\n prTitle?: string;\n prBody?: string;\n prCatalogInfoContent?: string;\n lastUpdate?: string;\n }> {\n const glConfig = this.integrations.gitlab.byUrl(input.repoUrl)?.config;\n if (!glConfig) {\n throw new Error(`Could not find GL 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 this.gitlabCredentialsProvider.getAllCredentials({\n host: glConfig.host,\n });\n if (credentials.length === 0) {\n throw new Error(`No credentials for GL integration`);\n }\n\n const branchName = getBranchName(this.config);\n for (const credential of credentials) {\n const glKit = buildGitlab(\n {\n logger: this.logger,\n cache: this.cache,\n },\n { credential, owner },\n glConfig.baseUrl,\n );\n try {\n return await findOpenPRForBranch(\n logger,\n this.config,\n glKit,\n owner,\n repo,\n branchName,\n input.includeCatalogInfoContent,\n );\n } catch (error: any) {\n logErrorIfNeeded(this.logger, 'Error fetching pull requests', error);\n }\n }\n return {};\n }\n\n async submitPrToRepo(\n logger: LoggerService,\n input: {\n repoUrl: string;\n gitUrl: gitUrlParse.GitUrl;\n defaultBranch?: string;\n prTitle: string;\n prBody: string;\n catalogInfoContent: string;\n },\n ): Promise<{\n prUrl?: string;\n prNumber?: number;\n hasChanges?: boolean;\n lastUpdate?: string;\n errors?: string[];\n }> {\n const fileName = getCatalogFilename(this.config);\n const errors: any[] = [];\n\n const result = await executeFunctionOnFirstSuccessfulIntegration(\n {\n logger: this.logger,\n cache: this.cache,\n config: this.config,\n gitlabCredentialsProvider: this.gitlabCredentialsProvider,\n },\n this.integrations,\n {\n repoUrl: input.repoUrl,\n fn: async (\n validatedRepo: ValidatedRepo,\n gitlab: InstanceType<typeof Gitlab<false>>,\n ): Promise<{\n successful: boolean;\n result?: {\n prUrl?: string;\n prNumber?: number;\n hasChanges?: boolean;\n lastUpdate?: string;\n };\n }> => {\n const { owner, repo, branchName } = validatedRepo;\n try {\n // Check if there is already a catalogInfo in the default branch\n const catalogInfoFileExists = await fileExistsInDefaultBranch(\n logger,\n gitlab,\n owner,\n repo,\n fileName,\n input.defaultBranch,\n );\n if (catalogInfoFileExists) {\n // No need to create a PR => component will be imported as is\n return {\n successful: true,\n result: {\n hasChanges: false,\n },\n };\n }\n\n const existingPrForBranch = await findOpenPRForBranch(\n logger,\n this.config,\n gitlab,\n owner,\n repo,\n branchName,\n );\n\n const repoData = await gitlab.Projects.show(`${owner}/${repo}`);\n\n const parentRef = await gitlab.Branches.show(\n `${owner}/${repo}`,\n repoData.default_branch,\n ); // This might not be neccesarry\n\n if (existingPrForBranch.prNum) {\n await createOrUpdateFileInBranch(\n gitlab,\n owner,\n repo,\n branchName,\n fileName,\n input.catalogInfoContent,\n );\n const pullRequestResponse = await gitlab.MergeRequests.edit(\n `${owner}/${repo}`,\n existingPrForBranch.prNum,\n {\n description: input.prBody,\n title: input.prTitle,\n targetBranch: repoData.default_branch,\n },\n );\n return {\n successful: true,\n result: {\n prNumber: existingPrForBranch.prNum,\n prUrl: pullRequestResponse.web_url,\n lastUpdate: pullRequestResponse.updated_at,\n },\n };\n }\n\n try {\n await gitlab.Branches.show(`${owner}/${repo}`, branchName);\n } catch (error: any) {\n if (error.cause.response.status === 404) {\n await gitlab.Branches.create(\n `${owner}/${repo}`,\n branchName,\n parentRef.name,\n );\n } else {\n throw error;\n }\n }\n\n // Might not be able to do this in the gitlab api\n // This is if the branch exists, but there wasn't a PR yet\n // if (branchExists) {\n // // update it in case it is outdated compared to the base branch\n // try {\n // await octo.repos.merge({\n // owner: owner,\n // repo: repo,\n // base: branchName,\n // head: repoData.data.default_branch,\n // });\n // } catch (error: any) {\n // logErrorIfNeeded(\n // this.logger,\n // `Could not merge default branch ${repoData.data.default_branch} into import branch ${branchName}`,\n // error,\n // );\n // }\n // }\n\n await createOrUpdateFileInBranch(\n gitlab,\n owner,\n repo,\n branchName,\n fileName,\n input.catalogInfoContent,\n );\n\n const pullRequestResponse = await gitlab.MergeRequests.create(\n `${owner}/${repo}`,\n branchName,\n repoData.default_branch,\n input.prTitle,\n {\n description: input.prBody,\n },\n );\n return {\n successful: true,\n result: {\n prNumber: pullRequestResponse.iid,\n prUrl: pullRequestResponse.web_url,\n lastUpdate: pullRequestResponse.updated_at,\n hasChanges: true,\n },\n };\n } catch (e: any) {\n logErrorIfNeeded(\n this.logger,\n `Couldn't create PR in ${input.repoUrl}`,\n e,\n );\n errors.push(e.message);\n return { successful: false };\n }\n },\n },\n );\n\n if (result) {\n return result;\n }\n\n logger.warn(\n `Tried all possible Gitlab credentials, but could not create PR in ${input.repoUrl}. Please try again later...`,\n );\n\n return {\n errors: errors,\n };\n }\n\n async hasFileInRepo(input: {\n repoUrl: string;\n defaultBranch?: string;\n fileName: string;\n }) {\n const fileExists = await executeFunctionOnFirstSuccessfulIntegration(\n {\n logger: this.logger,\n cache: this.cache,\n config: this.config,\n gitlabCredentialsProvider: this.gitlabCredentialsProvider,\n },\n this.integrations,\n {\n repoUrl: input.repoUrl,\n fn: async (\n validatedRepo: ValidatedRepo,\n gitlab: InstanceType<typeof Gitlab<false>>,\n ) => {\n const { owner, repo } = validatedRepo;\n const exists = await fileExistsInDefaultBranch(\n this.logger,\n gitlab,\n owner,\n repo,\n input.fileName,\n input.defaultBranch,\n );\n if (exists === undefined) {\n return { successful: false };\n }\n return { successful: true, result: exists };\n },\n },\n );\n\n if (fileExists === undefined) {\n throw new Error(\n `Could not determine if repo at ${input.repoUrl} already has a file named ${input.fileName} in its default branch (${input.defaultBranch})`,\n );\n }\n\n return fileExists;\n }\n\n async closeImportPR(\n logger: LoggerService,\n input: {\n repoUrl: string;\n gitUrl: gitUrlParse.GitUrl;\n comment: string;\n },\n ) {\n await executeFunctionOnFirstSuccessfulIntegration(\n {\n logger: this.logger,\n cache: this.cache,\n config: this.config,\n gitlabCredentialsProvider: this.gitlabCredentialsProvider,\n },\n this.integrations,\n {\n repoUrl: input.repoUrl,\n fn: async (\n validatedRepo: ValidatedRepo,\n gitlab: InstanceType<typeof Gitlab<false>>,\n ) => {\n const { owner, repo, branchName } = validatedRepo;\n try {\n const existingPrForBranch = await findOpenPRForBranch(\n logger,\n this.config,\n gitlab,\n owner,\n repo,\n branchName,\n );\n if (existingPrForBranch.prNum) {\n await closePRWithComment(\n gitlab,\n owner,\n repo,\n existingPrForBranch.prNum,\n input.comment,\n );\n }\n return { successful: true };\n } catch (e: any) {\n logErrorIfNeeded(\n this.logger,\n `Couldn't close PR in ${input.repoUrl}`,\n e,\n );\n return { successful: false };\n }\n },\n },\n );\n }\n\n async deleteImportBranch(input: {\n repoUrl: string;\n gitUrl: gitUrlParse.GitUrl;\n }) {\n await executeFunctionOnFirstSuccessfulIntegration(\n {\n logger: this.logger,\n cache: this.cache,\n config: this.config,\n gitlabCredentialsProvider: this.gitlabCredentialsProvider,\n },\n this.integrations,\n {\n repoUrl: input.repoUrl,\n fn: async (\n validatedRepo: ValidatedRepo,\n gitlab: InstanceType<typeof Gitlab<false>>,\n ) => {\n const { owner, repo, branchName } = validatedRepo;\n try {\n await gitlab.Branches.remove(`${owner}/${repo}`, branchName);\n return { successful: true };\n } catch (e: any) {\n logErrorIfNeeded(\n this.logger,\n `Couldn't close import PR and/or delete import branch in ${input.repoUrl}`,\n e,\n );\n return { successful: false };\n }\n },\n },\n );\n }\n\n async isRepoEmpty(input: { repoUrl: string }) {\n return await executeFunctionOnFirstSuccessfulIntegration(\n {\n logger: this.logger,\n cache: this.cache,\n config: this.config,\n gitlabCredentialsProvider: this.gitlabCredentialsProvider,\n },\n this.integrations,\n {\n repoUrl: input.repoUrl,\n fn: async (\n validatedRepo: ValidatedRepo,\n gitlab: InstanceType<typeof Gitlab<false>>,\n ) => {\n const { owner, repo } = validatedRepo;\n const resp = await gitlab.Repositories.allContributors(\n `${owner}/${repo}`,\n {\n showExpanded: true,\n },\n );\n return { successful: true, result: resp?.data?.length < 1 };\n },\n },\n );\n }\n\n async getPullRequest(\n repoUrl: string,\n pullRequestNumber: number,\n ): Promise<{\n title?: string;\n body?: string;\n merged?: boolean;\n lastUpdated?: string;\n prSha?: string;\n prBranch?: string;\n }> {\n const glConfig = this.integrations.gitlab.byUrl(repoUrl)?.config;\n if (!glConfig) {\n this.logger.error(\n `No Gitlab integration config found for repo ${repoUrl}`,\n );\n return {};\n }\n\n const gitUrl = gitUrlParse(repoUrl);\n const owner = gitUrl.owner;\n const repo = gitUrl.name;\n\n const credentials = await this.gitlabCredentialsProvider.getAllCredentials({\n host: glConfig.host,\n });\n\n if (credentials.length === 0) {\n this.logger.error(`No credentials for GL integration`);\n return {};\n }\n\n for (const credential of credentials) {\n const glKit = buildGitlab(\n {\n logger: this.logger,\n cache: this.cache,\n },\n { credential, owner },\n glConfig.baseUrl,\n );\n\n try {\n const pr = await glKit.MergeRequests.show(\n `${owner}/${repo}`,\n pullRequestNumber,\n );\n\n return {\n title: pr.title,\n body: pr.description || undefined,\n merged: pr.state === 'merged',\n lastUpdated: pr.updated_at,\n prSha: pr.sha,\n prBranch: pr.source_branch,\n };\n } catch (error: any) {\n this.logger.error(\n `Error fetching pull request ${pullRequestNumber} from ${repoUrl}`,\n error,\n );\n }\n }\n\n return {};\n }\n\n async getCatalogInfoFile(\n logger: LoggerService,\n input: {\n repoUrl: string;\n prNumber: number;\n prHeadSha: string;\n },\n ): Promise<string | undefined> {\n const glConfig = this.integrations.gitlab.byUrl(input.repoUrl)?.config;\n if (!glConfig) {\n logger.error(\n `No Gitlab integration config found for repo ${input.repoUrl}`,\n );\n return undefined;\n }\n\n const gitUrl = gitUrlParse(input.repoUrl);\n const owner = gitUrl.owner;\n const repo = gitUrl.name;\n\n const credentials = await this.gitlabCredentialsProvider.getAllCredentials({\n host: glConfig.host,\n });\n\n if (credentials.length === 0) {\n logger.error(`No credentials for GL integration`);\n return undefined;\n }\n\n for (const credential of credentials) {\n const glKit = buildGitlab(\n {\n logger: this.logger,\n cache: this.cache,\n },\n { credential, owner },\n glConfig.baseUrl,\n );\n\n try {\n const file = await glKit.RepositoryFiles.show(\n `${owner}/${repo}`,\n getCatalogFilename(this.config),\n input.prHeadSha,\n );\n\n if (file) {\n const content = Buffer.from(file.content, 'base64').toString('utf-8');\n return content;\n }\n } catch (error: any) {\n if (error.cause?.response?.status === 404) {\n logger.warn(\n `catalog-info.yaml not found in PR ${input.prNumber} of ${input.repoUrl}`,\n );\n return undefined;\n }\n logger.error(\n `Error fetching catalog-info.yaml from PR ${input.prNumber} of ${input.repoUrl}`,\n error,\n );\n return undefined;\n }\n }\n\n return undefined;\n }\n}\n"],"names":["ScmIntegrations","CustomGitlabCredentialsProvider","DefaultGitlabCredentialsProvider","gitUrlParse","getCredentialsForConfig","buildGitlab","DefaultPageNumber","DefaultPageSize","fetchFromAllIntegrations","addGitlabTokenGroups","computeTotalCount","addGitlabTokenOrgRepositories","addGitlabTokenRepositories","extractLocationOwnerMap","logErrorIfNeeded","getBranchName","findOpenPRForBranch","getCatalogFilename","executeFunctionOnFirstSuccessfulIntegration","fileExistsInDefaultBranch","createOrUpdateFileInBranch","pullRequestResponse","closePRWithComment"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"gitlabApiService.cjs.js","sources":["../../src/gitlab/gitlabApiService.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 DefaultGitlabCredentialsProvider,\n GitLabIntegrationConfig,\n ScmIntegrations,\n} from '@backstage/integration';\n\nimport { Gitlab } from '@gitbeaker/rest';\nimport gitUrlParse from 'git-url-parse';\n\nimport { getBranchName, getCatalogFilename } from '../catalog/catalogUtils';\nimport {\n computeTotalCount,\n extractLocationOwnerMap,\n logErrorIfNeeded,\n} from '../helpers';\nimport { GitApiService } from '../scm/GitApiService';\nimport {\n DefaultPageNumber,\n DefaultPageSize,\n} from '../service/handlers/handlers';\nimport { CustomGitlabCredentialsProvider } from './GitlabAppManager';\nimport {\n ExtendedGitlabCredentials,\n GitlabFetchError,\n GitlabOrganization,\n GitlabOrganizationResponse,\n GitlabRepository,\n GitlabRepositoryResponse,\n} from './types';\nimport { buildGitlab } from './utils/glUtils';\nimport { addGitlabTokenGroups } from './utils/orgUtils';\nimport { closePRWithComment, findOpenPRForBranch } from './utils/prUtils';\nimport {\n addGitlabTokenOrgRepositories,\n addGitlabTokenRepositories,\n createOrUpdateFileInBranch,\n fileExistsInDefaultBranch,\n ValidatedRepo,\n} from './utils/repoUtils';\nimport {\n executeFunctionOnFirstSuccessfulIntegration,\n fetchFromAllIntegrations,\n getCredentialsForConfig,\n} from './utils/utils';\n\nexport class GitlabApiService implements GitApiService {\n private readonly logger: LoggerService;\n private readonly integrations: ScmIntegrations;\n private readonly gitlabCredentialsProvider: CustomGitlabCredentialsProvider;\n private readonly config: Config;\n // Cache for storing ETags (used for efficient caching of unchanged data returned by GitLab)\n private readonly cache: CacheService;\n constructor(\n logger: LoggerService,\n config: Config,\n cacheService: CacheService,\n ) {\n this.logger = logger;\n this.config = config;\n this.integrations = ScmIntegrations.fromConfig(config);\n this.gitlabCredentialsProvider =\n CustomGitlabCredentialsProvider.fromIntegrations(this.integrations);\n this.cache = cacheService;\n }\n\n async getCredentials(repoUrl: string): Promise<{ token: string }> {\n const provider = DefaultGitlabCredentialsProvider.fromIntegrations(\n this.integrations,\n );\n const creds = await provider.getCredentials({\n url: repoUrl,\n });\n if (!creds || !creds.token) {\n throw new Error(`Token not configured for 'gitlab' provider`);\n }\n return {\n token: creds.token,\n };\n }\n\n async getRepositoryFromIntegrations(repoUrl: string): Promise<{\n repository?: GitlabRepository;\n errors?: GitlabFetchError[];\n }> {\n const gitUrl = gitUrlParse(repoUrl);\n\n const glConfig = this.integrations.gitlab.byUrl(repoUrl)?.config;\n if (!glConfig) {\n throw new Error(\n `No Gitlab integration config found for repo ${repoUrl}. Please add a configuration entry under 'integrations.gitlab`,\n );\n }\n\n const credentials = await getCredentialsForConfig(\n this.gitlabCredentialsProvider,\n glConfig,\n );\n let repository: GitlabRepository | undefined = undefined;\n for (const credential of credentials) {\n const glKit = buildGitlab(\n {\n logger: this.logger,\n cache: this.cache,\n },\n { credential, owner: gitUrl.owner },\n glConfig.baseUrl,\n );\n const repo = await glKit.Projects.show(`${gitUrl.owner}/${gitUrl.name}`);\n if (!repo) {\n continue;\n }\n repository = {\n name: repo.name,\n full_name: repo.path_with_namespace,\n url: repo._links.self,\n html_url: repo.web_url,\n default_branch: repo.default_branch,\n updated_at: repo.updated_at,\n };\n break;\n }\n\n return {\n repository,\n errors: [],\n };\n }\n\n async getOrganizationsFromIntegrations(\n pageNumber: number = DefaultPageNumber,\n pageSize: number = DefaultPageSize,\n search?: string,\n ): Promise<GitlabOrganizationResponse> {\n const groups = new Map<string, GitlabOrganization>();\n const result = await fetchFromAllIntegrations(\n {\n logger: this.logger,\n cache: this.cache,\n gitlabCredentialsProvider: this.gitlabCredentialsProvider,\n },\n this.integrations,\n {\n dataFetcher: async (\n glApi: InstanceType<typeof Gitlab<false>>,\n credential: ExtendedGitlabCredentials,\n glConfig: GitLabIntegrationConfig,\n ) => {\n const dataFetchErrors = new Map<number, GitlabFetchError>();\n const resp = await addGitlabTokenGroups(\n {\n logger: this.logger,\n },\n glApi,\n credential,\n {\n search,\n groups,\n pageNumber,\n pageSize,\n errors: dataFetchErrors,\n },\n );\n this.logger.debug(\n `Got ${resp.totalCount} groups(s) for ${glConfig.host}`,\n );\n return {\n result: resp.totalCount ?? 0,\n errors: Array.from(dataFetchErrors.values()),\n };\n },\n },\n );\n\n const groupList = Array.from(groups.values());\n const totalCount = computeTotalCount(groupList, result.data, pageSize);\n return {\n organizations: groupList,\n errors: Array.from(result.errors?.values() ?? []),\n totalCount,\n };\n }\n\n private async fetchUserTokenGitlabIntegrationRepositories(\n userTokens: Record<string, string>,\n fetcher: (\n glApi: InstanceType<typeof Gitlab<false>>,\n credential: ExtendedGitlabCredentials,\n errors: Map<number, GitlabFetchError>,\n ) => Promise<{ totalCount?: number }>,\n ): Promise<{ errors: GitlabFetchError[]; totalCount: number | undefined }> {\n const allErrors: GitlabFetchError[] = [];\n let totalCount: number | undefined;\n const glConfigs = this.integrations.gitlab.list().map(i => i.config);\n for (const glConfig of glConfigs) {\n const normalizedBase = glConfig.baseUrl.replace(/\\/$/, '');\n const token =\n userTokens[normalizedBase] ?? userTokens[`https://${glConfig.host}`];\n\n if (!token) {\n continue;\n }\n const userCredential: ExtendedGitlabCredentials = { token };\n const userGitlab = buildGitlab(\n { logger: this.logger, cache: this.cache },\n { credential: userCredential },\n glConfig.baseUrl, // NOTE: baseUrl, NOT apiBaseUrl (Gitlab constructor takes the base, not /api/v4)\n );\n const dataFetchErrors = new Map<number, GitlabFetchError>();\n const result = await fetcher(userGitlab, userCredential, dataFetchErrors);\n totalCount = (totalCount ?? 0) + (result.totalCount ?? 0);\n dataFetchErrors.forEach(err => allErrors.push(err));\n }\n return { errors: allErrors, totalCount };\n }\n\n async getOrgRepositoriesFromIntegrations(\n orgName: string,\n search?: string,\n pageNumber: number = DefaultPageNumber,\n pageSize: number = DefaultPageSize,\n userTokens?: Record<string, string>,\n ): Promise<GitlabRepositoryResponse> {\n const orgRepositories = new Map<string, GitlabRepository>();\n\n if (userTokens && Object.keys(userTokens).length > 0) {\n const { errors: allErrors, totalCount } =\n await this.fetchUserTokenGitlabIntegrationRepositories(\n userTokens,\n (userGitlab, userCredential, dataFetchErrors) =>\n addGitlabTokenOrgRepositories(\n { logger: this.logger },\n userGitlab,\n userCredential,\n orgName,\n orgRepositories,\n dataFetchErrors,\n { search, pageNumber, pageSize },\n ),\n );\n const repoList = Array.from(orgRepositories.values());\n return { repositories: repoList, errors: allErrors, totalCount };\n }\n\n const result = await fetchFromAllIntegrations(\n {\n logger: this.logger,\n cache: this.cache,\n gitlabCredentialsProvider: this.gitlabCredentialsProvider,\n },\n this.integrations,\n {\n dataFetcher: async (\n glApi: InstanceType<typeof Gitlab<false>>,\n credential: ExtendedGitlabCredentials,\n glConfig: GitLabIntegrationConfig,\n ) => {\n const dataFetchErrors = new Map<number, GitlabFetchError>();\n const resp = await addGitlabTokenOrgRepositories(\n {\n logger: this.logger,\n },\n glApi,\n credential,\n orgName,\n orgRepositories,\n dataFetchErrors,\n {\n search,\n pageNumber,\n pageSize,\n },\n );\n this.logger.debug(\n `Got ${resp.totalCount} org repo(s) for ${glConfig.host}`,\n );\n return {\n stopFetchingData: true,\n result: resp.totalCount ?? 0,\n errors: Array.from(dataFetchErrors.values()),\n };\n },\n },\n );\n\n const repoList = Array.from(orgRepositories.values());\n const totalCount = computeTotalCount(repoList, result.data, pageSize);\n return {\n repositories: repoList,\n errors: Array.from(result.errors?.values() ?? []),\n totalCount,\n };\n }\n\n /**\n * Returns GitlabRepositoryResponse containing:\n * - a list of unique repositories the gitlab integrations have access to\n * - a list of errors encountered by each token (if any exist)\n */\n async getRepositoriesFromIntegrations(\n search?: string,\n userTokens?: Record<string, string>,\n ): Promise<GitlabRepositoryResponse> {\n const repositories = new Map<string, GitlabRepository>();\n\n if (userTokens && Object.keys(userTokens).length > 0) {\n const { errors: allErrors, totalCount } =\n await this.fetchUserTokenGitlabIntegrationRepositories(\n userTokens,\n (userGitlab, userCredential, dataFetchErrors) =>\n addGitlabTokenRepositories(\n { logger: this.logger },\n userGitlab,\n userCredential,\n repositories,\n dataFetchErrors,\n { search },\n ),\n );\n const repoList = Array.from(repositories.values());\n return { repositories: repoList, errors: allErrors, totalCount };\n }\n\n const result = await fetchFromAllIntegrations(\n {\n logger: this.logger,\n cache: this.cache,\n gitlabCredentialsProvider: this.gitlabCredentialsProvider,\n },\n this.integrations,\n {\n dataFetcher: async (\n glApi: InstanceType<typeof Gitlab<false>>,\n credential: ExtendedGitlabCredentials,\n glConfig: GitLabIntegrationConfig,\n ) => {\n const dataFetchErrors = new Map<number, GitlabFetchError>();\n const resp = await addGitlabTokenRepositories(\n {\n logger: this.logger,\n },\n glApi,\n credential,\n repositories,\n dataFetchErrors,\n {\n search,\n },\n );\n this.logger.debug(\n `Got ${resp.totalCount} repo(s) for ${glConfig.host}`,\n );\n return {\n result: resp.totalCount ?? 0,\n errors: Array.from(dataFetchErrors.values()),\n };\n },\n },\n );\n\n const repoList = Array.from(repositories.values());\n const totalCount = computeTotalCount(\n repoList,\n result.data,\n DefaultPageSize,\n );\n return {\n repositories: repoList,\n errors: Array.from(result.errors?.values() ?? []),\n totalCount,\n };\n }\n\n async filterLocationsAccessibleFromIntegrations(\n locationUrls: string[],\n ): Promise<string[]> {\n const locationGitOwnerMap = extractLocationOwnerMap(locationUrls);\n\n const allAccessibleTokenOrgs = new Set<string>();\n const allAccessibleUsernames = new Set<string>();\n await fetchFromAllIntegrations(\n {\n logger: this.logger,\n cache: this.cache,\n gitlabCredentialsProvider: this.gitlabCredentialsProvider,\n },\n this.integrations,\n {\n dataFetcher: async (gitlab: InstanceType<typeof Gitlab<false>>) => {\n // find authenticated gitlab owner...\n try {\n const username = (await gitlab.Users.showCurrentUser()).username;\n if (username) {\n allAccessibleUsernames.add(username);\n }\n } catch (err) {\n logErrorIfNeeded(\n this.logger,\n 'failed to fetch gitlab current user',\n err,\n );\n }\n\n // ... along with orgs accessible from the token auth\n try {\n const allGroups = await gitlab.Groups.all<false, 'offset'>({\n allAvailable: false,\n });\n allGroups\n .map(org => org.path)\n ?.forEach((orgName: string) =>\n allAccessibleTokenOrgs.add(orgName),\n );\n } catch (err) {\n logErrorIfNeeded(this.logger, 'failed to fetch gitlab groups', err);\n }\n\n return {};\n },\n },\n );\n\n return locationUrls.filter(loc => {\n if (!locationGitOwnerMap.has(loc)) {\n return false;\n }\n const owner = locationGitOwnerMap.get(loc)!;\n return (\n allAccessibleTokenOrgs.has(owner) || allAccessibleUsernames.has(owner)\n );\n });\n }\n\n async findImportOpenPr(\n logger: LoggerService,\n input: {\n repoUrl: string;\n includeCatalogInfoContent?: boolean;\n },\n ): Promise<{\n prNum?: number;\n prUrl?: string;\n prTitle?: string;\n prBody?: string;\n prCatalogInfoContent?: string;\n lastUpdate?: string;\n }> {\n const glConfig = this.integrations.gitlab.byUrl(input.repoUrl)?.config;\n if (!glConfig) {\n throw new Error(`Could not find GL 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 this.gitlabCredentialsProvider.getAllCredentials({\n host: glConfig.host,\n });\n if (credentials.length === 0) {\n throw new Error(`No credentials for GL integration`);\n }\n\n const branchName = getBranchName(this.config);\n for (const credential of credentials) {\n const glKit = buildGitlab(\n {\n logger: this.logger,\n cache: this.cache,\n },\n { credential, owner },\n glConfig.baseUrl,\n );\n try {\n return await findOpenPRForBranch(\n logger,\n this.config,\n glKit,\n owner,\n repo,\n branchName,\n input.includeCatalogInfoContent,\n );\n } catch (error: any) {\n logErrorIfNeeded(this.logger, 'Error fetching pull requests', error);\n }\n }\n return {};\n }\n\n async submitPrToRepo(\n logger: LoggerService,\n input: {\n repoUrl: string;\n gitUrl: gitUrlParse.GitUrl;\n defaultBranch?: string;\n prTitle: string;\n prBody: string;\n catalogInfoContent: string;\n },\n ): Promise<{\n prUrl?: string;\n prNumber?: number;\n hasChanges?: boolean;\n lastUpdate?: string;\n errors?: string[];\n }> {\n const fileName = getCatalogFilename(this.config);\n const errors: any[] = [];\n\n const result = await executeFunctionOnFirstSuccessfulIntegration(\n {\n logger: this.logger,\n cache: this.cache,\n config: this.config,\n gitlabCredentialsProvider: this.gitlabCredentialsProvider,\n },\n this.integrations,\n {\n repoUrl: input.repoUrl,\n fn: async (\n validatedRepo: ValidatedRepo,\n gitlab: InstanceType<typeof Gitlab<false>>,\n ): Promise<{\n successful: boolean;\n result?: {\n prUrl?: string;\n prNumber?: number;\n hasChanges?: boolean;\n lastUpdate?: string;\n };\n }> => {\n const { owner, repo, branchName } = validatedRepo;\n try {\n // Check if there is already a catalogInfo in the default branch\n const catalogInfoFileExists = await fileExistsInDefaultBranch(\n logger,\n gitlab,\n owner,\n repo,\n fileName,\n input.defaultBranch,\n );\n if (catalogInfoFileExists) {\n // No need to create a PR => component will be imported as is\n return {\n successful: true,\n result: {\n hasChanges: false,\n },\n };\n }\n\n const existingPrForBranch = await findOpenPRForBranch(\n logger,\n this.config,\n gitlab,\n owner,\n repo,\n branchName,\n );\n\n const repoData = await gitlab.Projects.show(`${owner}/${repo}`);\n\n const parentRef = await gitlab.Branches.show(\n `${owner}/${repo}`,\n repoData.default_branch,\n ); // This might not be neccesarry\n\n if (existingPrForBranch.prNum) {\n await createOrUpdateFileInBranch(\n gitlab,\n owner,\n repo,\n branchName,\n fileName,\n input.catalogInfoContent,\n );\n const pullRequestResponse = await gitlab.MergeRequests.edit(\n `${owner}/${repo}`,\n existingPrForBranch.prNum,\n {\n description: input.prBody,\n title: input.prTitle,\n targetBranch: repoData.default_branch,\n },\n );\n return {\n successful: true,\n result: {\n prNumber: existingPrForBranch.prNum,\n prUrl: pullRequestResponse.web_url,\n lastUpdate: pullRequestResponse.updated_at,\n },\n };\n }\n\n try {\n await gitlab.Branches.show(`${owner}/${repo}`, branchName);\n } catch (error: any) {\n if (error.cause.response.status === 404) {\n await gitlab.Branches.create(\n `${owner}/${repo}`,\n branchName,\n parentRef.name,\n );\n } else {\n throw error;\n }\n }\n\n // Might not be able to do this in the gitlab api\n // This is if the branch exists, but there wasn't a PR yet\n // if (branchExists) {\n // // update it in case it is outdated compared to the base branch\n // try {\n // await octo.repos.merge({\n // owner: owner,\n // repo: repo,\n // base: branchName,\n // head: repoData.data.default_branch,\n // });\n // } catch (error: any) {\n // logErrorIfNeeded(\n // this.logger,\n // `Could not merge default branch ${repoData.data.default_branch} into import branch ${branchName}`,\n // error,\n // );\n // }\n // }\n\n await createOrUpdateFileInBranch(\n gitlab,\n owner,\n repo,\n branchName,\n fileName,\n input.catalogInfoContent,\n );\n\n const pullRequestResponse = await gitlab.MergeRequests.create(\n `${owner}/${repo}`,\n branchName,\n repoData.default_branch,\n input.prTitle,\n {\n description: input.prBody,\n },\n );\n return {\n successful: true,\n result: {\n prNumber: pullRequestResponse.iid,\n prUrl: pullRequestResponse.web_url,\n lastUpdate: pullRequestResponse.updated_at,\n hasChanges: true,\n },\n };\n } catch (e: any) {\n logErrorIfNeeded(\n this.logger,\n `Couldn't create PR in ${input.repoUrl}`,\n e,\n );\n errors.push(e.message);\n return { successful: false };\n }\n },\n },\n );\n\n if (result) {\n return result;\n }\n\n logger.warn(\n `Tried all possible Gitlab credentials, but could not create PR in ${input.repoUrl}. Please try again later...`,\n );\n\n return {\n errors: errors,\n };\n }\n\n async hasFileInRepo(input: {\n repoUrl: string;\n defaultBranch?: string;\n fileName: string;\n }) {\n const fileExists = await executeFunctionOnFirstSuccessfulIntegration(\n {\n logger: this.logger,\n cache: this.cache,\n config: this.config,\n gitlabCredentialsProvider: this.gitlabCredentialsProvider,\n },\n this.integrations,\n {\n repoUrl: input.repoUrl,\n fn: async (\n validatedRepo: ValidatedRepo,\n gitlab: InstanceType<typeof Gitlab<false>>,\n ) => {\n const { owner, repo } = validatedRepo;\n const exists = await fileExistsInDefaultBranch(\n this.logger,\n gitlab,\n owner,\n repo,\n input.fileName,\n input.defaultBranch,\n );\n if (exists === undefined) {\n return { successful: false };\n }\n return { successful: true, result: exists };\n },\n },\n );\n\n if (fileExists === undefined) {\n throw new Error(\n `Could not determine if repo at ${input.repoUrl} already has a file named ${input.fileName} in its default branch (${input.defaultBranch})`,\n );\n }\n\n return fileExists;\n }\n\n async closeImportPR(\n logger: LoggerService,\n input: {\n repoUrl: string;\n gitUrl: gitUrlParse.GitUrl;\n comment: string;\n },\n ) {\n await executeFunctionOnFirstSuccessfulIntegration(\n {\n logger: this.logger,\n cache: this.cache,\n config: this.config,\n gitlabCredentialsProvider: this.gitlabCredentialsProvider,\n },\n this.integrations,\n {\n repoUrl: input.repoUrl,\n fn: async (\n validatedRepo: ValidatedRepo,\n gitlab: InstanceType<typeof Gitlab<false>>,\n ) => {\n const { owner, repo, branchName } = validatedRepo;\n try {\n const existingPrForBranch = await findOpenPRForBranch(\n logger,\n this.config,\n gitlab,\n owner,\n repo,\n branchName,\n );\n if (existingPrForBranch.prNum) {\n await closePRWithComment(\n gitlab,\n owner,\n repo,\n existingPrForBranch.prNum,\n input.comment,\n );\n }\n return { successful: true };\n } catch (e: any) {\n logErrorIfNeeded(\n this.logger,\n `Couldn't close PR in ${input.repoUrl}`,\n e,\n );\n return { successful: false };\n }\n },\n },\n );\n }\n\n async deleteImportBranch(input: {\n repoUrl: string;\n gitUrl: gitUrlParse.GitUrl;\n }) {\n await executeFunctionOnFirstSuccessfulIntegration(\n {\n logger: this.logger,\n cache: this.cache,\n config: this.config,\n gitlabCredentialsProvider: this.gitlabCredentialsProvider,\n },\n this.integrations,\n {\n repoUrl: input.repoUrl,\n fn: async (\n validatedRepo: ValidatedRepo,\n gitlab: InstanceType<typeof Gitlab<false>>,\n ) => {\n const { owner, repo, branchName } = validatedRepo;\n try {\n await gitlab.Branches.remove(`${owner}/${repo}`, branchName);\n return { successful: true };\n } catch (e: any) {\n logErrorIfNeeded(\n this.logger,\n `Couldn't close import PR and/or delete import branch in ${input.repoUrl}`,\n e,\n );\n return { successful: false };\n }\n },\n },\n );\n }\n\n async isRepoEmpty(input: { repoUrl: string }) {\n return await executeFunctionOnFirstSuccessfulIntegration(\n {\n logger: this.logger,\n cache: this.cache,\n config: this.config,\n gitlabCredentialsProvider: this.gitlabCredentialsProvider,\n },\n this.integrations,\n {\n repoUrl: input.repoUrl,\n fn: async (\n validatedRepo: ValidatedRepo,\n gitlab: InstanceType<typeof Gitlab<false>>,\n ) => {\n const { owner, repo } = validatedRepo;\n const resp = await gitlab.Repositories.allContributors(\n `${owner}/${repo}`,\n {\n showExpanded: true,\n },\n );\n return { successful: true, result: resp?.data?.length < 1 };\n },\n },\n );\n }\n\n async getPullRequest(\n repoUrl: string,\n pullRequestNumber: number,\n ): Promise<{\n title?: string;\n body?: string;\n merged?: boolean;\n lastUpdated?: string;\n prSha?: string;\n prBranch?: string;\n }> {\n const glConfig = this.integrations.gitlab.byUrl(repoUrl)?.config;\n if (!glConfig) {\n this.logger.error(\n `No Gitlab integration config found for repo ${repoUrl}`,\n );\n return {};\n }\n\n const gitUrl = gitUrlParse(repoUrl);\n const owner = gitUrl.owner;\n const repo = gitUrl.name;\n\n const credentials = await this.gitlabCredentialsProvider.getAllCredentials({\n host: glConfig.host,\n });\n\n if (credentials.length === 0) {\n this.logger.error(`No credentials for GL integration`);\n return {};\n }\n\n for (const credential of credentials) {\n const glKit = buildGitlab(\n {\n logger: this.logger,\n cache: this.cache,\n },\n { credential, owner },\n glConfig.baseUrl,\n );\n\n try {\n const pr = await glKit.MergeRequests.show(\n `${owner}/${repo}`,\n pullRequestNumber,\n );\n\n return {\n title: pr.title,\n body: pr.description || undefined,\n merged: pr.state === 'merged',\n lastUpdated: pr.updated_at,\n prSha: pr.sha,\n prBranch: pr.source_branch,\n };\n } catch (error: any) {\n this.logger.error(\n `Error fetching pull request ${pullRequestNumber} from ${repoUrl}`,\n error,\n );\n }\n }\n\n return {};\n }\n\n async getCatalogInfoFile(\n logger: LoggerService,\n input: {\n repoUrl: string;\n prNumber: number;\n prHeadSha: string;\n },\n ): Promise<string | undefined> {\n const glConfig = this.integrations.gitlab.byUrl(input.repoUrl)?.config;\n if (!glConfig) {\n logger.error(\n `No Gitlab integration config found for repo ${input.repoUrl}`,\n );\n return undefined;\n }\n\n const gitUrl = gitUrlParse(input.repoUrl);\n const owner = gitUrl.owner;\n const repo = gitUrl.name;\n\n const credentials = await this.gitlabCredentialsProvider.getAllCredentials({\n host: glConfig.host,\n });\n\n if (credentials.length === 0) {\n logger.error(`No credentials for GL integration`);\n return undefined;\n }\n\n for (const credential of credentials) {\n const glKit = buildGitlab(\n {\n logger: this.logger,\n cache: this.cache,\n },\n { credential, owner },\n glConfig.baseUrl,\n );\n\n try {\n const file = await glKit.RepositoryFiles.show(\n `${owner}/${repo}`,\n getCatalogFilename(this.config),\n input.prHeadSha,\n );\n\n if (file) {\n const content = Buffer.from(file.content, 'base64').toString('utf-8');\n return content;\n }\n } catch (error: any) {\n if (error.cause?.response?.status === 404) {\n logger.warn(\n `catalog-info.yaml not found in PR ${input.prNumber} of ${input.repoUrl}`,\n );\n return undefined;\n }\n logger.error(\n `Error fetching catalog-info.yaml from PR ${input.prNumber} of ${input.repoUrl}`,\n error,\n );\n return undefined;\n }\n }\n\n return undefined;\n }\n}\n"],"names":["ScmIntegrations","CustomGitlabCredentialsProvider","DefaultGitlabCredentialsProvider","gitUrlParse","getCredentialsForConfig","buildGitlab","DefaultPageNumber","DefaultPageSize","fetchFromAllIntegrations","addGitlabTokenGroups","computeTotalCount","totalCount","addGitlabTokenOrgRepositories","repoList","addGitlabTokenRepositories","extractLocationOwnerMap","logErrorIfNeeded","getBranchName","findOpenPRForBranch","getCatalogFilename","executeFunctionOnFirstSuccessfulIntegration","fileExistsInDefaultBranch","createOrUpdateFileInBranch","pullRequestResponse","closePRWithComment"],"mappings":"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"}
|
|
@@ -6,7 +6,7 @@ const GITLAB_BASEURL_ENDPOINT = "https://gitlab.com";
|
|
|
6
6
|
function buildGitlab(_deps, input, baseUrl = GITLAB_BASEURL_ENDPOINT) {
|
|
7
7
|
const apiThing = new rest.Gitlab({
|
|
8
8
|
host: baseUrl,
|
|
9
|
-
|
|
9
|
+
oauthToken: input.credential.token
|
|
10
10
|
});
|
|
11
11
|
return apiThing;
|
|
12
12
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"glUtils.cjs.js","sources":["../../../src/gitlab/utils/glUtils.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';\n\nimport { Gitlab } from '@gitbeaker/rest';\n\nimport {\n type ExtendedGitlabCredentials,\n type GitlabFetchError,\n} from '../types';\n\nconst GITLAB_BASEURL_ENDPOINT = 'https://gitlab.com';\n\nexport function buildGitlab(\n _deps: {\n logger: LoggerService;\n cache: CacheService;\n },\n input: {\n credential: ExtendedGitlabCredentials;\n owner?: string;\n errors?: Map<number, GitlabFetchError>;\n },\n baseUrl: string = GITLAB_BASEURL_ENDPOINT,\n): InstanceType<typeof Gitlab<false>> {\n const apiThing = new Gitlab({\n host: baseUrl,\n
|
|
1
|
+
{"version":3,"file":"glUtils.cjs.js","sources":["../../../src/gitlab/utils/glUtils.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';\n\nimport { Gitlab } from '@gitbeaker/rest';\n\nimport {\n type ExtendedGitlabCredentials,\n type GitlabFetchError,\n} from '../types';\n\nconst GITLAB_BASEURL_ENDPOINT = 'https://gitlab.com';\n\nexport function buildGitlab(\n _deps: {\n logger: LoggerService;\n cache: CacheService;\n },\n input: {\n credential: ExtendedGitlabCredentials;\n owner?: string;\n errors?: Map<number, GitlabFetchError>;\n },\n baseUrl: string = GITLAB_BASEURL_ENDPOINT,\n): InstanceType<typeof Gitlab<false>> {\n const apiThing = new Gitlab({\n host: baseUrl,\n oauthToken: input.credential.token,\n });\n return apiThing;\n}\n"],"names":["Gitlab"],"mappings":";;;;AA4BA,MAAM,uBAAA,GAA0B,oBAAA;AAEzB,SAAS,WAAA,CACd,KAAA,EAIA,KAAA,EAKA,OAAA,GAAkB,uBAAA,EACkB;AACpC,EAAA,MAAM,QAAA,GAAW,IAAIA,WAAA,CAAO;AAAA,IAC1B,IAAA,EAAM,OAAA;AAAA,IACN,UAAA,EAAY,MAAM,UAAA,CAAW;AAAA,GAC9B,CAAA;AACD,EAAA,OAAO,QAAA;AACT;;;;"}
|
|
@@ -26,68 +26,28 @@ async function validateAndBuildRepoData(gitlabCredentialsProvider, integrations,
|
|
|
26
26
|
const branchName = catalogUtils.getBranchName(config);
|
|
27
27
|
return { glConfig, owner, repo, credentials, branchName };
|
|
28
28
|
}
|
|
29
|
-
async function
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
29
|
+
async function addGitlabTokenRepositories(deps, gitlab, credential, repositories, errors, reqParams) {
|
|
30
|
+
const lowercaseSearch = reqParams?.search?.toLocaleLowerCase();
|
|
31
|
+
let totalCount;
|
|
32
|
+
try {
|
|
33
|
+
const allRepositories = await listAllRepositoriesForAuthenticatedUser(
|
|
34
|
+
deps,
|
|
35
|
+
gitlab
|
|
36
|
+
);
|
|
37
|
+
const filteredRepositories = lowercaseSearch ? allRepositories.filter(
|
|
38
|
+
(repo) => repo.name.toLocaleLowerCase().includes(lowercaseSearch)
|
|
39
|
+
) : allRepositories;
|
|
40
|
+
filteredRepositories.forEach((repo) => {
|
|
41
|
+
repositories.set(repo.path_with_namespace, {
|
|
40
42
|
name: repo.name,
|
|
41
43
|
full_name: repo.path_with_namespace,
|
|
42
44
|
url: repo._links.self,
|
|
43
45
|
html_url: repo.web_url,
|
|
44
46
|
default_branch: repo.default_branch,
|
|
45
|
-
updated_at: repo
|
|
46
|
-
};
|
|
47
|
-
}) ?? []
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
async function addGitlabTokenRepositories(deps, gitlab, credential, repositories, errors, reqParams) {
|
|
51
|
-
const search = reqParams?.search;
|
|
52
|
-
const pageNumber = reqParams?.pageNumber ?? handlers.DefaultPageNumber;
|
|
53
|
-
const pageSize = reqParams?.pageSize ?? handlers.DefaultPageSize;
|
|
54
|
-
let totalCount;
|
|
55
|
-
try {
|
|
56
|
-
if (search) {
|
|
57
|
-
const searchResp = await searchRepos(
|
|
58
|
-
gitlab,
|
|
59
|
-
search,
|
|
60
|
-
pageNumber,
|
|
61
|
-
pageSize
|
|
62
|
-
);
|
|
63
|
-
totalCount = searchResp.totalCount;
|
|
64
|
-
searchResp.repositories.forEach(
|
|
65
|
-
(repo) => repositories.set(repo.full_name, repo)
|
|
66
|
-
);
|
|
67
|
-
} else {
|
|
68
|
-
const { data, paginationInfo } = await gitlab.Projects.all({
|
|
69
|
-
membership: true,
|
|
70
|
-
perPage: pageSize,
|
|
71
|
-
page: pageNumber,
|
|
72
|
-
showExpanded: true
|
|
47
|
+
updated_at: repo?.updated_at
|
|
73
48
|
});
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
name: repo.name,
|
|
77
|
-
full_name: repo.path_with_namespace,
|
|
78
|
-
url: repo._links.self,
|
|
79
|
-
html_url: repo.web_url,
|
|
80
|
-
default_branch: repo.default_branch,
|
|
81
|
-
updated_at: repo?.updated_at
|
|
82
|
-
});
|
|
83
|
-
});
|
|
84
|
-
totalCount = await utils.computeTotalCountFromPaginationInfo(
|
|
85
|
-
deps,
|
|
86
|
-
paginationInfo,
|
|
87
|
-
pageSize
|
|
88
|
-
// Not thrilled with this for some reason
|
|
89
|
-
);
|
|
90
|
-
}
|
|
49
|
+
});
|
|
50
|
+
totalCount = filteredRepositories.length;
|
|
91
51
|
} catch (err) {
|
|
92
52
|
utils.handleError(
|
|
93
53
|
deps,
|
|
@@ -190,11 +150,26 @@ async function createOrUpdateFileInBranch(gitlab, owner, repo, branchName, fileN
|
|
|
190
150
|
}
|
|
191
151
|
}
|
|
192
152
|
}
|
|
153
|
+
async function listAllRepositoriesForAuthenticatedUser(deps, gitlab) {
|
|
154
|
+
try {
|
|
155
|
+
const allProjects = await gitlab.Projects.all({
|
|
156
|
+
membership: true,
|
|
157
|
+
showExpanded: true,
|
|
158
|
+
orderBy: "name",
|
|
159
|
+
sort: "asc"
|
|
160
|
+
});
|
|
161
|
+
return allProjects.data;
|
|
162
|
+
} catch (error) {
|
|
163
|
+
deps.logger.error(
|
|
164
|
+
`Failed to list all repositories for authenticated user: ${error}`
|
|
165
|
+
);
|
|
166
|
+
throw error;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
193
169
|
|
|
194
170
|
exports.addGitlabTokenOrgRepositories = addGitlabTokenOrgRepositories;
|
|
195
171
|
exports.addGitlabTokenRepositories = addGitlabTokenRepositories;
|
|
196
172
|
exports.createOrUpdateFileInBranch = createOrUpdateFileInBranch;
|
|
197
173
|
exports.fileExistsInDefaultBranch = fileExistsInDefaultBranch;
|
|
198
|
-
exports.searchRepos = searchRepos;
|
|
199
174
|
exports.validateAndBuildRepoData = validateAndBuildRepoData;
|
|
200
175
|
//# sourceMappingURL=repoUtils.cjs.js.map
|