Commit d7134264 authored by jejacks0n's avatar jejacks0n

The readme checkbox for new projects is checked by default

Resolves the new_project_readme experiment to the candidate experience.
This experiment showed increased levels of engagement for subsequent
actions and days of engagement on projects that were included.

Changelog: changed
parent 3b265c06
......@@ -74,11 +74,6 @@ 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,
value: project_params[:initialize_with_readme].to_i
)
redirect_to(
project_path(@project, custom_import_params),
notice: _("Project '%{project_name}' was successfully created.") % { project_name: @project.name }
......
# frozen_string_literal: true
class NewProjectReadmeExperiment < ApplicationExperiment # rubocop:disable Gitlab/NamespacedClass
include ProjectCommitCount
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 (count = commit_count(project)) < INITIAL_WRITE_LIMIT
track(:write, property: project.created_at.to_s, value: count)
end
private
def commit_count(project)
commit_count_for(project,
default_count: INITIAL_WRITE_LIMIT,
max_count: INITIAL_WRITE_LIMIT,
experiment: name
)
end
end
......@@ -54,8 +54,7 @@
.form-group.row.initialize-with-readme-setting
%div{ :class => "col-sm-12" }
.form-check
- experiment(:new_project_readme, actor: current_user) do |e|
= check_box_tag 'project[initialize_with_readme]', '1', e.run, class: 'form-check-input', data: { qa_selector: "initialize_with_readme_checkbox", track_label: "#{track_label}", track_event: "activate_form_input", track_property: "init_with_readme", track_value: "" }
= check_box_tag 'project[initialize_with_readme]', '1', true, class: 'form-check-input', data: { qa_selector: "initialize_with_readme_checkbox", 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')
......
......@@ -124,7 +124,6 @@ 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)
experiment(:empty_repo_upload, project: project).track_initial_write
repository_update_hook_data = Gitlab::DataBuilder::Repository.update(project, user, changes, refs)
SystemHooksService.new.execute_hooks(repository_update_hook_data, :repository_update_hooks)
......
---
name: new_project_readme
rollout_issue_url:
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/51505
milestone: '13.8'
type: experiment
group: group::adoption
default_enabled: false
......@@ -435,32 +435,6 @@ 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,
initialize_with_readme: 1
}
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',
value: 1
).with_context(actor: user).on_next_instance
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) }
......
# 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) }
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) }
before do
stub_experiments(new_project_readme: :control)
end
it "tracks an event for the first commit on a project with a repository" do
expect(subject).to receive(:commit_count_for).with(project, default_count: described_class::INITIAL_WRITE_LIMIT, max_count: described_class::INITIAL_WRITE_LIMIT, experiment: 'new_project_readme').and_return(1)
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
allow(subject).to receive(:commit_count_for).and_return(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
allow(subject).to receive(:commit_count_for).and_return(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
end
end
......@@ -8,8 +8,6 @@ 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
......@@ -18,7 +16,6 @@ RSpec.describe 'User creates a project', :js do
find('[data-qa-panel-name="blank_project"]').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'
......
......@@ -85,14 +85,6 @@ 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
it 'tracks an event for the empty_repo_upload experiment', :experiment do
expect_next_instance_of(EmptyRepoUploadExperiment) do |e|
expect(e).to receive(:track_initial_write)
......
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