mirror of
https://github.com/stablyai/orca.git
synced 2026-11-14 01:47:24 +00:00
141 lines
4.1 KiB
TypeScript
141 lines
4.1 KiB
TypeScript
import { getProviderChecksOutcome } from '../source-control/checks/provider-check-summary'
|
|
import type { CheckStatus, ProviderCheckSummary } from './pull-request-types'
|
|
import {
|
|
canShowGitHubPRAutoMergeControl,
|
|
type GitHubPRAutoMergeAvailabilityInput
|
|
} from './pull-request-auto-merge-availability'
|
|
|
|
export type GitHubPRMergeStateInput = GitHubPRAutoMergeAvailabilityInput & {
|
|
checksStatus?: CheckStatus
|
|
checksSummary?: ProviderCheckSummary
|
|
}
|
|
|
|
export type GitHubPRMergeStateKind =
|
|
| 'merged'
|
|
| 'closed'
|
|
| 'draft'
|
|
| 'review_required'
|
|
| 'changes_requested'
|
|
| 'conflicts'
|
|
| 'merge_queue'
|
|
| 'merge_queue_auto_merge_on'
|
|
| 'merge_status_unavailable'
|
|
| 'behind'
|
|
| 'blocked'
|
|
| 'mergeable_checks_failed'
|
|
| 'mergeable_checks_pending'
|
|
| 'mergeable_checks_passed'
|
|
| 'mergeable'
|
|
| 'checks_passed'
|
|
| 'checking'
|
|
|
|
export type GitHubPRAutoMergeActionIntent =
|
|
| 'disable_auto_merge'
|
|
| 'merge_when_ready'
|
|
| 'enable_auto_merge'
|
|
|
|
export type GitHubPRMergeStateDecision = {
|
|
kind: GitHubPRMergeStateKind
|
|
directMergeAvailable: boolean
|
|
autoMergeAction: GitHubPRAutoMergeActionIntent | null
|
|
}
|
|
|
|
function checksState(item: GitHubPRMergeStateInput): CheckStatus | 'none' | undefined {
|
|
if (item.checksSummary) {
|
|
const outcome = item.checksStatus
|
|
? getProviderChecksOutcome(item.checksSummary, item.checksStatus)
|
|
: getProviderChecksOutcome(item.checksSummary)
|
|
return outcome === 'cancelled' ? 'failure' : outcome
|
|
}
|
|
return item.checksStatus
|
|
}
|
|
|
|
function hasFullMergeMetadata(item: GitHubPRMergeStateInput): boolean {
|
|
return item.mergeable !== undefined || item.mergeStateStatus !== undefined
|
|
}
|
|
|
|
function resolveAutoMergeAction(
|
|
item: GitHubPRMergeStateInput
|
|
): GitHubPRAutoMergeActionIntent | null {
|
|
if (!canShowGitHubPRAutoMergeControl(item)) {
|
|
return null
|
|
}
|
|
if (item.autoMergeEnabled === true) {
|
|
return 'disable_auto_merge'
|
|
}
|
|
if (item.mergeQueueRequired === true) {
|
|
return 'merge_when_ready'
|
|
}
|
|
return 'enable_auto_merge'
|
|
}
|
|
|
|
function resolveMergeStateKind(item: GitHubPRMergeStateInput): GitHubPRMergeStateKind {
|
|
if (item.state === 'merged') {
|
|
return 'merged'
|
|
}
|
|
if (item.state === 'closed') {
|
|
return 'closed'
|
|
}
|
|
if (item.state === 'draft') {
|
|
return 'draft'
|
|
}
|
|
if (item.reviewDecision === 'REVIEW_REQUIRED') {
|
|
return 'review_required'
|
|
}
|
|
if (item.reviewDecision === 'CHANGES_REQUESTED') {
|
|
return 'changes_requested'
|
|
}
|
|
if (item.mergeable === 'CONFLICTING' || item.mergeStateStatus === 'DIRTY') {
|
|
return 'conflicts'
|
|
}
|
|
if (item.mergeQueueRequired === true) {
|
|
return item.autoMergeEnabled ? 'merge_queue_auto_merge_on' : 'merge_queue'
|
|
}
|
|
const checkState = checksState(item)
|
|
if (!hasFullMergeMetadata(item)) {
|
|
// Missing metadata can coexist with green checks; main-process preflight remains the merge authority.
|
|
return checkState === 'success' ? 'checks_passed' : 'merge_status_unavailable'
|
|
}
|
|
if (item.mergeStateStatus === 'BEHIND') {
|
|
return 'behind'
|
|
}
|
|
if (item.mergeStateStatus === 'BLOCKED') {
|
|
return 'blocked'
|
|
}
|
|
if (
|
|
item.mergeable === 'MERGEABLE' ||
|
|
item.mergeStateStatus === 'CLEAN' ||
|
|
item.mergeStateStatus === 'UNSTABLE' ||
|
|
item.mergeStateStatus === 'HAS_HOOKS'
|
|
) {
|
|
if (checkState === 'failure') {
|
|
return 'mergeable_checks_failed'
|
|
}
|
|
if (checkState === 'pending') {
|
|
return 'mergeable_checks_pending'
|
|
}
|
|
return checkState === 'success' ? 'mergeable_checks_passed' : 'mergeable'
|
|
}
|
|
// Main-process preflight rechecks blockers when GitHub mergeability is still intermediate despite green checks.
|
|
return checkState === 'success' ? 'checks_passed' : 'checking'
|
|
}
|
|
|
|
const DIRECT_MERGE_KINDS: ReadonlySet<GitHubPRMergeStateKind> = new Set([
|
|
'mergeable_checks_failed',
|
|
'mergeable_checks_pending',
|
|
'mergeable_checks_passed',
|
|
'mergeable',
|
|
'checks_passed'
|
|
])
|
|
|
|
export function resolveGitHubPRMergeState(
|
|
item: GitHubPRMergeStateInput
|
|
): GitHubPRMergeStateDecision {
|
|
const kind = resolveMergeStateKind(item)
|
|
return {
|
|
kind,
|
|
directMergeAvailable: DIRECT_MERGE_KINDS.has(kind),
|
|
autoMergeAction: resolveAutoMergeAction(item)
|
|
}
|
|
}
|