Module: Wralph::Run::IterateCI

Defined in:
lib/wralph/run/iterate_ci.rb

Constant Summary collapse

MAX_RETRIES =
10

Class Method Summary collapse

Class Method Details

.run(issue_number, pr_number = nil) ⇒ Object



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/wralph/run/iterate_ci.rb', line 15

def self.run(issue_number, pr_number = nil)
  branch_name = "issue-#{issue_number}".freeze
  pr_number ||= begin
    stdout, = Interfaces::Shell.run_command("gh pr list --head #{branch_name} --json number -q '.[0].number'")
    pr_num = stdout.strip
    pr_num.empty? || pr_num == 'null' ? nil : pr_num
  end

  stdout, = Interfaces::Shell.run_command('git branch --show-current')
  current_branch = stdout.strip
  if current_branch != branch_name
    Interfaces::Print.error "You are not on the branch #{branch_name}. Please switch to the branch #{branch_name} and try again."
    exit 1
  end

  if pr_number.nil?
    Interfaces::Print.error "Could not determine PR number from the branch name."
    exit 1
  end

  plan_file = Interfaces::Repo.plan_file(issue_number)

  api_token = Interfaces::Ci.api_token
  if api_token.nil? || api_token.empty?
    Interfaces::Print.error 'ci_api_token is not set in .wralph/secrets.yaml'
    Interfaces::Print.error ''
    Interfaces::Print.error 'Please add your CircleCI API token to .wralph/secrets.yaml:'
    Interfaces::Print.error '  ci_api_token: your-token-here'
    exit 1
  else
    Interfaces::Print.success 'Loaded CI API token from .wralph/secrets.yaml'
  end
  retry_count = 0

  # Get repository info
  repo_owner, = Interfaces::Shell.run_command('gh repo view --json owner -q .owner.login')
  repo_name, = Interfaces::Shell.run_command('gh repo view --json name -q .name')

  # Ensure tmp directory exists
  FileUtils.mkdir_p(Interfaces::Repo.tmp_dir)

  while retry_count < MAX_RETRIES
    Interfaces::Print.info "Iteration #{retry_count + 1}/#{MAX_RETRIES}"

    # Wait for build to complete
    if Interfaces::Ci.wait_for_build(pr_number, repo_owner, repo_name, api_token)
      Interfaces::Print.success "CircleCI build passed! Issue ##{issue_number} has been successfully solved."
      return true
    end

    # Build failed, get failure details
    Interfaces::Print.warning 'Build failed. Analyzing failures...'
    failure_details = Interfaces::Ci.build_failures(pr_number, repo_owner, repo_name, api_token) || 'Could not fetch failure details'

    Interfaces::Print.info 'Failure details:'
    puts failure_details

    retry_count += 1

    if retry_count >= MAX_RETRIES
      Interfaces::Print.error "Maximum retry count (#{MAX_RETRIES}) reached. Please fix the issues manually."
      exit 1
    end

    # Store the failure details in a new file for each iteration
    filename = Interfaces::Repo.failure_details_file(branch_name, retry_count)
    File.write(filename, failure_details)

    # Fix the issues
    Interfaces::Print.info "Attempting to fix the issues (attempt #{retry_count}/#{MAX_RETRIES})..."

    fix_instructions = "      The CircleCI build for PR #\#{pr_number} has failed. The failure details have been logged into the following file:\n\n      \#{filename}\n\n      Do as follows:\n      1. Review your original plan that you documented in the plan file: `\#{plan_file}`\n      2. Analyze the failures above\n      3. Make the necessary changes to fix the issues\n      4. Commit and push the changes to the PR branch\n      5. After pushing, output \"FIXES_PUSHED\" so I know you've completed the fixes\n\n      The PR branch is: `issue-\#{issue_number}`\n    FIX_INSTRUCTIONS\n\n    # Pass fix instructions to claude code\n    fix_output = Interfaces::Agent.run(fix_instructions)\n    puts \"FIX_OUTPUT: \#{fix_output}\"\n\n    # Check if fixes were pushed\n    if fix_output.include?('FIXES_PUSHED')\n      Interfaces::Print.success 'Fixes have been pushed. Waiting before checking build status again...'\n      sleep 60 # Wait a bit for CircleCI to pick up the new commit\n    else\n      Interfaces::Print.error 'Could not confirm that fixes were pushed. Please check manually.'\n      exit 1\n    end\n  end\n\n  Interfaces::Print.error \"Failed to resolve CircleCI build issues after \#{MAX_RETRIES} attempts\"\n  exit 1\nend\n"