@jphutchins/code-review 0.1.0-alpha.30 → 0.1.0-alpha.31
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.js +67 -21
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -404,6 +404,7 @@ var renderStraysSection = (strays) => {
|
|
|
404
404
|
};
|
|
405
405
|
var asRecord = (u) => typeof u === "object" && u !== null && !Array.isArray(u) ? u : null;
|
|
406
406
|
var errMsg = (e) => e instanceof Error ? e.message : String(e);
|
|
407
|
+
var annotationSafe = (msg) => msg.replaceAll(/[\r\n]+/g, " ");
|
|
407
408
|
var tryParseJson = (text) => {
|
|
408
409
|
try {
|
|
409
410
|
return { ok: true, value: JSON.parse(text) };
|
|
@@ -972,16 +973,32 @@ var pad2 = (n) => String(n).padStart(2, "0");
|
|
|
972
973
|
var formatUtc = (d) => `${String(d.getUTCFullYear())}-${pad2(d.getUTCMonth() + 1)}-${pad2(d.getUTCDate())} ${pad2(d.getUTCHours())}:${pad2(d.getUTCMinutes())} UTC`;
|
|
973
974
|
|
|
974
975
|
// src/notice.ts
|
|
975
|
-
var
|
|
976
|
+
var NOTICE_KINDS = [
|
|
977
|
+
"security-blocked",
|
|
978
|
+
"triage-error",
|
|
979
|
+
"setup-failed",
|
|
980
|
+
"checkout-failed",
|
|
981
|
+
"no-output"
|
|
982
|
+
];
|
|
983
|
+
var isNoticeKind = (s) => NOTICE_KINDS.some((k) => k === s);
|
|
976
984
|
var blockquote = (text) => text.replaceAll("\n", "\n> ");
|
|
985
|
+
var reasoned = (lead, noReason, reasons) => typeof reasons === "string" && reasons.trim() !== "" ? `${lead}
|
|
986
|
+
|
|
987
|
+
> ${blockquote(reasons)}` : noReason;
|
|
977
988
|
var noticeSummary = (kind, reasons) => {
|
|
978
989
|
switch (kind) {
|
|
979
990
|
case "security-blocked":
|
|
980
|
-
return
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
991
|
+
return reasoned(
|
|
992
|
+
"### \u{1F6D1} Code review skipped by the security gate\n\nThe diff was flagged as unsafe to apply and execute:",
|
|
993
|
+
"### \u{1F6D1} Code review skipped by the security gate\n\nThe security triage returned an unsafe verdict without a reason. See workflow logs.",
|
|
994
|
+
reasons
|
|
995
|
+
);
|
|
996
|
+
case "triage-error":
|
|
997
|
+
return reasoned(
|
|
998
|
+
"### \u{1F6E0}\uFE0F Security gate could not evaluate\n\nThe security triage could not produce a verdict (operational error), so the review failed closed \u2014 this is an infrastructure failure, not a finding about this diff. Re-run to retry a transient fault; a persistent one is a configuration issue (see the workflow logs). The triage step reported:",
|
|
999
|
+
"### \u{1F6E0}\uFE0F Security gate could not evaluate\n\nThe security triage could not produce a verdict (operational error), so the review failed closed \u2014 this is an infrastructure failure, not a finding about this diff. Re-run to retry a transient fault; a persistent one is a configuration issue (see the workflow logs).",
|
|
1000
|
+
reasons
|
|
1001
|
+
);
|
|
985
1002
|
case "setup-failed":
|
|
986
1003
|
return "### \u{1F6E0}\uFE0F Review did not run\n\nThe review job failed before the security triage could run (e.g. dependency install or environment setup). See the workflow logs \u2014 this is an infrastructure failure, not a security verdict.";
|
|
987
1004
|
case "checkout-failed":
|
|
@@ -990,15 +1007,21 @@ The diff was flagged as unsafe to apply and execute:
|
|
|
990
1007
|
return "### \u26A0\uFE0F Review did not complete\n\nThe diff passed triage but the review produced no output. See workflow logs.";
|
|
991
1008
|
}
|
|
992
1009
|
};
|
|
993
|
-
var
|
|
1010
|
+
var noticeEnvelope = (summary) => ({
|
|
994
1011
|
schema_version: DEFAULT_SCHEMA_VERSION,
|
|
995
|
-
findings: noticeFindings(
|
|
1012
|
+
findings: noticeFindings(summary),
|
|
996
1013
|
models: [],
|
|
997
1014
|
turns: 0,
|
|
998
1015
|
duration_ms: 0,
|
|
999
1016
|
vendor_cost_usd: null,
|
|
1000
1017
|
incomplete: true
|
|
1001
1018
|
});
|
|
1019
|
+
var buildNoticeEnvelope = (kind, reasons) => noticeEnvelope(noticeSummary(kind, reasons));
|
|
1020
|
+
var buildUnknownNoticeEnvelope = (kind) => noticeEnvelope(
|
|
1021
|
+
`### \u26A0\uFE0F Review could not be rendered
|
|
1022
|
+
|
|
1023
|
+
The workflow asked for an unrecognized notice kind (\`${kind}\`) \u2014 the pinned code-review CLI is older than the workflow calling it (check that its version matches). Failing closed. See the workflow logs.`
|
|
1024
|
+
);
|
|
1002
1025
|
var identity = (decoded) => decoded;
|
|
1003
1026
|
var findingsTable = [
|
|
1004
1027
|
{
|
|
@@ -1082,6 +1105,7 @@ var resolvers = {
|
|
|
1082
1105
|
prices: (raw) => resolveSingleVersion("prices", raw)
|
|
1083
1106
|
};
|
|
1084
1107
|
var resolve = (kind, raw) => resolvers[kind](raw);
|
|
1108
|
+
var describeEndpoint = (args) => args.find((a) => a === "graphql" || a.includes("/") && !a.startsWith("-")) ?? args[0] ?? "(no endpoint)";
|
|
1085
1109
|
var runGhApi = (args, stdin, env) => new Promise((resolve3, reject) => {
|
|
1086
1110
|
const child = execFile(
|
|
1087
1111
|
"gh",
|
|
@@ -1091,7 +1115,7 @@ var runGhApi = (args, stdin, env) => new Promise((resolve3, reject) => {
|
|
|
1091
1115
|
if (err) {
|
|
1092
1116
|
const stderrStr = typeof stderr === "string" && stderr.trim() ? stderr.trim() : "";
|
|
1093
1117
|
const errStr = err instanceof Error ? err.message : "unknown error";
|
|
1094
|
-
reject(new Error(`gh api failed: ${stderrStr || errStr}`));
|
|
1118
|
+
reject(new Error(`gh api ${describeEndpoint(args)} failed: ${stderrStr || errStr}`));
|
|
1095
1119
|
} else {
|
|
1096
1120
|
resolve3(stdout);
|
|
1097
1121
|
}
|
|
@@ -1105,10 +1129,17 @@ var runGhApi = (args, stdin, env) => new Promise((resolve3, reject) => {
|
|
|
1105
1129
|
// src/pr.ts
|
|
1106
1130
|
var CANDIDATE_JQ = ".[] | {number: .number, state: .state, headRef: .head.ref, headSha: .head.sha}";
|
|
1107
1131
|
var parseCandidates = (stdout) => parseJsonl(stdout);
|
|
1132
|
+
var fetchDirectCandidates = async (repo, headSha, ghApi) => {
|
|
1133
|
+
try {
|
|
1134
|
+
return parseCandidates(
|
|
1135
|
+
await ghApi([`repos/${repo}/commits/${headSha}/pulls`, "--jq", CANDIDATE_JQ])
|
|
1136
|
+
);
|
|
1137
|
+
} catch {
|
|
1138
|
+
return [];
|
|
1139
|
+
}
|
|
1140
|
+
};
|
|
1108
1141
|
var fetchPrCandidates = async (repo, headSha, ghApi) => {
|
|
1109
|
-
const direct =
|
|
1110
|
-
await ghApi([`repos/${repo}/commits/${headSha}/pulls`, "--jq", CANDIDATE_JQ])
|
|
1111
|
-
);
|
|
1142
|
+
const direct = await fetchDirectCandidates(repo, headSha, ghApi);
|
|
1112
1143
|
if (direct.length > 0) return direct;
|
|
1113
1144
|
const open = parseCandidates(
|
|
1114
1145
|
await ghApi([
|
|
@@ -3240,25 +3271,36 @@ var adaptCmd = defineCommand({
|
|
|
3240
3271
|
var noticeCmd = defineCommand({
|
|
3241
3272
|
meta: {
|
|
3242
3273
|
name: "notice",
|
|
3243
|
-
description: "Emit an abstract envelope for a run that produced no completed review (security block, setup failure,
|
|
3274
|
+
description: "Emit an abstract envelope for a run that produced no completed review (security block, triage error, setup failure, checkout failure, or empty run) \u2014 flagged incomplete so the commenter renders it honestly and won't bury a real review"
|
|
3244
3275
|
},
|
|
3245
3276
|
args: {
|
|
3246
3277
|
kind: {
|
|
3247
3278
|
type: "positional",
|
|
3248
|
-
description:
|
|
3279
|
+
description: `One of: ${NOTICE_KINDS.join(", ")} (an unrecognized kind renders a generic incomplete notice rather than failing \u2014 the pinned CLI is older than the workflow)`,
|
|
3249
3280
|
required: true
|
|
3250
3281
|
},
|
|
3251
3282
|
reasons: {
|
|
3252
3283
|
type: "string",
|
|
3253
|
-
description: "security-blocked only: the triage's fail-closed reason string (empty/omitted \u21D2 the no-reason wording)"
|
|
3284
|
+
description: "security-blocked / triage-error only: the triage's fail-closed reason string (empty/omitted \u21D2 the no-reason wording)"
|
|
3254
3285
|
}
|
|
3255
3286
|
},
|
|
3287
|
+
// An unrecognized kind degrades to a generic incomplete notice instead of exiting non-zero: a
|
|
3288
|
+
// `notice <kind>` call under the workflow's `set -euo pipefail` must never crash the assemble
|
|
3289
|
+
// step into posting nothing, and an unknown kind almost always means version skew, not a typo.
|
|
3256
3290
|
run: ({ args }) => {
|
|
3257
|
-
|
|
3258
|
-
|
|
3259
|
-
|
|
3260
|
-
|
|
3291
|
+
if (!isNoticeKind(args.kind)) {
|
|
3292
|
+
process.stderr.write(
|
|
3293
|
+
`::warning::code-review notice: unrecognized kind "${args.kind}" \u2014 the pinned CLI is older than the workflow calling it; rendering a generic incomplete notice
|
|
3294
|
+
`
|
|
3295
|
+
);
|
|
3296
|
+
process.stdout.write(`${JSON.stringify(buildUnknownNoticeEnvelope(args.kind), null, 2)}
|
|
3261
3297
|
`);
|
|
3298
|
+
return;
|
|
3299
|
+
}
|
|
3300
|
+
process.stdout.write(
|
|
3301
|
+
`${JSON.stringify(buildNoticeEnvelope(args.kind, args.reasons), null, 2)}
|
|
3302
|
+
`
|
|
3303
|
+
);
|
|
3262
3304
|
}
|
|
3263
3305
|
});
|
|
3264
3306
|
var isExtractSchemaKind = (s) => s === "findings" || s === "triage";
|
|
@@ -3685,9 +3727,13 @@ var announceCmd = defineCommand({
|
|
|
3685
3727
|
runUrl: args["run-url"],
|
|
3686
3728
|
headBranch: args["head-branch"]
|
|
3687
3729
|
}).catch(
|
|
3688
|
-
(err) =>
|
|
3689
|
-
|
|
3730
|
+
(err) => (
|
|
3731
|
+
// `::warning::` so a persistently broken announce shows up in the run's annotations, not only
|
|
3732
|
+
// buried in the step log — `announce` otherwise reports success while having posted nothing.
|
|
3733
|
+
process.stderr.write(
|
|
3734
|
+
`::warning::code-review announce: could not post the in-progress sticky (${annotationSafe(errMsg(err))}) \u2014 continuing (cosmetic)
|
|
3690
3735
|
`
|
|
3736
|
+
)
|
|
3691
3737
|
)
|
|
3692
3738
|
);
|
|
3693
3739
|
}
|