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
end
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
def new_monthly_ci_minutes_enabled?
......
......@@ -473,6 +473,10 @@ module EE
return false unless created_after_credit_card_release_day?(project)
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?
::Feature.enabled?(:ci_require_credit_card_on_free_plan, project, default_enabled: :yaml)
elsif root_namespace.trial?
......
......@@ -1776,29 +1776,34 @@ RSpec.describe User do
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
nil | false | :enabled | :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 | :paid | %i[free trial] | 0 | true | 'self-hosted paid plan'
nil | false | :enabled | 0 | :trial | %i[free trial] | 0 | true | 'self-hosted missing CC on trial plan'
# saas
:saas | false | :enabled | :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 | nil | :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 | :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 | true | :enabled | :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 | :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 | :enabled | :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 | 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 | :enabled | :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 | false | :enabled | 0 | :paid | %i[free trial old_users] | 0 | true | 'missing CC on paid plan'
:saas | false | :enabled | 0 | :free | %i[free trial] | 0 | false | 'missing CC on free plan'
:saas | false | nil | 0 | :free | %i[free trial] | 0 | true | 'missing CC on free plan and shared runners disabled'
:saas | false | :enabled | 0 | :free | %i[free trial] | -1 | true | 'missing CC on free plan but old user'
: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 | 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 | 0 | :free | %i[free trial] | 0 | true | 'present CC on free plan'
:saas | false | :enabled | 0 | :free | %i[] | 0 | true | 'missing CC on free plan - FF off'
:saas | false | :enabled | 0 | :trial | %i[free trial] | 0 | false | 'missing CC on trial plan'
:saas | false | nil | 0 | :trial | %i[free trial] | 0 | true | 'missing CC on trial plan and shared runners disabled'
:saas | false | :enabled | 0 | :trial | %i[free trial] | -1 | true | 'missing CC on trial plan but old user'
: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 | 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 | 0 | :trial | %i[] | 0 | true | 'missing CC on trial plan - FF off'
: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
let(:shared_runners_enabled) { shared_runners == :enabled }
......@@ -1810,11 +1815,15 @@ RSpec.describe User do
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(: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)
stub_feature_flags(
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_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
it description do
......@@ -1830,25 +1839,30 @@ RSpec.describe User do
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
nil | false | :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 | :paid | %i[free trial] | 0 | true | 'self-hosted paid plan'
nil | false | 0 | :trial | %i[free trial] | 0 | true | 'self-hosted missing CC on trial plan'
# 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 | :free | %i[free trial] | -1 | true | 'missing CC on free 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 | true | :free | %i[free trial] | 0 | true | 'present CC on free plan'
:saas | false | :free | %i[] | 0 | true | 'missing CC on free plan - FF off'
:saas | false | 0 | :trial | %i[free trial] | 0 | false | 'missing CC on trial plan'
:saas | false | 0 | :trial | %i[free trial] | -1 | true | 'missing CC on trial plan but old user'
:saas | false | 0 | :trial | %i[free trial old_users] | -1 | false | 'missing CC on trial plan but old user and FF enabled'
:saas | false | 0 | :trial | %i[] | 0 | true | 'missing CC on trial 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 | :trial | %i[free trial] | -1 | true | 'missing CC on trial plan but old user'
:saas | false | :trial | %i[free trial old_users] | -1 | false | 'missing CC on trial plan but old user and FF enabled'
:saas | false | :trial | %i[] | 0 | true | 'missing CC on trial plan - FF off'
:saas | true | :trial | %i[free trial] | 0 | true | 'present CC on trial plan'
:saas | false | 100 | :free | %i[free] | 0 | false | 'missing CC on free plan with purchased minutes - FF off'
:saas | false | 100 | :free | %i[free skip_addon] | 0 | true | 'missing CC on free plan with purchased minutes'
:saas | false | 100 | :trial | %i[free trial] | 0 | false | 'missing CC on trial plan with purchased minutes - FF off'
:saas | false | 100 | :trial | %i[trial skip_addon] | 0 | true | 'missing CC on trial plan with purchased minutes'
end
with_them 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(project.namespace).to receive(:free_plan?).and_return(plan == :free)
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(
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_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
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