pr-shepherd 0.34.0 → 0.36.0
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 +3 -2
- package/.grok-plugin/marketplace.json +17 -0
- package/README.md +80 -43
- package/bin/api.d.mts +80 -0
- package/bin/api.mjs +236 -0
- package/bin/checks/classify.d.mts +41 -0
- package/bin/checks/startup-failures.d.mts +2 -0
- package/bin/checks/superseded.d.mts +21 -0
- package/bin/checks/triage.d.mts +4 -0
- package/bin/checks/triage.mjs +11 -3
- package/bin/classify/apply.d.mts +18 -0
- package/bin/classify/apply.mjs +4 -0
- package/bin/classify/loader.d.mts +10 -0
- package/bin/classify/types.d.mts +35 -0
- package/bin/cli/args.d.mts +18 -0
- package/bin/cli/args.mjs +1 -0
- package/bin/cli/clean-formatter.d.mts +2 -0
- package/bin/cli/default-poll.d.mts +2 -0
- package/bin/cli/default-poll.mjs +1 -0
- package/bin/cli/duration-flag.d.mts +2 -0
- package/bin/cli/duration.d.mts +13 -0
- package/bin/cli/fence.d.mts +1 -0
- package/bin/cli/fix-formatter-extra.d.mts +3 -0
- package/bin/cli/fix-formatter.d.mts +2 -0
- package/bin/cli/fix-formatter.mjs +6 -6
- package/bin/cli/formatters.d.mts +7 -0
- package/bin/cli/handlers.d.mts +4 -0
- package/bin/cli/handlers.mjs +11 -10
- package/bin/cli/help-command-pages.d.mts +231 -0
- package/bin/cli/help-command-pages.mjs +106 -1
- package/bin/cli/help-iterate-poll-pages.d.mts +4 -0
- package/bin/cli/help-iterate-poll-pages.mjs +14 -7
- package/bin/cli/help-log-file-page.d.mts +1 -0
- package/bin/cli/help-top-page.d.mts +1 -0
- package/bin/cli/help-top-page.mjs +16 -16
- package/bin/cli/help.d.mts +236 -0
- package/bin/cli/help.mjs +17 -0
- package/bin/cli/iterate-emitter.d.mts +8 -0
- package/bin/cli/iterate-flags.d.mts +11 -0
- package/bin/cli/iterate-formatter.d.mts +19 -0
- package/bin/cli/iterate-formatter.mjs +11 -2
- package/bin/cli/iterate-instructions.d.mts +6 -0
- package/bin/cli/iterate-lean.d.mts +12 -0
- package/bin/cli/iterate-lean.mjs +1 -0
- package/bin/cli/journal-formatter.d.mts +2 -0
- package/bin/cli/journal-formatter.mjs +15 -0
- package/bin/cli/journal-handler.d.mts +1 -0
- package/bin/cli/journal-handler.mjs +7 -20
- package/bin/cli/list-formatters.d.mts +76 -0
- package/bin/cli/list-formatters.mjs +9 -9
- package/bin/cli/mark-files-as-viewed-flags.d.mts +11 -0
- package/bin/cli/mark-files-as-viewed-formatter.d.mts +2 -0
- package/bin/cli/mutate-formatter.d.mts +2 -0
- package/bin/cli/poll-handler.d.mts +1 -0
- package/bin/cli/poll-handler.mjs +9 -2
- package/bin/cli/resolve-validators.d.mts +3 -0
- package/bin/cli/resolve-validators.mjs +3 -3
- package/bin/cli/runner.d.mts +7 -0
- package/bin/cli/suggestion-renderer.d.mts +3 -0
- package/bin/cli/validate-default-args.d.mts +6 -0
- package/bin/cli-parser.d.mts +2 -0
- package/bin/cli-parser.mjs +72 -16
- package/bin/commands/check-annotations.d.mts +5 -0
- package/bin/commands/check-status.d.mts +3 -0
- package/bin/commands/check-terminal-report.d.mts +5 -0
- package/bin/commands/check.d.mts +7 -0
- package/bin/commands/check.mjs +28 -23
- package/bin/commands/clean.d.mts +21 -0
- package/bin/commands/commit-suggestion-instruction.d.mts +8 -0
- package/bin/commands/commit-suggestion-instruction.mjs +3 -3
- package/bin/commands/commit-suggestion.d.mts +8 -0
- package/bin/commands/commit-suggestion.mjs +20 -13
- package/bin/commands/iterate/check-instructions.d.mts +16 -0
- package/bin/commands/iterate/check-instructions.mjs +3 -3
- package/bin/commands/iterate/classify.d.mts +18 -0
- package/bin/commands/iterate/classify.mjs +4 -4
- package/bin/commands/iterate/escalate.d.mts +31 -0
- package/bin/commands/iterate/escalate.mjs +7 -4
- package/bin/commands/iterate/fix-code.d.mts +25 -0
- package/bin/commands/iterate/fix-code.mjs +1 -1
- package/bin/commands/iterate/helpers.d.mts +14 -0
- package/bin/commands/iterate/helpers.mjs +19 -7
- package/bin/commands/iterate/index.d.mts +2 -0
- package/bin/commands/iterate/index.mjs +8 -12
- package/bin/commands/iterate/render.d.mts +5 -0
- package/bin/commands/iterate/render.mjs +8 -6
- package/bin/commands/iterate/reruns.d.mts +20 -0
- package/bin/commands/iterate/stall.d.mts +6 -0
- package/bin/commands/journal/index.d.mts +14 -0
- package/bin/commands/journal/index.mjs +1 -0
- package/bin/commands/journal/transform.d.mts +22 -0
- package/bin/commands/log-file.d.mts +5 -0
- package/bin/commands/mark-files-as-viewed.d.mts +26 -0
- package/bin/commands/mark-files-as-viewed.mjs +1 -0
- package/bin/commands/poll.d.mts +12 -0
- package/bin/commands/poll.mjs +52 -17
- package/bin/commands/ready-delay.d.mts +29 -0
- package/bin/commands/ready-delay.mjs +3 -13
- package/bin/commands/ready-mergeability.d.mts +15 -0
- package/bin/commands/resolve-mutate.d.mts +4 -0
- package/bin/commands/resolve-mutate.mjs +1 -0
- package/bin/commands/resolve.d.mts +4 -0
- package/bin/commands/shepherd-journal.d.mts +7 -0
- package/bin/commands/shepherd-journal.mjs +2 -2
- package/bin/comments/authors.d.mts +14 -0
- package/bin/comments/marker.d.mts +2 -0
- package/bin/comments/minimize-policy.d.mts +4 -0
- package/bin/comments/pending-ops.d.mts +15 -0
- package/bin/comments/rate-limit.d.mts +18 -0
- package/bin/comments/resolve.d.mts +34 -0
- package/bin/comments/resolve.mjs +1 -0
- package/bin/comments/review-thread-markers.d.mts +8 -0
- package/bin/comments/review-visibility.d.mts +28 -0
- package/bin/comments/sha-poll.d.mts +2 -0
- package/bin/comments/thread-visibility.d.mts +11 -0
- package/bin/comments/visible-comments.d.mts +11 -0
- package/bin/config/load.d.mts +60 -0
- package/bin/config/load.mjs +129 -16
- package/bin/config.json +0 -2
- package/bin/execution-context.d.mts +9 -0
- package/bin/execution-context.mjs +19 -0
- package/bin/exit-codes.d.mts +51 -0
- package/bin/github/activity.d.mts +3 -0
- package/bin/github/activity.mjs +7 -0
- package/bin/github/batch-page-helpers.d.mts +45 -0
- package/bin/github/batch-page-helpers.mjs +63 -0
- package/bin/github/batch-page.d.mts +14 -0
- package/bin/github/batch-page.mjs +62 -0
- package/bin/github/batch-parse-suites.d.mts +4 -0
- package/bin/github/batch-parse-suites.mjs +25 -0
- package/bin/github/batch-parser-helpers.d.mts +22 -0
- package/bin/github/batch-parsers-rules.d.mts +6 -0
- package/bin/github/batch-parsers-rules.mjs +122 -0
- package/bin/github/batch-parsers.d.mts +3 -0
- package/bin/github/batch-parsers.mjs +12 -0
- package/bin/github/batch-raw-rules.d.mts +59 -0
- package/bin/github/batch-raw-rules.mjs +1 -0
- package/bin/github/batch-raw-types.d.mts +216 -0
- package/bin/github/batch-response.d.mts +4 -0
- package/bin/github/batch.d.mts +24 -0
- package/bin/github/batch.mjs +14 -120
- package/bin/github/branch-protection.d.mts +3 -0
- package/bin/github/check-annotations.d.mts +2 -0
- package/bin/github/client.d.mts +46 -0
- package/bin/github/client.mjs +7 -2
- package/bin/github/errors.d.mts +25 -0
- package/bin/github/gql/batch-pr-page.gql +189 -0
- package/bin/github/gql/batch-pr.gql +79 -21
- package/bin/github/gql/commit-suggestion-thread.gql +40 -0
- package/bin/github/gql/review-thread-comments.gql +1 -0
- package/bin/github/graphql-http.d.mts +19 -0
- package/bin/github/graphql-response.d.mts +7 -0
- package/bin/github/http-auth.d.mts +4 -0
- package/bin/github/http-request.d.mts +7 -0
- package/bin/github/http-utils.d.mts +11 -0
- package/bin/github/http.d.mts +6 -0
- package/bin/github/http.mjs +2 -1
- package/bin/github/pagination.d.mts +46 -0
- package/bin/github/pagination.mjs +3 -2
- package/bin/github/queries.d.mts +28 -0
- package/bin/github/queries.mjs +4 -0
- package/bin/github/rest-http.d.mts +7 -0
- package/bin/github/rest-http.mjs +25 -86
- package/bin/github/rest-text.d.mts +1 -0
- package/bin/github/rest-text.mjs +88 -0
- package/bin/github/suggestion-thread.d.mts +9 -0
- package/bin/github/suggestion-thread.mjs +45 -0
- package/bin/github/thread-comments.d.mts +2 -0
- package/bin/github/thread-comments.mjs +12 -8
- package/bin/index.d.mts +10 -0
- package/bin/index.mjs +1 -1
- package/bin/log/log-file.d.mts +28 -0
- package/bin/log/session.d.mts +31 -0
- package/bin/log/setup.d.mts +6 -0
- package/bin/mcp/index.d.mts +5 -0
- package/bin/mcp/index.mjs +8 -0
- package/bin/mcp/server.d.mts +8 -0
- package/bin/mcp/server.mjs +157 -0
- package/bin/mcp-stdio.d.mts +2 -0
- package/bin/mcp-stdio.mjs +7 -0
- package/bin/merge-status/derive.d.mts +19 -0
- package/bin/merge-status/derive.mjs +2 -0
- package/bin/merge-status/requirements-format.d.mts +3 -0
- package/bin/merge-status/requirements-format.mjs +88 -0
- package/bin/merge-status/requirements.d.mts +2 -0
- package/bin/merge-status/requirements.mjs +51 -0
- package/bin/reporters/agent.d.mts +23 -0
- package/bin/reporters/agent.mjs +3 -0
- package/bin/state/base.d.mts +10 -0
- package/bin/state/base.mjs +23 -0
- package/bin/state/bot-cr-seen.d.mts +51 -0
- package/bin/state/bot-cr-seen.mjs +4 -14
- package/bin/state/fix-attempts.d.mts +27 -0
- package/bin/state/fix-attempts.mjs +3 -13
- package/bin/state/iterate-stall.d.mts +27 -0
- package/bin/state/iterate-stall.mjs +3 -13
- package/bin/state/seen-comments.d.mts +62 -0
- package/bin/state/seen-comments.mjs +6 -13
- package/bin/suggestions/extract.d.mts +8 -0
- package/bin/suggestions/parse.d.mts +48 -0
- package/bin/suggestions/patch.d.mts +14 -0
- package/bin/threads/transcript.d.mts +14 -0
- package/bin/threads/transcript.mjs +4 -0
- package/bin/types/activity.d.mts +30 -0
- package/bin/types/agent-thread.d.mts +9 -0
- package/bin/types/check-annotations.d.mts +14 -0
- package/bin/types/check-classification.d.mts +19 -0
- package/bin/types/github.d.mts +136 -0
- package/bin/types/iterate.d.mts +156 -0
- package/bin/types/merge-requirements.d.mts +82 -0
- package/bin/types/merge-requirements.mjs +2 -0
- package/bin/types/protected-run.d.mts +6 -0
- package/bin/types/report.d.mts +176 -0
- package/bin/types/review-thread.d.mts +12 -0
- package/bin/types.d.mts +10 -0
- package/bin/types.mjs +1 -0
- package/bin/util/markdown.d.mts +1 -0
- package/bin/util/path-segment.d.mts +4 -0
- package/bin/util/path-segment.mjs +2 -0
- package/bin/util/pool.d.mts +2 -0
- package/bin/util/pool.mjs +18 -0
- package/bin/util/sleep.d.mts +1 -0
- package/bin/util/worktree.d.mts +9 -0
- package/bin/util/worktree.mjs +4 -1
- package/package.json +51 -37
- package/plugins/pr-shepherd/.codex-plugin/plugin.json +3 -2
- package/plugins/pr-shepherd/.codex.mcp.json +8 -0
- package/plugins/pr-shepherd/.mcp.json +6 -0
- package/plugins/pr-shepherd/skills/mark-files-as-viewed/SKILL.md +5 -19
- package/plugins/pr-shepherd/skills/pr-shepherd/SKILL.md +6 -15
- package/src/classify/types.mts +12 -0
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
export const EMPTY_BRANCH_RULES = {
|
|
2
|
+
requiredApprovingReviewCount: 0,
|
|
3
|
+
requiresConversationResolution: false,
|
|
4
|
+
requiresCodeOwnerReviews: false,
|
|
5
|
+
requiresLastPushApproval: false,
|
|
6
|
+
requiresCommitSignatures: false,
|
|
7
|
+
requiresLinearHistory: false,
|
|
8
|
+
requiresStrictStatusChecks: false,
|
|
9
|
+
requiredStatusCheckContexts: [],
|
|
10
|
+
requiredDeploymentEnvironments: [],
|
|
11
|
+
requiresMergeQueue: false,
|
|
12
|
+
requiresWorkflows: false,
|
|
13
|
+
requiresCodeScanning: false,
|
|
14
|
+
};
|
|
15
|
+
export function parseBranchRules(baseRef) {
|
|
16
|
+
const rules = {
|
|
17
|
+
...EMPTY_BRANCH_RULES,
|
|
18
|
+
requiredStatusCheckContexts: [],
|
|
19
|
+
requiredDeploymentEnvironments: [],
|
|
20
|
+
};
|
|
21
|
+
if (!baseRef)
|
|
22
|
+
return rules;
|
|
23
|
+
foldClassicProtection(rules, baseRef.branchProtectionRule);
|
|
24
|
+
for (const node of baseRef.rules?.nodes ?? [])
|
|
25
|
+
foldRulesetRule(rules, node);
|
|
26
|
+
return rules;
|
|
27
|
+
}
|
|
28
|
+
export function parseMergeQueueEntry(raw) {
|
|
29
|
+
if (!raw)
|
|
30
|
+
return null;
|
|
31
|
+
return {
|
|
32
|
+
position: raw.position,
|
|
33
|
+
state: raw.state,
|
|
34
|
+
estimatedTimeToMerge: raw.estimatedTimeToMerge,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
export function parseStack(raw) {
|
|
38
|
+
if (!raw.stack)
|
|
39
|
+
return null;
|
|
40
|
+
return {
|
|
41
|
+
number: raw.stack.number,
|
|
42
|
+
size: raw.stack.size,
|
|
43
|
+
position: raw.stackEntry?.position ?? 0,
|
|
44
|
+
baseRefName: raw.stack.baseRefName,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
function foldClassicProtection(rules, bp) {
|
|
48
|
+
if (!bp)
|
|
49
|
+
return;
|
|
50
|
+
if (bp.requiresApprovingReviews) {
|
|
51
|
+
rules.requiredApprovingReviewCount = Math.max(rules.requiredApprovingReviewCount, bp.requiredApprovingReviewCount ?? 0);
|
|
52
|
+
}
|
|
53
|
+
if (bp.requiresConversationResolution)
|
|
54
|
+
rules.requiresConversationResolution = true;
|
|
55
|
+
if (bp.requiresCodeOwnerReviews)
|
|
56
|
+
rules.requiresCodeOwnerReviews = true;
|
|
57
|
+
if (bp.requireLastPushApproval)
|
|
58
|
+
rules.requiresLastPushApproval = true;
|
|
59
|
+
if (bp.requiresCommitSignatures)
|
|
60
|
+
rules.requiresCommitSignatures = true;
|
|
61
|
+
if (bp.requiresLinearHistory)
|
|
62
|
+
rules.requiresLinearHistory = true;
|
|
63
|
+
if (bp.requiresStrictStatusChecks)
|
|
64
|
+
rules.requiresStrictStatusChecks = true;
|
|
65
|
+
if (bp.requiresStatusChecks) {
|
|
66
|
+
mergeUnique(rules.requiredStatusCheckContexts, bp.requiredStatusCheckContexts ?? []);
|
|
67
|
+
}
|
|
68
|
+
if (bp.requiresDeployments) {
|
|
69
|
+
mergeUnique(rules.requiredDeploymentEnvironments, bp.requiredDeploymentEnvironments ?? []);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
function foldRulesetRule(rules, node) {
|
|
73
|
+
const p = node.parameters;
|
|
74
|
+
switch (node.type) {
|
|
75
|
+
case "PULL_REQUEST":
|
|
76
|
+
if (p?.requiredApprovingReviewCount != null) {
|
|
77
|
+
rules.requiredApprovingReviewCount = Math.max(rules.requiredApprovingReviewCount, p.requiredApprovingReviewCount);
|
|
78
|
+
}
|
|
79
|
+
if (p?.requiredReviewThreadResolution)
|
|
80
|
+
rules.requiresConversationResolution = true;
|
|
81
|
+
if (p?.requireCodeOwnerReview)
|
|
82
|
+
rules.requiresCodeOwnerReviews = true;
|
|
83
|
+
if (p?.requireLastPushApproval)
|
|
84
|
+
rules.requiresLastPushApproval = true;
|
|
85
|
+
break;
|
|
86
|
+
case "REQUIRED_REVIEW_THREAD_RESOLUTION":
|
|
87
|
+
rules.requiresConversationResolution = true;
|
|
88
|
+
break;
|
|
89
|
+
case "REQUIRED_STATUS_CHECKS":
|
|
90
|
+
if (p?.strictRequiredStatusChecksPolicy)
|
|
91
|
+
rules.requiresStrictStatusChecks = true;
|
|
92
|
+
mergeUnique(rules.requiredStatusCheckContexts, (p?.requiredStatusChecks ?? []).map((c) => c.context));
|
|
93
|
+
break;
|
|
94
|
+
case "REQUIRED_SIGNATURES":
|
|
95
|
+
rules.requiresCommitSignatures = true;
|
|
96
|
+
break;
|
|
97
|
+
case "REQUIRED_LINEAR_HISTORY":
|
|
98
|
+
rules.requiresLinearHistory = true;
|
|
99
|
+
break;
|
|
100
|
+
case "REQUIRED_DEPLOYMENTS":
|
|
101
|
+
mergeUnique(rules.requiredDeploymentEnvironments, p?.requiredDeploymentEnvironments ?? []);
|
|
102
|
+
break;
|
|
103
|
+
case "MERGE_QUEUE":
|
|
104
|
+
rules.requiresMergeQueue = true;
|
|
105
|
+
break;
|
|
106
|
+
case "WORKFLOWS":
|
|
107
|
+
case "REQUIRED_WORKFLOW_STATUS_CHECKS":
|
|
108
|
+
rules.requiresWorkflows = true;
|
|
109
|
+
break;
|
|
110
|
+
case "CODE_SCANNING":
|
|
111
|
+
rules.requiresCodeScanning = true;
|
|
112
|
+
break;
|
|
113
|
+
default:
|
|
114
|
+
break;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
function mergeUnique(target, values) {
|
|
118
|
+
for (const value of values) {
|
|
119
|
+
if (value && !target.includes(value))
|
|
120
|
+
target.push(value);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { BatchPrData } from "../types.mts";
|
|
2
|
+
import type { RawPr, RawThread, RawComment, RawReview, RawReviewSummary, RawContextNode } from "./batch-raw-types.mts";
|
|
3
|
+
export declare function parseRawPr(raw: RawPr, rawThreadPages: RawThread[], rawCommentNodes: RawComment[], rawReviewNodes: RawReview[], rawReviewSummaryNodes: RawReviewSummary[], rawApprovedReviewNodes: RawReviewSummary[], rawCheckNodes: RawContextNode[]): BatchPrData;
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { mapAuthorType, parseCreatedAt, mapStatusContextState, latestApprovedLogins, isReviewStale, mapCheckRunNode, } from "./batch-parser-helpers.mjs";
|
|
2
2
|
import { buildPrActivitySummary } from "./activity.mjs";
|
|
3
3
|
import { parseBranchProtection } from "./branch-protection.mjs";
|
|
4
|
+
import { parseBranchRules, parseMergeQueueEntry, parseStack } from "./batch-parsers-rules.mjs";
|
|
4
5
|
function parseReviewNode(r) {
|
|
5
6
|
const base = {
|
|
6
7
|
id: r.id,
|
|
7
8
|
author: r.author?.login ?? "unknown",
|
|
8
9
|
authorType: mapAuthorType(r.author?.__typename, r.author?.login),
|
|
10
|
+
...(r.authorAssociation !== undefined && { authorAssociation: r.authorAssociation }),
|
|
9
11
|
body: r.body,
|
|
10
12
|
createdAtUnix: r.createdAt ? parseCreatedAt(r.createdAt) : 0,
|
|
11
13
|
};
|
|
@@ -32,6 +34,7 @@ export function parseRawPr(raw, rawThreadPages, rawCommentNodes, rawReviewNodes,
|
|
|
32
34
|
...(c.pullRequestReview?.id ? { reviewId: c.pullRequestReview.id } : undefined),
|
|
33
35
|
author: c.author?.login ?? "unknown",
|
|
34
36
|
authorType: mapAuthorType(c.author?.__typename, c.author?.login),
|
|
37
|
+
...(c.authorAssociation !== undefined && { authorAssociation: c.authorAssociation }),
|
|
35
38
|
body: c.body,
|
|
36
39
|
url: c.url,
|
|
37
40
|
createdAtUnix: c.createdAt ? parseCreatedAt(c.createdAt) : 0,
|
|
@@ -47,6 +50,9 @@ export function parseRawPr(raw, rawThreadPages, rawCommentNodes, rawReviewNodes,
|
|
|
47
50
|
...(comment?.pullRequestReview?.id ? { reviewId: comment.pullRequestReview.id } : undefined),
|
|
48
51
|
author: comment?.author?.login ?? "unknown",
|
|
49
52
|
authorType: mapAuthorType(comment?.author?.__typename, comment?.author?.login),
|
|
53
|
+
...(comment?.authorAssociation !== undefined && {
|
|
54
|
+
authorAssociation: comment.authorAssociation,
|
|
55
|
+
}),
|
|
50
56
|
body: comment?.body ?? "",
|
|
51
57
|
url: comment?.url ?? "",
|
|
52
58
|
createdAtUnix: comment?.createdAt ? parseCreatedAt(comment.createdAt) : 0,
|
|
@@ -58,6 +64,7 @@ export function parseRawPr(raw, rawThreadPages, rawCommentNodes, rawReviewNodes,
|
|
|
58
64
|
isMinimized: c.isMinimized,
|
|
59
65
|
author: c.author?.login ?? "unknown",
|
|
60
66
|
authorType: mapAuthorType(c.author?.__typename, c.author?.login),
|
|
67
|
+
...(c.authorAssociation !== undefined && { authorAssociation: c.authorAssociation }),
|
|
61
68
|
body: c.body,
|
|
62
69
|
url: c.url,
|
|
63
70
|
createdAtUnix: c.createdAt ? parseCreatedAt(c.createdAt) : 0,
|
|
@@ -124,6 +131,11 @@ export function parseRawPr(raw, rawThreadPages, rawCommentNodes, rawReviewNodes,
|
|
|
124
131
|
approvedReviews,
|
|
125
132
|
checks,
|
|
126
133
|
branchProtection: parseBranchProtection(raw),
|
|
134
|
+
branchRules: parseBranchRules(raw.baseRef),
|
|
135
|
+
isInMergeQueue: raw.isInMergeQueue ?? false,
|
|
136
|
+
isMergeQueueEnabled: raw.isMergeQueueEnabled ?? false,
|
|
137
|
+
mergeQueueEntry: parseMergeQueueEntry(raw.mergeQueueEntry),
|
|
138
|
+
stack: parseStack(raw),
|
|
127
139
|
activity: buildPrActivitySummary(raw, comments, reviewThreads, reviewSummaries, allChangesRequestedReviews, approvedReviews),
|
|
128
140
|
};
|
|
129
141
|
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
export interface RawBranchProtectionRule {
|
|
2
|
+
requiresApprovingReviews: boolean;
|
|
3
|
+
requiredApprovingReviewCount: number;
|
|
4
|
+
requiresConversationResolution: boolean;
|
|
5
|
+
requiresStatusChecks: boolean;
|
|
6
|
+
requiredStatusCheckContexts: string[] | null;
|
|
7
|
+
requiresCodeOwnerReviews?: boolean;
|
|
8
|
+
requireLastPushApproval?: boolean;
|
|
9
|
+
requiresCommitSignatures?: boolean;
|
|
10
|
+
requiresLinearHistory?: boolean;
|
|
11
|
+
requiresStrictStatusChecks?: boolean;
|
|
12
|
+
requiresDeployments?: boolean;
|
|
13
|
+
requiredDeploymentEnvironments?: string[] | null;
|
|
14
|
+
}
|
|
15
|
+
interface RawMergeQueueEntry {
|
|
16
|
+
position: number;
|
|
17
|
+
state: string;
|
|
18
|
+
estimatedTimeToMerge: number | null;
|
|
19
|
+
}
|
|
20
|
+
interface RawStack {
|
|
21
|
+
number: number;
|
|
22
|
+
size: number;
|
|
23
|
+
baseRefName: string;
|
|
24
|
+
}
|
|
25
|
+
export interface RawRepositoryRule {
|
|
26
|
+
type: string;
|
|
27
|
+
parameters: RawRuleParameters | null;
|
|
28
|
+
}
|
|
29
|
+
interface RawRuleParameters {
|
|
30
|
+
requiredApprovingReviewCount?: number;
|
|
31
|
+
requiredReviewThreadResolution?: boolean;
|
|
32
|
+
requireCodeOwnerReview?: boolean;
|
|
33
|
+
requireLastPushApproval?: boolean;
|
|
34
|
+
strictRequiredStatusChecksPolicy?: boolean;
|
|
35
|
+
requiredStatusChecks?: Array<{
|
|
36
|
+
context: string;
|
|
37
|
+
}>;
|
|
38
|
+
requiredDeploymentEnvironments?: string[];
|
|
39
|
+
codeScanningTools?: Array<{
|
|
40
|
+
tool: string;
|
|
41
|
+
}>;
|
|
42
|
+
}
|
|
43
|
+
export interface RawBaseRef {
|
|
44
|
+
branchProtectionRule: RawBranchProtectionRule | null;
|
|
45
|
+
rules: {
|
|
46
|
+
nodes: RawRepositoryRule[];
|
|
47
|
+
} | null;
|
|
48
|
+
}
|
|
49
|
+
export interface RawPrMergeFields {
|
|
50
|
+
isInMergeQueue?: boolean;
|
|
51
|
+
isMergeQueueEnabled?: boolean;
|
|
52
|
+
mergeQueueEntry?: RawMergeQueueEntry | null;
|
|
53
|
+
stack?: RawStack | null;
|
|
54
|
+
stackEntry?: {
|
|
55
|
+
position: number;
|
|
56
|
+
} | null;
|
|
57
|
+
baseRef?: RawBaseRef | null;
|
|
58
|
+
}
|
|
59
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
import type { CommentAuthorAssociation } from "../types/github.mts";
|
|
2
|
+
import type { RawPrMergeFields } from "./batch-raw-rules.mts";
|
|
3
|
+
export interface RawBatchResponse {
|
|
4
|
+
repository: {
|
|
5
|
+
pullRequest: RawPr | null;
|
|
6
|
+
} | null;
|
|
7
|
+
}
|
|
8
|
+
export interface RawPr extends RawPrMergeFields {
|
|
9
|
+
id: string;
|
|
10
|
+
number: number;
|
|
11
|
+
state: string;
|
|
12
|
+
isDraft: boolean;
|
|
13
|
+
mergeable: string;
|
|
14
|
+
mergeStateStatus: string;
|
|
15
|
+
reviewDecision: string | null;
|
|
16
|
+
headRefOid: string;
|
|
17
|
+
headRefName: string;
|
|
18
|
+
headRepository: {
|
|
19
|
+
nameWithOwner: string;
|
|
20
|
+
} | null;
|
|
21
|
+
baseRefName: string;
|
|
22
|
+
baseRef: import("./batch-raw-rules.mts").RawBaseRef | null;
|
|
23
|
+
reviewRequests: {
|
|
24
|
+
nodes: Array<{
|
|
25
|
+
requestedReviewer: {
|
|
26
|
+
login?: string;
|
|
27
|
+
name?: string;
|
|
28
|
+
} | null;
|
|
29
|
+
}>;
|
|
30
|
+
};
|
|
31
|
+
latestReviews: {
|
|
32
|
+
nodes: Array<{
|
|
33
|
+
author: RawAuthor | null;
|
|
34
|
+
state: string;
|
|
35
|
+
}>;
|
|
36
|
+
};
|
|
37
|
+
reviewThreads: {
|
|
38
|
+
pageInfo: {
|
|
39
|
+
hasPreviousPage: boolean;
|
|
40
|
+
startCursor: string | null;
|
|
41
|
+
};
|
|
42
|
+
nodes: RawThread[];
|
|
43
|
+
};
|
|
44
|
+
comments: {
|
|
45
|
+
pageInfo: {
|
|
46
|
+
hasPreviousPage: boolean;
|
|
47
|
+
startCursor: string | null;
|
|
48
|
+
};
|
|
49
|
+
nodes: RawComment[];
|
|
50
|
+
};
|
|
51
|
+
changesRequestedReviews: {
|
|
52
|
+
pageInfo: {
|
|
53
|
+
hasPreviousPage: boolean;
|
|
54
|
+
startCursor: string | null;
|
|
55
|
+
};
|
|
56
|
+
nodes: RawReview[];
|
|
57
|
+
};
|
|
58
|
+
reviewSummaries: {
|
|
59
|
+
pageInfo: {
|
|
60
|
+
hasPreviousPage: boolean;
|
|
61
|
+
startCursor: string | null;
|
|
62
|
+
};
|
|
63
|
+
nodes: RawReviewSummary[];
|
|
64
|
+
};
|
|
65
|
+
allReviews?: {
|
|
66
|
+
totalCount: number;
|
|
67
|
+
};
|
|
68
|
+
approvedReviews: {
|
|
69
|
+
pageInfo: {
|
|
70
|
+
hasPreviousPage: boolean;
|
|
71
|
+
startCursor: string | null;
|
|
72
|
+
};
|
|
73
|
+
nodes: RawReviewSummary[];
|
|
74
|
+
};
|
|
75
|
+
commits: {
|
|
76
|
+
totalCount?: number;
|
|
77
|
+
nodes: Array<{
|
|
78
|
+
commit: {
|
|
79
|
+
oid: string;
|
|
80
|
+
committedDate?: string;
|
|
81
|
+
checkSuites?: RawCheckSuites;
|
|
82
|
+
statusCheckRollup: {
|
|
83
|
+
contexts: {
|
|
84
|
+
pageInfo: {
|
|
85
|
+
hasNextPage: boolean;
|
|
86
|
+
endCursor: string | null;
|
|
87
|
+
};
|
|
88
|
+
nodes: Array<RawContextNode | null>;
|
|
89
|
+
};
|
|
90
|
+
} | null;
|
|
91
|
+
};
|
|
92
|
+
}>;
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
interface RawCheckSuites {
|
|
96
|
+
pageInfo: {
|
|
97
|
+
hasNextPage: boolean;
|
|
98
|
+
};
|
|
99
|
+
nodes: Array<{
|
|
100
|
+
conclusion: string | null;
|
|
101
|
+
workflowRun: {
|
|
102
|
+
databaseId: number | null;
|
|
103
|
+
event: string | null;
|
|
104
|
+
url: string | null;
|
|
105
|
+
workflow: {
|
|
106
|
+
name: string | null;
|
|
107
|
+
} | null;
|
|
108
|
+
} | null;
|
|
109
|
+
}>;
|
|
110
|
+
}
|
|
111
|
+
interface RawAuthor {
|
|
112
|
+
__typename?: string;
|
|
113
|
+
login: string;
|
|
114
|
+
}
|
|
115
|
+
export interface RawThreadComment {
|
|
116
|
+
id: string;
|
|
117
|
+
isMinimized: boolean;
|
|
118
|
+
url: string;
|
|
119
|
+
authorAssociation?: CommentAuthorAssociation;
|
|
120
|
+
author: RawAuthor | null;
|
|
121
|
+
pullRequestReview?: {
|
|
122
|
+
id: string;
|
|
123
|
+
} | null;
|
|
124
|
+
body: string;
|
|
125
|
+
path: string | null;
|
|
126
|
+
line: number | null;
|
|
127
|
+
startLine: number | null;
|
|
128
|
+
createdAt?: string;
|
|
129
|
+
}
|
|
130
|
+
export interface RawThread {
|
|
131
|
+
id: string;
|
|
132
|
+
isResolved: boolean;
|
|
133
|
+
isOutdated: boolean;
|
|
134
|
+
path?: string | null;
|
|
135
|
+
line?: number | null;
|
|
136
|
+
startLine?: number | null;
|
|
137
|
+
comments: {
|
|
138
|
+
pageInfo?: {
|
|
139
|
+
hasNextPage: boolean;
|
|
140
|
+
endCursor: string | null;
|
|
141
|
+
};
|
|
142
|
+
nodes: RawThreadComment[];
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
export interface RawReviewThreadCommentsResponse {
|
|
146
|
+
node: {
|
|
147
|
+
__typename?: string;
|
|
148
|
+
comments: {
|
|
149
|
+
pageInfo: {
|
|
150
|
+
hasNextPage: boolean;
|
|
151
|
+
endCursor: string | null;
|
|
152
|
+
};
|
|
153
|
+
nodes: RawThreadComment[];
|
|
154
|
+
} | null;
|
|
155
|
+
} | null;
|
|
156
|
+
}
|
|
157
|
+
export interface RawComment {
|
|
158
|
+
id: string;
|
|
159
|
+
isMinimized: boolean;
|
|
160
|
+
url: string;
|
|
161
|
+
authorAssociation?: CommentAuthorAssociation;
|
|
162
|
+
author: RawAuthor | null;
|
|
163
|
+
body: string;
|
|
164
|
+
createdAt?: string;
|
|
165
|
+
}
|
|
166
|
+
export interface RawReview {
|
|
167
|
+
id: string;
|
|
168
|
+
authorAssociation?: CommentAuthorAssociation;
|
|
169
|
+
author: RawAuthor | null;
|
|
170
|
+
body: string;
|
|
171
|
+
createdAt?: string;
|
|
172
|
+
commit?: {
|
|
173
|
+
oid: string;
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
export interface RawReviewSummary {
|
|
177
|
+
id: string;
|
|
178
|
+
isMinimized: boolean;
|
|
179
|
+
authorAssociation?: CommentAuthorAssociation;
|
|
180
|
+
author: RawAuthor | null;
|
|
181
|
+
body: string;
|
|
182
|
+
createdAt?: string;
|
|
183
|
+
}
|
|
184
|
+
export type RawContextNode = {
|
|
185
|
+
__typename: "CheckRun";
|
|
186
|
+
id: string;
|
|
187
|
+
name: string;
|
|
188
|
+
status: string;
|
|
189
|
+
conclusion: string | null;
|
|
190
|
+
detailsUrl: string | null;
|
|
191
|
+
completedAt?: string | null;
|
|
192
|
+
startedAt?: string | null;
|
|
193
|
+
title: string | null;
|
|
194
|
+
summary: string | null;
|
|
195
|
+
checkSuite: {
|
|
196
|
+
createdAt?: string;
|
|
197
|
+
updatedAt?: string;
|
|
198
|
+
workflowRun: {
|
|
199
|
+
event: string;
|
|
200
|
+
createdAt?: string;
|
|
201
|
+
updatedAt?: string;
|
|
202
|
+
workflow?: {
|
|
203
|
+
name: string;
|
|
204
|
+
databaseId?: number | null;
|
|
205
|
+
} | null;
|
|
206
|
+
} | null;
|
|
207
|
+
} | null;
|
|
208
|
+
} | {
|
|
209
|
+
__typename: "StatusContext";
|
|
210
|
+
context: string;
|
|
211
|
+
state: string;
|
|
212
|
+
createdAt?: string;
|
|
213
|
+
targetUrl: string | null;
|
|
214
|
+
description: string | null;
|
|
215
|
+
};
|
|
216
|
+
export {};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { RepoInfo } from "./client.mts";
|
|
2
|
+
import type { RawBatchResponse, RawContextNode, RawPr } from "./batch-raw-types.mts";
|
|
3
|
+
export declare function requireRawPr(response: RawBatchResponse | null | undefined, pr: number, repo: RepoInfo): RawPr;
|
|
4
|
+
export declare function requireContextNodes(nodes: Array<RawContextNode | null>): RawContextNode[];
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { type RateLimitInfo, type RepoInfo } from "./client.mts";
|
|
2
|
+
import type { BatchPrData } from "../types.mts";
|
|
3
|
+
interface BatchResult {
|
|
4
|
+
data: BatchPrData;
|
|
5
|
+
rateLimit?: RateLimitInfo;
|
|
6
|
+
/** True when GraphQL returned a complete CheckSuite page; skip REST startup-failure fetch. */
|
|
7
|
+
checkSuitesComplete?: boolean;
|
|
8
|
+
}
|
|
9
|
+
interface FetchPrBatchOptions {
|
|
10
|
+
/**
|
|
11
|
+
* When false (default), the first-page approvedReviews are returned but
|
|
12
|
+
* backward pagination is skipped. Iterate's approvals-minimize flow sets this
|
|
13
|
+
* to true only when the user opts in, so long-lived PRs with > 50 approvals
|
|
14
|
+
* don't pay extra GraphQL round-trips per iterate call for data no consumer
|
|
15
|
+
* currently uses. The first page is free — already inside the one batch
|
|
16
|
+
* request — so there's no need to conditionally omit the field itself.
|
|
17
|
+
*/
|
|
18
|
+
paginateApprovedReviews?: boolean;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Fetch all PR data needed for a `shepherd check` in one (or a few, if paginating) GraphQL requests.
|
|
22
|
+
*/
|
|
23
|
+
export declare function fetchPrBatch(pr: number, repo: RepoInfo, opts?: FetchPrBatchOptions): Promise<BatchResult>;
|
|
24
|
+
export {};
|
package/bin/github/batch.mjs
CHANGED
|
@@ -1,134 +1,28 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { paginateForward, paginateBackward } from "./pagination.mjs";
|
|
1
|
+
import { graphqlWithRateLimit } from "./client.mjs";
|
|
3
2
|
import { hydrateThreadCommentPages } from "./thread-comments.mjs";
|
|
4
3
|
import { BATCH_PR_QUERY } from "./queries.mjs";
|
|
5
4
|
import { parseRawPr } from "./batch-parsers.mjs";
|
|
6
|
-
import {
|
|
5
|
+
import { parseCheckSuitesComplete, parseSuiteStartupFailures } from "./batch-parse-suites.mjs";
|
|
6
|
+
import { mergeStartupFailureChecks } from "../checks/startup-failures.mjs";
|
|
7
|
+
import { paginateBatchConnections } from "./batch-page.mjs";
|
|
8
|
+
import { requireRawPr } from "./batch-response.mjs";
|
|
7
9
|
/**
|
|
8
10
|
* Fetch all PR data needed for a `shepherd check` in one (or a few, if paginating) GraphQL requests.
|
|
9
11
|
*/
|
|
10
12
|
export async function fetchPrBatch(pr, repo, opts = {}) {
|
|
11
|
-
// First page: no cursor variables.
|
|
12
13
|
const result = await graphqlWithRateLimit(BATCH_PR_QUERY, {
|
|
13
14
|
owner: repo.owner,
|
|
14
15
|
repo: repo.name,
|
|
15
16
|
pr,
|
|
16
17
|
});
|
|
17
18
|
const raw = requireRawPr(result.data, pr, repo);
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
pr,
|
|
28
|
-
...(cursor ? { threadsCursor: cursor } : {}),
|
|
29
|
-
});
|
|
30
|
-
const pr2 = requireRawPr(res.data, pr, repo);
|
|
31
|
-
return pr2.reviewThreads;
|
|
32
|
-
}, raw.reviewThreads.pageInfo.startCursor);
|
|
33
|
-
// extra contains pages before the first page.
|
|
34
|
-
rawThreadPages = [...extra, ...rawThreadPages];
|
|
35
|
-
}
|
|
36
|
-
rawThreadPages = await hydrateThreadCommentPages(rawThreadPages);
|
|
37
|
-
// Paginate comments backward if the first page is incomplete.
|
|
38
|
-
let rawCommentNodes = raw.comments.nodes;
|
|
39
|
-
if (raw.comments.pageInfo.hasPreviousPage && raw.comments.pageInfo.startCursor) {
|
|
40
|
-
const extra = await paginateBackward(async (cursor) => {
|
|
41
|
-
const res = await graphql(BATCH_PR_QUERY, {
|
|
42
|
-
owner: repo.owner,
|
|
43
|
-
repo: repo.name,
|
|
44
|
-
pr,
|
|
45
|
-
...(cursor ? { commentsCursor: cursor } : {}),
|
|
46
|
-
});
|
|
47
|
-
const pr2 = requireRawPr(res.data, pr, repo);
|
|
48
|
-
return pr2.comments;
|
|
49
|
-
}, raw.comments.pageInfo.startCursor);
|
|
50
|
-
rawCommentNodes = [...extra, ...rawCommentNodes];
|
|
51
|
-
}
|
|
52
|
-
// Paginate CHANGES_REQUESTED reviews backward if the first page is incomplete.
|
|
53
|
-
let rawReviewNodes = raw.changesRequestedReviews.nodes;
|
|
54
|
-
if (raw.changesRequestedReviews.pageInfo.hasPreviousPage &&
|
|
55
|
-
raw.changesRequestedReviews.pageInfo.startCursor) {
|
|
56
|
-
const extra = await paginateBackward(async (cursor) => {
|
|
57
|
-
const res = await graphql(BATCH_PR_QUERY, {
|
|
58
|
-
owner: repo.owner,
|
|
59
|
-
repo: repo.name,
|
|
60
|
-
pr,
|
|
61
|
-
...(cursor ? { changesRequestedCursor: cursor } : {}),
|
|
62
|
-
});
|
|
63
|
-
const pr2 = requireRawPr(res.data, pr, repo);
|
|
64
|
-
return pr2.changesRequestedReviews;
|
|
65
|
-
}, raw.changesRequestedReviews.pageInfo.startCursor);
|
|
66
|
-
rawReviewNodes = [...extra, ...rawReviewNodes];
|
|
67
|
-
}
|
|
68
|
-
// Paginate COMMENTED review summaries backward if the first page is incomplete.
|
|
69
|
-
let rawReviewSummaryNodes = raw.reviewSummaries.nodes;
|
|
70
|
-
if (raw.reviewSummaries.pageInfo.hasPreviousPage && raw.reviewSummaries.pageInfo.startCursor) {
|
|
71
|
-
const extra = await paginateBackward(async (cursor) => {
|
|
72
|
-
const res = await graphql(BATCH_PR_QUERY, {
|
|
73
|
-
owner: repo.owner,
|
|
74
|
-
repo: repo.name,
|
|
75
|
-
pr,
|
|
76
|
-
...(cursor ? { reviewSummariesCursor: cursor } : {}),
|
|
77
|
-
});
|
|
78
|
-
const pr2 = requireRawPr(res.data, pr, repo);
|
|
79
|
-
return pr2.reviewSummaries;
|
|
80
|
-
}, raw.reviewSummaries.pageInfo.startCursor);
|
|
81
|
-
rawReviewSummaryNodes = [...extra, ...rawReviewSummaryNodes];
|
|
82
|
-
}
|
|
83
|
-
// Paginate APPROVED reviews backward if the first page is incomplete — gated behind
|
|
84
|
-
// `paginateApprovedReviews` because approvals minimization is opt-in. See FetchPrBatchOptions.
|
|
85
|
-
let rawApprovedReviewNodes = raw.approvedReviews.nodes;
|
|
86
|
-
if (opts.paginateApprovedReviews &&
|
|
87
|
-
raw.approvedReviews.pageInfo.hasPreviousPage &&
|
|
88
|
-
raw.approvedReviews.pageInfo.startCursor) {
|
|
89
|
-
const extra = await paginateBackward(async (cursor) => {
|
|
90
|
-
const res = await graphql(BATCH_PR_QUERY, {
|
|
91
|
-
owner: repo.owner,
|
|
92
|
-
repo: repo.name,
|
|
93
|
-
pr,
|
|
94
|
-
...(cursor ? { approvedReviewsCursor: cursor } : {}),
|
|
95
|
-
});
|
|
96
|
-
const pr2 = requireRawPr(res.data, pr, repo);
|
|
97
|
-
return pr2.approvedReviews;
|
|
98
|
-
}, raw.approvedReviews.pageInfo.startCursor);
|
|
99
|
-
rawApprovedReviewNodes = [...extra, ...rawApprovedReviewNodes];
|
|
100
|
-
}
|
|
101
|
-
// Paginate check contexts forward if the first page is incomplete.
|
|
102
|
-
let rawCheckNodes = requireContextNodes(raw.commits.nodes[0]?.commit.statusCheckRollup?.contexts.nodes ?? []);
|
|
103
|
-
const checksPageInfo = raw.commits.nodes[0]?.commit.statusCheckRollup?.contexts.pageInfo;
|
|
104
|
-
const firstOid = raw.commits.nodes[0]?.commit.oid;
|
|
105
|
-
if (checksPageInfo?.hasNextPage && checksPageInfo.endCursor) {
|
|
106
|
-
// Pass endCursor so paginateForward fetches pages *after* the already-
|
|
107
|
-
// fetched first page instead of re-fetching it from the start.
|
|
108
|
-
let pageCount = 0;
|
|
109
|
-
const extra = await paginateForward(async (cursor) => {
|
|
110
|
-
const res = await graphql(BATCH_PR_QUERY, {
|
|
111
|
-
owner: repo.owner,
|
|
112
|
-
repo: repo.name,
|
|
113
|
-
pr,
|
|
114
|
-
...(cursor ? { checksCursor: cursor } : {}),
|
|
115
|
-
});
|
|
116
|
-
const pr2 = requireRawPr(res.data, pr, repo);
|
|
117
|
-
if (!pr2?.commits.nodes[0]?.commit.statusCheckRollup) {
|
|
118
|
-
throw new Error(`Check-context pagination interrupted: statusCheckRollup disappeared on page ${pageCount + 2} (possible force-push race). Retry after the push stabilizes.`);
|
|
119
|
-
}
|
|
120
|
-
const currentOid = pr2.commits.nodes[0]?.commit.oid;
|
|
121
|
-
if (firstOid !== undefined && currentOid !== undefined && currentOid !== firstOid) {
|
|
122
|
-
throw new Error(`Check-context pagination interrupted: head commit changed from ${firstOid} to ${currentOid} between pages (force-push race). Retry.`);
|
|
123
|
-
}
|
|
124
|
-
pageCount++;
|
|
125
|
-
const ctxs = pr2.commits.nodes[0]?.commit.statusCheckRollup?.contexts;
|
|
126
|
-
if (!ctxs)
|
|
127
|
-
return { pageInfo: { hasNextPage: false, endCursor: null }, nodes: [] };
|
|
128
|
-
return { ...ctxs, nodes: requireContextNodes(ctxs.nodes) };
|
|
129
|
-
}, checksPageInfo.endCursor);
|
|
130
|
-
rawCheckNodes = [...rawCheckNodes, ...extra];
|
|
131
|
-
}
|
|
132
|
-
const data = parseRawPr(raw, rawThreadPages, rawCommentNodes, rawReviewNodes, rawReviewSummaryNodes, rawApprovedReviewNodes, rawCheckNodes);
|
|
133
|
-
return { data, rateLimit: result.rateLimit };
|
|
19
|
+
const paged = await paginateBatchConnections(pr, repo, raw, opts, result.rateLimit);
|
|
20
|
+
const rawThreadPages = await hydrateThreadCommentPages(paged.threads);
|
|
21
|
+
const data = parseRawPr(raw, rawThreadPages, paged.comments, paged.changesRequested, paged.reviewSummaries, paged.approvedReviews, paged.checks);
|
|
22
|
+
data.checks = mergeStartupFailureChecks(data.checks, parseSuiteStartupFailures(raw));
|
|
23
|
+
return {
|
|
24
|
+
data,
|
|
25
|
+
rateLimit: paged.rateLimit ?? result.rateLimit,
|
|
26
|
+
...(parseCheckSuitesComplete(raw) && { checkSuitesComplete: true }),
|
|
27
|
+
};
|
|
134
28
|
}
|