Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-04-27 15:08:19 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-04-27 15:08:19 +0300
commit863ba7d77355b305b06112b0c6c3cab3c09898b0 (patch)
tree6b657c3bfc0cff804fad6094ba61d42c6925c4d4 /app
parent359bc6940b1205035e14f028b75d0c9c80a1fd5e (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
-rw-r--r--app/assets/javascripts/boards/components/board_list.vue2
-rw-r--r--app/assets/javascripts/boards/components/board_list_header.vue27
-rw-r--r--app/assets/javascripts/diffs/utils/diff_file.js21
-rw-r--r--app/assets/javascripts/notes/stores/getters.js28
-rw-r--r--app/assets/stylesheets/page_bundles/boards.scss34
-rw-r--r--app/components/pajamas/alert_component.html.haml5
-rw-r--r--app/components/pajamas/alert_component.rb12
-rw-r--r--app/controllers/projects/settings/ci_cd_controller.rb2
-rw-r--r--app/controllers/projects_controller.rb1
-rw-r--r--app/models/alert_management/alert.rb4
-rw-r--r--app/models/alert_management/metric_image.rb4
-rw-r--r--app/models/ci/build.rb4
-rw-r--r--app/models/project.rb1
-rw-r--r--app/services/alert_management/metric_images/upload_service.rb2
-rw-r--r--app/services/import/bitbucket_server_service.rb2
-rw-r--r--app/services/import/github_service.rb2
-rw-r--r--app/services/projects/create_service.rb18
-rw-r--r--app/views/projects/settings/ci_cd/_form.html.haml14
-rw-r--r--app/views/projects/settings/ci_cd/show.html.haml2
19 files changed, 91 insertions, 94 deletions
diff --git a/app/assets/javascripts/boards/components/board_list.vue b/app/assets/javascripts/boards/components/board_list.vue
index 47f25f34d0c..66388f4eb43 100644
--- a/app/assets/javascripts/boards/components/board_list.vue
+++ b/app/assets/javascripts/boards/components/board_list.vue
@@ -287,7 +287,7 @@ export default {
:data-board-type="list.listType"
:class="{ 'bg-danger-100': boardItemsSizeExceedsMax }"
draggable=".board-card"
- class="board-list gl-w-full gl-h-full gl-list-style-none gl-mb-0 gl-p-2"
+ class="board-list gl-w-full gl-h-full gl-list-style-none gl-mb-0 gl-p-3 gl-pt-0"
data-testid="tree-root-wrapper"
@start="handleDragOnStart"
@end="handleDragOnEnd"
diff --git a/app/assets/javascripts/boards/components/board_list_header.vue b/app/assets/javascripts/boards/components/board_list_header.vue
index 9f70c84931f..a4298eb2544 100644
--- a/app/assets/javascripts/boards/components/board_list_header.vue
+++ b/app/assets/javascripts/boards/components/board_list_header.vue
@@ -126,7 +126,7 @@ export default {
return this.list.collapsed ? this.$options.i18n.expand : this.$options.i18n.collapse;
},
chevronIcon() {
- return this.list.collapsed ? 'chevron-down' : 'chevron-right';
+ return this.list.collapsed ? 'chevron-right' : 'chevron-down';
},
isNewIssueShown() {
return (this.listType === ListType.backlog || this.showListHeaderButton) && !this.isEpicBoard;
@@ -248,7 +248,6 @@ export default {
<template>
<header
:class="{
- 'has-border': list.label && list.label.color,
'gl-h-full': list.collapsed,
'board-inner gl-rounded-top-left-base gl-rounded-top-right-base': isSwimlanesHeader,
}"
@@ -279,28 +278,6 @@ export default {
@click="toggleExpanded"
/>
<!-- EE start -->
- <span
- v-if="showMilestoneListDetails"
- aria-hidden="true"
- class="milestone-icon"
- :class="{
- 'gl-mt-3 gl-rotate-90': list.collapsed,
- 'gl-mr-2': !list.collapsed,
- }"
- >
- <gl-icon name="timer" />
- </span>
-
- <span
- v-if="showIterationListDetails"
- aria-hidden="true"
- :class="{
- 'gl-mt-3 gl-rotate-90': list.collapsed,
- 'gl-mr-2': !list.collapsed,
- }"
- >
- <gl-icon name="iteration" />
- </span>
<a
v-if="showAssigneeListDetails"
@@ -399,7 +376,7 @@ export default {
<span class="gl-display-inline-flex">
<gl-tooltip :target="() => $refs.itemCount" :title="itemsTooltipLabel" />
<span ref="itemCount" class="gl-display-inline-flex gl-align-items-center">
- <gl-icon class="gl-mr-2" :name="countIcon" />
+ <gl-icon class="gl-mr-2" :name="countIcon" :size="16" />
<item-count
v-if="!isLoading"
:items-size="isEpicBoard ? list.epicsCount : boardList.issuesCount"
diff --git a/app/assets/javascripts/diffs/utils/diff_file.js b/app/assets/javascripts/diffs/utils/diff_file.js
index a7251bfa775..bcd9fa01278 100644
--- a/app/assets/javascripts/diffs/utils/diff_file.js
+++ b/app/assets/javascripts/diffs/utils/diff_file.js
@@ -93,6 +93,27 @@ export function getShortShaFromFile(file) {
return file.content_sha ? truncateSha(String(file.content_sha)) : null;
}
+export function match({ fileA, fileB, mode = 'universal' } = {}) {
+ const matching = {
+ universal: (a, b) => (a?.id && b?.id ? a.id === b.id : false),
+ /*
+ * MR mode can be wildly incorrect if there is ever the possibility of files from multiple MRs
+ * (e.g. a browser-local merge request/file cache).
+ * That's why the default here is "universal" mode: UUIDs can't conflict, but you can opt into
+ * the dangerous one.
+ *
+ * For reference:
+ * file_identifier_hash === sha1( `${filePath}-${Boolean(isNew)}-${Boolean(isDeleted)}-${Boolean(isRenamed)}` )
+ */
+ mr: (a, b) =>
+ a?.file_identifier_hash && b?.file_identifier_hash
+ ? a.file_identifier_hash === b.file_identifier_hash
+ : false,
+ };
+
+ return (matching[mode] || (() => false))(fileA, fileB);
+}
+
export function stats(file) {
let valid = false;
let classes = '';
diff --git a/app/assets/javascripts/notes/stores/getters.js b/app/assets/javascripts/notes/stores/getters.js
index a710ac0ccf5..9d184b14878 100644
--- a/app/assets/javascripts/notes/stores/getters.js
+++ b/app/assets/javascripts/notes/stores/getters.js
@@ -1,4 +1,5 @@
import { flattenDeep, clone } from 'lodash';
+import { match } from '~/diffs/utils/diff_file';
import { statusBoxState } from '~/issuable/components/status_box.vue';
import { isInMRPage } from '~/lib/utils/common_utils';
import * as constants from '../constants';
@@ -179,29 +180,42 @@ export const unresolvedDiscussionsIdsByDate = (state, getters) =>
// Sorts the array of resolvable yet unresolved discussions by
// comparing file names first. If file names are the same, compares
// line numbers.
-export const unresolvedDiscussionsIdsByDiff = (state, getters) =>
- getters.allResolvableDiscussions
+export const unresolvedDiscussionsIdsByDiff = (state, getters, allState) => {
+ const authoritativeFiles = allState.diffs.diffFiles;
+
+ return getters.allResolvableDiscussions
.filter((d) => !d.resolved && d.active)
.sort((a, b) => {
+ let order = 0;
+
if (!a.diff_file || !b.diff_file) {
- return 0;
+ return order;
}
- // Get file names comparison result
- const filenameComparison = a.diff_file.file_path.localeCompare(b.diff_file.file_path);
+ const authoritativeA = authoritativeFiles.find((source) =>
+ match({ fileA: source, fileB: a.diff_file, mode: 'mr' }),
+ );
+ const authoritativeB = authoritativeFiles.find((source) =>
+ match({ fileA: source, fileB: b.diff_file, mode: 'mr' }),
+ );
+
+ if (authoritativeA && authoritativeB) {
+ order = authoritativeA.order - authoritativeB.order;
+ }
// Get the line numbers, to compare within the same file
const aLines = [a.position.new_line, a.position.old_line];
const bLines = [b.position.new_line, b.position.old_line];
- return filenameComparison < 0 ||
- (filenameComparison === 0 &&
+ return order < 0 ||
+ (order === 0 &&
// .max() because one of them might be zero (if removed/added)
Math.max(aLines[0], aLines[1]) < Math.max(bLines[0], bLines[1]))
? -1
: 1;
})
.map((d) => d.id);
+};
export const resolvedDiscussionCount = (state, getters) => {
const resolvedMap = getters.resolvedDiscussionsById;
diff --git a/app/assets/stylesheets/page_bundles/boards.scss b/app/assets/stylesheets/page_bundles/boards.scss
index eecd4954e39..1a968abd6dd 100644
--- a/app/assets/stylesheets/page_bundles/boards.scss
+++ b/app/assets/stylesheets/page_bundles/boards.scss
@@ -131,8 +131,7 @@
.board-inner {
font-size: $issue-boards-font-size;
- background: var(--gray-10, $gray-10);
- border: 1px solid var(--gray-100, $gray-100);
+ background: var(--gray-50, $gray-50);
}
// to highlight columns we have animated pulse of box-shadow
@@ -169,33 +168,7 @@
}
}
-.board-header {
- &.has-border::before {
- border-top: 3px solid;
- border-color: inherit;
- border-top-left-radius: $border-radius-default;
- border-top-right-radius: $border-radius-default;
- content: '';
- position: absolute;
- width: calc(100% + 2px);
- top: 0;
- left: 0;
- margin-top: -1px;
- margin-right: -1px;
- margin-left: -1px;
- padding-top: 1px;
- padding-right: 1px;
- padding-left: 1px;
-
- .board-title {
- padding-top: ($gl-padding - 3px);
- padding-bottom: $gl-padding;
- }
- }
-}
-
.board-title {
- border-bottom: 1px solid var(--gray-100, $gray-100);
height: 3rem;
.max-issue-size::before {
@@ -219,7 +192,6 @@
.board-card {
background: var(--white, $white);
- border: 1px solid var(--gray-100, $gray-100);
box-shadow: 0 1px 2px rgba(var(--black, $black), 0.1);
line-height: $gl-padding;
list-style: none;
@@ -239,6 +211,10 @@
background-color: var(--blue-50, $blue-50);
}
+ &.sortable-chosen {
+ box-shadow: 0 2px 4px 0 rgba($black, 0.16);
+ }
+
.gl-label {
margin-top: 4px;
margin-right: 4px;
diff --git a/app/components/pajamas/alert_component.html.haml b/app/components/pajamas/alert_component.html.haml
index a1d3c700e57..92bf81a4f8d 100644
--- a/app/components/pajamas/alert_component.html.haml
+++ b/app/components/pajamas/alert_component.html.haml
@@ -1,5 +1,6 @@
-.gl-alert{ role: 'alert', class: ["gl-alert-#{@variant}", @alert_class], data: @alert_data }
- = sprite_icon(icon, css_class: icon_classes)
+.gl-alert{ role: 'alert', class: [base_class, @alert_class], data: @alert_data }
+ - if @show_icon
+ = sprite_icon(icon, css_class: icon_classes)
- if @dismissible
%button.btn.gl-dismiss-btn.btn-default.btn-sm.gl-button.btn-default-tertiary.btn-icon.js-close{ type: 'button',
aria: { label: _('Dismiss') },
diff --git a/app/components/pajamas/alert_component.rb b/app/components/pajamas/alert_component.rb
index 4bb6c41661b..ef35ae195b0 100644
--- a/app/components/pajamas/alert_component.rb
+++ b/app/components/pajamas/alert_component.rb
@@ -6,22 +6,32 @@ module Pajamas
# @param [String] title
# @param [Symbol] variant
# @param [Boolean] dismissible
+ # @param [Boolean] show_icon
# @param [String] alert_class
# @param [Hash] alert_data
# @param [String] close_button_class
# @param [Hash] close_button_data
def initialize(
- title: nil, variant: :info, dismissible: true,
+ title: nil, variant: :info, dismissible: true, show_icon: true,
alert_class: nil, alert_data: {}, close_button_class: nil, close_button_data: {})
@title = title
@variant = variant
@dismissible = dismissible
+ @show_icon = show_icon
@alert_class = alert_class
@alert_data = alert_data
@close_button_class = close_button_class
@close_button_data = close_button_data
end
+ def base_class
+ classes = ["gl-alert-#{@variant}"]
+ classes.push('gl-alert-not-dismissible') unless @dismissible
+ classes.push('gl-alert-no-icon') unless @show_icon
+
+ classes.join(' ')
+ end
+
private
delegate :sprite_icon, to: :helpers
diff --git a/app/controllers/projects/settings/ci_cd_controller.rb b/app/controllers/projects/settings/ci_cd_controller.rb
index 3f4d26bb6ec..8a6202990d4 100644
--- a/app/controllers/projects/settings/ci_cd_controller.rb
+++ b/app/controllers/projects/settings/ci_cd_controller.rb
@@ -87,7 +87,7 @@ module Projects
def permitted_project_params
[
:runners_token, :builds_enabled, :build_allow_git_fetch,
- :build_timeout_human_readable, :build_coverage_regex, :public_builds,
+ :build_timeout_human_readable, :public_builds,
:auto_cancel_pending_pipelines, :ci_config_path, :auto_rollback_enabled,
auto_devops_attributes: [:id, :domain, :enabled, :deploy_strategy],
ci_cd_settings_attributes: [:default_git_depth, :forward_deployment_enabled]
diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb
index e9dbc69fad3..53e30b97a16 100644
--- a/app/controllers/projects_controller.rb
+++ b/app/controllers/projects_controller.rb
@@ -420,7 +420,6 @@ class ProjectsController < Projects::ApplicationController
:allow_merge_on_skipped_pipeline,
:avatar,
:build_allow_git_fetch,
- :build_coverage_regex,
:build_timeout_human_readable,
:resolve_outdated_diff_discussions,
:container_registry_enabled,
diff --git a/app/models/alert_management/alert.rb b/app/models/alert_management/alert.rb
index 1ec3cb62c76..ba23d52ca81 100644
--- a/app/models/alert_management/alert.rb
+++ b/app/models/alert_management/alert.rb
@@ -143,10 +143,6 @@ module AlertManagement
reference.to_i > 0 && reference.to_i <= Gitlab::Database::MAX_INT_VALUE
end
- def metric_images_available?
- ::AlertManagement::MetricImage.available_for?(project)
- end
-
def prometheus?
monitoring_tool == Gitlab::AlertManagement::Payload::MONITORING_TOOLS[:prometheus]
end
diff --git a/app/models/alert_management/metric_image.rb b/app/models/alert_management/metric_image.rb
index 8175a31be7a..4ed28c3b1eb 100644
--- a/app/models/alert_management/metric_image.rb
+++ b/app/models/alert_management/metric_image.rb
@@ -7,10 +7,6 @@ module AlertManagement
belongs_to :alert, class_name: 'AlertManagement::Alert', foreign_key: 'alert_id', inverse_of: :metric_images
- def self.available_for?(project)
- true
- end
-
private
def local_path
diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb
index 6fb7fe93414..2eb97765a35 100644
--- a/app/models/ci/build.rb
+++ b/app/models/ci/build.rb
@@ -889,10 +889,6 @@ module Ci
job_artifacts.find_by(file_type: file_types_ids)&.file
end
- def coverage_regex
- super || project.try(:build_coverage_regex)
- end
-
def steps
[Gitlab::Ci::Build::Step.from_commands(self),
Gitlab::Ci::Build::Step.from_release(self),
diff --git a/app/models/project.rb b/app/models/project.rb
index 84db2b343e6..0b40ce8e46f 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -52,6 +52,7 @@ class Project < ApplicationRecord
ignore_columns :mirror_last_update_at, :mirror_last_successful_update_at, remove_after: '2021-09-22', remove_with: '14.4'
ignore_columns :pull_mirror_branch_prefix, remove_after: '2021-09-22', remove_with: '14.4'
+ ignore_columns :build_coverage_regex, remove_after: '2022-07-22', remove_with: '15.0'
STATISTICS_ATTRIBUTE = 'repositories_count'
UNKNOWN_IMPORT_URL = 'http://unknown.git'
diff --git a/app/services/alert_management/metric_images/upload_service.rb b/app/services/alert_management/metric_images/upload_service.rb
index e9db10594df..46e7e3dbedd 100644
--- a/app/services/alert_management/metric_images/upload_service.rb
+++ b/app/services/alert_management/metric_images/upload_service.rb
@@ -39,7 +39,7 @@ module AlertManagement
private
def can_upload_metrics?
- alert.metric_images_available? && current_user&.can?(:upload_alert_management_metric_image, alert)
+ current_user&.can?(:upload_alert_management_metric_image, alert)
end
end
end
diff --git a/app/services/import/bitbucket_server_service.rb b/app/services/import/bitbucket_server_service.rb
index cdb23370ddc..d1c22f06464 100644
--- a/app/services/import/bitbucket_server_service.rb
+++ b/app/services/import/bitbucket_server_service.rb
@@ -21,6 +21,8 @@ module Import
if project.persisted?
success(project)
+ elsif project.errors[:import_source_disabled].present?
+ error(project.errors[:import_source_disabled], :forbidden)
else
log_and_return_error(project_save_error(project), :unprocessable_entity)
end
diff --git a/app/services/import/github_service.rb b/app/services/import/github_service.rb
index a891dcc11e3..033f6bcb043 100644
--- a/app/services/import/github_service.rb
+++ b/app/services/import/github_service.rb
@@ -25,6 +25,8 @@ module Import
if project.persisted?
success(project)
+ elsif project.errors[:import_source_disabled].present?
+ error(project.errors[:import_source_disabled], :forbidden)
else
error(project_save_error(project), :unprocessable_entity)
end
diff --git a/app/services/projects/create_service.rb b/app/services/projects/create_service.rb
index a601cbb3a3e..997841fc7d5 100644
--- a/app/services/projects/create_service.rb
+++ b/app/services/projects/create_service.rb
@@ -4,6 +4,9 @@ module Projects
class CreateService < BaseService
include ValidatesClassificationLabel
+ ImportSourceDisabledError = Class.new(StandardError)
+ INTERNAL_IMPORT_SOURCES = %w[bare_repository gitlab_custom_project_template gitlab_project_migration].freeze
+
def initialize(user, params)
@current_user = user
@params = params.dup
@@ -25,6 +28,8 @@ module Projects
@project = Project.new(params)
+ validate_import_source_enabled!
+
@project.visibility_level = @project.group.visibility_level unless @project.visibility_level_allowed_by_group?
# If a project is newly created it should have shared runners settings
@@ -77,6 +82,9 @@ module Projects
rescue ActiveRecord::RecordInvalid => e
message = "Unable to save #{e.inspect}: #{e.record.errors.full_messages.join(", ")}"
fail(error: message)
+ rescue ImportSourceDisabledError => e
+ @project.errors.add(:import_source_disabled, e.message) if @project
+ fail(error: e.message)
rescue StandardError => e
@project.errors.add(:base, e.message) if @project
fail(error: e.message)
@@ -238,6 +246,16 @@ module Projects
private
+ def validate_import_source_enabled!
+ return unless @params[:import_type]
+
+ return if INTERNAL_IMPORT_SOURCES.include?(@params[:import_type])
+
+ unless ::Gitlab::CurrentSettings.import_sources&.include?(@params[:import_type])
+ raise ImportSourceDisabledError, "#{@params[:import_type]} import source is disabled"
+ end
+ end
+
def parent_namespace
@parent_namespace ||= Namespace.find_by_id(@params[:namespace_id]) || current_user.namespace
end
diff --git a/app/views/projects/settings/ci_cd/_form.html.haml b/app/views/projects/settings/ci_cd/_form.html.haml
index 5ef56cda6d2..3285fb609e2 100644
--- a/app/views/projects/settings/ci_cd/_form.html.haml
+++ b/app/views/projects/settings/ci_cd/_form.html.haml
@@ -77,19 +77,7 @@
= _("The maximum file size in megabytes for individual job artifacts.")
= link_to sprite_icon('question-o'), help_page_path('user/admin_area/settings/continuous_integration', anchor: 'maximum-artifacts-size'), target: '_blank', rel: 'noopener noreferrer'
- .form-group
- = f.label :build_coverage_regex, _("Test coverage parsing"), class: 'label-bold'
- .input-group
- %span.input-group-prepend
- .input-group-text /
- = f.text_field :build_coverage_regex, class: 'form-control gl-form-input', placeholder: 'Regular expression', data: { qa_selector: 'build_coverage_regex_field' }
- %span.input-group-append
- .input-group-text /
- %p.form-text.text-muted
- = html_escape(_('The regular expression used to find test coverage output in the job log. For example, use %{regex} for Simplecov (Ruby). Leave blank to disable.')) % { regex: '<code>\(\d+.\d+%\)</code>'.html_safe }
- = link_to sprite_icon('question-o'), help_page_path('ci/pipelines/settings', anchor: 'add-test-coverage-results-using-project-settings-deprecated'), target: '_blank', rel: 'noopener noreferrer'
-
- = f.submit _('Save changes'), class: "btn gl-button btn-confirm", data: { qa_selector: 'save_general_pipelines_changes_button' }
+ = f.submit _('Save changes'), class: "btn gl-button btn-confirm"
%hr
diff --git a/app/views/projects/settings/ci_cd/show.html.haml b/app/views/projects/settings/ci_cd/show.html.haml
index 28cde994d00..5238c712a41 100644
--- a/app/views/projects/settings/ci_cd/show.html.haml
+++ b/app/views/projects/settings/ci_cd/show.html.haml
@@ -7,7 +7,7 @@
- expanded = expanded_by_default?
- general_expanded = @project.errors.empty? ? expanded : true
-%section.settings#js-general-pipeline-settings.no-animate{ class: ('expanded' if general_expanded), data: { qa_selector: 'general_pipelines_settings_content' } }
+%section.settings#js-general-pipeline-settings.no-animate{ class: ('expanded' if general_expanded) }
.settings-header
%h4.settings-title.js-settings-toggle.js-settings-toggle-trigger-only
= _("General pipelines")