Skip to content

hide auto_duo_code_review_enabled in api response to avoid confusion in case if the namespace has no Duo enterprise purchase

What does this MR do and why?

The scope has been updated from the discussion here:

  1. Hide auto_duo_code_review_enabled field from API when the namespace doesn't have Duo enterprise purchase like we did for the UI. I feel this won't carry the same weight as much as the UI so we could just leave it as is, but it's a one line change so might as well do it.
  2. Add the same namespace check before displaying the no duo enterprise seat ask your admin warning for automatic reviews. I don't think we want to spam when the the Duo purchase gets expired since they won't be able to change the setting as the setting would only show up when they have an active purchase. The same warning would still show up when the user tries to request a review from Duo manually, but it won't show the warning in the case of automatic review even when this setting is enabled.

References

Screenshots or screen recordings

Before After

How to set up and validate locally

  1. setup gitlab saas and duo code review https://docs.gitlab.com/development/ee_features/#simulate-a-saas-instance https://gitlab.com/gitlab-org/gitlab-development-kit/-/blob/main/doc/howto/gitlab_ai_gateway.md
  2. I'm testing using this project:
[47] pry(main)> Project.last
=> #<Project id:1000000 gitlab-duo/test>>

and the setting is here: http://127.0.0.1:3000/gitlab-duo/test/-/settings/merge_requests

(1) let's create a variable for the original namespace

on = Project.last.namespace

We can see this project's namespace has the purchase:

sa = on.subscription_add_on_purchases.first
=> #<GitlabSubscriptions::AddOnPurchase:0x0000000319518e90
 id: 4,
 created_at: Tue, 06 May 2025 15:18:24.591580000 UTC +00:00,
 updated_at: Wed, 07 May 2025 00:12:15.128749000 UTC +00:00,
 subscription_add_on_id: 3,
 namespace_id: 1000000,
 quantity: 100,
 expires_on: Wed, 06 May 2026,
 purchase_xid: "C-98766",
 last_assigned_users_refreshed_at: Wed, 07 May 2025 00:00:10.921408000 UTC +00:00,
 trial: false,
 started_at: Tue, 06 May 2025,
 organization_id: 1>

and the add_on is duo_enterprise (id: 3)

[50] pry(main)> GitlabSubscriptions::AddOn.duo_enterprise.pick(:id)
=> 3
  1. Make an update API request to change auto_duo_code_review_enabled setting.
