summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2019-12-03 18:06:49 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2019-12-03 18:06:49 +0000
commitab7cf450ba19cf80b9534f25dc707b33845e3014 (patch)
treebbfa6aba83c48aea68d79c4179ce576b6eec326d /app
parent4204cf308596e0e26f578a6e2da88f49c0f4aad9 (diff)
downloadgitlab-ce-ab7cf450ba19cf80b9534f25dc707b33845e3014.tar.gz
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
-rw-r--r--app/assets/javascripts/pages/instance_statistics/dev_ops_score/index.js (renamed from app/assets/javascripts/pages/instance_statistics/conversational_development_index/index.js)0
-rw-r--r--app/controllers/application_controller.rb10
-rw-r--r--app/controllers/concerns/confirm_email_warning.rb7
-rw-r--r--app/controllers/concerns/sourcegraph_gon.rb2
-rw-r--r--app/controllers/concerns/uploads_actions.rb19
-rw-r--r--app/controllers/instance_statistics/dev_ops_score_controller.rb (renamed from app/controllers/instance_statistics/conversational_development_index_controller.rb)2
-rw-r--r--app/controllers/projects/branches_controller.rb8
-rw-r--r--app/finders/clusters/knative_version_role_binding_finder.rb17
-rw-r--r--app/graphql/mutations/issues/set_confidential.rb27
-rw-r--r--app/graphql/mutations/todos/mark_done.rb7
-rw-r--r--app/graphql/types/mutation_type.rb1
-rw-r--r--app/models/ci/build.rb12
-rw-r--r--app/models/clusters/platforms/kubernetes.rb15
-rw-r--r--app/models/concerns/ci/contextable.rb11
-rw-r--r--app/models/dashboard_group_milestone.rb4
-rw-r--r--app/models/dashboard_milestone.rb4
-rw-r--r--app/models/group_milestone.rb4
-rw-r--r--app/models/milestone.rb10
-rw-r--r--app/models/project.rb8
-rw-r--r--app/services/branches/create_service.rb39
-rw-r--r--app/services/branches/delete_merged_service.rb34
-rw-r--r--app/services/branches/delete_service.rb32
-rw-r--r--app/services/branches/validate_new_service.rb31
-rw-r--r--app/services/clusters/kubernetes/create_or_update_service_account_service.rb41
-rw-r--r--app/services/clusters/kubernetes/kubernetes.rb3
-rw-r--r--app/services/commits/commit_patch_service.rb2
-rw-r--r--app/services/commits/create_service.rb2
-rw-r--r--app/services/create_branch_service.rb38
-rw-r--r--app/services/delete_branch_service.rb30
-rw-r--r--app/services/delete_merged_branches_service.rb32
-rw-r--r--app/services/merge_requests/create_from_issue_service.rb2
-rw-r--r--app/services/merge_requests/merge_service.rb2
-rw-r--r--app/services/todo_service.rb8
-rw-r--r--app/services/validate_new_branch_service.rb21
-rw-r--r--app/views/instance_statistics/dev_ops_score/_callout.html.haml (renamed from app/views/instance_statistics/conversational_development_index/_callout.html.haml)6
-rw-r--r--app/views/instance_statistics/dev_ops_score/_card.html.haml (renamed from app/views/instance_statistics/conversational_development_index/_card.html.haml)0
-rw-r--r--app/views/instance_statistics/dev_ops_score/_disabled.html.haml (renamed from app/views/instance_statistics/conversational_development_index/_disabled.html.haml)2
-rw-r--r--app/views/instance_statistics/dev_ops_score/_no_data.html.haml (renamed from app/views/instance_statistics/conversational_development_index/_no_data.html.haml)4
-rw-r--r--app/views/instance_statistics/dev_ops_score/index.html.haml (renamed from app/views/instance_statistics/conversational_development_index/index.html.haml)4
-rw-r--r--app/views/layouts/nav/_dashboard.html.haml2
-rw-r--r--app/views/layouts/nav/sidebar/_instance_statistics.html.haml8
-rw-r--r--app/views/shared/icons/_dev_ops_score_no_data.svg (renamed from app/views/shared/icons/_convdev_no_data.svg)0
-rw-r--r--app/views/shared/icons/_dev_ops_score_no_index.svg (renamed from app/views/shared/icons/_convdev_no_index.svg)0
-rw-r--r--app/views/shared/icons/_dev_ops_score_overview.svg (renamed from app/views/shared/icons/_convdev_overview.svg)0
-rw-r--r--app/views/shared/milestones/_milestone.html.haml5
-rw-r--r--app/views/shared/milestones/_sidebar.html.haml53
-rw-r--r--app/views/shared/milestones/_tabs.html.haml16
-rw-r--r--app/workers/delete_merged_branches_worker.rb2
48 files changed, 389 insertions, 198 deletions
diff --git a/app/assets/javascripts/pages/instance_statistics/conversational_development_index/index.js b/app/assets/javascripts/pages/instance_statistics/dev_ops_score/index.js
index c1056537f90..c1056537f90 100644
--- a/app/assets/javascripts/pages/instance_statistics/conversational_development_index/index.js
+++ b/app/assets/javascripts/pages/instance_statistics/dev_ops_score/index.js
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 25c1d80b117..4d55d7f00f0 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -20,11 +20,11 @@ class ApplicationController < ActionController::Base
before_action :authenticate_user!, except: [:route_not_found]
before_action :enforce_terms!, if: :should_enforce_terms?
before_action :validate_user_service_ticket!
- before_action :check_password_expiration
+ before_action :check_password_expiration, if: :html_request?
before_action :ldap_security_check
before_action :sentry_context
before_action :default_headers
- before_action :add_gon_variables, unless: [:peek_request?, :json_request?]
+ before_action :add_gon_variables, if: :html_request?
before_action :configure_permitted_parameters, if: :devise_controller?
before_action :require_email, unless: :devise_controller?
before_action :active_user_check, unless: :devise_controller?
@@ -455,8 +455,8 @@ class ApplicationController < ActionController::Base
response.headers['Page-Title'] = URI.escape(page_title('GitLab'))
end
- def peek_request?
- request.path.start_with?('/-/peek')
+ def html_request?
+ request.format.html?
end
def json_request?
@@ -466,7 +466,7 @@ class ApplicationController < ActionController::Base
def should_enforce_terms?
return false unless Gitlab::CurrentSettings.current_application_settings.enforce_terms
- !(peek_request? || devise_controller?)
+ html_request? && !devise_controller?
end
def set_usage_stats_consent_flag
diff --git a/app/controllers/concerns/confirm_email_warning.rb b/app/controllers/concerns/confirm_email_warning.rb
index 86df0010665..32e1a46e580 100644
--- a/app/controllers/concerns/confirm_email_warning.rb
+++ b/app/controllers/concerns/confirm_email_warning.rb
@@ -4,15 +4,18 @@ module ConfirmEmailWarning
extend ActiveSupport::Concern
included do
- before_action :set_confirm_warning, if: -> { Feature.enabled?(:soft_email_confirmation) }
+ before_action :set_confirm_warning, if: :show_confirm_warning?
end
protected
+ def show_confirm_warning?
+ html_request? && request.get? && Feature.enabled?(:soft_email_confirmation)
+ end
+
def set_confirm_warning
return unless current_user
return if current_user.confirmed?
- return if peek_request? || json_request? || !request.get?
email = current_user.unconfirmed_email || current_user.email
diff --git a/app/controllers/concerns/sourcegraph_gon.rb b/app/controllers/concerns/sourcegraph_gon.rb
index ab4abd734fb..01925cf9d4d 100644
--- a/app/controllers/concerns/sourcegraph_gon.rb
+++ b/app/controllers/concerns/sourcegraph_gon.rb
@@ -4,7 +4,7 @@ module SourcegraphGon
extend ActiveSupport::Concern
included do
- before_action :push_sourcegraph_gon, unless: :json_request?
+ before_action :push_sourcegraph_gon, if: :html_request?
end
private
diff --git a/app/controllers/concerns/uploads_actions.rb b/app/controllers/concerns/uploads_actions.rb
index b87779c22d3..9b3b2c4a482 100644
--- a/app/controllers/concerns/uploads_actions.rb
+++ b/app/controllers/concerns/uploads_actions.rb
@@ -1,11 +1,16 @@
# frozen_string_literal: true
module UploadsActions
+ extend ActiveSupport::Concern
include Gitlab::Utils::StrongMemoize
include SendFileUpload
UPLOAD_MOUNTS = %w(avatar attachment file logo header_logo favicon).freeze
+ included do
+ prepend_before_action :set_request_format_from_path_extension
+ end
+
def create
uploader = UploadService.new(model, params[:file], uploader_class).execute
@@ -64,6 +69,20 @@ module UploadsActions
private
+ # Based on ActionDispatch::Http::MimeNegotiation. We have an
+ # initializer that monkey-patches this method out (so that repository
+ # paths don't guess a format based on extension), but we do want this
+ # behavior when serving uploads.
+ def set_request_format_from_path_extension
+ path = request.headers['action_dispatch.original_path'] || request.headers['PATH_INFO']
+
+ if match = path&.match(/\.(\w+)\z/)
+ format = Mime[match.captures.first]
+
+ request.format = format.symbol if format
+ end
+ end
+
def uploader_class
raise NotImplementedError
end
diff --git a/app/controllers/instance_statistics/conversational_development_index_controller.rb b/app/controllers/instance_statistics/dev_ops_score_controller.rb
index f34347b4d22..238f7fa7707 100644
--- a/app/controllers/instance_statistics/conversational_development_index_controller.rb
+++ b/app/controllers/instance_statistics/dev_ops_score_controller.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class InstanceStatistics::ConversationalDevelopmentIndexController < InstanceStatistics::ApplicationController
+class InstanceStatistics::DevOpsScoreController < InstanceStatistics::ApplicationController
# rubocop: disable CodeReuse/ActiveRecord
def index
@metric = DevOpsScore::Metric.order(:created_at).last&.present
diff --git a/app/controllers/projects/branches_controller.rb b/app/controllers/projects/branches_controller.rb
index a908da08f57..09754409104 100644
--- a/app/controllers/projects/branches_controller.rb
+++ b/app/controllers/projects/branches_controller.rb
@@ -46,7 +46,7 @@ class Projects::BranchesController < Projects::ApplicationController
def diverging_commit_counts
respond_to do |format|
format.json do
- service = Branches::DivergingCommitCountsService.new(repository)
+ service = ::Branches::DivergingCommitCountsService.new(repository)
branches = BranchesFinder.new(repository, params.permit(names: [])).execute
Gitlab::GitalyClient.allow_n_plus_1_calls do
@@ -63,7 +63,7 @@ class Projects::BranchesController < Projects::ApplicationController
redirect_to_autodeploy = project.empty_repo? && project.deployment_platform.present?
- result = CreateBranchService.new(project, current_user)
+ result = ::Branches::CreateService.new(project, current_user)
.execute(branch_name, ref)
success = (result[:status] == :success)
@@ -102,7 +102,7 @@ class Projects::BranchesController < Projects::ApplicationController
def destroy
@branch_name = Addressable::URI.unescape(params[:id])
- result = DeleteBranchService.new(project, current_user).execute(@branch_name)
+ result = ::Branches::DeleteService.new(project, current_user).execute(@branch_name)
respond_to do |format|
format.html do
@@ -118,7 +118,7 @@ class Projects::BranchesController < Projects::ApplicationController
end
def destroy_all_merged
- DeleteMergedBranchesService.new(@project, current_user).async_execute
+ ::Branches::DeleteMergedService.new(@project, current_user).async_execute
redirect_to project_branches_path(@project),
notice: _('Merged branches are being deleted. This can take some time depending on the number of branches. Please refresh the page to see changes.')
diff --git a/app/finders/clusters/knative_version_role_binding_finder.rb b/app/finders/clusters/knative_version_role_binding_finder.rb
new file mode 100644
index 00000000000..06ec5ea557f
--- /dev/null
+++ b/app/finders/clusters/knative_version_role_binding_finder.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+module Clusters
+ class KnativeVersionRoleBindingFinder
+ attr_reader :cluster
+
+ def initialize(cluster)
+ @cluster = cluster
+ end
+
+ def execute
+ cluster&.kubeclient&.get_cluster_role_bindings&.find do |resource|
+ resource.metadata.name == Clusters::Kubernetes::GITLAB_KNATIVE_VERSION_ROLE_BINDING_NAME
+ end
+ end
+ end
+end
diff --git a/app/graphql/mutations/issues/set_confidential.rb b/app/graphql/mutations/issues/set_confidential.rb
new file mode 100644
index 00000000000..0fff5518665
--- /dev/null
+++ b/app/graphql/mutations/issues/set_confidential.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+module Mutations
+ module Issues
+ class SetConfidential < Base
+ graphql_name 'IssueSetConfidential'
+
+ argument :confidential,
+ GraphQL::BOOLEAN_TYPE,
+ required: true,
+ description: 'Whether or not to set the issue as a confidential.'
+
+ def resolve(project_path:, iid:, confidential:)
+ issue = authorized_find!(project_path: project_path, iid: iid)
+ project = issue.project
+
+ ::Issues::UpdateService.new(project, current_user, confidential: confidential)
+ .execute(issue)
+
+ {
+ issue: issue,
+ errors: issue.errors.full_messages
+ }
+ end
+ end
+ end
+end
diff --git a/app/graphql/mutations/todos/mark_done.rb b/app/graphql/mutations/todos/mark_done.rb
index 5483708b5c6..d738e387c43 100644
--- a/app/graphql/mutations/todos/mark_done.rb
+++ b/app/graphql/mutations/todos/mark_done.rb
@@ -16,22 +16,21 @@ module Mutations
null: false,
description: 'The requested todo'
- # rubocop: disable CodeReuse/ActiveRecord
def resolve(id:)
todo = authorized_find!(id: id)
- mark_done(Todo.where(id: todo.id)) unless todo.done?
+
+ mark_done(todo)
{
todo: todo.reset,
errors: errors_on_object(todo)
}
end
- # rubocop: enable CodeReuse/ActiveRecord
private
def mark_done(todo)
- TodoService.new.mark_todos_as_done(todo, current_user)
+ TodoService.new.mark_todo_as_done(todo, current_user)
end
end
end
diff --git a/app/graphql/types/mutation_type.rb b/app/graphql/types/mutation_type.rb
index ecdbba477d7..e8f4ec06177 100644
--- a/app/graphql/types/mutation_type.rb
+++ b/app/graphql/types/mutation_type.rb
@@ -9,6 +9,7 @@ module Types
mount_mutation Mutations::AwardEmojis::Add
mount_mutation Mutations::AwardEmojis::Remove
mount_mutation Mutations::AwardEmojis::Toggle
+ mount_mutation Mutations::Issues::SetConfidential
mount_mutation Mutations::Issues::SetDueDate
mount_mutation Mutations::MergeRequests::SetLabels
mount_mutation Mutations::MergeRequests::SetLocked
diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb
index caa4478c848..1293b0d0f59 100644
--- a/app/models/ci/build.rb
+++ b/app/models/ci/build.rb
@@ -425,6 +425,18 @@ module Ci
end
end
+ def expanded_kubernetes_namespace
+ return unless has_environment?
+
+ namespace = options.dig(:environment, :kubernetes, :namespace)
+
+ if namespace.present?
+ strong_memoize(:expanded_kubernetes_namespace) do
+ ExpandVariables.expand(namespace, -> { simple_variables })
+ end
+ end
+ end
+
def has_environment?
environment.present?
end
diff --git a/app/models/clusters/platforms/kubernetes.rb b/app/models/clusters/platforms/kubernetes.rb
index 314ef78757d..ae720065387 100644
--- a/app/models/clusters/platforms/kubernetes.rb
+++ b/app/models/clusters/platforms/kubernetes.rb
@@ -63,7 +63,7 @@ module Clusters
default_value_for :authorization_type, :rbac
- def predefined_variables(project:, environment_name:)
+ def predefined_variables(project:, environment_name:, kubernetes_namespace: nil)
Gitlab::Ci::Variables::Collection.new.tap do |variables|
variables.append(key: 'KUBE_URL', value: api_url)
@@ -74,15 +74,15 @@ module Clusters
end
if !cluster.managed? || cluster.management_project == project
- namespace = Gitlab::Kubernetes::DefaultNamespace.new(cluster, project: project).from_environment_name(environment_name)
+ namespace = kubernetes_namespace || default_namespace(project, environment_name: environment_name)
variables
.append(key: 'KUBE_TOKEN', value: token, public: false, masked: true)
.append(key: 'KUBE_NAMESPACE', value: namespace)
.append(key: 'KUBECONFIG', value: kubeconfig(namespace), public: false, file: true)
- elsif kubernetes_namespace = find_persisted_namespace(project, environment_name: environment_name)
- variables.concat(kubernetes_namespace.predefined_variables)
+ elsif persisted_namespace = find_persisted_namespace(project, environment_name: environment_name)
+ variables.concat(persisted_namespace.predefined_variables)
end
variables.concat(cluster.predefined_variables)
@@ -107,6 +107,13 @@ module Clusters
private
+ def default_namespace(project, environment_name:)
+ Gitlab::Kubernetes::DefaultNamespace.new(
+ cluster,
+ project: project
+ ).from_environment_name(environment_name)
+ end
+
def find_persisted_namespace(project, environment_name:)
Clusters::KubernetesNamespaceFinder.new(
cluster,
diff --git a/app/models/concerns/ci/contextable.rb b/app/models/concerns/ci/contextable.rb
index b65e9096d4e..5ff537a7837 100644
--- a/app/models/concerns/ci/contextable.rb
+++ b/app/models/concerns/ci/contextable.rb
@@ -15,7 +15,7 @@ module Ci
variables.concat(project.predefined_variables)
variables.concat(pipeline.predefined_variables)
variables.concat(runner.predefined_variables) if runnable? && runner
- variables.concat(project.deployment_variables(environment: environment)) if environment
+ variables.concat(deployment_variables(environment: environment))
variables.concat(yaml_variables)
variables.concat(user_variables)
variables.concat(secret_group_variables)
@@ -72,6 +72,15 @@ module Ci
end
end
+ def deployment_variables(environment:)
+ return [] unless environment
+
+ project.deployment_variables(
+ environment: environment,
+ kubernetes_namespace: expanded_kubernetes_namespace
+ )
+ end
+
def secret_group_variables
return [] unless project.group
diff --git a/app/models/dashboard_group_milestone.rb b/app/models/dashboard_group_milestone.rb
index cf6094682f3..48c09f4cd6b 100644
--- a/app/models/dashboard_group_milestone.rb
+++ b/app/models/dashboard_group_milestone.rb
@@ -22,4 +22,8 @@ class DashboardGroupMilestone < GlobalMilestone
def dashboard_milestone?
true
end
+
+ def merge_requests_enabled?
+ true
+ end
end
diff --git a/app/models/dashboard_milestone.rb b/app/models/dashboard_milestone.rb
index 9b377b70e5b..fd59b94b737 100644
--- a/app/models/dashboard_milestone.rb
+++ b/app/models/dashboard_milestone.rb
@@ -12,4 +12,8 @@ class DashboardMilestone < GlobalMilestone
def project_milestone?
true
end
+
+ def merge_requests_enabled?
+ project.merge_requests_enabled?
+ end
end
diff --git a/app/models/group_milestone.rb b/app/models/group_milestone.rb
index bfda603c3cb..87338512d99 100644
--- a/app/models/group_milestone.rb
+++ b/app/models/group_milestone.rb
@@ -41,4 +41,8 @@ class GroupMilestone < GlobalMilestone
def legacy_group_milestone?
true
end
+
+ def merge_requests_enabled?
+ true
+ end
end
diff --git a/app/models/milestone.rb b/app/models/milestone.rb
index d0be54eed02..d29eb62af7a 100644
--- a/app/models/milestone.rb
+++ b/app/models/milestone.rb
@@ -274,6 +274,16 @@ class Milestone < ApplicationRecord
project_id.present?
end
+ def merge_requests_enabled?
+ if group_milestone?
+ # Assume that groups have at least one project with merge requests enabled.
+ # Otherwise, we would need to load all of the projects from the database.
+ true
+ elsif project_milestone?
+ project&.merge_requests_enabled?
+ end
+ end
+
private
# Milestone titles must be unique across project milestones and group milestones
diff --git a/app/models/project.rb b/app/models/project.rb
index 14207c48f66..03a99577d5c 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -1986,12 +1986,16 @@ class Project < ApplicationRecord
end
end
- def deployment_variables(environment:)
+ def deployment_variables(environment:, kubernetes_namespace: nil)
platform = deployment_platform(environment: environment)
return [] unless platform.present?
- platform.predefined_variables(project: self, environment_name: environment)
+ platform.predefined_variables(
+ project: self,
+ environment_name: environment,
+ kubernetes_namespace: kubernetes_namespace
+ )
end
def auto_devops_variables
diff --git a/app/services/branches/create_service.rb b/app/services/branches/create_service.rb
new file mode 100644
index 00000000000..c8afd97e6bf
--- /dev/null
+++ b/app/services/branches/create_service.rb
@@ -0,0 +1,39 @@
+# frozen_string_literal: true
+
+module Branches
+ class CreateService < BaseService
+ def execute(branch_name, ref, create_master_if_empty: true)
+ create_master_branch if create_master_if_empty && project.empty_repo?
+
+ result = ::Branches::ValidateNewService.new(project).execute(branch_name)
+
+ return result if result[:status] == :error
+
+ new_branch = repository.add_branch(current_user, branch_name, ref)
+
+ if new_branch
+ success(new_branch)
+ else
+ error("Invalid reference name: #{branch_name}")
+ end
+ rescue Gitlab::Git::PreReceiveError => ex
+ error(ex.message)
+ end
+
+ def success(branch)
+ super().merge(branch: branch)
+ end
+
+ private
+
+ def create_master_branch
+ project.repository.create_file(
+ current_user,
+ '/README.md',
+ '',
+ message: 'Add README.md',
+ branch_name: 'master'
+ )
+ end
+ end
+end
diff --git a/app/services/branches/delete_merged_service.rb b/app/services/branches/delete_merged_service.rb
new file mode 100644
index 00000000000..9fd5964bf94
--- /dev/null
+++ b/app/services/branches/delete_merged_service.rb
@@ -0,0 +1,34 @@
+# frozen_string_literal: true
+
+module Branches
+ class DeleteMergedService < BaseService
+ def async_execute
+ DeleteMergedBranchesWorker.perform_async(project.id, current_user.id)
+ end
+
+ def execute
+ raise Gitlab::Access::AccessDeniedError unless can?(current_user, :push_code, project)
+
+ branches = project.repository.merged_branch_names
+ # Prevent deletion of branches relevant to open merge requests
+ branches -= merge_request_branch_names
+ # Prevent deletion of protected branches
+ branches = branches.reject { |branch| ProtectedBranch.protected?(project, branch) }
+
+ branches.each do |branch|
+ ::Branches::DeleteService.new(project, current_user).execute(branch)
+ end
+ end
+
+ private
+
+ # rubocop: disable CodeReuse/ActiveRecord
+ def merge_request_branch_names
+ # reorder(nil) is necessary for SELECT DISTINCT because default scope adds an ORDER BY
+ source_names = project.origin_merge_requests.opened.reorder(nil).distinct.pluck(:source_branch)
+ target_names = project.merge_requests.opened.reorder(nil).distinct.pluck(:target_branch)
+ (source_names + target_names).uniq
+ end
+ # rubocop: enable CodeReuse/ActiveRecord
+ end
+end
diff --git a/app/services/branches/delete_service.rb b/app/services/branches/delete_service.rb
new file mode 100644
index 00000000000..ca2b4556b58
--- /dev/null
+++ b/app/services/branches/delete_service.rb
@@ -0,0 +1,32 @@
+# frozen_string_literal: true
+
+module Branches
+ class DeleteService < BaseService
+ def execute(branch_name)
+ repository = project.repository
+ branch = repository.find_branch(branch_name)
+
+ unless current_user.can?(:push_code, project)
+ return ServiceResponse.error(
+ message: 'You dont have push access to repo',
+ http_status: 405)
+ end
+
+ unless branch
+ return ServiceResponse.error(
+ message: 'No such branch',
+ http_status: 404)
+ end
+
+ if repository.rm_branch(current_user, branch_name)
+ ServiceResponse.success(message: 'Branch was deleted')
+ else
+ ServiceResponse.error(
+ message: 'Failed to remove branch',
+ http_status: 400)
+ end
+ rescue Gitlab::Git::PreReceiveError => ex
+ ServiceResponse.error(message: ex.message, http_status: 400)
+ end
+ end
+end
diff --git a/app/services/branches/validate_new_service.rb b/app/services/branches/validate_new_service.rb
new file mode 100644
index 00000000000..e45183d160f
--- /dev/null
+++ b/app/services/branches/validate_new_service.rb
@@ -0,0 +1,31 @@
+# frozen_string_literal: true
+
+module Branches
+ class ValidateNewService < BaseService
+ def initialize(project)
+ @project = project
+ end
+
+ def execute(branch_name, force: false)
+ return error('Branch name is invalid') unless valid_name?(branch_name)
+
+ if branch_exist?(branch_name) && !force
+ return error('Branch already exists')
+ end
+
+ success
+ rescue Gitlab::Git::PreReceiveError => ex
+ error(ex.message)
+ end
+
+ private
+
+ def valid_name?(branch_name)
+ Gitlab::GitRefValidator.validate(branch_name)
+ end
+
+ def branch_exist?(branch_name)
+ project.repository.branch_exists?(branch_name)
+ end
+ end
+end
diff --git a/app/services/clusters/kubernetes/create_or_update_service_account_service.rb b/app/services/clusters/kubernetes/create_or_update_service_account_service.rb
index d798dcdcfd3..0fea398d234 100644
--- a/app/services/clusters/kubernetes/create_or_update_service_account_service.rb
+++ b/app/services/clusters/kubernetes/create_or_update_service_account_service.rb
@@ -49,8 +49,14 @@ module Clusters
create_or_update_knative_serving_role
create_or_update_knative_serving_role_binding
+
create_or_update_crossplane_database_role
create_or_update_crossplane_database_role_binding
+
+ return unless knative_serving_namespace
+
+ create_or_update_knative_version_role
+ create_or_update_knative_version_role_binding
end
private
@@ -64,6 +70,12 @@ module Clusters
).ensure_exists!
end
+ def knative_serving_namespace
+ kubeclient.core_client.get_namespaces.find do |namespace|
+ namespace.metadata.name == Clusters::Kubernetes::KNATIVE_SERVING_NAMESPACE
+ end
+ end
+
def create_role_or_cluster_role_binding
if namespace_creator
kubeclient.create_or_update_role_binding(role_binding_resource)
@@ -88,6 +100,14 @@ module Clusters
kubeclient.update_role_binding(crossplane_database_role_binding_resource)
end
+ def create_or_update_knative_version_role
+ kubeclient.update_cluster_role(knative_version_role_resource)
+ end
+
+ def create_or_update_knative_version_role_binding
+ kubeclient.update_cluster_role_binding(knative_version_role_binding_resource)
+ end
+
def service_account_resource
Gitlab::Kubernetes::ServiceAccount.new(
service_account_name,
@@ -166,6 +186,27 @@ module Clusters
service_account_name: service_account_name
).generate
end
+
+ def knative_version_role_resource
+ Gitlab::Kubernetes::ClusterRole.new(
+ name: Clusters::Kubernetes::GITLAB_KNATIVE_VERSION_ROLE_NAME,
+ rules: [{
+ apiGroups: %w(apps),
+ resources: %w(deployments),
+ verbs: %w(list get)
+ }]
+ ).generate
+ end
+
+ def knative_version_role_binding_resource
+ subjects = [{ kind: 'ServiceAccount', name: service_account_name, namespace: service_account_namespace }]
+
+ Gitlab::Kubernetes::ClusterRoleBinding.new(
+ Clusters::Kubernetes::GITLAB_KNATIVE_VERSION_ROLE_BINDING_NAME,
+ Clusters::Kubernetes::GITLAB_KNATIVE_VERSION_ROLE_NAME,
+ subjects
+ ).generate
+ end
end
end
end
diff --git a/app/services/clusters/kubernetes/kubernetes.rb b/app/services/clusters/kubernetes/kubernetes.rb
index d29519999b2..59cb1c4b3a9 100644
--- a/app/services/clusters/kubernetes/kubernetes.rb
+++ b/app/services/clusters/kubernetes/kubernetes.rb
@@ -12,5 +12,8 @@ module Clusters
GITLAB_KNATIVE_SERVING_ROLE_BINDING_NAME = 'gitlab-knative-serving-rolebinding'
GITLAB_CROSSPLANE_DATABASE_ROLE_NAME = 'gitlab-crossplane-database-role'
GITLAB_CROSSPLANE_DATABASE_ROLE_BINDING_NAME = 'gitlab-crossplane-database-rolebinding'
+ GITLAB_KNATIVE_VERSION_ROLE_NAME = 'gitlab-knative-version-role'
+ GITLAB_KNATIVE_VERSION_ROLE_BINDING_NAME = 'gitlab-knative-version-rolebinding'
+ KNATIVE_SERVING_NAMESPACE = 'knative-serving'
end
end
diff --git a/app/services/commits/commit_patch_service.rb b/app/services/commits/commit_patch_service.rb
index 49113c3c691..4fa6c30e901 100644
--- a/app/services/commits/commit_patch_service.rb
+++ b/app/services/commits/commit_patch_service.rb
@@ -32,7 +32,7 @@ module Commits
end
def prepare_branch!
- branch_result = CreateBranchService.new(project, current_user)
+ branch_result = ::Branches::CreateService.new(project, current_user)
.execute(@branch_name, @start_branch)
if branch_result[:status] != :success
diff --git a/app/services/commits/create_service.rb b/app/services/commits/create_service.rb
index b42494563b2..bd238605ac1 100644
--- a/app/services/commits/create_service.rb
+++ b/app/services/commits/create_service.rb
@@ -101,7 +101,7 @@ module Commits
end
def validate_new_branch_name!
- result = ValidateNewBranchService.new(project, current_user).execute(@branch_name, force: force?)
+ result = ::Branches::ValidateNewService.new(project).execute(@branch_name, force: force?)
if result[:status] == :error
raise_error("Something went wrong when we tried to create '#{@branch_name}' for you: #{result[:message]}")
diff --git a/app/services/create_branch_service.rb b/app/services/create_branch_service.rb
deleted file mode 100644
index d58cb0f9e2b..00000000000
--- a/app/services/create_branch_service.rb
+++ /dev/null
@@ -1,38 +0,0 @@
-# frozen_string_literal: true
-
-class CreateBranchService < BaseService
- def execute(branch_name, ref, create_master_if_empty: true)
- create_master_branch if create_master_if_empty && project.empty_repo?
-
- result = ValidateNewBranchService.new(project, current_user)
- .execute(branch_name)
-
- return result if result[:status] == :error
-
- new_branch = repository.add_branch(current_user, branch_name, ref)
-
- if new_branch
- success(new_branch)
- else
- error("Invalid reference name: #{branch_name}")
- end
- rescue Gitlab::Git::PreReceiveError => ex
- error(ex.message)
- end
-
- def success(branch)
- super().merge(branch: branch)
- end
-
- private
-
- def create_master_branch
- project.repository.create_file(
- current_user,
- '/README.md',
- '',
- message: 'Add README.md',
- branch_name: 'master'
- )
- end
-end
diff --git a/app/services/delete_branch_service.rb b/app/services/delete_branch_service.rb
deleted file mode 100644
index fd41ce54486..00000000000
--- a/app/services/delete_branch_service.rb
+++ /dev/null
@@ -1,30 +0,0 @@
-# frozen_string_literal: true
-
-class DeleteBranchService < BaseService
- def execute(branch_name)
- repository = project.repository
- branch = repository.find_branch(branch_name)
-
- unless current_user.can?(:push_code, project)
- return ServiceResponse.error(
- message: 'You dont have push access to repo',
- http_status: 405)
- end
-
- unless branch
- return ServiceResponse.error(
- message: 'No such branch',
- http_status: 404)
- end
-
- if repository.rm_branch(current_user, branch_name)
- ServiceResponse.success(message: 'Branch was deleted')
- else
- ServiceResponse.error(
- message: 'Failed to remove branch',
- http_status: 400)
- end
- rescue Gitlab::Git::PreReceiveError => ex
- ServiceResponse.error(message: ex.message, http_status: 400)
- end
-end
diff --git a/app/services/delete_merged_branches_service.rb b/app/services/delete_merged_branches_service.rb
deleted file mode 100644
index 80de897e94b..00000000000
--- a/app/services/delete_merged_branches_service.rb
+++ /dev/null
@@ -1,32 +0,0 @@
-# frozen_string_literal: true
-
-class DeleteMergedBranchesService < BaseService
- def async_execute
- DeleteMergedBranchesWorker.perform_async(project.id, current_user.id)
- end
-
- def execute
- raise Gitlab::Access::AccessDeniedError unless can?(current_user, :push_code, project)
-
- branches = project.repository.merged_branch_names
- # Prevent deletion of branches relevant to open merge requests
- branches -= merge_request_branch_names
- # Prevent deletion of protected branches
- branches = branches.reject { |branch| ProtectedBranch.protected?(project, branch) }
-
- branches.each do |branch|
- DeleteBranchService.new(project, current_user).execute(branch)
- end
- end
-
- private
-
- # rubocop: disable CodeReuse/ActiveRecord
- def merge_request_branch_names
- # reorder(nil) is necessary for SELECT DISTINCT because default scope adds an ORDER BY
- source_names = project.origin_merge_requests.opened.reorder(nil).distinct.pluck(:source_branch)
- target_names = project.merge_requests.opened.reorder(nil).distinct.pluck(:target_branch)
- (source_names + target_names).uniq
- end
- # rubocop: enable CodeReuse/ActiveRecord
-end
diff --git a/app/services/merge_requests/create_from_issue_service.rb b/app/services/merge_requests/create_from_issue_service.rb
index 200a34cae04..95fb99d3e7a 100644
--- a/app/services/merge_requests/create_from_issue_service.rb
+++ b/app/services/merge_requests/create_from_issue_service.rb
@@ -19,7 +19,7 @@ module MergeRequests
return error('Not allowed to create merge request') unless can_create_merge_request?
return error('Invalid issue iid') unless @issue_iid.present? && issue.present?
- result = CreateBranchService.new(target_project, current_user).execute(branch_name, ref)
+ result = ::Branches::CreateService.new(target_project, current_user).execute(branch_name, ref)
return result if result[:status] == :error
new_merge_request = create(merge_request)
diff --git a/app/services/merge_requests/merge_service.rb b/app/services/merge_requests/merge_service.rb
index 2eef3eed804..4a109fe4e16 100644
--- a/app/services/merge_requests/merge_service.rb
+++ b/app/services/merge_requests/merge_service.rb
@@ -99,7 +99,7 @@ module MergeRequests
log_info("Post merge finished on JID #{merge_jid} with state #{state}")
if delete_source_branch?
- DeleteBranchService.new(@merge_request.source_project, branch_deletion_user)
+ ::Branches::DeleteService.new(@merge_request.source_project, branch_deletion_user)
.execute(merge_request.source_branch)
end
end
diff --git a/app/services/todo_service.rb b/app/services/todo_service.rb
index e7bcca1a38d..55f888d5664 100644
--- a/app/services/todo_service.rb
+++ b/app/services/todo_service.rb
@@ -179,6 +179,14 @@ class TodoService
mark_todos_as_done(todos, current_user)
end
+ def mark_todo_as_done(todo, current_user)
+ return if todo.done?
+
+ todo.update(state: :done)
+
+ current_user.update_todos_count_cache
+ end
+
# When user marks some todos as pending
def mark_todos_as_pending(todos, current_user)
update_todos_state(todos, current_user, :pending)
diff --git a/app/services/validate_new_branch_service.rb b/app/services/validate_new_branch_service.rb
deleted file mode 100644
index 3f4a59e5cee..00000000000
--- a/app/services/validate_new_branch_service.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-# frozen_string_literal: true
-
-require_relative 'base_service'
-
-class ValidateNewBranchService < BaseService
- def execute(branch_name, force: false)
- valid_branch = Gitlab::GitRefValidator.validate(branch_name)
-
- unless valid_branch
- return error('Branch name is invalid')
- end
-
- if project.repository.branch_exists?(branch_name) && !force
- return error('Branch already exists')
- end
-
- success
- rescue Gitlab::Git::PreReceiveError => ex
- error(ex.message)
- end
-end
diff --git a/app/views/instance_statistics/conversational_development_index/_callout.html.haml b/app/views/instance_statistics/dev_ops_score/_callout.html.haml
index 15e31fa3d9c..61f998424f2 100644
--- a/app/views/instance_statistics/conversational_development_index/_callout.html.haml
+++ b/app/views/instance_statistics/dev_ops_score/_callout.html.haml
@@ -1,5 +1,5 @@
.prepend-top-default
-.user-callout{ data: { uid: 'convdev_intro_callout_dismissed' } }
+.user-callout{ data: { uid: 'dev_ops_score_intro_callout_dismissed' } }
.bordered-box.landing.content-block
%button.btn.btn-default.close.js-close-callout{ type: 'button',
'aria-label' => _('Dismiss ConvDev introduction') }
@@ -9,5 +9,5 @@
= _('Introducing Your Conversational Development Index')
%p
= _('Your Conversational Development Index gives an overview of how you are using GitLab from a feature perspective. View how you compare with other organizations, discover features you are not using, and learn best practices through blog posts and white papers.')
- .svg-container.devops
- = custom_icon('convdev_overview')
+ .svg-container.convdev
+ = custom_icon('dev_ops_score_overview')
diff --git a/app/views/instance_statistics/conversational_development_index/_card.html.haml b/app/views/instance_statistics/dev_ops_score/_card.html.haml
index c63bd96a175..c63bd96a175 100644
--- a/app/views/instance_statistics/conversational_development_index/_card.html.haml
+++ b/app/views/instance_statistics/dev_ops_score/_card.html.haml
diff --git a/app/views/instance_statistics/conversational_development_index/_disabled.html.haml b/app/views/instance_statistics/dev_ops_score/_disabled.html.haml
index ddcbdf6dd27..da27ea17b61 100644
--- a/app/views/instance_statistics/conversational_development_index/_disabled.html.haml
+++ b/app/views/instance_statistics/dev_ops_score/_disabled.html.haml
@@ -1,6 +1,6 @@
.container.devops-empty
.col-sm-12.justify-content-center.text-center
- = custom_icon('convdev_no_index')
+ = custom_icon('dev_ops_score_no_index')
%h4= _('Usage ping is not enabled')
- if !current_user.admin?
%p
diff --git a/app/views/instance_statistics/conversational_development_index/_no_data.html.haml b/app/views/instance_statistics/dev_ops_score/_no_data.html.haml
index 2031bced4fc..54598244039 100644
--- a/app/views/instance_statistics/conversational_development_index/_no_data.html.haml
+++ b/app/views/instance_statistics/dev_ops_score/_no_data.html.haml
@@ -1,7 +1,7 @@
.container.devops-empty
.col-sm-12.justify-content-center.text-center
- = custom_icon('convdev_no_data')
+ = custom_icon('dev_ops_score_no_data')
%h4= _('Data is still calculating...')
%p
= _('In order to gather accurate feature usage data, it can take 1 to 2 weeks to see your index.')
- = link_to _('Learn more'), help_page_path('user/instance_statistics/convdev'), target: '_blank'
+ = link_to _('Learn more'), help_page_path('user/instance_statistics/dev_ops_score'), target: '_blank'
diff --git a/app/views/instance_statistics/conversational_development_index/index.html.haml b/app/views/instance_statistics/dev_ops_score/index.html.haml
index f9a40152380..bd457f4740a 100644
--- a/app/views/instance_statistics/conversational_development_index/index.html.haml
+++ b/app/views/instance_statistics/dev_ops_score/index.html.haml
@@ -2,7 +2,7 @@
- usage_ping_enabled = Gitlab::CurrentSettings.usage_ping_enabled
.container
- - if usage_ping_enabled && show_callout?('convdev_intro_callout_dismissed')
+ - if usage_ping_enabled && show_callout?('dev_ops_score_intro_callout_dismissed')
= render 'callout'
.prepend-top-default
@@ -19,7 +19,7 @@
= _('index')
%br
= _('score')
- = link_to icon('question-circle', 'aria-hidden' => 'true'), help_page_path('user/instance_statistics/convdev')
+ = link_to icon('question-circle', 'aria-hidden' => 'true'), help_page_path('user/instance_statistics/dev_ops_score')
.devops-cards.board-card-container
- @metric.cards.each do |card|
diff --git a/app/views/layouts/nav/_dashboard.html.haml b/app/views/layouts/nav/_dashboard.html.haml
index d339751848b..9a839765286 100644
--- a/app/views/layouts/nav/_dashboard.html.haml
+++ b/app/views/layouts/nav/_dashboard.html.haml
@@ -48,7 +48,7 @@
%li.dropdown
= render_if_exists 'dashboard/nav_link_list'
- if can?(current_user, :read_instance_statistics)
- = nav_link(controller: [:conversational_development_index, :cohorts]) do
+ = nav_link(controller: [:dev_ops_score, :cohorts]) do
= link_to instance_statistics_root_path do
= _('Instance Statistics')
- if current_user.admin?
diff --git a/app/views/layouts/nav/sidebar/_instance_statistics.html.haml b/app/views/layouts/nav/sidebar/_instance_statistics.html.haml
index 57180f27146..6a5f727bb48 100644
--- a/app/views/layouts/nav/sidebar/_instance_statistics.html.haml
+++ b/app/views/layouts/nav/sidebar/_instance_statistics.html.haml
@@ -6,15 +6,15 @@
= sprite_icon('chart', size: 24)
.sidebar-context-title= _('Instance Statistics')
%ul.sidebar-top-level-items
- = nav_link(controller: :conversational_development_index) do
- = link_to instance_statistics_conversational_development_index_index_path do
+ = nav_link(controller: :dev_ops_score) do
+ = link_to instance_statistics_dev_ops_score_index_path do
.nav-icon-container
= sprite_icon('comment')
%span.nav-item-name
= _('ConvDev Index')
%ul.sidebar-sub-level-items.is-fly-out-only
- = nav_link(controller: :conversational_development_index, html_options: { class: "fly-out-top-item" } ) do
- = link_to instance_statistics_conversational_development_index_index_path do
+ = nav_link(controller: :dev_ops_score, html_options: { class: "fly-out-top-item" } ) do
+ = link_to instance_statistics_dev_ops_score_index_path do
%strong.fly-out-top-item-name
= _('ConvDev Index')
diff --git a/app/views/shared/icons/_convdev_no_data.svg b/app/views/shared/icons/_dev_ops_score_no_data.svg
index ed32b2333e7..ed32b2333e7 100644
--- a/app/views/shared/icons/_convdev_no_data.svg
+++ b/app/views/shared/icons/_dev_ops_score_no_data.svg
diff --git a/app/views/shared/icons/_convdev_no_index.svg b/app/views/shared/icons/_dev_ops_score_no_index.svg
index 95c00e81d10..95c00e81d10 100644
--- a/app/views/shared/icons/_convdev_no_index.svg
+++ b/app/views/shared/icons/_dev_ops_score_no_index.svg
diff --git a/app/views/shared/icons/_convdev_overview.svg b/app/views/shared/icons/_dev_ops_score_overview.svg
index 2f31113bad7..2f31113bad7 100644
--- a/app/views/shared/icons/_convdev_overview.svg
+++ b/app/views/shared/icons/_dev_ops_score_overview.svg
diff --git a/app/views/shared/milestones/_milestone.html.haml b/app/views/shared/milestones/_milestone.html.haml
index b324f35c338..6e50b31fd71 100644
--- a/app/views/shared/milestones/_milestone.html.haml
+++ b/app/views/shared/milestones/_milestone.html.haml
@@ -43,8 +43,9 @@
.col-sm-4.milestone-progress
= milestone_progress_bar(milestone)
= link_to pluralize(milestone.total_issues_count(current_user), 'Issue'), issues_path
- &middot;
- = link_to pluralize(milestone.merge_requests_visible_to_user(current_user).size, 'Merge Request'), merge_requests_path
+ - if milestone.merge_requests_enabled?
+ &middot;
+ = link_to pluralize(milestone.merge_requests_visible_to_user(current_user).size, 'Merge Request'), merge_requests_path
.float-lg-right.light #{milestone.percent_complete(current_user)}% complete
.col-sm-2
.milestone-actions.d-flex.justify-content-sm-start.justify-content-md-end
diff --git a/app/views/shared/milestones/_sidebar.html.haml b/app/views/shared/milestones/_sidebar.html.haml
index b6656e6283c..fbbcc4f3e68 100644
--- a/app/views/shared/milestones/_sidebar.html.haml
+++ b/app/views/shared/milestones/_sidebar.html.haml
@@ -105,38 +105,39 @@
= render_if_exists 'shared/milestones/weight', milestone: milestone
- .block.merge-requests
- .sidebar-collapsed-icon.has-tooltip{ title: milestone_merge_requests_tooltip_text(milestone), data: { container: 'body', html: 'true', placement: 'left', boundary: 'viewport' } }
- %strong
- = custom_icon('mr_bold')
- %span= milestone.merge_requests.count
- .title.hide-collapsed
- Merge requests
- %span.badge.badge-pill= milestone.merge_requests.count
- .value.hide-collapsed.bold
- - if !project || can?(current_user, :read_merge_request, project)
- %span.milestone-stat
- = link_to milestones_browse_issuables_path(milestone, type: :merge_requests) do
+ - if milestone.merge_requests_enabled?
+ .block.merge-requests
+ .sidebar-collapsed-icon.has-tooltip{ title: milestone_merge_requests_tooltip_text(milestone), data: { container: 'body', html: 'true', placement: 'left', boundary: 'viewport' } }
+ %strong
+ = custom_icon('mr_bold')
+ %span= milestone.merge_requests.count
+ .title.hide-collapsed
+ Merge requests
+ %span.badge.badge-pill= milestone.merge_requests.count
+ .value.hide-collapsed.bold
+ - if !project || can?(current_user, :read_merge_request, project)
+ %span.milestone-stat
+ = link_to milestones_browse_issuables_path(milestone, type: :merge_requests) do
+ Open:
+ = milestone.merge_requests.opened.count
+ %span.milestone-stat
+ = link_to milestones_browse_issuables_path(milestone, type: :merge_requests, state: 'closed') do
+ Closed:
+ = milestone.merge_requests.closed.count
+ %span.milestone-stat
+ = link_to milestones_browse_issuables_path(milestone, type: :merge_requests, state: 'merged') do
+ Merged:
+ = milestone.merge_requests.merged.count
+ - else
+ %span.milestone-stat
Open:
= milestone.merge_requests.opened.count
- %span.milestone-stat
- = link_to milestones_browse_issuables_path(milestone, type: :merge_requests, state: 'closed') do
+ %span.milestone-stat
Closed:
= milestone.merge_requests.closed.count
- %span.milestone-stat
- = link_to milestones_browse_issuables_path(milestone, type: :merge_requests, state: 'merged') do
+ %span.milestone-stat
Merged:
= milestone.merge_requests.merged.count
- - else
- %span.milestone-stat
- Open:
- = milestone.merge_requests.opened.count
- %span.milestone-stat
- Closed:
- = milestone.merge_requests.closed.count
- %span.milestone-stat
- Merged:
- = milestone.merge_requests.merged.count
- if project
- recent_releases, total_count, more_count = recent_releases_with_counts(milestone)
diff --git a/app/views/shared/milestones/_tabs.html.haml b/app/views/shared/milestones/_tabs.html.haml
index f718c5767d1..538ebe79641 100644
--- a/app/views/shared/milestones/_tabs.html.haml
+++ b/app/views/shared/milestones/_tabs.html.haml
@@ -6,10 +6,11 @@
= link_to '#tab-issues', class: 'nav-link active', data: { toggle: 'tab', show: '.tab-issues-buttons' } do
= _('Issues')
%span.badge.badge-pill= milestone.issues_visible_to_user(current_user).size
- %li.nav-item
- = link_to '#tab-merge-requests', class: 'nav-link', data: { toggle: 'tab', endpoint: milestone_tab_path(milestone, 'merge_requests') } do
- = _('Merge Requests')
- %span.badge.badge-pill= milestone.merge_requests_visible_to_user(current_user).size
+ - if milestone.merge_requests_enabled?
+ %li.nav-item
+ = link_to '#tab-merge-requests', class: 'nav-link', data: { toggle: 'tab', endpoint: milestone_tab_path(milestone, 'merge_requests') } do
+ = _('Merge Requests')
+ %span.badge.badge-pill= milestone.merge_requests_visible_to_user(current_user).size
%li.nav-item
= link_to '#tab-participants', class: 'nav-link', data: { toggle: 'tab', endpoint: milestone_tab_path(milestone, 'participants') } do
= _('Participants')
@@ -26,9 +27,10 @@
.tab-content.milestone-content
.tab-pane.active#tab-issues{ data: { sort_endpoint: (sort_issues_project_milestone_path(@project, @milestone) if @project && current_user) } }
= render 'shared/milestones/issues_tab', issues: issues, show_project_name: show_project_name, show_full_project_name: show_full_project_name
- .tab-pane#tab-merge-requests
- -# loaded async
- = render "shared/milestones/tab_loading"
+ - if milestone.merge_requests_enabled?
+ .tab-pane#tab-merge-requests
+ -# loaded async
+ = render "shared/milestones/tab_loading"
.tab-pane#tab-participants
-# loaded async
= render "shared/milestones/tab_loading"
diff --git a/app/workers/delete_merged_branches_worker.rb b/app/workers/delete_merged_branches_worker.rb
index 44b3db30d0d..f3d86233c1b 100644
--- a/app/workers/delete_merged_branches_worker.rb
+++ b/app/workers/delete_merged_branches_worker.rb
@@ -15,7 +15,7 @@ class DeleteMergedBranchesWorker
user = User.find(user_id)
begin
- DeleteMergedBranchesService.new(project, user).execute
+ ::Branches::DeleteMergedService.new(project, user).execute
rescue Gitlab::Access::AccessDeniedError
return
end