Commit 109a57ca authored by Douglas Barbosa Alexandre's avatar Douglas Barbosa Alexandre

Merge branch 'project-level-mr-analytics' into 'master'

Project level Merge Request analytics

See merge request gitlab-org/gitlab!38139
parents cb5d8229 2a724001
# frozen_string_literal: true
class Projects::Analytics::MergeRequestAnalyticsController < Projects::ApplicationController
before_action :authorize_read_project_merge_request_analytics!
def show
end
end
...@@ -10,7 +10,8 @@ module EE ...@@ -10,7 +10,8 @@ module EE
super + [ super + [
insights_navbar_link(project, current_user), insights_navbar_link(project, current_user),
code_review_analytics_navbar_link(project, current_user), code_review_analytics_navbar_link(project, current_user),
project_issues_analytics_navbar_link(project, current_user) project_issues_analytics_navbar_link(project, current_user),
project_merge_request_analytics_navbar_link(project, current_user)
].compact ].compact
end end
...@@ -39,6 +40,17 @@ module EE ...@@ -39,6 +40,17 @@ module EE
) )
end end
def project_merge_request_analytics_navbar_link(project, current_user)
return unless project_nav_tab?(:merge_request_analytics)
return unless ::Gitlab::Analytics.project_merge_request_analytics_enabled?
navbar_sub_item(
title: _('Merge Request'),
path: 'projects/analytics/merge_requests_analytics#show',
link: project_analytics_merge_request_analytics_path(project)
)
end
def group_merge_request_analytics_navbar_link(group, current_user) def group_merge_request_analytics_navbar_link(group, current_user)
return unless group_sidebar_link?(:merge_request_analytics) return unless group_sidebar_link?(:merge_request_analytics)
......
...@@ -35,6 +35,10 @@ module EE ...@@ -35,6 +35,10 @@ module EE
nav_tabs << :code_review nav_tabs << :code_review
end end
if can?(current_user, :read_project_merge_request_analytics, project)
nav_tabs << :merge_request_analytics
end
if can?(current_user, :read_feature_flag, project) && !nav_tabs.include?(:operations) if can?(current_user, :read_feature_flag, project) && !nav_tabs.include?(:operations)
nav_tabs << :operations nav_tabs << :operations
end end
......
...@@ -30,6 +30,7 @@ class License < ApplicationRecord ...@@ -30,6 +30,7 @@ class License < ApplicationRecord
multiple_issue_assignees multiple_issue_assignees
multiple_ldap_servers multiple_ldap_servers
multiple_merge_request_assignees multiple_merge_request_assignees
project_merge_request_analytics
protected_refs_for_users protected_refs_for_users
push_rules push_rules
related_issues related_issues
......
...@@ -63,6 +63,10 @@ module EE ...@@ -63,6 +63,10 @@ module EE
@subject.has_regulated_settings? @subject.has_regulated_settings?
end end
condition(:project_merge_request_analytics_available) do
@subject.feature_available?(:project_merge_request_analytics)
end
condition(:cannot_modify_approvers_rules) do condition(:cannot_modify_approvers_rules) do
regulated_merge_request_approval_settings? regulated_merge_request_approval_settings?
end end
...@@ -368,6 +372,9 @@ module EE ...@@ -368,6 +372,9 @@ module EE
rule { can?(:read_merge_request) & code_review_analytics_enabled }.enable :read_code_review_analytics rule { can?(:read_merge_request) & code_review_analytics_enabled }.enable :read_code_review_analytics
rule { reporter & project_merge_request_analytics_available }
.enable :read_project_merge_request_analytics
rule { can?(:read_project) & requirements_available }.enable :read_requirement rule { can?(:read_project) & requirements_available }.enable :read_requirement
rule { requirements_available & reporter }.policy do rule { requirements_available & reporter }.policy do
......
...@@ -89,6 +89,7 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do ...@@ -89,6 +89,7 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do
namespace :analytics do namespace :analytics do
resources :code_reviews, only: [:index] resources :code_reviews, only: [:index]
resource :issues_analytics, only: [:show] resource :issues_analytics, only: [:show]
resource :merge_request_analytics, only: :show, constraints: -> (req) { Gitlab::Analytics.project_merge_request_analytics_enabled? }
end end
resources :approvers, only: :destroy resources :approvers, only: :destroy
......
...@@ -7,6 +7,7 @@ module Gitlab ...@@ -7,6 +7,7 @@ module Gitlab
PRODUCTIVITY_ANALYTICS_FEATURE_FLAG = :productivity_analytics PRODUCTIVITY_ANALYTICS_FEATURE_FLAG = :productivity_analytics
GROUP_COVERAGE_REPORTS_FEATURE_FLAG = :group_coverage_reports GROUP_COVERAGE_REPORTS_FEATURE_FLAG = :group_coverage_reports
GROUP_MERGE_REQUEST_ANALYTICS_FEATURE_FLAG = :group_merge_request_analytics GROUP_MERGE_REQUEST_ANALYTICS_FEATURE_FLAG = :group_merge_request_analytics
PROJECT_MERGE_REQUEST_ANALYTICS_FEATURE_FLAG = :project_merge_request_analytics
FEATURE_FLAGS = [ FEATURE_FLAGS = [
CYCLE_ANALYTICS_FEATURE_FLAG, CYCLE_ANALYTICS_FEATURE_FLAG,
...@@ -40,6 +41,10 @@ module Gitlab ...@@ -40,6 +41,10 @@ module Gitlab
feature_enabled?(GROUP_MERGE_REQUEST_ANALYTICS_FEATURE_FLAG) feature_enabled?(GROUP_MERGE_REQUEST_ANALYTICS_FEATURE_FLAG)
end end
def self.project_merge_request_analytics_enabled?
feature_enabled?(PROJECT_MERGE_REQUEST_ANALYTICS_FEATURE_FLAG)
end
def self.feature_enabled_by_default?(flag) def self.feature_enabled_by_default?(flag)
!!FEATURE_FLAG_DEFAULTS[flag] !!FEATURE_FLAG_DEFAULTS[flag]
end end
......
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Projects::Analytics::MergeRequestAnalyticsController do
let_it_be(:current_user) { create(:user) }
let_it_be(:group) { create(:group) }
let_it_be(:project) { create(:project, group: group) }
let_it_be(:feature_flag_name) { Gitlab::Analytics::PROJECT_MERGE_REQUEST_ANALYTICS_FEATURE_FLAG }
let_it_be(:feature_name) { :project_merge_request_analytics }
before do
sign_in(current_user)
stub_feature_flags(feature_flag_name => true)
stub_licensed_features(feature_name => true)
end
describe 'GET show' do
subject { get :show, params: { namespace_id: group, project_id: project } }
before do
group.add_maintainer(current_user)
end
it { is_expected.to be_successful }
context 'when license is missing' do
before do
stub_licensed_features(feature_name => false)
end
it { is_expected.to have_gitlab_http_status(:not_found) }
end
context 'when feature flag is off' do
before do
stub_feature_flags(feature_flag_name => false)
end
it { is_expected.to have_gitlab_http_status(:not_found) }
end
context 'when the user has no access to the group' do
before do
current_user.project_authorizations.delete_all
end
it { is_expected.to have_gitlab_http_status(:not_found) }
end
end
end
...@@ -7,6 +7,7 @@ RSpec.shared_context 'project navbar structure' do ...@@ -7,6 +7,7 @@ RSpec.shared_context 'project navbar structure' do
nav_sub_items: [ nav_sub_items: [
_('CI / CD'), _('CI / CD'),
(_('Code Review') if Gitlab.ee?), (_('Code Review') if Gitlab.ee?),
(_('Merge Request') if Gitlab.ee?),
_('Repository'), _('Repository'),
_('Value Stream') _('Value Stream')
] ]
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment