Commit 9d310f61 authored by Pavel Shutsin's avatar Pavel Shutsin

Merge branch 'minute-limit-banner' into 'master'

Add minute limit banner

See merge request gitlab-org/gitlab!84644
parents 01daca60 e077a2e6
...@@ -9,6 +9,7 @@ module Users ...@@ -9,6 +9,7 @@ module Users
FEATURE_FLAGS_NEW_VERSION = 'feature_flags_new_version' FEATURE_FLAGS_NEW_VERSION = 'feature_flags_new_version'
REGISTRATION_ENABLED_CALLOUT = 'registration_enabled_callout' REGISTRATION_ENABLED_CALLOUT = 'registration_enabled_callout'
UNFINISHED_TAG_CLEANUP_CALLOUT = 'unfinished_tag_cleanup_callout' UNFINISHED_TAG_CLEANUP_CALLOUT = 'unfinished_tag_cleanup_callout'
MINUTE_LIMIT_BANNER = 'minute_limit_banner'
SECURITY_NEWSLETTER_CALLOUT = 'security_newsletter_callout' SECURITY_NEWSLETTER_CALLOUT = 'security_newsletter_callout'
REGISTRATION_ENABLED_CALLOUT_ALLOWED_CONTROLLER_PATHS = [/^root/, /^dashboard\S*/, /^admin\S*/].freeze REGISTRATION_ENABLED_CALLOUT_ALLOWED_CONTROLLER_PATHS = [/^root/, /^dashboard\S*/, /^admin\S*/].freeze
...@@ -60,6 +61,10 @@ module Users ...@@ -60,6 +61,10 @@ module Users
!user_dismissed?(SECURITY_NEWSLETTER_CALLOUT) !user_dismissed?(SECURITY_NEWSLETTER_CALLOUT)
end end
def minute_limit_banner_dismissed?
user_dismissed?(MINUTE_LIMIT_BANNER)
end
private private
def user_dismissed?(feature_name, ignore_dismissal_earlier_than = nil) def user_dismissed?(feature_name, ignore_dismissal_earlier_than = nil)
......
...@@ -48,7 +48,8 @@ module Users ...@@ -48,7 +48,8 @@ module Users
storage_enforcement_banner_third_enforcement_threshold: 45, storage_enforcement_banner_third_enforcement_threshold: 45,
storage_enforcement_banner_fourth_enforcement_threshold: 46, storage_enforcement_banner_fourth_enforcement_threshold: 46,
attention_requests_top_nav: 47, attention_requests_top_nav: 47,
attention_requests_side_nav: 48 attention_requests_side_nav: 48,
minute_limit_banner: 49
} }
validates :feature_name, validates :feature_name,
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
- expanded = expanded_by_default? - expanded = expanded_by_default?
= render 'shared/namespaces/cascading_settings/lock_popovers' = render 'shared/namespaces/cascading_settings/lock_popovers'
= render_if_exists 'shared/minute_limit_banner', namespace: @group
%section.settings.gs-general.no-animate.expanded#js-general-settings %section.settings.gs-general.no-animate.expanded#js-general-settings
.settings-header .settings-header
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
- expanded = expanded_by_default? - expanded = expanded_by_default?
- general_expanded = @group.errors.empty? ? expanded : true - general_expanded = @group.errors.empty? ? expanded : true
= render_if_exists 'shared/minute_limit_banner', namespace: @group
-# Given we only have one field in this form which is also admin-only, -# Given we only have one field in this form which is also admin-only,
-# we don't want to show an empty section to non-admin users, -# we don't want to show an empty section to non-admin users,
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
= render_if_exists 'shared/qrtly_reconciliation_alert', group: @group = render_if_exists 'shared/qrtly_reconciliation_alert', group: @group
= render_if_exists 'shared/user_over_limit_free_plan_alert', source: @group = render_if_exists 'shared/user_over_limit_free_plan_alert', source: @group
= render_if_exists 'shared/minute_limit_banner', namespace: @group
- if show_invite_banner?(@group) - if show_invite_banner?(@group)
= content_for :group_invite_members_banner do = content_for :group_invite_members_banner do
......
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
- expanded = expanded_by_default? - expanded = expanded_by_default?
- reduce_visibility_form_id = 'reduce-visibility-form' - reduce_visibility_form_id = 'reduce-visibility-form'
= render_if_exists 'shared/minute_limit_banner', namespace: @project
%section.settings.general-settings.no-animate.expanded#js-general-settings %section.settings.general-settings.no-animate.expanded#js-general-settings
.settings-header .settings-header
%h4.settings-title.js-settings-toggle.js-settings-toggle-trigger-only= _('Naming, topics, avatar') %h4.settings-title.js-settings-toggle.js-settings-toggle-trigger-only= _('Naming, topics, avatar')
......
= render_if_exists 'shared/minute_limit_banner', namespace: @project
- page_title _("Jobs") - page_title _("Jobs")
- add_page_specific_style 'page_bundles/ci_status' - add_page_specific_style 'page_bundles/ci_status'
- admin = local_assigns.fetch(:admin, false) - admin = local_assigns.fetch(:admin, false)
......
= render_if_exists 'shared/minute_limit_banner', namespace: @project
- breadcrumb_title _("Schedules") - breadcrumb_title _("Schedules")
- page_title _("Pipeline Schedules") - page_title _("Pipeline Schedules")
- add_page_specific_style 'page_bundles/pipeline_schedules' - add_page_specific_style 'page_bundles/pipeline_schedules'
......
= render_if_exists 'shared/minute_limit_banner', namespace: @project
- page_title _('Pipelines') - page_title _('Pipelines')
- add_page_specific_style 'page_bundles/pipelines' - add_page_specific_style 'page_bundles/pipelines'
- add_page_specific_style 'page_bundles/ci_status' - add_page_specific_style 'page_bundles/ci_status'
......
= render_if_exists 'shared/minute_limit_banner', namespace: @project
- @content_class = "limit-container-width" unless fluid_layout - @content_class = "limit-container-width" unless fluid_layout
- page_title _("CI/CD Settings") - page_title _("CI/CD Settings")
- page_title _("CI/CD") - page_title _("CI/CD")
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
= auto_discovery_link_tag(:atom, project_path(@project, rss_url_options), title: "#{@project.name} activity") = auto_discovery_link_tag(:atom, project_path(@project, rss_url_options), title: "#{@project.name} activity")
= render_if_exists 'shared/user_over_limit_free_plan_alert', source: @project = render_if_exists 'shared/user_over_limit_free_plan_alert', source: @project
= render_if_exists 'shared/minute_limit_banner', namespace: @project
= render partial: 'flash_messages', locals: { project: @project } = render partial: 'flash_messages', locals: { project: @project }
= render "projects/last_push" = render "projects/last_push"
......
---
name: show_minute_limit_banner
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/84644
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/358191
milestone: '14.10'
type: development
group: group::workspace
default_enabled: false
...@@ -19115,6 +19115,7 @@ Name of the feature that the callout is for. ...@@ -19115,6 +19115,7 @@ Name of the feature that the callout is for.
| <a id="usercalloutfeaturenameenumgeo_migrate_hashed_storage"></a>`GEO_MIGRATE_HASHED_STORAGE` | Callout feature name for geo_migrate_hashed_storage. | | <a id="usercalloutfeaturenameenumgeo_migrate_hashed_storage"></a>`GEO_MIGRATE_HASHED_STORAGE` | Callout feature name for geo_migrate_hashed_storage. |
| <a id="usercalloutfeaturenameenumgke_cluster_integration"></a>`GKE_CLUSTER_INTEGRATION` | Callout feature name for gke_cluster_integration. | | <a id="usercalloutfeaturenameenumgke_cluster_integration"></a>`GKE_CLUSTER_INTEGRATION` | Callout feature name for gke_cluster_integration. |
| <a id="usercalloutfeaturenameenumgold_trial_billings"></a>`GOLD_TRIAL_BILLINGS` | Callout feature name for gold_trial_billings. | | <a id="usercalloutfeaturenameenumgold_trial_billings"></a>`GOLD_TRIAL_BILLINGS` | Callout feature name for gold_trial_billings. |
| <a id="usercalloutfeaturenameenumminute_limit_banner"></a>`MINUTE_LIMIT_BANNER` | Callout feature name for minute_limit_banner. |
| <a id="usercalloutfeaturenameenumnew_user_signups_cap_reached"></a>`NEW_USER_SIGNUPS_CAP_REACHED` | Callout feature name for new_user_signups_cap_reached. | | <a id="usercalloutfeaturenameenumnew_user_signups_cap_reached"></a>`NEW_USER_SIGNUPS_CAP_REACHED` | Callout feature name for new_user_signups_cap_reached. |
| <a id="usercalloutfeaturenameenumpersonal_access_token_expiry"></a>`PERSONAL_ACCESS_TOKEN_EXPIRY` | Callout feature name for personal_access_token_expiry. | | <a id="usercalloutfeaturenameenumpersonal_access_token_expiry"></a>`PERSONAL_ACCESS_TOKEN_EXPIRY` | Callout feature name for personal_access_token_expiry. |
| <a id="usercalloutfeaturenameenumpipeline_needs_banner"></a>`PIPELINE_NEEDS_BANNER` | Callout feature name for pipeline_needs_banner. | | <a id="usercalloutfeaturenameenumpipeline_needs_banner"></a>`PIPELINE_NEEDS_BANNER` | Callout feature name for pipeline_needs_banner. |
...@@ -61,6 +61,12 @@ module EE ...@@ -61,6 +61,12 @@ module EE
buy_storage_subscriptions_url(selected_group: namespace.id) buy_storage_subscriptions_url(selected_group: namespace.id)
end end
def show_minute_limit_banner?(namespace)
return false unless ::Gitlab.com? && ::Feature.enabled?(:show_minute_limit_banner, namespace.root_ancestor, default_enabled: :yaml) # rubocop:disable Layout/LineLength
namespace.root_ancestor.free_plan? && !minute_limit_banner_dismissed?
end
private private
def use_customers_dot_for_addon_path?(namespace) def use_customers_dot_for_addon_path?(namespace)
......
- if show_minute_limit_banner?(namespace)
.container-fluid
.row
= render Pajamas::AlertComponent.new(title: s_("Changes to free tier public projects"),
alert_class: 'gl-mt-5 js-minute-limit-banner',
alert_data: { feature_id: ::Users::CalloutsHelper::MINUTE_LIMIT_BANNER, dismiss_endpoint: callouts_path }) do
.gl-alert-body
- minutes_quota_link = external_link("included in the 400 minutes per month CI/CD minutes quota", "https://about.gitlab.com/blog/2021/11/11/public-project-minute-limits")
- enrollment_link = external_link("enroll in GitLab's Open Source Program", "https://about.gitlab.com/blog/2022/02/04/ultimate-perks-for-open-source-projects")
- faq_link = external_link("FAQ", "https://about.gitlab.com/pricing/faq-efficient-free-tier/#public-projects-on-gitlab-saas-free-tier")
= s_("1. Effective June 1, 2022, all free tier public projects will be %{minutes_quota_link}.").html_safe % { minutes_quota_link: minutes_quota_link }
%br
= s_("2. Before July 1, 2022, all free tier public open source projects will need to %{enrollment_link} to continue to receive GitLab Ultimate benefits.").html_safe % { enrollment_link: enrollment_link }
%br
%br
= s_("Please visit the %{faq_link} for more information.").html_safe % { faq_link: faq_link }
...@@ -222,4 +222,46 @@ RSpec.describe EE::NamespacesHelper do ...@@ -222,4 +222,46 @@ RSpec.describe EE::NamespacesHelper do
end end
end end
end end
describe '#show_minute_limit_banner?' do
let(:project) { create(:project) }
context 'on dot com' do
using RSpec::Parameterized::TableSyntax
where(:feature_flag_enabled, :free_plan, :user_dismissed_banner, :should_show_banner) do
true | true | false | true
true | true | true | false
true | false | false | false
false | true | false | false
end
with_them do
before do
allow(Gitlab).to receive(:com?).and_return(true)
stub_feature_flags(show_minute_limit_banner: feature_flag_enabled)
allow(project.root_ancestor).to receive(:free_plan?).and_return(free_plan)
allow(helper).to receive(:user_dismissed?).with('minute_limit_banner').and_return(user_dismissed_banner)
end
it 'shows the banner if required' do
expect(helper.show_minute_limit_banner?(project)).to eq(should_show_banner)
end
end
end
context 'not dot com' do
context 'when feature flag is enabled for a free project and user has not dismissed callout' do
before do
stub_feature_flags(show_minute_limit_banner: true)
allow(project.root_ancestor).to receive(:free_plan?).and_return(true)
allow(helper).to receive(:user_dismissed?).with('minute_limit_banner').and_return(false)
end
it 'does not show banner' do
expect(helper.show_minute_limit_banner?(project)).to eq(false)
end
end
end
end
end end
...@@ -1461,6 +1461,9 @@ msgstr[1] "" ...@@ -1461,6 +1461,9 @@ msgstr[1] ""
msgid "1-9 contributions" msgid "1-9 contributions"
msgstr "" msgstr ""
msgid "1. Effective June 1, 2022, all free tier public projects will be %{minutes_quota_link}."
msgstr ""
msgid "10-19 contributions" msgid "10-19 contributions"
msgstr "" msgstr ""
...@@ -1473,6 +1476,9 @@ msgstr "" ...@@ -1473,6 +1476,9 @@ msgstr ""
msgid "1st contribution!" msgid "1st contribution!"
msgstr "" msgstr ""
msgid "2. Before July 1, 2022, all free tier public open source projects will need to %{enrollment_link} to continue to receive GitLab Ultimate benefits."
msgstr ""
msgid "20-29 contributions" msgid "20-29 contributions"
msgstr "" msgstr ""
...@@ -7077,6 +7083,9 @@ msgstr "" ...@@ -7077,6 +7083,9 @@ msgstr ""
msgid "Changes the title to \"%{title_param}\"." msgid "Changes the title to \"%{title_param}\"."
msgstr "" msgstr ""
msgid "Changes to free tier public projects"
msgstr ""
msgid "Changes to the title have not been saved" msgid "Changes to the title have not been saved"
msgstr "" msgstr ""
...@@ -28282,6 +28291,9 @@ msgstr "" ...@@ -28282,6 +28291,9 @@ msgstr ""
msgid "Please use this form to report to the admin users who create spam issues, comments or behave inappropriately." msgid "Please use this form to report to the admin users who create spam issues, comments or behave inappropriately."
msgstr "" msgstr ""
msgid "Please visit the %{faq_link} for more information."
msgstr ""
msgid "Please wait a moment, this page will automatically refresh when ready." msgid "Please wait a moment, this page will automatically refresh when ready."
msgstr "" msgstr ""
......
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