Generate the Pages unique domain when the API enables it
What does this MR do and why?
PATCH /projects/:id/pages with pages_unique_domain_enabled=true returned 500 Internal Server Error for projects whose project_setting.pages_unique_domain is NULL, which is every project created before Pages unique domains existed. Pages::UpdateService saved the flag without generating a domain, so the ProjectSetting presence validation raised ActiveRecord::RecordInvalid, which API::Pages did not handle.
The service now calls Gitlab::Pages.add_unique_domain_to(project) when the flag is being enabled, the same helper Projects::UpdateService uses for the UI checkbox (a no-op for projects that already have a domain). Validation errors and Gitlab::Pages::UniqueDomainGenerationFailure are returned as a ServiceResponse.error with reason: :unprocessable_entity, and the API maps that to 422 instead of the previous catch-all 403.
Closes #628683 (closed)
References
Screenshots or screen recordings
Not applicable, API-only change.
How to set up and validate locally
- Put a project with Pages enabled into the legacy state (no unique domain yet). In a Rails console:
project = Project.find(<id>) project.project_setting.update_columns(pages_unique_domain_enabled: false, pages_unique_domain: nil) - Enable the unique domain through the API:
curl --request PATCH --header "PRIVATE-TOKEN: <token>" "http://gdk.test:3000/api/v4/projects/<id>/pages?pages_unique_domain_enabled=true" - Before this change the response is
{"message":"500 Internal Server Error"}and the Rails log showsValidation failed: Pages unique domain can't be blank. With this change the response is200with"is_unique_domain_enabled": trueand a generatedurl. - Validation errors now surface as
422, for examplepages_https_only=trueon a project with a custom domain that has no certificate.
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.
- Service and request specs cover the generated domain, the generation failure, and an invalid update.
- No database, UI, or documentation changes; the endpoint contract only gains a
422response where it returned500before. -
Changelog: fixedtrailer on the commit.