@jphutchins/code-review 0.1.0-alpha.29 → 0.1.0-alpha.30
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 +72 -10
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -972,7 +972,7 @@ var pad2 = (n) => String(n).padStart(2, "0");
|
|
|
972
972
|
var formatUtc = (d) => `${String(d.getUTCFullYear())}-${pad2(d.getUTCMonth() + 1)}-${pad2(d.getUTCDate())} ${pad2(d.getUTCHours())}:${pad2(d.getUTCMinutes())} UTC`;
|
|
973
973
|
|
|
974
974
|
// src/notice.ts
|
|
975
|
-
var isNoticeKind = (s) => s === "security-blocked" || s === "setup-failed" || s === "
|
|
975
|
+
var isNoticeKind = (s) => s === "security-blocked" || s === "setup-failed" || s === "checkout-failed" || s === "no-output";
|
|
976
976
|
var blockquote = (text) => text.replaceAll("\n", "\n> ");
|
|
977
977
|
var noticeSummary = (kind, reasons) => {
|
|
978
978
|
switch (kind) {
|
|
@@ -984,8 +984,8 @@ The diff was flagged as unsafe to apply and execute:
|
|
|
984
984
|
> ${blockquote(reasons)}` : "### \u{1F6D1} Code review skipped by the security gate\n\nThe security triage returned an unsafe verdict without a reason. See workflow logs.";
|
|
985
985
|
case "setup-failed":
|
|
986
986
|
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
|
-
case "
|
|
988
|
-
return "### \u26A0\uFE0F Could not
|
|
987
|
+
case "checkout-failed":
|
|
988
|
+
return "### \u26A0\uFE0F Could not check out the PR head\n\nThe PR head commit could not be fetched or checked out (it may have been force-pushed away, or is otherwise unavailable), so the review was skipped rather than run against the wrong tree. See workflow logs.";
|
|
989
989
|
case "no-output":
|
|
990
990
|
return "### \u26A0\uFE0F Review did not complete\n\nThe diff passed triage but the review produced no output. See workflow logs.";
|
|
991
991
|
}
|
|
@@ -1953,6 +1953,7 @@ var renderOutputs = (result) => {
|
|
|
1953
1953
|
return `pr=${String(result.pr)}
|
|
1954
1954
|
conclusion=${result.conclusion}
|
|
1955
1955
|
diff_size=${String(result.diffSize)}
|
|
1956
|
+
stacked=${String(result.stacked)}
|
|
1956
1957
|
`;
|
|
1957
1958
|
}
|
|
1958
1959
|
};
|
|
@@ -1975,6 +1976,7 @@ var runGit = (args) => new Promise((resolve3, reject) => {
|
|
|
1975
1976
|
var PrMetaCodec = t.type({
|
|
1976
1977
|
changed_files: t.number,
|
|
1977
1978
|
base_sha: t.string,
|
|
1979
|
+
base_ref: t.string,
|
|
1978
1980
|
title: t.string,
|
|
1979
1981
|
body: t.union([t.string, t.null])
|
|
1980
1982
|
});
|
|
@@ -1995,7 +1997,7 @@ var fetchPrMeta = async (repo, prNumber, ghApi) => {
|
|
|
1995
1997
|
const stdout = await ghApi([
|
|
1996
1998
|
`repos/${repo}/pulls/${String(prNumber)}`,
|
|
1997
1999
|
"--jq",
|
|
1998
|
-
"{changed_files: .changed_files, base_sha: .base.sha, title: .title, body: .body}"
|
|
2000
|
+
"{changed_files: .changed_files, base_sha: .base.sha, base_ref: .base.ref, title: .title, body: .body}"
|
|
1999
2001
|
]);
|
|
2000
2002
|
const decoded = PrMetaCodec.decode(JSON.parse(stdout));
|
|
2001
2003
|
if (decoded._tag === "Left") {
|
|
@@ -2010,6 +2012,53 @@ var fetchApiDiff = async (repo, prNumber, ghApi) => {
|
|
|
2010
2012
|
return null;
|
|
2011
2013
|
}
|
|
2012
2014
|
};
|
|
2015
|
+
var fetchFullDiff = async (repo, defaultBranch, headSha, ghApi, gitRun) => {
|
|
2016
|
+
try {
|
|
2017
|
+
const diff = await ghApi([
|
|
2018
|
+
`repos/${repo}/compare/${defaultBranch}...${headSha}`,
|
|
2019
|
+
"-H",
|
|
2020
|
+
"Accept: application/vnd.github.v3.diff"
|
|
2021
|
+
]);
|
|
2022
|
+
if (diff.length > 0) return diff;
|
|
2023
|
+
process.stderr.write(
|
|
2024
|
+
`compare diff for ${defaultBranch}...${headSha} was empty \u2014 falling back to git diff
|
|
2025
|
+
`
|
|
2026
|
+
);
|
|
2027
|
+
} catch (err) {
|
|
2028
|
+
process.stderr.write(`compare diff fetch failed (${errMsg(err)}) \u2014 falling back to git diff
|
|
2029
|
+
`);
|
|
2030
|
+
}
|
|
2031
|
+
await gitRun(["fetch", "origin", headSha]);
|
|
2032
|
+
const base = (await gitRun(["rev-parse", "HEAD"])).trim();
|
|
2033
|
+
return gitRun(["diff", `${base}...${headSha}`]);
|
|
2034
|
+
};
|
|
2035
|
+
var CommitCodec = t.type({
|
|
2036
|
+
sha: t.string,
|
|
2037
|
+
message: t.string,
|
|
2038
|
+
author: t.union([t.string, t.null]),
|
|
2039
|
+
email: t.union([t.string, t.null])
|
|
2040
|
+
});
|
|
2041
|
+
var COMMIT_JQ = ".commits[] | {sha: .sha, message: .commit.message, author: .commit.author.name, email: .commit.author.email}";
|
|
2042
|
+
var fetchCompareCommits = async (repo, defaultBranch, headSha, ghApi) => {
|
|
2043
|
+
const rows = parseJsonl(
|
|
2044
|
+
await ghApi([
|
|
2045
|
+
`repos/${repo}/compare/${defaultBranch}...${headSha}`,
|
|
2046
|
+
"--paginate",
|
|
2047
|
+
"--jq",
|
|
2048
|
+
COMMIT_JQ
|
|
2049
|
+
])
|
|
2050
|
+
);
|
|
2051
|
+
const decoded = rows.map((row) => CommitCodec.decode(row));
|
|
2052
|
+
const commits = decoded.flatMap((d) => d._tag === "Right" ? [d.right] : []);
|
|
2053
|
+
const dropped = decoded.length - commits.length;
|
|
2054
|
+
if (dropped > 0) {
|
|
2055
|
+
process.stderr.write(
|
|
2056
|
+
`Warning: ${String(dropped)} of ${String(rows.length)} commit row(s) failed to decode \u2014 their messages are NOT in the triage scan though a checkout's git log still exposes them
|
|
2057
|
+
`
|
|
2058
|
+
);
|
|
2059
|
+
}
|
|
2060
|
+
return commits;
|
|
2061
|
+
};
|
|
2013
2062
|
var COMMENT_JQ = ".[] | {id: .id, body: .body, user: {login: .user.login}, created_at: .created_at, author_association: .author_association}";
|
|
2014
2063
|
var REVIEW_COMMENT_JQ = ".[] | {body: .body, user: {login: .user.login}, created_at: .created_at, author_association: .author_association, path: .path, line: .line}";
|
|
2015
2064
|
var REVIEW_JQ = ".[] | {body: .body, user: {login: .user.login}, submitted_at: .submitted_at, author_association: .author_association, state: .state}";
|
|
@@ -2131,8 +2180,10 @@ var gather = async (input, ghApi = runGhApi, gitRun = runGit) => {
|
|
|
2131
2180
|
}
|
|
2132
2181
|
const prNumber = resolution.prNumber;
|
|
2133
2182
|
const meta = await fetchPrMeta(input.repo, prNumber, ghApi);
|
|
2134
|
-
const
|
|
2135
|
-
const
|
|
2183
|
+
const stacked = meta.base_ref !== input.defaultBranch;
|
|
2184
|
+
const prDiff = await (async () => {
|
|
2185
|
+
const apiDiff = await fetchApiDiff(input.repo, prNumber, ghApi);
|
|
2186
|
+
if (apiDiff !== null && !(apiDiff.length === 0 && meta.changed_files > 0)) return apiDiff;
|
|
2136
2187
|
process.stderr.write(
|
|
2137
2188
|
`PR diff fetch failed or was empty for ${String(meta.changed_files)} changed files \u2014 falling back to git diff
|
|
2138
2189
|
`
|
|
@@ -2140,7 +2191,11 @@ var gather = async (input, ghApi = runGhApi, gitRun = runGit) => {
|
|
|
2140
2191
|
await gitRun(["fetch", "origin", input.headSha]);
|
|
2141
2192
|
return gitRun(["diff", meta.base_sha, input.headSha]);
|
|
2142
2193
|
})();
|
|
2143
|
-
|
|
2194
|
+
const fullDiff = stacked ? await fetchFullDiff(input.repo, input.defaultBranch, input.headSha, ghApi, gitRun) : prDiff;
|
|
2195
|
+
const commits = await fetchCompareCommits(input.repo, input.defaultBranch, input.headSha, ghApi);
|
|
2196
|
+
writeFileSync(join(input.outDir, "full.diff"), fullDiff);
|
|
2197
|
+
writeFileSync(join(input.outDir, "pr.diff"), prDiff);
|
|
2198
|
+
writeFileSync(join(input.outDir, "commits.json"), JSON.stringify(commits));
|
|
2144
2199
|
writeFileSync(
|
|
2145
2200
|
join(input.outDir, "pr_context.json"),
|
|
2146
2201
|
JSON.stringify({ title: meta.title, body: meta.body })
|
|
@@ -2177,7 +2232,8 @@ var gather = async (input, ghApi = runGhApi, gitRun = runGit) => {
|
|
|
2177
2232
|
kind: "gathered",
|
|
2178
2233
|
pr: prNumber,
|
|
2179
2234
|
conclusion: input.conclusion,
|
|
2180
|
-
diffSize: Buffer.byteLength(
|
|
2235
|
+
diffSize: Buffer.byteLength(prDiff, "utf8"),
|
|
2236
|
+
stacked
|
|
2181
2237
|
};
|
|
2182
2238
|
};
|
|
2183
2239
|
|
|
@@ -3189,7 +3245,7 @@ var noticeCmd = defineCommand({
|
|
|
3189
3245
|
args: {
|
|
3190
3246
|
kind: {
|
|
3191
3247
|
type: "positional",
|
|
3192
|
-
description: "One of: security-blocked, setup-failed,
|
|
3248
|
+
description: "One of: security-blocked, setup-failed, checkout-failed, no-output",
|
|
3193
3249
|
required: true
|
|
3194
3250
|
},
|
|
3195
3251
|
reasons: {
|
|
@@ -3199,7 +3255,7 @@ var noticeCmd = defineCommand({
|
|
|
3199
3255
|
},
|
|
3200
3256
|
run: ({ args }) => {
|
|
3201
3257
|
const kind = isNoticeKind(args.kind) ? args.kind : fail(
|
|
3202
|
-
`Unknown notice kind "${args.kind}" \u2014 expected one of: security-blocked, setup-failed,
|
|
3258
|
+
`Unknown notice kind "${args.kind}" \u2014 expected one of: security-blocked, setup-failed, checkout-failed, no-output`
|
|
3203
3259
|
);
|
|
3204
3260
|
process.stdout.write(`${JSON.stringify(buildNoticeEnvelope(kind, args.reasons), null, 2)}
|
|
3205
3261
|
`);
|
|
@@ -3464,6 +3520,11 @@ var gatherCmd = defineCommand({
|
|
|
3464
3520
|
type: "string",
|
|
3465
3521
|
description: "Head branch to disambiguate the PR when multiple share a commit"
|
|
3466
3522
|
},
|
|
3523
|
+
"default-branch": {
|
|
3524
|
+
type: "string",
|
|
3525
|
+
description: "The repo's default branch \u2014 the trusted base the review checks out, and the reference for the full (triage) diff; a PR based on any other branch is treated as stacked",
|
|
3526
|
+
required: true
|
|
3527
|
+
},
|
|
3467
3528
|
"run-id": {
|
|
3468
3529
|
type: "string",
|
|
3469
3530
|
description: "CI run id (from workflow_run.id); its failing jobs' logs are downloaded on failure",
|
|
@@ -3488,6 +3549,7 @@ var gatherCmd = defineCommand({
|
|
|
3488
3549
|
repo: args.repo,
|
|
3489
3550
|
headSha: args["head-sha"],
|
|
3490
3551
|
headBranch: args["head-branch"],
|
|
3552
|
+
defaultBranch: args["default-branch"],
|
|
3491
3553
|
runId: args["run-id"],
|
|
3492
3554
|
conclusion: args.conclusion,
|
|
3493
3555
|
botLogin: args["bot-login"] || "github-actions[bot]",
|