diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-04-20 00:09:27 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-04-20 00:09:27 +0300 |
commit | c9bef85d79791d41292d2f0727eb362034ebba1e (patch) | |
tree | cb35ec5eb6a83c5d311c8b61ea213450972d8026 | |
parent | 6463521e08b00e62d3c877aefd8517f5387d54ab (diff) |
Add latest changes from gitlab-org/gitlab@master
155 files changed, 1107 insertions, 344 deletions
diff --git a/.gitlab/issue_templates/Feature Flag Roll Out.md b/.gitlab/issue_templates/Feature Flag Roll Out.md index 6575e919b7d..a67d0f4e31a 100644 --- a/.gitlab/issue_templates/Feature Flag Roll Out.md +++ b/.gitlab/issue_templates/Feature Flag Roll Out.md @@ -26,13 +26,10 @@ Are there any other stages or teams involved that need to be kept in the loop? ## The Rollout Plan -<!-- Describe how the feature should be rolled out, and check the right boxes. You can check multiple if applicable --> - -- [ ] Partial Rollout on GitLab.com with beta groups -- [ ] Rollout on GitLab.com for a certain period (How long) -- [ ] Percentage Rollout on GitLab.com - XX% - If it is possible to perform an incremental rollout, this should be preferred. Proposed increments are: `10%`, `50%`, `100%`. Proposed minimum time between increments is 15 minutes. -- [ ] Rollout Feature for everyone as soon as it's ready +- Partial Rollout on GitLab.com with beta groups +- Rollout on GitLab.com for a certain period (How long) +- Percentage Rollout on GitLab.com +- Rollout Feature for everyone as soon as it's ready <!-- Which dashboards from https://dashboards.gitlab.net are most relevant? Sentry errors reports can also be useful to review --> @@ -78,21 +75,13 @@ Are there any other stages or teams involved that need to be kept in the loop? - [ ] Verify behaviour (See Beta Groups) and add details with screenshots as a comment on this issue - -**Global Availability** ([More Info](https://docs.gitlab.com/ee/development/feature_flags/controls.html#communicate-the-change)) -*(Please Note that Beta,Alpha and General Availability (GA) are handled on a product level and not the feature-flag)* -<!-- The next checkboxes are probably only needed for high visibility and/or critical rollouts. Please refer to the official documentation linked above for more clarification --> - -- [ ] Coordinate a time to enable the flag with `#production` and `#g_delivery` on slack. - -- [ ] Announce on the issue an estimated time this will be enabled on GitLab.com +- [ ] If it is possible to perform an incremental rollout, this should be preferred. Proposed increments are: `10%`, `50%`, `100%`. Proposed minimum time between increments is 15 minutes. + - When setting percentages, make sure that the feature works correctly between feature checks. See https://gitlab.com/gitlab-org/gitlab/-/issues/327117 for more information + - For actor-based rollout: `/chatops run feature set feature_name 10 --actors` + - For time-based rollout: `/chatops run feature set feature_name 10` - [ ] Make the feature flag enabled by default i.e. Change `default_enabled` to `true` -- [ ] Enable on GitLab.com by running chatops command in `#production` (`/chatops run feature set feature_name true`) - -- [ ] Announce on the issue that the flag has been enabled - - [ ] Cross post chatops slack command to `#support_gitlab-com` ([more guidance when this is necessary in the dev docs](https://docs.gitlab.com/ee/development/feature_flags/controls.html#where-to-run-commands)) and in your team channel diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 22f261ab347..4bd885c35d2 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -845,11 +845,6 @@ Style/Next: Style/NumericLiteralPrefix: Enabled: false -# Offense count: 140 -# Cop supports --auto-correct. -Style/ParallelAssignment: - Enabled: false - # Offense count: 2698 # Cop supports --auto-correct. # Configuration parameters: PreferredDelimiters. diff --git a/GITALY_SERVER_VERSION b/GITALY_SERVER_VERSION index 59eda4e677d..1963fca425f 100644 --- a/GITALY_SERVER_VERSION +++ b/GITALY_SERVER_VERSION @@ -1 +1 @@ -f5c607b1ea9a59c35ae47b6b03bdf98ea183a379 +0f93ceb8a8ccfe38ee3fde399efcb49aa91cbedd diff --git a/app/controllers/clusters/clusters_controller.rb b/app/controllers/clusters/clusters_controller.rb index cdb26b0ea4f..c64301f72ba 100644 --- a/app/controllers/clusters/clusters_controller.rb +++ b/app/controllers/clusters/clusters_controller.rb @@ -308,7 +308,8 @@ class Clusters::ClustersController < Clusters::BaseController def proxy_variable_substitution_service @empty_service ||= Class.new(BaseService) do def initialize(proxyable, params) - @proxyable, @params = proxyable, params + @proxyable = proxyable + @params = params end def execute diff --git a/app/controllers/projects/commits_controller.rb b/app/controllers/projects/commits_controller.rb index 2ced72aab7e..9ca917841e9 100644 --- a/app/controllers/projects/commits_controller.rb +++ b/app/controllers/projects/commits_controller.rb @@ -63,7 +63,8 @@ class Projects::CommitsController < Projects::ApplicationController def set_commits render_404 unless @path.empty? || request.format == :atom || @repository.blob_at(@commit.id, @path) || @repository.tree(@commit.id, @path).entries.present? - @limit, @offset = (params[:limit] || 40).to_i, (params[:offset] || 0).to_i + @limit = (params[:limit] || 40).to_i + @offset = (params[:offset] || 0).to_i search = params[:search] author = params[:author] diff --git a/app/finders/ci/variables_finder.rb b/app/finders/ci/variables_finder.rb index d1546b27995..39a1a60596d 100644 --- a/app/finders/ci/variables_finder.rb +++ b/app/finders/ci/variables_finder.rb @@ -3,7 +3,8 @@ module Ci class VariablesFinder def initialize(resource, params) - @resource, @params = resource, params + @resource = resource + @params = params raise ArgumentError, 'Please provide params[:key]' if params[:key].blank? end diff --git a/app/finders/environments_by_deployments_finder.rb b/app/finders/environments_by_deployments_finder.rb index 7c0fb4c5424..76e1c050ea5 100644 --- a/app/finders/environments_by_deployments_finder.rb +++ b/app/finders/environments_by_deployments_finder.rb @@ -4,7 +4,9 @@ class EnvironmentsByDeploymentsFinder attr_reader :project, :current_user, :params def initialize(project, current_user, params = {}) - @project, @current_user, @params = project, current_user, params + @project = project + @current_user = current_user + @params = params end # rubocop: disable CodeReuse/ActiveRecord diff --git a/app/finders/environments_finder.rb b/app/finders/environments_finder.rb index 688c241dfb2..c64e850f440 100644 --- a/app/finders/environments_finder.rb +++ b/app/finders/environments_finder.rb @@ -6,7 +6,9 @@ class EnvironmentsFinder InvalidStatesError = Class.new(StandardError) def initialize(project, current_user, params = {}) - @project, @current_user, @params = project, current_user, params + @project = project + @current_user = current_user + @params = params end def execute diff --git a/app/finders/metrics/dashboards/annotations_finder.rb b/app/finders/metrics/dashboards/annotations_finder.rb index c42b8bf40e5..e97704738ea 100644 --- a/app/finders/metrics/dashboards/annotations_finder.rb +++ b/app/finders/metrics/dashboards/annotations_finder.rb @@ -4,7 +4,8 @@ module Metrics module Dashboards class AnnotationsFinder def initialize(dashboard:, params:) - @dashboard, @params = dashboard, params + @dashboard = dashboard + @params = params end def execute diff --git a/app/finders/metrics/users_starred_dashboards_finder.rb b/app/finders/metrics/users_starred_dashboards_finder.rb index 7244c51f9a7..2ef706c1b11 100644 --- a/app/finders/metrics/users_starred_dashboards_finder.rb +++ b/app/finders/metrics/users_starred_dashboards_finder.rb @@ -3,7 +3,9 @@ module Metrics class UsersStarredDashboardsFinder def initialize(user:, project:, params: {}) - @user, @project, @params = user, project, params + @user = user + @project = project + @params = params end def execute diff --git a/app/finders/packages/debian/distributions_finder.rb b/app/finders/packages/debian/distributions_finder.rb index 98afc918fb1..a5ac9f7e2f7 100644 --- a/app/finders/packages/debian/distributions_finder.rb +++ b/app/finders/packages/debian/distributions_finder.rb @@ -4,7 +4,8 @@ module Packages module Debian class DistributionsFinder def initialize(container, params = {}) - @container, @params = container, params + @container = container + @params = params end def execute diff --git a/app/graphql/gitlab_schema.rb b/app/graphql/gitlab_schema.rb index 76ac29fedeb..8369d0e120f 100644 --- a/app/graphql/gitlab_schema.rb +++ b/app/graphql/gitlab_schema.rb @@ -111,6 +111,7 @@ class GitlabSchema < GraphQL::Schema # # Options: # * :expected_type [Class] - the type of object this GlobalID should refer to. + # * :expected_type [[Class]] - array of the types of object this GlobalID should refer to. # # e.g. # @@ -120,14 +121,14 @@ class GitlabSchema < GraphQL::Schema # gid.model_class == ::Project # ``` def parse_gid(global_id, ctx = {}) - expected_type = ctx[:expected_type] + expected_types = Array(ctx[:expected_type]) gid = GlobalID.parse(global_id) raise Gitlab::Graphql::Errors::ArgumentError, "#{global_id} is not a valid GitLab ID." unless gid - if expected_type && gid.model_class.ancestors.exclude?(expected_type) - vars = { global_id: global_id, expected_type: expected_type } - msg = _('%{global_id} is not a valid ID for %{expected_type}.') % vars + if expected_types.any? && expected_types.none? { |type| gid.model_class.ancestors.include?(type) } + vars = { global_id: global_id, expected_types: expected_types.join(', ') } + msg = _('%{global_id} is not a valid ID for %{expected_types}.') % vars raise Gitlab::Graphql::Errors::ArgumentError, msg end diff --git a/app/graphql/resolvers/alert_management/http_integrations_resolver.rb b/app/graphql/resolvers/alert_management/http_integrations_resolver.rb index fb6682f8d7e..abc54614a59 100644 --- a/app/graphql/resolvers/alert_management/http_integrations_resolver.rb +++ b/app/graphql/resolvers/alert_management/http_integrations_resolver.rb @@ -3,19 +3,39 @@ module Resolvers module AlertManagement class HttpIntegrationsResolver < BaseResolver + include ::Gitlab::Graphql::Laziness + alias_method :project, :object + argument :id, Types::GlobalIDType[::AlertManagement::HttpIntegration], + required: false, + description: 'ID of the integration.' + type Types::AlertManagement::HttpIntegrationType.connection_type, null: true - def resolve(**args) - http_integrations + def resolve(id: nil) + return [] unless Ability.allowed?(current_user, :admin_operations, project) + + if id + integrations_by(gid: id) + else + http_integrations + end end private - def http_integrations - return [] unless Ability.allowed?(current_user, :admin_operations, project) + def integrations_by(gid:) + id = Types::GlobalIDType[::AlertManagement::HttpIntegration].coerce_isolated_input(gid) + object = GitlabSchema.find_by_gid(id) + + defer { object }.then do |integration| + ret = integration if project == integration&.project + Array.wrap(ret) + end + end + def http_integrations ::AlertManagement::HttpIntegrationsFinder.new(project, {}).execute end end diff --git a/app/graphql/resolvers/alert_management/integrations_resolver.rb b/app/graphql/resolvers/alert_management/integrations_resolver.rb index e027e0412bd..cb7e73c2d1a 100644 --- a/app/graphql/resolvers/alert_management/integrations_resolver.rb +++ b/app/graphql/resolvers/alert_management/integrations_resolver.rb @@ -3,27 +3,60 @@ module Resolvers module AlertManagement class IntegrationsResolver < BaseResolver + include ::Gitlab::Graphql::Laziness + alias_method :project, :object + argument :id, ::Types::GlobalIDType, + required: false, + description: 'ID of the integration.' + type Types::AlertManagement::IntegrationType.connection_type, null: true - def resolve(**args) - http_integrations + prometheus_integrations + def resolve(id: nil) + if id + integrations_by(gid: id) + else + http_integrations + prometheus_integrations + end end private + def integrations_by(gid:) + object = GitlabSchema.object_from_id(gid, expected_type: expected_integration_types) + defer { object }.then do |integration| + ret = integration if project == integration&.project + Array.wrap(ret) + end + end + def prometheus_integrations - return [] unless Ability.allowed?(current_user, :admin_project, project) + return [] unless prometheus_integrations_allowed? Array(project.prometheus_service) end def http_integrations - return [] unless Ability.allowed?(current_user, :admin_operations, project) + return [] unless http_integrations_allowed? ::AlertManagement::HttpIntegrationsFinder.new(project, {}).execute end + + def prometheus_integrations_allowed? + Ability.allowed?(current_user, :admin_project, project) + end + + def http_integrations_allowed? + Ability.allowed?(current_user, :admin_operations, project) + end + + def expected_integration_types + [].tap do |types| + types << ::AlertManagement::HttpIntegration if http_integrations_allowed? + types << ::PrometheusService if prometheus_integrations_allowed? + end + end end end end diff --git a/app/helpers/submodule_helper.rb b/app/helpers/submodule_helper.rb index 959178c47d7..f1e0be3a622 100644 --- a/app/helpers/submodule_helper.rb +++ b/app/helpers/submodule_helper.rb @@ -18,7 +18,8 @@ module SubmoduleHelper end if url =~ %r{([^/:]+)/([^/]+(?:\.git)?)\Z} - namespace, project = Regexp.last_match(1), Regexp.last_match(2) + namespace = Regexp.last_match(1) + project = Regexp.last_match(2) gitlab_hosts = [Gitlab.config.gitlab.url, Gitlab.config.gitlab_shell.ssh_path_prefix] diff --git a/app/models/ability.rb b/app/models/ability.rb index 514e923c380..ba46a98b951 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -58,7 +58,8 @@ class Ability def allowed?(user, action, subject = :global, opts = {}) if subject.is_a?(Hash) - opts, subject = subject, :global + opts = subject + subject = :global end policy = policy_for(user, subject) diff --git a/app/models/application_setting_implementation.rb b/app/models/application_setting_implementation.rb index e67d261d3b4..66a8d1f8105 100644 --- a/app/models/application_setting_implementation.rb +++ b/app/models/application_setting_implementation.rb @@ -438,11 +438,14 @@ module ApplicationSettingImplementation def parse_addr_and_port(str) case str when /\A\[(?<address> .* )\]:(?<port> \d+ )\z/x # string like "[::1]:80" - address, port = $~[:address], $~[:port] + address = $~[:address] + port = $~[:port] when /\A(?<address> [^:]+ ):(?<port> \d+ )\z/x # string like "127.0.0.1:80" - address, port = $~[:address], $~[:port] + address = $~[:address] + port = $~[:port] else # string with no port number - address, port = str, nil + address = str + port = nil end [address, port&.to_i] diff --git a/app/models/commit.rb b/app/models/commit.rb index 9d3b89c5996..5c3e3685c64 100644 --- a/app/models/commit.rb +++ b/app/models/commit.rb @@ -62,7 +62,8 @@ class Commit collection.sort do |a, b| operands = [a, b].tap { |o| o.reverse! if sort == 'desc' } - attr1, attr2 = operands.first.public_send(order_by), operands.second.public_send(order_by) # rubocop:disable GitlabSecurity/PublicSend + attr1 = operands.first.public_send(order_by) # rubocop:disable GitlabSecurity/PublicSend + attr2 = operands.second.public_send(order_by) # rubocop:disable GitlabSecurity/PublicSend # use case insensitive comparison for string values order_by.in?(%w[email name]) ? attr1.casecmp(attr2) : attr1 <=> attr2 diff --git a/app/models/concerns/taskable.rb b/app/models/concerns/taskable.rb index 5debfa6f834..d8867177059 100644 --- a/app/models/concerns/taskable.rb +++ b/app/models/concerns/taskable.rb @@ -30,7 +30,8 @@ module Taskable end def self.get_updated_tasks(old_content:, new_content:) - old_tasks, new_tasks = get_tasks(old_content), get_tasks(new_content) + old_tasks = get_tasks(old_content) + new_tasks = get_tasks(new_content) new_tasks.select.with_index do |new_task, i| old_task = old_tasks[i] diff --git a/app/models/design_management/design_action.rb b/app/models/design_management/design_action.rb index 22baa916296..43dcce545d2 100644 --- a/app/models/design_management/design_action.rb +++ b/app/models/design_management/design_action.rb @@ -29,7 +29,9 @@ module DesignManagement # - design [DesignManagement::Design]: the design that was changed # - action [Symbol]: the action that gitaly performed def initialize(design, action, content = nil) - @design, @action, @content = design, action, content + @design = design + @action = action + @content = content validate! end diff --git a/app/models/design_management/design_at_version.rb b/app/models/design_management/design_at_version.rb index 211211144f4..2f045358914 100644 --- a/app/models/design_management/design_at_version.rb +++ b/app/models/design_management/design_at_version.rb @@ -18,7 +18,8 @@ module DesignManagement validate :design_and_version_have_issue_id def initialize(design: nil, version: nil) - @design, @version = design, version + @design = design + @version = version end # The ID, needed by GraphQL types and as part of the Lazy-fetch diff --git a/app/models/design_management/version.rb b/app/models/design_management/version.rb index 49aec8b9720..5cfd8f3ec8e 100644 --- a/app/models/design_management/version.rb +++ b/app/models/design_management/version.rb @@ -14,7 +14,9 @@ module DesignManagement attr_reader :sha, :issue_id, :actions def initialize(sha, issue_id, actions) - @sha, @issue_id, @actions = sha, issue_id, actions + @sha = sha + @issue_id = issue_id + @actions = actions end def message diff --git a/app/models/external_issue.rb b/app/models/external_issue.rb index 68b2353556e..36030b80370 100644 --- a/app/models/external_issue.rb +++ b/app/models/external_issue.rb @@ -6,7 +6,8 @@ class ExternalIssue attr_reader :project def initialize(issue_identifier, project) - @issue_identifier, @project = issue_identifier, project + @issue_identifier = issue_identifier + @project = project end def to_s diff --git a/app/models/member.rb b/app/models/member.rb index ae9f6cb9eca..e978552592d 100644 --- a/app/models/member.rb +++ b/app/models/member.rb @@ -291,7 +291,9 @@ class Member < ApplicationRecord private def parse_users_list(source, list) - emails, user_ids, users = [], [], [] + emails = [] + user_ids = [] + users = [] existing_members = {} list.each do |item| diff --git a/app/models/preloaders/labels_preloader.rb b/app/models/preloaders/labels_preloader.rb index aad51748e65..427f2869aac 100644 --- a/app/models/preloaders/labels_preloader.rb +++ b/app/models/preloaders/labels_preloader.rb @@ -13,7 +13,9 @@ module Preloaders attr_reader :labels, :user, :project def initialize(labels, user, project = nil) - @labels, @user, @project = labels, user, project + @labels = labels + @user = user + @project = project end def preload_all diff --git a/app/models/project_services/external_wiki_service.rb b/app/models/project_services/external_wiki_service.rb index 7dd5b1fb00f..c41783d1af4 100644 --- a/app/models/project_services/external_wiki_service.rb +++ b/app/models/project_services/external_wiki_service.rb @@ -1,8 +1,8 @@ # frozen_string_literal: true class ExternalWikiService < Service + include ActionView::Helpers::UrlHelper prop_accessor :external_wiki_url - validates :external_wiki_url, presence: true, public_url: true, if: :activated? def title @@ -10,7 +10,7 @@ class ExternalWikiService < Service end def description - s_('ExternalWikiService|Replaces the link to the internal wiki with a link to an external wiki.') + s_('ExternalWikiService|Link to an external wiki from the sidebar.') end def self.to_param @@ -23,12 +23,19 @@ class ExternalWikiService < Service type: 'text', name: 'external_wiki_url', title: s_('ExternalWikiService|External wiki URL'), - placeholder: s_('ExternalWikiService|The URL of the external wiki'), + placeholder: s_('ExternalWikiService|https://example.com/xxx/wiki/...'), + help: 'Enter the URL to the external wiki.', required: true } ] end + def help + docs_link = link_to _('Learn more.'), Rails.application.routes.url_helpers.help_page_url('user/project/wiki/index', anchor: 'link-an-external-wiki'), target: '_blank', rel: 'noopener noreferrer' + + s_('Link an external wiki from the project\'s sidebar. %{docs_link}').html_safe % { docs_link: docs_link.html_safe } + end + def execute(_data) response = Gitlab::HTTP.get(properties['external_wiki_url'], verify: true) response.body if response.code == 200 diff --git a/app/services/application_settings/base_service.rb b/app/services/application_settings/base_service.rb index ebe067536ca..0929b30b7e9 100644 --- a/app/services/application_settings/base_service.rb +++ b/app/services/application_settings/base_service.rb @@ -3,7 +3,9 @@ module ApplicationSettings class BaseService < ::BaseService def initialize(application_setting, user, params = {}) - @application_setting, @current_user, @params = application_setting, user, params.dup + @application_setting = application_setting + @current_user = user + @params = params.dup end end end diff --git a/app/services/base_container_service.rb b/app/services/base_container_service.rb index 56e4b8c908c..6852237dc25 100644 --- a/app/services/base_container_service.rb +++ b/app/services/base_container_service.rb @@ -7,6 +7,8 @@ class BaseContainerService attr_reader :container, :current_user, :params def initialize(container:, current_user: nil, params: {}) - @container, @current_user, @params = container, current_user, params.dup + @container = container + @current_user = current_user + @params = params.dup end end diff --git a/app/services/base_service.rb b/app/services/base_service.rb index b4c4b6980a8..20dfeb67815 100644 --- a/app/services/base_service.rb +++ b/app/services/base_service.rb @@ -15,7 +15,9 @@ class BaseService attr_accessor :project, :current_user, :params def initialize(project, user = nil, params = {}) - @project, @current_user, @params = project, user, params.dup + @project = project + @current_user = user + @params = params.dup end delegate :repository, to: :project diff --git a/app/services/boards/base_service.rb b/app/services/boards/base_service.rb index 439a5c06223..83bb69b3822 100644 --- a/app/services/boards/base_service.rb +++ b/app/services/boards/base_service.rb @@ -6,7 +6,9 @@ module Boards attr_accessor :parent, :current_user, :params def initialize(parent, user, params = {}) - @parent, @current_user, @params = parent, user, params.dup + @parent = parent + @current_user = user + @params = params.dup end end end diff --git a/app/services/ci/create_pipeline_service.rb b/app/services/ci/create_pipeline_service.rb index 0fd47e625fd..ca936307acc 100644 --- a/app/services/ci/create_pipeline_service.rb +++ b/app/services/ci/create_pipeline_service.rb @@ -96,7 +96,8 @@ module Ci # rubocop: enable Metrics/ParameterLists def execute!(*args, &block) - source, params = args[0], Hash(args[1]) + source = args[0] + params = Hash(args[1]) execute(source, **params, &block).tap do |pipeline| unless pipeline.persisted? diff --git a/app/services/clusters/create_service.rb b/app/services/clusters/create_service.rb index 6693a58683f..cb2de8b943c 100644 --- a/app/services/clusters/create_service.rb +++ b/app/services/clusters/create_service.rb @@ -5,7 +5,8 @@ module Clusters attr_reader :current_user, :params def initialize(user = nil, params = {}) - @current_user, @params = user, params.dup + @current_user = user + @params = params.dup end def execute(access_token: nil) diff --git a/app/services/clusters/destroy_service.rb b/app/services/clusters/destroy_service.rb index a8de04683fa..371f947add7 100644 --- a/app/services/clusters/destroy_service.rb +++ b/app/services/clusters/destroy_service.rb @@ -5,7 +5,8 @@ module Clusters attr_reader :current_user, :params def initialize(user = nil, params = {}) - @current_user, @params = user, params.dup + @current_user = user + @params = params.dup @response = {} end diff --git a/app/services/clusters/update_service.rb b/app/services/clusters/update_service.rb index ba20826848d..5432d9fbca1 100644 --- a/app/services/clusters/update_service.rb +++ b/app/services/clusters/update_service.rb @@ -5,7 +5,8 @@ module Clusters attr_reader :current_user, :params def initialize(user = nil, params = {}) - @current_user, @params = user, params.dup + @current_user = user + @params = params.dup end def execute(cluster) diff --git a/app/services/draft_notes/base_service.rb b/app/services/draft_notes/base_service.rb index 95c291ea800..66f9e04ef24 100644 --- a/app/services/draft_notes/base_service.rb +++ b/app/services/draft_notes/base_service.rb @@ -5,7 +5,9 @@ module DraftNotes attr_accessor :merge_request, :current_user, :params def initialize(merge_request, current_user, params = nil) - @merge_request, @current_user, @params = merge_request, current_user, params.dup + @merge_request = merge_request + @current_user = current_user + @params = params.dup end def merge_request_activity_counter diff --git a/app/services/git/wiki_push_service.rb b/app/services/git/wiki_push_service.rb index 0905b2d98df..82958abfe6e 100644 --- a/app/services/git/wiki_push_service.rb +++ b/app/services/git/wiki_push_service.rb @@ -8,7 +8,9 @@ module Git attr_reader :wiki def initialize(wiki, current_user, params) - @wiki, @current_user, @params = wiki, current_user, params.dup + @wiki = wiki + @current_user = current_user + @params = params.dup end def execute diff --git a/app/services/git/wiki_push_service/change.rb b/app/services/git/wiki_push_service/change.rb index 3d1d0fe8c4e..9109a7f9d58 100644 --- a/app/services/git/wiki_push_service/change.rb +++ b/app/services/git/wiki_push_service/change.rb @@ -9,7 +9,9 @@ module Git # @param [Hash] change - must have keys `:oldrev` and `:newrev` # @param [Gitlab::Git::RawDiffChange] raw_change def initialize(wiki, change, raw_change) - @wiki, @raw_change, @change = wiki, raw_change, change + @wiki = wiki + @raw_change = raw_change + @change = change end def page diff --git a/app/services/groups/base_service.rb b/app/services/groups/base_service.rb index d6589970951..06136aff50e 100644 --- a/app/services/groups/base_service.rb +++ b/app/services/groups/base_service.rb @@ -5,7 +5,9 @@ module Groups attr_accessor :group, :current_user, :params def initialize(group, user, params = {}) - @group, @current_user, @params = group, user, params.dup + @group = group + @current_user = user + @params = params.dup end private diff --git a/app/services/groups/create_service.rb b/app/services/groups/create_service.rb index da9afe86e36..9ddb8ae7695 100644 --- a/app/services/groups/create_service.rb +++ b/app/services/groups/create_service.rb @@ -3,7 +3,8 @@ module Groups class CreateService < Groups::BaseService def initialize(user, params = {}) - @current_user, @params = user, params.dup + @current_user = user + @params = params.dup @chat_team = @params.delete(:create_chat_team) end diff --git a/app/services/groups/nested_create_service.rb b/app/services/groups/nested_create_service.rb index a51ac9aa593..35d45aaf0cc 100644 --- a/app/services/groups/nested_create_service.rb +++ b/app/services/groups/nested_create_service.rb @@ -5,7 +5,8 @@ module Groups attr_reader :group_path, :visibility_level def initialize(user, params) - @current_user, @params = user, params.dup + @current_user = user + @params = params.dup @group_path = @params.delete(:group_path) @visibility_level = @params.delete(:visibility_level) || Gitlab::CurrentSettings.current_application_settings.default_group_visibility diff --git a/app/services/issuable/bulk_update_service.rb b/app/services/issuable/bulk_update_service.rb index 13e289716ef..8bcbb92cd0e 100644 --- a/app/services/issuable/bulk_update_service.rb +++ b/app/services/issuable/bulk_update_service.rb @@ -7,7 +7,9 @@ module Issuable attr_accessor :parent, :current_user, :params def initialize(parent, user = nil, params = {}) - @parent, @current_user, @params = parent, user, params.dup + @parent = parent + @current_user = user + @params = params.dup end def execute(type) diff --git a/app/services/issuable_links/create_service.rb b/app/services/issuable_links/create_service.rb index 4816be566dd..cbb81f1f521 100644 --- a/app/services/issuable_links/create_service.rb +++ b/app/services/issuable_links/create_service.rb @@ -7,7 +7,9 @@ module IssuableLinks attr_reader :issuable, :current_user, :params def initialize(issuable, user, params) - @issuable, @current_user, @params = issuable, user, params.dup + @issuable = issuable + @current_user = user + @params = params.dup end def execute diff --git a/app/services/issuable_links/list_service.rb b/app/services/issuable_links/list_service.rb index 10a2da7eb03..fe9678dcc32 100644 --- a/app/services/issuable_links/list_service.rb +++ b/app/services/issuable_links/list_service.rb @@ -7,7 +7,8 @@ module IssuableLinks attr_reader :issuable, :current_user def initialize(issuable, user) - @issuable, @current_user = issuable, user + @issuable = issuable + @current_user = user end def execute diff --git a/app/services/jira_connect_subscriptions/base_service.rb b/app/services/jira_connect_subscriptions/base_service.rb index 0e5bb91660e..042169acb6f 100644 --- a/app/services/jira_connect_subscriptions/base_service.rb +++ b/app/services/jira_connect_subscriptions/base_service.rb @@ -5,7 +5,9 @@ module JiraConnectSubscriptions attr_accessor :jira_connect_installation, :current_user, :params def initialize(jira_connect_installation, user = nil, params = {}) - @jira_connect_installation, @current_user, @params = jira_connect_installation, user, params.dup + @jira_connect_installation = jira_connect_installation + @current_user = user + @params = params.dup end end end diff --git a/app/services/keys/base_service.rb b/app/services/keys/base_service.rb index 113e22b01ce..9b238e2f176 100644 --- a/app/services/keys/base_service.rb +++ b/app/services/keys/base_service.rb @@ -5,7 +5,8 @@ module Keys attr_accessor :user, :params def initialize(user, params = {}) - @user, @params = user, params + @user = user + @params = params @ip_address = @params.delete(:ip_address) end diff --git a/app/services/keys/create_service.rb b/app/services/keys/create_service.rb index c256de7b35d..c1c3ef8792f 100644 --- a/app/services/keys/create_service.rb +++ b/app/services/keys/create_service.rb @@ -5,7 +5,8 @@ module Keys attr_accessor :current_user def initialize(current_user, params = {}) - @current_user, @params = current_user, params + @current_user = current_user + @params = params @ip_address = @params.delete(:ip_address) @user = params.delete(:user) || current_user end diff --git a/app/services/mattermost/create_team_service.rb b/app/services/mattermost/create_team_service.rb index afcd6439a14..2cbcaaad5e1 100644 --- a/app/services/mattermost/create_team_service.rb +++ b/app/services/mattermost/create_team_service.rb @@ -3,7 +3,8 @@ module Mattermost class CreateTeamService < ::BaseService def initialize(group, current_user) - @group, @current_user = group, current_user + @group = group + @current_user = current_user end def execute diff --git a/app/services/metrics/dashboard/annotations/create_service.rb b/app/services/metrics/dashboard/annotations/create_service.rb index c04f4c56b51..54f4e96378c 100644 --- a/app/services/metrics/dashboard/annotations/create_service.rb +++ b/app/services/metrics/dashboard/annotations/create_service.rb @@ -13,7 +13,8 @@ module Metrics :create def initialize(user, params) - @user, @params = user, params + @user = user + @params = params end def execute diff --git a/app/services/metrics/dashboard/annotations/delete_service.rb b/app/services/metrics/dashboard/annotations/delete_service.rb index c6a6c4f5fbf..3efe6924a9b 100644 --- a/app/services/metrics/dashboard/annotations/delete_service.rb +++ b/app/services/metrics/dashboard/annotations/delete_service.rb @@ -11,7 +11,8 @@ module Metrics :delete def initialize(user, annotation) - @user, @annotation = user, annotation + @user = user + @annotation = annotation end def execute diff --git a/app/services/metrics/dashboard/grafana_metric_embed_service.rb b/app/services/metrics/dashboard/grafana_metric_embed_service.rb index b8c5c17c738..6069d236e82 100644 --- a/app/services/metrics/dashboard/grafana_metric_embed_service.rb +++ b/app/services/metrics/dashboard/grafana_metric_embed_service.rb @@ -122,7 +122,8 @@ module Metrics # Identifies the uid of the dashboard based on url format class GrafanaUidParser def initialize(grafana_url, project) - @grafana_url, @project = grafana_url, project + @grafana_url = grafana_url + @project = project end def parse @@ -145,7 +146,8 @@ module Metrics # If no panel is specified, defaults to the first valid panel. class DatasourceNameParser def initialize(grafana_url, grafana_dashboard) - @grafana_url, @grafana_dashboard = grafana_url, grafana_dashboard + @grafana_url = grafana_url + @grafana_dashboard = grafana_dashboard end def parse diff --git a/app/services/metrics/dashboard/panel_preview_service.rb b/app/services/metrics/dashboard/panel_preview_service.rb index 5b24d817fb6..02dd908e229 100644 --- a/app/services/metrics/dashboard/panel_preview_service.rb +++ b/app/services/metrics/dashboard/panel_preview_service.rb @@ -22,7 +22,9 @@ module Metrics ].freeze def initialize(project, panel_yaml, environment) - @project, @panel_yaml, @environment = project, panel_yaml, environment + @project = project + @panel_yaml = panel_yaml + @environment = environment end def execute diff --git a/app/services/metrics/users_starred_dashboards/create_service.rb b/app/services/metrics/users_starred_dashboards/create_service.rb index 7784ed4eb4e..9642df87861 100644 --- a/app/services/metrics/users_starred_dashboards/create_service.rb +++ b/app/services/metrics/users_starred_dashboards/create_service.rb @@ -11,7 +11,9 @@ module Metrics :create def initialize(user, project, dashboard_path) - @user, @project, @dashboard_path = user, project, dashboard_path + @user = user + @project = project + @dashboard_path = dashboard_path end def execute diff --git a/app/services/metrics/users_starred_dashboards/delete_service.rb b/app/services/metrics/users_starred_dashboards/delete_service.rb index 579715bd49f..229c0e8cfc0 100644 --- a/app/services/metrics/users_starred_dashboards/delete_service.rb +++ b/app/services/metrics/users_starred_dashboards/delete_service.rb @@ -5,7 +5,9 @@ module Metrics module UsersStarredDashboards class DeleteService < ::BaseService def initialize(user, project, dashboard_path = nil) - @user, @project, @dashboard_path = user, project, dashboard_path + @user = user + @project = project + @dashboard_path = dashboard_path end def execute diff --git a/app/services/milestones/base_service.rb b/app/services/milestones/base_service.rb index f30194c0bfe..0d7d855bf5e 100644 --- a/app/services/milestones/base_service.rb +++ b/app/services/milestones/base_service.rb @@ -6,7 +6,9 @@ module Milestones attr_accessor :parent, :current_user, :params def initialize(parent, user, params = {}) - @parent, @current_user, @params = parent, user, params.dup + @parent = parent + @current_user = user + @params = params.dup super end end diff --git a/app/services/milestones/find_or_create_service.rb b/app/services/milestones/find_or_create_service.rb index 881011e5106..b467ff98f54 100644 --- a/app/services/milestones/find_or_create_service.rb +++ b/app/services/milestones/find_or_create_service.rb @@ -5,7 +5,9 @@ module Milestones attr_accessor :project, :current_user, :params def initialize(project, user, params = {}) - @project, @current_user, @params = project, user, params.dup + @project = project + @current_user = user + @params = params.dup end def execute diff --git a/app/services/notification_recipients/builder/request_review.rb b/app/services/notification_recipients/builder/request_review.rb index 911d89c6a8e..8dd0c5d1587 100644 --- a/app/services/notification_recipients/builder/request_review.rb +++ b/app/services/notification_recipients/builder/request_review.rb @@ -6,7 +6,9 @@ module NotificationRecipients attr_reader :merge_request, :current_user, :reviewer def initialize(merge_request, current_user, reviewer) - @merge_request, @current_user, @reviewer = merge_request, current_user, reviewer + @merge_request = merge_request + @current_user = current_user + @reviewer = reviewer end def target diff --git a/app/services/packages/composer/composer_json_service.rb b/app/services/packages/composer/composer_json_service.rb index 98aabd84d3d..f346b654c59 100644 --- a/app/services/packages/composer/composer_json_service.rb +++ b/app/services/packages/composer/composer_json_service.rb @@ -6,7 +6,8 @@ module Packages InvalidJson = Class.new(StandardError) def initialize(project, target) - @project, @target = project, target + @project = project + @target = target end def execute diff --git a/app/services/packages/composer/version_parser_service.rb b/app/services/packages/composer/version_parser_service.rb index 811cac0b3b7..36275d1b680 100644 --- a/app/services/packages/composer/version_parser_service.rb +++ b/app/services/packages/composer/version_parser_service.rb @@ -4,7 +4,8 @@ module Packages module Composer class VersionParserService def initialize(tag_name: nil, branch_name: nil) - @tag_name, @branch_name = tag_name, branch_name + @tag_name = tag_name + @branch_name = branch_name end def execute diff --git a/app/services/packages/debian/create_distribution_service.rb b/app/services/packages/debian/create_distribution_service.rb index c6df033e3c1..f947d2e4293 100644 --- a/app/services/packages/debian/create_distribution_service.rb +++ b/app/services/packages/debian/create_distribution_service.rb @@ -4,7 +4,8 @@ module Packages module Debian class CreateDistributionService def initialize(container, user, params) - @container, @params = container, params + @container = container + @params = params @params[:creator] = user @components = params.delete(:components) || ['main'] diff --git a/app/services/packages/debian/process_changes_service.rb b/app/services/packages/debian/process_changes_service.rb index bf42cb78d39..881ad2c46f4 100644 --- a/app/services/packages/debian/process_changes_service.rb +++ b/app/services/packages/debian/process_changes_service.rb @@ -10,7 +10,8 @@ module Packages DEFAULT_LEASE_TIMEOUT = 1.hour.to_i.freeze def initialize(package_file, creator) - @package_file, @creator = package_file, creator + @package_file = package_file + @creator = creator end def execute diff --git a/app/services/packages/debian/update_distribution_service.rb b/app/services/packages/debian/update_distribution_service.rb index 5bb59b854e9..95face912d5 100644 --- a/app/services/packages/debian/update_distribution_service.rb +++ b/app/services/packages/debian/update_distribution_service.rb @@ -4,7 +4,8 @@ module Packages module Debian class UpdateDistributionService def initialize(distribution, params) - @distribution, @params = distribution, params + @distribution = distribution + @params = params @components = params.delete(:components) diff --git a/app/services/packages/maven/find_or_create_package_service.rb b/app/services/packages/maven/find_or_create_package_service.rb index 401e52f7e51..a6cffa3038c 100644 --- a/app/services/packages/maven/find_or_create_package_service.rb +++ b/app/services/packages/maven/find_or_create_package_service.rb @@ -33,7 +33,8 @@ module Packages # # The first upload has to create the proper package (the one with the version set). if params[:file_name] == Packages::Maven::Metadata.filename && !params[:path]&.ends_with?(SNAPSHOT_TERM) - package_name, version = params[:path], nil + package_name = params[:path] + version = nil else package_name, _, version = params[:path].rpartition('/') end diff --git a/app/services/projects/branches_by_mode_service.rb b/app/services/projects/branches_by_mode_service.rb index fb66bfa073b..dbdcef066f4 100644 --- a/app/services/projects/branches_by_mode_service.rb +++ b/app/services/projects/branches_by_mode_service.rb @@ -71,7 +71,8 @@ class Projects::BranchesByModeService # And increase it whenever we go to the next page previous_offset = params[:offset].to_i - previous_path, next_path = nil, nil + previous_path = nil + next_path = nil return [branches, previous_path, next_path] if branches.blank? diff --git a/app/services/projects/create_from_template_service.rb b/app/services/projects/create_from_template_service.rb index 45b52a1861c..3c66ff709c9 100644 --- a/app/services/projects/create_from_template_service.rb +++ b/app/services/projects/create_from_template_service.rb @@ -7,7 +7,8 @@ module Projects attr_reader :template_name def initialize(user, params) - @current_user, @params = user, params.to_h.dup + @current_user = user + @params = params.to_h.dup @template_name = @params.delete(:template_name).presence end diff --git a/app/services/projects/create_service.rb b/app/services/projects/create_service.rb index 6478398301d..5fb0bda912e 100644 --- a/app/services/projects/create_service.rb +++ b/app/services/projects/create_service.rb @@ -5,11 +5,12 @@ module Projects include ValidatesClassificationLabel def initialize(user, params) - @current_user, @params = user, params.dup - @skip_wiki = @params.delete(:skip_wiki) + @current_user = user + @params = params.dup + @skip_wiki = @params.delete(:skip_wiki) @initialize_with_readme = Gitlab::Utils.to_boolean(@params.delete(:initialize_with_readme)) - @import_data = @params.delete(:import_data) - @relations_block = @params.delete(:relations_block) + @import_data = @params.delete(:import_data) + @relations_block = @params.delete(:relations_block) end def execute diff --git a/app/services/projects/download_service.rb b/app/services/projects/download_service.rb index 9810db84605..72cb3997045 100644 --- a/app/services/projects/download_service.rb +++ b/app/services/projects/download_service.rb @@ -7,7 +7,8 @@ module Projects ].freeze def initialize(project, url) - @project, @url = project, url + @project = project + @url = url end def execute diff --git a/app/services/projects/gitlab_projects_import_service.rb b/app/services/projects/gitlab_projects_import_service.rb index 27cce15f97d..38f0e2f7c1a 100644 --- a/app/services/projects/gitlab_projects_import_service.rb +++ b/app/services/projects/gitlab_projects_import_service.rb @@ -11,7 +11,9 @@ module Projects attr_reader :current_user, :params def initialize(user, import_params, override_params = nil) - @current_user, @params, @override_params = user, import_params.dup, override_params + @current_user = user + @params = import_params.dup + @override_params = override_params end def execute diff --git a/app/services/projects/update_pages_service.rb b/app/services/projects/update_pages_service.rb index 5e092e887e1..6fa42b293c5 100644 --- a/app/services/projects/update_pages_service.rb +++ b/app/services/projects/update_pages_service.rb @@ -23,7 +23,8 @@ module Projects attr_reader :build def initialize(project, build) - @project, @build = project, build + @project = project + @build = build end def execute diff --git a/app/services/prometheus/proxy_variable_substitution_service.rb b/app/services/prometheus/proxy_variable_substitution_service.rb index 820b551c30a..846dfeb33ce 100644 --- a/app/services/prometheus/proxy_variable_substitution_service.rb +++ b/app/services/prometheus/proxy_variable_substitution_service.rb @@ -41,7 +41,8 @@ module Prometheus # } # }) def initialize(environment, params = {}) - @environment, @params = environment, params.deep_dup + @environment = environment + @params = params.deep_dup end # @return - params [Hash<Symbol,Any>] Returns a Hash containing a params key which is diff --git a/app/services/releases/base_service.rb b/app/services/releases/base_service.rb index d0e1577bd8d..de7c97b3518 100644 --- a/app/services/releases/base_service.rb +++ b/app/services/releases/base_service.rb @@ -8,7 +8,9 @@ module Releases attr_accessor :project, :current_user, :params def initialize(project, user = nil, params = {}) - @project, @current_user, @params = project, user, params.dup + @project = project + @current_user = user + @params = params.dup end def tag_name diff --git a/app/services/resource_events/change_labels_service.rb b/app/services/resource_events/change_labels_service.rb index ddf3b05ac10..89eb90e9360 100644 --- a/app/services/resource_events/change_labels_service.rb +++ b/app/services/resource_events/change_labels_service.rb @@ -5,7 +5,8 @@ module ResourceEvents attr_reader :resource, :user def initialize(resource, user) - @resource, @user = resource, user + @resource = resource + @user = user end def execute(added_labels: [], removed_labels: []) diff --git a/app/services/resource_events/change_state_service.rb b/app/services/resource_events/change_state_service.rb index c5120ba82e1..d68b86a1513 100644 --- a/app/services/resource_events/change_state_service.rb +++ b/app/services/resource_events/change_state_service.rb @@ -5,7 +5,8 @@ module ResourceEvents attr_reader :resource, :user def initialize(user:, resource:) - @user, @resource = user, resource + @user = user + @resource = resource end def execute(params) diff --git a/app/services/search/global_service.rb b/app/services/search/global_service.rb index 9038650adb7..055034d87a1 100644 --- a/app/services/search/global_service.rb +++ b/app/services/search/global_service.rb @@ -9,7 +9,8 @@ module Search attr_accessor :current_user, :params def initialize(user, params) - @current_user, @params = user, params.dup + @current_user = user + @params = params.dup end def execute diff --git a/app/services/search/project_service.rb b/app/services/search/project_service.rb index e5fc5a7a438..4227dfe2fac 100644 --- a/app/services/search/project_service.rb +++ b/app/services/search/project_service.rb @@ -9,7 +9,9 @@ module Search attr_accessor :project, :current_user, :params def initialize(project, user, params) - @project, @current_user, @params = project, user, params.dup + @project = project + @current_user = user + @params = params.dup end def execute diff --git a/app/services/task_list_toggle_service.rb b/app/services/task_list_toggle_service.rb index f6602a35033..32cfa198ce8 100644 --- a/app/services/task_list_toggle_service.rb +++ b/app/services/task_list_toggle_service.rb @@ -9,9 +9,11 @@ class TaskListToggleService attr_reader :updated_markdown, :updated_markdown_html def initialize(markdown, markdown_html, line_source:, line_number:, toggle_as_checked:) - @markdown, @markdown_html = markdown, markdown_html - @line_source, @line_number = line_source, line_number - @toggle_as_checked = toggle_as_checked + @markdown = markdown + @markdown_html = markdown_html + @line_source = line_source + @line_number = line_number + @toggle_as_checked = toggle_as_checked @updated_markdown, @updated_markdown_html = nil end diff --git a/app/services/two_factor/base_service.rb b/app/services/two_factor/base_service.rb index 7d3f63f3442..0957d7ebabd 100644 --- a/app/services/two_factor/base_service.rb +++ b/app/services/two_factor/base_service.rb @@ -7,7 +7,8 @@ module TwoFactor attr_reader :current_user, :params, :user def initialize(current_user, params = {}) - @current_user, @params = current_user, params + @current_user = current_user + @params = params @user = params.delete(:user) end end diff --git a/app/services/upload_service.rb b/app/services/upload_service.rb index 2bf4fcd90a0..39d1ffa4d6b 100644 --- a/app/services/upload_service.rb +++ b/app/services/upload_service.rb @@ -5,7 +5,10 @@ class UploadService attr_accessor :override_max_attachment_size def initialize(model, file, uploader_class = FileUploader, **uploader_context) - @model, @file, @uploader_class, @uploader_context = model, file, uploader_class, uploader_context + @model = model + @file = file + @uploader_class = uploader_class + @uploader_context = uploader_context end def execute diff --git a/app/services/user_agent_detail_service.rb b/app/services/user_agent_detail_service.rb index 5cb42e879a0..9302c86d3e6 100644 --- a/app/services/user_agent_detail_service.rb +++ b/app/services/user_agent_detail_service.rb @@ -4,7 +4,8 @@ class UserAgentDetailService attr_accessor :spammable, :request def initialize(spammable, request) - @spammable, @request = spammable, request + @spammable = spammable + @request = request end def create diff --git a/app/services/users/respond_to_terms_service.rb b/app/services/users/respond_to_terms_service.rb index 254480304f9..7cdfef1489b 100644 --- a/app/services/users/respond_to_terms_service.rb +++ b/app/services/users/respond_to_terms_service.rb @@ -3,7 +3,8 @@ module Users class RespondToTermsService def initialize(user, term) - @user, @term = user, term + @user = user + @term = term end # rubocop: disable CodeReuse/ActiveRecord diff --git a/app/services/users/set_status_service.rb b/app/services/users/set_status_service.rb index a907937070f..2b4be8c833b 100644 --- a/app/services/users/set_status_service.rb +++ b/app/services/users/set_status_service.rb @@ -7,7 +7,8 @@ module Users attr_reader :current_user, :target_user, :params def initialize(current_user, params) - @current_user, @params = current_user, params.dup + @current_user = current_user + @params = params.dup @target_user = params.delete(:user) || current_user end diff --git a/app/views/devise/mailer/_confirmation_instructions_account.text.erb b/app/views/devise/mailer/_confirmation_instructions_account.text.erb index 5bccb68bbe2..e6da78e3a3d 100644 --- a/app/views/devise/mailer/_confirmation_instructions_account.text.erb +++ b/app/views/devise/mailer/_confirmation_instructions_account.text.erb @@ -1,13 +1,13 @@ <% if @resource.unconfirmed_email.present? || !@resource.created_recently? %> <%= @resource.unconfirmed_email || @resource.email %>, -Use the link below to confirm your email address. +<%= _('Use the link below to confirm your email address.') %> <% else %> <% if Gitlab.com? %> -Thanks for signing up to GitLab! +<%= _('Thanks for signing up to GitLab!') %> <% else %> -Welcome, <%= @resource.name %>! +<%= _("Welcome, %{name}!") % { name: @resource.name } %> <% end %> -To get started, use the link below to confirm your account. -<% end %> +<%= _('To get started, use the link below to confirm your account.') %> +<% end %> <%= confirmation_url(@resource, confirmation_token: @token) %> diff --git a/app/views/help/instance_configuration/_gitlab_pages.html.haml b/app/views/help/instance_configuration/_gitlab_pages.html.haml index 94c25edaf82..55f043214f6 100644 --- a/app/views/help/instance_configuration/_gitlab_pages.html.haml +++ b/app/views/help/instance_configuration/_gitlab_pages.html.haml @@ -1,35 +1,35 @@ - gitlab_pages = @instance_configuration.settings[:gitlab_pages] - content_for :table_content do - %li= link_to 'GitLab Pages', '#gitlab-pages' + %li= link_to _('GitLab Pages'), '#gitlab-pages' - content_for :settings_content do %h2#gitlab-pages - GitLab Pages + = _('GitLab Pages') %p - Below are the settings for - = succeed('.') { link_to('GitLab Pages', gitlab_pages[:url], target: '_blank') } + - link_to_gitlab_pages = link_to(_('GitLab Pages'), gitlab_pages[:url], target: '_blank') + = _('Below are the settings for %{link_to_gitlab_pages}.').html_safe % { link_to_gitlab_pages: link_to_gitlab_pages } .table-responsive %table %thead %tr - %th Setting + %th= _('Setting') %th= instance_configuration_host(@instance_configuration.settings[:host]) %tbody %tr - %td Domain Name + %td= _('Domain Name') %td %code= instance_configuration_cell_html(gitlab_pages[:host]) %tr - %td IP Address + %td= _('IP Address') %td %code= instance_configuration_cell_html(gitlab_pages[:ip_address]) %tr - %td Port + %td= _('Port') %td %code= instance_configuration_cell_html(gitlab_pages[:port]) %br %p - The maximum size of your Pages site is regulated by the artifacts maximum - size which is part of #{succeed('.') { link_to('GitLab CI', '#gitlab-ci') }} + - link_to_gitlab_ci = link_to(_('GitLab CI'), '#gitlab-ci') + = _("The maximum size of your Pages site is regulated by the artifacts maximum size which is part of %{link_to_gitlab_ci}.").html_safe % { link_to_gitlab_ci: link_to_gitlab_ci } diff --git a/app/views/shared/_issuable_meta_data.html.haml b/app/views/shared/_issuable_meta_data.html.haml index 4b006bddbf6..6c3e15cbace 100644 --- a/app/views/shared/_issuable_meta_data.html.haml +++ b/app/views/shared/_issuable_meta_data.html.haml @@ -1,6 +1,7 @@ - note_count = @issuable_meta_data[issuable.id].user_notes_count - issue_votes = @issuable_meta_data[issuable.id] -- upvotes, downvotes = issue_votes.upvotes, issue_votes.downvotes +- upvotes = issue_votes.upvotes +- downvotes = issue_votes.downvotes - issuable_path = issuable_path(issuable, anchor: 'notes') - issuable_mr = @issuable_meta_data[issuable.id].merge_requests_count diff --git a/app/workers/object_storage/migrate_uploads_worker.rb b/app/workers/object_storage/migrate_uploads_worker.rb index f489e428e8d..666bacb0188 100644 --- a/app/workers/object_storage/migrate_uploads_worker.rb +++ b/app/workers/object_storage/migrate_uploads_worker.rb @@ -16,7 +16,8 @@ module ObjectStorage attr_accessor :error def initialize(upload, error = nil) - @upload, @error = upload, error + @upload = upload + @error = error end def success? diff --git a/changelogs/unreleased/321674-allow-to-filter-alert-management-integrations-by-id-take-2.yml b/changelogs/unreleased/321674-allow-to-filter-alert-management-integrations-by-id-take-2.yml new file mode 100644 index 00000000000..568bce470d9 --- /dev/null +++ b/changelogs/unreleased/321674-allow-to-filter-alert-management-integrations-by-id-take-2.yml @@ -0,0 +1,6 @@ +--- +title: Allow filtering GraphQL alertManagementIntegrations and alertManagementHttpIntegrations + by ID +merge_request: 57590 +author: +type: added diff --git a/changelogs/unreleased/36783-add-kotlin-support.yml b/changelogs/unreleased/36783-add-kotlin-support.yml new file mode 100644 index 00000000000..c97ca3e1661 --- /dev/null +++ b/changelogs/unreleased/36783-add-kotlin-support.yml @@ -0,0 +1,5 @@ +--- +title: Add kotlin support to spotbugs-sast job +merge_request: 59431 +author: +type: added diff --git a/changelogs/unreleased/Externalize-strings-in-_confirmation_instructions_account-text-erb.yml b/changelogs/unreleased/Externalize-strings-in-_confirmation_instructions_account-text-erb.yml new file mode 100644 index 00000000000..b0ba6c9a257 --- /dev/null +++ b/changelogs/unreleased/Externalize-strings-in-_confirmation_instructions_account-text-erb.yml @@ -0,0 +1,5 @@ +--- +title: Externalize strings in _confirmation_instructions_account.text.erb +merge_request: 58215 +author: nuwe1 +type: other diff --git a/changelogs/unreleased/Externalize-strings-in-instance_configuration-_gitlab_pages-html-haml.yml b/changelogs/unreleased/Externalize-strings-in-instance_configuration-_gitlab_pages-html-haml.yml new file mode 100644 index 00000000000..9c22f609fa8 --- /dev/null +++ b/changelogs/unreleased/Externalize-strings-in-instance_configuration-_gitlab_pages-html-haml.yml @@ -0,0 +1,5 @@ +--- +title: Externalize strings in instance_configuration/_gitlab_pages.html.haml +merge_request: 58437 +author: nuwe1 +type: other diff --git a/changelogs/unreleased/pl-rubocop-todo-parallel-assignment.yml b/changelogs/unreleased/pl-rubocop-todo-parallel-assignment.yml new file mode 100644 index 00000000000..422fc720079 --- /dev/null +++ b/changelogs/unreleased/pl-rubocop-todo-parallel-assignment.yml @@ -0,0 +1,5 @@ +--- +title: Resolves offenses Style/ParallelAssignment +merge_request: 57999 +author: Shubham Kumar (@imskr) +type: fixed diff --git a/changelogs/unreleased/ui-settings-okr-external-wiki.yml b/changelogs/unreleased/ui-settings-okr-external-wiki.yml new file mode 100644 index 00000000000..90ddccc546f --- /dev/null +++ b/changelogs/unreleased/ui-settings-okr-external-wiki.yml @@ -0,0 +1,5 @@ +--- +title: Updated outdated UI text and docs +merge_request: 58600 +author: +type: other diff --git a/changelogs/unreleased/update-auto-build-image-to-0-6-0.yml b/changelogs/unreleased/update-auto-build-image-to-0-6-0.yml new file mode 100644 index 00000000000..8b17a649651 --- /dev/null +++ b/changelogs/unreleased/update-auto-build-image-to-0-6-0.yml @@ -0,0 +1,5 @@ +--- +title: Update auto-build-image to v0.6.0, updating the included docker to 20.10.6 and pack to 0.18.0 +merge_request: 59525 +author: +type: changed diff --git a/doc/administration/geo/replication/datatypes.md b/doc/administration/geo/replication/datatypes.md index 1df2fb4e3ab..61f99257844 100644 --- a/doc/administration/geo/replication/datatypes.md +++ b/doc/administration/geo/replication/datatypes.md @@ -173,35 +173,35 @@ replicating data from those features will cause the data to be **lost**. If you wish to use those features on a **secondary** site, or to execute a failover successfully, you must replicate their data using some other means. -| Feature | Replicated (added in GitLab version) | Verified (added in GitLab version) | Object Storage replication (see [Geo with Object Storage](object_storage.md)) | Notes | -|:---------------------------------------------------------------------------------------------------------------|:-----------------------------------------------------------------------------------|:----------------------------------------------------------|:-------------------------------------------------------------------------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [Application data in PostgreSQL](../../postgresql/index.md) | **Yes** (10.2) | **Yes** (10.2) | No | | -| [Project repository](../../../user/project/repository/) | **Yes** (10.2) | **Yes** (10.7) | No | | -| [Project wiki repository](../../../user/project/wiki/) | **Yes** (10.2) | **Yes** (10.7) | No | -| [Group wiki repository](../../../user/project/wiki/index.md#group-wikis) | [**Yes** (13.10)](https://gitlab.com/gitlab-org/gitlab/-/issues/208147) | No | No | Behind feature flag `geo_group_wiki_repository_replication`, enabled by default | -| [Uploads](../../uploads.md) | **Yes** (10.2) | [No](https://gitlab.com/groups/gitlab-org/-/epics/1817) | No | Verified only on transfer or manually using [Integrity Check Rake Task](../../raketasks/check.md) on both sites and comparing the output between them. | -| [LFS objects](../../lfs/index.md) | **Yes** (10.2) | [No](https://gitlab.com/gitlab-org/gitlab/-/issues/8922) | Via Object Storage provider if supported. Native Geo support (Beta). | Verified only on transfer or manually using [Integrity Check Rake Task](../../raketasks/check.md) on both sites and comparing the output between them. GitLab versions 11.11.x and 12.0.x are affected by [a bug that prevents any new LFS objects from replicating](https://gitlab.com/gitlab-org/gitlab/-/issues/32696). | -| [Personal snippets](../../../user/snippets.md) | **Yes** (10.2) | **Yes** (10.2) | No | | -| [Project snippets](../../../user/snippets.md) | **Yes** (10.2) | **Yes** (10.2) | No | | -| [CI job artifacts (other than Job Logs)](../../../ci/pipelines/job_artifacts.md) | **Yes** (10.4) | [No](https://gitlab.com/gitlab-org/gitlab/-/issues/8923) | Via Object Storage provider if supported. Native Geo support (Beta) . | Verified only manually using [Integrity Check Rake Task](../../raketasks/check.md) on both sites and comparing the output between them | -| [CI Pipeline Artifacts](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/models/ci/pipeline_artifact.rb) | [**Yes** (13.11)](https://gitlab.com/gitlab-org/gitlab/-/issues/238464) | [**Yes** (13.11)](https://gitlab.com/gitlab-org/gitlab/-/issues/238464) | Via Object Storage provider if supported. Native Geo support (Beta). | Persists additional artifacts after a pipeline completes | -| [Job logs](../../job_logs.md) | **Yes** (10.4) | [No](https://gitlab.com/gitlab-org/gitlab/-/issues/8923) | Via Object Storage provider if supported. Native Geo support (Beta). | Verified only on transfer or manually using [Integrity Check Rake Task](../../raketasks/check.md) on both sites and comparing the output between them | -| [Object pools for forked project deduplication](../../../development/git_object_deduplication.md) | **Yes** | No | No | | -| [Container Registry](../../packages/container_registry.md) | **Yes** (12.3) | No | No | Disabled by default. See [instructions](docker_registry.md) to enable. | -| [Content in object storage (beta)](object_storage.md) | **Yes** (12.4) | [No](https://gitlab.com/gitlab-org/gitlab/-/issues/13845) | No | | -| [Project designs repository](../../../user/project/issues/design_management.md) | **Yes** (12.7) | [No](https://gitlab.com/gitlab-org/gitlab/-/issues/32467) | Via Object Storage provider if supported. Native Geo support (Beta). | | -| [Package Registry for npm](../../../user/packages/npm_registry/index.md) | **Yes** (13.2) | **Yes** (13.10) | Via Object Storage provider if supported. Native Geo support (Beta). | Behind feature flag `geo_package_file_replication`, enabled by default | -| [Package Registry for Maven](../../../user/packages/maven_repository/index.md) | **Yes** (13.2) | **Yes** (13.10) | Via Object Storage provider if supported. Native Geo support (Beta). | Behind feature flag `geo_package_file_replication`, enabled by default | -| [Package Registry for Conan](../../../user/packages/conan_repository/index.md) | **Yes** (13.2) | **Yes** (13.10) | Via Object Storage provider if supported. Native Geo support (Beta). | Behind feature flag `geo_package_file_replication`, enabled by default | -| [Package Registry for NuGet](../../../user/packages/nuget_repository/index.md) | **Yes** (13.2) | **Yes** (13.10) | Via Object Storage provider if supported. Native Geo support (Beta). | Behind feature flag `geo_package_file_replication`, enabled by default | -| [Package Registry for PyPI](../../../user/packages/pypi_repository/index.md) | **Yes** (13.2) | **Yes** (13.10) | Via Object Storage provider if supported. Native Geo support (Beta). | Behind feature flag `geo_package_file_replication`, enabled by default | -| [Package Registry for Composer](../../../user/packages/composer_repository/index.md) | **Yes** (13.2) | **Yes** (13.10) | Via Object Storage provider if supported. Native Geo support (Beta). | Behind feature flag `geo_package_file_replication`, enabled by default | -| [Package Registry for generic packages](../../../user/packages/generic_packages/index.md) | **Yes** (13.5) | **Yes** (13.10) | Via Object Storage provider if supported. Native Geo support (Beta). | Behind feature flag `geo_package_file_replication`, enabled by default | -| [Versioned Terraform State](../../terraform_state.md) | **Yes** (13.5) | No | Via Object Storage provider if supported. Native Geo support (Beta). | Behind feature flag `geo_terraform_state_version_replication`, enabled by default | -| [External merge request diffs](../../merge_request_diffs.md) | **Yes** (13.5) | No | Via Object Storage provider if supported. Native Geo support (Beta). | Behind feature flag `geo_merge_request_diff_replication`, enabled by default | -| [Versioned snippets](../../../user/snippets.md#versioned-snippets) | [**Yes** (13.7)](https://gitlab.com/groups/gitlab-org/-/epics/2809) | [No](https://gitlab.com/groups/gitlab-org/-/epics/2810) | No | | -| [Server-side Git hooks](../../server_hooks.md) | [No](https://gitlab.com/groups/gitlab-org/-/epics/1867) | No | No | | -| [Elasticsearch integration](../../../integration/elasticsearch.md) | [No](https://gitlab.com/gitlab-org/gitlab/-/issues/1186) | No | No | | -| [GitLab Pages](../../pages/index.md) | [No](https://gitlab.com/groups/gitlab-org/-/epics/589) | No | No | | -| [Dependency proxy images](../../../user/packages/dependency_proxy/index.md) | [No](https://gitlab.com/gitlab-org/gitlab/-/issues/259694) | No | No | Blocked on [Geo: Secondary Mimicry](https://gitlab.com/groups/gitlab-org/-/epics/1528). Note that replication of this cache is not needed for Disaster Recovery purposes because it can be recreated from external sources. | -| [Vulnerability Export](../../../user/application_security/vulnerability_report/#export-vulnerability-details) | [Not planned](https://gitlab.com/groups/gitlab-org/-/epics/3111) | No | Via Object Storage provider if supported. Native Geo support (Beta). | Not planned because they are ephemeral and sensitive. They can be regenerated on demand. | +|Feature | Replicated (added in GitLab version) | Verified (added in GitLab version) | Object Storage replication (see [Geo with Object Storage](object_storage.md)) | Notes | +|:--------------------------------------------------------------------------------------------------------------|:------------------------------------------------------------------------|:------------------------------------------------------------------------|:------------------------------------------------------------------------------|:------| +|[Application data in PostgreSQL](../../postgresql/index.md) | **Yes** (10.2) | **Yes** (10.2) | No | | +|[Project repository](../../../user/project/repository/) | **Yes** (10.2) | **Yes** (10.7) | No | | +|[Project wiki repository](../../../user/project/wiki/) | **Yes** (10.2) | **Yes** (10.7) | No | | +|[Group wiki repository](../../../user/project/wiki/index.md#group-wikis) | [**Yes** (13.10)](https://gitlab.com/gitlab-org/gitlab/-/issues/208147) | No | No | Behind feature flag `geo_group_wiki_repository_replication`, enabled by default. | +|[Uploads](../../uploads.md) | **Yes** (10.2) | [No](https://gitlab.com/groups/gitlab-org/-/epics/1817) | No | Verified only on transfer or manually using [Integrity Check Rake Task](../../raketasks/check.md) on both sites and comparing the output between them. | +|[LFS objects](../../lfs/index.md) | **Yes** (10.2) | [No](https://gitlab.com/gitlab-org/gitlab/-/issues/8922) | Via Object Storage provider if supported. Native Geo support (Beta). | Verified only on transfer or manually using [Integrity Check Rake Task](../../raketasks/check.md) on both sites and comparing the output between them. GitLab versions 11.11.x and 12.0.x are affected by [a bug that prevents any new LFS objects from replicating](https://gitlab.com/gitlab-org/gitlab/-/issues/32696). | +|[Personal snippets](../../../user/snippets.md) | **Yes** (10.2) | **Yes** (10.2) | No | | +|[Project snippets](../../../user/snippets.md) | **Yes** (10.2) | **Yes** (10.2) | No | | +|[CI job artifacts (other than Job Logs)](../../../ci/pipelines/job_artifacts.md) | **Yes** (10.4) | [No](https://gitlab.com/gitlab-org/gitlab/-/issues/8923) | Via Object Storage provider if supported. Native Geo support (Beta). | Verified only manually using [Integrity Check Rake Task](../../raketasks/check.md) on both sites and comparing the output between them. | +|[CI Pipeline Artifacts](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/models/ci/pipeline_artifact.rb) | [**Yes** (13.11)](https://gitlab.com/gitlab-org/gitlab/-/issues/238464) | [**Yes** (13.11)](https://gitlab.com/gitlab-org/gitlab/-/issues/238464) | Via Object Storage provider if supported. Native Geo support (Beta). | Persists additional artifacts after a pipeline completes | +|[Job logs](../../job_logs.md) | **Yes** (10.4) | [No](https://gitlab.com/gitlab-org/gitlab/-/issues/8923) | Via Object Storage provider if supported. Native Geo support (Beta). | Verified only on transfer or manually using [Integrity Check Rake Task](../../raketasks/check.md) on both sites and comparing the output between them. | +|[Object pools for forked project deduplication](../../../development/git_object_deduplication.md) | **Yes** | No | No | | +|[Container Registry](../../packages/container_registry.md) | **Yes** (12.3) | No | No | Disabled by default. See [instructions](docker_registry.md) to enable. | +|[Content in object storage (beta)](object_storage.md) | **Yes** (12.4) | [No](https://gitlab.com/gitlab-org/gitlab/-/issues/13845) | No | | +|[Project designs repository](../../../user/project/issues/design_management.md) | **Yes** (12.7) | [No](https://gitlab.com/gitlab-org/gitlab/-/issues/32467) | Via Object Storage provider if supported. Native Geo support (Beta). | | +|[Package Registry for npm](../../../user/packages/npm_registry/index.md) | **Yes** (13.2) | **Yes** (13.10) | Via Object Storage provider if supported. Native Geo support (Beta). | Behind feature flag `geo_package_file_replication`, enabled by default. | +|[Package Registry for Maven](../../../user/packages/maven_repository/index.md) | **Yes** (13.2) | **Yes** (13.10) | Via Object Storage provider if supported. Native Geo support (Beta). | Behind feature flag `geo_package_file_replication`, enabled by default. | +|[Package Registry for Conan](../../../user/packages/conan_repository/index.md) | **Yes** (13.2) | **Yes** (13.10) | Via Object Storage provider if supported. Native Geo support (Beta). | Behind feature flag `geo_package_file_replication`, enabled by default. | +|[Package Registry for NuGet](../../../user/packages/nuget_repository/index.md) | **Yes** (13.2) | **Yes** (13.10) | Via Object Storage provider if supported. Native Geo support (Beta). | Behind feature flag `geo_package_file_replication`, enabled by default. | +|[Package Registry for PyPI](../../../user/packages/pypi_repository/index.md) | **Yes** (13.2) | **Yes** (13.10) | Via Object Storage provider if supported. Native Geo support (Beta). | Behind feature flag `geo_package_file_replication`, enabled by default. | +|[Package Registry for Composer](../../../user/packages/composer_repository/index.md) | **Yes** (13.2) | **Yes** (13.10) | Via Object Storage provider if supported. Native Geo support (Beta). | Behind feature flag `geo_package_file_replication`, enabled by default. | +|[Package Registry for generic packages](../../../user/packages/generic_packages/index.md) | **Yes** (13.5) | **Yes** (13.10) | Via Object Storage provider if supported. Native Geo support (Beta). | Behind feature flag `geo_package_file_replication`, enabled by default. | +|[Versioned Terraform State](../../terraform_state.md) | **Yes** (13.5) | No | Via Object Storage provider if supported. Native Geo support (Beta). | Behind feature flag `geo_terraform_state_version_replication`, enabled by default. | +|[External merge request diffs](../../merge_request_diffs.md) | **Yes** (13.5) | No | Via Object Storage provider if supported. Native Geo support (Beta). | Behind feature flag `geo_merge_request_diff_replication`, enabled by default. | +|[Versioned snippets](../../../user/snippets.md#versioned-snippets) | [**Yes** (13.7)](https://gitlab.com/groups/gitlab-org/-/epics/2809) | [No](https://gitlab.com/groups/gitlab-org/-/epics/2810) | No | | +|[Server-side Git hooks](../../server_hooks.md) | [No](https://gitlab.com/groups/gitlab-org/-/epics/1867) | No | No | | +|[Elasticsearch integration](../../../integration/elasticsearch.md) | [No](https://gitlab.com/gitlab-org/gitlab/-/issues/1186) | No | No | | +|[GitLab Pages](../../pages/index.md) | [No](https://gitlab.com/groups/gitlab-org/-/epics/589) | No | No | | +|[Dependency proxy images](../../../user/packages/dependency_proxy/index.md) | [No](https://gitlab.com/gitlab-org/gitlab/-/issues/259694) | No | No | Blocked on [Geo: Secondary Mimicry](https://gitlab.com/groups/gitlab-org/-/epics/1528). Note that replication of this cache is not needed for Disaster Recovery purposes because it can be recreated from external sources. | +|[Vulnerability Export](../../../user/application_security/vulnerability_report/#export-vulnerability-details) | [Not planned](https://gitlab.com/groups/gitlab-org/-/epics/3111) | No | Via Object Storage provider if supported. Native Geo support (Beta). | Not planned because they are ephemeral and sensitive. They can be regenerated on demand. | diff --git a/doc/user/analytics/value_stream_analytics.md b/doc/user/analytics/value_stream_analytics.md index 54b98b5ec1d..2af98492ee7 100644 --- a/doc/user/analytics/value_stream_analytics.md +++ b/doc/user/analytics/value_stream_analytics.md @@ -62,12 +62,9 @@ The "Time" metrics near the top of the page are measured as follows: ## How the stages are measured -Value Stream Analytics records stage time and data based on the project issues with the -exception of the staging stage, where only data deployed to -production are measured. - -Specifically, if your CI is not set up and you have not defined a [production environment](#how-the-production-environment-is-identified), then you will not have any -data for this stage. +Value Stream Analytics uses start events and stop events to measure the time that an Issue or MR spends in each stage. +For example, a stage might start when one label is added to an issue, and end when another label is added. +Items are not included in the stage time calculation if they have not reached the stop event. Each stage of Value Stream Analytics is further described in the table below. diff --git a/doc/user/application_security/dast/index.md b/doc/user/application_security/dast/index.md index 5b32157d28e..d3f679fe9dd 100644 --- a/doc/user/application_security/dast/index.md +++ b/doc/user/application_security/dast/index.md @@ -72,6 +72,13 @@ To include the DAST template: For more information about template versioning, see the [CI/CD documentation](../../../development/cicd/templates.md#latest-version). +1. Add a `dast` stage to your GitLab CI stages configuration: + + ```yaml + stages: + - dast + ``` + 1. Add the template to GitLab, based on your version of GitLab: - In GitLab 11.9 and later, [include](../../../ci/yaml/README.md#includetemplate) diff --git a/doc/user/application_security/sast/index.md b/doc/user/application_security/sast/index.md index 754a60c2810..8a0c527f545 100644 --- a/doc/user/application_security/sast/index.md +++ b/doc/user/application_security/sast/index.md @@ -79,6 +79,7 @@ You can also [view our language roadmap](https://about.gitlab.com/direction/secu | JavaScript | [ESLint security plugin](https://github.com/nodesecurity/eslint-plugin-security) | 11.8 | | JavaScript | [Semgrep](https://semgrep.dev) | 13.10 | | Kotlin (Android) | [MobSF (beta)](https://github.com/MobSF/Mobile-Security-Framework-MobSF) | 13.5 | +| Kotlin (General) | [SpotBugs](https://spotbugs.github.io/) with the [find-sec-bugs](https://find-sec-bugs.github.io/) plugin | 13.11 | | Kubernetes manifests | [Kubesec](https://github.com/controlplaneio/kubesec) | 12.6 | | Node.js | [NodeJsScan](https://github.com/ajinabraham/NodeJsScan) | 11.1 | | Objective-C (iOS) | [MobSF (beta)](https://github.com/MobSF/Mobile-Security-Framework-MobSF) | 13.5 | diff --git a/doc/user/group/value_stream_analytics/index.md b/doc/user/group/value_stream_analytics/index.md index c59c673b360..6a512d78696 100644 --- a/doc/user/group/value_stream_analytics/index.md +++ b/doc/user/group/value_stream_analytics/index.md @@ -82,12 +82,9 @@ The "Time" metrics near the top of the page are measured as follows: ## How the stages are measured -Value Stream Analytics records stage time and data based on the project issues with the -exception of the staging stage, where only data deployed to -production are measured. - -Specifically, if your CI is not set up and you have not defined a [production environment](#how-the-production-environment-is-identified), then you will not have any -data for this stage. +Value Stream Analytics measures each stage from its start event to its stop event. +For example, a stage might start when one label is added to an issue, and end when another label is added. +Value Stream Analytics excludes work in progress, meaning it ignores any items that have not reached the stop event. Each stage of Value Stream Analytics is further described in the table below. diff --git a/doc/user/project/integrations/overview.md b/doc/user/project/integrations/overview.md index ca0d92b4f88..ef1f492bfbf 100644 --- a/doc/user/project/integrations/overview.md +++ b/doc/user/project/integrations/overview.md @@ -38,7 +38,7 @@ Click on the service links to see further configuration instructions and details | Drone CI | Run CI/CD pipelines with Drone. | **{check-circle}** Yes | | [Emails on push](emails_on_push.md) | Send commits and diff of each push by email. | **{dotted-circle}** No | | [EWM](ewm.md) | Use IBM Engineering Workflow Management as the issue tracker. | **{dotted-circle}** No | -| External wiki | Replace internal wiki link with external wiki link. | **{dotted-circle}** No | +| [External wiki](../wiki/index.md#link-an-external-wiki) | Link an external wiki. | **{dotted-circle}** No | | Flowdock | Use Flowdock with GitLab. | **{dotted-circle}** No | | [GitHub](github.md) | Obtain statuses for commits and pull requests. | **{dotted-circle}** No | | [Hangouts Chat](hangouts_chat.md) | Receive events notifications. | **{dotted-circle}** No | diff --git a/doc/user/project/wiki/index.md b/doc/user/project/wiki/index.md index 27f711da77d..a69141ac04d 100644 --- a/doc/user/project/wiki/index.md +++ b/doc/user/project/wiki/index.md @@ -237,6 +237,49 @@ Group wikis can be edited by members with [Developer permissions](../../permissi and above. Group wiki repositories can be moved using the [Group repository storage moves API](../../../api/group_repository_storage_moves.md). +## Link an external wiki + +To add a link to an external wiki from a project's left sidebar: + +1. In your project, go to **Settings > Integrations**. +1. Select **External wiki**. +1. Add the URL to your external wiki. +1. (Optional) Select **Test settings** to verify the connection. +1. Select **Save changes**. + +You can now see the **External wiki** option from your project's +left sidebar. + +When you enable this integration, the link to the external +wiki won't replace the link to the internal wiki. +To hide the internal wiki from the sidebar, [disable the project's wiki](#disable-the-projects-wiki). + +To hide the link to an external wiki: + +1. In your project, go to **Settings > Integrations**. +1. Select **External wiki**. +1. Unselect **Enable integration**. +1. Select **Save changes**. + +## Disable the project's wiki + +To disable a project's internal wiki: + +1. In your project, go to **Settings > General**. +1. Expand **Visibility, project features, permissions**. +1. Scroll down to find **Wiki** and toggle it off (in gray). +1. Select **Save changes**. + +The internal wiki is now disabled, and users and project members: + +- Cannot find the link to the wiki from the project's sidebar. +- Cannot add, delete, or edit wiki pages. +- Cannot view any wiki page. + +Previously added wiki pages are preserved in case you +want to re-enable the wiki. To re-enable it, repeat the process +to disable the wiki but toggle it on (in blue). + ## Resources - [Wiki settings for administrators](../../../administration/wikis/index.md) diff --git a/lib/banzai/filter/references/label_reference_filter.rb b/lib/banzai/filter/references/label_reference_filter.rb index 8508aa2b3c3..a6a5eec5d9a 100644 --- a/lib/banzai/filter/references/label_reference_filter.rb +++ b/lib/banzai/filter/references/label_reference_filter.rb @@ -18,7 +18,8 @@ module Banzai def references_in(text, pattern = Label.reference_pattern) labels = {} unescaped_html = unescape_html_entities(text).gsub(pattern) do |match| - namespace, project = $~[:namespace], $~[:project] + namespace = $~[:namespace] + project = $~[:project] project_path = full_project_path(namespace, project) label = find_label_cached(project_path, $~[:label_id], $~[:label_name]) diff --git a/lib/container_registry/config.rb b/lib/container_registry/config.rb index 40dd92befd2..aafa9b1c182 100644 --- a/lib/container_registry/config.rb +++ b/lib/container_registry/config.rb @@ -5,7 +5,8 @@ module ContainerRegistry attr_reader :tag, :blob, :data def initialize(tag, blob) - @tag, @blob = tag, blob + @tag = tag + @blob = blob @data = Gitlab::Json.parse(blob.data) end diff --git a/lib/container_registry/tag.rb b/lib/container_registry/tag.rb index 09c0aa66a0d..614b1b5e6c6 100644 --- a/lib/container_registry/tag.rb +++ b/lib/container_registry/tag.rb @@ -10,7 +10,8 @@ module ContainerRegistry delegate :revision, :short_revision, to: :config_blob, allow_nil: true def initialize(repository, name) - @repository, @name = repository, name + @repository = repository + @name = name end def valid? diff --git a/lib/declarative_policy/preferred_scope.rb b/lib/declarative_policy/preferred_scope.rb index d653a0ec1e1..9e512086593 100644 --- a/lib/declarative_policy/preferred_scope.rb +++ b/lib/declarative_policy/preferred_scope.rb @@ -5,7 +5,8 @@ module DeclarativePolicy PREFERRED_SCOPE_KEY = :"DeclarativePolicy.preferred_scope" def with_preferred_scope(scope) - Thread.current[PREFERRED_SCOPE_KEY], old_scope = scope, Thread.current[PREFERRED_SCOPE_KEY] + old_scope = Thread.current[PREFERRED_SCOPE_KEY] + Thread.current[PREFERRED_SCOPE_KEY] = scope yield ensure Thread.current[PREFERRED_SCOPE_KEY] = old_scope diff --git a/lib/file_size_validator.rb b/lib/file_size_validator.rb index 71908d2130f..e9868732172 100644 --- a/lib/file_size_validator.rb +++ b/lib/file_size_validator.rb @@ -11,7 +11,8 @@ class FileSizeValidator < ActiveModel::EachValidator if range = (options.delete(:in) || options.delete(:within)) raise ArgumentError, ":in and :within must be a Range" unless range.is_a?(Range) - options[:minimum], options[:maximum] = range.begin, range.end + options[:minimum] = range.begin + options[:maximum] = range.end options[:maximum] -= 1 if range.exclude_end? end diff --git a/lib/gitlab/batch_pop_queueing.rb b/lib/gitlab/batch_pop_queueing.rb index e18f1320ea4..62fc8cd048e 100644 --- a/lib/gitlab/batch_pop_queueing.rb +++ b/lib/gitlab/batch_pop_queueing.rb @@ -46,7 +46,8 @@ module Gitlab def initialize(namespace, queue_id) raise ArgumentError if namespace.empty? || queue_id.empty? - @namespace, @queue_id = namespace, queue_id + @namespace = namespace + @queue_id = queue_id end ## diff --git a/lib/gitlab/cache/ci/project_pipeline_status.rb b/lib/gitlab/cache/ci/project_pipeline_status.rb index d981f263c5e..9e958eb52fb 100644 --- a/lib/gitlab/cache/ci/project_pipeline_status.rb +++ b/lib/gitlab/cache/ci/project_pipeline_status.rb @@ -69,7 +69,9 @@ module Gitlab def load_from_project return unless commit - self.sha, self.status, self.ref = commit.sha, commit.status, project.default_branch + self.sha = commit.sha + self.status = commit.status + self.ref = project.default_branch end # We only cache the status for the HEAD commit of a project diff --git a/lib/gitlab/ci/build/artifacts/metadata.rb b/lib/gitlab/ci/build/artifacts/metadata.rb index c5afb16ab1a..88d624503df 100644 --- a/lib/gitlab/ci/build/artifacts/metadata.rb +++ b/lib/gitlab/ci/build/artifacts/metadata.rb @@ -17,7 +17,9 @@ module Gitlab attr_reader :stream, :path, :full_version def initialize(stream, path, **opts) - @stream, @path, @opts = stream, path, opts + @stream = stream + @path = path + @opts = opts @full_version = read_version end diff --git a/lib/gitlab/ci/templates/Jobs/Build.gitlab-ci.yml b/lib/gitlab/ci/templates/Jobs/Build.gitlab-ci.yml index 1c25d9d583b..196d42f3e3a 100644 --- a/lib/gitlab/ci/templates/Jobs/Build.gitlab-ci.yml +++ b/lib/gitlab/ci/templates/Jobs/Build.gitlab-ci.yml @@ -1,10 +1,10 @@ build: stage: build - image: "registry.gitlab.com/gitlab-org/cluster-integration/auto-build-image:v0.4.0" + image: "registry.gitlab.com/gitlab-org/cluster-integration/auto-build-image:v0.6.0" variables: DOCKER_TLS_CERTDIR: "" services: - - docker:19.03.12-dind + - docker:20.10.6-dind script: - | if [[ -z "$CI_COMMIT_TAG" ]]; then diff --git a/lib/gitlab/ci/templates/Security/DAST.latest.gitlab-ci.yml b/lib/gitlab/ci/templates/Security/DAST.latest.gitlab-ci.yml index 6e60d1fe1ac..533f8bb25f8 100644 --- a/lib/gitlab/ci/templates/Security/DAST.latest.gitlab-ci.yml +++ b/lib/gitlab/ci/templates/Security/DAST.latest.gitlab-ci.yml @@ -1,3 +1,16 @@ +# To use this template, add the following to your .gitlab-ci.yml file: +# +# include: +# template: DAST.latest.gitlab-ci.yml +# +# You also need to add a `dast` stage to your `stages:` configuration. A sample configuration for DAST: +# +# stages: +# - build +# - test +# - deploy +# - dast + # Read more about this feature here: https://docs.gitlab.com/ee/user/application_security/dast/ # Configure the scanning tool through the environment variables. diff --git a/lib/gitlab/ci/templates/Security/SAST.gitlab-ci.yml b/lib/gitlab/ci/templates/Security/SAST.gitlab-ci.yml index a1f0d2e5a48..3ebccfbba4a 100644 --- a/lib/gitlab/ci/templates/Security/SAST.gitlab-ci.yml +++ b/lib/gitlab/ci/templates/Security/SAST.gitlab-ci.yml @@ -352,3 +352,4 @@ spotbugs-sast: - '**/*.groovy' - '**/*.java' - '**/*.scala' + - '**/*.kt' diff --git a/lib/gitlab/contributor.rb b/lib/gitlab/contributor.rb index d74d5a86aa0..c1c270bc9e6 100644 --- a/lib/gitlab/contributor.rb +++ b/lib/gitlab/contributor.rb @@ -5,7 +5,9 @@ module Gitlab attr_accessor :email, :name, :commits, :additions, :deletions def initialize - @commits, @additions, @deletions = 0, 0, 0 + @commits = 0 + @additions = 0 + @deletions = 0 end end end diff --git a/lib/gitlab/database/migration_helpers.rb b/lib/gitlab/database/migration_helpers.rb index bc50f0c3c04..d06a73da8ac 100644 --- a/lib/gitlab/database/migration_helpers.rb +++ b/lib/gitlab/database/migration_helpers.rb @@ -577,17 +577,7 @@ module Gitlab # old_column - The name of the old column. # new_column - The name of the new column. def install_rename_triggers(table, old_column, new_column) - trigger_name = rename_trigger_name(table, old_column, new_column) - quoted_table = quote_table_name(table) - quoted_old = quote_column_name(old_column) - quoted_new = quote_column_name(new_column) - - install_rename_triggers_for_postgresql( - trigger_name, - quoted_table, - quoted_old, - quoted_new - ) + install_rename_triggers_for_postgresql(table, old_column, new_column) end # Changes the type of a column concurrently. @@ -1054,43 +1044,18 @@ module Gitlab end # Performs a concurrent column rename when using PostgreSQL. - def install_rename_triggers_for_postgresql(trigger, table, old, new) - execute <<-EOF.strip_heredoc - CREATE OR REPLACE FUNCTION #{trigger}() - RETURNS trigger AS - $BODY$ - BEGIN - NEW.#{new} := NEW.#{old}; - RETURN NEW; - END; - $BODY$ - LANGUAGE 'plpgsql' - VOLATILE - EOF - - execute <<-EOF.strip_heredoc - DROP TRIGGER IF EXISTS #{trigger} - ON #{table} - EOF - - execute <<-EOF.strip_heredoc - CREATE TRIGGER #{trigger} - BEFORE INSERT OR UPDATE - ON #{table} - FOR EACH ROW - EXECUTE FUNCTION #{trigger}() - EOF + def install_rename_triggers_for_postgresql(table, old, new, trigger_name: nil) + Gitlab::Database::UnidirectionalCopyTrigger.on_table(table).create(old, new, trigger_name: trigger_name) end # Removes the triggers used for renaming a PostgreSQL column concurrently. def remove_rename_triggers_for_postgresql(table, trigger) - execute("DROP TRIGGER IF EXISTS #{trigger} ON #{table}") - execute("DROP FUNCTION IF EXISTS #{trigger}()") + Gitlab::Database::UnidirectionalCopyTrigger.on_table(table).drop(trigger) end # Returns the (base) name to use for triggers when renaming columns. def rename_trigger_name(table, old, new) - 'trigger_' + Digest::SHA256.hexdigest("#{table}_#{old}_#{new}").first(12) + Gitlab::Database::UnidirectionalCopyTrigger.on_table(table).name(old, new) end # Returns an Array containing the indexes for the given column diff --git a/lib/gitlab/database/unidirectional_copy_trigger.rb b/lib/gitlab/database/unidirectional_copy_trigger.rb new file mode 100644 index 00000000000..029c894a5ff --- /dev/null +++ b/lib/gitlab/database/unidirectional_copy_trigger.rb @@ -0,0 +1,97 @@ +# frozen_string_literal: true + +module Gitlab + module Database + class UnidirectionalCopyTrigger + def self.on_table(table_name, connection: ActiveRecord::Base.connection) + new(table_name, connection) + end + + def name(from_column_names, to_column_names) + from_column_names, to_column_names = check_column_names!(from_column_names, to_column_names) + + unchecked_name(from_column_names, to_column_names) + end + + def create(from_column_names, to_column_names, trigger_name: nil) + from_column_names, to_column_names = check_column_names!(from_column_names, to_column_names) + trigger_name ||= unchecked_name(from_column_names, to_column_names) + + assignment_clauses = assignment_clauses_for_columns(from_column_names, to_column_names) + + connection.execute(<<~SQL) + CREATE OR REPLACE FUNCTION #{trigger_name}() + RETURNS trigger AS + $BODY$ + BEGIN + #{assignment_clauses}; + RETURN NEW; + END; + $BODY$ + LANGUAGE 'plpgsql' + VOLATILE + SQL + + connection.execute(<<~SQL) + DROP TRIGGER IF EXISTS #{trigger_name} + ON #{quoted_table_name} + SQL + + connection.execute(<<~SQL) + CREATE TRIGGER #{trigger_name} + BEFORE INSERT OR UPDATE + ON #{quoted_table_name} + FOR EACH ROW + EXECUTE FUNCTION #{trigger_name}() + SQL + end + + def drop(trigger_name) + connection.execute("DROP TRIGGER IF EXISTS #{trigger_name} ON #{quoted_table_name}") + connection.execute("DROP FUNCTION IF EXISTS #{trigger_name}()") + end + + private + + attr_reader :table_name, :connection + + def initialize(table_name, connection) + @table_name = table_name + @connection = connection + end + + def quoted_table_name + @quoted_table_name ||= connection.quote_table_name(table_name) + end + + def check_column_names!(from_column_names, to_column_names) + from_column_names = Array.wrap(from_column_names) + to_column_names = Array.wrap(to_column_names) + + unless from_column_names.size == to_column_names.size + raise ArgumentError, 'number of source and destination columns must match' + end + + [from_column_names, to_column_names] + end + + def unchecked_name(from_column_names, to_column_names) + joined_column_names = from_column_names.zip(to_column_names).flatten.join('_') + 'trigger_' + Digest::SHA256.hexdigest("#{table_name}_#{joined_column_names}").first(12) + end + + def assignment_clauses_for_columns(from_column_names, to_column_names) + combined_column_names = to_column_names.zip(from_column_names) + + assignment_clauses = combined_column_names.map do |(new_name, old_name)| + new_name = connection.quote_column_name(new_name) + old_name = connection.quote_column_name(old_name) + + "NEW.#{new_name} := NEW.#{old_name}" + end + + assignment_clauses.join(";\n ") + end + end + end +end diff --git a/lib/gitlab/diff/line.rb b/lib/gitlab/diff/line.rb index 66f506ec3aa..6cf414e29cc 100644 --- a/lib/gitlab/diff/line.rb +++ b/lib/gitlab/diff/line.rb @@ -13,8 +13,11 @@ module Gitlab attr_accessor :index, :type, :old_pos, :new_pos def initialize(text, type, index, old_pos, new_pos, parent_file: nil, line_code: nil, rich_text: nil) - @text, @type, @index = text, type, index - @old_pos, @new_pos = old_pos, new_pos + @text = text + @type = type + @index = index + @old_pos = old_pos + @new_pos = new_pos @parent_file = parent_file @rich_text = rich_text diff --git a/lib/gitlab/diff/suggestions_parser.rb b/lib/gitlab/diff/suggestions_parser.rb index dc65c7ccf9c..f3e6fc455ac 100644 --- a/lib/gitlab/diff/suggestions_parser.rb +++ b/lib/gitlab/diff/suggestions_parser.rb @@ -29,9 +29,8 @@ module Gitlab lines_above, lines_below = nil if lang_param && suggestion_params = fetch_suggestion_params(lang_param) - lines_above, lines_below = - suggestion_params[:above], - suggestion_params[:below] + lines_above = suggestion_params[:above] + lines_below = suggestion_params[:below] end Gitlab::Diff::Suggestion.new(node.text, diff --git a/lib/gitlab/external_authorization/access.rb b/lib/gitlab/external_authorization/access.rb index e111c41fcc2..21fa728fd3a 100644 --- a/lib/gitlab/external_authorization/access.rb +++ b/lib/gitlab/external_authorization/access.rb @@ -10,7 +10,8 @@ module Gitlab :load_type def initialize(user, label) - @user, @label = user, label + @user = user + @label = label end def loaded? diff --git a/lib/gitlab/external_authorization/cache.rb b/lib/gitlab/external_authorization/cache.rb index acdc028b4dc..509daeb0248 100644 --- a/lib/gitlab/external_authorization/cache.rb +++ b/lib/gitlab/external_authorization/cache.rb @@ -6,7 +6,8 @@ module Gitlab VALIDITY_TIME = 6.hours def initialize(user, label) - @user, @label = user, label + @user = user + @label = label end def load diff --git a/lib/gitlab/external_authorization/client.rb b/lib/gitlab/external_authorization/client.rb index b93a15a977c..582051010d3 100644 --- a/lib/gitlab/external_authorization/client.rb +++ b/lib/gitlab/external_authorization/client.rb @@ -13,7 +13,8 @@ module Gitlab }.freeze def initialize(user, label) - @user, @label = user, label + @user = user + @label = label end def request_access diff --git a/lib/gitlab/git/blame.rb b/lib/gitlab/git/blame.rb index 9e24306c05e..a5b1b7d914b 100644 --- a/lib/gitlab/git/blame.rb +++ b/lib/gitlab/git/blame.rb @@ -30,8 +30,10 @@ module Gitlab end def process_raw_blame(output) - lines, final = [], [] - info, commits = {}, {} + lines = [] + final = [] + info = {} + commits = {} # process the output output.split("\n").each do |line| diff --git a/lib/gitlab/git/merge_base.rb b/lib/gitlab/git/merge_base.rb index b27f7038c26..905d72cadbf 100644 --- a/lib/gitlab/git/merge_base.rb +++ b/lib/gitlab/git/merge_base.rb @@ -6,7 +6,8 @@ module Gitlab include Gitlab::Utils::StrongMemoize def initialize(repository, refs) - @repository, @refs = repository, refs + @repository = repository + @refs = refs end # Returns the SHA of the first common ancestor diff --git a/lib/gitlab/git/patches/commit_patches.rb b/lib/gitlab/git/patches/commit_patches.rb index c62994432d3..1182db10c34 100644 --- a/lib/gitlab/git/patches/commit_patches.rb +++ b/lib/gitlab/git/patches/commit_patches.rb @@ -7,7 +7,10 @@ module Gitlab include Gitlab::Git::WrapsGitalyErrors def initialize(user, repository, branch, patch_collection) - @user, @repository, @branch, @patches = user, repository, branch, patch_collection + @user = user + @repository = repository + @branch = branch + @patches = patch_collection end def commit diff --git a/lib/gitlab/graphql/loaders/batch_lfs_oid_loader.rb b/lib/gitlab/graphql/loaders/batch_lfs_oid_loader.rb index 67511c124e4..1945388cdd4 100644 --- a/lib/gitlab/graphql/loaders/batch_lfs_oid_loader.rb +++ b/lib/gitlab/graphql/loaders/batch_lfs_oid_loader.rb @@ -5,7 +5,8 @@ module Gitlab module Loaders class BatchLfsOidLoader def initialize(repository, blob_id) - @repository, @blob_id = repository, blob_id + @repository = repository + @blob_id = blob_id end def find diff --git a/lib/gitlab/graphql/loaders/batch_model_loader.rb b/lib/gitlab/graphql/loaders/batch_model_loader.rb index 9b85ba164d4..805864cdd4c 100644 --- a/lib/gitlab/graphql/loaders/batch_model_loader.rb +++ b/lib/gitlab/graphql/loaders/batch_model_loader.rb @@ -7,7 +7,8 @@ module Gitlab attr_reader :model_class, :model_id def initialize(model_class, model_id) - @model_class, @model_id = model_class, model_id + @model_class = model_class + @model_id = model_id end # rubocop: disable CodeReuse/ActiveRecord diff --git a/lib/gitlab/graphql/loaders/full_path_model_loader.rb b/lib/gitlab/graphql/loaders/full_path_model_loader.rb index 0aa237c78de..26c1ce64a83 100644 --- a/lib/gitlab/graphql/loaders/full_path_model_loader.rb +++ b/lib/gitlab/graphql/loaders/full_path_model_loader.rb @@ -9,7 +9,8 @@ module Gitlab attr_reader :model_class, :full_path def initialize(model_class, full_path) - @model_class, @full_path = model_class, full_path + @model_class = model_class + @full_path = full_path end def find diff --git a/lib/gitlab/graphql/pagination/keyset/conditions/base_condition.rb b/lib/gitlab/graphql/pagination/keyset/conditions/base_condition.rb index bd785880b57..6645dac36fa 100644 --- a/lib/gitlab/graphql/pagination/keyset/conditions/base_condition.rb +++ b/lib/gitlab/graphql/pagination/keyset/conditions/base_condition.rb @@ -13,7 +13,11 @@ module Gitlab # @param [Symbol] before_or_after indicates whether we want # items :before the cursor or :after the cursor def initialize(arel_table, order_list, values, operators, before_or_after) - @arel_table, @order_list, @values, @operators, @before_or_after = arel_table, order_list, values, operators, before_or_after + @arel_table = arel_table + @order_list = order_list + @values = values + @operators = operators + @before_or_after = before_or_after @before_or_after = :after unless [:after, :before].include?(@before_or_after) end diff --git a/lib/gitlab/graphql/pagination/keyset/query_builder.rb b/lib/gitlab/graphql/pagination/keyset/query_builder.rb index 29169449843..ee9c902c735 100644 --- a/lib/gitlab/graphql/pagination/keyset/query_builder.rb +++ b/lib/gitlab/graphql/pagination/keyset/query_builder.rb @@ -6,7 +6,10 @@ module Gitlab module Keyset class QueryBuilder def initialize(arel_table, order_list, decoded_cursor, before_or_after) - @arel_table, @order_list, @decoded_cursor, @before_or_after = arel_table, order_list, decoded_cursor, before_or_after + @arel_table = arel_table + @order_list = order_list + @decoded_cursor = decoded_cursor + @before_or_after = before_or_after if order_list.empty? raise ArgumentError.new('No ordering scopes have been supplied') diff --git a/lib/gitlab/phabricator_import/issues/importer.rb b/lib/gitlab/phabricator_import/issues/importer.rb index a58438452ff..478c26af030 100644 --- a/lib/gitlab/phabricator_import/issues/importer.rb +++ b/lib/gitlab/phabricator_import/issues/importer.rb @@ -4,7 +4,8 @@ module Gitlab module Issues class Importer def initialize(project, after = nil) - @project, @after = project, after + @project = project + @after = after end def execute diff --git a/lib/gitlab/phabricator_import/issues/task_importer.rb b/lib/gitlab/phabricator_import/issues/task_importer.rb index c17f3e1729a..9c419ecb700 100644 --- a/lib/gitlab/phabricator_import/issues/task_importer.rb +++ b/lib/gitlab/phabricator_import/issues/task_importer.rb @@ -4,7 +4,8 @@ module Gitlab module Issues class TaskImporter def initialize(project, task) - @project, @task = project, task + @project = project + @task = task end def execute diff --git a/lib/gitlab/phabricator_import/user_finder.rb b/lib/gitlab/phabricator_import/user_finder.rb index 4b50431e0e0..c6058d12527 100644 --- a/lib/gitlab/phabricator_import/user_finder.rb +++ b/lib/gitlab/phabricator_import/user_finder.rb @@ -4,7 +4,8 @@ module Gitlab module PhabricatorImport class UserFinder def initialize(project, phids) - @project, @phids = project, phids + @project = project + @phids = phids @loaded_phids = Set.new end diff --git a/lib/gitlab/project_template.rb b/lib/gitlab/project_template.rb index 56eeea6e746..32d3eeb8cd2 100644 --- a/lib/gitlab/project_template.rb +++ b/lib/gitlab/project_template.rb @@ -5,7 +5,11 @@ module Gitlab attr_reader :title, :name, :description, :preview, :logo def initialize(name, title, description, preview, logo = 'illustrations/gitlab_logo.svg') - @name, @title, @description, @preview, @logo = name, title, description, preview, logo + @name = name + @title = title + @description = description + @preview = preview + @logo = logo end def file diff --git a/lib/gitlab/relative_positioning/closed_range.rb b/lib/gitlab/relative_positioning/closed_range.rb index 8916d1face5..11fba05edee 100644 --- a/lib/gitlab/relative_positioning/closed_range.rb +++ b/lib/gitlab/relative_positioning/closed_range.rb @@ -4,7 +4,8 @@ module Gitlab module RelativePositioning class ClosedRange < RelativePositioning::Range def initialize(lhs, rhs) - @lhs, @rhs = lhs, rhs + @lhs = lhs + @rhs = rhs raise IllegalRange, 'Either lhs or rhs is missing' unless lhs && rhs raise IllegalRange, 'lhs and rhs cannot be the same object' if lhs == rhs end diff --git a/lib/gitlab/relative_positioning/gap.rb b/lib/gitlab/relative_positioning/gap.rb index ab894141a60..2e30e598eb0 100644 --- a/lib/gitlab/relative_positioning/gap.rb +++ b/lib/gitlab/relative_positioning/gap.rb @@ -6,7 +6,8 @@ module Gitlab attr_reader :start_pos, :end_pos def initialize(start_pos, end_pos) - @start_pos, @end_pos = start_pos, end_pos + @start_pos = start_pos + @end_pos = end_pos end def ==(other) diff --git a/lib/gitlab/slash_commands/base_command.rb b/lib/gitlab/slash_commands/base_command.rb index fcc120112f2..e184afa0032 100644 --- a/lib/gitlab/slash_commands/base_command.rb +++ b/lib/gitlab/slash_commands/base_command.rb @@ -36,7 +36,9 @@ module Gitlab attr_accessor :project, :current_user, :params, :chat_name def initialize(project, chat_name, params = {}) - @project, @current_user, @params = project, chat_name.user, params.dup + @project = project + @current_user = chat_name.user + @params = params.dup @chat_name = chat_name end diff --git a/lib/tasks/gitlab/db.rake b/lib/tasks/gitlab/db.rake index 676f97f6659..3baf4e7b7c6 100644 --- a/lib/tasks/gitlab/db.rake +++ b/lib/tasks/gitlab/db.rake @@ -221,7 +221,8 @@ namespace :gitlab do result_file = args[:result_file] || raise("Please specify result_file argument") raise "File exists already, won't overwrite: #{result_file}" if File.exist?(result_file) - verbose_was, ActiveRecord::Migration.verbose = ActiveRecord::Migration.verbose, true + verbose_was = ActiveRecord::Migration.verbose + ActiveRecord::Migration.verbose = true ctx = ActiveRecord::Base.connection.migration_context existing_versions = ctx.get_all_versions.to_set diff --git a/locale/gitlab.pot b/locale/gitlab.pot index da415e61dab..c7b3c85e5d2 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -553,7 +553,7 @@ msgstr "" msgid "%{gitlab_experience_text}. We won't share this information with anyone." msgstr "" -msgid "%{global_id} is not a valid ID for %{expected_type}." +msgid "%{global_id} is not a valid ID for %{expected_types}." msgstr "" msgid "%{group_docs_link_start}Groups%{group_docs_link_end} allow you to manage and collaborate across multiple projects. Members of a group have access to all of its projects." @@ -4938,6 +4938,9 @@ msgstr "" msgid "Below are the fingerprints for the current instance SSH host keys." msgstr "" +msgid "Below are the settings for %{link_to_gitlab_pages}." +msgstr "" + msgid "Below you will find all the groups that are public." msgstr "" @@ -6644,9 +6647,6 @@ msgstr "" msgid "Closes this %{quick_action_target}." msgstr "" -msgid "Cloud License" -msgstr "" - msgid "CloudLicense|Activate" msgstr "" @@ -11444,6 +11444,9 @@ msgstr "" msgid "Domain" msgstr "" +msgid "Domain Name" +msgstr "" + msgid "Domain cannot be deleted while associated to one or more clusters." msgstr "" @@ -13094,10 +13097,10 @@ msgstr "" msgid "ExternalWikiService|External wiki URL" msgstr "" -msgid "ExternalWikiService|Replaces the link to the internal wiki with a link to an external wiki." +msgid "ExternalWikiService|Link to an external wiki from the sidebar." msgstr "" -msgid "ExternalWikiService|The URL of the external wiki" +msgid "ExternalWikiService|https://example.com/xxx/wiki/..." msgstr "" msgid "Externally installed" @@ -19037,6 +19040,9 @@ msgstr "" msgid "Link Prometheus monitoring to GitLab." msgstr "" +msgid "Link an external wiki from the project's sidebar. %{docs_link}" +msgstr "" + msgid "Link copied" msgstr "" @@ -23813,6 +23819,9 @@ msgstr "" msgid "Popularity" msgstr "" +msgid "Port" +msgstr "" + msgid "Postman collection" msgstr "" @@ -31281,6 +31290,9 @@ msgstr "" msgid "The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0." msgstr "" +msgid "The maximum size of your Pages site is regulated by the artifacts maximum size which is part of %{link_to_gitlab_ci}." +msgstr "" + msgid "The merge conflicts for this merge request cannot be resolved through GitLab. Please try to resolve them locally." msgstr "" @@ -32815,6 +32827,9 @@ msgstr "" msgid "To get started, please enter your Gitea Host URL and a %{link_to_personal_token}." msgstr "" +msgid "To get started, use the link below to confirm your account." +msgstr "" + msgid "To help improve GitLab and its user experience, GitLab will periodically collect usage information." msgstr "" @@ -34110,6 +34125,9 @@ msgstr "" msgid "Use the link below to confirm your email address (%{email})" msgstr "" +msgid "Use the link below to confirm your email address." +msgstr "" + msgid "Use the search bar on the top of this page" msgstr "" diff --git a/package.json b/package.json index 9ee955bc9e2..a1db0434eb1 100644 --- a/package.json +++ b/package.json @@ -77,7 +77,7 @@ "codesandbox-api": "0.0.23", "compression-webpack-plugin": "^5.0.2", "copy-webpack-plugin": "^5.1.2", - "core-js": "^3.10.1", + "core-js": "^3.10.2", "cron-validator": "^1.1.1", "cropper": "^2.3.0", "css-loader": "^2.1.1", diff --git a/qa/qa/specs/features/browser_ui/2_plan/transient/comment_on_discussion_spec.rb b/qa/qa/specs/features/browser_ui/2_plan/transient/comment_on_discussion_spec.rb index cc03d6a7524..f2e4a320e04 100644 --- a/qa/qa/specs/features/browser_ui/2_plan/transient/comment_on_discussion_spec.rb +++ b/qa/qa/specs/features/browser_ui/2_plan/transient/comment_on_discussion_spec.rb @@ -29,7 +29,7 @@ module QA expect(issue_page).to have_comment(my_first_reply) - issue_page.reply_to_discussion(1, my_second_reply) + issue_page.reply_to_discussion(1, "#{my_second_reply}\n") expect(issue_page).to have_comment(my_second_reply) diff --git a/spec/finders/concerns/finder_with_group_hierarchy_spec.rb b/spec/finders/concerns/finder_with_group_hierarchy_spec.rb index b0c5f306665..8c2026a00a1 100644 --- a/spec/finders/concerns/finder_with_group_hierarchy_spec.rb +++ b/spec/finders/concerns/finder_with_group_hierarchy_spec.rb @@ -9,7 +9,8 @@ RSpec.describe FinderWithGroupHierarchy do include Gitlab::Utils::StrongMemoize def initialize(current_user, params = {}) - @current_user, @params = current_user, params + @current_user = current_user + @params = params end def execute(skip_authorization: false) diff --git a/spec/graphql/gitlab_schema_spec.rb b/spec/graphql/gitlab_schema_spec.rb index 4ddd74b1eb7..1f2c518f83c 100644 --- a/spec/graphql/gitlab_schema_spec.rb +++ b/spec/graphql/gitlab_schema_spec.rb @@ -206,18 +206,22 @@ RSpec.describe GitlabSchema do describe '.parse_gid' do let_it_be(:global_id) { 'gid://gitlab/TestOne/2147483647' } + subject(:parse_gid) { described_class.parse_gid(global_id) } + before do test_base = Class.new test_one = Class.new(test_base) test_two = Class.new(test_base) + test_three = Class.new(test_base) stub_const('TestBase', test_base) stub_const('TestOne', test_one) stub_const('TestTwo', test_two) + stub_const('TestThree', test_three) end it 'parses the gid' do - gid = described_class.parse_gid(global_id) + gid = parse_gid expect(gid.model_id).to eq '2147483647' expect(gid.model_class).to eq TestOne @@ -227,7 +231,7 @@ RSpec.describe GitlabSchema do let_it_be(:global_id) { 'malformed://gitlab/TestOne/2147483647' } it 'raises an error' do - expect { described_class.parse_gid(global_id) } + expect { parse_gid } .to raise_error(Gitlab::Graphql::Errors::ArgumentError, "#{global_id} is not a valid GitLab ID.") end end @@ -249,6 +253,33 @@ RSpec.describe GitlabSchema do expect { described_class.parse_gid(global_id, expected_type: TestTwo) } .to raise_error(Gitlab::Graphql::Errors::ArgumentError, "#{global_id} is not a valid ID for TestTwo.") end + + context 'when expected_type is an array' do + subject(:parse_gid) { described_class.parse_gid(global_id, expected_type: [TestOne, TestTwo]) } + + context 'when global_id is of type TestOne' do + it 'returns an object of an expected type' do + expect(parse_gid.model_class).to eq TestOne + end + end + + context 'when global_id is of type TestTwo' do + let_it_be(:global_id) { 'gid://gitlab/TestTwo/2147483647' } + + it 'returns an object of an expected type' do + expect(parse_gid.model_class).to eq TestTwo + end + end + + context 'when global_id is of type TestThree' do + let_it_be(:global_id) { 'gid://gitlab/TestThree/2147483647' } + + it 'rejects an unknown type' do + expect { parse_gid } + .to raise_error(Gitlab::Graphql::Errors::ArgumentError, "#{global_id} is not a valid ID for TestOne, TestTwo.") + end + end + end end end diff --git a/spec/graphql/resolvers/alert_management/http_integrations_resolver_spec.rb b/spec/graphql/resolvers/alert_management/http_integrations_resolver_spec.rb index 2cd61dd7bcf..a4d1101bc4f 100644 --- a/spec/graphql/resolvers/alert_management/http_integrations_resolver_spec.rb +++ b/spec/graphql/resolvers/alert_management/http_integrations_resolver_spec.rb @@ -14,7 +14,9 @@ RSpec.describe Resolvers::AlertManagement::HttpIntegrationsResolver do let_it_be(:inactive_http_integration) { create(:alert_management_http_integration, :inactive, project: project) } let_it_be(:other_proj_integration) { create(:alert_management_http_integration) } - subject { sync(resolve_http_integrations) } + let(:params) { {} } + + subject { sync(resolve_http_integrations(params)) } before do project.add_developer(developer) @@ -41,11 +43,25 @@ RSpec.describe Resolvers::AlertManagement::HttpIntegrationsResolver do let(:current_user) { maintainer } it { is_expected.to contain_exactly(active_http_integration) } + + context 'when HTTP Integration ID is given' do + context 'when integration is from the current project' do + let(:params) { { id: global_id_of(inactive_http_integration) } } + + it { is_expected.to contain_exactly(inactive_http_integration) } + end + + context 'when integration is from other project' do + let(:params) { { id: global_id_of(other_proj_integration) } } + + it { is_expected.to be_empty } + end + end end private def resolve_http_integrations(args = {}, context = { current_user: current_user }) - resolve(described_class, obj: project, ctx: context) + resolve(described_class, obj: project, args: args, ctx: context) end end diff --git a/spec/graphql/resolvers/alert_management/integrations_resolver_spec.rb b/spec/graphql/resolvers/alert_management/integrations_resolver_spec.rb index 36e409e0677..fb0fb6729d4 100644 --- a/spec/graphql/resolvers/alert_management/integrations_resolver_spec.rb +++ b/spec/graphql/resolvers/alert_management/integrations_resolver_spec.rb @@ -7,12 +7,16 @@ RSpec.describe Resolvers::AlertManagement::IntegrationsResolver do let_it_be(:current_user) { create(:user) } let_it_be(:project) { create(:project) } + let_it_be(:project2) { create(:project) } let_it_be(:prometheus_integration) { create(:prometheus_service, project: project) } let_it_be(:active_http_integration) { create(:alert_management_http_integration, project: project) } let_it_be(:inactive_http_integration) { create(:alert_management_http_integration, :inactive, project: project) } - let_it_be(:other_proj_integration) { create(:alert_management_http_integration) } + let_it_be(:other_proj_integration) { create(:alert_management_http_integration, project: project2) } + let_it_be(:other_proj_prometheus_integration) { create(:prometheus_service, project: project2) } - subject { sync(resolve_http_integrations) } + let(:params) { {} } + + subject { sync(resolve_http_integrations(params)) } specify do expect(described_class).to have_nullable_graphql_type(Types::AlertManagement::IntegrationType.connection_type) @@ -25,14 +29,43 @@ RSpec.describe Resolvers::AlertManagement::IntegrationsResolver do context 'user has permission' do before do project.add_maintainer(current_user) + project2.add_maintainer(current_user) end it { is_expected.to contain_exactly(active_http_integration, prometheus_integration) } + + context 'when HTTP Integration ID is given' do + context 'when integration is from the current project' do + let(:params) { { id: global_id_of(inactive_http_integration) } } + + it { is_expected.to contain_exactly(inactive_http_integration) } + end + + context 'when integration is from other project' do + let(:params) { { id: global_id_of(other_proj_integration) } } + + it { is_expected.to be_empty } + end + end + + context 'when Prometheus Integration ID is given' do + context 'when integration is from the current project' do + let(:params) { { id: global_id_of(prometheus_integration) } } + + it { is_expected.to contain_exactly(prometheus_integration) } + end + + context 'when integration is from other project' do + let(:params) { { id: global_id_of(other_proj_prometheus_integration) } } + + it { is_expected.to be_empty } + end + end end private def resolve_http_integrations(args = {}, context = { current_user: current_user }) - resolve(described_class, obj: project, ctx: context) + resolve(described_class, obj: project, args: args, ctx: context) end end diff --git a/spec/lib/gitlab/database/migration_helpers_spec.rb b/spec/lib/gitlab/database/migration_helpers_spec.rb index ac1d89b4225..44293086e79 100644 --- a/spec/lib/gitlab/database/migration_helpers_spec.rb +++ b/spec/lib/gitlab/database/migration_helpers_spec.rb @@ -835,7 +835,7 @@ RSpec.describe Gitlab::Database::MigrationHelpers do expect(model).to receive(:check_trigger_permissions!).with(:users) expect(model).to receive(:install_rename_triggers_for_postgresql) - .with(trigger_name, '"users"', '"old"', '"new"') + .with(:users, :old, :new) expect(model).to receive(:add_column) .with(:users, :new, :integer, @@ -860,14 +860,18 @@ RSpec.describe Gitlab::Database::MigrationHelpers do context 'with existing records and type casting' do let(:trigger_name) { model.rename_trigger_name(:users, :id, :new) } let(:user) { create(:user) } + let(:copy_trigger) { double('copy trigger') } + + before do + expect(Gitlab::Database::UnidirectionalCopyTrigger).to receive(:on_table) + .with(:users).and_return(copy_trigger) + end it 'copies the value to the new column using the type_cast_function', :aggregate_failures do expect(model).to receive(:copy_indexes).with(:users, :id, :new) expect(model).to receive(:add_not_null_constraint).with(:users, :new) expect(model).to receive(:execute).with("UPDATE \"users\" SET \"new\" = cast_to_jsonb_with_default(\"users\".\"id\") WHERE \"users\".\"id\" >= #{user.id}") - expect(model).to receive(:execute).with("DROP TRIGGER IF EXISTS #{trigger_name}\nON \"users\"\n") - expect(model).to receive(:execute).with("CREATE TRIGGER #{trigger_name}\nBEFORE INSERT OR UPDATE\nON \"users\"\nFOR EACH ROW\nEXECUTE FUNCTION #{trigger_name}()\n") - expect(model).to receive(:execute).with("CREATE OR REPLACE FUNCTION #{trigger_name}()\nRETURNS trigger AS\n$BODY$\nBEGIN\n NEW.\"new\" := NEW.\"id\";\n RETURN NEW;\nEND;\n$BODY$\nLANGUAGE 'plpgsql'\nVOLATILE\n") + expect(copy_trigger).to receive(:create).with(:id, :new, trigger_name: nil) model.rename_column_concurrently(:users, :id, :new, type_cast_function: 'cast_to_jsonb_with_default') end @@ -996,7 +1000,7 @@ RSpec.describe Gitlab::Database::MigrationHelpers do expect(model).to receive(:check_trigger_permissions!).with(:users) expect(model).to receive(:install_rename_triggers_for_postgresql) - .with(trigger_name, '"users"', '"old"', '"new"') + .with(:users, :old, :new) expect(model).to receive(:add_column) .with(:users, :old, :integer, @@ -1156,7 +1160,7 @@ RSpec.describe Gitlab::Database::MigrationHelpers do .with(:users, temp_undo_cleanup_column, :old) expect(model).to receive(:install_rename_triggers_for_postgresql) - .with(trigger_name, '"users"', '"old"', '"old_for_type_change"') + .with(:users, :old, 'old_for_type_change') model.undo_cleanup_concurrent_column_type_change(:users, :old, :string) end @@ -1182,7 +1186,7 @@ RSpec.describe Gitlab::Database::MigrationHelpers do .with(:users, temp_undo_cleanup_column, :old) expect(model).to receive(:install_rename_triggers_for_postgresql) - .with(trigger_name, '"users"', '"old"', '"old_for_type_change"') + .with(:users, :old, 'old_for_type_change') model.undo_cleanup_concurrent_column_type_change( :users, @@ -1204,28 +1208,25 @@ RSpec.describe Gitlab::Database::MigrationHelpers do describe '#install_rename_triggers_for_postgresql' do it 'installs the triggers for PostgreSQL' do - expect(model).to receive(:execute) - .with(/CREATE OR REPLACE FUNCTION foo()/m) + copy_trigger = double('copy trigger') - expect(model).to receive(:execute) - .with(/DROP TRIGGER IF EXISTS foo/m) + expect(Gitlab::Database::UnidirectionalCopyTrigger).to receive(:on_table) + .with(:users).and_return(copy_trigger) - expect(model).to receive(:execute) - .with(/CREATE TRIGGER foo/m) + expect(copy_trigger).to receive(:create).with(:old, :new, trigger_name: 'foo') - model.install_rename_triggers_for_postgresql('foo', :users, :old, :new) - end - - it 'does not fail if trigger already exists' do - model.install_rename_triggers_for_postgresql('foo', :users, :old, :new) - model.install_rename_triggers_for_postgresql('foo', :users, :old, :new) + model.install_rename_triggers_for_postgresql(:users, :old, :new, trigger_name: 'foo') end end describe '#remove_rename_triggers_for_postgresql' do it 'removes the function and trigger' do - expect(model).to receive(:execute).with('DROP TRIGGER IF EXISTS foo ON bar') - expect(model).to receive(:execute).with('DROP FUNCTION IF EXISTS foo()') + copy_trigger = double('copy trigger') + + expect(Gitlab::Database::UnidirectionalCopyTrigger).to receive(:on_table) + .with('bar').and_return(copy_trigger) + + expect(copy_trigger).to receive(:drop).with('foo') model.remove_rename_triggers_for_postgresql('bar', 'foo') end diff --git a/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_base_spec.rb b/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_base_spec.rb index 757da2d9092..1edcd890370 100644 --- a/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_base_spec.rb +++ b/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_base_spec.rb @@ -246,7 +246,8 @@ RSpec.describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameBase, : subject.track_rename('namespace', 'path/to/namespace', 'path/to/renamed') - old_path, new_path = [nil, nil] + old_path = nil + new_path = nil Gitlab::Redis::SharedState.with do |redis| rename_info = redis.lpop(key) old_path, new_path = Gitlab::Json.parse(rename_info) diff --git a/spec/lib/gitlab/database/unidirectional_copy_trigger_spec.rb b/spec/lib/gitlab/database/unidirectional_copy_trigger_spec.rb new file mode 100644 index 00000000000..2955c208f16 --- /dev/null +++ b/spec/lib/gitlab/database/unidirectional_copy_trigger_spec.rb @@ -0,0 +1,191 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Gitlab::Database::UnidirectionalCopyTrigger do + include Database::TriggerHelpers + + let(:table_name) { '_test_table' } + let(:connection) { ActiveRecord::Base.connection } + let(:copy_trigger) { described_class.on_table(table_name) } + + describe '#name' do + context 'when a single column name is given' do + subject(:trigger_name) { copy_trigger.name('id', 'other_id') } + + it 'returns the trigger name' do + expect(trigger_name).to eq('trigger_cfce7a56a9d6') + end + end + + context 'when multiple column names are given' do + subject(:trigger_name) { copy_trigger.name(%w[id fk_id], %w[other_id other_fk_id]) } + + it 'returns the trigger name' do + expect(trigger_name).to eq('trigger_166626e51481') + end + end + + context 'when a different number of new and old column names are given' do + it 'raises an error' do + expect do + copy_trigger.name(%w[id fk_id], %w[other_id]) + end.to raise_error(ArgumentError, 'number of source and destination columns must match') + end + end + end + + describe '#create' do + let(:model) { Class.new(ActiveRecord::Base) } + + before do + connection.execute(<<~SQL) + CREATE TABLE #{table_name} ( + id serial NOT NULL PRIMARY KEY, + other_id integer, + fk_id bigint, + other_fk_id bigint); + SQL + + model.table_name = table_name + end + + context 'when a single column name is given' do + let(:trigger_name) { 'trigger_cfce7a56a9d6' } + + it 'creates the trigger and function' do + expect_function_not_to_exist(trigger_name) + expect_trigger_not_to_exist(table_name, trigger_name) + + copy_trigger.create('id', 'other_id') + + expect_function_to_exist(trigger_name) + expect_valid_function_trigger(table_name, trigger_name, trigger_name, before: %w[insert update]) + end + + it 'properly copies the column data using the trigger function' do + copy_trigger.create('id', 'other_id') + + record = model.create!(id: 10) + expect(record.reload).to have_attributes(other_id: 10) + + record.update!({ id: 20 }) + expect(record.reload).to have_attributes(other_id: 20) + end + end + + context 'when multiple column names are given' do + let(:trigger_name) { 'trigger_166626e51481' } + + it 'creates the trigger and function to set all the columns' do + expect_function_not_to_exist(trigger_name) + expect_trigger_not_to_exist(table_name, trigger_name) + + copy_trigger.create(%w[id fk_id], %w[other_id other_fk_id]) + + expect_function_to_exist(trigger_name) + expect_valid_function_trigger(table_name, trigger_name, trigger_name, before: %w[insert update]) + end + + it 'properly copies the columns using the trigger function' do + copy_trigger.create(%w[id fk_id], %w[other_id other_fk_id]) + + record = model.create!(id: 10, fk_id: 20) + expect(record.reload).to have_attributes(other_id: 10, other_fk_id: 20) + + record.update!(id: 30, fk_id: 50) + expect(record.reload).to have_attributes(other_id: 30, other_fk_id: 50) + end + end + + context 'when a custom trigger name is given' do + let(:trigger_name) { '_test_trigger' } + + it 'creates the trigger and function with the custom name' do + expect_function_not_to_exist(trigger_name) + expect_trigger_not_to_exist(table_name, trigger_name) + + copy_trigger.create('id', 'other_id', trigger_name: trigger_name) + + expect_function_to_exist(trigger_name) + expect_valid_function_trigger(table_name, trigger_name, trigger_name, before: %w[insert update]) + end + end + + context 'when the trigger function already exists' do + let(:trigger_name) { 'trigger_cfce7a56a9d6' } + + it 'does not raise an error' do + expect_function_not_to_exist(trigger_name) + expect_trigger_not_to_exist(table_name, trigger_name) + + copy_trigger.create('id', 'other_id') + + expect_function_to_exist(trigger_name) + expect_valid_function_trigger(table_name, trigger_name, trigger_name, before: %w[insert update]) + + copy_trigger.create('id', 'other_id') + + expect_function_to_exist(trigger_name) + expect_valid_function_trigger(table_name, trigger_name, trigger_name, before: %w[insert update]) + end + end + + context 'when a different number of new and old column names are given' do + it 'raises an error' do + expect do + copy_trigger.create(%w[id fk_id], %w[other_id]) + end.to raise_error(ArgumentError, 'number of source and destination columns must match') + end + end + end + + describe '#drop' do + let(:trigger_name) { '_test_trigger' } + + before do + connection.execute(<<~SQL) + CREATE TABLE #{table_name} ( + id serial NOT NULL PRIMARY KEY, + other_id integer NOT NULL); + + CREATE FUNCTION #{trigger_name}() + RETURNS trigger + LANGUAGE plpgsql AS + $$ + BEGIN + RAISE NOTICE 'hello'; + RETURN NEW; + END + $$; + + CREATE TRIGGER #{trigger_name} + BEFORE INSERT OR UPDATE + ON #{table_name} + FOR EACH ROW + EXECUTE FUNCTION #{trigger_name}(); + SQL + end + + it 'drops the trigger and function for the given arguments' do + expect_function_to_exist(trigger_name) + expect_valid_function_trigger(table_name, trigger_name, trigger_name, before: %w[insert update]) + + copy_trigger.drop(trigger_name) + + expect_trigger_not_to_exist(table_name, trigger_name) + expect_function_not_to_exist(trigger_name) + end + + context 'when the trigger does not exist' do + it 'does not raise an error' do + copy_trigger.drop(trigger_name) + + expect_trigger_not_to_exist(table_name, trigger_name) + expect_function_not_to_exist(trigger_name) + + copy_trigger.drop(trigger_name) + end + end + end +end diff --git a/spec/lib/gitlab/diff/lines_unfolder_spec.rb b/spec/lib/gitlab/diff/lines_unfolder_spec.rb index 4163c0eced5..8385cba3532 100644 --- a/spec/lib/gitlab/diff/lines_unfolder_spec.rb +++ b/spec/lib/gitlab/diff/lines_unfolder_spec.rb @@ -302,7 +302,8 @@ RSpec.describe Gitlab::Diff::LinesUnfolder do new_diff_lines = subject.unfolded_diff_lines new_diff_lines.each_with_index do |line, i| - old_pos, new_pos = expected_diff_lines[i][0], expected_diff_lines[i][1] + old_pos = expected_diff_lines[i][0] + new_pos = expected_diff_lines[i][1] unless line.type == 'match' expect(line.line_code).to eq(Gitlab::Git.diff_line_code(diff_file.file_path, new_pos, old_pos)) @@ -396,7 +397,8 @@ RSpec.describe Gitlab::Diff::LinesUnfolder do new_diff_lines = subject.unfolded_diff_lines new_diff_lines.each_with_index do |line, i| - old_pos, new_pos = expected_diff_lines[i][0], expected_diff_lines[i][1] + old_pos = expected_diff_lines[i][0] + new_pos = expected_diff_lines[i][1] unless line.type == 'match' expect(line.line_code).to eq(Gitlab::Git.diff_line_code(diff_file.file_path, new_pos, old_pos)) @@ -490,7 +492,8 @@ RSpec.describe Gitlab::Diff::LinesUnfolder do new_diff_lines = subject.unfolded_diff_lines new_diff_lines.each_with_index do |line, i| - old_pos, new_pos = expected_diff_lines[i][0], expected_diff_lines[i][1] + old_pos = expected_diff_lines[i][0] + new_pos = expected_diff_lines[i][1] unless line.type == 'match' expect(line.line_code).to eq(Gitlab::Git.diff_line_code(diff_file.file_path, new_pos, old_pos)) @@ -581,7 +584,8 @@ RSpec.describe Gitlab::Diff::LinesUnfolder do new_diff_lines = subject.unfolded_diff_lines new_diff_lines.each_with_index do |line, i| - old_pos, new_pos = expected_diff_lines[i][0], expected_diff_lines[i][1] + old_pos = expected_diff_lines[i][0] + new_pos = expected_diff_lines[i][1] unless line.type == 'match' expect(line.line_code).to eq(Gitlab::Git.diff_line_code(diff_file.file_path, new_pos, old_pos)) @@ -691,7 +695,8 @@ RSpec.describe Gitlab::Diff::LinesUnfolder do new_diff_lines = subject.unfolded_diff_lines new_diff_lines.each_with_index do |line, i| - old_pos, new_pos = expected_diff_lines[i][0], expected_diff_lines[i][1] + old_pos = expected_diff_lines[i][0] + new_pos = expected_diff_lines[i][1] unless line.type == 'match' expect(line.line_code).to eq(Gitlab::Git.diff_line_code(diff_file.file_path, new_pos, old_pos)) @@ -783,7 +788,8 @@ RSpec.describe Gitlab::Diff::LinesUnfolder do new_diff_lines = subject.unfolded_diff_lines new_diff_lines.each_with_index do |line, i| - old_pos, new_pos = expected_diff_lines[i][0], expected_diff_lines[i][1] + old_pos = expected_diff_lines[i][0] + new_pos = expected_diff_lines[i][1] unless line.type == 'match' expect(line.line_code).to eq(Gitlab::Git.diff_line_code(diff_file.file_path, new_pos, old_pos)) diff --git a/spec/lib/gitlab/diff/suggestions_parser_spec.rb b/spec/lib/gitlab/diff/suggestions_parser_spec.rb index 5efce414dc8..a00c55d4fb2 100644 --- a/spec/lib/gitlab/diff/suggestions_parser_spec.rb +++ b/spec/lib/gitlab/diff/suggestions_parser_spec.rb @@ -56,7 +56,8 @@ RSpec.describe Gitlab::Diff::SuggestionsParser do end it 'parsed suggestion has correct data' do - from_line, to_line = position.new_line, position.new_line + from_line = position.new_line + to_line = position.new_line expect(subject.first.to_hash).to include(from_content: blob_lines_data(from_line, to_line), to_content: " foo\n bar\n", diff --git a/spec/lib/gitlab/markdown_cache/redis/extension_spec.rb b/spec/lib/gitlab/markdown_cache/redis/extension_spec.rb index 3dcb9f160ba..b5d458f15fc 100644 --- a/spec/lib/gitlab/markdown_cache/redis/extension_spec.rb +++ b/spec/lib/gitlab/markdown_cache/redis/extension_spec.rb @@ -7,7 +7,8 @@ RSpec.describe Gitlab::MarkdownCache::Redis::Extension, :clean_gitlab_redis_cach include CacheMarkdownField def initialize(title: nil, description: nil) - @title, @description = title, description + @title = title + @description = description end attr_reader :title, :description diff --git a/spec/lib/gitlab/utils/lazy_attributes_spec.rb b/spec/lib/gitlab/utils/lazy_attributes_spec.rb index dfffe70defb..1ebc9b0d711 100644 --- a/spec/lib/gitlab/utils/lazy_attributes_spec.rb +++ b/spec/lib/gitlab/utils/lazy_attributes_spec.rb @@ -13,8 +13,10 @@ RSpec.describe Gitlab::Utils::LazyAttributes do def initialize @number = -> { 1 } - @reader_1, @reader_2 = 'reader_1', -> { 'reader_2' } - @incorrect_type, @accessor_2 = -> { :incorrect_type }, -> { 'accessor_2' } + @reader_1 = 'reader_1' + @reader_2 = -> { 'reader_2' } + @incorrect_type = -> { :incorrect_type } + @accessor_2 = -> { 'accessor_2' } end end end diff --git a/spec/models/concerns/cache_markdown_field_spec.rb b/spec/models/concerns/cache_markdown_field_spec.rb index 6e62d4ef31b..33a4c8eac41 100644 --- a/spec/models/concerns/cache_markdown_field_spec.rb +++ b/spec/models/concerns/cache_markdown_field_spec.rb @@ -17,9 +17,13 @@ RSpec.describe CacheMarkdownField, :clean_gitlab_redis_cache do include CacheMarkdownField def initialize(args = {}) - @title, @description, @cached_markdown_version = args[:title], args[:description], args[:cached_markdown_version] - @title_html, @description_html = args[:title_html], args[:description_html] - @author, @project = args[:author], args[:project] + @title = args[:title] + @description = args[:description] + @cached_markdown_version = args[:cached_markdown_version] + @title_html = args[:title_html] + @description_html = args[:description_html] + @author = args[:author] + @project = args[:project] @parent_user = args[:parent_user] end diff --git a/spec/models/repository_spec.rb b/spec/models/repository_spec.rb index c1a292c9b30..a739f523008 100644 --- a/spec/models/repository_spec.rb +++ b/spec/models/repository_spec.rb @@ -1103,7 +1103,8 @@ RSpec.describe Repository do describe '#create_ref' do it 'redirects the call to write_ref' do - ref, ref_path = '1', '2' + ref = '1' + ref_path = '2' expect(repository.raw_repository).to receive(:write_ref).with(ref_path, ref) diff --git a/spec/requests/api/graphql/project/alert_management/integrations_spec.rb b/spec/requests/api/graphql/project/alert_management/integrations_spec.rb index b13805a61ce..0e029aee9e8 100644 --- a/spec/requests/api/graphql/project/alert_management/integrations_spec.rb +++ b/spec/requests/api/graphql/project/alert_management/integrations_spec.rb @@ -13,6 +13,8 @@ RSpec.describe 'getting Alert Management Integrations' do let_it_be(:inactive_http_integration) { create(:alert_management_http_integration, :inactive, project: project) } let_it_be(:other_project_http_integration) { create(:alert_management_http_integration) } + let(:params) { {} } + let(:fields) do <<~QUERY nodes { @@ -25,7 +27,7 @@ RSpec.describe 'getting Alert Management Integrations' do graphql_query_for( 'project', { 'fullPath' => project.full_path }, - query_graphql_field('alertManagementIntegrations', {}, fields) + query_graphql_field('alertManagementIntegrations', params, fields) ) end @@ -50,34 +52,78 @@ RSpec.describe 'getting Alert Management Integrations' do post_graphql(query, current_user: current_user) end - let(:http_integration) { integrations.first } - let(:prometheus_integration) { integrations.second } + context 'when no extra params given' do + let(:http_integration) { integrations.first } + let(:prometheus_integration) { integrations.second } - it_behaves_like 'a working graphql query' + it_behaves_like 'a working graphql query' + + it { expect(integrations.size).to eq(2) } + + it 'returns the correct properties of the integrations' do + expect(http_integration).to include( + 'id' => global_id_of(active_http_integration), + 'type' => 'HTTP', + 'name' => active_http_integration.name, + 'active' => active_http_integration.active, + 'token' => active_http_integration.token, + 'url' => active_http_integration.url, + 'apiUrl' => nil + ) - it { expect(integrations.size).to eq(2) } - - it 'returns the correct properties of the integrations' do - expect(http_integration).to include( - 'id' => GitlabSchema.id_from_object(active_http_integration).to_s, - 'type' => 'HTTP', - 'name' => active_http_integration.name, - 'active' => active_http_integration.active, - 'token' => active_http_integration.token, - 'url' => active_http_integration.url, - 'apiUrl' => nil - ) - - expect(prometheus_integration).to include( - 'id' => GitlabSchema.id_from_object(prometheus_service).to_s, - 'type' => 'PROMETHEUS', - 'name' => 'Prometheus', - 'active' => prometheus_service.manual_configuration?, - 'token' => project_alerting_setting.token, - 'url' => "http://localhost/#{project.full_path}/prometheus/alerts/notify.json", - 'apiUrl' => prometheus_service.api_url - ) + expect(prometheus_integration).to include( + 'id' => global_id_of(prometheus_service), + 'type' => 'PROMETHEUS', + 'name' => 'Prometheus', + 'active' => prometheus_service.manual_configuration?, + 'token' => project_alerting_setting.token, + 'url' => "http://localhost/#{project.full_path}/prometheus/alerts/notify.json", + 'apiUrl' => prometheus_service.api_url + ) + end end + + context 'when HTTP Integration ID is given' do + let(:params) { { id: global_id_of(active_http_integration) } } + + it_behaves_like 'a working graphql query' + + it { expect(integrations).to be_one } + + it 'returns the correct properties of the HTTP integration' do + expect(integrations.first).to include( + 'id' => global_id_of(active_http_integration), + 'type' => 'HTTP', + 'name' => active_http_integration.name, + 'active' => active_http_integration.active, + 'token' => active_http_integration.token, + 'url' => active_http_integration.url, + 'apiUrl' => nil + ) + end + end + + context 'when Prometheus Integration ID is given' do + let(:params) { { id: global_id_of(prometheus_service) } } + + it_behaves_like 'a working graphql query' + + it { expect(integrations).to be_one } + + it 'returns the correct properties of the Prometheus Integration' do + expect(integrations.first).to include( + 'id' => global_id_of(prometheus_service), + 'type' => 'PROMETHEUS', + 'name' => 'Prometheus', + 'active' => prometheus_service.manual_configuration?, + 'token' => project_alerting_setting.token, + 'url' => "http://localhost/#{project.full_path}/prometheus/alerts/notify.json", + 'apiUrl' => prometheus_service.api_url + ) + end + end + + it_behaves_like 'GraphQL query with several integrations requested', graphql_query_name: 'alertManagementIntegrations' end end end diff --git a/spec/support/helpers/graphql_helpers.rb b/spec/support/helpers/graphql_helpers.rb index fc21efa6db4..d714f04fbba 100644 --- a/spec/support/helpers/graphql_helpers.rb +++ b/spec/support/helpers/graphql_helpers.rb @@ -307,7 +307,10 @@ module GraphqlHelpers def query_graphql_field(name, attributes = {}, fields = nil, type = nil) type ||= name.to_s.classify - attributes, fields = [nil, attributes] if fields.nil? && !attributes.is_a?(Hash) + if fields.nil? && !attributes.is_a?(Hash) + fields = attributes + attributes = nil + end field = field_with_params(name, attributes) diff --git a/spec/support/helpers/key_generator_helper.rb b/spec/support/helpers/key_generator_helper.rb index 59c8eeb3692..58bde80a31f 100644 --- a/spec/support/helpers/key_generator_helper.rb +++ b/spec/support/helpers/key_generator_helper.rb @@ -27,7 +27,8 @@ module Spec # Encodes an openssh-mpi-encoded integer. def encode_mpi(n) # rubocop:disable Naming/UncommunicativeMethodParamName - chars, n = [], n.to_i + chars = [] + n = n.to_i chars << (n & 0xff) && n >>= 8 while n != 0 chars << 0 if chars.empty? || chars.last >= 0x80 chars.reverse.pack('C*') diff --git a/spec/support/shared_examples/requests/api/graphql/projects/alert_management/integrations_shared_examples.rb b/spec/support/shared_examples/requests/api/graphql/projects/alert_management/integrations_shared_examples.rb new file mode 100644 index 00000000000..c134f7d1839 --- /dev/null +++ b/spec/support/shared_examples/requests/api/graphql/projects/alert_management/integrations_shared_examples.rb @@ -0,0 +1,49 @@ +# frozen_string_literal: true + +RSpec.shared_examples 'GraphQL query with several integrations requested' do |graphql_query_name:| + context 'when several HTTP integrations requested' do + let(:params_ai) { { id: global_id_of(active_http_integration) } } + let(:params_ii) { { id: global_id_of(inactive_http_integration) } } + let(:fields) { "nodes { id name }" } + + let(:single_selection_query) do + graphql_query_for( + 'project', + { 'fullPath' => project.full_path }, + <<~QUERY + ai: #{query_graphql_field(graphql_query_name, params_ai, fields)} + QUERY + ) + end + + let(:multi_selection_query) do + graphql_query_for( + 'project', + { 'fullPath' => project.full_path }, + <<~QUERY + ai: #{query_graphql_field(graphql_query_name, params_ai, fields)} + ii: #{query_graphql_field(graphql_query_name, params_ii, fields)} + QUERY + ) + end + + it 'returns the correct properties of the integrations', :aggregate_failures do + post_graphql(multi_selection_query, current_user: current_user) + + expect(graphql_data.dig('project', 'ai', 'nodes')).to include( + 'id' => global_id_of(active_http_integration), + 'name' => active_http_integration.name + ) + + expect(graphql_data.dig('project', 'ii', 'nodes')).to include( + 'id' => global_id_of(inactive_http_integration), + 'name' => inactive_http_integration.name + ) + end + + it 'batches queries' do + expect { post_graphql(multi_selection_query, current_user: current_user) } + .to issue_same_number_of_queries_as { post_graphql(single_selection_query, current_user: current_user) }.ignoring_cached_queries + end + end +end diff --git a/spec/validators/x509_certificate_credentials_validator_spec.rb b/spec/validators/x509_certificate_credentials_validator_spec.rb index 9baa31c7257..9076aee7681 100644 --- a/spec/validators/x509_certificate_credentials_validator_spec.rb +++ b/spec/validators/x509_certificate_credentials_validator_spec.rb @@ -13,7 +13,9 @@ RSpec.describe X509CertificateCredentialsValidator do attr_accessor :certificate, :private_key, :passphrase def initialize(certificate, private_key, passphrase = nil) - @certificate, @private_key, @passphrase = certificate, private_key, passphrase + @certificate = certificate + @private_key = private_key + @passphrase = passphrase end end end diff --git a/yarn.lock b/yarn.lock index de7810e1d45..0d312032ce2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3387,10 +3387,10 @@ core-js-pure@^3.0.0: resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.6.5.tgz#c79e75f5e38dbc85a662d91eea52b8256d53b813" integrity sha512-lacdXOimsiD0QyNf9BC/mxivNJ/ybBGJXQFKzRekp1WTHoVUWsUHEn+2T8GJAzzIhyOuXA+gOxCVN3l+5PLPUA== -core-js@^3.1.3, core-js@^3.10.1: - version "3.10.1" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.10.1.tgz#e683963978b6806dcc6c0a4a8bd4ab0bdaf3f21a" - integrity sha512-pwCxEXnj27XG47mu7SXAwhLP3L5CrlvCB91ANUkIz40P27kUcvNfSdvyZJ9CLHiVoKSp+TTChMQMSKQEH/IQxA== +core-js@^3.1.3, core-js@^3.10.2: + version "3.10.2" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.10.2.tgz#17cb038ce084522a717d873b63f2b3ee532e2cd5" + integrity sha512-W+2oVYeNghuBr3yTzZFQ5rfmjZtYB/Ubg87R5YOmlGrIb+Uw9f7qjUbhsj+/EkXhcV7eOD3jiM4+sgraX3FZUw== core-js@~2.3.0: version "2.3.0" |