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 { +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 similarity index 100% rename from app/assets/javascripts/vue_shared/components/rich_content_editor/constants.js rename to 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 similarity index 100% rename from app/assets/javascripts/vue_shared/components/rich_content_editor/modals/add_image/add_image_modal.vue rename to 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 similarity index 100% rename from app/assets/javascripts/vue_shared/components/rich_content_editor/modals/add_image/upload_image_tab.vue rename to 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 similarity index 100% rename from app/assets/javascripts/vue_shared/components/rich_content_editor/modals/insert_video_modal.vue rename to 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 similarity index 100% rename from app/assets/javascripts/vue_shared/components/rich_content_editor/rich_content_editor.vue rename to 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 similarity index 100% rename from app/assets/javascripts/vue_shared/components/rich_content_editor/services/build_custom_renderer.js rename to 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 similarity index 100% rename from app/assets/javascripts/vue_shared/components/rich_content_editor/services/build_html_to_markdown_renderer.js rename to 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 similarity index 100% rename from app/assets/javascripts/vue_shared/components/rich_content_editor/services/editor_service.js rename to 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 similarity index 100% rename from app/assets/javascripts/vue_shared/components/rich_content_editor/services/renderers/build_uneditable_token.js rename to 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 similarity index 100% rename from app/assets/javascripts/vue_shared/components/rich_content_editor/services/renderers/render_attribute_definition.js rename to 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 similarity index 100% rename from app/assets/javascripts/vue_shared/components/rich_content_editor/services/renderers/render_embedded_ruby_text.js rename to 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 similarity index 100% rename from app/assets/javascripts/vue_shared/components/rich_content_editor/services/renderers/render_font_awesome_html_inline.js rename to 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 similarity index 100% rename from app/assets/javascripts/vue_shared/components/rich_content_editor/services/renderers/render_heading.js rename to 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 similarity index 100% rename from app/assets/javascripts/vue_shared/components/rich_content_editor/services/renderers/render_html_block.js rename to 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 similarity index 100% rename from app/assets/javascripts/vue_shared/components/rich_content_editor/services/renderers/render_identifier_instance_text.js rename to 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 similarity index 100% rename from app/assets/javascripts/vue_shared/components/rich_content_editor/services/renderers/render_identifier_paragraph.js rename to 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 similarity index 100% rename from app/assets/javascripts/vue_shared/components/rich_content_editor/services/renderers/render_list_item.js rename to 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 similarity index 100% rename from app/assets/javascripts/vue_shared/components/rich_content_editor/services/renderers/render_softbreak.js rename to 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 similarity index 100% rename from app/assets/javascripts/vue_shared/components/rich_content_editor/services/renderers/render_utils.js rename to 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 similarity index 100% rename from app/assets/javascripts/vue_shared/components/rich_content_editor/services/sanitize_html.js rename to 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 similarity index 100% rename from app/assets/javascripts/vue_shared/components/rich_content_editor/toolbar_item.vue rename to 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 similarity index 53% rename from config/initializers/active_record_ping.rb rename to 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).

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` +### Domain source configuration before 14.0 + +> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/217912) in GitLab 13.3. 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. +`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 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. +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. -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`. +We highly advise you to use `gitlab` configuration source as it will make transition to newer versions easier. -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. - -### GitLab API-based configuration - -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. - -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: -For other common issues, see the [troubleshooting section](#failed-to-connect-to-the-internal-gitlab-api) -or report an issue. + ```ruby + gitlab_pages['domain_config_source'] = "disk" + ``` + +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" ], @@ -300,6 +312,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 @@ -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 = /^(?\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) + shared_examples 'releases index page' do + context('when the user is a maintainer') do + before do + sign_in(maintainer) - visit project_releases_path(project) - end - - 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 - 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') - end - end - end + context 'when url points to external resource' do + let(:url) { 'http://google.com/download' } - 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 - - context 'sorting' do - def sort_page(by:, direction:) - within '[data-testid="releases-sort"]' do - find('.dropdown-toggle').click - - click_button(by, class: 'dropdown-item') - - find('.sorting-direction-button').click if direction == :ascending - 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) - - card_titles.each_with_index do |title, index| - expect(title).to have_content(expected_releases[index].name) + 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 - 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' + 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 - context "when the page is sorted by created_at ascending " do - let(:expected_releases) { [release_v2, release_v1, release_v3] } + 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 - before do - sort_page by: 'Created date', direction: :ascending + context 'sorting' do + def sort_page(by:, direction:) + within '[data-testid="releases-sort"]' do + find('.dropdown-toggle').click + + click_button(by, class: 'dropdown-item') + + find('.sorting-direction-button').click if direction == :ascending + end end - it_behaves_like 'releases sort order' + 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) + end + end + end + + 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 + + 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 + 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) + + # 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) + it_behaves_like 'releases index page' + end - within('.release-block', match: :first) do - expect(page).to have_content(release_v3.description) - - # 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 similarity index 90% rename from spec/frontend/vue_shared/components/rich_content_editor/editor_service_spec.js rename to 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 similarity index 88% rename from spec/frontend/vue_shared/components/rich_content_editor/modals/add_image/add_image_modal_spec.js rename to 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 similarity index 90% rename from spec/frontend/vue_shared/components/rich_content_editor/modals/add_image/upload_image_tab_spec.js rename to 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 similarity index 92% rename from spec/frontend/vue_shared/components/rich_content_editor/modals/insert_video_modal_spec.js rename to 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 similarity index 86% rename from spec/frontend/vue_shared/components/rich_content_editor/rich_content_editor_integration_spec.js rename to 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 similarity index 91% rename from spec/frontend/vue_shared/components/rich_content_editor/rich_content_editor_spec.js rename to 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 similarity index 89% rename from spec/frontend/vue_shared/components/rich_content_editor/services/build_custom_renderer_spec.js rename to 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 similarity index 98% rename from spec/frontend/vue_shared/components/rich_content_editor/services/build_html_to_markdown_renderer_spec.js rename to 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 similarity index 96% rename from spec/frontend/vue_shared/components/rich_content_editor/services/renderers/build_uneditable_token_spec.js rename to 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 similarity index 100% rename from spec/frontend/vue_shared/components/rich_content_editor/services/renderers/mock_data.js rename to 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 similarity index 87% rename from spec/frontend/vue_shared/components/rich_content_editor/services/renderers/render_attribute_definition_spec.js rename to 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 similarity index 76% rename from spec/frontend/vue_shared/components/rich_content_editor/services/renderers/render_embedded_ruby_spec.js rename to 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 similarity index 80% rename from spec/frontend/vue_shared/components/rich_content_editor/services/renderers/render_font_awesome_html_inline_spec.js rename to 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 similarity index 64% rename from spec/frontend/vue_shared/components/rich_content_editor/services/renderers/render_heading_spec.js rename to 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 similarity index 84% rename from spec/frontend/vue_shared/components/rich_content_editor/services/renderers/render_html_block_spec.js rename to 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 similarity index 90% rename from spec/frontend/vue_shared/components/rich_content_editor/services/renderers/render_identifier_instance_text_spec.js rename to 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 similarity index 95% rename from spec/frontend/vue_shared/components/rich_content_editor/services/renderers/render_identifier_paragraph_spec.js rename to 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 similarity index 64% rename from spec/frontend/vue_shared/components/rich_content_editor/services/renderers/render_list_item_spec.js rename to 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 similarity index 87% rename from spec/frontend/vue_shared/components/rich_content_editor/services/renderers/render_softbreak_spec.js rename to 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 similarity index 94% rename from spec/frontend/vue_shared/components/rich_content_editor/services/renderers/render_utils_spec.js rename to 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 similarity index 83% rename from spec/frontend/vue_shared/components/rich_content_editor/services/sanitize_html_spec.js rename to 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 similarity index 95% rename from spec/frontend/vue_shared/components/rich_content_editor/toolbar_item_spec.js rename to 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\"")