Commit 7c2e0e1b authored by Stan Hu's avatar Stan Hu Committed by Fabio Pitino

Waive credit card validation if project has paid CI/CD minutes

Previously users working on a namespace on a free plan would generally
be required to add a credit card if they use shared runners. However,
free namespaces are not really free if the owner pays for add-on CI/CD
minutes. In these instances, we should treat these namespaces as we do
with Ultimate/Premium and not require credit card validation for users
who use them.

Relates to https://gitlab.com/gitlab-org/gitlab/-/issues/349835

Changelog: fixed
EE: true
parent 9e971c74
---
name: ci_skip_require_credit_card_for_addon_ci_minutes
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/77829
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/349841
milestone: '14.7'
type: development
group: group::fulfillment
default_enabled: false
...@@ -267,7 +267,9 @@ module EE ...@@ -267,7 +267,9 @@ module EE
end end
def ci_minutes_quota def ci_minutes_quota
@ci_minutes_quota ||= ::Ci::Minutes::Quota.new(self) strong_memoize(:ci_minutes_quota) do
::Ci::Minutes::Quota.new(self)
end
end end
def new_monthly_ci_minutes_enabled? def new_monthly_ci_minutes_enabled?
......
...@@ -473,6 +473,10 @@ module EE ...@@ -473,6 +473,10 @@ module EE
return false unless created_after_credit_card_release_day?(project) return false unless created_after_credit_card_release_day?(project)
root_namespace = project.root_namespace root_namespace = project.root_namespace
ci_quota = root_namespace.ci_minutes_quota
return false if ci_quota.enabled? && ci_quota.limit.any_purchased? && ::Feature.enabled?(:ci_skip_require_credit_card_for_addon_ci_minutes, project, default_enabled: :yaml)
if root_namespace.free_plan? if root_namespace.free_plan?
::Feature.enabled?(:ci_require_credit_card_on_free_plan, project, default_enabled: :yaml) ::Feature.enabled?(:ci_require_credit_card_on_free_plan, project, default_enabled: :yaml)
elsif root_namespace.trial? elsif root_namespace.trial?
......
...@@ -1776,29 +1776,34 @@ RSpec.describe User do ...@@ -1776,29 +1776,34 @@ RSpec.describe User do
using RSpec::Parameterized::TableSyntax using RSpec::Parameterized::TableSyntax
where(:saas, :cc_present, :shared_runners, :plan, :feature_flags, :days_from_release, :result, :description) do where(:saas, :cc_present, :shared_runners, :addon_mins, :plan, :feature_flags, :days_from_release, :result, :description) do
# self-hosted # self-hosted
nil | false | :enabled | :paid | %i[free trial] | 0 | true | 'self-hosted paid plan' nil | false | :enabled | 0 | :paid | %i[free trial] | 0 | true | 'self-hosted paid plan'
nil | false | :enabled | :trial | %i[free trial] | 0 | true | 'self-hosted missing CC on trial plan' nil | false | :enabled | 0 | :trial | %i[free trial] | 0 | true | 'self-hosted missing CC on trial plan'
# saas # saas
:saas | false | :enabled | :paid | %i[free trial old_users] | 0 | true | 'missing CC on paid plan' :saas | false | :enabled | 0 | :paid | %i[free trial old_users] | 0 | true | 'missing CC on paid plan'
:saas | false | :enabled | :free | %i[free trial] | 0 | false | 'missing CC on free plan' :saas | false | :enabled | 0 | :free | %i[free trial] | 0 | false | 'missing CC on free plan'
:saas | false | nil | :free | %i[free trial] | 0 | true | 'missing CC on free plan and shared runners disabled' :saas | false | nil | 0 | :free | %i[free trial] | 0 | true | 'missing CC on free plan and shared runners disabled'
:saas | false | :enabled | :free | %i[free trial] | -1 | true | 'missing CC on free plan but old user' :saas | false | :enabled | 0 | :free | %i[free trial] | -1 | true | 'missing CC on free plan but old user'
:saas | false | :enabled | :free | %i[free trial old_users] | -1 | false | 'missing CC on free plan but old user and FF enabled' :saas | false | :enabled | 0 | :free | %i[free trial old_users] | -1 | false | 'missing CC on free plan but old user and FF enabled'
:saas | false | nil | :free | %i[free trial old_users] | -1 | true | 'missing CC on free plan but old user and FF enabled and shared runners disabled' :saas | false | nil | 0 | :free | %i[free trial old_users] | -1 | true | 'missing CC on free plan but old user and FF enabled and shared runners disabled'
:saas | true | :enabled | :free | %i[free trial] | 0 | true | 'present CC on free plan' :saas | true | :enabled | 0 | :free | %i[free trial] | 0 | true | 'present CC on free plan'
:saas | false | :enabled | :free | %i[] | 0 | true | 'missing CC on free plan - FF off' :saas | false | :enabled | 0 | :free | %i[] | 0 | true | 'missing CC on free plan - FF off'
:saas | false | :enabled | :trial | %i[free trial] | 0 | false | 'missing CC on trial plan' :saas | false | :enabled | 0 | :trial | %i[free trial] | 0 | false | 'missing CC on trial plan'
:saas | false | nil | :trial | %i[free trial] | 0 | true | 'missing CC on trial plan and shared runners disabled' :saas | false | nil | 0 | :trial | %i[free trial] | 0 | true | 'missing CC on trial plan and shared runners disabled'
:saas | false | :enabled | :trial | %i[free trial] | -1 | true | 'missing CC on trial plan but old user' :saas | false | :enabled | 0 | :trial | %i[free trial] | -1 | true | 'missing CC on trial plan but old user'
:saas | false | :enabled | :trial | %i[free trial old_users] | -1 | false | 'missing CC on trial plan but old user and FF enabled' :saas | false | :enabled | 0 | :trial | %i[free trial old_users] | -1 | false | 'missing CC on trial plan but old user and FF enabled'
:saas | false | nil | :trial | %i[free trial old_users] | -1 | true | 'missing CC on trial plan but old user and FF enabled and shared runners disabled' :saas | false | nil | 0 | :trial | %i[free trial old_users] | -1 | true | 'missing CC on trial plan but old user and FF enabled and shared runners disabled'
:saas | false | :enabled | :trial | %i[] | 0 | true | 'missing CC on trial plan - FF off' :saas | false | :enabled | 0 | :trial | %i[] | 0 | true | 'missing CC on trial plan - FF off'
:saas | true | :enabled | :trial | %i[free trial] | 0 | true | 'present CC on trial plan' :saas | true | :enabled | 0 | :trial | %i[free trial] | 0 | true | 'present CC on trial plan'
:saas | false | :enabled | 100 | :free | %i[free] | 0 | false | 'missing CC on free plan with purchased minutes - FF off'
:saas | false | :enabled | 100 | :free | %i[free skip_addon] | 0 | true | 'missing CC on free plan with purchased minutes'
:saas | false | :enabled | 100 | :trial | %i[free trial] | 0 | false | 'missing CC on trial plan with purchased minutes - FF off'
:saas | false | :enabled | 100 | :trial | %i[trial skip_addon] | 0 | true | 'missing CC on trial plan with purchased minutes'
end end
let(:shared_runners_enabled) { shared_runners == :enabled } let(:shared_runners_enabled) { shared_runners == :enabled }
...@@ -1810,11 +1815,15 @@ RSpec.describe User do ...@@ -1810,11 +1815,15 @@ RSpec.describe User do
allow(user).to receive(:credit_card_validated_at).and_return(Time.current) if cc_present allow(user).to receive(:credit_card_validated_at).and_return(Time.current) if cc_present
allow(project.namespace).to receive(:free_plan?).and_return(plan == :free) allow(project.namespace).to receive(:free_plan?).and_return(plan == :free)
allow(project.namespace).to receive(:trial?).and_return(plan == :trial) allow(project.namespace).to receive(:trial?).and_return(plan == :trial)
project.namespace.update!(extra_shared_runners_minutes_limit: addon_mins)
project.namespace.clear_memoization(:ci_minutes_quota)
project.update!(shared_runners_enabled: shared_runners_enabled) project.update!(shared_runners_enabled: shared_runners_enabled)
stub_feature_flags( stub_feature_flags(
ci_require_credit_card_on_free_plan: feature_flags.include?(:free), ci_require_credit_card_on_free_plan: feature_flags.include?(:free),
ci_require_credit_card_on_trial_plan: feature_flags.include?(:trial), ci_require_credit_card_on_trial_plan: feature_flags.include?(:trial),
ci_require_credit_card_for_old_users: feature_flags.include?(:old_users)) ci_require_credit_card_for_old_users: feature_flags.include?(:old_users),
ci_skip_require_credit_card_for_addon_ci_minutes: feature_flags.include?(:skip_addon))
end end
it description do it description do
...@@ -1830,25 +1839,30 @@ RSpec.describe User do ...@@ -1830,25 +1839,30 @@ RSpec.describe User do
using RSpec::Parameterized::TableSyntax using RSpec::Parameterized::TableSyntax
where(:saas, :cc_present, :plan, :feature_flags, :days_from_release, :result, :description) do where(:saas, :cc_present, :addon_mins, :plan, :feature_flags, :days_from_release, :result, :description) do
# self-hosted # self-hosted
nil | false | :paid | %i[free trial] | 0 | true | 'self-hosted paid plan' nil | false | 0 | :paid | %i[free trial] | 0 | true | 'self-hosted paid plan'
nil | false | :trial | %i[free trial] | 0 | true | 'self-hosted missing CC on trial plan' nil | false | 0 | :trial | %i[free trial] | 0 | true | 'self-hosted missing CC on trial plan'
# saas # saas
:saas | false | :paid | %i[free trial old_users] | 0 | true | 'missing CC on paid plan' :saas | false | 0 | :paid | %i[free trial old_users] | 0 | true | 'missing CC on paid plan'
:saas | false | 0 | :free | %i[free trial] | 0 | false | 'missing CC on free plan'
:saas | false | 0 | :free | %i[free trial] | -1 | true | 'missing CC on free plan but old user'
:saas | false | 0 | :free | %i[free trial old_users] | -1 | false | 'missing CC on free plan but old user and FF enabled'
:saas | true | 0 | :free | %i[free trial] | 0 | true | 'present CC on free plan'
:saas | false | 0 | :free | %i[] | 0 | true | 'missing CC on free plan - FF off'
:saas | false | :free | %i[free trial] | 0 | false | 'missing CC on free plan' :saas | false | 0 | :trial | %i[free trial] | 0 | false | 'missing CC on trial plan'
:saas | false | :free | %i[free trial] | -1 | true | 'missing CC on free plan but old user' :saas | false | 0 | :trial | %i[free trial] | -1 | true | 'missing CC on trial plan but old user'
:saas | false | :free | %i[free trial old_users] | -1 | false | 'missing CC on free plan but old user and FF enabled' :saas | false | 0 | :trial | %i[free trial old_users] | -1 | false | 'missing CC on trial plan but old user and FF enabled'
:saas | true | :free | %i[free trial] | 0 | true | 'present CC on free plan' :saas | false | 0 | :trial | %i[] | 0 | true | 'missing CC on trial plan - FF off'
:saas | false | :free | %i[] | 0 | true | 'missing CC on free plan - FF off' :saas | true | 0 | :trial | %i[free trial] | 0 | true | 'present CC on trial plan'
:saas | false | :trial | %i[free trial] | 0 | false | 'missing CC on trial plan' :saas | false | 100 | :free | %i[free] | 0 | false | 'missing CC on free plan with purchased minutes - FF off'
:saas | false | :trial | %i[free trial] | -1 | true | 'missing CC on trial plan but old user' :saas | false | 100 | :free | %i[free skip_addon] | 0 | true | 'missing CC on free plan with purchased minutes'
:saas | false | :trial | %i[free trial old_users] | -1 | false | 'missing CC on trial plan but old user and FF enabled' :saas | false | 100 | :trial | %i[free trial] | 0 | false | 'missing CC on trial plan with purchased minutes - FF off'
:saas | false | :trial | %i[] | 0 | true | 'missing CC on trial plan - FF off' :saas | false | 100 | :trial | %i[trial skip_addon] | 0 | true | 'missing CC on trial plan with purchased minutes'
:saas | true | :trial | %i[free trial] | 0 | true | 'present CC on trial plan'
end end
with_them do with_them do
...@@ -1858,10 +1872,13 @@ RSpec.describe User do ...@@ -1858,10 +1872,13 @@ RSpec.describe User do
allow(user).to receive(:credit_card_validated_at).and_return(Time.current) if cc_present allow(user).to receive(:credit_card_validated_at).and_return(Time.current) if cc_present
allow(project.namespace).to receive(:free_plan?).and_return(plan == :free) allow(project.namespace).to receive(:free_plan?).and_return(plan == :free)
allow(project.namespace).to receive(:trial?).and_return(plan == :trial) allow(project.namespace).to receive(:trial?).and_return(plan == :trial)
project.namespace.update!(extra_shared_runners_minutes_limit: addon_mins)
project.namespace.clear_memoization(:ci_minutes_quota)
stub_feature_flags( stub_feature_flags(
ci_require_credit_card_on_free_plan: feature_flags.include?(:free), ci_require_credit_card_on_free_plan: feature_flags.include?(:free),
ci_require_credit_card_on_trial_plan: feature_flags.include?(:trial), ci_require_credit_card_on_trial_plan: feature_flags.include?(:trial),
ci_require_credit_card_for_old_users: feature_flags.include?(:old_users)) ci_require_credit_card_for_old_users: feature_flags.include?(:old_users),
ci_skip_require_credit_card_for_addon_ci_minutes: feature_flags.include?(:skip_addon))
end end
it description do it description do
......
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