Commit 2fa461c9 authored by Gary Holtz's avatar Gary Holtz Committed by Jarka Košanová

Adding metrics for MRs with CODEOWNER approvals

This is pretty similar to the code for counting
projects with code owners, but the merge request
model needs the `UsageStatistics` module.
parent e97e979e
...@@ -3,15 +3,16 @@ ...@@ -3,15 +3,16 @@
class ApprovalMergeRequestRule < ApplicationRecord class ApprovalMergeRequestRule < ApplicationRecord
include Gitlab::Utils::StrongMemoize include Gitlab::Utils::StrongMemoize
include ApprovalRuleLike include ApprovalRuleLike
include EE::UsageStatistics # rubocop: disable Cop/InjectEnterpriseEditionModule
scope :not_matching_pattern, -> (pattern) { code_owner.where.not(name: pattern) } scope :not_matching_pattern, -> (pattern) { code_owner.where.not(name: pattern) }
scope :matching_pattern, -> (pattern) { code_owner.where(name: pattern) } scope :matching_pattern, -> (pattern) { code_owner.where(name: pattern) }
scope :from_project_rule, -> (project_rule) do scope :from_project_rule, -> (project_rule) do
joins(:approval_merge_request_rule_source) joins(:approval_merge_request_rule_source)
.where( .where(
approval_merge_request_rule_sources: { approval_project_rule_id: project_rule.id } approval_merge_request_rule_sources: { approval_project_rule_id: project_rule.id }
) )
end end
scope :for_unmerged_merge_requests, -> (merge_requests = nil) do scope :for_unmerged_merge_requests, -> (merge_requests = nil) do
query = joins(:merge_request).where.not(merge_requests: { state_id: MergeRequest.available_states[:merged] }) query = joins(:merge_request).where.not(merge_requests: { state_id: MergeRequest.available_states[:merged] })
...@@ -22,6 +23,8 @@ class ApprovalMergeRequestRule < ApplicationRecord ...@@ -22,6 +23,8 @@ class ApprovalMergeRequestRule < ApplicationRecord
query query
end end
end end
scope :code_owner_approval_optional, -> { code_owner.where(approvals_required: 0) }
scope :code_owner_approval_required, -> { code_owner.where('approvals_required > 0') }
validates :name, uniqueness: { scope: [:merge_request_id, :rule_type] } validates :name, uniqueness: { scope: [:merge_request_id, :rule_type] }
validates :rule_type, uniqueness: { scope: :merge_request_id, message: proc { _('any-approver for the merge request already exists') } }, if: :any_approver? validates :rule_type, uniqueness: { scope: :merge_request_id, message: proc { _('any-approver for the merge request already exists') } }, if: :any_approver?
......
---
title: Adding CODEOWNER approval metrics for merge requests
merge_request: 25386
author:
type: added
...@@ -147,6 +147,8 @@ module EE ...@@ -147,6 +147,8 @@ module EE
ldap_users: count(::User.ldap, 'users.id'), ldap_users: count(::User.ldap, 'users.id'),
pod_logs_usages_total: ::Gitlab::UsageCounters::PodLogs.usage_totals[:total], pod_logs_usages_total: ::Gitlab::UsageCounters::PodLogs.usage_totals[:total],
projects_enforcing_code_owner_approval: count(::Project.without_deleted.non_archived.requiring_code_owner_approval, batch: false), projects_enforcing_code_owner_approval: count(::Project.without_deleted.non_archived.requiring_code_owner_approval, batch: false),
merge_requests_with_optional_codeowners: distinct_count(::ApprovalMergeRequestRule.code_owner_approval_optional, :merge_request_id),
merge_requests_with_required_codeowners: distinct_count(::ApprovalMergeRequestRule.code_owner_approval_required, :merge_request_id),
projects_mirrored_with_pipelines_enabled: count(::Project.mirrored_with_enabled_pipelines, batch: false), projects_mirrored_with_pipelines_enabled: count(::Project.mirrored_with_enabled_pipelines, batch: false),
projects_reporting_ci_cd_back_to_github: count(::GithubService.without_defaults.active, batch: false), projects_reporting_ci_cd_back_to_github: count(::GithubService.without_defaults.active, batch: false),
projects_with_packages: count(::Packages::Package.select('distinct project_id'), batch: false), projects_with_packages: count(::Packages::Package.select('distinct project_id'), batch: false),
...@@ -221,6 +223,8 @@ module EE ...@@ -221,6 +223,8 @@ module EE
keys: distinct_count(::Key.regular_keys.where(time_period), :user_id), keys: distinct_count(::Key.regular_keys.where(time_period), :user_id),
merge_requests: distinct_count(::MergeRequest.where(time_period), :author_id), merge_requests: distinct_count(::MergeRequest.where(time_period), :author_id),
projects_enforcing_code_owner_approval: distinct_count(::Project.requiring_code_owner_approval.where(time_period), :creator_id), projects_enforcing_code_owner_approval: distinct_count(::Project.requiring_code_owner_approval.where(time_period), :creator_id),
merge_requests_with_optional_codeowners: distinct_count(::ApprovalMergeRequestRule.code_owner_approval_optional.where(time_period), :merge_request_id),
merge_requests_with_required_codeowners: distinct_count(::ApprovalMergeRequestRule.code_owner_approval_required.where(time_period), :merge_request_id),
projects_imported_from_github: distinct_count(::Project.github_imported.where(time_period), :creator_id), projects_imported_from_github: distinct_count(::Project.github_imported.where(time_period), :creator_id),
projects_with_repositories_enabled: distinct_count(::Project.with_repositories_enabled.where(time_period), :creator_id), projects_with_repositories_enabled: distinct_count(::Project.with_repositories_enabled.where(time_period), :creator_id),
protected_branches: distinct_count(::Project.with_protected_branches.where(time_period), :creator_id), protected_branches: distinct_count(::Project.with_protected_branches.where(time_period), :creator_id),
......
...@@ -132,24 +132,30 @@ describe Gitlab::UsageData do ...@@ -132,24 +132,30 @@ describe Gitlab::UsageData do
user = create(:user) user = create(:user)
project = create(:project, :repository_private, :github_imported, project = create(:project, :repository_private, :github_imported,
:test_repo, :remote_mirror, creator: user) :test_repo, :remote_mirror, creator: user)
merge_request = create(:merge_request, source_project: project)
create(:deploy_key, user: user) create(:deploy_key, user: user)
create(:key, user: user) create(:key, user: user)
create(:merge_request, source_project: project)
create(:project, creator: user) create(:project, creator: user)
create(:protected_branch, project: project) create(:protected_branch, project: project)
create(:remote_mirror, project: project) create(:remote_mirror, project: project)
create(:snippet, author: user) create(:snippet, author: user)
create(:suggestion, note: create(:note, project: project)) create(:suggestion, note: create(:note, project: project))
create(:code_owner_rule, merge_request: merge_request, approvals_required: 3)
create(:code_owner_rule, merge_request: merge_request, approvals_required: 7)
create_list(:code_owner_rule, 3, approvals_required: 2)
create_list(:code_owner_rule, 2)
end end
end end
expect(described_class.uncached_data[:usage_activity_by_stage][:create]).to eq( expect(described_class.uncached_data[:usage_activity_by_stage][:create]).to eq(
deploy_keys: 2, deploy_keys: 2,
keys: 2, keys: 2,
merge_requests: 2, merge_requests: 12,
projects_enforcing_code_owner_approval: 0, projects_enforcing_code_owner_approval: 0,
merge_requests_with_optional_codeowners: 4,
merge_requests_with_required_codeowners: 8,
projects_imported_from_github: 2, projects_imported_from_github: 2,
projects_with_repositories_enabled: 2, projects_with_repositories_enabled: 12,
protected_branches: 2, protected_branches: 2,
remote_mirrors: 2, remote_mirrors: 2,
snippets: 2, snippets: 2,
...@@ -158,10 +164,12 @@ describe Gitlab::UsageData do ...@@ -158,10 +164,12 @@ describe Gitlab::UsageData do
expect(described_class.uncached_data[:usage_activity_by_stage_monthly][:create]).to eq( expect(described_class.uncached_data[:usage_activity_by_stage_monthly][:create]).to eq(
deploy_keys: 1, deploy_keys: 1,
keys: 1, keys: 1,
merge_requests: 1, merge_requests: 6,
projects_enforcing_code_owner_approval: 0, projects_enforcing_code_owner_approval: 0,
merge_requests_with_optional_codeowners: 2,
merge_requests_with_required_codeowners: 4,
projects_imported_from_github: 1, projects_imported_from_github: 1,
projects_with_repositories_enabled: 1, projects_with_repositories_enabled: 6,
protected_branches: 1, protected_branches: 1,
remote_mirrors: 1, remote_mirrors: 1,
snippets: 1, snippets: 1,
......
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