Add new_addon_lead_endpoint feature flag and routing
What does this MR do and why?
Big picture: GitLab.com talks to CustomersDot (separate billing service) when a user starts an addon trial (Duo Pro / Duo Enterprise). Old setup: one URL trials/create_addon did two jobs — created lead AND applied trial. Messy.
We built a dedicated lead-only URL: leads/gitlab_com/addons. Job: create lead, nothing else. Already live in production.
Our job: wire GitLab.com to use the new URL for the lead step.
Why this approach (not a new client method + service refactor)?
Master already has generate_addon_trial_lead (lead step) split from generate_addon_trial (apply step). The service already calls the right method. Only thing wrong: the URL helper hardcoded the old URL. Smallest fix = swap that helper.
Mirrors the existing pattern: sibling helper addon_trial_endpoint does the same thing for the trial-apply step (different flag new_addon_trial_endpoint). Reviewers see the exact same shape side-by-side.
Also cleans up the temp measure from #582588 (closed) (option 2) per kgreif's note on the parent issue: lead routing now flips to the new endpoint via FF.
References
- Closes #582586 (closed)
- Rollout issue: #599046
- Parent epic: &20106
- CDot dependency (closed 2026-04-29): customers-gitlab-com#15123 (closed)
- Related context: #582588 (closed) (option 2 temp measure being cleaned up)
Screenshots or screen recordings
N/A. Backend-only change. No UI surface.
How to set up and validate locally
Manual verification
Run this in the worktree to confirm the URL helper flips with the flag. The private method addon_trial_lead_endpoint is the single source of truth for the URL generate_addon_trial_lead posts to.
Case 1: Feature flag OFF (default state) — URL stays on legacy trials/create_addon
Steps:
bin/rails runner '
Feature.disable(:new_addon_lead_endpoint)
puts "Feature.enabled? => #{Feature.enabled?(:new_addon_lead_endpoint, :instance).inspect}"
puts "addon_trial_lead_endpoint => #{Gitlab::SubscriptionPortal::Client.send(:addon_trial_lead_endpoint).inspect}"
'Output:
Feature.enabled? => false
addon_trial_lead_endpoint => "trials/create_addon"Confirms: with the flag off, generate_addon_trial_lead posts to the legacy URL — byte-identical to pre-MR behaviour.
Case 2: Feature flag ON — URL flips to new dedicated endpoint leads/gitlab_com/addons
Steps:
bin/rails runner '
Feature.enable(:new_addon_lead_endpoint)
puts "Feature.enabled? => #{Feature.enabled?(:new_addon_lead_endpoint, :instance).inspect}"
puts "addon_trial_lead_endpoint => #{Gitlab::SubscriptionPortal::Client.send(:addon_trial_lead_endpoint).inspect}"
Feature.disable(:new_addon_lead_endpoint) # reset
'Output:
Feature.enabled? => true
addon_trial_lead_endpoint => "leads/gitlab_com/addons"Confirms: with the flag on, generate_addon_trial_lead posts to the new dedicated CDot endpoint.
MR acceptance checklist
Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.