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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
|
# File 'lib/tutter/action/sppuppet.rb', line 55
def maybe_merge(pull_request_id, merge_command)
votes = {}
merger = nil
incident_merge_override = false
pr = @client.pull_request @project, pull_request_id
last_commit = @client.pull_request_commits(@project, pull_request_id).last
last_commit_date = last_commit.commit.committer.date
= @client.(@project, pull_request_id)
.each do |i|
next if last_commit_date > i.created_at
if i.body == '!merge' || i.body.start_with?(':shipit:') || i.body.start_with?(':ship:')
merger ||= i.attrs[:user].attrs[:login]
unless pr.user.login == i.attrs[:user].attrs[:login]
votes[i.attrs[:user].attrs[:login]] = 1
end
end
match = /^(:?([+-])1:?|LGTM)/.match(i.body)
if match
score = match[1] == '+' ? 1 : -1
unless pr.user.login == i.attrs[:user].attrs[:login]
votes[i.attrs[:user].attrs[:login]] = score
end
end
match = /^(:poop:|:hankey:|-2)/.match(i.body)
if match
msg = "Commit cannot be merged so long as a -2 comment appears in the PR."
return (pull_request_id, msg)
end
if /jira.*INCIDENT/.match(i.body)
incident_merge_override = true
end
end
if pr.mergeable_state != 'clean' && !incident_merge_override
msg = "Merge state for is not clean. Current state: #{pr.mergeable_state}\n"
reassure = "I will try to merge this for you when the builds turn green\n" +
"If your build fails or becomes stuck for some reason, just say 'rebuild'\n" +
'If you have an incident and want to skip the tests or the peer review, please post the link to the jira ticket.'
if merge_command
return (pull_request_id, msg + reassure)
else
return 200, msg
end
end
return 200, 'No merge comment found' unless merger
num_votes = votes.values.reduce(0) { |a, e| a + e }
if num_votes < @settings['plus_ones_required'] && !incident_merge_override
msg = "Not enough plus ones. #{@settings['plus_ones_required']} required, and only have #{num_votes}"
return (pull_request_id, msg)
end
json = { url: pr.url,
title: pr.title,
opened_by: pr.user.login,
description: pr.body,
commits: @client.pull_request_commits(@project, pr.number).map { |c| { author: c.author, message: c.commit.message, sha: c.commit.tree.sha } },
head_sha: pr.head.sha,
tests: @client.combined_status(@project, pr.head.sha).statuses.map { |s| {state: s.state, url: s.target_url, description: s.description } },
reviewers: votes.keys,
deployer: merger }
merge_msg = "Title: \#{pr.title}\nOpened by: \#{pr.user.login}\nReviewers: \#{votes.keys.join ', '}\nDeployer: \#{merger}\nURL: \#{pr.url}\nTests: \#{@client.combined_status(@project, pr.head.sha).statuses.map { |s| [s.state, s.description, s.target_url].join(\", \") }.join(\"\\n \")}\n\n\#{pr.body}\n"
if incident_merge_override
@client.add_labels_to_an_issue @project, pull_request_id, ['incident']
end
begin
merge_commit = @client.merge_pull_request(@project, pull_request_id, merge_msg)
rescue Octokit::MethodNotAllowed => e
return (pull_request_id, "Pull request not mergeable: #{e.message}")
end
puts merge_commit.inspect
json[:merge_sha] = merge_commit.sha
report_directory = "#{@settings['reports_dir']}/#{merge_commit.sha[0..1]}/#{merge_commit.sha[2..3]}"
report_path = "#{report_directory}/#{merge_commit.sha}.json"
if @settings['generate_reports']
FileUtils.mkdir_p report_directory
File.open(report_path, 'w') { |f| f.write(JSON.pretty_generate(json)) }
end
return 200, "merging #{pull_request_id} #{@project}"
end
|