tiangao@tgao--20240202-M7DJJ gitlab % curl --request GET --header "PRIVATE-TOKEN: " --url "http://127.0.0.1:3000/api/v4/projects/1000000"
{"id":1000000,"description":null,"name":"Test","name_with_namespace":"GitLab Duo / Test","path":"test","path_with_namespace":"gitlab-duo/test","created_at":"2025-05-06T15:18:19.892Z","default_branch":"main","tag_list":[],"topics":[],"ssh_url_to_repo":"ssh://git@127.0.0.1:2222/gitlab-duo/test.git","http_url_to_repo":"http://127.0.0.1:3000/gitlab-duo/test.git","web_url":"http://127.0.0.1:3000/gitlab-duo/test","readme_url":"http://127.0.0.1:3000/gitlab-duo/test/-/blob/main/README.md","forks_count":0,"avatar_url":null,"star_count":0,"last_activity_at":"2025-05-15T20:04:57.200Z","namespace":{"id":1000000,"name":"GitLab Duo","path":"gitlab-duo","kind":"group","full_path":"gitlab-duo","parent_id":null,"avatar_url":null,"web_url":"http://127.0.0.1:3000/groups/gitlab-duo"},"repository_storage":"default","_links":{"self":"http://127.0.0.1:3000/api/v4/projects/1000000","issues":"http://127.0.0.1:3000/api/v4/projects/1000000/issues","merge_requests":"http://127.0.0.1:3000/api/v4/projects/1000000/merge_requests","repo_branches":"http://127.0.0.1:3000/api/v4/projects/1000000/repository/branches","labels":"http://127.0.0.1:3000/api/v4/projects/1000000/labels","events":"http://127.0.0.1:3000/api/v4/projects/1000000/events","members":"http://127.0.0.1:3000/api/v4/projects/1000000/members","cluster_agents":"http://127.0.0.1:3000/api/v4/projects/1000000/cluster_agents"},"marked_for_deletion_at":null,"marked_for_deletion_on":null,"packages_enabled":true,"empty_repo":false,"archived":false,"visibility":"public","resolve_outdated_diff_discussions":false,"container_expiration_policy":{"cadence":"1d","enabled":false,"keep_n":10,"older_than":"90d","name_regex":".*","name_regex_keep":null,"next_run_at":"2025-05-07T15:18:19.937Z"},"repository_object_format":null,"issues_enabled":true,"merge_requests_enabled":true,"wiki_enabled":true,"jobs_enabled":true,"snippets_enabled":true,"container_registry_enabled":true,"service_desk_enabled":false,"service_desk_address":null,"can_create_merge_request_in":true,"issues_access_level":"enabled","repository_access_level":"enabled","merge_requests_access_level":"enabled","forking_access_level":"enabled","wiki_access_level":"enabled","builds_access_level":"enabled","snippets_access_level":"enabled","pages_access_level":"enabled","analytics_access_level":"enabled","container_registry_access_level":"enabled","security_and_compliance_access_level":"private","releases_access_level":"enabled","environments_access_level":"enabled","feature_flags_access_level":"enabled","infrastructure_access_level":"enabled","monitor_access_level":"enabled","model_experiments_access_level":"enabled","model_registry_access_level":"enabled","emails_disabled":false,"emails_enabled":true,"shared_runners_enabled":true,"lfs_enabled":true,"creator_id":1,"import_url":null,"import_type":null,"import_status":"none","import_error":null,"open_issues_count":1,"description_html":"","updated_at":"2025-05-15T20:04:57.200Z","ci_default_git_depth":20,"ci_delete_pipelines_in_seconds":null,"ci_forward_deployment_enabled":true,"ci_forward_deployment_rollback_allowed":true,"ci_job_token_scope_enabled":false,"ci_separated_caches":true,"ci_allow_fork_pipelines_to_run_in_parent_project":true,"ci_id_token_sub_claim_components":["project_path","ref_type","ref"],"build_git_strategy":"fetch","keep_latest_artifact":true,"restrict_user_defined_variables":false,"ci_pipeline_variables_minimum_override_role":"developer","runner_token_expiration_interval":null,"group_runners_enabled":true,"auto_cancel_pending_pipelines":"enabled","build_timeout":3600,"auto_devops_enabled":true,"auto_devops_deploy_strategy":"continuous","ci_push_repository_for_job_token_allowed":false,"runners_token":"GR1348941SFoTx4vEs2TGKy54zvnF","ci_config_path":null,"public_jobs":true,"shared_with_groups":[],"only_allow_merge_if_pipeline_succeeds":false,"allow_merge_on_skipped_pipeline":null,"request_access_enabled":true,"only_allow_merge_if_all_discussions_are_resolved":false,"remove_source_branch_after_merge":true,"printing_merge_request_link_enabled":true,"merge_method":"merge","merge_request_title_regex":null,"squash_option":"default_off","enforce_auth_checks_on_uploads":true,"suggestion_commit_message":null,"merge_commit_template":null,"squash_commit_template":null,"issue_branch_template":null,"warn_about_potentially_unwanted_characters":true,"autoclose_referenced_issues":true,"max_artifacts_size":null,"approvals_before_merge":0,"mirror":false,"external_authorization_classification_label":null,"requirements_enabled":true,"requirements_access_level":"enabled","security_and_compliance_enabled":true,"secret_push_protection_enabled":false,"pre_receive_secret_detection_enabled":false,"compliance_frameworks":[],"issues_template":null,"merge_requests_template":null,"ci_restrict_pipeline_cancellation_role":"developer","merge_pipelines_enabled":false,"merge_trains_enabled":false,"merge_trains_skip_train_allowed":false,"only_allow_merge_if_all_status_checks_passed":false,"allow_pipeline_trigger_approve_deployment":false,"prevent_merge_without_jira_issue":false,"auto_duo_code_review_enabled":false,"permissions":{"project_access":{"access_level":50,"notification_level":3},"group_access":{"access_level":50,"notification_level":3}}}%  
                                                                                                      

we can see:

"auto_duo_code_review_enabled":false

  1. Now let's expire the purchase.
