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

  1. 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)
  2. 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"
  3. Before this change the response is {"message":"500 Internal Server Error"} and the Rails log shows Validation failed: Pages unique domain can't be blank. With this change the response is 200 with "is_unique_domain_enabled": true and a generated url.
  4. Validation errors now surface as 422, for example pages_https_only=true on 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 422 response where it returned 500 before.
  • Changelog: fixed trailer on the commit.

Merge request reports

Loading
Loading