@link-assistant/hive-mind 2.2.2 → 2.2.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/CHANGELOG.md
CHANGED
package/package.json
CHANGED
package/src/github-merge.lib.mjs
CHANGED
|
@@ -446,7 +446,7 @@ export async function checkPRCIStatus(owner, repo, prNumber, verbose = false) {
|
|
|
446
446
|
* @param {string} repo - Repository name
|
|
447
447
|
* @param {number} prNumber - Pull request number
|
|
448
448
|
* @param {boolean} verbose - Whether to log verbose output
|
|
449
|
-
* @returns {Promise<{mergeable: boolean, reason: string|null, terminal?: boolean}>}
|
|
449
|
+
* @returns {Promise<{mergeable: boolean, mergeableState?: string|null, mergeStateStatus?: string|null, reason: string|null, terminal?: boolean}>}
|
|
450
450
|
*/
|
|
451
451
|
export async function checkPRMergeable(owner, repo, prNumber, verbose = false) {
|
|
452
452
|
// Issue #1339: GitHub computes mergeability asynchronously. When mergeStateStatus is
|
|
@@ -473,7 +473,7 @@ export async function checkPRMergeable(owner, repo, prNumber, verbose = false) {
|
|
|
473
473
|
if (verbose) {
|
|
474
474
|
console.log(`[VERBOSE] /merge: PR #${prNumber} mergeability still UNKNOWN after ${MAX_UNKNOWN_RETRIES} attempts`);
|
|
475
475
|
}
|
|
476
|
-
return { mergeable: false, reason: `Merge state: UNKNOWN (GitHub could not compute mergeability after ${MAX_UNKNOWN_RETRIES} attempts)` };
|
|
476
|
+
return { mergeable: false, mergeableState: pr.mergeable, mergeStateStatus: pr.mergeStateStatus, reason: `Merge state: UNKNOWN (GitHub could not compute mergeability after ${MAX_UNKNOWN_RETRIES} attempts)` };
|
|
477
477
|
}
|
|
478
478
|
|
|
479
479
|
const mergeable = pr.mergeable === 'MERGEABLE';
|
|
@@ -505,7 +505,7 @@ export async function checkPRMergeable(owner, repo, prNumber, verbose = false) {
|
|
|
505
505
|
console.log(`[VERBOSE] /merge: PR #${prNumber} mergeable: ${mergeable}, state: ${pr.mergeStateStatus}`);
|
|
506
506
|
}
|
|
507
507
|
|
|
508
|
-
return { mergeable, reason };
|
|
508
|
+
return { mergeable, mergeableState: pr.mergeable, mergeStateStatus: pr.mergeStateStatus, reason };
|
|
509
509
|
} catch (error) {
|
|
510
510
|
if (isTerminalGitHubEntityError(error)) {
|
|
511
511
|
const terminalError = getTerminalGitHubEntityErrorMessage(error);
|
|
@@ -464,6 +464,22 @@ export const shouldResetNoRunsCounter = (ciStatus, noWorkflowRunsForCommit = fal
|
|
|
464
464
|
return Boolean(ciStatus && ciStatus.status !== 'no_checks');
|
|
465
465
|
};
|
|
466
466
|
|
|
467
|
+
/**
|
|
468
|
+
* Issue #2031: GitHub can retain a failed check-run from an older workflow run
|
|
469
|
+
* alongside a newer successful run for the same job and HEAD SHA. The raw
|
|
470
|
+
* check-run rollup then says "failure" even though GitHub's live PR state is
|
|
471
|
+
* CLEAN/MERGEABLE. Only this explicit pair is strong enough to override the
|
|
472
|
+
* rollup; every other merge state remains conservative.
|
|
473
|
+
*/
|
|
474
|
+
export const isAuthoritativeCleanMergeState = mergeStatus => mergeStatus?.mergeable === true && mergeStatus?.mergeableState === 'MERGEABLE' && mergeStatus?.mergeStateStatus === 'CLEAN';
|
|
475
|
+
|
|
476
|
+
export const reconcileStaleCIBlockers = (blockers, ciStatus, mergeStatus) => {
|
|
477
|
+
if (ciStatus?.status !== 'failure' || !isAuthoritativeCleanMergeState(mergeStatus)) {
|
|
478
|
+
return blockers;
|
|
479
|
+
}
|
|
480
|
+
return blockers.filter(blocker => blocker.type !== 'ci_failure' && blocker.type !== 'ci_cancelled');
|
|
481
|
+
};
|
|
482
|
+
|
|
467
483
|
export const getMergeBlockers = async (owner, repo, prNumber, verbose = false, checkCount = 1, prBranchRef = null) => {
|
|
468
484
|
const blockers = [];
|
|
469
485
|
|
|
@@ -945,6 +961,16 @@ export const getMergeBlockers = async (owner, repo, prNumber, verbose = false, c
|
|
|
945
961
|
return { blockers, ciStatus, noCiConfigured: false, noCiTriggered: false, noWorkflowRunsForCommit };
|
|
946
962
|
}
|
|
947
963
|
|
|
964
|
+
if (ciStatus.status === 'failure' && isAuthoritativeCleanMergeState(mergeStatus)) {
|
|
965
|
+
const staleFailureBlockers = blockers.filter(blocker => blocker.type === 'ci_failure' || blocker.type === 'ci_cancelled');
|
|
966
|
+
if (staleFailureBlockers.length > 0) {
|
|
967
|
+
if (verbose) {
|
|
968
|
+
await log(`[VERBOSE] /merge: PR #${prNumber} is CLEAN/MERGEABLE according to GitHub; ignoring ${staleFailureBlockers.length} stale CI failure/cancellation blocker(s) from the raw check-run rollup`);
|
|
969
|
+
}
|
|
970
|
+
blockers.splice(0, blockers.length, ...reconcileStaleCIBlockers(blockers, ciStatus, mergeStatus));
|
|
971
|
+
}
|
|
972
|
+
}
|
|
973
|
+
|
|
948
974
|
if (!mergeStatus.mergeable) {
|
|
949
975
|
blockers.push({
|
|
950
976
|
type: 'not_mergeable',
|