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

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.dockerignore1
-rw-r--r--.gitlab/ci/gitlab-gems.gitlab-ci.yml8
-rw-r--r--.gitlab/ci/package-and-test-nightly/main.gitlab-ci.yml11
-rw-r--r--.gitlab/ci/package-and-test/main.gitlab-ci.yml33
-rw-r--r--.gitlab/ci/preflight.gitlab-ci.yml3
-rw-r--r--.gitlab/ci/rules.gitlab-ci.yml5
-rw-r--r--.rubocop_todo/gitlab/doc_url.yml1
-rw-r--r--.rubocop_todo/gitlab/namespaced_class.yml1
-rw-r--r--.rubocop_todo/layout/argument_alignment.yml1
-rw-r--r--.rubocop_todo/layout/line_length.yml1
-rw-r--r--.rubocop_todo/lint/ambiguous_regexp_literal.yml1
-rw-r--r--.rubocop_todo/lint/symbol_conversion.yml1
-rw-r--r--.rubocop_todo/rspec/context_wording.yml2
-rw-r--r--.rubocop_todo/rspec/missing_feature_category.yml1
-rw-r--r--.rubocop_todo/style/percent_literal_delimiters.yml1
-rw-r--r--.rubocop_todo/style/string_concatenation.yml1
-rw-r--r--Gemfile5
-rw-r--r--Gemfile.lock11
-rw-r--r--app/assets/javascripts/behaviors/markdown/render_gfm.js4
-rw-r--r--app/assets/javascripts/behaviors/markdown/render_sandboxed_mermaid.js11
-rw-r--r--app/assets/javascripts/issuable/components/status_box.vue41
-rw-r--r--app/assets/javascripts/issuable/popover/components/issue_popover.vue8
-rw-r--r--app/assets/javascripts/issuable/popover/components/mr_popover.vue8
-rw-r--r--app/assets/javascripts/issuable/popover/index.js20
-rw-r--r--app/assets/javascripts/lib/mermaid.js7
-rw-r--r--app/assets/javascripts/lib/utils/datetime/date_format_utility.js32
-rw-r--r--app/assets/javascripts/tracking/constants.js4
-rw-r--r--app/assets/javascripts/tracking/index.js2
-rw-r--r--app/assets/javascripts/tracking/internal_events.js36
-rw-r--r--app/controllers/concerns/uploads_actions.rb17
-rw-r--r--app/models/concerns/project_features_compatibility.rb2
-rw-r--r--app/validators/json_schemas/security_ci_configuration_schemas/sast_ui_schema.json38
-rwxr-xr-xbin/audit-event-type3
-rw-r--r--config/application.rb3
-rw-r--r--config/environments/test.rb2
-rw-r--r--db/docs/subscription_user_add_on_assignments.yml10
-rw-r--r--db/migrate/20230616164309_create_subscription_user_add_on_assignments.rb17
-rw-r--r--db/migrate/20230616164705_add_foreign_key_add_on_purchase_id_on_subscription_user_add_on_assignments.rb16
-rw-r--r--db/migrate/20230616164731_add_foreign_key_user_id_on_subscription_user_add_on_assignments.rb15
-rw-r--r--db/schema_migrations/202306161643091
-rw-r--r--db/schema_migrations/202306161647051
-rw-r--r--db/schema_migrations/202306161647311
-rw-r--r--db/structure.sql32
-rw-r--r--doc/administration/instance_limits.md157
-rw-r--r--doc/ci/runners/saas/macos_saas_runner.md21
-rw-r--r--doc/development/gems.md2
-rw-r--r--doc/development/pipelines/index.md8
-rw-r--r--doc/integration/advanced_search/elasticsearch_troubleshooting.md18
-rw-r--r--doc/user/permissions.md2
-rw-r--r--gems/gitlab-rspec/.gitlab-ci.yml2
-rw-r--r--gems/gitlab-rspec/gitlab-rspec.gemspec2
-rw-r--r--gems/gitlab-utils/.gitignore11
-rw-r--r--gems/gitlab-utils/.gitlab-ci.yml30
-rw-r--r--gems/gitlab-utils/.rspec3
-rw-r--r--gems/gitlab-utils/.rubocop.yml31
-rw-r--r--gems/gitlab-utils/Gemfile10
-rw-r--r--gems/gitlab-utils/Gemfile.lock193
-rw-r--r--gems/gitlab-utils/README.md8
-rw-r--r--gems/gitlab-utils/Rakefile12
-rw-r--r--gems/gitlab-utils/gitlab-utils.gemspec34
-rw-r--r--gems/gitlab-utils/lib/gitlab/utils.rb (renamed from lib/gitlab/utils.rb)18
-rw-r--r--gems/gitlab-utils/lib/gitlab/utils/all.rb6
-rw-r--r--gems/gitlab-utils/lib/gitlab/utils/strong_memoize.rb (renamed from lib/gitlab/utils/strong_memoize.rb)0
-rw-r--r--gems/gitlab-utils/lib/gitlab/utils/version.rb9
-rw-r--r--gems/gitlab-utils/lib/gitlab/version_info.rb (renamed from lib/gitlab/version_info.rb)6
-rw-r--r--gems/gitlab-utils/spec/gitlab/utils/strong_memoize_spec.rb (renamed from spec/lib/gitlab/utils/strong_memoize_spec.rb)24
-rw-r--r--gems/gitlab-utils/spec/gitlab/utils_spec.rb (renamed from spec/lib/gitlab/utils_spec.rb)20
-rw-r--r--gems/gitlab-utils/spec/gitlab/version_info_spec.rb (renamed from spec/lib/gitlab/version_info_spec.rb)4
-rw-r--r--gems/gitlab-utils/spec/spec_helper.rb23
-rw-r--r--lib/gitlab/cluster/lifecycle_events.rb2
-rw-r--r--lib/gitlab/sidekiq_logging/structured_logger.rb1
-rw-r--r--lib/gitlab/sidekiq_middleware/defer_jobs.rb2
-rw-r--r--lib/gitlab/task_helpers.rb2
-rw-r--r--lib/gitlab/utils/override.rb2
-rw-r--r--lib/tasks/gettext.rake2
-rw-r--r--locale/gitlab.pot18
-rw-r--r--metrics_server/dependencies.rb4
-rw-r--r--qa/Dockerfile4
-rw-r--r--qa/Gemfile1
-rw-r--r--qa/Gemfile.lock29
-rw-r--r--qa/gdk/Dockerfile.gdk4
-rw-r--r--qa/qa.rb3
-rw-r--r--qa/qa/scenario/test/integration/oauth.rb13
-rwxr-xr-xscripts/gitaly-test-build1
-rwxr-xr-xscripts/gitaly-test-spawn1
-rwxr-xr-xscripts/merge-simplecov1
-rwxr-xr-xscripts/setup-test-env2
-rw-r--r--sidekiq_cluster/cli.rb2
-rw-r--r--spec/controllers/groups/uploads_controller_spec.rb20
-rw-r--r--spec/deprecation_warnings.rb2
-rw-r--r--spec/fast_spec_helper.rb3
-rw-r--r--spec/features/markdown/sandboxed_mermaid_spec.rb5
-rw-r--r--spec/frontend/behaviors/markdown/render_sandboxed_mermaid_spec.js2
-rw-r--r--spec/frontend/issuable/components/status_box_spec.js2
-rw-r--r--spec/frontend/issuable/popover/components/issue_popover_spec.js2
-rw-r--r--spec/frontend/issuable/popover/components/mr_popover_spec.js2
-rw-r--r--spec/frontend/issuable/popover/index_spec.js68
-rw-r--r--spec/frontend/lib/utils/datetime/date_format_utility_spec.js15
-rw-r--r--spec/lib/gitlab/sidekiq_logging/structured_logger_spec.rb1
-rw-r--r--spec/lib/gitlab/sidekiq_middleware/defer_jobs_spec.rb9
-rw-r--r--spec/simplecov_env.rb2
-rw-r--r--spec/support/ability_check.rb2
-rw-r--r--spec/support/formatters/json_formatter.rb10
-rw-r--r--spec/support/helpers/gitaly_setup.rb3
-rw-r--r--spec/support/rspec.rb1
-rw-r--r--spec/support/shared_contexts/lib/gitlab/sidekiq_logging/structured_logger_shared_context.rb3
-rw-r--r--spec/support/shared_examples/controllers/uploads_actions_shared_examples.rb8
107 files changed, 966 insertions, 361 deletions
diff --git a/.dockerignore b/.dockerignore
index 0782627230a..a2d54fa65dd 100644
--- a/.dockerignore
+++ b/.dockerignore
@@ -80,4 +80,3 @@
/spec/
/symbol/
/tmp/
-/vendor/
diff --git a/.gitlab/ci/gitlab-gems.gitlab-ci.yml b/.gitlab/ci/gitlab-gems.gitlab-ci.yml
index adab179d2a2..aff272935c5 100644
--- a/.gitlab/ci/gitlab-gems.gitlab-ci.yml
+++ b/.gitlab/ci/gitlab-gems.gitlab-ci.yml
@@ -5,3 +5,11 @@ gems gitlab-rspec:
trigger:
include: gems/gitlab-rspec/.gitlab-ci.yml
strategy: depend
+
+gems gitlab-utils:
+ extends:
+ - .gems:rules:gitlab-utils
+ needs: []
+ trigger:
+ include: gems/gitlab-utils/.gitlab-ci.yml
+ strategy: depend
diff --git a/.gitlab/ci/package-and-test-nightly/main.gitlab-ci.yml b/.gitlab/ci/package-and-test-nightly/main.gitlab-ci.yml
index 34b4e853415..d1062250040 100644
--- a/.gitlab/ci/package-and-test-nightly/main.gitlab-ci.yml
+++ b/.gitlab/ci/package-and-test-nightly/main.gitlab-ci.yml
@@ -97,6 +97,17 @@ integration-opensearch-compatibility-version-2:
OPENSEARCH_VERSION: "2.0.1"
QA_SCENARIO: "Test::Integration::Opensearch"
+# ------------------------------------------
+# Relative url
+# ------------------------------------------
+relative-url:
+ extends:
+ - .qa
+ - .ee
+ - .parallel
+ variables:
+ QA_SCENARIO: Test::Instance::RelativeUrl
+
# ==========================================
# Post test stage
# ==========================================
diff --git a/.gitlab/ci/package-and-test/main.gitlab-ci.yml b/.gitlab/ci/package-and-test/main.gitlab-ci.yml
index fcea49e3103..8ed1bb5d067 100644
--- a/.gitlab/ci/package-and-test/main.gitlab-ci.yml
+++ b/.gitlab/ci/package-and-test/main.gitlab-ci.yml
@@ -81,6 +81,7 @@ instance-ff-inverse:
# ------------------------------------------
# ========== instance ===========
+
instance:
extends:
- .parallel
@@ -151,38 +152,6 @@ praefect-selective-parallel:
variables:
QA_TESTS: ""
-# ========== relative-url ===========
-
-relative-url:
- extends:
- - .qa
- - .parallel
- variables:
- QA_SCENARIO: Test::Instance::RelativeUrl
- rules:
- - !reference [.rules:test:qa-parallel, rules]
- - if: $QA_SUITES =~ /Test::Instance::All/
-
-relative-url-selective:
- extends: .qa
- variables:
- QA_SCENARIO: Test::Instance::RelativeUrl
- rules:
- - !reference [.rules:test:qa-selective, rules]
- - if: $QA_SUITES =~ /Test::Instance::All/
-
-relative-url-selective-parallel:
- extends:
- - .qa
- - .parallel
- variables:
- QA_SCENARIO: Test::Instance::RelativeUrl
- rules:
- - !reference [.rules:test:qa-selective-parallel, rules]
- - if: $QA_SUITES =~ /Test::Instance::All/
- variables:
- QA_TESTS: ""
-
# ========== decomposition-single-db ===========
decomposition-single-db:
diff --git a/.gitlab/ci/preflight.gitlab-ci.yml b/.gitlab/ci/preflight.gitlab-ci.yml
index 968402b2ea5..6a2ea85f393 100644
--- a/.gitlab/ci/preflight.gitlab-ci.yml
+++ b/.gitlab/ci/preflight.gitlab-ci.yml
@@ -24,9 +24,6 @@
- .ruby-cache
- .preflight:rules:rails-production-server-boot
- .use-pg13
- variables:
- BUNDLE_WITHOUT: "development:test"
- BUNDLE_WITH: "production"
# Test the puma configuration present in `config/puma.rb.example`
rails-production-server-boot-puma-example:
diff --git a/.gitlab/ci/rules.gitlab-ci.yml b/.gitlab/ci/rules.gitlab-ci.yml
index 6acc2dea2e2..007e5cefb89 100644
--- a/.gitlab/ci/rules.gitlab-ci.yml
+++ b/.gitlab/ci/rules.gitlab-ci.yml
@@ -2135,6 +2135,11 @@
- <<: *if-merge-request
changes: ["gems/gitlab-rspec/**/*"]
+.gems:rules:gitlab-utils:
+ rules:
+ - <<: *if-merge-request
+ changes: ["gems/gitlab-utils/**/*"]
+
#######################
# Vendored gems rules #
#######################
diff --git a/.rubocop_todo/gitlab/doc_url.yml b/.rubocop_todo/gitlab/doc_url.yml
index 119de2296ce..13537a142a1 100644
--- a/.rubocop_todo/gitlab/doc_url.yml
+++ b/.rubocop_todo/gitlab/doc_url.yml
@@ -43,7 +43,6 @@ Gitlab/DocUrl:
- 'lib/gitlab/pagination/keyset/unsupported_scope_order.rb'
- 'lib/gitlab/redis/hll.rb'
- 'lib/gitlab/slash_commands/presenters/help.rb'
- - 'lib/gitlab/utils/strong_memoize.rb'
- 'lib/initializer_connections.rb'
- 'lib/security/ci_configuration/base_build_action.rb'
- 'lib/tasks/db_obsolete_ignored_columns.rake'
diff --git a/.rubocop_todo/gitlab/namespaced_class.yml b/.rubocop_todo/gitlab/namespaced_class.yml
index 8a0dd63ae7c..4ab42f01790 100644
--- a/.rubocop_todo/gitlab/namespaced_class.yml
+++ b/.rubocop_todo/gitlab/namespaced_class.yml
@@ -1248,7 +1248,6 @@ Gitlab/NamespacedClass:
- 'lib/gitlab/user_access.rb'
- 'lib/gitlab/user_access_snippet.rb'
- 'lib/gitlab/uuid.rb'
- - 'lib/gitlab/version_info.rb'
- 'lib/gitlab/visibility_level_checker.rb'
- 'lib/gitlab/wiki_file_finder.rb'
- 'lib/gitlab/workhorse.rb'
diff --git a/.rubocop_todo/layout/argument_alignment.yml b/.rubocop_todo/layout/argument_alignment.yml
index 826e20fb40f..e774c081ef4 100644
--- a/.rubocop_todo/layout/argument_alignment.yml
+++ b/.rubocop_todo/layout/argument_alignment.yml
@@ -1820,7 +1820,6 @@ Layout/ArgumentAlignment:
- 'spec/lib/gitlab/usage_data_queries_spec.rb'
- 'spec/lib/gitlab/usage_data_spec.rb'
- 'spec/lib/gitlab/utils/lazy_attributes_spec.rb'
- - 'spec/lib/gitlab/utils_spec.rb'
- 'spec/lib/gitlab/workhorse_spec.rb'
- 'spec/lib/google_api/cloud_platform/client_spec.rb'
- 'spec/lib/peek/views/detailed_view_spec.rb'
diff --git a/.rubocop_todo/layout/line_length.yml b/.rubocop_todo/layout/line_length.yml
index 1deedbfc96e..a5fafa59388 100644
--- a/.rubocop_todo/layout/line_length.yml
+++ b/.rubocop_todo/layout/line_length.yml
@@ -4230,7 +4230,6 @@ Layout/LineLength:
- 'spec/lib/gitlab/utils/measuring_spec.rb'
- 'spec/lib/gitlab/utils/nokogiri_spec.rb'
- 'spec/lib/gitlab/utils/usage_data_spec.rb'
- - 'spec/lib/gitlab/utils_spec.rb'
- 'spec/lib/gitlab/web_ide/config/entry/global_spec.rb'
- 'spec/lib/gitlab/web_ide/config/entry/terminal_spec.rb'
- 'spec/lib/gitlab/webpack/file_loader_spec.rb'
diff --git a/.rubocop_todo/lint/ambiguous_regexp_literal.yml b/.rubocop_todo/lint/ambiguous_regexp_literal.yml
index c3b06ede5be..4754e381780 100644
--- a/.rubocop_todo/lint/ambiguous_regexp_literal.yml
+++ b/.rubocop_todo/lint/ambiguous_regexp_literal.yml
@@ -66,7 +66,6 @@ Lint/AmbiguousRegexpLiteral:
- 'spec/lib/gitlab/pagination/keyset/iterator_spec.rb'
- 'spec/lib/gitlab/sidekiq_middleware/duplicate_jobs/duplicate_job_spec.rb'
- 'spec/lib/gitlab/usage/metrics/aggregates/sources/postgres_hll_spec.rb'
- - 'spec/lib/gitlab/utils/strong_memoize_spec.rb'
- 'spec/lib/gitlab/web_ide/config/entry/global_spec.rb'
- 'spec/lib/gitlab/web_ide/config/entry/terminal_spec.rb'
- 'spec/lib/object_storage/direct_upload_spec.rb'
diff --git a/.rubocop_todo/lint/symbol_conversion.yml b/.rubocop_todo/lint/symbol_conversion.yml
index 147cd66f993..8799414c911 100644
--- a/.rubocop_todo/lint/symbol_conversion.yml
+++ b/.rubocop_todo/lint/symbol_conversion.yml
@@ -117,7 +117,6 @@ Lint/SymbolConversion:
- 'spec/lib/gitlab/search/abuse_validators/no_abusive_coercion_from_string_validator_spec.rb'
- 'spec/lib/gitlab/slug/path_spec.rb'
- 'spec/lib/gitlab/tracking_spec.rb'
- - 'spec/lib/gitlab/utils_spec.rb'
- 'spec/lib/google_api/cloud_platform/client_spec.rb'
- 'spec/lib/service_ping/devops_report_spec.rb'
- 'spec/models/integrations/prometheus_spec.rb'
diff --git a/.rubocop_todo/rspec/context_wording.yml b/.rubocop_todo/rspec/context_wording.yml
index af708ad54e5..1ce003ecd2f 100644
--- a/.rubocop_todo/rspec/context_wording.yml
+++ b/.rubocop_todo/rspec/context_wording.yml
@@ -2062,9 +2062,7 @@ RSpec/ContextWording:
- 'spec/lib/gitlab/usage_data_spec.rb'
- 'spec/lib/gitlab/utils/lazy_attributes_spec.rb'
- 'spec/lib/gitlab/utils/mime_type_spec.rb'
- - 'spec/lib/gitlab/utils/strong_memoize_spec.rb'
- 'spec/lib/gitlab/utils/usage_data_spec.rb'
- - 'spec/lib/gitlab/utils_spec.rb'
- 'spec/lib/gitlab/view/presenter/base_spec.rb'
- 'spec/lib/gitlab/visibility_level_checker_spec.rb'
- 'spec/lib/gitlab/visibility_level_spec.rb'
diff --git a/.rubocop_todo/rspec/missing_feature_category.yml b/.rubocop_todo/rspec/missing_feature_category.yml
index e3829a97b02..3cf0ed5c38c 100644
--- a/.rubocop_todo/rspec/missing_feature_category.yml
+++ b/.rubocop_todo/rspec/missing_feature_category.yml
@@ -4413,7 +4413,6 @@ RSpec/MissingFeatureCategory:
- 'spec/lib/gitlab/utils/safe_inline_hash_spec.rb'
- 'spec/lib/gitlab/utils/sanitize_node_link_spec.rb'
- 'spec/lib/gitlab/utils/usage_data_spec.rb'
- - 'spec/lib/gitlab/utils_spec.rb'
- 'spec/lib/gitlab/uuid_spec.rb'
- 'spec/lib/gitlab/verify/job_artifacts_spec.rb'
- 'spec/lib/gitlab/verify/lfs_objects_spec.rb'
diff --git a/.rubocop_todo/style/percent_literal_delimiters.yml b/.rubocop_todo/style/percent_literal_delimiters.yml
index 2e03bbf4557..bb29652fe96 100644
--- a/.rubocop_todo/style/percent_literal_delimiters.yml
+++ b/.rubocop_todo/style/percent_literal_delimiters.yml
@@ -843,7 +843,6 @@ Style/PercentLiteralDelimiters:
- 'spec/lib/gitlab/usage_data_counters/hll_redis_counter_spec.rb'
- 'spec/lib/gitlab/usage_data_spec.rb'
- 'spec/lib/gitlab/utils/log_limited_array_spec.rb'
- - 'spec/lib/gitlab/utils_spec.rb'
- 'spec/lib/gitlab/webpack/graphql_known_operations_spec.rb'
- 'spec/lib/gitlab/wiki_pages/front_matter_parser_spec.rb'
- 'spec/lib/object_storage/config_spec.rb'
diff --git a/.rubocop_todo/style/string_concatenation.yml b/.rubocop_todo/style/string_concatenation.yml
index 4e3b17fe4c0..34e4549a987 100644
--- a/.rubocop_todo/style/string_concatenation.yml
+++ b/.rubocop_todo/style/string_concatenation.yml
@@ -212,7 +212,6 @@ Style/StringConcatenation:
- 'spec/lib/gitlab/themes_spec.rb'
- 'spec/lib/gitlab/throttle_spec.rb'
- 'spec/lib/gitlab/tree_summary_spec.rb'
- - 'spec/lib/gitlab/utils_spec.rb'
- 'spec/lib/gitlab/visibility_level_spec.rb'
- 'spec/lib/gitlab/wiki_pages/front_matter_parser_spec.rb'
- 'spec/lib/gitlab/workhorse_spec.rb'
diff --git a/Gemfile b/Gemfile
index faada712239..d746892802e 100644
--- a/Gemfile
+++ b/Gemfile
@@ -20,6 +20,11 @@ gem 'bootsnap', '~> 1.16.0', require: false
gem 'openssl', '~> 3.0'
gem 'ipaddr', '~> 1.2.5'
+# GitLab Monorepo Gems
+group :monorepo do
+ gem 'gitlab-utils', path: 'gems/gitlab-utils'
+end
+
# Responders respond_to and respond_with
gem 'responders', '~> 3.0'
diff --git a/Gemfile.lock b/Gemfile.lock
index 8844732d35e..395293f17a2 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -5,6 +5,16 @@ PATH
rspec (~> 3.0)
PATH
+ remote: gems/gitlab-utils
+ specs:
+ gitlab-utils (0.1.0)
+ actionview (>= 6.1.7.2)
+ activesupport (>= 6.1.7.2)
+ addressable (~> 2.8)
+ nokogiri (~> 1.15.2)
+ rake (~> 13.0)
+
+PATH
remote: vendor/gems/attr_encrypted
specs:
attr_encrypted (3.2.4)
@@ -1778,6 +1788,7 @@ DEPENDENCIES
gitlab-rspec!
gitlab-sidekiq-fetcher!
gitlab-styles (~> 10.0.0)
+ gitlab-utils!
gitlab_chronic_duration (~> 0.10.6.2)
gitlab_omniauth-ldap (~> 2.2.0)
gitlab_quality-test_tooling (~> 0.8.1)
diff --git a/app/assets/javascripts/behaviors/markdown/render_gfm.js b/app/assets/javascripts/behaviors/markdown/render_gfm.js
index 39a7a76e91f..3b55611a8fa 100644
--- a/app/assets/javascripts/behaviors/markdown/render_gfm.js
+++ b/app/assets/javascripts/behaviors/markdown/render_gfm.js
@@ -9,7 +9,7 @@ import { renderJSONTable } from './render_json_table';
function initPopovers(elements) {
if (!elements.length) return;
- import(/* webpackChunkName: 'IssuablePopoverBundle' */ '~/issuable/popover')
+ import(/* webpackChunkName: 'IssuablePopoverBundle' */ 'ee_else_ce/issuable/popover')
.then(({ default: initIssuablePopovers }) => {
initIssuablePopovers(elements);
})
@@ -39,7 +39,7 @@ export function renderGFM(element) {
'.js-render-mermaid',
'[lang="json"][data-lang-params="table"]',
'.gfm-project_member',
- '.gfm-issue, .gfm-work_item, .gfm-merge_request',
+ '.gfm-issue, .gfm-work_item, .gfm-merge_request, .gfm-epic',
'.js-render-metrics',
'.js-render-observability',
].map((selector) => Array.from(element.querySelectorAll(selector)));
diff --git a/app/assets/javascripts/behaviors/markdown/render_sandboxed_mermaid.js b/app/assets/javascripts/behaviors/markdown/render_sandboxed_mermaid.js
index bd9e41ac0ba..22e9b2b9709 100644
--- a/app/assets/javascripts/behaviors/markdown/render_sandboxed_mermaid.js
+++ b/app/assets/javascripts/behaviors/markdown/render_sandboxed_mermaid.js
@@ -72,11 +72,14 @@ function fixElementSource(el) {
export function getSandboxFrameSrc() {
const path = joinPaths(gon.relative_url_root || '', SANDBOX_FRAME_PATH);
- if (!darkModeEnabled()) {
- return path;
+ let absoluteUrl = relativePathToAbsolute(path, getBaseURL());
+ if (darkModeEnabled()) {
+ absoluteUrl = setUrlParams({ darkMode: darkModeEnabled() }, absoluteUrl);
}
- const absoluteUrl = relativePathToAbsolute(path, getBaseURL());
- return setUrlParams({ darkMode: darkModeEnabled() }, absoluteUrl);
+ if (window.gon?.relative_url_root) {
+ absoluteUrl = setUrlParams({ relativeRootPath: window.gon.relative_url_root }, absoluteUrl);
+ }
+ return absoluteUrl;
}
function renderMermaidEl(el, source) {
diff --git a/app/assets/javascripts/issuable/components/status_box.vue b/app/assets/javascripts/issuable/components/status_box.vue
index 799c0a18444..a83884dd261 100644
--- a/app/assets/javascripts/issuable/components/status_box.vue
+++ b/app/assets/javascripts/issuable/components/status_box.vue
@@ -4,7 +4,13 @@ import Vue from 'vue';
import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import { fetchPolicies } from '~/lib/graphql';
import { __ } from '~/locale';
-import { STATUS_CLOSED, STATUS_OPEN, TYPE_ISSUE, TYPE_MERGE_REQUEST } from '~/issues/constants';
+import {
+ STATUS_CLOSED,
+ STATUS_OPEN,
+ TYPE_ISSUE,
+ TYPE_MERGE_REQUEST,
+ TYPE_EPIC,
+} from '~/issues/constants';
export const badgeState = Vue.observable({
state: '',
@@ -18,17 +24,22 @@ const CLASSES = {
merged: 'issuable-status-badge-merged',
};
-const ISSUE_ICONS = {
- opened: 'issues',
- locked: 'issues',
- closed: 'issue-closed',
-};
-
-const MERGE_REQUEST_ICONS = {
- opened: 'merge-request-open',
- locked: 'merge-request-open',
- closed: 'merge-request-close',
- merged: 'merge',
+const ICONS = {
+ [TYPE_EPIC]: {
+ opened: 'epic',
+ closed: 'epic-closed',
+ },
+ [TYPE_ISSUE]: {
+ opened: 'issues',
+ locked: 'issues',
+ closed: 'issue-closed',
+ },
+ [TYPE_MERGE_REQUEST]: {
+ opened: 'merge-request-open',
+ locked: 'merge-request-open',
+ closed: 'merge-request-close',
+ merged: 'merge',
+ },
};
const STATUS = {
@@ -91,10 +102,8 @@ export default {
return STATUS[this.state];
},
badgeIcon() {
- if (this.issuableType === TYPE_ISSUE) {
- return ISSUE_ICONS[this.state];
- }
- return MERGE_REQUEST_ICONS[this.state];
+ const type = this.issuableType || TYPE_MERGE_REQUEST;
+ return ICONS[type][this.state];
},
},
created() {
diff --git a/app/assets/javascripts/issuable/popover/components/issue_popover.vue b/app/assets/javascripts/issuable/popover/components/issue_popover.vue
index 55fb3958e82..044a1bba7ad 100644
--- a/app/assets/javascripts/issuable/popover/components/issue_popover.vue
+++ b/app/assets/javascripts/issuable/popover/components/issue_popover.vue
@@ -28,7 +28,7 @@ export default {
type: HTMLAnchorElement,
required: true,
},
- projectPath: {
+ namespacePath: {
type: String,
required: true,
},
@@ -65,10 +65,10 @@ export default {
query,
update: (data) => data.project.issue,
variables() {
- const { projectPath, iid } = this;
+ const { namespacePath, iid } = this;
return {
- projectPath,
+ projectPath: namespacePath,
iid,
};
},
@@ -100,7 +100,7 @@ export default {
<!-- eslint-disable @gitlab/vue-require-i18n-strings -->
<div>
<work-item-type-icon v-if="!$apollo.queries.issue.loading" :work-item-type="issue.type" />
- <span class="gl-text-secondary">{{ `${projectPath}#${iid}` }}</span>
+ <span class="gl-text-secondary">{{ `${namespacePath}#${iid}` }}</span>
</div>
<!-- eslint-enable @gitlab/vue-require-i18n-strings -->
diff --git a/app/assets/javascripts/issuable/popover/components/mr_popover.vue b/app/assets/javascripts/issuable/popover/components/mr_popover.vue
index af93430963e..e2c2181684f 100644
--- a/app/assets/javascripts/issuable/popover/components/mr_popover.vue
+++ b/app/assets/javascripts/issuable/popover/components/mr_popover.vue
@@ -19,7 +19,7 @@ export default {
type: HTMLAnchorElement,
required: true,
},
- projectPath: {
+ namespacePath: {
type: String,
required: true,
},
@@ -76,10 +76,10 @@ export default {
query,
update: (data) => data.project.mergeRequest,
variables() {
- const { projectPath, iid } = this;
+ const { namespacePath, iid } = this;
return {
- projectPath,
+ projectPath: namespacePath,
iid,
};
},
@@ -108,7 +108,7 @@ export default {
<h5 v-if="!$apollo.queries.mergeRequest.loading" class="my-2">{{ title }}</h5>
<!-- eslint-disable @gitlab/vue-require-i18n-strings -->
<div class="gl-text-secondary">
- {{ `${projectPath}!${iid}` }}
+ {{ `${namespacePath}!${iid}` }}
</div>
<!-- eslint-enable @gitlab/vue-require-i18n-strings -->
</div>
diff --git a/app/assets/javascripts/issuable/popover/index.js b/app/assets/javascripts/issuable/popover/index.js
index 9430419685b..58f015fe40e 100644
--- a/app/assets/javascripts/issuable/popover/index.js
+++ b/app/assets/javascripts/issuable/popover/index.js
@@ -4,7 +4,7 @@ import createDefaultClient from '~/lib/graphql';
import IssuePopover from './components/issue_popover.vue';
import MRPopover from './components/mr_popover.vue';
-const componentsByReferenceType = {
+export const componentsByReferenceTypeMap = {
issue: IssuePopover,
work_item: IssuePopover,
merge_request: MRPopover,
@@ -26,9 +26,10 @@ const popoverMountedAttr = 'data-popover-mounted';
* Adds a MergeRequestPopover component to the body, hands over as much data as the target element has in data attributes.
* loads based on data-project-path and data-iid more data about an MR from the API and sets it on the popover
*/
-const handleIssuablePopoverMount = ({
+export const handleIssuablePopoverMount = ({
+ componentsByReferenceType = componentsByReferenceTypeMap,
apolloProvider,
- projectPath,
+ namespacePath,
title,
iid,
referenceType,
@@ -42,7 +43,7 @@ const handleIssuablePopoverMount = ({
new PopoverComponent({
propsData: {
target,
- projectPath,
+ namespacePath,
iid,
cachedTitle: title,
},
@@ -53,7 +54,7 @@ const handleIssuablePopoverMount = ({
}, 200); // 200ms delay so not every mouseover triggers Popover + API Call
};
-export default (elements) => {
+export default (elements, issuablePopoverMount = handleIssuablePopoverMount) => {
if (elements.length > 0) {
Vue.use(VueApollo);
@@ -63,15 +64,16 @@ export default (elements) => {
const listenerAddedAttr = 'data-popover-listener-added';
elements.forEach((el) => {
- const { projectPath, iid, referenceType } = el.dataset;
+ const { projectPath, groupPath, iid, referenceType } = el.dataset;
const title = el.dataset.mrTitle || el.title;
+ const namespacePath = groupPath || projectPath;
- if (!el.getAttribute(listenerAddedAttr) && projectPath && title && iid && referenceType) {
+ if (!el.getAttribute(listenerAddedAttr) && namespacePath && title && iid && referenceType) {
el.addEventListener('mouseenter', ({ target }) => {
if (!el.getAttribute(popoverMountedAttr)) {
- handleIssuablePopoverMount({
+ issuablePopoverMount({
apolloProvider,
- projectPath,
+ namespacePath,
title,
iid,
referenceType,
diff --git a/app/assets/javascripts/lib/mermaid.js b/app/assets/javascripts/lib/mermaid.js
index bbc1d8ae1e1..5e62a023777 100644
--- a/app/assets/javascripts/lib/mermaid.js
+++ b/app/assets/javascripts/lib/mermaid.js
@@ -1,6 +1,13 @@
import mermaid from 'mermaid';
import { getParameterByName } from '~/lib/utils/url_utility';
+import { resetServiceWorkersPublicPath } from '~/lib/utils/webpack';
+const resetWebpackPublicPath = () => {
+ window.gon = { relative_url_root: getParameterByName('relativeRootPath') };
+ resetServiceWorkersPublicPath();
+};
+
+resetWebpackPublicPath();
const setIframeRenderedSize = (h, w) => {
const { origin } = window.location;
window.parent.postMessage({ h, w }, origin);
diff --git a/app/assets/javascripts/lib/utils/datetime/date_format_utility.js b/app/assets/javascripts/lib/utils/datetime/date_format_utility.js
index e1a57bf4589..b0264796d90 100644
--- a/app/assets/javascripts/lib/utils/datetime/date_format_utility.js
+++ b/app/assets/javascripts/lib/utils/datetime/date_format_utility.js
@@ -3,6 +3,7 @@ import dateFormat from '~/lib/dateformat';
import { roundToNearestHalf } from '~/lib/utils/common_utils';
import { sanitize } from '~/lib/dompurify';
import { s__, n__, __, sprintf } from '~/locale';
+import { parsePikadayDate } from './pikaday_utility';
/**
* Returns i18n month names array.
@@ -420,3 +421,34 @@ export const formatUtcOffset = (offset) => {
* @returns {String} the UTC timezone with the offset, e.g. `[UTC+2] Berlin, [UTC 0] London`
*/
export const formatTimezone = ({ offset, name }) => `[UTC${formatUtcOffset(offset)}] ${name}`;
+
+/**
+ * Returns humanized string showing date range from provided start and due dates.
+ *
+ * @param {Date} startDate
+ * @param {Date} dueDate
+ * @returns
+ */
+export const humanTimeframe = (startDate, dueDate) => {
+ const start = startDate ? parsePikadayDate(startDate) : null;
+ const due = dueDate ? parsePikadayDate(dueDate) : null;
+
+ if (startDate && dueDate) {
+ const startDateInWords = dateInWords(start, true, start.getFullYear() === due.getFullYear());
+ const dueDateInWords = dateInWords(due, true);
+
+ return sprintf(__('%{startDate} – %{dueDate}'), {
+ startDate: startDateInWords,
+ dueDate: dueDateInWords,
+ });
+ } else if (startDate && !dueDate) {
+ return sprintf(__('%{startDate} – No due date'), {
+ startDate: dateInWords(start, true, false),
+ });
+ } else if (!startDate && dueDate) {
+ return sprintf(__('No start date – %{dueDate}'), {
+ dueDate: dateInWords(due, true, false),
+ });
+ }
+ return '';
+};
diff --git a/app/assets/javascripts/tracking/constants.js b/app/assets/javascripts/tracking/constants.js
index 968e866eedd..0e440750fdb 100644
--- a/app/assets/javascripts/tracking/constants.js
+++ b/app/assets/javascripts/tracking/constants.js
@@ -25,3 +25,7 @@ export const URLS_CACHE_STORAGE_KEY = 'gl-snowplow-pseudonymized-urls';
export const REFERRER_TTL = 24 * 60 * 60 * 1000;
export const GOOGLE_ANALYTICS_ID_COOKIE_NAME = '_ga';
+
+export const GITLAB_INTERNAL_EVENT_CATEGORY = 'InternalEventTracking';
+
+export const SERVICE_PING_SCHEMA = 'iglu:com.gitlab/gitlab_service_ping/jsonschema/1-0-0';
diff --git a/app/assets/javascripts/tracking/index.js b/app/assets/javascripts/tracking/index.js
index 472ce3c5bbf..6494838abac 100644
--- a/app/assets/javascripts/tracking/index.js
+++ b/app/assets/javascripts/tracking/index.js
@@ -2,8 +2,10 @@ import { getAllExperimentContexts } from '~/experimentation/utils';
import { DEFAULT_SNOWPLOW_OPTIONS } from './constants';
import getStandardContext from './get_standard_context';
import Tracking from './tracking';
+import InternalEvents from './internal_events';
export { Tracking as default };
+export { InternalEvents };
/**
* Tracker initialization as defined in:
diff --git a/app/assets/javascripts/tracking/internal_events.js b/app/assets/javascripts/tracking/internal_events.js
new file mode 100644
index 00000000000..a69f192f520
--- /dev/null
+++ b/app/assets/javascripts/tracking/internal_events.js
@@ -0,0 +1,36 @@
+import API from '~/api';
+
+import Tracking from './tracking';
+import { GITLAB_INTERNAL_EVENT_CATEGORY, SERVICE_PING_SCHEMA } from './constants';
+
+const InternalEvents = {
+ /**
+ * Returns an implementation of this class in the form of
+ * a Vue mixin.
+ *
+ * @param {Object} opts - default options for all events
+ * @returns {Object}
+ */
+ mixin(opts = {}) {
+ return {
+ mixins: [Tracking.mixin(opts)],
+ methods: {
+ track_event(event) {
+ API.trackRedisHllUserEvent(event);
+ this.track(event, {
+ context: {
+ schema: SERVICE_PING_SCHEMA,
+ data: {
+ event_name: event,
+ data_source: 'redis_hll',
+ },
+ },
+ category: GITLAB_INTERNAL_EVENT_CATEGORY,
+ });
+ },
+ },
+ };
+ },
+};
+
+export default InternalEvents;
diff --git a/app/controllers/concerns/uploads_actions.rb b/app/controllers/concerns/uploads_actions.rb
index 222fcc17222..29b61264322 100644
--- a/app/controllers/concerns/uploads_actions.rb
+++ b/app/controllers/concerns/uploads_actions.rb
@@ -110,7 +110,7 @@ module UploadsActions
if uploader_mounted?
model.public_send(upload_mount) # rubocop:disable GitlabSecurity/PublicSend
else
- build_uploader_from_upload || build_uploader_from_params
+ build_uploader_from_upload
end
end
strong_memoize_attr :uploader
@@ -125,21 +125,6 @@ module UploadsActions
end
# rubocop: enable CodeReuse/ActiveRecord
- def build_uploader_from_params
- return unless uploader = build_uploader
-
- uploader.retrieve_from_store!(params[:filename])
-
- Gitlab::AppJsonLogger.info(
- message: 'Deprecated usage of build_uploader_from_params',
- uploader_class: uploader.class.name,
- path: params[:filename],
- exists: uploader.exists?
- )
-
- uploader
- end
-
def build_uploader
return unless params[:secret] && params[:filename]
diff --git a/app/models/concerns/project_features_compatibility.rb b/app/models/concerns/project_features_compatibility.rb
index 76c733b1c0b..c70100c03c8 100644
--- a/app/models/concerns/project_features_compatibility.rb
+++ b/app/models/concerns/project_features_compatibility.rb
@@ -4,7 +4,7 @@
#
# After migrating issues_enabled merge_requests_enabled builds_enabled snippets_enabled and wiki_enabled
# fields to a new table "project_features", support for the old fields is still needed in the API.
-require 'gitlab/utils'
+require 'gitlab/utils/all'
module ProjectFeaturesCompatibility
extend ActiveSupport::Concern
diff --git a/app/validators/json_schemas/security_ci_configuration_schemas/sast_ui_schema.json b/app/validators/json_schemas/security_ci_configuration_schemas/sast_ui_schema.json
index fb6b80e0725..9cfb62d4439 100644
--- a/app/validators/json_schemas/security_ci_configuration_schemas/sast_ui_schema.json
+++ b/app/validators/json_schemas/security_ci_configuration_schemas/sast_ui_schema.json
@@ -32,12 +32,12 @@
},
{
"field": "SEARCH_MAX_DEPTH",
- "label": "Search maximum depth",
+ "label": "Search Maximum Depth",
"type": "string",
"default_value": "",
"value": "",
"size": "SMALL",
- "description": "Maximum depth of language and framework detection"
+ "description": "Specifies the number of directory levels to be included in the repository search phase during SAST analysis. SAST scanner searches through the repository to detect the programming languages used and selects the corresponding analyzers. After that, the entire repository is analyzed."
}
],
"analyzers": [
@@ -80,56 +80,72 @@
"label": "Kubesec",
"enabled": true,
"description": "Kubernetes manifests, Helm Charts",
- "variables": []
+ "variables": [
+
+ ]
},
{
"name": "nodejs-scan",
"label": "Node.js Scan",
"enabled": true,
"description": "Node.js",
- "variables": []
+ "variables": [
+
+ ]
},
{
"name": "phpcs-security-audit",
"label": "PHP Security Audit",
"enabled": true,
"description": "PHP",
- "variables": []
+ "variables": [
+
+ ]
},
{
"name": "pmd-apex",
"label": "PMD APEX",
"enabled": true,
"description": "Apex (Salesforce)",
- "variables": []
+ "variables": [
+
+ ]
},
{
"name": "security-code-scan",
"label": "Security Code Scan",
"enabled": true,
"description": ".NET Core, .NET Framework",
- "variables": []
+ "variables": [
+
+ ]
},
{
"name": "semgrep",
"label": "Semgrep",
"enabled": true,
"description": "Multi-language scanning",
- "variables": []
+ "variables": [
+
+ ]
},
{
"name": "sobelow",
"label": "Sobelow",
"enabled": true,
"description": "Elixir (Phoenix)",
- "variables": []
+ "variables": [
+
+ ]
},
{
"name": "spotbugs",
"label": "Spotbugs",
"enabled": true,
"description": "Groovy, Java, Scala",
- "variables": []
+ "variables": [
+
+ ]
}
]
-} \ No newline at end of file
+}
diff --git a/bin/audit-event-type b/bin/audit-event-type
index fec34724c7c..e9d72aaba46 100755
--- a/bin/audit-event-type
+++ b/bin/audit-event-type
@@ -11,9 +11,10 @@ require 'yaml'
require 'fileutils'
require 'uri'
require 'readline'
+require_relative '../config/bundler_setup'
+require 'gitlab/utils/all'
require_relative '../lib/gitlab/audit/type/shared' unless defined?(::Gitlab::Audit::Type::Shared)
-require_relative '../lib/gitlab/utils' unless defined?(::Gitlab::Utils)
module AuditEventTypeHelpers
Abort = Class.new(StandardError)
diff --git a/config/application.rb b/config/application.rb
index 06153b377f3..c8bb56ce956 100644
--- a/config/application.rb
+++ b/config/application.rb
@@ -12,6 +12,8 @@ require 'action_mailer/railtie'
require 'action_cable/engine'
require 'rails/test_unit/railtie'
+require 'gitlab/utils/all'
+
Bundler.require(*Rails.groups)
module Gitlab
@@ -49,7 +51,6 @@ module Gitlab
ActiveSupport.to_time_preserves_timezone = false
require_dependency Rails.root.join('lib/gitlab')
- require_dependency Rails.root.join('lib/gitlab/utils')
require_dependency Rails.root.join('lib/gitlab/action_cable/config')
require_dependency Rails.root.join('lib/gitlab/redis/wrapper')
require_dependency Rails.root.join('lib/gitlab/redis/cache')
diff --git a/config/environments/test.rb b/config/environments/test.rb
index da91752549e..b919df45214 100644
--- a/config/environments/test.rb
+++ b/config/environments/test.rb
@@ -4,7 +4,7 @@ require 'gitlab/testing/request_blocker_middleware'
require 'gitlab/testing/robots_blocker_middleware'
require 'gitlab/testing/request_inspector_middleware'
require 'gitlab/testing/clear_process_memory_cache_middleware'
-require 'gitlab/utils'
+require 'gitlab/utils/all'
Rails.application.configure do
# Make sure the middleware is inserted first in middleware chain
diff --git a/db/docs/subscription_user_add_on_assignments.yml b/db/docs/subscription_user_add_on_assignments.yml
new file mode 100644
index 00000000000..acd9b821115
--- /dev/null
+++ b/db/docs/subscription_user_add_on_assignments.yml
@@ -0,0 +1,10 @@
+---
+table_name: subscription_user_add_on_assignments
+description: Tracks the assignment of an add-on to a user within a namespace
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/123967
+milestone: '16.2'
+feature_categories:
+- seat_cost_management
+classes:
+- GitlabSubscriptions::UserAddOnAssignment
+gitlab_schema: gitlab_main
diff --git a/db/migrate/20230616164309_create_subscription_user_add_on_assignments.rb b/db/migrate/20230616164309_create_subscription_user_add_on_assignments.rb
new file mode 100644
index 00000000000..cb184cd1987
--- /dev/null
+++ b/db/migrate/20230616164309_create_subscription_user_add_on_assignments.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class CreateSubscriptionUserAddOnAssignments < Gitlab::Database::Migration[2.1]
+ UNIQUE_INDEX_NAME = 'uniq_idx_user_add_on_assignments_on_add_on_purchase_and_user'
+
+ def change
+ create_table :subscription_user_add_on_assignments do |t|
+ t.bigint :add_on_purchase_id, null: false
+ t.bigint :user_id, null: false
+
+ t.timestamps_with_timezone null: false
+
+ t.index [:add_on_purchase_id, :user_id], unique: true, name: UNIQUE_INDEX_NAME
+ t.index :user_id
+ end
+ end
+end
diff --git a/db/migrate/20230616164705_add_foreign_key_add_on_purchase_id_on_subscription_user_add_on_assignments.rb b/db/migrate/20230616164705_add_foreign_key_add_on_purchase_id_on_subscription_user_add_on_assignments.rb
new file mode 100644
index 00000000000..d0d89bd5027
--- /dev/null
+++ b/db/migrate/20230616164705_add_foreign_key_add_on_purchase_id_on_subscription_user_add_on_assignments.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+class AddForeignKeyAddOnPurchaseIdOnSubscriptionUserAddOnAssignments < Gitlab::Database::Migration[2.1]
+ disable_ddl_transaction!
+
+ def up
+ add_concurrent_foreign_key :subscription_user_add_on_assignments, :subscription_add_on_purchases,
+ column: :add_on_purchase_id, on_delete: :cascade
+ end
+
+ def down
+ with_lock_retries do
+ remove_foreign_key :subscription_user_add_on_assignments, column: :add_on_purchase_id
+ end
+ end
+end
diff --git a/db/migrate/20230616164731_add_foreign_key_user_id_on_subscription_user_add_on_assignments.rb b/db/migrate/20230616164731_add_foreign_key_user_id_on_subscription_user_add_on_assignments.rb
new file mode 100644
index 00000000000..a28c798deec
--- /dev/null
+++ b/db/migrate/20230616164731_add_foreign_key_user_id_on_subscription_user_add_on_assignments.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class AddForeignKeyUserIdOnSubscriptionUserAddOnAssignments < Gitlab::Database::Migration[2.1]
+ disable_ddl_transaction!
+
+ def up
+ add_concurrent_foreign_key :subscription_user_add_on_assignments, :users, column: :user_id, on_delete: :cascade
+ end
+
+ def down
+ with_lock_retries do
+ remove_foreign_key :subscription_user_add_on_assignments, column: :user_id
+ end
+ end
+end
diff --git a/db/schema_migrations/20230616164309 b/db/schema_migrations/20230616164309
new file mode 100644
index 00000000000..b9fbdc7d33e
--- /dev/null
+++ b/db/schema_migrations/20230616164309
@@ -0,0 +1 @@
+f3b14748f1702972e7f5069edd9ed25d9896dfb11f4fc4a4386ca9c94533e10a \ No newline at end of file
diff --git a/db/schema_migrations/20230616164705 b/db/schema_migrations/20230616164705
new file mode 100644
index 00000000000..1bcb723524b
--- /dev/null
+++ b/db/schema_migrations/20230616164705
@@ -0,0 +1 @@
+75310614bb98a598b8425aa87a0a4a6561fa1b166461d55329c21aff849d71fc \ No newline at end of file
diff --git a/db/schema_migrations/20230616164731 b/db/schema_migrations/20230616164731
new file mode 100644
index 00000000000..2588271d9ac
--- /dev/null
+++ b/db/schema_migrations/20230616164731
@@ -0,0 +1 @@
+e6308ee437b6e57da16e1b8aff1d6a571ef849c4c7cccafe940710c799fa6eea \ No newline at end of file
diff --git a/db/structure.sql b/db/structure.sql
index 35c119628ce..5cff7ab4337 100644
--- a/db/structure.sql
+++ b/db/structure.sql
@@ -23057,6 +23057,23 @@ CREATE SEQUENCE subscription_add_ons_id_seq
ALTER SEQUENCE subscription_add_ons_id_seq OWNED BY subscription_add_ons.id;
+CREATE TABLE subscription_user_add_on_assignments (
+ id bigint NOT NULL,
+ add_on_purchase_id bigint NOT NULL,
+ user_id bigint NOT NULL,
+ created_at timestamp with time zone NOT NULL,
+ updated_at timestamp with time zone NOT NULL
+);
+
+CREATE SEQUENCE subscription_user_add_on_assignments_id_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+ALTER SEQUENCE subscription_user_add_on_assignments_id_seq OWNED BY subscription_user_add_on_assignments.id;
+
CREATE TABLE subscriptions (
id integer NOT NULL,
user_id integer,
@@ -25862,6 +25879,8 @@ ALTER TABLE ONLY subscription_add_on_purchases ALTER COLUMN id SET DEFAULT nextv
ALTER TABLE ONLY subscription_add_ons ALTER COLUMN id SET DEFAULT nextval('subscription_add_ons_id_seq'::regclass);
+ALTER TABLE ONLY subscription_user_add_on_assignments ALTER COLUMN id SET DEFAULT nextval('subscription_user_add_on_assignments_id_seq'::regclass);
+
ALTER TABLE ONLY subscriptions ALTER COLUMN id SET DEFAULT nextval('subscriptions_id_seq'::regclass);
ALTER TABLE ONLY suggestions ALTER COLUMN id SET DEFAULT nextval('suggestions_id_seq'::regclass);
@@ -28351,6 +28370,9 @@ ALTER TABLE ONLY subscription_add_on_purchases
ALTER TABLE ONLY subscription_add_ons
ADD CONSTRAINT subscription_add_ons_pkey PRIMARY KEY (id);
+ALTER TABLE ONLY subscription_user_add_on_assignments
+ ADD CONSTRAINT subscription_user_add_on_assignments_pkey PRIMARY KEY (id);
+
ALTER TABLE ONLY subscriptions
ADD CONSTRAINT subscriptions_pkey PRIMARY KEY (id);
@@ -32910,6 +32932,8 @@ CREATE INDEX index_subscription_add_on_purchases_on_subscription_add_on_id ON su
CREATE UNIQUE INDEX index_subscription_add_ons_on_name ON subscription_add_ons USING btree (name);
+CREATE INDEX index_subscription_user_add_on_assignments_on_user_id ON subscription_user_add_on_assignments USING btree (user_id);
+
CREATE INDEX index_subscriptions_on_project_id ON subscriptions USING btree (project_id);
CREATE UNIQUE INDEX index_subscriptions_on_subscribable_and_user_id_and_project_id ON subscriptions USING btree (subscribable_id, subscribable_type, user_id, project_id);
@@ -33556,6 +33580,8 @@ CREATE UNIQUE INDEX u_project_compliance_standards_adherence_for_reporting ON pr
CREATE UNIQUE INDEX uniq_idx_packages_packages_on_project_id_name_version_ml_model ON packages_packages USING btree (project_id, name, version) WHERE (package_type = 14);
+CREATE UNIQUE INDEX uniq_idx_user_add_on_assignments_on_add_on_purchase_and_user ON subscription_user_add_on_assignments USING btree (add_on_purchase_id, user_id);
+
CREATE UNIQUE INDEX uniq_pkgs_deb_grp_architectures_on_distribution_id_and_name ON packages_debian_group_architectures USING btree (distribution_id, name);
CREATE UNIQUE INDEX uniq_pkgs_deb_grp_components_on_distribution_id_and_name ON packages_debian_group_components USING btree (distribution_id, name);
@@ -35227,6 +35253,9 @@ ALTER TABLE ONLY notification_settings
ALTER TABLE ONLY lists
ADD CONSTRAINT fk_0d3f677137 FOREIGN KEY (board_id) REFERENCES boards(id) ON DELETE CASCADE;
+ALTER TABLE ONLY subscription_user_add_on_assignments
+ ADD CONSTRAINT fk_0d89020c49 FOREIGN KEY (add_on_purchase_id) REFERENCES subscription_add_on_purchases(id) ON DELETE CASCADE;
+
ALTER TABLE ONLY deployment_approvals
ADD CONSTRAINT fk_0f58311058 FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
@@ -35596,6 +35625,9 @@ ALTER TABLE ONLY integrations
ALTER TABLE ONLY user_interacted_projects
ADD CONSTRAINT fk_722ceba4f7 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
+ALTER TABLE ONLY subscription_user_add_on_assignments
+ ADD CONSTRAINT fk_724c2df9a8 FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
+
ALTER TABLE ONLY vulnerabilities
ADD CONSTRAINT fk_725465b774 FOREIGN KEY (dismissed_by_id) REFERENCES users(id) ON DELETE SET NULL;
diff --git a/doc/administration/instance_limits.md b/doc/administration/instance_limits.md
index df364a3f737..7a24db4347b 100644
--- a/doc/administration/instance_limits.md
+++ b/doc/administration/instance_limits.md
@@ -19,8 +19,6 @@ Read more about [configuring rate limits](../security/rate_limits.md).
### Issue creation
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/28129) in GitLab 12.10.
-
This setting limits the request rate to the issue creation endpoint.
Read more about [issue creation rate limits](../user/admin_area/settings/rate_limit_on_issues_creation.md).
@@ -37,8 +35,6 @@ Read more about [User and IP rate limits](../user/admin_area/settings/user_and_i
### By raw endpoint
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/30829) in GitLab 12.2.
-
This setting limits the request rate per endpoint.
Read more about [raw endpoint rate limits](../user/admin_area/settings/rate_limits_on_raw_endpoints.md).
@@ -69,8 +65,6 @@ Read more about [protected path rate limits](../user/admin_area/settings/protect
### Package Registry
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/57029) in GitLab 13.12.
-
This setting limits the request rate on the Packages API per user or IP. For more information, see
[Package Registry Rate Limits](../user/admin_area/settings/package_registry_rate_limits.md).
@@ -107,18 +101,16 @@ This setting limits the request rate on deprecated API endpoints per user or IP
### Import/Export
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/35728) in GitLab 13.2.
-
This setting limits the import/export actions for groups and projects.
| Limit | Default (per minute per user) |
|-------------------------|-------------------------------|
-| Project Import | 6 |
-| Project Export | 6 |
-| Project Export Download | 1 |
-| Group Import | 6 |
-| Group Export | 6 |
-| Group Export Download | 1 |
+| Project Import | 6 |
+| Project Export | 6 |
+| Project Export Download | 1 |
+| Group Import | 6 |
+| Group Export | 6 |
+| Group Export Download | 1 |
Read more about [import/export rate limits](../user/admin_area/settings/import_export_rate_limits.md).
@@ -162,10 +154,10 @@ Set the limit to `0` to disable it.
This setting limits search requests as follows:
-| Limit | Default (requests per minute) |
-|-------------------------|-------------------------------|
-| Authenticated user | 300 |
-| Unauthenticated user | 100 |
+| Limit | Default (requests per minute) |
+|----------------------|-------------------------------|
+| Authenticated user | 300 |
+| Unauthenticated user | 100 |
Search requests that exceed the search rate limit per minute return the following error:
@@ -191,8 +183,6 @@ Read more about [Gitaly concurrency limits](gitaly/configure_gitaly.md#limit-rpc
## Number of comments per issue, merge request, or commit
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/22388) in GitLab 12.4.
-
There's a limit to the number of comments that can be submitted on an issue,
merge request, or commit. When the limit is reached, system notes can still be
added so that the history of events is not lost, but the user-submitted
@@ -202,8 +192,6 @@ comment fails.
## Size of comments and descriptions of issues, merge requests, and epics
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/61974) in GitLab 12.2.
-
There is a limit to the size of comments and descriptions of issues, merge requests, and epics.
Attempting to add a body of text larger than the limit, results in an error, and the
item is also not created.
@@ -214,8 +202,6 @@ It's possible that this limit changes to a lower number in the future.
## Size of commit titles and descriptions
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/292039) in GitLab 13.9.
-
Commits with arbitrarily large messages may be pushed to GitLab, but the following
display limits apply:
@@ -231,9 +217,6 @@ are processed.
## Number of issues in the milestone overview
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/39453) in GitLab 12.10.
-> - [Set](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/58168) to 500 in GitLab 13.11.
-
The maximum number of issues loaded on the milestone overview page is 500.
When the number exceeds the limit the page displays an alert and links to a paginated
[issue list](../user/project/issues/managing_issues.md) of all issues in the milestone.
@@ -242,8 +225,6 @@ When the number exceeds the limit the page displays an alert and links to a pagi
## Number of pipelines per Git push
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/51401) in GitLab 11.10.
-
When pushing multiple changes with a single Git push, like multiple tags or branches,
only four tag or branch pipelines can be triggered. This limit prevents the accidental
creation of a large number of pipelines when using `git push --all` or `git push --mirror`.
@@ -259,12 +240,10 @@ instance if too many changes are pushed at once and a flood of pipelines are cre
## Retention of activity history
-Activity history for projects and individuals' profiles was limited to one year until [GitLab 11.4](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/52246) when it was extended to two years, and in [GitLab 12.4](https://gitlab.com/gitlab-org/gitlab/-/issues/33840) to three years.
+Activity history for projects and individuals' profiles is limited to three years.
## Number of embedded metrics
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/14939) in GitLab 12.7.
-
There is a limit when embedding metrics in GitLab Flavored Markdown (GLFM) for performance reasons.
- **Max limit**: 100 embeds.
@@ -343,8 +322,6 @@ Blocked recursive webhook calls are logged in `auth.log` with the message `"Recu
## Pull Mirroring Interval
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/237891) in GitLab 13.7.
-
The [minimum wait time between pull refreshes](../user/project/repository/mirror/index.md)
defaults to 300 seconds (5 minutes). For example, a pull refresh only runs once in a given 300 second period, regardless of how many times you trigger it.
@@ -362,8 +339,6 @@ Plan.default.actual_limits.update!(pull_mirror_interval_seconds: 200)
## Incoming emails from auto-responders
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/30327) in GitLab 12.4.
-
GitLab ignores all incoming emails sent from auto-responders by looking for the `X-Autoreply`
header. Such emails don't create comments on issues or merge requests.
@@ -376,8 +351,6 @@ and to limit memory consumption.
## Max offset allowed by the REST API for offset-based pagination
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/34565) in GitLab 13.0.
-
When using offset-based pagination in the REST API, there is a limit to the maximum
requested offset into the set of results. This limit is only applied to endpoints that
also support keyset-based pagination. More information about pagination options can be
@@ -401,8 +374,6 @@ Set the limit to `0` to disable it.
### Number of jobs in active pipelines
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/32823) in GitLab 12.6.
-
The total number of jobs in active pipelines can be limited per project. This limit is checked
each time a new pipeline is created. An active pipeline is any pipeline in one of the following states:
@@ -433,8 +404,6 @@ Set the limit to `0` to disable it.
### Maximum time jobs can run
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/16777) in GitLab 12.3.
-
The default maximum time that jobs can run for is 60 minutes. Jobs that run for
more than 60 minutes time out.
@@ -447,8 +416,6 @@ You can change the maximum time a job can run before it times out:
### Maximum number of deployment jobs in a pipeline
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/46931) in GitLab 13.7.
-
You can limit the maximum number of deployment jobs in a pipeline. A deployment is
any job with an [`environment`](../ci/environments/index.md) specified. The number
of deployments in a pipeline is checked at pipeline creation. Pipelines that have
@@ -470,8 +437,6 @@ Set the limit to `0` to disable it.
### Number of CI/CD subscriptions to a project
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/9045) in GitLab 12.9.
-
The total number of subscriptions can be limited per project. This limit is
checked each time a new subscription is created.
@@ -516,8 +481,6 @@ This limit is [enabled on GitLab.com](../user/gitlab_com/index.md#gitlab-cicd).
### Number of pipeline schedules
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/29566) in GitLab 12.10.
-
The total number of pipeline schedules can be limited per project. This limit is
checked each time a new pipeline schedule is created. If a new pipeline schedule
would cause the total number of pipeline schedules to exceed the limit, the
@@ -585,8 +548,6 @@ This limit is [enabled on GitLab.com](../user/gitlab_com/index.md#gitlab-cicd).
### Number of instance level variables
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/216097) in GitLab 13.1.
-
The total number of instance level CI/CD variables is limited at the instance level.
This limit is checked each time a new instance level variable is created. If a new variable
would cause the total number of variables to exceed the limit, the new variable is not created.
@@ -639,8 +600,6 @@ Plan.default.actual_limits.update!(project_ci_variables: 10000)
### Maximum file size per type of artifact
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/37226) in GitLab 13.3.
-
Job artifacts defined with [`artifacts:reports`](../ci/yaml/index.md#artifactsreports)
that are uploaded by the runner are rejected if the file size exceeds the maximum
file size limit. The limit is determined by comparing the project's
@@ -655,35 +614,35 @@ setting is used:
| Artifact limit name | Default value |
|---------------------------------------------|---------------|
-| `ci_max_artifact_size_accessibility` | 0 |
-| `ci_max_artifact_size_api_fuzzing` | 0 |
-| `ci_max_artifact_size_archive` | 0 |
-| `ci_max_artifact_size_browser_performance` | 0 |
-| `ci_max_artifact_size_cluster_applications` | 0 |
-| `ci_max_artifact_size_cobertura` | 0 |
-| `ci_max_artifact_size_codequality` | 0 |
-| `ci_max_artifact_size_container_scanning` | 0 |
-| `ci_max_artifact_size_coverage_fuzzing` | 0 |
-| `ci_max_artifact_size_dast` | 0 |
-| `ci_max_artifact_size_dependency_scanning` | 0 |
-| `ci_max_artifact_size_dotenv` | 0 |
-| `ci_max_artifact_size_junit` | 0 |
-| `ci_max_artifact_size_license_management` | 0 |
-| `ci_max_artifact_size_license_scanning` | 0 |
-| `ci_max_artifact_size_load_performance` | 0 |
-| `ci_max_artifact_size_lsif` | 100 MB ([Introduced at 20 MB](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/37226) in GitLab 13.3 and [raised to 100 MB](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/46980) in GitLab 13.6.) |
-| `ci_max_artifact_size_metadata` | 0 |
-| `ci_max_artifact_size_metrics_referee` | 0 |
-| `ci_max_artifact_size_metrics` | 0 |
-| `ci_max_artifact_size_network_referee` | 0 |
-| `ci_max_artifact_size_performance` | 0 |
-| `ci_max_artifact_size_requirements` | 0 |
-| `ci_max_artifact_size_requirements_v2` | 0 |
-| `ci_max_artifact_size_sast` | 0 |
-| `ci_max_artifact_size_secret_detection` | 0 |
-| `ci_max_artifact_size_terraform` | 5 MB ([introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/37018) in GitLab 13.3) |
-| `ci_max_artifact_size_trace` | 0 |
-| `ci_max_artifact_size_cyclonedx` | 1 MB |
+| `ci_max_artifact_size_accessibility` | 0 |
+| `ci_max_artifact_size_api_fuzzing` | 0 |
+| `ci_max_artifact_size_archive` | 0 |
+| `ci_max_artifact_size_browser_performance` | 0 |
+| `ci_max_artifact_size_cluster_applications` | 0 |
+| `ci_max_artifact_size_cobertura` | 0 |
+| `ci_max_artifact_size_codequality` | 0 |
+| `ci_max_artifact_size_container_scanning` | 0 |
+| `ci_max_artifact_size_coverage_fuzzing` | 0 |
+| `ci_max_artifact_size_dast` | 0 |
+| `ci_max_artifact_size_dependency_scanning` | 0 |
+| `ci_max_artifact_size_dotenv` | 0 |
+| `ci_max_artifact_size_junit` | 0 |
+| `ci_max_artifact_size_license_management` | 0 |
+| `ci_max_artifact_size_license_scanning` | 0 |
+| `ci_max_artifact_size_load_performance` | 0 |
+| `ci_max_artifact_size_lsif` | 100 MB |
+| `ci_max_artifact_size_metadata` | 0 |
+| `ci_max_artifact_size_metrics_referee` | 0 |
+| `ci_max_artifact_size_metrics` | 0 |
+| `ci_max_artifact_size_network_referee` | 0 |
+| `ci_max_artifact_size_performance` | 0 |
+| `ci_max_artifact_size_requirements` | 0 |
+| `ci_max_artifact_size_requirements_v2` | 0 |
+| `ci_max_artifact_size_sast` | 0 |
+| `ci_max_artifact_size_secret_detection` | 0 |
+| `ci_max_artifact_size_terraform` | 5 MB |
+| `ci_max_artifact_size_trace` | 0 |
+| `ci_max_artifact_size_cyclonedx` | 1 MB |
For example, to set the `ci_max_artifact_size_junit` limit to 10 MB on a self-managed
installation, run the following in the [GitLab Rails console](operations/rails_console.md#starting-a-rails-console-session):
@@ -732,10 +691,10 @@ GitLab SaaS subscribers have different limits defined per plan, affecting all pr
Self-managed GitLab Premium and Ultimate limits are defined by a default plan that affects all projects:
-| Runner scope | Default value |
-|---------------------------------------------|---------------|
-| `ci_registered_group_runners` | 1000 |
-| `ci_registered_project_runners` | 1000 |
+| Runner scope | Default value |
+|---------------------------------|---------------|
+| `ci_registered_group_runners` | 1000 |
+| `ci_registered_project_runners` | 1000 |
To update these limits, run the following in the
[GitLab Rails console](operations/rails_console.md#starting-a-rails-console-session):
@@ -839,28 +798,20 @@ Plan.default.actual_limits.update!(dotenv_size: 5.kilobytes)
### Limit inbound incident management alerts
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/17859) in GitLab 12.5.
-
This setting limits the number of inbound alert payloads over a period of time.
Read more about [incident management rate limits](../user/admin_area/settings/rate_limit_on_pipelines_creation.md).
### Prometheus Alert JSON payloads
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/19940) in GitLab 12.6.
-
Prometheus alert payloads sent to the `notify.json` endpoint are limited to 1 MB in size.
### Generic Alert JSON payloads
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/16441) in GitLab 12.4.
-
Alert payloads sent to the `notify.json` endpoint are limited to 1 MB in size.
### Metrics dashboard YAML files
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/34834) in GitLab 13.2.
-
The memory occupied by a parsed metrics dashboard YAML file cannot exceed 1 MB.
The maximum depth of each YAML file is limited to 100. The maximum depth of a YAML
@@ -891,8 +842,6 @@ panel_groups:
## Environment Dashboard limits **(PREMIUM)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/33895) in GitLab 13.4.
-
See [Environment Dashboard](../ci/environments/environments_dashboard.md#adding-a-project-to-the-dashboard) for the maximum number of displayed projects.
## Environment data on deploy boards
@@ -932,8 +881,6 @@ Reports that go over the 20 MB limit aren't loaded. Affected reports:
### Maximum file size indexed
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/8638) in GitLab 13.3.
-
You can set a limit on the content of repository files that are indexed in
Elasticsearch. Any files larger than this limit only index the filename.
The file content is neither indexed nor searchable.
@@ -949,8 +896,6 @@ is pre-allocated during indexing.
### Maximum field length
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/201826) in GitLab 12.8.
-
You can set a limit on the content of text fields indexed for advanced search.
Setting a maximum helps to reduce the load of the indexing processes. If any
text field exceeds this limit, then the text is truncated to this number of
@@ -987,8 +932,6 @@ The maximum allowed [push size](../user/admin_area/settings/account_and_limit_se
### Webhooks and Project Services
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/31009) in GitLab 12.4.
-
Total number of changes (branches or tags) in a single push. If changes are more
than the specified limit, hooks are not executed.
@@ -999,8 +942,6 @@ More information can be found in these documentations:
### Activities
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/31007) in GitLab 12.4.
-
Total number of changes (branches or tags) in a single push to determine whether
individual push events or a bulk push event are created.
@@ -1010,8 +951,6 @@ More information can be found in the [Push event activities limit and bulk push
### File Size Limits
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/218017) in GitLab 13.4.
-
The default maximum file size for a package that's uploaded to the [GitLab Package Registry](../user/packages/package_registry/index.md) varies by format:
- Conan: 3 GB
@@ -1074,14 +1013,6 @@ varies by file type:
- Image blob: 5 GB
- Image manifest: 10 MB
-## Branch retargeting on merge
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/320902) in GitLab 13.9.
-
-If a branch is merged while open merge requests still point to it, GitLab can
-retarget merge requests pointing to the now-merged branch. For more information, see
-[Update merge requests when target branch merges](../user/project/merge_requests/index.md#update-merge-requests-when-target-branch-merges).
-
## Maximum number of assignees and reviewers
> - Maximum assignees [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/368936) in GitLab 15.6.
diff --git a/doc/ci/runners/saas/macos_saas_runner.md b/doc/ci/runners/saas/macos_saas_runner.md
index 836a14d7521..a559fc7d53e 100644
--- a/doc/ci/runners/saas/macos_saas_runner.md
+++ b/doc/ci/runners/saas/macos_saas_runner.md
@@ -45,7 +45,7 @@ Each image runs a specific version of macOS and Xcode.
| (none, awaiting macOS 13) | `beta` |
NOTE:
-Each time you run a job that requires tooling or dependencies not available in the base image, those items must be added to the newly provisioned build VM increasing the total job duration.
+If your job requires tooling or dependencies not available in our available images, those can only be installed in the job execution.
## Image update policy
@@ -88,9 +88,6 @@ test:
- echo "running scripts in the test job"
```
-NOTE:
-You can specify a different Xcode image to run a job. To do so, replace the value for the `image` keyword with the value of the [virtual machine image name](#supported-macos-images) from the list of available images. The default value is our latest image.
-
## Code signing iOS Projects with fastlane
Before you can integrate GitLab with Apple services, install to a device, or deploy to the Apple App Store, you must [code sign](https://developer.apple.com/support/code-signing/) your application.
@@ -106,22 +103,22 @@ Related topics:
- [Code Signing Best Practice Guide](https://codesigning.guide/)
- [fastlane authentication with Apple Services guide](https://docs.fastlane.tools/getting-started/ios/authentication/)
-## Known Limitations and Usage Constraints
-
-- If the VM image does not include the specific software version you need for your job, then the job execution time will increase as the required software needs to be fetched and installed.
-- At this time, it is not possible to bring your own OS image.
-- The keychain for user `gitlab` is not publicly available. You must create a keychain instead.
-
## Optimizing Homebrew
By default, Homebrew checks for updates at the start of any operation. Homebrew has a
-release cycle that may be more frequent than the GitLab MacOS image release cycle. This
+release cycle that may be more frequent than the GitLab macOS image release cycle. This
difference in release cycles may cause steps that call `brew` to take extra time to complete
while Homebrew makes updates.
-To reduce build time due to unintended Homebrew updates, set the `HOMEBREW_NO_AUTO_UPDATE` variable in `.gitlab-ci.yml` :
+To reduce build time due to unintended Homebrew updates, set the `HOMEBREW_NO_AUTO_UPDATE` variable in `.gitlab-ci.yml`:
```yaml
variables:
HOMEBREW_NO_AUTO_UPDATE: 1
```
+
+## Known issues and usage constraints
+
+- If the VM image does not include the specific software version you need for your job, the required software must be fetched and installed. This causes an increase in job execution time.
+- It is not possible to bring your own OS image.
+- The keychain for user `gitlab` is not publicly available. You must create a keychain instead.
diff --git a/doc/development/gems.md b/doc/development/gems.md
index 4d364242efd..55963438347 100644
--- a/doc/development/gems.md
+++ b/doc/development/gems.md
@@ -107,7 +107,7 @@ You can see example adding new Gem: [!121676](https://gitlab.com/gitlab-org/gitl
rspec:
image: "ruby:${RUBY_VERSION}"
cache:
- key: gitlab-<name-of-gem>
+ key: gitlab-<name-of-gem>-${RUBY_VERSION}
paths:
- gitlab-<name-of-gem>/vendor/ruby
before_script:
diff --git a/doc/development/pipelines/index.md b/doc/development/pipelines/index.md
index cadba17f03e..9e6abaa8eb3 100644
--- a/doc/development/pipelines/index.md
+++ b/doc/development/pipelines/index.md
@@ -755,10 +755,14 @@ graph RL;
click 2_5-1 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations"
2_5-1 --> 1-3 & 1-6 & 1-14 & 1-15;
- 3_2-1["rspec:coverage (5 minutes)"];
+ ac-1["rspec:artifact-collector (2 minutes)<br/>(workaround for 'needs' limitation)"];
+ class ac-1 criticalPath;
+ ac-1 --> 2_5-1;
+
+ 3_2-1["rspec:coverage (3 minutes)"];
class 3_2-1 criticalPath;
click 3_2-1 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=7248745&udv=0"
- 3_2-1 -.->|"(don't use needs<br/>because of limitations)"| 2_5-1;
+ 3_2-1 --> ac-1;
4_3-1["rspec:undercoverage (1.3 minutes)"];
class 4_3-1 criticalPath;
diff --git a/doc/integration/advanced_search/elasticsearch_troubleshooting.md b/doc/integration/advanced_search/elasticsearch_troubleshooting.md
index e8eace7bd16..d3a065f1f99 100644
--- a/doc/integration/advanced_search/elasticsearch_troubleshooting.md
+++ b/doc/integration/advanced_search/elasticsearch_troubleshooting.md
@@ -256,6 +256,24 @@ Bulk requests getting rejected by the Elasticsearch nodes are likely due to load
Ensure that your Elasticsearch cluster meets the [system requirements](elasticsearch.md#system-requirements) and has enough resources
to perform bulk operations. See also the error ["429 (Too Many Requests)"](#indexing-fails-with-error-elastic-error-429-too-many-requests).
+### Indexing fails with `strict_dynamic_mapping_exception`
+
+Indexing might fail if all [advanced search migrations were not finished before doing a major upgrade](elasticsearch.md#all-migrations-must-be-finished-before-doing-a-major-upgrade).
+A large Sidekiq backlog might accompany this error. To fix the indexing failures, you must re-index the database, repositories, and wikis.
+
+1. Pause indexing so Sidekiq can catch up:
+
+ ```shell
+ sudo gitlab-rake gitlab:elastic:pause_indexing
+ ```
+
+1. [Recreate the index from scratch](#last-resort-to-recreate-an-index).
+1. Resume indexing:
+
+ ```shell
+ sudo gitlab-rake gitlab:elastic:resume_indexing
+ ```
+
### Last resort to recreate an index
There may be cases where somehow data never got indexed and it's not in the
diff --git a/doc/user/permissions.md b/doc/user/permissions.md
index 0b02de59ab4..c3a3c4f6d3c 100644
--- a/doc/user/permissions.md
+++ b/doc/user/permissions.md
@@ -58,11 +58,11 @@ The following table lists project permissions available for each role:
| Action | Guest | Reporter | Developer | Maintainer | Owner |
|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------|----------|-----------|------------|----------|
| [Analytics](analytics/index.md):<br>View [issue analytics](analytics/issue_analytics.md) | ✓ | ✓ | ✓ | ✓ | ✓ |
-| [Analytics](analytics/index.md):<br>View [merge request analytics](analytics/merge_request_analytics.md) | ✓ | ✓ | ✓ | ✓ | ✓ |
| [Analytics](analytics/index.md):<br>View [value stream analytics](group/value_stream_analytics/index.md) | ✓ | ✓ | ✓ | ✓ | ✓ |
| [Analytics](analytics/index.md):<br>View [DORA metrics](analytics/ci_cd_analytics.md) | | ✓ | ✓ | ✓ | ✓ |
| [Analytics](analytics/index.md):<br>View [CI/CD analytics](analytics/ci_cd_analytics.md) | | ✓ | ✓ | ✓ | ✓ |
| [Analytics](analytics/index.md):<br>View [code review analytics](analytics/code_review_analytics.md) | | ✓ | ✓ | ✓ | ✓ |
+| [Analytics](analytics/index.md):<br>View [merge request analytics](analytics/merge_request_analytics.md) | | ✓ | ✓ | ✓ | ✓ |
| [Analytics](analytics/index.md):<br>View [repository analytics](analytics/repository_analytics.md) | | ✓ | ✓ | ✓ | ✓ |
| [Application security](application_security/index.md):<br>View licenses in [dependency list](application_security/dependency_list/index.md) | | | ✓ | ✓ | ✓ |
| [Application security](application_security/index.md):<br>Create and run [on-demand DAST scans](application_security/dast/proxy-based.md#on-demand-scans) | | | ✓ | ✓ | ✓ |
diff --git a/gems/gitlab-rspec/.gitlab-ci.yml b/gems/gitlab-rspec/.gitlab-ci.yml
index 0932753d1e7..95bdc51cb7d 100644
--- a/gems/gitlab-rspec/.gitlab-ci.yml
+++ b/gems/gitlab-rspec/.gitlab-ci.yml
@@ -12,7 +12,7 @@ workflow:
rspec:
image: "ruby:${RUBY_VERSION}"
cache:
- key: gitlab-rspec
+ key: gitlab-rspec-${RUBY_VERSION}
paths:
- gitlab-rspec/vendor/ruby
before_script:
diff --git a/gems/gitlab-rspec/gitlab-rspec.gemspec b/gems/gitlab-rspec/gitlab-rspec.gemspec
index 061647190ec..f9cc83bb497 100644
--- a/gems/gitlab-rspec/gitlab-rspec.gemspec
+++ b/gems/gitlab-rspec/gitlab-rspec.gemspec
@@ -12,7 +12,7 @@ Gem::Specification.new do |spec|
spec.description = "A set of useful helpers to configure RSpec with various stubs and CI configs."
spec.homepage = "https://gitlab.com/gitlab-org/gitlab/-/tree/master/gems/gitlab-rspec"
spec.license = "MIT"
- spec.required_ruby_version = ">= 3.0"
+ spec.required_ruby_version = ">= 2.7"
spec.files = Dir['lib/**/*.rb']
spec.test_files = Dir['spec/**/*']
diff --git a/gems/gitlab-utils/.gitignore b/gems/gitlab-utils/.gitignore
new file mode 100644
index 00000000000..b04a8c840df
--- /dev/null
+++ b/gems/gitlab-utils/.gitignore
@@ -0,0 +1,11 @@
+/.bundle/
+/.yardoc
+/_yardoc/
+/coverage/
+/doc/
+/pkg/
+/spec/reports/
+/tmp/
+
+# rspec failure tracking
+.rspec_status
diff --git a/gems/gitlab-utils/.gitlab-ci.yml b/gems/gitlab-utils/.gitlab-ci.yml
new file mode 100644
index 00000000000..ab92953b57d
--- /dev/null
+++ b/gems/gitlab-utils/.gitlab-ci.yml
@@ -0,0 +1,30 @@
+# You can override the included template(s) by including variable overrides
+# SAST customization: https://docs.gitlab.com/ee/user/application_security/sast/#customizing-the-sast-settings
+# Secret Detection customization: https://docs.gitlab.com/ee/user/application_security/secret_detection/#customizing-settings
+# Dependency Scanning customization: https://docs.gitlab.com/ee/user/application_security/dependency_scanning/#customizing-the-dependency-scanning-settings
+# Note that environment variables can be set in several places
+# See https://docs.gitlab.com/ee/ci/variables/#cicd-variable-precedence
+workflow:
+ rules:
+ - if: $CI_MERGE_REQUEST_ID
+
+rspec:
+ image: "ruby:${RUBY_VERSION}"
+ cache:
+ key: gitlab-utils-${RUBY_VERSION}
+ paths:
+ - gitlab-utils/vendor/ruby
+ before_script:
+ - cd gems/gitlab-utils
+ - ruby -v # Print out ruby version for debugging
+ - gem install bundler --no-document # Bundler is not installed with the image
+ - bundle config set --local path 'vendor' # Install dependencies into ./vendor/ruby
+ - bundle config set with 'development'
+ - bundle config set --local frozen 'true' # Disallow Gemfile.lock changes on CI
+ - bundle config # Show bundler configuration
+ - bundle install -j $(nproc)
+ script:
+ - bundle exec rspec
+ parallel:
+ matrix:
+ - RUBY_VERSION: ["2.7", "3.0", "3.1", "3.2"]
diff --git a/gems/gitlab-utils/.rspec b/gems/gitlab-utils/.rspec
new file mode 100644
index 00000000000..34c5164d9b5
--- /dev/null
+++ b/gems/gitlab-utils/.rspec
@@ -0,0 +1,3 @@
+--format documentation
+--color
+--require spec_helper
diff --git a/gems/gitlab-utils/.rubocop.yml b/gems/gitlab-utils/.rubocop.yml
new file mode 100644
index 00000000000..7f0d48d1b2b
--- /dev/null
+++ b/gems/gitlab-utils/.rubocop.yml
@@ -0,0 +1,31 @@
+inherit_from:
+ - ../../.rubocop.yml
+
+CodeReuse/ActiveRecord:
+ Enabled: false
+
+Gitlab/DocUrl:
+ Enabled: false
+
+Gitlab/NamespacedClass:
+ Enabled: false
+
+AllCops:
+ TargetRubyVersion: 3.0
+
+Naming/FileName:
+ Exclude:
+ - spec/**/*.rb
+ - lib/gitlab/utils/all.rb
+
+Lint/AmbiguousRegexpLiteral:
+ Exclude:
+ - spec/**/*.rb
+
+RSpec/InstanceVariable:
+ Exclude:
+ - spec/**/*.rb
+
+Lint/BinaryOperatorWithIdenticalOperands:
+ Exclude:
+ - spec/**/*.rb
diff --git a/gems/gitlab-utils/Gemfile b/gems/gitlab-utils/Gemfile
new file mode 100644
index 00000000000..2c7228c874c
--- /dev/null
+++ b/gems/gitlab-utils/Gemfile
@@ -0,0 +1,10 @@
+# frozen_string_literal: true
+
+source "https://rubygems.org"
+
+# Specify your gem's dependencies in gitlab-utils.gemspec
+gemspec
+
+group :development, :test do
+ gem 'gitlab-rspec', path: '../gitlab-rspec'
+end
diff --git a/gems/gitlab-utils/Gemfile.lock b/gems/gitlab-utils/Gemfile.lock
new file mode 100644
index 00000000000..e7f954eeea3
--- /dev/null
+++ b/gems/gitlab-utils/Gemfile.lock
@@ -0,0 +1,193 @@
+PATH
+ remote: ../gitlab-rspec
+ specs:
+ gitlab-rspec (0.1.0)
+ rspec (~> 3.0)
+
+PATH
+ remote: .
+ specs:
+ gitlab-utils (0.1.0)
+ actionview (>= 6.1.7.2)
+ activesupport (>= 6.1.7.2)
+ addressable (~> 2.8)
+ nokogiri (~> 1.15.2)
+ rake (~> 13.0)
+
+GEM
+ remote: https://rubygems.org/
+ specs:
+ actionpack (7.0.5)
+ actionview (= 7.0.5)
+ activesupport (= 7.0.5)
+ rack (~> 2.0, >= 2.2.4)
+ rack-test (>= 0.6.3)
+ rails-dom-testing (~> 2.0)
+ rails-html-sanitizer (~> 1.0, >= 1.2.0)
+ actionview (7.0.5)
+ activesupport (= 7.0.5)
+ builder (~> 3.1)
+ erubi (~> 1.4)
+ rails-dom-testing (~> 2.0)
+ rails-html-sanitizer (~> 1.1, >= 1.2.0)
+ activesupport (7.0.5)
+ concurrent-ruby (~> 1.0, >= 1.0.2)
+ i18n (>= 1.6, < 2)
+ minitest (>= 5.1)
+ tzinfo (~> 2.0)
+ addressable (2.8.1)
+ public_suffix (>= 2.0.2, < 6.0)
+ ast (2.4.2)
+ benchmark-malloc (0.2.0)
+ benchmark-perf (0.6.0)
+ benchmark-trend (0.4.0)
+ binding_of_caller (1.0.0)
+ debug_inspector (>= 0.0.1)
+ builder (3.2.4)
+ coderay (1.1.3)
+ concurrent-ruby (1.2.2)
+ crass (1.0.6)
+ debug_inspector (1.1.0)
+ diff-lcs (1.5.0)
+ erubi (1.12.0)
+ factory_bot (6.2.1)
+ activesupport (>= 5.0.0)
+ factory_bot_rails (6.2.0)
+ factory_bot (~> 6.2.0)
+ railties (>= 5.0.0)
+ gitlab-styles (10.0.0)
+ rubocop (~> 1.43.0)
+ rubocop-graphql (~> 0.18)
+ rubocop-performance (~> 1.15)
+ rubocop-rails (~> 2.17)
+ rubocop-rspec (~> 2.18)
+ i18n (1.14.1)
+ concurrent-ruby (~> 1.0)
+ json (2.6.3)
+ loofah (2.21.3)
+ crass (~> 1.0.2)
+ nokogiri (>= 1.12.0)
+ method_source (1.0.0)
+ mini_portile2 (2.8.2)
+ minitest (5.18.1)
+ nokogiri (1.15.2)
+ mini_portile2 (~> 2.8.2)
+ racc (~> 1.4)
+ parallel (1.22.1)
+ parser (3.2.0.0)
+ ast (~> 2.4.1)
+ proc_to_ast (0.1.0)
+ coderay
+ parser
+ unparser
+ public_suffix (5.0.0)
+ racc (1.7.1)
+ rack (2.2.7)
+ rack-test (2.1.0)
+ rack (>= 1.3)
+ rails-dom-testing (2.0.3)
+ activesupport (>= 4.2.0)
+ nokogiri (>= 1.6)
+ rails-html-sanitizer (1.6.0)
+ loofah (~> 2.21)
+ nokogiri (~> 1.14)
+ railties (7.0.5)
+ actionpack (= 7.0.5)
+ activesupport (= 7.0.5)
+ method_source
+ rake (>= 12.2)
+ thor (~> 1.0)
+ zeitwerk (~> 2.5)
+ rainbow (3.1.1)
+ rake (13.0.6)
+ regexp_parser (2.6.0)
+ rexml (3.2.5)
+ rspec (3.12.0)
+ rspec-core (~> 3.12.0)
+ rspec-expectations (~> 3.12.0)
+ rspec-mocks (~> 3.12.0)
+ rspec-benchmark (0.6.0)
+ benchmark-malloc (~> 0.2)
+ benchmark-perf (~> 0.6)
+ benchmark-trend (~> 0.4)
+ rspec (>= 3.0)
+ rspec-core (3.12.0)
+ rspec-support (~> 3.12.0)
+ rspec-expectations (3.12.2)
+ diff-lcs (>= 1.2.0, < 2.0)
+ rspec-support (~> 3.12.0)
+ rspec-mocks (3.12.3)
+ diff-lcs (>= 1.2.0, < 2.0)
+ rspec-support (~> 3.12.0)
+ rspec-parameterized (1.0.0)
+ rspec-parameterized-core (< 2)
+ rspec-parameterized-table_syntax (< 2)
+ rspec-parameterized-core (1.0.0)
+ parser
+ proc_to_ast
+ rspec (>= 2.13, < 4)
+ unparser
+ rspec-parameterized-table_syntax (1.0.0)
+ binding_of_caller
+ rspec-parameterized-core (< 2)
+ rspec-rails (6.0.1)
+ actionpack (>= 6.1)
+ activesupport (>= 6.1)
+ railties (>= 6.1)
+ rspec-core (~> 3.11)
+ rspec-expectations (~> 3.11)
+ rspec-mocks (~> 3.11)
+ rspec-support (~> 3.11)
+ rspec-support (3.12.0)
+ rubocop (1.43.0)
+ json (~> 2.3)
+ parallel (~> 1.10)
+ parser (>= 3.2.0.0)
+ rainbow (>= 2.2.2, < 4.0)
+ regexp_parser (>= 1.8, < 3.0)
+ rexml (>= 3.2.5, < 4.0)
+ rubocop-ast (>= 1.24.1, < 2.0)
+ ruby-progressbar (~> 1.7)
+ unicode-display_width (>= 2.4.0, < 3.0)
+ rubocop-ast (1.24.1)
+ parser (>= 3.1.1.0)
+ rubocop-capybara (2.18.0)
+ rubocop (~> 1.41)
+ rubocop-graphql (0.19.0)
+ rubocop (>= 0.87, < 2)
+ rubocop-performance (1.18.0)
+ rubocop (>= 1.7.0, < 2.0)
+ rubocop-ast (>= 0.4.0)
+ rubocop-rails (2.19.1)
+ activesupport (>= 4.2.0)
+ rack (>= 1.1)
+ rubocop (>= 1.33.0, < 2.0)
+ rubocop-rspec (2.18.1)
+ rubocop (~> 1.33)
+ rubocop-capybara (~> 2.17)
+ ruby-progressbar (1.11.0)
+ thor (1.2.2)
+ tzinfo (2.0.6)
+ concurrent-ruby (~> 1.0)
+ unicode-display_width (2.4.2)
+ unparser (0.6.7)
+ diff-lcs (~> 1.3)
+ parser (>= 3.2.0)
+ zeitwerk (2.6.8)
+
+PLATFORMS
+ ruby
+
+DEPENDENCIES
+ factory_bot_rails (~> 6.2.0)
+ gitlab-rspec!
+ gitlab-styles (~> 10.0.0)
+ gitlab-utils!
+ rspec-benchmark (~> 0.6.0)
+ rspec-parameterized (~> 1.0)
+ rspec-rails (~> 6.0.1)
+ rubocop (~> 1.21)
+ rubocop-rspec (~> 2.18.1)
+
+BUNDLED WITH
+ 2.4.4
diff --git a/gems/gitlab-utils/README.md b/gems/gitlab-utils/README.md
new file mode 100644
index 00000000000..f7c7d83888b
--- /dev/null
+++ b/gems/gitlab-utils/README.md
@@ -0,0 +1,8 @@
+# Gitlab::Utils
+
+This Gem contains all code that is not dependent on application code
+or business logic and provides a generic functions like:
+
+- safe parsing of YAML
+- version comparisions
+- `strong_memoize`
diff --git a/gems/gitlab-utils/Rakefile b/gems/gitlab-utils/Rakefile
new file mode 100644
index 00000000000..cca71754493
--- /dev/null
+++ b/gems/gitlab-utils/Rakefile
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+require "bundler/gem_tasks"
+require "rspec/core/rake_task"
+
+RSpec::Core::RakeTask.new(:spec)
+
+require "rubocop/rake_task"
+
+RuboCop::RakeTask.new
+
+task default: %i[spec rubocop]
diff --git a/gems/gitlab-utils/gitlab-utils.gemspec b/gems/gitlab-utils/gitlab-utils.gemspec
new file mode 100644
index 00000000000..15e40ecc279
--- /dev/null
+++ b/gems/gitlab-utils/gitlab-utils.gemspec
@@ -0,0 +1,34 @@
+# frozen_string_literal: true
+
+require_relative "lib/gitlab/utils/version"
+
+Gem::Specification.new do |spec|
+ spec.name = "gitlab-utils"
+ spec.version = Gitlab::Utils::Version::VERSION
+ spec.authors = ["group::tenant scale"]
+ spec.email = ["engineering@gitlab.com"]
+
+ spec.summary = "GitLab's common helper methods"
+ spec.description = "A set of useful helpers methods to perform various conversions and checks."
+ spec.homepage = 'https://gitlab.com/gitlab-org/gitlab/-/tree/master/gems/gitlab-utils'
+ spec.license = 'MIT'
+ spec.required_ruby_version = ">= 3.0"
+
+ spec.files = Dir['lib/**/*.rb']
+ spec.test_files = Dir['spec/**/*']
+ spec.require_paths = ["lib"]
+
+ spec.add_runtime_dependency 'actionview', '>= 6.1.7.2'
+ spec.add_runtime_dependency 'activesupport', '>= 6.1.7.2'
+ spec.add_runtime_dependency 'addressable', '~> 2.8'
+ spec.add_runtime_dependency 'nokogiri', '~> 1.15.2'
+ spec.add_runtime_dependency 'rake', '~> 13.0'
+
+ spec.add_development_dependency 'factory_bot_rails', '~> 6.2.0'
+ spec.add_development_dependency 'gitlab-styles', '~> 10.0.0'
+ spec.add_development_dependency 'rspec-benchmark', '~> 0.6.0'
+ spec.add_development_dependency 'rspec-parameterized', '~> 1.0'
+ spec.add_development_dependency 'rspec-rails', '~> 6.0.1'
+ spec.add_development_dependency 'rubocop', '~> 1.21'
+ spec.add_development_dependency 'rubocop-rspec', '~> 2.18.1'
+end
diff --git a/lib/gitlab/utils.rb b/gems/gitlab-utils/lib/gitlab/utils.rb
index dc0112c14d6..4e08ee8fcaf 100644
--- a/lib/gitlab/utils.rb
+++ b/gems/gitlab-utils/lib/gitlab/utils.rb
@@ -1,9 +1,13 @@
# frozen_string_literal: true
+require "addressable/uri"
+require "active_support/all"
+require "action_view"
+
module Gitlab
module Utils
extend self
- DoubleEncodingError ||= Class.new(StandardError)
+ DoubleEncodingError = Class.new(StandardError)
def allowlisted?(absolute_path, allowlist)
path = absolute_path.downcase
@@ -15,7 +19,7 @@ module Gitlab
def decode_path(encoded_path)
decoded = CGI.unescape(encoded_path)
- if decoded != CGI.unescape(decoded)
+ if decoded != CGI.unescape(decoded) # rubocop:disable Style/IfUnlessModifier
raise DoubleEncodingError, "path #{encoded_path} is not allowed"
end
@@ -31,7 +35,7 @@ module Gitlab
raise ArgumentError, 'Negative string size provided!' if bytes < 0
truncated = str.each_char.each_with_object(+'') do |char, object|
- if object.bytesize + char.bytesize > bytes
+ if object.bytesize + char.bytesize > bytes # rubocop:disable Style/GuardClause
break object
else
object.concat(char)
@@ -43,7 +47,7 @@ module Gitlab
# Append path to host, making sure there's one single / in between
def append_path(host, path)
- "#{host.to_s.sub(%r{\/+$}, '')}/#{remove_leading_slashes(path)}"
+ "#{host.to_s.sub(%r{\/+$}, '')}/#{remove_leading_slashes(path)}" # rubocop:disable Style/RedundantRegexpEscape
end
def remove_leading_slashes(str)
@@ -128,7 +132,7 @@ module Gitlab
def deep_indifferent_access(data)
case data
when Array
- data.map(&method(:deep_indifferent_access))
+ data.map { |item| deep_indifferent_access(item) }
when Hash
data.with_indifferent_access
else
@@ -139,7 +143,7 @@ module Gitlab
def deep_symbolized_access(data)
case data
when Array
- data.map(&method(:deep_symbolized_access))
+ data.map { |item| deep_symbolized_access(item) }
when Hash
data.deep_symbolize_keys
else
@@ -242,7 +246,7 @@ module Gitlab
unless allow_nested
# nested brackets check
- return false if brackets.include?('[[') || brackets.include?(']]')
+ return false if brackets.include?('[[') || brackets.include?(']]') # rubocop:disable Style/SoleNestedConditional
end
# open / close brackets coherence check
diff --git a/gems/gitlab-utils/lib/gitlab/utils/all.rb b/gems/gitlab-utils/lib/gitlab/utils/all.rb
new file mode 100644
index 00000000000..200a21aad88
--- /dev/null
+++ b/gems/gitlab-utils/lib/gitlab/utils/all.rb
@@ -0,0 +1,6 @@
+# frozen_string_literal: true
+
+require_relative "../utils"
+require_relative "../version_info"
+require_relative "version"
+require_relative "strong_memoize"
diff --git a/lib/gitlab/utils/strong_memoize.rb b/gems/gitlab-utils/lib/gitlab/utils/strong_memoize.rb
index 2b3841b8f09..2b3841b8f09 100644
--- a/lib/gitlab/utils/strong_memoize.rb
+++ b/gems/gitlab-utils/lib/gitlab/utils/strong_memoize.rb
diff --git a/gems/gitlab-utils/lib/gitlab/utils/version.rb b/gems/gitlab-utils/lib/gitlab/utils/version.rb
new file mode 100644
index 00000000000..a9afe5bf845
--- /dev/null
+++ b/gems/gitlab-utils/lib/gitlab/utils/version.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Utils
+ module Version
+ VERSION = "0.1.0"
+ end
+ end
+end
diff --git a/lib/gitlab/version_info.rb b/gems/gitlab-utils/lib/gitlab/version_info.rb
index 0351c9b30b3..0f94aea04ad 100644
--- a/lib/gitlab/version_info.rb
+++ b/gems/gitlab-utils/lib/gitlab/version_info.rb
@@ -6,7 +6,7 @@ module Gitlab
attr_reader :major, :minor, :patch
- VERSION_REGEX = /(\d+)\.(\d+)\.(\d+)/.freeze
+ VERSION_REGEX = /(\d+)\.(\d+)\.(\d+)/
# To mitigate ReDoS, limit the length of the version string we're
# willing to check
MAX_VERSION_LENGTH = 128
@@ -21,7 +21,7 @@ module Gitlab
end
end
- def initialize(major = 0, minor = 0, patch = 0, suffix = nil)
+ def initialize(major = 0, minor = 0, patch = 0, suffix = nil) # rubocop:disable Metrics/ParameterLists
@major = major
@minor = minor
@patch = patch
@@ -59,7 +59,7 @@ module Gitlab
def to_s
if valid?
- "%d.%d.%d%s" % [@major, @minor, @patch, @suffix_s]
+ "%d.%d.%d%s" % [@major, @minor, @patch, @suffix_s] # rubocop:disable Style/FormatString
else
'Unknown'
end
diff --git a/spec/lib/gitlab/utils/strong_memoize_spec.rb b/gems/gitlab-utils/spec/gitlab/utils/strong_memoize_spec.rb
index ea8083e7d7f..05b25681043 100644
--- a/spec/lib/gitlab/utils/strong_memoize_spec.rb
+++ b/gems/gitlab-utils/spec/gitlab/utils/strong_memoize_spec.rb
@@ -1,13 +1,9 @@
# frozen_string_literal: true
-require 'fast_spec_helper'
-require 'rspec-benchmark'
-require 'rspec-parameterized'
-require 'active_support/testing/time_helpers'
+# rubocop:disable GitlabSecurity/PublicSend
-RSpec.configure do |config|
- config.include RSpec::Benchmark::Matchers
-end
+require 'spec_helper'
+require 'active_support/testing/time_helpers'
RSpec.describe Gitlab::Utils::StrongMemoize, feature_category: :shared do
include ActiveSupport::Testing::TimeHelpers
@@ -89,8 +85,8 @@ RSpec.describe Gitlab::Utils::StrongMemoize, feature_category: :shared do
let(:member_name) { described_class.normalize_key(method_name) }
it 'only calls the block once' do
- value0 = object.send(method_name)
- value1 = object.send(method_name)
+ value0 = object.public_send(method_name)
+ value1 = object.public_send(method_name)
expect(value0).to eq(value)
expect(value1).to eq(value)
@@ -98,7 +94,7 @@ RSpec.describe Gitlab::Utils::StrongMemoize, feature_category: :shared do
end
it 'returns and defines the instance variable for the exact value' do
- returned_value = object.send(method_name)
+ returned_value = object.public_send(method_name)
memoized_value = object.instance_variable_get(:"@#{member_name}")
expect(returned_value).to eql(value)
@@ -125,7 +121,7 @@ RSpec.describe Gitlab::Utils::StrongMemoize, feature_category: :shared do
end
end
- context "memory allocation", type: :benchmark do
+ context "with memory allocation", type: :benchmark do
let(:value) { 'aaa' }
before do
@@ -171,7 +167,7 @@ RSpec.describe Gitlab::Utils::StrongMemoize, feature_category: :shared do
end
end
- context 'value memoization test' do
+ context 'with value memoization test' do
let(:value) { 'value' }
it 'caches the value for specified number of seconds' do
@@ -265,7 +261,7 @@ RSpec.describe Gitlab::Utils::StrongMemoize, feature_category: :shared do
context "with value '#{value}'" do
let(:value) { value }
- context 'memoized after method definition' do
+ context 'with memoized after method definition' do
let(:method_name) { :method_name_attr }
it_behaves_like 'caching the value'
@@ -372,3 +368,5 @@ RSpec.describe Gitlab::Utils::StrongMemoize, feature_category: :shared do
end
end
end
+
+# rubocop:enable GitlabSecurity/PublicSend
diff --git a/spec/lib/gitlab/utils_spec.rb b/gems/gitlab-utils/spec/gitlab/utils_spec.rb
index 7b9504366ec..53593190eea 100644
--- a/spec/lib/gitlab/utils_spec.rb
+++ b/gems/gitlab-utils/spec/gitlab/utils_spec.rb
@@ -2,13 +2,14 @@
require 'spec_helper'
-RSpec.describe Gitlab::Utils do
+RSpec.describe Gitlab::Utils, feature_category: :shared do
using RSpec::Parameterized::TableSyntax
+ include StubENV
delegate :to_boolean, :boolean_to_yes_no, :slugify, :which,
- :ensure_array_from_string, :bytes_to_megabytes,
- :append_path, :remove_leading_slashes, :allowlisted?,
- :decode_path, :ms_to_round_sec, to: :described_class
+ :ensure_array_from_string, :bytes_to_megabytes,
+ :append_path, :remove_leading_slashes, :allowlisted?,
+ :decode_path, :ms_to_round_sec, to: :described_class
describe '.allowlisted?' do
let(:allowed_paths) { ['/home/foo', '/foo/bar', '/etc/passwd'] }
@@ -225,7 +226,7 @@ RSpec.describe Gitlab::Utils do
end
describe '.ensure_utf8_size' do
- context 'string is has less bytes than expected' do
+ context 'with string is has less bytes than expected' do
it 'backfills string with null characters' do
transformed = described_class.ensure_utf8_size('a' * 10, bytes: 32)
@@ -234,7 +235,7 @@ RSpec.describe Gitlab::Utils do
end
end
- context 'string size is exactly the one that is expected' do
+ context 'with string size is exactly the one that is expected' do
it 'returns original value' do
transformed = described_class.ensure_utf8_size('a' * 32, bytes: 32)
@@ -247,7 +248,7 @@ RSpec.describe Gitlab::Utils do
it 'backfills string with null characters' do
transformed = described_class.ensure_utf8_size('❤' * 6, bytes: 32)
- expect(transformed).to eq '❤❤❤❤❤❤' + ('0' * 14)
+ expect(transformed).to eq '❤❤❤❤❤❤' + ('0' * 14) # rubocop:disable Style/StringConcatenation
expect(transformed.bytesize).to eq 32
end
end
@@ -368,7 +369,7 @@ RSpec.describe Gitlab::Utils do
nil | { b: 3, a: 2 } | '?a=2&b=3'
'https://gitlab.com' | nil | 'https://gitlab.com'
'https://gitlab.com' | { b: 3, a: 2 } | 'https://gitlab.com?a=2&b=3'
- 'https://gitlab.com?a=1#foo' | { b: 3, 'a': 2 } | 'https://gitlab.com?a=2&b=3#foo'
+ 'https://gitlab.com?a=1#foo' | { b: 3, 'a' => 2 } | 'https://gitlab.com?a=2&b=3#foo'
'https://gitlab.com?a=1#foo' | [[:b, 3], [:a, 2]] | 'https://gitlab.com?a=2&b=3#foo'
end
@@ -391,7 +392,8 @@ RSpec.describe Gitlab::Utils do
end
it 'returns string with filtered access_token param' do
- expect(described_class.removes_sensitive_data_from_url('http://gitlab.com/auth.html#access_token=secret_token')).to eq('http://gitlab.com/auth.html#access_token=filtered')
+ expect(described_class.removes_sensitive_data_from_url('http://gitlab.com/auth.html#access_token=secret_token'))
+ .to eq('http://gitlab.com/auth.html#access_token=filtered')
end
it 'returns string with filtered access_token param but other params preserved' do
diff --git a/spec/lib/gitlab/version_info_spec.rb b/gems/gitlab-utils/spec/gitlab/version_info_spec.rb
index 99c7a762392..2b5f6bcb4c1 100644
--- a/spec/lib/gitlab/version_info_spec.rb
+++ b/gems/gitlab-utils/spec/gitlab/version_info_spec.rb
@@ -1,8 +1,8 @@
# frozen_string_literal: true
-require 'fast_spec_helper'
+require 'spec_helper'
-RSpec.describe Gitlab::VersionInfo do
+RSpec.describe Gitlab::VersionInfo, feature_category: :shared do
before do
@unknown = described_class.new
@v0_0_1 = described_class.new(0, 0, 1)
diff --git a/gems/gitlab-utils/spec/spec_helper.rb b/gems/gitlab-utils/spec/spec_helper.rb
new file mode 100644
index 00000000000..5dc3859f77d
--- /dev/null
+++ b/gems/gitlab-utils/spec/spec_helper.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+require 'rails'
+require 'rspec/mocks'
+require 'rspec-benchmark'
+require 'rspec-parameterized'
+
+require 'gitlab/rspec/all'
+require 'gitlab/utils/all'
+
+RSpec.configure do |config|
+ config.include RSpec::Benchmark::Matchers
+
+ # Enable flags like --only-failures and --next-failure
+ config.example_status_persistence_file_path = ".rspec_status"
+
+ # Disable RSpec exposing methods globally on `Module` and `main`
+ config.disable_monkey_patching!
+
+ config.expect_with :rspec do |c|
+ c.syntax = :expect
+ end
+end
diff --git a/lib/gitlab/cluster/lifecycle_events.rb b/lib/gitlab/cluster/lifecycle_events.rb
index b39d2a02f02..c6ce0aa6160 100644
--- a/lib/gitlab/cluster/lifecycle_events.rb
+++ b/lib/gitlab/cluster/lifecycle_events.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-require_relative '../utils' # Gitlab::Utils
+require 'gitlab/utils/all' # Gitlab::Utils
module Gitlab
module Cluster
diff --git a/lib/gitlab/sidekiq_logging/structured_logger.rb b/lib/gitlab/sidekiq_logging/structured_logger.rb
index c4566a6dc2a..ca52d588113 100644
--- a/lib/gitlab/sidekiq_logging/structured_logger.rb
+++ b/lib/gitlab/sidekiq_logging/structured_logger.rb
@@ -87,6 +87,7 @@ module Gitlab
payload['message'] = "#{message}: #{job_status}: #{payload['duration_s']} sec"
payload['job_status'] = job_status
payload['job_deferred_by'] = job['deferred_by'] if job['deferred']
+ payload['deferred_count'] = job['deferred_count'] if job['deferred']
Gitlab::ExceptionLogFormatter.format!(job_exception, payload) if job_exception
diff --git a/lib/gitlab/sidekiq_middleware/defer_jobs.rb b/lib/gitlab/sidekiq_middleware/defer_jobs.rb
index 0a12667865c..6a652f39349 100644
--- a/lib/gitlab/sidekiq_middleware/defer_jobs.rb
+++ b/lib/gitlab/sidekiq_middleware/defer_jobs.rb
@@ -22,6 +22,8 @@ module Gitlab
# Referred in job_logger's 'log_job_done' method to compute proper 'job_status'
job['deferred'] = true
job['deferred_by'] = deferred_by
+ job['deferred_count'] ||= 0
+ job['deferred_count'] += 1
worker.class.perform_in(delay, *job['args'])
counter.increment({ worker: worker.class.name })
diff --git a/lib/gitlab/task_helpers.rb b/lib/gitlab/task_helpers.rb
index b9800a4db73..f756d229ba1 100644
--- a/lib/gitlab/task_helpers.rb
+++ b/lib/gitlab/task_helpers.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require 'rainbow/ext/string'
-require_relative 'utils/strong_memoize'
+require 'gitlab/utils/all'
# rubocop:disable Rails/Output
module Gitlab
diff --git a/lib/gitlab/utils/override.rb b/lib/gitlab/utils/override.rb
index 1d02bcbb2d2..10370811bb5 100644
--- a/lib/gitlab/utils/override.rb
+++ b/lib/gitlab/utils/override.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-require_relative '../utils'
+require 'gitlab/utils/all'
require_relative '../environment'
module Gitlab
diff --git a/lib/tasks/gettext.rake b/lib/tasks/gettext.rake
index 825388461bc..1a659a930ab 100644
--- a/lib/tasks/gettext.rake
+++ b/lib/tasks/gettext.rake
@@ -42,7 +42,7 @@ namespace :gettext do
desc 'Lint all po files in `locale/'
task lint: :environment do
require 'simple_po_parser'
- require 'gitlab/utils'
+ require 'gitlab/utils/all'
require 'parallel'
FastGettext.silence_errors
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index a09096b6b92..e2b72fb0123 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -1120,6 +1120,12 @@ msgstr ""
msgid "%{spanStart}in%{spanEnd} %{errorFn}"
msgstr ""
+msgid "%{startDate} – %{dueDate}"
+msgstr ""
+
+msgid "%{startDate} – No due date"
+msgstr ""
+
msgid "%{start} to %{end}"
msgstr ""
@@ -17714,12 +17720,6 @@ msgstr ""
msgid "Epics, issues, and merge requests"
msgstr ""
-msgid "Epics|%{startDate} – %{dueDate}"
-msgstr ""
-
-msgid "Epics|%{startDate} – No due date"
-msgstr ""
-
msgid "Epics|Add a new epic"
msgstr ""
@@ -17735,9 +17735,6 @@ msgstr ""
msgid "Epics|Leave empty to inherit from milestone dates"
msgstr ""
-msgid "Epics|No start date – %{dueDate}"
-msgstr ""
-
msgid "Epics|Remove epic"
msgstr ""
@@ -30792,6 +30789,9 @@ msgstr ""
msgid "No starrers matched your search"
msgstr ""
+msgid "No start date – %{dueDate}"
+msgstr ""
+
msgid "No suggestions found"
msgstr ""
diff --git a/metrics_server/dependencies.rb b/metrics_server/dependencies.rb
index 233511eb505..c96fecd7cb7 100644
--- a/metrics_server/dependencies.rb
+++ b/metrics_server/dependencies.rb
@@ -11,11 +11,11 @@ require 'active_support/core_ext/numeric/bytes'
require 'prometheus/client'
require 'rack'
+require 'gitlab/utils/all'
+
require_relative 'settings_overrides'
require_relative '../lib/gitlab/daemon'
-require_relative '../lib/gitlab/utils'
-require_relative '../lib/gitlab/utils/strong_memoize'
require_relative '../lib/prometheus/cleanup_multiproc_dir_service'
require_relative '../lib/gitlab/metrics/prometheus'
require_relative '../lib/gitlab/metrics'
diff --git a/qa/Dockerfile b/qa/Dockerfile
index e5308d78f83..213ec3450cb 100644
--- a/qa/Dockerfile
+++ b/qa/Dockerfile
@@ -40,6 +40,8 @@ WORKDIR /home/gitlab/qa
# Install qa dependencies or fetch from cache if unchanged
#
COPY ./qa/Gemfile* /home/gitlab/qa/
+COPY ./vendor/gems/ /home/gitlab/vendor/gems/
+COPY ./gems/ /home/gitlab/gems/
RUN bundle config set --local without development \
&& bundle install --retry=3
@@ -47,9 +49,7 @@ COPY ./config/initializers/0_inject_enterprise_edition_module.rb /home/gitlab/co
COPY ./config/feature_flags /home/gitlab/config/feature_flags
COPY ./config/bundler_setup.rb /home/gitlab/config/
COPY ./lib/gitlab_edition.rb /home/gitlab/lib/
-COPY ./lib/gitlab/utils.rb /home/gitlab/lib/gitlab/
COPY ./INSTALLATION_TYPE ./VERSION /home/gitlab/
-COPY ./gems /home/gitlab/
COPY ./qa /home/gitlab/qa
diff --git a/qa/Gemfile b/qa/Gemfile
index c907240333f..2a7f221f91f 100644
--- a/qa/Gemfile
+++ b/qa/Gemfile
@@ -4,6 +4,7 @@ source 'https://rubygems.org'
gem 'gitlab-qa', '~> 11', '>= 11.2.0', require: 'gitlab/qa'
gem 'gitlab_quality-test_tooling', '~> 0.8.2', require: false
+gem 'gitlab-utils', path: '../gems/gitlab-utils'
gem 'activesupport', '~> 6.1.7.2' # This should stay in sync with the root's Gemfile
gem 'allure-rspec', '~> 2.20.0'
gem 'capybara', '~> 3.39.2'
diff --git a/qa/Gemfile.lock b/qa/Gemfile.lock
index 94eae5f80bb..861bb1e0def 100644
--- a/qa/Gemfile.lock
+++ b/qa/Gemfile.lock
@@ -1,6 +1,22 @@
+PATH
+ remote: ../gems/gitlab-utils
+ specs:
+ gitlab-utils (0.1.0)
+ actionview (>= 6.1.7.2)
+ activesupport (>= 6.1.7.2)
+ addressable (~> 2.8)
+ nokogiri (~> 1.15.2)
+ rake (~> 13.0)
+
GEM
remote: https://rubygems.org/
specs:
+ actionview (6.1.7.2)
+ activesupport (= 6.1.7.2)
+ builder (~> 3.1)
+ erubi (~> 1.4)
+ rails-dom-testing (~> 2.0)
+ rails-html-sanitizer (~> 1.1, >= 1.2.0)
activesupport (6.1.7.2)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 1.6, < 2)
@@ -55,6 +71,7 @@ GEM
confiner (0.4.0)
gitlab (>= 4.17)
zeitwerk (>= 2.5, < 3)
+ crass (1.0.6)
debug_inspector (1.1.0)
declarative (0.0.20)
deprecation_toolkit (2.0.3)
@@ -62,6 +79,7 @@ GEM
diff-lcs (1.3)
domain_name (0.5.20190701)
unf (>= 0.0.5, < 1.0.0)
+ erubi (1.12.0)
excon (0.92.4)
faker (3.2.0)
i18n (>= 1.8.11, < 2)
@@ -176,6 +194,9 @@ GEM
llhttp-ffi (0.4.0)
ffi-compiler (~> 1.0)
rake (~> 13.0)
+ loofah (2.21.3)
+ crass (~> 1.0.2)
+ nokogiri (>= 1.12.0)
macaddr (1.7.2)
systemu (~> 2.6.5)
matrix (0.4.2)
@@ -214,10 +235,15 @@ GEM
byebug (~> 11.0)
pry (>= 0.13, < 0.15)
public_suffix (5.0.1)
- racc (1.6.2)
+ racc (1.7.1)
rack (2.2.3.1)
rack-test (1.1.0)
rack (>= 1.0, < 3)
+ rails-dom-testing (2.0.3)
+ activesupport (>= 4.2.0)
+ nokogiri (>= 1.6)
+ rails-html-sanitizer (1.5.0)
+ loofah (~> 2.19, >= 2.19.1)
rainbow (3.1.1)
rake (13.0.6)
regexp_parser (2.1.1)
@@ -324,6 +350,7 @@ DEPENDENCIES
fog-core (= 2.1.0)
fog-google (~> 1.19)
gitlab-qa (~> 11, >= 11.2.0)
+ gitlab-utils!
gitlab_quality-test_tooling (~> 0.8.2)
influxdb-client (~> 2.9)
knapsack (~> 4.0)
diff --git a/qa/gdk/Dockerfile.gdk b/qa/gdk/Dockerfile.gdk
index cdb693841cb..2b296535622 100644
--- a/qa/gdk/Dockerfile.gdk
+++ b/qa/gdk/Dockerfile.gdk
@@ -98,8 +98,8 @@ RUN set -eux; \
# Install gitlab gem dependencies
#
COPY --chown=gdk:gdk Gemfile Gemfile.lock ./gitlab/
-COPY --chown=gdk:gdk vendor/gems ./gitlab/vendor/gems
-COPY --chown=gdk:gdk gems ./gitlab/gems
+COPY --chown=gdk:gdk vendor/gems/ ./gitlab/vendor/gems/
+COPY --chown=gdk:gdk gems/ ./gitlab/gems/
RUN make .gitlab-bundle && rm -rf ${GEM_HOME}/cache
# Install gitlab npm dependencies
diff --git a/qa/qa.rb b/qa/qa.rb
index f6fba30c079..0e3d343b861 100644
--- a/qa/qa.rb
+++ b/qa/qa.rb
@@ -2,8 +2,9 @@
Encoding.default_external = 'UTF-8'
+require 'gitlab/utils/all'
+
require_relative '../lib/gitlab_edition'
-require_relative '../lib/gitlab/utils'
require_relative '../config/initializers/0_inject_enterprise_edition_module'
require_relative 'lib/gitlab'
diff --git a/qa/qa/scenario/test/integration/oauth.rb b/qa/qa/scenario/test/integration/oauth.rb
new file mode 100644
index 00000000000..912156fbc29
--- /dev/null
+++ b/qa/qa/scenario/test/integration/oauth.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+module QA
+ module Scenario
+ module Test
+ module Integration
+ class OAuth < Test::Instance::All
+ tags :oauth
+ end
+ end
+ end
+ end
+end
diff --git a/scripts/gitaly-test-build b/scripts/gitaly-test-build
index 6901593009a..cfa089b327e 100755
--- a/scripts/gitaly-test-build
+++ b/scripts/gitaly-test-build
@@ -1,6 +1,7 @@
#!/usr/bin/env ruby
# frozen_string_literal: true
+require_relative '../config/bundler_setup'
require 'fileutils'
require_relative '../spec/support/helpers/gitaly_setup'
diff --git a/scripts/gitaly-test-spawn b/scripts/gitaly-test-spawn
index 475c7715bdd..9285b561ae0 100755
--- a/scripts/gitaly-test-spawn
+++ b/scripts/gitaly-test-spawn
@@ -3,6 +3,7 @@
# This script is used both in CI and in local development 'rspec' runs.
+require_relative '../config/bundler_setup'
require_relative '../spec/support/helpers/gitaly_setup'
class GitalyTestSpawn
diff --git a/scripts/merge-simplecov b/scripts/merge-simplecov
index 24be731549b..7db12839382 100755
--- a/scripts/merge-simplecov
+++ b/scripts/merge-simplecov
@@ -1,6 +1,7 @@
#!/usr/bin/env ruby
# frozen_string_literal: true
+require_relative '../config/bundler_setup'
require_relative '../spec/simplecov_env'
SimpleCovEnv.configure_profile
SimpleCovEnv.configure_formatter
diff --git a/scripts/setup-test-env b/scripts/setup-test-env
index ae00b569ce3..1c39483bb7a 100755
--- a/scripts/setup-test-env
+++ b/scripts/setup-test-env
@@ -25,8 +25,8 @@ require_relative '../lib/system_check/helpers'
require 'omniauth'
require 'omniauth-github'
require 'etc'
+require 'gitlab/utils/all'
require_relative '../lib/gitlab/access'
-require_relative '../lib/gitlab/utils'
unless defined?(License)
# This is needed to allow use of `Gitlab::ImportSources.values` in `1_settings.rb`.
diff --git a/sidekiq_cluster/cli.rb b/sidekiq_cluster/cli.rb
index 0d24f70c37d..fc065d799d4 100644
--- a/sidekiq_cluster/cli.rb
+++ b/sidekiq_cluster/cli.rb
@@ -5,11 +5,11 @@ require_relative '../config/bundler_setup'
require 'optparse'
require 'logger'
require 'time'
+require 'gitlab/utils/all'
# In environments where code is preloaded and cached such as `spring`,
# we may run into "already initialized" warnings, hence the check.
require_relative '../lib/gitlab'
-require_relative '../lib/gitlab/utils'
require_relative '../lib/gitlab/sidekiq_config/cli_methods'
require_relative '../lib/gitlab/sidekiq_config/worker_matcher'
require_relative '../lib/gitlab/sidekiq_logging/json_formatter'
diff --git a/spec/controllers/groups/uploads_controller_spec.rb b/spec/controllers/groups/uploads_controller_spec.rb
index 6649e8f057c..7795fff5541 100644
--- a/spec/controllers/groups/uploads_controller_spec.rb
+++ b/spec/controllers/groups/uploads_controller_spec.rb
@@ -76,31 +76,17 @@ RSpec.describe Groups::UploadsController do
context 'when uploader class does not match the upload' do
let(:uploader_class) { FileUploader }
- it 'responds with status 200 but logs a deprecation message' do
- expect(Gitlab::AppJsonLogger).to receive(:info).with(
- message: 'Deprecated usage of build_uploader_from_params',
- uploader_class: uploader_class.name,
- path: filename,
- exists: true
- )
-
+ it 'responds with status 404' do
show_upload
- expect(response).to have_gitlab_http_status(:ok)
+ expect(response).to have_gitlab_http_status(:not_found)
end
end
context 'when filename does not match' do
let(:invalid_filename) { 'invalid_filename.jpg' }
- it 'responds with status 404 and logs a deprecation message' do
- expect(Gitlab::AppJsonLogger).to receive(:info).with(
- message: 'Deprecated usage of build_uploader_from_params',
- uploader_class: uploader_class.name,
- path: invalid_filename,
- exists: false
- )
-
+ it 'responds with status 404' do
get :show, params: params.merge(secret: secret, filename: invalid_filename)
expect(response).to have_gitlab_http_status(:not_found)
diff --git a/spec/deprecation_warnings.rb b/spec/deprecation_warnings.rb
index 45fed5fecca..abdd13ee8e7 100644
--- a/spec/deprecation_warnings.rb
+++ b/spec/deprecation_warnings.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-require_relative '../lib/gitlab/utils'
+require 'gitlab/utils/all'
return if Gitlab::Utils.to_boolean(ENV['SILENCE_DEPRECATIONS'], default: false)
# Enable deprecation warnings by default and make them more visible
diff --git a/spec/fast_spec_helper.rb b/spec/fast_spec_helper.rb
index 03c8919912c..47a90efab1e 100644
--- a/spec/fast_spec_helper.rb
+++ b/spec/fast_spec_helper.rb
@@ -18,13 +18,12 @@ RSpec.configure(&:disable_monkey_patching!)
require 'active_support/all'
require 'pry'
+require 'gitlab/utils/all'
require_relative 'rails_autoload'
require_relative '../config/settings'
require_relative 'support/rspec'
require_relative '../lib/gitlab'
-require_relative '../lib/gitlab/utils'
-require_relative '../lib/gitlab/utils/strong_memoize'
require_relative 'simplecov_env'
SimpleCovEnv.start!
diff --git a/spec/features/markdown/sandboxed_mermaid_spec.rb b/spec/features/markdown/sandboxed_mermaid_spec.rb
index f8a535191da..87696eb82e5 100644
--- a/spec/features/markdown/sandboxed_mermaid_spec.rb
+++ b/spec/features/markdown/sandboxed_mermaid_spec.rb
@@ -16,8 +16,9 @@ RSpec.describe 'Sandboxed Mermaid rendering', :js, feature_category: :team_plann
MERMAID
end
- let_it_be(:expected) do
- %(<iframe src="/-/sandbox/mermaid" sandbox="allow-scripts allow-popups" frameborder="0" scrolling="no")
+ let(:expected) do
+ src = "http://#{Capybara.current_session.server.host}:#{Capybara.current_session.server.port}/-/sandbox/mermaid"
+ %(<iframe src="#{src}" sandbox="allow-scripts allow-popups" frameborder="0" scrolling="no")
end
context 'in an issue' do
diff --git a/spec/frontend/behaviors/markdown/render_sandboxed_mermaid_spec.js b/spec/frontend/behaviors/markdown/render_sandboxed_mermaid_spec.js
index de0e5063e49..88312a780d1 100644
--- a/spec/frontend/behaviors/markdown/render_sandboxed_mermaid_spec.js
+++ b/spec/frontend/behaviors/markdown/render_sandboxed_mermaid_spec.js
@@ -9,7 +9,7 @@ import renderMermaid, {
describe('Mermaid diagrams renderer', () => {
// Finders
- const findMermaidIframes = () => document.querySelectorAll('iframe[src="/-/sandbox/mermaid"]');
+ const findMermaidIframes = () => document.querySelectorAll('iframe[src*="/-/sandbox/mermaid"]');
const findDangerousMermaidAlert = () =>
createWrapper(document.querySelector('[data-testid="alert-warning"]'));
diff --git a/spec/frontend/issuable/components/status_box_spec.js b/spec/frontend/issuable/components/status_box_spec.js
index d26f287d90c..0d47595c9e6 100644
--- a/spec/frontend/issuable/components/status_box_spec.js
+++ b/spec/frontend/issuable/components/status_box_spec.js
@@ -18,6 +18,8 @@ describe('Merge request status box component', () => {
${'merge_request'} | ${'Merged'} | ${'merged'} | ${'issuable-status-badge-merged'} | ${'info'} | ${'merge'}
${'issue'} | ${'Open'} | ${'opened'} | ${'issuable-status-badge-open'} | ${'success'} | ${'issues'}
${'issue'} | ${'Closed'} | ${'closed'} | ${'issuable-status-badge-closed'} | ${'info'} | ${'issue-closed'}
+ ${'epic'} | ${'Open'} | ${'opened'} | ${'issuable-status-badge-open'} | ${'success'} | ${'epic'}
+ ${'epic'} | ${'Closed'} | ${'closed'} | ${'issuable-status-badge-closed'} | ${'info'} | ${'epic-closed'}
`(
'with issuableType set to "$issuableType" and state set to "$initialState"',
({ issuableType, badgeText, initialState, badgeClass, badgeVariant, badgeIcon }) => {
diff --git a/spec/frontend/issuable/popover/components/issue_popover_spec.js b/spec/frontend/issuable/popover/components/issue_popover_spec.js
index a7605016039..0596433ce9a 100644
--- a/spec/frontend/issuable/popover/components/issue_popover_spec.js
+++ b/spec/frontend/issuable/popover/components/issue_popover_spec.js
@@ -26,7 +26,7 @@ describe('Issue Popover', () => {
apolloProvider: createMockApollo([[issueQuery, queryResponse]]),
propsData: {
target: document.createElement('a'),
- projectPath: 'foo/bar',
+ namespacePath: 'foo/bar',
iid: '1',
cachedTitle: 'Cached title',
},
diff --git a/spec/frontend/issuable/popover/components/mr_popover_spec.js b/spec/frontend/issuable/popover/components/mr_popover_spec.js
index 5b29ecfc0ba..4ed783da853 100644
--- a/spec/frontend/issuable/popover/components/mr_popover_spec.js
+++ b/spec/frontend/issuable/popover/components/mr_popover_spec.js
@@ -64,7 +64,7 @@ describe('MR Popover', () => {
apolloProvider: createMockApollo([[mergeRequestQuery, queryResponse]]),
propsData: {
target: document.createElement('a'),
- projectPath: 'foo/bar',
+ namespacePath: 'foo/bar',
iid: '1',
cachedTitle: 'Cached Title',
},
diff --git a/spec/frontend/issuable/popover/index_spec.js b/spec/frontend/issuable/popover/index_spec.js
index b1aa7f0f0b0..bf9dce4867f 100644
--- a/spec/frontend/issuable/popover/index_spec.js
+++ b/spec/frontend/issuable/popover/index_spec.js
@@ -1,6 +1,6 @@
import { setHTMLFixture } from 'helpers/fixtures';
import * as createDefaultClient from '~/lib/graphql';
-import initIssuablePopovers from '~/issuable/popover/index';
+import initIssuablePopovers, * as popover from '~/issuable/popover/index';
createDefaultClient.default = jest.fn();
@@ -9,6 +9,7 @@ describe('initIssuablePopovers', () => {
let mr2;
let mr3;
let issue1;
+ let workItem1;
beforeEach(() => {
setHTMLFixture(`
@@ -24,30 +25,69 @@ describe('initIssuablePopovers', () => {
<div id="four" class="gfm-issue" title="title" data-iid="1" data-project-path="group/project" data-reference-type="issue">
MR3
</div>
+ <div id="five" class="gfm-work_item" title="title" data-iid="1" data-project-path="group/project" data-reference-type="work_item">
+ MR3
+ </div>
`);
mr1 = document.querySelector('#one');
mr2 = document.querySelector('#two');
mr3 = document.querySelector('#three');
issue1 = document.querySelector('#four');
-
- mr1.addEventListener = jest.fn();
- mr2.addEventListener = jest.fn();
- mr3.addEventListener = jest.fn();
- issue1.addEventListener = jest.fn();
+ workItem1 = document.querySelector('#five');
});
- it('does not add the same event listener twice', () => {
- initIssuablePopovers([mr1, mr1, mr2, issue1]);
+ describe('init function', () => {
+ beforeEach(() => {
+ mr1.addEventListener = jest.fn();
+ mr2.addEventListener = jest.fn();
+ mr3.addEventListener = jest.fn();
+ issue1.addEventListener = jest.fn();
+ workItem1.addEventListener = jest.fn();
+ });
+
+ it('does not add the same event listener twice', () => {
+ initIssuablePopovers([mr1, mr1, mr2, issue1, workItem1]);
+
+ expect(mr1.addEventListener).toHaveBeenCalledTimes(1);
+ expect(mr2.addEventListener).toHaveBeenCalledTimes(1);
+ expect(issue1.addEventListener).toHaveBeenCalledTimes(1);
+ expect(workItem1.addEventListener).toHaveBeenCalledTimes(1);
+ });
- expect(mr1.addEventListener).toHaveBeenCalledTimes(1);
- expect(mr2.addEventListener).toHaveBeenCalledTimes(1);
- expect(issue1.addEventListener).toHaveBeenCalledTimes(1);
+ it('does not add listener if it does not have the necessary data attributes', () => {
+ initIssuablePopovers([mr1, mr2, mr3]);
+
+ expect(mr3.addEventListener).not.toHaveBeenCalled();
+ });
});
- it('does not add listener if it does not have the necessary data attributes', () => {
- initIssuablePopovers([mr1, mr2, mr3]);
+ describe('mount function', () => {
+ const expectedMountObject = {
+ apolloProvider: expect.anything(),
+ iid: '1',
+ namespacePath: 'group/project',
+ title: 'title',
+ };
+
+ beforeEach(() => {
+ jest.spyOn(popover, 'handleIssuablePopoverMount').mockImplementation(jest.fn());
+ });
+
+ it('calls popover mount function with components for Issue, MR, and Work Item', () => {
+ initIssuablePopovers([mr1, issue1, workItem1], popover.handleIssuablePopoverMount);
+
+ [mr1, issue1, workItem1].forEach(async (el) => {
+ await el.dispatchEvent(new Event('mouseenter', { target: el }));
- expect(mr3.addEventListener).not.toHaveBeenCalled();
+ expect(popover.handleIssuablePopoverMount).toHaveBeenCalledWith(
+ expect.objectContaining({
+ ...expectedMountObject,
+ referenceType: el.dataset.referenceType,
+ target: el,
+ }),
+ );
+ });
+ });
});
});
diff --git a/spec/frontend/lib/utils/datetime/date_format_utility_spec.js b/spec/frontend/lib/utils/datetime/date_format_utility_spec.js
index e7a6367eeac..65018fe1625 100644
--- a/spec/frontend/lib/utils/datetime/date_format_utility_spec.js
+++ b/spec/frontend/lib/utils/datetime/date_format_utility_spec.js
@@ -152,3 +152,18 @@ describe('formatUtcOffset', () => {
expect(utils.formatUtcOffset(offset)).toEqual(expected);
});
});
+
+describe('humanTimeframe', () => {
+ it.each`
+ startDate | dueDate | returnValue
+ ${'2021-1-1'} | ${'2021-2-28'} | ${'Jan 1 – Feb 28, 2021'}
+ ${'2021-1-1'} | ${'2022-2-28'} | ${'Jan 1, 2021 – Feb 28, 2022'}
+ ${'2021-1-1'} | ${null} | ${'Jan 1, 2021 – No due date'}
+ ${null} | ${'2021-2-28'} | ${'No start date – Feb 28, 2021'}
+ `(
+ 'returns string "$returnValue" when startDate is $startDate and dueDate is $dueDate',
+ ({ startDate, dueDate, returnValue }) => {
+ expect(utils.humanTimeframe(startDate, dueDate)).toBe(returnValue);
+ },
+ );
+});
diff --git a/spec/lib/gitlab/sidekiq_logging/structured_logger_spec.rb b/spec/lib/gitlab/sidekiq_logging/structured_logger_spec.rb
index 1c23a619b38..5f2994165f2 100644
--- a/spec/lib/gitlab/sidekiq_logging/structured_logger_spec.rb
+++ b/spec/lib/gitlab/sidekiq_logging/structured_logger_spec.rb
@@ -436,6 +436,7 @@ RSpec.describe Gitlab::SidekiqLogging::StructuredLogger do
call_subject(job, 'test_queue') do
job['deferred'] = true
job['deferred_by'] = :feature_flag
+ job['deferred_count'] = 1
end
end
end
diff --git a/spec/lib/gitlab/sidekiq_middleware/defer_jobs_spec.rb b/spec/lib/gitlab/sidekiq_middleware/defer_jobs_spec.rb
index 195a79c22ec..88ba228b66b 100644
--- a/spec/lib/gitlab/sidekiq_middleware/defer_jobs_spec.rb
+++ b/spec/lib/gitlab/sidekiq_middleware/defer_jobs_spec.rb
@@ -43,6 +43,13 @@ RSpec.describe Gitlab::SidekiqMiddleware::DeferJobs, feature_category: :scalabil
expect(TestDeferredWorker).to receive(:perform_in).with(described_class::DELAY, *job['args'])
expect { |b| subject.call(TestDeferredWorker.new, job, queue, &b) }.not_to yield_control
end
+
+ it 'increments the defer_count' do
+ (1..5).each do |count|
+ subject.call(TestDeferredWorker.new, job, queue)
+ expect(job).to include('deferred_count' => count)
+ end
+ end
end
context 'for other workers' do
@@ -51,7 +58,7 @@ RSpec.describe Gitlab::SidekiqMiddleware::DeferJobs, feature_category: :scalabil
end
end
- it 'increments the counter' do
+ it 'increments the metric counter' do
subject.call(TestDeferredWorker.new, job, queue)
counter = ::Gitlab::Metrics.registry.get(:sidekiq_jobs_deferred_total)
diff --git a/spec/simplecov_env.rb b/spec/simplecov_env.rb
index bea312369f7..af722f45ae5 100644
--- a/spec/simplecov_env.rb
+++ b/spec/simplecov_env.rb
@@ -3,7 +3,7 @@
require 'simplecov'
require 'simplecov-cobertura'
require 'simplecov-lcov'
-require_relative '../lib/gitlab/utils'
+require 'gitlab/utils/all'
module SimpleCovEnv
extend self
diff --git a/spec/support/ability_check.rb b/spec/support/ability_check.rb
index 213944506bb..5b56b9925f6 100644
--- a/spec/support/ability_check.rb
+++ b/spec/support/ability_check.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-require 'gitlab/utils/strong_memoize'
+require 'gitlab/utils/all'
module Support
module AbilityCheck
diff --git a/spec/support/formatters/json_formatter.rb b/spec/support/formatters/json_formatter.rb
index e9d65af710a..f477d5e9e6a 100644
--- a/spec/support/formatters/json_formatter.rb
+++ b/spec/support/formatters/json_formatter.rb
@@ -26,11 +26,15 @@ module Support
hash[:exceptions] = exceptions.map do |exception|
hash = {
class: exception.class.name,
- message: exception.message,
- message_lines: strip_ansi_codes(notification.message_lines),
- backtrace: notification.formatted_backtrace
+ message: exception.message
}
+ hash[:backtrace] = notification.formatted_backtrace if notification.respond_to?(:backtrace)
+
+ if notification.respond_to?(:message_lines)
+ hash[:message_lines] = strip_ansi_codes(notification.message_lines)
+ end
+
if loglinking
hash.merge!(
correlation_id: exception.message[match_data_after(loglinking::CORRELATION_ID_TITLE)],
diff --git a/spec/support/helpers/gitaly_setup.rb b/spec/support/helpers/gitaly_setup.rb
index 7db9e0aaf09..06390406efc 100644
--- a/spec/support/helpers/gitaly_setup.rb
+++ b/spec/support/helpers/gitaly_setup.rb
@@ -10,8 +10,7 @@ require 'securerandom'
require 'socket'
require 'logger'
require 'fileutils'
-
-require_relative '../../../lib/gitlab/utils'
+require 'gitlab/utils/all'
module GitalySetup
extend self
diff --git a/spec/support/rspec.rb b/spec/support/rspec.rb
index b34f8fe9a22..4479e679d67 100644
--- a/spec/support/rspec.rb
+++ b/spec/support/rspec.rb
@@ -8,6 +8,7 @@ require_relative "helpers/stub_object_storage"
require_relative "helpers/fast_rails_root"
require 'gitlab/rspec/all'
+require 'gitlab/utils/all'
RSpec::Expectations.configuration.on_potential_false_positives = :raise
diff --git a/spec/support/shared_contexts/lib/gitlab/sidekiq_logging/structured_logger_shared_context.rb b/spec/support/shared_contexts/lib/gitlab/sidekiq_logging/structured_logger_shared_context.rb
index 1b50ef3fcff..b3b376ff6fe 100644
--- a/spec/support/shared_contexts/lib/gitlab/sidekiq_logging/structured_logger_shared_context.rb
+++ b/spec/support/shared_contexts/lib/gitlab/sidekiq_logging/structured_logger_shared_context.rb
@@ -69,7 +69,8 @@ RSpec.shared_context 'structured_logger' do
end_payload.merge(
'message' => 'TestWorker JID-da883554ee4fe414012f5f42: deferred: 0.0 sec',
'job_status' => 'deferred',
- 'job_deferred_by' => :feature_flag
+ 'job_deferred_by' => :feature_flag,
+ 'deferred_count' => 1
)
end
diff --git a/spec/support/shared_examples/controllers/uploads_actions_shared_examples.rb b/spec/support/shared_examples/controllers/uploads_actions_shared_examples.rb
index 0792ac14e47..772e03950da 100644
--- a/spec/support/shared_examples/controllers/uploads_actions_shared_examples.rb
+++ b/spec/support/shared_examples/controllers/uploads_actions_shared_examples.rb
@@ -94,14 +94,6 @@ RSpec.shared_examples 'handle uploads' do
expect(response).to have_gitlab_http_status(:not_found)
end
-
- it 'is a working exploit without the validation' do
- allow_any_instance_of(FileUploader).to receive(:secret) { secret }
-
- show_upload
-
- expect(response).to have_gitlab_http_status(:ok)
- end
end
context 'when accessing a specific upload via different model' do