summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Gemfile4
-rw-r--r--Gemfile.lock14
-rw-r--r--app/graphql/mutations/alert_management/http_integration/create.rb11
-rw-r--r--app/graphql/mutations/alert_management/http_integration/http_integration_base.rb7
-rw-r--r--app/graphql/mutations/alert_management/http_integration/update.rb4
-rw-r--r--app/helpers/groups/group_members_helper.rb2
-rw-r--r--app/helpers/projects/project_members_helper.rb26
-rw-r--r--app/serializers/group_group_link_entity.rb50
-rw-r--r--app/serializers/group_group_link_serializer.rb5
-rw-r--r--app/serializers/group_link/group_group_link_entity.rb25
-rw-r--r--app/serializers/group_link/group_group_link_serializer.rb7
-rw-r--r--app/serializers/group_link/group_link_entity.rb34
-rw-r--r--app/serializers/group_link/project_group_link_entity.rb22
-rw-r--r--app/serializers/group_link/project_group_link_serializer.rb7
-rw-r--r--app/services/alert_management/http_integrations/update_service.rb15
-rw-r--r--changelogs/unreleased/fj-create-group-repository-storage-move-table.yml5
-rw-r--r--changelogs/unreleased/id-update-bundler-audit.yml5
-rw-r--r--changelogs/unreleased/id-update-default-value-for.yml5
-rw-r--r--changelogs/unreleased/mc-backstage-cleanup-artifact-expiry-migration-problem.yml5
-rw-r--r--changelogs/unreleased/remove-owner-data-from-group-webhooks.yml5
-rw-r--r--config/routes/project.rb4
-rw-r--r--db/migrate/20210115090452_create_group_repository_storage_move.rb34
-rw-r--r--db/post_migrate/20201208175117_schedule_backfilling_artifact_expiry_migration.rb18
-rw-r--r--db/post_migrate/20210115215854_cancel_artifact_expiry_backfill.rb22
-rw-r--r--db/schema_migrations/202101150904521
-rw-r--r--db/schema_migrations/202101152158541
-rw-r--r--db/structure.sql31
-rw-r--r--doc/administration/geo/replication/version_specific_updates.md8
-rw-r--r--doc/api/graphql/reference/gitlab_schema.graphql10
-rw-r--r--doc/api/graphql/reference/gitlab_schema.json28
-rw-r--r--doc/system_hooks/system_hooks.md12
-rw-r--r--lib/api/debian_group_packages.rb2
-rw-r--r--lib/api/debian_package_endpoints.rb10
-rw-r--r--lib/api/debian_project_packages.rb8
-rw-r--r--lib/gitlab/hook_data/group_builder.rb8
-rw-r--r--locale/gitlab.pot3
-rw-r--r--spec/fixtures/api/schemas/group_group_links.json6
-rw-r--r--spec/fixtures/api/schemas/group_link/group_group_link.json16
-rw-r--r--spec/fixtures/api/schemas/group_link/group_group_links.json6
-rw-r--r--spec/fixtures/api/schemas/group_link/group_link.json (renamed from spec/fixtures/api/schemas/entities/group_group_link.json)10
-rw-r--r--spec/fixtures/api/schemas/group_link/project_group_link.json16
-rw-r--r--spec/fixtures/api/schemas/group_link/project_group_links.json6
-rw-r--r--spec/helpers/groups/group_members_helper_spec.rb2
-rw-r--r--spec/helpers/projects/project_members_helper_spec.rb56
-rw-r--r--spec/lib/gitlab/hook_data/group_builder_spec.rb5
-rw-r--r--spec/requests/api/debian_group_packages_spec.rb20
-rw-r--r--spec/requests/api/debian_project_packages_spec.rb28
-rw-r--r--spec/requests/api/graphql/mutations/alert_management/http_integration/update_spec.rb16
-rw-r--r--spec/serializers/group_link/group_group_link_entity_spec.rb (renamed from spec/serializers/group_group_link_entity_spec.rb)8
-rw-r--r--spec/serializers/group_link/group_group_link_serializer_spec.rb (renamed from spec/serializers/group_group_link_serializer_spec.rb)4
-rw-r--r--spec/serializers/group_link/group_link_entity_spec.rb25
-rw-r--r--spec/serializers/group_link/project_group_link_entity_spec.rb30
-rw-r--r--spec/serializers/group_link/project_group_link_serializer_spec.rb13
-rw-r--r--spec/services/system_hooks_service_spec.rb6
-rw-r--r--spec/support/shared_examples/graphql/mutations/http_integrations_shared_examples.rb75
55 files changed, 628 insertions, 178 deletions
diff --git a/Gemfile b/Gemfile
index 1b1e7fb8e82..c1443a193b7 100644
--- a/Gemfile
+++ b/Gemfile
@@ -10,7 +10,7 @@ gem 'responders', '~> 3.0'
gem 'sprockets', '~> 3.7.0'
# Default values for AR models
-gem 'default_value_for', '~> 3.3.0'
+gem 'default_value_for', '~> 3.4.0'
# Supported DBs
gem 'pg', '~> 1.1'
@@ -374,7 +374,7 @@ group :development, :test do
gem 'scss_lint', '~> 0.59.0', require: false
gem 'haml_lint', '~> 0.36.0', require: false
- gem 'bundler-audit', '~> 0.6.1', require: false
+ gem 'bundler-audit', '~> 0.7.0.1', require: false
gem 'benchmark-ips', '~> 2.3.0', require: false
diff --git a/Gemfile.lock b/Gemfile.lock
index ac97a5d1433..59eb3421266 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -150,9 +150,9 @@ GEM
bullet (6.1.0)
activesupport (>= 3.0.0)
uniform_notifier (~> 1.11)
- bundler-audit (0.6.1)
+ bundler-audit (0.7.0.1)
bundler (>= 1.2.0, < 3)
- thor (~> 0.18)
+ thor (>= 0.18, < 2)
byebug (11.1.3)
capybara (3.34.0)
addressable
@@ -227,8 +227,8 @@ GEM
html-pipeline
declarative (0.0.20)
declarative-option (0.1.0)
- default_value_for (3.3.0)
- activerecord (>= 3.2.0, < 6.1)
+ default_value_for (3.4.0)
+ activerecord (>= 3.2.0, < 7.0)
deprecation_toolkit (1.5.1)
activesupport (>= 4.2)
derailed_benchmarks (1.8.1)
@@ -1177,7 +1177,7 @@ GEM
daemons (~> 1.0, >= 1.0.9)
eventmachine (~> 1.0, >= 1.0.4)
rack (>= 1, < 3)
- thor (0.20.3)
+ thor (1.1.0)
thread_safe (0.3.6)
thrift (0.13.0)
tilt (2.0.10)
@@ -1306,7 +1306,7 @@ DEPENDENCIES
brakeman (~> 4.2)
browser (~> 4.2)
bullet (~> 6.1.0)
- bundler-audit (~> 0.6.1)
+ bundler-audit (~> 0.7.0.1)
capybara (~> 3.34.0)
capybara-screenshot (~> 1.0.22)
carrierwave (~> 1.3)
@@ -1320,7 +1320,7 @@ DEPENDENCIES
danger (~> 8.0.6)
database_cleaner (~> 1.7.0)
deckar01-task_list (= 2.3.1)
- default_value_for (~> 3.3.0)
+ default_value_for (~> 3.4.0)
deprecation_toolkit (~> 1.5.1)
derailed_benchmarks
device_detector
diff --git a/app/graphql/mutations/alert_management/http_integration/create.rb b/app/graphql/mutations/alert_management/http_integration/create.rb
index ff165d7f302..e1531148a76 100644
--- a/app/graphql/mutations/alert_management/http_integration/create.rb
+++ b/app/graphql/mutations/alert_management/http_integration/create.rb
@@ -21,27 +21,20 @@ module Mutations
description: 'Whether the integration is receiving alerts.'
def resolve(args)
- @project = authorized_find!(full_path: args[:project_path])
+ project = authorized_find!(full_path: args[:project_path])
response ::AlertManagement::HttpIntegrations::CreateService.new(
project,
current_user,
- http_integration_params(args)
+ http_integration_params(project, args)
).execute
end
private
- attr_reader :project
-
def find_object(full_path:)
resolve_project(full_path: full_path)
end
-
- # overriden in EE
- def http_integration_params(args)
- args.slice(:name, :active)
- end
end
end
end
diff --git a/app/graphql/mutations/alert_management/http_integration/http_integration_base.rb b/app/graphql/mutations/alert_management/http_integration/http_integration_base.rb
index 147df982bec..e33b7bb399a 100644
--- a/app/graphql/mutations/alert_management/http_integration/http_integration_base.rb
+++ b/app/graphql/mutations/alert_management/http_integration/http_integration_base.rb
@@ -23,7 +23,14 @@ module Mutations
errors: result.errors
}
end
+
+ # overriden in EE
+ def http_integration_params(_project, args)
+ args.slice(:name, :active)
+ end
end
end
end
end
+
+Mutations::AlertManagement::HttpIntegration::HttpIntegrationBase.prepend_if_ee('::EE::Mutations::AlertManagement::HttpIntegration::HttpIntegrationBase')
diff --git a/app/graphql/mutations/alert_management/http_integration/update.rb b/app/graphql/mutations/alert_management/http_integration/update.rb
index 431fccaa5e5..b1e4ce841ee 100644
--- a/app/graphql/mutations/alert_management/http_integration/update.rb
+++ b/app/graphql/mutations/alert_management/http_integration/update.rb
@@ -24,10 +24,12 @@ module Mutations
response ::AlertManagement::HttpIntegrations::UpdateService.new(
integration,
current_user,
- args.slice(:name, :active)
+ http_integration_params(integration.project, args)
).execute
end
end
end
end
end
+
+Mutations::AlertManagement::HttpIntegration::Update.prepend_if_ee('::EE::Mutations::AlertManagement::HttpIntegration::Update')
diff --git a/app/helpers/groups/group_members_helper.rb b/app/helpers/groups/group_members_helper.rb
index 76f31dc97cb..0f2c7ba2630 100644
--- a/app/helpers/groups/group_members_helper.rb
+++ b/app/helpers/groups/group_members_helper.rb
@@ -14,7 +14,7 @@ module Groups::GroupMembersHelper
end
def group_group_links_data_json(group_links)
- GroupGroupLinkSerializer.new.represent(group_links, { current_user: current_user }).to_json
+ GroupLink::GroupGroupLinkSerializer.new.represent(group_links, { current_user: current_user }).to_json
end
def members_data_json(group, members)
diff --git a/app/helpers/projects/project_members_helper.rb b/app/helpers/projects/project_members_helper.rb
index 168526d2abb..7c6989c0830 100644
--- a/app/helpers/projects/project_members_helper.rb
+++ b/app/helpers/projects/project_members_helper.rb
@@ -26,4 +26,30 @@ module Projects::ProjectMembersHelper
project.group.has_owner?(current_user)
end
+
+ def project_group_links_data_json(group_links)
+ GroupLink::ProjectGroupLinkSerializer.new.represent(group_links, { current_user: current_user }).to_json
+ end
+
+ def project_members_data_json(project, members)
+ MemberSerializer.new.represent(members, { current_user: current_user, group: project.group }).to_json
+ end
+
+ def project_members_list_data_attributes(project, members)
+ {
+ members: project_members_data_json(project, members),
+ member_path: project_project_member_path(project, ':id'),
+ source_id: project.id,
+ can_manage_members: can_manage_project_members?(project)
+ }
+ end
+
+ def project_group_links_list_data_attributes(project, group_links)
+ {
+ members: project_group_links_data_json(group_links),
+ member_path: project_group_link_path(project, ':id'),
+ source_id: project.id,
+ can_manage_members: can_manage_project_members?(project)
+ }
+ end
end
diff --git a/app/serializers/group_group_link_entity.rb b/app/serializers/group_group_link_entity.rb
deleted file mode 100644
index 1e736214f54..00000000000
--- a/app/serializers/group_group_link_entity.rb
+++ /dev/null
@@ -1,50 +0,0 @@
-# frozen_string_literal: true
-
-class GroupGroupLinkEntity < Grape::Entity
- include RequestAwareEntity
-
- expose :id
- expose :created_at
- expose :expires_at do |group_link|
- group_link.expires_at&.to_time
- end
-
- expose :can_update do |group_link|
- can_manage?(group_link)
- end
-
- expose :can_remove do |group_link|
- can_manage?(group_link)
- end
-
- expose :access_level do
- expose :human_access, as: :string_value
- expose :group_access, as: :integer_value
- end
-
- expose :valid_roles do |group_link|
- group_link.class.access_options
- end
-
- expose :shared_with_group do
- expose :avatar_url do |group_link|
- group_link.shared_with_group.avatar_url(only_path: false)
- end
-
- expose :web_url do |group_link|
- group_link.shared_with_group.web_url
- end
-
- expose :shared_with_group, merge: true, using: GroupBasicEntity
- end
-
- private
-
- def current_user
- options[:current_user]
- end
-
- def can_manage?(group_link)
- can?(current_user, :admin_group_member, group_link.shared_group)
- end
-end
diff --git a/app/serializers/group_group_link_serializer.rb b/app/serializers/group_group_link_serializer.rb
deleted file mode 100644
index 6ae8daf9207..00000000000
--- a/app/serializers/group_group_link_serializer.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-# frozen_string_literal: true
-
-class GroupGroupLinkSerializer < BaseSerializer
- entity GroupGroupLinkEntity
-end
diff --git a/app/serializers/group_link/group_group_link_entity.rb b/app/serializers/group_link/group_group_link_entity.rb
new file mode 100644
index 00000000000..cedc8bd8582
--- /dev/null
+++ b/app/serializers/group_link/group_group_link_entity.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+module GroupLink
+ class GroupGroupLinkEntity < GroupLink::GroupLinkEntity
+ include RequestAwareEntity
+
+ expose :can_update do |group_link|
+ can_manage?(group_link)
+ end
+
+ expose :can_remove do |group_link|
+ can_manage?(group_link)
+ end
+
+ private
+
+ def current_user
+ options[:current_user]
+ end
+
+ def can_manage?(group_link)
+ can?(current_user, :admin_group_member, group_link.shared_group)
+ end
+ end
+end
diff --git a/app/serializers/group_link/group_group_link_serializer.rb b/app/serializers/group_link/group_group_link_serializer.rb
new file mode 100644
index 00000000000..1e3f861f09a
--- /dev/null
+++ b/app/serializers/group_link/group_group_link_serializer.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+module GroupLink
+ class GroupGroupLinkSerializer < BaseSerializer
+ entity GroupLink::GroupGroupLinkEntity
+ end
+end
diff --git a/app/serializers/group_link/group_link_entity.rb b/app/serializers/group_link/group_link_entity.rb
new file mode 100644
index 00000000000..12349320b6f
--- /dev/null
+++ b/app/serializers/group_link/group_link_entity.rb
@@ -0,0 +1,34 @@
+# frozen_string_literal: true
+
+module GroupLink
+ class GroupLinkEntity < Grape::Entity
+ include RequestAwareEntity
+
+ expose :id
+ expose :created_at
+ expose :expires_at do |group_link|
+ group_link.expires_at&.to_time
+ end
+
+ expose :access_level do
+ expose :human_access, as: :string_value
+ expose :group_access, as: :integer_value
+ end
+
+ expose :valid_roles do |group_link|
+ group_link.class.access_options
+ end
+
+ expose :shared_with_group do
+ expose :avatar_url do |group_link|
+ group_link.shared_with_group.avatar_url(only_path: false, size: Member::AVATAR_SIZE)
+ end
+
+ expose :web_url do |group_link|
+ group_link.shared_with_group.web_url
+ end
+
+ expose :shared_with_group, merge: true, using: GroupBasicEntity
+ end
+ end
+end
diff --git a/app/serializers/group_link/project_group_link_entity.rb b/app/serializers/group_link/project_group_link_entity.rb
new file mode 100644
index 00000000000..2ff275fff01
--- /dev/null
+++ b/app/serializers/group_link/project_group_link_entity.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+module GroupLink
+ class ProjectGroupLinkEntity < GroupLink::GroupLinkEntity
+ include RequestAwareEntity
+ include Projects::ProjectMembersHelper
+
+ expose :can_update do |group_link|
+ can_manage_project_members?(group_link.project)
+ end
+
+ expose :can_remove do |group_link|
+ can_manage_project_members?(group_link.project)
+ end
+
+ private
+
+ def current_user
+ options[:current_user]
+ end
+ end
+end
diff --git a/app/serializers/group_link/project_group_link_serializer.rb b/app/serializers/group_link/project_group_link_serializer.rb
new file mode 100644
index 00000000000..b2559e61e31
--- /dev/null
+++ b/app/serializers/group_link/project_group_link_serializer.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+module GroupLink
+ class ProjectGroupLinkSerializer < BaseSerializer
+ entity GroupLink::ProjectGroupLinkEntity
+ end
+end
diff --git a/app/services/alert_management/http_integrations/update_service.rb b/app/services/alert_management/http_integrations/update_service.rb
index 220c4e759f0..af079f670b8 100644
--- a/app/services/alert_management/http_integrations/update_service.rb
+++ b/app/services/alert_management/http_integrations/update_service.rb
@@ -9,7 +9,7 @@ module AlertManagement
def initialize(integration, current_user, params)
@integration = integration
@current_user = current_user
- @params = params
+ @params = params.with_indifferent_access
end
def execute
@@ -17,7 +17,7 @@ module AlertManagement
params[:token] = nil if params.delete(:regenerate_token)
- if integration.update(params)
+ if integration.update(permitted_params)
success
else
error(integration.errors.full_messages.to_sentence)
@@ -32,6 +32,15 @@ module AlertManagement
current_user&.can?(:admin_operations, integration)
end
+ def permitted_params
+ params.slice(*permitted_params_keys)
+ end
+
+ # overriden in EE
+ def permitted_params_keys
+ %i[name active token]
+ end
+
def error(message)
ServiceResponse.error(message: message)
end
@@ -46,3 +55,5 @@ module AlertManagement
end
end
end
+
+::AlertManagement::HttpIntegrations::UpdateService.prepend_if_ee('::EE::AlertManagement::HttpIntegrations::UpdateService')
diff --git a/changelogs/unreleased/fj-create-group-repository-storage-move-table.yml b/changelogs/unreleased/fj-create-group-repository-storage-move-table.yml
new file mode 100644
index 00000000000..bd0b61cf944
--- /dev/null
+++ b/changelogs/unreleased/fj-create-group-repository-storage-move-table.yml
@@ -0,0 +1,5 @@
+---
+title: Create Groups::RepositoryStorageMove table
+merge_request: 51803
+author:
+type: added
diff --git a/changelogs/unreleased/id-update-bundler-audit.yml b/changelogs/unreleased/id-update-bundler-audit.yml
new file mode 100644
index 00000000000..99cca4f2319
--- /dev/null
+++ b/changelogs/unreleased/id-update-bundler-audit.yml
@@ -0,0 +1,5 @@
+---
+title: Update bundler-audit gem to 0.7.0.1
+merge_request: 52269
+author:
+type: other
diff --git a/changelogs/unreleased/id-update-default-value-for.yml b/changelogs/unreleased/id-update-default-value-for.yml
new file mode 100644
index 00000000000..e696aef5ab6
--- /dev/null
+++ b/changelogs/unreleased/id-update-default-value-for.yml
@@ -0,0 +1,5 @@
+---
+title: Update default_value_for gem to 3.4.0
+merge_request: 52271
+author:
+type: other
diff --git a/changelogs/unreleased/mc-backstage-cleanup-artifact-expiry-migration-problem.yml b/changelogs/unreleased/mc-backstage-cleanup-artifact-expiry-migration-problem.yml
new file mode 100644
index 00000000000..bbe9a5bebfe
--- /dev/null
+++ b/changelogs/unreleased/mc-backstage-cleanup-artifact-expiry-migration-problem.yml
@@ -0,0 +1,5 @@
+---
+title: Cancel artifact expiry backfill background jobs.
+merge_request: 51821
+author:
+type: fixed
diff --git a/changelogs/unreleased/remove-owner-data-from-group-webhooks.yml b/changelogs/unreleased/remove-owner-data-from-group-webhooks.yml
new file mode 100644
index 00000000000..0b1114ab974
--- /dev/null
+++ b/changelogs/unreleased/remove-owner-data-from-group-webhooks.yml
@@ -0,0 +1,5 @@
+---
+title: Remove group owner data from webhooks
+merge_request: 52071
+author:
+type: changed
diff --git a/config/routes/project.rb b/config/routes/project.rb
index 2e61bc8175e..c74d0c19d35 100644
--- a/config/routes/project.rb
+++ b/config/routes/project.rb
@@ -132,7 +132,7 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do
end
end
- resources :project_members, except: [:show, :new, :edit], constraints: { id: %r{[a-zA-Z./0-9_\-#%+]+} }, concerns: :access_requestable do
+ resources :project_members, except: [:show, :new, :edit], constraints: { id: %r{[a-zA-Z./0-9_\-#%+:]+} }, concerns: :access_requestable do
collection do
delete :leave
@@ -219,7 +219,7 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do
resources :starrers, only: [:index]
resources :forks, only: [:index, :new, :create]
- resources :group_links, only: [:create, :update, :destroy], constraints: { id: /\d+/ }
+ resources :group_links, only: [:create, :update, :destroy], constraints: { id: /\d+|:id/ }
resource :import, only: [:new, :create, :show]
resource :avatar, only: [:show, :destroy]
diff --git a/db/migrate/20210115090452_create_group_repository_storage_move.rb b/db/migrate/20210115090452_create_group_repository_storage_move.rb
new file mode 100644
index 00000000000..bd168dce5ac
--- /dev/null
+++ b/db/migrate/20210115090452_create_group_repository_storage_move.rb
@@ -0,0 +1,34 @@
+# frozen_string_literal: true
+
+class CreateGroupRepositoryStorageMove < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ disable_ddl_transaction!
+
+ def up
+ unless table_exists?(:group_repository_storage_moves)
+ with_lock_retries do
+ create_table :group_repository_storage_moves do |t|
+ t.timestamps_with_timezone
+ t.references :group, references: :namespace, column: :group_id, index: true, null: false
+ t.integer :state, limit: 2, default: 1, null: false
+ t.text :source_storage_name, null: false
+ t.text :destination_storage_name, null: false
+
+ t.foreign_key :namespaces, column: :group_id, on_delete: :cascade
+ end
+ end
+ end
+
+ add_text_limit(:group_repository_storage_moves, :source_storage_name, 255, constraint_name: 'group_repository_storage_moves_source_storage_name')
+ add_text_limit(:group_repository_storage_moves, :destination_storage_name, 255, constraint_name: 'group_repository_storage_moves_destination_storage_name')
+ end
+
+ def down
+ with_lock_retries do
+ drop_table :group_repository_storage_moves
+ end
+ end
+end
diff --git a/db/post_migrate/20201208175117_schedule_backfilling_artifact_expiry_migration.rb b/db/post_migrate/20201208175117_schedule_backfilling_artifact_expiry_migration.rb
index f11c0bbe33a..1ffe9abbc58 100644
--- a/db/post_migrate/20201208175117_schedule_backfilling_artifact_expiry_migration.rb
+++ b/db/post_migrate/20201208175117_schedule_backfilling_artifact_expiry_migration.rb
@@ -24,12 +24,18 @@ class ScheduleBackfillingArtifactExpiryMigration < ActiveRecord::Migration[6.0]
# Needs to be removed in a later migration
add_concurrent_index(:ci_job_artifacts, %i(id created_at), where: INDEX_CONDITION, name: INDEX_NAME)
- queue_background_migration_jobs_by_range_at_intervals(
- JobArtifact.without_expiry_date.before_switch,
- ::Gitlab::BackgroundMigration::BackfillArtifactExpiryDate,
- 2.minutes,
- batch_size: 200_000
- )
+ # queue_background_migration_jobs_by_range_at_intervals(
+ # JobArtifact.without_expiry_date.before_switch,
+ # ::Gitlab::BackgroundMigration::BackfillArtifactExpiryDate,
+ # 2.minutes,
+ # batch_size: 200_000
+ # )
+ # The scheduling code was using the full class symbol
+ # (`::Gitlab::BackgroundMigration::BackfillArtifactExpiryDate`) instead of a
+ # string with the class name (`BackfillArtifactExpiryDate`) by mistake,
+ # which resulted in an error. It is commented out so it's a no-op to prevent
+ # errors and will be reintroduced with
+ # https://gitlab.com/gitlab-org/gitlab/-/merge_requests/51822.
end
def down
diff --git a/db/post_migrate/20210115215854_cancel_artifact_expiry_backfill.rb b/db/post_migrate/20210115215854_cancel_artifact_expiry_backfill.rb
new file mode 100644
index 00000000000..8a03a90a1c5
--- /dev/null
+++ b/db/post_migrate/20210115215854_cancel_artifact_expiry_backfill.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+class CancelArtifactExpiryBackfill < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+ MIGRATION = 'BackfillArtifactExpiryDate'
+
+ disable_ddl_transaction!
+
+ def up
+ Gitlab::BackgroundMigration.steal(MIGRATION) do |job|
+ job.delete
+
+ false
+ end
+ end
+
+ def down
+ # no-op
+ end
+end
diff --git a/db/schema_migrations/20210115090452 b/db/schema_migrations/20210115090452
new file mode 100644
index 00000000000..92c5574e71f
--- /dev/null
+++ b/db/schema_migrations/20210115090452
@@ -0,0 +1 @@
+5415850ae27c507fd8b1df20951e25b42352f4f9ec8e1402019533170edabdb8 \ No newline at end of file
diff --git a/db/schema_migrations/20210115215854 b/db/schema_migrations/20210115215854
new file mode 100644
index 00000000000..c27de41ad0a
--- /dev/null
+++ b/db/schema_migrations/20210115215854
@@ -0,0 +1 @@
+cb846ce5f6270cfdc543c3d4ad3e861b2a92445b952ee8f0a02f4171b9792411 \ No newline at end of file
diff --git a/db/structure.sql b/db/structure.sql
index ddbd329d9f2..2939895ec07 100644
--- a/db/structure.sql
+++ b/db/structure.sql
@@ -13044,6 +13044,27 @@ CREATE TABLE group_merge_request_approval_settings (
allow_author_approval boolean DEFAULT false NOT NULL
);
+CREATE TABLE group_repository_storage_moves (
+ id bigint NOT NULL,
+ created_at timestamp with time zone NOT NULL,
+ updated_at timestamp with time zone NOT NULL,
+ group_id bigint NOT NULL,
+ state smallint DEFAULT 1 NOT NULL,
+ source_storage_name text NOT NULL,
+ destination_storage_name text NOT NULL,
+ CONSTRAINT group_repository_storage_moves_destination_storage_name CHECK ((char_length(destination_storage_name) <= 255)),
+ CONSTRAINT group_repository_storage_moves_source_storage_name CHECK ((char_length(source_storage_name) <= 255))
+);
+
+CREATE SEQUENCE group_repository_storage_moves_id_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+ALTER SEQUENCE group_repository_storage_moves_id_seq OWNED BY group_repository_storage_moves.id;
+
CREATE TABLE group_wiki_repositories (
shard_id bigint NOT NULL,
group_id bigint NOT NULL,
@@ -18733,6 +18754,8 @@ ALTER TABLE ONLY group_group_links ALTER COLUMN id SET DEFAULT nextval('group_gr
ALTER TABLE ONLY group_import_states ALTER COLUMN group_id SET DEFAULT nextval('group_import_states_group_id_seq'::regclass);
+ALTER TABLE ONLY group_repository_storage_moves ALTER COLUMN id SET DEFAULT nextval('group_repository_storage_moves_id_seq'::regclass);
+
ALTER TABLE ONLY historical_data ALTER COLUMN id SET DEFAULT nextval('historical_data_id_seq'::regclass);
ALTER TABLE ONLY identities ALTER COLUMN id SET DEFAULT nextval('identities_id_seq'::regclass);
@@ -19969,6 +19992,9 @@ ALTER TABLE ONLY group_import_states
ALTER TABLE ONLY group_merge_request_approval_settings
ADD CONSTRAINT group_merge_request_approval_settings_pkey PRIMARY KEY (group_id);
+ALTER TABLE ONLY group_repository_storage_moves
+ ADD CONSTRAINT group_repository_storage_moves_pkey PRIMARY KEY (id);
+
ALTER TABLE ONLY group_wiki_repositories
ADD CONSTRAINT group_wiki_repositories_pkey PRIMARY KEY (group_id);
@@ -21950,6 +21976,8 @@ CREATE INDEX index_group_import_states_on_group_id ON group_import_states USING
CREATE INDEX index_group_import_states_on_user_id ON group_import_states USING btree (user_id) WHERE (user_id IS NOT NULL);
+CREATE INDEX index_group_repository_storage_moves_on_group_id ON group_repository_storage_moves USING btree (group_id);
+
CREATE UNIQUE INDEX index_group_stages_on_group_id_group_value_stream_id_and_name ON analytics_cycle_analytics_group_stages USING btree (group_id, group_value_stream_id, name);
CREATE UNIQUE INDEX index_group_wiki_repositories_on_disk_path ON group_wiki_repositories USING btree (disk_path);
@@ -25260,6 +25288,9 @@ ALTER TABLE ONLY packages_pypi_metadata
ALTER TABLE ONLY packages_dependency_links
ADD CONSTRAINT fk_rails_96ef1c00d3 FOREIGN KEY (package_id) REFERENCES packages_packages(id) ON DELETE CASCADE;
+ALTER TABLE ONLY group_repository_storage_moves
+ ADD CONSTRAINT fk_rails_982bb5daf1 FOREIGN KEY (group_id) REFERENCES namespaces(id) ON DELETE CASCADE;
+
ALTER TABLE ONLY resource_label_events
ADD CONSTRAINT fk_rails_9851a00031 FOREIGN KEY (merge_request_id) REFERENCES merge_requests(id) ON DELETE CASCADE;
diff --git a/doc/administration/geo/replication/version_specific_updates.md b/doc/administration/geo/replication/version_specific_updates.md
index 0d8eba555ab..41e9dbe677c 100644
--- a/doc/administration/geo/replication/version_specific_updates.md
+++ b/doc/administration/geo/replication/version_specific_updates.md
@@ -11,6 +11,14 @@ Check this document if it includes instructions for the version you are updating
These steps go together with the [general steps](updating_the_geo_nodes.md#general-update-steps)
for updating Geo nodes.
+## Updating to GitLab 13.8
+
+We've detected an issue with the `FetchRemove` call that is used by Geo secondaries. This causes performance issues as we execute reference transaction hooks for each updated reference. Please hold off upgrading until this is in [the 13.8.1 patch release.](https://gitlab.com/gitlab-org/gitaly/-/merge_requests/3002). More details are available [in this issue](https://gitlab.com/gitlab-org/git/-/issues/79).
+
+## Updating to GitLab 13.7
+
+We've detected an issue with the `FetchRemove` call that is used by Geo secondaries. This causes performance issues as we execute reference transaction hooks for each updated reference. Please hold off upgrading until this is in [the 13.7.5 patch release.](https://gitlab.com/gitlab-org/gitaly/-/merge_requests/3002). More details are available [in this issue](https://gitlab.com/gitlab-org/git/-/issues/79).
+
## Updating to GitLab 13.5
In GitLab 13.5, there is a [regression that prevents viewing a list of container repositories and registries](https://gitlab.com/gitlab-org/gitlab/-/issues/285475) on Geo secondaries. This issue is fixed in GitLab 13.6.1 and later.
diff --git a/doc/api/graphql/reference/gitlab_schema.graphql b/doc/api/graphql/reference/gitlab_schema.graphql
index 5bd712a9caa..c0bf434bf98 100644
--- a/doc/api/graphql/reference/gitlab_schema.graphql
+++ b/doc/api/graphql/reference/gitlab_schema.graphql
@@ -11622,6 +11622,16 @@ input HttpIntegrationUpdateInput {
The name of the integration.
"""
name: String
+
+ """
+ The custom mapping of GitLab alert attributes to fields from the payload_example.
+ """
+ payloadAttributeMappings: [AlertManagementPayloadAlertFieldInput!]
+
+ """
+ The example of an alert payload.
+ """
+ payloadExample: JsonString
}
"""
diff --git a/doc/api/graphql/reference/gitlab_schema.json b/doc/api/graphql/reference/gitlab_schema.json
index eb1792dc4b8..156befc5109 100644
--- a/doc/api/graphql/reference/gitlab_schema.json
+++ b/doc/api/graphql/reference/gitlab_schema.json
@@ -31575,6 +31575,34 @@
"defaultValue": null
},
{
+ "name": "payloadExample",
+ "description": "The example of an alert payload.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "JsonString",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "payloadAttributeMappings",
+ "description": "The custom mapping of GitLab alert attributes to fields from the payload_example.",
+ "type": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "INPUT_OBJECT",
+ "name": "AlertManagementPayloadAlertFieldInput",
+ "ofType": null
+ }
+ }
+ },
+ "defaultValue": null
+ },
+ {
"name": "clientMutationId",
"description": "A unique identifier for the client performing the mutation.",
"type": {
diff --git a/doc/system_hooks/system_hooks.md b/doc/system_hooks/system_hooks.md
index 7e4d274f21b..196d88bc530 100644
--- a/doc/system_hooks/system_hooks.md
+++ b/doc/system_hooks/system_hooks.md
@@ -300,15 +300,11 @@ If the user is blocked via LDAP, `state` is `ldap_blocked`.
"updated_at": "2012-07-21T07:38:22Z",
"event_name": "group_create",
"name": "StoreCloud",
- "owner_email": null,
- "owner_name": null,
"path": "storecloud",
"group_id": 78
}
```
-`owner_name` and `owner_email` are always `null`. Please see <https://gitlab.com/gitlab-org/gitlab/-/issues/20011>.
-
**Group removed:**
```json
@@ -317,15 +313,11 @@ If the user is blocked via LDAP, `state` is `ldap_blocked`.
"updated_at": "2012-07-21T07:38:22Z",
"event_name": "group_destroy",
"name": "StoreCloud",
- "owner_email": null,
- "owner_name": null,
"path": "storecloud",
"group_id": 78
}
```
-`owner_name` and `owner_email` are always `null`. Please see [issue #20011](https://gitlab.com/gitlab-org/gitlab/-/issues/20011).
-
**Group renamed:**
```json
@@ -337,15 +329,11 @@ If the user is blocked via LDAP, `state` is `ldap_blocked`.
"path": "better-name",
"full_path": "parent-group/better-name",
"group_id": 64,
- "owner_name": null,
- "owner_email": null,
"old_path": "old-name",
"old_full_path": "parent-group/old-name"
}
```
-`owner_name` and `owner_email` are always `null`. Please see <https://gitlab.com/gitlab-org/gitlab/-/issues/20011>.
-
**New Group Member:**
```json
diff --git a/lib/api/debian_group_packages.rb b/lib/api/debian_group_packages.rb
index e3cacc4132f..2235e0858ac 100644
--- a/lib/api/debian_group_packages.rb
+++ b/lib/api/debian_group_packages.rb
@@ -13,7 +13,7 @@ module API
authorize_read_package!(user_group)
end
- namespace ':id/-/packages/debian' do
+ namespace ':id/packages/debian' do
include DebianPackageEndpoints
end
end
diff --git a/lib/api/debian_package_endpoints.rb b/lib/api/debian_package_endpoints.rb
index 9aff34933f7..507c9a5c3eb 100644
--- a/lib/api/debian_package_endpoints.rb
+++ b/lib/api/debian_package_endpoints.rb
@@ -51,7 +51,7 @@ module API
end
namespace 'dists/*distribution', requirements: DISTRIBUTION_REQUIREMENTS do
- # GET {projects|groups}/:id/-/packages/debian/dists/*distribution/Release.gpg
+ # GET {projects|groups}/:id/packages/debian/dists/*distribution/Release.gpg
desc 'The Release file signature' do
detail 'This feature was introduced in GitLab 13.5'
end
@@ -61,7 +61,7 @@ module API
not_found!
end
- # GET {projects|groups}/:id/-/packages/debian/dists/*distribution/Release
+ # GET {projects|groups}/:id/packages/debian/dists/*distribution/Release
desc 'The unsigned Release file' do
detail 'This feature was introduced in GitLab 13.5'
end
@@ -72,7 +72,7 @@ module API
'TODO Release'
end
- # GET {projects|groups}/:id/-/packages/debian/dists/*distribution/InRelease
+ # GET {projects|groups}/:id/packages/debian/dists/*distribution/InRelease
desc 'The signed Release file' do
detail 'This feature was introduced in GitLab 13.5'
end
@@ -88,7 +88,7 @@ module API
end
namespace ':component/binary-:architecture', requirements: COMPONENT_ARCHITECTURE_REQUIREMENTS do
- # GET {projects|groups}/:id/-/packages/debian/dists/*distribution/:component/binary-:architecture/Packages
+ # GET {projects|groups}/:id/packages/debian/dists/*distribution/:component/binary-:architecture/Packages
desc 'The binary files index' do
detail 'This feature was introduced in GitLab 13.5'
end
@@ -108,7 +108,7 @@ module API
end
namespace 'pool/:component/:letter/:source_package', requirements: COMPONENT_LETTER_SOURCE_PACKAGE_REQUIREMENTS do
- # GET {projects|groups}/:id/-/packages/debian/pool/:component/:letter/:source_package/:file_name
+ # GET {projects|groups}/:id/packages/debian/pool/:component/:letter/:source_package/:file_name
params do
requires :file_name, type: String, desc: 'The Debian File Name'
end
diff --git a/lib/api/debian_project_packages.rb b/lib/api/debian_project_packages.rb
index f8129c18dff..8ae0d2ba28b 100644
--- a/lib/api/debian_project_packages.rb
+++ b/lib/api/debian_project_packages.rb
@@ -13,17 +13,17 @@ module API
authorize_read_package!
end
- namespace ':id/-/packages/debian' do
+ namespace ':id/packages/debian' do
include DebianPackageEndpoints
params do
requires :file_name, type: String, desc: 'The file name'
end
- namespace 'incoming/:file_name', requirements: FILE_NAME_REQUIREMENTS do
+ namespace ':file_name', requirements: FILE_NAME_REQUIREMENTS do
content_type :json, Gitlab::Workhorse::INTERNAL_API_CONTENT_TYPE
- # PUT {projects|groups}/:id/-/packages/debian/incoming/:file_name
+ # PUT {projects|groups}/:id/packages/debian/:file_name
params do
requires :file, type: ::API::Validations::Types::WorkhorseFile, desc: 'The package file to be published (generated by Multipart middleware)'
end
@@ -42,7 +42,7 @@ module API
forbidden!
end
- # PUT {projects|groups}/:id/-/packages/debian/incoming/:file_name/authorize
+ # PUT {projects|groups}/:id/packages/debian/:file_name/authorize
route_setting :authentication, deploy_token_allowed: true, basic_auth_personal_access_token: true, job_token_allowed: :basic_auth
put 'authorize' do
authorize_workhorse!(
diff --git a/lib/gitlab/hook_data/group_builder.rb b/lib/gitlab/hook_data/group_builder.rb
index 25c34a4c4a7..5f76144eb83 100644
--- a/lib/gitlab/hook_data/group_builder.rb
+++ b/lib/gitlab/hook_data/group_builder.rb
@@ -14,8 +14,6 @@ module Gitlab
# :path=>"group1",
# :full_path=>"group1",
# :group_id=>1,
- # :owner_name=>nil,
- # :owner_email=>nil,
# :old_path=>"old-path",
# :old_full_path=>"old-path"
# }
@@ -32,15 +30,11 @@ module Gitlab
private
def group_data
- owner = group.owner
-
{
name: group.name,
path: group.path,
full_path: group.full_path,
- group_id: group.id,
- owner_name: owner.try(:name),
- owner_email: owner.try(:email)
+ group_id: group.id
}
end
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 48e9d55d3ca..87184ea37aa 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -7989,6 +7989,9 @@ msgstr ""
msgid "Copy value"
msgstr ""
+msgid "CorpusManagement|Fuzz testing corpus management"
+msgstr ""
+
msgid "Could not add admins as members"
msgstr ""
diff --git a/spec/fixtures/api/schemas/group_group_links.json b/spec/fixtures/api/schemas/group_group_links.json
deleted file mode 100644
index f8b4e7f035b..00000000000
--- a/spec/fixtures/api/schemas/group_group_links.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "type": "array",
- "items": {
- "$ref": "entities/group_group_link.json"
- }
-}
diff --git a/spec/fixtures/api/schemas/group_link/group_group_link.json b/spec/fixtures/api/schemas/group_link/group_group_link.json
new file mode 100644
index 00000000000..bfca5c885e3
--- /dev/null
+++ b/spec/fixtures/api/schemas/group_link/group_group_link.json
@@ -0,0 +1,16 @@
+{
+ "type": "object",
+ "allOf": [
+ { "$ref": "group_link.json" },
+ {
+ "required": [
+ "can_update",
+ "can_remove"
+ ],
+ "properties": {
+ "can_update": { "type": "boolean" },
+ "can_remove": { "type": "boolean" }
+ }
+ }
+ ]
+}
diff --git a/spec/fixtures/api/schemas/group_link/group_group_links.json b/spec/fixtures/api/schemas/group_link/group_group_links.json
new file mode 100644
index 00000000000..2c0bf20f524
--- /dev/null
+++ b/spec/fixtures/api/schemas/group_link/group_group_links.json
@@ -0,0 +1,6 @@
+{
+ "type": "array",
+ "items": {
+ "$ref": "group_group_link.json"
+ }
+}
diff --git a/spec/fixtures/api/schemas/entities/group_group_link.json b/spec/fixtures/api/schemas/group_link/group_link.json
index bf94bbb3ce4..300790728a8 100644
--- a/spec/fixtures/api/schemas/entities/group_group_link.json
+++ b/spec/fixtures/api/schemas/group_link/group_link.json
@@ -4,8 +4,6 @@
"id",
"created_at",
"expires_at",
- "can_update",
- "can_remove",
"access_level",
"valid_roles"
],
@@ -13,15 +11,14 @@
"id": { "type": "integer" },
"created_at": { "type": "date-time" },
"expires_at": { "type": ["date-time", "null"] },
- "can_update": { "type": "boolean" },
- "can_remove": { "type": "boolean" },
"access_level": {
"type": "object",
"required": ["integer_value", "string_value"],
"properties": {
"integer_value": { "type": "integer" },
"string_value": { "type": "string" }
- }
+ },
+ "additionalProperties": false
},
"valid_roles": { "type": "object" },
"shared_with_group": {
@@ -34,7 +31,8 @@
"full_path": { "type": "string" },
"avatar_url": { "type": ["string", "null"] },
"web_url": { "type": "string" }
- }
+ },
+ "additionalProperties": false
}
}
}
diff --git a/spec/fixtures/api/schemas/group_link/project_group_link.json b/spec/fixtures/api/schemas/group_link/project_group_link.json
new file mode 100644
index 00000000000..bfca5c885e3
--- /dev/null
+++ b/spec/fixtures/api/schemas/group_link/project_group_link.json
@@ -0,0 +1,16 @@
+{
+ "type": "object",
+ "allOf": [
+ { "$ref": "group_link.json" },
+ {
+ "required": [
+ "can_update",
+ "can_remove"
+ ],
+ "properties": {
+ "can_update": { "type": "boolean" },
+ "can_remove": { "type": "boolean" }
+ }
+ }
+ ]
+}
diff --git a/spec/fixtures/api/schemas/group_link/project_group_links.json b/spec/fixtures/api/schemas/group_link/project_group_links.json
new file mode 100644
index 00000000000..fc024d67f36
--- /dev/null
+++ b/spec/fixtures/api/schemas/group_link/project_group_links.json
@@ -0,0 +1,6 @@
+{
+ "type": "array",
+ "items": {
+ "$ref": "project_group_link.json"
+ }
+}
diff --git a/spec/helpers/groups/group_members_helper_spec.rb b/spec/helpers/groups/group_members_helper_spec.rb
index e83585e5efb..99efc7963e6 100644
--- a/spec/helpers/groups/group_members_helper_spec.rb
+++ b/spec/helpers/groups/group_members_helper_spec.rb
@@ -29,7 +29,7 @@ RSpec.describe Groups::GroupMembersHelper do
it 'matches json schema' do
json = helper.group_group_links_data_json(shared_group.shared_with_group_links)
- expect(json).to match_schema('group_group_links')
+ expect(json).to match_schema('group_link/group_group_links')
end
end
diff --git a/spec/helpers/projects/project_members_helper_spec.rb b/spec/helpers/projects/project_members_helper_spec.rb
index cc290367e34..5e0b4df7f7f 100644
--- a/spec/helpers/projects/project_members_helper_spec.rb
+++ b/spec/helpers/projects/project_members_helper_spec.rb
@@ -3,6 +3,8 @@
require 'spec_helper'
RSpec.describe Projects::ProjectMembersHelper do
+ include MembersPresentation
+
let_it_be(:current_user) { create(:user) }
let_it_be(:project) { create(:project) }
@@ -142,4 +144,58 @@ RSpec.describe Projects::ProjectMembersHelper do
it { is_expected.to be(false) }
end
end
+
+ describe 'project members' do
+ let_it_be(:project_members) { create_list(:project_member, 1, project: project) }
+
+ describe '#project_members_data_json' do
+ it 'matches json schema' do
+ expect(helper.project_members_data_json(project, present_members(project_members))).to match_schema('members')
+ end
+ end
+
+ describe '#project_members_list_data_attributes' do
+ let(:allow_admin_project) { true }
+
+ before do
+ allow(helper).to receive(:project_project_member_path).with(project, ':id').and_return('/foo-bar/-/project_members/:id')
+ end
+
+ it 'returns expected hash' do
+ expect(helper.project_members_list_data_attributes(project, present_members(project_members))).to include({
+ members: helper.project_members_data_json(project, present_members(project_members)),
+ member_path: '/foo-bar/-/project_members/:id',
+ source_id: project.id,
+ can_manage_members: true
+ })
+ end
+ end
+ end
+
+ describe 'project group links' do
+ let_it_be(:project_group_links) { create_list(:project_group_link, 1, project: project) }
+ let(:allow_admin_project) { true }
+
+ describe '#project_group_links_data_json' do
+ it 'matches json schema' do
+ expect(helper.project_group_links_data_json(project_group_links)).to match_schema('group_link/project_group_links')
+ end
+ end
+
+ describe '#project_group_links_list_data_attributes' do
+ before do
+ allow(helper).to receive(:project_group_link_path).with(project, ':id').and_return('/foo-bar/-/group_links/:id')
+ allow(helper).to receive(:can?).with(current_user, :admin_project_member, project).and_return(true)
+ end
+
+ it 'returns expected hash' do
+ expect(helper.project_group_links_list_data_attributes(project, project_group_links)).to include({
+ members: helper.project_group_links_data_json(project_group_links),
+ member_path: '/foo-bar/-/group_links/:id',
+ source_id: project.id,
+ can_manage_members: true
+ })
+ end
+ end
+ end
end
diff --git a/spec/lib/gitlab/hook_data/group_builder_spec.rb b/spec/lib/gitlab/hook_data/group_builder_spec.rb
index d95669d502f..d7347ff99d4 100644
--- a/spec/lib/gitlab/hook_data/group_builder_spec.rb
+++ b/spec/lib/gitlab/hook_data/group_builder_spec.rb
@@ -10,8 +10,7 @@ RSpec.describe Gitlab::HookData::GroupBuilder do
let(:event_name) { data[:event_name] }
let(:attributes) do
[
- :event_name, :created_at, :updated_at, :name, :path, :full_path, :group_id,
- :owner_name, :owner_email
+ :event_name, :created_at, :updated_at, :name, :path, :full_path, :group_id
]
end
@@ -24,8 +23,6 @@ RSpec.describe Gitlab::HookData::GroupBuilder do
expect(data[:path]).to eq(group.path)
expect(data[:full_path]).to eq(group.full_path)
expect(data[:group_id]).to eq(group.id)
- expect(data[:owner_name]).to eq(nil)
- expect(data[:owner_email]).to eq(nil)
expect(data[:created_at]).to eq(group.created_at.xmlschema)
expect(data[:updated_at]).to eq(group.updated_at.xmlschema)
end
diff --git a/spec/requests/api/debian_group_packages_spec.rb b/spec/requests/api/debian_group_packages_spec.rb
index 8a05d20fb33..9d63d675a02 100644
--- a/spec/requests/api/debian_group_packages_spec.rb
+++ b/spec/requests/api/debian_group_packages_spec.rb
@@ -6,32 +6,32 @@ RSpec.describe API::DebianGroupPackages do
include WorkhorseHelpers
include_context 'Debian repository shared context', :group do
- describe 'GET groups/:id/-/packages/debian/dists/*distribution/Release.gpg' do
- let(:url) { "/groups/#{group.id}/-/packages/debian/dists/#{distribution}/Release.gpg" }
+ describe 'GET groups/:id/packages/debian/dists/*distribution/Release.gpg' do
+ let(:url) { "/groups/#{group.id}/packages/debian/dists/#{distribution}/Release.gpg" }
it_behaves_like 'Debian group repository GET endpoint', :not_found, nil
end
- describe 'GET groups/:id/-/packages/debian/dists/*distribution/Release' do
- let(:url) { "/groups/#{group.id}/-/packages/debian/dists/#{distribution}/Release" }
+ describe 'GET groups/:id/packages/debian/dists/*distribution/Release' do
+ let(:url) { "/groups/#{group.id}/packages/debian/dists/#{distribution}/Release" }
it_behaves_like 'Debian group repository GET endpoint', :success, 'TODO Release'
end
- describe 'GET groups/:id/-/packages/debian/dists/*distribution/InRelease' do
- let(:url) { "/groups/#{group.id}/-/packages/debian/dists/#{distribution}/InRelease" }
+ describe 'GET groups/:id/packages/debian/dists/*distribution/InRelease' do
+ let(:url) { "/groups/#{group.id}/packages/debian/dists/#{distribution}/InRelease" }
it_behaves_like 'Debian group repository GET endpoint', :not_found, nil
end
- describe 'GET groups/:id/-/packages/debian/dists/*distribution/:component/binary-:architecture/Packages' do
- let(:url) { "/groups/#{group.id}/-/packages/debian/dists/#{distribution}/#{component}/binary-#{architecture}/Packages" }
+ describe 'GET groups/:id/packages/debian/dists/*distribution/:component/binary-:architecture/Packages' do
+ let(:url) { "/groups/#{group.id}/packages/debian/dists/#{distribution}/#{component}/binary-#{architecture}/Packages" }
it_behaves_like 'Debian group repository GET endpoint', :success, 'TODO Packages'
end
- describe 'GET groups/:id/-/packages/debian/pool/:component/:letter/:source_package/:file_name' do
- let(:url) { "/groups/#{group.id}/-/packages/debian/pool/#{component}/#{letter}/#{source_package}/#{package_name}_#{package_version}_#{architecture}.deb" }
+ describe 'GET groups/:id/packages/debian/pool/:component/:letter/:source_package/:file_name' do
+ let(:url) { "/groups/#{group.id}/packages/debian/pool/#{component}/#{letter}/#{source_package}/#{package_name}_#{package_version}_#{architecture}.deb" }
it_behaves_like 'Debian group repository GET endpoint', :success, 'TODO File'
end
diff --git a/spec/requests/api/debian_project_packages_spec.rb b/spec/requests/api/debian_project_packages_spec.rb
index 663b69b1b76..4941f2a77f4 100644
--- a/spec/requests/api/debian_project_packages_spec.rb
+++ b/spec/requests/api/debian_project_packages_spec.rb
@@ -6,46 +6,46 @@ RSpec.describe API::DebianProjectPackages do
include WorkhorseHelpers
include_context 'Debian repository shared context', :project do
- describe 'GET projects/:id/-/packages/debian/dists/*distribution/Release.gpg' do
- let(:url) { "/projects/#{project.id}/-/packages/debian/dists/#{distribution}/Release.gpg" }
+ describe 'GET projects/:id/packages/debian/dists/*distribution/Release.gpg' do
+ let(:url) { "/projects/#{project.id}/packages/debian/dists/#{distribution}/Release.gpg" }
it_behaves_like 'Debian project repository GET endpoint', :not_found, nil
end
- describe 'GET projects/:id/-/packages/debian/dists/*distribution/Release' do
- let(:url) { "/projects/#{project.id}/-/packages/debian/dists/#{distribution}/Release" }
+ describe 'GET projects/:id/packages/debian/dists/*distribution/Release' do
+ let(:url) { "/projects/#{project.id}/packages/debian/dists/#{distribution}/Release" }
it_behaves_like 'Debian project repository GET endpoint', :success, 'TODO Release'
end
- describe 'GET projects/:id/-/packages/debian/dists/*distribution/InRelease' do
- let(:url) { "/projects/#{project.id}/-/packages/debian/dists/#{distribution}/InRelease" }
+ describe 'GET projects/:id/packages/debian/dists/*distribution/InRelease' do
+ let(:url) { "/projects/#{project.id}/packages/debian/dists/#{distribution}/InRelease" }
it_behaves_like 'Debian project repository GET endpoint', :not_found, nil
end
- describe 'GET projects/:id/-/packages/debian/dists/*distribution/:component/binary-:architecture/Packages' do
- let(:url) { "/projects/#{project.id}/-/packages/debian/dists/#{distribution}/#{component}/binary-#{architecture}/Packages" }
+ describe 'GET projects/:id/packages/debian/dists/*distribution/:component/binary-:architecture/Packages' do
+ let(:url) { "/projects/#{project.id}/packages/debian/dists/#{distribution}/#{component}/binary-#{architecture}/Packages" }
it_behaves_like 'Debian project repository GET endpoint', :success, 'TODO Packages'
end
- describe 'GET projects/:id/-/packages/debian/pool/:component/:letter/:source_package/:file_name' do
- let(:url) { "/projects/#{project.id}/-/packages/debian/pool/#{component}/#{letter}/#{source_package}/#{package_name}_#{package_version}_#{architecture}.deb" }
+ describe 'GET projects/:id/packages/debian/pool/:component/:letter/:source_package/:file_name' do
+ let(:url) { "/projects/#{project.id}/packages/debian/pool/#{component}/#{letter}/#{source_package}/#{package_name}_#{package_version}_#{architecture}.deb" }
it_behaves_like 'Debian project repository GET endpoint', :success, 'TODO File'
end
- describe 'PUT projects/:id/-/packages/debian/incoming/:file_name' do
+ describe 'PUT projects/:id/packages/debian/:file_name' do
let(:method) { :put }
- let(:url) { "/projects/#{project.id}/-/packages/debian/incoming/#{file_name}" }
+ let(:url) { "/projects/#{project.id}/packages/debian/#{file_name}" }
it_behaves_like 'Debian project repository PUT endpoint', :created, nil
end
- describe 'PUT projects/:id/-/packages/debian/incoming/:file_name/authorize' do
+ describe 'PUT projects/:id/packages/debian/:file_name/authorize' do
let(:method) { :put }
- let(:url) { "/projects/#{project.id}/-/packages/debian/incoming/#{file_name}/authorize" }
+ let(:url) { "/projects/#{project.id}/packages/debian/#{file_name}/authorize" }
it_behaves_like 'Debian project repository PUT endpoint', :created, nil, is_authorize: true
end
diff --git a/spec/requests/api/graphql/mutations/alert_management/http_integration/update_spec.rb b/spec/requests/api/graphql/mutations/alert_management/http_integration/update_spec.rb
index bf7eb3d980c..18cbb7d8b00 100644
--- a/spec/requests/api/graphql/mutations/alert_management/http_integration/update_spec.rb
+++ b/spec/requests/api/graphql/mutations/alert_management/http_integration/update_spec.rb
@@ -5,7 +5,7 @@ require 'spec_helper'
RSpec.describe 'Updating an existing HTTP Integration' do
include GraphqlHelpers
- let_it_be(:user) { create(:user) }
+ let_it_be(:current_user) { create(:user) }
let_it_be(:project) { create(:project) }
let_it_be(:integration) { create(:alert_management_http_integration, project: project) }
@@ -32,18 +32,8 @@ RSpec.describe 'Updating an existing HTTP Integration' do
let(:mutation_response) { graphql_mutation_response(:http_integration_update) }
before do
- project.add_maintainer(user)
+ project.add_maintainer(current_user)
end
- it 'updates the integration' do
- post_graphql_mutation(mutation, current_user: user)
-
- integration_response = mutation_response['integration']
-
- expect(response).to have_gitlab_http_status(:success)
- expect(integration_response['id']).to eq(GitlabSchema.id_from_object(integration).to_s)
- expect(integration_response['name']).to eq('Modified Name')
- expect(integration_response['active']).to be_falsey
- expect(integration_response['url']).to include('modified-name')
- end
+ it_behaves_like 'updating an existing HTTP integration'
end
diff --git a/spec/serializers/group_group_link_entity_spec.rb b/spec/serializers/group_link/group_group_link_entity_spec.rb
index 9affe4af381..15bcbbcb1d6 100644
--- a/spec/serializers/group_group_link_entity_spec.rb
+++ b/spec/serializers/group_link/group_group_link_entity_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe GroupGroupLinkEntity do
+RSpec.describe GroupLink::GroupGroupLinkEntity do
include_context 'group_group_link'
let_it_be(:current_user) { create(:user) }
@@ -13,15 +13,15 @@ RSpec.describe GroupGroupLinkEntity do
end
it 'matches json schema' do
- expect(entity.to_json).to match_schema('entities/group_group_link')
+ expect(entity.to_json).to match_schema('group_link/group_group_link')
end
- context 'a user with :admin_group_member permissions' do
+ context 'when current user has `:admin_group_member` permissions' do
before do
allow(entity).to receive(:can?).with(current_user, :admin_group_member, shared_group).and_return(true)
end
- it 'sets `can_update` and `can_remove` to `true`' do
+ it 'exposes `can_update` and `can_remove` as `true`' do
json = entity.as_json
expect(json[:can_update]).to be true
diff --git a/spec/serializers/group_group_link_serializer_spec.rb b/spec/serializers/group_link/group_group_link_serializer_spec.rb
index 0d977ea0a9a..a4ca32dae7b 100644
--- a/spec/serializers/group_group_link_serializer_spec.rb
+++ b/spec/serializers/group_link/group_group_link_serializer_spec.rb
@@ -2,12 +2,12 @@
require 'spec_helper'
-RSpec.describe GroupGroupLinkSerializer do
+RSpec.describe GroupLink::GroupGroupLinkSerializer do
include_context 'group_group_link'
subject(:json) { described_class.new.represent(shared_group.shared_with_group_links).to_json }
it 'matches json schema' do
- expect(json).to match_schema('group_group_links')
+ expect(json).to match_schema('group_link/group_group_links')
end
end
diff --git a/spec/serializers/group_link/group_link_entity_spec.rb b/spec/serializers/group_link/group_link_entity_spec.rb
new file mode 100644
index 00000000000..941445feaa2
--- /dev/null
+++ b/spec/serializers/group_link/group_link_entity_spec.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe GroupLink::GroupLinkEntity do
+ include_context 'group_group_link'
+
+ let(:entity) { described_class.new(group_group_link) }
+ let(:entity_hash) { entity.as_json }
+
+ it 'matches json schema' do
+ expect(entity.to_json).to match_schema('group_link/group_link')
+ end
+
+ it 'correctly exposes `valid_roles`' do
+ expect(entity_hash[:valid_roles]).to include(Gitlab::Access.options_with_owner)
+ end
+
+ it 'correctly exposes `shared_with_group.avatar_url`' do
+ avatar_url = 'https://gitlab.com/uploads/-/system/group/avatar/24/foobar.png?width=40'
+ allow(shared_with_group).to receive(:avatar_url).with(only_path: false, size: Member::AVATAR_SIZE).and_return(avatar_url)
+
+ expect(entity_hash[:shared_with_group][:avatar_url]).to match(avatar_url)
+ end
+end
diff --git a/spec/serializers/group_link/project_group_link_entity_spec.rb b/spec/serializers/group_link/project_group_link_entity_spec.rb
new file mode 100644
index 00000000000..0bb3d06933b
--- /dev/null
+++ b/spec/serializers/group_link/project_group_link_entity_spec.rb
@@ -0,0 +1,30 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe GroupLink::ProjectGroupLinkEntity do
+ let_it_be(:current_user) { create(:user) }
+ let_it_be(:project_group_link) { create(:project_group_link) }
+ let(:entity) { described_class.new(project_group_link) }
+
+ before do
+ allow(entity).to receive(:current_user).and_return(current_user)
+ end
+
+ it 'matches json schema' do
+ expect(entity.to_json).to match_schema('group_link/project_group_link')
+ end
+
+ context 'when current user has `admin_project_member` permissions' do
+ before do
+ allow(entity).to receive(:can?).with(current_user, :admin_project_member, project_group_link.project).and_return(true)
+ end
+
+ it 'exposes `can_update` and `can_remove` as `true`' do
+ json = entity.as_json
+
+ expect(json[:can_update]).to be true
+ expect(json[:can_remove]).to be true
+ end
+ end
+end
diff --git a/spec/serializers/group_link/project_group_link_serializer_spec.rb b/spec/serializers/group_link/project_group_link_serializer_spec.rb
new file mode 100644
index 00000000000..ecd5d4d70e4
--- /dev/null
+++ b/spec/serializers/group_link/project_group_link_serializer_spec.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe GroupLink::ProjectGroupLinkSerializer do
+ let_it_be(:project_group_links) { create_list(:project_group_link, 1) }
+
+ subject(:json) { described_class.new.represent(project_group_links).to_json }
+
+ it 'matches json schema' do
+ expect(json).to match_schema('group_link/project_group_links')
+ end
+end
diff --git a/spec/services/system_hooks_service_spec.rb b/spec/services/system_hooks_service_spec.rb
index 63ed19bd556..1ec5237370f 100644
--- a/spec/services/system_hooks_service_spec.rb
+++ b/spec/services/system_hooks_service_spec.rb
@@ -45,15 +45,13 @@ RSpec.describe SystemHooksService do
it do
expect(event_data(group, :create)).to include(
- :event_name, :name, :created_at, :updated_at, :path, :group_id,
- :owner_name, :owner_email
+ :event_name, :name, :created_at, :updated_at, :path, :group_id
)
end
it do
expect(event_data(group, :destroy)).to include(
- :event_name, :name, :created_at, :updated_at, :path, :group_id,
- :owner_name, :owner_email
+ :event_name, :name, :created_at, :updated_at, :path, :group_id
)
end
diff --git a/spec/support/shared_examples/graphql/mutations/http_integrations_shared_examples.rb b/spec/support/shared_examples/graphql/mutations/http_integrations_shared_examples.rb
index 0338eb43f8d..4468af1a603 100644
--- a/spec/support/shared_examples/graphql/mutations/http_integrations_shared_examples.rb
+++ b/spec/support/shared_examples/graphql/mutations/http_integrations_shared_examples.rb
@@ -17,3 +17,78 @@ RSpec.shared_examples 'creating a new HTTP integration' do
expect(integration_response['apiUrl']).to eq(nil)
end
end
+
+RSpec.shared_examples 'updating an existing HTTP integration' do
+ it 'updates the integration' do
+ post_graphql_mutation(mutation, current_user: current_user)
+
+ integration_response = mutation_response['integration']
+
+ expect(response).to have_gitlab_http_status(:success)
+ expect(integration_response['id']).to eq(GitlabSchema.id_from_object(integration).to_s)
+ expect(integration_response['name']).to eq('Modified Name')
+ expect(integration_response['active']).to be_falsey
+ expect(integration_response['url']).to include('modified-name')
+ end
+end
+
+RSpec.shared_examples 'validating the payload_example' do
+ context 'with invalid payloadExample attribute' do
+ let(:payload_example) { 'not a JSON' }
+
+ it 'responds with errors' do
+ post_graphql_mutation(mutation, current_user: current_user)
+
+ expect_graphql_errors_to_include(/was provided invalid value for payloadExample \(Invalid JSON string/)
+ end
+ end
+
+ it 'validates the payload_example size' do
+ allow(::Gitlab::Utils::DeepSize)
+ .to receive(:new)
+ .with(Gitlab::Json.parse(payload_example))
+ .and_return(double(valid?: false))
+
+ post_graphql_mutation(mutation, current_user: current_user)
+
+ expect_graphql_errors_to_include(/payloadExample JSON is too big/)
+ end
+end
+
+RSpec.shared_examples 'validating the payload_attribute_mappings' do
+ context 'with invalid payloadAttributeMapping attribute does not contain fieldName' do
+ let(:payload_attribute_mappings) do
+ [{ path: %w[alert name], type: 'STRING' }]
+ end
+
+ it 'responds with errors' do
+ post_graphql_mutation(mutation, current_user: current_user)
+
+ expect_graphql_errors_to_include(/was provided invalid value for payloadAttributeMappings\.0\.fieldName \(Expected value to not be null/)
+ end
+ end
+
+ context 'with invalid payloadAttributeMapping attribute does not contain path' do
+ let(:payload_attribute_mappings) do
+ [{ fieldName: 'TITLE', type: 'STRING' }]
+ end
+
+ it 'responds with errors' do
+ post_graphql_mutation(mutation, current_user: current_user)
+
+ expect_graphql_errors_to_include(/was provided invalid value for payloadAttributeMappings\.0\.path \(Expected value to not be null/)
+ end
+ end
+
+ context 'with invalid payloadAttributeMapping attribute does not contain type' do
+ let(:payload_attribute_mappings) do
+ [{ fieldName: 'TITLE', path: %w[alert name] }]
+ end
+
+ it 'responds with errors' do
+ post_graphql_mutation(mutation, current_user: current_user)
+
+ expect_graphql_errors_to_include(/was provided invalid value for payloadAttributeMappings\.0\.type \(Expected value to not be null/)
+ end
+ end
+end