summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Gemfile.rails5.lock18
-rw-r--r--app/assets/javascripts/vue_shared/components/stacked_progress_bar.vue6
-rw-r--r--app/helpers/import_helper.rb4
-rw-r--r--app/services/merge_requests/build_service.rb19
-rw-r--r--app/views/import/_githubish_status.html.haml2
-rw-r--r--app/views/import/bitbucket/status.html.haml2
-rw-r--r--app/views/import/bitbucket_server/status.html.haml2
-rw-r--r--changelogs/unreleased/6028-show-generic-percent-stacked-progress-bar.yml6
-rw-r--r--changelogs/unreleased/fix-mr-title-fallback-logic.yml5
-rw-r--r--changelogs/unreleased/rails5-update-gemfile-lock.yml5
-rw-r--r--changelogs/unreleased/sh-insert-git-data-in-separate-transaction.yml5
-rw-r--r--changelogs/unreleased/sh-sanitize-project-import-names.yml5
-rw-r--r--lib/gitlab/bitbucket_server_import/importer.rb18
-rw-r--r--lib/gitlab/import/merge_request_creator.rb40
-rw-r--r--qa/qa/page/project/import/github.rb2
-rw-r--r--spec/helpers/import_helper_spec.rb10
-rw-r--r--spec/javascripts/vue_shared/components/stacked_progress_bar_spec.js6
-rw-r--r--spec/lib/gitlab/import/merge_request_creator_spec.rb43
-rw-r--r--spec/services/merge_requests/build_service_spec.rb4
19 files changed, 167 insertions, 35 deletions
diff --git a/Gemfile.rails5.lock b/Gemfile.rails5.lock
index f9ec29cde90..63b450d3f62 100644
--- a/Gemfile.rails5.lock
+++ b/Gemfile.rails5.lock
@@ -126,7 +126,7 @@ GEM
numerizer (~> 0.1.1)
chunky_png (1.3.5)
citrus (3.0.2)
- coderay (1.1.1)
+ coderay (1.1.2)
coercible (1.0.0)
descendants_tracker (~> 0.0.1)
commonmarker (0.17.8)
@@ -495,7 +495,7 @@ GEM
memoist (0.16.0)
memoizable (0.4.2)
thread_safe (~> 0.3, >= 0.3.1)
- method_source (0.8.2)
+ method_source (0.9.0)
mime-types (3.1)
mime-types-data (~> 3.2015)
mime-types-data (3.2016.0521)
@@ -638,12 +638,11 @@ GEM
unparser
procto (0.0.3)
prometheus-client-mmap (0.9.4)
- pry (0.10.4)
+ pry (0.11.3)
coderay (~> 1.1.0)
- method_source (~> 0.8.1)
- slop (~> 3.4)
- pry-byebug (3.4.2)
- byebug (~> 9.0)
+ method_source (~> 0.9.0)
+ pry-byebug (3.4.3)
+ byebug (>= 9.0, < 9.1)
pry (~> 0.10)
pry-rails (0.3.5)
pry (>= 0.9.10)
@@ -751,7 +750,7 @@ GEM
retriable (3.1.2)
rinku (2.0.0)
rotp (2.1.2)
- rouge (3.2.0)
+ rouge (3.2.1)
rqrcode (0.7.0)
chunky_png
rqrcode-rails3 (0.1.7)
@@ -817,7 +816,7 @@ GEM
rubyzip (1.2.1)
rufus-scheduler (3.4.0)
et-orbi (~> 1.0)
- rugged (0.27.2)
+ rugged (0.27.4)
safe_yaml (1.0.4)
sanitize (4.6.6)
crass (~> 1.0.2)
@@ -878,7 +877,6 @@ GEM
simplecov-html (~> 0.10.0)
simplecov-html (0.10.0)
slack-notifier (1.5.1)
- slop (3.6.0)
spring (2.0.1)
activesupport (>= 4.2)
spring-commands-rspec (1.0.4)
diff --git a/app/assets/javascripts/vue_shared/components/stacked_progress_bar.vue b/app/assets/javascripts/vue_shared/components/stacked_progress_bar.vue
index f44d361c47e..78fde463507 100644
--- a/app/assets/javascripts/vue_shared/components/stacked_progress_bar.vue
+++ b/app/assets/javascripts/vue_shared/components/stacked_progress_bar.vue
@@ -71,7 +71,11 @@ export default {
},
methods: {
getPercent(count) {
- return roundOffFloat((count / this.totalCount) * 100, 1);
+ const percent = roundOffFloat((count / this.totalCount) * 100, 1);
+ if (percent > 0 && percent < 1) {
+ return '< 1';
+ }
+ return percent;
},
barStyle(percent) {
return `width: ${percent}%;`;
diff --git a/app/helpers/import_helper.rb b/app/helpers/import_helper.rb
index 4664b1728c4..c65f1565425 100644
--- a/app/helpers/import_helper.rb
+++ b/app/helpers/import_helper.rb
@@ -5,6 +5,10 @@ module ImportHelper
false
end
+ def sanitize_project_name(name)
+ name.gsub(/[^\w\-]/, '-')
+ end
+
def import_project_target(owner, name)
namespace = current_user.can_create_group? ? owner : current_user.namespace_path
"#{namespace}/#{name}"
diff --git a/app/services/merge_requests/build_service.rb b/app/services/merge_requests/build_service.rb
index bc988eb2a26..55750269bb4 100644
--- a/app/services/merge_requests/build_service.rb
+++ b/app/services/merge_requests/build_service.rb
@@ -128,8 +128,7 @@ module MergeRequests
#
def assign_title_and_description
assign_title_and_description_from_single_commit
- assign_title_from_issue if target_project.issues_enabled? || target_project.external_issue_tracker
-
+ merge_request.title ||= title_from_issue if target_project.issues_enabled? || target_project.external_issue_tracker
merge_request.title ||= source_branch.titleize.humanize
merge_request.title = wip_title if compare_commits.empty?
@@ -159,20 +158,18 @@ module MergeRequests
merge_request.description ||= commit.description.try(:strip)
end
- def assign_title_from_issue
+ def title_from_issue
return unless issue
- merge_request.title = "Resolve \"#{issue.title}\"" if issue.is_a?(Issue)
+ return "Resolve \"#{issue.title}\"" if issue.is_a?(Issue)
- return if merge_request.title.present?
+ return if issue_iid.blank?
- if issue_iid.present?
- title_parts = ["Resolve #{issue.to_reference}"]
- branch_title = source_branch.downcase.remove(issue_iid.downcase).titleize.humanize
+ title_parts = ["Resolve #{issue.to_reference}"]
+ branch_title = source_branch.downcase.remove(issue_iid.downcase).titleize.humanize
- title_parts << "\"#{branch_title}\"" if branch_title.present?
- merge_request.title = title_parts.join(' ')
- end
+ title_parts << "\"#{branch_title}\"" if branch_title.present?
+ title_parts.join(' ')
end
def issue_iid
diff --git a/app/views/import/_githubish_status.html.haml b/app/views/import/_githubish_status.html.haml
index f0d1e837317..f4a29ed18dc 100644
--- a/app/views/import/_githubish_status.html.haml
+++ b/app/views/import/_githubish_status.html.haml
@@ -45,7 +45,7 @@
= text_field_tag :path, current_user.namespace_path, class: "input-group-text input-large form-control", tabindex: 1, disabled: true
%span.input-group-prepend
.input-group-text /
- = text_field_tag :path, repo.name, class: "input-mini form-control", tabindex: 2, autofocus: true, required: true
+ = text_field_tag :path, sanitize_project_name(repo.name), class: "input-mini form-control", tabindex: 2, autofocus: true, required: true
%td.import-actions.job-status
= button_tag class: "btn btn-import js-add-to-import" do
= has_ci_cd_only_params? ? _('Connect') : _('Import')
diff --git a/app/views/import/bitbucket/status.html.haml b/app/views/import/bitbucket/status.html.haml
index a75b7aa9dd2..3b1b5e55302 100644
--- a/app/views/import/bitbucket/status.html.haml
+++ b/app/views/import/bitbucket/status.html.haml
@@ -63,7 +63,7 @@
= text_field_tag :path, current_user.namespace_path, class: "input-group-text input-large form-control", tabindex: 1, disabled: true
%span.input-group-prepend
.input-group-text /
- = text_field_tag :path, repo.name, class: "input-mini form-control", tabindex: 2, autofocus: true, required: true
+ = text_field_tag :path, sanitize_project_name(repo.slug), class: "input-mini form-control", tabindex: 2, autofocus: true, required: true
%td.import-actions.job-status
= button_tag class: 'btn btn-import js-add-to-import' do
= _('Import')
diff --git a/app/views/import/bitbucket_server/status.html.haml b/app/views/import/bitbucket_server/status.html.haml
index 3d05a5e696f..ae09e0dfa18 100644
--- a/app/views/import/bitbucket_server/status.html.haml
+++ b/app/views/import/bitbucket_server/status.html.haml
@@ -61,7 +61,7 @@
= text_field_tag :path, current_user.namespace_path, class: "input-group-text input-large form-control", tabindex: 1, disabled: true
%span.input-group-prepend
.input-group-text /
- = text_field_tag :path, repo.name, class: "input-mini form-control", tabindex: 2, autofocus: true, required: true
+ = text_field_tag :path, sanitize_project_name(repo.slug), class: "input-mini form-control", tabindex: 2, autofocus: true, required: true
%td.import-actions.job-status
= button_tag class: 'btn btn-import js-add-to-import' do
Import
diff --git a/changelogs/unreleased/6028-show-generic-percent-stacked-progress-bar.yml b/changelogs/unreleased/6028-show-generic-percent-stacked-progress-bar.yml
new file mode 100644
index 00000000000..94098dd0144
--- /dev/null
+++ b/changelogs/unreleased/6028-show-generic-percent-stacked-progress-bar.yml
@@ -0,0 +1,6 @@
+---
+title: Show '< 1%' when percent value evaluated is less than 1 on Stacked Progress
+ Bar
+merge_request: 21306
+author:
+type: fixed
diff --git a/changelogs/unreleased/fix-mr-title-fallback-logic.yml b/changelogs/unreleased/fix-mr-title-fallback-logic.yml
new file mode 100644
index 00000000000..5056c38573b
--- /dev/null
+++ b/changelogs/unreleased/fix-mr-title-fallback-logic.yml
@@ -0,0 +1,5 @@
+---
+title: Fix fallback logic for automatic MR title assignment
+merge_request: 20930
+author: Franz Liedke
+type: fixed
diff --git a/changelogs/unreleased/rails5-update-gemfile-lock.yml b/changelogs/unreleased/rails5-update-gemfile-lock.yml
new file mode 100644
index 00000000000..3891b16e2b8
--- /dev/null
+++ b/changelogs/unreleased/rails5-update-gemfile-lock.yml
@@ -0,0 +1,5 @@
+---
+title: Rails5 update Gemfile.rails5.lock
+merge_request: 21388
+author: Jasper Maes
+type: other
diff --git a/changelogs/unreleased/sh-insert-git-data-in-separate-transaction.yml b/changelogs/unreleased/sh-insert-git-data-in-separate-transaction.yml
new file mode 100644
index 00000000000..116929b2f53
--- /dev/null
+++ b/changelogs/unreleased/sh-insert-git-data-in-separate-transaction.yml
@@ -0,0 +1,5 @@
+---
+title: 'Bitbucket Server importer: Eliminate most idle-in-transaction issues'
+merge_request:
+author:
+type: performance
diff --git a/changelogs/unreleased/sh-sanitize-project-import-names.yml b/changelogs/unreleased/sh-sanitize-project-import-names.yml
new file mode 100644
index 00000000000..6e0284bda08
--- /dev/null
+++ b/changelogs/unreleased/sh-sanitize-project-import-names.yml
@@ -0,0 +1,5 @@
+---
+title: Use slugs for default project path and sanitize names before import
+merge_request: 21367
+author:
+type: fixed
diff --git a/lib/gitlab/bitbucket_server_import/importer.rb b/lib/gitlab/bitbucket_server_import/importer.rb
index 268d21a77d1..b591d94668f 100644
--- a/lib/gitlab/bitbucket_server_import/importer.rb
+++ b/lib/gitlab/bitbucket_server_import/importer.rb
@@ -1,7 +1,10 @@
+# frozen_string_literal: true
+
module Gitlab
module BitbucketServerImport
class Importer
include Gitlab::ShellAdapter
+
attr_reader :recover_missing_commits
attr_reader :project, :project_key, :repository_slug, :client, :errors, :users
@@ -175,21 +178,18 @@ module Gitlab
description = ''
description += @formatter.author_line(pull_request.author) unless find_user_id(pull_request.author_email)
description += pull_request.description if pull_request.description
-
- source_branch_sha = pull_request.source_branch_sha
- target_branch_sha = pull_request.target_branch_sha
author_id = gitlab_user_id(pull_request.author_email)
attributes = {
iid: pull_request.iid,
title: pull_request.title,
description: description,
- source_project: project,
+ source_project_id: project.id,
source_branch: Gitlab::Git.ref_name(pull_request.source_branch_name),
- source_branch_sha: source_branch_sha,
- target_project: project,
+ source_branch_sha: pull_request.source_branch_sha,
+ target_project_id: project.id,
target_branch: Gitlab::Git.ref_name(pull_request.target_branch_name),
- target_branch_sha: target_branch_sha,
+ target_branch_sha: pull_request.target_branch_sha,
state: pull_request.state,
author_id: author_id,
assignee_id: nil,
@@ -197,7 +197,9 @@ module Gitlab
updated_at: pull_request.updated_at
}
- merge_request = project.merge_requests.create!(attributes)
+ creator = Gitlab::Import::MergeRequestCreator.new(project)
+ merge_request = creator.execute(attributes)
+
import_pull_request_comments(pull_request, merge_request) if merge_request.persisted?
end
diff --git a/lib/gitlab/import/merge_request_creator.rb b/lib/gitlab/import/merge_request_creator.rb
new file mode 100644
index 00000000000..a01951b0762
--- /dev/null
+++ b/lib/gitlab/import/merge_request_creator.rb
@@ -0,0 +1,40 @@
+# frozen_string_literal: true
+
+# This module is designed for importers that need to create many merge
+# requests quickly. When creating merge requests there are a lot of hooks
+# that may run, for many different reasons. Many of these hooks (e.g. the ones
+# used for rendering Markdown) are completely unnecessary and may even lead to
+# transaction timeouts.
+#
+# To ensure importing merge requests requests has a minimal impact and can
+# complete in a reasonable time we bypass all the hooks by inserting the row
+# and then retrieving it. We then only perform the additional work that is
+# strictly necessary.
+module Gitlab
+ module Import
+ class MergeRequestCreator
+ include ::Gitlab::Import::DatabaseHelpers
+ include ::Gitlab::Import::MergeRequestHelpers
+
+ attr_accessor :project
+
+ def initialize(project)
+ @project = project
+ end
+
+ def execute(attributes)
+ source_branch_sha = attributes.delete(:source_branch_sha)
+ target_branch_sha = attributes.delete(:target_branch_sha)
+ iid = attributes[:iid]
+
+ merge_request, already_exists = create_merge_request_without_hooks(project, attributes, iid)
+
+ if merge_request
+ insert_or_replace_git_data(merge_request, source_branch_sha, target_branch_sha, already_exists)
+ end
+
+ merge_request
+ end
+ end
+ end
+end
diff --git a/qa/qa/page/project/import/github.rb b/qa/qa/page/project/import/github.rb
index 36567927194..1a410a0f8a5 100644
--- a/qa/qa/page/project/import/github.rb
+++ b/qa/qa/page/project/import/github.rb
@@ -14,7 +14,7 @@ module QA
element :project_import_row, 'data: { qa: { repo_path: repo.full_name } }'
element :project_namespace_select
element :project_namespace_field, 'select_tag :namespace_id'
- element :project_path_field, 'text_field_tag :path, repo.name'
+ element :project_path_field, 'text_field_tag :path, sanitize_project_name(repo.name)'
element :import_button, "_('Import')"
end
diff --git a/spec/helpers/import_helper_spec.rb b/spec/helpers/import_helper_spec.rb
index 033155617c6..cb0ea4e26ba 100644
--- a/spec/helpers/import_helper_spec.rb
+++ b/spec/helpers/import_helper_spec.rb
@@ -1,6 +1,16 @@
require 'rails_helper'
describe ImportHelper do
+ describe '#sanitize_project_name' do
+ it 'removes whitespace' do
+ expect(helper.sanitize_project_name('my test repo')).to eq('my-test-repo')
+ end
+
+ it 'removes disallowed characters' do
+ expect(helper.sanitize_project_name('Test&me$over*h_ere')).to eq('Test-me-over-h_ere')
+ end
+ end
+
describe '#import_project_target' do
let(:user) { create(:user) }
diff --git a/spec/javascripts/vue_shared/components/stacked_progress_bar_spec.js b/spec/javascripts/vue_shared/components/stacked_progress_bar_spec.js
index 076d940961d..f1fe2e996fc 100644
--- a/spec/javascripts/vue_shared/components/stacked_progress_bar_spec.js
+++ b/spec/javascripts/vue_shared/components/stacked_progress_bar_spec.js
@@ -44,7 +44,11 @@ describe('StackedProgressBarComponent', () => {
});
it('returns percentage with decimal place from provided count based on `totalCount`', () => {
- expect(vm.getPercent(10)).toBe(0.2);
+ expect(vm.getPercent(67)).toBe(1.3);
+ });
+
+ it('returns percentage as `< 1` from provided count based on `totalCount` when evaluated value is less than 1', () => {
+ expect(vm.getPercent(10)).toBe('< 1');
});
});
diff --git a/spec/lib/gitlab/import/merge_request_creator_spec.rb b/spec/lib/gitlab/import/merge_request_creator_spec.rb
new file mode 100644
index 00000000000..cd3359da341
--- /dev/null
+++ b/spec/lib/gitlab/import/merge_request_creator_spec.rb
@@ -0,0 +1,43 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::Import::MergeRequestCreator do
+ let(:project) { create(:project, :repository) }
+
+ subject { described_class.new(project) }
+
+ describe '#execute' do
+ context 'merge request already exists' do
+ let(:merge_request) { create(:merge_request, target_project: project, source_project: project) }
+ let(:commits) { merge_request.merge_request_diffs.first.commits }
+ let(:attributes) { HashWithIndifferentAccess.new(merge_request.attributes) }
+
+ it 'updates the data' do
+ commits_count = commits.count
+ merge_request.merge_request_diffs.destroy_all # rubocop: disable DestroyAll
+
+ expect(merge_request.merge_request_diffs.count).to eq(0)
+
+ subject.execute(attributes)
+
+ expect(merge_request.reload.merge_request_diffs.count).to eq(1)
+ expect(merge_request.reload.merge_request_diffs.first.commits.count).to eq(commits_count)
+ end
+ end
+
+ context 'new merge request' do
+ let(:merge_request) { build(:merge_request, target_project: project, source_project: project) }
+ let(:attributes) { HashWithIndifferentAccess.new(merge_request.attributes) }
+
+ it 'creates a new merge request' do
+ attributes.delete(:id)
+
+ expect { subject.execute(attributes) }.to change { MergeRequest.count }.by(1)
+
+ new_mr = MergeRequest.last
+ expect(new_mr.merge_request_diffs.count).to eq(1)
+ end
+ end
+ end
+end
diff --git a/spec/services/merge_requests/build_service_spec.rb b/spec/services/merge_requests/build_service_spec.rb
index 6aed481939e..0ced5d1b6d6 100644
--- a/spec/services/merge_requests/build_service_spec.rb
+++ b/spec/services/merge_requests/build_service_spec.rb
@@ -169,6 +169,10 @@ describe MergeRequests::BuildService do
end
end
+ it 'uses the title of the commit as the title of the merge request' do
+ expect(merge_request.title).to eq('Initial commit')
+ end
+
it 'appends the closing description' do
expected_description = [commit_description, closing_message].compact.join("\n\n")