summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md18
-rw-r--r--app/assets/javascripts/releases/components/releases_sort_apollo_client.vue1
-rw-r--r--app/assets/javascripts/static_site_editor/components/edit_area.vue4
-rw-r--r--app/assets/javascripts/static_site_editor/rich_content_editor/constants.js (renamed from app/assets/javascripts/vue_shared/components/rich_content_editor/constants.js)0
-rw-r--r--app/assets/javascripts/static_site_editor/rich_content_editor/modals/add_image/add_image_modal.vue (renamed from app/assets/javascripts/vue_shared/components/rich_content_editor/modals/add_image/add_image_modal.vue)0
-rw-r--r--app/assets/javascripts/static_site_editor/rich_content_editor/modals/add_image/upload_image_tab.vue (renamed from app/assets/javascripts/vue_shared/components/rich_content_editor/modals/add_image/upload_image_tab.vue)0
-rw-r--r--app/assets/javascripts/static_site_editor/rich_content_editor/modals/insert_video_modal.vue (renamed from app/assets/javascripts/vue_shared/components/rich_content_editor/modals/insert_video_modal.vue)0
-rw-r--r--app/assets/javascripts/static_site_editor/rich_content_editor/rich_content_editor.vue (renamed from app/assets/javascripts/vue_shared/components/rich_content_editor/rich_content_editor.vue)0
-rw-r--r--app/assets/javascripts/static_site_editor/rich_content_editor/services/build_custom_renderer.js (renamed from app/assets/javascripts/vue_shared/components/rich_content_editor/services/build_custom_renderer.js)0
-rw-r--r--app/assets/javascripts/static_site_editor/rich_content_editor/services/build_html_to_markdown_renderer.js (renamed from app/assets/javascripts/vue_shared/components/rich_content_editor/services/build_html_to_markdown_renderer.js)0
-rw-r--r--app/assets/javascripts/static_site_editor/rich_content_editor/services/editor_service.js (renamed from app/assets/javascripts/vue_shared/components/rich_content_editor/services/editor_service.js)0
-rw-r--r--app/assets/javascripts/static_site_editor/rich_content_editor/services/renderers/build_uneditable_token.js (renamed from app/assets/javascripts/vue_shared/components/rich_content_editor/services/renderers/build_uneditable_token.js)0
-rw-r--r--app/assets/javascripts/static_site_editor/rich_content_editor/services/renderers/render_attribute_definition.js (renamed from app/assets/javascripts/vue_shared/components/rich_content_editor/services/renderers/render_attribute_definition.js)0
-rw-r--r--app/assets/javascripts/static_site_editor/rich_content_editor/services/renderers/render_embedded_ruby_text.js (renamed from app/assets/javascripts/vue_shared/components/rich_content_editor/services/renderers/render_embedded_ruby_text.js)0
-rw-r--r--app/assets/javascripts/static_site_editor/rich_content_editor/services/renderers/render_font_awesome_html_inline.js (renamed from app/assets/javascripts/vue_shared/components/rich_content_editor/services/renderers/render_font_awesome_html_inline.js)0
-rw-r--r--app/assets/javascripts/static_site_editor/rich_content_editor/services/renderers/render_heading.js (renamed from app/assets/javascripts/vue_shared/components/rich_content_editor/services/renderers/render_heading.js)0
-rw-r--r--app/assets/javascripts/static_site_editor/rich_content_editor/services/renderers/render_html_block.js (renamed from app/assets/javascripts/vue_shared/components/rich_content_editor/services/renderers/render_html_block.js)0
-rw-r--r--app/assets/javascripts/static_site_editor/rich_content_editor/services/renderers/render_identifier_instance_text.js (renamed from app/assets/javascripts/vue_shared/components/rich_content_editor/services/renderers/render_identifier_instance_text.js)0
-rw-r--r--app/assets/javascripts/static_site_editor/rich_content_editor/services/renderers/render_identifier_paragraph.js (renamed from app/assets/javascripts/vue_shared/components/rich_content_editor/services/renderers/render_identifier_paragraph.js)0
-rw-r--r--app/assets/javascripts/static_site_editor/rich_content_editor/services/renderers/render_list_item.js (renamed from app/assets/javascripts/vue_shared/components/rich_content_editor/services/renderers/render_list_item.js)0
-rw-r--r--app/assets/javascripts/static_site_editor/rich_content_editor/services/renderers/render_softbreak.js (renamed from app/assets/javascripts/vue_shared/components/rich_content_editor/services/renderers/render_softbreak.js)0
-rw-r--r--app/assets/javascripts/static_site_editor/rich_content_editor/services/renderers/render_utils.js (renamed from app/assets/javascripts/vue_shared/components/rich_content_editor/services/renderers/render_utils.js)0
-rw-r--r--app/assets/javascripts/static_site_editor/rich_content_editor/services/sanitize_html.js (renamed from app/assets/javascripts/vue_shared/components/rich_content_editor/services/sanitize_html.js)0
-rw-r--r--app/assets/javascripts/static_site_editor/rich_content_editor/toolbar_item.vue (renamed from app/assets/javascripts/vue_shared/components/rich_content_editor/toolbar_item.vue)0
-rw-r--r--app/views/import/_githubish_status.html.haml3
-rw-r--r--app/views/import/bitbucket_server/new.html.haml7
-rw-r--r--app/views/import/bitbucket_server/status.html.haml1
-rw-r--r--app/views/import/fogbugz/new.html.haml4
-rw-r--r--app/views/import/fogbugz/new_user_map.html.haml4
-rw-r--r--app/views/import/fogbugz/status.html.haml1
-rw-r--r--app/views/import/gitea/new.html.haml3
-rw-r--r--app/views/import/gitea/status.html.haml1
-rw-r--r--app/views/import/github/new.html.haml6
-rw-r--r--app/views/import/github/status.html.haml2
-rw-r--r--app/views/import/gitlab/status.html.haml1
-rw-r--r--app/views/import/gitlab_projects/new.html.haml3
-rw-r--r--app/views/import/manifest/new.html.haml4
-rw-r--r--app/views/import/manifest/status.html.haml1
-rw-r--r--app/views/import/phabricator/new.html.haml7
-rw-r--r--app/views/projects/ci/builds/_build.html.haml2
-rw-r--r--app/views/projects/jobs/_table.html.haml2
-rw-r--r--config/initializers/active_record_postgresql_adapter.rb (renamed from config/initializers/active_record_ping.rb)6
-rw-r--r--doc/administration/geo/replication/datatypes.md32
-rw-r--r--doc/administration/pages/index.md109
-rw-r--r--doc/api/boards.md3
-rw-r--r--doc/api/groups.md20
-rw-r--r--doc/api/project_clusters.md9
-rw-r--r--doc/api/projects.md94
-rw-r--r--doc/api/search.md6
-rw-r--r--doc/architecture/blueprints/container_registry_metadata_database/index.md4
-rw-r--r--doc/development/usage_ping/dictionary.md12
-rw-r--r--doc/user/application_security/container_scanning/index.md2
-rw-r--r--lib/api/entities/basic_project_details.rb25
-rw-r--r--lib/gitlab/database/postgresql_adapter/type_map_cache.rb44
-rw-r--r--lib/gitlab/json.rb4
-rw-r--r--locale/gitlab.pot3
-rw-r--r--qa/qa/runtime/allure_report.rb10
-rw-r--r--spec/features/groups/members/manage_members_spec.rb6
-rw-r--r--spec/features/projects/import_export/import_file_spec.rb10
-rw-r--r--spec/features/projects/members/list_spec.rb6
-rw-r--r--spec/features/projects/releases/user_views_releases_spec.rb173
-rw-r--r--spec/fixtures/api/schemas/public_api/v4/board.json2
-rw-r--r--spec/fixtures/api/schemas/public_api/v4/project.json8
-rw-r--r--spec/frontend/fixtures/static/projects.json9
-rw-r--r--spec/frontend/static_site_editor/components/edit_area_spec.js4
-rw-r--r--spec/frontend/static_site_editor/rich_content_editor/editor_service_spec.js (renamed from spec/frontend/vue_shared/components/rich_content_editor/editor_service_spec.js)14
-rw-r--r--spec/frontend/static_site_editor/rich_content_editor/modals/add_image/add_image_modal_spec.js (renamed from spec/frontend/vue_shared/components/rich_content_editor/modals/add_image/add_image_modal_spec.js)6
-rw-r--r--spec/frontend/static_site_editor/rich_content_editor/modals/add_image/upload_image_tab_spec.js (renamed from spec/frontend/vue_shared/components/rich_content_editor/modals/add_image/upload_image_tab_spec.js)2
-rw-r--r--spec/frontend/static_site_editor/rich_content_editor/modals/insert_video_modal_spec.js (renamed from spec/frontend/vue_shared/components/rich_content_editor/modals/insert_video_modal_spec.js)2
-rw-r--r--spec/frontend/static_site_editor/rich_content_editor/rich_content_editor_integration_spec.js (renamed from spec/frontend/vue_shared/components/rich_content_editor/rich_content_editor_integration_spec.js)6
-rw-r--r--spec/frontend/static_site_editor/rich_content_editor/rich_content_editor_spec.js (renamed from spec/frontend/vue_shared/components/rich_content_editor/rich_content_editor_spec.js)12
-rw-r--r--spec/frontend/static_site_editor/rich_content_editor/services/build_custom_renderer_spec.js (renamed from spec/frontend/vue_shared/components/rich_content_editor/services/build_custom_renderer_spec.js)2
-rw-r--r--spec/frontend/static_site_editor/rich_content_editor/services/build_html_to_markdown_renderer_spec.js (renamed from spec/frontend/vue_shared/components/rich_content_editor/services/build_html_to_markdown_renderer_spec.js)2
-rw-r--r--spec/frontend/static_site_editor/rich_content_editor/services/renderers/build_uneditable_token_spec.js (renamed from spec/frontend/vue_shared/components/rich_content_editor/services/renderers/build_uneditable_token_spec.js)2
-rw-r--r--spec/frontend/static_site_editor/rich_content_editor/services/renderers/mock_data.js (renamed from spec/frontend/vue_shared/components/rich_content_editor/services/renderers/mock_data.js)0
-rw-r--r--spec/frontend/static_site_editor/rich_content_editor/services/renderers/render_attribute_definition_spec.js (renamed from spec/frontend/vue_shared/components/rich_content_editor/services/renderers/render_attribute_definition_spec.js)2
-rw-r--r--spec/frontend/static_site_editor/rich_content_editor/services/renderers/render_embedded_ruby_spec.js (renamed from spec/frontend/vue_shared/components/rich_content_editor/services/renderers/render_embedded_ruby_spec.js)4
-rw-r--r--spec/frontend/static_site_editor/rich_content_editor/services/renderers/render_font_awesome_html_inline_spec.js (renamed from spec/frontend/vue_shared/components/rich_content_editor/services/renderers/render_font_awesome_html_inline_spec.js)4
-rw-r--r--spec/frontend/static_site_editor/rich_content_editor/services/renderers/render_heading_spec.js (renamed from spec/frontend/vue_shared/components/rich_content_editor/services/renderers/render_heading_spec.js)4
-rw-r--r--spec/frontend/static_site_editor/rich_content_editor/services/renderers/render_html_block_spec.js (renamed from spec/frontend/vue_shared/components/rich_content_editor/services/renderers/render_html_block_spec.js)4
-rw-r--r--spec/frontend/static_site_editor/rich_content_editor/services/renderers/render_identifier_instance_text_spec.js (renamed from spec/frontend/vue_shared/components/rich_content_editor/services/renderers/render_identifier_instance_text_spec.js)4
-rw-r--r--spec/frontend/static_site_editor/rich_content_editor/services/renderers/render_identifier_paragraph_spec.js (renamed from spec/frontend/vue_shared/components/rich_content_editor/services/renderers/render_identifier_paragraph_spec.js)2
-rw-r--r--spec/frontend/static_site_editor/rich_content_editor/services/renderers/render_list_item_spec.js (renamed from spec/frontend/vue_shared/components/rich_content_editor/services/renderers/render_list_item_spec.js)4
-rw-r--r--spec/frontend/static_site_editor/rich_content_editor/services/renderers/render_softbreak_spec.js (renamed from spec/frontend/vue_shared/components/rich_content_editor/services/renderers/render_softbreak_spec.js)2
-rw-r--r--spec/frontend/static_site_editor/rich_content_editor/services/renderers/render_utils_spec.js (renamed from spec/frontend/vue_shared/components/rich_content_editor/services/renderers/render_utils_spec.js)4
-rw-r--r--spec/frontend/static_site_editor/rich_content_editor/services/sanitize_html_spec.js (renamed from spec/frontend/vue_shared/components/rich_content_editor/services/sanitize_html_spec.js)2
-rw-r--r--spec/frontend/static_site_editor/rich_content_editor/toolbar_item_spec.js (renamed from spec/frontend/vue_shared/components/rich_content_editor/toolbar_item_spec.js)2
-rw-r--r--spec/lib/gitlab/database/postgresql_adapter/type_map_cache_spec.rb75
-rw-r--r--spec/lib/gitlab/json_spec.rb12
-rw-r--r--spec/requests/api/project_attributes.yml1
-rw-r--r--spec/requests/api/projects_spec.rb11
-rw-r--r--spec/support/helpers/query_recorder.rb7
-rw-r--r--workhorse/internal/artifacts/entry.go19
-rw-r--r--workhorse/internal/artifacts/entry_test.go4
94 files changed, 586 insertions, 305 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 669dec87484..6610dbfd397 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,24 @@
documentation](doc/development/changelog.md) for instructions on adding your own
entry.
+## 13.12.3 (2021-06-07)
+
+### Added (1 change)
+
+- [Add an option to expose description_html in Release API](gitlab-org/gitlab@47f3fba10dfa82c65b6b006d56cc1724aac411eb) ([merge request](gitlab-org/gitlab!63393))
+
+### Fixed (5 changes)
+
+- [Fix spam detection with Akismet client](gitlab-org/gitlab@75dbe8d017ed691d0517f0a6ca7b9bdd866fa9d9) ([merge request](gitlab-org/gitlab!63393))
+- [Set CSP back to disabled by default](gitlab-org/gitlab@f8f2dbf229693e20171185ae8e31fd59ce2131b3) ([merge request](gitlab-org/gitlab!63393))
+- [Fix CSP issues related to captchas](gitlab-org/gitlab@cec54814460994ea40311f1091fb7f091d04964f) ([merge request](gitlab-org/gitlab!63393))
+- [Fix issue with frames not loading in Safari](gitlab-org/gitlab@77b9355f244370b1c184943581f3b6cc27495931) ([merge request](gitlab-org/gitlab!63393))
+- [Catch PgQuery::ParseError errors and log as-is](gitlab-org/gitlab@a4f36df3701208b5d015e1e818f3d5be3577697a) ([merge request](gitlab-org/gitlab!62795))
+
+### Changed (1 change)
+
+- [Improve SSH key expiration warning emails](gitlab-org/gitlab@2e3929503046ab1da5635ef295321ce08843f937) ([merge request](gitlab-org/gitlab!63393))
+
## 13.12.1 (2021-05-25)
### Fixed (3 changes)
diff --git a/app/assets/javascripts/releases/components/releases_sort_apollo_client.vue b/app/assets/javascripts/releases/components/releases_sort_apollo_client.vue
index c102a2765c9..7257b34bbf6 100644
--- a/app/assets/javascripts/releases/components/releases_sort_apollo_client.vue
+++ b/app/assets/javascripts/releases/components/releases_sort_apollo_client.vue
@@ -76,6 +76,7 @@ export default {
<gl-sorting
:text="sortText"
:is-ascending="isDirectionAscending"
+ data-testid="releases-sort"
@sortDirectionChange="onDirectionChange"
>
<gl-sorting-item
diff --git a/app/assets/javascripts/static_site_editor/components/edit_area.vue b/app/assets/javascripts/static_site_editor/components/edit_area.vue
index a51a4f9f604..ea775eff358 100644
--- a/app/assets/javascripts/static_site_editor/components/edit_area.vue
+++ b/app/assets/javascripts/static_site_editor/components/edit_area.vue
@@ -1,7 +1,7 @@
<script>
+import { EDITOR_TYPES } from '~/static_site_editor/rich_content_editor/constants';
+import RichContentEditor from '~/static_site_editor/rich_content_editor/rich_content_editor.vue';
import parseSourceFile from '~/static_site_editor/services/parse_source_file';
-import { EDITOR_TYPES } from '~/vue_shared/components/rich_content_editor/constants';
-import RichContentEditor from '~/vue_shared/components/rich_content_editor/rich_content_editor.vue';
import imageRepository from '../image_repository';
import formatter from '../services/formatter';
import renderImage from '../services/renderers/render_image';
diff --git a/app/assets/javascripts/vue_shared/components/rich_content_editor/constants.js b/app/assets/javascripts/static_site_editor/rich_content_editor/constants.js
index cbb30baa488..cbb30baa488 100644
--- a/app/assets/javascripts/vue_shared/components/rich_content_editor/constants.js
+++ b/app/assets/javascripts/static_site_editor/rich_content_editor/constants.js
diff --git a/app/assets/javascripts/vue_shared/components/rich_content_editor/modals/add_image/add_image_modal.vue b/app/assets/javascripts/static_site_editor/rich_content_editor/modals/add_image/add_image_modal.vue
index 82060d2e4ad..82060d2e4ad 100644
--- a/app/assets/javascripts/vue_shared/components/rich_content_editor/modals/add_image/add_image_modal.vue
+++ b/app/assets/javascripts/static_site_editor/rich_content_editor/modals/add_image/add_image_modal.vue
diff --git a/app/assets/javascripts/vue_shared/components/rich_content_editor/modals/add_image/upload_image_tab.vue b/app/assets/javascripts/static_site_editor/rich_content_editor/modals/add_image/upload_image_tab.vue
index 9baa7f286d7..9baa7f286d7 100644
--- a/app/assets/javascripts/vue_shared/components/rich_content_editor/modals/add_image/upload_image_tab.vue
+++ b/app/assets/javascripts/static_site_editor/rich_content_editor/modals/add_image/upload_image_tab.vue
diff --git a/app/assets/javascripts/vue_shared/components/rich_content_editor/modals/insert_video_modal.vue b/app/assets/javascripts/static_site_editor/rich_content_editor/modals/insert_video_modal.vue
index 99bb2080610..99bb2080610 100644
--- a/app/assets/javascripts/vue_shared/components/rich_content_editor/modals/insert_video_modal.vue
+++ b/app/assets/javascripts/static_site_editor/rich_content_editor/modals/insert_video_modal.vue
diff --git a/app/assets/javascripts/vue_shared/components/rich_content_editor/rich_content_editor.vue b/app/assets/javascripts/static_site_editor/rich_content_editor/rich_content_editor.vue
index 8988dab85d2..8988dab85d2 100644
--- a/app/assets/javascripts/vue_shared/components/rich_content_editor/rich_content_editor.vue
+++ b/app/assets/javascripts/static_site_editor/rich_content_editor/rich_content_editor.vue
diff --git a/app/assets/javascripts/vue_shared/components/rich_content_editor/services/build_custom_renderer.js b/app/assets/javascripts/static_site_editor/rich_content_editor/services/build_custom_renderer.js
index 6ffd280e005..6ffd280e005 100644
--- a/app/assets/javascripts/vue_shared/components/rich_content_editor/services/build_custom_renderer.js
+++ b/app/assets/javascripts/static_site_editor/rich_content_editor/services/build_custom_renderer.js
diff --git a/app/assets/javascripts/vue_shared/components/rich_content_editor/services/build_html_to_markdown_renderer.js b/app/assets/javascripts/static_site_editor/rich_content_editor/services/build_html_to_markdown_renderer.js
index 273e0a59963..273e0a59963 100644
--- a/app/assets/javascripts/vue_shared/components/rich_content_editor/services/build_html_to_markdown_renderer.js
+++ b/app/assets/javascripts/static_site_editor/rich_content_editor/services/build_html_to_markdown_renderer.js
diff --git a/app/assets/javascripts/vue_shared/components/rich_content_editor/services/editor_service.js b/app/assets/javascripts/static_site_editor/rich_content_editor/services/editor_service.js
index 026a4069d9b..026a4069d9b 100644
--- a/app/assets/javascripts/vue_shared/components/rich_content_editor/services/editor_service.js
+++ b/app/assets/javascripts/static_site_editor/rich_content_editor/services/editor_service.js
diff --git a/app/assets/javascripts/vue_shared/components/rich_content_editor/services/renderers/build_uneditable_token.js b/app/assets/javascripts/static_site_editor/rich_content_editor/services/renderers/build_uneditable_token.js
index 638e5fd6f60..638e5fd6f60 100644
--- a/app/assets/javascripts/vue_shared/components/rich_content_editor/services/renderers/build_uneditable_token.js
+++ b/app/assets/javascripts/static_site_editor/rich_content_editor/services/renderers/build_uneditable_token.js
diff --git a/app/assets/javascripts/vue_shared/components/rich_content_editor/services/renderers/render_attribute_definition.js b/app/assets/javascripts/static_site_editor/rich_content_editor/services/renderers/render_attribute_definition.js
index bd419447a48..bd419447a48 100644
--- a/app/assets/javascripts/vue_shared/components/rich_content_editor/services/renderers/render_attribute_definition.js
+++ b/app/assets/javascripts/static_site_editor/rich_content_editor/services/renderers/render_attribute_definition.js
diff --git a/app/assets/javascripts/vue_shared/components/rich_content_editor/services/renderers/render_embedded_ruby_text.js b/app/assets/javascripts/static_site_editor/rich_content_editor/services/renderers/render_embedded_ruby_text.js
index 0e122f598e5..0e122f598e5 100644
--- a/app/assets/javascripts/vue_shared/components/rich_content_editor/services/renderers/render_embedded_ruby_text.js
+++ b/app/assets/javascripts/static_site_editor/rich_content_editor/services/renderers/render_embedded_ruby_text.js
diff --git a/app/assets/javascripts/vue_shared/components/rich_content_editor/services/renderers/render_font_awesome_html_inline.js b/app/assets/javascripts/static_site_editor/rich_content_editor/services/renderers/render_font_awesome_html_inline.js
index 572f6e3cf9d..572f6e3cf9d 100644
--- a/app/assets/javascripts/vue_shared/components/rich_content_editor/services/renderers/render_font_awesome_html_inline.js
+++ b/app/assets/javascripts/static_site_editor/rich_content_editor/services/renderers/render_font_awesome_html_inline.js
diff --git a/app/assets/javascripts/vue_shared/components/rich_content_editor/services/renderers/render_heading.js b/app/assets/javascripts/static_site_editor/rich_content_editor/services/renderers/render_heading.js
index 71026fd0d65..71026fd0d65 100644
--- a/app/assets/javascripts/vue_shared/components/rich_content_editor/services/renderers/render_heading.js
+++ b/app/assets/javascripts/static_site_editor/rich_content_editor/services/renderers/render_heading.js
diff --git a/app/assets/javascripts/vue_shared/components/rich_content_editor/services/renderers/render_html_block.js b/app/assets/javascripts/static_site_editor/rich_content_editor/services/renderers/render_html_block.js
index 710b807275b..710b807275b 100644
--- a/app/assets/javascripts/vue_shared/components/rich_content_editor/services/renderers/render_html_block.js
+++ b/app/assets/javascripts/static_site_editor/rich_content_editor/services/renderers/render_html_block.js
diff --git a/app/assets/javascripts/vue_shared/components/rich_content_editor/services/renderers/render_identifier_instance_text.js b/app/assets/javascripts/static_site_editor/rich_content_editor/services/renderers/render_identifier_instance_text.js
index d7716543b53..d7716543b53 100644
--- a/app/assets/javascripts/vue_shared/components/rich_content_editor/services/renderers/render_identifier_instance_text.js
+++ b/app/assets/javascripts/static_site_editor/rich_content_editor/services/renderers/render_identifier_instance_text.js
diff --git a/app/assets/javascripts/vue_shared/components/rich_content_editor/services/renderers/render_identifier_paragraph.js b/app/assets/javascripts/static_site_editor/rich_content_editor/services/renderers/render_identifier_paragraph.js
index 4829f0f2243..4829f0f2243 100644
--- a/app/assets/javascripts/vue_shared/components/rich_content_editor/services/renderers/render_identifier_paragraph.js
+++ b/app/assets/javascripts/static_site_editor/rich_content_editor/services/renderers/render_identifier_paragraph.js
diff --git a/app/assets/javascripts/vue_shared/components/rich_content_editor/services/renderers/render_list_item.js b/app/assets/javascripts/static_site_editor/rich_content_editor/services/renderers/render_list_item.js
index 71026fd0d65..71026fd0d65 100644
--- a/app/assets/javascripts/vue_shared/components/rich_content_editor/services/renderers/render_list_item.js
+++ b/app/assets/javascripts/static_site_editor/rich_content_editor/services/renderers/render_list_item.js
diff --git a/app/assets/javascripts/vue_shared/components/rich_content_editor/services/renderers/render_softbreak.js b/app/assets/javascripts/static_site_editor/rich_content_editor/services/renderers/render_softbreak.js
index c004e839821..c004e839821 100644
--- a/app/assets/javascripts/vue_shared/components/rich_content_editor/services/renderers/render_softbreak.js
+++ b/app/assets/javascripts/static_site_editor/rich_content_editor/services/renderers/render_softbreak.js
diff --git a/app/assets/javascripts/vue_shared/components/rich_content_editor/services/renderers/render_utils.js b/app/assets/javascripts/static_site_editor/rich_content_editor/services/renderers/render_utils.js
index eff5dbf59f2..eff5dbf59f2 100644
--- a/app/assets/javascripts/vue_shared/components/rich_content_editor/services/renderers/render_utils.js
+++ b/app/assets/javascripts/static_site_editor/rich_content_editor/services/renderers/render_utils.js
diff --git a/app/assets/javascripts/vue_shared/components/rich_content_editor/services/sanitize_html.js b/app/assets/javascripts/static_site_editor/rich_content_editor/services/sanitize_html.js
index 486d88466b7..486d88466b7 100644
--- a/app/assets/javascripts/vue_shared/components/rich_content_editor/services/sanitize_html.js
+++ b/app/assets/javascripts/static_site_editor/rich_content_editor/services/sanitize_html.js
diff --git a/app/assets/javascripts/vue_shared/components/rich_content_editor/toolbar_item.vue b/app/assets/javascripts/static_site_editor/rich_content_editor/toolbar_item.vue
index 85a67c087bb..85a67c087bb 100644
--- a/app/assets/javascripts/vue_shared/components/rich_content_editor/toolbar_item.vue
+++ b/app/assets/javascripts/static_site_editor/rich_content_editor/toolbar_item.vue
diff --git a/app/views/import/_githubish_status.html.haml b/app/views/import/_githubish_status.html.haml
index 221529a048b..02a8f3142c6 100644
--- a/app/views/import/_githubish_status.html.haml
+++ b/app/views/import/_githubish_status.html.haml
@@ -5,6 +5,9 @@
- paginatable = local_assigns.fetch(:paginatable, false)
- provider_title = Gitlab::ImportSources.title(provider)
+- header_title _("New project"), new_project_path
+- add_to_breadcrumbs s_('ProjectsNew|Import project'), new_projects_path(anchor: 'import_project')
+
#import-projects-mount-element{ data: { provider: provider, provider_title: provider_title,
can_select_namespace: current_user.can_select_namespace?.to_s,
ci_cd_only: has_ci_cd_only_params?.to_s,
diff --git a/app/views/import/bitbucket_server/new.html.haml b/app/views/import/bitbucket_server/new.html.haml
index 8a3fe1a816c..ce6bdd7a2fb 100644
--- a/app/views/import/bitbucket_server/new.html.haml
+++ b/app/views/import/bitbucket_server/new.html.haml
@@ -1,7 +1,6 @@
-- title = _('Bitbucket Server Import')
-- page_title title
-- breadcrumb_title title
-- header_title _("Projects"), root_path
+- page_title _('Bitbucket Server Import')
+- header_title _("New project"), new_project_path
+- add_to_breadcrumbs s_('ProjectsNew|Import project'), new_projects_path(anchor: 'import_project')
%h3.page-title.d-flex
.gl-display-flex.gl-align-items-center.gl-justify-content-center
diff --git a/app/views/import/bitbucket_server/status.html.haml b/app/views/import/bitbucket_server/status.html.haml
index 7c4e6913c53..79b2810e06d 100644
--- a/app/views/import/bitbucket_server/status.html.haml
+++ b/app/views/import/bitbucket_server/status.html.haml
@@ -1,5 +1,4 @@
- page_title _('Bitbucket Server import')
-- header_title _('Projects'), root_path
%h3.page-title.d-flex
.gl-display-flex.gl-align-items-center.gl-justify-content-center
diff --git a/app/views/import/fogbugz/new.html.haml b/app/views/import/fogbugz/new.html.haml
index ab836174024..51156797270 100644
--- a/app/views/import/fogbugz/new.html.haml
+++ b/app/views/import/fogbugz/new.html.haml
@@ -1,5 +1,7 @@
- page_title _("FogBugz Import")
-- header_title _("Projects"), root_path
+- header_title _("New project"), new_project_path
+- add_to_breadcrumbs s_('ProjectsNew|Import project'), new_projects_path(anchor: 'import_project')
+
%h3.page-title.d-flex
.gl-display-flex.gl-align-items-center.gl-justify-content-center
= sprite_icon('bug', css_class: 'gl-mr-2')
diff --git a/app/views/import/fogbugz/new_user_map.html.haml b/app/views/import/fogbugz/new_user_map.html.haml
index 832289c3166..4281d77e833 100644
--- a/app/views/import/fogbugz/new_user_map.html.haml
+++ b/app/views/import/fogbugz/new_user_map.html.haml
@@ -1,5 +1,7 @@
- page_title _('User map'), _('FogBugz import')
-- header_title _("Projects"), root_path
+- header_title _("New project"), new_project_path
+- add_to_breadcrumbs s_('ProjectsNew|Import project'), new_projects_path(anchor: 'import_project')
+
%h3.page-title.d-flex
.gl-display-flex.gl-align-items-center.gl-justify-content-center
= sprite_icon('bug', css_class: 'gl-mr-2')
diff --git a/app/views/import/fogbugz/status.html.haml b/app/views/import/fogbugz/status.html.haml
index e04a412e3bc..dcc0e94441c 100644
--- a/app/views/import/fogbugz/status.html.haml
+++ b/app/views/import/fogbugz/status.html.haml
@@ -1,5 +1,4 @@
- page_title _("FogBugz import")
-- header_title _("Projects"), root_path
%h3.page-title.d-flex
.gl-display-flex.gl-align-items-center.gl-justify-content-center
= sprite_icon('bug', css_class: 'gl-mr-2')
diff --git a/app/views/import/gitea/new.html.haml b/app/views/import/gitea/new.html.haml
index 27786806d17..288ae5f1cec 100644
--- a/app/views/import/gitea/new.html.haml
+++ b/app/views/import/gitea/new.html.haml
@@ -1,5 +1,6 @@
- page_title _("Gitea Import")
-- header_title _("Projects"), root_path
+- header_title _("New project"), new_project_path
+- add_to_breadcrumbs s_('ProjectsNew|Import project'), new_projects_path(anchor: 'import_project')
%h3.page-title
= custom_icon('gitea_logo')
diff --git a/app/views/import/gitea/status.html.haml b/app/views/import/gitea/status.html.haml
index ef0693e73c3..1bdcec0c574 100644
--- a/app/views/import/gitea/status.html.haml
+++ b/app/views/import/gitea/status.html.haml
@@ -1,5 +1,4 @@
- page_title _("Gitea Import")
-- header_title _("Projects"), root_path
%h3.page-title
= custom_icon('gitea_logo')
= _('Import Projects from Gitea')
diff --git a/app/views/import/github/new.html.haml b/app/views/import/github/new.html.haml
index 32143f823d7..3407f9202bf 100644
--- a/app/views/import/github/new.html.haml
+++ b/app/views/import/github/new.html.haml
@@ -1,9 +1,9 @@
- title = _('Authenticate with GitHub')
- page_title title
-- breadcrumb_title title
-- header_title _("Projects"), root_path
+- header_title _("New project"), new_project_path
+- add_to_breadcrumbs s_('ProjectsNew|Import project'), new_projects_path(anchor: 'import_project')
-%h2.page-title
+%h3.page-title
= title
%p
diff --git a/app/views/import/github/status.html.haml b/app/views/import/github/status.html.haml
index b62f98f5ded..820c2f06c8f 100644
--- a/app/views/import/github/status.html.haml
+++ b/app/views/import/github/status.html.haml
@@ -1,7 +1,5 @@
- title = has_ci_cd_only_params? ? _('Connect repositories from GitHub') : _('GitHub import')
- page_title title
-- breadcrumb_title title
-- header_title _("Projects"), root_path
%h3.page-title.mb-0.gl-display-flex
.gl-display-flex.gl-align-items-center.gl-justify-content-center
= sprite_icon('github', css_class: 'gl-mr-2')
diff --git a/app/views/import/gitlab/status.html.haml b/app/views/import/gitlab/status.html.haml
index ef803a36e79..b7b1fae1b73 100644
--- a/app/views/import/gitlab/status.html.haml
+++ b/app/views/import/gitlab/status.html.haml
@@ -1,5 +1,4 @@
- page_title _("GitLab.com import")
-- header_title _("Projects"), root_path
%h3.page-title
= sprite_icon('heart', css_class: 'gl-vertical-align-middle')
= _('Import projects from GitLab.com')
diff --git a/app/views/import/gitlab_projects/new.html.haml b/app/views/import/gitlab_projects/new.html.haml
index 8ba62c91e6a..8daddbb0042 100644
--- a/app/views/import/gitlab_projects/new.html.haml
+++ b/app/views/import/gitlab_projects/new.html.haml
@@ -1,5 +1,6 @@
- page_title _("GitLab Import")
-- header_title _("Projects"), root_path
+- header_title _("New project"), new_project_path
+- add_to_breadcrumbs s_('ProjectsNew|Import project'), new_projects_path(anchor: 'import_project')
%h3.page-title.d-flex
.gl-display-flex.gl-align-items-center.gl-justify-content-center
diff --git a/app/views/import/manifest/new.html.haml b/app/views/import/manifest/new.html.haml
index 852f269f2ed..bfaff3bb300 100644
--- a/app/views/import/manifest/new.html.haml
+++ b/app/views/import/manifest/new.html.haml
@@ -1,5 +1,7 @@
- page_title _("Manifest file import")
-- header_title _("Projects"), root_path
+- header_title _("New project"), new_project_path
+- add_to_breadcrumbs s_('ProjectsNew|Import project'), new_projects_path(anchor: 'import_project')
+
%h3.page-title
= _('Manifest file import')
diff --git a/app/views/import/manifest/status.html.haml b/app/views/import/manifest/status.html.haml
index c3e77554b09..45d03575713 100644
--- a/app/views/import/manifest/status.html.haml
+++ b/app/views/import/manifest/status.html.haml
@@ -1,5 +1,4 @@
- page_title _("Manifest import")
-- header_title _("Projects"), root_path
%h3.page-title
= _('Manifest file import')
diff --git a/app/views/import/phabricator/new.html.haml b/app/views/import/phabricator/new.html.haml
index 960d3df2c42..9596fdb615a 100644
--- a/app/views/import/phabricator/new.html.haml
+++ b/app/views/import/phabricator/new.html.haml
@@ -1,7 +1,6 @@
-- title = _('Phabricator Server Import')
-- page_title title
-- breadcrumb_title title
-- header_title _("Projects"), root_path
+- page_title _('Phabricator Server Import')
+- header_title _("New project"), new_project_path
+- add_to_breadcrumbs s_('ProjectsNew|Import project'), new_projects_path(anchor: 'import_project')
%h3.page-title.d-flex
.gl-display-flex.gl-align-items-center.gl-justify-content-center
diff --git a/app/views/projects/ci/builds/_build.html.haml b/app/views/projects/ci/builds/_build.html.haml
index 0cc595de7be..824e876500b 100644
--- a/app/views/projects/ci/builds/_build.html.haml
+++ b/app/views/projects/ci/builds/_build.html.haml
@@ -97,7 +97,7 @@
#{job.coverage}%
%td
- .gl-display-flex
+ .gl-text-right
.btn-group
- if can?(current_user, :read_job_artifacts, job) && job.artifacts?
= link_to download_project_job_artifacts_path(job.project, job), rel: 'nofollow', download: '', title: _('Download artifacts'), class: 'gl-button btn btn-default btn-icon' do
diff --git a/app/views/projects/jobs/_table.html.haml b/app/views/projects/jobs/_table.html.haml
index 819837a9eff..2d8b7315a29 100644
--- a/app/views/projects/jobs/_table.html.haml
+++ b/app/views/projects/jobs/_table.html.haml
@@ -12,7 +12,7 @@
= s_('Jobs|Use jobs to automate your tasks')
%p
= s_('Jobs|Jobs are the building blocks of a GitLab CI/CD pipeline. Each job has a specific task, like testing code. To set up jobs in a CI/CD pipeline, add a CI/CD configuration file to your project.')
- = link_to s_('Jobs|Create CI/CD configuration file'), project_ci_pipeline_editor_path(project), class: 'btn gl-button btn-info js-empty-state-button'
+ = link_to s_('Jobs|Create CI/CD configuration file'), project_ci_pipeline_editor_path(project), class: 'btn gl-button btn-confirm js-empty-state-button'
- else
.nothing-here-block= s_('Jobs|No jobs to show')
- else
diff --git a/config/initializers/active_record_ping.rb b/config/initializers/active_record_postgresql_adapter.rb
index 7088c690a51..6bf38506e37 100644
--- a/config/initializers/active_record_ping.rb
+++ b/config/initializers/active_record_postgresql_adapter.rb
@@ -1,7 +1,9 @@
# frozen_string_literal: true
-# # frozen_string_literal: true
-
if Gitlab::Utils.to_boolean(ENV['ENABLE_ACTIVERECORD_EMPTY_PING'], default: true)
ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.prepend(Gitlab::Database::PostgresqlAdapter::EmptyQueryPing)
end
+
+if Gitlab::Utils.to_boolean(ENV['ENABLE_ACTIVERECORD_TYPEMAP_CACHE'], default: false)
+ ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.prepend(Gitlab::Database::PostgresqlAdapter::TypeMapCache)
+end
diff --git a/doc/administration/geo/replication/datatypes.md b/doc/administration/geo/replication/datatypes.md
index e2f12cbd8dc..ddcb7372fc2 100644
--- a/doc/administration/geo/replication/datatypes.md
+++ b/doc/administration/geo/replication/datatypes.md
@@ -180,7 +180,7 @@ successfully, you must replicate their data using some other means.
|[Project wiki repository](../../../user/project/wiki/) | **Yes** (10.2) | **Yes** (10.7) | No | |
|[Group wiki repository](../../../user/project/wiki/index.md#group-wikis) | [**Yes** (13.10)](https://gitlab.com/gitlab-org/gitlab/-/issues/208147) | No | No | Behind feature flag `geo_group_wiki_repository_replication`, enabled by default. |
|[Uploads](../../uploads.md) | **Yes** (10.2) | [No](https://gitlab.com/groups/gitlab-org/-/epics/1817) | No | Verified only on transfer or manually using [Integrity Check Rake Task](../../raketasks/check.md) on both sites and comparing the output between them. |
-|[LFS objects](../../lfs/index.md) | **Yes** (10.2) | [No](https://gitlab.com/gitlab-org/gitlab/-/issues/8922) | Via Object Storage provider if supported. Native Geo support (Beta). | Verified only on transfer or manually using [Integrity Check Rake Task](../../raketasks/check.md) on both sites and comparing the output between them. GitLab versions 11.11.x and 12.0.x are affected by [a bug that prevents any new LFS objects from replicating](https://gitlab.com/gitlab-org/gitlab/-/issues/32696). |
+|[LFS objects](../../lfs/index.md) | **Yes** (10.2) | [No](https://gitlab.com/gitlab-org/gitlab/-/issues/8922) | Via Object Storage provider if supported. Native Geo support (Beta). | Verified only on transfer or manually using [Integrity Check Rake Task](../../raketasks/check.md) on both sites and comparing the output between them. GitLab versions 11.11.x and 12.0.x are affected by [a bug that prevents any new LFS objects from replicating](https://gitlab.com/gitlab-org/gitlab/-/issues/32696).<br /><br />Behind feature flag `geo_lfs_object_replication`, enabled by default. |
|[Personal snippets](../../../user/snippets.md) | **Yes** (10.2) | **Yes** (10.2) | No | |
|[Project snippets](../../../user/snippets.md) | **Yes** (10.2) | **Yes** (10.2) | No | |
|[CI job artifacts (other than Job Logs)](../../../ci/pipelines/job_artifacts.md) | **Yes** (10.4) | [No](https://gitlab.com/gitlab-org/gitlab/-/issues/8923) | Via Object Storage provider if supported. Native Geo support (Beta). | Verified only manually using [Integrity Check Rake Task](../../raketasks/check.md) on both sites and comparing the output between them. |
@@ -205,33 +205,3 @@ successfully, you must replicate their data using some other means.
|[GitLab Pages](../../pages/index.md) | [No](https://gitlab.com/groups/gitlab-org/-/epics/589) | No | No | |
|[Dependency proxy images](../../../user/packages/dependency_proxy/index.md) | [No](https://gitlab.com/gitlab-org/gitlab/-/issues/259694) | No | No | Blocked on [Geo: Secondary Mimicry](https://gitlab.com/groups/gitlab-org/-/epics/1528). Note that replication of this cache is not needed for Disaster Recovery purposes because it can be recreated from external sources. |
|[Vulnerability Export](../../../user/application_security/vulnerability_report/#export-vulnerability-details) | [Not planned](https://gitlab.com/groups/gitlab-org/-/epics/3111) | No | Via Object Storage provider if supported. Native Geo support (Beta). | Not planned because they are ephemeral and sensitive. They can be regenerated on demand. |
-
-#### LFS object replication using the self service framework
-
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/276696) in GitLab 13.12.
-> - [Deployed behind a feature flag](../../../user/feature_flags.md), enabled by default.
-> - Not enabled on GitLab.com as Geo is not enabled.
-> - Recommended for production use.
-> - For GitLab self-managed instances, GitLab administrators can opt to [disable it](#enable-or-disable-lfs-object-replication-using-the-self-service-framework).
-
-There can be [risks when disabling released features](../../../user/feature_flags.md#risks-when-disabling-released-features).
-Refer to this feature's version history for more details.
-
-##### Enable or disable LFS object replication using the self service framework
-
-LFS object replication using the self service framework is under development but ready for production use. It is
-deployed behind a feature flag that is **enabled by default**.
-[GitLab administrators with access to the GitLab Rails console](../../../administration/feature_flags.md)
-can opt to disable it.
-
-To enable it:
-
-```ruby
-Feature.enable(:geo_lfs_object_replication)
-```
-
-To disable it:
-
-```ruby
-Feature.disable(:geo_lfs_object_replication)
-```
diff --git a/doc/administration/pages/index.md b/doc/administration/pages/index.md
index e0ee201d25d..b9637f1b6f5 100644
--- a/doc/administration/pages/index.md
+++ b/doc/administration/pages/index.md
@@ -246,7 +246,7 @@ control over how the Pages daemon runs and serves content in your environment.
| `gitlab_retrieval_timeout` | The maximum time to wait for a response from the GitLab API per request (default: 30s). |
| `gitlab_retrieval_interval` | The interval to wait before retrying to resolve a domain's configuration via the GitLab API (default: 1s). |
| `gitlab_retrieval_retries` | The maximum number of times to retry to resolve a domain's configuration via the API (default: 3). |
-| `domain_config_source` | Domain configuration source (default: `auto`) |
+| `domain_config_source` | This parameter was removed in 14.0, on earlier versions it can be used to enable and test API domain configuration source |
| `gitlab_id` | The OAuth application public ID. Leave blank to automatically fill when Pages authenticates with GitLab. |
| `gitlab_secret` | The OAuth application secret. Leave blank to automatically fill when Pages authenticates with GitLab. |
| `auth_scope` | The OAuth application scope to use for authentication. Must match GitLab Pages OAuth application settings. Leave blank to use `api` scope by default. |
@@ -281,6 +281,7 @@ control over how the Pages daemon runs and serves content in your environment.
| **`pages_nginx[]`** | |
| `enable` | Include a virtual host `server{}` block for Pages inside NGINX. Needed for NGINX to proxy traffic back to the Pages daemon. Set to `false` if the Pages daemon should directly receive all requests, for example, when using [custom domains](index.md#custom-domains). |
| `FF_ENABLE_REDIRECTS` | Feature flag to disable redirects (enabled by default). Read the [redirects documentation](../../user/project/pages/redirects.md#disable-redirects) for more information. |
+| `use_legacy_storage` | Temporarily-introduced parameter allowing to use legacy domain configuration source and storage. [Will be removed in GitLab 14.3](https://gitlab.com/gitlab-org/omnibus-gitlab/-/issues/6166). |
---
@@ -756,51 +757,37 @@ Pages server.
## Domain source configuration
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/217912) in GitLab 13.3.
+When GitLab Pages daemon serves pages requests it firstly needs to identify which project should be used to
+serve the requested URL and how its content is stored.
-GitLab Pages can use different sources to get domain configuration.
-The default value for Omnibus installations is `nil`.
+Before GitLab 13.3, all pages content was extracted to the special shared directory,
+and each project had a special configuration file.
+The Pages daemon was reading these configuration files and storing their content in memory.
- ```ruby
- gitlab_pages['domain_config_source'] = nil
- ```
+This approach had several disadvantages and was replaced with GitLab Pages using the internal GitLab API
+every time a new domain is requested.
+The domain information is also cached by the Pages daemon to speed up subsequent requests.
-If left unchanged, GitLab Pages tries to use any available source (either `gitlab` or `disk`). The
-preferred source is `gitlab`, which uses [API-based configuration](#gitlab-api-based-configuration).
+From [GitLab 13.3 to GitLab 13.12](#domain-source-configuration-before-140) GitLab Pages supported both ways of obtaining domain information.
-On large GitLab instances, using the API-based configuration significantly improves the pages daemon startup time, as there is no need to load all custom domains configuration into memory.
+Starting from [GitLab 14.0](https://gitlab.com/gitlab-org/omnibus-gitlab/-/issues/5993) GitLab Pages uses API
+by default and fails to start if it can't connect to it.
+For common issues, see the [troubleshooting section](#failed-to-connect-to-the-internal-gitlab-api).
For more details see this [blog post](https://about.gitlab.com/blog/2020/08/03/how-gitlab-pages-uses-the-gitlab-api-to-serve-content/).
-### Deprecated `domain_config_source`
-
-WARNING:
-The flag `gitlab_pages['domain_config_source']` is deprecated for use in [GitLab 13.9](https://gitlab.com/gitlab-org/gitlab/-/issues/217913),
-and is planned for removal in GitLab 14.0.
-
-GitLab 13.0 introduced the special flag `domain_config_source` to support manual opt-in to
-[API-based configuration](#gitlab-api-based-configuration).
-GitLab 13.7 introduced the [`auto` value](https://gitlab.com/gitlab-org/gitlab/-/issues/218358)
-to support a smoother transition to API-based configuration.
+### Domain source configuration before 14.0
-Starting with GitLab 14.0, GitLab Pages only supports API-based configuration, and
-[disk source configuration is removed](https://gitlab.com/gitlab-org/gitlab-pages/-/issues/382).
-Therefore, GitLab 14.0 also removes `domain_config_source`.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/217912) in GitLab 13.3.
-GitLab Pages fails to start if it can't connect to the GitLab API. For other common issues, see the
-[troubleshooting section](#failed-to-connect-to-the-internal-gitlab-api)
-or report an issue.
+WARNING:
+`domain_config_source` parameter is removed and has no effect starting from [GitLab 14.0](https://gitlab.com/gitlab-org/omnibus-gitlab/-/issues/5993)
-### GitLab API-based configuration
+From [GitLab 13.3](https://gitlab.com/gitlab-org/gitlab/-/issues/217912) to [GitLab 13.12](https://gitlab.com/gitlab-org/omnibus-gitlab/-/issues/5993) GitLab Pages can either use `disk` or `gitlab` domain configuration source.
-WARNING:
-The flag `gitlab_pages['domain_config_source']` is deprecated for use in [GitLab 13.9](https://gitlab.com/gitlab-org/gitlab/-/issues/217913),
-and is planned for removal in GitLab 14.0. In GitLab 14.0 and later, GitLab Pages attempts to
-connect to the API automatically, without requiring the manual configuration steps shown here. Pages
-fails to start if this automatic connection fails.
+We highly advise you to use `gitlab` configuration source as it will make transition to newer versions easier.
-GitLab Pages can use an API-based configuration. This replaces disk source configuration, which
-was used prior to GitLab 13.0. Follow these steps to enable it:
+To explicitly enable API source:
1. Add the following to your `/etc/gitlab/gitlab.rb` file:
@@ -810,14 +797,15 @@ was used prior to GitLab 13.0. Follow these steps to enable it:
1. [Reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure) for the changes to take effect.
-If you encounter an issue, you can disable it by choosing `disk`:
+Or if you want to use legacy confiration source you can:
-```ruby
-gitlab_pages['domain_config_source'] = "disk"
-```
+1. Add the following to your `/etc/gitlab/gitlab.rb` file:
+
+ ```ruby
+ gitlab_pages['domain_config_source'] = "disk"
+ ```
-For other common issues, see the [troubleshooting section](#failed-to-connect-to-the-internal-gitlab-api)
-or report an issue.
+1. [Reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure) for the changes to take effect.
### GitLab API cache configuration
@@ -1052,7 +1040,7 @@ To migrate GitLab Pages to GitLab 14.0:
1. If your current GitLab version is lower than 13.12, then you first need to upgrade to 13.12.
Upgrading directly to 14.0 may cause downtime for some web-sites hosted on GitLab Pages
until you finish the following steps.
-1. Enable the [API-based configuration](#gitlab-api-based-configuration), which
+1. Set [`domain_config_source` to `gitlab`](#domain-source-configuration-before-140), which
is the default starting from GitLab 14.0. Skip this step if you're already running GitLab 14.0 or above.
1. If you want to store your pages content in the [object storage](#using-object-storage), make sure to configure it.
If you want to store the pages content locally or continue using an NFS server, skip this step.
@@ -1082,6 +1070,16 @@ but commented out to help encourage others to add to it in the future. -->
## Troubleshooting
+### How to see GitLab Pages logs
+
+You can see Pages daemon logs by running:
+
+```shell
+sudo gitlab-ctl tail gitlab-pages
+```
+
+You can also find the log file in `/var/log/gitlab/gitlab-pages/current`.
+
### `open /etc/ssl/ca-bundle.pem: permission denied`
GitLab Pages runs inside a `chroot` jail, usually in a uniquely numbered directory like
@@ -1216,7 +1214,7 @@ Alternatively, run the CI pipelines of those projects that contain a `pages` job
### Failed to connect to the internal GitLab API
-If you have enabled [API-based configuration](#gitlab-api-based-configuration) and see the following error:
+If you see the following error:
```plaintext
ERRO[0010] Failed to connect to the internal GitLab API after 0.50s error="failed to connect to internal Pages API: HTTP status: 401"
@@ -1237,11 +1235,6 @@ error="failed to connect to internal Pages API: Get \"https://gitlab.example.com
### Pages cannot communicate with an instance of the GitLab API
-WARNING:
-The flag `gitlab_pages['domain_config_source']` is [deprecated](#deprecated-domain_config_source)
-for use in [GitLab 13.9](https://gitlab.com/gitlab-org/gitlab/-/issues/217913),
-and is planned for removal in GitLab 14.0.
-
If you use the default value for `domain_config_source=auto` and run multiple instances of GitLab
Pages, you may see intermittent 502 error responses while serving Pages content. You may also see
the following warning in the Pages logs:
@@ -1322,3 +1315,25 @@ To enable disk access:
```
1. [Reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure).
+
+### GitLab Pages doesn't work after upgrading to GitLab 14.0 or above
+
+GitLab 14.0 introduces a number of changes to GitLab Pages which may require manual intervention.
+
+1. Firstly [follow the migration guide](#migrate-gitlab-pages-to-140).
+1. If it doesn't work, see [GitLab Pages logs](#how-to-see-gitlab-pages-logs), and if you see any errors there then search them on this page.
+
+WARNING:
+As the last resort you can temporarily enable legacy storage and configuration mechanisms. Support for them [will be removed in GitLab 14.3](https://gitlab.com/gitlab-org/omnibus-gitlab/-/issues/6166), so GitLab Pages will stop working if don't resolve the underlying issue.
+
+To do that:
+
+1. Please describe the issue you're seeing in [here](https://gitlab.com/gitlab-org/gitlab/-/issues/331699).
+
+1. Edit `/etc/gitlab/gitlab.rb`:
+
+ ```ruby
+ gitlab_pages['use_legacy_storage'] = true
+ ```
+
+1. [Reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure).
diff --git a/doc/api/boards.md b/doc/api/boards.md
index 3252036c840..3cdd9552d66 100644
--- a/doc/api/boards.md
+++ b/doc/api/boards.md
@@ -250,7 +250,8 @@ Example response:
"path_with_namespace": "diaspora/diaspora-project-site",
"created_at": "2018-07-03T05:48:49.982Z",
"default_branch": null,
- "tag_list": [],
+ "tag_list": [], //deprecated, use `topics` instead
+ "topics": [],
"ssh_url_to_repo": "ssh://user@example.com/diaspora/diaspora-project-site.git",
"http_url_to_repo": "http://example.com/diaspora/diaspora-project-site.git",
"web_url": "http://example.com/diaspora/diaspora-project-site",
diff --git a/doc/api/groups.md b/doc/api/groups.md
index 5976f0f005d..54119ba64f3 100644
--- a/doc/api/groups.md
+++ b/doc/api/groups.md
@@ -302,7 +302,8 @@ Example response:
"id": 9,
"description": "foo",
"default_branch": "master",
- "tag_list": [],
+ "tag_list": [], //deprecated, use `topics` instead
+ "topics": [],
"archived": false,
"visibility": "internal",
"ssh_url_to_repo": "git@gitlab.example.com/html5-boilerplate.git",
@@ -381,9 +382,8 @@ Example response:
"path_with_namespace":"h5bp/html5-boilerplate",
"created_at":"2020-04-27T06:13:22.642Z",
"default_branch":"master",
- "tag_list":[
-
- ],
+ "tag_list":[], //deprecated, use `topics` instead
+ "topics":[],
"ssh_url_to_repo":"ssh://git@gitlab.com/h5bp/html5-boilerplate.git",
"http_url_to_repo":"http://gitlab.com/h5bp/html5-boilerplate.git",
"web_url":"http://gitlab.com/h5bp/html5-boilerplate",
@@ -540,7 +540,8 @@ Example response:
"id": 7,
"description": "Voluptas veniam qui et beatae voluptas doloremque explicabo facilis.",
"default_branch": "master",
- "tag_list": [],
+ "tag_list": [], //deprecated, use `topics` instead
+ "topics": [],
"archived": false,
"visibility": "public",
"ssh_url_to_repo": "git@gitlab.example.com:twitter/typeahead-js.git",
@@ -578,7 +579,8 @@ Example response:
"id": 6,
"description": "Aspernatur omnis repudiandae qui voluptatibus eaque.",
"default_branch": "master",
- "tag_list": [],
+ "tag_list": [], //deprecated, use `topics` instead
+ "topics": [],
"archived": false,
"visibility": "internal",
"ssh_url_to_repo": "git@gitlab.example.com:twitter/flight.git",
@@ -618,7 +620,8 @@ Example response:
"id": 8,
"description": "Velit eveniet provident fugiat saepe eligendi autem.",
"default_branch": "master",
- "tag_list": [],
+ "tag_list": [], //deprecated, use `topics` instead
+ "topics": [],
"archived": false,
"visibility": "private",
"ssh_url_to_repo": "git@gitlab.example.com:h5bp/html5-boilerplate.git",
@@ -886,7 +889,8 @@ Example response:
"id": 9,
"description": "foo",
"default_branch": "master",
- "tag_list": [],
+ "tag_list": [], //deprecated, use `topics` instead
+ "topics": [],
"public": false,
"archived": false,
"visibility": "internal",
diff --git a/doc/api/project_clusters.md b/doc/api/project_clusters.md
index ab7ad241631..88a4d10a08a 100644
--- a/doc/api/project_clusters.md
+++ b/doc/api/project_clusters.md
@@ -151,7 +151,8 @@ Example response:
"path_with_namespace":"root/project-with-clusters-api",
"created_at":"2019-01-02T20:13:32.600Z",
"default_branch":null,
- "tag_list":[],
+ "tag_list":[], //deprecated, use `topics` instead
+ "topics":[],
"ssh_url_to_repo":"ssh://gitlab.example.com/root/project-with-clusters-api.git",
"http_url_to_repo":"https://gitlab.example.com/root/project-with-clusters-api.git",
"web_url":"https://gitlab.example.com/root/project-with-clusters-api",
@@ -247,7 +248,8 @@ Example response:
"path_with_namespace":"root/project-with-clusters-api",
"created_at":"2019-01-02T20:13:32.600Z",
"default_branch":null,
- "tag_list":[],
+ "tag_list":[], //deprecated, use `topics` instead
+ "topics":[],
"ssh_url_to_repo":"ssh:://gitlab.example.com/root/project-with-clusters-api.git",
"http_url_to_repo":"https://gitlab.example.com/root/project-with-clusters-api.git",
"web_url":"https://gitlab.example.com/root/project-with-clusters-api",
@@ -357,7 +359,8 @@ Example response:
"path_with_namespace":"root/project-with-clusters-api",
"created_at":"2019-01-02T20:13:32.600Z",
"default_branch":null,
- "tag_list":[],
+ "tag_list":[], //deprecated, use `topics` instead
+ "topics":[],
"ssh_url_to_repo":"ssh:://gitlab.example.com/root/project-with-clusters-api.git",
"http_url_to_repo":"https://gitlab.example.com/root/project-with-clusters-api.git",
"web_url":"https://gitlab.example.com/root/project-with-clusters-api",
diff --git a/doc/api/projects.md b/doc/api/projects.md
index 6fd9ca81b8c..3e32b6f0aa3 100644
--- a/doc/api/projects.md
+++ b/doc/api/projects.md
@@ -59,7 +59,7 @@ GET /projects
| `sort` | string | **{dotted-circle}** No | Return projects sorted in `asc` or `desc` order. Default is `desc`. |
| `starred` | boolean | **{dotted-circle}** No | Limit by projects starred by the current user. |
| `statistics` | boolean | **{dotted-circle}** No | Include project statistics. |
-| `topic` | string | **{dotted-circle}** No | Comma-separated topic names. Limit results to projects that match all of given topics. See `tag_list` attribute. |
+| `topic` | string | **{dotted-circle}** No | Comma-separated topic names. Limit results to projects that match all of given topics. See `topics` attribute. |
| `visibility` | string | **{dotted-circle}** No | Limit by visibility `public`, `internal`, or `private`. |
| `wiki_checksum_failed` **(PREMIUM)** | boolean | **{dotted-circle}** No | Limit projects where the wiki checksum calculation has failed ([Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/6137) in [GitLab Premium](https://about.gitlab.com/pricing/) 11.2). |
| `with_custom_attributes` | boolean | **{dotted-circle}** No | Include [custom attributes](custom_attributes.md) in response. _(admins only)_ |
@@ -82,7 +82,11 @@ When `simple=true` or the user is unauthenticated this returns something like:
"http_url_to_repo": "http://example.com/diaspora/diaspora-client.git",
"web_url": "http://example.com/diaspora/diaspora-client",
"readme_url": "http://example.com/diaspora/diaspora-client/blob/master/README.md",
- "tag_list": [
+ "tag_list": [ //deprecated, use `topics` instead
+ "example",
+ "disapora client"
+ ],
+ "topics": [
"example",
"disapora client"
],
@@ -116,7 +120,11 @@ When the user is authenticated and `simple` is not set this returns something li
"http_url_to_repo": "http://example.com/diaspora/diaspora-client.git",
"web_url": "http://example.com/diaspora/diaspora-client",
"readme_url": "http://example.com/diaspora/diaspora-client/blob/master/README.md",
- "tag_list": [
+ "tag_list": [ //deprecated, use `topics` instead
+ "example",
+ "disapora client"
+ ],
+ "topics": [
"example",
"disapora client"
],
@@ -200,7 +208,11 @@ When the user is authenticated and `simple` is not set this returns something li
"http_url_to_repo": "http://example.com/brightbox/puppet.git",
"web_url": "http://example.com/brightbox/puppet",
"readme_url": "http://example.com/brightbox/puppet/blob/master/README.md",
- "tag_list": [
+ "tag_list": [ //deprecated, use `topics` instead
+ "example",
+ "puppet"
+ ],
+ "topics": [
"example",
"puppet"
],
@@ -301,6 +313,10 @@ When the user is authenticated and `simple` is not set this returns something li
```
NOTE:
+The `tag_list` attribute has been deprecated
+and is removed in API v5 in favor of the `topics` attribute.
+
+NOTE:
For users of [GitLab Premium or higher](https://about.gitlab.com/pricing/),
the `marked_for_deletion_at` attribute has been deprecated, and is removed
in API v5 in favor of the `marked_for_deletion_on` attribute.
@@ -378,7 +394,11 @@ GET /users/:user_id/projects
"http_url_to_repo": "http://example.com/diaspora/diaspora-client.git",
"web_url": "http://example.com/diaspora/diaspora-client",
"readme_url": "http://example.com/diaspora/diaspora-client/blob/master/README.md",
- "tag_list": [
+ "tag_list": [ //deprecated, use `topics` instead
+ "example",
+ "disapora client"
+ ],
+ "topics": [
"example",
"disapora client"
],
@@ -462,7 +482,11 @@ GET /users/:user_id/projects
"http_url_to_repo": "http://example.com/brightbox/puppet.git",
"web_url": "http://example.com/brightbox/puppet",
"readme_url": "http://example.com/brightbox/puppet/blob/master/README.md",
- "tag_list": [
+ "tag_list": [ //deprecated, use `topics` instead
+ "example",
+ "puppet"
+ ],
+ "topics": [
"example",
"puppet"
],
@@ -606,7 +630,11 @@ Example response:
"http_url_to_repo": "http://example.com/diaspora/diaspora-client.git",
"web_url": "http://example.com/diaspora/diaspora-client",
"readme_url": "http://example.com/diaspora/diaspora-client/blob/master/README.md",
- "tag_list": [
+ "tag_list": [ //deprecated, use `topics` instead
+ "example",
+ "disapora client"
+ ],
+ "topics": [
"example",
"disapora client"
],
@@ -683,7 +711,11 @@ Example response:
"http_url_to_repo": "http://example.com/brightbox/puppet.git",
"web_url": "http://example.com/brightbox/puppet",
"readme_url": "http://example.com/brightbox/puppet/blob/master/README.md",
- "tag_list": [
+ "tag_list": [ //deprecated, use `topics` instead
+ "example",
+ "puppet"
+ ],
+ "topics": [
"example",
"puppet"
],
@@ -804,7 +836,11 @@ GET /projects/:id
"http_url_to_repo": "http://example.com/diaspora/diaspora-project-site.git",
"web_url": "http://example.com/diaspora/diaspora-project-site",
"readme_url": "http://example.com/diaspora/diaspora-project-site/blob/master/README.md",
- "tag_list": [
+ "tag_list": [ //deprecated, use `topics` instead
+ "example",
+ "disapora project"
+ ],
+ "topics": [
"example",
"disapora project"
],
@@ -940,6 +976,10 @@ GET /projects/:id
}
```
+NOTE:
+The `tag_list` attribute has been deprecated
+and is removed in API v5 in favor of the `topics` attribute.
+
Users of [GitLab Premium or higher](https://about.gitlab.com/pricing/)
can also see the `approvals_before_merge` parameter:
@@ -974,7 +1014,8 @@ If the project is a fork, and you provide a valid token to authenticate, the
"path_with_namespace":"gitlab-org/gitlab-foss",
"created_at":"2013-09-26T06:02:36.000Z",
"default_branch":"master",
- "tag_list":[],
+ "tag_list":[], //deprecated, use `topics` instead
+ "topics":[],
"ssh_url_to_repo":"git@gitlab.com:gitlab-org/gitlab-foss.git",
"http_url_to_repo":"https://gitlab.com/gitlab-org/gitlab-foss.git",
"web_url":"https://gitlab.com/gitlab-org/gitlab-foss",
@@ -1393,7 +1434,11 @@ Example responses:
"http_url_to_repo": "http://example.com/diaspora/diaspora-project-site.git",
"web_url": "http://example.com/diaspora/diaspora-project-site",
"readme_url": "http://example.com/diaspora/diaspora-project-site/blob/master/README.md",
- "tag_list": [
+ "tag_list": [ //deprecated, use `topics` instead
+ "example",
+ "disapora project"
+ ],
+ "topics": [
"example",
"disapora project"
],
@@ -1480,7 +1525,11 @@ Example response:
"http_url_to_repo": "http://example.com/diaspora/diaspora-project-site.git",
"web_url": "http://example.com/diaspora/diaspora-project-site",
"readme_url": "http://example.com/diaspora/diaspora-project-site/blob/master/README.md",
- "tag_list": [
+ "tag_list": [ //deprecated, use `topics` instead
+ "example",
+ "disapora project"
+ ],
+ "topics": [
"example",
"disapora project"
],
@@ -1573,7 +1622,11 @@ Example response:
"http_url_to_repo": "http://example.com/diaspora/diaspora-project-site.git",
"web_url": "http://example.com/diaspora/diaspora-project-site",
"readme_url": "http://example.com/diaspora/diaspora-project-site/blob/master/README.md",
- "tag_list": [
+ "tag_list": [ //deprecated, use `topics` instead
+ "example",
+ "disapora project"
+ ],
+ "topics": [
"example",
"disapora project"
],
@@ -1741,7 +1794,11 @@ Example response:
"http_url_to_repo": "http://example.com/diaspora/diaspora-project-site.git",
"web_url": "http://example.com/diaspora/diaspora-project-site",
"readme_url": "http://example.com/diaspora/diaspora-project-site/blob/master/README.md",
- "tag_list": [
+ "tag_list": [ //deprecated, use `topics` instead
+ "example",
+ "disapora project"
+ ],
+ "topics": [
"example",
"disapora project"
],
@@ -1855,7 +1912,11 @@ Example response:
"http_url_to_repo": "http://example.com/diaspora/diaspora-project-site.git",
"web_url": "http://example.com/diaspora/diaspora-project-site",
"readme_url": "http://example.com/diaspora/diaspora-project-site/blob/master/README.md",
- "tag_list": [
+ "tag_list": [ //deprecated, use `topics` instead
+ "example",
+ "disapora project"
+ ],
+ "topics": [
"example",
"disapora project"
],
@@ -2441,7 +2502,8 @@ Example response:
"path_with_namespace": "cute-cats/hello-world",
"created_at": "2020-10-15T16:25:22.415Z",
"default_branch": "master",
- "tag_list": [],
+ "tag_list": [], //deprecated, use `topics` instead
+ "topics": [],
"ssh_url_to_repo": "git@gitlab.example.com:cute-cats/hello-world.git",
"http_url_to_repo": "https://gitlab.example.com/cute-cats/hello-world.git",
"web_url": "https://gitlab.example.com/cute-cats/hello-world",
diff --git a/doc/api/search.md b/doc/api/search.md
index c8f24c0924a..cc5a23cd7a7 100644
--- a/doc/api/search.md
+++ b/doc/api/search.md
@@ -54,7 +54,8 @@ Example response:
"path_with_namespace": "twitter/flight",
"created_at": "2017-09-05T07:58:01.621Z",
"default_branch": "master",
- "tag_list":[],
+ "tag_list":[], //deprecated, use `topics` instead
+ "topics":[],
"ssh_url_to_repo": "ssh://jarka@localhost:2222/twitter/flight.git",
"http_url_to_repo": "http://localhost:3000/twitter/flight.git",
"web_url": "http://localhost:3000/twitter/flight",
@@ -475,7 +476,8 @@ Example response:
"path_with_namespace": "twitter/flight",
"created_at": "2017-09-05T07:58:01.621Z",
"default_branch": "master",
- "tag_list":[],
+ "tag_list":[], //deprecated, use `topics` instead
+ "topics":[],
"ssh_url_to_repo": "ssh://jarka@localhost:2222/twitter/flight.git",
"http_url_to_repo": "http://localhost:3000/twitter/flight.git",
"web_url": "http://localhost:3000/twitter/flight",
diff --git a/doc/architecture/blueprints/container_registry_metadata_database/index.md b/doc/architecture/blueprints/container_registry_metadata_database/index.md
index 86628b31536..7ff9a523fea 100644
--- a/doc/architecture/blueprints/container_registry_metadata_database/index.md
+++ b/doc/architecture/blueprints/container_registry_metadata_database/index.md
@@ -1,6 +1,6 @@
---
-stage: package
-group: package
+stage: Package
+group: Package
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
comments: false
description: 'Container Registry metadata database'
diff --git a/doc/development/usage_ping/dictionary.md b/doc/development/usage_ping/dictionary.md
index 2002c70e7d0..f3e78c08747 100644
--- a/doc/development/usage_ping/dictionary.md
+++ b/doc/development/usage_ping/dictionary.md
@@ -7174,6 +7174,18 @@ Status: `data_available`
Tiers: `free`
+### `license_billable_users`
+
+Number of all billable users (active users excluding bots and guests).
+
+[YAML definition](https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/config/metrics/license/20210531204603_license_billable_users.yml)
+
+Group: `group::product intelligence`
+
+Status: `implemented`
+
+Tiers: `premium`, `ultimate`
+
### `license_expires_at`
The date the license ends
diff --git a/doc/user/application_security/container_scanning/index.md b/doc/user/application_security/container_scanning/index.md
index 336fffc380b..ef5a97f0c9d 100644
--- a/doc/user/application_security/container_scanning/index.md
+++ b/doc/user/application_security/container_scanning/index.md
@@ -175,7 +175,7 @@ You can [configure](#customizing-the-container-scanning-settings) analyzers by u
| `CI_APPLICATION_TAG` | `$CI_COMMIT_SHA` | Docker repository tag for the image to be scanned. | All |
| `CS_ANALYZER_IMAGE` | `$SECURE_ANALYZERS_PREFIX/$CS_PROJECT:$CS_MAJOR_VERSION` | Docker image of the analyzer. | All |
| `CS_DOCKER_INSECURE` | `"false"` | Allow access to secure Docker registries using HTTPS without validating the certificates. | All |
-| `CS_REGISTRY_INSECURE` | `"false"` | Allow access to insecure registries (HTTP only). Should only be set to `true` when testing the image locally. | All |
+| `CS_REGISTRY_INSECURE` | `"false"` | Allow access to insecure registries (HTTP only). Should only be set to `true` when testing the image locally. | Trivy. The registry must listen on port `80/tcp`. |
| `CS_SEVERITY_THRESHOLD` | `UNKNOWN` | Severity level threshold. The scanner outputs vulnerabilities with severity level higher than or equal to this threshold. Supported levels are Unknown, Low, Medium, High, and Critical. | Trivy |
| `DOCKER_IMAGE` | `$CI_APPLICATION_REPOSITORY:$CI_APPLICATION_TAG` | The Docker image to be scanned. If set, this variable overrides the `$CI_APPLICATION_REPOSITORY` and `$CI_APPLICATION_TAG` variables. | All |
| `DOCKER_PASSWORD` | `$CI_REGISTRY_PASSWORD` | Password for accessing a Docker registry requiring authentication. | All |
diff --git a/lib/api/entities/basic_project_details.rb b/lib/api/entities/basic_project_details.rb
index 2de49d6ed40..91831fe2bdf 100644
--- a/lib/api/entities/basic_project_details.rb
+++ b/lib/api/entities/basic_project_details.rb
@@ -4,15 +4,13 @@ module API
module Entities
class BasicProjectDetails < Entities::ProjectIdentity
include ::API::ProjectsRelationBuilder
+ include Gitlab::Utils::StrongMemoize
expose :default_branch, if: -> (project, options) { Ability.allowed?(options[:current_user], :download_code, project) }
# Avoids an N+1 query: https://github.com/mbleigh/acts-as-taggable-on/issues/91#issuecomment-168273770
- expose :tag_list do |project|
- # Tags is a preloaded association. If we perform then sorting
- # through the database, it will trigger a new query, ending up
- # in an N+1 if we have several projects
- project.tags.pluck(:name).sort # rubocop:disable CodeReuse/ActiveRecord
- end
+
+ expose :topic_names, as: :tag_list
+ expose :topic_names, as: :topics
expose :ssh_url_to_repo, :http_url_to_repo, :web_url, :readme_url
@@ -40,7 +38,7 @@ module API
# rubocop: disable CodeReuse/ActiveRecord
def self.preload_relation(projects_relation, options = {})
- # Preloading tags, should be done with using only `:tags`,
+ # Preloading topics, should be done with using only `:tags`,
# as `:tags` are defined as: `has_many :tags, through: :taggings`
# N+1 is solved then by using `subject.tags.map(&:name)`
# MR describing the solution: https://gitlab.com/gitlab-org/gitlab-foss/merge_requests/20555
@@ -50,6 +48,19 @@ module API
.preload(namespace: [:route, :owner])
end
# rubocop: enable CodeReuse/ActiveRecord
+
+ private
+
+ alias_method :project, :object
+
+ def topic_names
+ # Topics is a preloaded association. If we perform then sorting
+ # through the database, it will trigger a new query, ending up
+ # in an N+1 if we have several projects
+ strong_memoize(:topic_names) do
+ project.tags.pluck(:name).sort # rubocop:disable CodeReuse/ActiveRecord
+ end
+ end
end
end
end
diff --git a/lib/gitlab/database/postgresql_adapter/type_map_cache.rb b/lib/gitlab/database/postgresql_adapter/type_map_cache.rb
new file mode 100644
index 00000000000..ff66d9115ab
--- /dev/null
+++ b/lib/gitlab/database/postgresql_adapter/type_map_cache.rb
@@ -0,0 +1,44 @@
+# frozen_string_literal: true
+
+# Caches loading of additional types from the DB
+# https://github.com/rails/rails/blob/v6.0.3.2/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb#L521-L589
+
+# rubocop:disable Gitlab/ModuleWithInstanceVariables
+
+module Gitlab
+ module Database
+ module PostgresqlAdapter
+ module TypeMapCache
+ extend ActiveSupport::Concern
+
+ TYPE_MAP_CACHE_MONITOR = ::Monitor.new
+
+ class_methods do
+ def type_map_cache
+ TYPE_MAP_CACHE_MONITOR.synchronize do
+ @type_map_cache ||= {}
+ end
+ end
+ end
+
+ def initialize_type_map(map = type_map)
+ TYPE_MAP_CACHE_MONITOR.synchronize do
+ cached_type_map = self.class.type_map_cache[@connection_parameters.hash]
+ break @type_map = cached_type_map if cached_type_map
+
+ super
+ self.class.type_map_cache[@connection_parameters.hash] = map
+ end
+ end
+
+ def reload_type_map
+ TYPE_MAP_CACHE_MONITOR.synchronize do
+ self.class.type_map_cache[@connection_parameters.hash] = nil
+ end
+
+ super
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/json.rb b/lib/gitlab/json.rb
index 561cd4509b1..767ce310b5a 100644
--- a/lib/gitlab/json.rb
+++ b/lib/gitlab/json.rb
@@ -242,7 +242,7 @@ module Gitlab
def self.encode(object, limit: 25.megabytes)
return ::Gitlab::Json.dump(object) unless Feature.enabled?(:json_limited_encoder)
- buffer = []
+ buffer = StringIO.new
buffer_size = 0
::Yajl::Encoder.encode(object) do |data_chunk|
@@ -254,7 +254,7 @@ module Gitlab
buffer_size += chunk_size
end
- buffer.join('')
+ buffer.string
end
end
end
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 3f2945ecdf0..da43500f26c 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -19162,9 +19162,6 @@ msgstr ""
msgid "LFS"
msgstr ""
-msgid "LFS object"
-msgstr ""
-
msgid "LFS objects"
msgstr ""
diff --git a/qa/qa/runtime/allure_report.rb b/qa/qa/runtime/allure_report.rb
index cf8d33e0a6d..5e9ae3e7bbe 100644
--- a/qa/qa/runtime/allure_report.rb
+++ b/qa/qa/runtime/allure_report.rb
@@ -23,9 +23,17 @@ module QA
#
# @return [void]
def configure_allure
+ # Match job names like ee:relative, ce:update etc. and set as execution environment
+ env_matcher = /^(?<env>\w{2}:\S+)/
+
AllureRspec.configure do |config|
config.results_directory = 'tmp/allure-results'
config.clean_results_directory = true
+
+ # Set custom environment name to separate same specs executed on different environments
+ if Env.running_in_ci? && Env.ci_job_name.match?(env_matcher)
+ config.environment = Env.ci_job_name.match(env_matcher).named_captures['env']
+ end
end
end
@@ -67,7 +75,7 @@ module QA
issue = example.metadata.dig(:quarantine, :issue)
example.issue('Issue', issue) if issue
- example.add_link(name: "Job(#{ENV['CI_JOB_NAME']})", url: ENV['CI_JOB_URL']) if ENV['CI']
+ example.add_link(name: "Job(#{Env.ci_job_name})", url: Env.ci_job_url) if Env.running_in_ci?
end
end
end
diff --git a/spec/features/groups/members/manage_members_spec.rb b/spec/features/groups/members/manage_members_spec.rb
index eef92b5839d..4241d20e6f7 100644
--- a/spec/features/groups/members/manage_members_spec.rb
+++ b/spec/features/groups/members/manage_members_spec.rb
@@ -81,7 +81,8 @@ RSpec.describe 'Groups > Members > Manage members' do
category: 'Members::CreateService',
action: 'create_member',
label: 'unknown',
- property: 'existing_user'
+ property: 'existing_user',
+ user: user1
)
end
@@ -189,7 +190,8 @@ RSpec.describe 'Groups > Members > Manage members' do
category: 'Members::InviteService',
action: 'create_member',
label: 'unknown',
- property: 'net_new_user'
+ property: 'net_new_user',
+ user: user1
)
end
end
diff --git a/spec/features/projects/import_export/import_file_spec.rb b/spec/features/projects/import_export/import_file_spec.rb
index af228764c17..25836514981 100644
--- a/spec/features/projects/import_export/import_file_spec.rb
+++ b/spec/features/projects/import_export/import_file_spec.rb
@@ -30,14 +30,14 @@ RSpec.describe 'Import/Export - project import integration test', :js do
it 'user imports an exported project successfully', :sidekiq_might_not_need_inline do
visit new_project_path
- click_import_project_tab
+ click_import_project
click_link 'GitLab export'
fill_in :name, with: 'Test Project Name', visible: true
fill_in :path, with: 'test-project-path', visible: true
attach_file('file', file)
- expect { click_on 'Import project' }.to change { Project.count }.by(1)
+ expect { click_button 'Import project' }.to change { Project.count }.by(1)
project = Project.last
expect(project).not_to be_nil
@@ -49,11 +49,11 @@ RSpec.describe 'Import/Export - project import integration test', :js do
visit new_project_path
- click_import_project_tab
+ click_import_project
click_link 'GitLab export'
fill_in :name, with: project.name, visible: true
attach_file('file', file)
- click_on 'Import project'
+ click_button 'Import project'
page.within('.flash-container') do
expect(page).to have_content('Project could not be imported')
@@ -61,7 +61,7 @@ RSpec.describe 'Import/Export - project import integration test', :js do
end
end
- def click_import_project_tab
+ def click_import_project
find('[data-qa-selector="import_project_link"]').click
end
end
diff --git a/spec/features/projects/members/list_spec.rb b/spec/features/projects/members/list_spec.rb
index c3cc6b02439..46583985509 100644
--- a/spec/features/projects/members/list_spec.rb
+++ b/spec/features/projects/members/list_spec.rb
@@ -60,7 +60,8 @@ RSpec.describe 'Project members list', :js do
category: 'Members::CreateService',
action: 'create_member',
label: 'unknown',
- property: 'existing_user'
+ property: 'existing_user',
+ user: user1
)
end
@@ -117,7 +118,8 @@ RSpec.describe 'Project members list', :js do
category: 'Members::InviteService',
action: 'create_member',
label: 'unknown',
- property: 'net_new_user'
+ property: 'net_new_user',
+ user: user1
)
end
diff --git a/spec/features/projects/releases/user_views_releases_spec.rb b/spec/features/projects/releases/user_views_releases_spec.rb
index 5d0a1015de4..fcb1b6a0015 100644
--- a/spec/features/projects/releases/user_views_releases_spec.rb
+++ b/spec/features/projects/releases/user_views_releases_spec.rb
@@ -15,134 +15,151 @@ RSpec.describe 'User views releases', :js do
let_it_be(:guest) { create(:user) }
before do
- stub_feature_flags(releases_index_apollo_client: false)
project.add_maintainer(maintainer)
project.add_guest(guest)
end
- context('when the user is a maintainer') do
- before do
- sign_in(maintainer)
-
- visit project_releases_path(project)
- end
+ shared_examples 'releases index page' do
+ context('when the user is a maintainer') do
+ before do
+ sign_in(maintainer)
- it 'sees the release' do
- page.within("##{release_v1.tag}") do
- expect(page).to have_content(release_v1.name)
- expect(page).to have_content(release_v1.tag)
- expect(page).not_to have_content('Upcoming Release')
+ visit project_releases_path(project)
end
- end
-
- context 'when there is a link as an asset' do
- let!(:release_link) { create(:release_link, release: release_v1, url: url ) }
- let(:url) { "#{project.web_url}/-/jobs/1/artifacts/download" }
- let(:direct_asset_link) { Gitlab::Routing.url_helpers.project_release_url(project, release_v1) << "/downloads#{release_link.filepath}" }
- it 'sees the link' do
- page.within("##{release_v1.tag} .js-assets-list") do
- expect(page).to have_link release_link.name, href: direct_asset_link
- expect(page).not_to have_css('[data-testid="external-link-indicator"]')
+ it 'sees the release' do
+ page.within("##{release_v1.tag}") do
+ expect(page).to have_content(release_v1.name)
+ expect(page).to have_content(release_v1.tag)
+ expect(page).not_to have_content('Upcoming Release')
end
end
- context 'when there is a link redirect' do
- let!(:release_link) { create(:release_link, release: release_v1, name: 'linux-amd64 binaries', filepath: '/binaries/linux-amd64', url: url) }
+ context 'when there is a link as an asset' do
+ let!(:release_link) { create(:release_link, release: release_v1, url: url ) }
let(:url) { "#{project.web_url}/-/jobs/1/artifacts/download" }
+ let(:direct_asset_link) { Gitlab::Routing.url_helpers.project_release_url(project, release_v1) << "/downloads#{release_link.filepath}" }
- it 'sees the link', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/329301' do
+ it 'sees the link' do
page.within("##{release_v1.tag} .js-assets-list") do
expect(page).to have_link release_link.name, href: direct_asset_link
expect(page).not_to have_css('[data-testid="external-link-indicator"]')
end
end
- end
- context 'when url points to external resource' do
- let(:url) { 'http://google.com/download' }
+ context 'when there is a link redirect' do
+ let!(:release_link) { create(:release_link, release: release_v1, name: 'linux-amd64 binaries', filepath: '/binaries/linux-amd64', url: url) }
+ let(:url) { "#{project.web_url}/-/jobs/1/artifacts/download" }
- it 'sees that the link is external resource', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/329302' do
- page.within("##{release_v1.tag} .js-assets-list") do
- expect(page).to have_css('[data-testid="external-link-indicator"]')
+ it 'sees the link', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/329301' do
+ page.within("##{release_v1.tag} .js-assets-list") do
+ expect(page).to have_link release_link.name, href: direct_asset_link
+ expect(page).not_to have_css('[data-testid="external-link-indicator"]')
+ end
+ end
+ end
+
+ context 'when url points to external resource' do
+ let(:url) { 'http://google.com/download' }
+
+ it 'sees that the link is external resource', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/329302' do
+ page.within("##{release_v1.tag} .js-assets-list") do
+ expect(page).to have_css('[data-testid="external-link-indicator"]')
+ end
end
end
end
- end
- context 'with an upcoming release' do
- it 'sees the upcoming tag' do
- page.within("##{release_v3.tag}") do
- expect(page).to have_content('Upcoming Release')
+ context 'with an upcoming release' do
+ it 'sees the upcoming tag' do
+ page.within("##{release_v3.tag}") do
+ expect(page).to have_content('Upcoming Release')
+ end
end
end
- end
- context 'with a tag containing a slash' do
- it 'sees the release' do
- page.within("##{release_v2.tag.parameterize}") do
- expect(page).to have_content(release_v2.name)
- expect(page).to have_content(release_v2.tag)
+ context 'with a tag containing a slash' do
+ it 'sees the release' do
+ page.within("##{release_v2.tag.parameterize}") do
+ expect(page).to have_content(release_v2.name)
+ expect(page).to have_content(release_v2.tag)
+ end
end
end
- end
- context 'sorting' do
- def sort_page(by:, direction:)
- within '[data-testid="releases-sort"]' do
- find('.dropdown-toggle').click
+ context 'sorting' do
+ def sort_page(by:, direction:)
+ within '[data-testid="releases-sort"]' do
+ find('.dropdown-toggle').click
- click_button(by, class: 'dropdown-item')
+ click_button(by, class: 'dropdown-item')
- find('.sorting-direction-button').click if direction == :ascending
+ find('.sorting-direction-button').click if direction == :ascending
+ end
end
- end
- shared_examples 'releases sort order' do
- it "sorts the releases #{description}" do
- card_titles = page.all('.release-block .card-title', minimum: expected_releases.count)
+ shared_examples 'releases sort order' do
+ it "sorts the releases #{description}" do
+ card_titles = page.all('.release-block .card-title', minimum: expected_releases.count)
- card_titles.each_with_index do |title, index|
- expect(title).to have_content(expected_releases[index].name)
+ card_titles.each_with_index do |title, index|
+ expect(title).to have_content(expected_releases[index].name)
+ end
end
end
- end
- context "when the page is sorted by the default sort order" do
- let(:expected_releases) { [release_v3, release_v2, release_v1] }
+ context "when the page is sorted by the default sort order" do
+ let(:expected_releases) { [release_v3, release_v2, release_v1] }
- it_behaves_like 'releases sort order'
- end
+ it_behaves_like 'releases sort order'
+ end
- context "when the page is sorted by created_at ascending " do
- let(:expected_releases) { [release_v2, release_v1, release_v3] }
+ context "when the page is sorted by created_at ascending " do
+ let(:expected_releases) { [release_v2, release_v1, release_v3] }
- before do
- sort_page by: 'Created date', direction: :ascending
+ before do
+ sort_page by: 'Created date', direction: :ascending
+ end
+
+ it_behaves_like 'releases sort order'
end
+ end
+ end
+
+ context('when the user is a guest') do
+ before do
+ sign_in(guest)
+ end
+
+ it 'renders release info except for Git-related data' do
+ visit project_releases_path(project)
+
+ within('.release-block', match: :first) do
+ expect(page).to have_content(release_v3.description)
- it_behaves_like 'releases sort order'
+ # The following properties (sometimes) include Git info,
+ # so they are not rendered for Guest users
+ expect(page).not_to have_content(release_v3.name)
+ expect(page).not_to have_content(release_v3.tag)
+ expect(page).not_to have_content(release_v3.commit.short_id)
+ end
end
end
end
- context('when the user is a guest') do
+ context 'when the releases_index_apollo_client feature flag is enabled' do
before do
- sign_in(guest)
+ stub_feature_flags(releases_index_apollo_client: true)
end
- it 'renders release info except for Git-related data' do
- visit project_releases_path(project)
-
- within('.release-block', match: :first) do
- expect(page).to have_content(release_v3.description)
+ it_behaves_like 'releases index page'
+ end
- # The following properties (sometimes) include Git info,
- # so they are not rendered for Guest users
- expect(page).not_to have_content(release_v3.name)
- expect(page).not_to have_content(release_v3.tag)
- expect(page).not_to have_content(release_v3.commit.short_id)
- end
+ context 'when the releases_index_apollo_client feature flag is disabled' do
+ before do
+ stub_feature_flags(releases_index_apollo_client: false)
end
+
+ it_behaves_like 'releases index page'
end
end
diff --git a/spec/fixtures/api/schemas/public_api/v4/board.json b/spec/fixtures/api/schemas/public_api/v4/board.json
index c3a140c1bd7..11dfa131e88 100644
--- a/spec/fixtures/api/schemas/public_api/v4/board.json
+++ b/spec/fixtures/api/schemas/public_api/v4/board.json
@@ -15,6 +15,7 @@
"description",
"default_branch",
"tag_list",
+ "topics",
"ssh_url_to_repo",
"http_url_to_repo",
"web_url",
@@ -34,6 +35,7 @@
"description": { "type": ["string", "null"] },
"default_branch": { "type": ["string", "null"] },
"tag_list": { "type": "array" },
+ "topics": { "type": "array" },
"ssh_url_to_repo": { "type": "string" },
"http_url_to_repo": { "type": "string" },
"web_url": { "type": "string" },
diff --git a/spec/fixtures/api/schemas/public_api/v4/project.json b/spec/fixtures/api/schemas/public_api/v4/project.json
index 4a3149f2bdc..2f708538d96 100644
--- a/spec/fixtures/api/schemas/public_api/v4/project.json
+++ b/spec/fixtures/api/schemas/public_api/v4/project.json
@@ -15,6 +15,12 @@
"type": "string"
}
},
+ "topics": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
"ssh_url_to_repo": { "type": "string" },
"http_url_to_repo": { "type": "string" },
"web_url": { "type": "string" },
@@ -37,7 +43,7 @@
},
"required": [
"id", "name", "name_with_namespace", "description", "path",
- "path_with_namespace", "created_at", "default_branch", "tag_list",
+ "path_with_namespace", "created_at", "default_branch", "tag_list", "topics",
"ssh_url_to_repo", "http_url_to_repo", "web_url", "readme_url", "avatar_url",
"star_count", "forks_count", "last_activity_at", "namespace"
],
diff --git a/spec/frontend/fixtures/static/projects.json b/spec/frontend/fixtures/static/projects.json
index f28d9899099..d843549039b 100644
--- a/spec/frontend/fixtures/static/projects.json
+++ b/spec/frontend/fixtures/static/projects.json
@@ -3,6 +3,7 @@
"description": "",
"default_branch": null,
"tag_list": [],
+ "topics": [],
"public": true,
"archived": false,
"visibility_level": 20,
@@ -54,6 +55,7 @@
"description": "Voluptatem quae nulla eius numquam ullam voluptatibus quia modi.",
"default_branch": "master",
"tag_list": [],
+ "topics": [],
"public": false,
"archived": false,
"visibility_level": 0,
@@ -114,6 +116,7 @@
"description": "Modi odio mollitia dolorem qui.",
"default_branch": "master",
"tag_list": [],
+ "topics": [],
"public": false,
"archived": false,
"visibility_level": 0,
@@ -162,6 +165,7 @@
"description": "Omnis asperiores ipsa et beatae quidem necessitatibus quia.",
"default_branch": "master",
"tag_list": [],
+ "topics": [],
"public": true,
"archived": false,
"visibility_level": 20,
@@ -210,6 +214,7 @@
"description": "Voluptatem commodi voluptate placeat architecto beatae illum dolores fugiat.",
"default_branch": "master",
"tag_list": [],
+ "topics": [],
"public": false,
"archived": false,
"visibility_level": 0,
@@ -258,6 +263,7 @@
"description": "Aut molestias quas est ut aperiam officia quod libero.",
"default_branch": "master",
"tag_list": [],
+ "topics": [],
"public": true,
"archived": false,
"visibility_level": 20,
@@ -309,6 +315,7 @@
"description": "Excepturi molestiae quia repellendus omnis est illo illum eligendi.",
"default_branch": "master",
"tag_list": [],
+ "topics": [],
"public": true,
"archived": false,
"visibility_level": 20,
@@ -357,6 +364,7 @@
"description": "Adipisci quaerat dignissimos enim sed ipsam dolorem quia.",
"default_branch": "master",
"tag_list": [],
+ "topics": [],
"public": false,
"archived": false,
"visibility_level": 10,
@@ -408,6 +416,7 @@
"description": "Vel voluptatem maxime saepe ex quia.",
"default_branch": "master",
"tag_list": [],
+ "topics": [],
"public": false,
"archived": false,
"visibility_level": 0,
diff --git a/spec/frontend/static_site_editor/components/edit_area_spec.js b/spec/frontend/static_site_editor/components/edit_area_spec.js
index 17fb3fe788a..1d6245e9dbb 100644
--- a/spec/frontend/static_site_editor/components/edit_area_spec.js
+++ b/spec/frontend/static_site_editor/components/edit_area_spec.js
@@ -7,8 +7,8 @@ import EditDrawer from '~/static_site_editor/components/edit_drawer.vue';
import EditHeader from '~/static_site_editor/components/edit_header.vue';
import PublishToolbar from '~/static_site_editor/components/publish_toolbar.vue';
import UnsavedChangesConfirmDialog from '~/static_site_editor/components/unsaved_changes_confirm_dialog.vue';
-import { EDITOR_TYPES } from '~/vue_shared/components/rich_content_editor/constants';
-import RichContentEditor from '~/vue_shared/components/rich_content_editor/rich_content_editor.vue';
+import { EDITOR_TYPES } from '~/static_site_editor/rich_content_editor/constants';
+import RichContentEditor from '~/static_site_editor/rich_content_editor/rich_content_editor.vue';
import {
sourceContentTitle as title,
diff --git a/spec/frontend/vue_shared/components/rich_content_editor/editor_service_spec.js b/spec/frontend/static_site_editor/rich_content_editor/editor_service_spec.js
index ce2b0d1ddc1..cd0d09c085f 100644
--- a/spec/frontend/vue_shared/components/rich_content_editor/editor_service_spec.js
+++ b/spec/frontend/static_site_editor/rich_content_editor/editor_service_spec.js
@@ -1,5 +1,5 @@
-import buildCustomRenderer from '~/vue_shared/components/rich_content_editor/services/build_custom_renderer';
-import buildHTMLToMarkdownRenderer from '~/vue_shared/components/rich_content_editor/services/build_html_to_markdown_renderer';
+import buildCustomRenderer from '~/static_site_editor/rich_content_editor/services/build_custom_renderer';
+import buildHTMLToMarkdownRenderer from '~/static_site_editor/rich_content_editor/services/build_html_to_markdown_renderer';
import {
generateToolbarItem,
addCustomEventListener,
@@ -9,12 +9,12 @@ import {
insertVideo,
getMarkdown,
getEditorOptions,
-} from '~/vue_shared/components/rich_content_editor/services/editor_service';
-import sanitizeHTML from '~/vue_shared/components/rich_content_editor/services/sanitize_html';
+} from '~/static_site_editor/rich_content_editor/services/editor_service';
+import sanitizeHTML from '~/static_site_editor/rich_content_editor/services/sanitize_html';
-jest.mock('~/vue_shared/components/rich_content_editor/services/build_html_to_markdown_renderer');
-jest.mock('~/vue_shared/components/rich_content_editor/services/build_custom_renderer');
-jest.mock('~/vue_shared/components/rich_content_editor/services/sanitize_html');
+jest.mock('~/static_site_editor/rich_content_editor/services/build_html_to_markdown_renderer');
+jest.mock('~/static_site_editor/rich_content_editor/services/build_custom_renderer');
+jest.mock('~/static_site_editor/rich_content_editor/services/sanitize_html');
describe('Editor Service', () => {
let mockInstance;
diff --git a/spec/frontend/vue_shared/components/rich_content_editor/modals/add_image/add_image_modal_spec.js b/spec/frontend/static_site_editor/rich_content_editor/modals/add_image/add_image_modal_spec.js
index 97aecda97d2..86ae016987d 100644
--- a/spec/frontend/vue_shared/components/rich_content_editor/modals/add_image/add_image_modal_spec.js
+++ b/spec/frontend/static_site_editor/rich_content_editor/modals/add_image/add_image_modal_spec.js
@@ -1,8 +1,8 @@
import { GlModal, GlTabs } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
-import { IMAGE_TABS } from '~/vue_shared/components/rich_content_editor/constants';
-import AddImageModal from '~/vue_shared/components/rich_content_editor/modals/add_image/add_image_modal.vue';
-import UploadImageTab from '~/vue_shared/components/rich_content_editor/modals/add_image/upload_image_tab.vue';
+import { IMAGE_TABS } from '~/static_site_editor/rich_content_editor/constants';
+import AddImageModal from '~/static_site_editor/rich_content_editor/modals/add_image/add_image_modal.vue';
+import UploadImageTab from '~/static_site_editor/rich_content_editor/modals/add_image/upload_image_tab.vue';
describe('Add Image Modal', () => {
let wrapper;
diff --git a/spec/frontend/vue_shared/components/rich_content_editor/modals/add_image/upload_image_tab_spec.js b/spec/frontend/static_site_editor/rich_content_editor/modals/add_image/upload_image_tab_spec.js
index 81fd059ce4f..11b73d58259 100644
--- a/spec/frontend/vue_shared/components/rich_content_editor/modals/add_image/upload_image_tab_spec.js
+++ b/spec/frontend/static_site_editor/rich_content_editor/modals/add_image/upload_image_tab_spec.js
@@ -1,5 +1,5 @@
import { shallowMount } from '@vue/test-utils';
-import UploadImageTab from '~/vue_shared/components/rich_content_editor/modals/add_image/upload_image_tab.vue';
+import UploadImageTab from '~/static_site_editor/rich_content_editor/modals/add_image/upload_image_tab.vue';
describe('Upload Image Tab', () => {
let wrapper;
diff --git a/spec/frontend/vue_shared/components/rich_content_editor/modals/insert_video_modal_spec.js b/spec/frontend/static_site_editor/rich_content_editor/modals/insert_video_modal_spec.js
index 3e9eaf58181..392d31bf039 100644
--- a/spec/frontend/vue_shared/components/rich_content_editor/modals/insert_video_modal_spec.js
+++ b/spec/frontend/static_site_editor/rich_content_editor/modals/insert_video_modal_spec.js
@@ -1,6 +1,6 @@
import { GlModal } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
-import InsertVideoModal from '~/vue_shared/components/rich_content_editor/modals/insert_video_modal.vue';
+import InsertVideoModal from '~/static_site_editor/rich_content_editor/modals/insert_video_modal.vue';
describe('Insert Video Modal', () => {
let wrapper;
diff --git a/spec/frontend/vue_shared/components/rich_content_editor/rich_content_editor_integration_spec.js b/spec/frontend/static_site_editor/rich_content_editor/rich_content_editor_integration_spec.js
index 47b1abd2ad2..6c02ec506c6 100644
--- a/spec/frontend/vue_shared/components/rich_content_editor/rich_content_editor_integration_spec.js
+++ b/spec/frontend/static_site_editor/rich_content_editor/rich_content_editor_integration_spec.js
@@ -1,8 +1,8 @@
import Editor from '@toast-ui/editor';
-import buildMarkdownToHTMLRenderer from '~/vue_shared/components/rich_content_editor/services/build_custom_renderer';
-import { registerHTMLToMarkdownRenderer } from '~/vue_shared/components/rich_content_editor/services/editor_service';
+import buildMarkdownToHTMLRenderer from '~/static_site_editor/rich_content_editor/services/build_custom_renderer';
+import { registerHTMLToMarkdownRenderer } from '~/static_site_editor/rich_content_editor/services/editor_service';
-describe('vue_shared/components/rich_content_editor', () => {
+describe('static_site_editor/rich_content_editor', () => {
let editor;
const buildEditor = () => {
diff --git a/spec/frontend/vue_shared/components/rich_content_editor/rich_content_editor_spec.js b/spec/frontend/static_site_editor/rich_content_editor/rich_content_editor_spec.js
index 8eb880b3984..3b0d2993a5d 100644
--- a/spec/frontend/vue_shared/components/rich_content_editor/rich_content_editor_spec.js
+++ b/spec/frontend/static_site_editor/rich_content_editor/rich_content_editor_spec.js
@@ -5,10 +5,10 @@ import {
EDITOR_HEIGHT,
EDITOR_PREVIEW_STYLE,
CUSTOM_EVENTS,
-} from '~/vue_shared/components/rich_content_editor/constants';
-import AddImageModal from '~/vue_shared/components/rich_content_editor/modals/add_image/add_image_modal.vue';
-import InsertVideoModal from '~/vue_shared/components/rich_content_editor/modals/insert_video_modal.vue';
-import RichContentEditor from '~/vue_shared/components/rich_content_editor/rich_content_editor.vue';
+} from '~/static_site_editor/rich_content_editor/constants';
+import AddImageModal from '~/static_site_editor/rich_content_editor/modals/add_image/add_image_modal.vue';
+import InsertVideoModal from '~/static_site_editor/rich_content_editor/modals/insert_video_modal.vue';
+import RichContentEditor from '~/static_site_editor/rich_content_editor/rich_content_editor.vue';
import {
addCustomEventListener,
@@ -18,9 +18,9 @@ import {
registerHTMLToMarkdownRenderer,
getEditorOptions,
getMarkdown,
-} from '~/vue_shared/components/rich_content_editor/services/editor_service';
+} from '~/static_site_editor/rich_content_editor/services/editor_service';
-jest.mock('~/vue_shared/components/rich_content_editor/services/editor_service', () => ({
+jest.mock('~/static_site_editor/rich_content_editor/services/editor_service', () => ({
addCustomEventListener: jest.fn(),
removeCustomEventListener: jest.fn(),
addImage: jest.fn(),
diff --git a/spec/frontend/vue_shared/components/rich_content_editor/services/build_custom_renderer_spec.js b/spec/frontend/static_site_editor/rich_content_editor/services/build_custom_renderer_spec.js
index a823d04024d..202e13e8bff 100644
--- a/spec/frontend/vue_shared/components/rich_content_editor/services/build_custom_renderer_spec.js
+++ b/spec/frontend/static_site_editor/rich_content_editor/services/build_custom_renderer_spec.js
@@ -1,4 +1,4 @@
-import buildCustomHTMLRenderer from '~/vue_shared/components/rich_content_editor/services/build_custom_renderer';
+import buildCustomHTMLRenderer from '~/static_site_editor/rich_content_editor/services/build_custom_renderer';
describe('Build Custom Renderer Service', () => {
describe('buildCustomHTMLRenderer', () => {
diff --git a/spec/frontend/vue_shared/components/rich_content_editor/services/build_html_to_markdown_renderer_spec.js b/spec/frontend/static_site_editor/rich_content_editor/services/build_html_to_markdown_renderer_spec.js
index 3caf03dabba..c9cba3e8689 100644
--- a/spec/frontend/vue_shared/components/rich_content_editor/services/build_html_to_markdown_renderer_spec.js
+++ b/spec/frontend/static_site_editor/rich_content_editor/services/build_html_to_markdown_renderer_spec.js
@@ -1,4 +1,4 @@
-import buildHTMLToMarkdownRenderer from '~/vue_shared/components/rich_content_editor/services/build_html_to_markdown_renderer';
+import buildHTMLToMarkdownRenderer from '~/static_site_editor/rich_content_editor/services/build_html_to_markdown_renderer';
import { attributeDefinition } from './renderers/mock_data';
describe('rich_content_editor/services/html_to_markdown_renderer', () => {
diff --git a/spec/frontend/vue_shared/components/rich_content_editor/services/renderers/build_uneditable_token_spec.js b/spec/frontend/static_site_editor/rich_content_editor/services/renderers/build_uneditable_token_spec.js
index 7a7e3055520..ef3ff052cb2 100644
--- a/spec/frontend/vue_shared/components/rich_content_editor/services/renderers/build_uneditable_token_spec.js
+++ b/spec/frontend/static_site_editor/rich_content_editor/services/renderers/build_uneditable_token_spec.js
@@ -6,7 +6,7 @@ import {
buildUneditableBlockTokens,
buildUneditableInlineTokens,
buildUneditableHtmlAsTextTokens,
-} from '~/vue_shared/components/rich_content_editor/services/renderers/build_uneditable_token';
+} from '~/static_site_editor/rich_content_editor/services/renderers/build_uneditable_token';
import {
originInlineToken,
diff --git a/spec/frontend/vue_shared/components/rich_content_editor/services/renderers/mock_data.js b/spec/frontend/static_site_editor/rich_content_editor/services/renderers/mock_data.js
index 407072fb596..407072fb596 100644
--- a/spec/frontend/vue_shared/components/rich_content_editor/services/renderers/mock_data.js
+++ b/spec/frontend/static_site_editor/rich_content_editor/services/renderers/mock_data.js
diff --git a/spec/frontend/vue_shared/components/rich_content_editor/services/renderers/render_attribute_definition_spec.js b/spec/frontend/static_site_editor/rich_content_editor/services/renderers/render_attribute_definition_spec.js
index 69fd9a67a21..6d96dd3bbca 100644
--- a/spec/frontend/vue_shared/components/rich_content_editor/services/renderers/render_attribute_definition_spec.js
+++ b/spec/frontend/static_site_editor/rich_content_editor/services/renderers/render_attribute_definition_spec.js
@@ -1,4 +1,4 @@
-import renderer from '~/vue_shared/components/rich_content_editor/services/renderers/render_attribute_definition';
+import renderer from '~/static_site_editor/rich_content_editor/services/renderers/render_attribute_definition';
import { attributeDefinition } from './mock_data';
describe('rich_content_editor/renderers/render_attribute_definition', () => {
diff --git a/spec/frontend/vue_shared/components/rich_content_editor/services/renderers/render_embedded_ruby_spec.js b/spec/frontend/static_site_editor/rich_content_editor/services/renderers/render_embedded_ruby_spec.js
index 0c59d9f569b..29e2b5b3b16 100644
--- a/spec/frontend/vue_shared/components/rich_content_editor/services/renderers/render_embedded_ruby_spec.js
+++ b/spec/frontend/static_site_editor/rich_content_editor/services/renderers/render_embedded_ruby_spec.js
@@ -1,5 +1,5 @@
-import renderer from '~/vue_shared/components/rich_content_editor/services/renderers/render_embedded_ruby_text';
-import { renderUneditableLeaf } from '~/vue_shared/components/rich_content_editor/services/renderers/render_utils';
+import renderer from '~/static_site_editor/rich_content_editor/services/renderers/render_embedded_ruby_text';
+import { renderUneditableLeaf } from '~/static_site_editor/rich_content_editor/services/renderers/render_utils';
import { buildMockTextNode, normalTextNode } from './mock_data';
diff --git a/spec/frontend/vue_shared/components/rich_content_editor/services/renderers/render_font_awesome_html_inline_spec.js b/spec/frontend/static_site_editor/rich_content_editor/services/renderers/render_font_awesome_html_inline_spec.js
index c1aaed6f0c3..0fda847b688 100644
--- a/spec/frontend/vue_shared/components/rich_content_editor/services/renderers/render_font_awesome_html_inline_spec.js
+++ b/spec/frontend/static_site_editor/rich_content_editor/services/renderers/render_font_awesome_html_inline_spec.js
@@ -1,5 +1,5 @@
-import { buildUneditableInlineTokens } from '~/vue_shared/components/rich_content_editor/services/renderers/build_uneditable_token';
-import renderer from '~/vue_shared/components/rich_content_editor/services/renderers/render_font_awesome_html_inline';
+import { buildUneditableInlineTokens } from '~/static_site_editor/rich_content_editor/services/renderers/build_uneditable_token';
+import renderer from '~/static_site_editor/rich_content_editor/services/renderers/render_font_awesome_html_inline';
import { normalTextNode } from './mock_data';
diff --git a/spec/frontend/vue_shared/components/rich_content_editor/services/renderers/render_heading_spec.js b/spec/frontend/static_site_editor/rich_content_editor/services/renderers/render_heading_spec.js
index 76abc1ec3d8..cf4a90885df 100644
--- a/spec/frontend/vue_shared/components/rich_content_editor/services/renderers/render_heading_spec.js
+++ b/spec/frontend/static_site_editor/rich_content_editor/services/renderers/render_heading_spec.js
@@ -1,5 +1,5 @@
-import renderer from '~/vue_shared/components/rich_content_editor/services/renderers/render_heading';
-import * as renderUtils from '~/vue_shared/components/rich_content_editor/services/renderers/render_utils';
+import renderer from '~/static_site_editor/rich_content_editor/services/renderers/render_heading';
+import * as renderUtils from '~/static_site_editor/rich_content_editor/services/renderers/render_utils';
describe('rich_content_editor/renderers/render_heading', () => {
it('canRender delegates to renderUtils.willAlwaysRender', () => {
diff --git a/spec/frontend/vue_shared/components/rich_content_editor/services/renderers/render_html_block_spec.js b/spec/frontend/static_site_editor/rich_content_editor/services/renderers/render_html_block_spec.js
index 234f6a4d4ca..9c937ac22f4 100644
--- a/spec/frontend/vue_shared/components/rich_content_editor/services/renderers/render_html_block_spec.js
+++ b/spec/frontend/static_site_editor/rich_content_editor/services/renderers/render_html_block_spec.js
@@ -1,5 +1,5 @@
-import { buildUneditableHtmlAsTextTokens } from '~/vue_shared/components/rich_content_editor/services/renderers/build_uneditable_token';
-import renderer from '~/vue_shared/components/rich_content_editor/services/renderers/render_html_block';
+import { buildUneditableHtmlAsTextTokens } from '~/static_site_editor/rich_content_editor/services/renderers/build_uneditable_token';
+import renderer from '~/static_site_editor/rich_content_editor/services/renderers/render_html_block';
describe('rich_content_editor/services/renderers/render_html_block', () => {
const htmlBlockNode = {
diff --git a/spec/frontend/vue_shared/components/rich_content_editor/services/renderers/render_identifier_instance_text_spec.js b/spec/frontend/static_site_editor/rich_content_editor/services/renderers/render_identifier_instance_text_spec.js
index 425d0f41bcd..15fb2c3a430 100644
--- a/spec/frontend/vue_shared/components/rich_content_editor/services/renderers/render_identifier_instance_text_spec.js
+++ b/spec/frontend/static_site_editor/rich_content_editor/services/renderers/render_identifier_instance_text_spec.js
@@ -1,5 +1,5 @@
-import { buildUneditableInlineTokens } from '~/vue_shared/components/rich_content_editor/services/renderers/build_uneditable_token';
-import renderer from '~/vue_shared/components/rich_content_editor/services/renderers/render_identifier_instance_text';
+import { buildUneditableInlineTokens } from '~/static_site_editor/rich_content_editor/services/renderers/build_uneditable_token';
+import renderer from '~/static_site_editor/rich_content_editor/services/renderers/render_identifier_instance_text';
import { buildMockTextNode, normalTextNode } from './mock_data';
diff --git a/spec/frontend/vue_shared/components/rich_content_editor/services/renderers/render_identifier_paragraph_spec.js b/spec/frontend/static_site_editor/rich_content_editor/services/renderers/render_identifier_paragraph_spec.js
index 470cf9bddaa..6a2b89a8dcf 100644
--- a/spec/frontend/vue_shared/components/rich_content_editor/services/renderers/render_identifier_paragraph_spec.js
+++ b/spec/frontend/static_site_editor/rich_content_editor/services/renderers/render_identifier_paragraph_spec.js
@@ -1,4 +1,4 @@
-import renderer from '~/vue_shared/components/rich_content_editor/services/renderers/render_identifier_paragraph';
+import renderer from '~/static_site_editor/rich_content_editor/services/renderers/render_identifier_paragraph';
import { buildMockTextNode } from './mock_data';
diff --git a/spec/frontend/vue_shared/components/rich_content_editor/services/renderers/render_list_item_spec.js b/spec/frontend/static_site_editor/rich_content_editor/services/renderers/render_list_item_spec.js
index c1ab700535b..1e8e62b9dd2 100644
--- a/spec/frontend/vue_shared/components/rich_content_editor/services/renderers/render_list_item_spec.js
+++ b/spec/frontend/static_site_editor/rich_content_editor/services/renderers/render_list_item_spec.js
@@ -1,5 +1,5 @@
-import renderer from '~/vue_shared/components/rich_content_editor/services/renderers/render_list_item';
-import * as renderUtils from '~/vue_shared/components/rich_content_editor/services/renderers/render_utils';
+import renderer from '~/static_site_editor/rich_content_editor/services/renderers/render_list_item';
+import * as renderUtils from '~/static_site_editor/rich_content_editor/services/renderers/render_utils';
describe('rich_content_editor/renderers/render_list_item', () => {
it('canRender delegates to renderUtils.willAlwaysRender', () => {
diff --git a/spec/frontend/vue_shared/components/rich_content_editor/services/renderers/render_softbreak_spec.js b/spec/frontend/static_site_editor/rich_content_editor/services/renderers/render_softbreak_spec.js
index 3c3d2354cb9..d8d1e6ff295 100644
--- a/spec/frontend/vue_shared/components/rich_content_editor/services/renderers/render_softbreak_spec.js
+++ b/spec/frontend/static_site_editor/rich_content_editor/services/renderers/render_softbreak_spec.js
@@ -1,4 +1,4 @@
-import renderer from '~/vue_shared/components/rich_content_editor/services/renderers/render_softbreak';
+import renderer from '~/static_site_editor/rich_content_editor/services/renderers/render_softbreak';
describe('Render softbreak renderer', () => {
describe('canRender', () => {
diff --git a/spec/frontend/vue_shared/components/rich_content_editor/services/renderers/render_utils_spec.js b/spec/frontend/static_site_editor/rich_content_editor/services/renderers/render_utils_spec.js
index 7c1809c290c..49b8936a9f7 100644
--- a/spec/frontend/vue_shared/components/rich_content_editor/services/renderers/render_utils_spec.js
+++ b/spec/frontend/static_site_editor/rich_content_editor/services/renderers/render_utils_spec.js
@@ -1,13 +1,13 @@
import {
buildUneditableBlockTokens,
buildUneditableOpenTokens,
-} from '~/vue_shared/components/rich_content_editor/services/renderers/build_uneditable_token';
+} from '~/static_site_editor/rich_content_editor/services/renderers/build_uneditable_token';
import {
renderUneditableLeaf,
renderUneditableBranch,
renderWithAttributeDefinitions,
willAlwaysRender,
-} from '~/vue_shared/components/rich_content_editor/services/renderers/render_utils';
+} from '~/static_site_editor/rich_content_editor/services/renderers/render_utils';
import { originToken, uneditableCloseToken, attributeDefinition } from './mock_data';
diff --git a/spec/frontend/vue_shared/components/rich_content_editor/services/sanitize_html_spec.js b/spec/frontend/static_site_editor/rich_content_editor/services/sanitize_html_spec.js
index f2182ef60d7..2f2d3beb53d 100644
--- a/spec/frontend/vue_shared/components/rich_content_editor/services/sanitize_html_spec.js
+++ b/spec/frontend/static_site_editor/rich_content_editor/services/sanitize_html_spec.js
@@ -1,4 +1,4 @@
-import sanitizeHTML from '~/vue_shared/components/rich_content_editor/services/sanitize_html';
+import sanitizeHTML from '~/static_site_editor/rich_content_editor/services/sanitize_html';
describe('rich_content_editor/services/sanitize_html', () => {
it.each`
diff --git a/spec/frontend/vue_shared/components/rich_content_editor/toolbar_item_spec.js b/spec/frontend/static_site_editor/rich_content_editor/toolbar_item_spec.js
index 5a56b499769..c9dcf9cfe2e 100644
--- a/spec/frontend/vue_shared/components/rich_content_editor/toolbar_item_spec.js
+++ b/spec/frontend/static_site_editor/rich_content_editor/toolbar_item_spec.js
@@ -1,7 +1,7 @@
import { GlIcon } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
-import ToolbarItem from '~/vue_shared/components/rich_content_editor/toolbar_item.vue';
+import ToolbarItem from '~/static_site_editor/rich_content_editor/toolbar_item.vue';
describe('Toolbar Item', () => {
let wrapper;
diff --git a/spec/lib/gitlab/database/postgresql_adapter/type_map_cache_spec.rb b/spec/lib/gitlab/database/postgresql_adapter/type_map_cache_spec.rb
new file mode 100644
index 00000000000..299adc36dbc
--- /dev/null
+++ b/spec/lib/gitlab/database/postgresql_adapter/type_map_cache_spec.rb
@@ -0,0 +1,75 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Database::PostgresqlAdapter::TypeMapCache do
+ let(:db_config) { ActiveRecord::Base.configurations.configs_for(env_name: 'test', name: 'primary').configuration_hash }
+ let(:adapter_class) do
+ Class.new(ActiveRecord::ConnectionAdapters::PostgreSQLAdapter)
+ end
+
+ describe '#initialize_type_map' do
+ it 'caches loading of types in memory' do
+ initialize_connection.disconnect!
+ recorder_without_cache = ActiveRecord::QueryRecorder.new(skip_schema_queries: false) { initialize_connection.disconnect! }
+
+ expect(recorder_without_cache.log).to include(a_string_matching(/FROM pg_type/)).twice
+
+ adapter_class.prepend(described_class)
+
+ initialize_connection.disconnect!
+ recorder_with_cache = ActiveRecord::QueryRecorder.new(skip_schema_queries: false) { initialize_connection.disconnect! }
+
+ expect(recorder_with_cache.count).to be < recorder_without_cache.count
+
+ # There's still one pg_type query left here because `#add_pg_decoders` executes another pg_type query
+ # in https://github.com/rails/rails/blob/v6.1.3.2/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb#L912.
+ # This query is much cheaper because it only returns very few records.
+ expect(recorder_with_cache.log).to include(a_string_matching(/FROM pg_type/)).once
+ end
+
+ it 'only reuses the cache if the connection parameters are exactly the same' do
+ adapter_class.prepend(described_class)
+
+ initialize_connection.disconnect!
+
+ other_config = db_config.dup
+ other_config[:connect_timeout] = db_config[:connect_timeout].to_i + 10
+
+ recorder = ActiveRecord::QueryRecorder.new(skip_schema_queries: false) { initialize_connection(other_config).disconnect! }
+
+ expect(recorder.log).to include(a_string_matching(/FROM pg_type/)).twice
+ end
+ end
+
+ describe '#reload_type_map' do
+ it 'clears the cache and executes the type map query again' do
+ adapter_class.prepend(described_class)
+
+ initialize_connection.disconnect!
+
+ connection = initialize_connection
+ recorder = ActiveRecord::QueryRecorder.new(skip_schema_queries: false) { connection.reload_type_map }
+
+ expect(recorder.log).to include(a_string_matching(/FROM pg_type/)).once
+ end
+ end
+
+ # Based on https://github.com/rails/rails/blob/v6.1.3.2/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb#L36-L41
+ def initialize_connection(config = db_config)
+ conn_params = config.symbolize_keys.compact
+
+ conn_params[:user] = conn_params.delete(:username) if conn_params[:username]
+ conn_params[:dbname] = conn_params.delete(:database) if conn_params[:database]
+
+ valid_conn_param_keys = PG::Connection.conndefaults_hash.keys + [:requiressl]
+ conn_params.slice!(*valid_conn_param_keys)
+
+ adapter_class.new(
+ adapter_class.new_client(conn_params),
+ ActiveRecord::Base.logger,
+ conn_params,
+ config
+ )
+ end
+end
diff --git a/spec/lib/gitlab/json_spec.rb b/spec/lib/gitlab/json_spec.rb
index 42c4b315edf..f9f57752b0a 100644
--- a/spec/lib/gitlab/json_spec.rb
+++ b/spec/lib/gitlab/json_spec.rb
@@ -411,7 +411,7 @@ RSpec.describe Gitlab::Json do
end
describe Gitlab::Json::LimitedEncoder do
- subject { described_class.encode(obj, limit: 8.kilobytes) }
+ subject { described_class.encode(obj, limit: 10.kilobytes) }
context 'when object size is acceptable' do
let(:obj) { { test: true } }
@@ -431,6 +431,16 @@ RSpec.describe Gitlab::Json do
end
end
+ context 'when object contains ASCII-8BIT encoding' do
+ let(:obj) { [{ a: "\x8F" }] * 1000 }
+
+ it 'does not raise encoding error' do
+ expect { subject }.not_to raise_error
+ expect(subject).to be_a(String)
+ expect(subject.size).to eq(10001)
+ end
+ end
+
context 'when json_limited_encoder is disabled' do
let(:obj) { [{ test: true }] * 1000 }
diff --git a/spec/requests/api/project_attributes.yml b/spec/requests/api/project_attributes.yml
index d28442bd692..2f1cd009fbc 100644
--- a/spec/requests/api/project_attributes.yml
+++ b/spec/requests/api/project_attributes.yml
@@ -69,6 +69,7 @@ itself: # project
- shared_with_groups
- ssh_url_to_repo
- tag_list
+ - topics
- web_url
build_auto_devops: # auto_devops
diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb
index e103aa3d6de..51b87a55b1e 100644
--- a/spec/requests/api/projects_spec.rb
+++ b/spec/requests/api/projects_spec.rb
@@ -184,13 +184,14 @@ RSpec.describe API::Projects do
end
end
- it 'includes the project labels as the tag_list' do
+ it 'includes project topics' do
get api('/projects', user)
expect(response).to have_gitlab_http_status(:ok)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
- expect(json_response.first.keys).to include('tag_list')
+ expect(json_response.first.keys).to include('tag_list') # deprecated in favor of 'topics'
+ expect(json_response.first.keys).to include('topics')
end
it 'includes open_issues_count' do
@@ -1892,7 +1893,8 @@ RSpec.describe API::Projects do
expect(json_response['id']).to eq(project.id)
expect(json_response['description']).to eq(project.description)
expect(json_response['default_branch']).to eq(project.default_branch)
- expect(json_response['tag_list']).to be_an Array
+ expect(json_response['tag_list']).to be_an Array # deprecated in favor of 'topics'
+ expect(json_response['topics']).to be_an Array
expect(json_response['archived']).to be_falsey
expect(json_response['visibility']).to be_present
expect(json_response['ssh_url_to_repo']).to be_present
@@ -1969,7 +1971,8 @@ RSpec.describe API::Projects do
expect(json_response['id']).to eq(project.id)
expect(json_response['description']).to eq(project.description)
expect(json_response['default_branch']).to eq(project.default_branch)
- expect(json_response['tag_list']).to be_an Array
+ expect(json_response['tag_list']).to be_an Array # deprecated in favor of 'topics'
+ expect(json_response['topics']).to be_an Array
expect(json_response['archived']).to be_falsey
expect(json_response['visibility']).to be_present
expect(json_response['ssh_url_to_repo']).to be_present
diff --git a/spec/support/helpers/query_recorder.rb b/spec/support/helpers/query_recorder.rb
index 05afbc336da..d18a1d23584 100644
--- a/spec/support/helpers/query_recorder.rb
+++ b/spec/support/helpers/query_recorder.rb
@@ -2,15 +2,16 @@
module ActiveRecord
class QueryRecorder
- attr_reader :log, :skip_cached, :cached, :data
+ attr_reader :log, :skip_cached, :skip_schema_queries, :cached, :data
UNKNOWN = %w[unknown unknown].freeze
- def initialize(skip_cached: true, log_file: nil, query_recorder_debug: false, &block)
+ def initialize(skip_cached: true, skip_schema_queries: true, log_file: nil, query_recorder_debug: false, &block)
@data = Hash.new { |h, k| h[k] = { count: 0, occurrences: [], backtrace: [], durations: [] } }
@log = []
@cached = []
@skip_cached = skip_cached
+ @skip_schema_queries = skip_schema_queries
@query_recorder_debug = ENV['QUERY_RECORDER_DEBUG'] || query_recorder_debug
@log_file = log_file
record(&block) if block_given?
@@ -79,7 +80,7 @@ module ActiveRecord
if values[:cached] && skip_cached
@cached << values[:sql]
- elsif !values[:name]&.include?("SCHEMA")
+ elsif !skip_schema_queries || !values[:name]&.include?("SCHEMA")
backtrace = @query_recorder_debug ? show_backtrace(values, duration) : nil
@log << values[:sql]
store_sql_by_source(values: values, duration: duration, backtrace: backtrace)
diff --git a/workhorse/internal/artifacts/entry.go b/workhorse/internal/artifacts/entry.go
index e727e82ec5f..0c697d40020 100644
--- a/workhorse/internal/artifacts/entry.go
+++ b/workhorse/internal/artifacts/entry.go
@@ -5,6 +5,7 @@ import (
"context"
"fmt"
"io"
+ "mime"
"net/http"
"os"
"os/exec"
@@ -52,6 +53,14 @@ func (e *entry) Inject(w http.ResponseWriter, r *http.Request, sendData string)
}
}
+func detectFileContentType(fileName string) string {
+ contentType := mime.TypeByExtension(filepath.Ext(fileName))
+ if contentType == "" {
+ contentType = "application/octet-stream"
+ }
+ return contentType
+}
+
func unpackFileFromZip(ctx context.Context, archivePath, encodedFilename string, headers http.Header, output io.Writer) error {
fileName, err := zipartifacts.DecodeFileEntry(encodedFilename)
if err != nil {
@@ -88,15 +97,7 @@ func unpackFileFromZip(ctx context.Context, archivePath, encodedFilename string,
// Write http headers about the file
headers.Set("Content-Length", contentLength)
-
- // Using application/octet-stream tells the client that we don't
- // really know what Content-Type is. Since this file is being sent
- // as attachment, browsers don't need to know to save the
- // file. Chrome doesn't appear to pay attention to Content-Type when
- // Content-Disposition is an attachment, and Firefox only uses it if there
- // is no extension in the filename. Thus, there's no need for
- // Workhorse to guess Content-Type based on the filename.
- headers.Set("Content-Type", "application/octet-stream")
+ headers.Set("Content-Type", detectFileContentType(fileName))
headers.Set("Content-Disposition", "attachment; filename=\""+escapeQuotes(basename)+"\"")
// Copy file body to client
if _, err := io.Copy(output, reader); err != nil {
diff --git a/workhorse/internal/artifacts/entry_test.go b/workhorse/internal/artifacts/entry_test.go
index 35e2bf06a0c..6f1e9d360aa 100644
--- a/workhorse/internal/artifacts/entry_test.go
+++ b/workhorse/internal/artifacts/entry_test.go
@@ -54,7 +54,7 @@ func TestDownloadingFromValidArchive(t *testing.T) {
testhelper.RequireResponseHeader(t, response,
"Content-Type",
- "application/octet-stream")
+ "text/plain; charset=utf-8")
testhelper.RequireResponseHeader(t, response,
"Content-Disposition",
"attachment; filename=\"test.txt\"")
@@ -88,7 +88,7 @@ func TestDownloadingFromValidHTTPArchive(t *testing.T) {
testhelper.RequireResponseHeader(t, response,
"Content-Type",
- "application/octet-stream")
+ "text/plain; charset=utf-8")
testhelper.RequireResponseHeader(t, response,
"Content-Disposition",
"attachment; filename=\"test.txt\"")