@red-hat-developer-hub/backstage-plugin-bulk-import-backend 6.2.0 → 6.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 +12 -0
- package/dist/catalog/catalogHttpClient.cjs.js +1 -0
- package/dist/catalog/catalogHttpClient.cjs.js.map +1 -1
- package/dist/generated/openapidocument.cjs.js +80 -1
- package/dist/generated/openapidocument.cjs.js.map +1 -1
- package/dist/github/githubApiService.cjs.js +5 -4
- package/dist/github/githubApiService.cjs.js.map +1 -1
- package/dist/github/utils/orgUtils.cjs.js +1 -0
- package/dist/github/utils/orgUtils.cjs.js.map +1 -1
- package/dist/github/utils/prUtils.cjs.js +1 -0
- package/dist/github/utils/prUtils.cjs.js.map +1 -1
- package/dist/github/utils/utils.cjs.js +1 -28
- package/dist/github/utils/utils.cjs.js.map +1 -1
- package/dist/gitlab/GitlabAppManager.cjs.js +54 -0
- package/dist/gitlab/GitlabAppManager.cjs.js.map +1 -0
- package/dist/gitlab/gitlabApiService.cjs.js +558 -0
- package/dist/gitlab/gitlabApiService.cjs.js.map +1 -0
- package/dist/gitlab/utils/glUtils.cjs.js +15 -0
- package/dist/gitlab/utils/glUtils.cjs.js.map +1 -0
- package/dist/gitlab/utils/orgUtils.cjs.js +72 -0
- package/dist/gitlab/utils/orgUtils.cjs.js.map +1 -0
- package/dist/gitlab/utils/prUtils.cjs.js +72 -0
- package/dist/gitlab/utils/prUtils.cjs.js.map +1 -0
- package/dist/gitlab/utils/repoUtils.cjs.js +200 -0
- package/dist/gitlab/utils/repoUtils.cjs.js.map +1 -0
- package/dist/gitlab/utils/utils.cjs.js +130 -0
- package/dist/gitlab/utils/utils.cjs.js.map +1 -0
- package/dist/helpers/utils.cjs.js +37 -0
- package/dist/helpers/utils.cjs.js.map +1 -1
- package/dist/service/handlers/import/bulkImports.cjs.js +61 -32
- package/dist/service/handlers/import/bulkImports.cjs.js.map +1 -1
- package/dist/service/handlers/import/importStatus.cjs.js +4 -7
- 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 +4 -2
- package/dist/service/handlers/repository/repositories.cjs.js.map +1 -1
- package/dist/service/router.cjs.js +20 -10
- package/dist/service/router.cjs.js.map +1 -1
- package/package.json +11 -10
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var handlers = require('../../service/handlers/handlers.cjs.js');
|
|
4
|
+
var utils = require('./utils.cjs.js');
|
|
5
|
+
|
|
6
|
+
async function addGitlabTokenGroups(deps, gitlab, credential, params) {
|
|
7
|
+
const search = params.search;
|
|
8
|
+
const groups = params.groups;
|
|
9
|
+
const errors = params.errors;
|
|
10
|
+
const pageNumber = params.pageNumber ?? handlers.DefaultPageNumber;
|
|
11
|
+
const pageSize = params.pageSize ?? handlers.DefaultPageSize;
|
|
12
|
+
let totalCount;
|
|
13
|
+
try {
|
|
14
|
+
let matchingGroups;
|
|
15
|
+
if (search) {
|
|
16
|
+
const { data, paginationInfo } = await gitlab.Groups.all({
|
|
17
|
+
allAvailable: false,
|
|
18
|
+
search,
|
|
19
|
+
perPage: pageSize,
|
|
20
|
+
page: pageNumber,
|
|
21
|
+
showExpanded: true
|
|
22
|
+
});
|
|
23
|
+
matchingGroups = data ?? [];
|
|
24
|
+
totalCount = await utils.computeTotalCountFromPaginationInfo(
|
|
25
|
+
deps,
|
|
26
|
+
paginationInfo,
|
|
27
|
+
pageSize
|
|
28
|
+
// Not thrilled with this for some reason
|
|
29
|
+
);
|
|
30
|
+
} else {
|
|
31
|
+
const { data, paginationInfo } = await gitlab.Groups.all({
|
|
32
|
+
allAvailable: false,
|
|
33
|
+
perPage: pageSize,
|
|
34
|
+
page: pageNumber,
|
|
35
|
+
showExpanded: true
|
|
36
|
+
});
|
|
37
|
+
matchingGroups = data ?? [];
|
|
38
|
+
totalCount = await utils.computeTotalCountFromPaginationInfo(
|
|
39
|
+
deps,
|
|
40
|
+
paginationInfo,
|
|
41
|
+
pageSize
|
|
42
|
+
// Not thrilled with this for some reason
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
for (const group of matchingGroups) {
|
|
46
|
+
const glGroup = {
|
|
47
|
+
id: group.id,
|
|
48
|
+
name: group.path,
|
|
49
|
+
description: group.description ?? void 0,
|
|
50
|
+
url: group.web_url,
|
|
51
|
+
avatar_url: group.avatar_url
|
|
52
|
+
// From here down gitlab doesn't really have while calling the group api
|
|
53
|
+
// public_repos: group?.data?.public_repos,
|
|
54
|
+
// total_private_repos: group?.data?.total_private_repos,
|
|
55
|
+
// owned_private_repos: group?.data?.owned_private_repos,
|
|
56
|
+
};
|
|
57
|
+
groups.set(group.path, glGroup);
|
|
58
|
+
}
|
|
59
|
+
} catch (err) {
|
|
60
|
+
utils.handleError(
|
|
61
|
+
{ logger: deps.logger },
|
|
62
|
+
"Fetching groups with token from token",
|
|
63
|
+
credential,
|
|
64
|
+
errors,
|
|
65
|
+
err
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
return { totalCount };
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
exports.addGitlabTokenGroups = addGitlabTokenGroups;
|
|
72
|
+
//# sourceMappingURL=orgUtils.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orgUtils.cjs.js","sources":["../../../src/gitlab/utils/orgUtils.ts"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { LoggerService } from '@backstage/backend-plugin-api';\nimport type { GitlabCredentials } from '@backstage/integration';\n\nimport { Gitlab } from '@gitbeaker/rest';\n\nimport {\n DefaultPageNumber,\n DefaultPageSize,\n} from '../../service/handlers/handlers';\nimport type { GitlabFetchError, GitlabOrganization } from '../types';\nimport { computeTotalCountFromPaginationInfo, handleError } from './utils';\n\nexport async function addGitlabTokenGroups(\n deps: {\n logger: LoggerService;\n },\n gitlab: InstanceType<typeof Gitlab<false>>,\n credential: GitlabCredentials,\n params: {\n search: string | undefined;\n groups: Map<string, GitlabOrganization>;\n errors: Map<number, GitlabFetchError>;\n pageNumber: number;\n pageSize: number;\n },\n): Promise<{ totalCount?: number }> {\n const search = params.search;\n const groups = params.groups;\n const errors = params.errors;\n const pageNumber = params.pageNumber ?? DefaultPageNumber;\n const pageSize = params.pageSize ?? DefaultPageSize;\n\n let totalCount: number | undefined;\n try {\n let matchingGroups;\n if (search) {\n // Use the group api with the search param.\n // I noticed that using this api will only return values when 3 or more characters are used for the search\n // that api gives us all the things the token has access\n const { data, paginationInfo } = await gitlab.Groups.all<true, 'offset'>({\n allAvailable: false,\n search: search,\n perPage: pageSize,\n page: pageNumber,\n showExpanded: true,\n });\n\n matchingGroups = data ?? [];\n\n totalCount = await computeTotalCountFromPaginationInfo(\n deps,\n paginationInfo,\n pageSize, // Not thrilled with this for some reason\n );\n } else {\n /**\n * The Groups all endpoint will grab all the groups the gitlab token has explicit access to.\n */\n\n const { data, paginationInfo } = await gitlab.Groups.all<true, 'offset'>({\n allAvailable: false,\n perPage: pageSize,\n page: pageNumber,\n showExpanded: true,\n });\n\n matchingGroups = data ?? [];\n\n totalCount = await computeTotalCountFromPaginationInfo(\n deps,\n paginationInfo,\n pageSize, // Not thrilled with this for some reason\n );\n }\n\n // Gitlab groups don't provide the same info that the github org provides, but some might not be needed\n // All the info we need is already part of that first request, so no need to go out again\n // Just in case we need it in the future, the gitlab.Groups.show('GROUP_ID') can be used to get a few more pieced of info\n for (const group of matchingGroups) {\n const glGroup: GitlabOrganization = {\n id: group.id,\n name: group.path,\n description: group.description ?? undefined,\n url: group.web_url,\n avatar_url: group.avatar_url,\n // From here down gitlab doesn't really have while calling the group api\n // public_repos: group?.data?.public_repos,\n // total_private_repos: group?.data?.total_private_repos,\n // owned_private_repos: group?.data?.owned_private_repos,\n };\n groups.set(group.path, glGroup);\n }\n } catch (err) {\n handleError(\n { logger: deps.logger },\n 'Fetching groups with token from token',\n credential,\n errors,\n err,\n );\n }\n return { totalCount };\n}\n"],"names":["DefaultPageNumber","DefaultPageSize","computeTotalCountFromPaginationInfo","handleError"],"mappings":";;;;;AA4BA,eAAsB,oBACpB,CAAA,IAAA,EAGA,MACA,EAAA,UAAA,EACA,MAOkC,EAAA;AAClC,EAAA,MAAM,SAAS,MAAO,CAAA,MAAA;AACtB,EAAA,MAAM,SAAS,MAAO,CAAA,MAAA;AACtB,EAAA,MAAM,SAAS,MAAO,CAAA,MAAA;AACtB,EAAM,MAAA,UAAA,GAAa,OAAO,UAAc,IAAAA,0BAAA;AACxC,EAAM,MAAA,QAAA,GAAW,OAAO,QAAY,IAAAC,wBAAA;AAEpC,EAAI,IAAA,UAAA;AACJ,EAAI,IAAA;AACF,IAAI,IAAA,cAAA;AACJ,IAAA,IAAI,MAAQ,EAAA;AAIV,MAAA,MAAM,EAAE,IAAM,EAAA,cAAA,KAAmB,MAAM,MAAA,CAAO,OAAO,GAAoB,CAAA;AAAA,QACvE,YAAc,EAAA,KAAA;AAAA,QACd,MAAA;AAAA,QACA,OAAS,EAAA,QAAA;AAAA,QACT,IAAM,EAAA,UAAA;AAAA,QACN,YAAc,EAAA;AAAA,OACf,CAAA;AAED,MAAA,cAAA,GAAiB,QAAQ,EAAC;AAE1B,MAAA,UAAA,GAAa,MAAMC,yCAAA;AAAA,QACjB,IAAA;AAAA,QACA,cAAA;AAAA,QACA;AAAA;AAAA,OACF;AAAA,KACK,MAAA;AAKL,MAAA,MAAM,EAAE,IAAM,EAAA,cAAA,KAAmB,MAAM,MAAA,CAAO,OAAO,GAAoB,CAAA;AAAA,QACvE,YAAc,EAAA,KAAA;AAAA,QACd,OAAS,EAAA,QAAA;AAAA,QACT,IAAM,EAAA,UAAA;AAAA,QACN,YAAc,EAAA;AAAA,OACf,CAAA;AAED,MAAA,cAAA,GAAiB,QAAQ,EAAC;AAE1B,MAAA,UAAA,GAAa,MAAMA,yCAAA;AAAA,QACjB,IAAA;AAAA,QACA,cAAA;AAAA,QACA;AAAA;AAAA,OACF;AAAA;AAMF,IAAA,KAAA,MAAW,SAAS,cAAgB,EAAA;AAClC,MAAA,MAAM,OAA8B,GAAA;AAAA,QAClC,IAAI,KAAM,CAAA,EAAA;AAAA,QACV,MAAM,KAAM,CAAA,IAAA;AAAA,QACZ,WAAA,EAAa,MAAM,WAAe,IAAA,KAAA,CAAA;AAAA,QAClC,KAAK,KAAM,CAAA,OAAA;AAAA,QACX,YAAY,KAAM,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA,OAKpB;AACA,MAAO,MAAA,CAAA,GAAA,CAAI,KAAM,CAAA,IAAA,EAAM,OAAO,CAAA;AAAA;AAChC,WACO,GAAK,EAAA;AACZ,IAAAC,iBAAA;AAAA,MACE,EAAE,MAAQ,EAAA,IAAA,CAAK,MAAO,EAAA;AAAA,MACtB,uCAAA;AAAA,MACA,UAAA;AAAA,MACA,MAAA;AAAA,MACA;AAAA,KACF;AAAA;AAEF,EAAA,OAAO,EAAE,UAAW,EAAA;AACtB;;;;"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var catalogUtils = require('../../catalog/catalogUtils.cjs.js');
|
|
4
|
+
require('@backstage/errors');
|
|
5
|
+
require('@backstage/plugin-permission-common');
|
|
6
|
+
require('@red-hat-developer-hub/backstage-plugin-bulk-import-common');
|
|
7
|
+
require('just-kebab-case');
|
|
8
|
+
var loggingUtils = require('../../helpers/loggingUtils.cjs.js');
|
|
9
|
+
require('git-url-parse');
|
|
10
|
+
|
|
11
|
+
async function findOpenPRForBranch(logger, config, gitlab, owner, repo, branchName, withCatalogInfoContent = false) {
|
|
12
|
+
try {
|
|
13
|
+
const response = await gitlab.MergeRequests.all({
|
|
14
|
+
projectId: `${owner}/${repo}`,
|
|
15
|
+
state: "opened"
|
|
16
|
+
});
|
|
17
|
+
for (const pull of response) {
|
|
18
|
+
if (pull.source_branch === branchName) {
|
|
19
|
+
return {
|
|
20
|
+
prNum: pull.iid,
|
|
21
|
+
prUrl: pull.web_url,
|
|
22
|
+
prTitle: pull.title,
|
|
23
|
+
prBody: pull.description ?? void 0,
|
|
24
|
+
prCatalogInfoContent: withCatalogInfoContent ? await getCatalogInfoContentFromPR(
|
|
25
|
+
logger,
|
|
26
|
+
config,
|
|
27
|
+
gitlab,
|
|
28
|
+
owner,
|
|
29
|
+
repo,
|
|
30
|
+
pull.iid,
|
|
31
|
+
pull.sha
|
|
32
|
+
) : void 0,
|
|
33
|
+
lastUpdate: pull.updated_at
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
} catch (error) {
|
|
38
|
+
loggingUtils.logErrorIfNeeded(logger, "Error fetching pull requests", error);
|
|
39
|
+
}
|
|
40
|
+
return {};
|
|
41
|
+
}
|
|
42
|
+
async function getCatalogInfoContentFromPR(logger, config, gitlab, owner, repo, prNumber, prHeadSha) {
|
|
43
|
+
try {
|
|
44
|
+
const filePath = catalogUtils.getCatalogFilename(config);
|
|
45
|
+
const fileContentResponse = await gitlab.RepositoryFiles.show(
|
|
46
|
+
`${owner}/${repo}`,
|
|
47
|
+
filePath,
|
|
48
|
+
prHeadSha
|
|
49
|
+
);
|
|
50
|
+
if (!("content" in fileContentResponse)) {
|
|
51
|
+
return void 0;
|
|
52
|
+
}
|
|
53
|
+
return Buffer.from(fileContentResponse.content, "base64").toString("utf-8");
|
|
54
|
+
} catch (error) {
|
|
55
|
+
loggingUtils.logErrorIfNeeded(
|
|
56
|
+
logger,
|
|
57
|
+
`Error fetching catalog-info content from PR ${prNumber}`,
|
|
58
|
+
error
|
|
59
|
+
);
|
|
60
|
+
return undefined;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
async function closePRWithComment(gitlab, owner, repo, prNum, comment) {
|
|
64
|
+
await gitlab.MergeRequestNotes.create(`${owner}/${repo}`, prNum, comment);
|
|
65
|
+
await gitlab.MergeRequests.edit(`${owner}/${repo}`, prNum, {
|
|
66
|
+
stateEvent: "close"
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
exports.closePRWithComment = closePRWithComment;
|
|
71
|
+
exports.findOpenPRForBranch = findOpenPRForBranch;
|
|
72
|
+
//# sourceMappingURL=prUtils.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prUtils.cjs.js","sources":["../../../src/gitlab/utils/prUtils.ts"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { LoggerService } from '@backstage/backend-plugin-api';\nimport type { Config } from '@backstage/config';\n\nimport { getCatalogFilename } from '../../catalog/catalogUtils';\nimport { logErrorIfNeeded } from '../../helpers';\n\nexport async function findOpenPRForBranch(\n logger: LoggerService,\n config: Config,\n gitlab: any,\n owner: string,\n repo: string,\n branchName: string,\n withCatalogInfoContent: boolean = false,\n): Promise<{\n prNum?: number;\n prUrl?: string;\n prTitle?: string;\n prBody?: string;\n prCatalogInfoContent?: string;\n lastUpdate?: string;\n}> {\n try {\n const response = await gitlab.MergeRequests.all({\n projectId: `${owner}/${repo}`,\n state: 'opened',\n });\n\n for (const pull of response) {\n if (pull.source_branch === branchName) {\n return {\n prNum: pull.iid,\n prUrl: pull.web_url,\n prTitle: pull.title,\n prBody: pull.description ?? undefined,\n prCatalogInfoContent: withCatalogInfoContent\n ? await getCatalogInfoContentFromPR(\n logger,\n config,\n gitlab,\n owner,\n repo,\n pull.iid,\n pull.sha,\n )\n : undefined,\n lastUpdate: pull.updated_at,\n };\n }\n }\n } catch (error) {\n logErrorIfNeeded(logger, 'Error fetching pull requests', error);\n }\n return {};\n}\n\nasync function getCatalogInfoContentFromPR(\n logger: LoggerService,\n config: Config,\n gitlab: any,\n owner: string,\n repo: string,\n prNumber: number,\n prHeadSha: string,\n): Promise<string | undefined> {\n try {\n const filePath = getCatalogFilename(config);\n const fileContentResponse = await gitlab.RepositoryFiles.show(\n `${owner}/${repo}`,\n filePath,\n prHeadSha,\n );\n if (!('content' in fileContentResponse)) {\n return undefined;\n }\n return Buffer.from(fileContentResponse.content, 'base64').toString('utf-8');\n } catch (error: any) {\n logErrorIfNeeded(\n logger,\n `Error fetching catalog-info content from PR ${prNumber}`,\n error,\n );\n return undefined;\n }\n}\n\nexport async function closePRWithComment(\n gitlab: any,\n owner: string,\n repo: string,\n prNum: number,\n comment: string,\n) {\n await gitlab.MergeRequestNotes.create(`${owner}/${repo}`, prNum, comment);\n await gitlab.MergeRequests.edit(`${owner}/${repo}`, prNum, {\n stateEvent: 'close',\n });\n}\n"],"names":["logErrorIfNeeded","getCatalogFilename"],"mappings":";;;;;;;;;;AAsBsB,eAAA,mBAAA,CACpB,QACA,MACA,EAAA,MAAA,EACA,OACA,IACA,EAAA,UAAA,EACA,yBAAkC,KAQjC,EAAA;AACD,EAAI,IAAA;AACF,IAAA,MAAM,QAAW,GAAA,MAAM,MAAO,CAAA,aAAA,CAAc,GAAI,CAAA;AAAA,MAC9C,SAAW,EAAA,CAAA,EAAG,KAAK,CAAA,CAAA,EAAI,IAAI,CAAA,CAAA;AAAA,MAC3B,KAAO,EAAA;AAAA,KACR,CAAA;AAED,IAAA,KAAA,MAAW,QAAQ,QAAU,EAAA;AAC3B,MAAI,IAAA,IAAA,CAAK,kBAAkB,UAAY,EAAA;AACrC,QAAO,OAAA;AAAA,UACL,OAAO,IAAK,CAAA,GAAA;AAAA,UACZ,OAAO,IAAK,CAAA,OAAA;AAAA,UACZ,SAAS,IAAK,CAAA,KAAA;AAAA,UACd,MAAA,EAAQ,KAAK,WAAe,IAAA,KAAA,CAAA;AAAA,UAC5B,oBAAA,EAAsB,yBAClB,MAAM,2BAAA;AAAA,YACJ,MAAA;AAAA,YACA,MAAA;AAAA,YACA,MAAA;AAAA,YACA,KAAA;AAAA,YACA,IAAA;AAAA,YACA,IAAK,CAAA,GAAA;AAAA,YACL,IAAK,CAAA;AAAA,WAEP,GAAA,KAAA,CAAA;AAAA,UACJ,YAAY,IAAK,CAAA;AAAA,SACnB;AAAA;AACF;AACF,WACO,KAAO,EAAA;AACd,IAAiBA,6BAAA,CAAA,MAAA,EAAQ,gCAAgC,KAAK,CAAA;AAAA;AAEhE,EAAA,OAAO,EAAC;AACV;AAEA,eAAe,4BACb,MACA,EAAA,MAAA,EACA,QACA,KACA,EAAA,IAAA,EACA,UACA,SAC6B,EAAA;AAC7B,EAAI,IAAA;AACF,IAAM,MAAA,QAAA,GAAWC,gCAAmB,MAAM,CAAA;AAC1C,IAAM,MAAA,mBAAA,GAAsB,MAAM,MAAA,CAAO,eAAgB,CAAA,IAAA;AAAA,MACvD,CAAA,EAAG,KAAK,CAAA,CAAA,EAAI,IAAI,CAAA,CAAA;AAAA,MAChB,QAAA;AAAA,MACA;AAAA,KACF;AACA,IAAI,IAAA,EAAE,aAAa,mBAAsB,CAAA,EAAA;AACvC,MAAO,OAAA,KAAA,CAAA;AAAA;AAET,IAAA,OAAO,OAAO,IAAK,CAAA,mBAAA,CAAoB,SAAS,QAAQ,CAAA,CAAE,SAAS,OAAO,CAAA;AAAA,WACnE,KAAY,EAAA;AACnB,IAAAD,6BAAA;AAAA,MACE,MAAA;AAAA,MACA,+CAA+C,QAAQ,CAAA,CAAA;AAAA,MACvD;AAAA,KACF;AACA,IAAO,OAAA,SAAA;AAAA;AAEX;AAEA,eAAsB,kBACpB,CAAA,MAAA,EACA,KACA,EAAA,IAAA,EACA,OACA,OACA,EAAA;AACA,EAAM,MAAA,MAAA,CAAO,kBAAkB,MAAO,CAAA,CAAA,EAAG,KAAK,CAAI,CAAA,EAAA,IAAI,CAAI,CAAA,EAAA,KAAA,EAAO,OAAO,CAAA;AACxE,EAAM,MAAA,MAAA,CAAO,cAAc,IAAK,CAAA,CAAA,EAAG,KAAK,CAAI,CAAA,EAAA,IAAI,IAAI,KAAO,EAAA;AAAA,IACzD,UAAY,EAAA;AAAA,GACb,CAAA;AACH;;;;;"}
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var gitUrlParse = require('git-url-parse');
|
|
4
|
+
var catalogUtils = require('../../catalog/catalogUtils.cjs.js');
|
|
5
|
+
var handlers = require('../../service/handlers/handlers.cjs.js');
|
|
6
|
+
var utils = require('./utils.cjs.js');
|
|
7
|
+
|
|
8
|
+
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
|
|
9
|
+
|
|
10
|
+
var gitUrlParse__default = /*#__PURE__*/_interopDefaultCompat(gitUrlParse);
|
|
11
|
+
|
|
12
|
+
async function validateAndBuildRepoData(gitlabCredentialsProvider, integrations, config, input) {
|
|
13
|
+
const glConfig = integrations.gitlab.byUrl(input.repoUrl)?.config;
|
|
14
|
+
if (!glConfig) {
|
|
15
|
+
throw new Error(`Could not find GL integration from ${input.repoUrl}`);
|
|
16
|
+
}
|
|
17
|
+
const gitUrl = gitUrlParse__default.default(input.repoUrl);
|
|
18
|
+
const owner = gitUrl.organization;
|
|
19
|
+
const repo = gitUrl.name;
|
|
20
|
+
const credentials = await gitlabCredentialsProvider.getAllCredentials({
|
|
21
|
+
host: glConfig.host
|
|
22
|
+
});
|
|
23
|
+
if (credentials.length === 0) {
|
|
24
|
+
throw new Error(`No credentials for GL integration`);
|
|
25
|
+
}
|
|
26
|
+
const branchName = catalogUtils.getBranchName(config);
|
|
27
|
+
return { glConfig, owner, repo, credentials, branchName };
|
|
28
|
+
}
|
|
29
|
+
async function searchRepos(gitlab, glSearchQuery, pageNumber = handlers.DefaultPageNumber, pageSize = handlers.DefaultPageSize) {
|
|
30
|
+
const repoSearchResp = await gitlab.Projects.all({
|
|
31
|
+
search: glSearchQuery,
|
|
32
|
+
membership: true,
|
|
33
|
+
perPage: pageSize,
|
|
34
|
+
page: pageNumber
|
|
35
|
+
});
|
|
36
|
+
return {
|
|
37
|
+
totalCount: repoSearchResp?.paginationInfo?.total,
|
|
38
|
+
repositories: repoSearchResp?.data?.map((repo) => {
|
|
39
|
+
return {
|
|
40
|
+
name: repo.name,
|
|
41
|
+
full_name: repo.path_with_namespace,
|
|
42
|
+
url: repo._links.self,
|
|
43
|
+
html_url: repo.web_url,
|
|
44
|
+
default_branch: repo.default_branch,
|
|
45
|
+
updated_at: repo.updated_at
|
|
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
|
|
73
|
+
});
|
|
74
|
+
data?.forEach((repo) => {
|
|
75
|
+
repositories.set(repo.path_with_namespace, {
|
|
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
|
+
}
|
|
91
|
+
} catch (err) {
|
|
92
|
+
utils.handleError(
|
|
93
|
+
deps,
|
|
94
|
+
"Fetching repositories with token from token",
|
|
95
|
+
credential,
|
|
96
|
+
errors,
|
|
97
|
+
err
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
return { totalCount };
|
|
101
|
+
}
|
|
102
|
+
async function addGitlabTokenOrgRepositories(deps, gitlab, credential, org, repositories, errors, reqParams) {
|
|
103
|
+
const search = reqParams?.search;
|
|
104
|
+
const pageNumber = reqParams?.pageNumber ?? handlers.DefaultPageNumber;
|
|
105
|
+
const pageSize = reqParams?.pageSize ?? handlers.DefaultPageSize;
|
|
106
|
+
let totalCount;
|
|
107
|
+
try {
|
|
108
|
+
const params = {
|
|
109
|
+
perPage: pageSize,
|
|
110
|
+
search: search ?? void 0,
|
|
111
|
+
page: pageNumber,
|
|
112
|
+
showExpanded: true
|
|
113
|
+
};
|
|
114
|
+
const { data, paginationInfo } = await gitlab.Groups.allProjects(org, params);
|
|
115
|
+
data?.forEach((repo) => {
|
|
116
|
+
repositories.set(repo.path_with_namespace, {
|
|
117
|
+
name: repo.name,
|
|
118
|
+
full_name: repo.path_with_namespace,
|
|
119
|
+
url: repo._links.self,
|
|
120
|
+
html_url: repo.web_url,
|
|
121
|
+
default_branch: repo.default_branch,
|
|
122
|
+
updated_at: repo.updated_at
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
totalCount = await utils.computeTotalCountFromPaginationInfo(
|
|
126
|
+
deps,
|
|
127
|
+
paginationInfo,
|
|
128
|
+
pageSize
|
|
129
|
+
// Not thrilled with this for some reason
|
|
130
|
+
);
|
|
131
|
+
} catch (err) {
|
|
132
|
+
utils.handleError(
|
|
133
|
+
deps,
|
|
134
|
+
"Fetching org repositories with token from token",
|
|
135
|
+
credential,
|
|
136
|
+
errors,
|
|
137
|
+
err
|
|
138
|
+
);
|
|
139
|
+
}
|
|
140
|
+
return { totalCount };
|
|
141
|
+
}
|
|
142
|
+
async function fileExistsInDefaultBranch(logger, gitlab, owner, repo, fileName, defaultBranch = "main") {
|
|
143
|
+
try {
|
|
144
|
+
await gitlab.RepositoryFiles.show(
|
|
145
|
+
`${owner}/${repo}`,
|
|
146
|
+
fileName,
|
|
147
|
+
defaultBranch
|
|
148
|
+
);
|
|
149
|
+
return true;
|
|
150
|
+
} catch (error) {
|
|
151
|
+
if (error.cause.response.status === 404) {
|
|
152
|
+
return false;
|
|
153
|
+
}
|
|
154
|
+
logger.debug(
|
|
155
|
+
`Unable to determine if a file named ${fileName} already exists in repo ${repo}: ${error}`
|
|
156
|
+
);
|
|
157
|
+
return undefined;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
async function createOrUpdateFileInBranch(gitlab, owner, repo, branchName, fileName, fileContent) {
|
|
161
|
+
try {
|
|
162
|
+
const existingFile = await gitlab.RepositoryFiles.show(
|
|
163
|
+
`${owner}/${repo}`,
|
|
164
|
+
fileName,
|
|
165
|
+
branchName
|
|
166
|
+
);
|
|
167
|
+
if (Array.isArray(existingFile) || !("content_sha256" in existingFile)) {
|
|
168
|
+
throw new Error(
|
|
169
|
+
`The content at path ${fileName} is not a file or the response from gitlab does not contain the 'content_sha256' property.`
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
await gitlab.RepositoryFiles.edit(
|
|
173
|
+
`${owner}/${repo}`,
|
|
174
|
+
fileName,
|
|
175
|
+
branchName,
|
|
176
|
+
fileContent,
|
|
177
|
+
`Add ${fileName} config file`
|
|
178
|
+
);
|
|
179
|
+
} catch (error) {
|
|
180
|
+
if (error.cause.response.status === 404) {
|
|
181
|
+
await gitlab.RepositoryFiles.create(
|
|
182
|
+
`${owner}/${repo}`,
|
|
183
|
+
fileName,
|
|
184
|
+
branchName,
|
|
185
|
+
fileContent,
|
|
186
|
+
`Add ${fileName} config file`
|
|
187
|
+
);
|
|
188
|
+
} else {
|
|
189
|
+
throw error;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
exports.addGitlabTokenOrgRepositories = addGitlabTokenOrgRepositories;
|
|
195
|
+
exports.addGitlabTokenRepositories = addGitlabTokenRepositories;
|
|
196
|
+
exports.createOrUpdateFileInBranch = createOrUpdateFileInBranch;
|
|
197
|
+
exports.fileExistsInDefaultBranch = fileExistsInDefaultBranch;
|
|
198
|
+
exports.searchRepos = searchRepos;
|
|
199
|
+
exports.validateAndBuildRepoData = validateAndBuildRepoData;
|
|
200
|
+
//# sourceMappingURL=repoUtils.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repoUtils.cjs.js","sources":["../../../src/gitlab/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 GitlabCredentials,\n GitLabIntegrationConfig,\n ScmIntegrations,\n} from '@backstage/integration';\n\nimport {\n AllGroupProjectsOptions,\n BasePaginationRequestOptions,\n Gitlab,\n OffsetPaginationRequestOptions,\n ProjectSchema,\n ShowExpanded,\n Sudo,\n} from '@gitbeaker/rest';\nimport gitUrlParse from 'git-url-parse';\n\nimport { getBranchName } from '../../catalog/catalogUtils';\nimport {\n DefaultPageNumber,\n DefaultPageSize,\n} from '../../service/handlers/handlers';\nimport { CustomGitlabCredentialsProvider } from '../GitlabAppManager';\nimport type {\n ExtendedGitlabCredentials,\n GitlabFetchError,\n GitlabRepository,\n} from '../types';\nimport { computeTotalCountFromPaginationInfo, handleError } from './utils';\n\nexport type ValidatedRepo = {\n glConfig: GitLabIntegrationConfig;\n credentials: ExtendedGitlabCredentials[];\n owner: string;\n repo: string;\n branchName: string;\n};\n\nexport async function validateAndBuildRepoData(\n gitlabCredentialsProvider: CustomGitlabCredentialsProvider,\n integrations: ScmIntegrations,\n config: Config,\n input: {\n repoUrl: string;\n },\n): Promise<ValidatedRepo> {\n const glConfig = 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 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(config);\n return { glConfig, owner, repo, credentials, branchName };\n}\n\nexport async function searchRepos(\n gitlab: InstanceType<typeof Gitlab<false>>,\n glSearchQuery: string,\n pageNumber: number = DefaultPageNumber,\n pageSize: number = DefaultPageSize,\n): Promise<{ totalCount?: number; repositories: GitlabRepository[] }> {\n const repoSearchResp = await gitlab.Projects.all<true, 'offset'>({\n search: glSearchQuery,\n membership: true,\n perPage: pageSize,\n page: pageNumber,\n });\n\n return {\n totalCount: repoSearchResp?.paginationInfo?.total,\n repositories:\n repoSearchResp?.data?.map((repo: ProjectSchema) => {\n return {\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 }) ?? [],\n };\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 addGitlabTokenRepositories(\n deps: {\n logger: LoggerService;\n },\n gitlab: InstanceType<typeof Gitlab<false>>,\n credential: GitlabCredentials,\n repositories: Map<string, GitlabRepository>,\n errors: Map<number, GitlabFetchError>,\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 // Use the projects api with the search param\n // that api gives us all the things the token has access to including the different projects in various groups\n\n const searchResp = await searchRepos(\n gitlab,\n search,\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 Projects.all method with the membership: true option will grab all the repositories/projects the gitlab 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 { data, paginationInfo } = await gitlab.Projects.all<\n true,\n 'offset'\n >({\n membership: true,\n perPage: pageSize,\n page: pageNumber,\n showExpanded: true,\n });\n\n data?.forEach((repo: ProjectSchema) => {\n repositories.set(repo.path_with_namespace, {\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 });\n\n /*\n paginationInfo: {\n total: , This is the total amount of repos, but will be NaN if the value is above 10k, see: https://github.com/jdalrymple/gitbeaker/issues/839#issuecomment-636482319\n next: ,\n current: ,\n previous: ,\n perPage: ,\n totalPages:\n }\n */\n\n totalCount = await computeTotalCountFromPaginationInfo(\n deps,\n paginationInfo,\n pageSize, // Not thrilled with this for some reason\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 addGitlabTokenOrgRepositories(\n deps: {\n logger: LoggerService;\n },\n gitlab: InstanceType<typeof Gitlab<false>>,\n credential: GitlabCredentials,\n org: string,\n repositories: Map<string, GitlabRepository>,\n errors: Map<number, GitlabFetchError>,\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 // For Search: Use the group allProjects api with the search param.\n // I noticed that using this api will only return values when 3 or more characters are used for the search\n // that api gives us all the things the token has access\n const params:\n | (AllGroupProjectsOptions &\n BasePaginationRequestOptions<'offset'> &\n OffsetPaginationRequestOptions &\n Sudo &\n ShowExpanded<true>)\n | undefined = {\n perPage: pageSize,\n search: search ?? undefined,\n page: pageNumber,\n showExpanded: true,\n };\n\n const { data, paginationInfo } = await gitlab.Groups.allProjects<\n true,\n 'offset'\n >(org, params);\n\n data?.forEach((repo: ProjectSchema) => {\n repositories.set(repo.path_with_namespace, {\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 });\n\n totalCount = await computeTotalCountFromPaginationInfo(\n deps,\n paginationInfo,\n pageSize, // Not thrilled with this for some reason\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 gitlab: InstanceType<typeof Gitlab<false>>,\n owner: string,\n repo: string,\n fileName: string,\n defaultBranch: string = 'main',\n) {\n try {\n await gitlab.RepositoryFiles.show(\n `${owner}/${repo}`,\n fileName,\n defaultBranch,\n );\n return true;\n } catch (error: any) {\n if (error.cause.response.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 gitlab: InstanceType<typeof Gitlab<false>>,\n owner: string,\n repo: string,\n branchName: string,\n fileName: string,\n fileContent: string,\n): Promise<void> {\n try {\n const existingFile = await gitlab.RepositoryFiles.show(\n `${owner}/${repo}`,\n fileName,\n 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) || !('content_sha256' in existingFile)) {\n throw new Error(\n `The content at path ${fileName} is not a file or the response from gitlab does not contain the 'content_sha256' property.`,\n );\n }\n // If the file already exists, update it\n await gitlab.RepositoryFiles.edit(\n `${owner}/${repo}`,\n fileName,\n branchName,\n fileContent,\n `Add ${fileName} config file`,\n );\n } catch (error: any) {\n if (error.cause.response.status === 404) {\n // If the file does not exist, create it\n await gitlab.RepositoryFiles.create(\n `${owner}/${repo}`,\n fileName,\n branchName,\n fileContent,\n `Add ${fileName} config file`,\n );\n } else {\n throw error;\n }\n }\n}\n"],"names":["gitUrlParse","getBranchName","DefaultPageNumber","DefaultPageSize","computeTotalCountFromPaginationInfo","handleError"],"mappings":"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"}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
require('@backstage/errors');
|
|
4
|
+
require('@backstage/plugin-permission-common');
|
|
5
|
+
require('@red-hat-developer-hub/backstage-plugin-bulk-import-common');
|
|
6
|
+
require('just-kebab-case');
|
|
7
|
+
var loggingUtils = require('../../helpers/loggingUtils.cjs.js');
|
|
8
|
+
require('git-url-parse');
|
|
9
|
+
var glUtils = require('./glUtils.cjs.js');
|
|
10
|
+
var repoUtils = require('./repoUtils.cjs.js');
|
|
11
|
+
|
|
12
|
+
function createCredentialError(err) {
|
|
13
|
+
if (err) {
|
|
14
|
+
return {
|
|
15
|
+
type: "token",
|
|
16
|
+
error: {
|
|
17
|
+
name: err.name,
|
|
18
|
+
message: err.message
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
return undefined;
|
|
23
|
+
}
|
|
24
|
+
function verifyAndGetIntegrations(deps, integrations) {
|
|
25
|
+
const glConfigs = integrations.gitlab.list().map((glInit) => glInit.config);
|
|
26
|
+
if (glConfigs.length === 0) {
|
|
27
|
+
deps.logger.debug(
|
|
28
|
+
"No GitLab Integration in config => returning an empty list of repositories."
|
|
29
|
+
);
|
|
30
|
+
throw new Error(
|
|
31
|
+
"Looks like there is no GitLab Integration in config. Please add a configuration entry under 'integrations.gitlab"
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
return glConfigs;
|
|
35
|
+
}
|
|
36
|
+
async function getCredentialsFromIntegrations(gitlabCredentialsProvider, glConfigs) {
|
|
37
|
+
const credentialsByConfig = /* @__PURE__ */ new Map();
|
|
38
|
+
for (const glConfig of glConfigs) {
|
|
39
|
+
const creds = await getCredentialsForConfig(
|
|
40
|
+
gitlabCredentialsProvider,
|
|
41
|
+
glConfig
|
|
42
|
+
);
|
|
43
|
+
credentialsByConfig.set(glConfig, creds);
|
|
44
|
+
}
|
|
45
|
+
return credentialsByConfig;
|
|
46
|
+
}
|
|
47
|
+
async function getCredentialsForConfig(gitlabCredentialsProvider, glConfig) {
|
|
48
|
+
return await gitlabCredentialsProvider.getAllCredentials({
|
|
49
|
+
host: glConfig.host
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
function handleError(deps, desc, _credential, errors, err) {
|
|
53
|
+
loggingUtils.logErrorIfNeeded(deps.logger, `${desc} failed`, err);
|
|
54
|
+
const credentialError = createCredentialError(err);
|
|
55
|
+
if (credentialError) {
|
|
56
|
+
errors.set(-1, credentialError);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
async function computeTotalCountFromPaginationInfo(deps, paginationInfo, pageSize) {
|
|
60
|
+
if (isNaN(paginationInfo.total)) {
|
|
61
|
+
deps.logger.debug(
|
|
62
|
+
`Too many result, total count is NaN, returning current page size`
|
|
63
|
+
);
|
|
64
|
+
return pageSize;
|
|
65
|
+
}
|
|
66
|
+
return paginationInfo.total;
|
|
67
|
+
}
|
|
68
|
+
async function executeFunctionOnFirstSuccessfulIntegration(deps, integrations, params) {
|
|
69
|
+
const validatedRepo = await repoUtils.validateAndBuildRepoData(
|
|
70
|
+
deps.gitlabCredentialsProvider,
|
|
71
|
+
integrations,
|
|
72
|
+
deps.config,
|
|
73
|
+
params
|
|
74
|
+
);
|
|
75
|
+
for (const credential of validatedRepo.credentials) {
|
|
76
|
+
const glKit = glUtils.buildGitlab(
|
|
77
|
+
deps,
|
|
78
|
+
{ credential, owner: validatedRepo.owner },
|
|
79
|
+
validatedRepo.glConfig.baseUrl
|
|
80
|
+
);
|
|
81
|
+
const res = await params.fn(validatedRepo, glKit);
|
|
82
|
+
if (!res.successful) {
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
return res.result;
|
|
86
|
+
}
|
|
87
|
+
return undefined;
|
|
88
|
+
}
|
|
89
|
+
async function fetchFromAllIntegrations(deps, integrations, params) {
|
|
90
|
+
const glConfigs = verifyAndGetIntegrations(deps, integrations);
|
|
91
|
+
const credentialsByConfig = await getCredentialsFromIntegrations(
|
|
92
|
+
deps.gitlabCredentialsProvider,
|
|
93
|
+
glConfigs
|
|
94
|
+
);
|
|
95
|
+
const errors = /* @__PURE__ */ new Map();
|
|
96
|
+
const data = [];
|
|
97
|
+
const dataErrs = [];
|
|
98
|
+
let stopFetchingData = false;
|
|
99
|
+
for (const [glConfig, credentials] of credentialsByConfig) {
|
|
100
|
+
if (stopFetchingData) {
|
|
101
|
+
break;
|
|
102
|
+
}
|
|
103
|
+
deps.logger.debug(
|
|
104
|
+
`Got ${credentials.length} credential(s) for ${glConfig.host}`
|
|
105
|
+
);
|
|
106
|
+
for (const credential of credentials) {
|
|
107
|
+
const glKit = glUtils.buildGitlab(deps, { credential, errors }, glConfig.baseUrl);
|
|
108
|
+
const res = await params.dataFetcher(glKit, credential, glConfig);
|
|
109
|
+
res.errors?.forEach((err) => dataErrs.push(err));
|
|
110
|
+
if (res.result) {
|
|
111
|
+
data.push(res.result);
|
|
112
|
+
}
|
|
113
|
+
stopFetchingData = res.stopFetchingData;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
const aggregatedErrors = /* @__PURE__ */ new Map();
|
|
117
|
+
errors.forEach((err, num) => aggregatedErrors.set(num, err));
|
|
118
|
+
dataErrs.forEach((err, idx) => aggregatedErrors.set(idx, err));
|
|
119
|
+
return { data, errors: aggregatedErrors };
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
exports.computeTotalCountFromPaginationInfo = computeTotalCountFromPaginationInfo;
|
|
123
|
+
exports.createCredentialError = createCredentialError;
|
|
124
|
+
exports.executeFunctionOnFirstSuccessfulIntegration = executeFunctionOnFirstSuccessfulIntegration;
|
|
125
|
+
exports.fetchFromAllIntegrations = fetchFromAllIntegrations;
|
|
126
|
+
exports.getCredentialsForConfig = getCredentialsForConfig;
|
|
127
|
+
exports.getCredentialsFromIntegrations = getCredentialsFromIntegrations;
|
|
128
|
+
exports.handleError = handleError;
|
|
129
|
+
exports.verifyAndGetIntegrations = verifyAndGetIntegrations;
|
|
130
|
+
//# sourceMappingURL=utils.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.cjs.js","sources":["../../../src/gitlab/utils/utils.ts"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type {\n CacheService,\n LoggerService,\n} from '@backstage/backend-plugin-api';\nimport type { Config } from '@backstage/config';\nimport {\n ScmIntegrations,\n type GitLabIntegrationConfig,\n} from '@backstage/integration';\n\nimport { Gitlab, OffsetPagination } from '@gitbeaker/rest';\n\nimport { logErrorIfNeeded } from '../../helpers';\nimport type { CustomGitlabCredentialsProvider } from '../GitlabAppManager';\nimport {\n type ExtendedGitlabCredentials,\n type GitlabFetchError,\n} from '../types';\nimport { buildGitlab } from './glUtils';\nimport { validateAndBuildRepoData, ValidatedRepo } from './repoUtils';\n\n// /**\n// * Creates the GitlabFetchError to be stored in the returned errors array of the returned GitlabRepositoryResponse object\n// */\nexport function createCredentialError(\n err?: Error,\n): GitlabFetchError | undefined {\n if (err) {\n return {\n type: 'token',\n error: {\n name: err.name,\n message: err.message,\n },\n };\n }\n return undefined;\n}\n\nexport function verifyAndGetIntegrations(\n deps: {\n logger: LoggerService;\n },\n\n integrations: ScmIntegrations,\n) {\n const glConfigs = integrations.gitlab.list().map(glInit => glInit.config);\n\n if (glConfigs.length === 0) {\n deps.logger.debug(\n 'No GitLab Integration in config => returning an empty list of repositories.',\n );\n throw new Error(\n \"Looks like there is no GitLab Integration in config. Please add a configuration entry under 'integrations.gitlab\",\n );\n }\n return glConfigs;\n}\n\nexport async function getCredentialsFromIntegrations(\n gitlabCredentialsProvider: CustomGitlabCredentialsProvider,\n glConfigs: GitLabIntegrationConfig[],\n) {\n const credentialsByConfig = new Map<\n GitLabIntegrationConfig,\n ExtendedGitlabCredentials[]\n >();\n for (const glConfig of glConfigs) {\n const creds = await getCredentialsForConfig(\n gitlabCredentialsProvider,\n glConfig,\n );\n credentialsByConfig.set(glConfig, creds);\n }\n return credentialsByConfig;\n}\n\nexport async function getCredentialsForConfig(\n gitlabCredentialsProvider: CustomGitlabCredentialsProvider,\n glConfig: GitLabIntegrationConfig,\n) {\n return await gitlabCredentialsProvider.getAllCredentials({\n host: glConfig.host,\n });\n}\n\nexport function handleError(\n deps: {\n logger: LoggerService;\n },\n desc: string,\n _credential: ExtendedGitlabCredentials,\n errors: Map<number, GitlabFetchError>,\n err: any,\n) {\n logErrorIfNeeded(deps.logger, `${desc} failed`, err);\n const credentialError = createCredentialError(err as Error);\n if (credentialError) {\n errors.set(-1, credentialError);\n }\n}\n\nexport async function computeTotalCountFromPaginationInfo(\n deps: {\n logger: LoggerService;\n },\n paginationInfo: OffsetPagination,\n pageSize?: number,\n): Promise<number | undefined> {\n /*\n paginationInfo: {\n total: , This is the total amount of repos, but will be NaN if the value is above 10k, see: https://github.com/jdalrymple/gitbeaker/issues/839#issuecomment-636482319\n next: ,\n current: ,\n previous: ,\n perPage: ,\n totalPages:\n }\n */\n\n if (isNaN(paginationInfo.total)) {\n deps.logger.debug(\n `Too many result, total count is NaN, returning current page size`,\n );\n return pageSize;\n }\n return paginationInfo.total;\n}\n\nexport async function executeFunctionOnFirstSuccessfulIntegration<T>(\n deps: {\n logger: LoggerService;\n cache: CacheService;\n config: Config;\n gitlabCredentialsProvider: CustomGitlabCredentialsProvider;\n },\n integrations: ScmIntegrations,\n params: {\n repoUrl: string;\n fn: (\n validatedRepo: ValidatedRepo,\n gitlab: InstanceType<typeof Gitlab<false>>,\n ) => Promise<{ successful: boolean; result?: T }>;\n },\n) {\n const validatedRepo = await validateAndBuildRepoData(\n deps.gitlabCredentialsProvider,\n integrations,\n deps.config,\n params,\n );\n for (const credential of validatedRepo.credentials) {\n const glKit = buildGitlab(\n deps,\n { credential, owner: validatedRepo.owner },\n validatedRepo.glConfig.baseUrl,\n );\n const res = await params.fn(validatedRepo, glKit);\n if (!res.successful) {\n continue;\n }\n return res.result;\n }\n return undefined;\n}\n\nexport async function fetchFromAllIntegrations<T>(\n deps: {\n logger: LoggerService;\n cache: CacheService;\n gitlabCredentialsProvider: CustomGitlabCredentialsProvider;\n },\n integrations: ScmIntegrations,\n params: {\n dataFetcher: (\n gitlab: InstanceType<typeof Gitlab<false>>,\n credential: ExtendedGitlabCredentials,\n glConfig: GitLabIntegrationConfig,\n ) => Promise<{\n stopFetchingData?: boolean;\n result?: T;\n errors?: GitlabFetchError[];\n }>;\n },\n) {\n const glConfigs = verifyAndGetIntegrations(deps, integrations);\n\n const credentialsByConfig = await getCredentialsFromIntegrations(\n deps.gitlabCredentialsProvider,\n glConfigs,\n );\n const errors = new Map<number, GitlabFetchError>();\n const data: T[] = [];\n const dataErrs: GitlabFetchError[] = [];\n let stopFetchingData: boolean | undefined = false;\n for (const [glConfig, credentials] of credentialsByConfig) {\n if (stopFetchingData) {\n break;\n }\n deps.logger.debug(\n `Got ${credentials.length} credential(s) for ${glConfig.host}`,\n );\n for (const credential of credentials) {\n const glKit = buildGitlab(deps, { credential, errors }, glConfig.baseUrl);\n const res = await params.dataFetcher(glKit, credential, glConfig);\n res.errors?.forEach(err => dataErrs.push(err));\n\n if (res.result) {\n data.push(res.result);\n }\n\n stopFetchingData = res.stopFetchingData;\n }\n }\n\n const aggregatedErrors = new Map<number, GitlabFetchError>();\n errors.forEach((err, num) => aggregatedErrors.set(num, err));\n dataErrs.forEach((err, idx) => aggregatedErrors.set(idx, err));\n\n return { data, errors: aggregatedErrors };\n}\n"],"names":["logErrorIfNeeded","validateAndBuildRepoData","buildGitlab"],"mappings":"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"}
|
|
@@ -1,11 +1,48 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
var gitUrlParse = require('git-url-parse');
|
|
4
|
+
|
|
5
|
+
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
|
|
6
|
+
|
|
7
|
+
var gitUrlParse__default = /*#__PURE__*/_interopDefaultCompat(gitUrlParse);
|
|
8
|
+
|
|
3
9
|
function getNestedValue(obj, path) {
|
|
4
10
|
return path.split(".").reduce(
|
|
5
11
|
(acc, key) => acc && acc[key] ? acc[key] : undefined,
|
|
6
12
|
obj
|
|
7
13
|
);
|
|
8
14
|
}
|
|
15
|
+
function extractLocationOwnerMap(locationUrls) {
|
|
16
|
+
const locationGitOwnerMap = /* @__PURE__ */ new Map();
|
|
17
|
+
for (const locationUrl of locationUrls) {
|
|
18
|
+
const split = locationUrl.split("/blob/");
|
|
19
|
+
if (split.length < 2) {
|
|
20
|
+
continue;
|
|
21
|
+
}
|
|
22
|
+
locationGitOwnerMap.set(locationUrl, gitUrlParse__default.default(split[0]).owner);
|
|
23
|
+
}
|
|
24
|
+
return locationGitOwnerMap;
|
|
25
|
+
}
|
|
26
|
+
function computeTotalCount(data, countList, pageSize) {
|
|
27
|
+
let totalCount = countList.reduce(
|
|
28
|
+
(accumulator, currentValue) => accumulator + currentValue,
|
|
29
|
+
0
|
|
30
|
+
);
|
|
31
|
+
if (totalCount < pageSize) {
|
|
32
|
+
totalCount = data.length;
|
|
33
|
+
}
|
|
34
|
+
return totalCount;
|
|
35
|
+
}
|
|
36
|
+
function parseGitURLForApprovalTool(repoUrl) {
|
|
37
|
+
const parsedRepoUrl = new URL(repoUrl);
|
|
38
|
+
if (parsedRepoUrl.hostname.includes("gitlab")) {
|
|
39
|
+
return "GITLAB";
|
|
40
|
+
}
|
|
41
|
+
return "GIT";
|
|
42
|
+
}
|
|
9
43
|
|
|
44
|
+
exports.computeTotalCount = computeTotalCount;
|
|
45
|
+
exports.extractLocationOwnerMap = extractLocationOwnerMap;
|
|
10
46
|
exports.getNestedValue = getNestedValue;
|
|
47
|
+
exports.parseGitURLForApprovalTool = parseGitURLForApprovalTool;
|
|
11
48
|
//# sourceMappingURL=utils.cjs.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.cjs.js","sources":["../../src/helpers/utils.ts"],"sourcesContent":["/*\n * Copyright
|
|
1
|
+
{"version":3,"file":"utils.cjs.js","sources":["../../src/helpers/utils.ts"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport gitUrlParse from 'git-url-parse';\n\nexport function getNestedValue<T>(obj: T, path: string): any {\n return path\n .split('.')\n .reduce(\n (acc, key) =>\n acc && (acc as Record<string, any>)[key]\n ? (acc as Record<string, any>)[key]\n : undefined,\n obj,\n );\n}\n\nexport function extractLocationOwnerMap(locationUrls: string[]) {\n const locationGitOwnerMap = new Map<string, string>();\n for (const locationUrl of locationUrls) {\n const split = locationUrl.split('/blob/');\n if (split.length < 2) {\n continue;\n }\n locationGitOwnerMap.set(locationUrl, gitUrlParse(split[0]).owner);\n }\n return locationGitOwnerMap;\n}\n\nexport function computeTotalCount<T>(\n data: T[],\n countList: number[],\n pageSize: number,\n) {\n let totalCount = countList.reduce(\n (accumulator, currentValue) => accumulator + currentValue,\n 0,\n );\n if (totalCount < pageSize) {\n totalCount = data.length;\n }\n return totalCount;\n}\n\nexport function parseGitURLForApprovalTool(repoUrl: string) {\n const parsedRepoUrl = new URL(repoUrl);\n if (parsedRepoUrl.hostname.includes('gitlab')) {\n return 'GITLAB';\n }\n\n return 'GIT';\n}\n"],"names":["gitUrlParse"],"mappings":";;;;;;;;AAkBgB,SAAA,cAAA,CAAkB,KAAQ,IAAmB,EAAA;AAC3D,EAAO,OAAA,IAAA,CACJ,KAAM,CAAA,GAAG,CACT,CAAA,MAAA;AAAA,IACC,CAAC,KAAK,GACJ,KAAA,GAAA,IAAQ,IAA4B,GAAG,CAAA,GAClC,GAA4B,CAAA,GAAG,CAChC,GAAA,SAAA;AAAA,IACN;AAAA,GACF;AACJ;AAEO,SAAS,wBAAwB,YAAwB,EAAA;AAC9D,EAAM,MAAA,mBAAA,uBAA0B,GAAoB,EAAA;AACpD,EAAA,KAAA,MAAW,eAAe,YAAc,EAAA;AACtC,IAAM,MAAA,KAAA,GAAQ,WAAY,CAAA,KAAA,CAAM,QAAQ,CAAA;AACxC,IAAI,IAAA,KAAA,CAAM,SAAS,CAAG,EAAA;AACpB,MAAA;AAAA;AAEF,IAAA,mBAAA,CAAoB,IAAI,WAAa,EAAAA,4BAAA,CAAY,MAAM,CAAC,CAAC,EAAE,KAAK,CAAA;AAAA;AAElE,EAAO,OAAA,mBAAA;AACT;AAEgB,SAAA,iBAAA,CACd,IACA,EAAA,SAAA,EACA,QACA,EAAA;AACA,EAAA,IAAI,aAAa,SAAU,CAAA,MAAA;AAAA,IACzB,CAAC,WAAa,EAAA,YAAA,KAAiB,WAAc,GAAA,YAAA;AAAA,IAC7C;AAAA,GACF;AACA,EAAA,IAAI,aAAa,QAAU,EAAA;AACzB,IAAA,UAAA,GAAa,IAAK,CAAA,MAAA;AAAA;AAEpB,EAAO,OAAA,UAAA;AACT;AAEO,SAAS,2BAA2B,OAAiB,EAAA;AAC1D,EAAM,MAAA,aAAA,GAAgB,IAAI,GAAA,CAAI,OAAO,CAAA;AACrC,EAAA,IAAI,aAAc,CAAA,QAAA,CAAS,QAAS,CAAA,QAAQ,CAAG,EAAA;AAC7C,IAAO,OAAA,QAAA;AAAA;AAGT,EAAO,OAAA,KAAA;AACT;;;;;;;"}
|