From ef2c517527f5d6e48cb97a8f1f1b6f9710052561 Mon Sep 17 00:00:00 2001 From: GitLab Bot Date: Thu, 7 Nov 2024 03:22:58 +0000 Subject: [PATCH] Add latest changes from gitlab-org/gitlab@master --- .rubocop_todo/layout/line_length.yml | 10 ---- .../rspec/example_without_description.yml | 1 - .rubocop_todo/rspec/named_subject.yml | 1 - .../rspec/repeated_example_group_body.yml | 1 - app/helpers/visibility_level_helper.rb | 25 +++++--- app/helpers/whats_new_helper.rb | 4 +- app/helpers/wiki_helper.rb | 39 ++++++++++--- app/mailers/emails/members.rb | 14 ++++- app/mailers/emails/merge_requests.rb | 35 ++++++++++-- app/mailers/emails/pages_domains.rb | 5 +- app/mailers/emails/profile.rb | 43 +++++++++++--- app/mailers/previews/notify_preview.rb | 57 +++++++++++++------ .../analytics/cycle_analytics/aggregation.rb | 11 +++- .../cycle_analytics/issue_stage_event.rb | 3 +- app/uploaders/ci/secure_file_uploader.rb | 4 -- app/uploaders/terraform/state_uploader.rb | 4 -- .../16-1-dependency-proxy-graphql-field.yml | 5 ++ .../17-6-remove-migration-state-graphql.yml | 16 ++++++ ..._backfill_security_findings_project_id.yml | 8 +++ ...9184904_update_admin_bot_user_confirmed.rb | 17 ++++++ ...e_backfill_security_findings_project_id.rb | 27 ++------- ...e_backfill_security_findings_project_id.rb | 35 ++++++++++++ db/schema_migrations/20241029184904 | 1 + db/schema_migrations/20241104065605 | 1 + .../documentation/styleguide/word_list.md | 6 ++ doc/integration/jira/index.md | 2 +- doc/update/deprecations.md | 18 ++++++ lib/api/merge_requests.rb | 6 +- .../entities/vs_code_setting_reference.rb | 8 +-- .../vs_code/settings/vs_code_settings_sync.rb | 2 +- .../representation/activity.rb | 20 +++++++ .../representation/comment.rb | 5 ++ .../backfill_security_findings_project_id.rb | 8 +++ .../representation/activity_spec.rb | 8 +++ .../representation/comment_spec.rb | 43 +++++++------- ...kfill_security_findings_project_id_spec.rb | 17 +----- ...kfill_security_findings_project_id_spec.rb | 30 ++++++++++ spec/requests/api/merge_requests_spec.rb | 32 +++++++++-- 38 files changed, 429 insertions(+), 143 deletions(-) create mode 100644 data/deprecations/17-6-remove-migration-state-graphql.yml create mode 100644 db/docs/batched_background_migrations/requeue_backfill_security_findings_project_id.yml create mode 100644 db/migrate/20241029184904_update_admin_bot_user_confirmed.rb create mode 100644 db/post_migrate/20241104065605_requeue_backfill_security_findings_project_id.rb create mode 100644 db/schema_migrations/20241029184904 create mode 100644 db/schema_migrations/20241104065605 create mode 100644 spec/migrations/20241104065605_requeue_backfill_security_findings_project_id_spec.rb diff --git a/.rubocop_todo/layout/line_length.yml b/.rubocop_todo/layout/line_length.yml index ae3c3e2de40..fac74cb5f63 100644 --- a/.rubocop_todo/layout/line_length.yml +++ b/.rubocop_todo/layout/line_length.yml @@ -138,16 +138,6 @@ Layout/LineLength: - 'app/helpers/import_helper.rb' - 'app/helpers/issuables_helper.rb' - 'app/helpers/labels_helper.rb' - - 'app/helpers/visibility_level_helper.rb' - - 'app/helpers/whats_new_helper.rb' - - 'app/helpers/wiki_helper.rb' - - 'app/mailers/emails/members.rb' - - 'app/mailers/emails/merge_requests.rb' - - 'app/mailers/emails/pages_domains.rb' - - 'app/mailers/emails/profile.rb' - - 'app/mailers/previews/notify_preview.rb' - - 'app/models/analytics/cycle_analytics/aggregation.rb' - - 'app/models/analytics/cycle_analytics/issue_stage_event.rb' - 'app/models/analytics/cycle_analytics/merge_request_stage_event.rb' - 'app/models/application_record.rb' - 'app/models/application_setting.rb' diff --git a/.rubocop_todo/rspec/example_without_description.yml b/.rubocop_todo/rspec/example_without_description.yml index 1af8550cf0b..bbafdd169e5 100644 --- a/.rubocop_todo/rspec/example_without_description.yml +++ b/.rubocop_todo/rspec/example_without_description.yml @@ -299,7 +299,6 @@ RSpec/ExampleWithoutDescription: - 'spec/lib/bitbucket/representation/issue_spec.rb' - 'spec/lib/bitbucket/representation/pull_request_spec.rb' - 'spec/lib/bitbucket_server/representation/activity_spec.rb' - - 'spec/lib/bitbucket_server/representation/comment_spec.rb' - 'spec/lib/bitbucket_server/representation/pull_request_comment_spec.rb' - 'spec/lib/bitbucket_server/representation/pull_request_spec.rb' - 'spec/lib/bulk_imports/groups/pipelines/group_attributes_pipeline_spec.rb' diff --git a/.rubocop_todo/rspec/named_subject.yml b/.rubocop_todo/rspec/named_subject.yml index a5f287fcc2d..d45e211a378 100644 --- a/.rubocop_todo/rspec/named_subject.yml +++ b/.rubocop_todo/rspec/named_subject.yml @@ -1586,7 +1586,6 @@ RSpec/NamedSubject: - 'spec/lib/bitbucket_server/collection_spec.rb' - 'spec/lib/bitbucket_server/connection_spec.rb' - 'spec/lib/bitbucket_server/representation/activity_spec.rb' - - 'spec/lib/bitbucket_server/representation/comment_spec.rb' - 'spec/lib/bitbucket_server/representation/pull_request_comment_spec.rb' - 'spec/lib/bitbucket_server/representation/pull_request_spec.rb' - 'spec/lib/bitbucket_server/representation/repo_spec.rb' diff --git a/.rubocop_todo/rspec/repeated_example_group_body.yml b/.rubocop_todo/rspec/repeated_example_group_body.yml index d6cd19cf67a..f434e14b24a 100644 --- a/.rubocop_todo/rspec/repeated_example_group_body.yml +++ b/.rubocop_todo/rspec/repeated_example_group_body.yml @@ -27,7 +27,6 @@ RSpec/RepeatedExampleGroupBody: - 'spec/lib/api/entities/application_setting_spec.rb' - 'spec/lib/banzai/filter/references/commit_range_reference_filter_spec.rb' - 'spec/lib/banzai/filter/references/commit_reference_filter_spec.rb' - - 'spec/lib/bitbucket_server/representation/comment_spec.rb' - 'spec/lib/gitlab/blob_helper_spec.rb' - 'spec/lib/gitlab/ci/config/entry/release_spec.rb' - 'spec/lib/gitlab/ci/pipeline/seed/build_spec.rb' diff --git a/app/helpers/visibility_level_helper.rb b/app/helpers/visibility_level_helper.rb index f718c9a90ad..9d10a112f85 100644 --- a/app/helpers/visibility_level_helper.rb +++ b/app/helpers/visibility_level_helper.rb @@ -146,7 +146,10 @@ module VisibilityLevelHelper def project_visibility_level_description(level) case level when Gitlab::VisibilityLevel::PRIVATE - s_("VisibilityLevel|Project access must be granted explicitly to each user. If this project is part of a group, access is granted to members of the group.") + s_( + "VisibilityLevel|Project access must be granted explicitly to each user. " \ + "If this project is part of a group, access is granted to members of the group." + ) when Gitlab::VisibilityLevel::INTERNAL s_("VisibilityLevel|The project can be accessed by any logged in user except external users.") when Gitlab::VisibilityLevel::PUBLIC @@ -155,7 +158,9 @@ module VisibilityLevelHelper end def show_updated_public_description_for_setting(group) - group && !group.new_record? && Gitlab::CurrentSettings.current_application_settings.try(:should_check_namespace_plan?) + group && + !group.new_record? && + Gitlab::CurrentSettings.current_application_settings.try(:should_check_namespace_plan?) end def group_visibility_level_description(level, group = nil) @@ -163,7 +168,9 @@ module VisibilityLevelHelper when Gitlab::VisibilityLevel::PRIVATE s_("VisibilityLevel|The group and its projects can only be viewed by members.") when Gitlab::VisibilityLevel::INTERNAL - s_("VisibilityLevel|The group and any internal projects can be viewed by any logged in user except external users.") + s_( + "VisibilityLevel|The group and any internal projects can be viewed by any logged in user except external users." + ) when Gitlab::VisibilityLevel::PUBLIC unless show_updated_public_description_for_setting(group) return s_('VisibilityLevel|The group and any public projects can be viewed without any authentication.') @@ -171,12 +178,16 @@ module VisibilityLevelHelper Kernel.format( s_( - 'VisibilityLevel|The group, any public projects, and any of their members, issues, and merge requests can be viewed without authentication. ' \ + 'VisibilityLevel|The group, any public projects, and any of their members, issues, ' \ + 'and merge requests can be viewed without authentication. ' \ 'Public groups and projects will be indexed by search engines. ' \ 'Read more about %{free_user_limit_doc_link_start}free user limits%{link_end}, ' \ - 'or %{group_billings_link_start}upgrade to a paid tier%{link_end}.'), - free_user_limit_doc_link_start: "".html_safe, - group_billings_link_start: "".html_safe, + 'or %{group_billings_link_start}upgrade to a paid tier%{link_end}.' + ), + free_user_limit_doc_link_start: "".html_safe, + group_billings_link_start: "".html_safe, link_end: "".html_safe ).html_safe end diff --git a/app/helpers/whats_new_helper.rb b/app/helpers/whats_new_helper.rb index e31117d5e3b..aa6e91c3d30 100644 --- a/app/helpers/whats_new_helper.rb +++ b/app/helpers/whats_new_helper.rb @@ -36,7 +36,9 @@ module WhatsNewHelper when 'current_tier' _("Only include features new to your current subscription tier.") when 'disabled' - _("%{italic_start}What's new%{italic_end} is inactive and cannot be viewed.").html_safe % { italic_start: ''.html_safe, italic_end: ''.html_safe } + _("%{italic_start}What's new%{italic_end} is inactive and cannot be viewed.").html_safe % { + italic_start: ''.html_safe, italic_end: ''.html_safe + } end end end diff --git a/app/helpers/wiki_helper.rb b/app/helpers/wiki_helper.rb index 72bd5d2511b..879d67b3b0b 100644 --- a/app/helpers/wiki_helper.rb +++ b/app/helpers/wiki_helper.rb @@ -22,7 +22,10 @@ module WikiHelper end def wiki_sidebar_toggle_button - render Pajamas::ButtonComponent.new(icon: 'chevron-double-lg-left', button_options: { class: 'sidebar-toggle js-sidebar-wiki-toggle' }) + render Pajamas::ButtonComponent.new( + icon: 'chevron-double-lg-left', + button_options: { class: 'sidebar-toggle js-sidebar-wiki-toggle' } + ) end # Produces a pure text breadcrumb for a given page. @@ -68,14 +71,25 @@ module WikiHelper link_options = { action: action, direction: reversed_direction } - render Pajamas::ButtonComponent.new(href: wiki_path(wiki, **link_options), icon: "sort-#{icon_class}", button_options: { class: link_class, title: title }) + render Pajamas::ButtonComponent.new( + href: wiki_path(wiki, **link_options), + icon: "sort-#{icon_class}", + button_options: { class: link_class, title: title } + ) end def wiki_empty_state_messages(wiki) case wiki.container when Project - writable_body = s_("WikiEmpty|Use GitLab Wiki to collaborate on documentation in a project or group. You can store wiki pages written in markup formats like Markdown or AsciiDoc in a separate Git repository, and access the wiki through Git, the GitLab web interface, or the API.") - writable_body += s_("WikiEmpty| Have a Confluence wiki already? Use that instead.") if show_enable_confluence_integration?(wiki.container) + writable_body = s_( + "WikiEmpty|Use GitLab Wiki to collaborate on documentation in a project or group. " \ + "You can store wiki pages written in markup formats like Markdown or AsciiDoc in a " \ + "separate Git repository, and access the wiki through Git, the GitLab web interface, or the API." + ) + + if show_enable_confluence_integration?(wiki.container) + writable_body += s_("WikiEmpty| Have a Confluence wiki already? Use that instead.") + end { writable: { @@ -84,18 +98,29 @@ module WikiHelper }, readonly: { title: s_('WikiEmpty|This wiki doesn\'t have any content yet'), - body: s_('WikiEmpty|You can use GitLab Wiki to collaborate on documentation in a project or group. You can store wiki pages written in markup formats like Markdown or AsciiDoc in a separate Git repository, and access the wiki through Git, the GitLab web interface, or the API.') + body: s_( + 'WikiEmpty|You can use GitLab Wiki to collaborate on documentation in a project or group. ' \ + 'You can store wiki pages written in markup formats like Markdown or AsciiDoc in a ' \ + 'separate Git repository, and access the wiki through Git, the GitLab web interface, or the API.' + ) } } when Group { writable: { title: s_('WikiEmpty|Get started with wikis'), - body: s_("WikiEmpty|Use GitLab Wiki to collaborate on documentation in a project or group. You can store wiki pages written in markup formats like Markdown or AsciiDoc in a separate Git repository, and access the wiki through Git, the GitLab web interface, or the API.") + body: s_( + "WikiEmpty|Use GitLab Wiki to collaborate on documentation in a project or group. " \ + "You can store wiki pages written in markup formats like Markdown or AsciiDoc in a " \ + "separate Git repository, and access the wiki through Git, the GitLab web interface, or the API." + ) }, readonly: { title: s_('WikiEmpty|This wiki doesn\'t have any content yet'), - body: s_('WikiEmpty|You can use GitLab Wiki to collaborate on documentation in a project or group. You can store wiki pages written in markup formats like Markdown or AsciiDoc in a separate Git repository, and access the wiki through Git, the GitLab web interface, or the API.') + body: s_('WikiEmpty|You can use GitLab Wiki to collaborate on documentation in a project or group. ' \ + 'You can store wiki pages written in markup formats like Markdown or AsciiDoc in a ' \ + 'separate Git repository, and access the wiki through Git, the GitLab web interface, or the API.' + ) } } else diff --git a/app/mailers/emails/members.rb b/app/mailers/emails/members.rb index 11352f5b73e..369839020cf 100644 --- a/app/mailers/emails/members.rb +++ b/app/mailers/emails/members.rb @@ -91,7 +91,12 @@ module Emails email_with_layout( to: member.user.notification_email_for(notification_group), - subject: subject(s_("Your membership will expire in %{days_to_expire} days") % { days_to_expire: @days_to_expire })) + subject: subject( + s_("Your membership will expire in %{days_to_expire} days") % { + days_to_expire: @days_to_expire + } + ) + ) end # rubocop: disable CodeReuse/ActiveRecord @@ -115,7 +120,12 @@ module Emails private def member_exists? - Gitlab::AppLogger.info("Tried to send an email invitation for a deleted group. Member id: #{@member_id}") if member.blank? + if member.blank? + Gitlab::AppLogger.info( + "Tried to send an email invitation for a deleted group. Member id: #{@member_id}" + ) + end + member.present? end diff --git a/app/mailers/emails/merge_requests.rb b/app/mailers/emails/merge_requests.rb index 2b4a92e8aa4..33d0ee3d4b4 100644 --- a/app/mailers/emails/merge_requests.rb +++ b/app/mailers/emails/merge_requests.rb @@ -25,7 +25,16 @@ module Emails end # existing_commits - an array containing the first and last commits - def push_to_merge_request_email(recipient_id, merge_request_id, updated_by_user_id, reason = nil, new_commits:, total_new_commits_count:, existing_commits:, total_existing_commits_count:) + def push_to_merge_request_email( + recipient_id, + merge_request_id, + updated_by_user_id, + reason = nil, + new_commits:, + total_new_commits_count:, + existing_commits:, + total_existing_commits_count: + ) setup_merge_request_mail(merge_request_id, recipient_id) @new_commits = new_commits @@ -49,7 +58,13 @@ module Emails end # rubocop: disable CodeReuse/ActiveRecord - def reassigned_merge_request_email(recipient_id, merge_request_id, previous_assignee_ids, updated_by_user_id, reason = nil) + def reassigned_merge_request_email( + recipient_id, + merge_request_id, + previous_assignee_ids, + updated_by_user_id, + reason = nil + ) setup_merge_request_mail(merge_request_id, recipient_id) previous_assignees = [] @@ -62,7 +77,13 @@ module Emails # rubocop: enable CodeReuse/ActiveRecord # rubocop: disable CodeReuse/ActiveRecord - def changed_reviewer_of_merge_request_email(recipient_id, merge_request_id, previous_reviewer_ids, updated_by_user_id, reason = nil) + def changed_reviewer_of_merge_request_email( + recipient_id, + merge_request_id, + previous_reviewer_ids, + updated_by_user_id, + reason = nil + ) setup_merge_request_mail(merge_request_id, recipient_id) @previous_reviewers = [] @@ -87,7 +108,13 @@ module Emails mail_answer_thread(@merge_request, merge_request_thread_options(updated_by_user_id, reason)) end - def changed_milestone_merge_request_email(recipient_id, merge_request_id, milestone, updated_by_user_id, reason = nil) + def changed_milestone_merge_request_email( + recipient_id, + merge_request_id, + milestone, + updated_by_user_id, + reason = nil + ) setup_merge_request_mail(merge_request_id, recipient_id) @milestone = milestone diff --git a/app/mailers/emails/pages_domains.rb b/app/mailers/emails/pages_domains.rb index a6e9da18689..a0975952fee 100644 --- a/app/mailers/emails/pages_domains.rb +++ b/app/mailers/emails/pages_domains.rb @@ -46,7 +46,10 @@ module Emails @domain = domain @project = domain.project - subject_text = _("ACTION REQUIRED: Something went wrong while obtaining the Let's Encrypt certificate for GitLab Pages domain '%{domain}'") % { domain: domain.domain } + subject_text = _( + "ACTION REQUIRED: Something went wrong while obtaining the Let's Encrypt certificate for " \ + "GitLab Pages domain '%{domain}'" + ) % { domain: domain.domain } mail_with_locale( to: recipient.notification_email_for(@project.group), subject: subject(subject_text) diff --git a/app/mailers/emails/profile.rb b/app/mailers/emails/profile.rb index a2460ab8c60..18ae1341bea 100644 --- a/app/mailers/emails/profile.rb +++ b/app/mailers/emails/profile.rb @@ -93,7 +93,10 @@ module Emails @target_url = user_settings_personal_access_tokens_url @token_name = token_name - email_with_layout(to: @user.notification_email_or_default, subject: subject(_("A new personal access token has been created"))) + email_with_layout( + to: @user.notification_email_or_default, + subject: subject(_("A new personal access token has been created")) + ) end def access_token_about_to_expire_email(user, token_names, params = {}) @@ -106,7 +109,14 @@ module Emails @target_url = user_settings_personal_access_tokens_url @days_to_expire = params.fetch(:days_to_expire, PersonalAccessToken::DAYS_TO_EXPIRE) - email_with_layout(to: @user.notification_email_or_default, subject: subject(_("Your personal access tokens will expire in %{days_to_expire} days or less") % { days_to_expire: @days_to_expire })) + email_with_layout( + to: @user.notification_email_or_default, + subject: subject( + _("Your personal access tokens will expire in %{days_to_expire} days or less") % { + days_to_expire: @days_to_expire + } + ) + ) end def access_token_expired_email(user, token_names = []) @@ -116,7 +126,10 @@ module Emails @token_names = token_names @target_url = user_settings_personal_access_tokens_url - email_with_layout(to: @user.notification_email_or_default, subject: subject(_("Your personal access tokens have expired"))) + email_with_layout( + to: @user.notification_email_or_default, + subject: subject(_("Your personal access tokens have expired")) + ) end def access_token_revoked_email(user, token_name, source = nil) @@ -127,7 +140,10 @@ module Emails @target_url = user_settings_personal_access_tokens_url @source = source - email_with_layout(to: @user.notification_email_or_default, subject: subject(_("Your personal access token has been revoked"))) + email_with_layout( + to: @user.notification_email_or_default, + subject: subject(_("Your personal access token has been revoked")) + ) end def ssh_key_expired_email(user, fingerprints) @@ -170,7 +186,12 @@ module Emails email_with_layout( to: @user.notification_email_or_default, - subject: subject(_("Attempted sign in to %{host} using an incorrect verification code") % { host: Gitlab.config.gitlab.host })) + subject: subject( + _("Attempted sign in to %{host} using an incorrect verification code") % { + host: Gitlab.config.gitlab.host + } + ) + ) end def disabled_two_factor_email(user) @@ -178,7 +199,10 @@ module Emails @user = user - email_with_layout(to: @user.notification_email_or_default, subject: subject(_("Two-factor authentication disabled"))) + email_with_layout( + to: @user.notification_email_or_default, + subject: subject(_("Two-factor authentication disabled")) + ) end def new_email_address_added_email(user, email) @@ -198,7 +222,12 @@ module Emails email_with_layout( to: @user.notification_email_or_default, - subject: subject(s_("Achievements|%{namespace_full_path} awarded you the %{achievement_name} achievement") % { namespace_full_path: @achievement.namespace.full_path, achievement_name: @achievement.name })) + subject: subject( + s_("Achievements|%{namespace_full_path} awarded you the %{achievement_name} achievement") % { + namespace_full_path: @achievement.namespace.full_path, achievement_name: @achievement.name + } + ) + ) end end end diff --git a/app/mailers/previews/notify_preview.rb b/app/mailers/previews/notify_preview.rb index 1c2d3d5381b..6a3f0d95fa5 100644 --- a/app/mailers/previews/notify_preview.rb +++ b/app/mailers/previews/notify_preview.rb @@ -60,7 +60,13 @@ class NotifyPreview < ActionMailer::Preview diff_refs: merge_request.diff_refs ) - create_note(noteable_type: 'merge_request', noteable_id: merge_request.id, type: 'DiffNote', position: position, note: note) + create_note( + noteable_type: 'merge_request', + noteable_id: merge_request.id, + type: 'DiffNote', + position: position, + note: note + ) end end @@ -119,7 +125,12 @@ class NotifyPreview < ActionMailer::Preview end def issues_csv_email - Notify.issues_csv_email(user, project, '1997,Ford,E350', { truncated: false, rows_expected: 3, rows_written: 3 }).message + Notify.issues_csv_email( + user, + project, + '1997,Ford,E350', + { truncated: false, rows_expected: 3, rows_written: 3 } + ).message end def new_issue_email @@ -190,7 +201,12 @@ class NotifyPreview < ActionMailer::Preview def pages_domain_enabled_email cleanup do - pages_domain = PagesDomain.new(domain: 'my.example.com', project: project, verified_at: Time.now, enabled_until: 1.week.from_now) + pages_domain = PagesDomain.new( + domain: 'my.example.com', + project: project, + verified_at: Time.now, + enabled_until: 1.week.from_now + ) Notify.pages_domain_enabled_email(pages_domain, user).message end @@ -350,7 +366,10 @@ class NotifyPreview < ActionMailer::Preview end def github_gists_import_errors_email - Notify.github_gists_import_errors_email(user.id, { '12345' => 'Snippet maximum file count exceeded', '67890' => 'error message 2' }).message + Notify.github_gists_import_errors_email( + user.id, + { '12345' => 'Snippet maximum file count exceeded', '67890' => 'error message 2' } + ).message end def bulk_import_complete @@ -414,23 +433,25 @@ class NotifyPreview < ActionMailer::Preview end def custom_email_verification - @custom_email_verification ||= project.service_desk_custom_email_verification || ServiceDesk::CustomEmailVerification.create!( - project: project, - token: 'XXXXXXXXXXXX', - triggerer: user, - triggered_at: Time.current, - state: 'started' - ) + @custom_email_verification ||= project.service_desk_custom_email_verification || + ServiceDesk::CustomEmailVerification.create!( + project: project, + token: 'XXXXXXXXXXXX', + triggerer: user, + triggered_at: Time.current, + state: 'started' + ) end def custom_email_credential - @custom_email_credential ||= project.service_desk_custom_email_credential || ServiceDesk::CustomEmailCredential.create!( - project: project, - smtp_address: 'smtp.gmail.com', # Use gmail, because Gitlab::HTTP_V2::UrlBlocker resolves DNS - smtp_port: 587, - smtp_username: 'user@gmail.com', - smtp_password: 'supersecret' - ) + @custom_email_credential ||= project.service_desk_custom_email_credential || + ServiceDesk::CustomEmailCredential.create!( + project: project, + smtp_address: 'smtp.gmail.com', # Use gmail, because Gitlab::HTTP_V2::UrlBlocker resolves DNS + smtp_port: 587, + smtp_username: 'user@gmail.com', + smtp_password: 'supersecret' + ) end def service_desk_setting diff --git a/app/models/analytics/cycle_analytics/aggregation.rb b/app/models/analytics/cycle_analytics/aggregation.rb index 0a77c693134..8d83ca7ce5f 100644 --- a/app/models/analytics/cycle_analytics/aggregation.rb +++ b/app/models/analytics/cycle_analytics/aggregation.rb @@ -4,9 +4,16 @@ class Analytics::CycleAnalytics::Aggregation < ApplicationRecord include FromUnion include Analytics::CycleAnalytics::Parentable - validates :incremental_runtimes_in_seconds, :incremental_processed_records, :full_runtimes_in_seconds, :full_processed_records, presence: true, length: { maximum: 10 }, allow_blank: true + validates :incremental_runtimes_in_seconds, + :incremental_processed_records, + :full_runtimes_in_seconds, + :full_processed_records, + presence: true, + length: { maximum: 10 }, + allow_blank: true - scope :priority_order, ->(column_to_sort = :last_incremental_run_at) { order(arel_table[column_to_sort].asc.nulls_first) } + scope :priority_order, + ->(column_to_sort = :last_incremental_run_at) { order(arel_table[column_to_sort].asc.nulls_first) } scope :enabled, -> { where('enabled IS TRUE') } def cursor_for(mode, model) diff --git a/app/models/analytics/cycle_analytics/issue_stage_event.rb b/app/models/analytics/cycle_analytics/issue_stage_event.rb index 7bc490bdc78..7f8a365bfac 100644 --- a/app/models/analytics/cycle_analytics/issue_stage_event.rb +++ b/app/models/analytics/cycle_analytics/issue_stage_event.rb @@ -14,7 +14,8 @@ module Analytics scope :assigned_to, ->(user) do assignees_class = IssueAssignee - condition = assignees_class.where(user_id: user).where(arel_table[:issue_id].eq(assignees_class.arel_table[:issue_id])) + condition = assignees_class.where(user_id: user) + .where(arel_table[:issue_id].eq(assignees_class.arel_table[:issue_id])) where(condition.arel.exists) end diff --git a/app/uploaders/ci/secure_file_uploader.rb b/app/uploaders/ci/secure_file_uploader.rb index 85a285ff581..09d9b3abafb 100644 --- a/app/uploaders/ci/secure_file_uploader.rb +++ b/app/uploaders/ci/secure_file_uploader.rb @@ -6,10 +6,6 @@ module Ci storage_location :ci_secure_files - # TODO: Remove this line - # See https://gitlab.com/gitlab-org/gitlab/-/issues/232917 - alias_method :upload, :model - # Use Lockbox to encrypt/decrypt the stored file (registers CarrierWave callbacks) encrypt(key: :key) diff --git a/app/uploaders/terraform/state_uploader.rb b/app/uploaders/terraform/state_uploader.rb index d35072e0385..8ee2b0579c5 100644 --- a/app/uploaders/terraform/state_uploader.rb +++ b/app/uploaders/terraform/state_uploader.rb @@ -6,10 +6,6 @@ module Terraform storage_location :terraform_state - # TODO: Remove this line - # See https://gitlab.com/gitlab-org/gitlab/-/issues/232917 - alias_method :upload, :model - delegate :terraform_state, :project_id, to: :model # Use Lockbox to encrypt/decrypt the stored file (registers CarrierWave callbacks) diff --git a/data/deprecations/16-1-dependency-proxy-graphql-field.yml b/data/deprecations/16-1-dependency-proxy-graphql-field.yml index 80b43e33f41..c63bfd6735f 100644 --- a/data/deprecations/16-1-dependency-proxy-graphql-field.yml +++ b/data/deprecations/16-1-dependency-proxy-graphql-field.yml @@ -5,6 +5,11 @@ reporter: trizzi # (required) GitLab username of the person reporting the deprecation stage: Package # (required) String value of the stage that the feature was created in. e.g., Growth issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/414236 # (required) Link to the deprecation issue in GitLab + impact: low + scope: group + resolution_role: developer + manual_task: true + window: "3" body: | # (required) Do not modify this line, instead modify the lines below. You can use GraphQL to query the amount of storage used by the GitLab Dependency Proxy. However, the `dependencyProxyTotalSizeInBytes` field is limited to ~2Gb (in bytes), which is not always large enough for the Dependency Proxy. As a result, `dependencyProxyTotalSizeInBytes` is deprecated and will be removed in GitLab 17.0. diff --git a/data/deprecations/17-6-remove-migration-state-graphql.yml b/data/deprecations/17-6-remove-migration-state-graphql.yml new file mode 100644 index 00000000000..deaa8ccdfe5 --- /dev/null +++ b/data/deprecations/17-6-remove-migration-state-graphql.yml @@ -0,0 +1,16 @@ +- title: "Removal of `migrationState` field in `ContainerRepository` GraphQL API" + announcement_milestone: "17.6" + removal_milestone: "18.0" + breaking_change: true + reporter: trizzi + stage: Package + issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/459869 + impact: low + scope: project + resolution_role: developer + manual_task: true + window: "3" + body: | + The `migrationState` field in the `ContainerRepositoryType` of GitLab's GraphQL API will be removed in GitLab 18.0. This deprecation is part of our efforts to streamline and improve our API. + + To prepare for this change, we recommend reviewing and updating your GraphQL queries that interact with the `ContainerRepositoryType`. Remove any references to the `migrationState` field and adjust your application logic accordingly. diff --git a/db/docs/batched_background_migrations/requeue_backfill_security_findings_project_id.yml b/db/docs/batched_background_migrations/requeue_backfill_security_findings_project_id.yml new file mode 100644 index 00000000000..b61b0902d45 --- /dev/null +++ b/db/docs/batched_background_migrations/requeue_backfill_security_findings_project_id.yml @@ -0,0 +1,8 @@ +--- +migration_job_name: RequeueBackfillSecurityFindingsProjectId +description: Backfills sharding key `security_findings.project_id` from `vulnerability_scanners`. +feature_category: vulnerability_management +introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/171503 +milestone: '17.6' +queued_migration_version: 20241104065605 +finalized_by: # version of the migration that finalized this BBM diff --git a/db/migrate/20241029184904_update_admin_bot_user_confirmed.rb b/db/migrate/20241029184904_update_admin_bot_user_confirmed.rb new file mode 100644 index 00000000000..9d8142fc6ff --- /dev/null +++ b/db/migrate/20241029184904_update_admin_bot_user_confirmed.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +class UpdateAdminBotUserConfirmed < Gitlab::Database::Migration[2.2] + restrict_gitlab_migration gitlab_schema: :gitlab_main + + milestone '17.6' + + def up + execute <<~SQL + UPDATE "users" SET "confirmed_at" = now(), "private_profile" = TRUE WHERE "users"."user_type" = 11 + SQL + end + + def down + # noop + end +end diff --git a/db/post_migrate/20241014114624_queue_backfill_security_findings_project_id.rb b/db/post_migrate/20241014114624_queue_backfill_security_findings_project_id.rb index 0ec756f79dd..2110ecdf1f1 100644 --- a/db/post_migrate/20241014114624_queue_backfill_security_findings_project_id.rb +++ b/db/post_migrate/20241014114624_queue_backfill_security_findings_project_id.rb @@ -10,31 +10,12 @@ class QueueBackfillSecurityFindingsProjectId < Gitlab::Database::Migration[2.2] SUB_BATCH_SIZE = 100 def up - queue_batched_background_migration( - MIGRATION, - :security_findings, - :id, - :project_id, - :vulnerability_scanners, - :project_id, - :scanner_id, - job_interval: DELAY_INTERVAL, - batch_size: BATCH_SIZE, - sub_batch_size: SUB_BATCH_SIZE - ) + # no-op because there was a bug in the original migration, which has been + # fixed by https://gitlab.com/gitlab-org/gitlab/-/merge_requests/171503 end def down - delete_batched_background_migration( - MIGRATION, - :security_findings, - :id, - [ - :project_id, - :vulnerability_scanners, - :project_id, - :scanner_id - ] - ) + # no-op because there was a bug in the original migration, which has been + # fixed by https://gitlab.com/gitlab-org/gitlab/-/merge_requests/171503 end end diff --git a/db/post_migrate/20241104065605_requeue_backfill_security_findings_project_id.rb b/db/post_migrate/20241104065605_requeue_backfill_security_findings_project_id.rb new file mode 100644 index 00000000000..13eb8e9164a --- /dev/null +++ b/db/post_migrate/20241104065605_requeue_backfill_security_findings_project_id.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true + +class RequeueBackfillSecurityFindingsProjectId < Gitlab::Database::Migration[2.2] + milestone '17.6' + + restrict_gitlab_migration gitlab_schema: :gitlab_sec + + MIGRATION = "BackfillSecurityFindingsProjectId" + DELAY_INTERVAL = 2.minutes + TABLE_NAME = :security_findings + BATCH_COLUMN = :id + MAX_BATCH_SIZE = 150_000 + GITLAB_OPTIMIZED_BATCH_SIZE = 50_000 + GITLAB_OPTIMIZED_SUB_BATCH_SIZE = 250 + JOB_ARGS = %i[project_id vulnerability_scanners project_id scanner_id] + + def up + delete_batched_background_migration(MIGRATION, TABLE_NAME, BATCH_COLUMN, JOB_ARGS) + + queue_batched_background_migration( + MIGRATION, + TABLE_NAME, + BATCH_COLUMN, + *JOB_ARGS, + job_interval: DELAY_INTERVAL, + max_batch_size: MAX_BATCH_SIZE, + batch_size: GITLAB_OPTIMIZED_BATCH_SIZE, + sub_batch_size: GITLAB_OPTIMIZED_SUB_BATCH_SIZE + ) + end + + def down + delete_batched_background_migration(MIGRATION, TABLE_NAME, BATCH_COLUMN, JOB_ARGS) + end +end diff --git a/db/schema_migrations/20241029184904 b/db/schema_migrations/20241029184904 new file mode 100644 index 00000000000..337d45ea9b2 --- /dev/null +++ b/db/schema_migrations/20241029184904 @@ -0,0 +1 @@ +93fc508504c8fb566244c2528d5b78d74c541d10f3e4a769c32fc18de464eedc \ No newline at end of file diff --git a/db/schema_migrations/20241104065605 b/db/schema_migrations/20241104065605 new file mode 100644 index 00000000000..27a270e17ee --- /dev/null +++ b/db/schema_migrations/20241104065605 @@ -0,0 +1 @@ +9428a6ad7128e71a67a2c23903ad1318a008f79b54d1bf9558d802cc378d9da3 \ No newline at end of file diff --git a/doc/development/documentation/styleguide/word_list.md b/doc/development/documentation/styleguide/word_list.md index 9a7f8575733..3a89bc37e82 100644 --- a/doc/development/documentation/styleguide/word_list.md +++ b/doc/development/documentation/styleguide/word_list.md @@ -2338,6 +2338,12 @@ You **turn on** or **turn off** a toggle. For example: - Turn on the **blah** toggle. +## top-level group + +Use lowercase for **top-level group** (hyphenated). + +Do not use **root group**. + ## TFA, two-factor authentication Use [**2FA** and **two-factor authentication**](#2fa-two-factor-authentication) instead. diff --git a/doc/integration/jira/index.md b/doc/integration/jira/index.md index aa2c9684ec3..608201542e3 100644 --- a/doc/integration/jira/index.md +++ b/doc/integration/jira/index.md @@ -20,7 +20,7 @@ GitLab offers two Jira integrations. You can use one or both integrations ### Jira issues integration -> - Name [updated](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/166555) to Jira issues integration in GitLab 17.6. +> - [Changed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/166555) feature name to Jira issues integration in GitLab 17.6. You can use the [Jira issues integration](configure.md) developed by GitLab with Jira Cloud, Jira Data Center, or Jira Server. With this integration, you can: diff --git a/doc/update/deprecations.md b/doc/update/deprecations.md index f1034d0dfcb..bbcd91c51c0 100644 --- a/doc/update/deprecations.md +++ b/doc/update/deprecations.md @@ -632,6 +632,24 @@ This change is a breaking change. You should [create a runner in the UI](https:/
+### Removal of `migrationState` field in `ContainerRepository` GraphQL API + +
+ +- Announced in GitLab 17.6 +- Removal in GitLab 18.0 ([breaking change](https://docs.gitlab.com/ee/update/terminology.html#breaking-change)) +- To discuss this change or learn more, see the [deprecation issue](https://gitlab.com/gitlab-org/gitlab/-/issues/459869). + +
+ +The `migrationState` field in the `ContainerRepositoryType` of GitLab's GraphQL API will be removed in GitLab 18.0. This deprecation is part of our efforts to streamline and improve our API. + +To prepare for this change, we recommend reviewing and updating your GraphQL queries that interact with the `ContainerRepositoryType`. Remove any references to the `migrationState` field and adjust your application logic accordingly. + +
+ +
+ ### Remove `previousStageJobsOrNeeds` from GraphQL
diff --git a/lib/api/merge_requests.rb b/lib/api/merge_requests.rb index 25d20adb71a..3d4943f5665 100644 --- a/lib/api/merge_requests.rb +++ b/lib/api/merge_requests.rb @@ -11,7 +11,8 @@ module API before { authenticate_non_get! } allow_access_with_scope :ai_workflows, if: ->(request) do - request.get? || request.head? || request.put? + request.get? || request.head? || + (request.put? && request.path.match?(%r{/api/v\d+/projects/\d+/merge_requests/\d+$})) # Only allow basic MR updates end rescue_from ActiveRecord::QueryCanceled do |_e| @@ -713,8 +714,7 @@ module API merge_request = find_project_merge_request(params[:merge_request_iid]) # Merge request can not be merged because the user doesn't have - # permissions to push into target branch - # + # permissions to push into target branch. unauthorized! unless merge_request.can_be_merged_by?(current_user) merge_when_pipeline_succeeds = to_boolean(params[:merge_when_pipeline_succeeds]) diff --git a/lib/api/vs_code/settings/entities/vs_code_setting_reference.rb b/lib/api/vs_code/settings/entities/vs_code_setting_reference.rb index 38af85dc0c7..cb1912e7ecb 100644 --- a/lib/api/vs_code/settings/entities/vs_code_setting_reference.rb +++ b/lib/api/vs_code/settings/entities/vs_code_setting_reference.rb @@ -8,10 +8,10 @@ module API include ::API::Helpers::RelatedResourcesHelpers expose :url do |setting| - expose_path(api_v4_vscode_settings_sync_v1_resource_path( - resource_name: setting[:setting_type], - id: setting[:uuid] - )) + resource_name = setting[:setting_type] + id = setting[:uuid] + path = "/api/v4/vscode/settings_sync/v1/resource/#{resource_name}/#{id}" + expose_path(path) end expose :created do |setting| setting[:updated_at]&.to_i diff --git a/lib/api/vs_code/settings/vs_code_settings_sync.rb b/lib/api/vs_code/settings/vs_code_settings_sync.rb index 3c6c204de66..4ded20946d1 100644 --- a/lib/api/vs_code/settings/vs_code_settings_sync.rb +++ b/lib/api/vs_code/settings/vs_code_settings_sync.rb @@ -24,7 +24,7 @@ module API end resource :vscode do - resource :settings_sync do + resource '/settings_sync(/:settings_context_hash)' do content_type :json, 'application/json' content_type :json, 'text/plain' diff --git a/lib/bitbucket_server/representation/activity.rb b/lib/bitbucket_server/representation/activity.rb index 98126bfaa2d..df77fd0d026 100644 --- a/lib/bitbucket_server/representation/activity.rb +++ b/lib/bitbucket_server/representation/activity.rb @@ -35,6 +35,14 @@ module BitbucketServer commit.dig('committer', 'displayName') end + def committer_name + commit.dig('committer', 'displayName') + end + + def committer_username + commit.dig('committer', 'slug') + end + def committer_email commit.dig('committer', 'emailAddress') end @@ -53,6 +61,10 @@ module BitbucketServer action == 'APPROVED' end + def approver_name + raw.dig('user', 'displayName') + end + def approver_username raw.dig('user', 'slug') end @@ -65,6 +77,10 @@ module BitbucketServer action == 'DECLINED' end + def decliner_name + raw.dig('user', 'displayName') + end + def decliner_username raw.dig('user', 'slug') end @@ -80,12 +96,16 @@ module BitbucketServer def to_hash { id: id, + committer_name: committer_user, committer_user: committer_user, + committer_username: committer_username, committer_email: committer_email, merge_timestamp: merge_timestamp, merge_commit: merge_commit, + approver_name: approver_name, approver_username: approver_username, approver_email: approver_email, + decliner_name: decliner_name, decliner_username: decliner_username, decliner_email: decliner_email, created_at: created_at diff --git a/lib/bitbucket_server/representation/comment.rb b/lib/bitbucket_server/representation/comment.rb index a8452b9467e..d2b0a42b9e6 100644 --- a/lib/bitbucket_server/representation/comment.rb +++ b/lib/bitbucket_server/representation/comment.rb @@ -37,6 +37,10 @@ module BitbucketServer raw_comment['id'] end + def author_name + author['displayName'] + end + def author_username author['username'] || author['slug'] || @@ -81,6 +85,7 @@ module BitbucketServer { id: id, + author_name: author_name, author_email: author_email, author_username: author_username, note: note, diff --git a/lib/gitlab/background_migration/backfill_security_findings_project_id.rb b/lib/gitlab/background_migration/backfill_security_findings_project_id.rb index 8cf081db7bf..d7cdc5c7bd1 100644 --- a/lib/gitlab/background_migration/backfill_security_findings_project_id.rb +++ b/lib/gitlab/background_migration/backfill_security_findings_project_id.rb @@ -5,6 +5,14 @@ module Gitlab class BackfillSecurityFindingsProjectId < BackfillDesiredShardingKeyJob operation_name :backfill_security_findings_project_id feature_category :vulnerability_management + + scope_to ->(relation) { relation } + + def perform + each_sub_batch do |sub_batch| + sub_batch.connection.execute(construct_query(sub_batch: sub_batch.where(backfill_column => nil))) + end + end end end end diff --git a/spec/lib/bitbucket_server/representation/activity_spec.rb b/spec/lib/bitbucket_server/representation/activity_spec.rb index 7be0a058f6e..32899050a04 100644 --- a/spec/lib/bitbucket_server/representation/activity_spec.rb +++ b/spec/lib/bitbucket_server/representation/activity_spec.rb @@ -49,6 +49,8 @@ RSpec.describe BitbucketServer::Representation::Activity, feature_category: :imp it { expect(subject.comment?).to be_falsey } it { expect(subject.inline_comment?).to be_falsey } it { expect(subject.committer_user).to eq('root') } + it { expect(subject.committer_name).to eq('root') } + it { expect(subject.committer_username).to eq('slug') } it { expect(subject.committer_email).to eq('test.user@example.com') } it { expect(subject.merge_timestamp).to be_a(Time) } it { expect(subject.created_at).to be_a(Time) } @@ -60,6 +62,8 @@ RSpec.describe BitbucketServer::Representation::Activity, feature_category: :imp a_hash_including( id: 7, committer_user: 'root', + committer_name: 'root', + committer_username: 'slug', committer_email: 'test.user@example.com', merge_commit: '839fa9a2d434eb697815b8fcafaecc51accfdbbc' ) @@ -76,6 +80,7 @@ RSpec.describe BitbucketServer::Representation::Activity, feature_category: :imp it { expect(subject.inline_comment?).to be_falsey } it { expect(subject.merge_event?).to be_falsey } it { expect(subject.approved_event?).to be_truthy } + it { expect(subject.approver_name).to eq('root') } it { expect(subject.approver_username).to eq('slug') } it { expect(subject.approver_email).to eq('test.user@example.com') } it { expect(subject.created_at).to be_a(Time) } @@ -85,6 +90,7 @@ RSpec.describe BitbucketServer::Representation::Activity, feature_category: :imp expect(subject.to_hash).to match( a_hash_including( id: 15, + approver_name: 'root', approver_username: 'slug', approver_email: 'test.user@example.com' ) @@ -101,6 +107,7 @@ RSpec.describe BitbucketServer::Representation::Activity, feature_category: :imp it { expect(subject.inline_comment?).to be_falsey } it { expect(subject.merge_event?).to be_falsey } it { expect(subject.declined_event?).to be_truthy } + it { expect(subject.decliner_name).to eq('root') } it { expect(subject.decliner_username).to eq('slug') } it { expect(subject.decliner_email).to eq('test.user@example.com') } it { expect(subject.created_at).to be_a(Time) } @@ -110,6 +117,7 @@ RSpec.describe BitbucketServer::Representation::Activity, feature_category: :imp expect(subject.to_hash).to match( a_hash_including( id: 18, + decliner_name: 'root', decliner_username: 'slug', decliner_email: 'test.user@example.com' ) diff --git a/spec/lib/bitbucket_server/representation/comment_spec.rb b/spec/lib/bitbucket_server/representation/comment_spec.rb index 25404a4c081..7e32da8a7f7 100644 --- a/spec/lib/bitbucket_server/representation/comment_spec.rb +++ b/spec/lib/bitbucket_server/representation/comment_spec.rb @@ -6,15 +6,19 @@ RSpec.describe BitbucketServer::Representation::Comment, feature_category: :impo let(:activities) { Gitlab::Json.parse(fixture_file('importers/bitbucket_server/activities.json'))['values'] } let(:comment) { activities.first } - subject { described_class.new(comment) } + subject(:comment_representation) { described_class.new(comment) } describe '#id' do - it { expect(subject.id).to eq(9) } + it { expect(comment_representation.id).to eq(9) } + end + + describe '#author_name' do + it { expect(comment_representation.author_name).to eq('root') } end describe '#author_username' do it 'returns username' do - expect(subject.author_username).to eq('username') + expect(comment_representation.author_username).to eq('username') end context 'when username is absent' do @@ -23,7 +27,7 @@ RSpec.describe BitbucketServer::Representation::Comment, feature_category: :impo end it 'returns slug' do - expect(subject.author_username).to eq('slug') + expect(comment_representation.author_username).to eq('slug') end end @@ -34,55 +38,56 @@ RSpec.describe BitbucketServer::Representation::Comment, feature_category: :impo end it 'returns displayName' do - expect(subject.author_username).to eq('root') + expect(comment_representation.author_username).to eq('root') end end end describe '#author_email' do - it { expect(subject.author_email).to eq('test.user@example.com') } + it { expect(comment_representation.author_email).to eq('test.user@example.com') } end describe '#note' do - it { expect(subject.note).to eq('is this a new line?') } + it { expect(comment_representation.note).to eq('is this a new line?') } end describe '#created_at' do - it { expect(subject.created_at).to be_a(Time) } + it { expect(comment_representation.created_at).to be_a(Time) } end describe '#updated_at' do - it { expect(subject.created_at).to be_a(Time) } + it { expect(comment_representation.updated_at).to be_a(Time) } end describe '#comments' do - it { expect(subject.comments.count).to eq(4) } - it { expect(subject.comments).to all(be_a(described_class)) } - it { expect(subject.comments.map(&:note)).to match_array(["Hello world", "Ok", "hello", "hi"]) } + it { expect(comment_representation.comments.count).to eq(4) } + it { expect(comment_representation.comments).to all(be_a(described_class)) } + it { expect(comment_representation.comments.map(&:note)).to match_array(["Hello world", "Ok", "hello", "hi"]) } # The thread should look like: # - # is this a new line? (subject) + # is this a new line? (comment_representation) # -> Hello world (first) # -> Ok (third) # -> Hi (fourth) # -> hello (second) it 'comments have the right parent' do - first, second, third, fourth = subject.comments[0..4] + first, second, third, fourth = comment_representation.comments[0..4] - expect(subject.parent_comment).to be_nil - expect(first.parent_comment).to eq(subject) - expect(second.parent_comment).to eq(subject) + expect(comment_representation.parent_comment).to be_nil + expect(first.parent_comment).to eq(comment_representation) + expect(second.parent_comment).to eq(comment_representation) expect(third.parent_comment).to eq(first) expect(fourth.parent_comment).to eq(first) end end describe '#to_hash' do - it do - expect(subject.to_hash).to match( + specify do + expect(comment_representation.to_hash).to match( a_hash_including( id: 9, + author_name: 'root', author_email: 'test.user@example.com', author_username: 'username', note: 'is this a new line?', diff --git a/spec/migrations/20241014114624_queue_backfill_security_findings_project_id_spec.rb b/spec/migrations/20241014114624_queue_backfill_security_findings_project_id_spec.rb index ab332af48ec..aa2cf2f02d5 100644 --- a/spec/migrations/20241014114624_queue_backfill_security_findings_project_id_spec.rb +++ b/spec/migrations/20241014114624_queue_backfill_security_findings_project_id_spec.rb @@ -6,27 +6,14 @@ require_migration! RSpec.describe QueueBackfillSecurityFindingsProjectId, migration: :gitlab_sec, feature_category: :vulnerability_management do let!(:batched_migration) { described_class::MIGRATION } - it 'schedules a new batched migration' do + it 'does not schedules a new batched migration' do reversible_migration do |migration| migration.before -> { expect(batched_migration).not_to have_scheduled_batched_migration } migration.after -> { - expect(batched_migration).to have_scheduled_batched_migration( - table_name: :security_findings, - column_name: :id, - interval: described_class::DELAY_INTERVAL, - batch_size: described_class::BATCH_SIZE, - sub_batch_size: described_class::SUB_BATCH_SIZE, - gitlab_schema: :gitlab_sec, - job_arguments: [ - :project_id, - :vulnerability_scanners, - :project_id, - :scanner_id - ] - ) + expect(batched_migration).not_to have_scheduled_batched_migration } end end diff --git a/spec/migrations/20241104065605_requeue_backfill_security_findings_project_id_spec.rb b/spec/migrations/20241104065605_requeue_backfill_security_findings_project_id_spec.rb new file mode 100644 index 00000000000..0285d5cc715 --- /dev/null +++ b/spec/migrations/20241104065605_requeue_backfill_security_findings_project_id_spec.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true + +require 'spec_helper' +require_migration! + +RSpec.describe RequeueBackfillSecurityFindingsProjectId, migration: :gitlab_sec, feature_category: :vulnerability_management do + let!(:batched_migration) { described_class::MIGRATION } + let(:expected_job_args) { %i[project_id vulnerability_scanners project_id scanner_id] } + + it 'schedules a new batched migration' do + reversible_migration do |migration| + migration.before -> { + expect(batched_migration).not_to have_scheduled_batched_migration + } + + migration.after -> { + expect(batched_migration).to have_scheduled_batched_migration( + table_name: described_class::TABLE_NAME, + column_name: described_class::BATCH_COLUMN, + interval: described_class::DELAY_INTERVAL, + max_batch_size: described_class::MAX_BATCH_SIZE, + batch_size: described_class::GITLAB_OPTIMIZED_BATCH_SIZE, + sub_batch_size: described_class::GITLAB_OPTIMIZED_SUB_BATCH_SIZE, + gitlab_schema: :gitlab_sec, + job_arguments: expected_job_args + ) + } + end + end +end diff --git a/spec/requests/api/merge_requests_spec.rb b/spec/requests/api/merge_requests_spec.rb index 59a719897ac..66fb86660e1 100644 --- a/spec/requests/api/merge_requests_spec.rb +++ b/spec/requests/api/merge_requests_spec.rb @@ -2810,6 +2810,19 @@ RSpec.describe API::MergeRequests, :aggregate_failures, feature_category: :sourc expect(json_response['reviewers']).to be_empty end end + + context 'with oauth token that has ai_workflows scope' do + let(:token) { create(:oauth_access_token, user: user, scopes: [:ai_workflows]) } + + it "allows access" do + put api( + "/projects/#{project.id}/merge_requests/#{merge_request.iid}?title=new_title", + oauth_access_token: token + ) + + expect(response).to have_gitlab_http_status(:ok) + end + end end describe "POST /projects/:id/merge_requests/:merge_request_iid/context_commits" do @@ -3066,13 +3079,10 @@ RSpec.describe API::MergeRequests, :aggregate_failures, feature_category: :sourc context 'with oauth token that has ai_workflows scope' do let(:token) { create(:oauth_access_token, user: user, scopes: [:ai_workflows]) } - it "allows access" do - put api( - "/projects/#{project.id}/merge_requests/#{merge_request.iid}?title=new_title", - oauth_access_token: token - ) + it "does not allow access" do + put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/merge", oauth_access_token: token) - expect(response).to have_gitlab_http_status(:ok) + expect(response).to have_gitlab_http_status(:forbidden) end end @@ -4003,6 +4013,16 @@ RSpec.describe API::MergeRequests, :aggregate_failures, feature_category: :sourc end describe 'PUT :id/merge_requests/:merge_request_iid/rebase' do + context 'with oauth token that has ai_workflows scope' do + let(:token) { create(:oauth_access_token, user: user, scopes: [:ai_workflows]) } + + it "does not allow access" do + put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/rebase", oauth_access_token: token) + + expect(response).to have_gitlab_http_status(:forbidden) + end + end + context 'when rebase can be performed' do it 'enqueues a rebase of the merge request against the target branch' do Sidekiq::Testing.fake! do