Adding enabler id for dependency bump project setting

What does this MR do and why?

This MR records which user enabled the Duo dependency-bump breaking-changes project setting, so the automated resolution workflow can later run under that person's identity (and fail closed if they lose access).

Changes:

  • Adds a nullable duo_dependency_bump_breaking_changes_enabled_by_id column to project_settings, with a concurrent index and a foreign key to users (ON DELETE SET NULL).
  • Adds the belongs_to :duo_dependency_bump_breaking_changes_enabled_by association to ProjectSetting (EE).
  • Projects::UpdateService (EE) stamps current_user on the false → true transition and clears the reference when the setting is disabled. It preserves the original enabler when the setting is already enabled, and handles both the nested project_setting_attributes shape (web UI) and the top-level attribute (REST API).

References

Database Migrations

Click to expand database migrations

### Up

bundle exec rake db:migrate:up:main VERSION=20260703040000
main: == [advisory_lock_connection] object_id: 161000, pg_backend_pid: 92312
main: == 20260703040000 AddDuoDependencyBumpBreakingChangesEnabledByToProjectSettings: migrating 
main: -- add_column(:project_settings, :duo_dependency_bump_breaking_changes_enabled_by_id, :bigint)
main:    -> 0.0422s
main: == 20260703040000 AddDuoDependencyBumpBreakingChangesEnabledByToProjectSettings: migrated (0.0496s) 

main: == [advisory_lock_connection] object_id: 161000, pg_backend_pid: 92312

bundle exec rake db:migrate:up:main VERSION=20260703040001
main: == [advisory_lock_connection] object_id: 161000, pg_backend_pid: 92634
main: == 20260703040001 AddIndexForDuoDependencyBumpBreakingChangesEnabledBy: migrating 
main: -- transaction_open?(nil)
main:    -> 0.0000s
main: -- view_exists?(:postgres_partitions)
main:    -> 0.0390s
main: -- index_exists?(:project_settings, :duo_dependency_bump_breaking_changes_enabled_by_id, {:name=>"idx_project_settings_on_duo_dep_bump_bc_enabled_by_id", :algorithm=>:concurrently})
main:    -> 0.0031s
main: -- execute("SET statement_timeout TO 0")
main:    -> 0.0004s
main: -- add_index(:project_settings, :duo_dependency_bump_breaking_changes_enabled_by_id, {:name=>"idx_project_settings_on_duo_dep_bump_bc_enabled_by_id", :algorithm=>:concurrently})
main:    -> 0.0052s
main: -- execute("RESET statement_timeout")
main:    -> 0.0003s
main: == 20260703040001 AddIndexForDuoDependencyBumpBreakingChangesEnabledBy: migrated (0.0713s) 

main: == [advisory_lock_connection] object_id: 161000, pg_backend_pid: 92634

bundle exec rake db:migrate:up:main VERSION=20260703040002
main: == [advisory_lock_connection] object_id: 161000, pg_backend_pid: 93006
main: == 20260703040002 AddForeignKeyForDuoDependencyBumpBreakingChangesEnabledBy: migrating 
main: -- transaction_open?(nil)
main:    -> 0.0000s
main: -- transaction_open?(nil)
main:    -> 0.0000s
main: -- execute("LOCK TABLE users, project_settings IN SHARE ROW EXCLUSIVE MODE")
main:    -> 0.0005s
main: -- execute("ALTER TABLE project_settings ADD CONSTRAINT fk_bdc8715f08 FOREIGN KEY (duo_dependency_bump_breaking_changes_enabled_by_id) REFERENCES users (id) ON DELETE SET NULL NOT VALID;")
main:    -> 0.0038s
main: -- execute("SET statement_timeout TO 0")
main:    -> 0.0003s
main: -- execute("ALTER TABLE project_settings VALIDATE CONSTRAINT fk_bdc8715f08;")
main:    -> 0.0058s
main: -- execute("RESET statement_timeout")
main:    -> 0.0005s
main: == 20260703040002 AddForeignKeyForDuoDependencyBumpBreakingChangesEnabledBy: migrated (0.0900s) 

