codetether_agent/github_pr/
autopilot.rs1use serde::{Deserialize, Serialize};
4
5#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
7#[serde(rename_all = "snake_case")]
8pub enum PrLifecycle {
9 Draft,
10 CiRunning,
11 CiFailed,
12 Fixing,
13 CiGreen,
14 AwaitingReview,
15 ReviewCommentsReceived,
16 AddressingComments,
17 ReadyToMerge,
18 Merged,
19 Failedterminal,
20}
21
22#[derive(Debug, Clone)]
24pub struct AutopilotConfig {
25 pub issue_number: Option<u64>,
26 pub branch_prefix: String,
27 pub max_fix_iterations: usize,
28 pub poll_interval_secs: u64,
29 pub auto_merge: bool,
30}
31
32impl Default for AutopilotConfig {
33 fn default() -> Self {
34 Self {
35 issue_number: None,
36 branch_prefix: "autopilot".to_string(),
37 max_fix_iterations: 5,
38 poll_interval_secs: 30,
39 auto_merge: false,
40 }
41 }
42}
43
44pub fn advance_lifecycle(
46 current: &PrLifecycle,
47 ci_green: bool,
48 has_review_comments: bool,
49) -> PrLifecycle {
50 match current {
51 PrLifecycle::Draft => PrLifecycle::CiRunning,
52 PrLifecycle::CiRunning if ci_green => PrLifecycle::CiGreen,
53 PrLifecycle::CiRunning => PrLifecycle::CiFailed,
54 PrLifecycle::CiFailed => PrLifecycle::Fixing,
55 PrLifecycle::Fixing => PrLifecycle::CiRunning,
56 PrLifecycle::CiGreen if has_review_comments => PrLifecycle::ReviewCommentsReceived,
57 PrLifecycle::CiGreen => PrLifecycle::AwaitingReview,
58 PrLifecycle::ReviewCommentsReceived => PrLifecycle::AddressingComments,
59 PrLifecycle::AddressingComments => PrLifecycle::CiRunning,
60 PrLifecycle::AwaitingReview if has_review_comments => PrLifecycle::ReviewCommentsReceived,
61 PrLifecycle::AwaitingReview => PrLifecycle::ReadyToMerge,
62 other => other.clone(),
63 }
64}