Commit 8c5712a4 authored by Douwe Maan's avatar Douwe Maan

Merge branch 'gh-disable-webhooks'

parents acef028d 1fb1e64f
...@@ -51,6 +51,7 @@ v 8.8.4 (unreleased) ...@@ -51,6 +51,7 @@ v 8.8.4 (unreleased)
- Remove prev/next buttons on issues and merge requests - Remove prev/next buttons on issues and merge requests
- Import GitHub repositories respecting the API rate limit - Import GitHub repositories respecting the API rate limit
- Fix importer for GitHub comments on diff - Fix importer for GitHub comments on diff
- Disable Webhooks before proceeding with the GitHub import
v 8.8.3 v 8.8.3
- Fix 404 page when viewing TODOs that contain milestones or labels in different projects. !4312 - Fix 404 page when viewing TODOs that contain milestones or labels in different projects. !4312
......
...@@ -4,6 +4,10 @@ ...@@ -4,6 +4,10 @@
%i.fa.fa-github %i.fa.fa-github
Import projects from GitHub Import projects from GitHub
%p
%i.fa.fa-warning
To import GitHub pull requests, any pull request source branches that had been deleted are temporarily restored on GitHub. To prevent any connected CI services from being overloaded with dozens of irrelevant branches being created and deleted again, GitHub webhooks are temporarily disabled during the import process.
%p.light %p.light
Select projects you want to import. Select projects you want to import.
%hr %hr
......
module Gitlab
module GithubImport
class HookFormatter
EVENTS = %w[* create delete pull_request push].freeze
attr_reader :raw
delegate :id, :name, :active, to: :raw
def initialize(raw)
@raw = raw
end
def config
raw.config.attrs
end
def valid?
(EVENTS & raw.events).any? && active
end
end
end
end
...@@ -109,6 +109,9 @@ module Gitlab ...@@ -109,6 +109,9 @@ module Gitlab
end end
def import_pull_requests def import_pull_requests
hooks = client.hooks(repo).map { |raw| HookFormatter.new(raw) }.select(&:valid?)
disable_webhooks(hooks)
pull_requests = paginate { client.pull_requests(repo, state: :all, sort: :created, direction: :asc, per_page: 100) } pull_requests = paginate { client.pull_requests(repo, state: :all, sort: :created, direction: :asc, per_page: 100) }
pull_requests = pull_requests.map { |raw| PullRequestFormatter.new(project, raw) }.select(&:valid?) pull_requests = pull_requests.map { |raw| PullRequestFormatter.new(project, raw) }.select(&:valid?)
...@@ -116,7 +119,7 @@ module Gitlab ...@@ -116,7 +119,7 @@ module Gitlab
target_branches_removed = pull_requests.reject(&:target_branch_exists?).map { |pr| [pr.target_branch_name, pr.target_branch_sha] } target_branches_removed = pull_requests.reject(&:target_branch_exists?).map { |pr| [pr.target_branch_name, pr.target_branch_sha] }
branches_removed = source_branches_removed | target_branches_removed branches_removed = source_branches_removed | target_branches_removed
create_refs(branches_removed) restore_branches(branches_removed)
pull_requests.each do |pull_request| pull_requests.each do |pull_request|
merge_request = pull_request.create! merge_request = pull_request.create!
...@@ -129,10 +132,25 @@ module Gitlab ...@@ -129,10 +132,25 @@ module Gitlab
rescue ActiveRecord::RecordInvalid => e rescue ActiveRecord::RecordInvalid => e
raise Projects::ImportService::Error, e.message raise Projects::ImportService::Error, e.message
ensure ensure
delete_refs(branches_removed) clean_up_restored_branches(branches_removed)
clean_up_disabled_webhooks(hooks)
end
def disable_webhooks(hooks)
update_webhooks(hooks, active: false)
end
def clean_up_disabled_webhooks(hooks)
update_webhooks(hooks, active: true)
end
def update_webhooks(hooks, options)
hooks.each do |hook|
client.edit_hook(repo, hook.id, hook.name, hook.config, options)
end
end end
def create_refs(branches) def restore_branches(branches)
branches.each do |name, sha| branches.each do |name, sha|
sleep rate_limit_sleep_time if rate_limit_exceed? sleep rate_limit_sleep_time if rate_limit_exceed?
client.create_ref(repo, "refs/heads/#{name}", sha) client.create_ref(repo, "refs/heads/#{name}", sha)
...@@ -141,7 +159,7 @@ module Gitlab ...@@ -141,7 +159,7 @@ module Gitlab
project.repository.fetch_ref(repo_url, '+refs/heads/*', 'refs/heads/*') project.repository.fetch_ref(repo_url, '+refs/heads/*', 'refs/heads/*')
end end
def delete_refs(branches) def clean_up_restored_branches(branches)
branches.each do |name, _| branches.each do |name, _|
sleep rate_limit_sleep_time if rate_limit_exceed? sleep rate_limit_sleep_time if rate_limit_exceed?
client.delete_ref(repo, "heads/#{name}") client.delete_ref(repo, "heads/#{name}")
......
require 'spec_helper'
describe Gitlab::GithubImport::HookFormatter, lib: true do
describe '#id' do
it 'returns raw id' do
raw = double(id: 100000)
formatter = described_class.new(raw)
expect(formatter.id).to eq 100000
end
end
describe '#name' do
it 'returns raw id' do
raw = double(name: 'web')
formatter = described_class.new(raw)
expect(formatter.name).to eq 'web'
end
end
describe '#config' do
it 'returns raw config.attrs' do
raw = double(config: double(attrs: { url: 'http://something.com/webhook' }))
formatter = described_class.new(raw)
expect(formatter.config).to eq({ url: 'http://something.com/webhook' })
end
end
describe '#valid?' do
it 'returns true when events contains the wildcard event' do
raw = double(events: ['*', 'commit_comment'], active: true)
formatter = described_class.new(raw)
expect(formatter.valid?).to eq true
end
it 'returns true when events contains the create event' do
raw = double(events: ['create', 'commit_comment'], active: true)
formatter = described_class.new(raw)
expect(formatter.valid?).to eq true
end
it 'returns true when events contains delete event' do
raw = double(events: ['delete', 'commit_comment'], active: true)
formatter = described_class.new(raw)
expect(formatter.valid?).to eq true
end
it 'returns true when events contains pull_request event' do
raw = double(events: ['pull_request', 'commit_comment'], active: true)
formatter = described_class.new(raw)
expect(formatter.valid?).to eq true
end
it 'returns false when events does not contains branch related events' do
raw = double(events: ['member', 'commit_comment'], active: true)
formatter = described_class.new(raw)
expect(formatter.valid?).to eq false
end
it 'returns false when hook is not active' do
raw = double(events: ['pull_request', 'commit_comment'], active: false)
formatter = described_class.new(raw)
expect(formatter.valid?).to eq false
end
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment