Skip to content

Commit

Permalink
Add latest changes from gitlab-org/gitlab@master
Browse files Browse the repository at this point in the history
  • Loading branch information
GitLab Bot committed May 20, 2020
1 parent 1d5ae04 commit f781b0b
Show file tree
Hide file tree
Showing 22 changed files with 553 additions and 37 deletions.
19 changes: 19 additions & 0 deletions .gitlab/ci/frontend.gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -334,3 +334,22 @@ webpack-dev-server:
expire_in: 31d
paths:
- webpack-dev-server.json

bundle-size-review:
extends:
- .default-retry
- .frontend:rules:bundle-size-review
image: registry.gitlab.com/gitlab-org/gitlab-build-images:danger
stage: test
needs: ["gitlab:assets:compile pull-cache"]
script:
- mkdir -p bundle-size-review
- cp webpack-report/index.html bundle-size-review/bundle-report.html
- yarn global add https://gitlab.com/gitlab-org/frontend/playground/webpack-memory-metrics.git
- danger --dangerfile=danger/bundle_size/Dangerfile --fail-on-errors=true --verbose --danger_id=bundle-size-review
artifacts:
when: always
name: bundle-size-review
expire_in: 31d
paths:
- bundle-size-review
22 changes: 17 additions & 5 deletions .gitlab/ci/rules.gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,11 @@

.frontend-patterns: &frontend-patterns
- "{package.json,yarn.lock}"
- "{babel.config,jest.config}.js"
- "babel.config.js"
- "jest.config.{base,integration,unit}.js"
- ".csscomb.json"
- "Dockerfile.assets"
- "config/**/*.js"
- "vendor/assets/**/*"
- "{,ee/}{app/assets,app/helpers,app/presenters,app/views,locale,public,symbol}/**/*"

Expand All @@ -93,7 +95,8 @@

.code-patterns: &code-patterns
- "{package.json,yarn.lock}"
- "{babel.config,jest.config}.js"
- "babel.config.js"
- "jest.config.{base,integration,unit}.js"
- ".csscomb.json"
- "Dockerfile.assets"
- "vendor/assets/**/*"
Expand All @@ -113,7 +116,8 @@

.code-backstage-patterns: &code-backstage-patterns
- "{package.json,yarn.lock}"
- "{babel.config,jest.config}.js"
- "babel.config.js"
- "jest.config.{base,integration,unit}.js"
- ".csscomb.json"
- "Dockerfile.assets"
- "vendor/assets/**/*"
Expand All @@ -135,7 +139,8 @@

.code-qa-patterns: &code-qa-patterns
- "{package.json,yarn.lock}"
- "{babel.config,jest.config}.js"
- "babel.config.js"
- "jest.config.{base,integration,unit}.js"
- ".csscomb.json"
- "Dockerfile.assets"
- "vendor/assets/**/*"
Expand All @@ -154,7 +159,8 @@

.code-backstage-qa-patterns: &code-backstage-qa-patterns
- "{package.json,yarn.lock}"
- "{babel.config,jest.config}.js"
- "babel.config.js"
- "jest.config.{base,integration,unit}.js"
- ".csscomb.json"
- "Dockerfile.assets"
- "vendor/assets/**/*"
Expand Down Expand Up @@ -335,6 +341,12 @@
changes: *frontend-dependency-patterns
allow_failure: true

.frontend:rules:bundle-size-review:
rules:
- if: '$DANGER_GITLAB_API_TOKEN && $CI_MERGE_REQUEST_IID && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "master"'
changes: *frontend-patterns
allow_failure: true

################
# Memory rules #
################
Expand Down
1 change: 0 additions & 1 deletion .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -375,7 +375,6 @@ RSpec/LeakyConstantDeclaration:
- 'spec/models/concerns/bulk_insertable_associations_spec.rb'
- 'spec/models/concerns/triggerable_hooks_spec.rb'
- 'spec/models/repository_spec.rb'
- 'spec/requests/api/graphql/tasks/task_completion_status_spec.rb'
- 'spec/serializers/commit_entity_spec.rb'
- 'spec/services/clusters/applications/check_installation_progress_service_spec.rb'
- 'spec/services/clusters/applications/check_uninstall_progress_service_spec.rb'
Expand Down
2 changes: 2 additions & 0 deletions app/controllers/concerns/integrations_actions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,12 @@ def edit

