Backfill model access levels to private on non-public projects

What does this MR do and why?

Queues a batched background migration that sets model_registry_access_level and model_experiments_access_level to PRIVATE on existing internal and private projects where they are currently ENABLED. PRIVATE and DISABLED rows are left untouched, and public projects are not changed.

This aligns the stored Featurable access level on existing projects with the access ProjectPolicy already enforces for non-public projects (member-only), so the access level can later become the source of truth without changing observable behavior.

Sequencing

Depends on !241157 (merged) (dynamic defaults), now merged — this MR has retargeted to master and been rebased onto it. The dynamic-default code needs to be live before this backfill runs so that non-public projects created afterward keep the PRIVATE default; that ordering is satisfied now that !241157 (merged) merged ahead of this MR.

Migration

Batched background migration (gitlab_main_org), queued in a post-deployment migration. No schema change. The per-sub-batch statement:

UPDATE project_features
SET
  model_registry_access_level =
    CASE WHEN project_features.model_registry_access_level = 20 THEN 10
         ELSE project_features.model_registry_access_level END,
  model_experiments_access_level =
    CASE WHEN project_features.model_experiments_access_level = 20 THEN 10
         ELSE project_features.model_experiments_access_level END
FROM projects
WHERE project_features.id IN (<sub_batch ids>)
  AND projects.id = project_features.project_id
  AND projects.visibility_level <> 20            -- not PUBLIC
  AND (project_features.model_registry_access_level = 20
       OR project_features.model_experiments_access_level = 20);  -- ENABLED

(20 = ENABLED / VisibilityLevel::PUBLIC, 10 = PRIVATE.) The migration is idempotent — already-PRIVATE/DISABLED rows no longer match the ENABLED filter on a re-run. ### Database migration testing

Executed on GitLab.com data via the db:gitlabcom-database-testing pipeline — the post-deploy migration passed with no measurable DB size change:

Migration Total runtime Result
20260617140000 QueueBackfillModelFeaturesAccessLevel 4.7 s ✅

The post-deploy migration only queues the batched background migration (the INSERT into batched_background_migrations ran in ~10.7 ms); every query completed in well under 1 s. The per-sub-batch UPDATE shown above is exercised by the BBM at execution time.

Steps to reproduce

  1. On an existing private or internal project, ensure Model registry / Model experiments show Everyone With Access (the pre-Task-A default).
  2. Run the background migration to completion.
  3. Settings > General > Visibility now shows Only Project Members for both features. Public projects are unchanged.

References

Edited by Ian Anderson

Merge request reports

Loading
Loading