Commit e34cb182 authored by Marius Bobin's avatar Marius Bobin

Add option to enable promo feature on GitLab.com

Remove ANY_PLAN_FEATURES implementation for CI/CD functionality
and replace them with a feature flag approach
parent 8c92785b
......@@ -35,3 +35,7 @@ the instance license.
```ruby
License.feature_available?(:feature_symbol)
```
## Enabling promo features on GitLab.com
A paid feature can be made available to everyone on GitLab.com by enabling the feature flag `"promo_#{feature}"`.
......@@ -187,13 +187,6 @@ class License < ApplicationRecord
'GitLab_ServiceDesk' => :service_desk
}.freeze
# Features added here are available for all namespaces.
ANY_PLAN_FEATURES = %i[
ci_cd_projects
github_project_service_integration
repository_mirrors
].freeze
# Global features that cannot be restricted to only a subset of projects or namespaces.
# Use `License.feature_available?(:feature)` to check if these features are available.
# For all other features, use `project.feature_available?` or `namespace.feature_available?` when possible.
......@@ -299,9 +292,7 @@ class License < ApplicationRecord
end
def promo_feature_available?(feature)
return false unless ::Feature.enabled?(:free_period_for_pull_mirroring, default_enabled: true)
ANY_PLAN_FEATURES.include?(feature)
::Feature.enabled?("promo_#{feature}", default_enabled: false)
end
def history
......
......@@ -142,7 +142,6 @@ class UpdateAllMirrorsWorker # rubocop:disable Scalability/IdempotentWorker
end
def check_mirror_plans_in_query?
::Gitlab::CurrentSettings.should_check_namespace_plan? &&
!::Feature.enabled?(:free_period_for_pull_mirroring, default_enabled: true)
::Gitlab::CurrentSettings.should_check_namespace_plan?
end
end
......@@ -310,6 +310,7 @@ describe Namespace do
before do
stub_application_setting_on_object(group, should_check_namespace_plan: true)
stub_feature_flags(promo_ci_cd_projects: true)
end
it 'returns true when the feature is available globally' do
......
......@@ -831,28 +831,22 @@ describe License do
end
describe '#promo_feature_available?' do
subject { described_class.promo_feature_available?(feature) }
subject { described_class.promo_feature_available?(:container_scanning) }
shared_examples 'CI CD trial features' do |status|
context 'with promo_container_scanning disabled' do
before do
stub_feature_flags(free_period_for_pull_mirroring: status)
stub_feature_flags(promo_container_scanning: false)
end
License::ANY_PLAN_FEATURES.each do |feature_name|
context "with #{feature_name}" do
let(:feature) { feature_name }
it { is_expected.to eq(status) }
end
end
it { is_expected.to be_falsey }
end
context 'with free_period_for_pull_mirroring enabled' do
it_behaves_like 'CI CD trial features', true
context 'with promo_container_scanning enabled' do
before do
stub_feature_flags(promo_container_scanning: true)
end
context 'with free_period_for_pull_mirroring disabled' do
it_behaves_like 'CI CD trial features', false
it { is_expected.to be_truthy }
end
end
......
......@@ -670,9 +670,9 @@ describe Project do
end
License::EEU_FEATURES.each do |feature_sym|
context feature_sym.to_s do
let(:feature) { feature_sym }
context feature_sym.to_s do
unless License::GLOBAL_FEATURES.include?(feature_sym)
context "checking #{feature_sym} availability both on Global and Namespace license" do
let(:check_namespace_plan) { true }
......@@ -729,6 +729,17 @@ describe Project do
is_expected.to eq(false)
end
end
context 'with promo feature flag' do
let(:allowed_on_global_license) { true }
before do
project.clear_memoization(:licensed_feature_available)
stub_feature_flags("promo_#{feature}" => true)
end
it { is_expected.to be_truthy }
end
end
end
......
......@@ -132,7 +132,6 @@ describe Projects::CreateService, '#execute' do
context 'with checks on the namespace' do
before do
stub_const('License::ANY_PLAN_FEATURES', [])
enable_namespace_license_check!
end
......
......@@ -145,10 +145,6 @@ describe UpdateAllMirrorsWorker do
project
end
before do
stub_feature_flags(free_period_for_pull_mirroring: false)
end
let_it_be(:project1) { scheduled_mirror(at: 8.weeks.ago) }
let_it_be(:project2) { scheduled_mirror(at: 7.weeks.ago) }
......@@ -188,9 +184,9 @@ describe UpdateAllMirrorsWorker do
let(:unlicensed_projects) { [unlicensed_project1, unlicensed_project2, unlicensed_project3, unlicensed_project4] }
context 'after the free period for pull mirroring' do
context 'when using SQL to filter projects' do
before do
stub_feature_flags(free_period_for_pull_mirroring: false)
allow(subject).to receive(:check_mirror_plans_in_query?).and_return(true)
end
context 'when capacity is in excess' do
......@@ -216,8 +212,7 @@ describe UpdateAllMirrorsWorker do
context 'when checking licenses on each record individually' do
before do
stub_feature_flags(free_period_for_pull_mirroring: true)
stub_const('License::ANY_PLAN_FEATURES', [])
allow(subject).to receive(:check_mirror_plans_in_query?).and_return(false)
end
context 'when capacity is in excess' do
......@@ -247,7 +242,7 @@ describe UpdateAllMirrorsWorker do
end
end
context 'when capacity is exacly sufficient' do
context 'when capacity is exactly sufficient' do
it "schedules all available mirrors" do
schedule_mirrors!(capacity: 3)
......
......@@ -199,6 +199,10 @@ RSpec.configure do |config|
stub_feature_flags(vue_issuable_sidebar: false)
stub_feature_flags(vue_issuable_epic_sidebar: false)
allow(Feature).to receive(:enabled?)
.with(/\Apromo_\w+\z/, default_enabled: false)
.and_return(false)
# Stub these calls due to being expensive operations
# It can be reenabled for specific tests via:
#
......
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