Skip to content

Commit dc807ac

Browse files
author
GitLab Bot
committed
Add latest changes from gitlab-org/gitlab@master
1 parent d053330 commit dc807ac

File tree

85 files changed

+1593
-1107
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

85 files changed

+1593
-1107
lines changed

.rubocop_todo/layout/line_continuation_spacing.yml

-3
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,6 @@ Layout/LineContinuationSpacing:
66
- 'app/helpers/tags_helper.rb'
77
- 'app/helpers/tree_helper.rb'
88
- 'app/models/concerns/spammable.rb'
9-
- 'app/models/work_items/parent_link.rb'
10-
- 'app/services/feature_flags/update_service.rb'
11-
- 'app/services/issues/build_service.rb'
129
- 'app/services/merge_requests/merge_service.rb'
1310
- 'app/services/users/email_verification/validate_token_service.rb'
1411
- 'ee/app/controllers/ee/ldap/omniauth_callbacks_controller.rb'

GITALY_SERVER_VERSION

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1365200de8ffffff9a46f274e58fbd3956d16638
1+
d2a6fe593bb0ce9f364c5aa58b5158fa88a8b9ae

app/assets/javascripts/boards/boards_util.js

+11-16
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,7 @@ const parseFilters = (filters) => {
314314
* @param {Object} objParam.filterFields - data on what filters are available for given issuableType (based on GraphQL schema)
315315
*/
316316
export const filterVariables = ({ filters, issuableType, filterInfo, filterFields, options }) => {
317-
const customFields = new Map();
317+
const customFieldRegex = /^custom-field\[(\d*)\]$/;
318318

319319
return parseFilters(filters)
320320
.map(([k, v, negated]) => {
@@ -325,7 +325,7 @@ export const filterVariables = ({ filters, issuableType, filterInfo, filterField
325325
return [remappedKey, v, negated];
326326
})
327327
.filter(([k, , negated]) => {
328-
if (k.startsWith('custom-field') && options.hasCustomFieldsFeature) {
328+
if (k.match(customFieldRegex) && options.hasCustomFieldsFeature) {
329329
return true;
330330
}
331331

@@ -347,22 +347,17 @@ export const filterVariables = ({ filters, issuableType, filterInfo, filterField
347347
.map(([k, v, negated]) => {
348348
let newK = k;
349349
let newV = v;
350-
if (k.startsWith('custom-field') && options.hasCustomFieldsFeature) {
351-
let customFieldId = k.replace('custom-field[', '').replace(']', '');
352-
customFieldId = convertToGraphQLId(TYPENAME_CUSTOM_FIELD, customFieldId);
353-
354-
const existingSelectedOptions = customFields.has(customFieldId)
355-
? customFields.get(customFieldId)
356-
: [];
357-
358-
const selectedOptionIds = [...existingSelectedOptions];
359-
selectedOptionIds.push(convertToGraphQLId(TYPENAME_CUSTOM_FIELD_SELECT_OPTION, v));
360-
customFields.set(customFieldId, selectedOptionIds);
361-
350+
if (k.match(customFieldRegex) && options.hasCustomFieldsFeature) {
351+
const [, customFieldId] = customFieldRegex.exec(k);
362352
newV = [
363353
{
364-
customFieldId,
365-
selectedOptionIds,
354+
customFieldId: convertToGraphQLId(TYPENAME_CUSTOM_FIELD, customFieldId),
355+
selectedOptionIds: [
356+
convertToGraphQLId(
357+
TYPENAME_CUSTOM_FIELD_SELECT_OPTION,
358+
Array.isArray(v) ? v[v.length - 1] : v,
359+
),
360+
],
366361
},
367362
];
368363
newK = 'customField';
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<template>
2+
<!--NOOP in FOSS-->
3+
<div></div>
4+
</template>

app/assets/javascripts/ci/job_details/job_app.vue

+4-4
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { throttle, isEmpty } from 'lodash';
55
// eslint-disable-next-line no-restricted-imports
66
import { mapGetters, mapState, mapActions } from 'vuex';
77
import JobLogTopBar from 'ee_else_ce/ci/job_details/components/job_log_top_bar.vue';
8-
import RootCauseAnalysisButton from 'ee_else_ce/ci/job_details/components/root_cause_analysis_button.vue';
8+
import RootCauseAnalysisHotspotExperiment from 'ee_else_ce/ci/job_details/components/root_cause_analysis_hotspot_experiment.vue';
99
import SafeHtml from '~/vue_shared/directives/safe_html';
1010
import glAbilitiesMixin from '~/vue_shared/mixins/gl_abilities_mixin';
1111
import { isScrolledToBottom } from '~/lib/utils/scroll_utils';
@@ -31,7 +31,7 @@ export default {
3131
GlIcon,
3232
Log,
3333
JobLogTopBar,
34-
RootCauseAnalysisButton,
34+
RootCauseAnalysisHotspotExperiment,
3535
StuckBlock,
3636
UnmetPrerequisitesBlock,
3737
Sidebar,
@@ -330,8 +330,8 @@ export default {
330330
class="rca-bar-component gl-fixed gl-px-5 gl-py-2 xl:gl-px-6"
331331
data-testid="rca-bar-component"
332332
>
333-
<div class="gl-flex gl-w-full">
334-
<root-cause-analysis-button
333+
<div class="rca-bar-content gl-flex gl-w-full" data-testid="rca-bar-content">
334+
<root-cause-analysis-hotspot-experiment
335335
:job-id="job.id"
336336
:job-status-group="job.status.group"
337337
:can-troubleshoot-job="glAbilities.troubleshootJobWithAi"

app/assets/javascripts/ci/pipelines_page/components/failure_widget/failed_job_details.vue

+3-3
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,15 @@ import CiIcon from '~/vue_shared/components/ci_icon/ci_icon.vue';
77
import SafeHtml from '~/vue_shared/directives/safe_html';
88
import { BRIDGE_KIND, BUILD_KIND } from '~/ci/pipeline_details/graph/constants';
99
import RetryMrFailedJobMutation from '~/ci/merge_requests/graphql/mutations/retry_mr_failed_job.mutation.graphql';
10-
import RootCauseAnalysisButton from 'ee_else_ce/ci/job_details/components/root_cause_analysis_button.vue';
10+
import RootCauseAnalysisHotspotExperiment from 'ee_else_ce/ci/job_details/components/root_cause_analysis_hotspot_experiment.vue';
1111
1212
export default {
1313
components: {
1414
CiIcon,
1515
GlButton,
1616
GlLink,
1717
GlTooltip,
18-
RootCauseAnalysisButton,
18+
RootCauseAnalysisHotspotExperiment,
1919
},
2020
directives: {
2121
GlTooltip: GlTooltipDirective,
@@ -128,7 +128,7 @@ export default {
128128
{{ tooltipErrorText }}
129129
</gl-tooltip>
130130
<div class="col-4 gl-flex gl-max-w-full gl-flex-grow gl-justify-end gl-gap-3">
131-
<root-cause-analysis-button
131+
<root-cause-analysis-hotspot-experiment
132132
:job-gid="job.id"
133133
:job-status-group="statusGroup"
134134
:can-troubleshoot-job="canTroubleshootJob"

app/assets/stylesheets/components/rapid_diffs/_index.scss

+1
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@
22
@import './diff_file_component';
33
@import './text_file_viewers';
44
@import './no_preview';
5+
@import './empty_state';
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
.rd-app-empty-state {
2+
@apply gl-mt-5;
3+
text-align: center;
4+
}
5+
6+
.rd-app-empty-state-card {
7+
@apply gl-bg-subtle;
8+
}

app/components/rapid_diffs/empty_state_component.html.haml

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
.rd-app-empty-state.gl-mt-5.gl-text-center
2-
= render Pajamas::CardComponent.new(card_options: { class: "gl-bg-subtle" }) do |c|
1+
.rd-app-empty-state
2+
= render Pajamas::CardComponent.new(card_options: { class: "rd-app-empty-state-card" }) do |c|
33
- c.with_body do
44
= render Pajamas::EmptyStateComponent.new(svg_path: 'illustrations/empty-state/empty-commit-md.svg',
55
title: message) do |c|

app/helpers/emails_helper.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ def email_action(url)
2424
def action_title(url)
2525
return unless url
2626

27-
%w[merge_requests issues work_items commit].each do |action|
27+
%w[merge_requests issues work_items commit wikis].each do |action|
2828
return "View #{action.humanize.singularize}" if url.split("/").include?(action)
2929
end
3030

app/helpers/milestones_helper.rb

-23
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,7 @@
11
# frozen_string_literal: true
22

33
module MilestonesHelper
4-
def milestone_header_class(primary, issuables)
5-
header_color = milestone_header_color(primary: primary)
6-
header_border = milestone_header_border(issuables)
7-
8-
"#{header_color} #{header_border} gl-flex"
9-
end
10-
11-
def milestone_counter_class(primary)
12-
primary ? 'gl-text-white' : 'gl-text-subtle'
13-
end
14-
154
def milestone_issuable_group(issuable)
165
(issuable.respond_to?(:namespace) && issuable.namespace.is_a?(Group) ? issuable.namespace : nil)
176
end
18-
19-
private
20-
21-
def milestone_header_color(primary: false)
22-
return '' unless primary
23-
24-
'gl-bg-blue-500 gl-text-white'
25-
end
26-
27-
def milestone_header_border(issuables)
28-
issuables.empty? ? 'gl-border-b-0 gl-rounded-base' : ''
29-
end
307
end

app/mailers/emails/notes.rb

+9
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,15 @@ def note_design_email(recipient_id, note_id, reason = nil)
5959
mail_answer_note_thread(design, @note, note_thread_options(reason))
6060
end
6161

62+
def note_wiki_page_email(recipient_id, note_id, reason = nil)
63+
setup_note_mail(note_id, recipient_id)
64+
65+
@wiki_page = @note.noteable
66+
@target_url = Gitlab::UrlBuilder.build(@wiki_page, **note_target_url_query_params)
67+
68+
mail_answer_note_thread(@wiki_page, @note, note_thread_options(reason))
69+
end
70+
6271
private
6372

6473
def note_target_url_options

app/mailers/previews/notify_preview.rb

+25
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,27 @@ def note_merge_request_email_for_individual_note
1717
end
1818
end
1919

20+
def note_wiki_page_email_for_individual_note
21+
note_email(:note_wiki_page_email) do
22+
note = <<-MD.strip_heredoc
23+
This is an individual note on a merge request :smiley:
24+
25+
In this notification email, we expect to see:
26+
27+
- The note contents (that's what you're looking at)
28+
- A link to view this note on GitLab
29+
- An explanation for why the user is receiving this notification
30+
MD
31+
32+
create_note(
33+
noteable_type: 'WikiPage::Meta',
34+
noteable_id: wiki_page_meta.id,
35+
note: note,
36+
project: wiki_page_meta.project
37+
)
38+
end
39+
end
40+
2041
def new_user_email
2142
Notify.new_user_email(user.id).message
2243
end
@@ -517,6 +538,10 @@ def merge_request
517538
@merge_request ||= project.merge_requests.first
518539
end
519540

541+
def wiki_page_meta
542+
@wiki_page_meta ||= WikiPage::Meta.last
543+
end
544+
520545
def milestone
521546
@milestone ||= issue.milestone
522547
end

app/models/cloud_connector/service_access_token.rb

-4
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,5 @@ class ServiceAccessToken < ApplicationRecord
1919
def expired?
2020
expires_at.past?
2121
end
22-
23-
def refresh_required?
24-
expires_at < 2.days.from_now
25-
end
2622
end
2723
end

app/models/wiki_page/meta.rb

+4
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,10 @@ def to_reference
164164
canonical_slug
165165
end
166166

167+
def reference_link_text
168+
canonical_slug
169+
end
170+
167171
# Used by app/policies/todo_policy.rb
168172
def readable_by?(user)
169173
Ability.allowed?(user, :read_wiki, self)

app/models/work_items/parent_link.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ def validate_confidentiality
6464

6565
if work_item_parent.confidential? && !work_item.confidential?
6666
errors.add :work_item, format(
67-
_("cannot assign a non-confidential %{work_item_type} to a confidential "\
67+
_("cannot assign a non-confidential %{work_item_type} to a confidential " \
6868
"parent. Make the %{work_item_type} confidential and try again."),
6969
work_item_type: work_item.work_item_type.name.downcase
7070
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# frozen_string_literal: true
2+
3+
module AutoMerge # rubocop:disable Gitlab/BoundedContexts -- Existing module
4+
class AvailabilityCheck
5+
ABORT_REASONS = {
6+
forbidden: 'they do not have permission to merge the merge request.',
7+
mergeability_checks_failed: ->(check) {
8+
"the merge request cannot be merged. Failed mergeability check: #{check || 'unknown'}"
9+
},
10+
merge_trains_disabled: 'merge trains are disabled for this project.',
11+
missing_diff_head_pipeline: 'the pipeline associated with this merge request is missing or out of sync.',
12+
incomplete_diff_head_pipeline: 'the merge request currently has a pipeline in progress.',
13+
default: 'this merge request cannot be added to the merge train.'
14+
}.freeze
15+
16+
def self.success
17+
new(
18+
status: :available
19+
)
20+
end
21+
22+
def self.error(unavailable_reason:, unsuccessful_check: nil)
23+
new(
24+
status: :unavailable,
25+
unavailable_reason: unavailable_reason,
26+
unsuccessful_check: unsuccessful_check
27+
)
28+
end
29+
30+
attr_reader :status, :unavailable_reason, :unsuccessful_check
31+
32+
def initialize(status:, unavailable_reason: nil, unsuccessful_check: nil)
33+
self.status = status
34+
self.unavailable_reason = unavailable_reason
35+
self.unsuccessful_check = unsuccessful_check
36+
end
37+
38+
def available?
39+
status == :available
40+
end
41+
42+
def abort_message
43+
message = ABORT_REASONS[unavailable_reason] || ABORT_REASONS[:default]
44+
message.respond_to?(:call) ? message.call(unsuccessful_check) : message
45+
end
46+
47+
private
48+
49+
attr_writer :status, :unavailable_reason, :unsuccessful_check
50+
end
51+
end

app/services/auto_merge/base_service.rb

+22-3
Original file line numberDiff line numberDiff line change
@@ -58,14 +58,33 @@ def abort(merge_request, reason)
5858

5959
def available_for?(merge_request)
6060
strong_memoize("available_for_#{merge_request.id}") do
61-
merge_request.can_be_merged_by?(current_user) &&
62-
merge_request.mergeability_checks_pass?(**skippable_available_for_checks(merge_request)) &&
63-
yield
61+
availability_details(merge_request).available?
6462
end
6563
end
6664

6765
private
6866

67+
def availability_details(merge_request)
68+
strong_memoize("availability_details_#{merge_request.id}") do
69+
unless merge_request.can_be_merged_by?(current_user)
70+
next AutoMerge::AvailabilityCheck.error(unavailable_reason: :forbidden)
71+
end
72+
73+
mergeability_checks = merge_request.execute_merge_checks(
74+
MergeRequest.all_mergeability_checks,
75+
params: skippable_available_for_checks(merge_request),
76+
execute_all: false
77+
)
78+
79+
unless mergeability_checks.success?
80+
next AutoMerge::AvailabilityCheck.error(unavailable_reason: :mergeability_checks_failed,
81+
unsuccessful_check: mergeability_checks.payload[:unsuccessful_check])
82+
end
83+
84+
block_given? ? yield : AvailabilityCheck.success
85+
end
86+
end
87+
6988
def skippable_available_for_checks(merge_request)
7089
merge_request.skipped_mergeable_checks(
7190
auto_merge_requested: true,

app/services/auto_merge/merge_when_checks_pass_service.rb

+8-5
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,16 @@ def abort(merge_request, reason)
4141
end
4242
end
4343

44-
override :available_for
45-
def available_for?(merge_request)
44+
# availability_details are responsible for validating whether the service is available_for a merge request and sets
45+
# an unavailable_reason if it is not
46+
override :availability_details
47+
def availability_details(merge_request)
4648
super do
47-
next false if merge_request.project.merge_trains_enabled?
48-
next false if merge_request.mergeable? && !merge_request.diff_head_pipeline_considered_in_progress?
49+
default_reason = AutoMerge::AvailabilityCheck.error(unavailable_reason: :default)
50+
next default_reason if merge_request.project.merge_trains_enabled?
51+
next default_reason if merge_request.mergeable? && !merge_request.diff_head_pipeline_considered_in_progress?
4952

50-
next true
53+
AutoMerge::AvailabilityCheck.success
5154
end
5255
end
5356

app/services/ci/create_pipeline_service.rb

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ class CreatePipelineService < BaseService
1616
Gitlab::Ci::Pipeline::Chain::AssignPartition,
1717
Gitlab::Ci::Pipeline::Chain::PipelineExecutionPolicies::EvaluatePolicies,
1818
Gitlab::Ci::Pipeline::Chain::Skip,
19+
Gitlab::Ci::Pipeline::Chain::Validate::Config,
1920
Gitlab::Ci::Pipeline::Chain::Config::Content,
2021
Gitlab::Ci::Pipeline::Chain::Config::Process,
2122
Gitlab::Ci::Pipeline::Chain::StopLinting,

0 commit comments

Comments
 (0)