Link group add-on purchase CTAs to Customers Portal
What does this MR do and why?
Points the in-product Compute Minutes and Storage purchase CTAs for group namespaces at the Customers Portal, instead of routing them through /-/subscriptions/buy_minutes and /-/subscriptions/buy_storage. Personal namespaces already link directly.
The current group links are not broken; they resolve correctly through the in-product route. This removes the redirect hop, which is the goal of epic &14769: update the CTAs so the GitLab.com purchase controller can eventually be deleted. Removing the hop also preserves ref_source=group_usage_quotas_page, which the controller drops today when it rebuilds the URL.
All seven flows listed in the issue come from two helpers, so this is one predicate.
Changes
use_customers_dot_for_addon_path?returns the Customers Portal URL for group namespaces on GitLab.com whencustomers_dot_addon_ctasis enabled. Personal namespaces still returntrueunconditionally.- The mailer-only helpers move to a new
use_customers_dot_for_addon_email?, keeping their previous behaviour. Splitting the predicate is what holds the emails still, since all five helpers previously shared one. - Adds the
customers_dot_addon_ctasfeature flag (gitlab_com_derisk, disabled by default).
Self-managed is excluded because these routes are not SaaS gated and gl_namespace_id is a GitLab.com concept. The SaaS check is redundant for the two Usage Quotas rows, which already return early for non-SaaS, but load bearing for the three alert components, which can render on self-managed: the minutes alert when an admin sets a compute quota, and the two storage alerts when automatic_purchased_storage_allocation is enabled.
The Usage Quotas tab buttons now open in a new tab for groups, matching personal namespaces. The alert CTAs have no target and stay in the same tab either way.
Out of scope
- Notification emails. The issue assigns them to #464117, which moved to
group::purchaseon 9 September.buy_additional_minutes_urlandbuy_storage_urlare unchanged, as the evidence below shows. - CTA copy. The description asks for
Purchase more compute minutes, but that was revised 13 minutes later toBuy more compute minutes, which is what the alert reads today and what the Customers Portal page is titled. - Maintainer permission gate. The Usage Quotas Storage tab is reachable at Maintainer and its button has no role check, unlike the Pipelines tab. Today those users get a fast 404 from
add_on_purchase_flow; afterwards they reach the Customers Portal checkout and are rejected only atPOST, because the add-on gate calls the namespaces API withowned_only: falseandUser#namespaces(owned_only: false)returnsgroups, notowned_groups. Adding that gate is outside this issue. It is worth a decision before the flag is rolled out.
Prior art: !239359 (closed) attempted the same predicate change and was closed because its bug diagnosis was wrong. This differs by being scoped to GitLab.com, flag gated, and leaving the emails alone.
Screenshots or screen recordings
Group Usage Quotas, Pipelines tab, in GDK with SaaS simulated. Same group in both. The strip under each shot carries the button's href and target, read from the DOM in that same run.
| Before | After |
|---|---|
![]() |
![]() |
Helper output for the same group. The three [UI] rows change; the two [mailer] rows are identical, which is the notification email links staying put.
| Before | After |
|---|---|
![]() |
![]() |
ee/spec/helpers, ee/spec/components, ee/spec/mailers: 129 examples, 0 failures. rubocop: 3 files inspected, no offenses.
How to set up and validate locally
Feature.enable(:customers_dot_addon_ctas, Group.find_by_full_path('your-group'))- With SaaS simulated, visit
/groups/<group>/-/usage_quotas. The Pipelines and Storage tab buttons point atcustomers.gitlab.com/buy_pipeline_minutes?gl_namespace_id=<id>and/buy_storage?gl_namespace_id=<id>, and open in a new tab. Feature.disable(:customers_dot_addon_ctas)and confirm both revert to/-/subscriptions/buy_*.- Confirm a compute minutes notification email still links to
/-/subscriptions/buy_minutes.
MR acceptance checklist
- Tests added for the new behaviour, covering the flag enabled, disabled, and enabled for a single namespace.
- Feature flag disabled by default, with an actor.
- Rollout issue created: #628857
- Staging verification, including a self-managed instance with a compute quota set.
Resolves #461740. Note autoclose_referenced_issues is false on this project, so merging will not close the issue.



