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
|
# File 'lib/tutter/action/sppuppet.rb', line 20
def run
if @data['action'] == 'opened' && @settings['post_instructions']
issue = @data['number']
= @settings['instructions'] || "To merge at least #{@settings['plus_ones_required']} person other than the submitter needs to write a comment with saying _+1_ or :+1:. Then write _!merge_ or :shipit: to trigger the merging."
begin
@client.(@project, issue, )
return 200, "Commented!"
rescue Octokit::NotFound
return 404, "Octokit returned 404, this could be an issue with your access token"
rescue Octokit::Unauthorized
return 401, "Authorization to #{@project} failed, please verify your access token"
rescue Octokit::TooManyLoginAttempts
return 429, "Account for #{@project} has been temporary locked down due to to many failed login attempts"
end
end
if @data['action'] != 'created'
return 200, 'not a new comment, skipping'
end
pull_request_id = @data['issue']['number']
pr = @client.pull_request @project, pull_request_id
plus_one = {}
merge = false
if pr.mergeable_state != 'clean'
return 200, "merge state for #{@project} #{pull_request_id} is not clean. Current state: #{pr.mergeable_state}"
end
if pr. == 0
return 200, 'no comments, skipping'
end
return 200, 'merge state not clean' unless pr.mergeable
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 /^(\+1|:\+1)/.match i.body
unless pr.user.login == i.attrs[:user].attrs[:login]
plus_one[i.attrs[:user].attrs[:login]] = 1
end
end
if /^(\-1|:\-1:)/.match i.body
return 200, "#{@project} #{pull_request_id} has a -1. I will not take the blame"
end
end
merge = (.last.body == '!merge' || .last.body.starts_with?(':shipit:'))
if plus_one.count >= @settings['plus_ones_required'] && merge
json = { url: pr.html_url,
title: pr.title,
author: pr.user.login,
description: pr.body,
commits: @client.pull_request_commits(@project, pr.number).map { |c| { author: c.author.login, 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: plus_one.keys,
deployer: .last.user.login }
json[:merge_sha] = @client.merge_pull_request(@project, pull_request_id, 'SHIPPING!!').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}"
elsif plus_one.count >= @settings['plus_ones_required']
return 200, "have enough +1, but no merge command"
else
return 200, "not enough +1, have #{plus_one.count} but need #{@settings['plus_ones_required']}"
end
end
|