def update
saved = integration.update(service_params[:service])
overwrite = ActiveRecord::Type::Boolean.new.cast(params[:overwrite])

respond_to do |format|
format.html do
if saved
PropagateIntegrationWorker.perform_async(integration.id, overwrite)
redirect_to scoped_edit_integration_path(integration), notice: success_message
else
render 'shared/integrations/edit'
Expand Down
25 changes: 25 additions & 0 deletions app/models/data_list.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# frozen_string_literal: true

class DataList
def initialize(batch, data_fields_hash, klass)
@batch = batch
@data_fields_hash = data_fields_hash
@klass = klass
end

def to_array
[klass, columns, values]
end

private

attr_reader :batch, :data_fields_hash, :klass

def columns
data_fields_hash.keys << 'service_id'
end

def values
batch.map { |row| data_fields_hash.values << row['id'] }
end
end
8 changes: 8 additions & 0 deletions app/models/service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,14 @@ def json_fields
%w(active)
end

def to_service_hash
as_json(methods: :type, except: %w[id template instance project_id])
end

def to_data_fields_hash
data_fields.as_json(only: data_fields.class.column_names).except('id', 'service_id')
end

def test_data(project, user)
Gitlab::DataBuilder::Push.build_sample(project, user)
end
Expand Down
27 changes: 27 additions & 0 deletions app/models/service_list.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# frozen_string_literal: true

class ServiceList
def initialize(batch, service_hash, extra_hash = {})
@batch = batch
@service_hash = service_hash
@extra_hash = extra_hash
end

def to_array
[Service, columns, values]
end

private

attr_reader :batch, :service_hash, :extra_hash

def columns
(service_hash.keys << 'project_id') + extra_hash.keys
end

def values
batch.map do |project_id|
(service_hash.values << project_id) + extra_hash.values
end
end
end
144 changes: 144 additions & 0 deletions app/services/admin/propagate_integration_service.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
# frozen_string_literal: true

module Admin
class PropagateIntegrationService
BATCH_SIZE = 100

delegate :data_fields_present?, to: :integration

def self.propagate(integration:, overwrite:)
new(integration, overwrite).propagate
end

def initialize(integration, overwrite)
@integration = integration
@overwrite = overwrite
end

def propagate
if overwrite
update_integration_for_all_projects
else
update_integration_for_inherited_projects
end

create_integration_for_projects_without_integration
end

private

attr_reader :integration, :overwrite

# rubocop: disable Cop/InBatches
# rubocop: disable CodeReuse/ActiveRecord
def update_integration_for_inherited_projects
Service.where(type: integration.type, inherit_from_id: integration.id).in_batches(of: BATCH_SIZE) do |batch|
bulk_update_from_integration(batch)
end
end

def update_integration_for_all_projects
Service.where(type: integration.type).in_batches(of: BATCH_SIZE) do |batch|
bulk_update_from_integration(batch)
end
end
# rubocop: enable Cop/InBatches
# rubocop: enable CodeReuse/ActiveRecord

# rubocop: disable CodeReuse/ActiveRecord
def bulk_update_from_integration(batch)
# Retrieving the IDs instantiates the ActiveRecord relation (batch)
# into concrete models, otherwise update_all will clear the relation.
# https://stackoverflow.com/q/34811646/462015
batch_ids = batch.pluck(:id)

Service.transaction do
batch.update_all(service_hash)

if data_fields_present?
integration.data_fields.class.where(service_id: batch_ids).update_all(data_fields_hash)
end
end
end
# rubocop: enable CodeReuse/ActiveRecord

def create_integration_for_projects_without_integration
loop do
batch = Project.uncached { project_ids_without_integration }

bulk_create_from_integration(batch) unless batch.empty?

break if batch.size < BATCH_SIZE
end
end

