Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
098c9a1d51
commit
ef2c517527
|
|
@ -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'
|
||||
|
|
|
|||
|
|
@ -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'
|
||||
|
|
|
|||
|
|
@ -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'
|
||||
|
|
|
|||
|
|
@ -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'
|
||||
|
|
|
|||
|
|
@ -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: "<a href='#{help_page_path('user/free_user_limit.md')}' target='_blank' rel='noopener noreferrer'>".html_safe,
|
||||
group_billings_link_start: "<a href='#{group_billings_path(group)}' target='_blank' rel='noopener noreferrer'>".html_safe,
|
||||
'or %{group_billings_link_start}upgrade to a paid tier%{link_end}.'
|
||||
),
|
||||
free_user_limit_doc_link_start: "<a href='#{help_page_path('user/free_user_limit.md')}' target='_blank' " \
|
||||
"rel='noopener noreferrer'>".html_safe,
|
||||
group_billings_link_start: "<a href='#{group_billings_path(group)}' target='_blank' " \
|
||||
"rel='noopener noreferrer'>".html_safe,
|
||||
link_end: "</a>".html_safe
|
||||
).html_safe
|
||||
end
|
||||
|
|
|
|||
|
|
@ -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: '<i>'.html_safe, italic_end: '</i>'.html_safe }
|
||||
_("%{italic_start}What's new%{italic_end} is inactive and cannot be viewed.").html_safe % {
|
||||
italic_start: '<i>'.html_safe, italic_end: '</i>'.html_safe
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -0,0 +1 @@
|
|||
93fc508504c8fb566244c2528d5b78d74c541d10f3e4a769c32fc18de464eedc
|
||||
|
|
@ -0,0 +1 @@
|
|||
9428a6ad7128e71a67a2c23903ad1318a008f79b54d1bf9558d802cc378d9da3
|
||||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -632,6 +632,24 @@ This change is a breaking change. You should [create a runner in the UI](https:/
|
|||
|
||||
<div class="deprecation breaking-change" data-milestone="18.0">
|
||||
|
||||
### Removal of `migrationState` field in `ContainerRepository` GraphQL API
|
||||
|
||||
<div class="deprecation-notes">
|
||||
|
||||
- Announced in GitLab <span class="milestone">17.6</span>
|
||||
- Removal in GitLab <span class="milestone">18.0</span> ([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).
|
||||
|
||||
</div>
|
||||
|
||||
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.
|
||||
|
||||
</div>
|
||||
|
||||
<div class="deprecation breaking-change" data-milestone="18.0">
|
||||
|
||||
### Remove `previousStageJobsOrNeeds` from GraphQL
|
||||
|
||||
<div class="deprecation-notes">
|
||||
|
|
|
|||
|
|
@ -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])
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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'
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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'
|
||||
)
|
||||
|
|
|
|||
|
|
@ -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?',
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue