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:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-10-06 21:12:19 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2021-10-06 21:12:19 +0300
commit30e5ae4c2b9c1674dc222e4bde0daa3f9795782e (patch)
tree9e19ad1a246e986cd3a8e3842179a972b808ccd1
parent47d926e838b670f5bfeebab36ddd524f5397c5ca (diff)
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--.gitlab/CODEOWNERS1
-rw-r--r--app/assets/javascripts/packages/details/index.js32
-rw-r--r--app/assets/javascripts/packages_and_registries/infrastructure_registry/details/components/app.vue (renamed from app/assets/javascripts/packages/details/components/app.vue)12
-rw-r--r--app/assets/javascripts/packages_and_registries/infrastructure_registry/details/components/details_title.vue (renamed from app/assets/javascripts/packages_and_registries/infrastructure_registry/components/details_title.vue)0
-rw-r--r--app/assets/javascripts/packages_and_registries/infrastructure_registry/details/components/file_sha.vue (renamed from app/assets/javascripts/packages/details/components/file_sha.vue)0
-rw-r--r--app/assets/javascripts/packages_and_registries/infrastructure_registry/details/components/package_files.vue (renamed from app/assets/javascripts/packages/details/components/package_files.vue)2
-rw-r--r--app/assets/javascripts/packages_and_registries/infrastructure_registry/details/components/package_history.vue (renamed from app/assets/javascripts/packages/details/components/package_history.vue)2
-rw-r--r--app/assets/javascripts/packages_and_registries/infrastructure_registry/details/components/terraform_installation.vue (renamed from app/assets/javascripts/packages_and_registries/infrastructure_registry/components/terraform_installation.vue)0
-rw-r--r--app/assets/javascripts/packages_and_registries/infrastructure_registry/details/constants.js (renamed from app/assets/javascripts/packages/details/constants.js)2
-rw-r--r--app/assets/javascripts/packages_and_registries/infrastructure_registry/details/store/actions.js (renamed from app/assets/javascripts/packages/details/store/actions.js)0
-rw-r--r--app/assets/javascripts/packages_and_registries/infrastructure_registry/details/store/getters.js (renamed from app/assets/javascripts/packages/details/store/getters.js)0
-rw-r--r--app/assets/javascripts/packages_and_registries/infrastructure_registry/details/store/index.js (renamed from app/assets/javascripts/packages/details/store/index.js)0
-rw-r--r--app/assets/javascripts/packages_and_registries/infrastructure_registry/details/store/mutation_types.js (renamed from app/assets/javascripts/packages/details/store/mutation_types.js)0
-rw-r--r--app/assets/javascripts/packages_and_registries/infrastructure_registry/details/store/mutations.js (renamed from app/assets/javascripts/packages/details/store/mutations.js)0
-rw-r--r--app/assets/javascripts/packages_and_registries/infrastructure_registry/details_app_bundle.js4
-rw-r--r--app/assets/javascripts/packages_and_registries/package_registry/components/details/package_history.vue2
-rw-r--r--app/assets/javascripts/packages_and_registries/shared/constants.js1
-rw-r--r--app/assets/javascripts/tracking/tracking.js7
-rw-r--r--app/graphql/mutations/issues/create.rb5
-rw-r--r--app/models/loose_foreign_keys/deleted_record.rb44
-rw-r--r--app/services/base_project_service.rb10
-rw-r--r--danger/product_intelligence/Dangerfile1
-rw-r--r--db/migrate/20210819185500_create_external_audit_event_destinations_table.rb15
-rw-r--r--db/migrate/20211004081911_add_external_event_destination_limit_to_plan_limits.rb7
-rw-r--r--db/migrate/20211005092428_drop_time_range_partitioned_loose_fk.rb27
-rw-r--r--db/migrate/20211005093558_add_range_partitioned_loose_fk_table.rb29
-rw-r--r--db/migrate/20211005100112_recreate_loose_fk_insert_function.rb40
-rw-r--r--db/schema_migrations/202108191855001
-rw-r--r--db/schema_migrations/202110040819111
-rw-r--r--db/schema_migrations/202110050924281
-rw-r--r--db/schema_migrations/202110050935581
-rw-r--r--db/schema_migrations/202110051001121
-rw-r--r--db/structure.sql87
-rw-r--r--doc/api/graphql/reference/index.md111
-rw-r--r--doc/development/integrations/secure.md4
-rw-r--r--doc/security/asset_proxy.md4
-rw-r--r--doc/security/crime_vulnerability.md4
-rw-r--r--doc/security/index.md4
-rw-r--r--doc/security/information_exclusivity.md4
-rw-r--r--doc/security/project_import_decompressed_archive_size_limits.md4
-rw-r--r--doc/security/rack_attack.md4
-rw-r--r--doc/security/rate_limits.md4
-rw-r--r--doc/security/unlock_user.md4
-rw-r--r--doc/security/webhooks.md4
-rw-r--r--doc/update/index.md10
-rw-r--r--doc/user/admin_area/monitoring/background_migrations.md90
-rw-r--r--doc/user/application_security/container_scanning/index.md33
-rw-r--r--lib/gitlab/content_security_policy/config_loader.rb20
-rw-r--r--lib/gitlab/import_export/merge_request_parser.rb4
-rw-r--r--qa/qa/page/project/packages/show.rb2
-rw-r--r--spec/frontend/packages_and_registries/infrastructure_registry/components/details/components/__snapshots__/file_sha_spec.js.snap (renamed from spec/frontend/packages/details/components/__snapshots__/file_sha_spec.js.snap)0
-rw-r--r--spec/frontend/packages_and_registries/infrastructure_registry/components/details/components/__snapshots__/terraform_installation_spec.js.snap (renamed from spec/frontend/packages_and_registries/infrastructure_registry/components/__snapshots__/terraform_installation_spec.js.snap)0
-rw-r--r--spec/frontend/packages_and_registries/infrastructure_registry/components/details/components/app_spec.js (renamed from spec/frontend/packages/details/components/app_spec.js)14
-rw-r--r--spec/frontend/packages_and_registries/infrastructure_registry/components/details/components/details_title_spec.js (renamed from spec/frontend/packages_and_registries/infrastructure_registry/components/details_title_spec.js)2
-rw-r--r--spec/frontend/packages_and_registries/infrastructure_registry/components/details/components/file_sha_spec.js (renamed from spec/frontend/packages/details/components/file_sha_spec.js)2
-rw-r--r--spec/frontend/packages_and_registries/infrastructure_registry/components/details/components/package_files_spec.js (renamed from spec/frontend/packages/details/components/package_files_spec.js)4
-rw-r--r--spec/frontend/packages_and_registries/infrastructure_registry/components/details/components/package_history_spec.js (renamed from spec/frontend/packages/details/components/package_history_spec.js)6
-rw-r--r--spec/frontend/packages_and_registries/infrastructure_registry/components/details/components/terraform_installation_spec.js (renamed from spec/frontend/packages_and_registries/infrastructure_registry/components/terraform_installation_spec.js)2
-rw-r--r--spec/frontend/packages_and_registries/infrastructure_registry/components/details/mock_data.js (renamed from spec/frontend/packages/details/mock_data.js)0
-rw-r--r--spec/frontend/packages_and_registries/infrastructure_registry/components/details/store/actions_spec.js (renamed from spec/frontend/packages/details/store/actions_spec.js)8
-rw-r--r--spec/frontend/packages_and_registries/infrastructure_registry/components/details/store/getters_spec.js (renamed from spec/frontend/packages/details/store/getters_spec.js)4
-rw-r--r--spec/frontend/packages_and_registries/infrastructure_registry/components/details/store/mutations_spec.js (renamed from spec/frontend/packages/details/store/mutations_spec.js)6
-rw-r--r--spec/frontend/packages_and_registries/package_registry/components/details/package_history_spec.js2
-rw-r--r--spec/frontend/tracking_spec.js7
-rw-r--r--spec/lib/gitlab/content_security_policy/config_loader_spec.rb27
-rw-r--r--spec/lib/gitlab/database/migration_helpers/loose_foreign_key_helpers_spec.rb9
-rw-r--r--spec/lib/gitlab/import_export/merge_request_parser_spec.rb36
-rw-r--r--spec/models/loose_foreign_keys/deleted_record_spec.rb56
68 files changed, 602 insertions, 228 deletions
diff --git a/.gitlab/CODEOWNERS b/.gitlab/CODEOWNERS
index c277d52f5b0..40170d2ed19 100644
--- a/.gitlab/CODEOWNERS
+++ b/.gitlab/CODEOWNERS
@@ -39,6 +39,7 @@
/doc/install/ @marcel.amirault
/doc/operations/ @ngaskill @rdickenson
/doc/push_rules/ @aqualls
+/doc/security/ @eread
/doc/ssh/ @eread
/doc/subscriptions/ @sselhorn
/doc/topics/autodevops/ @marcia
diff --git a/app/assets/javascripts/packages/details/index.js b/app/assets/javascripts/packages/details/index.js
deleted file mode 100644
index 5b9d58a3860..00000000000
--- a/app/assets/javascripts/packages/details/index.js
+++ /dev/null
@@ -1,32 +0,0 @@
-import Vue from 'vue';
-import Translate from '~/vue_shared/translate';
-import PackagesApp from './components/app.vue';
-import createStore from './store';
-
-Vue.use(Translate);
-
-export default () => {
- const el = document.querySelector('#js-vue-packages-detail');
- const { package: packageJson, canDelete: canDeleteStr, ...rest } = el.dataset;
- const packageEntity = JSON.parse(packageJson);
- const canDelete = canDeleteStr === 'true';
-
- const store = createStore({
- packageEntity,
- packageFiles: packageEntity.package_files,
- canDelete,
- ...rest,
- });
-
- // eslint-disable-next-line no-new
- new Vue({
- el,
- components: {
- PackagesApp,
- },
- store,
- render(createElement) {
- return createElement('packages-app');
- },
- });
-};
diff --git a/app/assets/javascripts/packages/details/components/app.vue b/app/assets/javascripts/packages_and_registries/infrastructure_registry/details/components/app.vue
index 462252ce944..6016757c1b9 100644
--- a/app/assets/javascripts/packages/details/components/app.vue
+++ b/app/assets/javascripts/packages_and_registries/infrastructure_registry/details/components/app.vue
@@ -13,13 +13,13 @@ import { mapActions, mapState } from 'vuex';
import { numberToHumanSize } from '~/lib/utils/number_utils';
import { objectToQuery } from '~/lib/utils/url_utility';
import { s__, __ } from '~/locale';
-import TerraformTitle from '~/packages_and_registries/infrastructure_registry/components/details_title.vue';
-import TerraformInstallation from '~/packages_and_registries/infrastructure_registry/components/terraform_installation.vue';
+import TerraformTitle from '~/packages_and_registries/infrastructure_registry/details/components/details_title.vue';
+import TerraformInstallation from '~/packages_and_registries/infrastructure_registry/details/components/terraform_installation.vue';
import Tracking from '~/tracking';
-import PackageListRow from '../../shared/components/package_list_row.vue';
-import PackagesListLoader from '../../shared/components/packages_list_loader.vue';
-import { TrackingActions, SHOW_DELETE_SUCCESS_ALERT } from '../../shared/constants';
-import { packageTypeToTrackCategory } from '../../shared/utils';
+import PackageListRow from '~/packages/shared/components/package_list_row.vue';
+import PackagesListLoader from '~/packages/shared/components/packages_list_loader.vue';
+import { TrackingActions, SHOW_DELETE_SUCCESS_ALERT } from '~/packages/shared/constants';
+import { packageTypeToTrackCategory } from '~/packages/shared/utils';
import PackageFiles from './package_files.vue';
import PackageHistory from './package_history.vue';
diff --git a/app/assets/javascripts/packages_and_registries/infrastructure_registry/components/details_title.vue b/app/assets/javascripts/packages_and_registries/infrastructure_registry/details/components/details_title.vue
index 3e551706ed0..3e551706ed0 100644
--- a/app/assets/javascripts/packages_and_registries/infrastructure_registry/components/details_title.vue
+++ b/app/assets/javascripts/packages_and_registries/infrastructure_registry/details/components/details_title.vue
diff --git a/app/assets/javascripts/packages/details/components/file_sha.vue b/app/assets/javascripts/packages_and_registries/infrastructure_registry/details/components/file_sha.vue
index a25839be7e1..a25839be7e1 100644
--- a/app/assets/javascripts/packages/details/components/file_sha.vue
+++ b/app/assets/javascripts/packages_and_registries/infrastructure_registry/details/components/file_sha.vue
diff --git a/app/assets/javascripts/packages/details/components/package_files.vue b/app/assets/javascripts/packages_and_registries/infrastructure_registry/details/components/package_files.vue
index 0563b612d04..ab4cfccd023 100644
--- a/app/assets/javascripts/packages/details/components/package_files.vue
+++ b/app/assets/javascripts/packages_and_registries/infrastructure_registry/details/components/package_files.vue
@@ -3,10 +3,10 @@ import { GlLink, GlTable, GlDropdownItem, GlDropdown, GlIcon, GlButton } from '@
import { last } from 'lodash';
import { numberToHumanSize } from '~/lib/utils/number_utils';
import { __ } from '~/locale';
-import FileSha from '~/packages/details/components/file_sha.vue';
import Tracking from '~/tracking';
import FileIcon from '~/vue_shared/components/file_icon.vue';
import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
+import FileSha from './file_sha.vue';
export default {
name: 'PackageFiles',
diff --git a/app/assets/javascripts/packages/details/components/package_history.vue b/app/assets/javascripts/packages_and_registries/infrastructure_registry/details/components/package_history.vue
index 27d2f208a42..33abc0341b7 100644
--- a/app/assets/javascripts/packages/details/components/package_history.vue
+++ b/app/assets/javascripts/packages_and_registries/infrastructure_registry/details/components/package_history.vue
@@ -4,7 +4,7 @@ import { GlLink, GlSprintf } from '@gitlab/ui';
import { first } from 'lodash';
import { truncateSha } from '~/lib/utils/text_utility';
import { s__, n__ } from '~/locale';
-import { HISTORY_PIPELINES_LIMIT } from '~/packages/details/constants';
+import { HISTORY_PIPELINES_LIMIT } from '~/packages_and_registries/shared/constants';
import HistoryItem from '~/vue_shared/components/registry/history_item.vue';
import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
diff --git a/app/assets/javascripts/packages_and_registries/infrastructure_registry/components/terraform_installation.vue b/app/assets/javascripts/packages_and_registries/infrastructure_registry/details/components/terraform_installation.vue
index c62bf7fb722..c62bf7fb722 100644
--- a/app/assets/javascripts/packages_and_registries/infrastructure_registry/components/terraform_installation.vue
+++ b/app/assets/javascripts/packages_and_registries/infrastructure_registry/details/components/terraform_installation.vue
diff --git a/app/assets/javascripts/packages/details/constants.js b/app/assets/javascripts/packages_and_registries/infrastructure_registry/details/constants.js
index a1981797c0c..c0c67faffba 100644
--- a/app/assets/javascripts/packages/details/constants.js
+++ b/app/assets/javascripts/packages_and_registries/infrastructure_registry/details/constants.js
@@ -3,5 +3,3 @@ import { s__ } from '~/locale';
export const FETCH_PACKAGE_VERSIONS_ERROR = s__(
'PackageRegistry|Unable to fetch package version information.',
);
-
-export const HISTORY_PIPELINES_LIMIT = 5;
diff --git a/app/assets/javascripts/packages/details/store/actions.js b/app/assets/javascripts/packages_and_registries/infrastructure_registry/details/store/actions.js
index a03fa8d9d63..a03fa8d9d63 100644
--- a/app/assets/javascripts/packages/details/store/actions.js
+++ b/app/assets/javascripts/packages_and_registries/infrastructure_registry/details/store/actions.js
diff --git a/app/assets/javascripts/packages/details/store/getters.js b/app/assets/javascripts/packages_and_registries/infrastructure_registry/details/store/getters.js
index 6a17e7aa6d6..6a17e7aa6d6 100644
--- a/app/assets/javascripts/packages/details/store/getters.js
+++ b/app/assets/javascripts/packages_and_registries/infrastructure_registry/details/store/getters.js
diff --git a/app/assets/javascripts/packages/details/store/index.js b/app/assets/javascripts/packages_and_registries/infrastructure_registry/details/store/index.js
index 15e17bcfaac..15e17bcfaac 100644
--- a/app/assets/javascripts/packages/details/store/index.js
+++ b/app/assets/javascripts/packages_and_registries/infrastructure_registry/details/store/index.js
diff --git a/app/assets/javascripts/packages/details/store/mutation_types.js b/app/assets/javascripts/packages_and_registries/infrastructure_registry/details/store/mutation_types.js
index 590f2d9f970..590f2d9f970 100644
--- a/app/assets/javascripts/packages/details/store/mutation_types.js
+++ b/app/assets/javascripts/packages_and_registries/infrastructure_registry/details/store/mutation_types.js
diff --git a/app/assets/javascripts/packages/details/store/mutations.js b/app/assets/javascripts/packages_and_registries/infrastructure_registry/details/store/mutations.js
index 762fd5a4040..762fd5a4040 100644
--- a/app/assets/javascripts/packages/details/store/mutations.js
+++ b/app/assets/javascripts/packages_and_registries/infrastructure_registry/details/store/mutations.js
diff --git a/app/assets/javascripts/packages_and_registries/infrastructure_registry/details_app_bundle.js b/app/assets/javascripts/packages_and_registries/infrastructure_registry/details_app_bundle.js
index 98942b1e578..32fbc9382fd 100644
--- a/app/assets/javascripts/packages_and_registries/infrastructure_registry/details_app_bundle.js
+++ b/app/assets/javascripts/packages_and_registries/infrastructure_registry/details_app_bundle.js
@@ -1,7 +1,7 @@
import Vue from 'vue';
import { parseBoolean } from '~/lib/utils/common_utils';
-import PackagesApp from '~/packages/details/components/app.vue';
-import createStore from '~/packages/details/store';
+import PackagesApp from '~/packages_and_registries/infrastructure_registry/details/components/app.vue';
+import createStore from '~/packages_and_registries/infrastructure_registry/details/store';
import Translate from '~/vue_shared/translate';
Vue.use(Translate);
diff --git a/app/assets/javascripts/packages_and_registries/package_registry/components/details/package_history.vue b/app/assets/javascripts/packages_and_registries/package_registry/components/details/package_history.vue
index 408bd2e3dfe..f47040ebf26 100644
--- a/app/assets/javascripts/packages_and_registries/package_registry/components/details/package_history.vue
+++ b/app/assets/javascripts/packages_and_registries/package_registry/components/details/package_history.vue
@@ -5,7 +5,7 @@ import { first } from 'lodash';
import { getIdFromGraphQLId } from '~/graphql_shared/utils';
import { truncateSha } from '~/lib/utils/text_utility';
import { s__, n__ } from '~/locale';
-import { HISTORY_PIPELINES_LIMIT } from '~/packages/details/constants';
+import { HISTORY_PIPELINES_LIMIT } from '~/packages_and_registries/shared/constants';
import HistoryItem from '~/vue_shared/components/registry/history_item.vue';
import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
diff --git a/app/assets/javascripts/packages_and_registries/shared/constants.js b/app/assets/javascripts/packages_and_registries/shared/constants.js
index d38a849ade9..7d2971bd8c7 100644
--- a/app/assets/javascripts/packages_and_registries/shared/constants.js
+++ b/app/assets/javascripts/packages_and_registries/shared/constants.js
@@ -1,2 +1,3 @@
export const FILTERED_SEARCH_TERM = 'filtered-search-term';
export const FILTERED_SEARCH_TYPE = 'type';
+export const HISTORY_PIPELINES_LIMIT = 5;
diff --git a/app/assets/javascripts/tracking/tracking.js b/app/assets/javascripts/tracking/tracking.js
index c305709a22b..c26abc261ed 100644
--- a/app/assets/javascripts/tracking/tracking.js
+++ b/app/assets/javascripts/tracking/tracking.js
@@ -177,9 +177,12 @@ export default class Tracking {
}
const referrers = getReferrersCache();
- const pageLinks = Object.seal({ url: '', referrer: '', originalUrl: window.location.href });
+ const pageLinks = Object.seal({
+ url: pageUrl,
+ referrer: '',
+ originalUrl: window.location.href,
+ });
- pageLinks.url = `${pageUrl}${window.location.hash}`;
window.snowplow('setCustomUrl', pageLinks.url);
if (document.referrer) {
diff --git a/app/graphql/mutations/issues/create.rb b/app/graphql/mutations/issues/create.rb
index 32f96f1bfe6..70a8f539ccf 100644
--- a/app/graphql/mutations/issues/create.rb
+++ b/app/graphql/mutations/issues/create.rb
@@ -71,7 +71,7 @@ module Mutations
def resolve(project_path:, **attributes)
project = authorized_find!(project_path)
- params = build_create_issue_params(attributes.merge(author_id: current_user.id))
+ params = build_create_issue_params(attributes.merge(author_id: current_user.id), project)
spam_params = ::Spam::SpamParams.new_from_request(request: context[:request])
issue = ::Issues::CreateService.new(project: project, current_user: current_user, params: params, spam_params: spam_params).execute
@@ -88,7 +88,8 @@ module Mutations
private
- def build_create_issue_params(params)
+ # _project argument is unused here, but it is necessary on the EE version of the method
+ def build_create_issue_params(params, _project)
params[:milestone_id] &&= params[:milestone_id]&.model_id
params[:assignee_ids] &&= params[:assignee_ids].map { |assignee_id| assignee_id&.model_id }
params[:label_ids] &&= params[:label_ids].map { |label_id| label_id&.model_id }
diff --git a/app/models/loose_foreign_keys/deleted_record.rb b/app/models/loose_foreign_keys/deleted_record.rb
index a39d88b2e49..ca5a2800a03 100644
--- a/app/models/loose_foreign_keys/deleted_record.rb
+++ b/app/models/loose_foreign_keys/deleted_record.rb
@@ -2,48 +2,4 @@
class LooseForeignKeys::DeletedRecord < ApplicationRecord
extend SuppressCompositePrimaryKeyWarning
- include PartitionedTable
-
- partitioned_by :created_at, strategy: :monthly, retain_for: 3.months, retain_non_empty_partitions: true
-
- scope :ordered_by_primary_keys, -> { order(:created_at, :deleted_table_name, :deleted_table_primary_key_value) }
-
- def self.load_batch(batch_size)
- ordered_by_primary_keys
- .limit(batch_size)
- .to_a
- end
-
- # Because the table has composite primary keys, the delete_all or delete methods are not going to work.
- # This method implements deletion that benefits from the primary key index, example:
- #
- # > DELETE
- # > FROM "loose_foreign_keys_deleted_records"
- # > WHERE (created_at,
- # > deleted_table_name,
- # > deleted_table_primary_key_value) IN
- # > (SELECT created_at::TIMESTAMP WITH TIME ZONE,
- # > deleted_table_name,
- # > deleted_table_primary_key_value
- # > FROM (VALUES (LIST_OF_VALUES)) AS primary_key_values (created_at, deleted_table_name, deleted_table_primary_key_value))
- def self.delete_records(records)
- values = records.pluck(:created_at, :deleted_table_name, :deleted_table_primary_key_value)
-
- primary_keys = connection.primary_keys(table_name).join(', ')
-
- primary_keys_with_type_cast = [
- Arel.sql('created_at::timestamp with time zone'),
- Arel.sql('deleted_table_name'),
- Arel.sql('deleted_table_primary_key_value')
- ]
-
- value_list = Arel::Nodes::ValuesList.new(values)
-
- # (SELECT primary keys FROM VALUES)
- inner_query = Arel::SelectManager.new
- inner_query.from("#{Arel::Nodes::Grouping.new([value_list]).as('primary_key_values').to_sql} (#{primary_keys})")
- inner_query.projections = primary_keys_with_type_cast
-
- where(Arel::Nodes::Grouping.new([Arel.sql(primary_keys)]).in(inner_query)).delete_all
- end
end
diff --git a/app/services/base_project_service.rb b/app/services/base_project_service.rb
index fb466e61673..1bf4a235a79 100644
--- a/app/services/base_project_service.rb
+++ b/app/services/base_project_service.rb
@@ -2,6 +2,8 @@
# Base class, scoped by project
class BaseProjectService < ::BaseContainerService
+ include ::Gitlab::Utils::StrongMemoize
+
attr_accessor :project
def initialize(project:, current_user: nil, params: {})
@@ -11,4 +13,12 @@ class BaseProjectService < ::BaseContainerService
end
delegate :repository, to: :project
+
+ private
+
+ def project_group
+ strong_memoize(:project_group) do
+ project.group
+ end
+ end
end
diff --git a/danger/product_intelligence/Dangerfile b/danger/product_intelligence/Dangerfile
index 0a2545c6d51..fd6ae76b4f1 100644
--- a/danger/product_intelligence/Dangerfile
+++ b/danger/product_intelligence/Dangerfile
@@ -5,6 +5,7 @@ CHANGED_FILES_MESSAGE = <<~MSG
For the following files, a review from the [Data team and Product Intelligence team](https://gitlab.com/groups/gitlab-org/growth/product-intelligence/engineers/-/group_members?with_inherited_permissions=exclude) is recommended
Please check the ~"product intelligence" [guide](https://docs.gitlab.com/ee/development/usage_ping.html).
+For MR review guidelines, see the [Service Ping review guidelines](https://docs.gitlab.com/ee/development/usage_ping/review_guidelines.html) or the [Snowplow review guidelines](https://docs.gitlab.com/ee/development/snowplow/review_guidelines.html).
%<changed_files>s
diff --git a/db/migrate/20210819185500_create_external_audit_event_destinations_table.rb b/db/migrate/20210819185500_create_external_audit_event_destinations_table.rb
new file mode 100644
index 00000000000..bf0725a77a0
--- /dev/null
+++ b/db/migrate/20210819185500_create_external_audit_event_destinations_table.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class CreateExternalAuditEventDestinationsTable < Gitlab::Database::Migration[1.0]
+ enable_lock_retries!
+
+ def change
+ create_table :audit_events_external_audit_event_destinations do |t|
+ t.references :namespace, index: false, null: false, foreign_key: { on_delete: :cascade }
+ t.text :destination_url, null: false, limit: 255 # rubocop:disable Migration/AddLimitToTextColumns
+ t.timestamps_with_timezone null: false
+
+ t.index [:namespace_id, :destination_url], unique: true, name: 'index_external_audit_event_destinations_on_namespace_id'
+ end
+ end
+end
diff --git a/db/migrate/20211004081911_add_external_event_destination_limit_to_plan_limits.rb b/db/migrate/20211004081911_add_external_event_destination_limit_to_plan_limits.rb
new file mode 100644
index 00000000000..3e44c388617
--- /dev/null
+++ b/db/migrate/20211004081911_add_external_event_destination_limit_to_plan_limits.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+class AddExternalEventDestinationLimitToPlanLimits < Gitlab::Database::Migration[1.0]
+ def change
+ add_column(:plan_limits, :external_audit_event_destinations, :integer, default: 5, null: false)
+ end
+end
diff --git a/db/migrate/20211005092428_drop_time_range_partitioned_loose_fk.rb b/db/migrate/20211005092428_drop_time_range_partitioned_loose_fk.rb
new file mode 100644
index 00000000000..2aaf5e4cf87
--- /dev/null
+++ b/db/migrate/20211005092428_drop_time_range_partitioned_loose_fk.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+class DropTimeRangePartitionedLooseFk < Gitlab::Database::Migration[1.0]
+ include Gitlab::Database::PartitioningMigrationHelpers
+
+ def up
+ # the table is not in use
+ drop_table :loose_foreign_keys_deleted_records # rubocop: disable Migration/DropTable
+ end
+
+ def down
+ constraint_name = check_constraint_name('loose_foreign_keys_deleted_records', 'deleted_table_name', 'max_length')
+ execute(<<~SQL)
+ CREATE TABLE loose_foreign_keys_deleted_records (
+ created_at timestamp with time zone NOT NULL DEFAULT NOW(),
+ deleted_table_name text NOT NULL,
+ deleted_table_primary_key_value bigint NOT NULL,
+ PRIMARY KEY (created_at, deleted_table_name, deleted_table_primary_key_value),
+ CONSTRAINT #{constraint_name} CHECK ((char_length(deleted_table_name) <= 63))
+ ) PARTITION BY RANGE (created_at);
+ SQL
+
+ min_date = Date.today - 1.month
+ max_date = Date.today + 3.months
+ create_daterange_partitions('loose_foreign_keys_deleted_records', 'created_at', min_date, max_date)
+ end
+end
diff --git a/db/migrate/20211005093558_add_range_partitioned_loose_fk_table.rb b/db/migrate/20211005093558_add_range_partitioned_loose_fk_table.rb
new file mode 100644
index 00000000000..6f52b6ec63b
--- /dev/null
+++ b/db/migrate/20211005093558_add_range_partitioned_loose_fk_table.rb
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+class AddRangePartitionedLooseFkTable < Gitlab::Database::Migration[1.0]
+ include Gitlab::Database::PartitioningMigrationHelpers::TableManagementHelpers
+
+ def up
+ constraint_name = check_constraint_name('loose_foreign_keys_deleted_records', 'fully_qualified_table_name', 'max_length')
+ execute(<<~SQL)
+ CREATE TABLE loose_foreign_keys_deleted_records (
+ id BIGSERIAL NOT NULL,
+ partition bigint NOT NULL,
+ primary_key_value bigint NOT NULL,
+ status smallint NOT NULL DEFAULT 1,
+ created_at timestamp with time zone NOT NULL DEFAULT NOW(),
+ fully_qualified_table_name text NOT NULL,
+ PRIMARY KEY (partition, id),
+ CONSTRAINT #{constraint_name} CHECK ((char_length(fully_qualified_table_name) <= 150))
+ ) PARTITION BY LIST (partition);
+
+ CREATE TABLE gitlab_partitions_static.loose_foreign_keys_deleted_records_1
+ PARTITION OF loose_foreign_keys_deleted_records
+ FOR VALUES IN (1);
+ SQL
+ end
+
+ def down
+ drop_table :loose_foreign_keys_deleted_records
+ end
+end
diff --git a/db/migrate/20211005100112_recreate_loose_fk_insert_function.rb b/db/migrate/20211005100112_recreate_loose_fk_insert_function.rb
new file mode 100644
index 00000000000..b03ad069eba
--- /dev/null
+++ b/db/migrate/20211005100112_recreate_loose_fk_insert_function.rb
@@ -0,0 +1,40 @@
+# frozen_string_literal: true
+
+class RecreateLooseFkInsertFunction < Gitlab::Database::Migration[1.0]
+ include Gitlab::Database::MigrationHelpers::LooseForeignKeyHelpers
+
+ def up
+ execute(<<~SQL)
+ CREATE OR REPLACE FUNCTION #{DELETED_RECORDS_INSERT_FUNCTION_NAME}()
+ RETURNS TRIGGER AS
+ $$
+ BEGIN
+ INSERT INTO loose_foreign_keys_deleted_records
+ (partition, fully_qualified_table_name, primary_key_value)
+ SELECT 1, TG_TABLE_SCHEMA || '.' || TG_TABLE_NAME, old_table.id FROM old_table
+ ON CONFLICT DO NOTHING;
+
+ RETURN NULL;
+ END
+ $$ LANGUAGE PLPGSQL
+ SQL
+ end
+
+ def down
+ # old function
+ execute(<<~SQL)
+ CREATE OR REPLACE FUNCTION #{DELETED_RECORDS_INSERT_FUNCTION_NAME}()
+ RETURNS TRIGGER AS
+ $$
+ BEGIN
+ INSERT INTO loose_foreign_keys_deleted_records
+ (deleted_table_name, deleted_table_primary_key_value)
+ SELECT TG_TABLE_NAME, old_table.id FROM old_table
+ ON CONFLICT DO NOTHING;
+
+ RETURN NULL;
+ END
+ $$ LANGUAGE PLPGSQL
+ SQL
+ end
+end
diff --git a/db/schema_migrations/20210819185500 b/db/schema_migrations/20210819185500
new file mode 100644
index 00000000000..1f92c1d81a9
--- /dev/null
+++ b/db/schema_migrations/20210819185500
@@ -0,0 +1 @@
+eab87cb4abfad7542fcff7c25d984e4a7588c824a13b379cb16c87d0c077cfbb \ No newline at end of file
diff --git a/db/schema_migrations/20211004081911 b/db/schema_migrations/20211004081911
new file mode 100644
index 00000000000..c849cb776d8
--- /dev/null
+++ b/db/schema_migrations/20211004081911
@@ -0,0 +1 @@
+cc53e8c85fdb00c0772987516e0c23f5349cc6dc1e21b4124eb50efdaa6a4fcd \ No newline at end of file
diff --git a/db/schema_migrations/20211005092428 b/db/schema_migrations/20211005092428
new file mode 100644
index 00000000000..0ac1a5f6ee6
--- /dev/null
+++ b/db/schema_migrations/20211005092428
@@ -0,0 +1 @@
+43abb71ecc1f1b4e699af1258934884a06e4e4eb1445ec3cc7a2c6668f42f14a \ No newline at end of file
diff --git a/db/schema_migrations/20211005093558 b/db/schema_migrations/20211005093558
new file mode 100644
index 00000000000..943f905b497
--- /dev/null
+++ b/db/schema_migrations/20211005093558
@@ -0,0 +1 @@
+16638e14f1920b2e615dcb14965b7ef2a16ead099e7f8b1cdad6dd75d6d45107 \ No newline at end of file
diff --git a/db/schema_migrations/20211005100112 b/db/schema_migrations/20211005100112
new file mode 100644
index 00000000000..1f7a92ca316
--- /dev/null
+++ b/db/schema_migrations/20211005100112
@@ -0,0 +1 @@
+196cd1cf84babb12e92830bf2b7a0315499fdb976f825d4913a506e744b4fd53 \ No newline at end of file
diff --git a/db/structure.sql b/db/structure.sql
index b8b94d53e00..72ba7ac328e 100644
--- a/db/structure.sql
+++ b/db/structure.sql
@@ -27,8 +27,8 @@ CREATE FUNCTION insert_into_loose_foreign_keys_deleted_records() RETURNS trigger
AS $$
BEGIN
INSERT INTO loose_foreign_keys_deleted_records
- (deleted_table_name, deleted_table_primary_key_value)
- SELECT TG_TABLE_NAME, old_table.id FROM old_table
+ (partition, fully_qualified_table_name, primary_key_value)
+ SELECT 1, TG_TABLE_SCHEMA || '.' || TG_TABLE_NAME, old_table.id FROM old_table
ON CONFLICT DO NOTHING;
RETURN NULL;
@@ -128,14 +128,6 @@ CREATE TABLE incident_management_pending_issue_escalations (
)
PARTITION BY RANGE (process_at);
-CREATE TABLE loose_foreign_keys_deleted_records (
- created_at timestamp with time zone DEFAULT now() NOT NULL,
- deleted_table_name text NOT NULL,
- deleted_table_primary_key_value bigint NOT NULL,
- CONSTRAINT check_7229f9527e CHECK ((char_length(deleted_table_name) <= 63))
-)
-PARTITION BY RANGE (created_at);
-
CREATE TABLE web_hook_logs (
id bigint NOT NULL,
web_hook_id integer NOT NULL,
@@ -945,6 +937,37 @@ CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_st
);
ALTER TABLE ONLY analytics_cycle_analytics_merge_request_stage_events ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_31 FOR VALUES WITH (modulus 32, remainder 31);
+CREATE TABLE loose_foreign_keys_deleted_records (
+ id bigint NOT NULL,
+ partition bigint NOT NULL,
+ primary_key_value bigint NOT NULL,
+ status smallint DEFAULT 1 NOT NULL,
+ created_at timestamp with time zone DEFAULT now() NOT NULL,
+ fully_qualified_table_name text NOT NULL,
+ CONSTRAINT check_1a541f3235 CHECK ((char_length(fully_qualified_table_name) <= 150))
+)
+PARTITION BY LIST (partition);
+
+CREATE SEQUENCE loose_foreign_keys_deleted_records_id_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+ALTER SEQUENCE loose_foreign_keys_deleted_records_id_seq OWNED BY loose_foreign_keys_deleted_records.id;
+
+CREATE TABLE gitlab_partitions_static.loose_foreign_keys_deleted_records_1 (
+ id bigint DEFAULT nextval('loose_foreign_keys_deleted_records_id_seq'::regclass) NOT NULL,
+ partition bigint NOT NULL,
+ primary_key_value bigint NOT NULL,
+ status smallint DEFAULT 1 NOT NULL,
+ created_at timestamp with time zone DEFAULT now() NOT NULL,
+ fully_qualified_table_name text NOT NULL,
+ CONSTRAINT check_1a541f3235 CHECK ((char_length(fully_qualified_table_name) <= 150))
+);
+ALTER TABLE ONLY loose_foreign_keys_deleted_records ATTACH PARTITION gitlab_partitions_static.loose_foreign_keys_deleted_records_1 FOR VALUES IN ('1');
+
CREATE TABLE product_analytics_events_experimental (
id bigint NOT NULL,
project_id integer NOT NULL,
@@ -10604,6 +10627,24 @@ CREATE SEQUENCE atlassian_identities_user_id_seq
ALTER SEQUENCE atlassian_identities_user_id_seq OWNED BY atlassian_identities.user_id;
+CREATE TABLE audit_events_external_audit_event_destinations (
+ id bigint NOT NULL,
+ namespace_id bigint NOT NULL,
+ destination_url text NOT NULL,
+ created_at timestamp with time zone NOT NULL,
+ updated_at timestamp with time zone NOT NULL,
+ CONSTRAINT check_2feafb9daf CHECK ((char_length(destination_url) <= 255))
+);
+
+CREATE SEQUENCE audit_events_external_audit_event_destinations_id_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+ALTER SEQUENCE audit_events_external_audit_event_destinations_id_seq OWNED BY audit_events_external_audit_event_destinations.id;
+
CREATE SEQUENCE audit_events_id_seq
START WITH 1
INCREMENT BY 1
@@ -17389,7 +17430,8 @@ CREATE TABLE plan_limits (
ci_max_artifact_size_cluster_image_scanning integer DEFAULT 0 NOT NULL,
ci_jobs_trace_size_limit integer DEFAULT 100 NOT NULL,
pages_file_entries integer DEFAULT 200000 NOT NULL,
- dast_profile_schedules integer DEFAULT 1 NOT NULL
+ dast_profile_schedules integer DEFAULT 1 NOT NULL,
+ external_audit_event_destinations integer DEFAULT 5 NOT NULL
);
CREATE SEQUENCE plan_limits_id_seq
@@ -20951,6 +20993,8 @@ ALTER TABLE ONLY atlassian_identities ALTER COLUMN user_id SET DEFAULT nextval('
ALTER TABLE ONLY audit_events ALTER COLUMN id SET DEFAULT nextval('audit_events_id_seq'::regclass);
+ALTER TABLE ONLY audit_events_external_audit_event_destinations ALTER COLUMN id SET DEFAULT nextval('audit_events_external_audit_event_destinations_id_seq'::regclass);
+
ALTER TABLE ONLY authentication_events ALTER COLUMN id SET DEFAULT nextval('authentication_events_id_seq'::regclass);
ALTER TABLE ONLY award_emoji ALTER COLUMN id SET DEFAULT nextval('award_emoji_id_seq'::regclass);
@@ -21405,6 +21449,8 @@ ALTER TABLE ONLY list_user_preferences ALTER COLUMN id SET DEFAULT nextval('list
ALTER TABLE ONLY lists ALTER COLUMN id SET DEFAULT nextval('lists_id_seq'::regclass);
+ALTER TABLE ONLY loose_foreign_keys_deleted_records ALTER COLUMN id SET DEFAULT nextval('loose_foreign_keys_deleted_records_id_seq'::regclass);
+
ALTER TABLE ONLY members ALTER COLUMN id SET DEFAULT nextval('members_id_seq'::regclass);
ALTER TABLE ONLY merge_request_assignees ALTER COLUMN id SET DEFAULT nextval('merge_request_assignees_id_seq'::regclass);
@@ -22027,6 +22073,12 @@ ALTER TABLE ONLY gitlab_partitions_static.analytics_cycle_analytics_merge_reques
ALTER TABLE ONLY gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_31
ADD CONSTRAINT analytics_cycle_analytics_merge_request_stage_events_31_pkey PRIMARY KEY (stage_event_hash_id, merge_request_id);
+ALTER TABLE ONLY loose_foreign_keys_deleted_records
+ ADD CONSTRAINT loose_foreign_keys_deleted_records_pkey PRIMARY KEY (partition, id);
+
+ALTER TABLE ONLY gitlab_partitions_static.loose_foreign_keys_deleted_records_1
+ ADD CONSTRAINT loose_foreign_keys_deleted_records_1_pkey PRIMARY KEY (partition, id);
+
ALTER TABLE ONLY product_analytics_events_experimental
ADD CONSTRAINT product_analytics_events_experimental_pkey PRIMARY KEY (id, project_id);
@@ -22324,6 +22376,9 @@ ALTER TABLE ONLY ar_internal_metadata
ALTER TABLE ONLY atlassian_identities
ADD CONSTRAINT atlassian_identities_pkey PRIMARY KEY (user_id);
+ALTER TABLE ONLY audit_events_external_audit_event_destinations
+ ADD CONSTRAINT audit_events_external_audit_event_destinations_pkey PRIMARY KEY (id);
+
ALTER TABLE ONLY audit_events
ADD CONSTRAINT audit_events_pkey PRIMARY KEY (id, created_at);
@@ -23095,9 +23150,6 @@ ALTER TABLE ONLY list_user_preferences
ALTER TABLE ONLY lists
ADD CONSTRAINT lists_pkey PRIMARY KEY (id);
-ALTER TABLE ONLY loose_foreign_keys_deleted_records
- ADD CONSTRAINT loose_foreign_keys_deleted_records_pkey PRIMARY KEY (created_at, deleted_table_name, deleted_table_primary_key_value);
-
ALTER TABLE ONLY members
ADD CONSTRAINT members_pkey PRIMARY KEY (id);
@@ -25115,6 +25167,8 @@ CREATE UNIQUE INDEX index_experiments_on_name ON experiments USING btree (name);
CREATE INDEX index_expired_and_not_notified_personal_access_tokens ON personal_access_tokens USING btree (id, expires_at) WHERE ((impersonation = false) AND (revoked = false) AND (expire_notification_delivered = false));
+CREATE UNIQUE INDEX index_external_audit_event_destinations_on_namespace_id ON audit_events_external_audit_event_destinations USING btree (namespace_id, destination_url);
+
CREATE UNIQUE INDEX index_external_pull_requests_on_project_and_branches ON external_pull_requests USING btree (project_id, source_branch, target_branch);
CREATE UNIQUE INDEX index_feature_flag_scopes_on_flag_id_and_environment_scope ON operations_feature_flag_scopes USING btree (feature_flag_id, environment_scope);
@@ -27121,6 +27175,8 @@ ALTER INDEX analytics_cycle_analytics_merge_request_stage_events_pkey ATTACH PAR
ALTER INDEX analytics_cycle_analytics_merge_request_stage_events_pkey ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_31_pkey;
+ALTER INDEX loose_foreign_keys_deleted_records_pkey ATTACH PARTITION gitlab_partitions_static.loose_foreign_keys_deleted_records_1_pkey;
+
ALTER INDEX index_product_analytics_events_experimental_project_and_time ATTACH PARTITION gitlab_partitions_static.product_analytics_events_expe_project_id_collector_tstamp_idx10;
ALTER INDEX index_product_analytics_events_experimental_project_and_time ATTACH PARTITION gitlab_partitions_static.product_analytics_events_expe_project_id_collector_tstamp_idx11;
@@ -28321,6 +28377,9 @@ ALTER TABLE ONLY packages_conan_file_metadata
ALTER TABLE ONLY ci_build_pending_states
ADD CONSTRAINT fk_rails_0bbbfeaf9d FOREIGN KEY (build_id) REFERENCES ci_builds(id) ON DELETE CASCADE;
+ALTER TABLE ONLY audit_events_external_audit_event_destinations
+ ADD CONSTRAINT fk_rails_0bc80a4edc FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE;
+
ALTER TABLE ONLY operations_user_lists
ADD CONSTRAINT fk_rails_0c716e079b FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md
index f924eac904a..00f21539848 100644
--- a/doc/api/graphql/reference/index.md
+++ b/doc/api/graphql/reference/index.md
@@ -1271,6 +1271,9 @@ Input type: `CreateIssueInput`
| <a id="mutationcreateissueepicid"></a>`epicId` | [`EpicID`](#epicid) | ID of an epic to associate the issue with. |
| <a id="mutationcreateissuehealthstatus"></a>`healthStatus` | [`HealthStatus`](#healthstatus) | Desired health status. |
| <a id="mutationcreateissueiid"></a>`iid` | [`Int`](#int) | IID (internal ID) of a project issue. Only admins and project owners can modify. |
+| <a id="mutationcreateissueiterationcadenceid"></a>`iterationCadenceId` | [`IterationsCadenceID`](#iterationscadenceid) | Global iteration cadence ID. Required when `iterationWildcardId` is provided. |
+| <a id="mutationcreateissueiterationid"></a>`iterationId` | [`IterationID`](#iterationid) | Global iteration ID. Mutually exlusive argument with `iterationWildcardId`. |
+| <a id="mutationcreateissueiterationwildcardid"></a>`iterationWildcardId` | [`IssueCreationIterationWildcardId`](#issuecreationiterationwildcardid) | Iteration wildcard ID. Supported values are: `CURRENT`. Mutually exclusive argument with `iterationId`. iterationCadenceId also required when this argument is provided. |
| <a id="mutationcreateissuelabelids"></a>`labelIds` | [`[LabelID!]`](#labelid) | IDs of labels to be added to the issue. |
| <a id="mutationcreateissuelabels"></a>`labels` | [`[String!]`](#string) | Labels of the issue. |
| <a id="mutationcreateissuelocked"></a>`locked` | [`Boolean`](#boolean) | Indicates discussion is locked on the issue. |
@@ -2437,6 +2440,64 @@ Input type: `ExportRequirementsInput`
| <a id="mutationexportrequirementsclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationexportrequirementserrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
+### `Mutation.externalAuditEventDestinationCreate`
+
+Input type: `ExternalAuditEventDestinationCreateInput`
+
+#### Arguments
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="mutationexternalauditeventdestinationcreateclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
+| <a id="mutationexternalauditeventdestinationcreatedestinationurl"></a>`destinationUrl` | [`String!`](#string) | Destination URL. |
+| <a id="mutationexternalauditeventdestinationcreategrouppath"></a>`groupPath` | [`ID!`](#id) | Group path. |
+
+#### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="mutationexternalauditeventdestinationcreateclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
+| <a id="mutationexternalauditeventdestinationcreateerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
+| <a id="mutationexternalauditeventdestinationcreateexternalauditeventdestination"></a>`externalAuditEventDestination` | [`ExternalAuditEventDestination`](#externalauditeventdestination) | Destination created. |
+
+### `Mutation.externalAuditEventDestinationDestroy`
+
+Input type: `ExternalAuditEventDestinationDestroyInput`
+
+#### Arguments
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="mutationexternalauditeventdestinationdestroyclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
+| <a id="mutationexternalauditeventdestinationdestroyid"></a>`id` | [`AuditEventsExternalAuditEventDestinationID!`](#auditeventsexternalauditeventdestinationid) | ID of external audit event destination to destroy. |
+
+#### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="mutationexternalauditeventdestinationdestroyclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
+| <a id="mutationexternalauditeventdestinationdestroyerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
+
+### `Mutation.externalAuditEventDestinationUpdate`
+
+Input type: `ExternalAuditEventDestinationUpdateInput`
+
+#### Arguments
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="mutationexternalauditeventdestinationupdateclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
+| <a id="mutationexternalauditeventdestinationupdatedestinationurl"></a>`destinationUrl` | [`String`](#string) | Destination URL to change. |
+| <a id="mutationexternalauditeventdestinationupdateid"></a>`id` | [`AuditEventsExternalAuditEventDestinationID!`](#auditeventsexternalauditeventdestinationid) | ID of external audit event destination to destroy. |
+
+#### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="mutationexternalauditeventdestinationupdateclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
+| <a id="mutationexternalauditeventdestinationupdateerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
+| <a id="mutationexternalauditeventdestinationupdateexternalauditeventdestination"></a>`externalAuditEventDestination` | [`ExternalAuditEventDestination`](#externalauditeventdestination) | Updated destination. |
+
### `Mutation.gitlabSubscriptionActivate`
Input type: `GitlabSubscriptionActivateInput`
@@ -5947,6 +6008,29 @@ The edge type for [`Event`](#event).
| <a id="eventedgecursor"></a>`cursor` | [`String!`](#string) | A cursor for use in pagination. |
| <a id="eventedgenode"></a>`node` | [`Event`](#event) | The item at the end of the edge. |
+#### `ExternalAuditEventDestinationConnection`
+
+The connection type for [`ExternalAuditEventDestination`](#externalauditeventdestination).
+
+##### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="externalauditeventdestinationconnectionedges"></a>`edges` | [`[ExternalAuditEventDestinationEdge]`](#externalauditeventdestinationedge) | A list of edges. |
+| <a id="externalauditeventdestinationconnectionnodes"></a>`nodes` | [`[ExternalAuditEventDestination]`](#externalauditeventdestination) | A list of nodes. |
+| <a id="externalauditeventdestinationconnectionpageinfo"></a>`pageInfo` | [`PageInfo!`](#pageinfo) | Information to aid in pagination. |
+
+#### `ExternalAuditEventDestinationEdge`
+
+The edge type for [`ExternalAuditEventDestination`](#externalauditeventdestination).
+
+##### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="externalauditeventdestinationedgecursor"></a>`cursor` | [`String!`](#string) | A cursor for use in pagination. |
+| <a id="externalauditeventdestinationedgenode"></a>`node` | [`ExternalAuditEventDestination`](#externalauditeventdestination) | The item at the end of the edge. |
+
#### `GroupConnection`
The connection type for [`Group`](#group).
@@ -9841,6 +9925,18 @@ Representing an event.
| <a id="eventid"></a>`id` | [`ID!`](#id) | ID of the event. |
| <a id="eventupdatedat"></a>`updatedAt` | [`Time!`](#time) | When this event was updated. |
+### `ExternalAuditEventDestination`
+
+Represents an external resource to send audit events to.
+
+#### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="externalauditeventdestinationdestinationurl"></a>`destinationUrl` | [`String!`](#string) | External destination to send audit events to. |
+| <a id="externalauditeventdestinationgroup"></a>`group` | [`Group!`](#group) | Group the destination belongs to. |
+| <a id="externalauditeventdestinationid"></a>`id` | [`ID!`](#id) | ID of the destination. |
+
### `ExternalIssue`
Represents an external issue.
@@ -10066,6 +10162,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
| <a id="groupemailsdisabled"></a>`emailsDisabled` | [`Boolean`](#boolean) | Indicates if a group has email notifications disabled. |
| <a id="groupepicboards"></a>`epicBoards` | [`EpicBoardConnection`](#epicboardconnection) | Find epic boards. (see [Connections](#connections)) |
| <a id="groupepicsenabled"></a>`epicsEnabled` | [`Boolean`](#boolean) | Indicates if Epics are enabled for namespace. |
+| <a id="groupexternalauditeventdestinations"></a>`externalAuditEventDestinations` | [`ExternalAuditEventDestinationConnection`](#externalauditeventdestinationconnection) | External locations that receive audit events belonging to the group. Available only when feature flag `ff_external_audit_events_namespace` is enabled. This flag is disabled by default, because the feature is experimental and is subject to change without notice. (see [Connections](#connections)) |
| <a id="groupfullname"></a>`fullName` | [`String!`](#string) | Full name of the namespace. |
| <a id="groupfullpath"></a>`fullPath` | [`ID!`](#id) | Full path of the namespace. |
| <a id="groupid"></a>`id` | [`ID!`](#id) | ID of the namespace. |
@@ -15820,6 +15917,14 @@ State of a GitLab issue or merge request.
| <a id="issuablestatelocked"></a>`locked` | Discussion has been locked. |
| <a id="issuablestateopened"></a>`opened` | In open state. |
+### `IssueCreationIterationWildcardId`
+
+Iteration ID wildcard values for issue creation.
+
+| Value | Description |
+| ----- | ----------- |
+| <a id="issuecreationiterationwildcardidcurrent"></a>`CURRENT` | Current iteration. |
+
### `IssueSort`
Values for sorting issues.
@@ -16717,6 +16822,12 @@ A `AnalyticsDevopsAdoptionEnabledNamespaceID` is a global ID. It is encoded as a
An example `AnalyticsDevopsAdoptionEnabledNamespaceID` is: `"gid://gitlab/Analytics::DevopsAdoption::EnabledNamespace/1"`.
+### `AuditEventsExternalAuditEventDestinationID`
+
+A `AuditEventsExternalAuditEventDestinationID` is a global ID. It is encoded as a string.
+
+An example `AuditEventsExternalAuditEventDestinationID` is: `"gid://gitlab/AuditEvents::ExternalAuditEventDestination/1"`.
+
### `AwardableID`
A `AwardableID` is a global ID. It is encoded as a string.
diff --git a/doc/development/integrations/secure.md b/doc/development/integrations/secure.md
index 05fa3a0439e..34293845d17 100644
--- a/doc/development/integrations/secure.md
+++ b/doc/development/integrations/secure.md
@@ -539,7 +539,7 @@ affecting version `2.50.3-2+deb9u1` of Debian package `glib2.0`:
"namespace": "production",
"kind": "Deployment",
"name": "nginx-ingress",
- "container": "nginx",
+ "container_name": "nginx",
"agent_id": "1"
}
}
@@ -548,7 +548,7 @@ affecting version `2.50.3-2+deb9u1` of Debian package `glib2.0`:
The affected package is found when scanning a deployment using the `index.docker.io/library/nginx:1.18` image.
The location fingerprint of a Cluster Image Scanning vulnerability combines the
-`namespace`, `kind`, `name`, and `container` fields from the `kubernetes_resource`,
+`namespace`, `kind`, `name`, and `container_name` fields from the `kubernetes_resource`,
as well as the package `name`, so these fields are required. The `image` field is also mandatory.
The `cluster_id` and `agent_id` are mutually exclusive, and one of them must be present.
All other fields are optional.
diff --git a/doc/security/asset_proxy.md b/doc/security/asset_proxy.md
index d6b85eb5c9f..abeb5c401da 100644
--- a/doc/security/asset_proxy.md
+++ b/doc/security/asset_proxy.md
@@ -1,6 +1,6 @@
---
-stage: none
-group: unassigned
+stage: Manage
+group: Access
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
diff --git a/doc/security/crime_vulnerability.md b/doc/security/crime_vulnerability.md
index a8dee8f589a..801a294dd81 100644
--- a/doc/security/crime_vulnerability.md
+++ b/doc/security/crime_vulnerability.md
@@ -1,6 +1,6 @@
---
-stage: none
-group: unassigned
+stage: Manage
+group: Access
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
type: reference
---
diff --git a/doc/security/index.md b/doc/security/index.md
index 35e93fc2c55..832af93b95e 100644
--- a/doc/security/index.md
+++ b/doc/security/index.md
@@ -1,6 +1,6 @@
---
-stage: none
-group: unassigned
+stage: Manage
+group: Access
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
comments: false
type: index
diff --git a/doc/security/information_exclusivity.md b/doc/security/information_exclusivity.md
index dd5ef6e6a65..162346c8874 100644
--- a/doc/security/information_exclusivity.md
+++ b/doc/security/information_exclusivity.md
@@ -1,6 +1,6 @@
---
-stage: none
-group: unassigned
+stage: Manage
+group: Access
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
type: concepts
---
diff --git a/doc/security/project_import_decompressed_archive_size_limits.md b/doc/security/project_import_decompressed_archive_size_limits.md
index 6510cf459be..3c5099b1f75 100644
--- a/doc/security/project_import_decompressed_archive_size_limits.md
+++ b/doc/security/project_import_decompressed_archive_size_limits.md
@@ -1,6 +1,6 @@
---
-stage: none
-group: unassigned
+stage: Manage
+group: Access
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
type: reference, howto
---
diff --git a/doc/security/rack_attack.md b/doc/security/rack_attack.md
index 4894af1fa19..b0bebc5a956 100644
--- a/doc/security/rack_attack.md
+++ b/doc/security/rack_attack.md
@@ -1,6 +1,6 @@
---
-stage: none
-group: unassigned
+stage: Manage
+group: Access
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
type: reference, howto
---
diff --git a/doc/security/rate_limits.md b/doc/security/rate_limits.md
index 03173fdea94..3e0887ffb22 100644
--- a/doc/security/rate_limits.md
+++ b/doc/security/rate_limits.md
@@ -1,6 +1,6 @@
---
-stage: none
-group: unassigned
+stage: Manage
+group: Access
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
type: reference, howto
---
diff --git a/doc/security/unlock_user.md b/doc/security/unlock_user.md
index da451d96ef9..ceb375a9ad1 100644
--- a/doc/security/unlock_user.md
+++ b/doc/security/unlock_user.md
@@ -1,6 +1,6 @@
---
-stage: none
-group: unassigned
+stage: Manage
+group: Access
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
type: howto
---
diff --git a/doc/security/webhooks.md b/doc/security/webhooks.md
index 7c94ad0bed2..89dd4f8e5fc 100644
--- a/doc/security/webhooks.md
+++ b/doc/security/webhooks.md
@@ -1,6 +1,6 @@
---
-stage: none
-group: unassigned
+stage: Manage
+group: Access
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
type: concepts, reference, howto
---
diff --git a/doc/update/index.md b/doc/update/index.md
index 6e69c3989ad..057d2bbd831 100644
--- a/doc/update/index.md
+++ b/doc/update/index.md
@@ -92,6 +92,16 @@ To check the status of [batched background migrations](../user/admin_area/monito
![queued batched background migrations table](img/batched_background_migrations_queued_v14_0.png)
+The status of batched background migrations can also be queried directly in the database.
+
+1. Log into a `psql` prompt according to the directions for your instance's installation method
+(for example, `sudo gitlab-psql` for Omnibus installations).
+1. Run the following query in the `psql` session to see details on incomplete batched background migrations:
+
+ ```sql
+ select job_class_name, table_name, column_name, job_arguments from batched_background_migrations where status <> 3;
+ ```
+
**For Omnibus installations**
You can also run:
diff --git a/doc/user/admin_area/monitoring/background_migrations.md b/doc/user/admin_area/monitoring/background_migrations.md
index 5765a530baf..058eaffae44 100644
--- a/doc/user/admin_area/monitoring/background_migrations.md
+++ b/doc/user/admin_area/monitoring/background_migrations.md
@@ -91,13 +91,95 @@ Expected batched background migration for the given configuration to be marked a
{:job_class_name=>"CopyColumnUsingBackgroundMigrationJob", :table_name=>"push_event_payloads", :column_name=>"event_id", :job_arguments=>[["event_id"], ["event_id_convert_to_bigint"]]}
```
-To fix this error:
+First, check if you have followed the [version-specific upgrade instructions for 14.2](../../../update/index.md#1420).
+If you have, you can [manually finish the batched background migration](#manually-finishing-a-batched-background-migration).
+If you haven't, choose one of the following methods:
-1. Update to either 14.0.5 or 14.1.
-1. [Check the status](#check-the-status-of-background-migrations) of the batched background migration from the error message, and make sure it is listed as finished. If it is still active, either wait until it is done, or finalize it manually using the command suggested in the error, for example:
+1. [Rollback and upgrade](#roll-back-and-follow-the-required-upgrade-path) through one of the required
+versions before updating to 14.2+.
+1. [Roll forward](#roll-forward-and-finish-the-migrations-on-the-upgraded-version), staying on the current
+version and manually and ensure that the batched migrations complete successfully.
+
+#### Roll back and follow the required upgrade path
+
+1. [Rollback and restore the previously installed version](../../../update/restore_after_failure.md#roll-back-to-an-earlier-version-and-restore-a-backup)
+1. Update to either 14.0.5 or 14.1 **before** updating to 14.2+
+1. [Check the status](#check-the-status-of-background-migrations) of the batched background migrations and
+make sure they are all marked as finished before attempting to upgrade again. If any remain marked as active,
+you can [manually finish them](#manually-finishing-a-batched-background-migration).
+
+#### Roll forward and finish the migrations on the upgraded version
+
+##### For a deployment with downtime
+
+To run all the batched background migrations, it can take a significant amount of time
+depending on the size of your GitLab installation.
+
+1. [Check the status](#check-the-status-of-background-migrations) of the batched background migrations in the
+database, and [manually run them](#manually-finishing-a-batched-background-migration) with the appropriate
+arguments until the status query returns no rows.
+1. When the status of all of all them is marked as complete, re-run migrations for your installation.
+1. [Complete the database migrations](../../../administration/raketasks/maintenance.md#run-incomplete-database-migrations) from your GitLab upgrade:
+
+ ```plaintext
+ sudo gitlab-rake db:migrate
+ ```
+
+1. Run a reconfigure:
+
+ ```plaintext
+ sudo gitlab-ctl reconfigure
+ ```
+
+1. Finish the upgrade for your installation.
+
+##### For a no-downtime deployment
+
+As the failing migrations are post-deployment migrations, you can remain on a running instance of the upgraded
+version and wait for the batched background migrations to finish normally.
+
+1. [Check the status](#check-the-status-of-background-migrations) of the batched background migration from
+the error message, and make sure it is listed as finished. If it is still active, either wait until it is done,
+or [manually finish it](#manually-finishing-a-batched-background-migration).
+1. Re-run migrations for your installation, so the remaining post-deployment migrations finish.
+
+### Manually finishing a batched background migration
+
+If you need to manually finish a batched background migration due to an
+error, you can run:
+
+```shell
+sudo gitlab-rake gitlab:background_migrations:finalize[<job_class_name>,<table_name>,<column_name>,'<job_arguments>']
+```
+
+Replace the values in angle brackets with the correct
+arguments. For example, if you receive an error similar to this:
+
+```plaintext
+StandardError: An error has occurred, all later migrations canceled:
+
+Expected batched background migration for the given configuration to be marked as 'finished', but it is 'active':
+ {:job_class_name=>"CopyColumnUsingBackgroundMigrationJob", :table_name=>"push_event_payloads", :column_name=>"event_id", :job_arguments=>[["event_id"], ["event_id_convert_to_bigint"]]}
+```
+
+Plug the arguments from the error message into the command:
```shell
sudo gitlab-rake gitlab:background_migrations:finalize[CopyColumnUsingBackgroundMigrationJob,push_event_payloads,event_id,'[["event_id"]\, ["event_id_convert_to_bigint"]]']
```
-1. You can now update to GitLab 14.2 or higher.
+If you need to manually run a batched background migration to continue an upgrade, you can
+[check the status](#check-the-status-of-background-migrations) in the database and get the
+arguments from the query results. For example, if the query returns this:
+
+```plaintext
+ job_class_name | table_name | column_name | job_arguments
+---------------------------------------+------------+-------------+------------------------------------
+ CopyColumnUsingBackgroundMigrationJob | events | id | [["id"], ["id_convert_to_bigint"]]
+ ```
+
+The results from the query can be plugged into the command:
+
+```shell
+sudo gitlab-rake gitlab:background_migrations:finalize[CopyColumnUsingBackgroundMigrationJob,events,id,'[["id"]\, ["id_convert_to_bigint"]]']
+```
diff --git a/doc/user/application_security/container_scanning/index.md b/doc/user/application_security/container_scanning/index.md
index 0e5399f9d56..83bda25d6f2 100644
--- a/doc/user/application_security/container_scanning/index.md
+++ b/doc/user/application_security/container_scanning/index.md
@@ -420,6 +420,39 @@ The above template works for a GitLab Docker registry running on a local install
you're using a non-GitLab Docker registry, you must change the `$CI_REGISTRY` value and the
`docker login` credentials to match your local registry's details.
+#### Scan images in external private registries
+
+To scan an image in an external private registry, you must configure access credentials so the
+container scanning analyzer can authenticate itself before attempting to access the image to scan.
+
+If you use the GitLab [Container Registry](../../packages/container_registry/),
+the `DOCKER_USER` and `DOCKER_PASSWORD` [configuration variables](#available-cicd-variables)
+are set automatically and you can skip this configuration.
+
+This example shows the configuration needed to scan images in a private [Google Container Registry](https://cloud.google.com/container-registry/):
+
+```yaml
+include:
+ - template: Security/Container-Scanning.gitlab-ci.yml
+
+container_scanning:
+ variables:
+ DOCKER_USER: _json_key
+ DOCKER_PASSWORD: "$GCP_CREDENTIALS"
+ DOCKER_IMAGE: "gcr.io/path-to-you-registry/image:tag"
+```
+
+Before you commit this configuration, [add a CI/CD variable](../../../ci/variables/#add-a-cicd-variable-to-a-project)
+for `GCP_CREDENTIALS` containing the JSON key, as described in the
+[Google Cloud Platform Container Registry documentation](https://cloud.google.com/container-registry/docs/advanced-authentication#json-key).
+Also:
+
+- The value of the variable may not fit the masking requirements for the **Mask variable** option,
+ so the value could be exposed in the job logs.
+- Scans may not run in unprotected feature branches if you select the **Protect variable** option.
+- Consider creating credentials with read-only permissions and rotating them regularly if the
+ options aren't selected.
+
## Running the standalone container scanning tool
It's possible to run the [GitLab container scanning tool](https://gitlab.com/gitlab-org/security-products/analyzers/container-scanning)
diff --git a/lib/gitlab/content_security_policy/config_loader.rb b/lib/gitlab/content_security_policy/config_loader.rb
index bdcedd1896d..0e3fa8b8d87 100644
--- a/lib/gitlab/content_security_policy/config_loader.rb
+++ b/lib/gitlab/content_security_policy/config_loader.rb
@@ -35,6 +35,10 @@ module Gitlab
# However Safari seems to read child-src first so we'll just keep both equal
directives['child_src'] = directives['frame_src']
+ # connect_src with 'self' includes https/wss variations of the origin,
+ # however, safari hasn't covered this yet and we need to explicitly add
+ # support for websocket origins until Safari catches up with the specs
+ allow_websocket_connections(directives)
allow_webpack_dev_server(directives) if Rails.env.development?
allow_cdn(directives, Settings.gitlab.cdn_host) if Settings.gitlab.cdn_host.present?
allow_customersdot(directives) if Rails.env.development? && ENV['CUSTOMER_PORTAL_URL'].present?
@@ -67,6 +71,22 @@ module Gitlab
arguments.strip.split(' ').map(&:strip)
end
+ def self.allow_websocket_connections(directives)
+ http_ports = [80, 443]
+ host = Gitlab.config.gitlab.host
+ port = Gitlab.config.gitlab.port
+ secure = Gitlab.config.gitlab.https
+ protocol = secure ? 'wss' : 'ws'
+
+ ws_url = "#{protocol}://#{host}"
+
+ unless http_ports.include?(port)
+ ws_url = "#{ws_url}:#{port}"
+ end
+
+ append_to_directive(directives, 'connect_src', ws_url)
+ end
+
def self.allow_webpack_dev_server(directives)
secure = Settings.webpack.dev_server['https']
host_and_port = "#{Settings.webpack.dev_server['host']}:#{Settings.webpack.dev_server['port']}"
diff --git a/lib/gitlab/import_export/merge_request_parser.rb b/lib/gitlab/import_export/merge_request_parser.rb
index 3910afef108..301e90e3171 100644
--- a/lib/gitlab/import_export/merge_request_parser.rb
+++ b/lib/gitlab/import_export/merge_request_parser.rb
@@ -39,7 +39,9 @@ module Gitlab
# created manually. Ignore failures so we get the merge request itself if
# the commits are missing.
def create_source_branch
- @project.repository.create_branch(@merge_request.source_branch, @diff_head_sha)
+ if @merge_request.open?
+ @project.repository.create_branch(@merge_request.source_branch, @diff_head_sha)
+ end
rescue StandardError => err
Gitlab::Import::Logger.warn(
message: 'Import warning: Failed to create source branch',
diff --git a/qa/qa/page/project/packages/show.rb b/qa/qa/page/project/packages/show.rb
index 59e9a3752c7..4872c0bc705 100644
--- a/qa/qa/page/project/packages/show.rb
+++ b/qa/qa/page/project/packages/show.rb
@@ -5,7 +5,7 @@ module QA
module Project
module Packages
class Show < QA::Page::Base
- view 'app/assets/javascripts/packages/details/components/app.vue' do
+ view 'app/assets/javascripts/packages_and_registries/package_registry/components/details/app.vue' do
element :delete_button
element :delete_modal_button
element :package_information_content
diff --git a/spec/frontend/packages/details/components/__snapshots__/file_sha_spec.js.snap b/spec/frontend/packages_and_registries/infrastructure_registry/components/details/components/__snapshots__/file_sha_spec.js.snap
index 881d441e116..881d441e116 100644
--- a/spec/frontend/packages/details/components/__snapshots__/file_sha_spec.js.snap
+++ b/spec/frontend/packages_and_registries/infrastructure_registry/components/details/components/__snapshots__/file_sha_spec.js.snap
diff --git a/spec/frontend/packages_and_registries/infrastructure_registry/components/__snapshots__/terraform_installation_spec.js.snap b/spec/frontend/packages_and_registries/infrastructure_registry/components/details/components/__snapshots__/terraform_installation_spec.js.snap
index 03236737572..03236737572 100644
--- a/spec/frontend/packages_and_registries/infrastructure_registry/components/__snapshots__/terraform_installation_spec.js.snap
+++ b/spec/frontend/packages_and_registries/infrastructure_registry/components/details/components/__snapshots__/terraform_installation_spec.js.snap
diff --git a/spec/frontend/packages/details/components/app_spec.js b/spec/frontend/packages_and_registries/infrastructure_registry/components/details/components/app_spec.js
index 206c5fcf544..c7c10cef504 100644
--- a/spec/frontend/packages/details/components/app_spec.js
+++ b/spec/frontend/packages_and_registries/infrastructure_registry/components/details/components/app_spec.js
@@ -5,19 +5,19 @@ import Vuex from 'vuex';
import { useMockLocationHelper } from 'helpers/mock_window_location_helper';
import stubChildren from 'helpers/stub_children';
-import PackagesApp from '~/packages/details/components/app.vue';
-import PackageFiles from '~/packages/details/components/package_files.vue';
-import PackageHistory from '~/packages/details/components/package_history.vue';
-import * as getters from '~/packages/details/store/getters';
+import PackagesApp from '~/packages_and_registries/infrastructure_registry/details/components/app.vue';
+import PackageFiles from '~/packages_and_registries/infrastructure_registry/details/components/package_files.vue';
+import PackageHistory from '~/packages_and_registries/infrastructure_registry/details/components/package_history.vue';
+import * as getters from '~/packages_and_registries/infrastructure_registry/details/store/getters';
import PackageListRow from '~/packages/shared/components/package_list_row.vue';
import PackagesListLoader from '~/packages/shared/components/packages_list_loader.vue';
import { TrackingActions } from '~/packages/shared/constants';
import * as SharedUtils from '~/packages/shared/utils';
-import TerraformTitle from '~/packages_and_registries/infrastructure_registry/components/details_title.vue';
-import TerraformInstallation from '~/packages_and_registries/infrastructure_registry/components/terraform_installation.vue';
+import TerraformTitle from '~/packages_and_registries/infrastructure_registry/details/components/details_title.vue';
+import TerraformInstallation from '~/packages_and_registries/infrastructure_registry/details/components/terraform_installation.vue';
import Tracking from '~/tracking';
-import { mavenPackage, mavenFiles, npmPackage } from '../../mock_data';
+import { mavenPackage, mavenFiles, npmPackage } from 'jest/packages/mock_data';
const localVue = createLocalVue();
localVue.use(Vuex);
diff --git a/spec/frontend/packages_and_registries/infrastructure_registry/components/details_title_spec.js b/spec/frontend/packages_and_registries/infrastructure_registry/components/details/components/details_title_spec.js
index 87e0059344c..a012ec4ab05 100644
--- a/spec/frontend/packages_and_registries/infrastructure_registry/components/details_title_spec.js
+++ b/spec/frontend/packages_and_registries/infrastructure_registry/components/details/components/details_title_spec.js
@@ -1,7 +1,7 @@
import { shallowMount, createLocalVue } from '@vue/test-utils';
import Vuex from 'vuex';
import { terraformModule, mavenFiles, npmPackage } from 'jest/packages/mock_data';
-import component from '~/packages_and_registries/infrastructure_registry/components/details_title.vue';
+import component from '~/packages_and_registries/infrastructure_registry/details/components/details_title.vue';
import TitleArea from '~/vue_shared/components/registry/title_area.vue';
const localVue = createLocalVue();
diff --git a/spec/frontend/packages/details/components/file_sha_spec.js b/spec/frontend/packages_and_registries/infrastructure_registry/components/details/components/file_sha_spec.js
index 7bfcf78baab..9ce590bfb51 100644
--- a/spec/frontend/packages/details/components/file_sha_spec.js
+++ b/spec/frontend/packages_and_registries/infrastructure_registry/components/details/components/file_sha_spec.js
@@ -1,6 +1,6 @@
import { shallowMount } from '@vue/test-utils';
-import FileSha from '~/packages/details/components/file_sha.vue';
+import FileSha from '~/packages_and_registries/infrastructure_registry/details/components/file_sha.vue';
import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
import DetailsRow from '~/vue_shared/components/registry/details_row.vue';
diff --git a/spec/frontend/packages/details/components/package_files_spec.js b/spec/frontend/packages_and_registries/infrastructure_registry/components/details/components/package_files_spec.js
index e8e5a24d3a3..0c5aa30223b 100644
--- a/spec/frontend/packages/details/components/package_files_spec.js
+++ b/spec/frontend/packages_and_registries/infrastructure_registry/components/details/components/package_files_spec.js
@@ -2,11 +2,11 @@ import { GlDropdown, GlButton } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
import { nextTick } from 'vue/';
import stubChildren from 'helpers/stub_children';
-import component from '~/packages/details/components/package_files.vue';
+import component from '~/packages_and_registries/infrastructure_registry/details/components/package_files.vue';
import FileIcon from '~/vue_shared/components/file_icon.vue';
import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
-import { npmFiles, mavenFiles } from '../../mock_data';
+import { npmFiles, mavenFiles } from 'jest/packages/mock_data';
describe('Package Files', () => {
let wrapper;
diff --git a/spec/frontend/packages/details/components/package_history_spec.js b/spec/frontend/packages_and_registries/infrastructure_registry/components/details/components/package_history_spec.js
index 244805a9c82..4987af9f5b0 100644
--- a/spec/frontend/packages/details/components/package_history_spec.js
+++ b/spec/frontend/packages_and_registries/infrastructure_registry/components/details/components/package_history_spec.js
@@ -1,12 +1,12 @@
import { GlLink, GlSprintf } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import { stubComponent } from 'helpers/stub_component';
-import component from '~/packages/details/components/package_history.vue';
-import { HISTORY_PIPELINES_LIMIT } from '~/packages/details/constants';
+import component from '~/packages_and_registries/infrastructure_registry/details/components/package_history.vue';
+import { HISTORY_PIPELINES_LIMIT } from '~/packages_and_registries/shared/constants';
import HistoryItem from '~/vue_shared/components/registry/history_item.vue';
import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
-import { mavenPackage, mockPipelineInfo } from '../../mock_data';
+import { mavenPackage, mockPipelineInfo } from 'jest/packages/mock_data';
describe('Package History', () => {
let wrapper;
diff --git a/spec/frontend/packages_and_registries/infrastructure_registry/components/terraform_installation_spec.js b/spec/frontend/packages_and_registries/infrastructure_registry/components/details/components/terraform_installation_spec.js
index ee1548ed5eb..c26784a4b75 100644
--- a/spec/frontend/packages_and_registries/infrastructure_registry/components/terraform_installation_spec.js
+++ b/spec/frontend/packages_and_registries/infrastructure_registry/components/details/components/terraform_installation_spec.js
@@ -1,7 +1,7 @@
import { shallowMount, createLocalVue } from '@vue/test-utils';
import Vuex from 'vuex';
import { terraformModule as packageEntity } from 'jest/packages/mock_data';
-import TerraformInstallation from '~/packages_and_registries/infrastructure_registry/components/terraform_installation.vue';
+import TerraformInstallation from '~/packages_and_registries/infrastructure_registry/details/components/terraform_installation.vue';
import CodeInstructions from '~/vue_shared/components/registry/code_instruction.vue';
const localVue = createLocalVue();
diff --git a/spec/frontend/packages/details/mock_data.js b/spec/frontend/packages_and_registries/infrastructure_registry/components/details/mock_data.js
index d43abcedb2e..d43abcedb2e 100644
--- a/spec/frontend/packages/details/mock_data.js
+++ b/spec/frontend/packages_and_registries/infrastructure_registry/components/details/mock_data.js
diff --git a/spec/frontend/packages/details/store/actions_spec.js b/spec/frontend/packages_and_registries/infrastructure_registry/components/details/store/actions_spec.js
index b16e50debc4..61fa69c2f7a 100644
--- a/spec/frontend/packages/details/store/actions_spec.js
+++ b/spec/frontend/packages_and_registries/infrastructure_registry/components/details/store/actions_spec.js
@@ -1,19 +1,19 @@
import testAction from 'helpers/vuex_action_helper';
import Api from '~/api';
import createFlash from '~/flash';
-import { FETCH_PACKAGE_VERSIONS_ERROR } from '~/packages/details/constants';
+import { FETCH_PACKAGE_VERSIONS_ERROR } from '~/packages_and_registries/infrastructure_registry/details/constants';
import {
fetchPackageVersions,
deletePackage,
deletePackageFile,
-} from '~/packages/details/store/actions';
-import * as types from '~/packages/details/store/mutation_types';
+} from '~/packages_and_registries/infrastructure_registry/details/store/actions';
+import * as types from '~/packages_and_registries/infrastructure_registry/details/store/mutation_types';
import {
DELETE_PACKAGE_ERROR_MESSAGE,
DELETE_PACKAGE_FILE_ERROR_MESSAGE,
DELETE_PACKAGE_FILE_SUCCESS_MESSAGE,
} from '~/packages/shared/constants';
-import { npmPackage as packageEntity } from '../../mock_data';
+import { npmPackage as packageEntity } from '../../../../../packages/mock_data';
jest.mock('~/flash.js');
jest.mock('~/api.js');
diff --git a/spec/frontend/packages/details/store/getters_spec.js b/spec/frontend/packages_and_registries/infrastructure_registry/components/details/store/getters_spec.js
index 4eccb766a89..8740691a8ee 100644
--- a/spec/frontend/packages/details/store/getters_spec.js
+++ b/spec/frontend/packages_and_registries/infrastructure_registry/components/details/store/getters_spec.js
@@ -1,9 +1,9 @@
-import { packagePipeline } from '~/packages/details/store/getters';
+import { packagePipeline } from '~/packages_and_registries/infrastructure_registry/details/store/getters';
import {
npmPackage,
mockPipelineInfo,
mavenPackage as packageWithoutBuildInfo,
-} from '../../mock_data';
+} from 'jest/packages/mock_data';
describe('Getters PackageDetails Store', () => {
let state;
diff --git a/spec/frontend/packages/details/store/mutations_spec.js b/spec/frontend/packages_and_registries/infrastructure_registry/components/details/store/mutations_spec.js
index 296ed02d786..6efefea4a14 100644
--- a/spec/frontend/packages/details/store/mutations_spec.js
+++ b/spec/frontend/packages_and_registries/infrastructure_registry/components/details/store/mutations_spec.js
@@ -1,6 +1,6 @@
-import * as types from '~/packages/details/store/mutation_types';
-import mutations from '~/packages/details/store/mutations';
-import { npmPackage as packageEntity } from '../../mock_data';
+import * as types from '~/packages_and_registries/infrastructure_registry/details/store/mutation_types';
+import mutations from '~/packages_and_registries/infrastructure_registry/details/store/mutations';
+import { npmPackage as packageEntity } from 'jest/packages/mock_data';
describe('Mutations package details Store', () => {
let mockState;
diff --git a/spec/frontend/packages_and_registries/package_registry/components/details/package_history_spec.js b/spec/frontend/packages_and_registries/package_registry/components/details/package_history_spec.js
index b69008f04f0..57b8be40a7c 100644
--- a/spec/frontend/packages_and_registries/package_registry/components/details/package_history_spec.js
+++ b/spec/frontend/packages_and_registries/package_registry/components/details/package_history_spec.js
@@ -5,7 +5,7 @@ import {
packageData,
packagePipelines,
} from 'jest/packages_and_registries/package_registry/mock_data';
-import { HISTORY_PIPELINES_LIMIT } from '~/packages/details/constants';
+import { HISTORY_PIPELINES_LIMIT } from '~/packages_and_registries/shared/constants';
import component from '~/packages_and_registries/package_registry/components/details/package_history.vue';
import HistoryItem from '~/vue_shared/components/registry/history_item.vue';
import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
diff --git a/spec/frontend/tracking_spec.js b/spec/frontend/tracking_spec.js
index 1aa64e049bb..38c93157221 100644
--- a/spec/frontend/tracking_spec.js
+++ b/spec/frontend/tracking_spec.js
@@ -332,14 +332,13 @@ describe('Tracking', () => {
});
});
- it('appends the hash/fragment to the pseudonymized URL', () => {
- const hash = 'first-heading';
+ it('does not appends the hash/fragment to the pseudonymized URL', () => {
window.gl.snowplowPseudonymizedPageUrl = TEST_HOST;
- window.location.hash = hash;
+ window.location.hash = 'first-heading';
Tracking.setAnonymousUrls();
- expect(snowplowSpy).toHaveBeenCalledWith('setCustomUrl', `${TEST_HOST}#${hash}`);
+ expect(snowplowSpy).toHaveBeenCalledWith('setCustomUrl', TEST_HOST);
});
it('does not set the referrer URL by default', () => {
diff --git a/spec/lib/gitlab/content_security_policy/config_loader_spec.rb b/spec/lib/gitlab/content_security_policy/config_loader_spec.rb
index 239eff11bf3..3ec332dace5 100644
--- a/spec/lib/gitlab/content_security_policy/config_loader_spec.rb
+++ b/spec/lib/gitlab/content_security_policy/config_loader_spec.rb
@@ -11,6 +11,7 @@ RSpec.describe Gitlab::ContentSecurityPolicy::ConfigLoader do
directives: {
base_uri: 'http://example.com',
child_src: "'self' https://child.example.com",
+ connect_src: "'self' ws://example.com",
default_src: "'self' https://other.example.com",
script_src: "'self' https://script.exammple.com ",
worker_src: "data: https://worker.example.com",
@@ -52,6 +53,28 @@ RSpec.describe Gitlab::ContentSecurityPolicy::ConfigLoader do
expect(directives['child_src']).to eq(directives['frame_src'])
end
+ context 'adds all websocket origins to support Safari' do
+ it 'with insecure domain' do
+ stub_config_setting(host: 'example.com', https: false)
+ expect(directives['connect_src']).to eq("'self' ws://example.com")
+ end
+
+ it 'with secure domain' do
+ stub_config_setting(host: 'example.com', https: true)
+ expect(directives['connect_src']).to eq("'self' wss://example.com")
+ end
+
+ it 'with custom port' do
+ stub_config_setting(host: 'example.com', port: '1234')
+ expect(directives['connect_src']).to eq("'self' ws://example.com:1234")
+ end
+
+ it 'with custom port and secure domain' do
+ stub_config_setting(host: 'example.com', https: true, port: '1234')
+ expect(directives['connect_src']).to eq("'self' wss://example.com:1234")
+ end
+ end
+
context 'when CDN host is defined' do
before do
stub_config_setting(cdn_host: 'https://example.com')
@@ -67,10 +90,11 @@ RSpec.describe Gitlab::ContentSecurityPolicy::ConfigLoader do
context 'when sentry is configured' do
before do
stub_sentry_settings
+ stub_config_setting(host: 'example.com')
end
it 'adds sentry path to CSP without user' do
- expect(directives['connect_src']).to eq("'self' dummy://example.com/43")
+ expect(directives['connect_src']).to eq("'self' ws://example.com dummy://example.com/43")
end
end
@@ -113,6 +137,7 @@ RSpec.describe Gitlab::ContentSecurityPolicy::ConfigLoader do
expect(policy.directives['base-uri']).to eq([csp_config[:directives][:base_uri]])
expect(policy.directives['default-src']).to eq(expected_config(:default_src))
+ expect(policy.directives['connect-src']).to eq(expected_config(:connect_src))
expect(policy.directives['child-src']).to eq(expected_config(:child_src))
expect(policy.directives['worker-src']).to eq(expected_config(:worker_src))
expect(policy.directives['report-uri']).to eq(expected_config(:report_uri))
diff --git a/spec/lib/gitlab/database/migration_helpers/loose_foreign_key_helpers_spec.rb b/spec/lib/gitlab/database/migration_helpers/loose_foreign_key_helpers_spec.rb
index 708d1be6e00..54b3ad22faf 100644
--- a/spec/lib/gitlab/database/migration_helpers/loose_foreign_key_helpers_spec.rb
+++ b/spec/lib/gitlab/database/migration_helpers/loose_foreign_key_helpers_spec.rb
@@ -19,6 +19,10 @@ RSpec.describe Gitlab::Database::MigrationHelpers::LooseForeignKeyHelpers do
end
end
+ after(:all) do
+ migration.drop_table :loose_fk_test_table
+ end
+
before do
3.times { model.create! }
end
@@ -45,8 +49,9 @@ RSpec.describe Gitlab::Database::MigrationHelpers::LooseForeignKeyHelpers do
expect(LooseForeignKeys::DeletedRecord.count).to eq(1)
deleted_record = LooseForeignKeys::DeletedRecord.all.first
- expect(deleted_record.deleted_table_primary_key_value).to eq(record_to_be_deleted.id)
- expect(deleted_record.deleted_table_name).to eq('loose_fk_test_table')
+ expect(deleted_record.primary_key_value).to eq(record_to_be_deleted.id)
+ expect(deleted_record.fully_qualified_table_name).to eq('public.loose_fk_test_table')
+ expect(deleted_record.partition).to eq(1)
end
it 'stores multiple record deletions' do
diff --git a/spec/lib/gitlab/import_export/merge_request_parser_spec.rb b/spec/lib/gitlab/import_export/merge_request_parser_spec.rb
index c558c12f581..550cefea805 100644
--- a/spec/lib/gitlab/import_export/merge_request_parser_spec.rb
+++ b/spec/lib/gitlab/import_export/merge_request_parser_spec.rb
@@ -13,9 +13,11 @@ RSpec.describe Gitlab::ImportExport::MergeRequestParser do
create(:merge_request, source_project: forked_project, target_project: project)
end
+ let(:diff_head_sha) { SecureRandom.hex(20) }
+
let(:parsed_merge_request) do
described_class.new(project,
- 'abcd',
+ diff_head_sha,
merge_request,
merge_request.as_json).parse!
end
@@ -34,14 +36,34 @@ RSpec.describe Gitlab::ImportExport::MergeRequestParser do
expect(project.repository.branch_exists?(parsed_merge_request.target_branch)).to be true
end
- it 'parses a MR that has no source branch' do
- allow_next_instance_of(described_class) do |instance|
- allow(instance).to receive(:branch_exists?).and_call_original
- allow(instance).to receive(:branch_exists?).with(merge_request.source_branch).and_return(false)
- allow(instance).to receive(:fork_merge_request?).and_return(true)
+ # Source and target branch are only created when: fork_merge_request
+ context 'fork merge request' do
+ before do
+ allow_next_instance_of(described_class) do |instance|
+ allow(instance).to receive(:fork_merge_request?).and_return(true)
+ end
+ end
+
+ it 'parses a MR that has no source branch' do
+ allow_next_instance_of(described_class) do |instance|
+ allow(instance).to receive(:branch_exists?).and_call_original
+ allow(instance).to receive(:branch_exists?).with(merge_request.source_branch).and_return(false)
+ end
+
+ expect(parsed_merge_request).to eq(merge_request)
end
- expect(parsed_merge_request).to eq(merge_request)
+ it 'parses a MR that is closed' do
+ merge_request.update!(state: :closed, source_branch: 'new_branch')
+
+ expect(project.repository.branch_exists?(parsed_merge_request.source_branch)).to be false
+ end
+
+ it 'parses a MR that is merged' do
+ merge_request.update!(state: :merged, source_branch: 'new_branch')
+
+ expect(project.repository.branch_exists?(parsed_merge_request.source_branch)).to be false
+ end
end
context 'when the merge request has diffs' do
diff --git a/spec/models/loose_foreign_keys/deleted_record_spec.rb b/spec/models/loose_foreign_keys/deleted_record_spec.rb
deleted file mode 100644
index db2f8b4d2d3..00000000000
--- a/spec/models/loose_foreign_keys/deleted_record_spec.rb
+++ /dev/null
@@ -1,56 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe LooseForeignKeys::DeletedRecord do
- let_it_be(:deleted_record_1) { described_class.create!(created_at: 1.day.ago, deleted_table_name: 'projects', deleted_table_primary_key_value: 5) }
- let_it_be(:deleted_record_2) { described_class.create!(created_at: 3.days.ago, deleted_table_name: 'projects', deleted_table_primary_key_value: 1) }
- let_it_be(:deleted_record_3) { described_class.create!(created_at: 5.days.ago, deleted_table_name: 'projects', deleted_table_primary_key_value: 3) }
- let_it_be(:deleted_record_4) { described_class.create!(created_at: 10.days.ago, deleted_table_name: 'projects', deleted_table_primary_key_value: 1) } # duplicate
-
- # skip created_at because it gets truncated after insert
- def map_attributes(records)
- records.pluck(:deleted_table_name, :deleted_table_primary_key_value)
- end
-
- describe 'partitioning strategy' do
- it 'has retain_non_empty_partitions option' do
- expect(described_class.partitioning_strategy.retain_non_empty_partitions).to eq(true)
- end
- end
-
- describe '.load_batch' do
- it 'loads records and orders them by creation date' do
- records = described_class.load_batch(4)
-
- expect(map_attributes(records)).to eq([['projects', 1], ['projects', 3], ['projects', 1], ['projects', 5]])
- end
-
- it 'supports configurable batch size' do
- records = described_class.load_batch(2)
-
- expect(map_attributes(records)).to eq([['projects', 1], ['projects', 3]])
- end
- end
-
- describe '.delete_records' do
- it 'deletes exactly one record' do
- described_class.delete_records([deleted_record_2])
-
- expect(described_class.count).to eq(3)
- expect(described_class.find_by(created_at: deleted_record_2.created_at)).to eq(nil)
- end
-
- it 'deletes two records' do
- described_class.delete_records([deleted_record_2, deleted_record_4])
-
- expect(described_class.count).to eq(2)
- end
-
- it 'deletes all records' do
- described_class.delete_records([deleted_record_1, deleted_record_2, deleted_record_3, deleted_record_4])
-
- expect(described_class.count).to eq(0)
- end
- end
-end