summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md13
-rw-r--r--Gemfile8
-rw-r--r--Gemfile.lock22
-rw-r--r--app/assets/stylesheets/framework/issue_box.scss5
-rw-r--r--app/assets/stylesheets/pages/milestone.scss3
-rw-r--r--app/controllers/admin/application_settings_controller.rb2
-rw-r--r--app/controllers/application_controller.rb2
-rw-r--r--app/controllers/groups/milestones_controller.rb21
-rw-r--r--app/controllers/sherlock/transactions_controller.rb2
-rw-r--r--app/helpers/milestones_helper.rb15
-rw-r--r--app/models/ci/build.rb4
-rw-r--r--app/models/clusters/applications/ingress.rb2
-rw-r--r--app/models/clusters/applications/knative.rb2
-rw-r--r--app/models/concerns/milestoneish.rb2
-rw-r--r--app/models/dashboard_group_milestone.rb20
-rw-r--r--app/models/dashboard_milestone.rb10
-rw-r--r--app/models/global_milestone.rb116
-rw-r--r--app/models/group_milestone.rb29
-rw-r--r--app/models/merge_request.rb2
-rw-r--r--app/models/milestone.rb6
-rw-r--r--app/models/project_services/kubernetes_service.rb2
-rw-r--r--app/views/dashboard/milestones/_milestone.html.haml2
-rw-r--r--app/views/projects/services/prometheus/_metrics.html.haml2
-rw-r--r--app/views/projects/services/prometheus/_show.html.haml2
-rw-r--r--app/views/shared/milestones/_milestone.html.haml14
-rw-r--r--app/views/shared/milestones/_top.html.haml11
-rw-r--r--changelogs/unreleased/51668-fix-line-numbers.yml5
-rw-r--r--changelogs/unreleased/54953-fix-commit_email_hostname-accessor-in-fake_application_settings.yml5
-rw-r--r--changelogs/unreleased/55103-hide-group-cluster-features.yml5
-rw-r--r--changelogs/unreleased/55836-docs-fix-navigation-style-in-docs.yml5
-rw-r--r--changelogs/unreleased/ccr-49289_milestone_link.yml5
-rw-r--r--changelogs/unreleased/deprecated-insert-sql.yml5
-rw-r--r--changelogs/unreleased/deprecated-redirect-back.yml5
-rw-r--r--changelogs/unreleased/fj-55781-fix-api-blob-content-disposition.yml5
-rw-r--r--changelogs/unreleased/markdown-toolbar-btn-fix.yml5
-rw-r--r--changelogs/unreleased/sh-fix-clone-geo-dropdown.yml5
-rw-r--r--changelogs/unreleased/sh-fix-http-clone-panel.yml5
-rw-r--r--db/migrate/20180413022611_create_missing_namespace_for_internal_users.rb2
-rw-r--r--doc/administration/job_artifacts.md12
-rw-r--r--doc/administration/monitoring/performance/request_profiling.md4
-rw-r--r--doc/api/services.md2
-rw-r--r--doc/ci/examples/test-and-deploy-python-application-to-heroku.md2
-rw-r--r--doc/install/openshift_and_gitlab/index.md4
-rw-r--r--doc/topics/authentication/index.md2
-rw-r--r--doc/user/project/integrations/prometheus.md4
-rw-r--r--lib/backup/manager.rb2
-rw-r--r--qa/Gemfile3
-rw-r--r--qa/Gemfile.lock13
-rw-r--r--spec/controllers/dashboard/milestones_controller_spec.rb2
-rw-r--r--spec/controllers/groups/milestones_controller_spec.rb2
-rw-r--r--spec/features/groups/milestone_spec.rb5
-rw-r--r--spec/features/groups/milestones_sorting_spec.rb1
-rw-r--r--spec/models/global_milestone_spec.rb119
-rw-r--r--spec/models/group_milestone_spec.rb27
-rw-r--r--spec/requests/api/runner_spec.rb2
-rw-r--r--spec/requests/lfs_http_spec.rb2
-rw-r--r--spec/uploaders/file_uploader_spec.rb2
-rw-r--r--spec/uploaders/object_storage_spec.rb2
58 files changed, 324 insertions, 264 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index a1c928aedf3..56ac809b548 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,19 @@
documentation](doc/development/changelog.md) for instructions on adding your own
entry.
+## 11.6.2 (2019-01-02)
+
+### Fixed (7 changes)
+
+- Hide cluster features that don't work yet with Group Clusters. !23935
+- Fix a 500 error that could occur until all migrations are done. !23939
+- Fix missing Git clone button when protocol restriction setting enabled. !24015
+- Fix clone dropdown parent inheritance issues in HAML. !24029
+- Fix content-disposition in blobs and files API endpoint. !24078
+- Fixed markdown toolbar buttons.
+- Adjust line-height of blame view line numbers.
+
+
## 11.6.1 (2018-12-28)
### Security (15 changes)
diff --git a/Gemfile b/Gemfile
index 34e6fd17129..c46961fa77d 100644
--- a/Gemfile
+++ b/Gemfile
@@ -127,7 +127,7 @@ gem 'asciidoctor-plantuml', '0.0.8'
gem 'rouge', '~> 3.1'
gem 'truncato', '~> 0.7.9'
gem 'bootstrap_form', '~> 2.7.0'
-gem 'nokogiri', '~> 1.8.4'
+gem 'nokogiri', '~> 1.8.5'
gem 'escape_utils', '~> 1.1'
# Calendar rendering
@@ -322,7 +322,7 @@ end
group :development, :test do
gem 'bootsnap', '~> 1.3'
gem 'bullet', '~> 5.5.0', require: !!ENV['ENABLE_BULLET']
- gem 'pry-byebug', '~> 3.4.1', platform: :mri
+ gem 'pry-byebug', '~> 3.5.1', platform: :mri
gem 'pry-rails', '~> 0.3.4'
gem 'awesome_print', require: false
@@ -342,8 +342,8 @@ group :development, :test do
# Generate Fake data
gem 'ffaker', '~> 2.10'
- gem 'capybara', '~> 2.15'
- gem 'capybara-screenshot', '~> 1.0.0'
+ gem 'capybara', '~> 2.16.1'
+ gem 'capybara-screenshot', '~> 1.0.18'
gem 'selenium-webdriver', '~> 3.12'
gem 'spring', '~> 2.0.0'
diff --git a/Gemfile.lock b/Gemfile.lock
index 1f7f58d59e0..78cf4d19078 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -97,16 +97,16 @@ GEM
bundler-audit (0.5.0)
bundler (~> 1.2)
thor (~> 0.18)
- byebug (9.0.6)
- capybara (2.15.1)
+ byebug (9.1.0)
+ capybara (2.16.1)
addressable
mini_mime (>= 0.1.3)
nokogiri (>= 1.3.3)
rack (>= 1.0.0)
rack-test (>= 0.5.4)
xpath (~> 2.0)
- capybara-screenshot (1.0.14)
- capybara (>= 1.0, < 3)
+ capybara-screenshot (1.0.22)
+ capybara (>= 1.0, < 4)
launchy
carrierwave (1.3.0)
activemodel (>= 4.0.0)
@@ -595,8 +595,8 @@ GEM
pry (0.11.3)
coderay (~> 1.1.0)
method_source (~> 0.9.0)
- pry-byebug (3.4.3)
- byebug (>= 9.0, < 9.1)
+ pry-byebug (3.5.1)
+ byebug (~> 9.1)
pry (~> 0.10)
pry-rails (0.3.6)
pry (>= 0.10.4)
@@ -963,8 +963,8 @@ DEPENDENCIES
browser (~> 2.5)
bullet (~> 5.5.0)
bundler-audit (~> 0.5.0)
- capybara (~> 2.15)
- capybara-screenshot (~> 1.0.0)
+ capybara (~> 2.16.1)
+ capybara-screenshot (~> 1.0.18)
carrierwave (~> 1.3)
charlock_holmes (~> 0.7.5)
chronic (~> 0.10.2)
@@ -1059,7 +1059,7 @@ DEPENDENCIES
nakayoshi_fork (~> 0.0.4)
net-ldap
net-ssh (~> 5.0)
- nokogiri (~> 1.8.4)
+ nokogiri (~> 1.8.5)
oauth2 (~> 1.4)
octokit (~> 4.9)
omniauth (~> 1.8)
@@ -1087,7 +1087,7 @@ DEPENDENCIES
pg (~> 0.18.2)
premailer-rails (~> 1.9.7)
prometheus-client-mmap (~> 0.9.4)
- pry-byebug (~> 3.4.1)
+ pry-byebug (~> 3.5.1)
pry-rails (~> 0.3.4)
puma (~> 3.12)
puma_worker_killer
@@ -1171,4 +1171,4 @@ DEPENDENCIES
wikicloth (= 0.8.1)
BUNDLED WITH
- 1.17.1
+ 1.17.3
diff --git a/app/assets/stylesheets/framework/issue_box.scss b/app/assets/stylesheets/framework/issue_box.scss
index a66604e56ff..e51f230a680 100644
--- a/app/assets/stylesheets/framework/issue_box.scss
+++ b/app/assets/stylesheets/framework/issue_box.scss
@@ -45,9 +45,4 @@
&.status-box-upcoming {
background: $gl-text-color-secondary;
}
-
- &.status-box-milestone {
- color: $gl-text-color;
- background: $gray-darker;
- }
}
diff --git a/app/assets/stylesheets/pages/milestone.scss b/app/assets/stylesheets/pages/milestone.scss
index 1e92582d6d9..94bf32945fc 100644
--- a/app/assets/stylesheets/pages/milestone.scss
+++ b/app/assets/stylesheets/pages/milestone.scss
@@ -1,3 +1,5 @@
+$status-box-line-height: 26px;
+
.issues-sortable-list .str-truncated {
max-width: 90%;
}
@@ -38,6 +40,7 @@
font-size: $tooltip-font-size;
margin-top: 0;
margin-right: $gl-padding-4;
+ line-height: $status-box-line-height;
@include media-breakpoint-down(xs) {
line-height: unset;
diff --git a/app/controllers/admin/application_settings_controller.rb b/app/controllers/admin/application_settings_controller.rb
index 8f683ca06ad..8f267eccc8a 100644
--- a/app/controllers/admin/application_settings_controller.rb
+++ b/app/controllers/admin/application_settings_controller.rb
@@ -77,7 +77,7 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
def reset_health_check_token
@application_setting.reset_health_check_access_token!
flash[:notice] = 'New health check access token has been generated!'
- redirect_to :back
+ redirect_back_or_default
end
def clear_repository_check_states
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 140a625d333..a8fc848c879 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -76,7 +76,7 @@ class ApplicationController < ActionController::Base
end
def redirect_back_or_default(default: root_path, options: {})
- redirect_to request.referer.present? ? :back : default, options
+ redirect_back(fallback_location: default, **options)
end
def not_found
diff --git a/app/controllers/groups/milestones_controller.rb b/app/controllers/groups/milestones_controller.rb
index b42116b0f36..868deea3f01 100644
--- a/app/controllers/groups/milestones_controller.rb
+++ b/app/controllers/groups/milestones_controller.rb
@@ -43,14 +43,7 @@ class Groups::MilestonesController < Groups::ApplicationController
def update
# Keep this compatible with legacy group milestones where we have to update
# all projects milestones states at once.
- if @milestone.legacy_group_milestone?
- update_params = milestone_params.select { |key| key == "state_event" }
- milestones = @milestone.milestones
- else
- update_params = milestone_params
- milestones = [@milestone]
- end
-
+ milestones, update_params = get_milestones_for_update
milestones.each do |milestone|
Milestones::UpdateService.new(milestone.parent, current_user, update_params).execute(milestone)
end
@@ -71,6 +64,14 @@ class Groups::MilestonesController < Groups::ApplicationController
private
+ def get_milestones_for_update
+ if @milestone.legacy_group_milestone?
+ [@milestone.milestones, legacy_milestone_params]
+ else
+ [[@milestone], milestone_params]
+ end
+ end
+
def authorize_admin_milestones!
return render_404 unless can?(current_user, :admin_milestone, group)
end
@@ -79,6 +80,10 @@ class Groups::MilestonesController < Groups::ApplicationController
params.require(:milestone).permit(:title, :description, :start_date, :due_date, :state_event)
end
+ def legacy_milestone_params
+ params.require(:milestone).permit(:state_event)
+ end
+
def milestone_path
if @milestone.legacy_group_milestone?
group_milestone_path(group, @milestone.safe_title, title: @milestone.title)
diff --git a/app/controllers/sherlock/transactions_controller.rb b/app/controllers/sherlock/transactions_controller.rb
index 46e382e594e..8d1847507cc 100644
--- a/app/controllers/sherlock/transactions_controller.rb
+++ b/app/controllers/sherlock/transactions_controller.rb
@@ -15,7 +15,7 @@ module Sherlock
def destroy_all
Gitlab::Sherlock.collection.clear
- redirect_to :back, status: :found
+ redirect_back_or_default(options: { status: :found })
end
end
end
diff --git a/app/helpers/milestones_helper.rb b/app/helpers/milestones_helper.rb
index 327b69e5110..50aec83b867 100644
--- a/app/helpers/milestones_helper.rb
+++ b/app/helpers/milestones_helper.rb
@@ -231,12 +231,15 @@ module MilestonesHelper
end
end
- def group_or_dashboard_milestone_path(milestone)
- if milestone.group_milestone?
- group_milestone_path(milestone.group, milestone.iid, milestone: { title: milestone.title })
- else
- dashboard_milestone_path(milestone.safe_title, title: milestone.title)
- end
+ def group_or_project_milestone_path(milestone)
+ params =
+ if milestone.group_milestone?
+ { milestone: { title: milestone.title } }
+ else
+ { title: milestone.title }
+ end
+
+ milestone_path(milestone.milestone, params)
end
def can_admin_project_milestones?
diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb
index b128a254b96..aeb35538d67 100644
--- a/app/models/ci/build.rb
+++ b/app/models/ci/build.rb
@@ -221,6 +221,10 @@ module Ci
next unless build.project
build.deployment&.drop
+ end
+
+ after_transition any => [:failed] do |build|
+ next unless build.project
if build.retry_failure?
begin
diff --git a/app/models/clusters/applications/ingress.rb b/app/models/clusters/applications/ingress.rb
index 8f8790585a3..7799f069742 100644
--- a/app/models/clusters/applications/ingress.rb
+++ b/app/models/clusters/applications/ingress.rb
@@ -23,7 +23,7 @@ module Clusters
FETCH_IP_ADDRESS_DELAY = 30.seconds
state_machine :status do
- before_transition any => [:installed] do |application|
+ after_transition any => [:installed] do |application|
application.run_after_commit do
ClusterWaitForIngressIpAddressWorker.perform_in(
FETCH_IP_ADDRESS_DELAY, application.name, application.id)
diff --git a/app/models/clusters/applications/knative.rb b/app/models/clusters/applications/knative.rb
index 0c72d7d8340..5ac152278da 100644
--- a/app/models/clusters/applications/knative.rb
+++ b/app/models/clusters/applications/knative.rb
@@ -20,7 +20,7 @@ module Clusters
self.reactive_cache_key = ->(knative) { [knative.class.model_name.singular, knative.id] }
state_machine :status do
- before_transition any => [:installed] do |application|
+ after_transition any => [:installed] do |application|
application.run_after_commit do
ClusterWaitForIngressIpAddressWorker.perform_in(
FETCH_IP_ADDRESS_DELAY, application.name, application.id)
diff --git a/app/models/concerns/milestoneish.rb b/app/models/concerns/milestoneish.rb
index e44a069b730..055ffe04646 100644
--- a/app/models/concerns/milestoneish.rb
+++ b/app/models/concerns/milestoneish.rb
@@ -42,7 +42,7 @@ module Milestoneish
def issues_visible_to_user(user)
memoize_per_user(user, :issues_visible_to_user) do
IssuesFinder.new(user, issues_finder_params)
- .execute.preload(:assignees).where(milestone_id: milestoneish_ids)
+ .execute.preload(:assignees).where(milestone_id: milestoneish_id)
end
end
diff --git a/app/models/dashboard_group_milestone.rb b/app/models/dashboard_group_milestone.rb
index ad0bb55f0a7..9bcc95e35a5 100644
--- a/app/models/dashboard_group_milestone.rb
+++ b/app/models/dashboard_group_milestone.rb
@@ -6,7 +6,7 @@ class DashboardGroupMilestone < GlobalMilestone
attr_reader :group_name
def initialize(milestone)
- super(milestone.title, Array(milestone))
+ super
@group_name = milestone.group.full_name
end
@@ -18,22 +18,4 @@ class DashboardGroupMilestone < GlobalMilestone
.active
.map { |m| new(m) }
end
-
- override :group_milestone?
- def group_milestone?
- @first_milestone.group_milestone?
- end
-
- override :milestoneish_ids
- def milestoneish_ids
- milestones.map(&:id)
- end
-
- def group
- @first_milestone.group
- end
-
- def iid
- @first_milestone.iid
- end
end
diff --git a/app/models/dashboard_milestone.rb b/app/models/dashboard_milestone.rb
index 96bc8090b81..9b377b70e5b 100644
--- a/app/models/dashboard_milestone.rb
+++ b/app/models/dashboard_milestone.rb
@@ -1,11 +1,15 @@
# frozen_string_literal: true
class DashboardMilestone < GlobalMilestone
- def issues_finder_params
- { authorized_only: true }
+ attr_reader :project_name
+
+ def initialize(milestone)
+ super
+
+ @project_name = milestone.project.full_name
end
- def dashboard_milestone?
+ def project_milestone?
true
end
end
diff --git a/app/models/global_milestone.rb b/app/models/global_milestone.rb
index 085ffd16c6a..4e82f3fed27 100644
--- a/app/models/global_milestone.rb
+++ b/app/models/global_milestone.rb
@@ -3,69 +3,78 @@
class GlobalMilestone
include Milestoneish
- EPOCH = DateTime.parse('1970-01-01')
STATE_COUNT_HASH = { opened: 0, closed: 0, all: 0 }.freeze
- attr_accessor :title, :milestones
+ attr_reader :milestone
alias_attribute :name, :title
+ delegate :title, :state, :due_date, :start_date, :participants, :project, :group, :expires_at, :closed?, :iid, :group_milestone?, :safe_title, :milestoneish_id, to: :milestone
+
+ def to_hash
+ {
+ name: title,
+ title: title,
+ group_name: group&.full_name,
+ project_name: project&.full_name
+ }
+ end
+
def for_display
- @first_milestone
+ @milestone
end
def self.build_collection(projects, params)
- params =
- { project_ids: projects.map(&:id), state: params[:state] }
-
- child_milestones = MilestonesFinder.new(params).execute # rubocop: disable CodeReuse/Finder
-
- milestones = child_milestones.select(:id, :title).group_by(&:title).map do |title, grouped|
- milestones_relation = Milestone.where(id: grouped.map(&:id))
- new(title, milestones_relation)
- end
+ items = Milestone.of_projects(projects)
+ .reorder_by_due_date_asc
+ .order_by_name_asc
- milestones.sort_by { |milestone| milestone.due_date || EPOCH }
+ Milestone.filter_by_state(items, params[:state]).map { |m| new(m) }
end
+ # necessary for legacy milestones
def self.build(projects, title)
- child_milestones = Milestone.of_projects(projects).where(title: title)
- return if child_milestones.blank?
+ milestones = Milestone.of_projects(projects).where(title: title)
+ return if milestones.blank?
- new(title, child_milestones)
+ new(milestones.first)
end
- def self.count_by_state(milestones_by_state_and_title, state)
- milestones_by_state_and_title.count do |(milestone_state, _), _|
- milestone_state == state
+ def self.states_count(projects, group = nil)
+ legacy_group_milestones_count = legacy_group_milestone_states_count(projects)
+ group_milestones_count = group_milestones_states_count(group)
+
+ legacy_group_milestones_count.merge(group_milestones_count) do |k, legacy_group_milestones_count, group_milestones_count|
+ legacy_group_milestones_count + group_milestones_count
end
end
- private_class_method :count_by_state
- def initialize(title, milestones)
- @title = title
- @name = title
- @milestones = milestones
- @first_milestone = milestones.find {|m| m.description.present? } || milestones.first
- end
+ def self.group_milestones_states_count(group)
+ return STATE_COUNT_HASH unless group
- def milestoneish_ids
- milestones.select(:id)
- end
+ counts_by_state = Milestone.of_groups(group).count_by_state
- def safe_title
- @title.to_slug.normalize.to_s
+ {
+ opened: counts_by_state['active'] || 0,
+ closed: counts_by_state['closed'] || 0,
+ all: counts_by_state.values.sum
+ }
end
- def projects
- @projects ||= Project.for_milestones(milestoneish_ids)
- end
+ def self.legacy_group_milestone_states_count(projects)
+ return STATE_COUNT_HASH unless projects
- def state
- milestones.each do |milestone|
- return 'active' if milestone.state != 'closed'
- end
+ # We need to reorder(nil) on the projects, because the controller passes them in sorted.
+ relation = Milestone.of_projects(projects.reorder(nil)).count_by_state
- 'closed'
+ {
+ opened: relation['active'] || 0,
+ closed: relation['closed'] || 0,
+ all: relation.values.sum
+ }
+ end
+
+ def initialize(milestone)
+ @milestone = milestone
end
def active?
@@ -77,37 +86,14 @@ class GlobalMilestone
end
def issues
- @issues ||= Issue.of_milestones(milestoneish_ids).includes(:project, :assignees, :labels)
+ @issues ||= Issue.of_milestones(milestone).includes(:project, :assignees, :labels)
end
def merge_requests
- @merge_requests ||= MergeRequest.of_milestones(milestoneish_ids).includes(:target_project, :assignee, :labels)
- end
-
- def participants
- @participants ||= milestones.map(&:participants).flatten.uniq
+ @merge_requests ||= MergeRequest.of_milestones(milestone).includes(:target_project, :assignee, :labels)
end
def labels
- @labels ||= GlobalLabel.build_collection(milestones.includes(:labels).map(&:labels).flatten)
- .sort_by!(&:title)
- end
-
- def due_date
- return @due_date if defined?(@due_date)
-
- @due_date =
- if @milestones.all? { |x| x.due_date == @milestones.first.due_date }
- @milestones.first.due_date
- end
- end
-
- def start_date
- return @start_date if defined?(@start_date)
-
- @start_date =
- if @milestones.all? { |x| x.start_date == @milestones.first.start_date }
- @milestones.first.start_date
- end
+ @labels ||= GlobalLabel.build_collection(milestone.labels).sort_by!(&:title)
end
end
diff --git a/app/models/group_milestone.rb b/app/models/group_milestone.rb
index 9dfaebacc83..a58537de319 100644
--- a/app/models/group_milestone.rb
+++ b/app/models/group_milestone.rb
@@ -1,18 +1,35 @@
# frozen_string_literal: true
# Group Milestones are milestones that can be shared among many projects within the same group
class GroupMilestone < GlobalMilestone
- attr_accessor :group
+ attr_reader :group, :milestones
def self.build_collection(group, projects, params)
- super(projects, params).each do |milestone|
- milestone.group = group
+ params =
+ { state: params[:state] }
+
+ project_milestones = Milestone.of_projects(projects)
+ child_milestones = Milestone.filter_by_state(project_milestones, params[:state])
+ grouped_milestones = child_milestones.group_by(&:title)
+
+ grouped_milestones.map do |title, grouped|
+ new(title, grouped, group)
end
end
def self.build(group, projects, title)
- super(projects, title).tap do |milestone|
- milestone&.group = group
- end
+ child_milestones = Milestone.of_projects(projects).where(title: title)
+ return if child_milestones.blank?
+
+ new(title, child_milestones, group)
+ end
+
+ def initialize(title, milestones, group)
+ @milestones = milestones
+ @group = group
+ end
+
+ def milestone
+ @milestone ||= milestones.find { |m| m.description.present? } || milestones.first
end
def issues_finder_params
diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb
index b937bef100b..6092c56b925 100644
--- a/app/models/merge_request.rb
+++ b/app/models/merge_request.rb
@@ -105,7 +105,9 @@ class MergeRequest < ActiveRecord::Base
before_transition any => :opened do |merge_request|
merge_request.merge_jid = nil
+ end
+ after_transition any => :opened do |merge_request|
merge_request.run_after_commit do
UpdateHeadPipelineForMergeRequestWorker.perform_async(merge_request.id)
end
diff --git a/app/models/milestone.rb b/app/models/milestone.rb
index 6dc0fca68e6..f55c39d9912 100644
--- a/app/models/milestone.rb
+++ b/app/models/milestone.rb
@@ -94,6 +94,10 @@ class Milestone < ActiveRecord::Base
end
end
+ def count_by_state
+ reorder(nil).group(:state).count
+ end
+
def predefined?(milestone)
milestone == Any ||
milestone == None ||
@@ -215,7 +219,7 @@ class Milestone < ActiveRecord::Base
self.class.reference_prefix + self.title
end
- def milestoneish_ids
+ def milestoneish_id
id
end
diff --git a/app/models/project_services/kubernetes_service.rb b/app/models/project_services/kubernetes_service.rb
index b801fd84a07..f69edd60003 100644
--- a/app/models/project_services/kubernetes_service.rb
+++ b/app/models/project_services/kubernetes_service.rb
@@ -53,7 +53,7 @@ class KubernetesService < DeploymentService
end
def description
- 'Kubernetes / Openshift integration'
+ 'Kubernetes / OpenShift integration'
end
def help
diff --git a/app/views/dashboard/milestones/_milestone.html.haml b/app/views/dashboard/milestones/_milestone.html.haml
index b876d6fd1f3..89212eb6bf9 100644
--- a/app/views/dashboard/milestones/_milestone.html.haml
+++ b/app/views/dashboard/milestones/_milestone.html.haml
@@ -1,5 +1,5 @@
= render 'shared/milestones/milestone',
- milestone_path: group_or_dashboard_milestone_path(milestone),
+ milestone_path: group_or_project_milestone_path(milestone),
issues_path: issues_dashboard_path(milestone_title: milestone.title),
merge_requests_path: merge_requests_dashboard_path(milestone_title: milestone.title),
milestone: milestone,
diff --git a/app/views/projects/services/prometheus/_metrics.html.haml b/app/views/projects/services/prometheus/_metrics.html.haml
index 597c029f755..a1d74b91002 100644
--- a/app/views/projects/services/prometheus/_metrics.html.haml
+++ b/app/views/projects/services/prometheus/_metrics.html.haml
@@ -1,6 +1,6 @@
- project = local_assigns.fetch(:project)
-.card.js-panel-monitored-metrics{ data: { active_metrics: active_common_project_prometheus_metrics_path(project, :json), metrics_help_path: help_page_path('user/project/integrations/prometheus_library/metrics') } }
+.card.js-panel-monitored-metrics{ data: { active_metrics: active_common_project_prometheus_metrics_path(project, :json), metrics_help_path: help_page_path('user/project/integrations/prometheus_library/index') } }
.card-header
= s_('PrometheusService|Common metrics')
%span.badge.badge-pill.js-monitored-count 0
diff --git a/app/views/projects/services/prometheus/_show.html.haml b/app/views/projects/services/prometheus/_show.html.haml
index 1d0b0265bb7..9d4574c4590 100644
--- a/app/views/projects/services/prometheus/_show.html.haml
+++ b/app/views/projects/services/prometheus/_show.html.haml
@@ -4,7 +4,7 @@
= s_('PrometheusService|Metrics')
%p
= s_('PrometheusService|Common metrics are automatically monitored based on a library of metrics from popular exporters.')
- = link_to s_('PrometheusService|More information'), help_page_path('user/project/integrations/prometheus_library/metrics'), target: '_blank', rel: "noopener noreferrer"
+ = link_to s_('PrometheusService|More information'), help_page_path('user/project/integrations/prometheus_library/index'), target: '_blank', rel: "noopener noreferrer"
.col-lg-9
= render 'projects/services/prometheus/metrics', project: @project
diff --git a/app/views/shared/milestones/_milestone.html.haml b/app/views/shared/milestones/_milestone.html.haml
index ed7fefba56d..40b8374848e 100644
--- a/app/views/shared/milestones/_milestone.html.haml
+++ b/app/views/shared/milestones/_milestone.html.haml
@@ -1,5 +1,5 @@
- dashboard = local_assigns[:dashboard]
-- custom_dom_id = dom_id(milestone.try(:milestones) ? milestone.milestones.first : milestone)
+- custom_dom_id = dom_id(milestone.try(:milestone) ? milestone.milestone : milestone)
- milestone_type = milestone.group_milestone? ? 'Group Milestone' : 'Project Milestone'
%li{ class: "milestone milestone-#{milestone.closed? ? 'closed' : 'open'}", id: custom_dom_id }
@@ -21,10 +21,12 @@
= milestone.group.full_name
- if milestone.legacy_group_milestone?
.projects
- - milestone.milestones.each do |milestone|
- = link_to milestone_path(milestone) do
- %span.label-badge.label-badge-blue.d-inline-block.append-bottom-5
- = dashboard ? milestone.project.full_name : milestone.project.name
+ - link_to milestone_path(milestone.milestone) do
+ %span.label-badge.label-badge-blue.d-inline-block.append-bottom-5
+ = dashboard ? milestone.project.full_name : milestone.project.name
+ - if milestone.project
+ .label-badge.label-badge-gray.d-inline-block
+ = milestone.project.full_name
.col-sm-4.milestone-progress
= milestone_progress_bar(milestone)
@@ -58,5 +60,5 @@
- else
= link_to 'Close Milestone', group_milestone_route(milestone, {state_event: :close }), method: :put, class: "btn btn-sm btn-grouped btn-close"
- if dashboard
- .status-box.status-box-milestone
+ .label-badge.label-badge-gray
= milestone_type
diff --git a/app/views/shared/milestones/_top.html.haml b/app/views/shared/milestones/_top.html.haml
index 0499b04a482..55b1c14022f 100644
--- a/app/views/shared/milestones/_top.html.haml
+++ b/app/views/shared/milestones/_top.html.haml
@@ -62,20 +62,19 @@
%th Open issues
%th State
%th Due date
- - milestone.milestones.each do |ms|
%tr
%td
- - project_name = group ? ms.project.name : ms.project.full_name
- = link_to project_name, project_milestone_path(ms.project, ms)
+ - project_name = group ? milestone.project.name : milestone.project.full_name
+ = link_to project_name, milestone_path(milestone.milestone)
%td
- = ms.issues_visible_to_user(current_user).opened.count
+ = milestone.milestone.issues_visible_to_user(current_user).opened.count
%td
- - if ms.closed?
+ - if milestone.closed?
Closed
- else
Open
%td
- = ms.expires_at
+ = milestone.expires_at
- elsif milestone.group_milestone?
%br
View
diff --git a/changelogs/unreleased/51668-fix-line-numbers.yml b/changelogs/unreleased/51668-fix-line-numbers.yml
deleted file mode 100644
index ac6e45e3cc7..00000000000
--- a/changelogs/unreleased/51668-fix-line-numbers.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Adjust line-height of blame view line numbers
-merge_request:
-author:
-type: fixed
diff --git a/changelogs/unreleased/54953-fix-commit_email_hostname-accessor-in-fake_application_settings.yml b/changelogs/unreleased/54953-fix-commit_email_hostname-accessor-in-fake_application_settings.yml
deleted file mode 100644
index 623b3a7319c..00000000000
--- a/changelogs/unreleased/54953-fix-commit_email_hostname-accessor-in-fake_application_settings.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix a 500 error that could occur until all migrations are done
-merge_request: 23939
-author:
-type: fixed
diff --git a/changelogs/unreleased/55103-hide-group-cluster-features.yml b/changelogs/unreleased/55103-hide-group-cluster-features.yml
deleted file mode 100644
index fbe780d6f01..00000000000
--- a/changelogs/unreleased/55103-hide-group-cluster-features.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Hide cluster features that don't work yet with Group Clusters
-merge_request: 23935
-author:
-type: fixed
diff --git a/changelogs/unreleased/55836-docs-fix-navigation-style-in-docs.yml b/changelogs/unreleased/55836-docs-fix-navigation-style-in-docs.yml
new file mode 100644
index 00000000000..2ac3599175b
--- /dev/null
+++ b/changelogs/unreleased/55836-docs-fix-navigation-style-in-docs.yml
@@ -0,0 +1,5 @@
+---
+title: Fix navigation style in docs
+merge_request: 24090
+author: Takuya Noguchi
+type: other
diff --git a/changelogs/unreleased/ccr-49289_milestone_link.yml b/changelogs/unreleased/ccr-49289_milestone_link.yml
new file mode 100644
index 00000000000..14c09752a24
--- /dev/null
+++ b/changelogs/unreleased/ccr-49289_milestone_link.yml
@@ -0,0 +1,5 @@
+---
+title: Add project milestone link
+merge_request: 22552
+author:
+type: added
diff --git a/changelogs/unreleased/deprecated-insert-sql.yml b/changelogs/unreleased/deprecated-insert-sql.yml
new file mode 100644
index 00000000000..ad21fbd9dde
--- /dev/null
+++ b/changelogs/unreleased/deprecated-insert-sql.yml
@@ -0,0 +1,5 @@
+---
+title: 'Fix deprecation: insert_sql is deprecated and will be removed'
+merge_request: 23944
+author: Jasper Maes
+type: other
diff --git a/changelogs/unreleased/deprecated-redirect-back.yml b/changelogs/unreleased/deprecated-redirect-back.yml
new file mode 100644
index 00000000000..7fc567fbdb5
--- /dev/null
+++ b/changelogs/unreleased/deprecated-redirect-back.yml
@@ -0,0 +1,5 @@
+---
+title: 'Fix deprecation: redirect_to :back is deprecated'
+merge_request: 23943
+author: Jasper Maes
+type: other
diff --git a/changelogs/unreleased/fj-55781-fix-api-blob-content-disposition.yml b/changelogs/unreleased/fj-55781-fix-api-blob-content-disposition.yml
deleted file mode 100644
index 2e1d9889b22..00000000000
--- a/changelogs/unreleased/fj-55781-fix-api-blob-content-disposition.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix content-disposition in blobs and files API endpoint
-merge_request: 24078
-author:
-type: fixed
diff --git a/changelogs/unreleased/markdown-toolbar-btn-fix.yml b/changelogs/unreleased/markdown-toolbar-btn-fix.yml
deleted file mode 100644
index eefb4d19f86..00000000000
--- a/changelogs/unreleased/markdown-toolbar-btn-fix.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fixed markdown toolbar buttons
-merge_request:
-author:
-type: fixed
diff --git a/changelogs/unreleased/sh-fix-clone-geo-dropdown.yml b/changelogs/unreleased/sh-fix-clone-geo-dropdown.yml
deleted file mode 100644
index 1c0cbdc3a2c..00000000000
--- a/changelogs/unreleased/sh-fix-clone-geo-dropdown.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix clone dropdown parent inheritance issues in HAML
-merge_request: 24029
-author:
-type: fixed
diff --git a/changelogs/unreleased/sh-fix-http-clone-panel.yml b/changelogs/unreleased/sh-fix-http-clone-panel.yml
deleted file mode 100644
index ab220bd5076..00000000000
--- a/changelogs/unreleased/sh-fix-http-clone-panel.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix missing Git clone button when protocol restriction setting enabled
-merge_request: 24015
-author:
-type: fixed
diff --git a/db/migrate/20180413022611_create_missing_namespace_for_internal_users.rb b/db/migrate/20180413022611_create_missing_namespace_for_internal_users.rb
index 90d869a8c10..8de8b3bcc2e 100644
--- a/db/migrate/20180413022611_create_missing_namespace_for_internal_users.rb
+++ b/db/migrate/20180413022611_create_missing_namespace_for_internal_users.rb
@@ -46,7 +46,7 @@ class CreateMissingNamespaceForInternalUsers < ActiveRecord::Migration[4.2]
end
insert_query = "INSERT INTO namespaces(owner_id, path, name, created_at, updated_at) VALUES(#{user_id}, '#{path}', '#{path}', NOW(), NOW())"
- namespace_id = connection.insert_sql(insert_query)
+ namespace_id = connection.insert(insert_query)
create_route(namespace_id)
end
diff --git a/doc/administration/job_artifacts.md b/doc/administration/job_artifacts.md
index a1ea78b64bd..25ae535d1ec 100644
--- a/doc/administration/job_artifacts.md
+++ b/doc/administration/job_artifacts.md
@@ -165,12 +165,6 @@ _The artifacts are stored by default in
gitlab-rake gitlab:artifacts:migrate
```
- Currently this has to be executed manually and it will allow you to
- migrate the existing artifacts to the object storage, but all new
- artifacts will still be stored on the local disk. In the future
- you will be given an option to define a default storage artifacts for all
- new files.
-
---
**In installations from source:**
@@ -201,12 +195,6 @@ _The artifacts are stored by default in
sudo -u git -H bundle exec rake gitlab:artifacts:migrate RAILS_ENV=production
```
- Currently this has to be executed manually and it will allow you to
- migrate the existing artifacts to the object storage, but all new
- artifacts will still be stored on the local disk. In the future
- you will be given an option to define a default storage artifacts for all
- new files.
-
## Expiring artifacts
If an expiry date is used for the artifacts, they are marked for deletion
diff --git a/doc/administration/monitoring/performance/request_profiling.md b/doc/administration/monitoring/performance/request_profiling.md
index dfd9be3d04c..726882fbb87 100644
--- a/doc/administration/monitoring/performance/request_profiling.md
+++ b/doc/administration/monitoring/performance/request_profiling.md
@@ -2,14 +2,14 @@
## Procedure
-1. Grab the profiling token from `Monitoring > Requests Profiles` admin page
+1. Grab the profiling token from **Monitoring > Requests Profiles** admin page
(highlighted in a blue in the image below).
![Profile token](img/request_profiling_token.png)
1. Pass the header `X-Profile-Token: <token>` to the request you want to profile. You can use:
- Browser extensions. For example, [ModHeader](https://chrome.google.com/webstore/detail/modheader/idgpnmonknjnojddfkpgkljpfnnfcklj) Chrome extension.
- `curl`. For example, `curl --header 'X-Profile-Token: <token>' https://gitlab.example.com/group/project`.
1. Once request is finished (which will take a little longer than usual), you can
- view the profiling output from `Monitoring > Requests Profiles` admin page.
+ view the profiling output from **Monitoring > Requests Profiles** admin page.
![Profiling output](img/request_profile_result.png)
## Cleaning up
diff --git a/doc/api/services.md b/doc/api/services.md
index f122bac6f1f..c4edaa17815 100644
--- a/doc/api/services.md
+++ b/doc/api/services.md
@@ -573,7 +573,7 @@ DELETE /projects/:id/services/jira
## Kubernetes
-Kubernetes / Openshift integration
+Kubernetes / OpenShift integration
CAUTION: **Warning:**
Kubernetes service integration has been deprecated in GitLab 10.3. API service endpoints will continue to work as long as the Kubernetes service is active, however if the service is inactive API endpoints will automatically return a `400 Bad Request`. Read [GitLab 10.3 release post](https://about.gitlab.com/2017/12/22/gitlab-10-3-released/#kubernetes-integration-service) for more information.
diff --git a/doc/ci/examples/test-and-deploy-python-application-to-heroku.md b/doc/ci/examples/test-and-deploy-python-application-to-heroku.md
index ec0b5aaed09..b59271e400f 100644
--- a/doc/ci/examples/test-and-deploy-python-application-to-heroku.md
+++ b/doc/ci/examples/test-and-deploy-python-application-to-heroku.md
@@ -47,7 +47,7 @@ This project has three jobs:
## Store API keys
-You'll need to create two variables in `Settings > CI/CD > Variables` on your GitLab project settings:
+You'll need to create two variables in **Settings > CI/CD > Variables** in your GitLab project:
- `HEROKU_STAGING_API_KEY` - Heroku API key used to deploy staging app.
- `HEROKU_PRODUCTION_API_KEY` - Heroku API key used to deploy production app.
diff --git a/doc/install/openshift_and_gitlab/index.md b/doc/install/openshift_and_gitlab/index.md
index 4c88b6f97fc..25a87dbd9de 100644
--- a/doc/install/openshift_and_gitlab/index.md
+++ b/doc/install/openshift_and_gitlab/index.md
@@ -18,7 +18,7 @@ In this tutorial, we will see how to deploy GitLab in OpenShift using GitLab's
official Docker image while getting familiar with the web interface and CLI
tools that will help us achieve our goal.
-For a video demonstration on installing GitLab on Openshift, check the article [In 13 minutes from Kubernetes to a complete application development tool](https://about.gitlab.com/2016/11/14/idea-to-production/).
+For a video demonstration on installing GitLab on OpenShift, check the article [In 13 minutes from Kubernetes to a complete application development tool](https://about.gitlab.com/2016/11/14/idea-to-production/).
---
@@ -518,7 +518,7 @@ PaaS and managing your applications with the ease of containers.
[templates]: https://docs.openshift.org/latest/architecture/core_concepts/templates.html "Documentation - OpenShift templates"
[old-post]: https://blog.openshift.com/deploy-gitlab-openshift/ "Old post - Deploy GitLab on OpenShift"
[line]: https://gitlab.com/gitlab-org/omnibus-gitlab/blob/658c065c8d022ce858dd63eaeeadb0b2ddc8deea/docker/openshift-template.json#L239 "GitLab - OpenShift template"
-[oc-gh]: https://github.com/openshift/origin/releases/tag/v1.3.0 "Openshift 1.3.0 release on GitHub"
+[oc-gh]: https://github.com/openshift/origin/releases/tag/v1.3.0 "OpenShift Origin 1.3.0 release on GitHub"
[ha]: ../../administration/high_availability/gitlab.html "Documentation - GitLab High Availability"
[replicas]: https://docs.openshift.org/latest/architecture/core_concepts/deployments.html#replication-controllers "Documentation - Replication controller"
[autoscaling]: https://docs.openshift.org/latest/dev_guide/pod_autoscaling.html "Documentation - Autoscale"
diff --git a/doc/topics/authentication/index.md b/doc/topics/authentication/index.md
index 766a23c419d..a354d3e7884 100644
--- a/doc/topics/authentication/index.md
+++ b/doc/topics/authentication/index.md
@@ -45,4 +45,4 @@ This page gathers all the resources for the topic **Authentication** within GitL
- [Kanboard Plugin GitLab Authentication](https://github.com/kanboard/plugin-gitlab-auth)
- [Jenkins GitLab OAuth Plugin](https://wiki.jenkins.io/display/JENKINS/GitLab+OAuth+Plugin)
- [How to customize GitLab to support OpenID authentication](http://eric.van-der-vlist.com/blog/2013/11/23/how-to-customize-gitlab-to-support-openid-authentication/)
-- [Openshift - Configuring Authentication and User Agent](https://docs.openshift.org/latest/install_config/configuring_authentication.html#GitLab)
+- [OKD - Configuring Authentication and User Agent](https://docs.okd.io/latest/install_config/configuring_authentication.html#GitLab)
diff --git a/doc/user/project/integrations/prometheus.md b/doc/user/project/integrations/prometheus.md
index d9a2eeb32ae..5de8e66e7eb 100644
--- a/doc/user/project/integrations/prometheus.md
+++ b/doc/user/project/integrations/prometheus.md
@@ -30,7 +30,7 @@ GitLab can seamlessly deploy and manage Prometheus on a [connected Kubernetes cl
Once you have a connected Kubernetes cluster with Helm installed, deploying a managed Prometheus is as easy as a single click.
-1. Go to the `Operations > Kubernetes` page, to view your connected clusters
+1. Go to the **Operations > Kubernetes** page to view your connected clusters
1. Select the cluster you would like to deploy Prometheus to
1. Click the **Install** button to deploy Prometheus to the cluster
@@ -88,7 +88,7 @@ to integrate with.
Once configured, GitLab will attempt to retrieve performance metrics for any
environment which has had a successful deployment.
-GitLab will automatically scan the Prometheus server for metrics from known serves like Kubernetes and NGINX, and attempt to identify individual environment. The supported metrics and scan process is detailed in our [Prometheus Metric Library documentation](prometheus_library/metrics.html).
+GitLab will automatically scan the Prometheus server for metrics from known serves like Kubernetes and NGINX, and attempt to identify individual environment. The supported metrics and scan process is detailed in our [Prometheus Metric Library documentation](prometheus_library/index.md).
You can view the performance dashboard for an environment by [clicking on the monitoring button](../../../ci/environments.md#monitoring-environments).
diff --git a/lib/backup/manager.rb b/lib/backup/manager.rb
index a0434a66ef1..0add2b3f875 100644
--- a/lib/backup/manager.rb
+++ b/lib/backup/manager.rb
@@ -195,7 +195,7 @@ module Backup
if connection.service == ::Fog::Storage::Local
connection.directories.create(key: remote_directory)
else
- connection.directories.get(remote_directory)
+ connection.directories.new(key: remote_directory)
end
end
diff --git a/qa/Gemfile b/qa/Gemfile
index d69c71003ae..75ad7bd07af 100644
--- a/qa/Gemfile
+++ b/qa/Gemfile
@@ -5,5 +5,6 @@ gem 'capybara', '~> 2.16.1'
gem 'capybara-screenshot', '~> 1.0.18'
gem 'rake', '~> 12.3.0'
gem 'rspec', '~> 3.7'
-gem 'selenium-webdriver', '~> 3.8.0'
+gem 'selenium-webdriver', '~> 3.12'
gem 'airborne', '~> 0.2.13'
+gem 'nokogiri', '~> 1.8.5'
diff --git a/qa/Gemfile.lock b/qa/Gemfile.lock
index d61ecf8fbb5..55f3211482b 100644
--- a/qa/Gemfile.lock
+++ b/qa/Gemfile.lock
@@ -25,7 +25,7 @@ GEM
capybara-screenshot (1.0.18)
capybara (>= 1.0, < 3)
launchy
- childprocess (0.8.0)
+ childprocess (0.9.0)
ffi (~> 1.0, >= 1.0.11)
coderay (1.1.2)
concurrent-ruby (1.0.5)
@@ -47,7 +47,7 @@ GEM
mini_portile2 (2.3.0)
minitest (5.11.1)
netrc (0.11.0)
- nokogiri (1.8.2)
+ nokogiri (1.8.5)
mini_portile2 (~> 2.3.0)
pry (0.11.3)
coderay (~> 1.1.0)
@@ -78,9 +78,9 @@ GEM
rspec-support (~> 3.7.0)
rspec-support (3.7.0)
rubyzip (1.2.2)
- selenium-webdriver (3.8.0)
+ selenium-webdriver (3.141.0)
childprocess (~> 0.5)
- rubyzip (~> 1.0)
+ rubyzip (~> 1.2, >= 1.2.2)
thread_safe (0.3.6)
tzinfo (1.2.4)
thread_safe (~> 0.1)
@@ -97,10 +97,11 @@ DEPENDENCIES
airborne (~> 0.2.13)
capybara (~> 2.16.1)
capybara-screenshot (~> 1.0.18)
+ nokogiri (~> 1.8.5)
pry-byebug (~> 3.5.1)
rake (~> 12.3.0)
rspec (~> 3.7)
- selenium-webdriver (~> 3.8.0)
+ selenium-webdriver (~> 3.12)
BUNDLED WITH
- 1.17.1
+ 1.17.3
diff --git a/spec/controllers/dashboard/milestones_controller_spec.rb b/spec/controllers/dashboard/milestones_controller_spec.rb
index 8a8cc14fd4c..c9ccd5f7c55 100644
--- a/spec/controllers/dashboard/milestones_controller_spec.rb
+++ b/spec/controllers/dashboard/milestones_controller_spec.rb
@@ -52,7 +52,7 @@ describe Dashboard::MilestonesController do
expect(response).to have_gitlab_http_status(200)
expect(json_response.size).to eq(2)
- expect(json_response.map { |i| i["first_milestone"]["id"] }).to match_array([group_milestone.id, project_milestone.id])
+ expect(json_response.map { |i| i["name"] }).to match_array([group_milestone.name, project_milestone.name])
expect(json_response.map { |i| i["group_name"] }.compact).to match_array(group.name)
end
diff --git a/spec/controllers/groups/milestones_controller_spec.rb b/spec/controllers/groups/milestones_controller_spec.rb
index b8e1e08cff7..40d991a669c 100644
--- a/spec/controllers/groups/milestones_controller_spec.rb
+++ b/spec/controllers/groups/milestones_controller_spec.rb
@@ -64,7 +64,7 @@ describe Groups::MilestonesController do
context 'when there is a title parameter' do
it 'searches for a legacy group milestone' do
- expect(GlobalMilestone).to receive(:build)
+ expect(GroupMilestone).to receive(:build)
expect(Milestone).not_to receive(:find_by_iid)
get :show, params: { group_id: group.to_param, id: title, title: milestone1.safe_title }
diff --git a/spec/features/groups/milestone_spec.rb b/spec/features/groups/milestone_spec.rb
index 174840794ed..d57eb87ca77 100644
--- a/spec/features/groups/milestone_spec.rb
+++ b/spec/features/groups/milestone_spec.rb
@@ -81,7 +81,7 @@ describe 'Group milestones' do
description: 'Lorem Ipsum is simply dummy text'
)
end
- let!(:active_project_milestone2) { create(:milestone, project: other_project, state: 'active', title: 'v1.0') }
+ let!(:active_project_milestone2) { create(:milestone, project: other_project, state: 'active', title: 'v1.1') }
let!(:closed_project_milestone1) { create(:milestone, project: project, state: 'closed', title: 'v2.0') }
let!(:closed_project_milestone2) { create(:milestone, project: other_project, state: 'closed', title: 'v2.0') }
let!(:active_group_milestone) { create(:milestone, group: group, state: 'active', title: 'GL-113') }
@@ -104,7 +104,7 @@ describe 'Group milestones' do
legacy_milestone = GroupMilestone.build_collection(group, group.projects, { state: 'active' }).first
expect(page).to have_selector("#milestone_#{active_group_milestone.id}", count: 1)
- expect(page).to have_selector("#milestone_#{legacy_milestone.milestones.first.id}", count: 1)
+ expect(page).to have_selector("#milestone_#{legacy_milestone.milestone.id}", count: 1)
end
it 'shows milestone detail and supports its edit' do
@@ -121,6 +121,7 @@ describe 'Group milestones' do
it 'renders milestones' do
expect(page).to have_content('v1.0')
+ expect(page).to have_content('v1.1')
expect(page).to have_content('GL-113')
expect(page).to have_link(
'1 Issue',
diff --git a/spec/features/groups/milestones_sorting_spec.rb b/spec/features/groups/milestones_sorting_spec.rb
index bc226ff41c1..7bc015ea28f 100644
--- a/spec/features/groups/milestones_sorting_spec.rb
+++ b/spec/features/groups/milestones_sorting_spec.rb
@@ -42,6 +42,7 @@ describe 'Milestones sorting', :js do
expect(page).to have_button('Due later')
+ # assert descending sorting
within '.milestones' do
expect(page.all('ul.content-list > li').first.text).to include('v1.0')
expect(page.all('ul.content-list > li')[1].text).to include('v3.0')
diff --git a/spec/models/global_milestone_spec.rb b/spec/models/global_milestone_spec.rb
index b6355455c1d..62699df5611 100644
--- a/spec/models/global_milestone_spec.rb
+++ b/spec/models/global_milestone_spec.rb
@@ -65,56 +65,103 @@ describe GlobalMilestone do
)
end
- before do
- projects = [
+ let!(:projects) do
+ [
project1,
project2,
project3
]
-
- @global_milestones = described_class.build_collection(projects, {})
end
- it 'has all project milestones' do
- expect(@global_milestones.count).to eq(2)
+ let!(:global_milestones) { described_class.build_collection(projects, {}) }
+
+ context 'when building a collection of milestones' do
+ it 'has all project milestones' do
+ expect(global_milestones.count).to eq(6)
+ end
+
+ it 'has all project milestones titles' do
+ expect(global_milestones.map(&:title)).to match_array(['Milestone v1.2', 'Milestone v1.2', 'Milestone v1.2', 'VD-123', 'VD-123', 'VD-123'])
+ end
+
+ it 'has all project milestones' do
+ expect(global_milestones.size).to eq(6)
+ end
+
+ it 'sorts collection by due date' do
+ expect(global_milestones.map(&:due_date)).to eq [milestone1_due_date, milestone1_due_date, milestone1_due_date, nil, nil, nil]
+ end
end
- it 'has all project milestones titles' do
- expect(@global_milestones.map(&:title)).to match_array(['Milestone v1.2', 'VD-123'])
+ context 'when adding new milestones' do
+ it 'does not add more queries' do
+ control_count = ActiveRecord::QueryRecorder.new do
+ described_class.build_collection(projects, {})
+ end.count
+
+ create_list(:milestone, 3, project: project3)
+
+ expect do
+ described_class.build_collection(projects, {})
+ end.not_to exceed_all_query_limit(control_count)
+ end
end
+ end
+
+ describe '.states_count' do
+ context 'when the projects have milestones' do
+ before do
+ create(:closed_milestone, title: 'Active Group Milestone', project: project3)
+ create(:active_milestone, title: 'Active Group Milestone', project: project1)
+ create(:active_milestone, title: 'Active Group Milestone', project: project2)
+ create(:closed_milestone, title: 'Closed Group Milestone', project: project1)
+ create(:closed_milestone, title: 'Closed Group Milestone', project: project2)
+ create(:closed_milestone, title: 'Closed Group Milestone', project: project3)
+ create(:closed_milestone, title: 'Closed Group Milestone 4', group: group)
+ end
+
+ it 'returns the quantity of global milestones and group milestones in each possible state' do
+ expected_count = { opened: 2, closed: 5, all: 7 }
- it 'has all project milestones' do
- expect(@global_milestones.map { |group_milestone| group_milestone.milestones.count }.sum).to eq(6)
+ count = described_class.states_count(Project.all, group)
+
+ expect(count).to eq(expected_count)
+ end
+
+ it 'returns the quantity of global milestones in each possible state' do
+ expected_count = { opened: 2, closed: 4, all: 6 }
+
+ count = described_class.states_count(Project.all)
+
+ expect(count).to eq(expected_count)
+ end
end
- it 'sorts collection by due date' do
- expect(@global_milestones.map(&:due_date)).to eq [nil, milestone1_due_date]
+ context 'when the projects do not have milestones' do
+ before do
+ project1
+ end
+
+ it 'returns 0 as the quantity of global milestones in each state' do
+ expected_count = { opened: 0, closed: 0, all: 0 }
+
+ count = described_class.states_count(Project.all)
+
+ expect(count).to eq(expected_count)
+ end
end
end
describe '#initialize' do
let(:milestone1_project1) { create(:milestone, title: "Milestone v1.2", project: project1) }
- let(:milestone1_project2) { create(:milestone, title: "Milestone v1.2", project: project2) }
- let(:milestone1_project3) { create(:milestone, title: "Milestone v1.2", project: project3) }
-
- before do
- milestones =
- [
- milestone1_project1,
- milestone1_project2,
- milestone1_project3
- ]
- milestones_relation = Milestone.where(id: milestones.map(&:id))
-
- @global_milestone = described_class.new(milestone1_project1.title, milestones_relation)
- end
+ subject(:global_milestone) { described_class.new(milestone1_project1) }
it 'has exactly one group milestone' do
- expect(@global_milestone.title).to eq('Milestone v1.2')
+ expect(global_milestone.title).to eq('Milestone v1.2')
end
it 'has all project milestones with the same title' do
- expect(@global_milestone.milestones.count).to eq(3)
+ expect(global_milestone.milestone).to eq(milestone1_project1)
end
end
@@ -122,7 +169,7 @@ describe GlobalMilestone do
let(:milestone) { create(:milestone, title: "git / test", project: project1) }
it 'strips out slashes and spaces' do
- global_milestone = described_class.new(milestone.title, Milestone.where(id: milestone.id))
+ global_milestone = described_class.new(milestone)
expect(global_milestone.safe_title).to eq('git-test')
end
@@ -132,11 +179,8 @@ describe GlobalMilestone do
context 'when at least one milestone is active' do
it 'returns active' do
title = 'Active Group Milestone'
- milestones = [
- create(:active_milestone, title: title),
- create(:closed_milestone, title: title)
- ]
- global_milestone = described_class.new(title, milestones)
+
+ global_milestone = described_class.new(create(:active_milestone, title: title))
expect(global_milestone.state).to eq('active')
end
@@ -145,11 +189,8 @@ describe GlobalMilestone do
context 'when all milestones are closed' do
it 'returns closed' do
title = 'Closed Group Milestone'
- milestones = [
- create(:closed_milestone, title: title),
- create(:closed_milestone, title: title)
- ]
- global_milestone = described_class.new(title, milestones)
+
+ global_milestone = described_class.new(create(:closed_milestone, title: title))
expect(global_milestone.state).to eq('closed')
end
diff --git a/spec/models/group_milestone_spec.rb b/spec/models/group_milestone_spec.rb
index b60676afc91..fcc33cd95fe 100644
--- a/spec/models/group_milestone_spec.rb
+++ b/spec/models/group_milestone_spec.rb
@@ -20,13 +20,36 @@ describe GroupMilestone do
end
describe '.build_collection' do
- before do
- project_milestone
+ let(:group) { create(:group) }
+ let(:project1) { create(:project, group: group) }
+ let(:project2) { create(:project, path: 'gitlab-ci', group: group) }
+ let(:project3) { create(:project, path: 'cookbook-gitlab', group: group) }
+
+ let!(:projects) do
+ [
+ project1,
+ project2,
+ project3
+ ]
end
it 'returns array of milestones, each with group assigned' do
milestones = described_class.build_collection(group, [project], {})
expect(milestones).to all(have_attributes(group: group))
end
+
+ context 'when adding new milestones' do
+ it 'does not add more queries' do
+ control_count = ActiveRecord::QueryRecorder.new do
+ described_class.build_collection(group, projects, {})
+ end.count
+
+ create(:milestone, title: 'This title', project: project1)
+
+ expect do
+ described_class.build_collection(group, projects, {})
+ end.not_to exceed_all_query_limit(control_count)
+ end
+ end
end
end
diff --git a/spec/requests/api/runner_spec.rb b/spec/requests/api/runner_spec.rb
index c63621fe7d1..2f322cc7054 100644
--- a/spec/requests/api/runner_spec.rb
+++ b/spec/requests/api/runner_spec.rb
@@ -1320,7 +1320,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do
end
before do
- fog_connection.directories.get('artifacts').files.create(
+ fog_connection.directories.new(key: 'artifacts').files.create(
key: 'tmp/uploads/12312300',
body: 'content'
)
diff --git a/spec/requests/lfs_http_spec.rb b/spec/requests/lfs_http_spec.rb
index 3cc29a7076d..f1514e90eb2 100644
--- a/spec/requests/lfs_http_spec.rb
+++ b/spec/requests/lfs_http_spec.rb
@@ -1123,7 +1123,7 @@ describe 'Git LFS API and storage' do
context 'with valid remote_id' do
before do
- fog_connection.directories.get('lfs-objects').files.create(
+ fog_connection.directories.new(key: 'lfs-objects').files.create(
key: 'tmp/uploads/12312300',
body: 'content'
)
diff --git a/spec/uploaders/file_uploader_spec.rb b/spec/uploaders/file_uploader_spec.rb
index c74e0bf1955..db9e5eb2ad6 100644
--- a/spec/uploaders/file_uploader_spec.rb
+++ b/spec/uploaders/file_uploader_spec.rb
@@ -201,7 +201,7 @@ describe FileUploader do
end
let!(:fog_file) do
- fog_connection.directories.get('uploads').files.create(
+ fog_connection.directories.new(key: 'uploads').files.create(
key: 'tmp/uploads/test/123123',
body: 'content'
)
diff --git a/spec/uploaders/object_storage_spec.rb b/spec/uploaders/object_storage_spec.rb
index 7e673681c31..533e9d87ea6 100644
--- a/spec/uploaders/object_storage_spec.rb
+++ b/spec/uploaders/object_storage_spec.rb
@@ -716,7 +716,7 @@ describe ObjectStorage do
end
let!(:fog_file) do
- fog_connection.directories.get('uploads').files.create(
+ fog_connection.directories.new(key: 'uploads').files.create(
key: 'tmp/uploads/test/123123',
body: 'content'
)