def bulk_create_from_integration(batch)
service_list = ServiceList.new(batch, service_hash, { 'inherit_from_id' => integration.id }).to_array

Project.transaction do
results = bulk_insert(*service_list)

if data_fields_present?
data_list = DataList.new(results, data_fields_hash, integration.data_fields.class).to_array

bulk_insert(*data_list)
end

run_callbacks(batch)
end
end

def bulk_insert(klass, columns, values_array)
items_to_insert = values_array.map { |array| Hash[columns.zip(array)] }

klass.insert_all(items_to_insert, returning: [:id])
end

# rubocop: disable CodeReuse/ActiveRecord
def run_callbacks(batch)
if active_external_issue_tracker?
Project.where(id: batch).update_all(has_external_issue_tracker: true)
end

if active_external_wiki?
Project.where(id: batch).update_all(has_external_wiki: true)
end
end
# rubocop: enable CodeReuse/ActiveRecord

def active_external_issue_tracker?
integration.issue_tracker? && !integration.default
end

def active_external_wiki?
integration.type == 'ExternalWikiService'
end

def project_ids_without_integration
Project.connection.select_values(
<<-SQL
SELECT id
FROM projects
WHERE NOT EXISTS (
SELECT true
FROM services
WHERE services.project_id = projects.id
AND services.type = #{ActiveRecord::Base.connection.quote(integration.type)}
)
AND projects.pending_delete = false
AND projects.archived = false
LIMIT #{BATCH_SIZE}
SQL
)
end

def service_hash
@service_hash ||= integration.to_service_hash
.tap { |json| json['inherit_from_id'] = integration.id }
end

def data_fields_hash
@data_fields_hash ||= integration.to_data_fields_hash
end
end
end
16 changes: 7 additions & 9 deletions app/services/projects/propagate_service_template.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,17 +35,15 @@ def propagate_projects_with_template
end

def bulk_create_from_template(batch)
service_list = batch.map do |project_id|
service_hash.values << project_id
end
service_list = ServiceList.new(batch, service_hash).to_array

Project.transaction do
results = bulk_insert(Service, service_hash.keys << 'project_id', service_list)
results = bulk_insert(*service_list)

if data_fields_present?
data_list = results.map { |row| data_hash.values << row['id'] }
data_list = DataList.new(results, data_fields_hash, template.data_fields.class).to_array

bulk_insert(template.data_fields.class, data_hash.keys << 'service_id', data_list)
bulk_insert(*data_list)
end

run_callbacks(batch)
Expand Down Expand Up @@ -77,11 +75,11 @@ def bulk_insert(klass, columns, values_array)
end

def service_hash
@service_hash ||= template.as_json(methods: :type, except: %w[id template project_id])
@service_hash ||= template.to_service_hash
end

def data_hash
@data_hash ||= template.data_fields.as_json(only: template.data_fields.class.column_names).except('id', 'service_id')
def data_fields_hash
@data_fields_hash ||= template.to_data_fields_hash
end

# rubocop: disable CodeReuse/ActiveRecord
Expand Down
7 changes: 7 additions & 0 deletions app/workers/all_queues.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1291,6 +1291,13 @@
:resource_boundary: :unknown
:weight: 1
:idempotent: true
- :name: propagate_integration
:feature_category: :integrations
:has_external_dependencies:
:urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent: true
- :name: propagate_service_template
:feature_category: :source_code_management
:has_external_dependencies:
Expand Down
16 changes: 16 additions & 0 deletions app/workers/propagate_integration_worker.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# frozen_string_literal: true

class PropagateIntegrationWorker
include ApplicationWorker

feature_category :integrations

idempotent!

def perform(integration_id, overwrite)
Admin::PropagateIntegrationService.propagate(
integration: Service.find(integration_id),
overwrite: overwrite
)
end
end
5 changes: 5 additions & 0 deletions changelogs/unreleased/leaky-constant-fix-14.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
title: Fix leaky constant issue in task completion status spec
merge_request: 32043
author: Rajendra Kadam
type: fixed
Loading

0 comments on commit f781b0b

Please sign in to comment.