main: == [advisory_lock_connection] object_id: 161000, pg_backend_pid: 93006

### Down

bundle exec rake db:migrate:down:main VERSION=20260703040002
main: == [advisory_lock_connection] object_id: 160980, pg_backend_pid: 90723
main: == 20260703040002 AddForeignKeyForDuoDependencyBumpBreakingChangesEnabledBy: reverting 
main: -- transaction_open?(nil)
main:    -> 0.0000s
main: -- remove_foreign_key(:project_settings, {:column=>:duo_dependency_bump_breaking_changes_enabled_by_id})
main:    -> 0.0057s
main: == 20260703040002 AddForeignKeyForDuoDependencyBumpBreakingChangesEnabledBy: reverted (0.1041s) 

main: == [advisory_lock_connection] object_id: 160980, pg_backend_pid: 90723

bundle exec rake db:migrate:down:main VERSION=20260703040001
[DEPRECATION] This gem has been renamed to 'omniauth-entra-id' and will no longer be supported. Please switch to 'omniauth-entra-id' as soon as possible.
main: == [advisory_lock_connection] object_id: 161000, pg_backend_pid: 91394
main: == 20260703040001 AddIndexForDuoDependencyBumpBreakingChangesEnabledBy: reverting 
main: -- transaction_open?(nil)
main:    -> 0.0000s
main: -- view_exists?(:postgres_partitions)
main:    -> 0.0364s
main: -- index_name_exists?(:project_settings, "idx_project_settings_on_duo_dep_bump_bc_enabled_by_id")
main:    -> 0.0014s
main: -- execute("SET statement_timeout TO 0")
main:    -> 0.0008s
main: -- remove_index(:project_settings, {:algorithm=>:concurrently, :name=>"idx_project_settings_on_duo_dep_bump_bc_enabled_by_id"})
main:    -> 0.0033s
main: -- execute("RESET statement_timeout")
main:    -> 0.0006s
main: == 20260703040001 AddIndexForDuoDependencyBumpBreakingChangesEnabledBy: reverted (0.0656s) 

main: == [advisory_lock_connection] object_id: 161000, pg_backend_pid: 91394

bundle exec rake db:migrate:down:main VERSION=20260703040000
[DEPRECATION] This gem has been renamed to 'omniauth-entra-id' and will no longer be supported. Please switch to 'omniauth-entra-id' as soon as possible.
main: == [advisory_lock_connection] object_id: 161000, pg_backend_pid: 91729
main: == 20260703040000 AddDuoDependencyBumpBreakingChangesEnabledByToProjectSettings: reverting 
main: -- remove_column(:project_settings, :duo_dependency_bump_breaking_changes_enabled_by_id, :bigint)
main:    -> 0.0484s
main: == 20260703040000 AddDuoDependencyBumpBreakingChangesEnabledByToProjectSettings: reverted (0.0584s) 

main: == [advisory_lock_connection] object_id: 161000, pg_backend_pid: 91729

Screenshots or screen recordings

No user-facing UI changes — this MR only records the enabler behind the existing GitLab Duo settings toggle.

Before After

How to set up and validate locally

  1. Enable the feature flag in the Rails console:

    Feature.enable(:enable_dependency_bump_breaking_changes)
  2. Enable the setting for a project, either from Settings → GitLab Duo in the UI, or via the REST API:

    curl --request PUT "http://localhost:3000/api/v4/projects/<project_id>" \
      --header "PRIVATE-TOKEN: <token>" \
      --data "duo_dependency_bump_breaking_changes_enabled=true"
  3. Confirm the enabler was recorded:

    Project.find(<project_id>).project_setting.duo_dependency_bump_breaking_changes_enabled_by_id
    # => the enabling user's ID
  4. Disable the setting (UI or ...enabled=false via the API) and confirm the reference is cleared back to nil.

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.

Edited by Hitesh Raghuvanshi

Merge request reports

Loading
Loading