@jphutchins/code-review 0.1.0-alpha.31 → 0.1.0-alpha.33
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 +279 -39
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1068,9 +1068,9 @@ var formatErrors = (errors) => errors.map(describeValidationError);
|
|
|
1068
1068
|
var declaredVersion = (raw) => typeof raw === "object" && raw !== null && "schema_version" in raw ? typeof raw.schema_version === "string" ? raw.schema_version : void 0 : void 0;
|
|
1069
1069
|
var supportedVersions = (kind) => tableFor(kind).map((entry) => entry.minor);
|
|
1070
1070
|
var defaultVersion = (kind) => {
|
|
1071
|
-
const
|
|
1072
|
-
if (!
|
|
1073
|
-
return
|
|
1071
|
+
const latest2 = tableFor(kind).find((entry) => entry.latest);
|
|
1072
|
+
if (!latest2) throw new Error(`Registry invariant violated \u2014 no latest entry for "${kind}"`);
|
|
1073
|
+
return latest2.defaultVersion;
|
|
1074
1074
|
};
|
|
1075
1075
|
var bundledSchemaPath = (relativePath) => resolve$1(import.meta.dirname, "..", "schema", relativePath);
|
|
1076
1076
|
var schemaPathFor = (kind, version) => {
|
|
@@ -1105,27 +1105,61 @@ var resolvers = {
|
|
|
1105
1105
|
prices: (raw) => resolveSingleVersion("prices", raw)
|
|
1106
1106
|
};
|
|
1107
1107
|
var resolve = (kind, raw) => resolvers[kind](raw);
|
|
1108
|
-
var
|
|
1109
|
-
var
|
|
1108
|
+
var MAX_BUFFER = 100 * 1024 * 1024;
|
|
1109
|
+
var MAX_TIMEOUT_MS = 2147483647;
|
|
1110
|
+
var parseTimeoutMs = (raw, fallback) => {
|
|
1111
|
+
if (raw === void 0 || !/^\d+$/.test(raw)) return fallback;
|
|
1112
|
+
const parsed = Number(raw);
|
|
1113
|
+
return parsed > 0 && parsed <= MAX_TIMEOUT_MS ? parsed : fallback;
|
|
1114
|
+
};
|
|
1115
|
+
var SUBPROCESS_TIMEOUT_ENV = "CODE_REVIEW_SUBPROCESS_TIMEOUT_MS";
|
|
1116
|
+
var DEFAULT_SUBPROCESS_TIMEOUT_MS = 12e4;
|
|
1117
|
+
var subprocessTimeoutMs = () => parseTimeoutMs(process.env[SUBPROCESS_TIMEOUT_ENV], DEFAULT_SUBPROCESS_TIMEOUT_MS);
|
|
1118
|
+
var classifyExecError = (err, stderr, timeoutMs) => {
|
|
1119
|
+
const e = err;
|
|
1120
|
+
const stderrStr = stderr.trim();
|
|
1121
|
+
if (e.code === "ERR_CHILD_PROCESS_STDIO_MAXBUFFER")
|
|
1122
|
+
return `output exceeded ${String(MAX_BUFFER)} bytes (killed)`;
|
|
1123
|
+
if (e.killed === true)
|
|
1124
|
+
return `no response within ${String(timeoutMs)}ms (killed a hung child)${stderrStr ? `: ${stderrStr}` : ""}`;
|
|
1125
|
+
return stderrStr || errMsg(err);
|
|
1126
|
+
};
|
|
1127
|
+
var execFileWithTimeout = (spec) => new Promise((resolve3, reject) => {
|
|
1110
1128
|
const child = execFile(
|
|
1111
|
-
|
|
1112
|
-
[
|
|
1113
|
-
{
|
|
1129
|
+
spec.command,
|
|
1130
|
+
[...spec.args],
|
|
1131
|
+
{
|
|
1132
|
+
...spec.env ? { env: { ...process.env, ...spec.env } } : {},
|
|
1133
|
+
encoding: "utf-8",
|
|
1134
|
+
maxBuffer: MAX_BUFFER,
|
|
1135
|
+
timeout: spec.timeoutMs,
|
|
1136
|
+
killSignal: "SIGKILL"
|
|
1137
|
+
},
|
|
1114
1138
|
(err, stdout, stderr) => {
|
|
1115
|
-
if (err)
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
resolve3(stdout);
|
|
1121
|
-
}
|
|
1139
|
+
if (err)
|
|
1140
|
+
reject(
|
|
1141
|
+
new Error(`${spec.label} failed: ${classifyExecError(err, stderr, spec.timeoutMs)}`)
|
|
1142
|
+
);
|
|
1143
|
+
else resolve3(stdout);
|
|
1122
1144
|
}
|
|
1123
1145
|
);
|
|
1124
|
-
if (stdin !== void 0) {
|
|
1125
|
-
child.stdin?.
|
|
1146
|
+
if (spec.stdin !== void 0) {
|
|
1147
|
+
child.stdin?.on("error", () => void 0);
|
|
1148
|
+
child.stdin?.end(spec.stdin);
|
|
1126
1149
|
}
|
|
1127
1150
|
});
|
|
1128
1151
|
|
|
1152
|
+
// src/gh.ts
|
|
1153
|
+
var describeEndpoint = (args) => args.find((a) => a === "graphql" || a.includes("/") && !a.startsWith("-")) ?? args[0] ?? "(no endpoint)";
|
|
1154
|
+
var runGhApi = (args, stdin, env) => execFileWithTimeout({
|
|
1155
|
+
command: "gh",
|
|
1156
|
+
args: ["api", ...args],
|
|
1157
|
+
label: `gh api ${describeEndpoint(args)}`,
|
|
1158
|
+
timeoutMs: subprocessTimeoutMs(),
|
|
1159
|
+
env,
|
|
1160
|
+
stdin
|
|
1161
|
+
});
|
|
1162
|
+
|
|
1129
1163
|
// src/pr.ts
|
|
1130
1164
|
var CANDIDATE_JQ = ".[] | {number: .number, state: .state, headRef: .head.ref, headSha: .head.sha}";
|
|
1131
1165
|
var parseCandidates = (stdout) => parseJsonl(stdout);
|
|
@@ -1725,6 +1759,134 @@ var announce = async (input, ghApi = runGhApi) => {
|
|
|
1725
1759
|
ghApi
|
|
1726
1760
|
);
|
|
1727
1761
|
};
|
|
1762
|
+
var incompleteBody = (headSha, runUrl, existingBody) => {
|
|
1763
|
+
const notice = `${DEFAULT_MARKER}
|
|
1764
|
+
|
|
1765
|
+
\u26A0\uFE0F **Code review did not complete** for \`${headSha.slice(0, 7)}\` \u2014 the review job failed ([run](${runUrl})). Re-request the review; do not treat this round as spent.`;
|
|
1766
|
+
const carried = existingBody ? carryForwardMarkers(existingBody) : "";
|
|
1767
|
+
return carried ? `${notice}
|
|
1768
|
+
|
|
1769
|
+
${carried}` : notice;
|
|
1770
|
+
};
|
|
1771
|
+
var reportIncomplete = async (input, ghApi = runGhApi) => {
|
|
1772
|
+
const candidates = await fetchPrCandidates(input.repo, input.headSha, ghApi);
|
|
1773
|
+
const resolution = resolvePr(candidates, input.headBranch);
|
|
1774
|
+
if (resolution.kind !== "open") {
|
|
1775
|
+
process.stderr.write(
|
|
1776
|
+
`No open PR for ${input.headSha} \u2014 nothing to report (${resolution.kind})
|
|
1777
|
+
`
|
|
1778
|
+
);
|
|
1779
|
+
return;
|
|
1780
|
+
}
|
|
1781
|
+
const existing = await findBotComment(
|
|
1782
|
+
input.repo,
|
|
1783
|
+
resolution.prNumber,
|
|
1784
|
+
input.botLogin,
|
|
1785
|
+
DEFAULT_MARKER,
|
|
1786
|
+
ghApi
|
|
1787
|
+
);
|
|
1788
|
+
if (existing !== null && parseReviewComplete(existing.body)) {
|
|
1789
|
+
process.stderr.write(`Sticky already reflects a completed review \u2014 leaving it in place
|
|
1790
|
+
`);
|
|
1791
|
+
return;
|
|
1792
|
+
}
|
|
1793
|
+
if (existing !== null && !existing.body.includes(input.runUrl)) {
|
|
1794
|
+
process.stderr.write(`Sticky belongs to another run \u2014 leaving it in place
|
|
1795
|
+
`);
|
|
1796
|
+
return;
|
|
1797
|
+
}
|
|
1798
|
+
await upsertSticky(
|
|
1799
|
+
input.repo,
|
|
1800
|
+
resolution.prNumber,
|
|
1801
|
+
existing,
|
|
1802
|
+
incompleteBody(input.headSha, input.runUrl, existing?.body),
|
|
1803
|
+
ghApi
|
|
1804
|
+
);
|
|
1805
|
+
};
|
|
1806
|
+
|
|
1807
|
+
// src/checkrun.ts
|
|
1808
|
+
var CHECK_RUN_NAME = "Code review";
|
|
1809
|
+
var latest = (checks) => checks.reduce(
|
|
1810
|
+
(best, c) => best === null || c.id > best.id ? c : best,
|
|
1811
|
+
null
|
|
1812
|
+
);
|
|
1813
|
+
var isOpen = (status) => status === "in_progress" || status === "queued";
|
|
1814
|
+
var settled = /* @__PURE__ */ new Set(["success", "neutral", "skipped"]);
|
|
1815
|
+
var decideCheckAction = (checks, intent) => {
|
|
1816
|
+
const head = latest(checks);
|
|
1817
|
+
switch (intent) {
|
|
1818
|
+
case "in_progress":
|
|
1819
|
+
return head !== null && isOpen(head.status) ? { kind: "noop", reason: "a check is already in progress for this head" } : { kind: "create", status: "in_progress" };
|
|
1820
|
+
case "neutral":
|
|
1821
|
+
if (head === null) return { kind: "create", status: "completed", conclusion: "neutral" };
|
|
1822
|
+
return head.status === "completed" && head.conclusion === "neutral" ? { kind: "noop", reason: "the check already records this completed review" } : { kind: "patch", id: head.id, status: "completed", conclusion: "neutral" };
|
|
1823
|
+
case "failure":
|
|
1824
|
+
if (head === null) return { kind: "create", status: "completed", conclusion: "failure" };
|
|
1825
|
+
if (head.status === "completed" && head.conclusion !== null && settled.has(head.conclusion))
|
|
1826
|
+
return { kind: "noop", reason: "a completed review already recorded this head" };
|
|
1827
|
+
return head.status === "completed" && head.conclusion === "failure" ? { kind: "noop", reason: "the check already records this failure" } : { kind: "patch", id: head.id, status: "completed", conclusion: "failure" };
|
|
1828
|
+
}
|
|
1829
|
+
};
|
|
1830
|
+
var CHECK_JQ = ".check_runs[] | {id: .id, status: .status, conclusion: .conclusion}";
|
|
1831
|
+
var fetchChecks = async (repo, headSha, ghApi) => parseJsonl(
|
|
1832
|
+
await ghApi([
|
|
1833
|
+
`repos/${repo}/commits/${headSha}/check-runs?check_name=${encodeURIComponent(CHECK_RUN_NAME)}&per_page=100`,
|
|
1834
|
+
"--paginate",
|
|
1835
|
+
"--jq",
|
|
1836
|
+
CHECK_JQ
|
|
1837
|
+
])
|
|
1838
|
+
);
|
|
1839
|
+
var output = (intent, runUrl) => {
|
|
1840
|
+
switch (intent) {
|
|
1841
|
+
case "in_progress":
|
|
1842
|
+
return {
|
|
1843
|
+
title: "Code review in progress",
|
|
1844
|
+
summary: `The review is running \u2014 [see the run](${runUrl}).`
|
|
1845
|
+
};
|
|
1846
|
+
case "neutral":
|
|
1847
|
+
return {
|
|
1848
|
+
title: "Code review complete",
|
|
1849
|
+
summary: `The review was posted \u2014 [see the run](${runUrl}).`
|
|
1850
|
+
};
|
|
1851
|
+
case "failure":
|
|
1852
|
+
return {
|
|
1853
|
+
title: "Code review did not complete",
|
|
1854
|
+
summary: `The review job failed \u2014 [see the run](${runUrl}). Re-request the review; do not treat this round as spent.`
|
|
1855
|
+
};
|
|
1856
|
+
}
|
|
1857
|
+
};
|
|
1858
|
+
var checkRun = async (input, ghApi = runGhApi) => {
|
|
1859
|
+
const action = decideCheckAction(
|
|
1860
|
+
await fetchChecks(input.repo, input.headSha, ghApi),
|
|
1861
|
+
input.intent
|
|
1862
|
+
);
|
|
1863
|
+
if (action.kind === "noop") {
|
|
1864
|
+
process.stderr.write(`code-review check-run: ${action.reason} \u2014 leaving it
|
|
1865
|
+
`);
|
|
1866
|
+
return;
|
|
1867
|
+
}
|
|
1868
|
+
const body = action.kind === "create" ? {
|
|
1869
|
+
name: CHECK_RUN_NAME,
|
|
1870
|
+
head_sha: input.headSha,
|
|
1871
|
+
status: action.status,
|
|
1872
|
+
details_url: input.runUrl,
|
|
1873
|
+
...action.conclusion ? { conclusion: action.conclusion } : {},
|
|
1874
|
+
output: output(input.intent, input.runUrl)
|
|
1875
|
+
} : {
|
|
1876
|
+
status: action.status,
|
|
1877
|
+
conclusion: action.conclusion,
|
|
1878
|
+
details_url: input.runUrl,
|
|
1879
|
+
output: output(input.intent, input.runUrl)
|
|
1880
|
+
};
|
|
1881
|
+
const endpoint = action.kind === "create" ? [`--method`, `POST`, `repos/${input.repo}/check-runs`, `--input`, `-`] : [
|
|
1882
|
+
`--method`,
|
|
1883
|
+
`PATCH`,
|
|
1884
|
+
`repos/${input.repo}/check-runs/${String(action.id)}`,
|
|
1885
|
+
`--input`,
|
|
1886
|
+
`-`
|
|
1887
|
+
];
|
|
1888
|
+
await ghApi(endpoint, JSON.stringify(body));
|
|
1889
|
+
};
|
|
1728
1890
|
var DURATION_RE = /^(\d+)(h|m|s)$/;
|
|
1729
1891
|
var USD_RE = /^\$(\d+(?:\.\d+)?)$/;
|
|
1730
1892
|
var toSeconds = (n, unit) => unit === "h" ? n * 3600 : unit === "m" ? n * 60 : n;
|
|
@@ -1931,12 +2093,12 @@ var resolveCiRun = async (repo, headSha, workflowName, ghApi) => {
|
|
|
1931
2093
|
`
|
|
1932
2094
|
);
|
|
1933
2095
|
}
|
|
1934
|
-
const
|
|
2096
|
+
const latest2 = runs.filter((r) => r.name === workflowName).reduce(
|
|
1935
2097
|
(best, r) => best === null || r.run_number > best.run_number ? r : best,
|
|
1936
2098
|
null
|
|
1937
2099
|
);
|
|
1938
2100
|
return {
|
|
1939
|
-
run:
|
|
2101
|
+
run: latest2 === null ? null : { id: latest2.id, status: latest2.status ?? "unknown", conclusion: latest2.conclusion },
|
|
1940
2102
|
seenNames: [...new Set(runs.flatMap((r) => r.name === null ? [] : [r.name]))]
|
|
1941
2103
|
};
|
|
1942
2104
|
};
|
|
@@ -1988,21 +2150,11 @@ stacked=${String(result.stacked)}
|
|
|
1988
2150
|
`;
|
|
1989
2151
|
}
|
|
1990
2152
|
};
|
|
1991
|
-
var runGit = (args) =>
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
(err, stdout, stderr) => {
|
|
1997
|
-
if (err) {
|
|
1998
|
-
const stderrStr = typeof stderr === "string" && stderr.trim() ? stderr.trim() : "";
|
|
1999
|
-
const errStr = err instanceof Error ? err.message : "unknown error";
|
|
2000
|
-
reject(new Error(`git ${args.join(" ")} failed: ${stderrStr || errStr}`));
|
|
2001
|
-
} else {
|
|
2002
|
-
resolve3(stdout);
|
|
2003
|
-
}
|
|
2004
|
-
}
|
|
2005
|
-
);
|
|
2153
|
+
var runGit = (args) => execFileWithTimeout({
|
|
2154
|
+
command: "git",
|
|
2155
|
+
args,
|
|
2156
|
+
label: `git ${args.join(" ")}`,
|
|
2157
|
+
timeoutMs: subprocessTimeoutMs()
|
|
2006
2158
|
});
|
|
2007
2159
|
var PrMetaCodec = t.type({
|
|
2008
2160
|
changed_files: t.number,
|
|
@@ -2698,7 +2850,7 @@ var renderCmd = defineCommand({
|
|
|
2698
2850
|
const prices = decode(PriceMapCodec.decode(readJSON(priceResolution.path)), "prices");
|
|
2699
2851
|
const template = readFileSync(templatePath, "utf-8");
|
|
2700
2852
|
const testReport = args["test-report"] ? decode(TestSummaryCodec.decode(readJSON(args["test-report"])), "test report") : void 0;
|
|
2701
|
-
const
|
|
2853
|
+
const output2 = render({
|
|
2702
2854
|
findings,
|
|
2703
2855
|
envelope,
|
|
2704
2856
|
prices,
|
|
@@ -2710,7 +2862,7 @@ var renderCmd = defineCommand({
|
|
|
2710
2862
|
testReport,
|
|
2711
2863
|
postedAt: formatUtc(/* @__PURE__ */ new Date())
|
|
2712
2864
|
});
|
|
2713
|
-
process.stdout.write(
|
|
2865
|
+
process.stdout.write(output2);
|
|
2714
2866
|
}
|
|
2715
2867
|
});
|
|
2716
2868
|
var inlineCmd = defineCommand({
|
|
@@ -2900,7 +3052,7 @@ var budgetHookCmd = defineCommand({
|
|
|
2900
3052
|
const prices = args.prices ? tryReadPrices(args.prices) : null;
|
|
2901
3053
|
const spentUsd = prices !== null && usage ? computeCost(usage.models, prices).totalCostUSD : null;
|
|
2902
3054
|
const wallMs = args.wall ? parseWallMs(args.wall) : null;
|
|
2903
|
-
const
|
|
3055
|
+
const output2 = evaluateBudgetHook(input, {
|
|
2904
3056
|
spentUsd,
|
|
2905
3057
|
budgetUsd: parseBudgetUsd(args["budget-usd"]),
|
|
2906
3058
|
elapsedMs: anchoredElapsedMs({
|
|
@@ -2924,7 +3076,7 @@ var budgetHookCmd = defineCommand({
|
|
|
2924
3076
|
});
|
|
2925
3077
|
if (asRecord(input)?.["hook_event_name"] === "PostToolBatch" && !isSubagentHookInput(input))
|
|
2926
3078
|
snapshotIfValid(draftPath);
|
|
2927
|
-
process.stdout.write(`${JSON.stringify(
|
|
3079
|
+
process.stdout.write(`${JSON.stringify(output2)}
|
|
2928
3080
|
`);
|
|
2929
3081
|
} catch (err) {
|
|
2930
3082
|
process.stderr.write(`code-review budget-hook: degrading to no-op \u2014 ${errMsg(err)}
|
|
@@ -3290,7 +3442,7 @@ var noticeCmd = defineCommand({
|
|
|
3290
3442
|
run: ({ args }) => {
|
|
3291
3443
|
if (!isNoticeKind(args.kind)) {
|
|
3292
3444
|
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
|
|
3445
|
+
`::warning::code-review notice: unrecognized kind "${annotationSafe(args.kind)}" \u2014 the pinned CLI is older than the workflow calling it; rendering a generic incomplete notice
|
|
3294
3446
|
`
|
|
3295
3447
|
);
|
|
3296
3448
|
process.stdout.write(`${JSON.stringify(buildUnknownNoticeEnvelope(args.kind), null, 2)}
|
|
@@ -3738,6 +3890,92 @@ var announceCmd = defineCommand({
|
|
|
3738
3890
|
);
|
|
3739
3891
|
}
|
|
3740
3892
|
});
|
|
3893
|
+
var isCheckIntent = (s) => s === "in_progress" || s === "neutral" || s === "failure";
|
|
3894
|
+
var checkRunCmd = defineCommand({
|
|
3895
|
+
meta: {
|
|
3896
|
+
name: "check-run",
|
|
3897
|
+
description: "Upsert the native 'Code review' check-run on the head SHA \u2014 the attribution surface that appears in the PR's own checks list and (writing to the base repo) works for fork PRs too. `in_progress` at review start, `neutral` when the review completes, `failure` when it didn't. Forward-only: `failure` never overwrites a completed review."
|
|
3898
|
+
},
|
|
3899
|
+
args: {
|
|
3900
|
+
repo: { type: "string", description: "Repository (owner/name)", required: true },
|
|
3901
|
+
"head-sha": {
|
|
3902
|
+
type: "string",
|
|
3903
|
+
description: "Head SHA the check-run is anchored to",
|
|
3904
|
+
required: true
|
|
3905
|
+
},
|
|
3906
|
+
status: {
|
|
3907
|
+
type: "positional",
|
|
3908
|
+
description: "One of: in_progress, neutral, failure",
|
|
3909
|
+
required: true
|
|
3910
|
+
},
|
|
3911
|
+
"run-url": {
|
|
3912
|
+
type: "string",
|
|
3913
|
+
description: "Workflow run URL the check-run's details link to",
|
|
3914
|
+
required: true
|
|
3915
|
+
}
|
|
3916
|
+
},
|
|
3917
|
+
run: async ({ args }) => {
|
|
3918
|
+
if (!isCheckIntent(args.status)) {
|
|
3919
|
+
process.stderr.write(
|
|
3920
|
+
`::warning::code-review check-run: unrecognized status "${annotationSafe(args.status)}" \u2014 expected in_progress, neutral, or failure; skipping
|
|
3921
|
+
`
|
|
3922
|
+
);
|
|
3923
|
+
return;
|
|
3924
|
+
}
|
|
3925
|
+
await checkRun({
|
|
3926
|
+
repo: args.repo,
|
|
3927
|
+
headSha: args["head-sha"],
|
|
3928
|
+
intent: args.status,
|
|
3929
|
+
runUrl: args["run-url"]
|
|
3930
|
+
}).catch(
|
|
3931
|
+
(err) => process.stderr.write(
|
|
3932
|
+
`::warning::code-review check-run: could not upsert the check-run (${annotationSafe(errMsg(err))}) \u2014 continuing (attribution aid)
|
|
3933
|
+
`
|
|
3934
|
+
)
|
|
3935
|
+
);
|
|
3936
|
+
}
|
|
3937
|
+
});
|
|
3938
|
+
var reportIncompleteCmd = defineCommand({
|
|
3939
|
+
meta: {
|
|
3940
|
+
name: "report-incomplete",
|
|
3941
|
+
description: "Post (or update) the sticky when a review job hard-failed and posted nothing \u2014 an attributed 'did not complete' notice linking the run, telling the reader to re-request. Never buries a completed review, and never overwrites a superseding run's live in-progress placeholder. (A cancelled review is left to the superseding run that took over.)"
|
|
3942
|
+
},
|
|
3943
|
+
args: {
|
|
3944
|
+
repo: { type: "string", description: "Repository (owner/name)", required: true },
|
|
3945
|
+
"head-sha": {
|
|
3946
|
+
type: "string",
|
|
3947
|
+
description: "Trusted head SHA to resolve the PR (from workflow_run.head_sha)",
|
|
3948
|
+
required: true
|
|
3949
|
+
},
|
|
3950
|
+
"run-url": {
|
|
3951
|
+
type: "string",
|
|
3952
|
+
description: "Workflow run URL the notice links to",
|
|
3953
|
+
required: true
|
|
3954
|
+
},
|
|
3955
|
+
"bot-login": {
|
|
3956
|
+
type: "string",
|
|
3957
|
+
description: "Bot login to trust for the sticky comment upsert (default: github-actions[bot])"
|
|
3958
|
+
},
|
|
3959
|
+
"head-branch": {
|
|
3960
|
+
type: "string",
|
|
3961
|
+
description: "Head branch to disambiguate the PR when multiple share a commit"
|
|
3962
|
+
}
|
|
3963
|
+
},
|
|
3964
|
+
run: async ({ args }) => {
|
|
3965
|
+
await reportIncomplete({
|
|
3966
|
+
repo: args.repo,
|
|
3967
|
+
headSha: args["head-sha"],
|
|
3968
|
+
botLogin: args["bot-login"] || "github-actions[bot]",
|
|
3969
|
+
runUrl: args["run-url"],
|
|
3970
|
+
headBranch: args["head-branch"]
|
|
3971
|
+
}).catch(
|
|
3972
|
+
(err) => process.stderr.write(
|
|
3973
|
+
`::warning::code-review report-incomplete: could not post the failure notice (${annotationSafe(errMsg(err))}) \u2014 continuing
|
|
3974
|
+
`
|
|
3975
|
+
)
|
|
3976
|
+
);
|
|
3977
|
+
}
|
|
3978
|
+
});
|
|
3741
3979
|
var requireCeilingSec = (raw) => {
|
|
3742
3980
|
if (raw === void 0) return null;
|
|
3743
3981
|
const ms = parseWallMs(raw);
|
|
@@ -3911,6 +4149,8 @@ var main = defineCommand({
|
|
|
3911
4149
|
inline: inlineCmd,
|
|
3912
4150
|
post: postCmd,
|
|
3913
4151
|
announce: announceCmd,
|
|
4152
|
+
"check-run": checkRunCmd,
|
|
4153
|
+
"report-incomplete": reportIncompleteCmd,
|
|
3914
4154
|
cost: costCmd,
|
|
3915
4155
|
"check-cost": checkCostCmd,
|
|
3916
4156
|
validate: validateCmd,
|