Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
390582e118
commit
e4ea43b2b8
62 changed files with 427 additions and 408 deletions
|
@ -52,14 +52,6 @@ Layout/ClosingParenthesisIndentation:
|
|||
- 'spec/support/helpers/stub_object_storage.rb'
|
||||
- 'spec/workers/remove_unreferenced_lfs_objects_worker_spec.rb'
|
||||
|
||||
# Offense count: 1
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: EnforcedStyle.
|
||||
# SupportedStyles: leading, trailing
|
||||
Layout/DotPosition:
|
||||
Exclude:
|
||||
- 'app/models/concerns/relative_positioning.rb'
|
||||
|
||||
# Offense count: 69
|
||||
# Cop supports --auto-correct.
|
||||
Layout/EmptyLinesAroundArguments:
|
||||
|
@ -100,12 +92,6 @@ Layout/IndentFirstParameter:
|
|||
- 'spec/support/helpers/repo_helpers.rb'
|
||||
- 'spec/support/helpers/stub_object_storage.rb'
|
||||
|
||||
# Offense count: 1
|
||||
# Cop supports --auto-correct.
|
||||
Layout/LeadingBlankLines:
|
||||
Exclude:
|
||||
- 'lib/tasks/yarn.rake'
|
||||
|
||||
# Offense count: 54
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: EnforcedStyle, IndentationWidth.
|
||||
|
@ -150,11 +136,6 @@ Layout/SpaceInsideBlockBraces:
|
|||
Layout/SpaceInsideParens:
|
||||
Enabled: false
|
||||
|
||||
# Offense count: 1
|
||||
Lint/DisjunctiveAssignmentInConstructor:
|
||||
Exclude:
|
||||
- 'app/models/uploads/base.rb'
|
||||
|
||||
# Offense count: 19
|
||||
Lint/DuplicateMethods:
|
||||
Exclude:
|
||||
|
@ -177,21 +158,6 @@ Lint/DuplicateMethods:
|
|||
Lint/MissingCopEnableDirective:
|
||||
Enabled: false
|
||||
|
||||
# Offense count: 2
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: Whitelist.
|
||||
# Whitelist: present?, blank?, presence, try, try!
|
||||
Lint/SafeNavigationConsistency:
|
||||
Exclude:
|
||||
- 'lib/gitlab/gpg/commit.rb'
|
||||
|
||||
# Offense count: 2
|
||||
# Cop supports --auto-correct.
|
||||
Lint/ToJSON:
|
||||
Exclude:
|
||||
- 'lib/gitlab/cycle_analytics/usage_data.rb'
|
||||
- 'lib/gitlab/template/base_template.rb'
|
||||
|
||||
# Offense count: 6
|
||||
Lint/UriEscapeUnescape:
|
||||
Exclude:
|
||||
|
@ -200,12 +166,6 @@ Lint/UriEscapeUnescape:
|
|||
- 'spec/lib/google_api/auth_spec.rb'
|
||||
- 'spec/requests/api/files_spec.rb'
|
||||
|
||||
# Offense count: 1
|
||||
# Configuration parameters: CheckForMethodsWithNoSideEffects.
|
||||
Lint/Void:
|
||||
Exclude:
|
||||
- 'lib/gitlab/git/diff_collection.rb'
|
||||
|
||||
# Offense count: 165
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: AutoCorrect, AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns.
|
||||
|
@ -284,12 +244,6 @@ RSpec/LetBeforeExamples:
|
|||
- 'spec/rubocop/cop/migration/update_column_in_batches_spec.rb'
|
||||
- 'spec/serializers/pipeline_details_entity_spec.rb'
|
||||
|
||||
# Offense count: 1
|
||||
# Cop supports --auto-correct.
|
||||
RSpec/MultipleSubjects:
|
||||
Exclude:
|
||||
- 'spec/services/merge_requests/create_from_issue_service_spec.rb'
|
||||
|
||||
# Offense count: 2018
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: Strict, EnforcedStyle, AllowedExplicitMatchers.
|
||||
|
@ -319,12 +273,6 @@ RSpec/ScatteredSetup:
|
|||
- 'spec/requests/api/jobs_spec.rb'
|
||||
- 'spec/services/projects/create_service_spec.rb'
|
||||
|
||||
# Offense count: 1
|
||||
# Cop supports --auto-correct.
|
||||
RSpec/SharedContext:
|
||||
Exclude:
|
||||
- 'spec/features/admin/admin_groups_spec.rb'
|
||||
|
||||
# Offense count: 4
|
||||
RSpec/VoidExpect:
|
||||
Exclude:
|
||||
|
@ -348,12 +296,6 @@ Rails/ApplicationController:
|
|||
- 'spec/controllers/concerns/continue_params_spec.rb'
|
||||
- 'spec/lib/marginalia_spec.rb'
|
||||
|
||||
# Offense count: 1
|
||||
# Cop supports --auto-correct.
|
||||
Rails/ApplicationMailer:
|
||||
Exclude:
|
||||
- 'app/mailers/base_mailer.rb'
|
||||
|
||||
# Offense count: 8
|
||||
# Cop supports --auto-correct.
|
||||
Rails/BelongsTo:
|
||||
|
@ -414,14 +356,6 @@ Rails/LinkToBlank:
|
|||
Rails/RakeEnvironment:
|
||||
Enabled: false
|
||||
|
||||
# Offense count: 1
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: Include.
|
||||
# Include: app/models/**/*.rb
|
||||
Rails/RedundantAllowNil:
|
||||
Exclude:
|
||||
- 'app/models/application_setting.rb'
|
||||
|
||||
# Offense count: 868
|
||||
# Configuration parameters: Blacklist, Whitelist.
|
||||
# Blacklist: decrement!, decrement_counter, increment!, increment_counter, toggle!, touch, update_all, update_attribute, update_column, update_columns, update_counters
|
||||
|
@ -457,12 +391,6 @@ Style/CommentedKeyword:
|
|||
- 'lib/tasks/gitlab/backup.rake'
|
||||
- 'spec/tasks/gitlab/backup_rake_spec.rb'
|
||||
|
||||
# Offense count: 1
|
||||
# Cop supports --auto-correct.
|
||||
Style/Dir:
|
||||
Exclude:
|
||||
- 'qa/qa.rb'
|
||||
|
||||
# Offense count: 6
|
||||
# Cop supports --auto-correct.
|
||||
Style/EachWithObject:
|
||||
|
@ -591,13 +519,6 @@ Style/NumericLiteralPrefix:
|
|||
Style/NumericPredicate:
|
||||
Enabled: false
|
||||
|
||||
# Offense count: 2
|
||||
# Cop supports --auto-correct.
|
||||
Style/OrAssignment:
|
||||
Exclude:
|
||||
- 'lib/api/commit_statuses.rb'
|
||||
- 'lib/gitlab/project_transfer.rb'
|
||||
|
||||
# Offense count: 106
|
||||
# Cop supports --auto-correct.
|
||||
Style/ParallelAssignment:
|
||||
|
@ -632,12 +553,6 @@ Style/PerlBackrefs:
|
|||
Style/RaiseArgs:
|
||||
Enabled: false
|
||||
|
||||
# Offense count: 1
|
||||
# Cop supports --auto-correct.
|
||||
Style/RedundantConditional:
|
||||
Exclude:
|
||||
- 'lib/system_check/helpers.rb'
|
||||
|
||||
# Offense count: 221
|
||||
# Cop supports --auto-correct.
|
||||
Style/RedundantFreeze:
|
||||
|
@ -704,12 +619,6 @@ Style/SingleLineMethods:
|
|||
Style/SpecialGlobalVars:
|
||||
EnforcedStyle: use_perl_names
|
||||
|
||||
# Offense count: 1
|
||||
# Cop supports --auto-correct.
|
||||
Style/StderrPuts:
|
||||
Exclude:
|
||||
- 'config/initializers/rspec_profiling.rb'
|
||||
|
||||
# Offense count: 75
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: EnforcedStyle.
|
||||
|
@ -736,30 +645,6 @@ Style/TernaryParentheses:
|
|||
- 'spec/requests/api/pipeline_schedules_spec.rb'
|
||||
- 'spec/support/capybara.rb'
|
||||
|
||||
# Offense count: 2
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: EnforcedStyleForMultiline.
|
||||
# SupportedStylesForMultiline: comma, consistent_comma, no_comma
|
||||
Style/TrailingCommaInArrayLiteral:
|
||||
Exclude:
|
||||
- 'ee/spec/models/project_spec.rb'
|
||||
- 'spec/lib/gitlab/metrics/dashboard/processor_spec.rb'
|
||||
|
||||
# Offense count: 1
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: EnforcedStyleForMultiline.
|
||||
# SupportedStylesForMultiline: comma, consistent_comma, no_comma
|
||||
Style/TrailingCommaInHashLiteral:
|
||||
Exclude:
|
||||
- 'lib/gitlab/ci/ansi2html.rb'
|
||||
|
||||
# Offense count: 2
|
||||
# Cop supports --auto-correct.
|
||||
Style/UnlessElse:
|
||||
Exclude:
|
||||
- 'lib/backup/manager.rb'
|
||||
- 'lib/gitlab/project_search_results.rb'
|
||||
|
||||
# Offense count: 8
|
||||
# Cop supports --auto-correct.
|
||||
Style/UnneededCondition:
|
||||
|
@ -776,13 +661,6 @@ Style/UnneededCondition:
|
|||
Style/UnneededInterpolation:
|
||||
Enabled: false
|
||||
|
||||
# Offense count: 2
|
||||
# Cop supports --auto-correct.
|
||||
Style/UnneededSort:
|
||||
Exclude:
|
||||
- 'app/models/concerns/resolvable_discussion.rb'
|
||||
- 'lib/gitlab/highlight.rb'
|
||||
|
||||
RSpec/ReceiveCounts:
|
||||
Exclude:
|
||||
- 'ee/spec/models/broadcast_message_spec.rb'
|
||||
|
@ -907,4 +785,4 @@ RSpec/ContextMethod:
|
|||
- 'spec/services/projects/open_issues_count_service_spec.rb'
|
||||
- 'spec/services/quick_actions/interpret_service_spec.rb'
|
||||
- 'spec/support/shared_examples/services/boards/issues_list_service_shared_examples.rb'
|
||||
- 'spec/uploaders/namespace_file_uploader_spec.rb'
|
||||
- 'spec/uploaders/namespace_file_uploader_spec.rb'
|
||||
|
|
|
@ -132,11 +132,6 @@ export default {
|
|||
type: String,
|
||||
required: true,
|
||||
},
|
||||
environmentsEndpoint: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: '',
|
||||
},
|
||||
currentEnvironmentName: {
|
||||
type: String,
|
||||
required: true,
|
||||
|
@ -218,9 +213,7 @@ export default {
|
|||
]),
|
||||
...mapGetters('monitoringDashboard', ['getMetricStates', 'filteredEnvironments']),
|
||||
firstDashboard() {
|
||||
return this.environmentsEndpoint.length > 0 && this.allDashboards.length > 0
|
||||
? this.allDashboards[0]
|
||||
: {};
|
||||
return this.allDashboards.length > 0 ? this.allDashboards[0] : {};
|
||||
},
|
||||
selectedDashboard() {
|
||||
return this.allDashboards.find(d => d.path === this.currentDashboard) || this.firstDashboard;
|
||||
|
@ -246,7 +239,6 @@ export default {
|
|||
created() {
|
||||
this.setEndpoints({
|
||||
metricsEndpoint: this.metricsEndpoint,
|
||||
environmentsEndpoint: this.environmentsEndpoint,
|
||||
deploymentsEndpoint: this.deploymentsEndpoint,
|
||||
dashboardEndpoint: this.dashboardEndpoint,
|
||||
dashboardsEndpoint: this.dashboardsEndpoint,
|
||||
|
|
|
@ -172,7 +172,6 @@ export default {
|
|||
|
||||
[types.SET_ENDPOINTS](state, endpoints) {
|
||||
state.metricsEndpoint = endpoints.metricsEndpoint;
|
||||
state.environmentsEndpoint = endpoints.environmentsEndpoint;
|
||||
state.deploymentsEndpoint = endpoints.deploymentsEndpoint;
|
||||
state.dashboardEndpoint = endpoints.dashboardEndpoint;
|
||||
state.dashboardsEndpoint = endpoints.dashboardsEndpoint;
|
||||
|
|
|
@ -2,7 +2,6 @@ import invalidUrl from '~/lib/utils/invalid_url';
|
|||
|
||||
export default () => ({
|
||||
metricsEndpoint: null,
|
||||
environmentsEndpoint: null,
|
||||
deploymentsEndpoint: null,
|
||||
dashboardEndpoint: invalidUrl,
|
||||
emptyState: 'gettingStarted',
|
||||
|
|
|
@ -1,12 +1,8 @@
|
|||
<script>
|
||||
import { GlButton } from '@gitlab/ui';
|
||||
import ClipboardButton from '../../vue_shared/components/clipboard_button.vue';
|
||||
import Icon from '~/vue_shared/components/icon.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Icon,
|
||||
GlButton,
|
||||
ClipboardButton,
|
||||
},
|
||||
props: {
|
||||
|
@ -26,13 +22,5 @@ export default {
|
|||
:title="s__('ServerlessURL|Copy URL')"
|
||||
class="input-group-text js-clipboard-btn"
|
||||
/>
|
||||
<gl-button
|
||||
:href="uri"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer nofollow"
|
||||
class="input-group-text btn btn-default"
|
||||
>
|
||||
<icon name="external-link" />
|
||||
</gl-button>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
@ -146,9 +146,15 @@ export default {
|
|||
auto_merge_strategy: useAutoMerge ? this.mr.preferredAutoMergeStrategy : undefined,
|
||||
should_remove_source_branch: this.removeSourceBranch === true,
|
||||
squash: this.squashBeforeMerge,
|
||||
squash_commit_message: this.squashCommitMessage,
|
||||
};
|
||||
|
||||
// If users can't alter the squash message (e.g. for 1-commit merge requests),
|
||||
// we shouldn't send the commit message because that would make the backend
|
||||
// do unnecessary work.
|
||||
if (this.shouldShowSquashBeforeMerge) {
|
||||
options.squash_commit_message = this.squashCommitMessage;
|
||||
}
|
||||
|
||||
this.isMakingRequest = true;
|
||||
this.service
|
||||
.merge(options)
|
||||
|
|
|
@ -66,6 +66,8 @@ class Dashboard::ProjectsController < Dashboard::ApplicationController
|
|||
@total_user_projects_count = ProjectsFinder.new(params: { non_public: true }, current_user: current_user).execute
|
||||
@total_starred_projects_count = ProjectsFinder.new(params: { starred: true }, current_user: current_user).execute
|
||||
|
||||
finder_params[:use_cte] = Feature.enabled?(:use_cte_for_projects_finder, default_enabled: true)
|
||||
|
||||
projects = ProjectsFinder
|
||||
.new(params: finder_params, current_user: current_user)
|
||||
.execute
|
||||
|
|
|
@ -44,6 +44,8 @@ class ProjectsFinder < UnionFinder
|
|||
init_collection
|
||||
end
|
||||
|
||||
use_cte = params.delete(:use_cte)
|
||||
collection = Project.wrap_authorized_projects_with_cte(collection) if use_cte
|
||||
collection = filter_projects(collection)
|
||||
sort(collection)
|
||||
end
|
||||
|
@ -177,7 +179,7 @@ class ProjectsFinder < UnionFinder
|
|||
end
|
||||
|
||||
def sort(items)
|
||||
params[:sort].present? ? items.sort_by_attribute(params[:sort]) : items.order_id_desc
|
||||
params[:sort].present? ? items.sort_by_attribute(params[:sort]) : items.projects_order_id_desc
|
||||
end
|
||||
|
||||
def by_archived(projects)
|
||||
|
|
|
@ -33,7 +33,6 @@ module EnvironmentsHelper
|
|||
"dashboard-endpoint" => metrics_dashboard_project_environment_path(project, environment, format: :json),
|
||||
"deployments-endpoint" => project_environment_deployments_path(project, environment, format: :json),
|
||||
"default-branch" => project.default_branch,
|
||||
"environments-endpoint": project_environments_path(project, format: :json),
|
||||
"project-path" => project_path(project),
|
||||
"tags-path" => project_tags_path(project),
|
||||
"has-metrics" => "#{environment.has_metrics?}",
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AbuseReportMailer < BaseMailer
|
||||
class AbuseReportMailer < ApplicationMailer
|
||||
layout 'empty_mailer'
|
||||
|
||||
helper EmailsHelper
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class BaseMailer < ActionMailer::Base
|
||||
class ApplicationMailer < ActionMailer::Base
|
||||
around_action :render_with_default_locale
|
||||
|
||||
helper ApplicationHelper
|
|
@ -1,6 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class EmailRejectionMailer < BaseMailer
|
||||
class EmailRejectionMailer < ApplicationMailer
|
||||
layout 'empty_mailer'
|
||||
|
||||
helper EmailsHelper
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Notify < BaseMailer
|
||||
class Notify < ApplicationMailer
|
||||
include ActionDispatch::Routing::PolymorphicRoutes
|
||||
include GitlabRoutingHelper
|
||||
include EmailsHelper
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class RepositoryCheckMailer < BaseMailer
|
||||
class RepositoryCheckMailer < ApplicationMailer
|
||||
# rubocop: disable CodeReuse/ActiveRecord
|
||||
layout 'empty_mailer'
|
||||
|
||||
|
|
|
@ -142,7 +142,7 @@ class ApplicationSetting < ApplicationRecord
|
|||
if: :auto_devops_enabled?
|
||||
|
||||
validates :enabled_git_access_protocol,
|
||||
inclusion: { in: %w(ssh http), allow_blank: true, allow_nil: true }
|
||||
inclusion: { in: %w(ssh http), allow_blank: true }
|
||||
|
||||
validates :domain_blacklist,
|
||||
presence: { message: 'Domain blacklist cannot be empty if Blacklist is enabled.' },
|
||||
|
|
|
@ -16,7 +16,7 @@ module Clusters
|
|||
include ::Gitlab::Utils::StrongMemoize
|
||||
|
||||
include IgnorableColumns
|
||||
ignore_column :kibana_hostname, remove_with: '12.8', remove_after: '2020-01-22'
|
||||
ignore_column :kibana_hostname, remove_with: '12.9', remove_after: '2020-02-22'
|
||||
|
||||
default_value_for :version, VERSION
|
||||
|
||||
|
|
|
@ -237,8 +237,7 @@ module RelativePositioning
|
|||
|
||||
relation
|
||||
.pluck(self.class.relative_positioning_parent_column, Arel.sql("#{calculation}(relative_position) AS position"))
|
||||
.first&.
|
||||
last
|
||||
.first&.last
|
||||
end
|
||||
|
||||
def scoped_items
|
||||
|
|
|
@ -63,7 +63,7 @@ module ResolvableDiscussion
|
|||
return unless resolved?
|
||||
|
||||
strong_memoize(:last_resolved_note) do
|
||||
resolved_notes.sort_by(&:resolved_at).last
|
||||
resolved_notes.max_by(&:resolved_at)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -397,6 +397,8 @@ class Project < ApplicationRecord
|
|||
scope :sorted_by_stars_desc, -> { reorder(star_count: :desc) }
|
||||
scope :sorted_by_stars_asc, -> { reorder(star_count: :asc) }
|
||||
scope :sorted_by_name_asc_limited, ->(limit) { reorder(name: :asc).limit(limit) }
|
||||
# Sometimes queries (e.g. using CTEs) require explicit disambiguation with table name
|
||||
scope :projects_order_id_desc, -> { reorder("#{table_name}.id DESC") }
|
||||
|
||||
scope :in_namespace, ->(namespace_ids) { where(namespace_id: namespace_ids) }
|
||||
scope :personal, ->(user) { where(namespace_id: user.namespace_id) }
|
||||
|
@ -543,6 +545,11 @@ class Project < ApplicationRecord
|
|||
)
|
||||
end
|
||||
|
||||
def self.wrap_authorized_projects_with_cte(collection)
|
||||
cte = Gitlab::SQL::CTE.new(:authorized_projects, collection)
|
||||
Project.with(cte.to_arel).from(cte.alias_to(Project.arel_table))
|
||||
end
|
||||
|
||||
scope :active, -> { joins(:issues, :notes, :merge_requests).order('issues.created_at, notes.created_at, merge_requests.created_at DESC') }
|
||||
scope :abandoned, -> { where('projects.last_activity_at < ?', 6.months.ago) }
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ module Uploads
|
|||
attr_reader :logger
|
||||
|
||||
def initialize(logger: nil)
|
||||
@logger ||= Rails.logger # rubocop:disable Gitlab/RailsLogger
|
||||
@logger = Rails.logger # rubocop:disable Gitlab/RailsLogger
|
||||
end
|
||||
|
||||
def delete_keys_async(keys_to_delete)
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
pre_installed_knative: @cluster.knative_pre_installed? ? 'true': 'false',
|
||||
help_path: help_page_path('user/project/clusters/index.md', anchor: 'installing-applications'),
|
||||
ingress_help_path: help_page_path('user/project/clusters/index.md', anchor: 'getting-the-external-endpoint'),
|
||||
ingress_dns_help_path: help_page_path('user/project/clusters/index.md', anchor: 'manually-determining-the-external-endpoint'),
|
||||
ingress_dns_help_path: help_page_path('user/clusters/applications.md', anchor: 'pointing-your-dns-at-the-external-endpoint'),
|
||||
ingress_mod_security_help_path: help_page_path('user/clusters/applications.md', anchor: 'web-application-firewall-modsecurity'),
|
||||
environments_help_path: help_page_path('ci/environments', anchor: 'defining-environments'),
|
||||
clusters_help_path: help_page_path('user/project/clusters/index.md', anchor: 'deploying-to-a-kubernetes-cluster'),
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Remove invalid data from issue_tracker_data table
|
||||
merge_request:
|
||||
author:
|
||||
type: fixed
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Fix broken link to documentation
|
||||
merge_request: 23715
|
||||
author:
|
||||
type: fixed
|
5
changelogs/unreleased/ak-migration-cleanu.yml
Normal file
5
changelogs/unreleased/ak-migration-cleanu.yml
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Remove kibana_hostname column from clusters_applications_elastic_stacks table
|
||||
merge_request: 23503
|
||||
author:
|
||||
type: changed
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Add selective sync support to Geo Nodes API create endpoint
|
||||
merge_request: 23729
|
||||
author: Rajendra Kadam
|
||||
type: added
|
5
changelogs/unreleased/sh-fix-squash-one-commit.yml
Normal file
5
changelogs/unreleased/sh-fix-squash-one-commit.yml
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Skip squashing with only one commit in a merge request
|
||||
merge_request: 23744
|
||||
author:
|
||||
type: fixed
|
5
changelogs/unreleased/sh-use-cte-for-projects-finder.yml
Normal file
5
changelogs/unreleased/sh-use-cte-for-projects-finder.yml
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Use CTE optimization fence for loading projects in dashboard
|
||||
merge_request: 23754
|
||||
author:
|
||||
type: performance
|
|
@ -46,7 +46,7 @@ module RspecProfilingExt
|
|||
rescue => err
|
||||
return if @already_logged_example_finished_error # rubocop:disable Gitlab/ModuleWithInstanceVariables
|
||||
|
||||
$stderr.puts "rspec_profiling couldn't collect an example: #{err}. Further warnings suppressed."
|
||||
warn "rspec_profiling couldn't collect an example: #{err}. Further warnings suppressed."
|
||||
@already_logged_example_finished_error = true # rubocop:disable Gitlab/ModuleWithInstanceVariables
|
||||
end
|
||||
|
||||
|
|
9
db/post_migrate/20200122144759_drop_kibana_column.rb
Normal file
9
db/post_migrate/20200122144759_drop_kibana_column.rb
Normal file
|
@ -0,0 +1,9 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class DropKibanaColumn < ActiveRecord::Migration[5.2]
|
||||
DOWNTIME = false
|
||||
|
||||
def change
|
||||
remove_column :clusters_applications_elastic_stacks, :kibana_hostname, :string, limit: 255
|
||||
end
|
||||
end
|
|
@ -0,0 +1,24 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# See http://doc.gitlab.com/ce/development/migration_style_guide.html
|
||||
# for more information on how to write migrations for GitLab.
|
||||
|
||||
class RemoveInvalidIssueTrackerData < ActiveRecord::Migration[5.2]
|
||||
include Gitlab::Database::MigrationHelpers
|
||||
|
||||
DOWNTIME = false
|
||||
|
||||
def up
|
||||
sql = "DELETE FROM issue_tracker_data WHERE \
|
||||
(length(encrypted_issues_url) > 0 AND encrypted_issues_url_iv IS NULL) \
|
||||
OR (length(encrypted_new_issue_url) > 0 AND encrypted_new_issue_url_iv IS NULL) \
|
||||
OR (length(encrypted_project_url) > 0 AND encrypted_project_url_iv IS NULL)"
|
||||
|
||||
execute(sql)
|
||||
end
|
||||
|
||||
def down
|
||||
# We need to figure out why migrating data to issue_tracker_data table
|
||||
# failed and then can recreate the data
|
||||
end
|
||||
end
|
|
@ -10,7 +10,7 @@
|
|||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(version: 2020_01_24_053531) do
|
||||
ActiveRecord::Schema.define(version: 2020_01_27_090233) do
|
||||
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "pg_trgm"
|
||||
|
@ -1150,7 +1150,6 @@ ActiveRecord::Schema.define(version: 2020_01_24_053531) do
|
|||
t.bigint "cluster_id", null: false
|
||||
t.integer "status", null: false
|
||||
t.string "version", limit: 255, null: false
|
||||
t.string "kibana_hostname", limit: 255
|
||||
t.text "status_reason"
|
||||
t.index ["cluster_id"], name: "index_clusters_applications_elastic_stacks_on_cluster_id", unique: true
|
||||
end
|
||||
|
|
|
@ -30,6 +30,10 @@ curl --header "PRIVATE-TOKEN: <your_access_token>" https://primary.example.com/a
|
|||
| `verification_max_capacity` | integer | no | Control the maximum concurrency of repository verification for this node. Defaults to 100. |
|
||||
| `container_repositories_max_capacity` | integer | no | Control the maximum concurrency of container repository sync for this node. Defaults to 10. |
|
||||
| `sync_object_storage` | boolean | no | Flag indicating if the secondary Geo node will replicate blobs in Object Storage. Defaults to false. |
|
||||
| `selective_sync_type` | string | no | Limit syncing to only specific groups or shards. Valid values: `"namespaces"`, `"shards"`, or `null`. |
|
||||
| `selective_sync_shards` | array | no | The repository storage for the projects synced if `selective_sync_type` == `shards`. |
|
||||
| `selective_sync_namespace_ids` | array | no | The IDs of groups that should be synced, if `selective_sync_type` == `namespaces`. |
|
||||
| `minimum_reverification_interval` | integer | no | The interval (in days) in which the repository verification is valid. Once expired, it will be reverified. This has no effect when set on a secondary node. |
|
||||
|
||||
Example response:
|
||||
|
||||
|
@ -45,6 +49,10 @@ Example response:
|
|||
"files_max_capacity": 10,
|
||||
"repos_max_capacity": 25,
|
||||
"verification_max_capacity": 100,
|
||||
"selective_sync_type": "namespaces",
|
||||
"selective_sync_shards": [],
|
||||
"selective_sync_namespace_ids": [1, 25],
|
||||
"minimum_reverification_interval": 7,
|
||||
"container_repositories_max_capacity": 10,
|
||||
"sync_object_storage": false,
|
||||
"clone_protocol": "http",
|
||||
|
|
|
@ -76,14 +76,12 @@ module API
|
|||
|
||||
name = params[:name] || params[:context] || 'default'
|
||||
|
||||
unless pipeline
|
||||
pipeline = user_project.ci_pipelines.create!(
|
||||
source: :external,
|
||||
sha: commit.sha,
|
||||
ref: ref,
|
||||
user: current_user,
|
||||
protected: user_project.protected_for?(ref))
|
||||
end
|
||||
pipeline ||= user_project.ci_pipelines.create!(
|
||||
source: :external,
|
||||
sha: commit.sha,
|
||||
ref: ref,
|
||||
user: current_user,
|
||||
protected: user_project.protected_for?(ref))
|
||||
|
||||
status = GenericCommitStatus.running_or_pending.find_or_initialize_by(
|
||||
project: user_project,
|
||||
|
|
|
@ -135,11 +135,11 @@ module Backup
|
|||
|
||||
progress.print 'Unpacking backup ... '
|
||||
|
||||
unless Kernel.system(*%W(tar -xf #{tar_file}))
|
||||
if Kernel.system(*%W(tar -xf #{tar_file}))
|
||||
progress.puts 'done'.color(:green)
|
||||
else
|
||||
progress.puts 'unpacking backup failed'.color(:red)
|
||||
exit 1
|
||||
else
|
||||
progress.puts 'done'.color(:green)
|
||||
end
|
||||
|
||||
ENV["VERSION"] = "#{settings[:db_version]}" if settings[:db_version].to_i > 0
|
||||
|
|
|
@ -15,7 +15,7 @@ module Gitlab
|
|||
4 => 'blue',
|
||||
5 => 'magenta',
|
||||
6 => 'cyan',
|
||||
7 => 'white', # not that this is gray in the dark (aka default) color table
|
||||
7 => 'white' # not that this is gray in the dark (aka default) color table
|
||||
}.freeze
|
||||
|
||||
STYLE_SWITCHES = {
|
||||
|
|
|
@ -12,7 +12,7 @@ module Gitlab
|
|||
@options = { from: 7.days.ago }
|
||||
end
|
||||
|
||||
def to_json
|
||||
def to_json(*)
|
||||
total = 0
|
||||
|
||||
values =
|
||||
|
|
|
@ -102,7 +102,7 @@ module Gitlab
|
|||
def populate!
|
||||
return if @populated
|
||||
|
||||
each { nil } # force a loop through all diffs
|
||||
each {} # force a loop through all diffs
|
||||
nil
|
||||
end
|
||||
|
||||
|
|
|
@ -16,13 +16,13 @@ module Gitlab
|
|||
|
||||
def signature_text
|
||||
strong_memoize(:signature_text) do
|
||||
@signature_data&.itself && @signature_data[0]
|
||||
@signature_data&.itself && @signature_data[0] # rubocop:disable Lint/SafeNavigationConsistency
|
||||
end
|
||||
end
|
||||
|
||||
def signed_text
|
||||
strong_memoize(:signed_text) do
|
||||
@signature_data&.itself && @signature_data[1]
|
||||
@signature_data&.itself && @signature_data[1] # rubocop:disable Lint/SafeNavigationConsistency
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ module Gitlab
|
|||
@lexer ||= custom_language || begin
|
||||
Rouge::Lexer.guess(filename: @blob_name, source: @blob_content).new
|
||||
rescue Rouge::Guesser::Ambiguous => e
|
||||
e.alternatives.sort_by(&:tag).first
|
||||
e.alternatives.min_by(&:tag)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -106,10 +106,10 @@ module Gitlab
|
|||
|
||||
@wiki_blobs ||= begin
|
||||
if project.wiki_enabled? && query.present?
|
||||
unless project.wiki.empty?
|
||||
Gitlab::WikiFileFinder.new(project, repository_wiki_ref).find(query)
|
||||
else
|
||||
if project.wiki.empty?
|
||||
[]
|
||||
else
|
||||
Gitlab::WikiFileFinder.new(project, repository_wiki_ref).find(query)
|
||||
end
|
||||
else
|
||||
[]
|
||||
|
|
|
@ -32,7 +32,7 @@ module Gitlab
|
|||
private
|
||||
|
||||
def move(path_was, path, base_dir = nil)
|
||||
base_dir = root_dir unless base_dir
|
||||
base_dir ||= root_dir
|
||||
from = File.join(base_dir, path_was)
|
||||
to = File.join(base_dir, path)
|
||||
FileUtils.mv(from, to)
|
||||
|
|
|
@ -33,7 +33,7 @@ module Gitlab
|
|||
self
|
||||
end
|
||||
|
||||
def to_json
|
||||
def to_json(*)
|
||||
{ key: key, name: name, content: content }
|
||||
end
|
||||
|
||||
|
|
|
@ -57,11 +57,7 @@ module SystemCheck
|
|||
end
|
||||
|
||||
def should_sanitize?
|
||||
if ENV['SANITIZE'] == 'true'
|
||||
true
|
||||
else
|
||||
false
|
||||
end
|
||||
ENV['SANITIZE'] == 'true'
|
||||
end
|
||||
|
||||
def omnibus_gitlab?
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
namespace :yarn do
|
||||
desc 'Ensure Yarn is installed'
|
||||
|
|
|
@ -22014,9 +22014,6 @@ msgstr ""
|
|||
msgid "ciReport|%{linkStartTag}Learn more about codequality reports %{linkEndTag}"
|
||||
msgstr ""
|
||||
|
||||
msgid "ciReport|%{namespace} is affected by %{vulnerability}."
|
||||
msgstr ""
|
||||
|
||||
msgid "ciReport|%{remainingPackagesCount} more"
|
||||
msgstr ""
|
||||
|
||||
|
@ -22075,9 +22072,6 @@ msgstr ""
|
|||
msgid "ciReport|%{reportType}: Loading resulted in an error"
|
||||
msgstr ""
|
||||
|
||||
msgid "ciReport|%{vulnerability} in %{featurename}"
|
||||
msgstr ""
|
||||
|
||||
msgid "ciReport|(errors when loading results)"
|
||||
msgstr ""
|
||||
|
||||
|
@ -22234,15 +22228,6 @@ msgstr ""
|
|||
msgid "ciReport|There was an error reverting the dismissal. Please try again."
|
||||
msgstr ""
|
||||
|
||||
msgid "ciReport|Upgrade %{name} from %{version} to %{fixed}."
|
||||
msgstr ""
|
||||
|
||||
msgid "ciReport|Upgrade %{name} to %{fixed}."
|
||||
msgstr ""
|
||||
|
||||
msgid "ciReport|Upgrade to %{fixed}."
|
||||
msgstr ""
|
||||
|
||||
msgid "ciReport|Used by %{packagesString}"
|
||||
msgid_plural "ciReport|Used by %{packagesString}, and %{lastPackage}"
|
||||
msgstr[0] ""
|
||||
|
|
|
@ -111,7 +111,6 @@
|
|||
"raw-loader": "^3.1.0",
|
||||
"sanitize-html": "^1.20.0",
|
||||
"select2": "3.5.2-browserify",
|
||||
"sha1": "^1.1.1",
|
||||
"smooshpack": "^0.0.54",
|
||||
"sortablejs": "^1.10.0",
|
||||
"sql.js": "^0.4.0",
|
||||
|
|
2
qa/qa.rb
2
qa/qa.rb
|
@ -1,6 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
$: << File.expand_path(File.dirname(__FILE__))
|
||||
$: << File.expand_path(__dir__)
|
||||
|
||||
Encoding.default_external = 'UTF-8'
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
require 'digest/sha1'
|
||||
|
||||
module QA
|
||||
context 'Release', :docker, quarantine: 'https://gitlab.com/gitlab-org/gitlab/issues/196047' do
|
||||
context 'Release', :docker do
|
||||
describe 'Git clone using a deploy key' do
|
||||
before do
|
||||
Flow::Login.sign_in
|
||||
|
|
|
@ -134,7 +134,7 @@ describe 'Admin Groups' do
|
|||
end
|
||||
|
||||
describe 'add user into a group', :js do
|
||||
shared_context 'adds user into a group' do
|
||||
shared_examples 'adds user into a group' do
|
||||
it do
|
||||
visit admin_group_path(group)
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ describe 'User squashes a merge request', :js do
|
|||
let(:user) { create(:user) }
|
||||
let(:project) { create(:project, :repository) }
|
||||
let(:source_branch) { 'csv' }
|
||||
let(:protected_source_branch) { false }
|
||||
|
||||
let!(:original_head) { project.repository.commit('master') }
|
||||
|
||||
|
@ -40,7 +41,7 @@ describe 'User squashes a merge request', :js do
|
|||
def accept_mr
|
||||
expect(page).to have_button('Merge')
|
||||
|
||||
uncheck 'Delete source branch'
|
||||
uncheck 'Delete source branch' unless protected_source_branch
|
||||
click_on 'Merge'
|
||||
end
|
||||
|
||||
|
@ -56,14 +57,34 @@ describe 'User squashes a merge request', :js do
|
|||
end
|
||||
|
||||
context 'when the MR has only one commit' do
|
||||
let(:source_branch) { 'master' }
|
||||
let(:target_branch) { 'branch-merged' }
|
||||
let(:protected_source_branch) { true }
|
||||
let(:source_sha) { project.commit(source_branch).sha }
|
||||
let(:target_sha) { project.commit(target_branch).sha }
|
||||
|
||||
before do
|
||||
merge_request = create(:merge_request, source_project: project, target_project: project, source_branch: 'master', target_branch: 'branch-merged')
|
||||
merge_request = create(:merge_request, source_project: project, target_project: project, source_branch: source_branch, target_branch: target_branch, squash: true)
|
||||
|
||||
visit project_merge_request_path(project, merge_request)
|
||||
end
|
||||
|
||||
it 'does not show the squash checkbox' do
|
||||
it 'accepts the merge request without issuing a squash request', :sidekiq_inline do
|
||||
expect_next_instance_of(Gitlab::GitalyClient::OperationService) do |instance|
|
||||
expect(instance).not_to receive(:user_squash)
|
||||
end
|
||||
|
||||
expect(project.repository.ancestor?(source_branch, target_branch)).to be_falsey
|
||||
expect(page).not_to have_field('squash')
|
||||
|
||||
accept_mr
|
||||
|
||||
expect(page).to have_content('Merged')
|
||||
|
||||
latest_target_commits = project.repository.commits_between(source_sha, target_sha).map(&:raw)
|
||||
|
||||
expect(latest_target_commits.count).to eq(1)
|
||||
expect(project.repository.ancestor?(source_branch, target_branch)).to be_truthy
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -28,210 +28,227 @@ describe ProjectsFinder, :do_not_mock_admin_mode do
|
|||
let(:params) { {} }
|
||||
let(:current_user) { user }
|
||||
let(:project_ids_relation) { nil }
|
||||
let(:finder) { described_class.new(params: params, current_user: current_user, project_ids_relation: project_ids_relation) }
|
||||
let(:use_cte) { true }
|
||||
let(:finder) { described_class.new(params: params.merge(use_cte: use_cte), current_user: current_user, project_ids_relation: project_ids_relation) }
|
||||
|
||||
subject { finder.execute }
|
||||
|
||||
describe 'without a user' do
|
||||
let(:current_user) { nil }
|
||||
shared_examples 'ProjectFinder#execute examples' do
|
||||
describe 'without a user' do
|
||||
let(:current_user) { nil }
|
||||
|
||||
it { is_expected.to eq([public_project]) }
|
||||
end
|
||||
|
||||
describe 'with a user' do
|
||||
describe 'without private projects' do
|
||||
it { is_expected.to match_array([public_project, internal_project]) }
|
||||
it { is_expected.to eq([public_project]) }
|
||||
end
|
||||
|
||||
describe 'with private projects' do
|
||||
describe 'with a user' do
|
||||
describe 'without private projects' do
|
||||
it { is_expected.to match_array([public_project, internal_project]) }
|
||||
end
|
||||
|
||||
describe 'with private projects' do
|
||||
before do
|
||||
private_project.add_maintainer(user)
|
||||
end
|
||||
|
||||
it { is_expected.to match_array([public_project, internal_project, private_project]) }
|
||||
end
|
||||
end
|
||||
|
||||
describe 'with project_ids_relation' do
|
||||
let(:project_ids_relation) { Project.where(id: internal_project.id) }
|
||||
|
||||
it { is_expected.to eq([internal_project]) }
|
||||
end
|
||||
|
||||
describe 'with id_after' do
|
||||
context 'only returns projects with a project id greater than given' do
|
||||
let(:params) { { id_after: internal_project.id }}
|
||||
|
||||
it { is_expected.to eq([public_project]) }
|
||||
end
|
||||
end
|
||||
|
||||
describe 'with id_before' do
|
||||
context 'only returns projects with a project id less than given' do
|
||||
let(:params) { { id_before: public_project.id }}
|
||||
|
||||
it { is_expected.to eq([internal_project]) }
|
||||
end
|
||||
end
|
||||
|
||||
describe 'with both id_before and id_after' do
|
||||
context 'only returns projects with a project id less than given' do
|
||||
let!(:projects) { create_list(:project, 5, :public) }
|
||||
let(:params) { { id_after: projects.first.id, id_before: projects.last.id }}
|
||||
|
||||
it { is_expected.to contain_exactly(*projects[1..-2]) }
|
||||
end
|
||||
end
|
||||
|
||||
describe 'filter by visibility_level' do
|
||||
before do
|
||||
private_project.add_maintainer(user)
|
||||
end
|
||||
|
||||
it { is_expected.to match_array([public_project, internal_project, private_project]) }
|
||||
context 'private' do
|
||||
let(:params) { { visibility_level: Gitlab::VisibilityLevel::PRIVATE } }
|
||||
|
||||
it { is_expected.to eq([private_project]) }
|
||||
end
|
||||
|
||||
context 'internal' do
|
||||
let(:params) { { visibility_level: Gitlab::VisibilityLevel::INTERNAL } }
|
||||
|
||||
it { is_expected.to eq([internal_project]) }
|
||||
end
|
||||
|
||||
context 'public' do
|
||||
let(:params) { { visibility_level: Gitlab::VisibilityLevel::PUBLIC } }
|
||||
|
||||
it { is_expected.to eq([public_project]) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'with project_ids_relation' do
|
||||
let(:project_ids_relation) { Project.where(id: internal_project.id) }
|
||||
describe 'filter by tags' do
|
||||
before do
|
||||
public_project.tag_list.add('foo')
|
||||
public_project.save!
|
||||
end
|
||||
|
||||
it { is_expected.to eq([internal_project]) }
|
||||
end
|
||||
|
||||
describe 'with id_after' do
|
||||
context 'only returns projects with a project id greater than given' do
|
||||
let(:params) { { id_after: internal_project.id }}
|
||||
let(:params) { { tag: 'foo' } }
|
||||
|
||||
it { is_expected.to eq([public_project]) }
|
||||
end
|
||||
end
|
||||
|
||||
describe 'with id_before' do
|
||||
context 'only returns projects with a project id less than given' do
|
||||
let(:params) { { id_before: public_project.id }}
|
||||
describe 'filter by personal' do
|
||||
let!(:personal_project) { create(:project, namespace: user.namespace) }
|
||||
let(:params) { { personal: true } }
|
||||
|
||||
it { is_expected.to eq([internal_project]) }
|
||||
end
|
||||
end
|
||||
|
||||
describe 'with both id_before and id_after' do
|
||||
context 'only returns projects with a project id less than given' do
|
||||
let!(:projects) { create_list(:project, 5, :public) }
|
||||
let(:params) { { id_after: projects.first.id, id_before: projects.last.id }}
|
||||
|
||||
it { is_expected.to contain_exactly(*projects[1..-2]) }
|
||||
end
|
||||
end
|
||||
|
||||
describe 'filter by visibility_level' do
|
||||
before do
|
||||
private_project.add_maintainer(user)
|
||||
it { is_expected.to eq([personal_project]) }
|
||||
end
|
||||
|
||||
context 'private' do
|
||||
let(:params) { { visibility_level: Gitlab::VisibilityLevel::PRIVATE } }
|
||||
describe 'filter by search' do
|
||||
let(:params) { { search: 'C' } }
|
||||
|
||||
it { is_expected.to eq([public_project]) }
|
||||
end
|
||||
|
||||
describe 'filter by name for backward compatibility' do
|
||||
let(:params) { { name: 'C' } }
|
||||
|
||||
it { is_expected.to eq([public_project]) }
|
||||
end
|
||||
|
||||
describe 'filter by archived' do
|
||||
let!(:archived_project) { create(:project, :public, :archived, name: 'E', path: 'E') }
|
||||
|
||||
context 'non_archived=true' do
|
||||
let(:params) { { non_archived: true } }
|
||||
|
||||
it { is_expected.to match_array([public_project, internal_project]) }
|
||||
end
|
||||
|
||||
context 'non_archived=false' do
|
||||
let(:params) { { non_archived: false } }
|
||||
|
||||
it { is_expected.to match_array([public_project, internal_project, archived_project]) }
|
||||
end
|
||||
|
||||
describe 'filter by archived only' do
|
||||
let(:params) { { archived: 'only' } }
|
||||
|
||||
it { is_expected.to eq([archived_project]) }
|
||||
end
|
||||
|
||||
describe 'filter by archived for backward compatibility' do
|
||||
let(:params) { { archived: false } }
|
||||
|
||||
it { is_expected.to match_array([public_project, internal_project]) }
|
||||
end
|
||||
end
|
||||
|
||||
describe 'filter by trending' do
|
||||
let!(:trending_project) { create(:trending_project, project: public_project) }
|
||||
let(:params) { { trending: true } }
|
||||
|
||||
it { is_expected.to eq([public_project]) }
|
||||
end
|
||||
|
||||
describe 'filter by owned' do
|
||||
let(:params) { { owned: true } }
|
||||
let!(:owned_project) { create(:project, :private, namespace: current_user.namespace) }
|
||||
|
||||
it { is_expected.to eq([owned_project]) }
|
||||
end
|
||||
|
||||
describe 'filter by non_public' do
|
||||
let(:params) { { non_public: true } }
|
||||
|
||||
before do
|
||||
private_project.add_developer(current_user)
|
||||
end
|
||||
|
||||
it { is_expected.to eq([private_project]) }
|
||||
end
|
||||
|
||||
context 'internal' do
|
||||
let(:params) { { visibility_level: Gitlab::VisibilityLevel::INTERNAL } }
|
||||
describe 'filter by starred' do
|
||||
let(:params) { { starred: true } }
|
||||
|
||||
it { is_expected.to eq([internal_project]) }
|
||||
end
|
||||
|
||||
context 'public' do
|
||||
let(:params) { { visibility_level: Gitlab::VisibilityLevel::PUBLIC } }
|
||||
|
||||
it { is_expected.to eq([public_project]) }
|
||||
end
|
||||
end
|
||||
|
||||
describe 'filter by tags' do
|
||||
before do
|
||||
public_project.tag_list.add('foo')
|
||||
public_project.save!
|
||||
end
|
||||
|
||||
let(:params) { { tag: 'foo' } }
|
||||
|
||||
it { is_expected.to eq([public_project]) }
|
||||
end
|
||||
|
||||
describe 'filter by personal' do
|
||||
let!(:personal_project) { create(:project, namespace: user.namespace) }
|
||||
let(:params) { { personal: true } }
|
||||
|
||||
it { is_expected.to eq([personal_project]) }
|
||||
end
|
||||
|
||||
describe 'filter by search' do
|
||||
let(:params) { { search: 'C' } }
|
||||
|
||||
it { is_expected.to eq([public_project]) }
|
||||
end
|
||||
|
||||
describe 'filter by name for backward compatibility' do
|
||||
let(:params) { { name: 'C' } }
|
||||
|
||||
it { is_expected.to eq([public_project]) }
|
||||
end
|
||||
|
||||
describe 'filter by archived' do
|
||||
let!(:archived_project) { create(:project, :public, :archived, name: 'E', path: 'E') }
|
||||
|
||||
context 'non_archived=true' do
|
||||
let(:params) { { non_archived: true } }
|
||||
|
||||
it { is_expected.to match_array([public_project, internal_project]) }
|
||||
end
|
||||
|
||||
context 'non_archived=false' do
|
||||
let(:params) { { non_archived: false } }
|
||||
|
||||
it { is_expected.to match_array([public_project, internal_project, archived_project]) }
|
||||
end
|
||||
|
||||
describe 'filter by archived only' do
|
||||
let(:params) { { archived: 'only' } }
|
||||
|
||||
it { is_expected.to eq([archived_project]) }
|
||||
end
|
||||
|
||||
describe 'filter by archived for backward compatibility' do
|
||||
let(:params) { { archived: false } }
|
||||
|
||||
it { is_expected.to match_array([public_project, internal_project]) }
|
||||
end
|
||||
end
|
||||
|
||||
describe 'filter by trending' do
|
||||
let!(:trending_project) { create(:trending_project, project: public_project) }
|
||||
let(:params) { { trending: true } }
|
||||
|
||||
it { is_expected.to eq([public_project]) }
|
||||
end
|
||||
|
||||
describe 'filter by owned' do
|
||||
let(:params) { { owned: true } }
|
||||
let!(:owned_project) { create(:project, :private, namespace: current_user.namespace) }
|
||||
|
||||
it { is_expected.to eq([owned_project]) }
|
||||
end
|
||||
|
||||
describe 'filter by non_public' do
|
||||
let(:params) { { non_public: true } }
|
||||
|
||||
before do
|
||||
private_project.add_developer(current_user)
|
||||
end
|
||||
|
||||
it { is_expected.to eq([private_project]) }
|
||||
end
|
||||
|
||||
describe 'filter by starred' do
|
||||
let(:params) { { starred: true } }
|
||||
|
||||
before do
|
||||
current_user.toggle_star(public_project)
|
||||
end
|
||||
|
||||
it { is_expected.to eq([public_project]) }
|
||||
|
||||
it 'returns only projects the user has access to' do
|
||||
current_user.toggle_star(private_project)
|
||||
|
||||
is_expected.to eq([public_project])
|
||||
end
|
||||
end
|
||||
|
||||
describe 'filter by without_deleted' do
|
||||
let(:params) { { without_deleted: true } }
|
||||
let!(:pending_delete_project) { create(:project, :public, pending_delete: true) }
|
||||
|
||||
it { is_expected.to match_array([public_project, internal_project]) }
|
||||
end
|
||||
|
||||
describe 'sorting' do
|
||||
let(:params) { { sort: 'name_asc' } }
|
||||
|
||||
it { is_expected.to eq([internal_project, public_project]) }
|
||||
end
|
||||
|
||||
describe 'with admin user' do
|
||||
let(:user) { create(:admin) }
|
||||
|
||||
context 'admin mode enabled' do
|
||||
before do
|
||||
enable_admin_mode!(current_user)
|
||||
current_user.toggle_star(public_project)
|
||||
end
|
||||
|
||||
it { is_expected.to match_array([public_project, internal_project, private_project, shared_project]) }
|
||||
it { is_expected.to eq([public_project]) }
|
||||
|
||||
it 'returns only projects the user has access to' do
|
||||
current_user.toggle_star(private_project)
|
||||
|
||||
is_expected.to eq([public_project])
|
||||
expect(subject.count).to eq(1)
|
||||
expect(subject.limit(1000).count).to eq(1)
|
||||
end
|
||||
end
|
||||
|
||||
context 'admin mode disabled' do
|
||||
describe 'filter by without_deleted' do
|
||||
let(:params) { { without_deleted: true } }
|
||||
let!(:pending_delete_project) { create(:project, :public, pending_delete: true) }
|
||||
|
||||
it { is_expected.to match_array([public_project, internal_project]) }
|
||||
end
|
||||
|
||||
describe 'sorting' do
|
||||
let(:params) { { sort: 'name_asc' } }
|
||||
|
||||
it { is_expected.to eq([internal_project, public_project]) }
|
||||
end
|
||||
|
||||
describe 'with admin user' do
|
||||
let(:user) { create(:admin) }
|
||||
|
||||
context 'admin mode enabled' do
|
||||
before do
|
||||
enable_admin_mode!(current_user)
|
||||
end
|
||||
|
||||
it { is_expected.to match_array([public_project, internal_project, private_project, shared_project]) }
|
||||
end
|
||||
|
||||
context 'admin mode disabled' do
|
||||
it { is_expected.to match_array([public_project, internal_project]) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'without CTE flag enabled' do
|
||||
let(:use_cte) { false }
|
||||
|
||||
it_behaves_like 'ProjectFinder#execute examples'
|
||||
end
|
||||
|
||||
describe 'with CTE flag enabled' do
|
||||
let(:use_cte) { true }
|
||||
|
||||
it_behaves_like 'ProjectFinder#execute examples'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -23,7 +23,6 @@ export const propsData = {
|
|||
emptyNoDataSvgPath: '/path/to/no-data.svg',
|
||||
emptyNoDataSmallSvgPath: '/path/to/no-data-small.svg',
|
||||
emptyUnableToConnectSvgPath: '/path/to/unable-to-connect.svg',
|
||||
environmentsEndpoint: '/root/hello-prometheus/-/environments.json',
|
||||
currentEnvironmentName: 'production',
|
||||
customMetricsAvailable: false,
|
||||
customMetricsPath: '',
|
||||
|
|
|
@ -159,7 +159,6 @@ describe('Monitoring store actions', () => {
|
|||
{
|
||||
metricsEndpoint: 'additional_metrics.json',
|
||||
deploymentsEndpoint: 'deployments.json',
|
||||
environmentsEndpoint: 'deployments.json',
|
||||
},
|
||||
mockedState,
|
||||
[
|
||||
|
@ -168,7 +167,6 @@ describe('Monitoring store actions', () => {
|
|||
payload: {
|
||||
metricsEndpoint: 'additional_metrics.json',
|
||||
deploymentsEndpoint: 'deployments.json',
|
||||
environmentsEndpoint: 'deployments.json',
|
||||
},
|
||||
},
|
||||
],
|
||||
|
|
|
@ -81,13 +81,11 @@ describe('Monitoring mutations', () => {
|
|||
it('should set all the endpoints', () => {
|
||||
mutations[types.SET_ENDPOINTS](stateCopy, {
|
||||
metricsEndpoint: 'additional_metrics.json',
|
||||
environmentsEndpoint: 'environments.json',
|
||||
deploymentsEndpoint: 'deployments.json',
|
||||
dashboardEndpoint: 'dashboard.json',
|
||||
projectPath: '/gitlab-org/gitlab-foss',
|
||||
});
|
||||
expect(stateCopy.metricsEndpoint).toEqual('additional_metrics.json');
|
||||
expect(stateCopy.environmentsEndpoint).toEqual('environments.json');
|
||||
expect(stateCopy.deploymentsEndpoint).toEqual('deployments.json');
|
||||
expect(stateCopy.dashboardEndpoint).toEqual('dashboard.json');
|
||||
expect(stateCopy.projectPath).toEqual('/gitlab-org/gitlab-foss');
|
||||
|
|
|
@ -29,7 +29,6 @@ describe EnvironmentsHelper do
|
|||
'metrics-endpoint' => additional_metrics_project_environment_path(project, environment, format: :json),
|
||||
'deployments-endpoint' => project_environment_deployments_path(project, environment, format: :json),
|
||||
'default-branch' => 'master',
|
||||
'environments-endpoint': project_environments_path(project, format: :json),
|
||||
'project-path' => project_path(project),
|
||||
'tags-path' => project_tags_path(project),
|
||||
'has-metrics' => "#{environment.has_metrics?}",
|
||||
|
|
|
@ -30,7 +30,6 @@ const propsData = {
|
|||
emptyNoDataSvgPath: '/path/to/no-data.svg',
|
||||
emptyNoDataSmallSvgPath: '/path/to/no-data-small.svg',
|
||||
emptyUnableToConnectSvgPath: '/path/to/unable-to-connect.svg',
|
||||
environmentsEndpoint: '/root/hello-prometheus/environments/35',
|
||||
currentEnvironmentName: 'production',
|
||||
customMetricsAvailable: false,
|
||||
customMetricsPath: '',
|
||||
|
|
|
@ -62,7 +62,7 @@ describe Gitlab::Metrics::Dashboard::Processor do
|
|||
'metric_a1', # group priority 1, panel weight 1
|
||||
project_business_metric.id, # group priority 0, panel weight nil (0)
|
||||
project_response_metric.id, # group priority -5, panel weight nil (0)
|
||||
project_system_metric.id, # group priority -10, panel weight nil (0)
|
||||
project_system_metric.id # group priority -10, panel weight nil (0)
|
||||
]
|
||||
actual_metrics_order = all_metrics.map { |m| m[:id] || m[:metric_id] }
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ describe 'Marginalia spec' do
|
|||
end
|
||||
end
|
||||
|
||||
class MarginaliaTestMailer < BaseMailer
|
||||
class MarginaliaTestMailer < ApplicationMailer
|
||||
def first_user
|
||||
User.first
|
||||
end
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
require Rails.root.join('db', 'post_migrate', '20200127090233_remove_invalid_issue_tracker_data.rb')
|
||||
|
||||
describe RemoveInvalidIssueTrackerData, :migration do
|
||||
let(:issue_tracker_data) { table(:issue_tracker_data) }
|
||||
let(:services) { table(:services) }
|
||||
|
||||
let(:service) { services.create(id: 1) }
|
||||
let(:data) do
|
||||
{
|
||||
service_id: service.id,
|
||||
encrypted_issues_url: 'http:url.com',
|
||||
encrypted_issues_url_iv: 'somevalue',
|
||||
encrypted_new_issue_url: 'http:url.com',
|
||||
encrypted_new_issue_url_iv: 'somevalue',
|
||||
encrypted_project_url: 'username',
|
||||
encrypted_project_url_iv: 'somevalue'
|
||||
}
|
||||
end
|
||||
|
||||
let!(:valid_data) { issue_tracker_data.create(data) }
|
||||
let!(:empty_data) { issue_tracker_data.create(service_id: service.id) }
|
||||
let!(:invalid_issues_url) do
|
||||
data[:encrypted_issues_url_iv] = nil
|
||||
issue_tracker_data.create(data)
|
||||
end
|
||||
let!(:missing_issues_url) do
|
||||
data[:encrypted_issues_url] = ''
|
||||
data[:encrypted_issues_url_iv] = nil
|
||||
issue_tracker_data.create(data)
|
||||
end
|
||||
let!(:invalid_new_isue_url) do
|
||||
data[:encrypted_new_issue_url_iv] = nil
|
||||
issue_tracker_data.create(data)
|
||||
end
|
||||
let!(:missing_new_issue_url) do
|
||||
data[:encrypted_new_issue_url] = ''
|
||||
issue_tracker_data.create(data)
|
||||
end
|
||||
let!(:invalid_project_url) do
|
||||
data[:encrypted_project_url_iv] = nil
|
||||
issue_tracker_data.create(data)
|
||||
end
|
||||
let!(:missing_project_url) do
|
||||
data[:encrypted_project_url] = nil
|
||||
data[:encrypted_project_url_iv] = nil
|
||||
issue_tracker_data.create(data)
|
||||
end
|
||||
|
||||
it 'removes the invalid data' do
|
||||
valid_data_records = [valid_data, empty_data, missing_issues_url, missing_new_issue_url, missing_project_url]
|
||||
|
||||
expect { migrate! }.to change { issue_tracker_data.count }.from(8).to(5)
|
||||
|
||||
expect(issue_tracker_data.all).to match_array(valid_data_records)
|
||||
end
|
||||
end
|
|
@ -3780,6 +3780,25 @@ describe Project do
|
|||
end
|
||||
end
|
||||
|
||||
describe '.wrap_authorized_projects_with_cte' do
|
||||
let!(:user) { create(:user) }
|
||||
|
||||
let!(:private_project) do
|
||||
create(:project, :private, creator: user, namespace: user.namespace)
|
||||
end
|
||||
|
||||
let!(:public_project) { create(:project, :public) }
|
||||
|
||||
let(:projects) { described_class.all.public_or_visible_to_user(user) }
|
||||
|
||||
subject { described_class.wrap_authorized_projects_with_cte(projects) }
|
||||
|
||||
it 'wrapped query matches original' do
|
||||
expect(subject.to_sql).to match(/^WITH "authorized_projects" AS/)
|
||||
expect(subject).to match_array(projects)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#pages_available?' do
|
||||
let(:project) { create(:project, group: group) }
|
||||
|
||||
|
|
|
@ -11,10 +11,8 @@ describe MergeRequests::CreateFromIssueService do
|
|||
let(:milestone_id) { create(:milestone, project: project).id }
|
||||
let(:issue) { create(:issue, project: project, milestone_id: milestone_id) }
|
||||
let(:custom_source_branch) { 'custom-source-branch' }
|
||||
|
||||
subject(:service) { described_class.new(project, user, service_params) }
|
||||
|
||||
subject(:service_with_custom_source_branch) { described_class.new(project, user, branch_name: custom_source_branch, **service_params) }
|
||||
let(:service) { described_class.new(project, user, service_params) }
|
||||
let(:service_with_custom_source_branch) { described_class.new(project, user, branch_name: custom_source_branch, **service_params) }
|
||||
|
||||
before do
|
||||
project.add_developer(user)
|
||||
|
|
12
yarn.lock
12
yarn.lock
|
@ -2501,7 +2501,7 @@ chardet@^0.5.0:
|
|||
resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.5.0.tgz#fe3ac73c00c3d865ffcc02a0682e2c20b6a06029"
|
||||
integrity sha512-9ZTaoBaePSCFvNlNGrsyI8ZVACP2svUtq0DkM7t4K2ClAa96sqOIRjAzDTc8zXzFt1cZR46rRzLTiHFSJ+Qw0g==
|
||||
|
||||
"charenc@>= 0.0.1", charenc@~0.0.1:
|
||||
charenc@~0.0.1:
|
||||
version "0.0.2"
|
||||
resolved "https://registry.yarnpkg.com/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667"
|
||||
integrity sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc=
|
||||
|
@ -3114,7 +3114,7 @@ cross-spawn@^5.0.1:
|
|||
shebang-command "^1.2.0"
|
||||
which "^1.2.9"
|
||||
|
||||
"crypt@>= 0.0.1", crypt@~0.0.1:
|
||||
crypt@~0.0.1:
|
||||
version "0.0.2"
|
||||
resolved "https://registry.yarnpkg.com/crypt/-/crypt-0.0.2.tgz#88d7ff7ec0dfb86f713dc87bbb42d044d3e6c41b"
|
||||
integrity sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs=
|
||||
|
@ -10136,14 +10136,6 @@ sha.js@^2.4.0, sha.js@^2.4.8:
|
|||
inherits "^2.0.1"
|
||||
safe-buffer "^5.0.1"
|
||||
|
||||
sha1@^1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/sha1/-/sha1-1.1.1.tgz#addaa7a93168f393f19eb2b15091618e2700f848"
|
||||
integrity sha1-rdqnqTFo85PxnrKxUJFhjicA+Eg=
|
||||
dependencies:
|
||||
charenc ">= 0.0.1"
|
||||
crypt ">= 0.0.1"
|
||||
|
||||
shallow-clone@^3.0.0:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/shallow-clone/-/shallow-clone-3.0.1.tgz#8f2981ad92531f55035b01fb230769a40e02efa3"
|
||||
|
|
Loading…
Reference in a new issue