lib/tutter/action/sppuppet.rb in tutter-sppuppet-0.0.21 vs lib/tutter/action/sppuppet.rb in tutter-sppuppet-0.0.22
- old
+ new
@@ -20,103 +20,138 @@
# Not a new comment, ignore
return 200, 'not a new comment, skipping'
end
pull_request_id = @data['issue']['number']
- pr = @client.pull_request @project, pull_request_id
- votes = {}
- merge = (@data['comment']['body'] == '!merge' ||
+ merge_command = (@data['comment']['body'] == '!merge' ||
@data['comment']['body'].start_with?(':shipit:'))
- return 200, 'Not a merge comment' unless merge
+ return 200, 'Not a merge comment' unless merge_command
- unless pr.mergeable_state == 'clean'
- msg = "Merge state for is not clean. Current state: #{pr.mergeable_state}\nHave the tests finished running?"
- @client.add_comment(@project, pull_request_id, msg)
+ return maybe_merge(pull_request_id, true)
+
+ when 'status'
+ return 200, 'Merge state not clean' unless @data['state'] == 'success'
+ commit_sha = @data['commit']['sha']
+ @client.pull_requests(@project).each do |pr|
+ return maybe_merge(pr.number,false) if pr.head.sha == commit_sha
+ end
+ return 200, "Found no pull requests matching #{commit_sha}"
+
+ when 'pull_request'
+ # If a new pull request is opened, comment with instructions
+ if @data['action'] == 'opened' && @settings['post_instructions']
+ issue = @data['number']
+ comment = @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."
+ return post_comment(issue, comment)
+ else
+ return 200, 'Not posting instructions'
+ end
+ else
+ return 200, "Unhandled event type #{@event}"
+ end
+ end
+
+ def maybe_merge(pull_request_id, merge_command)
+ votes = {}
+ merger = nil
+ pr = @client.pull_request @project, pull_request_id
+
+ unless pr.mergeable_state == 'clean'
+ 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\''
+ if merge_command
+ return post_comment(pull_request_id, msg + reassure)
+ else
return 200, msg
end
+ end
- # We fetch the latest commit and it's date.
- last_commit = @client.pull_request_commits(@project, pull_request_id).last
- last_commit_date = last_commit.commit.committer.date
+ # We fetch the latest commit and it's date.
+ last_commit = @client.pull_request_commits(@project, pull_request_id).last
+ last_commit_date = last_commit.commit.committer.date
- comments = @client.issue_comments(@project, pull_request_id)
+ comments = @client.issue_comments(@project, pull_request_id)
- # Check each comment for +1 and merge comments
- comments.each do |i|
- # Comment is older than last commit.
- # We only want to check for +1 in newer comments
- next if last_commit_date > i.created_at
+ # Check each comment for +1 and merge comments
+ comments.each do |i|
+ # Comment is older than last commit.
+ # We only want to check newer comments
+ next if last_commit_date > i.created_at
- match = /^:?([+-])1:?/.match(i.body)
- if match
- score = match[1] == '+' ? 1 : -1
- # pull request submitter cant +1
- unless pr.user.login == i.attrs[:user].attrs[:login]
- votes[i.attrs[:user].attrs[:login]] = score
- end
+ if (i.body == '!merge' || i.body.start_with?(':shipit:'))
+ merger ||= i.attrs[:user]
+ # Count as a +1 if it is not the author
+ unless pr.user.login == i.attrs[:user].attrs[:login]
+ votes[i.attrs[:user].attrs[:login]] = 1
end
end
- num_votes = votes.values.reduce(0) { |a, e| a + e }
- if num_votes < @settings['plus_ones_required']
- msg = "Not enough plus ones. #{@settings['plus_ones_required']} required, and only have #{num_votes}"
- @client.add_comment(@project, pull_request_id, msg)
- return 200, msg
+ match = /^:?([+-])1:?/.match(i.body)
+ if match
+ score = match[1] == '+' ? 1 : -1
+ # pull request submitter cant +1
+ unless pr.user.login == i.attrs[:user].attrs[:login]
+ votes[i.attrs[:user].attrs[:login]] = score
+ end
end
+ end
- json = { url: pr.url,
- title: pr.title,
- author: 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: comments.last.user.login }
- # TODO: Word wrap description
- merge_msg = <<MERGE_MSG
+ 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']
+ msg = "Not enough plus ones. #{@settings['plus_ones_required']} required, and only have #{num_votes}"
+ return post_comment(pull_request_id, msg)
+ end
+
+ json = { url: pr.url,
+ title: pr.title,
+ author: 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 }
+ # TODO: Word wrap description
+ merge_msg = <<MERGE_MSG
Title: #{pr.title}
-Description: #{pr.body}
Author: #{pr.user.login}
Reviewers: #{votes.keys.join ', '}
-Deployer: #{comments.last.user.login}
+Deployer: #{merger}
URL: #{pr.url}
+
+#{pr.body}
MERGE_MSG
- begin
- merge_commit = @client.merge_pull_request(@project, pull_request_id, merge_msg)
- rescue Octokit::MethodNotAllowed => e
- return 200, "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}"
- when 'pull_request'
- # If a new pull request is opened, comment with instructions
- if @data['action'] == 'opened' && @settings['post_instructions']
- issue = @data['number']
- comment = @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.add_comment(@project, issue, comment)
- 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
- else
- return 200, 'Not posting instructions'
- end
- else
- return 200, "Unhandled event type #{@event}"
+ begin
+ merge_commit = @client.merge_pull_request(@project, pull_request_id, merge_msg)
+ rescue Octokit::MethodNotAllowed => e
+ return post_comment(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
+
+ def post_comment(issue, comment)
+ begin
+ @client.add_comment(@project, issue, comment)
+ return 200, "Commented:\n" + comment
+ 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
+
end