pr-shepherd 0.30.0 → 0.30.1
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/.claude-plugin/plugin.json +1 -1
- package/bin/commands/iterate/fix-code.mjs +8 -6
- package/bin/commands/iterate/helpers.mjs +2 -13
- package/bin/commands/iterate/reruns.mjs +44 -0
- package/bin/github/batch-parsers.mjs +4 -6
- package/bin/github/gql/batch-pr.gql +1 -0
- package/package.json +1 -1
- package/plugins/pr-shepherd/.codex-plugin/plugin.json +1 -1
|
@@ -7,7 +7,7 @@ import { checkEscalateTriggers, validateBaseBranch, buildEscalateSuggestion, bui
|
|
|
7
7
|
import { buildResolveCommand } from "./classify.mjs";
|
|
8
8
|
import { buildFixInstructions } from "./render.mjs";
|
|
9
9
|
import { applyStallGuard } from "./stall.mjs";
|
|
10
|
-
import { tryCancelRun, buildInProgressRunIds } from "./helpers.mjs";
|
|
10
|
+
import { tryCancelRun, buildAutoCancelRunIds, buildInProgressRunIds } from "./helpers.mjs";
|
|
11
11
|
import { annotationMarkerBody } from "../check-annotations.mjs";
|
|
12
12
|
import { threadTranscriptBody } from "../../threads/transcript.mjs";
|
|
13
13
|
import { isHumanAuthor, isConfiguredBotAuthor } from "../../comments/authors.mjs";
|
|
@@ -78,10 +78,8 @@ export async function handleFixCode(ctx) {
|
|
|
78
78
|
await writeFixAttempts({ owner: repoOwner, repo: repoName, pr: prNumber }, { headSha, threadAttempts, threadBodyHashes });
|
|
79
79
|
let cancelled = [];
|
|
80
80
|
if (!opts.noAutoCancelActionable) {
|
|
81
|
-
const
|
|
82
|
-
|
|
83
|
-
];
|
|
84
|
-
const results = await Promise.all(uniqueRunIds.map((id) => tryCancelRun(id, repoOwner, repoName)));
|
|
81
|
+
const runIds = buildAutoCancelRunIds(report);
|
|
82
|
+
const results = await Promise.all(runIds.map((id) => tryCancelRun(id, repoOwner, repoName)));
|
|
85
83
|
cancelled = results.filter((id) => id !== null);
|
|
86
84
|
}
|
|
87
85
|
const cancelledSet = new Set(cancelled);
|
|
@@ -100,7 +98,11 @@ export async function handleFixCode(ctx) {
|
|
|
100
98
|
hasConflicts ||
|
|
101
99
|
changesRequestedReviews.length > 0 ||
|
|
102
100
|
actionableComments.length > 0;
|
|
103
|
-
const inProgressRunIds = pushLikely
|
|
101
|
+
const inProgressRunIds = pushLikely
|
|
102
|
+
? buildInProgressRunIds(report, cancelledSet, {
|
|
103
|
+
suppressProtectedFreshReruns: false,
|
|
104
|
+
})
|
|
105
|
+
: [];
|
|
104
106
|
const commentMinimizeIds = report.comments.minimizeIds ?? actionableComments.map((c) => c.id);
|
|
105
107
|
const allCommentIds = [...commentMinimizeIds, ...reviewSummaryIds];
|
|
106
108
|
const { resolveCommand, resolveOnlyCommand } = buildResolveCommand(threads, resolutionOnlyThreads, allCommentIds, changesRequestedReviews, checks, prNumber, botUsernames, ruleAutoResolveThreadIds);
|
|
@@ -2,13 +2,7 @@ import { execFile as execFileCb } from "node:child_process";
|
|
|
2
2
|
import { promisify } from "node:util";
|
|
3
3
|
import { rest } from "../../github/http.mjs";
|
|
4
4
|
const execFile = promisify(execFileCb);
|
|
5
|
-
export
|
|
6
|
-
return [
|
|
7
|
-
...new Set(report.checks.inProgress
|
|
8
|
-
.map((c) => c.runId)
|
|
9
|
-
.filter((id) => id !== null && !cancelledSet.has(id))),
|
|
10
|
-
];
|
|
11
|
-
}
|
|
5
|
+
export { buildAutoCancelRunIds, buildInProgressRunIds } from "./reruns.mjs";
|
|
12
6
|
export function buildSummary(report) {
|
|
13
7
|
return {
|
|
14
8
|
passing: report.checks.passing.length,
|
|
@@ -17,12 +11,7 @@ export function buildSummary(report) {
|
|
|
17
11
|
inProgress: report.checks.inProgress.length,
|
|
18
12
|
};
|
|
19
13
|
}
|
|
20
|
-
/**
|
|
21
|
-
* Build the full list of CI checks relevant to PR readiness: triggered by a PR
|
|
22
|
-
* event (or StatusContext with null event), completed, and not skipped/neutral.
|
|
23
|
-
* Includes both passing and failing. Failing entries carry workflowName, jobName,
|
|
24
|
-
* failedStep, and summary.
|
|
25
|
-
*/
|
|
14
|
+
/** Build completed, non-skipped checks relevant to PR readiness. */
|
|
26
15
|
export function buildRelevantChecks(report) {
|
|
27
16
|
const excluded = new Set([null, "SKIPPED", "NEUTRAL"]);
|
|
28
17
|
const passing = report.checks.passing.flatMap((c) => {
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
function matchesRerunCheck(failure, check) {
|
|
2
|
+
if (failure.runId !== null && check.runId !== null) {
|
|
3
|
+
return failure.runId === check.runId && failure.name === check.name;
|
|
4
|
+
}
|
|
5
|
+
return failure.runId === null && check.runId === null && failure.name === check.name;
|
|
6
|
+
}
|
|
7
|
+
function isProtectedByFreshRerun(failure, check) {
|
|
8
|
+
const attemptStartedAt = check.startedAtUnix ?? check.updatedAtUnix ?? check.createdAtUnix;
|
|
9
|
+
return (attemptStartedAt !== undefined &&
|
|
10
|
+
matchesRerunCheck(failure, check) &&
|
|
11
|
+
failure.completedAtUnix !== undefined &&
|
|
12
|
+
attemptStartedAt >= failure.completedAtUnix &&
|
|
13
|
+
(failure.startedAtUnix === undefined || failure.startedAtUnix < attemptStartedAt));
|
|
14
|
+
}
|
|
15
|
+
function hasProtectedFreshRerun(failure, checks) {
|
|
16
|
+
return checks.some((check) => isProtectedByFreshRerun(failure, check));
|
|
17
|
+
}
|
|
18
|
+
function isProtectedFreshRerun(check, failures) {
|
|
19
|
+
const matchingFailures = failures.filter((failure) => matchesRerunCheck(failure, check));
|
|
20
|
+
return (matchingFailures.length > 0 &&
|
|
21
|
+
matchingFailures.every((failure) => isProtectedByFreshRerun(failure, check)));
|
|
22
|
+
}
|
|
23
|
+
function protectedFreshRerunIds(report) {
|
|
24
|
+
return new Set(report.checks.inProgress
|
|
25
|
+
.filter((check) => isProtectedFreshRerun(check, report.checks.failing))
|
|
26
|
+
.map((check) => check.runId)
|
|
27
|
+
.filter((id) => id !== null));
|
|
28
|
+
}
|
|
29
|
+
export function buildAutoCancelRunIds(report) {
|
|
30
|
+
return [
|
|
31
|
+
...new Set(report.checks.failing
|
|
32
|
+
.filter((check) => !hasProtectedFreshRerun(check, report.checks.inProgress))
|
|
33
|
+
.map((check) => check.runId)
|
|
34
|
+
.filter((id) => id !== null)),
|
|
35
|
+
];
|
|
36
|
+
}
|
|
37
|
+
export function buildInProgressRunIds(report, cancelledSet, opts = {}) {
|
|
38
|
+
const protectedRunIds = opts.suppressProtectedFreshReruns === false ? new Set() : protectedFreshRerunIds(report);
|
|
39
|
+
return [
|
|
40
|
+
...new Set(report.checks.inProgress
|
|
41
|
+
.map((check) => check.runId)
|
|
42
|
+
.filter((id) => id !== null && !cancelledSet.has(id) && !protectedRunIds.has(id))),
|
|
43
|
+
];
|
|
44
|
+
}
|
|
@@ -84,14 +84,11 @@ export function parseRawPr(raw, rawThreadPages, rawCommentNodes, rawReviewNodes,
|
|
|
84
84
|
const event = node.checkSuite?.workflowRun?.event ?? null;
|
|
85
85
|
const runId = extractRunId(node.detailsUrl);
|
|
86
86
|
const summary = extractCheckRunSummary(node.title, node.summary);
|
|
87
|
-
const rawCreatedAt = node.checkSuite
|
|
88
|
-
|
|
89
|
-
: undefined;
|
|
90
|
-
const rawUpdatedAt = node.checkSuite
|
|
91
|
-
? (node.checkSuite.workflowRun?.updatedAt ?? node.checkSuite.updatedAt)
|
|
92
|
-
: undefined;
|
|
87
|
+
const rawCreatedAt = node.checkSuite?.workflowRun?.createdAt ?? node.checkSuite?.createdAt;
|
|
88
|
+
const rawUpdatedAt = node.checkSuite?.workflowRun?.updatedAt ?? node.checkSuite?.updatedAt;
|
|
93
89
|
const createdAtUnix = rawCreatedAt ? parseCreatedAt(rawCreatedAt) : undefined;
|
|
94
90
|
const startedAtUnix = node.startedAt ? parseCreatedAt(node.startedAt) : undefined;
|
|
91
|
+
const completedAtUnix = node.completedAt ? parseCreatedAt(node.completedAt) : undefined;
|
|
95
92
|
const updatedAtUnix = rawUpdatedAt ? parseCreatedAt(rawUpdatedAt) : undefined;
|
|
96
93
|
return [
|
|
97
94
|
{
|
|
@@ -105,6 +102,7 @@ export function parseRawPr(raw, rawThreadPages, rawCommentNodes, rawReviewNodes,
|
|
|
105
102
|
runId,
|
|
106
103
|
...(createdAtUnix !== undefined && { createdAtUnix }),
|
|
107
104
|
...(startedAtUnix !== undefined && { startedAtUnix }),
|
|
105
|
+
...(completedAtUnix !== undefined && { completedAtUnix }),
|
|
108
106
|
...(updatedAtUnix !== undefined && { updatedAtUnix }),
|
|
109
107
|
...(summary !== undefined && { summary }),
|
|
110
108
|
},
|
package/package.json
CHANGED