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
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')
FileUtils.mkdir_p(Interfaces::Repo.tmp_dir)
while retry_count < MAX_RETRIES
Interfaces::Print.info "Iteration #{retry_count + 1}/#{MAX_RETRIES}"
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
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
filename = Interfaces::Repo.failure_details_file(branch_name, retry_count)
File.write(filename, failure_details)
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"
|