sa.expires_on = 1.day.ago
sa.save
tiangao@tgao--20240202-M7DJJ gitlab % curl --request GET --header "PRIVATE-TOKEN: " --url "http://127.0.0.1:3000/api/v4/projects/1000000"
{"id":1000000,"description":null,"name":"Test","name_with_namespace":"GitLab Duo / Test","path":"test","path_with_namespace":"gitlab-duo/test","created_at":"2025-05-06T15:18:19.892Z","default_branch":"main","tag_list":[],"topics":[],"ssh_url_to_repo":"ssh://git@127.0.0.1:2222/gitlab-duo/test.git","http_url_to_repo":"http://127.0.0.1:3000/gitlab-duo/test.git","web_url":"http://127.0.0.1:3000/gitlab-duo/test","readme_url":"http://127.0.0.1:3000/gitlab-duo/test/-/blob/main/README.md","forks_count":0,"avatar_url":null,"star_count":0,"last_activity_at":"2025-05-15T20:04:57.200Z","namespace":{"id":1000000,"name":"GitLab Duo","path":"gitlab-duo","kind":"group","full_path":"gitlab-duo","parent_id":null,"avatar_url":null,"web_url":"http://127.0.0.1:3000/groups/gitlab-duo"},"repository_storage":"default","_links":{"self":"http://127.0.0.1:3000/api/v4/projects/1000000","issues":"http://127.0.0.1:3000/api/v4/projects/1000000/issues","merge_requests":"http://127.0.0.1:3000/api/v4/projects/1000000/merge_requests","repo_branches":"http://127.0.0.1:3000/api/v4/projects/1000000/repository/branches","labels":"http://127.0.0.1:3000/api/v4/projects/1000000/labels","events":"http://127.0.0.1:3000/api/v4/projects/1000000/events","members":"http://127.0.0.1:3000/api/v4/projects/1000000/members","cluster_agents":"http://127.0.0.1:3000/api/v4/projects/1000000/cluster_agents"},"marked_for_deletion_at":null,"marked_for_deletion_on":null,"packages_enabled":true,"empty_repo":false,"archived":false,"visibility":"public","resolve_outdated_diff_discussions":false,"container_expiration_policy":{"cadence":"1d","enabled":false,"keep_n":10,"older_than":"90d","name_regex":".*","name_regex_keep":null,"next_run_at":"2025-05-07T15:18:19.937Z"},"repository_object_format":null,"issues_enabled":true,"merge_requests_enabled":true,"wiki_enabled":true,"jobs_enabled":true,"snippets_enabled":true,"container_registry_enabled":true,"service_desk_enabled":false,"service_desk_address":null,"can_create_merge_request_in":true,"issues_access_level":"enabled","repository_access_level":"enabled","merge_requests_access_level":"enabled","forking_access_level":"enabled","wiki_access_level":"enabled","builds_access_level":"enabled","snippets_access_level":"enabled","pages_access_level":"enabled","analytics_access_level":"enabled","container_registry_access_level":"enabled","security_and_compliance_access_level":"private","releases_access_level":"enabled","environments_access_level":"enabled","feature_flags_access_level":"enabled","infrastructure_access_level":"enabled","monitor_access_level":"enabled","model_experiments_access_level":"enabled","model_registry_access_level":"enabled","emails_disabled":false,"emails_enabled":true,"shared_runners_enabled":true,"lfs_enabled":true,"creator_id":1,"import_url":null,"import_type":null,"import_status":"none","import_error":null,"open_issues_count":1,"description_html":"","updated_at":"2025-05-15T20:04:57.200Z","ci_default_git_depth":20,"ci_delete_pipelines_in_seconds":null,"ci_forward_deployment_enabled":true,"ci_forward_deployment_rollback_allowed":true,"ci_job_token_scope_enabled":false,"ci_separated_caches":true,"ci_allow_fork_pipelines_to_run_in_parent_project":true,"ci_id_token_sub_claim_components":["project_path","ref_type","ref"],"build_git_strategy":"fetch","keep_latest_artifact":true,"restrict_user_defined_variables":false,"ci_pipeline_variables_minimum_override_role":"developer","runner_token_expiration_interval":null,"group_runners_enabled":true,"auto_cancel_pending_pipelines":"enabled","build_timeout":3600,"auto_devops_enabled":true,"auto_devops_deploy_strategy":"continuous","ci_push_repository_for_job_token_allowed":false,"runners_token":"GR1348941SFoTx4vEs2TGKy54zvnF","ci_config_path":null,"public_jobs":true,"shared_with_groups":[],"only_allow_merge_if_pipeline_succeeds":false,"allow_merge_on_skipped_pipeline":null,"request_access_enabled":true,"only_allow_merge_if_all_discussions_are_resolved":false,"remove_source_branch_after_merge":true,"printing_merge_request_link_enabled":true,"merge_method":"merge","merge_request_title_regex":null,"squash_option":"default_off","enforce_auth_checks_on_uploads":true,"suggestion_commit_message":null,"merge_commit_template":null,"squash_commit_template":null,"issue_branch_template":null,"warn_about_potentially_unwanted_characters":true,"autoclose_referenced_issues":true,"max_artifacts_size":null,"approvals_before_merge":0,"mirror":false,"external_authorization_classification_label":null,"requirements_enabled":true,"requirements_access_level":"enabled","security_and_compliance_enabled":true,"secret_push_protection_enabled":false,"pre_receive_secret_detection_enabled":false,"compliance_frameworks":[],"issues_template":null,"merge_requests_template":null,"ci_restrict_pipeline_cancellation_role":"developer","merge_pipelines_enabled":false,"merge_trains_enabled":false,"merge_trains_skip_train_allowed":false,"only_allow_merge_if_all_status_checks_passed":false,"allow_pipeline_trigger_approve_deployment":false,"prevent_merge_without_jira_issue":false,"permissions":{"project_access":{"access_level":50,"notification_level":3},"group_access":{"access_level":50,"notification_level":3}}}

this time auto_duo_code_review_enabled does not exist in response.

"auto_duo_code_review_enabled":false

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.

Related to #539512 (closed)

Edited by Tian Gao

Merge request reports

Loading