@synkro-sh/cli 1.3.40 → 1.3.41
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/bootstrap.js +28 -66
- package/dist/bootstrap.js.map +1 -1
- package/package.json +1 -1
package/dist/bootstrap.js
CHANGED
|
@@ -3746,7 +3746,7 @@ function writeConfigEnv(opts) {
|
|
|
3746
3746
|
`SYNKRO_CREDENTIALS_PATH=${shellQuoteSingle(credsPath)}`,
|
|
3747
3747
|
`SYNKRO_TIER=${shellQuoteSingle(safeTier)}`,
|
|
3748
3748
|
`SYNKRO_INFERENCE=${shellQuoteSingle(safeInference)}`,
|
|
3749
|
-
`SYNKRO_VERSION=${shellQuoteSingle("1.3.
|
|
3749
|
+
`SYNKRO_VERSION=${shellQuoteSingle("1.3.41")}`
|
|
3750
3750
|
];
|
|
3751
3751
|
if (safeUserId) lines.push(`SYNKRO_USER_ID=${shellQuoteSingle(safeUserId)}`);
|
|
3752
3752
|
if (safeOrgId) lines.push(`SYNKRO_ORG_ID=${shellQuoteSingle(safeOrgId)}`);
|
|
@@ -4793,54 +4793,9 @@ async function ensureOpenPr(repo, prNumber, sha) {
|
|
|
4793
4793
|
try {
|
|
4794
4794
|
pr = ghJson(["api", `/repos/${repo}/pulls/${prNumber}`]);
|
|
4795
4795
|
} catch {
|
|
4796
|
-
return { prNumber, sha, branched: false };
|
|
4797
|
-
}
|
|
4798
|
-
if (pr.state === "open") {
|
|
4799
|
-
return { prNumber, sha, branched: false };
|
|
4800
|
-
}
|
|
4801
|
-
if (pr.merged) {
|
|
4802
|
-
console.log(`PR #${prNumber} is merged. Scanning original diff and posting findings there.
|
|
4803
|
-
`);
|
|
4804
|
-
return { prNumber, sha: pr.head.sha, branched: false };
|
|
4805
|
-
}
|
|
4806
|
-
console.log(`PR #${prNumber} is closed. Creating a scan branch...
|
|
4807
|
-
`);
|
|
4808
|
-
const scanBranch = `synkro/scan-${pr.head.ref}-${Date.now()}`;
|
|
4809
|
-
try {
|
|
4810
|
-
execSync5(`gh api -X POST /repos/${repo}/git/refs --input -`, {
|
|
4811
|
-
encoding: "utf-8",
|
|
4812
|
-
input: JSON.stringify({ ref: `refs/heads/${scanBranch}`, sha: pr.head.sha }),
|
|
4813
|
-
stdio: ["pipe", "pipe", "pipe"]
|
|
4814
|
-
});
|
|
4815
|
-
} catch (err) {
|
|
4816
|
-
console.warn(`Failed to create scan branch: ${err.message}`);
|
|
4817
|
-
return { prNumber, sha, branched: false };
|
|
4818
|
-
}
|
|
4819
|
-
try {
|
|
4820
|
-
const newPrBody = `Security scan of closed PR #${prNumber} (\`${pr.head.ref}\`).
|
|
4821
|
-
|
|
4822
|
-
This PR contains no code changes \u2014 it exists so Synkro can post review findings on an active PR.`;
|
|
4823
|
-
const result = ghJson([
|
|
4824
|
-
"api",
|
|
4825
|
-
"-X",
|
|
4826
|
-
"POST",
|
|
4827
|
-
`/repos/${repo}/pulls`,
|
|
4828
|
-
"-f",
|
|
4829
|
-
`title=Synkro Scan: ${pr.title}`,
|
|
4830
|
-
"-f",
|
|
4831
|
-
`body=${newPrBody}`,
|
|
4832
|
-
"-f",
|
|
4833
|
-
`head=${scanBranch}`,
|
|
4834
|
-
"-f",
|
|
4835
|
-
`base=${pr.base.ref}`
|
|
4836
|
-
]);
|
|
4837
|
-
console.log(`Opened PR #${result.number} for scan findings.
|
|
4838
|
-
`);
|
|
4839
|
-
return { prNumber: result.number, sha: result.head.sha, branched: true };
|
|
4840
|
-
} catch (err) {
|
|
4841
|
-
console.warn(`Failed to open scan PR: ${err.message}`);
|
|
4842
|
-
return { prNumber, sha, branched: false };
|
|
4796
|
+
return { prNumber, sha, branched: false, prState: "unknown", merged: false };
|
|
4843
4797
|
}
|
|
4798
|
+
return { prNumber, sha: pr.head.sha, branched: false, prState: pr.state, merged: pr.merged };
|
|
4844
4799
|
}
|
|
4845
4800
|
function getPrFiles(repo, prNumber) {
|
|
4846
4801
|
const data = ghJson([
|
|
@@ -5117,7 +5072,28 @@ ${linesStr}: ${first.description}
|
|
|
5117
5072
|
severity: maxSeverity
|
|
5118
5073
|
};
|
|
5119
5074
|
}
|
|
5120
|
-
function postPrReview(repo, prNumber, sha, review) {
|
|
5075
|
+
function postPrReview(repo, prNumber, sha, review, skipLineReview = false) {
|
|
5076
|
+
function postIssueComment() {
|
|
5077
|
+
try {
|
|
5078
|
+
const body = `## \u{1F512} Synkro Security Review
|
|
5079
|
+
|
|
5080
|
+
${review.summary}
|
|
5081
|
+
|
|
5082
|
+
` + review.comments.map((c) => `**${c.path}:${c.line}** \u2014 ${c.body}`).join("\n\n");
|
|
5083
|
+
execSync5(`gh api -X POST /repos/${repo}/issues/${prNumber}/comments --input -`, {
|
|
5084
|
+
encoding: "utf-8",
|
|
5085
|
+
input: JSON.stringify({ body }),
|
|
5086
|
+
stdio: ["pipe", "ignore", "pipe"]
|
|
5087
|
+
});
|
|
5088
|
+
console.log(" \u2713 Posted issue comment with findings.");
|
|
5089
|
+
} catch (err) {
|
|
5090
|
+
console.warn("Failed to post issue comment:", err.message);
|
|
5091
|
+
}
|
|
5092
|
+
}
|
|
5093
|
+
if (skipLineReview) {
|
|
5094
|
+
postIssueComment();
|
|
5095
|
+
return;
|
|
5096
|
+
}
|
|
5121
5097
|
const preferredEvent = review.severity === "critical" || review.severity === "high" ? "REQUEST_CHANGES" : "COMMENT";
|
|
5122
5098
|
function tryPost(event) {
|
|
5123
5099
|
const body = JSON.stringify({
|
|
@@ -5143,27 +5119,12 @@ ${review.summary}`,
|
|
|
5143
5119
|
if (combined.includes("own pull request") && event === "REQUEST_CHANGES") {
|
|
5144
5120
|
return false;
|
|
5145
5121
|
}
|
|
5146
|
-
console.warn(`Failed to post review: ${(stderr || stdout || err.message).slice(0, 200)}`);
|
|
5147
5122
|
return false;
|
|
5148
5123
|
}
|
|
5149
5124
|
}
|
|
5150
5125
|
if (tryPost(preferredEvent)) return;
|
|
5151
5126
|
if (preferredEvent === "REQUEST_CHANGES" && tryPost("COMMENT")) return;
|
|
5152
|
-
|
|
5153
|
-
const fallbackBody = `## \u{1F512} Synkro Security Review
|
|
5154
|
-
|
|
5155
|
-
${review.summary}
|
|
5156
|
-
|
|
5157
|
-
` + review.comments.map((c) => `**${c.path}:${c.line}** \u2014 ${c.body}`).join("\n\n");
|
|
5158
|
-
execSync5(`gh api -X POST /repos/${repo}/issues/${prNumber}/comments --input -`, {
|
|
5159
|
-
encoding: "utf-8",
|
|
5160
|
-
input: JSON.stringify({ body: fallbackBody }),
|
|
5161
|
-
stdio: ["pipe", "ignore", "pipe"]
|
|
5162
|
-
});
|
|
5163
|
-
console.log(" \u2713 Posted fallback issue comment.");
|
|
5164
|
-
} catch (err2) {
|
|
5165
|
-
console.warn("Failed to post fallback comment:", err2.message);
|
|
5166
|
-
}
|
|
5127
|
+
postIssueComment();
|
|
5167
5128
|
}
|
|
5168
5129
|
function postCheckRun(repo, sha, conclusion, findings) {
|
|
5169
5130
|
const summary = findings.length === 0 ? "No security findings." : `${findings.length} finding(s):
|
|
@@ -5318,7 +5279,8 @@ Total: ${allFindings.length} finding(s) across ${eligible.length} file(s) in ${t
|
|
|
5318
5279
|
const review = await spawnOpusConsolidator(allFindings, claudeToken);
|
|
5319
5280
|
console.log(` \u2192 ${review.comments.length} review comment(s), severity: ${review.severity}`);
|
|
5320
5281
|
if (review.comments.length > 0) {
|
|
5321
|
-
|
|
5282
|
+
const skipLineReview = prTarget.prState === "closed" && !prTarget.merged;
|
|
5283
|
+
postPrReview(repo, activePrNumber, activeSha, review, skipLineReview);
|
|
5322
5284
|
}
|
|
5323
5285
|
}
|
|
5324
5286
|
const conclusion = shouldFail(allFindings, failThreshold) ? "failure" : "success";
|