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

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.rubocop_manual_todo.yml2
-rw-r--r--.rubocop_todo.yml5
-rw-r--r--app/finders/ci/pipelines_finder.rb2
-rw-r--r--app/helpers/services_helper.rb24
-rw-r--r--app/models/ci/build.rb3
-rw-r--r--app/models/ci/stage.rb2
-rw-r--r--app/models/clusters/clusters_hierarchy.rb2
-rw-r--r--app/models/commit_status.rb2
-rw-r--r--app/models/environment.rb2
-rw-r--r--app/models/project.rb2
-rw-r--r--app/models/project_services/microsoft_teams_service.rb14
-rw-r--r--app/models/user.rb9
-rw-r--r--app/services/ci/cancel_user_pipelines_service.rb18
-rw-r--r--app/services/ci/retry_build_service.rb2
-rw-r--r--app/services/ci/retry_pipeline_service.rb2
-rw-r--r--app/services/merge_requests/base_service.rb2
-rw-r--r--app/services/namespaces/in_product_marketing_emails_service.rb2
-rw-r--r--app/services/todos/destroy/base_service.rb2
-rw-r--r--app/services/todos/destroy/private_features_service.rb2
-rw-r--r--app/workers/all_queues.yml8
-rw-r--r--app/workers/build_finished_worker.rb4
-rw-r--r--app/workers/ci/merge_requests/add_todo_when_build_fails_worker.rb21
-rw-r--r--changelogs/unreleased/324045-remove-feature-flag.yml5
-rw-r--r--changelogs/unreleased/325509-set-namespaces-traversal_ids-for-production-gitlab-org-group.yml5
-rw-r--r--changelogs/unreleased/issue-220040-fix-rails-savebang-banzai-module.yml5
-rw-r--r--changelogs/unreleased/pl-rubocop-todo-where-not.yml5
-rw-r--r--config/feature_flags/development/async_add_build_failure_todo.yml (renamed from config/feature_flags/development/abort_user_pipelines_on_block.yml)10
-rw-r--r--config/metrics/schema.json4
-rw-r--r--db/post_migrate/20200406102120_backfill_deployment_clusters_from_deployments.rb2
-rw-r--r--db/post_migrate/20200811130433_create_missing_vulnerabilities_issue_links.rb4
-rw-r--r--db/post_migrate/20210311045139_set_traversal_ids_for_gitlab_org_group_com.rb88
-rw-r--r--db/schema_migrations/202103110451391
-rw-r--r--doc/user/project/integrations/img/microsoft_teams_configuration.pngbin29336 -> 0 bytes
-rw-r--r--doc/user/project/integrations/microsoft_teams.md82
-rw-r--r--lib/gitlab/background_migration/populate_merge_request_assignees_table.rb2
-rw-r--r--lib/gitlab/background_migration/wrongfully_confirmed_email_unconfirmer.rb2
-rw-r--r--lib/gitlab/import_export/uploads_manager.rb2
-rw-r--r--locale/gitlab.pot24
-rw-r--r--spec/lib/banzai/reference_parser/external_issue_parser_spec.rb2
-rw-r--r--spec/lib/banzai/reference_redactor_spec.rb2
-rw-r--r--spec/lib/gitlab/analytics/cycle_analytics/stage_events/code_stage_start_spec.rb2
-rw-r--r--spec/lib/gitlab/usage/metric_definition_spec.rb4
-rw-r--r--spec/migrations/clean_up_noteable_id_for_notes_on_commits_spec.rb2
-rw-r--r--spec/migrations/migrate_bot_type_to_user_type_spec.rb2
-rw-r--r--spec/models/ci/build_spec.rb43
-rw-r--r--spec/models/user_spec.rb26
-rw-r--r--spec/serializers/service_event_entity_spec.rb4
-rw-r--r--spec/services/ci/cancel_user_pipelines_service_spec.rb35
-rw-r--r--spec/services/ci/retry_build_service_spec.rb2
-rw-r--r--spec/services/ci/retry_pipeline_service_spec.rb2
-rw-r--r--spec/services/merge_requests/add_todo_when_build_fails_service_spec.rb6
-rw-r--r--spec/services/namespaces/in_product_marketing_emails_service_spec.rb2
-rw-r--r--spec/workers/build_finished_worker_spec.rb50
-rw-r--r--spec/workers/ci/merge_requests/add_todo_when_build_fails_worker_spec.rb53
-rwxr-xr-x[-rw-r--r--]vendor/gitignore/C++.gitignore0
-rwxr-xr-x[-rw-r--r--]vendor/gitignore/Java.gitignore0
56 files changed, 392 insertions, 218 deletions
diff --git a/.rubocop_manual_todo.yml b/.rubocop_manual_todo.yml
index 8e5b6a02b49..3569347dd43 100644
--- a/.rubocop_manual_todo.yml
+++ b/.rubocop_manual_todo.yml
@@ -232,8 +232,6 @@ Rails/SaveBang:
- 'spec/initializers/fog_google_https_private_urls_spec.rb'
- 'spec/lib/after_commit_queue_spec.rb'
- 'spec/lib/backup/manager_spec.rb'
- - 'spec/lib/banzai/reference_parser/external_issue_parser_spec.rb'
- - 'spec/lib/banzai/reference_redactor_spec.rb'
- 'spec/lib/gitlab/alerting/alert_spec.rb'
- 'spec/lib/gitlab/analytics/cycle_analytics/records_fetcher_spec.rb'
- 'spec/lib/gitlab/auth/ldap/user_spec.rb'
diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml
index f01dedb40dd..f06496d4519 100644
--- a/.rubocop_todo.yml
+++ b/.rubocop_todo.yml
@@ -640,11 +640,6 @@ Rails/WhereEquals:
Rails/WhereExists:
Enabled: false
-# Offense count: 21
-# Cop supports --auto-correct.
-Rails/WhereNot:
- Enabled: false
-
# Offense count: 8
# Cop supports --auto-correct.
Security/YAMLLoad:
diff --git a/app/finders/ci/pipelines_finder.rb b/app/finders/ci/pipelines_finder.rb
index a77faebb160..e509cf940b8 100644
--- a/app/finders/ci/pipelines_finder.rb
+++ b/app/finders/ci/pipelines_finder.rb
@@ -131,7 +131,7 @@ module Ci
def by_yaml_errors(items)
case Gitlab::Utils.to_boolean(params[:yaml_errors])
when true
- items.where("yaml_errors IS NOT NULL")
+ items.where.not(yaml_errors: nil)
when false
items.where("yaml_errors IS NULL")
else
diff --git a/app/helpers/services_helper.rb b/app/helpers/services_helper.rb
index 1bbfdb431de..666286b3016 100644
--- a/app/helpers/services_helper.rb
+++ b/app/helpers/services_helper.rb
@@ -4,29 +4,29 @@ module ServicesHelper
def service_event_description(event)
case event
when "push", "push_events"
- s_("ProjectService|Event will be triggered by a push to the repository")
+ s_("ProjectService|Event triggered when someone pushes to the repository.")
when "tag_push", "tag_push_events"
- s_("ProjectService|Event will be triggered when a new tag is pushed to the repository")
+ s_("ProjectService|Event triggered when a new tag is pushed to the repository.")
when "note", "note_events"
- s_("ProjectService|Event will be triggered when someone adds a comment")
+ s_("ProjectService|Event triggered when someone adds a comment.")
when "confidential_note", "confidential_note_events"
- s_("ProjectService|Event will be triggered when someone adds a comment on a confidential issue")
+ s_("ProjectService|Event triggered when someone adds a comment on a confidential issue.")
when "issue", "issue_events"
- s_("ProjectService|Event will be triggered when an issue is created/updated/closed")
+ s_("ProjectService|Event triggered when an issue is created, updated, or closed.")
when "confidential_issue", "confidential_issue_events"
- s_("ProjectService|Event will be triggered when a confidential issue is created/updated/closed")
+ s_("ProjectService|Event triggered when a confidential issue is created, updated, or closed.")
when "merge_request", "merge_request_events"
- s_("ProjectService|Event will be triggered when a merge request is created/updated/merged")
+ s_("ProjectService|Event triggered when a merge request is created, updated, or merged.")
when "pipeline", "pipeline_events"
- s_("ProjectService|Event will be triggered when a pipeline status changes")
+ s_("ProjectService|Event triggered when a pipeline status changes.")
when "wiki_page", "wiki_page_events"
- s_("ProjectService|Event will be triggered when a wiki page is created/updated")
+ s_("ProjectService|Event triggered when a wiki page is created or updated.")
when "commit", "commit_events"
- s_("ProjectService|Event will be triggered when a commit is created/updated")
+ s_("ProjectService|Event triggered when a commit is created or updated.")
when "deployment"
- s_("ProjectService|Event will be triggered when a deployment starts or finishes")
+ s_("ProjectService|Event triggered when a deployment starts or finishes.")
when "alert"
- s_("ProjectService|Event will be triggered when a new, unique alert is recorded")
+ s_("ProjectService|Event triggered when a new, unique alert is recorded.")
end
end
diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb
index dce9168a9a4..1f7f5f6babe 100644
--- a/app/models/ci/build.rb
+++ b/app/models/ci/build.rb
@@ -93,8 +93,7 @@ module Ci
validates :ref, presence: true
scope :not_interruptible, -> do
- joins(:metadata).where('ci_builds_metadata.id NOT IN (?)',
- Ci::BuildMetadata.scoped_build.with_interruptible.select(:id))
+ joins(:metadata).where.not('ci_builds_metadata.id' => Ci::BuildMetadata.scoped_build.with_interruptible.select(:id))
end
scope :unstarted, -> { where(runner_id: nil) }
diff --git a/app/models/ci/stage.rb b/app/models/ci/stage.rb
index fe6889a6808..9dd75150ac7 100644
--- a/app/models/ci/stage.rb
+++ b/app/models/ci/stage.rb
@@ -44,7 +44,7 @@ module Ci
next if position.present?
self.position = statuses.select(:stage_idx)
- .where('stage_idx IS NOT NULL')
+ .where.not(stage_idx: nil)
.group(:stage_idx)
.order('COUNT(*) DESC')
.first&.stage_idx.to_i
diff --git a/app/models/clusters/clusters_hierarchy.rb b/app/models/clusters/clusters_hierarchy.rb
index c9c18d8c96a..125783e6ee1 100644
--- a/app/models/clusters/clusters_hierarchy.rb
+++ b/app/models/clusters/clusters_hierarchy.rb
@@ -16,7 +16,7 @@ module Clusters
model
.unscoped
- .where('clusters.id IS NOT NULL')
+ .where.not('clusters.id' => nil)
.with
.recursive(cte.to_arel)
.from(cte_alias)
diff --git a/app/models/commit_status.rb b/app/models/commit_status.rb
index e64380f5d91..fe262d48ac4 100644
--- a/app/models/commit_status.rb
+++ b/app/models/commit_status.rb
@@ -56,6 +56,7 @@ class CommitStatus < ApplicationRecord
scope :by_name, -> (name) { where(name: name) }
scope :in_pipelines, ->(pipelines) { where(pipeline: pipelines) }
scope :eager_load_pipeline, -> { eager_load(:pipeline, project: { namespace: :route }) }
+ scope :with_pipeline, -> { joins(:pipeline) }
scope :for_project_paths, -> (paths) do
where(project: Project.where_full_path_in(Array(paths)))
@@ -180,6 +181,7 @@ class CommitStatus < ApplicationRecord
end
after_transition any => :failed do |commit_status|
+ next if Feature.enabled?(:async_add_build_failure_todo, commit_status.project, default_enabled: :yaml)
next unless commit_status.project
# rubocop: disable CodeReuse/ServiceClass
diff --git a/app/models/environment.rb b/app/models/environment.rb
index 96b44c9ac0a..4cc65f4e295 100644
--- a/app/models/environment.rb
+++ b/app/models/environment.rb
@@ -86,7 +86,7 @@ class Environment < ApplicationRecord
end
scope :for_project, -> (project) { where(project_id: project) }
- scope :for_tier, -> (tier) { where(tier: tier).where('tier IS NOT NULL') }
+ scope :for_tier, -> (tier) { where(tier: tier).where.not(tier: nil) }
scope :with_deployment, -> (sha) { where('EXISTS (?)', Deployment.select(1).where('deployments.environment_id = environments.id').where(sha: sha)) }
scope :unfoldered, -> { where(environment_type: nil) }
scope :with_rank, -> do
diff --git a/app/models/project.rb b/app/models/project.rb
index eb0382414de..2431b40a8be 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -519,7 +519,7 @@ class Project < ApplicationRecord
scope :with_packages, -> { joins(:packages) }
scope :in_namespace, ->(namespace_ids) { where(namespace_id: namespace_ids) }
scope :personal, ->(user) { where(namespace_id: user.namespace_id) }
- scope :joined, ->(user) { where('namespace_id != ?', user.namespace_id) }
+ scope :joined, ->(user) { where.not(namespace_id: user.namespace_id) }
scope :starred_by, ->(user) { joins(:users_star_projects).where('users_star_projects.user_id': user.id) }
scope :visible_to_user, ->(user) { where(id: user.authorized_projects.select(:id).reorder(nil)) }
scope :visible_to_user_and_access_level, ->(user, access_level) { where(id: user.authorized_projects.where('project_authorizations.access_level >= ?', access_level).select(:id).reorder(nil)) }
diff --git a/app/models/project_services/microsoft_teams_service.rb b/app/models/project_services/microsoft_teams_service.rb
index e8e12a9a206..803c1255195 100644
--- a/app/models/project_services/microsoft_teams_service.rb
+++ b/app/models/project_services/microsoft_teams_service.rb
@@ -2,7 +2,7 @@
class MicrosoftTeamsService < ChatNotificationService
def title
- 'Microsoft Teams Notification'
+ 'Microsoft Teams notifications'
end
def description
@@ -14,13 +14,7 @@ class MicrosoftTeamsService < ChatNotificationService
end
def help
- 'This service sends notifications about projects events to Microsoft Teams channels.<br />
- To set up this service:
- <ol>
- <li><a href="https://docs.microsoft.com/en-us/microsoftteams/platform/concepts/connectors/connectors-using#setting-up-a-custom-incoming-webhook">Setup a custom Incoming Webhook using Office 365 Connectors For Microsoft Teams</a>.</li>
- <li>Paste the <strong>Webhook URL</strong> into the field below.</li>
- <li>Select events below to enable notifications.</li>
- </ol>'
+ '<p>Use this service to send notifications about events in GitLab projects to your Microsoft Teams channels. <a href="https://docs.gitlab.com/ee/user/project/integrations/microsoft_teams.html">How do I configure this integration?</a></p>'
end
def webhook_placeholder
@@ -40,8 +34,8 @@ class MicrosoftTeamsService < ChatNotificationService
def default_fields
[
- { type: 'text', name: 'webhook', placeholder: "e.g. #{webhook_placeholder}" },
- { type: 'checkbox', name: 'notify_only_broken_pipelines' },
+ { type: 'text', name: 'webhook', placeholder: "#{webhook_placeholder}" },
+ { type: 'checkbox', name: 'notify_only_broken_pipelines', help: 'If selected, successful pipelines do not trigger a notification event.' },
{ type: 'select', name: 'branches_to_be_notified', choices: branch_choices }
]
end
diff --git a/app/models/user.rb b/app/models/user.rb
index decd1117c6c..de7bb1ccf49 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -353,12 +353,7 @@ class User < ApplicationRecord
# this state transition object in order to do a rollback.
# For this reason the tradeoff is to disable this cop.
after_transition any => :blocked do |user|
- if Feature.enabled?(:abort_user_pipelines_on_block, user)
- Ci::AbortPipelinesService.new.execute(user.pipelines)
- else
- Ci::CancelUserPipelinesService.new.execute(user)
- end
-
+ Ci::AbortPipelinesService.new.execute(user.pipelines)
Ci::DisableUserPipelineSchedulesService.new.execute(user)
end
# rubocop: enable CodeReuse/ServiceClass
@@ -1041,7 +1036,7 @@ class User < ApplicationRecord
[
Project.where(namespace: namespace),
Project.joins(:project_authorizations)
- .where("projects.namespace_id <> ?", namespace.id)
+ .where.not('projects.namespace_id' => namespace.id)
.where(project_authorizations: { user_id: id, access_level: Gitlab::Access::OWNER })
],
remove_duplicates: false
diff --git a/app/services/ci/cancel_user_pipelines_service.rb b/app/services/ci/cancel_user_pipelines_service.rb
deleted file mode 100644
index 3d3a8032e8e..00000000000
--- a/app/services/ci/cancel_user_pipelines_service.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-# frozen_string_literal: true
-
-module Ci
- class CancelUserPipelinesService
- # rubocop: disable CodeReuse/ActiveRecord
- # This is a bug with CodeReuse/ActiveRecord cop
- # https://gitlab.com/gitlab-org/gitlab/issues/32332
- def execute(user)
- # TODO: fix N+1 queries https://gitlab.com/gitlab-org/gitlab/-/issues/300685
- user.pipelines.cancelable.find_each(&:cancel_running)
-
- ServiceResponse.success(message: 'Pipeline canceled')
- rescue ActiveRecord::StaleObjectError
- ServiceResponse.error(message: 'Error canceling pipeline')
- end
- # rubocop: enable CodeReuse/ActiveRecord
- end
-end
diff --git a/app/services/ci/retry_build_service.rb b/app/services/ci/retry_build_service.rb
index 9355b82b598..3d58f3d9e9a 100644
--- a/app/services/ci/retry_build_service.rb
+++ b/app/services/ci/retry_build_service.rb
@@ -21,7 +21,7 @@ module Ci
Gitlab::OptimisticLocking.retry_lock(new_build, name: 'retry_build', &:enqueue)
- MergeRequests::AddTodoWhenBuildFailsService
+ ::MergeRequests::AddTodoWhenBuildFailsService
.new(project, current_user)
.close(new_build)
end
diff --git a/app/services/ci/retry_pipeline_service.rb b/app/services/ci/retry_pipeline_service.rb
index 90ee7b9b3ba..bb8590a769c 100644
--- a/app/services/ci/retry_pipeline_service.rb
+++ b/app/services/ci/retry_pipeline_service.rb
@@ -28,7 +28,7 @@ module Ci
pipeline.reset_ancestor_bridges!
- MergeRequests::AddTodoWhenBuildFailsService
+ ::MergeRequests::AddTodoWhenBuildFailsService
.new(project, current_user)
.close_all(pipeline)
diff --git a/app/services/merge_requests/base_service.rb b/app/services/merge_requests/base_service.rb
index 317cd11a69d..4cbb6b77c50 100644
--- a/app/services/merge_requests/base_service.rb
+++ b/app/services/merge_requests/base_service.rb
@@ -164,7 +164,7 @@ module MergeRequests
def pipeline_merge_requests(pipeline)
pipeline.all_merge_requests.opened.each do |merge_request|
- next unless pipeline == merge_request.head_pipeline
+ next unless pipeline.id == merge_request.head_pipeline_id
yield merge_request
end
diff --git a/app/services/namespaces/in_product_marketing_emails_service.rb b/app/services/namespaces/in_product_marketing_emails_service.rb
index aa29c8574ad..2b3c0c382a8 100644
--- a/app/services/namespaces/in_product_marketing_emails_service.rb
+++ b/app/services/namespaces/in_product_marketing_emails_service.rb
@@ -27,7 +27,7 @@ module Namespaces
end
def execute
- raise NotImplementedError, "Track #{track} not defined" unless TRACKS.key?(track)
+ raise ArgumentError, "Track #{track} not defined" unless TRACKS.key?(track)
groups_for_track.each_batch do |groups|
groups.each do |group|
diff --git a/app/services/todos/destroy/base_service.rb b/app/services/todos/destroy/base_service.rb
index 7378f10e7c4..4e971246185 100644
--- a/app/services/todos/destroy/base_service.rb
+++ b/app/services/todos/destroy/base_service.rb
@@ -13,7 +13,7 @@ module Todos
# rubocop: disable CodeReuse/ActiveRecord
def without_authorized(items)
- items.where('todos.user_id NOT IN (?)', authorized_users)
+ items.where.not('todos.user_id' => authorized_users)
end
# rubocop: enable CodeReuse/ActiveRecord
diff --git a/app/services/todos/destroy/private_features_service.rb b/app/services/todos/destroy/private_features_service.rb
index bd49519d694..44c3ff231f8 100644
--- a/app/services/todos/destroy/private_features_service.rb
+++ b/app/services/todos/destroy/private_features_service.rb
@@ -36,7 +36,7 @@ module Todos
items = Todo.where(project_id: project_id)
items = items.where(user_id: user_id) if user_id
- items.where('user_id NOT IN (?)', authorized_users)
+ items.where.not(user_id: authorized_users)
.where(target_type: target_types)
.delete_all
end
diff --git a/app/workers/all_queues.yml b/app/workers/all_queues.yml
index 921def1eef8..a542c8e179d 100644
--- a/app/workers/all_queues.yml
+++ b/app/workers/all_queues.yml
@@ -1235,6 +1235,14 @@
:weight: 3
:idempotent:
:tags: []
+- :name: pipeline_default:ci_merge_requests_add_todo_when_build_fails
+ :feature_category: :continuous_integration
+ :has_external_dependencies:
+ :urgency: :low
+ :resource_boundary: :unknown
+ :weight: 3
+ :idempotent: true
+ :tags: []
- :name: pipeline_default:ci_pipeline_bridge_status
:feature_category: :continuous_integration
:has_external_dependencies:
diff --git a/app/workers/build_finished_worker.rb b/app/workers/build_finished_worker.rb
index 3f99b30fdf7..c9cfb1da10b 100644
--- a/app/workers/build_finished_worker.rb
+++ b/app/workers/build_finished_worker.rb
@@ -37,6 +37,10 @@ class BuildFinishedWorker # rubocop:disable Scalability/IdempotentWorker
ExpirePipelineCacheWorker.perform_async(build.pipeline_id)
ChatNotificationWorker.perform_async(build.id) if build.pipeline.chat?
+ if build.failed? && Feature.enabled?(:async_add_build_failure_todo, build.project, default_enabled: :yaml)
+ ::Ci::MergeRequests::AddTodoWhenBuildFailsWorker.perform_async(build.id)
+ end
+
##
# We want to delay sending a build trace to object storage operation to
# validate that this fixes a race condition between this and flushing live
diff --git a/app/workers/ci/merge_requests/add_todo_when_build_fails_worker.rb b/app/workers/ci/merge_requests/add_todo_when_build_fails_worker.rb
new file mode 100644
index 00000000000..d5e097dc2b5
--- /dev/null
+++ b/app/workers/ci/merge_requests/add_todo_when_build_fails_worker.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+module Ci
+ module MergeRequests
+ class AddTodoWhenBuildFailsWorker
+ include ApplicationWorker
+ include PipelineQueue
+
+ urgency :low
+ idempotent!
+
+ def perform(job_id)
+ job = ::CommitStatus.with_pipeline.find_by_id(job_id)
+ project = job&.project
+
+ return unless job && project
+
+ ::MergeRequests::AddTodoWhenBuildFailsService.new(job.project, nil).execute(job)
+ end
+ end
+ end
+end
diff --git a/changelogs/unreleased/324045-remove-feature-flag.yml b/changelogs/unreleased/324045-remove-feature-flag.yml
new file mode 100644
index 00000000000..838d1923556
--- /dev/null
+++ b/changelogs/unreleased/324045-remove-feature-flag.yml
@@ -0,0 +1,5 @@
+---
+title: Bulk-abort user pipelines on block
+merge_request: 57801
+author:
+type: performance
diff --git a/changelogs/unreleased/325509-set-namespaces-traversal_ids-for-production-gitlab-org-group.yml b/changelogs/unreleased/325509-set-namespaces-traversal_ids-for-production-gitlab-org-group.yml
new file mode 100644
index 00000000000..fc438b5cc6b
--- /dev/null
+++ b/changelogs/unreleased/325509-set-namespaces-traversal_ids-for-production-gitlab-org-group.yml
@@ -0,0 +1,5 @@
+---
+title: Backfill traversal_ids for gitlab-org .com
+merge_request: 57075
+author:
+type: performance
diff --git a/changelogs/unreleased/issue-220040-fix-rails-savebang-banzai-module.yml b/changelogs/unreleased/issue-220040-fix-rails-savebang-banzai-module.yml
new file mode 100644
index 00000000000..f3715817ea0
--- /dev/null
+++ b/changelogs/unreleased/issue-220040-fix-rails-savebang-banzai-module.yml
@@ -0,0 +1,5 @@
+---
+title: Fix Rails/SaveBang Rubocop offenses for banzai modules
+merge_request: 58108
+author: Huzaifa Iftikhar @huzaifaiftikhar
+type: fixed
diff --git a/changelogs/unreleased/pl-rubocop-todo-where-not.yml b/changelogs/unreleased/pl-rubocop-todo-where-not.yml
new file mode 100644
index 00000000000..da8c041ec10
--- /dev/null
+++ b/changelogs/unreleased/pl-rubocop-todo-where-not.yml
@@ -0,0 +1,5 @@
+---
+title: Resolves rubocop offenses Rails/WhereNot
+merge_request: 58062
+author: Shubham Kumar (@imskr)
+type: fixed
diff --git a/config/feature_flags/development/abort_user_pipelines_on_block.yml b/config/feature_flags/development/async_add_build_failure_todo.yml
index b0e4fb30fc2..6bb1a84ed82 100644
--- a/config/feature_flags/development/abort_user_pipelines_on_block.yml
+++ b/config/feature_flags/development/async_add_build_failure_todo.yml
@@ -1,8 +1,8 @@
---
-name: abort_user_pipelines_on_block
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56126
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/324045
-milestone: '13.10'
+name: async_add_build_failure_todo
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/57490/diffs
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/326726
+milestone: '13.11'
type: development
-group: group::memory
+group: group::continuous integration
default_enabled: false
diff --git a/config/metrics/schema.json b/config/metrics/schema.json
index 4e5d4162a05..8878b3bc744 100644
--- a/config/metrics/schema.json
+++ b/config/metrics/schema.json
@@ -5,6 +5,10 @@
"key_path": {
"type": "string"
},
+ "name": {
+ "type": ["string", "null"],
+ "pattern": "^([a-z]+_)*[a-z]+$"
+ },
"description": {
"type": "string"
},
diff --git a/db/post_migrate/20200406102120_backfill_deployment_clusters_from_deployments.rb b/db/post_migrate/20200406102120_backfill_deployment_clusters_from_deployments.rb
index 76b00796d1a..ab217ba92ab 100644
--- a/db/post_migrate/20200406102120_backfill_deployment_clusters_from_deployments.rb
+++ b/db/post_migrate/20200406102120_backfill_deployment_clusters_from_deployments.rb
@@ -17,7 +17,7 @@ class BackfillDeploymentClustersFromDeployments < ActiveRecord::Migration[6.0]
class Deployment < ActiveRecord::Base
include EachBatch
- default_scope { where('cluster_id IS NOT NULL') } # rubocop:disable Cop/DefaultScope
+ default_scope { where.not(cluster_id: nil) } # rubocop:disable Cop/DefaultScope
self.table_name = 'deployments'
end
diff --git a/db/post_migrate/20200811130433_create_missing_vulnerabilities_issue_links.rb b/db/post_migrate/20200811130433_create_missing_vulnerabilities_issue_links.rb
index 891201eaa52..031d9ea49e2 100644
--- a/db/post_migrate/20200811130433_create_missing_vulnerabilities_issue_links.rb
+++ b/db/post_migrate/20200811130433_create_missing_vulnerabilities_issue_links.rb
@@ -18,11 +18,11 @@ class CreateMissingVulnerabilitiesIssueLinks < ActiveRecord::Migration[6.0]
disable_ddl_transaction!
def up
- VulnerabilitiesFeedback.where('issue_id IS NOT NULL').each_batch do |relation|
+ VulnerabilitiesFeedback.where.not(issue_id: nil).each_batch do |relation|
timestamp = Time.now
issue_links = relation
.joins("JOIN vulnerability_occurrences vo ON vo.project_id = vulnerability_feedback.project_id AND vo.report_type = vulnerability_feedback.category AND encode(vo.project_fingerprint, 'hex') = vulnerability_feedback.project_fingerprint")
- .where('vo.vulnerability_id IS NOT NULL')
+ .where.not('vo.vulnerability_id' => nil)
.pluck(:vulnerability_id, :issue_id)
.map do |v_id, i_id|
{
diff --git a/db/post_migrate/20210311045139_set_traversal_ids_for_gitlab_org_group_com.rb b/db/post_migrate/20210311045139_set_traversal_ids_for_gitlab_org_group_com.rb
new file mode 100644
index 00000000000..8cef1f1cc2b
--- /dev/null
+++ b/db/post_migrate/20210311045139_set_traversal_ids_for_gitlab_org_group_com.rb
@@ -0,0 +1,88 @@
+# frozen_string_literal: true
+
+class SetTraversalIdsForGitlabOrgGroupCom < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ def up
+ return unless Gitlab.com?
+
+ # namespace ID 9970 is gitlab-org on .com
+ with_lock_retries do
+ execute(<<~SQL)
+ UPDATE
+ namespaces
+ SET
+ traversal_ids = cte.traversal_ids
+ FROM
+ (
+ WITH RECURSIVE cte(id, traversal_ids, cycle) AS (
+ VALUES
+ (9970, ARRAY[9970], false)
+ UNION ALL
+ SELECT
+ n.id,
+ cte.traversal_ids || n.id,
+ n.id = ANY(cte.traversal_ids)
+ FROM
+ namespaces n,
+ cte
+ WHERE
+ n.parent_id = cte.id
+ AND NOT cycle
+ )
+ SELECT
+ id,
+ traversal_ids
+ FROM
+ cte FOR
+ UPDATE
+ ) as cte
+ WHERE
+ namespaces.id = cte.id
+ AND namespaces.traversal_ids <> cte.traversal_ids
+ SQL
+ end
+ end
+
+ def down
+ return unless Gitlab.com?
+
+ # namespace ID 9970 is gitlab-org on .com
+ with_lock_retries do
+ execute(<<~SQL)
+ UPDATE
+ namespaces
+ SET
+ traversal_ids = '{}'
+ FROM
+ (
+ WITH RECURSIVE cte(id, traversal_ids, cycle) AS (
+ VALUES
+ (9970, ARRAY[9970], false)
+ UNION ALL
+ SELECT
+ n.id,
+ cte.traversal_ids || n.id,
+ n.id = ANY(cte.traversal_ids)
+ FROM
+ namespaces n,
+ cte
+ WHERE
+ n.parent_id = cte.id
+ AND NOT cycle
+ )
+ SELECT
+ id,
+ traversal_ids
+ FROM
+ cte FOR
+ UPDATE
+ ) as cte
+ WHERE
+ namespaces.id = cte.id
+ SQL
+ end
+ end
+end
diff --git a/db/schema_migrations/20210311045139 b/db/schema_migrations/20210311045139
new file mode 100644
index 00000000000..71026c1b2af
--- /dev/null
+++ b/db/schema_migrations/20210311045139
@@ -0,0 +1 @@
+2387c8a5516aaf8bcf44c9bad45bfc9844d68d2c03330f67773ce046b21a7a6c \ No newline at end of file
diff --git a/doc/user/project/integrations/img/microsoft_teams_configuration.png b/doc/user/project/integrations/img/microsoft_teams_configuration.png
deleted file mode 100644
index 22ad28e3f73..00000000000
--- a/doc/user/project/integrations/img/microsoft_teams_configuration.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/project/integrations/microsoft_teams.md b/doc/user/project/integrations/microsoft_teams.md
index 41e0938fc3b..795ead573f2 100644
--- a/doc/user/project/integrations/microsoft_teams.md
+++ b/doc/user/project/integrations/microsoft_teams.md
@@ -6,49 +6,55 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Microsoft Teams service **(FREE)**
-## On Microsoft Teams
+You can integrate Microsoft Teams with GitLab, and display notifications about GitLab projects
+in Microsoft Teams. To integrate the services, you must:
-To enable Microsoft Teams integration you must create an incoming webhook integration on Microsoft
-Teams by following the steps below:
+1. [Configure Microsoft Teams](#configure-microsoft-teams) to enable a webhook
+ to listen for changes.
+1. [Configure your GitLab project](#configure-your-gitlab-project) to push notifications
+ to the Microsoft Teams webhook.
-1. Search for "incoming webhook" on the search bar in Microsoft Teams and select the
- **Incoming Webhook** item.
+## Configure Microsoft Teams
+
+To configure Microsoft Teams to listen for notifications from GitLab:
+
+1. In Microsoft Teams, search for "incoming webhook" in the search bar, and select the
+ **Incoming Webhook** item:
![Select Incoming Webhook](img/microsoft_teams_select_incoming_webhook.png)
-1. Click the **Add to a team** button.
+1. Select **Add to a team**.
1. Select the team and channel you want to add the integration to.
1. Add a name for the webhook. The name is displayed next to every message that
comes in through the webhook.
-1. Copy the webhook URL for the next steps.
-
-Learn more about
-[setting up an incoming webhook on Microsoft Teams](https://docs.microsoft.com/en-us/microsoftteams/platform/webhooks-and-connectors/how-to/connectors-using#setting-up-a-custom-incoming-webhook).
-
-## On GitLab
-
-After you set up Microsoft Teams, it's time to set up GitLab.
-
-Navigate to the [Integrations page](overview.md#accessing-integrations)
-and select the **Microsoft Teams Notification** service to configure it.
-There, you see a checkbox with the following events that can be triggered:
-
-- Push
-- Issue
-- Confidential issue
-- Merge request
-- Note
-- Tag push
-- Pipeline
-- Wiki page
-
-At the end fill in your Microsoft Teams details:
-
-| Field | Description |
-| ----- | ----------- |
-| **Webhook** | The incoming webhook URL which you have to set up on Microsoft Teams. |
-| **Notify only broken pipelines** | If you choose to enable the **Pipeline** event and you want to be only notified about failed pipelines. |
-
-After you are all done, click **Save changes** for the changes to take effect.
-
-![Microsoft Teams configuration](img/microsoft_teams_configuration.png)
+1. Copy the webhook URL, as you need it to configure GitLab.
+
+## Configure your GitLab project
+
+After you configure Microsoft Teams to receive notifications, you must configure
+GitLab to send the notifications:
+
+1. Sign in to GitLab as a user with [Administrator](../../permissions.md) and go
+ to your project's page.
+1. Go to **Settings > Integrations** and select **Microsoft Teams Notification**.
+1. Select **Active** to enable the integration.
+1. Select the check box next to each **Trigger** to enable:
+ - Push
+ - Issue
+ - Confidential issue
+ - Merge request
+ - Note
+ - Confidential note
+ - Tag push
+ - Pipeline - If you enable this trigger, you can also select **Notify only broken pipelines** to be notified only about failed pipelines.
+ - Wiki page
+1. In **Webhook**, paste the URL you copied when you
+ [configured Microsoft Teams](#configure-microsoft-teams).
+1. (Optional) If you enabled the pipeline trigger, you can select the
+ **Notify only broken pipelines** check box to push notifications only when pipelines break.
+1. Select the branches you want to send notifications for.
+1. Click **Save changes**.
+
+## Resources
+
+- [Setting up an incoming webhook on Microsoft Teams](https://docs.microsoft.com/en-us/microsoftteams/platform/webhooks-and-connectors/how-to/connectors-using#setting-up-a-custom-incoming-webhook).
diff --git a/lib/gitlab/background_migration/populate_merge_request_assignees_table.rb b/lib/gitlab/background_migration/populate_merge_request_assignees_table.rb
index eb4bc0aaf28..28cc4a5e3fa 100644
--- a/lib/gitlab/background_migration/populate_merge_request_assignees_table.rb
+++ b/lib/gitlab/background_migration/populate_merge_request_assignees_table.rb
@@ -11,7 +11,7 @@ module Gitlab
MergeRequest
.where(merge_request_assignees_not_exists_clause)
.where(id: from_id..to_id)
- .where('assignee_id IS NOT NULL')
+ .where.not(assignee_id: nil)
.select(:id, :assignee_id)
.to_sql
diff --git a/lib/gitlab/background_migration/wrongfully_confirmed_email_unconfirmer.rb b/lib/gitlab/background_migration/wrongfully_confirmed_email_unconfirmer.rb
index 5b01141d8c1..665ad7abcbb 100644
--- a/lib/gitlab/background_migration/wrongfully_confirmed_email_unconfirmer.rb
+++ b/lib/gitlab/background_migration/wrongfully_confirmed_email_unconfirmer.rb
@@ -27,7 +27,7 @@ module Gitlab
joins(:user)
.merge(UserModel.active)
.where(id: (start_id..stop_id))
- .where('emails.confirmed_at IS NOT NULL')
+ .where.not('emails.confirmed_at' => nil)
.where('emails.confirmed_at = users.confirmed_at')
.where('emails.email <> users.email')
.where('NOT EXISTS (SELECT 1 FROM user_synced_attributes_metadata WHERE user_id=users.id AND email_synced IS true)')
diff --git a/lib/gitlab/import_export/uploads_manager.rb b/lib/gitlab/import_export/uploads_manager.rb
index 428bcbe8dc5..2f15cdd7506 100644
--- a/lib/gitlab/import_export/uploads_manager.rb
+++ b/lib/gitlab/import_export/uploads_manager.rb
@@ -76,7 +76,7 @@ module Gitlab
def project_uploads_except_avatar(avatar_path)
return @project.uploads unless avatar_path
- @project.uploads.where("path != ?", avatar_path)
+ @project.uploads.where.not(path: avatar_path)
end
def download_and_copy(upload)
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index d4e0b68f6e5..01c1699bc4a 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -24110,40 +24110,40 @@ msgstr ""
msgid "ProjectService|Enter new password"
msgstr ""
-msgid "ProjectService|Event will be triggered by a push to the repository"
+msgid "ProjectService|Event triggered when a commit is created or updated."
msgstr ""
-msgid "ProjectService|Event will be triggered when a commit is created/updated"
+msgid "ProjectService|Event triggered when a confidential issue is created, updated, or closed."
msgstr ""
-msgid "ProjectService|Event will be triggered when a confidential issue is created/updated/closed"
+msgid "ProjectService|Event triggered when a deployment starts or finishes."
msgstr ""
-msgid "ProjectService|Event will be triggered when a deployment starts or finishes"
+msgid "ProjectService|Event triggered when a merge request is created, updated, or merged."
msgstr ""
-msgid "ProjectService|Event will be triggered when a merge request is created/updated/merged"
+msgid "ProjectService|Event triggered when a new tag is pushed to the repository."
msgstr ""
-msgid "ProjectService|Event will be triggered when a new tag is pushed to the repository"
+msgid "ProjectService|Event triggered when a new, unique alert is recorded."
msgstr ""
-msgid "ProjectService|Event will be triggered when a new, unique alert is recorded"
+msgid "ProjectService|Event triggered when a pipeline status changes."
msgstr ""
-msgid "ProjectService|Event will be triggered when a pipeline status changes"
+msgid "ProjectService|Event triggered when a wiki page is created or updated."
msgstr ""
-msgid "ProjectService|Event will be triggered when a wiki page is created/updated"
+msgid "ProjectService|Event triggered when an issue is created, updated, or closed."
msgstr ""
-msgid "ProjectService|Event will be triggered when an issue is created/updated/closed"
+msgid "ProjectService|Event triggered when someone adds a comment on a confidential issue."
msgstr ""
-msgid "ProjectService|Event will be triggered when someone adds a comment"
+msgid "ProjectService|Event triggered when someone adds a comment."
msgstr ""
-msgid "ProjectService|Event will be triggered when someone adds a comment on a confidential issue"
+msgid "ProjectService|Event triggered when someone pushes to the repository."
msgstr ""
msgid "ProjectService|Issue URL"
diff --git a/spec/lib/banzai/reference_parser/external_issue_parser_spec.rb b/spec/lib/banzai/reference_parser/external_issue_parser_spec.rb
index 5f92eb42e74..0c1b98e5ec3 100644
--- a/spec/lib/banzai/reference_parser/external_issue_parser_spec.rb
+++ b/spec/lib/banzai/reference_parser/external_issue_parser_spec.rb
@@ -21,7 +21,7 @@ RSpec.describe Banzai::ReferenceParser::ExternalIssueParser do
levels.each do |level|
it "creates reference when the feature is #{level}" do
- project.project_feature.update(issues_access_level: level)
+ project.project_feature.update!(issues_access_level: level)
visible_nodes = subject.nodes_visible_to_user(user, [link])
diff --git a/spec/lib/banzai/reference_redactor_spec.rb b/spec/lib/banzai/reference_redactor_spec.rb
index 668e427cfa2..78cceedd0e5 100644
--- a/spec/lib/banzai/reference_redactor_spec.rb
+++ b/spec/lib/banzai/reference_redactor_spec.rb
@@ -64,7 +64,7 @@ RSpec.describe Banzai::ReferenceRedactor do
let(:redactor) { described_class.new(Banzai::RenderContext.new(project, user)) }
before do
- project.update(pending_delete: true)
+ project.update!(pending_delete: true)
end
it 'redacts an issue attached' do
diff --git a/spec/lib/gitlab/analytics/cycle_analytics/stage_events/code_stage_start_spec.rb b/spec/lib/gitlab/analytics/cycle_analytics/stage_events/code_stage_start_spec.rb
index 52e9f2d9846..b6f9c8106c9 100644
--- a/spec/lib/gitlab/analytics/cycle_analytics/stage_events/code_stage_start_spec.rb
+++ b/spec/lib/gitlab/analytics/cycle_analytics/stage_events/code_stage_start_spec.rb
@@ -15,7 +15,7 @@ RSpec.describe Gitlab::Analytics::CycleAnalytics::StageEvents::CodeStageStart do
other_merge_request = create(:merge_request, source_project: project, source_branch: 'a', target_branch: 'master')
- records = subject.apply_query_customization(MergeRequest.all).where('merge_requests_closing_issues.issue_id IS NOT NULL')
+ records = subject.apply_query_customization(MergeRequest.all).where.not('merge_requests_closing_issues.issue_id' => nil)
expect(records).to eq([merge_request])
expect(records).not_to include(other_merge_request)
end
diff --git a/spec/lib/gitlab/usage/metric_definition_spec.rb b/spec/lib/gitlab/usage/metric_definition_spec.rb
index 8b592838f5d..f98cc4cbcb7 100644
--- a/spec/lib/gitlab/usage/metric_definition_spec.rb
+++ b/spec/lib/gitlab/usage/metric_definition_spec.rb
@@ -16,7 +16,8 @@ RSpec.describe Gitlab::Usage::MetricDefinition do
time_frame: 'none',
data_source: 'database',
distribution: %w(ee ce),
- tier: %w(free starter premium ultimate bronze silver gold)
+ tier: %w(free starter premium ultimate bronze silver gold),
+ name: 'count_boards'
}
end
@@ -53,6 +54,7 @@ RSpec.describe Gitlab::Usage::MetricDefinition do
:distribution | nil
:distribution | 'test'
:tier | %w(test ee)
+ :name | 'count_<adjective_describing>_boards'
end
with_them do
diff --git a/spec/migrations/clean_up_noteable_id_for_notes_on_commits_spec.rb b/spec/migrations/clean_up_noteable_id_for_notes_on_commits_spec.rb
index 531c1dbb76a..268fadee0af 100644
--- a/spec/migrations/clean_up_noteable_id_for_notes_on_commits_spec.rb
+++ b/spec/migrations/clean_up_noteable_id_for_notes_on_commits_spec.rb
@@ -25,7 +25,7 @@ RSpec.describe CleanUpNoteableIdForNotesOnCommits do
end
def dirty_notes_on_commits
- notes.where(noteable_type: 'Commit').where('noteable_id IS NOT NULL')
+ notes.where(noteable_type: 'Commit').where.not(noteable_id: nil)
end
def other_notes
diff --git a/spec/migrations/migrate_bot_type_to_user_type_spec.rb b/spec/migrations/migrate_bot_type_to_user_type_spec.rb
index 2b85f2a7f69..fcd7f1ebcb8 100644
--- a/spec/migrations/migrate_bot_type_to_user_type_spec.rb
+++ b/spec/migrations/migrate_bot_type_to_user_type_spec.rb
@@ -15,6 +15,6 @@ RSpec.describe MigrateBotTypeToUserType, :migration do
migrate!
- expect(users.where('user_type IS NOT NULL').map(&:user_type)).to match_array([1, 2, 3])
+ expect(users.where.not(user_type: nil).map(&:user_type)).to match_array([1, 2, 3])
end
end
diff --git a/spec/models/ci/build_spec.rb b/spec/models/ci/build_spec.rb
index aa3cc0800a8..fa0e72e7ad4 100644
--- a/spec/models/ci/build_spec.rb
+++ b/spec/models/ci/build_spec.rb
@@ -3582,10 +3582,10 @@ RSpec.describe Ci::Build do
end
describe 'state transition when build fails' do
- let(:service) { MergeRequests::AddTodoWhenBuildFailsService.new(project, user) }
+ let(:service) { ::MergeRequests::AddTodoWhenBuildFailsService.new(project, user) }
before do
- allow(MergeRequests::AddTodoWhenBuildFailsService).to receive(:new).and_return(service)
+ allow(::MergeRequests::AddTodoWhenBuildFailsService).to receive(:new).and_return(service)
allow(service).to receive(:close)
end
@@ -3670,15 +3670,42 @@ RSpec.describe Ci::Build do
subject.drop!
end
- it 'creates a todo' do
- project.add_developer(user)
+ context 'when async_add_build_failure_todo flag enabled' do
+ it 'creates a todo async', :sidekiq_inline do
+ project.add_developer(user)
+
+ expect_next_instance_of(TodoService) do |todo_service|
+ expect(todo_service)
+ .to receive(:merge_request_build_failed).with(merge_request)
+ end
- expect_next_instance_of(TodoService) do |todo_service|
- expect(todo_service)
- .to receive(:merge_request_build_failed).with(merge_request)
+ subject.drop!
end
- subject.drop!
+ it 'does not create a sync todo' do
+ project.add_developer(user)
+
+ expect(TodoService).not_to receive(:new)
+
+ subject.drop!
+ end
+ end
+
+ context 'when async_add_build_failure_todo flag disabled' do
+ before do
+ stub_feature_flags(async_add_build_failure_todo: false)
+ end
+
+ it 'creates a todo sync' do
+ project.add_developer(user)
+
+ expect_next_instance_of(TodoService) do |todo_service|
+ expect(todo_service)
+ .to receive(:merge_request_build_failed).with(merge_request)
+ end
+
+ subject.drop!
+ end
end
end
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index 9498aa75289..ac92311e132 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -1790,28 +1790,14 @@ RSpec.describe User do
context 'when user has running CI pipelines' do
let(:service) { double }
+ let(:pipelines) { build_list(:ci_pipeline, 3, :running) }
- context 'with abort_user_pipelines_on_block feature enabled' do
- let(:pipelines) { build_list(:ci_pipeline, 3, :running) }
+ it 'aborts all running pipelines and related jobs' do
+ expect(user).to receive(:pipelines).and_return(pipelines)
+ expect(Ci::AbortPipelinesService).to receive(:new).and_return(service)
+ expect(service).to receive(:execute).with(pipelines)
- it 'aborts all running pipelines and related jobs' do
- stub_feature_flags(abort_user_pipelines_on_block: true)
- expect(user).to receive(:pipelines).and_return(pipelines)
- expect(Ci::AbortPipelinesService).to receive(:new).and_return(service)
- expect(service).to receive(:execute).with(pipelines)
-
- user.block
- end
- end
-
- context 'with abort_user_pipelines_on_block feature disabled' do
- it 'cancels all running pipelines and related jobs' do
- stub_feature_flags(abort_user_pipelines_on_block: false)
- expect(Ci::CancelUserPipelinesService).to receive(:new).and_return(service)
- expect(service).to receive(:execute).with(user)
-
- user.block
- end
+ user.block
end
end
diff --git a/spec/serializers/service_event_entity_spec.rb b/spec/serializers/service_event_entity_spec.rb
index 09bb8bca43b..34ffd93ea0c 100644
--- a/spec/serializers/service_event_entity_spec.rb
+++ b/spec/serializers/service_event_entity_spec.rb
@@ -17,7 +17,7 @@ RSpec.describe ServiceEventEntity do
let(:event) { 'push' }
it 'exposes correct attributes' do
- expect(subject[:description]).to eq('Event will be triggered by a push to the repository')
+ expect(subject[:description]).to eq('Event triggered when someone pushes to the repository.')
expect(subject[:name]).to eq('push_events')
expect(subject[:title]).to eq('push')
expect(subject[:value]).to be(true)
@@ -29,7 +29,7 @@ RSpec.describe ServiceEventEntity do
let(:event) { 'note' }
it 'exposes correct attributes' do
- expect(subject[:description]).to eq('Event will be triggered when someone adds a comment')
+ expect(subject[:description]).to eq('Event triggered when someone adds a comment.')
expect(subject[:name]).to eq('note_events')
expect(subject[:title]).to eq('note')
expect(subject[:value]).to eq(false)
diff --git a/spec/services/ci/cancel_user_pipelines_service_spec.rb b/spec/services/ci/cancel_user_pipelines_service_spec.rb
deleted file mode 100644
index 8491242dfd5..00000000000
--- a/spec/services/ci/cancel_user_pipelines_service_spec.rb
+++ /dev/null
@@ -1,35 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Ci::CancelUserPipelinesService do
- describe '#execute' do
- let(:user) { create(:user) }
-
- subject { described_class.new.execute(user) }
-
- context 'when user has running CI pipelines' do
- let(:pipeline) { create(:ci_pipeline, :running, user: user) }
- let!(:build) { create(:ci_build, :running, pipeline: pipeline) }
-
- it 'cancels all running pipelines and related jobs', :sidekiq_might_not_need_inline do
- subject
-
- expect(pipeline.reload).to be_canceled
- expect(build.reload).to be_canceled
- end
- end
-
- context 'when an error ocurrs' do
- it 'raises a service level error' do
- service = double(execute: ServiceResponse.error(message: 'Error canceling pipeline'))
- allow(::Ci::CancelUserPipelinesService).to receive(:new).and_return(service)
-
- result = subject
-
- expect(result).to be_a(ServiceResponse)
- expect(result).to be_error
- end
- end
- end
-end
diff --git a/spec/services/ci/retry_build_service_spec.rb b/spec/services/ci/retry_build_service_spec.rb
index bdf60bb3fdc..7dd3d963e56 100644
--- a/spec/services/ci/retry_build_service_spec.rb
+++ b/spec/services/ci/retry_build_service_spec.rb
@@ -181,7 +181,7 @@ RSpec.describe Ci::RetryBuildService do
end
it 'resolves todos for old build that failed' do
- expect(MergeRequests::AddTodoWhenBuildFailsService)
+ expect(::MergeRequests::AddTodoWhenBuildFailsService)
.to receive_message_chain(:new, :close)
service.execute(build)
diff --git a/spec/services/ci/retry_pipeline_service_spec.rb b/spec/services/ci/retry_pipeline_service_spec.rb
index 3c6a99efbf8..3e2e9f07723 100644
--- a/spec/services/ci/retry_pipeline_service_spec.rb
+++ b/spec/services/ci/retry_pipeline_service_spec.rb
@@ -272,7 +272,7 @@ RSpec.describe Ci::RetryPipelineService, '#execute' do
end
it 'closes all todos about failed jobs for pipeline' do
- expect(MergeRequests::AddTodoWhenBuildFailsService)
+ expect(::MergeRequests::AddTodoWhenBuildFailsService)
.to receive_message_chain(:new, :close_all)
service.execute(pipeline)
diff --git a/spec/services/merge_requests/add_todo_when_build_fails_service_spec.rb b/spec/services/merge_requests/add_todo_when_build_fails_service_spec.rb
index 3c81ad6722d..6edaa91b8b2 100644
--- a/spec/services/merge_requests/add_todo_when_build_fails_service_spec.rb
+++ b/spec/services/merge_requests/add_todo_when_build_fails_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe MergeRequests::AddTodoWhenBuildFailsService do
+RSpec.describe ::MergeRequests::AddTodoWhenBuildFailsService do
let(:user) { create(:user) }
let(:project) { create(:project, :repository) }
let(:sha) { '1234567890abcdef1234567890abcdef12345678' }
@@ -24,8 +24,8 @@ RSpec.describe MergeRequests::AddTodoWhenBuildFailsService do
before do
allow_any_instance_of(MergeRequest)
- .to receive(:head_pipeline)
- .and_return(pipeline)
+ .to receive(:head_pipeline_id)
+ .and_return(pipeline.id)
allow(service).to receive(:todo_service).and_return(todo_service)
end
diff --git a/spec/services/namespaces/in_product_marketing_emails_service_spec.rb b/spec/services/namespaces/in_product_marketing_emails_service_spec.rb
index 3aa4d0b2f39..43c41b5c99d 100644
--- a/spec/services/namespaces/in_product_marketing_emails_service_spec.rb
+++ b/spec/services/namespaces/in_product_marketing_emails_service_spec.rb
@@ -218,7 +218,7 @@ RSpec.describe Namespaces::InProductMarketingEmailsService, '#execute' do
stub_const("#{described_class}::TRACKS", { bar: :git_write })
end
- it { expect { subject }.to raise_error(NotImplementedError, 'Track foo not defined') }
+ it { expect { subject }.to raise_error(ArgumentError, 'Track foo not defined') }
end
context 'when group is a sub-group' do
diff --git a/spec/workers/build_finished_worker_spec.rb b/spec/workers/build_finished_worker_spec.rb
index 6d040f83dc7..638bf8ab12b 100644
--- a/spec/workers/build_finished_worker_spec.rb
+++ b/spec/workers/build_finished_worker_spec.rb
@@ -6,10 +6,8 @@ RSpec.describe BuildFinishedWorker do
subject { described_class.new.perform(build.id) }
describe '#perform' do
- let(:build) { create(:ci_build, :success, pipeline: create(:ci_pipeline)) }
-
context 'when build exists' do
- let!(:build) { create(:ci_build) }
+ let_it_be(:build) { create(:ci_build, :success, pipeline: create(:ci_pipeline)) }
before do
expect(Ci::Build).to receive(:find_by).with(id: build.id).and_return(build)
@@ -30,6 +28,42 @@ RSpec.describe BuildFinishedWorker do
subject
end
+
+ context 'when build is failed' do
+ before do
+ build.update!(status: :failed)
+ end
+
+ it 'adds a todo' do
+ expect(::Ci::MergeRequests::AddTodoWhenBuildFailsWorker).to receive(:perform_async)
+
+ subject
+ end
+
+ context 'when async_add_build_failure_todo disabled' do
+ before do
+ stub_feature_flags(async_add_build_failure_todo: false)
+ end
+
+ it 'does not add a todo' do
+ expect(::Ci::MergeRequests::AddTodoWhenBuildFailsWorker).not_to receive(:perform_async)
+
+ subject
+ end
+ end
+ end
+
+ context 'when build has a chat' do
+ before do
+ build.pipeline.update!(source: :chat)
+ end
+
+ it 'schedules a ChatNotification job' do
+ expect(ChatNotificationWorker).to receive(:perform_async).with(build.id)
+
+ subject
+ end
+ end
end
context 'when build does not exist' do
@@ -38,15 +72,5 @@ RSpec.describe BuildFinishedWorker do
.not_to raise_error
end
end
-
- context 'when build has a chat' do
- let(:build) { create(:ci_build, :success, pipeline: create(:ci_pipeline, source: :chat)) }
-
- it 'schedules a ChatNotification job' do
- expect(ChatNotificationWorker).to receive(:perform_async).with(build.id)
-
- subject
- end
- end
end
end
diff --git a/spec/workers/ci/merge_requests/add_todo_when_build_fails_worker_spec.rb b/spec/workers/ci/merge_requests/add_todo_when_build_fails_worker_spec.rb
new file mode 100644
index 00000000000..4690c73d121
--- /dev/null
+++ b/spec/workers/ci/merge_requests/add_todo_when_build_fails_worker_spec.rb
@@ -0,0 +1,53 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Ci::MergeRequests::AddTodoWhenBuildFailsWorker do
+ describe '#perform' do
+ let_it_be(:project) { create(:project) }
+ let_it_be(:pipeline) { create(:ci_pipeline, :detached_merge_request_pipeline) }
+ let_it_be(:job) { create(:ci_build, project: project, pipeline: pipeline, status: :failed) }
+
+ let(:job_args) { job.id }
+
+ subject(:perform_twice) { perform_multiple(job_args, exec_times: 2) }
+
+ include_examples 'an idempotent worker' do
+ it 'executes todo service' do
+ service = double
+ expect(::MergeRequests::AddTodoWhenBuildFailsService).to receive(:new).with(project, nil).and_return(service).twice
+ expect(service).to receive(:execute).with(job).twice
+
+ perform_twice
+ end
+ end
+
+ context 'when job does not exist' do
+ let(:job_args) { 0 }
+
+ it 'returns nil' do
+ expect(described_class.new.perform(job_args)).to eq(nil)
+ end
+ end
+
+ context 'when project does not exist' do
+ before do
+ job.update!(project_id: nil)
+ end
+
+ it 'returns nil' do
+ expect(described_class.new.perform(job_args)).to eq(nil)
+ end
+ end
+
+ context 'when pipeline does not exist' do
+ before do
+ job.update_attribute('pipeline_id', nil)
+ end
+
+ it 'returns nil' do
+ expect(described_class.new.perform(job_args)).to eq(nil)
+ end
+ end
+ end
+end
diff --git a/vendor/gitignore/C++.gitignore b/vendor/gitignore/C++.gitignore
index 259148fa18f..259148fa18f 100644..100755
--- a/vendor/gitignore/C++.gitignore
+++ b/vendor/gitignore/C++.gitignore
diff --git a/vendor/gitignore/Java.gitignore b/vendor/gitignore/Java.gitignore
index a1c2a238a96..a1c2a238a96 100644..100755
--- a/vendor/gitignore/Java.gitignore
+++ b/vendor/gitignore/Java.gitignore