Support creating a remote branch to import closed pull requests

This commit is contained in:
Stan Hu 2018-07-03 16:37:17 -07:00
parent 5f362686ca
commit d3c75ea4d9
3 changed files with 82 additions and 2 deletions

View File

@ -27,6 +27,16 @@ module BitbucketServer
get_collection(path, :repo)
end
def create_branch(project_key, repo, branch_name, sha)
payload = {
name: branch_name,
startPoint: sha,
message: 'GitLab temporary branch for import'
}
connection.post("/projects/#{project_key}/repos/#{repo}/branches", payload.to_json)
end
private
def get_collection(path, type)

View File

@ -12,7 +12,6 @@ module BitbucketServer
end
def get(path, extra_query = {})
auth = { username: username, password: token }
response = Gitlab::HTTP.get(build_url(path),
basic_auth: auth,
params: extra_query)
@ -20,8 +19,23 @@ module BitbucketServer
response.parsed_response
end
def post(path, body)
Gitlab::HTTP.post(build_url(path),
basic_auth: auth,
headers: post_headers,
body: body)
end
private
def auth
@auth ||= { username: username, password: token }
end
def post_headers
@post_headers ||= { 'Content-Type' => 'application/json' }
end
def build_url(path)
return path if path.starts_with?(root_url)

View File

@ -4,6 +4,16 @@ module Gitlab
include Gitlab::ShellAdapter
attr_reader :project, :project_key, :repository_slug, :client, :errors, :users
REMOTE_NAME = 'bitbucket_server'.freeze
def self.imports_repository?
true
end
def self.refmap
[:heads, :tags, '+refs/pull-requests/*/to:refs/merge-requests/*/head']
end
def initialize(project)
@project = project
@project_key = project.import_data.data['project_key']
@ -12,9 +22,11 @@ module Gitlab
@formatter = Gitlab::ImportFormatter.new
@errors = []
@users = {}
@temp_branches = []
end
def execute
import_repository
import_pull_requests
handle_errors
@ -48,11 +60,55 @@ module Gitlab
@repo ||= client.repo(project_key, repository_slug)
end
def sha_exists?(sha)
project.repository.commit(sha)
end
def track_temp_branch(pull_request, index)
temp_branch_name = "gitlab/import/pull-request/#{pull_request.iid}-#{index}"
@temp_branches << temp_branch_name
temp_branch_name
end
def restore_branches(pull_request)
shas_to_restore = [pull_request.source_branch_sha, pull_request.target_branch_sha]
resync = false
shas_to_restore.each_with_index do |sha, index|
next if sha_exists?(sha)
branch_name = track_temp_branch(pull_request, index)
response = client.create_branch(project_key, repository_slug, branch_name, sha)
if response.success?
resync = true
else
Rails.logger.warn("BitbucketServerImporter: Unable to recreate branch for SHA #{sha}: #{response.code}")
end
end
import_repository if resync
end
def import_repository
project.ensure_repository
project.repository.fetch_as_mirror(project.import_url, refmap: self.class.refmap, remote_name: REMOTE_NAME)
rescue Gitlab::Shell::Error, Gitlab::Git::RepositoryMirroring::RemoteError => e
# Expire cache to prevent scenarios such as:
# 1. First import failed, but the repo was imported successfully, so +exists?+ returns true
# 2. Retried import, repo is broken or not imported but +exists?+ still returns true
project.repository.expire_content_cache if project.repository_exists?
raise RuntimeError, e.message
end
def import_pull_requests
pull_requests = client.pull_requests(project_key, repository_slug)
pull_requests.each do |pull_request|
begin
restore_branches(pull_request)
description = ''
description += @formatter.author_line(pull_request.author) unless find_user_id(pull_request.author_email)
description += pull_request.description