Skip to content
This repository has been archived by the owner on Oct 5, 2023. It is now read-only.

Commit

Permalink
Merge pull request #93 from socialcast/webhook-friendliness
Browse files Browse the repository at this point in the history
Webhook friendliness
  • Loading branch information
seanwalbran committed Feb 22, 2016
2 parents 93b5a7f + 188144e commit 2b1f846
Show file tree
Hide file tree
Showing 11 changed files with 783 additions and 260 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ tmtags
coverage
rdoc
pkg
.byebug_history

#bundler
Gemfile.lock
Expand Down
12 changes: 11 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ Test the token with the [`git findpr`](https://github.com/socialcast/socialcast-

### Options
* ```--quiet```: suppress posting message in Socialcast
* config/scgitx.yml option `share_via_pr_comments`: Set to `true` to post reviewrequest and integration messages
as pull request comments instead of Socialcast posts.

## git start <new_branch_name (optional)>

Expand All @@ -50,9 +52,17 @@ Find pull requests on github including a given commit

List branches merged into remote origin/`branch` and not also merged into origin/`base_branch`

## git createpr

create a pull request on github for the current branch, without assigning it for review.

## git reviewrequest

create a pull request on github for peer review of the current branch.
create and assign a pull request on github for peer review of the current branch. See `assignpr` for additional options.

## git assignpr

assign the pull request on github for the current branch for peer review.

### Optional:
Specify a Review Buddy mapping that will reference the local Github username and @mention a pre-assigned review buddy in the Socialcast Review Request message. Specify the mapping by creating a .scgitx YML file relative to the Repo Root: config/scgitx.yml with the following format:
Expand Down
4 changes: 4 additions & 0 deletions bin/git-assignpr
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/usr/bin/env ruby

require File.join(File.dirname(__FILE__), '..', 'lib', 'socialcast-git-extensions', 'cli.rb')
Socialcast::Gitx::CLI.start (['assignpr'] + ARGV)
4 changes: 4 additions & 0 deletions bin/git-createpr
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/usr/bin/env ruby

require File.join(File.dirname(__FILE__), '..', 'lib', 'socialcast-git-extensions', 'cli.rb')
Socialcast::Gitx::CLI.start (['createpr'] + ARGV)
108 changes: 82 additions & 26 deletions lib/socialcast-git-extensions/cli.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,24 @@ def initialize(*args)
RestClient.log = Logger.new(STDOUT) if options[:trace]
end

desc "reviewrequest", "Create a pull request on github"
desc "createpr", "Create a pull request on github"
method_option :description, :type => :string, :aliases => '-d', :desc => 'pull request description'
# @see http://developer.github.com/v3/pulls/
def createpr
update unless @skip_update
description = options[:description] || editor_input(PULL_REQUEST_DESCRIPTION)
branch = current_branch
repo = current_repo
url = create_pull_request(branch, repo, description)['html_url']
say "Pull request created: #{url}"
end

desc "assignpr", "Assign the pull request on github for review"
method_option :additional_reviewers, :type => :string, :aliases => '-a', :desc => 'add additional reviewers to mention automatically, and skips the prompt'
method_option :skip_additional_reviewers, :type => :string, :aliases => '-s', :desc => 'Skips adding additional reviewers'
# @see http://developer.github.com/v3/pulls/
def reviewrequest(*additional_reviewers)
update
def assignpr(*additional_reviewers)
update unless @skip_update

primary_mention = if buddy = socialcast_review_buddy(current_user)
"assigned to @#{buddy}"
Expand All @@ -58,16 +69,34 @@ def reviewrequest(*additional_reviewers)
end
end

assignee = github_review_buddy(current_user)

description = options[:description] || editor_input(PULL_REQUEST_DESCRIPTION)
branch = current_branch
repo = current_repo
url = create_pull_request branch, repo, description, assignee
say "Pull request created: #{url}"
current_pr = current_pr_for_branch(repo, branch)
issue_url = current_pr['issue_url']
url = current_pr['html_url']

assignee = github_review_buddy(current_user)
assign_pull_request(assignee, issue_url) if assignee

review_message = ["#reviewrequest for #{branch} in #{current_repo}", "PR #{url} #{primary_mention}", '', description, '', secondary_mention, "/cc @#{developer_group} #scgitx", '', changelog_summary(branch)].compact.join("\n").gsub(/\n{2,}/, "\n\n")
post review_message, :message_type => 'review_request'
if use_pr_comments?
issue_message = ['#reviewrequest', primary_mention, secondary_mention, "\n/cc @#{developer_group} #scgitx"].compact.join(' ')
comment_on_issue(issue_url, issue_message)
else
review_message = ["#reviewrequest for #{branch} in #{current_repo}", "PR #{url} #{primary_mention}", '', current_pr['body'], '', secondary_mention, "/cc @#{developer_group} #scgitx", '', changelog_summary(branch)].compact.join("\n").gsub(/\n{2,}/, "\n\n")
post review_message, :message_type => 'review_request'
end
end

desc "reviewrequest", "Create and assign a pull request on github"
method_option :description, :type => :string, :aliases => '-d', :desc => 'pull request description'
method_option :additional_reviewers, :type => :string, :aliases => '-a', :desc => 'add additional reviewers to mention automatically, and skips the prompt'
method_option :skip_additional_reviewers, :type => :string, :aliases => '-s', :desc => 'Skips adding additional reviewers'
# @see http://developer.github.com/v3/pulls/
def reviewrequest(*additional_reviewers)
update
@skip_update = true
createpr
assignpr(*additional_reviewers)
end

desc "findpr", "Find pull requests including a given commit"
Expand Down Expand Up @@ -104,14 +133,21 @@ def backportpr(pull_request_num, maintenance_branch)
maintenance_branch_url = "https://github.com/#{repo}/tree/#{maintenance_branch}"
description = "Backport ##{pull_request_num} to #{maintenance_branch_url}\n***\n#{pull_request_data['body']}"

pull_request_url = create_pull_request(backport_branch, repo, description, assignee)
pr_hash = create_pull_request(backport_branch, repo, description)
assign_pull_request(assignee, pr_hash['issue_url']) if assignee

review_message = ["#reviewrequest backport ##{pull_request_num} to #{maintenance_branch} in #{current_repo} #scgitx"]
if socialcast_reviewer
review_message << "/cc @#{socialcast_reviewer} for #backport track"
reviewer_mention = "@#{socialcast_reviewer}" if socialcast_reviewer
if use_pr_comments?
issue_message = ['#reviewrequest backport', reviewer_mention, "/cc @#{developer_group} #scgitx"].compact.join(' ')
comment_on_issue(pr_hash['issue_url'], issue_message)
else
review_message = ["#reviewrequest backport ##{pull_request_num} to #{maintenance_branch} in #{current_repo} #scgitx"]
if socialcast_reviewer
review_message << "/cc #{reviewer_mention} for #backport track"
end
review_message << "/cc @#{developer_group}"
post review_message.join("\n\n"), :url => pr_hash['html_url'], :message_type => 'review_request'
end
review_message << "/cc @#{developer_group}"
post review_message.join("\n\n"), :url => pull_request_url, :message_type => 'review_request'
ensure
ENV['BASE_BRANCH'] = original_base_branch
end
Expand Down Expand Up @@ -192,12 +228,26 @@ def integrate(target_branch = prototype_branch)
integrate_branch(target_branch, prototype_branch) if target_branch == staging_branch
run_cmd "git checkout #{branch}"

message = <<-EOS.strip_heredoc
#worklog integrating #{branch} into #{target_branch} in #{current_repo} #scgitx
/cc @#{developer_group}
EOS
current_pr = begin
current_pr_for_branch(current_repo, current_branch)
rescue => e
say e.message.to_s
nil
end

post message.strip
say("WARNING: Unable to find current pull request. Use `git createpr` to create one.", :red) unless current_pr

if use_pr_comments? && current_pr
issue_message = "Integrated into #{target_branch}"
comment_on_issue(current_pr['issue_url'], issue_message) unless options[:quiet]
else
message = <<-EOS.strip_heredoc
#worklog integrating #{branch} into #{target_branch} in #{current_repo} #scgitx
/cc @#{developer_group}
EOS

post message.strip
end
end

desc 'promote', '(DEPRECATED) promote the current branch into staging'
Expand Down Expand Up @@ -264,12 +314,14 @@ def release
integrate_branch(base_branch, staging_branch)
cleanup

message = <<-EOS.strip_heredoc
#worklog releasing #{branch} to #{base_branch} in #{current_repo} #scgitx
/cc @#{developer_group}
EOS
unless use_pr_comments?
message = <<-EOS.strip_heredoc
#worklog releasing #{branch} to #{base_branch} in #{current_repo} #scgitx
/cc @#{developer_group}
EOS

post message.strip
post message.strip
end
end

private
Expand All @@ -282,6 +334,10 @@ def enforce_staging_before_release?
!!config['enforce_staging_before_release']
end

def use_pr_comments?
config['share_via_pr_comments'] == true
end

# post a message in socialcast
# skip sharing message if CLI quiet option is present
def post(message, params = {})
Expand Down
35 changes: 25 additions & 10 deletions lib/socialcast-git-extensions/github.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,21 +31,16 @@ def authorization_token
throw e
end

# returns the url of the created pull request
# @see http://developer.github.com/v3/pulls/
def create_pull_request(branch, repo, body, assignee)
def create_pull_request(branch, repo, body)
payload = {:title => branch, :base => base_branch, :head => branch, :body => body}.to_json
say "Creating pull request for "
say "#{branch} ", :green
say "against "
say "#{base_branch} ", :green
say "in "
say repo, :green
data = github_api_request("POST", "repos/#{repo}/pulls", payload)
assign_pull_request(branch, assignee, data) if assignee ## Unfortunately this needs to be done in a seperate request.

url = data['html_url']
url
github_api_request("POST", "repos/#{repo}/pulls", payload)
end

# find the PRs matching the given commit hash
Expand All @@ -56,13 +51,33 @@ def pull_requests_for_commit(repo, commit_hash)
github_api_request "GET", "search/issues?q=#{query}"
end

def assign_pull_request(branch, assignee, data)
issue_payload = { :title => branch, :assignee => assignee }.to_json
github_api_request "PATCH", data['issue_url'], issue_payload
# find the PRs for a given branch
# https://developer.github.com/v3/pulls/#list-pull-requests
def pull_requests_for_branch(repo, branch)
head_name = "#{repo.split('/').first}:#{branch}"
github_api_request "GET", "repos/#{repo}/pulls?head=#{head_name}"
end

# find the current PR for a given branch
def current_pr_for_branch(repo, branch)
prs = pull_requests_for_branch(repo, branch)
raise "Multiple (#{prs.size}) open PRs for #{branch} found in #{repo}, unable to proceed" if prs.size > 1
prs.first
end

def assign_pull_request(assignee, issue_url)
issue_payload = { :assignee => assignee }.to_json
github_api_request "PATCH", issue_url, issue_payload
rescue => e
say "Failed to assign pull request: #{e.message}", :red
end

# post a comment on an issue
# https://developer.github.com/v3/issues/comments/#create-a-comment
def comment_on_issue(issue_url, comment_body)
github_api_request 'POST', "#{issue_url}/comments", { :body => comment_body }.to_json
end

# @returns [String] socialcast username to assign the review to
# @returns [nil] when no buddy system configured or user not found
def socialcast_review_buddy(current_user)
Expand Down
2 changes: 1 addition & 1 deletion lib/socialcast-git-extensions/version.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
module Socialcast
module Gitx
VERSION = "3.3"
VERSION = "4.0"
end
end
3 changes: 2 additions & 1 deletion socialcast-git-extensions.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,14 @@ Gem::Specification.new do |s|

s.add_runtime_dependency 'rugged', '>= 0.23'
s.add_runtime_dependency 'socialcast', '~> 1.3.0'
s.add_runtime_dependency 'activesupport', '~> 4.0'
s.add_runtime_dependency 'activesupport', '>= 4.0'
s.add_runtime_dependency 'rest-client', '~> 1.7'
s.add_runtime_dependency 'thor', '~> 0.19.1'
s.add_runtime_dependency 'rake', '~> 10.3'
s.add_development_dependency 'rspec', '~> 3.0'
s.add_development_dependency 'pry', '~> 0.9.12.6'
s.add_development_dependency 'webmock', '~> 1.21'
s.add_development_dependency 'byebug'

s.files = `git ls-files`.split("\n")
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
Expand Down
Loading

0 comments on commit 2b1f846

Please sign in to comment.