mobbdev 1.0.58 → 1.0.60
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/dist/index.mjs +919 -599
- package/package.json +2 -1
package/dist/index.mjs
CHANGED
|
@@ -145,6 +145,7 @@ var IssueType_Enum = /* @__PURE__ */ ((IssueType_Enum2) => {
|
|
|
145
145
|
IssueType_Enum2["InsecureBinderConfiguration"] = "INSECURE_BINDER_CONFIGURATION";
|
|
146
146
|
IssueType_Enum2["InsecureCookie"] = "INSECURE_COOKIE";
|
|
147
147
|
IssueType_Enum2["InsecureRandomness"] = "INSECURE_RANDOMNESS";
|
|
148
|
+
IssueType_Enum2["InsecureUuidVersion"] = "INSECURE_UUID_VERSION";
|
|
148
149
|
IssueType_Enum2["InsufficientLogging"] = "INSUFFICIENT_LOGGING";
|
|
149
150
|
IssueType_Enum2["JqueryDeprecatedSymbols"] = "JQUERY_DEPRECATED_SYMBOLS";
|
|
150
151
|
IssueType_Enum2["LeftoverDebugCode"] = "LEFTOVER_DEBUG_CODE";
|
|
@@ -222,19 +223,20 @@ var Vulnerability_Report_Issue_State_Enum = /* @__PURE__ */ ((Vulnerability_Repo
|
|
|
222
223
|
Vulnerability_Report_Issue_State_Enum2["Unsupported"] = "Unsupported";
|
|
223
224
|
return Vulnerability_Report_Issue_State_Enum2;
|
|
224
225
|
})(Vulnerability_Report_Issue_State_Enum || {});
|
|
225
|
-
var Vulnerability_Report_Issue_Tag_Enum = /* @__PURE__ */ ((
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
return
|
|
226
|
+
var Vulnerability_Report_Issue_Tag_Enum = /* @__PURE__ */ ((Vulnerability_Report_Issue_Tag_Enum3) => {
|
|
227
|
+
Vulnerability_Report_Issue_Tag_Enum3["AutogeneratedCode"] = "AUTOGENERATED_CODE";
|
|
228
|
+
Vulnerability_Report_Issue_Tag_Enum3["AuxiliaryCode"] = "AUXILIARY_CODE";
|
|
229
|
+
Vulnerability_Report_Issue_Tag_Enum3["FalsePositive"] = "FALSE_POSITIVE";
|
|
230
|
+
Vulnerability_Report_Issue_Tag_Enum3["TestCode"] = "TEST_CODE";
|
|
231
|
+
Vulnerability_Report_Issue_Tag_Enum3["VendorCode"] = "VENDOR_CODE";
|
|
232
|
+
return Vulnerability_Report_Issue_Tag_Enum3;
|
|
232
233
|
})(Vulnerability_Report_Issue_Tag_Enum || {});
|
|
233
234
|
var Vulnerability_Report_Vendor_Enum = /* @__PURE__ */ ((Vulnerability_Report_Vendor_Enum3) => {
|
|
234
235
|
Vulnerability_Report_Vendor_Enum3["Checkmarx"] = "checkmarx";
|
|
235
236
|
Vulnerability_Report_Vendor_Enum3["CheckmarxXml"] = "checkmarxXml";
|
|
236
237
|
Vulnerability_Report_Vendor_Enum3["Codeql"] = "codeql";
|
|
237
238
|
Vulnerability_Report_Vendor_Enum3["Fortify"] = "fortify";
|
|
239
|
+
Vulnerability_Report_Vendor_Enum3["Opengrep"] = "opengrep";
|
|
238
240
|
Vulnerability_Report_Vendor_Enum3["Semgrep"] = "semgrep";
|
|
239
241
|
Vulnerability_Report_Vendor_Enum3["Snyk"] = "snyk";
|
|
240
242
|
Vulnerability_Report_Vendor_Enum3["Sonarqube"] = "sonarqube";
|
|
@@ -412,8 +414,12 @@ var GetVulByNodesMetadataDocument = `
|
|
|
412
414
|
path
|
|
413
415
|
startLine
|
|
414
416
|
vulnerabilityReportIssue {
|
|
415
|
-
|
|
417
|
+
safeIssueType
|
|
416
418
|
fixId
|
|
419
|
+
category
|
|
420
|
+
vulnerabilityReportIssueTags {
|
|
421
|
+
tag: vulnerability_report_issue_tag_value
|
|
422
|
+
}
|
|
417
423
|
}
|
|
418
424
|
}
|
|
419
425
|
fixablePrVuls: vulnerability_report_issue_aggregate(
|
|
@@ -437,6 +443,25 @@ var GetVulByNodesMetadataDocument = `
|
|
|
437
443
|
count
|
|
438
444
|
}
|
|
439
445
|
}
|
|
446
|
+
irrelevantVulnerabilityReportIssue: vulnerability_report(
|
|
447
|
+
where: {id: {_eq: $vulnerabilityReportId}}
|
|
448
|
+
) {
|
|
449
|
+
vulnerabilityReportIssues(
|
|
450
|
+
where: {fixId: {_is_null: true}, _or: [{category: {_eq: "Irrelevant"}}, {category: {_eq: "FalsePositive"}}]}
|
|
451
|
+
) {
|
|
452
|
+
id
|
|
453
|
+
safeIssueType
|
|
454
|
+
fixId
|
|
455
|
+
category
|
|
456
|
+
vulnerabilityReportIssueTags {
|
|
457
|
+
tag: vulnerability_report_issue_tag_value
|
|
458
|
+
}
|
|
459
|
+
codeNodes(order_by: {index: desc}, where: {_or: $filters}) {
|
|
460
|
+
path
|
|
461
|
+
startLine
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
}
|
|
440
465
|
}
|
|
441
466
|
`;
|
|
442
467
|
var UpdateScmTokenDocument = `
|
|
@@ -899,7 +924,7 @@ var FixPageFixReportZ = z3.object({
|
|
|
899
924
|
|
|
900
925
|
// src/features/analysis/scm/shared/src/types/issue.ts
|
|
901
926
|
var MAX_SOURCE_CODE_FILE_SIZE_IN_BYTES = 1e5;
|
|
902
|
-
var
|
|
927
|
+
var CATEGORY = {
|
|
903
928
|
NoFix: "NoFix",
|
|
904
929
|
Unsupported: "Unsupported",
|
|
905
930
|
Irrelevant: "Irrelevant",
|
|
@@ -907,11 +932,11 @@ var category = {
|
|
|
907
932
|
Fixable: "Fixable"
|
|
908
933
|
};
|
|
909
934
|
var ValidCategoriesZ = z4.union([
|
|
910
|
-
z4.literal(
|
|
911
|
-
z4.literal(
|
|
912
|
-
z4.literal(
|
|
913
|
-
z4.literal(
|
|
914
|
-
z4.literal(
|
|
935
|
+
z4.literal(CATEGORY.NoFix),
|
|
936
|
+
z4.literal(CATEGORY.Unsupported),
|
|
937
|
+
z4.literal(CATEGORY.Irrelevant),
|
|
938
|
+
z4.literal(CATEGORY.FalsePositive),
|
|
939
|
+
z4.literal(CATEGORY.Fixable)
|
|
915
940
|
]);
|
|
916
941
|
var BaseIssuePartsZ = z4.object({
|
|
917
942
|
id: z4.string().uuid(),
|
|
@@ -972,13 +997,13 @@ var FalsePositivePartsZ = z4.object({
|
|
|
972
997
|
});
|
|
973
998
|
var IssuePartsWithFixZ = BaseIssuePartsZ.merge(
|
|
974
999
|
z4.object({
|
|
975
|
-
category: z4.literal(
|
|
1000
|
+
category: z4.literal(CATEGORY.Irrelevant),
|
|
976
1001
|
fix: FixPartsForFixScreenZ.nullish()
|
|
977
1002
|
})
|
|
978
1003
|
);
|
|
979
1004
|
var IssuePartsFpZ = BaseIssuePartsZ.merge(
|
|
980
1005
|
z4.object({
|
|
981
|
-
category: z4.literal(
|
|
1006
|
+
category: z4.literal(CATEGORY.FalsePositive),
|
|
982
1007
|
fpId: z4.string().uuid(),
|
|
983
1008
|
getFalsePositive: FalsePositivePartsZ
|
|
984
1009
|
})
|
|
@@ -986,9 +1011,9 @@ var IssuePartsFpZ = BaseIssuePartsZ.merge(
|
|
|
986
1011
|
var GeneralIssueZ = BaseIssuePartsZ.merge(
|
|
987
1012
|
z4.object({
|
|
988
1013
|
category: z4.union([
|
|
989
|
-
z4.literal(
|
|
990
|
-
z4.literal(
|
|
991
|
-
z4.literal(
|
|
1014
|
+
z4.literal(CATEGORY.NoFix),
|
|
1015
|
+
z4.literal(CATEGORY.Unsupported),
|
|
1016
|
+
z4.literal(CATEGORY.Fixable)
|
|
992
1017
|
])
|
|
993
1018
|
})
|
|
994
1019
|
);
|
|
@@ -1013,6 +1038,13 @@ var GetIssueScreenDataZ = z4.object({
|
|
|
1013
1038
|
issueIndexes: GetIssueIndexesZ
|
|
1014
1039
|
});
|
|
1015
1040
|
var IssueBucketZ = z4.enum(["fixable", "irrelevant", "remaining"]);
|
|
1041
|
+
var mapCategoryToBucket = {
|
|
1042
|
+
FalsePositive: "irrelevant",
|
|
1043
|
+
Irrelevant: "irrelevant",
|
|
1044
|
+
NoFix: "remaining",
|
|
1045
|
+
Unsupported: "remaining",
|
|
1046
|
+
Fixable: "fixable"
|
|
1047
|
+
};
|
|
1016
1048
|
|
|
1017
1049
|
// src/features/analysis/scm/shared/src/types/types.ts
|
|
1018
1050
|
import { z as z7 } from "zod";
|
|
@@ -1108,7 +1140,8 @@ var issueTypeMap = {
|
|
|
1108
1140
|
["USE_OF_HARD_CODED_CRYPTOGRAPHIC_KEY" /* UseOfHardCodedCryptographicKey */]: "Use of Hardcoded Cryptographic Key",
|
|
1109
1141
|
["MISSING_SSL_MINVERSION" /* MissingSslMinversion */]: "Missing SSL MinVersion",
|
|
1110
1142
|
["WEBSOCKET_MISSING_ORIGIN_CHECK" /* WebsocketMissingOriginCheck */]: "Missing Websocket Origin Check",
|
|
1111
|
-
["DUPLICATED_STRINGS" /* DuplicatedStrings */]: "String Literals Should not Be Duplicated"
|
|
1143
|
+
["DUPLICATED_STRINGS" /* DuplicatedStrings */]: "String Literals Should not Be Duplicated",
|
|
1144
|
+
["INSECURE_UUID_VERSION" /* InsecureUuidVersion */]: "Insecure UUID Version"
|
|
1112
1145
|
};
|
|
1113
1146
|
var issueTypeZ = z5.nativeEnum(IssueType_Enum);
|
|
1114
1147
|
var getIssueTypeFriendlyString = (issueType) => {
|
|
@@ -1118,6 +1151,29 @@ var getIssueTypeFriendlyString = (issueType) => {
|
|
|
1118
1151
|
}
|
|
1119
1152
|
return issueTypeMap[issueTypeZParseRes.data];
|
|
1120
1153
|
};
|
|
1154
|
+
function getTagTooltip(tag) {
|
|
1155
|
+
switch (tag) {
|
|
1156
|
+
case "FALSE_POSITIVE":
|
|
1157
|
+
return "Issue was found to be a false positive";
|
|
1158
|
+
case "TEST_CODE":
|
|
1159
|
+
return "Issue found in test files, not production code";
|
|
1160
|
+
case "VENDOR_CODE":
|
|
1161
|
+
return "Issue is in external libraries or dependencies not owned or maintained by your team";
|
|
1162
|
+
case "AUTOGENERATED_CODE":
|
|
1163
|
+
return "Code created by tools or frameworks, not manually written";
|
|
1164
|
+
case "AUXILIARY_CODE":
|
|
1165
|
+
return "Issue found in supporting files that don\u2019t impact core functionality";
|
|
1166
|
+
default:
|
|
1167
|
+
return tag;
|
|
1168
|
+
}
|
|
1169
|
+
}
|
|
1170
|
+
var issueDescription = {
|
|
1171
|
+
["AUTOGENERATED_CODE" /* AutogeneratedCode */]: "The flagged code is generated automatically by tools or frameworks as part of the build or runtime process. This categorization highlights that **the issue resides in non-manual code**, which often requires tool-specific solutions or exemptions.",
|
|
1172
|
+
["AUXILIARY_CODE" /* AuxiliaryCode */]: "The flagged code is auxiliary or supporting code, such as configuration files, build scripts, or other non-application logic. This categorization indicates that the issue is not directly related to the application\u2019s core functionality.",
|
|
1173
|
+
["FALSE_POSITIVE" /* FalsePositive */]: "The flagged code **does not represent an actual vulnerability within the application\u2019s context.** This categorization indicates that the issue is either misidentified by the scanner or deemed irrelevant to the application\u2019s functionality.",
|
|
1174
|
+
["TEST_CODE" /* TestCode */]: "The flagged code resides in a test-specific path or context. This categorization indicates that **it supports testing scenarios and is isolated from production use**.",
|
|
1175
|
+
["VENDOR_CODE" /* VendorCode */]: "The flagged code originates from a third-party library or dependency maintained externally. This categorization suggests that **the issue lies outside the application\u2019s direct control** and should be addressed by the vendor if necessary."
|
|
1176
|
+
};
|
|
1121
1177
|
|
|
1122
1178
|
// src/features/analysis/scm/shared/src/validations.ts
|
|
1123
1179
|
var IssueTypeSettingZ = z6.object({
|
|
@@ -1733,12 +1789,8 @@ import { z as z29 } from "zod";
|
|
|
1733
1789
|
// src/features/analysis/add_fix_comments_for_pr/add_fix_comments_for_pr.ts
|
|
1734
1790
|
import Debug8 from "debug";
|
|
1735
1791
|
|
|
1736
|
-
// src/features/analysis/scm/github/
|
|
1737
|
-
import {
|
|
1738
|
-
|
|
1739
|
-
// src/features/analysis/scm/constants.ts
|
|
1740
|
-
var MOBB_ICON_IMG = "https://app.mobb.ai/gh-action/Logo_Rounded_Icon.svg";
|
|
1741
|
-
var MAX_BRANCHES_FETCH = 1e3;
|
|
1792
|
+
// src/features/analysis/scm/github/GithubSCMLib.ts
|
|
1793
|
+
import { z as z24 } from "zod";
|
|
1742
1794
|
|
|
1743
1795
|
// src/features/analysis/scm/errors.ts
|
|
1744
1796
|
var InvalidRepoUrlError = class extends Error {
|
|
@@ -1768,6 +1820,21 @@ var RepoNoTokenAccessError = class extends Error {
|
|
|
1768
1820
|
}
|
|
1769
1821
|
};
|
|
1770
1822
|
|
|
1823
|
+
// src/features/analysis/scm/scmSubmit/index.ts
|
|
1824
|
+
import { simpleGit } from "simple-git";
|
|
1825
|
+
var isValidBranchName = async (branchName) => {
|
|
1826
|
+
const git = simpleGit();
|
|
1827
|
+
try {
|
|
1828
|
+
const res = await git.raw(["check-ref-format", "--branch", branchName]);
|
|
1829
|
+
if (res) {
|
|
1830
|
+
return true;
|
|
1831
|
+
}
|
|
1832
|
+
return false;
|
|
1833
|
+
} catch (e) {
|
|
1834
|
+
return false;
|
|
1835
|
+
}
|
|
1836
|
+
};
|
|
1837
|
+
|
|
1771
1838
|
// src/features/analysis/scm/types.ts
|
|
1772
1839
|
import { z as z14 } from "zod";
|
|
1773
1840
|
|
|
@@ -2014,13 +2081,19 @@ var fixDetailsData = {
|
|
|
2014
2081
|
["USE_OF_HARD_CODED_CRYPTOGRAPHIC_KEY" /* UseOfHardCodedCryptographicKey */]: void 0,
|
|
2015
2082
|
["MISSING_SSL_MINVERSION" /* MissingSslMinversion */]: void 0,
|
|
2016
2083
|
["WEBSOCKET_MISSING_ORIGIN_CHECK" /* WebsocketMissingOriginCheck */]: void 0,
|
|
2017
|
-
["DUPLICATED_STRINGS" /* DuplicatedStrings */]: void 0
|
|
2084
|
+
["DUPLICATED_STRINGS" /* DuplicatedStrings */]: void 0,
|
|
2085
|
+
["INSECURE_UUID_VERSION" /* InsecureUuidVersion */]: void 0
|
|
2018
2086
|
};
|
|
2019
2087
|
|
|
2020
2088
|
// src/features/analysis/scm/shared/src/commitDescriptionMarkup.ts
|
|
2021
2089
|
function capitalizeFirstLetter(str) {
|
|
2022
2090
|
return str?.length ? str[0].toUpperCase() + str.slice(1) : "";
|
|
2023
2091
|
}
|
|
2092
|
+
function lowercaseFirstLetter(str) {
|
|
2093
|
+
if (!str)
|
|
2094
|
+
return str;
|
|
2095
|
+
return `${str.charAt(0).toLowerCase()}${str.slice(1)}`;
|
|
2096
|
+
}
|
|
2024
2097
|
var severityToEmoji = {
|
|
2025
2098
|
["critical" /* Critical */]: "\u{1F6A8}",
|
|
2026
2099
|
["high" /* High */]: "\u{1F6A9}",
|
|
@@ -2032,7 +2105,8 @@ var getCommitDescription = ({
|
|
|
2032
2105
|
issueType,
|
|
2033
2106
|
severity,
|
|
2034
2107
|
guidances,
|
|
2035
|
-
fixUrl
|
|
2108
|
+
fixUrl,
|
|
2109
|
+
irrelevantIssueWithTags
|
|
2036
2110
|
}) => {
|
|
2037
2111
|
const issueTypeString = getIssueTypeFriendlyString(issueType);
|
|
2038
2112
|
let description = `This change fixes a **${severity} severity** (${severityToEmoji[severity]}) **${issueTypeString}** issue reported by **${capitalizeFirstLetter(
|
|
@@ -2042,6 +2116,17 @@ var getCommitDescription = ({
|
|
|
2042
2116
|
`;
|
|
2043
2117
|
const parseIssueTypeRes = z9.nativeEnum(IssueType_Enum).safeParse(issueType);
|
|
2044
2118
|
if (issueType && parseIssueTypeRes.success) {
|
|
2119
|
+
if (irrelevantIssueWithTags?.[0]?.tag) {
|
|
2120
|
+
description += `
|
|
2121
|
+
> [!tip]
|
|
2122
|
+
> This issue was found to be irrelevant to your project - ${lowercaseFirstLetter(getTagTooltip(irrelevantIssueWithTags[0].tag))}.
|
|
2123
|
+
> Mobb recommends to ignore this issue, however fix is available if you think differently.
|
|
2124
|
+
|
|
2125
|
+
|
|
2126
|
+
## Justification
|
|
2127
|
+
${issueDescription[irrelevantIssueWithTags[0].tag]}
|
|
2128
|
+
`;
|
|
2129
|
+
}
|
|
2045
2130
|
const staticData = fixDetailsData[parseIssueTypeRes.data];
|
|
2046
2131
|
if (staticData) {
|
|
2047
2132
|
description += `## Issue description
|
|
@@ -2063,6 +2148,36 @@ ${guidances.map(({ guidance }) => `## Additional actions required
|
|
|
2063
2148
|
}
|
|
2064
2149
|
return description;
|
|
2065
2150
|
};
|
|
2151
|
+
var getCommitIssueDescription = ({
|
|
2152
|
+
vendor,
|
|
2153
|
+
issueType,
|
|
2154
|
+
irrelevantIssueWithTags
|
|
2155
|
+
}) => {
|
|
2156
|
+
const issueTypeString = getIssueTypeFriendlyString(issueType);
|
|
2157
|
+
let description = `The following issues reported by ${capitalizeFirstLetter(vendor)} on this PR were found to be irrelevant to your project:
|
|
2158
|
+
`;
|
|
2159
|
+
const parseIssueTypeRes = z9.nativeEnum(IssueType_Enum).safeParse(issueType);
|
|
2160
|
+
if (issueType && parseIssueTypeRes.success) {
|
|
2161
|
+
if (irrelevantIssueWithTags?.[0]?.tag) {
|
|
2162
|
+
description += `
|
|
2163
|
+
> [!tip]
|
|
2164
|
+
> ${issueTypeString} - ${lowercaseFirstLetter(getTagTooltip(irrelevantIssueWithTags[0].tag))}.
|
|
2165
|
+
> Mobb recommends to ignore this issue, however fix is available if you think differently.
|
|
2166
|
+
|
|
2167
|
+
|
|
2168
|
+
## Justification
|
|
2169
|
+
${issueDescription[irrelevantIssueWithTags[0].tag]}
|
|
2170
|
+
`;
|
|
2171
|
+
}
|
|
2172
|
+
const staticData = fixDetailsData[parseIssueTypeRes.data];
|
|
2173
|
+
if (staticData) {
|
|
2174
|
+
description += `## Issue description
|
|
2175
|
+
${staticData.issueDescription}
|
|
2176
|
+
`;
|
|
2177
|
+
}
|
|
2178
|
+
}
|
|
2179
|
+
return description;
|
|
2180
|
+
};
|
|
2066
2181
|
|
|
2067
2182
|
// src/features/analysis/scm/shared/src/guidances.ts
|
|
2068
2183
|
import { z as z12 } from "zod";
|
|
@@ -3766,6 +3881,15 @@ function getFixUrl({
|
|
|
3766
3881
|
}) {
|
|
3767
3882
|
return `${appBaseUrl}/organization/${organizationId}/project/${projectId}/report/${analysisId}/fix/${fixId}`;
|
|
3768
3883
|
}
|
|
3884
|
+
function getIssueUrl({
|
|
3885
|
+
appBaseUrl,
|
|
3886
|
+
issueId,
|
|
3887
|
+
projectId,
|
|
3888
|
+
organizationId,
|
|
3889
|
+
analysisId
|
|
3890
|
+
}) {
|
|
3891
|
+
return `${appBaseUrl}/organization/${organizationId}/project/${projectId}/report/${analysisId}/issue/${issueId}`;
|
|
3892
|
+
}
|
|
3769
3893
|
|
|
3770
3894
|
// src/features/analysis/scm/types.ts
|
|
3771
3895
|
var ReferenceType = /* @__PURE__ */ ((ReferenceType2) => {
|
|
@@ -3805,92 +3929,8 @@ var GetRefererenceResultZ = z14.object({
|
|
|
3805
3929
|
type: z14.nativeEnum(ReferenceType)
|
|
3806
3930
|
});
|
|
3807
3931
|
|
|
3808
|
-
// src/features/analysis/scm/github/consts.ts
|
|
3809
|
-
var POST_COMMENT_PATH = "POST /repos/{owner}/{repo}/pulls/{pull_number}/comments";
|
|
3810
|
-
var DELETE_COMMENT_PATH = "DELETE /repos/{owner}/{repo}/pulls/comments/{comment_id}";
|
|
3811
|
-
var UPDATE_COMMENT_PATH = "PATCH /repos/{owner}/{repo}/pulls/comments/{comment_id}";
|
|
3812
|
-
var GET_PR_COMMENTS_PATH = "GET /repos/{owner}/{repo}/pulls/{pull_number}/comments";
|
|
3813
|
-
var GET_PR_COMMENT_PATH = "GET /repos/{owner}/{repo}/pulls/comments/{comment_id}";
|
|
3814
|
-
var REPLY_TO_CODE_REVIEW_COMMENT_PATH = "POST /repos/{owner}/{repo}/pulls/{pull_number}/comments/{comment_id}/replies";
|
|
3815
|
-
var GET_PR = "GET /repos/{owner}/{repo}/pulls/{pull_number}";
|
|
3816
|
-
var POST_GENERAL_PR_COMMENT = "POST /repos/{owner}/{repo}/issues/{issue_number}/comments";
|
|
3817
|
-
var GET_GENERAL_PR_COMMENTS = "GET /repos/{owner}/{repo}/issues/{issue_number}/comments";
|
|
3818
|
-
var DELETE_GENERAL_PR_COMMENT = "DELETE /repos/{owner}/{repo}/issues/comments/{comment_id}";
|
|
3819
|
-
var CREATE_OR_UPDATE_A_REPOSITORY_SECRET = "PUT /repos/{owner}/{repo}/actions/secrets/{secret_name}";
|
|
3820
|
-
var GET_A_REPOSITORY_PUBLIC_KEY = "GET /repos/{owner}/{repo}/actions/secrets/public-key";
|
|
3821
|
-
var GET_USER = "GET /user";
|
|
3822
|
-
var GET_USER_REPOS = "GET /user/repos";
|
|
3823
|
-
var GET_REPO_BRANCHES = "GET /repos/{owner}/{repo}/branches";
|
|
3824
|
-
var GET_BLAME_DOCUMENT = `
|
|
3825
|
-
query GetBlame(
|
|
3826
|
-
$owner: String!
|
|
3827
|
-
$repo: String!
|
|
3828
|
-
$ref: String!
|
|
3829
|
-
$path: String!
|
|
3830
|
-
) {
|
|
3831
|
-
repository(name: $repo, owner: $owner) {
|
|
3832
|
-
# branch name
|
|
3833
|
-
object(expression: $ref) {
|
|
3834
|
-
# cast Target to a Commit
|
|
3835
|
-
... on Commit {
|
|
3836
|
-
# full repo-relative path to blame file
|
|
3837
|
-
blame(path: $path) {
|
|
3838
|
-
ranges {
|
|
3839
|
-
commit {
|
|
3840
|
-
author {
|
|
3841
|
-
user {
|
|
3842
|
-
name
|
|
3843
|
-
login
|
|
3844
|
-
}
|
|
3845
|
-
}
|
|
3846
|
-
authoredDate
|
|
3847
|
-
}
|
|
3848
|
-
startingLine
|
|
3849
|
-
endingLine
|
|
3850
|
-
age
|
|
3851
|
-
}
|
|
3852
|
-
}
|
|
3853
|
-
}
|
|
3854
|
-
|
|
3855
|
-
}
|
|
3856
|
-
}
|
|
3857
|
-
}
|
|
3858
|
-
`;
|
|
3859
|
-
|
|
3860
|
-
// src/features/analysis/scm/github/utils/encrypt_secret.ts
|
|
3861
|
-
import sodium from "libsodium-wrappers";
|
|
3862
|
-
async function encryptSecret(secret, key) {
|
|
3863
|
-
await sodium.ready;
|
|
3864
|
-
const binkey = sodium.from_base64(key, sodium.base64_variants.ORIGINAL);
|
|
3865
|
-
const binsec = sodium.from_string(secret);
|
|
3866
|
-
const encBytes = sodium.crypto_box_seal(binsec, binkey);
|
|
3867
|
-
return sodium.to_base64(encBytes, sodium.base64_variants.ORIGINAL);
|
|
3868
|
-
}
|
|
3869
|
-
|
|
3870
|
-
// src/features/analysis/scm/github/utils/utils.ts
|
|
3871
|
-
import { Octokit } from "octokit";
|
|
3872
|
-
import { fetch as fetch2, ProxyAgent as ProxyAgent2 } from "undici";
|
|
3873
|
-
|
|
3874
|
-
// src/features/analysis/scm/ado/constants.ts
|
|
3875
|
-
var DEFUALT_ADO_ORIGIN = scmCloudUrl.Ado;
|
|
3876
|
-
|
|
3877
|
-
// src/features/analysis/scm/ado/utils.ts
|
|
3878
|
-
import querystring from "node:querystring";
|
|
3879
|
-
import * as api from "azure-devops-node-api";
|
|
3880
|
-
import Debug2 from "debug";
|
|
3881
|
-
import { z as z18 } from "zod";
|
|
3882
|
-
|
|
3883
|
-
// src/features/analysis/scm/env.ts
|
|
3884
|
-
import { z as z15 } from "zod";
|
|
3885
|
-
var EnvVariablesZod = z15.object({
|
|
3886
|
-
GITLAB_API_TOKEN: z15.string().optional(),
|
|
3887
|
-
GITHUB_API_TOKEN: z15.string().optional(),
|
|
3888
|
-
GIT_PROXY_HOST: z15.string()
|
|
3889
|
-
});
|
|
3890
|
-
var { GITLAB_API_TOKEN, GITHUB_API_TOKEN, GIT_PROXY_HOST } = EnvVariablesZod.parse(process.env);
|
|
3891
|
-
|
|
3892
3932
|
// src/features/analysis/scm/utils/index.ts
|
|
3893
|
-
import { z as
|
|
3933
|
+
import { z as z15 } from "zod";
|
|
3894
3934
|
function getFixUrlWithRedirect(params) {
|
|
3895
3935
|
const {
|
|
3896
3936
|
fixId,
|
|
@@ -3912,6 +3952,27 @@ function getFixUrlWithRedirect(params) {
|
|
|
3912
3952
|
analysisId
|
|
3913
3953
|
})}?${searchParams.toString()}`;
|
|
3914
3954
|
}
|
|
3955
|
+
function getIssueUrlWithRedirect(params) {
|
|
3956
|
+
const {
|
|
3957
|
+
issueId,
|
|
3958
|
+
projectId,
|
|
3959
|
+
organizationId,
|
|
3960
|
+
analysisId,
|
|
3961
|
+
redirectUrl,
|
|
3962
|
+
appBaseUrl,
|
|
3963
|
+
commentId
|
|
3964
|
+
} = params;
|
|
3965
|
+
const searchParams = new URLSearchParams();
|
|
3966
|
+
searchParams.append("commit_redirect_url", redirectUrl);
|
|
3967
|
+
searchParams.append("comment_id", commentId.toString());
|
|
3968
|
+
return `${getIssueUrl({
|
|
3969
|
+
appBaseUrl,
|
|
3970
|
+
issueId,
|
|
3971
|
+
projectId,
|
|
3972
|
+
organizationId,
|
|
3973
|
+
analysisId
|
|
3974
|
+
})}?${searchParams.toString()}`;
|
|
3975
|
+
}
|
|
3915
3976
|
function getCommitUrl(params) {
|
|
3916
3977
|
const {
|
|
3917
3978
|
fixId,
|
|
@@ -3933,6 +3994,27 @@ function getCommitUrl(params) {
|
|
|
3933
3994
|
analysisId
|
|
3934
3995
|
})}/commit?${searchParams.toString()}`;
|
|
3935
3996
|
}
|
|
3997
|
+
function getCommitIssueUrl(params) {
|
|
3998
|
+
const {
|
|
3999
|
+
issueId,
|
|
4000
|
+
projectId,
|
|
4001
|
+
organizationId,
|
|
4002
|
+
analysisId,
|
|
4003
|
+
redirectUrl,
|
|
4004
|
+
appBaseUrl,
|
|
4005
|
+
commentId
|
|
4006
|
+
} = params;
|
|
4007
|
+
const searchParams = new URLSearchParams();
|
|
4008
|
+
searchParams.append("redirect_url", redirectUrl);
|
|
4009
|
+
searchParams.append("comment_id", commentId.toString());
|
|
4010
|
+
return `${getIssueUrl({
|
|
4011
|
+
appBaseUrl,
|
|
4012
|
+
issueId,
|
|
4013
|
+
projectId,
|
|
4014
|
+
organizationId,
|
|
4015
|
+
analysisId
|
|
4016
|
+
})}/commit?${searchParams.toString()}`;
|
|
4017
|
+
}
|
|
3936
4018
|
var userNamePattern = /^(https?:\/\/)([^@]+@)?([^/]+\/.+)$/;
|
|
3937
4019
|
var sshPattern = /^git@([\w.-]+):([\w./-]+)$/;
|
|
3938
4020
|
function normalizeUrl(repoUrl) {
|
|
@@ -3959,7 +4041,7 @@ function shouldValidateUrl(repoUrl) {
|
|
|
3959
4041
|
return repoUrl && isUrlHasPath(repoUrl);
|
|
3960
4042
|
}
|
|
3961
4043
|
function isBrokerUrl(url) {
|
|
3962
|
-
return
|
|
4044
|
+
return z15.string().uuid().safeParse(new URL(url).host).success;
|
|
3963
4045
|
}
|
|
3964
4046
|
function buildAuthorizedRepoUrl(args) {
|
|
3965
4047
|
const { url, username, password } = args;
|
|
@@ -3995,7 +4077,7 @@ function getCloudScmLibTypeFromUrl(url) {
|
|
|
3995
4077
|
return void 0;
|
|
3996
4078
|
}
|
|
3997
4079
|
function getScmLibTypeFromScmType(scmType) {
|
|
3998
|
-
const parsedScmType =
|
|
4080
|
+
const parsedScmType = z15.nativeEnum(ScmType).parse(scmType);
|
|
3999
4081
|
return scmTypeToScmLibScmType[parsedScmType];
|
|
4000
4082
|
}
|
|
4001
4083
|
function getScmConfig({
|
|
@@ -4061,70 +4143,226 @@ function getScmConfig({
|
|
|
4061
4143
|
};
|
|
4062
4144
|
}
|
|
4063
4145
|
|
|
4064
|
-
// src/features/analysis/scm/
|
|
4065
|
-
|
|
4066
|
-
|
|
4067
|
-
|
|
4068
|
-
|
|
4069
|
-
|
|
4070
|
-
|
|
4071
|
-
|
|
4072
|
-
|
|
4073
|
-
token_type: z17.string().min(1),
|
|
4074
|
-
refresh_token: z17.string().min(1)
|
|
4075
|
-
});
|
|
4076
|
-
var AdoAuthResultWithOrgsZ = AdoAuthResultZ.extend({
|
|
4077
|
-
scmOrgs: z17.array(z17.string())
|
|
4078
|
-
});
|
|
4079
|
-
var profileZ = z17.object({
|
|
4080
|
-
displayName: z17.string(),
|
|
4081
|
-
publicAlias: z17.string().min(1),
|
|
4082
|
-
emailAddress: z17.string(),
|
|
4083
|
-
coreRevision: z17.number(),
|
|
4084
|
-
timeStamp: z17.string(),
|
|
4085
|
-
id: z17.string(),
|
|
4086
|
-
revision: z17.number()
|
|
4087
|
-
});
|
|
4088
|
-
var accountsZ = z17.object({
|
|
4089
|
-
count: z17.number(),
|
|
4090
|
-
value: z17.array(
|
|
4091
|
-
z17.object({
|
|
4092
|
-
accountId: z17.string(),
|
|
4093
|
-
accountUri: z17.string(),
|
|
4094
|
-
accountName: z17.string()
|
|
4095
|
-
})
|
|
4096
|
-
)
|
|
4097
|
-
});
|
|
4098
|
-
|
|
4099
|
-
// src/features/analysis/scm/ado/utils.ts
|
|
4100
|
-
var debug2 = Debug2("mobbdev:scm:ado");
|
|
4101
|
-
function _getPublicAdoClient({
|
|
4102
|
-
orgName,
|
|
4103
|
-
origin: origin2
|
|
4104
|
-
}) {
|
|
4105
|
-
const orgUrl = `${origin2}/${orgName}`;
|
|
4106
|
-
const authHandler = api.getPersonalAccessTokenHandler("");
|
|
4107
|
-
authHandler.canHandleAuthentication = () => false;
|
|
4108
|
-
authHandler.prepareRequest = (_options) => {
|
|
4109
|
-
return;
|
|
4110
|
-
};
|
|
4111
|
-
const connection = new api.WebApi(orgUrl, authHandler);
|
|
4112
|
-
return connection;
|
|
4113
|
-
}
|
|
4114
|
-
function removeTrailingSlash(str) {
|
|
4115
|
-
return str.trim().replace(/\/+$/, "");
|
|
4116
|
-
}
|
|
4117
|
-
function parseAdoOwnerAndRepo(adoUrl) {
|
|
4118
|
-
adoUrl = removeTrailingSlash(adoUrl);
|
|
4119
|
-
const parsingResult = parseScmURL(adoUrl, "Ado" /* Ado */);
|
|
4120
|
-
if (!parsingResult || parsingResult.scmType !== "Ado" /* Ado */) {
|
|
4121
|
-
throw new InvalidUrlPatternError(`
|
|
4122
|
-
: ${adoUrl}`);
|
|
4146
|
+
// src/features/analysis/scm/scm.ts
|
|
4147
|
+
var SCMLib = class {
|
|
4148
|
+
constructor(url, accessToken, scmOrg) {
|
|
4149
|
+
__publicField(this, "url");
|
|
4150
|
+
__publicField(this, "accessToken");
|
|
4151
|
+
__publicField(this, "scmOrg");
|
|
4152
|
+
this.accessToken = accessToken;
|
|
4153
|
+
this.url = url;
|
|
4154
|
+
this.scmOrg = scmOrg;
|
|
4123
4155
|
}
|
|
4124
|
-
|
|
4125
|
-
|
|
4126
|
-
|
|
4127
|
-
|
|
4156
|
+
async getUrlWithCredentials() {
|
|
4157
|
+
if (!this.url) {
|
|
4158
|
+
console.error("no url for getUrlWithCredentials()");
|
|
4159
|
+
throw new Error("no url");
|
|
4160
|
+
}
|
|
4161
|
+
const trimmedUrl = this.url.trim().replace(/\/$/, "");
|
|
4162
|
+
const accessToken = this.getAccessToken();
|
|
4163
|
+
if (!accessToken) {
|
|
4164
|
+
return trimmedUrl;
|
|
4165
|
+
}
|
|
4166
|
+
if (this.scmLibType === "ADO" /* ADO */) {
|
|
4167
|
+
const { host, protocol, pathname } = new URL(trimmedUrl);
|
|
4168
|
+
return `${protocol}//${accessToken}@${host}${pathname}`;
|
|
4169
|
+
}
|
|
4170
|
+
const finalUrl = this.scmLibType === "GITLAB" /* GITLAB */ ? `${trimmedUrl}.git` : trimmedUrl;
|
|
4171
|
+
const username = await this._getUsernameForAuthUrl();
|
|
4172
|
+
return buildAuthorizedRepoUrl({
|
|
4173
|
+
url: finalUrl,
|
|
4174
|
+
username,
|
|
4175
|
+
password: accessToken
|
|
4176
|
+
});
|
|
4177
|
+
}
|
|
4178
|
+
getAccessToken() {
|
|
4179
|
+
return this.accessToken || "";
|
|
4180
|
+
}
|
|
4181
|
+
getUrl() {
|
|
4182
|
+
return this.url;
|
|
4183
|
+
}
|
|
4184
|
+
getName() {
|
|
4185
|
+
if (!this.url) {
|
|
4186
|
+
return "";
|
|
4187
|
+
}
|
|
4188
|
+
return this.url.split("/").at(-1) || "";
|
|
4189
|
+
}
|
|
4190
|
+
_validateAccessToken() {
|
|
4191
|
+
if (!this.accessToken) {
|
|
4192
|
+
console.error("no access token");
|
|
4193
|
+
throw new Error("no access token");
|
|
4194
|
+
}
|
|
4195
|
+
}
|
|
4196
|
+
static async getIsValidBranchName(branchName) {
|
|
4197
|
+
return isValidBranchName(branchName);
|
|
4198
|
+
}
|
|
4199
|
+
_validateAccessTokenAndUrl() {
|
|
4200
|
+
this._validateAccessToken();
|
|
4201
|
+
this._validateUrl();
|
|
4202
|
+
}
|
|
4203
|
+
_validateUrl() {
|
|
4204
|
+
if (!this.url) {
|
|
4205
|
+
console.error("no url");
|
|
4206
|
+
throw new InvalidRepoUrlError("no url");
|
|
4207
|
+
}
|
|
4208
|
+
}
|
|
4209
|
+
};
|
|
4210
|
+
|
|
4211
|
+
// src/features/analysis/scm/github/github.ts
|
|
4212
|
+
import { RequestError } from "@octokit/request-error";
|
|
4213
|
+
|
|
4214
|
+
// src/features/analysis/scm/constants.ts
|
|
4215
|
+
var MOBB_ICON_IMG = "https://app.mobb.ai/gh-action/Logo_Rounded_Icon.svg";
|
|
4216
|
+
var MAX_BRANCHES_FETCH = 1e3;
|
|
4217
|
+
|
|
4218
|
+
// src/features/analysis/scm/github/consts.ts
|
|
4219
|
+
var POST_COMMENT_PATH = "POST /repos/{owner}/{repo}/pulls/{pull_number}/comments";
|
|
4220
|
+
var DELETE_COMMENT_PATH = "DELETE /repos/{owner}/{repo}/pulls/comments/{comment_id}";
|
|
4221
|
+
var UPDATE_COMMENT_PATH = "PATCH /repos/{owner}/{repo}/pulls/comments/{comment_id}";
|
|
4222
|
+
var GET_PR_COMMENTS_PATH = "GET /repos/{owner}/{repo}/pulls/{pull_number}/comments";
|
|
4223
|
+
var GET_PR_COMMENT_PATH = "GET /repos/{owner}/{repo}/pulls/comments/{comment_id}";
|
|
4224
|
+
var REPLY_TO_CODE_REVIEW_COMMENT_PATH = "POST /repos/{owner}/{repo}/pulls/{pull_number}/comments/{comment_id}/replies";
|
|
4225
|
+
var GET_PR = "GET /repos/{owner}/{repo}/pulls/{pull_number}";
|
|
4226
|
+
var POST_GENERAL_PR_COMMENT = "POST /repos/{owner}/{repo}/issues/{issue_number}/comments";
|
|
4227
|
+
var GET_GENERAL_PR_COMMENTS = "GET /repos/{owner}/{repo}/issues/{issue_number}/comments";
|
|
4228
|
+
var DELETE_GENERAL_PR_COMMENT = "DELETE /repos/{owner}/{repo}/issues/comments/{comment_id}";
|
|
4229
|
+
var CREATE_OR_UPDATE_A_REPOSITORY_SECRET = "PUT /repos/{owner}/{repo}/actions/secrets/{secret_name}";
|
|
4230
|
+
var GET_A_REPOSITORY_PUBLIC_KEY = "GET /repos/{owner}/{repo}/actions/secrets/public-key";
|
|
4231
|
+
var GET_USER = "GET /user";
|
|
4232
|
+
var GET_USER_REPOS = "GET /user/repos";
|
|
4233
|
+
var GET_REPO_BRANCHES = "GET /repos/{owner}/{repo}/branches";
|
|
4234
|
+
var GET_BLAME_DOCUMENT = `
|
|
4235
|
+
query GetBlame(
|
|
4236
|
+
$owner: String!
|
|
4237
|
+
$repo: String!
|
|
4238
|
+
$ref: String!
|
|
4239
|
+
$path: String!
|
|
4240
|
+
) {
|
|
4241
|
+
repository(name: $repo, owner: $owner) {
|
|
4242
|
+
# branch name
|
|
4243
|
+
object(expression: $ref) {
|
|
4244
|
+
# cast Target to a Commit
|
|
4245
|
+
... on Commit {
|
|
4246
|
+
# full repo-relative path to blame file
|
|
4247
|
+
blame(path: $path) {
|
|
4248
|
+
ranges {
|
|
4249
|
+
commit {
|
|
4250
|
+
author {
|
|
4251
|
+
user {
|
|
4252
|
+
name
|
|
4253
|
+
login
|
|
4254
|
+
}
|
|
4255
|
+
}
|
|
4256
|
+
authoredDate
|
|
4257
|
+
}
|
|
4258
|
+
startingLine
|
|
4259
|
+
endingLine
|
|
4260
|
+
age
|
|
4261
|
+
}
|
|
4262
|
+
}
|
|
4263
|
+
}
|
|
4264
|
+
|
|
4265
|
+
}
|
|
4266
|
+
}
|
|
4267
|
+
}
|
|
4268
|
+
`;
|
|
4269
|
+
|
|
4270
|
+
// src/features/analysis/scm/github/utils/encrypt_secret.ts
|
|
4271
|
+
import sodium from "libsodium-wrappers";
|
|
4272
|
+
async function encryptSecret(secret, key) {
|
|
4273
|
+
await sodium.ready;
|
|
4274
|
+
const binkey = sodium.from_base64(key, sodium.base64_variants.ORIGINAL);
|
|
4275
|
+
const binsec = sodium.from_string(secret);
|
|
4276
|
+
const encBytes = sodium.crypto_box_seal(binsec, binkey);
|
|
4277
|
+
return sodium.to_base64(encBytes, sodium.base64_variants.ORIGINAL);
|
|
4278
|
+
}
|
|
4279
|
+
|
|
4280
|
+
// src/features/analysis/scm/github/utils/utils.ts
|
|
4281
|
+
import { Octokit } from "octokit";
|
|
4282
|
+
import { fetch as fetch2, ProxyAgent as ProxyAgent2 } from "undici";
|
|
4283
|
+
|
|
4284
|
+
// src/features/analysis/scm/ado/constants.ts
|
|
4285
|
+
var DEFUALT_ADO_ORIGIN = scmCloudUrl.Ado;
|
|
4286
|
+
|
|
4287
|
+
// src/features/analysis/scm/ado/utils.ts
|
|
4288
|
+
import querystring from "node:querystring";
|
|
4289
|
+
import * as api from "azure-devops-node-api";
|
|
4290
|
+
import Debug2 from "debug";
|
|
4291
|
+
import { z as z18 } from "zod";
|
|
4292
|
+
|
|
4293
|
+
// src/features/analysis/scm/env.ts
|
|
4294
|
+
import { z as z16 } from "zod";
|
|
4295
|
+
var EnvVariablesZod = z16.object({
|
|
4296
|
+
GITLAB_API_TOKEN: z16.string().optional(),
|
|
4297
|
+
GITHUB_API_TOKEN: z16.string().optional(),
|
|
4298
|
+
GIT_PROXY_HOST: z16.string()
|
|
4299
|
+
});
|
|
4300
|
+
var { GITLAB_API_TOKEN, GITHUB_API_TOKEN, GIT_PROXY_HOST } = EnvVariablesZod.parse(process.env);
|
|
4301
|
+
|
|
4302
|
+
// src/features/analysis/scm/ado/validation.ts
|
|
4303
|
+
import { z as z17 } from "zod";
|
|
4304
|
+
var ValidPullRequestStatusZ = z17.union([
|
|
4305
|
+
z17.literal(1 /* Active */),
|
|
4306
|
+
z17.literal(2 /* Abandoned */),
|
|
4307
|
+
z17.literal(3 /* Completed */)
|
|
4308
|
+
]);
|
|
4309
|
+
var AdoAuthResultZ = z17.object({
|
|
4310
|
+
access_token: z17.string().min(1),
|
|
4311
|
+
token_type: z17.string().min(1),
|
|
4312
|
+
refresh_token: z17.string().min(1)
|
|
4313
|
+
});
|
|
4314
|
+
var AdoAuthResultWithOrgsZ = AdoAuthResultZ.extend({
|
|
4315
|
+
scmOrgs: z17.array(z17.string())
|
|
4316
|
+
});
|
|
4317
|
+
var profileZ = z17.object({
|
|
4318
|
+
displayName: z17.string(),
|
|
4319
|
+
publicAlias: z17.string().min(1),
|
|
4320
|
+
emailAddress: z17.string(),
|
|
4321
|
+
coreRevision: z17.number(),
|
|
4322
|
+
timeStamp: z17.string(),
|
|
4323
|
+
id: z17.string(),
|
|
4324
|
+
revision: z17.number()
|
|
4325
|
+
});
|
|
4326
|
+
var accountsZ = z17.object({
|
|
4327
|
+
count: z17.number(),
|
|
4328
|
+
value: z17.array(
|
|
4329
|
+
z17.object({
|
|
4330
|
+
accountId: z17.string(),
|
|
4331
|
+
accountUri: z17.string(),
|
|
4332
|
+
accountName: z17.string()
|
|
4333
|
+
})
|
|
4334
|
+
)
|
|
4335
|
+
});
|
|
4336
|
+
|
|
4337
|
+
// src/features/analysis/scm/ado/utils.ts
|
|
4338
|
+
var debug2 = Debug2("mobbdev:scm:ado");
|
|
4339
|
+
function _getPublicAdoClient({
|
|
4340
|
+
orgName,
|
|
4341
|
+
origin: origin2
|
|
4342
|
+
}) {
|
|
4343
|
+
const orgUrl = `${origin2}/${orgName}`;
|
|
4344
|
+
const authHandler = api.getPersonalAccessTokenHandler("");
|
|
4345
|
+
authHandler.canHandleAuthentication = () => false;
|
|
4346
|
+
authHandler.prepareRequest = (_options) => {
|
|
4347
|
+
return;
|
|
4348
|
+
};
|
|
4349
|
+
const connection = new api.WebApi(orgUrl, authHandler);
|
|
4350
|
+
return connection;
|
|
4351
|
+
}
|
|
4352
|
+
function removeTrailingSlash(str) {
|
|
4353
|
+
return str.trim().replace(/\/+$/, "");
|
|
4354
|
+
}
|
|
4355
|
+
function parseAdoOwnerAndRepo(adoUrl) {
|
|
4356
|
+
adoUrl = removeTrailingSlash(adoUrl);
|
|
4357
|
+
const parsingResult = parseScmURL(adoUrl, "Ado" /* Ado */);
|
|
4358
|
+
if (!parsingResult || parsingResult.scmType !== "Ado" /* Ado */) {
|
|
4359
|
+
throw new InvalidUrlPatternError(`
|
|
4360
|
+
: ${adoUrl}`);
|
|
4361
|
+
}
|
|
4362
|
+
const {
|
|
4363
|
+
organization,
|
|
4364
|
+
repoName,
|
|
4365
|
+
projectName,
|
|
4128
4366
|
projectPath,
|
|
4129
4367
|
pathElements,
|
|
4130
4368
|
hostname,
|
|
@@ -4671,88 +4909,6 @@ async function getAdoRepoList({
|
|
|
4671
4909
|
|
|
4672
4910
|
// src/features/analysis/scm/ado/AdoSCMLib.ts
|
|
4673
4911
|
import { setTimeout as setTimeout2 } from "node:timers/promises";
|
|
4674
|
-
|
|
4675
|
-
// src/features/analysis/scm/scmSubmit/index.ts
|
|
4676
|
-
import { simpleGit } from "simple-git";
|
|
4677
|
-
var isValidBranchName = async (branchName) => {
|
|
4678
|
-
const git = simpleGit();
|
|
4679
|
-
try {
|
|
4680
|
-
const res = await git.raw(["check-ref-format", "--branch", branchName]);
|
|
4681
|
-
if (res) {
|
|
4682
|
-
return true;
|
|
4683
|
-
}
|
|
4684
|
-
return false;
|
|
4685
|
-
} catch (e) {
|
|
4686
|
-
return false;
|
|
4687
|
-
}
|
|
4688
|
-
};
|
|
4689
|
-
|
|
4690
|
-
// src/features/analysis/scm/scm.ts
|
|
4691
|
-
var SCMLib = class {
|
|
4692
|
-
constructor(url, accessToken, scmOrg) {
|
|
4693
|
-
__publicField(this, "url");
|
|
4694
|
-
__publicField(this, "accessToken");
|
|
4695
|
-
__publicField(this, "scmOrg");
|
|
4696
|
-
this.accessToken = accessToken;
|
|
4697
|
-
this.url = url;
|
|
4698
|
-
this.scmOrg = scmOrg;
|
|
4699
|
-
}
|
|
4700
|
-
async getUrlWithCredentials() {
|
|
4701
|
-
if (!this.url) {
|
|
4702
|
-
console.error("no url for getUrlWithCredentials()");
|
|
4703
|
-
throw new Error("no url");
|
|
4704
|
-
}
|
|
4705
|
-
const trimmedUrl = this.url.trim().replace(/\/$/, "");
|
|
4706
|
-
const accessToken = this.getAccessToken();
|
|
4707
|
-
if (!accessToken) {
|
|
4708
|
-
return trimmedUrl;
|
|
4709
|
-
}
|
|
4710
|
-
if (this.scmLibType === "ADO" /* ADO */) {
|
|
4711
|
-
const { host, protocol, pathname } = new URL(trimmedUrl);
|
|
4712
|
-
return `${protocol}//${accessToken}@${host}${pathname}`;
|
|
4713
|
-
}
|
|
4714
|
-
const finalUrl = this.scmLibType === "GITLAB" /* GITLAB */ ? `${trimmedUrl}.git` : trimmedUrl;
|
|
4715
|
-
const username = await this._getUsernameForAuthUrl();
|
|
4716
|
-
return buildAuthorizedRepoUrl({
|
|
4717
|
-
url: finalUrl,
|
|
4718
|
-
username,
|
|
4719
|
-
password: accessToken
|
|
4720
|
-
});
|
|
4721
|
-
}
|
|
4722
|
-
getAccessToken() {
|
|
4723
|
-
return this.accessToken || "";
|
|
4724
|
-
}
|
|
4725
|
-
getUrl() {
|
|
4726
|
-
return this.url;
|
|
4727
|
-
}
|
|
4728
|
-
getName() {
|
|
4729
|
-
if (!this.url) {
|
|
4730
|
-
return "";
|
|
4731
|
-
}
|
|
4732
|
-
return this.url.split("/").at(-1) || "";
|
|
4733
|
-
}
|
|
4734
|
-
_validateAccessToken() {
|
|
4735
|
-
if (!this.accessToken) {
|
|
4736
|
-
console.error("no access token");
|
|
4737
|
-
throw new Error("no access token");
|
|
4738
|
-
}
|
|
4739
|
-
}
|
|
4740
|
-
static async getIsValidBranchName(branchName) {
|
|
4741
|
-
return isValidBranchName(branchName);
|
|
4742
|
-
}
|
|
4743
|
-
_validateAccessTokenAndUrl() {
|
|
4744
|
-
this._validateAccessToken();
|
|
4745
|
-
this._validateUrl();
|
|
4746
|
-
}
|
|
4747
|
-
_validateUrl() {
|
|
4748
|
-
if (!this.url) {
|
|
4749
|
-
console.error("no url");
|
|
4750
|
-
throw new InvalidRepoUrlError("no url");
|
|
4751
|
-
}
|
|
4752
|
-
}
|
|
4753
|
-
};
|
|
4754
|
-
|
|
4755
|
-
// src/features/analysis/scm/ado/AdoSCMLib.ts
|
|
4756
4912
|
async function initAdoSdk(params) {
|
|
4757
4913
|
const { url, accessToken, scmOrg } = params;
|
|
4758
4914
|
const adoClientParams = await getAdoClientParams({
|
|
@@ -5395,353 +5551,104 @@ var BitbucketSCMLib = class extends SCMLib {
|
|
|
5395
5551
|
case "public":
|
|
5396
5552
|
return {};
|
|
5397
5553
|
case "token":
|
|
5398
|
-
return { authorization: `Bearer ${this.accessToken}` };
|
|
5399
|
-
case "basic": {
|
|
5400
|
-
this._validateAccessToken();
|
|
5401
|
-
const { username, password } = getUserAndPassword(this.accessToken);
|
|
5402
|
-
return {
|
|
5403
|
-
authorization: `Basic ${Buffer.from(
|
|
5404
|
-
username + ":" + password
|
|
5405
|
-
).toString("base64")}`
|
|
5406
|
-
};
|
|
5407
|
-
}
|
|
5408
|
-
}
|
|
5409
|
-
}
|
|
5410
|
-
async getDownloadUrl(sha) {
|
|
5411
|
-
this._validateUrl();
|
|
5412
|
-
return this.bitbucketSdk.getDownloadUrl({ url: this.url, sha });
|
|
5413
|
-
}
|
|
5414
|
-
async _getUsernameForAuthUrl() {
|
|
5415
|
-
this._validateAccessTokenAndUrl();
|
|
5416
|
-
const user = await this.bitbucketSdk.getUser();
|
|
5417
|
-
if (!user.username) {
|
|
5418
|
-
throw new Error("no username found");
|
|
5419
|
-
}
|
|
5420
|
-
return user.username;
|
|
5421
|
-
}
|
|
5422
|
-
async getIsRemoteBranch(branch) {
|
|
5423
|
-
this._validateAccessTokenAndUrl();
|
|
5424
|
-
try {
|
|
5425
|
-
const res = await this.bitbucketSdk.getBranch({
|
|
5426
|
-
branchName: branch,
|
|
5427
|
-
repoUrl: this.url
|
|
5428
|
-
});
|
|
5429
|
-
return res.name === branch;
|
|
5430
|
-
} catch (e) {
|
|
5431
|
-
return false;
|
|
5432
|
-
}
|
|
5433
|
-
}
|
|
5434
|
-
async getUserHasAccessToRepo() {
|
|
5435
|
-
this._validateAccessTokenAndUrl();
|
|
5436
|
-
return this.bitbucketSdk.getIsUserCollaborator({ repoUrl: this.url });
|
|
5437
|
-
}
|
|
5438
|
-
async getUsername() {
|
|
5439
|
-
this._validateAccessToken();
|
|
5440
|
-
const res = await this.bitbucketSdk.getUser();
|
|
5441
|
-
return z21.string().parse(res.username);
|
|
5442
|
-
}
|
|
5443
|
-
async getSubmitRequestStatus(_scmSubmitRequestId) {
|
|
5444
|
-
this._validateAccessTokenAndUrl();
|
|
5445
|
-
const pullRequestRes = await this.bitbucketSdk.getPullRequest({
|
|
5446
|
-
prNumber: Number(_scmSubmitRequestId),
|
|
5447
|
-
url: this.url
|
|
5448
|
-
});
|
|
5449
|
-
switch (pullRequestRes.state) {
|
|
5450
|
-
case "OPEN":
|
|
5451
|
-
return "open";
|
|
5452
|
-
case "MERGED":
|
|
5453
|
-
return "merged";
|
|
5454
|
-
case "DECLINED":
|
|
5455
|
-
return "closed";
|
|
5456
|
-
default:
|
|
5457
|
-
throw new Error(`unknown state ${pullRequestRes.state} `);
|
|
5458
|
-
}
|
|
5459
|
-
}
|
|
5460
|
-
async getRepoBlameRanges(_ref, _path) {
|
|
5461
|
-
return [];
|
|
5462
|
-
}
|
|
5463
|
-
async getReferenceData(ref) {
|
|
5464
|
-
this._validateUrl();
|
|
5465
|
-
return this.bitbucketSdk.getReferenceData({ url: this.url, ref });
|
|
5466
|
-
}
|
|
5467
|
-
async getRepoDefaultBranch() {
|
|
5468
|
-
this._validateUrl();
|
|
5469
|
-
const repoRes = await this.bitbucketSdk.getRepo({ repoUrl: this.url });
|
|
5470
|
-
return z21.string().parse(repoRes.mainbranch?.name);
|
|
5471
|
-
}
|
|
5472
|
-
getSubmitRequestUrl(submitRequestId) {
|
|
5473
|
-
this._validateUrl();
|
|
5474
|
-
const { repo_slug, workspace } = parseBitbucketOrganizationAndRepo(this.url);
|
|
5475
|
-
return Promise.resolve(
|
|
5476
|
-
`https://bitbucket.org/${workspace}/${repo_slug}/pull-requests/${submitRequestId}`
|
|
5477
|
-
);
|
|
5478
|
-
}
|
|
5479
|
-
async getSubmitRequestId(submitRequestUrl) {
|
|
5480
|
-
const match = submitRequestUrl.match(/\/pull-requests\/(\d+)/);
|
|
5481
|
-
return match?.[1] || "";
|
|
5482
|
-
}
|
|
5483
|
-
getCommitUrl(commitId) {
|
|
5484
|
-
this._validateUrl();
|
|
5485
|
-
const { repo_slug, workspace } = parseBitbucketOrganizationAndRepo(this.url);
|
|
5486
|
-
return Promise.resolve(
|
|
5487
|
-
`https://bitbucket.org/${workspace}/${repo_slug}/commits/${commitId}`
|
|
5488
|
-
);
|
|
5489
|
-
}
|
|
5490
|
-
async addCommentToSubmitRequest(submitRequestId, comment) {
|
|
5491
|
-
this._validateUrl();
|
|
5492
|
-
await this.bitbucketSdk.addCommentToPullRequest({
|
|
5493
|
-
prNumber: Number(submitRequestId),
|
|
5494
|
-
url: this.url,
|
|
5495
|
-
markdownComment: comment
|
|
5496
|
-
});
|
|
5497
|
-
}
|
|
5498
|
-
};
|
|
5499
|
-
|
|
5500
|
-
// src/features/analysis/scm/github/GithubSCMLib.ts
|
|
5501
|
-
import { z as z22 } from "zod";
|
|
5502
|
-
var GithubSCMLib = class extends SCMLib {
|
|
5503
|
-
// we don't always need a url, what's important is that we have an access token
|
|
5504
|
-
constructor(url, accessToken, scmOrg) {
|
|
5505
|
-
super(url, accessToken, scmOrg);
|
|
5506
|
-
__publicField(this, "githubSdk");
|
|
5507
|
-
this.githubSdk = getGithubSdk({
|
|
5508
|
-
auth: accessToken,
|
|
5509
|
-
url
|
|
5510
|
-
});
|
|
5511
|
-
}
|
|
5512
|
-
async createSubmitRequest(params) {
|
|
5513
|
-
this._validateAccessTokenAndUrl();
|
|
5514
|
-
const { targetBranchName, sourceBranchName, title, body } = params;
|
|
5515
|
-
const pullRequestResult = await this.githubSdk.createPullRequest({
|
|
5516
|
-
title,
|
|
5517
|
-
body,
|
|
5518
|
-
targetBranchName,
|
|
5519
|
-
sourceBranchName,
|
|
5520
|
-
repoUrl: this.url
|
|
5521
|
-
});
|
|
5522
|
-
return String(pullRequestResult.data.number);
|
|
5523
|
-
}
|
|
5524
|
-
async forkRepo(repoUrl) {
|
|
5525
|
-
this._validateAccessToken();
|
|
5526
|
-
return this.githubSdk.forkRepo({
|
|
5527
|
-
repoUrl
|
|
5528
|
-
});
|
|
5529
|
-
}
|
|
5530
|
-
async createOrUpdateRepositorySecret(params) {
|
|
5531
|
-
this._validateAccessTokenAndUrl();
|
|
5532
|
-
const { owner, repo } = parseGithubOwnerAndRepo(this.url);
|
|
5533
|
-
const { data: repositoryPublicKeyResponse } = await this.githubSdk.getRepositoryPublicKey({ owner, repo });
|
|
5534
|
-
const { key_id, key } = repositoryPublicKeyResponse;
|
|
5535
|
-
const encryptedValue = await encryptSecret(params.value, key);
|
|
5536
|
-
return this.githubSdk.createOrUpdateRepositorySecret({
|
|
5537
|
-
encrypted_value: encryptedValue,
|
|
5538
|
-
secret_name: params.name,
|
|
5539
|
-
key_id,
|
|
5540
|
-
owner,
|
|
5541
|
-
repo
|
|
5542
|
-
});
|
|
5543
|
-
}
|
|
5544
|
-
async createPullRequestWithNewFile(sourceRepoUrl, filesPaths, userRepoUrl, title, body) {
|
|
5545
|
-
const { pull_request_url } = await this.githubSdk.createPr({
|
|
5546
|
-
sourceRepoUrl,
|
|
5547
|
-
filesPaths,
|
|
5548
|
-
userRepoUrl,
|
|
5549
|
-
title,
|
|
5550
|
-
body
|
|
5551
|
-
});
|
|
5552
|
-
return { pull_request_url };
|
|
5553
|
-
}
|
|
5554
|
-
async validateParams() {
|
|
5555
|
-
return githubValidateParams(this.url, this.accessToken);
|
|
5556
|
-
}
|
|
5557
|
-
async postPrComment(params) {
|
|
5558
|
-
this._validateAccessTokenAndUrl();
|
|
5559
|
-
const { owner, repo } = parseGithubOwnerAndRepo(this.url);
|
|
5560
|
-
return this.githubSdk.postPrComment({
|
|
5561
|
-
...params,
|
|
5562
|
-
owner,
|
|
5563
|
-
repo
|
|
5564
|
-
});
|
|
5565
|
-
}
|
|
5566
|
-
async updatePrComment(params) {
|
|
5567
|
-
this._validateAccessTokenAndUrl();
|
|
5568
|
-
const { owner, repo } = parseGithubOwnerAndRepo(this.url);
|
|
5569
|
-
return this.githubSdk.updatePrComment({
|
|
5570
|
-
...params,
|
|
5571
|
-
owner,
|
|
5572
|
-
repo
|
|
5573
|
-
});
|
|
5574
|
-
}
|
|
5575
|
-
async deleteComment(params) {
|
|
5576
|
-
this._validateAccessTokenAndUrl();
|
|
5577
|
-
const { owner, repo } = parseGithubOwnerAndRepo(this.url);
|
|
5578
|
-
return this.githubSdk.deleteComment({
|
|
5579
|
-
...params,
|
|
5580
|
-
owner,
|
|
5581
|
-
repo
|
|
5582
|
-
});
|
|
5583
|
-
}
|
|
5584
|
-
async getPrComments(params) {
|
|
5585
|
-
this._validateAccessTokenAndUrl();
|
|
5586
|
-
const { owner, repo } = parseGithubOwnerAndRepo(this.url);
|
|
5587
|
-
return this.githubSdk.getPrComments({
|
|
5588
|
-
per_page: 100,
|
|
5589
|
-
...params,
|
|
5590
|
-
owner,
|
|
5591
|
-
repo
|
|
5592
|
-
});
|
|
5593
|
-
}
|
|
5594
|
-
async getPrDiff(params) {
|
|
5595
|
-
this._validateAccessTokenAndUrl();
|
|
5596
|
-
const { owner, repo } = parseGithubOwnerAndRepo(this.url);
|
|
5597
|
-
const prRes = await this.githubSdk.getPrDiff({
|
|
5598
|
-
...params,
|
|
5599
|
-
owner,
|
|
5600
|
-
repo
|
|
5601
|
-
});
|
|
5602
|
-
return z22.string().parse(prRes.data);
|
|
5603
|
-
}
|
|
5604
|
-
async getRepoList(_scmOrg) {
|
|
5605
|
-
this._validateAccessToken();
|
|
5606
|
-
return this.githubSdk.getGithubRepoList();
|
|
5607
|
-
}
|
|
5608
|
-
async getBranchList() {
|
|
5609
|
-
this._validateAccessTokenAndUrl();
|
|
5610
|
-
const branches = await this.githubSdk.getGithubBranchList(this.url);
|
|
5611
|
-
return branches.data.map((branch) => branch.name);
|
|
5612
|
-
}
|
|
5613
|
-
get scmLibType() {
|
|
5614
|
-
return "GITHUB" /* GITHUB */;
|
|
5615
|
-
}
|
|
5616
|
-
getAuthHeaders() {
|
|
5617
|
-
if (this.accessToken) {
|
|
5618
|
-
return { authorization: `Bearer ${this.accessToken}` };
|
|
5554
|
+
return { authorization: `Bearer ${this.accessToken}` };
|
|
5555
|
+
case "basic": {
|
|
5556
|
+
this._validateAccessToken();
|
|
5557
|
+
const { username, password } = getUserAndPassword(this.accessToken);
|
|
5558
|
+
return {
|
|
5559
|
+
authorization: `Basic ${Buffer.from(
|
|
5560
|
+
username + ":" + password
|
|
5561
|
+
).toString("base64")}`
|
|
5562
|
+
};
|
|
5563
|
+
}
|
|
5619
5564
|
}
|
|
5620
|
-
return {};
|
|
5621
5565
|
}
|
|
5622
|
-
getDownloadUrl(sha) {
|
|
5566
|
+
async getDownloadUrl(sha) {
|
|
5623
5567
|
this._validateUrl();
|
|
5624
|
-
|
|
5625
|
-
if (!res) {
|
|
5626
|
-
throw new InvalidRepoUrlError("invalid repo url");
|
|
5627
|
-
}
|
|
5628
|
-
const { protocol, hostname, organization, repoName } = res;
|
|
5629
|
-
const downloadUrl = isGithubOnPrem(this.url) ? `${protocol}//${hostname}/api/v3/repos/${organization}/${repoName}/zipball/${sha}` : `https://api.${hostname}/repos/${organization}/${repoName}/zipball/${sha}`;
|
|
5630
|
-
return Promise.resolve(downloadUrl);
|
|
5568
|
+
return this.bitbucketSdk.getDownloadUrl({ url: this.url, sha });
|
|
5631
5569
|
}
|
|
5632
5570
|
async _getUsernameForAuthUrl() {
|
|
5633
|
-
|
|
5571
|
+
this._validateAccessTokenAndUrl();
|
|
5572
|
+
const user = await this.bitbucketSdk.getUser();
|
|
5573
|
+
if (!user.username) {
|
|
5574
|
+
throw new Error("no username found");
|
|
5575
|
+
}
|
|
5576
|
+
return user.username;
|
|
5634
5577
|
}
|
|
5635
5578
|
async getIsRemoteBranch(branch) {
|
|
5636
|
-
this.
|
|
5637
|
-
|
|
5579
|
+
this._validateAccessTokenAndUrl();
|
|
5580
|
+
try {
|
|
5581
|
+
const res = await this.bitbucketSdk.getBranch({
|
|
5582
|
+
branchName: branch,
|
|
5583
|
+
repoUrl: this.url
|
|
5584
|
+
});
|
|
5585
|
+
return res.name === branch;
|
|
5586
|
+
} catch (e) {
|
|
5587
|
+
return false;
|
|
5588
|
+
}
|
|
5638
5589
|
}
|
|
5639
5590
|
async getUserHasAccessToRepo() {
|
|
5640
5591
|
this._validateAccessTokenAndUrl();
|
|
5641
|
-
|
|
5642
|
-
return this.githubSdk.getGithubIsUserCollaborator({
|
|
5643
|
-
repoUrl: this.url,
|
|
5644
|
-
username
|
|
5645
|
-
});
|
|
5592
|
+
return this.bitbucketSdk.getIsUserCollaborator({ repoUrl: this.url });
|
|
5646
5593
|
}
|
|
5647
5594
|
async getUsername() {
|
|
5648
5595
|
this._validateAccessToken();
|
|
5649
|
-
|
|
5650
|
-
|
|
5651
|
-
async getSubmitRequestStatus(scmSubmitRequestId) {
|
|
5652
|
-
this._validateAccessTokenAndUrl();
|
|
5653
|
-
return this.githubSdk.getGithubPullRequestStatus({
|
|
5654
|
-
repoUrl: this.url,
|
|
5655
|
-
prNumber: Number(scmSubmitRequestId)
|
|
5656
|
-
});
|
|
5596
|
+
const res = await this.bitbucketSdk.getUser();
|
|
5597
|
+
return z21.string().parse(res.username);
|
|
5657
5598
|
}
|
|
5658
|
-
async
|
|
5599
|
+
async getSubmitRequestStatus(_scmSubmitRequestId) {
|
|
5659
5600
|
this._validateAccessTokenAndUrl();
|
|
5660
|
-
await this.
|
|
5661
|
-
|
|
5662
|
-
|
|
5663
|
-
markdownComment: comment
|
|
5601
|
+
const pullRequestRes = await this.bitbucketSdk.getPullRequest({
|
|
5602
|
+
prNumber: Number(_scmSubmitRequestId),
|
|
5603
|
+
url: this.url
|
|
5664
5604
|
});
|
|
5605
|
+
switch (pullRequestRes.state) {
|
|
5606
|
+
case "OPEN":
|
|
5607
|
+
return "open";
|
|
5608
|
+
case "MERGED":
|
|
5609
|
+
return "merged";
|
|
5610
|
+
case "DECLINED":
|
|
5611
|
+
return "closed";
|
|
5612
|
+
default:
|
|
5613
|
+
throw new Error(`unknown state ${pullRequestRes.state} `);
|
|
5614
|
+
}
|
|
5665
5615
|
}
|
|
5666
|
-
async getRepoBlameRanges(
|
|
5667
|
-
|
|
5668
|
-
return await this.githubSdk.getGithubBlameRanges({
|
|
5669
|
-
ref,
|
|
5670
|
-
path: path8,
|
|
5671
|
-
gitHubUrl: this.url
|
|
5672
|
-
});
|
|
5616
|
+
async getRepoBlameRanges(_ref, _path) {
|
|
5617
|
+
return [];
|
|
5673
5618
|
}
|
|
5674
5619
|
async getReferenceData(ref) {
|
|
5675
5620
|
this._validateUrl();
|
|
5676
|
-
return this.
|
|
5677
|
-
}
|
|
5678
|
-
async getPrComment(commentId) {
|
|
5679
|
-
this._validateUrl();
|
|
5680
|
-
const { owner, repo } = parseGithubOwnerAndRepo(this.url);
|
|
5681
|
-
return await this.githubSdk.getPrComment({
|
|
5682
|
-
repo,
|
|
5683
|
-
owner,
|
|
5684
|
-
comment_id: commentId
|
|
5685
|
-
});
|
|
5621
|
+
return this.bitbucketSdk.getReferenceData({ url: this.url, ref });
|
|
5686
5622
|
}
|
|
5687
5623
|
async getRepoDefaultBranch() {
|
|
5688
5624
|
this._validateUrl();
|
|
5689
|
-
|
|
5625
|
+
const repoRes = await this.bitbucketSdk.getRepo({ repoUrl: this.url });
|
|
5626
|
+
return z21.string().parse(repoRes.mainbranch?.name);
|
|
5690
5627
|
}
|
|
5691
|
-
|
|
5692
|
-
this.
|
|
5693
|
-
const {
|
|
5694
|
-
|
|
5695
|
-
|
|
5696
|
-
|
|
5697
|
-
pull_number: submitRequestUrl
|
|
5698
|
-
});
|
|
5699
|
-
return getPrRes.data.html_url;
|
|
5628
|
+
getSubmitRequestUrl(submitRequestId) {
|
|
5629
|
+
this._validateUrl();
|
|
5630
|
+
const { repo_slug, workspace } = parseBitbucketOrganizationAndRepo(this.url);
|
|
5631
|
+
return Promise.resolve(
|
|
5632
|
+
`https://bitbucket.org/${workspace}/${repo_slug}/pull-requests/${submitRequestId}`
|
|
5633
|
+
);
|
|
5700
5634
|
}
|
|
5701
5635
|
async getSubmitRequestId(submitRequestUrl) {
|
|
5702
|
-
const match = submitRequestUrl.match(/\/pull\/(\d+)/);
|
|
5636
|
+
const match = submitRequestUrl.match(/\/pull-requests\/(\d+)/);
|
|
5703
5637
|
return match?.[1] || "";
|
|
5704
5638
|
}
|
|
5705
|
-
|
|
5706
|
-
this.
|
|
5707
|
-
const {
|
|
5708
|
-
|
|
5709
|
-
|
|
5710
|
-
|
|
5711
|
-
commitSha: commitId
|
|
5712
|
-
});
|
|
5713
|
-
return getCommitRes.data.html_url;
|
|
5714
|
-
}
|
|
5715
|
-
async postGeneralPrComment(params) {
|
|
5716
|
-
const { prNumber, body } = params;
|
|
5717
|
-
this._validateAccessTokenAndUrl();
|
|
5718
|
-
const { owner, repo } = parseGithubOwnerAndRepo(this.url);
|
|
5719
|
-
return await this.githubSdk.postGeneralPrComment({
|
|
5720
|
-
issue_number: prNumber,
|
|
5721
|
-
owner,
|
|
5722
|
-
repo,
|
|
5723
|
-
body
|
|
5724
|
-
});
|
|
5725
|
-
}
|
|
5726
|
-
async getGeneralPrComments(params) {
|
|
5727
|
-
const { prNumber } = params;
|
|
5728
|
-
this._validateAccessTokenAndUrl();
|
|
5729
|
-
const { owner, repo } = parseGithubOwnerAndRepo(this.url);
|
|
5730
|
-
return await this.githubSdk.getGeneralPrComments({
|
|
5731
|
-
issue_number: prNumber,
|
|
5732
|
-
owner,
|
|
5733
|
-
repo
|
|
5734
|
-
});
|
|
5639
|
+
getCommitUrl(commitId) {
|
|
5640
|
+
this._validateUrl();
|
|
5641
|
+
const { repo_slug, workspace } = parseBitbucketOrganizationAndRepo(this.url);
|
|
5642
|
+
return Promise.resolve(
|
|
5643
|
+
`https://bitbucket.org/${workspace}/${repo_slug}/commits/${commitId}`
|
|
5644
|
+
);
|
|
5735
5645
|
}
|
|
5736
|
-
async
|
|
5737
|
-
|
|
5738
|
-
|
|
5739
|
-
|
|
5740
|
-
|
|
5741
|
-
|
|
5742
|
-
owner,
|
|
5743
|
-
repo,
|
|
5744
|
-
comment_id: commentId
|
|
5646
|
+
async addCommentToSubmitRequest(submitRequestId, comment) {
|
|
5647
|
+
this._validateUrl();
|
|
5648
|
+
await this.bitbucketSdk.addCommentToPullRequest({
|
|
5649
|
+
prNumber: Number(submitRequestId),
|
|
5650
|
+
url: this.url,
|
|
5651
|
+
markdownComment: comment
|
|
5745
5652
|
});
|
|
5746
5653
|
}
|
|
5747
5654
|
};
|
|
@@ -5761,11 +5668,11 @@ import {
|
|
|
5761
5668
|
} from "undici";
|
|
5762
5669
|
|
|
5763
5670
|
// src/features/analysis/scm/gitlab/types.ts
|
|
5764
|
-
import { z as
|
|
5765
|
-
var GitlabAuthResultZ =
|
|
5766
|
-
access_token:
|
|
5767
|
-
token_type:
|
|
5768
|
-
refresh_token:
|
|
5671
|
+
import { z as z22 } from "zod";
|
|
5672
|
+
var GitlabAuthResultZ = z22.object({
|
|
5673
|
+
access_token: z22.string(),
|
|
5674
|
+
token_type: z22.string(),
|
|
5675
|
+
refresh_token: z22.string()
|
|
5769
5676
|
});
|
|
5770
5677
|
|
|
5771
5678
|
// src/features/analysis/scm/gitlab/gitlab.ts
|
|
@@ -6307,7 +6214,7 @@ var GitlabSCMLib = class extends SCMLib {
|
|
|
6307
6214
|
};
|
|
6308
6215
|
|
|
6309
6216
|
// src/features/analysis/scm/scmFactory.ts
|
|
6310
|
-
import { z as
|
|
6217
|
+
import { z as z23 } from "zod";
|
|
6311
6218
|
|
|
6312
6219
|
// src/features/analysis/scm/StubSCMLib.ts
|
|
6313
6220
|
var StubSCMLib = class extends SCMLib {
|
|
@@ -6429,7 +6336,7 @@ async function createScmLib({ url, accessToken, scmType, scmOrg }, { propagateEx
|
|
|
6429
6336
|
if (e instanceof InvalidRepoUrlError && url) {
|
|
6430
6337
|
throw new RepoNoTokenAccessError(
|
|
6431
6338
|
"no access to repo",
|
|
6432
|
-
scmLibScmTypeToScmType[
|
|
6339
|
+
scmLibScmTypeToScmType[z23.nativeEnum(ScmLibScmType).parse(scmType)]
|
|
6433
6340
|
);
|
|
6434
6341
|
}
|
|
6435
6342
|
console.error(`error validating scm: ${scmType} `, e);
|
|
@@ -6905,8 +6812,256 @@ function getGithubSdk(params = {}) {
|
|
|
6905
6812
|
async getUserInfo() {
|
|
6906
6813
|
return octokit.request(GET_USER);
|
|
6907
6814
|
}
|
|
6908
|
-
};
|
|
6909
|
-
}
|
|
6815
|
+
};
|
|
6816
|
+
}
|
|
6817
|
+
|
|
6818
|
+
// src/features/analysis/scm/github/GithubSCMLib.ts
|
|
6819
|
+
var GithubSCMLib = class extends SCMLib {
|
|
6820
|
+
// we don't always need a url, what's important is that we have an access token
|
|
6821
|
+
constructor(url, accessToken, scmOrg) {
|
|
6822
|
+
super(url, accessToken, scmOrg);
|
|
6823
|
+
__publicField(this, "githubSdk");
|
|
6824
|
+
this.githubSdk = getGithubSdk({
|
|
6825
|
+
auth: accessToken,
|
|
6826
|
+
url
|
|
6827
|
+
});
|
|
6828
|
+
}
|
|
6829
|
+
async createSubmitRequest(params) {
|
|
6830
|
+
this._validateAccessTokenAndUrl();
|
|
6831
|
+
const { targetBranchName, sourceBranchName, title, body } = params;
|
|
6832
|
+
const pullRequestResult = await this.githubSdk.createPullRequest({
|
|
6833
|
+
title,
|
|
6834
|
+
body,
|
|
6835
|
+
targetBranchName,
|
|
6836
|
+
sourceBranchName,
|
|
6837
|
+
repoUrl: this.url
|
|
6838
|
+
});
|
|
6839
|
+
return String(pullRequestResult.data.number);
|
|
6840
|
+
}
|
|
6841
|
+
async forkRepo(repoUrl) {
|
|
6842
|
+
this._validateAccessToken();
|
|
6843
|
+
return this.githubSdk.forkRepo({
|
|
6844
|
+
repoUrl
|
|
6845
|
+
});
|
|
6846
|
+
}
|
|
6847
|
+
async createOrUpdateRepositorySecret(params) {
|
|
6848
|
+
this._validateAccessTokenAndUrl();
|
|
6849
|
+
const { owner, repo } = parseGithubOwnerAndRepo(this.url);
|
|
6850
|
+
const { data: repositoryPublicKeyResponse } = await this.githubSdk.getRepositoryPublicKey({ owner, repo });
|
|
6851
|
+
const { key_id, key } = repositoryPublicKeyResponse;
|
|
6852
|
+
const encryptedValue = await encryptSecret(params.value, key);
|
|
6853
|
+
return this.githubSdk.createOrUpdateRepositorySecret({
|
|
6854
|
+
encrypted_value: encryptedValue,
|
|
6855
|
+
secret_name: params.name,
|
|
6856
|
+
key_id,
|
|
6857
|
+
owner,
|
|
6858
|
+
repo
|
|
6859
|
+
});
|
|
6860
|
+
}
|
|
6861
|
+
async createPullRequestWithNewFile(sourceRepoUrl, filesPaths, userRepoUrl, title, body) {
|
|
6862
|
+
const { pull_request_url } = await this.githubSdk.createPr({
|
|
6863
|
+
sourceRepoUrl,
|
|
6864
|
+
filesPaths,
|
|
6865
|
+
userRepoUrl,
|
|
6866
|
+
title,
|
|
6867
|
+
body
|
|
6868
|
+
});
|
|
6869
|
+
return { pull_request_url };
|
|
6870
|
+
}
|
|
6871
|
+
async validateParams() {
|
|
6872
|
+
return githubValidateParams(this.url, this.accessToken);
|
|
6873
|
+
}
|
|
6874
|
+
async postPrComment(params) {
|
|
6875
|
+
this._validateAccessTokenAndUrl();
|
|
6876
|
+
const { owner, repo } = parseGithubOwnerAndRepo(this.url);
|
|
6877
|
+
return this.githubSdk.postPrComment({
|
|
6878
|
+
...params,
|
|
6879
|
+
owner,
|
|
6880
|
+
repo
|
|
6881
|
+
});
|
|
6882
|
+
}
|
|
6883
|
+
async updatePrComment(params) {
|
|
6884
|
+
this._validateAccessTokenAndUrl();
|
|
6885
|
+
const { owner, repo } = parseGithubOwnerAndRepo(this.url);
|
|
6886
|
+
return this.githubSdk.updatePrComment({
|
|
6887
|
+
...params,
|
|
6888
|
+
owner,
|
|
6889
|
+
repo
|
|
6890
|
+
});
|
|
6891
|
+
}
|
|
6892
|
+
async deleteComment(params) {
|
|
6893
|
+
this._validateAccessTokenAndUrl();
|
|
6894
|
+
const { owner, repo } = parseGithubOwnerAndRepo(this.url);
|
|
6895
|
+
return this.githubSdk.deleteComment({
|
|
6896
|
+
...params,
|
|
6897
|
+
owner,
|
|
6898
|
+
repo
|
|
6899
|
+
});
|
|
6900
|
+
}
|
|
6901
|
+
async getPrComments(params) {
|
|
6902
|
+
this._validateAccessTokenAndUrl();
|
|
6903
|
+
const { owner, repo } = parseGithubOwnerAndRepo(this.url);
|
|
6904
|
+
return this.githubSdk.getPrComments({
|
|
6905
|
+
per_page: 100,
|
|
6906
|
+
...params,
|
|
6907
|
+
owner,
|
|
6908
|
+
repo
|
|
6909
|
+
});
|
|
6910
|
+
}
|
|
6911
|
+
async getPrDiff(params) {
|
|
6912
|
+
this._validateAccessTokenAndUrl();
|
|
6913
|
+
const { owner, repo } = parseGithubOwnerAndRepo(this.url);
|
|
6914
|
+
const prRes = await this.githubSdk.getPrDiff({
|
|
6915
|
+
...params,
|
|
6916
|
+
owner,
|
|
6917
|
+
repo
|
|
6918
|
+
});
|
|
6919
|
+
return z24.string().parse(prRes.data);
|
|
6920
|
+
}
|
|
6921
|
+
async getRepoList(_scmOrg) {
|
|
6922
|
+
this._validateAccessToken();
|
|
6923
|
+
return this.githubSdk.getGithubRepoList();
|
|
6924
|
+
}
|
|
6925
|
+
async getBranchList() {
|
|
6926
|
+
this._validateAccessTokenAndUrl();
|
|
6927
|
+
const branches = await this.githubSdk.getGithubBranchList(this.url);
|
|
6928
|
+
return branches.data.map((branch) => branch.name);
|
|
6929
|
+
}
|
|
6930
|
+
get scmLibType() {
|
|
6931
|
+
return "GITHUB" /* GITHUB */;
|
|
6932
|
+
}
|
|
6933
|
+
getAuthHeaders() {
|
|
6934
|
+
if (this.accessToken) {
|
|
6935
|
+
return { authorization: `Bearer ${this.accessToken}` };
|
|
6936
|
+
}
|
|
6937
|
+
return {};
|
|
6938
|
+
}
|
|
6939
|
+
getDownloadUrl(sha) {
|
|
6940
|
+
this._validateUrl();
|
|
6941
|
+
const res = parseScmURL(this.url, "GitHub" /* GitHub */);
|
|
6942
|
+
if (!res) {
|
|
6943
|
+
throw new InvalidRepoUrlError("invalid repo url");
|
|
6944
|
+
}
|
|
6945
|
+
const { protocol, hostname, organization, repoName } = res;
|
|
6946
|
+
const downloadUrl = isGithubOnPrem(this.url) ? `${protocol}//${hostname}/api/v3/repos/${organization}/${repoName}/zipball/${sha}` : `https://api.${hostname}/repos/${organization}/${repoName}/zipball/${sha}`;
|
|
6947
|
+
return Promise.resolve(downloadUrl);
|
|
6948
|
+
}
|
|
6949
|
+
async _getUsernameForAuthUrl() {
|
|
6950
|
+
return this.getUsername();
|
|
6951
|
+
}
|
|
6952
|
+
async getIsRemoteBranch(branch) {
|
|
6953
|
+
this._validateUrl();
|
|
6954
|
+
return this.githubSdk.getGithubIsRemoteBranch({ branch, repoUrl: this.url });
|
|
6955
|
+
}
|
|
6956
|
+
async getUserHasAccessToRepo() {
|
|
6957
|
+
this._validateAccessTokenAndUrl();
|
|
6958
|
+
const username = await this.getUsername();
|
|
6959
|
+
return this.githubSdk.getGithubIsUserCollaborator({
|
|
6960
|
+
repoUrl: this.url,
|
|
6961
|
+
username
|
|
6962
|
+
});
|
|
6963
|
+
}
|
|
6964
|
+
async getUsername() {
|
|
6965
|
+
this._validateAccessToken();
|
|
6966
|
+
return this.githubSdk.getGithubUsername();
|
|
6967
|
+
}
|
|
6968
|
+
async getSubmitRequestStatus(scmSubmitRequestId) {
|
|
6969
|
+
this._validateAccessTokenAndUrl();
|
|
6970
|
+
return this.githubSdk.getGithubPullRequestStatus({
|
|
6971
|
+
repoUrl: this.url,
|
|
6972
|
+
prNumber: Number(scmSubmitRequestId)
|
|
6973
|
+
});
|
|
6974
|
+
}
|
|
6975
|
+
async addCommentToSubmitRequest(submitRequestId, comment) {
|
|
6976
|
+
this._validateAccessTokenAndUrl();
|
|
6977
|
+
await this.githubSdk.createMarkdownCommentOnPullRequest({
|
|
6978
|
+
repoUrl: this.url,
|
|
6979
|
+
prNumber: Number(submitRequestId),
|
|
6980
|
+
markdownComment: comment
|
|
6981
|
+
});
|
|
6982
|
+
}
|
|
6983
|
+
async getRepoBlameRanges(ref, path8) {
|
|
6984
|
+
this._validateUrl();
|
|
6985
|
+
return await this.githubSdk.getGithubBlameRanges({
|
|
6986
|
+
ref,
|
|
6987
|
+
path: path8,
|
|
6988
|
+
gitHubUrl: this.url
|
|
6989
|
+
});
|
|
6990
|
+
}
|
|
6991
|
+
async getReferenceData(ref) {
|
|
6992
|
+
this._validateUrl();
|
|
6993
|
+
return this.githubSdk.getGithubReferenceData({ ref, gitHubUrl: this.url });
|
|
6994
|
+
}
|
|
6995
|
+
async getPrComment(commentId) {
|
|
6996
|
+
this._validateUrl();
|
|
6997
|
+
const { owner, repo } = parseGithubOwnerAndRepo(this.url);
|
|
6998
|
+
return await this.githubSdk.getPrComment({
|
|
6999
|
+
repo,
|
|
7000
|
+
owner,
|
|
7001
|
+
comment_id: commentId
|
|
7002
|
+
});
|
|
7003
|
+
}
|
|
7004
|
+
async getRepoDefaultBranch() {
|
|
7005
|
+
this._validateUrl();
|
|
7006
|
+
return await this.githubSdk.getGithubRepoDefaultBranch(this.url);
|
|
7007
|
+
}
|
|
7008
|
+
async getSubmitRequestUrl(submitRequestUrl) {
|
|
7009
|
+
this._validateAccessTokenAndUrl();
|
|
7010
|
+
const { owner, repo } = parseGithubOwnerAndRepo(this.url);
|
|
7011
|
+
const getPrRes = await this.githubSdk.getPr({
|
|
7012
|
+
owner,
|
|
7013
|
+
repo,
|
|
7014
|
+
pull_number: submitRequestUrl
|
|
7015
|
+
});
|
|
7016
|
+
return getPrRes.data.html_url;
|
|
7017
|
+
}
|
|
7018
|
+
async getSubmitRequestId(submitRequestUrl) {
|
|
7019
|
+
const match = submitRequestUrl.match(/\/pull\/(\d+)/);
|
|
7020
|
+
return match?.[1] || "";
|
|
7021
|
+
}
|
|
7022
|
+
async getCommitUrl(commitId) {
|
|
7023
|
+
this._validateAccessTokenAndUrl();
|
|
7024
|
+
const { owner, repo } = parseGithubOwnerAndRepo(this.url);
|
|
7025
|
+
const getCommitRes = await this.githubSdk.getCommit({
|
|
7026
|
+
owner,
|
|
7027
|
+
repo,
|
|
7028
|
+
commitSha: commitId
|
|
7029
|
+
});
|
|
7030
|
+
return getCommitRes.data.html_url;
|
|
7031
|
+
}
|
|
7032
|
+
async postGeneralPrComment(params) {
|
|
7033
|
+
const { prNumber, body } = params;
|
|
7034
|
+
this._validateAccessTokenAndUrl();
|
|
7035
|
+
const { owner, repo } = parseGithubOwnerAndRepo(this.url);
|
|
7036
|
+
return await this.githubSdk.postGeneralPrComment({
|
|
7037
|
+
issue_number: prNumber,
|
|
7038
|
+
owner,
|
|
7039
|
+
repo,
|
|
7040
|
+
body
|
|
7041
|
+
});
|
|
7042
|
+
}
|
|
7043
|
+
async getGeneralPrComments(params) {
|
|
7044
|
+
const { prNumber } = params;
|
|
7045
|
+
this._validateAccessTokenAndUrl();
|
|
7046
|
+
const { owner, repo } = parseGithubOwnerAndRepo(this.url);
|
|
7047
|
+
return await this.githubSdk.getGeneralPrComments({
|
|
7048
|
+
issue_number: prNumber,
|
|
7049
|
+
owner,
|
|
7050
|
+
repo
|
|
7051
|
+
});
|
|
7052
|
+
}
|
|
7053
|
+
async deleteGeneralPrComment({
|
|
7054
|
+
commentId
|
|
7055
|
+
}) {
|
|
7056
|
+
this._validateAccessTokenAndUrl();
|
|
7057
|
+
const { owner, repo } = parseGithubOwnerAndRepo(this.url);
|
|
7058
|
+
return this.githubSdk.deleteGeneralPrComment({
|
|
7059
|
+
owner,
|
|
7060
|
+
repo,
|
|
7061
|
+
comment_id: commentId
|
|
7062
|
+
});
|
|
7063
|
+
}
|
|
7064
|
+
};
|
|
6910
7065
|
|
|
6911
7066
|
// src/features/analysis/add_fix_comments_for_pr/utils/utils.ts
|
|
6912
7067
|
import Debug7 from "debug";
|
|
@@ -6986,8 +7141,9 @@ import Debug6 from "debug";
|
|
|
6986
7141
|
import { z as z25 } from "zod";
|
|
6987
7142
|
var debug6 = Debug6("mobbdev:handle-finished-analysis");
|
|
6988
7143
|
var getCommitFixButton = (commitUrl) => `<a href="${commitUrl}"><img src=${COMMIT_FIX_SVG}></a>`;
|
|
6989
|
-
function
|
|
7144
|
+
function buildFixCommentBody({
|
|
6990
7145
|
fix,
|
|
7146
|
+
issueId,
|
|
6991
7147
|
commentId,
|
|
6992
7148
|
commentUrl,
|
|
6993
7149
|
scanner,
|
|
@@ -6995,9 +7151,19 @@ function buildCommentBody({
|
|
|
6995
7151
|
projectId,
|
|
6996
7152
|
analysisId,
|
|
6997
7153
|
organizationId,
|
|
6998
|
-
patch
|
|
7154
|
+
patch,
|
|
7155
|
+
irrelevantIssueWithTags
|
|
6999
7156
|
}) {
|
|
7000
|
-
const
|
|
7157
|
+
const isIrrelevantIssueWithTags = irrelevantIssueWithTags?.[0]?.tag;
|
|
7158
|
+
const commitUrl = isIrrelevantIssueWithTags ? getCommitIssueUrl({
|
|
7159
|
+
appBaseUrl: WEB_APP_URL,
|
|
7160
|
+
issueId,
|
|
7161
|
+
projectId,
|
|
7162
|
+
analysisId,
|
|
7163
|
+
organizationId,
|
|
7164
|
+
redirectUrl: commentUrl,
|
|
7165
|
+
commentId
|
|
7166
|
+
}) : getCommitUrl({
|
|
7001
7167
|
appBaseUrl: WEB_APP_URL,
|
|
7002
7168
|
fixId,
|
|
7003
7169
|
projectId,
|
|
@@ -7006,7 +7172,15 @@ function buildCommentBody({
|
|
|
7006
7172
|
redirectUrl: commentUrl,
|
|
7007
7173
|
commentId
|
|
7008
7174
|
});
|
|
7009
|
-
const fixUrl =
|
|
7175
|
+
const fixUrl = isIrrelevantIssueWithTags ? getIssueUrlWithRedirect({
|
|
7176
|
+
appBaseUrl: WEB_APP_URL,
|
|
7177
|
+
issueId,
|
|
7178
|
+
projectId,
|
|
7179
|
+
analysisId,
|
|
7180
|
+
organizationId,
|
|
7181
|
+
redirectUrl: commentUrl,
|
|
7182
|
+
commentId
|
|
7183
|
+
}) : getFixUrlWithRedirect({
|
|
7010
7184
|
appBaseUrl: WEB_APP_URL,
|
|
7011
7185
|
fixId,
|
|
7012
7186
|
projectId,
|
|
@@ -7038,7 +7212,8 @@ function buildCommentBody({
|
|
|
7038
7212
|
issueType: validFixParseRes.data.safeIssueType,
|
|
7039
7213
|
issueLanguage: validFixParseRes.data.safeIssueLanguage,
|
|
7040
7214
|
fixExtraContext: validFixParseRes.data.patchAndQuestions.extraContext
|
|
7041
|
-
})
|
|
7215
|
+
}),
|
|
7216
|
+
irrelevantIssueWithTags
|
|
7042
7217
|
}) : "";
|
|
7043
7218
|
const diff = `\`\`\`diff
|
|
7044
7219
|
${patch}
|
|
@@ -7052,6 +7227,37 @@ ${getCommitFixButton(
|
|
|
7052
7227
|
)}
|
|
7053
7228
|
${fixPageLink}`;
|
|
7054
7229
|
}
|
|
7230
|
+
function buildIssueCommentBody({
|
|
7231
|
+
issueId,
|
|
7232
|
+
commentId,
|
|
7233
|
+
commentUrl,
|
|
7234
|
+
scanner,
|
|
7235
|
+
issueType,
|
|
7236
|
+
projectId,
|
|
7237
|
+
analysisId,
|
|
7238
|
+
organizationId,
|
|
7239
|
+
irrelevantIssueWithTags
|
|
7240
|
+
}) {
|
|
7241
|
+
const issueUrl = getIssueUrlWithRedirect({
|
|
7242
|
+
appBaseUrl: WEB_APP_URL,
|
|
7243
|
+
issueId,
|
|
7244
|
+
projectId,
|
|
7245
|
+
analysisId,
|
|
7246
|
+
organizationId,
|
|
7247
|
+
redirectUrl: commentUrl,
|
|
7248
|
+
commentId
|
|
7249
|
+
});
|
|
7250
|
+
const title = `# ${MobbIconMarkdown} Irrelevant issues were spotted - no action required \u{1F9F9}`;
|
|
7251
|
+
const subTitle = getCommitIssueDescription({
|
|
7252
|
+
issueType,
|
|
7253
|
+
vendor: scannerToVulnerability_Report_Vendor_Enum[scanner],
|
|
7254
|
+
irrelevantIssueWithTags
|
|
7255
|
+
});
|
|
7256
|
+
const issuePageLink = `[Learn more and fine tune the issue](${issueUrl})`;
|
|
7257
|
+
return `${title}
|
|
7258
|
+
${subTitle}
|
|
7259
|
+
${issuePageLink}`;
|
|
7260
|
+
}
|
|
7055
7261
|
|
|
7056
7262
|
// src/features/analysis/add_fix_comments_for_pr/utils/utils.ts
|
|
7057
7263
|
var debug7 = Debug7("mobbdev:handle-finished-analysis");
|
|
@@ -7109,6 +7315,53 @@ function deleteAllPreviousGeneralPrComments(params) {
|
|
|
7109
7315
|
}
|
|
7110
7316
|
});
|
|
7111
7317
|
}
|
|
7318
|
+
async function postIssueComment(params) {
|
|
7319
|
+
const {
|
|
7320
|
+
vulnerabilityReportIssueCodeNode,
|
|
7321
|
+
projectId,
|
|
7322
|
+
analysisId,
|
|
7323
|
+
organizationId,
|
|
7324
|
+
scm,
|
|
7325
|
+
commitSha,
|
|
7326
|
+
pullRequest,
|
|
7327
|
+
scanner
|
|
7328
|
+
} = params;
|
|
7329
|
+
const {
|
|
7330
|
+
path: path8,
|
|
7331
|
+
startLine,
|
|
7332
|
+
vulnerabilityReportIssue: {
|
|
7333
|
+
vulnerabilityReportIssueTags,
|
|
7334
|
+
category,
|
|
7335
|
+
safeIssueType
|
|
7336
|
+
},
|
|
7337
|
+
vulnerabilityReportIssueId
|
|
7338
|
+
} = vulnerabilityReportIssueCodeNode;
|
|
7339
|
+
const irrelevantIssueWithTags = mapCategoryToBucket[category] === "irrelevant" && vulnerabilityReportIssueTags?.length > 0 ? vulnerabilityReportIssueTags : [];
|
|
7340
|
+
const commentRes = await scm.postPrComment({
|
|
7341
|
+
body: `# ${MobbIconMarkdown} Your fix is ready!
|
|
7342
|
+
Refresh the page in order to see the changes.`,
|
|
7343
|
+
pull_number: pullRequest,
|
|
7344
|
+
commit_id: commitSha,
|
|
7345
|
+
path: path8,
|
|
7346
|
+
line: startLine
|
|
7347
|
+
});
|
|
7348
|
+
const commentId = commentRes.data.id;
|
|
7349
|
+
const commentBody = buildIssueCommentBody({
|
|
7350
|
+
issueId: vulnerabilityReportIssueId,
|
|
7351
|
+
issueType: safeIssueType,
|
|
7352
|
+
irrelevantIssueWithTags,
|
|
7353
|
+
commentId,
|
|
7354
|
+
commentUrl: commentRes.data.html_url,
|
|
7355
|
+
scanner,
|
|
7356
|
+
projectId,
|
|
7357
|
+
analysisId,
|
|
7358
|
+
organizationId
|
|
7359
|
+
});
|
|
7360
|
+
return await scm.updatePrComment({
|
|
7361
|
+
body: commentBody,
|
|
7362
|
+
comment_id: commentId
|
|
7363
|
+
});
|
|
7364
|
+
}
|
|
7112
7365
|
async function postFixComment(params) {
|
|
7113
7366
|
const {
|
|
7114
7367
|
vulnerabilityReportIssueCodeNode,
|
|
@@ -7124,8 +7377,10 @@ async function postFixComment(params) {
|
|
|
7124
7377
|
const {
|
|
7125
7378
|
path: path8,
|
|
7126
7379
|
startLine,
|
|
7127
|
-
vulnerabilityReportIssue: { fixId }
|
|
7380
|
+
vulnerabilityReportIssue: { fixId, vulnerabilityReportIssueTags, category },
|
|
7381
|
+
vulnerabilityReportIssueId
|
|
7128
7382
|
} = vulnerabilityReportIssueCodeNode;
|
|
7383
|
+
const irrelevantIssueWithTags = mapCategoryToBucket[category] === "irrelevant" && vulnerabilityReportIssueTags?.length > 0 ? vulnerabilityReportIssueTags : [];
|
|
7129
7384
|
const fix = fixesById[fixId];
|
|
7130
7385
|
if (!fix || fix.patchAndQuestions.__typename !== "FixData") {
|
|
7131
7386
|
throw new Error(`fix ${fixId} not found`);
|
|
@@ -7142,8 +7397,10 @@ Refresh the page in order to see the changes.`,
|
|
|
7142
7397
|
line: startLine
|
|
7143
7398
|
});
|
|
7144
7399
|
const commentId = commentRes.data.id;
|
|
7145
|
-
const commentBody =
|
|
7400
|
+
const commentBody = buildFixCommentBody({
|
|
7146
7401
|
fix,
|
|
7402
|
+
issueId: vulnerabilityReportIssueId,
|
|
7403
|
+
irrelevantIssueWithTags,
|
|
7147
7404
|
commentId,
|
|
7148
7405
|
commentUrl: commentRes.data.html_url,
|
|
7149
7406
|
scanner,
|
|
@@ -7297,7 +7554,7 @@ async function addFixCommentsForPr({
|
|
|
7297
7554
|
gqlClient,
|
|
7298
7555
|
scanner
|
|
7299
7556
|
}) {
|
|
7300
|
-
if (_scm instanceof GithubSCMLib
|
|
7557
|
+
if (!(_scm instanceof GithubSCMLib)) {
|
|
7301
7558
|
return;
|
|
7302
7559
|
}
|
|
7303
7560
|
const scm = _scm;
|
|
@@ -7319,7 +7576,10 @@ async function addFixCommentsForPr({
|
|
|
7319
7576
|
gqlClient,
|
|
7320
7577
|
vulnerabilityReportId: getAnalysisRes.vulnerabilityReportId
|
|
7321
7578
|
});
|
|
7322
|
-
const {
|
|
7579
|
+
const {
|
|
7580
|
+
vulnerabilityReportIssueCodeNodes,
|
|
7581
|
+
irrelevantVulnerabilityReportIssues
|
|
7582
|
+
} = prVulenrabilities;
|
|
7323
7583
|
const fixesId = vulnerabilityReportIssueCodeNodes.map(
|
|
7324
7584
|
({ vulnerabilityReportIssue: { fixId } }) => fixId
|
|
7325
7585
|
);
|
|
@@ -7348,6 +7608,33 @@ async function addFixCommentsForPr({
|
|
|
7348
7608
|
});
|
|
7349
7609
|
}
|
|
7350
7610
|
),
|
|
7611
|
+
...irrelevantVulnerabilityReportIssues.map((vulnerabilityReportIssue) => {
|
|
7612
|
+
return vulnerabilityReportIssue.codeNodes.map(
|
|
7613
|
+
(vulnerabilityReportIssueCodeNode) => {
|
|
7614
|
+
return postIssueComment({
|
|
7615
|
+
vulnerabilityReportIssueCodeNode: {
|
|
7616
|
+
path: vulnerabilityReportIssueCodeNode.path,
|
|
7617
|
+
startLine: vulnerabilityReportIssueCodeNode.startLine,
|
|
7618
|
+
vulnerabilityReportIssue: {
|
|
7619
|
+
fixId: "",
|
|
7620
|
+
safeIssueType: vulnerabilityReportIssue.safeIssueType,
|
|
7621
|
+
vulnerabilityReportIssueTags: vulnerabilityReportIssue.vulnerabilityReportIssueTags,
|
|
7622
|
+
category: vulnerabilityReportIssue.category
|
|
7623
|
+
},
|
|
7624
|
+
vulnerabilityReportIssueId: vulnerabilityReportIssue.id
|
|
7625
|
+
},
|
|
7626
|
+
projectId,
|
|
7627
|
+
analysisId,
|
|
7628
|
+
organizationId,
|
|
7629
|
+
fixesById,
|
|
7630
|
+
scm,
|
|
7631
|
+
pullRequest,
|
|
7632
|
+
scanner,
|
|
7633
|
+
commitSha
|
|
7634
|
+
});
|
|
7635
|
+
}
|
|
7636
|
+
);
|
|
7637
|
+
}),
|
|
7351
7638
|
postAnalysisInsightComment({
|
|
7352
7639
|
prVulenrabilities,
|
|
7353
7640
|
pullRequest,
|
|
@@ -7552,9 +7839,37 @@ var VulnerabilityReportIssueCodeNodeZ = z27.object({
|
|
|
7552
7839
|
path: z27.string(),
|
|
7553
7840
|
startLine: z27.number(),
|
|
7554
7841
|
vulnerabilityReportIssue: z27.object({
|
|
7555
|
-
fixId: z27.string()
|
|
7842
|
+
fixId: z27.string(),
|
|
7843
|
+
category: ValidCategoriesZ,
|
|
7844
|
+
safeIssueType: z27.string(),
|
|
7845
|
+
vulnerabilityReportIssueTags: z27.array(
|
|
7846
|
+
z27.object({
|
|
7847
|
+
tag: z27.nativeEnum(Vulnerability_Report_Issue_Tag_Enum)
|
|
7848
|
+
})
|
|
7849
|
+
)
|
|
7556
7850
|
})
|
|
7557
7851
|
});
|
|
7852
|
+
var VulnerabilityReportIssueNoFixCodeNodeZ = z27.object({
|
|
7853
|
+
vulnerabilityReportIssues: z27.array(
|
|
7854
|
+
z27.object({
|
|
7855
|
+
id: z27.string(),
|
|
7856
|
+
fixId: z27.string().nullable(),
|
|
7857
|
+
category: ValidCategoriesZ,
|
|
7858
|
+
safeIssueType: z27.string(),
|
|
7859
|
+
codeNodes: z27.array(
|
|
7860
|
+
z27.object({
|
|
7861
|
+
path: z27.string(),
|
|
7862
|
+
startLine: z27.number()
|
|
7863
|
+
})
|
|
7864
|
+
),
|
|
7865
|
+
vulnerabilityReportIssueTags: z27.array(
|
|
7866
|
+
z27.object({
|
|
7867
|
+
tag: z27.nativeEnum(Vulnerability_Report_Issue_Tag_Enum)
|
|
7868
|
+
})
|
|
7869
|
+
)
|
|
7870
|
+
})
|
|
7871
|
+
)
|
|
7872
|
+
});
|
|
7558
7873
|
var GetVulByNodesMetadataZ = z27.object({
|
|
7559
7874
|
vulnerabilityReportIssueCodeNodes: z27.array(VulnerabilityReportIssueCodeNodeZ),
|
|
7560
7875
|
nonFixablePrVuls: z27.object({
|
|
@@ -7571,7 +7886,10 @@ var GetVulByNodesMetadataZ = z27.object({
|
|
|
7571
7886
|
aggregate: z27.object({
|
|
7572
7887
|
count: z27.number()
|
|
7573
7888
|
})
|
|
7574
|
-
})
|
|
7889
|
+
}),
|
|
7890
|
+
irrelevantVulnerabilityReportIssue: z27.array(
|
|
7891
|
+
VulnerabilityReportIssueNoFixCodeNodeZ
|
|
7892
|
+
)
|
|
7575
7893
|
});
|
|
7576
7894
|
|
|
7577
7895
|
// src/features/analysis/graphql/gql.ts
|
|
@@ -7723,6 +8041,7 @@ var GQLClient = class {
|
|
|
7723
8041
|
const totalScanVulnerabilities = parsedGetVulByNodesMetadataRes.totalScanVulnerabilities.aggregate.count;
|
|
7724
8042
|
const vulnerabilitiesOutsidePr = totalScanVulnerabilities - nonFixablePrVuls - fixablePrVuls;
|
|
7725
8043
|
const totalPrVulnerabilities = nonFixablePrVuls + fixablePrVuls;
|
|
8044
|
+
const irrelevantVulnerabilityReportIssues = parsedGetVulByNodesMetadataRes.irrelevantVulnerabilityReportIssue?.[0]?.vulnerabilityReportIssues ?? [];
|
|
7726
8045
|
return {
|
|
7727
8046
|
vulnerabilityReportIssueCodeNodes: Object.values(
|
|
7728
8047
|
uniqueVulByNodesMetadata
|
|
@@ -7731,7 +8050,8 @@ var GQLClient = class {
|
|
|
7731
8050
|
fixablePrVuls,
|
|
7732
8051
|
totalScanVulnerabilities,
|
|
7733
8052
|
vulnerabilitiesOutsidePr,
|
|
7734
|
-
totalPrVulnerabilities
|
|
8053
|
+
totalPrVulnerabilities,
|
|
8054
|
+
irrelevantVulnerabilityReportIssues
|
|
7735
8055
|
};
|
|
7736
8056
|
}
|
|
7737
8057
|
async digestVulnerabilityReport({
|