patchrelay 0.36.2 → 0.36.3
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/build-info.json
CHANGED
|
@@ -327,6 +327,21 @@ async function evaluateGitHubIssueHealth(snapshot, config, runCommand, reviewQui
|
|
|
327
327
|
},
|
|
328
328
|
};
|
|
329
329
|
}
|
|
330
|
+
if (gateCheckStatus === "success"
|
|
331
|
+
&& reviewDecision === "CHANGES_REQUESTED"
|
|
332
|
+
&& mergeConflictDetected
|
|
333
|
+
&& issue.factoryState !== "changes_requested"
|
|
334
|
+
&& issue.activeRunId === undefined
|
|
335
|
+
&& ageMs >= RECONCILIATION_GRACE_MS) {
|
|
336
|
+
return {
|
|
337
|
+
ciEntry,
|
|
338
|
+
finding: {
|
|
339
|
+
status: "fail",
|
|
340
|
+
scope: "github:branch-upkeep",
|
|
341
|
+
message: "PR is still dirty after requested changes, but no branch-upkeep run is active",
|
|
342
|
+
},
|
|
343
|
+
};
|
|
344
|
+
}
|
|
330
345
|
if (gateCheckStatus === "success"
|
|
331
346
|
&& reviewDecision === "CHANGES_REQUESTED"
|
|
332
347
|
&& latestBlockingReviewHeadSha === pr.headRefOid
|
|
@@ -423,6 +438,9 @@ function deriveCiOwner(params) {
|
|
|
423
438
|
: "downstream";
|
|
424
439
|
}
|
|
425
440
|
if (params.reviewDecision === "CHANGES_REQUESTED") {
|
|
441
|
+
if (params.mergeConflictDetected) {
|
|
442
|
+
return params.factoryState === "changes_requested" ? "patchrelay" : "unknown";
|
|
443
|
+
}
|
|
426
444
|
if (params.factoryState === "changes_requested")
|
|
427
445
|
return "patchrelay";
|
|
428
446
|
if (params.reviewQuillAttempt)
|
|
@@ -451,6 +469,9 @@ function describeCiOwnership(params) {
|
|
|
451
469
|
&& params.latestBlockingReviewHeadSha
|
|
452
470
|
&& params.currentHeadSha !== params.latestBlockingReviewHeadSha);
|
|
453
471
|
if (params.owner === "patchrelay") {
|
|
472
|
+
if (params.mergeConflictDetected) {
|
|
473
|
+
return "PatchRelay owns the next branch-upkeep move";
|
|
474
|
+
}
|
|
454
475
|
return params.gateCheckStatus === "failure"
|
|
455
476
|
? "PatchRelay owns the next CI repair move"
|
|
456
477
|
: "PatchRelay owns the next requested-changes move";
|
|
@@ -479,6 +500,11 @@ function describeCiOwnership(params) {
|
|
|
479
500
|
: "Waiting on external GitHub automation";
|
|
480
501
|
}
|
|
481
502
|
if (params.reviewDecision === "CHANGES_REQUESTED") {
|
|
503
|
+
if (params.mergeConflictDetected) {
|
|
504
|
+
return headAdvancedPastBlockingReview
|
|
505
|
+
? "PR is still dirty after a newer pushed head and no branch-upkeep run is active"
|
|
506
|
+
: "PR is still dirty on the current blocked head and no branch-upkeep run is active";
|
|
507
|
+
}
|
|
482
508
|
return blockingReviewTargetsCurrentHead
|
|
483
509
|
? "Requested changes still block the same head and no fix run is active"
|
|
484
510
|
: "Waiting on review after a newer pushed head";
|
|
@@ -16,6 +16,22 @@ function isReviewDecisionChangesRequested(value) {
|
|
|
16
16
|
function isReviewDecisionReviewRequired(value) {
|
|
17
17
|
return value?.trim().toUpperCase() === "REVIEW_REQUIRED";
|
|
18
18
|
}
|
|
19
|
+
function buildBranchUpkeepContext(prNumber, baseBranch, mergeStateStatus, headSha) {
|
|
20
|
+
const promptContext = [
|
|
21
|
+
`The requested code change may already be present, but GitHub still reports PR #${prNumber} as ${mergeStateStatus ?? "DIRTY"} against latest ${baseBranch}.`,
|
|
22
|
+
`This turn is branch upkeep on the existing PR branch: update onto latest ${baseBranch}, resolve any conflicts, rerun the narrowest relevant verification, and push a newer head.`,
|
|
23
|
+
"Do not stop just because the requested code change is already present. Review can only move forward after a new pushed head.",
|
|
24
|
+
].join(" ");
|
|
25
|
+
return {
|
|
26
|
+
branchUpkeepRequired: true,
|
|
27
|
+
reviewFixMode: "branch_upkeep",
|
|
28
|
+
wakeReason: "branch_upkeep",
|
|
29
|
+
promptContext,
|
|
30
|
+
...(mergeStateStatus ? { mergeStateStatus } : {}),
|
|
31
|
+
...(headSha ? { failingHeadSha: headSha } : {}),
|
|
32
|
+
baseBranch,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
19
35
|
function hasCompletedReviewQuillVerdict(entries) {
|
|
20
36
|
return (entries ?? []).some((entry) => entry.__typename === "CheckRun"
|
|
21
37
|
&& entry.name === "review-quill/verdict"
|
|
@@ -475,6 +491,23 @@ export class IdleIssueReconciler {
|
|
|
475
491
|
mergeConflictDetected,
|
|
476
492
|
downstreamOwned,
|
|
477
493
|
});
|
|
494
|
+
if (reactiveIntent?.runType === "branch_upkeep" && mergeConflictDetected) {
|
|
495
|
+
this.logger.info({ issueKey: issue.issueKey, prNumber: issue.prNumber, mergeable: pr.mergeable, mergeStateStatus: pr.mergeStateStatus }, "Reconciliation: PR still needs branch upkeep after requested changes");
|
|
496
|
+
this.advanceIdleIssue(issue, reactiveIntent.compatibilityFactoryState, {
|
|
497
|
+
pendingRunType: reactiveIntent.runType,
|
|
498
|
+
pendingRunContext: buildBranchUpkeepContext(issue.prNumber, project.github?.baseBranch ?? "main", pr.mergeStateStatus, pr.headRefOid),
|
|
499
|
+
});
|
|
500
|
+
this.feed?.publish({
|
|
501
|
+
level: "warn",
|
|
502
|
+
kind: "github",
|
|
503
|
+
issueKey: issue.issueKey,
|
|
504
|
+
projectId: issue.projectId,
|
|
505
|
+
stage: reactiveIntent.compatibilityFactoryState,
|
|
506
|
+
status: "branch_upkeep_queued",
|
|
507
|
+
summary: `PR #${issue.prNumber} is still dirty after requested changes, dispatching branch upkeep`,
|
|
508
|
+
});
|
|
509
|
+
return;
|
|
510
|
+
}
|
|
478
511
|
if (reactiveIntent?.runType === "queue_repair" && mergeConflictDetected) {
|
|
479
512
|
this.logger.info({ issueKey: issue.issueKey, prNumber: issue.prNumber, mergeable: pr.mergeable }, "Reconciliation: PR needs queue repair from fresh GitHub truth");
|
|
480
513
|
this.advanceIdleIssue(issue, reactiveIntent.compatibilityFactoryState, {
|
|
@@ -510,7 +543,7 @@ export class IdleIssueReconciler {
|
|
|
510
543
|
return;
|
|
511
544
|
}
|
|
512
545
|
if (mergeConflictDetected) {
|
|
513
|
-
this.logger.debug({ issueKey: issue.issueKey, prNumber: issue.prNumber, mergeable: pr.mergeable, mergeStateStatus: pr.mergeStateStatus }, "Reconciliation: PR is dirty but
|
|
546
|
+
this.logger.debug({ issueKey: issue.issueKey, prNumber: issue.prNumber, mergeable: pr.mergeable, mergeStateStatus: pr.mergeStateStatus }, "Reconciliation: PR is dirty but no automation owner was derived");
|
|
514
547
|
}
|
|
515
548
|
}
|
|
516
549
|
catch (error) {
|
package/dist/issue-session.js
CHANGED
|
@@ -59,6 +59,13 @@ export function deriveIssueSessionReactiveIntent(params) {
|
|
|
59
59
|
};
|
|
60
60
|
}
|
|
61
61
|
if (params.prReviewState === "changes_requested") {
|
|
62
|
+
if (params.mergeConflictDetected) {
|
|
63
|
+
return {
|
|
64
|
+
runType: "branch_upkeep",
|
|
65
|
+
wakeReason: "branch_upkeep",
|
|
66
|
+
compatibilityFactoryState: "changes_requested",
|
|
67
|
+
};
|
|
68
|
+
}
|
|
62
69
|
return {
|
|
63
70
|
runType: "review_fix",
|
|
64
71
|
wakeReason: "review_changes_requested",
|