Fix PR merge dropdown availability when checks pass (#5220)

* fix github pr merge dropdown availability

Co-authored-by: Orca <help@stably.ai>

* address pr merge review comments

Co-authored-by: Orca <help@stably.ai>

---------

Co-authored-by: Orca <help@stably.ai>
This commit is contained in:
Jinwoo Hong 2026-06-11 16:24:30 -07:00 committed by GitHub
parent 58ce969fcb
commit 042ce674da
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 75 additions and 6 deletions

View File

@ -67,13 +67,43 @@ describe('presentGitHubPRMergeState', () => {
it('labels unresolved GitHub mergeability as checking', () => {
expect(
presentGitHubPRMergeState(pr({ mergeable: 'UNKNOWN', mergeStateStatus: null }))
presentGitHubPRMergeState(
pr({
mergeable: 'UNKNOWN',
mergeStateStatus: null,
checksSummary: { state: 'pending', total: 1, passed: 0, failed: 0, pending: 1 }
})
)
).toMatchObject({
label: 'Checking',
directMergeAvailable: false
})
})
it('allows direct merge when GitHub mergeability is unavailable but checks have passed', () => {
expect(
presentGitHubPRMergeState({
state: 'open',
checksSummary: { state: 'success', total: 3, passed: 3, failed: 0, pending: 0 }
})
).toMatchObject({
label: 'Checks passed',
directMergeAvailable: true
})
expect(
presentGitHubPRMergeState(
pr({
mergeable: 'UNKNOWN',
mergeStateStatus: null,
checksSummary: { state: 'success', total: 3, passed: 3, failed: 0, pending: 0 }
})
)
).toMatchObject({
label: 'Checks passed',
directMergeAvailable: true
})
})
it('suppresses auto-merge actions for non-open PR states', () => {
expect(
presentGitHubPRMergeState(pr({ state: 'closed', mergeQueueRequired: true })).autoMergeAction

View File

@ -45,10 +45,29 @@ function checksState(item: GitHubPRMergeStateInput): CheckStatus | 'none' | unde
return item.checksStatus
}
function checksPassed(item: GitHubPRMergeStateInput): boolean {
return checksState(item) === 'success'
}
function hasFullMergeMetadata(item: GitHubPRMergeStateInput): boolean {
return item.mergeable !== undefined || item.mergeStateStatus !== undefined
}
function passedChecksMergePresentation(
autoMergeAction: GitHubPRAutoMergeAction | null
): GitHubPRMergeStatePresentation {
return {
label: translate('auto.components.github.pr.merge.state.a5b66afb58', 'Checks passed'),
tone: SUCCESS_TONE,
tooltip: translate(
'auto.components.github.pr.merge.state.fbd4f57f0a',
'Checks passed. Merge eligibility will be checked again before merging.'
),
directMergeAvailable: true,
autoMergeAction
}
}
export function presentGitHubPRMergeState(
item: GitHubPRMergeStateInput
): GitHubPRMergeStatePresentation {
@ -154,6 +173,11 @@ export function presentGitHubPRMergeState(
}
}
if (!hasFullMergeMetadata(item)) {
// Why: GitHub can omit merge metadata while checks are already green; let
// users attempt merge and rely on the main-process preflight for blockers.
if (checksPassed(item)) {
return passedChecksMergePresentation(autoMergeAction)
}
return {
label: translate('auto.components.github.pr.merge.state.bd4f27b50e', 'Merge'),
tone: MUTED_TONE,
@ -238,6 +262,11 @@ export function presentGitHubPRMergeState(
autoMergeAction
}
}
// Why: GitHub may still report intermediate mergeability while checks are
// green; the merge command re-checks authoritative blockers before merging.
if (checksPassed(item)) {
return passedChecksMergePresentation(autoMergeAction)
}
return {
label: translate('auto.components.github.pr.merge.state.f958920f3a', 'Checking'),
tone: MUTED_TONE,

View File

@ -1629,7 +1629,9 @@
"331ebe1170": "Add this pull request to the GitHub merge queue",
"b169f943e1": "Merge when ready",
"62703b1dc4": "GitHub auto-merge is enabled for this pull request",
"48d75ae118": "Disable auto-merge"
"48d75ae118": "Disable auto-merge",
"a5b66afb58": "Checks passed",
"fbd4f57f0a": "Checks passed. Merge eligibility will be checked again before merging."
}
}
},

View File

@ -1629,7 +1629,9 @@
"331ebe1170": "Agregue esta solicitud de extracción a la cola de combinación de GitHub",
"b169f943e1": "Fusionar cuando esté listo",
"62703b1dc4": "La fusión automática de GitHub está habilitada para esta solicitud de extracción",
"48d75ae118": "Deshabilitar la fusión automática"
"48d75ae118": "Deshabilitar la fusión automática",
"a5b66afb58": "Comprobaciones aprobadas",
"fbd4f57f0a": "Comprobaciones aprobadas. La elegibilidad de fusión se volverá a comprobar antes de fusionar."
}
}
},

View File

@ -1629,7 +1629,9 @@
"331ebe1170": "このPRを GitHub マージ キューに追加します",
"b169f943e1": "準備ができたらマージ",
"62703b1dc4": "このPRでは GitHub 自動マージが有効になっています",
"48d75ae118": "自動マージを無効にする"
"48d75ae118": "自動マージを無効にする",
"a5b66afb58": "チェックは通過しました",
"fbd4f57f0a": "チェックは通過しました。マージ可否はマージ前に再確認されます。"
}
}
},

View File

@ -1629,7 +1629,9 @@
"331ebe1170": "GitHub 병합 대기열에 이 PR을 추가하세요.",
"b169f943e1": "준비되면 병합",
"62703b1dc4": "이 PR에 대해 GitHub 자동 병합이 활성화되었습니다.",
"48d75ae118": "자동 병합 비활성화"
"48d75ae118": "자동 병합 비활성화",
"a5b66afb58": "검사 통과",
"fbd4f57f0a": "검사를 통과했습니다. 병합 전에 병합 가능 여부를 다시 확인합니다."
}
}
},

View File

@ -1629,7 +1629,9 @@
"331ebe1170": "将此PR添加到 GitHub 合并队列",
"b169f943e1": "准备好后合并",
"62703b1dc4": "为此PR启用了 GitHub 自动合并",
"48d75ae118": "禁用自动合并"
"48d75ae118": "禁用自动合并",
"a5b66afb58": "检查已通过",
"fbd4f57f0a": "检查已通过。合并资格将在合并前再次验证。"
}
}
},