diff options
author | Shinya Maeda <shinya@gitlab.com> | 2018-07-30 10:11:43 +0900 |
---|---|---|
committer | Shinya Maeda <shinya@gitlab.com> | 2018-07-30 10:11:43 +0900 |
commit | 1f9992625ed8a954dde5b8e662e764c48598104d (patch) | |
tree | 07a4873d2de8dba00413175fa1bb994372e0e96b | |
parent | 8b3c7f57b249b087a36eb36588223d1c7c4dbafe (diff) | |
parent | 87f03f01735fb4b6dbef2e4bf625cf2546523a4e (diff) | |
download | gitlab-ce-1f9992625ed8a954dde5b8e662e764c48598104d.tar.gz |
Merge branch 'master-ce' into artifact-format-v2
67 files changed, 451 insertions, 226 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 8ba36bbad7b..b4b672b55c6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,24 @@ documentation](doc/development/changelog.md) for instructions on adding your own entry. +## 11.1.3 (2018-07-27) + +### Fixed (8 changes, 1 of them is from the community) + +- Rework some projects table indexes around repository_storage field. !20377 +- Fix navigation to First and Next discussion on MR Changes tab. !20434 +- Fix showing outdated discussions on Changes tab. !20445 +- Fix autosave and ESC confirmation issues for MR discussions. !20569 +- Fix rendering of the context lines in MR diffs page. !20642 +- Don't overflow project/group dropdown results. !20704 (gfyoung) +- Fixed IDE not opening JSON files. !20798 +- Disable Gitaly timeouts when creating or restoring backups. !20810 + +### Performance (1 change) + +- Reduces the client side memory footprint on merge requests. !20744 + + ## 11.1.2 (2018-07-26) ### Security (4 changes) diff --git a/GITLAB_SHELL_VERSION b/GITLAB_SHELL_VERSION index 69adf3456f8..0ee843cc604 100644 --- a/GITLAB_SHELL_VERSION +++ b/GITLAB_SHELL_VERSION @@ -1 +1 @@ -7.1.5 +7.2.0 diff --git a/Gemfile.rails5.lock b/Gemfile.rails5.lock index cb64fe554ff..b055b561b61 100644 --- a/Gemfile.rails5.lock +++ b/Gemfile.rails5.lock @@ -364,7 +364,7 @@ GEM grape-entity (0.7.1) activesupport (>= 4.0) multi_json (>= 1.3.2) - grape-path-helpers (1.0.5) + grape-path-helpers (1.0.6) activesupport (>= 4, < 5.1) grape (~> 1.0) rake (~> 12) @@ -378,7 +378,8 @@ GEM google-protobuf (~> 3.1) googleapis-common-protos-types (~> 1.0.0) googleauth (>= 0.5.1, < 0.7) - haml (4.0.7) + haml (5.0.4) + temple (>= 0.8.0) tilt haml_lint (0.26.0) haml (>= 4.0, < 5.1) @@ -400,7 +401,7 @@ GEM hipchat (1.5.2) httparty mimemagic - html-pipeline (2.8.3) + html-pipeline (2.8.4) activesupport (>= 2) nokogiri (>= 1.4) html2text (0.2.0) @@ -518,7 +519,7 @@ GEM net-ssh (5.0.1) netrc (0.11.0) nio4r (2.3.1) - nokogiri (1.8.3) + nokogiri (1.8.4) mini_portile2 (~> 2.3.0) nokogumbo (1.5.0) nokogiri @@ -821,7 +822,7 @@ GEM et-orbi (~> 1.0) rugged (0.27.2) safe_yaml (1.0.4) - sanitize (4.6.5) + sanitize (4.6.6) crass (~> 1.0.2) nokogiri (>= 1.4.4) nokogumbo (~> 1.4) @@ -915,7 +916,7 @@ GEM rack (>= 1, < 3) thor (0.19.4) thread_safe (0.3.6) - tilt (2.0.6) + tilt (2.0.8) timecop (0.8.1) timfel-krb5-auth (0.8.3) toml (0.1.2) diff --git a/app/assets/javascripts/badges/components/badge.vue b/app/assets/javascripts/badges/components/badge.vue index b4bfaee1d85..155c348286c 100644 --- a/app/assets/javascripts/badges/components/badge.vue +++ b/app/assets/javascripts/badges/components/badge.vue @@ -93,7 +93,7 @@ export default { <icon :size="16" class="prepend-left-8 append-right-8" - name="doc_image" + name="doc-image" aria-hidden="true" /> </div> diff --git a/app/assets/javascripts/ide/components/commit_sidebar/stage_button.vue b/app/assets/javascripts/ide/components/commit_sidebar/stage_button.vue index 7014b9f605e..e6044401c9f 100644 --- a/app/assets/javascripts/ide/components/commit_sidebar/stage_button.vue +++ b/app/assets/javascripts/ide/components/commit_sidebar/stage_button.vue @@ -56,7 +56,7 @@ export default { > <icon :size="12" - name="more" + name="ellipsis_h" /> </button> <div class="dropdown-menu dropdown-menu-right"> diff --git a/app/assets/javascripts/pipelines/components/graph/dropdown_job_component.vue b/app/assets/javascripts/pipelines/components/graph/dropdown_job_component.vue index 14518f86dc7..8487c8036ee 100644 --- a/app/assets/javascripts/pipelines/components/graph/dropdown_job_component.vue +++ b/app/assets/javascripts/pipelines/components/graph/dropdown_job_component.vue @@ -14,7 +14,7 @@ import tooltip from '../../../vue_shared/directives/tooltip'; * "id": 4256, * "name": "test", * "status": { - * "icon": "icon_status_success", + * "icon": "status_success", * "text": "passed", * "label": "passed", * "group": "success", diff --git a/app/assets/javascripts/pipelines/components/graph/job_component.vue b/app/assets/javascripts/pipelines/components/graph/job_component.vue index 84a3d58b770..66f95147193 100644 --- a/app/assets/javascripts/pipelines/components/graph/job_component.vue +++ b/app/assets/javascripts/pipelines/components/graph/job_component.vue @@ -13,7 +13,7 @@ import tooltip from '../../../vue_shared/directives/tooltip'; * "id": 4256, * "name": "test", * "status": { - * "icon": "icon_status_success", + * "icon": "status_success", * "text": "passed", * "label": "passed", * "group": "success", diff --git a/app/assets/stylesheets/snippets.scss b/app/assets/stylesheets/snippets.scss index 64110f9c3a0..bd777c66b56 100644 --- a/app/assets/stylesheets/snippets.scss +++ b/app/assets/stylesheets/snippets.scss @@ -22,8 +22,8 @@ height: 16px; background-size: cover; - &.gl-snippet-icon-doc_code { background-position: 0 0; } - &.gl-snippet-icon-doc_text { background-position: 0 -16px; } + &.gl-snippet-icon-doc-code { background-position: 0 0; } + &.gl-snippet-icon-doc-text { background-position: 0 -16px; } &.gl-snippet-icon-download { background-position: 0 -32px; } } diff --git a/app/finders/admin/projects_finder.rb b/app/finders/admin/projects_finder.rb index 53b77f5fed9..543bf1a1415 100644 --- a/app/finders/admin/projects_finder.rb +++ b/app/finders/admin/projects_finder.rb @@ -7,7 +7,7 @@ class Admin::ProjectsFinder end def execute - items = Project.without_deleted.with_statistics + items = Project.without_deleted.with_statistics.with_route items = by_namespace_id(items) items = by_visibilty_level(items) items = by_with_push(items) @@ -16,7 +16,7 @@ class Admin::ProjectsFinder items = by_archived(items) items = by_personal(items) items = by_name(items) - items = items.includes(namespace: [:owner]) + items = items.includes(namespace: [:owner, :route]) sort(items).page(params[:page]) end diff --git a/app/helpers/snippets_helper.rb b/app/helpers/snippets_helper.rb index 733832c1bbb..a05640773ad 100644 --- a/app/helpers/snippets_helper.rb +++ b/app/helpers/snippets_helper.rb @@ -116,7 +116,7 @@ module SnippetsHelper raw_project_snippet_url(@snippet.project, @snippet) end - link_to external_snippet_icon('doc_code'), snippet_raw_url, class: 'btn', target: '_blank', rel: 'noopener noreferrer', title: 'Open raw' + link_to external_snippet_icon('doc-code'), snippet_raw_url, class: 'btn', target: '_blank', rel: 'noopener noreferrer', title: 'Open raw' end def embedded_snippet_download_button diff --git a/app/mailers/notify.rb b/app/mailers/notify.rb index 1db1482d6b7..0e1e39501f5 100644 --- a/app/mailers/notify.rb +++ b/app/mailers/notify.rb @@ -124,7 +124,7 @@ class Notify < BaseMailer fallback_reply_message_id = "<reply-#{reply_key}@#{Gitlab.config.gitlab.host}>".freeze headers['References'] ||= [] - headers['References'] << fallback_reply_message_id + headers['References'].unshift(fallback_reply_message_id) @reply_by_email = true end @@ -158,7 +158,7 @@ class Notify < BaseMailer def mail_answer_thread(model, headers = {}) headers['Message-ID'] = "<#{SecureRandom.hex}@#{Gitlab.config.gitlab.host}>" headers['In-Reply-To'] = message_id(model) - headers['References'] = message_id(model) + headers['References'] = [message_id(model)] headers[:subject]&.prepend('Re: ') diff --git a/app/models/concerns/routable.rb b/app/models/concerns/routable.rb index 0176a12a131..cb91f8fbac8 100644 --- a/app/models/concerns/routable.rb +++ b/app/models/concerns/routable.rb @@ -90,34 +90,17 @@ module Routable end def full_name - if route && route.name.present? - @full_name ||= route.name # rubocop:disable Gitlab/ModuleWithInstanceVariables - else - update_route if persisted? - - build_full_name - end + route&.name || build_full_name end - # Every time `project.namespace.becomes(Namespace)` is called for polymorphic_path, - # a new instance is instantiated, and we end up duplicating the same query to retrieve - # the route. Caching this per request ensures that even if we have multiple instances, - # we will not have to duplicate work, avoiding N+1 queries in some cases. def full_path - return uncached_full_path unless RequestStore.active? && persisted? - - RequestStore[full_path_key] ||= uncached_full_path + route&.path || build_full_path end def full_path_components full_path.split('/') end - def expires_full_path_cache - RequestStore.delete(full_path_key) if RequestStore.active? - @full_path = nil # rubocop:disable Gitlab/ModuleWithInstanceVariables - end - def build_full_path if parent && path parent.full_path + '/' + path @@ -138,16 +121,6 @@ module Routable self.errors[:path].concat(route_path_errors) if route_path_errors end - def uncached_full_path - if route && route.path.present? - @full_path ||= route.path # rubocop:disable Gitlab/ModuleWithInstanceVariables - else - update_route if persisted? - - build_full_path - end - end - def full_name_changed? name_changed? || parent_changed? end @@ -156,10 +129,6 @@ module Routable path_changed? || parent_changed? end - def full_path_key - @full_path_key ||= "routable/full_path/#{self.class.name}/#{self.id}" - end - def build_full_name if parent && name parent.human_name + ' / ' + name @@ -168,18 +137,9 @@ module Routable end end - def update_route - return if Gitlab::Database.read_only? - - prepare_route - route.save - end - def prepare_route route || build_route(source: self) route.path = build_full_path route.name = build_full_name - @full_path = nil # rubocop:disable Gitlab/ModuleWithInstanceVariables - @full_name = nil # rubocop:disable Gitlab/ModuleWithInstanceVariables end end diff --git a/app/models/concerns/storage/legacy_namespace.rb b/app/models/concerns/storage/legacy_namespace.rb index ae6595320cb..f5225cd81ed 100644 --- a/app/models/concerns/storage/legacy_namespace.rb +++ b/app/models/concerns/storage/legacy_namespace.rb @@ -11,8 +11,6 @@ module Storage Namespace.find(parent_id_was) # raise NotFound early if needed end - expires_full_path_cache - move_repositories if parent_changed? diff --git a/app/models/deploy_token.rb b/app/models/deploy_token.rb index 7ab647abe93..fdbe95059e5 100644 --- a/app/models/deploy_token.rb +++ b/app/models/deploy_token.rb @@ -1,6 +1,7 @@ class DeployToken < ActiveRecord::Base include Expirable include TokenAuthenticatable + include PolicyActor add_authentication_token_field :token AVAILABLE_SCOPES = %i(read_repository read_registry).freeze @@ -58,10 +59,6 @@ class DeployToken < ActiveRecord::Base write_attribute(:expires_at, value.presence || Forever.date) end - def admin? - false - end - private def ensure_at_least_one_scope diff --git a/app/models/namespace.rb b/app/models/namespace.rb index 7034c633268..c1dc2f55346 100644 --- a/app/models/namespace.rb +++ b/app/models/namespace.rb @@ -304,7 +304,6 @@ class Namespace < ActiveRecord::Base def write_projects_repository_config all_projects.find_each do |project| - project.expires_full_path_cache # we need to clear cache to validate renames correctly project.write_repository_config end end diff --git a/app/models/project.rb b/app/models/project.rb index 32315dfaa01..b876270116e 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -1238,8 +1238,6 @@ class Project < ActiveRecord::Base return true if skip_disk_validation return false unless repository_storage - expires_full_path_cache # we need to clear cache to validate renames correctly - # Check if repository with same path already exists on disk we can # skip this for the hashed storage because the path does not change if legacy_storage? && repository_with_same_path_already_exists? @@ -1618,7 +1616,6 @@ class Project < ActiveRecord::Base # When we import a project overwriting the original project, there # is a move operation. In that case we don't want to send the instructions. send_move_instructions(full_path_was) unless import_started? - expires_full_path_cache self.old_path_with_namespace = full_path_was SystemHooksService.new.execute_hooks_for(self, :rename) diff --git a/app/policies/concerns/policy_actor.rb b/app/policies/concerns/policy_actor.rb new file mode 100644 index 00000000000..069d065280e --- /dev/null +++ b/app/policies/concerns/policy_actor.rb @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +# Include this module if we want to pass something else than the user to +# check policies. This defines several methods which the policy checker +# would call and check. +module PolicyActor + extend ActiveSupport::Concern + + def blocked? + false + end + + def admin? + false + end + + def external? + false + end + + def internal? + false + end + + def access_locked? + false + end + + def required_terms_not_accepted? + false + end + + def can_create_group + false + end +end diff --git a/app/serializers/pipeline_serializer.rb b/app/serializers/pipeline_serializer.rb index 4a33160afa1..3205578b83e 100644 --- a/app/serializers/pipeline_serializer.rb +++ b/app/serializers/pipeline_serializer.rb @@ -11,10 +11,15 @@ class PipelineSerializer < BaseSerializer :retryable_builds, :cancelable_statuses, :trigger_requests, - :project, :manual_actions, :artifacts, - { pending_builds: :project } + { + pending_builds: :project, + project: [:route, { namespace: :route }], + artifacts: { + project: [:route, { namespace: :route }] + } + } ]) end diff --git a/app/services/projects/transfer_service.rb b/app/services/projects/transfer_service.rb index a4a66330546..c2a0c5fa7f3 100644 --- a/app/services/projects/transfer_service.rb +++ b/app/services/projects/transfer_service.rb @@ -77,7 +77,6 @@ module Projects Gitlab::PagesTransfer.new.move_project(project.path, @old_namespace.full_path, @new_namespace.full_path) project.old_path_with_namespace = @old_path - project.expires_full_path_cache write_repository_config(@new_path) diff --git a/app/views/admin/projects/_projects.html.haml b/app/views/admin/projects/_projects.html.haml index 00933d726d9..fdaacc098e0 100644 --- a/app/views/admin/projects/_projects.html.haml +++ b/app/views/admin/projects/_projects.html.haml @@ -17,7 +17,7 @@ - if project.archived %span.badge.badge-warning archived .title - = link_to [:admin, project.namespace.becomes(Namespace), project] do + = link_to(admin_namespace_project_path(project.namespace, project)) do .dash-project-avatar .avatar-container.s40 = project_icon(project, alt: '', class: 'avatar project-avatar s40') diff --git a/app/views/layouts/header/_default.html.haml b/app/views/layouts/header/_default.html.haml index 97c04dda8cb..e8d31992149 100644 --- a/app/views/layouts/header/_default.html.haml +++ b/app/views/layouts/header/_default.html.haml @@ -67,5 +67,5 @@ %button.navbar-toggler.d-block.d-sm-none{ type: 'button' } %span.sr-only= _("Toggle navigation") - = sprite_icon('more', size: 12, css_class: 'more-icon js-navbar-toggle-right') + = sprite_icon('ellipsis_h', size: 12, css_class: 'more-icon js-navbar-toggle-right') = sprite_icon('close', size: 12, css_class: 'close-icon js-navbar-toggle-left') diff --git a/app/views/layouts/nav/sidebar/_group.html.haml b/app/views/layouts/nav/sidebar/_group.html.haml index 0a3b5ec7eea..d471dd84550 100644 --- a/app/views/layouts/nav/sidebar/_group.html.haml +++ b/app/views/layouts/nav/sidebar/_group.html.haml @@ -15,7 +15,7 @@ = nav_link(path: ['groups#show', 'groups#activity', 'groups#subgroups', 'analytics#show'], html_options: { class: 'home' }) do = link_to group_path(@group) do .nav-icon-container - = sprite_icon('project') + = sprite_icon('home') %span.nav-item-name = _('Overview') diff --git a/app/views/layouts/nav/sidebar/_profile.html.haml b/app/views/layouts/nav/sidebar/_profile.html.haml index 94863a3460d..d65f153b451 100644 --- a/app/views/layouts/nav/sidebar/_profile.html.haml +++ b/app/views/layouts/nav/sidebar/_profile.html.haml @@ -110,7 +110,7 @@ = nav_link(controller: :gpg_keys) do = link_to profile_gpg_keys_path do .nav-icon-container - = sprite_icon('key-2') + = sprite_icon('key-modern') %span.nav-item-name = _('GPG Keys') %ul.sidebar-sub-level-items.is-fly-out-only diff --git a/app/views/layouts/nav/sidebar/_project.html.haml b/app/views/layouts/nav/sidebar/_project.html.haml index 0ec61df1f0a..2c262a2b7dd 100644 --- a/app/views/layouts/nav/sidebar/_project.html.haml +++ b/app/views/layouts/nav/sidebar/_project.html.haml @@ -11,7 +11,7 @@ = nav_link(path: sidebar_projects_paths, html_options: { class: 'home' }) do = link_to project_path(@project), class: 'shortcuts-project' do .nav-icon-container - = sprite_icon('project') + = sprite_icon('home') %span.nav-item-name = _('Project') @@ -40,7 +40,7 @@ = nav_link(controller: sidebar_repository_paths) do = link_to project_tree_path(@project), class: 'shortcuts-tree' do .nav-icon-container - = sprite_icon('doc_text') + = sprite_icon('doc-text') %span.nav-item-name = _('Repository') diff --git a/app/views/projects/jobs/_sidebar.html.haml b/app/views/projects/jobs/_sidebar.html.haml index 64c441492bc..759efd4e9d4 100644 --- a/app/views/projects/jobs/_sidebar.html.haml +++ b/app/views/projects/jobs/_sidebar.html.haml @@ -86,7 +86,7 @@ - HasStatus::ORDERED_STATUSES.each do |build_status| - builds.select{|build| build.status == build_status}.each do |build| .build-job{ class: sidebar_build_class(build, @build), data: { stage: build.stage } } - - tooltip = sanitize(build.tooltip_message) + - tooltip = sanitize(build.tooltip_message.dup) = link_to(project_job_path(@project, build), data: { toggle: 'tooltip', html: 'true', title: tooltip, container: 'body' }) do = sprite_icon('arrow-right', size:16, css_class: 'icon-arrow-right') %span{ class: "ci-status-icon-#{build.status}" } diff --git a/app/views/shared/snippets/_embed.html.haml b/app/views/shared/snippets/_embed.html.haml index 36f56fbad1a..c7f0511d1de 100644 --- a/app/views/shared/snippets/_embed.html.haml +++ b/app/views/shared/snippets/_embed.html.haml @@ -2,7 +2,7 @@ .gitlab-embed-snippets .js-file-title.file-title-flex-parent .file-header-content - = external_snippet_icon('doc_text') + = external_snippet_icon('doc-text') %strong.file-title-name %a.gitlab-embedded-snippets-title{ href: url_for(only_path: false, overwrite_params: nil) } diff --git a/changelogs/unreleased/4525-fix-project-indexes.yml b/changelogs/unreleased/4525-fix-project-indexes.yml deleted file mode 100644 index 930e3b934c2..00000000000 --- a/changelogs/unreleased/4525-fix-project-indexes.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Rework some projects table indexes around repository_storage field -merge_request: 20377 -author: -type: fixed diff --git a/changelogs/unreleased/48817-fix-mr-changes-discussion-navigation.yml b/changelogs/unreleased/48817-fix-mr-changes-discussion-navigation.yml deleted file mode 100644 index ec4b843b863..00000000000 --- a/changelogs/unreleased/48817-fix-mr-changes-discussion-navigation.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fix navigation to First and Next discussion on MR Changes tab -merge_request: 20434 -author: -type: fixed diff --git a/changelogs/unreleased/_acet-fix-expanding-context-lines.yml b/changelogs/unreleased/_acet-fix-expanding-context-lines.yml deleted file mode 100644 index 41b4dbca5d6..00000000000 --- a/changelogs/unreleased/_acet-fix-expanding-context-lines.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fix rendering of the context lines in MR diffs page -merge_request: 20642 -author: -type: fixed diff --git a/changelogs/unreleased/_acet-fix-mr-autosave.yml b/changelogs/unreleased/_acet-fix-mr-autosave.yml deleted file mode 100644 index f87b32f68e2..00000000000 --- a/changelogs/unreleased/_acet-fix-mr-autosave.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fix autosave and ESC confirmation issues for MR discussions -merge_request: 20569 -author: -type: fixed diff --git a/changelogs/unreleased/_acet-fix-outdated-discussions.yml b/changelogs/unreleased/_acet-fix-outdated-discussions.yml deleted file mode 100644 index d31483b4765..00000000000 --- a/changelogs/unreleased/_acet-fix-outdated-discussions.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fix showing outdated discussions on Changes tab -merge_request: 20445 -author: -type: fixed diff --git a/changelogs/unreleased/ide-edit-json-files.yml b/changelogs/unreleased/ide-edit-json-files.yml deleted file mode 100644 index 2a6e6b80de1..00000000000 --- a/changelogs/unreleased/ide-edit-json-files.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fixed IDE not opening JSON files -merge_request: 20798 -author: -type: fixed diff --git a/changelogs/unreleased/project-dropdown-list-overflow.yml b/changelogs/unreleased/project-dropdown-list-overflow.yml deleted file mode 100644 index 9b74a68291b..00000000000 --- a/changelogs/unreleased/project-dropdown-list-overflow.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Don't overflow project/group dropdown results -merge_request: 20704 -author: gfyoung -type: fixed diff --git a/changelogs/unreleased/rails5-update-gemfile-lock-2.yml b/changelogs/unreleased/rails5-update-gemfile-lock-2.yml new file mode 100644 index 00000000000..1f3e9bd2238 --- /dev/null +++ b/changelogs/unreleased/rails5-update-gemfile-lock-2.yml @@ -0,0 +1,5 @@ +--- +title: Rails5 update Gemfile.rails5.lock +merge_request: 20858 +author: Jasper Maes +type: fixed diff --git a/changelogs/unreleased/stop-dynamic-routable-creation.yml b/changelogs/unreleased/stop-dynamic-routable-creation.yml new file mode 100644 index 00000000000..8bfcb5b2d11 --- /dev/null +++ b/changelogs/unreleased/stop-dynamic-routable-creation.yml @@ -0,0 +1,5 @@ +--- +title: Stop dynamically creating project and namespace routes +merge_request: 20313 +author: +type: performance diff --git a/changelogs/unreleased/tc-reorder-mail-notify-references.yml b/changelogs/unreleased/tc-reorder-mail-notify-references.yml new file mode 100644 index 00000000000..689afda0259 --- /dev/null +++ b/changelogs/unreleased/tc-reorder-mail-notify-references.yml @@ -0,0 +1,5 @@ +--- +title: Put fallback reply-key address first in the References header +merge_request: 20871 +author: +type: changed diff --git a/changelogs/unreleased/tz-mr-refactor-memory-reduction.yml b/changelogs/unreleased/tz-mr-refactor-memory-reduction.yml deleted file mode 100644 index 16003fa9cad..00000000000 --- a/changelogs/unreleased/tz-mr-refactor-memory-reduction.yml +++ /dev/null @@ -1,5 +0,0 @@ ----
-title: Reduces the client side memory footprint on merge requests
-merge_request: 20744
-author:
-type: performance
diff --git a/changelogs/unreleased/zj-backup-timeout.yml b/changelogs/unreleased/zj-backup-timeout.yml deleted file mode 100644 index b2ad2ed8c63..00000000000 --- a/changelogs/unreleased/zj-backup-timeout.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Disable Gitaly timeouts when creating or restoring backups -merge_request: 20810 -author: -type: fixed diff --git a/config/application.rb b/config/application.rb index b4b9deee8fd..b9d4f6765e3 100644 --- a/config/application.rb +++ b/config/application.rb @@ -43,6 +43,7 @@ module Gitlab #{config.root}/app/models/members #{config.root}/app/models/project_services #{config.root}/app/workers/concerns + #{config.root}/app/policies/concerns #{config.root}/app/services/concerns #{config.root}/app/serializers/concerns #{config.root}/app/finders/concerns diff --git a/db/migrate/20180702124358_remove_orphaned_routes.rb b/db/migrate/20180702124358_remove_orphaned_routes.rb new file mode 100644 index 00000000000..6f6e289ba87 --- /dev/null +++ b/db/migrate/20180702124358_remove_orphaned_routes.rb @@ -0,0 +1,49 @@ +# See http://doc.gitlab.com/ce/development/migration_style_guide.html +# for more information on how to write migrations for GitLab. + +class RemoveOrphanedRoutes < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + DOWNTIME = false + + disable_ddl_transaction! + + class Route < ActiveRecord::Base + self.table_name = 'routes' + include EachBatch + + def self.orphaned_namespace_routes + where(source_type: 'Namespace') + .where('NOT EXISTS ( SELECT 1 FROM namespaces WHERE namespaces.id = routes.source_id )') + end + + def self.orphaned_project_routes + where(source_type: 'Project') + .where('NOT EXISTS ( SELECT 1 FROM projects WHERE projects.id = routes.source_id )') + end + end + + def up + # Some of these queries can take up to 10 seconds to run on GitLab.com, + # which is pretty close to our 15 second statement timeout. To ensure a + # smooth deployment procedure we disable the statement timeouts for this + # migration, just in case. + disable_statement_timeout + + # On GitLab.com there are around 4000 orphaned project routes, and around + # 150 orphaned namespace routes. + [ + Route.orphaned_project_routes, + Route.orphaned_namespace_routes + ].each do |relation| + relation.each_batch(of: 1_000) do |batch| + batch.delete_all + end + end + end + + def down + # There is no way to restore orphaned routes, and this doesn't make any + # sense anyway. + end +end diff --git a/db/migrate/20180702134423_generate_missing_routes.rb b/db/migrate/20180702134423_generate_missing_routes.rb new file mode 100644 index 00000000000..994725f9bd1 --- /dev/null +++ b/db/migrate/20180702134423_generate_missing_routes.rb @@ -0,0 +1,143 @@ +# See http://doc.gitlab.com/ce/development/migration_style_guide.html +# for more information on how to write migrations for GitLab. + +# This migration generates missing routes for any projects and namespaces that +# don't already have a route. +# +# On GitLab.com this would insert 611 project routes, and 0 namespace routes. +# The exact number could vary per instance, so we take care of both just in +# case. +class GenerateMissingRoutes < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + DOWNTIME = false + + disable_ddl_transaction! + + class User < ActiveRecord::Base + self.table_name = 'users' + end + + class Route < ActiveRecord::Base + self.table_name = 'routes' + end + + module Routable + def build_full_path + if parent && path + parent.build_full_path + '/' + path + else + path + end + end + + def build_full_name + if parent && name + parent.human_name + ' / ' + name + else + name + end + end + + def human_name + build_full_name + end + + def attributes_for_insert + time = Time.zone.now + + { + # We can't use "self.class.name" here as that would include the + # migration namespace. + source_type: source_type_for_route, + source_id: id, + created_at: time, + updated_at: time, + name: build_full_name, + + # The route path might already be taken. Instead of trying to generate a + # new unique name on every conflict, we just append the row ID to the + # route path. + path: "#{build_full_path}-#{id}" + } + end + end + + class Project < ActiveRecord::Base + self.table_name = 'projects' + + include EachBatch + include GenerateMissingRoutes::Routable + + belongs_to :namespace, class_name: 'GenerateMissingRoutes::Namespace' + + has_one :route, + as: :source, + inverse_of: :source, + class_name: 'GenerateMissingRoutes::Route' + + alias_method :parent, :namespace + alias_attribute :parent_id, :namespace_id + + def self.without_routes + where( + 'NOT EXISTS ( + SELECT 1 + FROM routes + WHERE source_type = ? + AND source_id = projects.id + )', + 'Project' + ) + end + + def source_type_for_route + 'Project' + end + end + + class Namespace < ActiveRecord::Base + self.table_name = 'namespaces' + + include EachBatch + include GenerateMissingRoutes::Routable + + belongs_to :parent, class_name: 'GenerateMissingRoutes::Namespace' + belongs_to :owner, class_name: 'GenerateMissingRoutes::User' + + has_one :route, + as: :source, + inverse_of: :source, + class_name: 'GenerateMissingRoutes::Route' + + def self.without_routes + where( + 'NOT EXISTS ( + SELECT 1 + FROM routes + WHERE source_type = ? + AND source_id = namespaces.id + )', + 'Namespace' + ) + end + + def source_type_for_route + 'Namespace' + end + end + + def up + [Namespace, Project].each do |model| + model.without_routes.each_batch(of: 100) do |batch| + rows = batch.map(&:attributes_for_insert) + + Gitlab::Database.bulk_insert(:routes, rows) + end + end + end + + def down + # Removing routes we previously generated makes no sense. + end +end diff --git a/lib/gitlab/git/conflict/resolver.rb b/lib/gitlab/git/conflict/resolver.rb index 0e4a973301f..6dc792c16b8 100644 --- a/lib/gitlab/git/conflict/resolver.rb +++ b/lib/gitlab/git/conflict/resolver.rb @@ -17,7 +17,7 @@ module Gitlab end rescue GRPC::FailedPrecondition => e raise Gitlab::Git::Conflict::Resolver::ConflictSideMissing.new(e.message) - rescue Rugged::ReferenceError, Rugged::OdbError, GRPC::BadStatus => e + rescue GRPC::BadStatus => e raise Gitlab::Git::CommandError.new(e) end diff --git a/lib/gitlab/git/repository.rb b/lib/gitlab/git/repository.rb index 0356e8efc5c..eb02c7ac8e1 100644 --- a/lib/gitlab/git/repository.rb +++ b/lib/gitlab/git/repository.rb @@ -558,7 +558,9 @@ module Gitlab if is_enabled gitaly_operation_client.user_update_branch(branch_name, user, newrev, oldrev) else - OperationService.new(user, self).update_branch(branch_name, newrev, oldrev) + Gitlab::GitalyClient::StorageSettings.allow_disk_access do + OperationService.new(user, self).update_branch(branch_name, newrev, oldrev) + end end end end @@ -832,18 +834,9 @@ module Gitlab Gitlab::Git.check_namespace!(source_repository) source_repository = RemoteRepository.new(source_repository) unless source_repository.is_a?(RemoteRepository) - message, status = GitalyClient.migrate(:fetch_ref) do |is_enabled| - if is_enabled - gitaly_fetch_ref(source_repository, source_ref: source_ref, target_ref: target_ref) - else - # When removing this code, also remove source_repository#path - # to remove deprecated method calls - local_fetch_ref(source_repository.path, source_ref: source_ref, target_ref: target_ref) - end - end - - # Make sure ref was created, and raise Rugged::ReferenceError when not - raise Rugged::ReferenceError, message if status != 0 + args = %W(fetch --no-tags -f #{GITALY_INTERNAL_URL} #{source_ref}:#{target_ref}) + message, status = run_git(args, env: source_repository.fetch_env) + raise Gitlab::Git::CommandError, message if status != 0 target_ref end @@ -1244,17 +1237,6 @@ module Gitlab gitaly_repository_client.apply_gitattributes(revision) end - def local_fetch_ref(source_path, source_ref:, target_ref:) - args = %W(fetch --no-tags -f #{source_path} #{source_ref}:#{target_ref}) - run_git(args) - end - - def gitaly_fetch_ref(source_repository, source_ref:, target_ref:) - args = %W(fetch --no-tags -f #{GITALY_INTERNAL_URL} #{source_ref}:#{target_ref}) - - run_git(args, env: source_repository.fetch_env) - end - def gitaly_delete_refs(*ref_names) gitaly_ref_client.delete_refs(refs: ref_names) if ref_names.any? end diff --git a/lib/gitlab/git/repository_mirroring.rb b/lib/gitlab/git/repository_mirroring.rb index 8835bfb2481..65eb5cc18cf 100644 --- a/lib/gitlab/git/repository_mirroring.rb +++ b/lib/gitlab/git/repository_mirroring.rb @@ -6,7 +6,9 @@ module Gitlab if is_enabled gitaly_ref_client.remote_branches(remote_name) else - rugged_remote_branches(remote_name) + Gitlab::GitalyClient::StorageSettings.allow_disk_access do + rugged_remote_branches(remote_name) + end end end end diff --git a/lib/gitlab/import_export/merge_request_parser.rb b/lib/gitlab/import_export/merge_request_parser.rb index d0527f014a7..62a1833b39c 100644 --- a/lib/gitlab/import_export/merge_request_parser.rb +++ b/lib/gitlab/import_export/merge_request_parser.rb @@ -27,7 +27,11 @@ module Gitlab # Gitaly migration: https://gitlab.com/gitlab-org/gitaly/issues/1295 def fetch_ref - @project.repository.fetch_ref(@project.repository, source_ref: @diff_head_sha, target_ref: @merge_request.source_branch) + target_ref = Gitlab::Git::BRANCH_REF_PREFIX + @merge_request.source_branch + + unless @project.repository.fetch_source_branch!(@project.repository, @diff_head_sha, target_ref) + Rails.logger.warn("Import/Export warning: Failed to create #{target_ref} for MR: #{@merge_request.iid}") + end end def branch_exists?(branch_name) diff --git a/package.json b/package.json index 33a6827e7df..2a8761e32d6 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "webpack-prod": "NODE_ENV=production webpack --config config/webpack.config.js" }, "dependencies": { - "@gitlab-org/gitlab-svgs": "^1.26.0", + "@gitlab-org/gitlab-svgs": "^1.27.0", "@gitlab-org/gitlab-ui": "1.0.5", "autosize": "^4.0.0", "axios": "^0.17.1", diff --git a/spec/controllers/projects/pipelines_controller_spec.rb b/spec/controllers/projects/pipelines_controller_spec.rb index 290fcd4f8e6..d89716b1b50 100644 --- a/spec/controllers/projects/pipelines_controller_spec.rb +++ b/spec/controllers/projects/pipelines_controller_spec.rb @@ -55,10 +55,8 @@ describe Projects::PipelinesController do stub_feature_flags(ci_pipeline_persisted_stages: false) end - it 'returns JSON with serialized pipelines', :request_store do - queries = ActiveRecord::QueryRecorder.new do - get_pipelines_index_json - end + it 'returns JSON with serialized pipelines' do + get_pipelines_index_json expect(response).to have_gitlab_http_status(:ok) expect(response).to match_response_schema('pipeline') @@ -73,8 +71,14 @@ describe Projects::PipelinesController do json_response.dig('pipelines', 0, 'details', 'stages').tap do |stages| expect(stages.count).to eq 3 end + end + + it 'does not execute N+1 queries' do + queries = ActiveRecord::QueryRecorder.new do + get_pipelines_index_json + end - expect(queries.count).to be_within(5).of(30) + expect(queries.count).to be <= 36 end end diff --git a/spec/fixtures/emails/commands_in_reply.eml b/spec/fixtures/emails/commands_in_reply.eml index 712f6f797b4..6a467ccbbc6 100644 --- a/spec/fixtures/emails/commands_in_reply.eml +++ b/spec/fixtures/emails/commands_in_reply.eml @@ -8,7 +8,7 @@ From: Jake the Dog <jake@adventuretime.ooo> To: reply+59d8df8370b7e95c5a49fbf86aeb2c93@appmail.adventuretime.ooo Message-ID: <CADkmRc+rNGAGGbV2iE5p918UVy4UyJqVcXRO2=otppgzduJSg@mail.gmail.com> In-Reply-To: <issue_1@localhost> -References: <issue_1@localhost> <reply-59d8df8370b7e95c5a49fbf86aeb2c93@localhost> +References: <reply-59d8df8370b7e95c5a49fbf86aeb2c93@localhost> <issue_1@localhost> Subject: re: [Discourse Meta] eviltrout posted in 'Adventure Time Sux' Mime-Version: 1.0 Content-Type: text/plain; diff --git a/spec/fixtures/emails/commands_only_reply.eml b/spec/fixtures/emails/commands_only_reply.eml index 2d2e2f94290..9b8d25c406e 100644 --- a/spec/fixtures/emails/commands_only_reply.eml +++ b/spec/fixtures/emails/commands_only_reply.eml @@ -8,7 +8,7 @@ From: Jake the Dog <jake@adventuretime.ooo> To: reply+59d8df8370b7e95c5a49fbf86aeb2c93@appmail.adventuretime.ooo Message-ID: <CADkmRc+rNGAGGbV2iE5p918UVy4UyJqVcXRO2=otppgzduJSg@mail.gmail.com> In-Reply-To: <issue_1@localhost> -References: <issue_1@localhost> <reply-59d8df8370b7e95c5a49fbf86aeb2c93@localhost> +References: <reply-59d8df8370b7e95c5a49fbf86aeb2c93@localhost> <issue_1@localhost> Subject: re: [Discourse Meta] eviltrout posted in 'Adventure Time Sux' Mime-Version: 1.0 Content-Type: text/plain; diff --git a/spec/fixtures/emails/reply_without_subaddressing_and_key_inside_references.eml b/spec/fixtures/emails/reply_without_subaddressing_and_key_inside_references.eml index 39d5cefbc2a..609d9d9e93d 100644 --- a/spec/fixtures/emails/reply_without_subaddressing_and_key_inside_references.eml +++ b/spec/fixtures/emails/reply_without_subaddressing_and_key_inside_references.eml @@ -8,7 +8,7 @@ From: Jake the Dog <jake@adventuretime.ooo> To: reply@appmail.adventuretime.ooo Message-ID: <CADkmRc+rNGAGGbV2iE5p918UVy4UyJqVcXRO2=otppgzduJSg@mail.gmail.com> In-Reply-To: <issue_1@localhost> -References: <issue_1@localhost> <reply-59d8df8370b7e95c5a49fbf86aeb2c93@localhost> +References: <reply-59d8df8370b7e95c5a49fbf86aeb2c93@localhost> <issue_1@localhost> Subject: re: [Discourse Meta] eviltrout posted in 'Adventure Time Sux' Mime-Version: 1.0 Content-Type: text/plain; diff --git a/spec/fixtures/emails/reply_without_subaddressing_and_key_inside_references_with_a_comma.eml b/spec/fixtures/emails/reply_without_subaddressing_and_key_inside_references_with_a_comma.eml index 6823db0cfc8..7be1ed5bf44 100644 --- a/spec/fixtures/emails/reply_without_subaddressing_and_key_inside_references_with_a_comma.eml +++ b/spec/fixtures/emails/reply_without_subaddressing_and_key_inside_references_with_a_comma.eml @@ -8,7 +8,7 @@ From: Jake the Dog <jake@adventuretime.ooo> To: reply@appmail.adventuretime.ooo Message-ID: <CADkmRc+rNGAGGbV2iE5p918UVy4UyJqVcXRO2=otppgzduJSg@mail.gmail.com> In-Reply-To: <issue_1@localhost> -References: <issue_1@localhost> <reply-59d8df8370b7e95c5a49fbf86aeb2c93@localhost>,<exchange@microsoft.com> +References: <reply-59d8df8370b7e95c5a49fbf86aeb2c93@localhost> <issue_1@localhost>,<exchange@microsoft.com> Subject: re: [Discourse Meta] eviltrout posted in 'Adventure Time Sux' Mime-Version: 1.0 Content-Type: text/plain; diff --git a/spec/fixtures/emails/update_commands_only_reply.eml b/spec/fixtures/emails/update_commands_only_reply.eml index bb0d2b0e03a..927a62f6475 100644 --- a/spec/fixtures/emails/update_commands_only_reply.eml +++ b/spec/fixtures/emails/update_commands_only_reply.eml @@ -8,7 +8,7 @@ From: Jake the Dog <jake@adventuretime.ooo> To: reply+59d8df8370b7e95c5a49fbf86aeb2c93@appmail.adventuretime.ooo Message-ID: <CADkmRc+rNGAGGbV2iE5p918UVy4UyJqVcXRO2=otppgzduJSg@mail.gmail.com> In-Reply-To: <issue_1@localhost> -References: <issue_1@localhost> <reply-59d8df8370b7e95c5a49fbf86aeb2c93@localhost> +References: <reply-59d8df8370b7e95c5a49fbf86aeb2c93@localhost> <issue_1@localhost> Subject: re: [Discourse Meta] eviltrout posted in 'Adventure Time Sux' Mime-Version: 1.0 Content-Type: text/plain; diff --git a/spec/fixtures/emails/valid_reply.eml b/spec/fixtures/emails/valid_reply.eml index 980e10a8812..5fbeebdb6b0 100644 --- a/spec/fixtures/emails/valid_reply.eml +++ b/spec/fixtures/emails/valid_reply.eml @@ -8,7 +8,7 @@ From: Jake the Dog <jake@adventuretime.ooo> To: reply+59d8df8370b7e95c5a49fbf86aeb2c93@appmail.adventuretime.ooo Message-ID: <CADkmRc+rNGAGGbV2iE5p918UVy4UyJqVcXRO2=otppgzduJSg@mail.gmail.com> In-Reply-To: <issue_1@localhost> -References: <issue_1@localhost> <reply-59d8df8370b7e95c5a49fbf86aeb2c93@localhost> +References: <reply-59d8df8370b7e95c5a49fbf86aeb2c93@localhost> <issue_1@localhost> Subject: re: [Discourse Meta] eviltrout posted in 'Adventure Time Sux' Mime-Version: 1.0 Content-Type: text/plain; diff --git a/spec/helpers/snippets_helper_spec.rb b/spec/helpers/snippets_helper_spec.rb index 0323ffb641c..ce5e037f88d 100644 --- a/spec/helpers/snippets_helper_spec.rb +++ b/spec/helpers/snippets_helper_spec.rb @@ -7,13 +7,13 @@ describe SnippetsHelper do it 'gives view raw button of embedded snippets for project snippets' do @snippet = create(:project_snippet, :public) - expect(embedded_snippet_raw_button.to_s).to eq("<a class=\"btn\" target=\"_blank\" rel=\"noopener noreferrer\" title=\"Open raw\" href=\"#{raw_project_snippet_url(@snippet.project, @snippet)}\">#{external_snippet_icon('doc_code')}</a>") + expect(embedded_snippet_raw_button.to_s).to eq("<a class=\"btn\" target=\"_blank\" rel=\"noopener noreferrer\" title=\"Open raw\" href=\"#{raw_project_snippet_url(@snippet.project, @snippet)}\">#{external_snippet_icon('doc-code')}</a>") end it 'gives view raw button of embedded snippets for personal snippets' do @snippet = create(:personal_snippet, :public) - expect(embedded_snippet_raw_button.to_s).to eq("<a class=\"btn\" target=\"_blank\" rel=\"noopener noreferrer\" title=\"Open raw\" href=\"#{raw_snippet_url(@snippet)}\">#{external_snippet_icon('doc_code')}</a>") + expect(embedded_snippet_raw_button.to_s).to eq("<a class=\"btn\" target=\"_blank\" rel=\"noopener noreferrer\" title=\"Open raw\" href=\"#{raw_snippet_url(@snippet)}\">#{external_snippet_icon('doc-code')}</a>") end end diff --git a/spec/javascripts/pipelines/graph/dropdown_job_component_spec.js b/spec/javascripts/pipelines/graph/dropdown_job_component_spec.js index 608a0d4be67..ff584396d61 100644 --- a/spec/javascripts/pipelines/graph/dropdown_job_component_spec.js +++ b/spec/javascripts/pipelines/graph/dropdown_job_component_spec.js @@ -12,7 +12,7 @@ describe('dropdown job component', () => { id: 4256, name: '<img src=x onerror=alert(document.domain)>', status: { - icon: 'icon_status_success', + icon: 'status_success', text: 'passed', label: 'passed', tooltip: 'passed', @@ -31,7 +31,7 @@ describe('dropdown job component', () => { id: 4299, name: 'test', status: { - icon: 'icon_status_success', + icon: 'status_success', text: 'passed', label: 'passed', tooltip: 'passed', @@ -50,7 +50,7 @@ describe('dropdown job component', () => { name: 'rspec:linux', size: 2, status: { - icon: 'icon_status_success', + icon: 'status_success', text: 'passed', label: 'passed', tooltip: 'passed', diff --git a/spec/javascripts/pipelines/graph/job_component_spec.js b/spec/javascripts/pipelines/graph/job_component_spec.js index 59f18d9397d..215ce1e81b5 100644 --- a/spec/javascripts/pipelines/graph/job_component_spec.js +++ b/spec/javascripts/pipelines/graph/job_component_spec.js @@ -169,7 +169,7 @@ describe('pipeline graph job component', () => { id: 4259, name: '<img src=x onerror=alert(document.domain)>', status: { - icon: 'icon_status_success', + icon: 'status_success', label: 'success', tooltip: 'failed', }, diff --git a/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb b/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb index bac5693c830..a88ac0a091e 100644 --- a/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb +++ b/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb @@ -16,7 +16,7 @@ describe Gitlab::ImportExport::ProjectTreeRestorer do @shared = @project.import_export_shared allow(@shared).to receive(:export_path).and_return('spec/lib/gitlab/import_export/') - allow_any_instance_of(Repository).to receive(:fetch_ref).and_return(true) + allow_any_instance_of(Repository).to receive(:fetch_source_branch!).and_return(true) allow_any_instance_of(Gitlab::Git::Repository).to receive(:branch_exists?).and_return(false) expect_any_instance_of(Gitlab::Git::Repository).to receive(:create_branch).with('feature', 'DCBA') diff --git a/spec/migrations/generate_missing_routes_spec.rb b/spec/migrations/generate_missing_routes_spec.rb new file mode 100644 index 00000000000..32515d353b0 --- /dev/null +++ b/spec/migrations/generate_missing_routes_spec.rb @@ -0,0 +1,84 @@ +require 'spec_helper' +require Rails.root.join('db', 'migrate', '20180702134423_generate_missing_routes.rb') + +describe GenerateMissingRoutes, :migration do + describe '#up' do + let(:namespaces) { table(:namespaces) } + let(:projects) { table(:projects) } + let(:routes) { table(:routes) } + + it 'creates routes for projects without a route' do + namespace = namespaces.create!(name: 'GitLab', path: 'gitlab') + + routes.create!( + path: 'gitlab', + source_type: 'Namespace', + source_id: namespace.id + ) + + project = projects.create!( + name: 'GitLab CE', + path: 'gitlab-ce', + namespace_id: namespace.id + ) + + described_class.new.up + + route = routes.where(source_type: 'Project').take + + expect(route.source_id).to eq(project.id) + expect(route.path).to eq("gitlab/gitlab-ce-#{project.id}") + end + + it 'creates routes for namespaces without a route' do + namespace = namespaces.create!(name: 'GitLab', path: 'gitlab') + + described_class.new.up + + route = routes.where(source_type: 'Namespace').take + + expect(route.source_id).to eq(namespace.id) + expect(route.path).to eq("gitlab-#{namespace.id}") + end + + it 'does not create routes for namespaces that already have a route' do + namespace = namespaces.create!(name: 'GitLab', path: 'gitlab') + + routes.create!( + path: 'gitlab', + source_type: 'Namespace', + source_id: namespace.id + ) + + described_class.new.up + + expect(routes.count).to eq(1) + end + + it 'does not create routes for projects that already have a route' do + namespace = namespaces.create!(name: 'GitLab', path: 'gitlab') + + routes.create!( + path: 'gitlab', + source_type: 'Namespace', + source_id: namespace.id + ) + + project = projects.create!( + name: 'GitLab CE', + path: 'gitlab-ce', + namespace_id: namespace.id + ) + + routes.create!( + path: 'gitlab/gitlab-ce', + source_type: 'Project', + source_id: project.id + ) + + described_class.new.up + + expect(routes.count).to eq(2) + end + end +end diff --git a/spec/models/concerns/routable_spec.rb b/spec/models/concerns/routable_spec.rb index ed3e28fbeca..565266321d3 100644 --- a/spec/models/concerns/routable_spec.rb +++ b/spec/models/concerns/routable_spec.rb @@ -12,16 +12,6 @@ describe Group, 'Routable' do it { is_expected.to have_many(:redirect_routes).dependent(:destroy) } end - describe 'GitLab read-only instance' do - it 'does not save route if route is not present' do - group.route.path = '' - allow(Gitlab::Database).to receive(:read_only?).and_return(true) - expect(group).to receive(:update_route).and_call_original - - expect { group.full_path }.to change { Route.count }.by(0) - end - end - describe 'Callbacks' do it 'creates route record on create' do expect(group.route.path).to eq(group.path) @@ -131,29 +121,6 @@ describe Group, 'Routable' do it { expect(group.full_path).to eq(group.path) } it { expect(nested_group.full_path).to eq("#{group.full_path}/#{nested_group.path}") } - - context 'with RequestStore active', :request_store do - it 'does not load the route table more than once' do - group.expires_full_path_cache - expect(group).to receive(:uncached_full_path).once.and_call_original - - 3.times { group.full_path } - expect(group.full_path).to eq(group.path) - end - end - end - - describe '#expires_full_path_cache' do - context 'with RequestStore active', :request_store do - it 'expires the full_path cache' do - expect(group.full_path).to eq('foo') - - group.route.update(path: 'bar', name: 'bar') - group.expires_full_path_cache - - expect(group.full_path).to eq('bar') - end - end end describe '#full_name' do diff --git a/spec/models/namespace_spec.rb b/spec/models/namespace_spec.rb index 8ff16cbd7cc..9b7f932ec3a 100644 --- a/spec/models/namespace_spec.rb +++ b/spec/models/namespace_spec.rb @@ -323,6 +323,16 @@ describe Namespace do parent.update(path: 'mygroup_new') + # Routes are loaded when creating the projects, so we need to manually + # reload them for the below code to be aware of the above UPDATE. + [ + project_in_parent_group, + hashed_project_in_subgroup, + legacy_project_in_subgroup + ].each do |project| + project.route.reload + end + expect(project_rugged(project_in_parent_group).config['gitlab.fullpath']).to eq "mygroup_new/#{project_in_parent_group.path}" expect(project_rugged(hashed_project_in_subgroup).config['gitlab.fullpath']).to eq "mygroup_new/mysubgroup/#{hashed_project_in_subgroup.path}" expect(project_rugged(legacy_project_in_subgroup).config['gitlab.fullpath']).to eq "mygroup_new/mysubgroup/#{legacy_project_in_subgroup.path}" diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index 88442247093..b75ca91b007 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -2958,8 +2958,6 @@ describe Project do expect(project).to receive(:expire_caches_before_rename) - expect(project).to receive(:expires_full_path_cache) - project.rename_repo end @@ -3119,8 +3117,6 @@ describe Project do expect(project).to receive(:expire_caches_before_rename) - expect(project).to receive(:expires_full_path_cache) - project.rename_repo end diff --git a/spec/models/repository_spec.rb b/spec/models/repository_spec.rb index 5d64602ca56..52ec8dbe25a 100644 --- a/spec/models/repository_spec.rb +++ b/spec/models/repository_spec.rb @@ -1129,16 +1129,12 @@ describe Repository do end it 'raises Rugged::ReferenceError' do - raise_reference_error = raise_error(Rugged::ReferenceError) do |err| - expect(err.cause).to be_nil - end - expect do Gitlab::Git::OperationService.new(git_user, target_project.repository.raw_repository) .with_branch('feature', start_repository: project.repository.raw_repository, &:itself) - end.to raise_reference_error + end.to raise_error(Gitlab::Git::CommandError) end end diff --git a/spec/policies/concerns/policy_actor_spec.rb b/spec/policies/concerns/policy_actor_spec.rb new file mode 100644 index 00000000000..27db9710a38 --- /dev/null +++ b/spec/policies/concerns/policy_actor_spec.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe PolicyActor do + it 'implements all the methods from user' do + methods = subject.instance_methods + + # User.instance_methods do not return all methods until an instance is + # initialized. So here we just use an instance + expect(build(:user).methods).to include(*methods) + end +end diff --git a/spec/serializers/pipeline_serializer_spec.rb b/spec/serializers/pipeline_serializer_spec.rb index eb4235e3ee6..cf57776346a 100644 --- a/spec/serializers/pipeline_serializer_spec.rb +++ b/spec/serializers/pipeline_serializer_spec.rb @@ -125,7 +125,7 @@ describe PipelineSerializer do it 'verifies number of queries', :request_store do recorded = ActiveRecord::QueryRecorder.new { subject } - expect(recorded.count).to be_within(2).of(27) + expect(recorded.count).to be_within(2).of(31) expect(recorded.cached_count).to eq(0) end end @@ -144,7 +144,7 @@ describe PipelineSerializer do # pipeline. With the same ref this check is cached but if refs are # different then there is an extra query per ref # https://gitlab.com/gitlab-org/gitlab-ce/issues/46368 - expect(recorded.count).to be_within(2).of(30) + expect(recorded.count).to be_within(2).of(34) expect(recorded.cached_count).to eq(0) end end diff --git a/spec/services/projects/transfer_service_spec.rb b/spec/services/projects/transfer_service_spec.rb index 7e85f599afb..1a85c52fc97 100644 --- a/spec/services/projects/transfer_service_spec.rb +++ b/spec/services/projects/transfer_service_spec.rb @@ -31,12 +31,6 @@ describe Projects::TransferService do transfer_project(project, user, group) end - it 'expires full_path cache' do - expect(project).to receive(:expires_full_path_cache) - - transfer_project(project, user, group) - end - it 'invalidates the user\'s personal_project_count cache' do expect(user).to receive(:invalidate_personal_projects_count) diff --git a/spec/support/shared_examples/notify_shared_examples.rb b/spec/support/shared_examples/notify_shared_examples.rb index d176d3fa425..5beae005cf7 100644 --- a/spec/support/shared_examples/notify_shared_examples.rb +++ b/spec/support/shared_examples/notify_shared_examples.rb @@ -77,7 +77,7 @@ shared_examples 'a thread answer email with reply-by-email enabled' do aggregate_failures do is_expected.to have_header('Message-ID', /\A<.*@#{host}>\Z/) is_expected.to have_header('In-Reply-To', "<#{route_key}@#{host}>") - is_expected.to have_header('References', /\A<#{route_key}@#{host}> <reply\-.*@#{host}>\Z/ ) + is_expected.to have_header('References', /\A<reply\-.*@#{host}> <#{route_key}@#{host}>\Z/ ) is_expected.to have_subject(/^Re: /) end end diff --git a/yarn.lock b/yarn.lock index ab84c63e837..21e62a6d36a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -78,9 +78,9 @@ lodash "^4.2.0" to-fast-properties "^2.0.0" -"@gitlab-org/gitlab-svgs@^1.23.0", "@gitlab-org/gitlab-svgs@^1.26.0": - version "1.26.0" - resolved "https://registry.yarnpkg.com/@gitlab-org/gitlab-svgs/-/gitlab-svgs-1.26.0.tgz#d89c633e866d031a9e4787b05eacc7144c3a7791" +"@gitlab-org/gitlab-svgs@^1.23.0", "@gitlab-org/gitlab-svgs@^1.27.0": + version "1.27.0" + resolved "https://registry.yarnpkg.com/@gitlab-org/gitlab-svgs/-/gitlab-svgs-1.27.0.tgz#638e70399ebd59e503732177316bb9a18bf7a13f" "@gitlab-org/gitlab-ui@1.0.5": version "1.0.5" |