diff --git a/src/renderer/src/components/github-pr-merge-state.test.ts b/src/renderer/src/components/github-pr-merge-state.test.ts index f71fc03d2..d8443dc77 100644 --- a/src/renderer/src/components/github-pr-merge-state.test.ts +++ b/src/renderer/src/components/github-pr-merge-state.test.ts @@ -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 diff --git a/src/renderer/src/components/github-pr-merge-state.ts b/src/renderer/src/components/github-pr-merge-state.ts index 071e02705..321125615 100644 --- a/src/renderer/src/components/github-pr-merge-state.ts +++ b/src/renderer/src/components/github-pr-merge-state.ts @@ -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, diff --git a/src/renderer/src/i18n/locales/en.json b/src/renderer/src/i18n/locales/en.json index 74a6e581f..a28c9ac11 100644 --- a/src/renderer/src/i18n/locales/en.json +++ b/src/renderer/src/i18n/locales/en.json @@ -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." } } }, diff --git a/src/renderer/src/i18n/locales/es.json b/src/renderer/src/i18n/locales/es.json index 81cb45855..9e8ddf91e 100644 --- a/src/renderer/src/i18n/locales/es.json +++ b/src/renderer/src/i18n/locales/es.json @@ -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." } } }, diff --git a/src/renderer/src/i18n/locales/ja.json b/src/renderer/src/i18n/locales/ja.json index ebb3e6827..2df99b634 100644 --- a/src/renderer/src/i18n/locales/ja.json +++ b/src/renderer/src/i18n/locales/ja.json @@ -1629,7 +1629,9 @@ "331ebe1170": "このPRを GitHub マージ キューに追加します", "b169f943e1": "準備ができたらマージ", "62703b1dc4": "このPRでは GitHub 自動マージが有効になっています", - "48d75ae118": "自動マージを無効にする" + "48d75ae118": "自動マージを無効にする", + "a5b66afb58": "チェックは通過しました", + "fbd4f57f0a": "チェックは通過しました。マージ可否はマージ前に再確認されます。" } } }, diff --git a/src/renderer/src/i18n/locales/ko.json b/src/renderer/src/i18n/locales/ko.json index cece5c20d..b5d964e9c 100644 --- a/src/renderer/src/i18n/locales/ko.json +++ b/src/renderer/src/i18n/locales/ko.json @@ -1629,7 +1629,9 @@ "331ebe1170": "GitHub 병합 대기열에 이 PR을 추가하세요.", "b169f943e1": "준비되면 병합", "62703b1dc4": "이 PR에 대해 GitHub 자동 병합이 활성화되었습니다.", - "48d75ae118": "자동 병합 비활성화" + "48d75ae118": "자동 병합 비활성화", + "a5b66afb58": "검사 통과", + "fbd4f57f0a": "검사를 통과했습니다. 병합 전에 병합 가능 여부를 다시 확인합니다." } } }, diff --git a/src/renderer/src/i18n/locales/zh.json b/src/renderer/src/i18n/locales/zh.json index e257e257c..e40a79a91 100644 --- a/src/renderer/src/i18n/locales/zh.json +++ b/src/renderer/src/i18n/locales/zh.json @@ -1629,7 +1629,9 @@ "331ebe1170": "将此PR添加到 GitHub 合并队列", "b169f943e1": "准备好后合并", "62703b1dc4": "为此PR启用了 GitHub 自动合并", - "48d75ae118": "禁用自动合并" + "48d75ae118": "禁用自动合并", + "a5b66afb58": "检查已通过", + "fbd4f57f0a": "检查已通过。合并资格将在合并前再次验证。" } } },