Skip to content

Commit

Permalink
[Issue reenhanced#149] Fix for PR ending as "Closed" instead of "Merg…
Browse files Browse the repository at this point in the history
…ed" - Calling Github API to Squash Merge the PR as opposed doing it manually
  • Loading branch information
simonzhu24 committed May 2, 2016
1 parent 7925721 commit 26a5868
Show file tree
Hide file tree
Showing 8 changed files with 230 additions and 132 deletions.
28 changes: 10 additions & 18 deletions README.rdoc
Original file line number Diff line number Diff line change
Expand Up @@ -205,9 +205,9 @@ You kick butt. You've got your code reviewed and now you're ready to merge it do
Reflow's +deliver+ requires you to have a pull request, so you'll be protected on those mornings when the coffee isn't working yet.
We built this <b>to get in your way and make you follow the process</b>. If you don't like it, do it by hand. You already know what you're doing.

You'll be presented with a prefilled commit message based on the body of your pull request which includes the text <code>Closes #XX</code> that will automatically close the associated pull request on github when deliver completes.
You'll be presented with a prefilled commit message based on the body of your pull request which includes the text <code>Merges #XX</code> that will automatically merge the associated pull request on github when deliver completes.

Make a mistake and deliver too early? It happens. You'll be prompted after you edit your commit message if you want to push your updated +master+ to github. If you answer 'n', then you'll want to do <code>git reset --hard origin/master</code> and checkout your branch again.
Want to clean up your feature branch afterwards? You'll be prompted after you edit your commit message if you want to clean up your +feature_branch+ on github. If you answer 'n', then your feature_branch will exist for you to clean it up later.

This is what it looks like:
$ git reflow deliver
Expand Down Expand Up @@ -276,25 +276,17 @@ This is what we do behind the scenes when you do +deliver+

If the review is done, it's time to merge. Here's what happens:

First, update our local +master+ so we don't get conflicts
git checkout master
git pull origin master
First, we call the github_api gem to merge the pull request

Next, squash merge our feature branch
git merge --squash nh-branch-name
Next, we prompt you if you want to deploy and cleanup
Would you like cleanup your feature branch?

Now, we'll apply a little magic so we have a great commit message by default. Your editor will open and you'll see a nice default for your commit message based on the pull request body.

Once you've saved the commit, prompt the user to see if we should continue
Merge complete!
Would you like to push this branch to your remote repo and cleanup your feature branch?

If 'y', then we'll push to +master+ and delete the feature branch
git push origin master
git push origin :nh-branch-name
git branch -D nh-branch-name
If 'y', then we'll update the +master+ and delete the feature branch
git pull origin #{base_branch}
git push origin :#{feature_branch}
git branch -D #{feature_branch}

If 'n', then just stop here. The user can reset his local +master+.
If 'n', then just stop here. The user can clean up his branch locally.

And we're done.

Expand Down
39 changes: 22 additions & 17 deletions lib/git_reflow.rb
Original file line number Diff line number Diff line change
Expand Up @@ -107,10 +107,6 @@ def deliver(options = {})
feature_branch = current_branch
base_branch = options['base'] || 'master'

update_current_branch
fetch_destination(base_branch)
update_destination(feature_branch)

begin
existing_pull_request = git_server.find_open_pull_request( :from => current_branch, :to => base_branch )

Expand All @@ -127,32 +123,41 @@ def deliver(options = {})
if existing_pull_request.good_to_merge?(force: options['skip_lgtm'])
puts "Merging pull request ##{existing_pull_request.number}: '#{existing_pull_request.title}', from '#{existing_pull_request.feature_branch_name}' into '#{existing_pull_request.base_branch_name}'"

update_destination(base_branch)
merge_feature_branch(feature_branch,
:destination_branch => base_branch,
:pull_request_number => existing_pull_request.number,
:lgtm_authors => existing_pull_request.approvals,
:message => commit_message)
committed = run_command_with_label 'git commit', with_system: true
res = existing_pull_request.merge_feature_branch(
feature_branch,
:destination_branch => base_branch,
:pull_request_number => existing_pull_request.number,
:lgtm_authors => existing_pull_request.approvals,
:title => existing_pull_request.title,
:message => commit_message,
:head => existing_pull_request.head
)

if committed
say "Merge complete!", :success
if res.code == "200"
# if committed
say "Pull Request successfully merged.", :success

# check if user always wants to push and cleanup, otherwise ask
always_deploy_and_cleanup = GitReflow::Config.get('reflow.always-deploy-and-cleanup') == "true"
deploy_and_cleanup = always_deploy_and_cleanup || (ask "Would you like to push this branch to your remote repo and cleanup your feature branch? ") =~ /^y/i
deploy_and_cleanup = always_deploy_and_cleanup || (ask "Would you like to cleanup your feature branch? ") =~ /^y/i

if deploy_and_cleanup
run_command_with_label "git push origin #{base_branch}"
# Pulls merged changes from remote base_branch
run_command_with_label "git pull origin #{base_branch}"
run_command_with_label "git push origin :#{feature_branch}"
run_command_with_label "git branch -D #{feature_branch}"
puts "Nice job buddy."
else
puts "Cleanup halted. Local changes were not pushed to remote repo.".colorize(:red)
puts "To reset and go back to your branch run \`git reset --hard origin/#{base_branch} && git checkout #{feature_branch}\`"
end

elsif res.code == "405"
say "Pull Request is not mergeable. Try 'git reflow refresh' first.", :deliver_halted
elsif res.code == "409"
say "Head branch was modified. Review and try the merge again. Try 'git reflow refresh' first.", :deliver_halted
else
say "There were problems commiting your feature... please check the errors above and try again.", :error
say "There was another error. Please review the pull request and try again.", :deliver_halted
end
else
say existing_pull_request.rejection_message, :deliver_halted
Expand Down Expand Up @@ -185,7 +190,7 @@ def deploy(destination_server)
end

def git_server
@git_server ||= GitServer.connect provider: GitReflow::Config.get('reflow.git-server').strip, silent: true
@git_server ||= GitServer.connect provider: "#{GitReflow::Config.get('reflow.git-server')}".strip, silent: true
end

end
7 changes: 7 additions & 0 deletions lib/git_reflow/commands/setup.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,12 @@
GitReflow::Config.add "constants.minimumApprovals", ask("Set the minimum number of approvals (leaving blank will require approval from all commenters): "), local: reflow_options[:project_only]
GitReflow::Config.add "constants.approvalRegex", GitReflow::GitServer::PullRequest::DEFAULT_APPROVAL_REGEX, local: reflow_options[:project_only]

say("Enter the follow information associated with your remote repository: (The information is used to run 'git reflow deliver'.")
GitReflow::Config.add "github.owner", ask("Enter the owner of the remote repository: "), local: reflow_options[:project_only]
GitReflow::Config.add "github.repo", ask("Enter the name of the remote repository: "), local: reflow_options[:project_only]

# Sets the user's github auth token
GitReflow::Config.set "github.oauth-token", ask("Set the your local github authorization token: (You cannot run 'git reflow deliver' without it!) "), local: reflow_options[:project_only]
say("Thanks! Your settings are saved to #{GitReflow::Config::CONFIG_FILE_PATH}.")
end
end
18 changes: 18 additions & 0 deletions lib/git_reflow/git_server/bit_bucket/pull_request.rb
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,24 @@ def approvals
approved
end

def merge_feature_branch(feature_branch_name, options = {})
options[:destination_branch] ||= 'master'

message = "#{options[:message]}"

if "#{options[:pull_request_number]}".length > 0
message << "\nMerges ##{options[:pull_request_number]}\n"
end

if lgtm_authors = Array(options[:lgtm_authors]) and lgtm_authors.any?
message << "\nLGTM given by: @#{lgtm_authors.join(', @')}\n"
end

run_command_with_label "git checkout #{options[:destination_branch]}"
run_command_with_label "git merge --squash #{feature_branch_name}"

append_to_squashed_commit_message(message) if message.length > 0
end
end
end
end
Expand Down
32 changes: 32 additions & 0 deletions lib/git_reflow/git_server/git_hub/pull_request.rb
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,38 @@ def approved?
end
end

def merge_feature_branch(feature_branch_name, options = {})
# binding.pry
options[:destination_branch] ||= 'master'

message = "#{options[:message]}"

if "#{options[:pull_request_number]}".length > 0
message << "\nMerges ##{options[:pull_request_number]}\n"
end

if lgtm_authors = Array(options[:lgtm_authors]) and lgtm_authors.any?
message << "\nLGTM given by: @#{lgtm_authors.join(', @')}\n"
end

data = {
"commit_title" => options[:title],
"commit_message" => options[:message],
"sha" => options[:head].sha,
"squash" => true
}

res = GitReflow::GitServer::GitHub.connection.pull_requests.merge(
"#{GitReflow::Config.get('github.owner')}",
"#{GitReflow::Config.get('github.repo')}",
"#{options[:pull_request_number]}",
data
)

append_to_squashed_commit_message(message) if message.length > 0
return res
end

def build
github_build_status = GitReflow.git_server.get_build_status(self.head.sha)
build_status_object = Struct.new(:state, :description, :url)
Expand Down
1 change: 1 addition & 0 deletions lib/git_reflow/git_server/pull_request.rb
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ def all_comments_addressed?
end

def good_to_merge?(force: false)

return true if force

(build_status.nil? or build_status == "success") and approved?
Expand Down
Loading

0 comments on commit 26a5868

Please sign in to comment.