summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitlab/issue_templates/Query Performance Investigation.md39
-rw-r--r--GITALY_SERVER_VERSION2
-rw-r--r--Gemfile2
-rw-r--r--Gemfile.lock4
-rw-r--r--app/assets/javascripts/users_select/index.js2
-rw-r--r--app/controllers/projects/merge_requests/creations_controller.rb1
-rw-r--r--app/controllers/projects/merge_requests_controller.rb1
-rw-r--r--app/controllers/projects_controller.rb1
-rw-r--r--app/experiments/new_project_readme_experiment.rb45
-rw-r--r--app/services/merge_requests/update_service.rb15
-rw-r--r--app/views/projects/_new_project_fields.html.haml3
-rw-r--r--app/workers/post_receive.rb2
-rw-r--r--config/feature_flags/development/reviewer_approval_rules.yml8
-rw-r--r--config/feature_flags/development/usage_data_i_code_review_edit_mr_desc.yml8
-rw-r--r--config/feature_flags/development/usage_data_i_code_review_edit_mr_title.yml8
-rw-r--r--doc/subscriptions/bronze_starter.md2
-rw-r--r--doc/user/packages/container_registry/index.md14
-rw-r--r--doc/user/project/merge_requests/getting_started.md36
-rw-r--r--lib/gitlab/usage_data_counters/known_events/common.yml10
-rw-r--r--lib/gitlab/usage_data_counters/merge_request_activity_unique_counter.rb10
-rw-r--r--spec/controllers/projects_controller_spec.rb23
-rw-r--r--spec/experiments/new_project_readme_experiment_spec.rb93
-rw-r--r--spec/features/projects/user_creates_project_spec.rb6
-rw-r--r--spec/lib/gitlab/usage_data_counters/merge_request_activity_unique_counter_spec.rb16
-rw-r--r--spec/services/merge_requests/update_service_spec.rb13
-rw-r--r--spec/support/gitlab_experiment.rb2
-rw-r--r--spec/workers/post_receive_spec.rb8
27 files changed, 317 insertions, 57 deletions
diff --git a/.gitlab/issue_templates/Query Performance Investigation.md b/.gitlab/issue_templates/Query Performance Investigation.md
new file mode 100644
index 00000000000..3f2a6361d64
--- /dev/null
+++ b/.gitlab/issue_templates/Query Performance Investigation.md
@@ -0,0 +1,39 @@
+## Description
+
+As the name implies, the purpose of the template is to detail underperforming queries for futher investigation.
+
+### Steps
+
+- [ ] Rename the issue to - `Query Performance Investigation - [Query Snippet | Table info]`
+ - For example - `Query Performance Investigation - SELECT "namespaces".* FROM "namespaces" WHERE "namespaces"."id" = $1 LIMIT $2`
+- [ ] Provide information in the Requested Data Points table
+- [ ] Provide [priority and severity labels](https://about.gitlab.com/handbook/engineering/quality/issue-triage/#availability)
+- [ ] If this requires immediate attention cc `@gitlab-org/database-team` and reach out in the #g_database slack channel
+
+### Requested Data points
+
+Please provide as many of these fields as possible when submitting a query performance report.
+
+- TPS
+- Duration
+- Source of calls (Sidekiq, WebAPI, etc)
+- Query ID
+- SQL Statement
+- Query Plan
+- Query Example
+- Total number of calls (relative)
+- % of Total time
+
+<!--
+
+- Example of a postgres checkup report - https://gitlab.com/gitlab-com/gl-infra/infrastructure/-/snippets/2056787
+- Epic - Improving the Database resource usage (&365) - https://gitlab.com/groups/gitlab-com/gl-infra/-/epics/365#short-term-query-improvements
+- Past examples of query performance investigations that have led to this template creation.
+ - Possible Index suggestion or query rewriting (#292454) - https://gitlab.com/gitlab-org/gitlab/-/issues/292454)
+ - High number of Sessions to the database with the value SET parameter (#292022) - https://gitlab.com/gitlab-org/gitlab/-/issues/292022)
+ - Query performance "Select 1" (#220055) - https://gitlab.com/gitlab-org/gitlab/-/issues/220055
+ - Select statements that are in execution during database CPU utilization peak times - licenses table (#292900) - https://gitlab.com/gitlab-org/gitlab/-/issues/292900
+
+-->
+
+/label ~"group::database" ~"database::triage"
diff --git a/GITALY_SERVER_VERSION b/GITALY_SERVER_VERSION
index 84ed6bb02a5..8cff79b875e 100644
--- a/GITALY_SERVER_VERSION
+++ b/GITALY_SERVER_VERSION
@@ -1 +1 @@
-ad75eb15e8e667620e7cd1386e8361aaef7598d9
+ac9d905cb3e40b2c7cdd5369d858d608c95cf168
diff --git a/Gemfile b/Gemfile
index 3af1143e5d0..e87ec6b94c5 100644
--- a/Gemfile
+++ b/Gemfile
@@ -477,7 +477,7 @@ gem 'flipper', '~> 0.17.1'
gem 'flipper-active_record', '~> 0.17.1'
gem 'flipper-active_support_cache_store', '~> 0.17.1'
gem 'unleash', '~> 0.1.5'
-gem 'gitlab-experiment', '~> 0.4.8'
+gem 'gitlab-experiment', '~> 0.4.9'
# Structured logging
gem 'lograge', '~> 0.5'
diff --git a/Gemfile.lock b/Gemfile.lock
index 39850135e9a..9de6cbe530b 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -425,7 +425,7 @@ GEM
github-markup (1.7.0)
gitlab-chronic (0.10.5)
numerizer (~> 0.2)
- gitlab-experiment (0.4.8)
+ gitlab-experiment (0.4.9)
activesupport (>= 3.0)
scientist (~> 1.5, >= 1.5.0)
gitlab-fog-azure-rm (1.0.0)
@@ -1371,7 +1371,7 @@ DEPENDENCIES
gitaly (~> 13.8.0.pre.rc3)
github-markup (~> 1.7.0)
gitlab-chronic (~> 0.10.5)
- gitlab-experiment (~> 0.4.8)
+ gitlab-experiment (~> 0.4.9)
gitlab-fog-azure-rm (~> 1.0)
gitlab-labkit (= 0.14.0)
gitlab-license (~> 1.0)
diff --git a/app/assets/javascripts/users_select/index.js b/app/assets/javascripts/users_select/index.js
index cab30a85e2a..26d1d760454 100644
--- a/app/assets/javascripts/users_select/index.js
+++ b/app/assets/javascripts/users_select/index.js
@@ -834,7 +834,7 @@ UsersSelect.prototype.renderRowAvatar = function (issuableType, user, img) {
UsersSelect.prototype.renderApprovalRules = function (elsClassName, approvalRules = []) {
const count = approvalRules.length;
- if (!gon.features?.reviewerApprovalRules || !elsClassName?.includes('reviewer') || !count) {
+ if (!elsClassName?.includes('reviewer') || !count) {
return '';
}
diff --git a/app/controllers/projects/merge_requests/creations_controller.rb b/app/controllers/projects/merge_requests/creations_controller.rb
index 947a4a680f8..e79c19c3b67 100644
--- a/app/controllers/projects/merge_requests/creations_controller.rb
+++ b/app/controllers/projects/merge_requests/creations_controller.rb
@@ -13,7 +13,6 @@ class Projects::MergeRequests::CreationsController < Projects::MergeRequests::Ap
before_action do
push_frontend_feature_flag(:mr_collapsed_approval_rules, @project)
- push_frontend_feature_flag(:reviewer_approval_rules, @project, default_enabled: :yaml)
end
def new
diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb
index 817fb7a31f5..973e43831f1 100644
--- a/app/controllers/projects/merge_requests_controller.rb
+++ b/app/controllers/projects/merge_requests_controller.rb
@@ -53,7 +53,6 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
before_action do
push_frontend_feature_flag(:mr_collapsed_approval_rules, @project)
- push_frontend_feature_flag(:reviewer_approval_rules, @project, default_enabled: :yaml)
end
around_action :allow_gitaly_ref_name_caching, only: [:index, :show, :discussions]
diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb
index 64cb1c1ee52..0be0281a184 100644
--- a/app/controllers/projects_controller.rb
+++ b/app/controllers/projects_controller.rb
@@ -75,6 +75,7 @@ class ProjectsController < Projects::ApplicationController
@project = ::Projects::CreateService.new(current_user, project_params(attributes: project_params_create_attributes)).execute
if @project.saved?
+ experiment(:new_project_readme, actor: current_user).track(:created, property: active_new_project_tab)
redirect_to(
project_path(@project, custom_import_params),
notice: _("Project '%{project_name}' was successfully created.") % { project_name: @project.name }
diff --git a/app/experiments/new_project_readme_experiment.rb b/app/experiments/new_project_readme_experiment.rb
new file mode 100644
index 00000000000..8f88ad2adc1
--- /dev/null
+++ b/app/experiments/new_project_readme_experiment.rb
@@ -0,0 +1,45 @@
+# frozen_string_literal: true
+
+class NewProjectReadmeExperiment < ApplicationExperiment # rubocop:disable Gitlab/NamespacedClass
+ include Gitlab::Git::WrapsGitalyErrors
+
+ INITIAL_WRITE_LIMIT = 3
+ EXPERIMENT_START_DATE = DateTime.parse('2021/1/20')
+ MAX_ACCOUNT_AGE = 7.days
+
+ exclude { context.value[:actor].nil? }
+ exclude { context.actor.created_at < MAX_ACCOUNT_AGE.ago }
+
+ def control_behavior
+ false # we don't want the checkbox to be checked
+ end
+
+ def candidate_behavior
+ true # check the checkbox by default
+ end
+
+ def track_initial_writes(project)
+ return unless should_track? # early return if we don't need to ask for commit counts
+ return unless project.created_at > EXPERIMENT_START_DATE # early return for older projects
+ return unless (commit_count = commit_count_for(project)) < INITIAL_WRITE_LIMIT
+
+ track(:write, property: project.created_at.to_s, value: commit_count)
+ end
+
+ private
+
+ def commit_count_for(project)
+ raw_repo = project.repository&.raw_repository
+ return INITIAL_WRITE_LIMIT unless raw_repo&.root_ref
+
+ begin
+ Gitlab::GitalyClient::CommitService.new(raw_repo).commit_count(raw_repo.root_ref, {
+ all: true, # include all branches
+ max_count: INITIAL_WRITE_LIMIT # limit as an optimization
+ })
+ rescue StandardError => e
+ Gitlab::ErrorTracking.track_exception(e, experiment: name)
+ INITIAL_WRITE_LIMIT
+ end
+ end
+end
diff --git a/app/services/merge_requests/update_service.rb b/app/services/merge_requests/update_service.rb
index 45f81d972db..ffed0a957c2 100644
--- a/app/services/merge_requests/update_service.rb
+++ b/app/services/merge_requests/update_service.rb
@@ -87,8 +87,23 @@ module MergeRequests
MergeRequests::CloseService
end
+ def before_update(issuable, skip_spam_check: false)
+ return unless issuable.changed?
+
+ @issuable_changes = issuable.changes
+ end
+
def after_update(issuable)
issuable.cache_merge_request_closes_issues!(current_user)
+
+ return unless @issuable_changes
+
+ %w(title description).each do |action|
+ next unless @issuable_changes.key?(action)
+
+ Gitlab::UsageDataCounters::MergeRequestActivityUniqueCounter
+ .public_send("track_#{action}_edit_action".to_sym, user: current_user) # rubocop:disable GitlabSecurity/PublicSend
+ end
end
private
diff --git a/app/views/projects/_new_project_fields.html.haml b/app/views/projects/_new_project_fields.html.haml
index ee35f734e3e..2fe5ce2d5b7 100644
--- a/app/views/projects/_new_project_fields.html.haml
+++ b/app/views/projects/_new_project_fields.html.haml
@@ -54,7 +54,8 @@
.form-group.row.initialize-with-readme-setting
%div{ :class => "col-sm-12" }
.form-check
- = check_box_tag 'project[initialize_with_readme]', '1', false, class: 'form-check-input qa-initialize-with-readme-checkbox', data: { track_label: "#{track_label}", track_event: "activate_form_input", track_property: "init_with_readme", track_value: "" }
+ - experiment(:new_project_readme, actor: current_user) do |e|
+ = check_box_tag 'project[initialize_with_readme]', '1', e.run, class: 'form-check-input qa-initialize-with-readme-checkbox', data: { track_label: "#{track_label}", track_event: "activate_form_input", track_property: "init_with_readme", track_value: "" }
= label_tag 'project[initialize_with_readme]', class: 'form-check-label' do
.option-title
%strong= s_('ProjectsNew|Initialize repository with a README')
diff --git a/app/workers/post_receive.rb b/app/workers/post_receive.rb
index 9fe7dd31e68..ac55f883fc5 100644
--- a/app/workers/post_receive.rb
+++ b/app/workers/post_receive.rb
@@ -2,6 +2,7 @@
class PostReceive # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
+ include Gitlab::Experiment::Dsl
feature_category :source_code_management
urgency :high
@@ -121,6 +122,7 @@ class PostReceive # rubocop:disable Scalability/IdempotentWorker
end
def after_project_changes_hooks(project, user, refs, changes)
+ experiment(:new_project_readme, actor: user).track_initial_writes(project)
repository_update_hook_data = Gitlab::DataBuilder::Repository.update(project, user, changes, refs)
SystemHooksService.new.execute_hooks(repository_update_hook_data, :repository_update_hooks)
Gitlab::UsageDataCounters::SourceCodeCounter.count(:pushes)
diff --git a/config/feature_flags/development/reviewer_approval_rules.yml b/config/feature_flags/development/reviewer_approval_rules.yml
deleted file mode 100644
index 78bc52de5b3..00000000000
--- a/config/feature_flags/development/reviewer_approval_rules.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: reviewer_approval_rules
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/46738
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/293742
-milestone: '13.7'
-type: development
-group: group::code review
-default_enabled: true
diff --git a/config/feature_flags/development/usage_data_i_code_review_edit_mr_desc.yml b/config/feature_flags/development/usage_data_i_code_review_edit_mr_desc.yml
new file mode 100644
index 00000000000..cd49759c1d8
--- /dev/null
+++ b/config/feature_flags/development/usage_data_i_code_review_edit_mr_desc.yml
@@ -0,0 +1,8 @@
+---
+name: usage_data_i_code_review_edit_mr_desc
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/issues/292830
+rollout_issue_url:
+milestone: '13.9'
+type: development
+group: group::code review
+default_enabled: true
diff --git a/config/feature_flags/development/usage_data_i_code_review_edit_mr_title.yml b/config/feature_flags/development/usage_data_i_code_review_edit_mr_title.yml
new file mode 100644
index 00000000000..61d238b312a
--- /dev/null
+++ b/config/feature_flags/development/usage_data_i_code_review_edit_mr_title.yml
@@ -0,0 +1,8 @@
+---
+name: usage_data_i_code_review_edit_mr_title
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/issues/292830
+rollout_issue_url:
+milestone: '13.9'
+type: development
+group: group::code review
+default_enabled: true
diff --git a/doc/subscriptions/bronze_starter.md b/doc/subscriptions/bronze_starter.md
index 6977ccca0e2..8b223953007 100644
--- a/doc/subscriptions/bronze_starter.md
+++ b/doc/subscriptions/bronze_starter.md
@@ -66,7 +66,7 @@ the tiers are no longer mentioned in GitLab documentation:
- [Full code quality reports in the code quality tab](../user/project/merge_requests/code_quality.md#code-quality-reports)
- [Merge request approvals](../user/project/merge_requests/merge_request_approvals.md)
- [Multiple assignees](../user/project/merge_requests/getting_started.md#multiple-assignees)
- - [Approval Rule information for Reviewers](../user/project/merge_requests/getting_started.md#approval-rule-information-for-reviewers), and [enabling or disabling it](../user/project/merge_requests/getting_started.md#enable-or-disable-approval-rule-information-for-reviewers)
+ - [Approval Rule information for Reviewers](../user/project/merge_requests/getting_started.md#approval-rule-information-for-reviewers) **(PREMIUM)**
- [Required Approvals](../user/project/merge_requests/merge_request_approvals.md#required-approvals)
- [Code Owners as eligible approvers](../user/project/merge_requests/merge_request_approvals.md#code-owners-as-eligible-approvers)
- All [Approval rules](../user/project/merge_requests/merge_request_approvals.md#approval-rules) features
diff --git a/doc/user/packages/container_registry/index.md b/doc/user/packages/container_registry/index.md
index b19be5f6bdc..c169fd478fd 100644
--- a/doc/user/packages/container_registry/index.md
+++ b/doc/user/packages/container_registry/index.md
@@ -559,16 +559,22 @@ Here are examples of regex patterns you may want to use:
v.+
```
-- Match tags that contain `master`:
+- Match only the tag named `master`:
```plaintext
master
```
-- Match tags that either start with `v`, contain `master`, or contain `release`:
+- Match tags that are either named or start with `release`:
```plaintext
- (?:v.+|master|release)
+ release.*
+ ```
+
+- Match tags that either start with `v`, are named `master`, or begin with `release`:
+
+ ```plaintext
+ (?:v.+|master|release.*)
```
### Set cleanup limits to conserve resources
@@ -649,7 +655,7 @@ If you see the following message:
Check the regex patterns to ensure they are valid.
-You can use [Rubular](https://rubular.com/) to check your regex.
+GitLab uses [RE2 syntax](https://github.com/google/re2/wiki/Syntax) for regular expressions in the cleanup policy. You can test them with the [regex101 regex tester](https://regex101.com/).
View some common [regex pattern examples](#regex-pattern-examples).
## Use the Container Registry to store Helm Charts
diff --git a/doc/user/project/merge_requests/getting_started.md b/doc/user/project/merge_requests/getting_started.md
index 9fde7037a60..11d7dcad71b 100644
--- a/doc/user/project/merge_requests/getting_started.md
+++ b/doc/user/project/merge_requests/getting_started.md
@@ -133,16 +133,7 @@ To request it, open the **Reviewers** drop-down box to search for the user you w
#### Approval Rule information for Reviewers **(PREMIUM)**
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/233736) in GitLab 13.8.
-> - Moved to GitLab Premium in 13.9.
-> - It was [deployed behind a feature flag](../../../user/feature_flags.md), disabled by default.
-> - [Became enabled by default](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/51183) in GitLab 13.8.
-> - It's enabled on GitLab.com.
-> - It's recommended for production use.
-> - It can be enabled or disabled for a single project.
-> - For GitLab self-managed instances, GitLab administrators can opt to [disable it](#enable-or-disable-approval-rule-information-for-reviewers). **(PREMIUM SELF)**
-
-WARNING:
-This feature might not be available to you. Check the **version history** note above for details.
+> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/293742) in GitLab 13.9.
When editing the **Reviewers** field in a new or existing merge request, GitLab
displays the name of the matching [approval rule](merge_request_approvals.md#approval-rules)
@@ -156,31 +147,6 @@ This example shows reviewers and approval rules in a merge request sidebar:
![Reviewer approval rules in sidebar](img/reviewer_approval_rules_sidebar_v13_8.png)
-##### Enable or disable Approval Rule information for Reviewers **(PREMIUM SELF)**
-
-Merge Request Reviewers is under development and ready for production use.
-It is deployed behind a feature flag that is **enabled by default**.
-[GitLab administrators with access to the GitLab Rails console](../../../administration/feature_flags.md)
-can opt to disable it.
-
-To enable it:
-
-```ruby
-# For the instance
-Feature.enable(:reviewer_approval_rules)
-# For a single project
-Feature.enable(:reviewer_approval_rules, Project.find(<project id>))
-```
-
-To disable it:
-
-```ruby
-# For the instance
-Feature.disable(:reviewer_approval_rules)
-# For a single project
-Feature.disable(:reviewer_approval_rules, Project.find(<project id>))
-```
-
### Merge requests to close issues
If the merge request is being created to resolve an issue, you can
diff --git a/lib/gitlab/usage_data_counters/known_events/common.yml b/lib/gitlab/usage_data_counters/known_events/common.yml
index 413b5076a20..7c3d0ea6e42 100644
--- a/lib/gitlab/usage_data_counters/known_events/common.yml
+++ b/lib/gitlab/usage_data_counters/known_events/common.yml
@@ -496,6 +496,16 @@
category: code_review
aggregation: weekly
feature_flag: usage_data_i_code_review_user_unresolve_thread
+- name: i_code_review_edit_mr_title
+ redis_slot: code_review
+ category: code_review
+ aggregation: weekly
+ feature_flag: usage_data_i_code_review_edit_mr_title
+- name: i_code_review_edit_mr_desc
+ redis_slot: code_review
+ category: code_review
+ aggregation: weekly
+ feature_flag: usage_data_i_code_review_edit_mr_desc
- name: i_code_review_user_merge_mr
redis_slot: code_review
category: code_review
diff --git a/lib/gitlab/usage_data_counters/merge_request_activity_unique_counter.rb b/lib/gitlab/usage_data_counters/merge_request_activity_unique_counter.rb
index 1985ac0695b..a8c0cbcc1cc 100644
--- a/lib/gitlab/usage_data_counters/merge_request_activity_unique_counter.rb
+++ b/lib/gitlab/usage_data_counters/merge_request_activity_unique_counter.rb
@@ -24,6 +24,8 @@ module Gitlab
MR_UNRESOLVE_THREAD_ACTION = 'i_code_review_user_unresolve_thread'
MR_ASSIGNED_USERS_ACTION = 'i_code_review_user_assigned'
MR_REVIEW_REQUESTED_USERS_ACTION = 'i_code_review_user_review_requested'
+ MR_EDIT_MR_TITLE_ACTION = 'i_code_review_edit_mr_title'
+ MR_EDIT_MR_DESC_ACTION = 'i_code_review_edit_mr_desc'
class << self
def track_mr_diffs_action(merge_request:)
@@ -98,6 +100,14 @@ module Gitlab
track_unique_action_by_users(MR_REVIEW_REQUESTED_USERS_ACTION, users)
end
+ def track_title_edit_action(user:)
+ track_unique_action_by_user(MR_EDIT_MR_TITLE_ACTION, user)
+ end
+
+ def track_description_edit_action(user:)
+ track_unique_action_by_user(MR_EDIT_MR_DESC_ACTION, user)
+ end
+
private
def track_unique_action_by_merge_request(action, merge_request)
diff --git a/spec/controllers/projects_controller_spec.rb b/spec/controllers/projects_controller_spec.rb
index a611ac16cd9..5f09e8a0747 100644
--- a/spec/controllers/projects_controller_spec.rb
+++ b/spec/controllers/projects_controller_spec.rb
@@ -384,6 +384,29 @@ RSpec.describe ProjectsController do
end
end
+ describe 'POST create' do
+ let!(:project_params) do
+ {
+ path: 'foo',
+ description: 'bar',
+ namespace_id: user.namespace.id,
+ visibility_level: Gitlab::VisibilityLevel::PUBLIC
+ }
+ end
+
+ before do
+ sign_in(user)
+ end
+
+ it 'tracks a created event for the new_project_readme experiment', :experiment do
+ expect(experiment(:new_project_readme)).to track(:created, property: 'blank').on_any_instance.with_context(
+ actor: user
+ )
+
+ post :create, params: { project: project_params }
+ end
+ end
+
describe 'POST #archive' do
let_it_be(:group) { create(:group) }
let_it_be(:project) { create(:project, group: group) }
diff --git a/spec/experiments/new_project_readme_experiment_spec.rb b/spec/experiments/new_project_readme_experiment_spec.rb
new file mode 100644
index 00000000000..17e28cf6e7f
--- /dev/null
+++ b/spec/experiments/new_project_readme_experiment_spec.rb
@@ -0,0 +1,93 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe NewProjectReadmeExperiment, :experiment do
+ subject { described_class.new(actor: actor) }
+
+ let(:actor) { User.new(id: 42, created_at: Time.current) }
+
+ before do
+ stub_experiments(new_project_readme: :control)
+ end
+
+ describe "exclusions" do
+ let(:threshold) { described_class::MAX_ACCOUNT_AGE }
+
+ it { is_expected.to exclude(actor: User.new(created_at: (threshold + 1.minute).ago)) }
+ it { is_expected.not_to exclude(actor: User.new(created_at: (threshold - 1.minute).ago)) }
+ end
+
+ describe "the control behavior" do
+ subject { described_class.new(actor: actor).run(:control) }
+
+ it { is_expected.to be false }
+ end
+
+ describe "the candidate behavior" do
+ subject { described_class.new(actor: actor).run(:candidate) }
+
+ it { is_expected.to be true }
+ end
+
+ context "when tracking initial writes" do
+ let!(:project) { create(:project, :repository) }
+
+ def stub_gitaly_count(count = 1)
+ allow(Gitlab::GitalyClient).to receive(:call).and_call_original
+ allow(Gitlab::GitalyClient).to receive(:call).with(anything, :commit_service, :count_commits, anything, anything)
+ .and_return(double(count: count))
+ end
+
+ before do
+ stub_gitaly_count
+ end
+
+ it "tracks an event for the first commit on a project with a repository" do
+ expect(subject).to receive(:track).with(:write, property: project.created_at.to_s, value: 1).and_call_original
+
+ subject.track_initial_writes(project)
+ end
+
+ it "tracks an event for the second commit on a project with a repository" do
+ stub_gitaly_count(2)
+
+ expect(subject).to receive(:track).with(:write, property: project.created_at.to_s, value: 2).and_call_original
+
+ subject.track_initial_writes(project)
+ end
+
+ it "doesn't track if the repository has more then 2 commits" do
+ stub_gitaly_count(3)
+
+ expect(subject).not_to receive(:track)
+
+ subject.track_initial_writes(project)
+ end
+
+ it "doesn't track when we generally shouldn't" do
+ allow(subject).to receive(:should_track?).and_return(false)
+
+ expect(subject).not_to receive(:track)
+
+ subject.track_initial_writes(project)
+ end
+
+ it "doesn't track if the project is older" do
+ expect(project).to receive(:created_at).and_return(described_class::EXPERIMENT_START_DATE - 1.minute)
+
+ expect(subject).not_to receive(:track)
+
+ subject.track_initial_writes(project)
+ end
+
+ it "handles exceptions by logging them" do
+ allow(Gitlab::GitalyClient).to receive(:call).with(anything, :commit_service, :count_commits, anything, anything)
+ .and_raise(e = StandardError.new('_message_'))
+
+ expect(Gitlab::ErrorTracking).to receive(:track_exception).with(e, experiment: 'new_project_readme')
+
+ subject.track_initial_writes(project)
+ end
+ end
+end
diff --git a/spec/features/projects/user_creates_project_spec.rb b/spec/features/projects/user_creates_project_spec.rb
index feb5f348256..aff3022bd4e 100644
--- a/spec/features/projects/user_creates_project_spec.rb
+++ b/spec/features/projects/user_creates_project_spec.rb
@@ -8,6 +8,8 @@ RSpec.describe 'User creates a project', :js do
before do
sign_in(user)
create(:personal_key, user: user)
+
+ stub_experiments(new_project_readme: :candidate)
end
it 'creates a new project' do
@@ -16,6 +18,10 @@ RSpec.describe 'User creates a project', :js do
find('[data-qa-selector="blank_project_link"]').click
fill_in(:project_name, with: 'Empty')
+ # part of the new_project_readme experiment
+ expect(page).to have_checked_field 'Initialize repository with a README'
+ uncheck 'Initialize repository with a README'
+
page.within('#content-body') do
click_button('Create project')
end
diff --git a/spec/lib/gitlab/usage_data_counters/merge_request_activity_unique_counter_spec.rb b/spec/lib/gitlab/usage_data_counters/merge_request_activity_unique_counter_spec.rb
index 509ba43ef32..f5fc2e71097 100644
--- a/spec/lib/gitlab/usage_data_counters/merge_request_activity_unique_counter_spec.rb
+++ b/spec/lib/gitlab/usage_data_counters/merge_request_activity_unique_counter_spec.rb
@@ -89,6 +89,22 @@ RSpec.describe Gitlab::UsageDataCounters::MergeRequestActivityUniqueCounter, :cl
end
end
+ describe '.track_title_edit_action' do
+ subject { described_class.track_title_edit_action(user: user) }
+
+ it_behaves_like 'a tracked merge request unique event' do
+ let(:action) { described_class::MR_EDIT_MR_TITLE_ACTION }
+ end
+ end
+
+ describe '.track_description_edit_action' do
+ subject { described_class.track_description_edit_action(user: user) }
+
+ it_behaves_like 'a tracked merge request unique event' do
+ let(:action) { described_class::MR_EDIT_MR_DESC_ACTION }
+ end
+ end
+
describe '.track_create_comment_action' do
subject { described_class.track_create_comment_action(note: note) }
diff --git a/spec/services/merge_requests/update_service_spec.rb b/spec/services/merge_requests/update_service_spec.rb
index a161379b5f1..6505bf85919 100644
--- a/spec/services/merge_requests/update_service_spec.rb
+++ b/spec/services/merge_requests/update_service_spec.rb
@@ -87,6 +87,19 @@ RSpec.describe MergeRequests::UpdateService, :mailer do
expect(@merge_request.discussion_locked).to be_truthy
end
+ context 'usage counters' do
+ let(:merge_request2) { create(:merge_request) }
+
+ it 'update as expected' do
+ expect(Gitlab::UsageDataCounters::MergeRequestActivityUniqueCounter)
+ .to receive(:track_title_edit_action).once.with(user: user)
+ expect(Gitlab::UsageDataCounters::MergeRequestActivityUniqueCounter)
+ .to receive(:track_description_edit_action).once.with(user: user)
+
+ MergeRequests::UpdateService.new(project, user, opts).execute(merge_request2)
+ end
+ end
+
context 'updating milestone' do
RSpec.shared_examples 'updates milestone' do
it 'sets milestone' do
diff --git a/spec/support/gitlab_experiment.rb b/spec/support/gitlab_experiment.rb
index 7844b85963d..2281c18eb2e 100644
--- a/spec/support/gitlab_experiment.rb
+++ b/spec/support/gitlab_experiment.rb
@@ -6,7 +6,7 @@ require 'gitlab/experiment/rspec'
# This is a temporary fix until we have a larger discussion around the
# challenges raised in https://gitlab.com/gitlab-org/gitlab/-/issues/300104
class ApplicationExperiment < Gitlab::Experiment # rubocop:disable Gitlab/NamespacedClass
- def initialize(*args)
+ def initialize(name = nil, variant_name = nil, **context)
super
Feature.persist_used!(feature_flag_name)
end
diff --git a/spec/workers/post_receive_spec.rb b/spec/workers/post_receive_spec.rb
index 5b8d8878a99..aaae0988602 100644
--- a/spec/workers/post_receive_spec.rb
+++ b/spec/workers/post_receive_spec.rb
@@ -85,6 +85,14 @@ RSpec.describe PostReceive do
perform
end
+
+ it 'tracks an event for the new_project_readme experiment', :experiment do
+ expect_next_instance_of(NewProjectReadmeExperiment, :new_project_readme, nil, actor: empty_project.owner) do |e|
+ expect(e).to receive(:track_initial_writes).with(empty_project)
+ end
+
+ perform
+ end
end
shared_examples 'not updating remote mirrors' do