diff options
224 files changed, 1165 insertions, 919 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 3ecedd44c89..1d969164cfe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,172 @@ documentation](doc/development/changelog.md) for instructions on adding your own entry. +## 9.5.0 (2017-08-22) + +- [FIXED] Fix timeouts when creating projects in groups with many members. !13508 +- [FIXED] Improve API pagination headers when no record found. !13629 (Jordan Patterson) +- [FIXED] Fix deleting GitLab Pages files when a project is removed. !13631 +- [FIXED] Fix commit list not loading the correct page when scrolling. +- [OTHER] Cache the number of forks of a project. !13535 +- GPG signed commits integration. !9546 (Alexis Reigel) +- Alert the user if a Wiki page changed while they were editing it in order to prevent overwriting changes. !9707 (Hiroyuki Sato) +- Add custom linter for inline JavaScript to haml_lint. !9742 (winniehell) +- Add /shrug and /tableflip commands. !10068 (Alex Ives) +- Allow wiki pages to be renamed in the UI. !10069 (wendy0402) +- Insert user name directly without encoding. !10085 (Nathan Neulinger <nneul@neulinger.org>) +- Avoid plucking Todo ids in TodoService. !10845 +- Handle errors while a project is being deleted asynchronously. !11088 +- Decrease ABC threshold to 56.96. !11227 (Maxim Rydkin) +- Remove Mattermost team when deleting a group. !11362 +- Block access to failing repository storage. !11449 +- Add coordinator url to admin area runner page. !11603 +- Allow testing any events for project hooks and system hooks. !11728 (Alexander Randa (@randaalex)) +- Disallow running the pipeline if ref is protected and user cannot merge the branch or create the tag. !11910 +- Remove project_key from the Jira configuration. !12050 +- Add CSRF token verification to API. !12154 (Vitaliy @blackst0ne Klachkov) +- Fixes needed when GitLab sign-in is not enabled. !12491 (Robin Bobbitt) +- Lazy load images for better Frontend performance. !12503 +- Replaces dashboard/event_filters.feature spinach with rspec. !12651 (Alexander Randa (@randaalex)) +- Toggle import description with import_sources_enabled. !12691 (Brianna Kicia) +- Bump scss-lint to 0.54.0. !12733 (Takuya Noguchi) +- Enable SpaceAfterComma in scss-lint. !12734 (Takuya Noguchi) +- Remove CSS for nprogress removed. !12737 (Takuya Noguchi) +- Enable UnnecessaryParentReference in scss-lint. !12738 (Takuya Noguchi) +- Extract "@request.env[devise.mapping] = Devise.mappings[:user]" to a test helper. !12742 (Jacopo Beschi @jacopo-beschi) +- Enable ImportPath in scss-lint. !12749 (Takuya Noguchi) +- Enable PropertySpelling in scss-lint. !12752 (Takuya Noguchi) +- Add API for protected branches to allow for wildcard matching and no access restrictions. !12756 (Eric Yu) +- refactor initializations in dropzone_input.js. !12768 (Brandon Everett) +- Improve CSS for global nav dropdown UI. !12772 (Takuya Noguchi) +- Remove public/ci/favicon.ico. !12803 (Takuya Noguchi) +- Enable DeclarationOrder in scss-lint. !12805 (Takuya Noguchi) +- Increase width of dropdown menus automatically. !12809 (Thomas Wucher) +- Enable BangFormat in scss-lint [ci skip]. !12815 (Takuya Noguchi) +- Added /duplicate quick action to close a duplicate issue. !12845 (Ryan Scott) +- Make all application-settings accessible through the API. !12851 +- Remove Inactive Personal Access Tokens list from Access Tokens page. !12866 +- Replaces dashboard/dashboard.feature spinach with rspec. !12876 (Alexander Randa (@randaalex)) +- Reduce memory usage of the GitHub importer. !12886 +- Bump fog-core to 1.44.3 and fog providers' plugins to latest. !12897 (Takuya Noguchi) +- Use only CSS to truncate commit message in blame. !12900 (Takuya Noguchi) +- Protect manual actions against protected tag too. !12908 +- Allow to configure automatic retry of a failed CI/CD job. !12909 +- Remove help message about prioritized labels for non-members. !12912 (Takuya Noguchi) +- Add link to doc/api/ci/lint.md. !12914 (Takuya Noguchi) +- Add RequestCache which makes caching with RequestStore easier. !12920 +- Free up some top level words, reject top level groups named like files in the public folder. !12932 +- Extend API for Group Secret Variable. !12936 +- Hide description about protected branches to non-member. !12945 (Takuya Noguchi) +- Support custom directory in gitlab:backup:create task. !12984 (Markus Koller) +- Raise guessed encoding confidence threshold to 50. !12990 +- Add author_id & assignee_id param to /issues API. !13004 +- Fix today day highlight in calendar. !13048 +- Prevent LDAP login callback from being called with a GET request. !13059 +- Add top-level merge_requests API endpoint. !13060 +- Handle maximum pages artifacts size correctly. !13072 +- Enable gitaly_post_upload_pack by default. !13078 +- Add Prometheus metrics exporter to Sidekiq. !13082 +- Fix improperly skipped backups of wikis. !13096 +- Projects can be created from templates. !13108 +- Fix the /projects/:id/repository/branches endpoint to handle dots in the branch name when the project full path contains a `/`. !13115 +- Fix project logos that are not centered vertically on list pages. !13124 (Florian Lemaitre) +- Derive project path from import URL. !13131 +- Fix deletion of deploy keys linked to other projects. !13162 +- repository archive download url now ends with selected file extension. !13178 (haseebeqx) +- Show auto-generated avatars for Groups without avatars. !13188 +- Allow any logged in users to read_users_list even if it's restricted. !13201 +- Unlock stuck merge request and set the proper state. !13207 +- Fix timezone inconsistencies in user contribution graph. !13208 +- Fix Issue board when using Ruby 2.4. !13220 +- Don't rename namespace called system when upgrading from 9.1.x to 9.5. !13228 +- Fix encoding error for WebHook logging. !13230 (Alexander Randa (@randaalex)) +- Uniquify reserved word usernames on OAuth user creation. !13244 (Robin Bobbitt) +- Expose target_iid in Events API. !13247 (sue445) +- Add star for action scope, in order to delete image from registry. !13248 (jean) +- Make Delete Merged Branches handle wildcard protected branches correctly. !13251 +- Fix an order of operations for CI connection error message in merge request widget. !13252 +- Don't send rejection mails for all auto-generated mails. !13254 +- Expose noteable_iid in Note. !13265 (sue445) +- Fix pipeline_schedules pages when active schedule has an abnormal state. !13286 +- Move some code from services to workers in order to improve performance. !13326 +- Fix destroy of case-insensitive conflicting redirects. !13357 +- Fix the /projects/:id/repository/tags endpoint to handle dots in the tag name when the project full path contains a `/`. !13368 +- Fix the /projects/:id/repository/commits endpoint to handle dots in the ref name when the project full path contains a `/`. !13370 +- Project pending delete no longer return 500 error in admins projects view. !13389 +- Use full path of user's avatar in webhooks. !13401 (Vitaliy @blackst0ne Klachkov) +- Make GPGME temporary directory handling thread safe. !13481 (Alexis Reigel) +- Add support for kube_namespace in Metrics queries. !16169 +- Fix bar chart does not display label at 0 hour. !35136 (Jason Dai) +- Use project_ref_path to create the link to a branch to fix links that 404. +- Declare related resources into V4 API entities. +- Add Slack and JIRA services counts to Usage Data. +- Prevent web hook and project service background jobs from going to the dead jobs queue. +- Display specific error message when JIRA test fails. +- clean up merge request widget UI. +- Associate Issues tab only with internal issues tracker. +- Remove events column from notification settings table. +- Clarifies and rearranges the input variables on the kubernetes integration page and adjusts the docs slightly to meet the same order. +- Respect blockquote line breaks in markdown. +- Update confidential issue UI - add confidential visibility and settings to sidebar. +- Add icons to contextual sidebars. +- Make contextual sidebar collapsible. +- Update Pipeline's badge count in Merge Request and Commits view to match real-time content. +- Added link to the MR widget that directs to the monitoring dashboard. +- Use jQuery to control scroll behavior in job log for cross browser consistency. +- move edit comment button outside of dropdown. +- Updates vue resource and code according to breaking changes. +- Add GitHub imported projects count to usage data. +- Rename about to overview for group and project page. +- Prevent disabled pagination button to be clicked. +- Remove coffee-rails gem. (Takuya Noguchi) +- Remove net-ssh gem. (Takuya Noguchi) +- Bump rubocop to 0.49.1 and rubocop-rspec to 1.15.1. (Takuya Noguchi) +- improve file upload/replace experience. +- allow closing Cycle Analytics intro box in firefox. +- Fix label creation from new list for subgroup projects. +- fix transient js error in rspec tests. +- fix jump to next discussion button. +- Fix translations for Star/Unstar in JS file. +- Improve mobile sidebar. +- Rename Pipelines tab to CI / CD in new navigation. +- Fix display of new diff comments after changing b between diff views. +- Store & use ConvDev percentages returned by the Version app. +- Fixes new issue button for failed job returning 404. +- Align OR separator to center in new project page. +- Add filtered search to group issue dashboard. +- Cache Appearance instances in Redis. +- Fixed breadcrumbs title aggressively collapsing. +- Better caching and indexing of broadcast messages. +- Moved diff changed files into a dropdown. +- Improve performance of large (initial) push into default branch. +- Improve performance of checking for projects on the projects dashboard. +- Eager load project creators for project dashboards. +- Modify if condition to be more readable. +- Fix links to group milestones from issue and merge request sidebar. +- Remove hidden symlinks from project import files. +- Fixed sign-in restrictions buttons not toggling active state. +- Fix replying to commit comments on merge requests created from forks. +- Support Markdown references, autocomplete, and quick actions for group milestones. +- Cache recent projects for group-level new resource creation. +- Fix API responses when dealing with txt files. +- Fix project milestones import when projects belongs to a group. +- Fix Mattermost integration. +- Memoize the number of personal projects a user has to reduce COUNT queries. +- Merge issuable "reopened" state into "opened". +- Migrate events into a new format to reduce the storage necessary and improve performance. +- MR branch link now links to tree instead of commits. +- Use Prev/Next pagination for exploring projects. +- Pass before_script and script as-is preserving arrays. +- Change project FK migration to skip existing FKs. +- Remove redundant query when retrieving the most recent push of a user. +- Re-organise "issues" indexes for faster ordering. +- Disallow Git URLs that include a username or hostname beginning with a non-alphanumeric character. +- Fix search box losing focus when typing. +- Add structured logging for Rails processes. +- Skip oAuth authorization for trusted applications. +- Use a specialized class for querying events to improve performance. +- Update build badges to be pipeline badges and display passing instead of success. + ## 9.4.5 (2017-08-14) - Fix deletion of deploy keys linked to other projects. !13162 @@ -152,7 +152,7 @@ gem 'acts-as-taggable-on', '~> 4.0' gem 'sidekiq', '~> 5.0' gem 'sidekiq-cron', '~> 0.6.0' gem 'redis-namespace', '~> 1.5.2' -gem 'sidekiq-limit_fetch', '~> 3.4' +gem 'sidekiq-limit_fetch', '~> 3.4', require: false # Cron Parser gem 'rufus-scheduler', '~> 3.4' @@ -1 +1 @@ -9.5.0-pre +9.6.0-pre diff --git a/app/assets/javascripts/project_select_combo_button.js b/app/assets/javascripts/project_select_combo_button.js index f799d9d619a..46a26fb91f4 100644 --- a/app/assets/javascripts/project_select_combo_button.js +++ b/app/assets/javascripts/project_select_combo_button.js @@ -4,10 +4,10 @@ export default class ProjectSelectComboButton { constructor(select) { this.projectSelectInput = $(select); this.newItemBtn = $('.new-project-item-link'); - this.newItemBtnBaseText = this.newItemBtn.data('label'); - this.itemType = this.deriveItemTypeFromLabel(); + this.resourceType = this.newItemBtn.data('type'); + this.resourceLabel = this.newItemBtn.data('label'); + this.formattedText = this.deriveTextVariants(); this.groupId = this.projectSelectInput.data('groupId'); - this.bindEvents(); this.initLocalStorage(); } @@ -23,9 +23,7 @@ export default class ProjectSelectComboButton { const localStorageIsSafe = AccessorUtilities.isLocalStorageAccessSafe(); if (localStorageIsSafe) { - const itemTypeKebabed = this.newItemBtnBaseText.toLowerCase().split(' ').join('-'); - - this.localStorageKey = ['group', this.groupId, itemTypeKebabed, 'recent-project'].join('-'); + this.localStorageKey = ['group', this.groupId, this.formattedText.localStorageItemType, 'recent-project'].join('-'); this.setBtnTextFromLocalStorage(); } } @@ -57,19 +55,14 @@ export default class ProjectSelectComboButton { setNewItemBtnAttributes(project) { if (project) { this.newItemBtn.attr('href', project.url); - this.newItemBtn.text(`${this.newItemBtnBaseText} in ${project.name}`); + this.newItemBtn.text(`${this.formattedText.defaultTextPrefix} in ${project.name}`); this.newItemBtn.enable(); } else { - this.newItemBtn.text(`Select project to create ${this.itemType}`); + this.newItemBtn.text(`Select project to create ${this.formattedText.presetTextSuffix}`); this.newItemBtn.disable(); } } - deriveItemTypeFromLabel() { - // label is either 'New issue' or 'New merge request' - return this.newItemBtnBaseText.split(' ').slice(1).join(' '); - } - getProjectFromLocalStorage() { const projectString = localStorage.getItem(this.localStorageKey); @@ -81,5 +74,19 @@ export default class ProjectSelectComboButton { localStorage.setItem(this.localStorageKey, projectString); } + + deriveTextVariants() { + const defaultTextPrefix = this.resourceLabel; + + // the trailing slice call depluralizes each of these strings (e.g. new-issues -> new-issue) + const localStorageItemType = `new-${this.resourceType.split('_').join('-').slice(0, -1)}`; + const presetTextSuffix = this.resourceType.split('_').join(' ').slice(0, -1); + + return { + localStorageItemType, // new-issue / new-merge-request + defaultTextPrefix, // New issue / New merge request + presetTextSuffix, // issue / merge request + }; + } } diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb index f76b3f69e9e..994e736d66e 100644 --- a/app/controllers/groups_controller.rb +++ b/app/controllers/groups_controller.rb @@ -26,6 +26,13 @@ class GroupsController < Groups::ApplicationController def new @group = Group.new + + if params[:parent_id].present? + parent = Group.find_by(id: params[:parent_id]) + if can?(current_user, :create_subgroup, parent) + @group.parent = parent + end + end end def create diff --git a/app/helpers/application_settings_helper.rb b/app/helpers/application_settings_helper.rb index 150188f0b65..3b76da238e0 100644 --- a/app/helpers/application_settings_helper.rb +++ b/app/helpers/application_settings_helper.rb @@ -116,6 +116,7 @@ module ApplicationSettingsHelper :email_author_in_body, :enabled_git_access_protocol, :gravatar_enabled, + :hashed_storage_enabled, :help_page_hide_commercial_content, :help_page_support_url, :help_page_text, diff --git a/app/models/broadcast_message.rb b/app/models/broadcast_message.rb index 3692bcc680d..fdc5a2adea0 100644 --- a/app/models/broadcast_message.rb +++ b/app/models/broadcast_message.rb @@ -19,11 +19,21 @@ class BroadcastMessage < ActiveRecord::Base after_commit :flush_redis_cache def self.current - Rails.cache.fetch(CACHE_KEY) do - where('ends_at > :now AND starts_at <= :now', now: Time.zone.now) - .reorder(id: :asc) - .to_a - end + messages = Rails.cache.fetch(CACHE_KEY) { current_and_future_messages.to_a } + + return messages if messages.empty? + + now_or_future = messages.select(&:now_or_future?) + + # If there are cached entries but none are to be displayed we'll purge the + # cache so we don't keep running this code all the time. + Rails.cache.delete(CACHE_KEY) if now_or_future.empty? + + now_or_future.select(&:now?) + end + + def self.current_and_future_messages + where('ends_at > :now', now: Time.zone.now).reorder(id: :asc) end def active? @@ -38,6 +48,18 @@ class BroadcastMessage < ActiveRecord::Base ends_at < Time.zone.now end + def now? + (starts_at..ends_at).cover?(Time.zone.now) + end + + def future? + starts_at > Time.zone.now + end + + def now_or_future? + now? || future? + end + def flush_redis_cache Rails.cache.delete(CACHE_KEY) end diff --git a/app/models/concerns/storage/legacy_project.rb b/app/models/concerns/storage/legacy_project.rb deleted file mode 100644 index 815db712285..00000000000 --- a/app/models/concerns/storage/legacy_project.rb +++ /dev/null @@ -1,76 +0,0 @@ -module Storage - module LegacyProject - extend ActiveSupport::Concern - - def disk_path - full_path - end - - def ensure_storage_path_exist - gitlab_shell.add_namespace(repository_storage_path, namespace.full_path) - end - - def rename_repo - path_was = previous_changes['path'].first - old_path_with_namespace = File.join(namespace.full_path, path_was) - new_path_with_namespace = File.join(namespace.full_path, path) - - Rails.logger.error "Attempting to rename #{old_path_with_namespace} -> #{new_path_with_namespace}" - - if has_container_registry_tags? - Rails.logger.error "Project #{old_path_with_namespace} cannot be renamed because container registry tags are present!" - - # we currently doesn't support renaming repository if it contains images in container registry - raise StandardError.new('Project cannot be renamed, because images are present in its container registry') - end - - expire_caches_before_rename(old_path_with_namespace) - - if gitlab_shell.mv_repository(repository_storage_path, old_path_with_namespace, new_path_with_namespace) - # If repository moved successfully we need to send update instructions to users. - # However we cannot allow rollback since we moved repository - # So we basically we mute exceptions in next actions - begin - gitlab_shell.mv_repository(repository_storage_path, "#{old_path_with_namespace}.wiki", "#{new_path_with_namespace}.wiki") - send_move_instructions(old_path_with_namespace) - expires_full_path_cache - - @old_path_with_namespace = old_path_with_namespace - - SystemHooksService.new.execute_hooks_for(self, :rename) - - @repository = nil - rescue => e - Rails.logger.error "Exception renaming #{old_path_with_namespace} -> #{new_path_with_namespace}: #{e}" - # Returning false does not rollback after_* transaction but gives - # us information about failing some of tasks - false - end - else - Rails.logger.error "Repository could not be renamed: #{old_path_with_namespace} -> #{new_path_with_namespace}" - - # if we cannot move namespace directory we should rollback - # db changes in order to prevent out of sync between db and fs - raise StandardError.new('repository cannot be renamed') - end - - Gitlab::AppLogger.info "Project was renamed: #{old_path_with_namespace} -> #{new_path_with_namespace}" - - Gitlab::UploadsTransfer.new.rename_project(path_was, path, namespace.full_path) - Gitlab::PagesTransfer.new.rename_project(path_was, path, namespace.full_path) - end - - def create_repository(force: false) - # Forked import is handled asynchronously - return if forked? && !force - - if gitlab_shell.add_repository(repository_storage_path, path_with_namespace) - repository.after_create - true - else - errors.add(:base, 'Failed to create repository via gitlab-shell') - false - end - end - end -end diff --git a/app/models/project.rb b/app/models/project.rb index be248bc99e1..37f4dd08355 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -17,7 +17,6 @@ class Project < ActiveRecord::Base include ProjectFeaturesCompatibility include SelectForProjectAuthorization include Routable - include Storage::LegacyProject extend Gitlab::ConfigHelper @@ -25,6 +24,7 @@ class Project < ActiveRecord::Base NUMBER_OF_PERMITTED_BOARDS = 1 UNKNOWN_IMPORT_URL = 'http://unknown.git'.freeze + LATEST_STORAGE_VERSION = 1 cache_markdown_field :description, pipeline: :description @@ -32,6 +32,8 @@ class Project < ActiveRecord::Base :merge_requests_enabled?, :issues_enabled?, to: :project_feature, allow_nil: true + delegate :base_dir, :disk_path, :ensure_storage_path_exists, to: :storage + default_value_for :archived, false default_value_for :visibility_level, gitlab_config_features.visibility_level default_value_for :container_registry_enabled, gitlab_config_features.container_registry @@ -44,32 +46,24 @@ class Project < ActiveRecord::Base default_value_for :snippets_enabled, gitlab_config_features.snippets default_value_for :only_allow_merge_if_all_discussions_are_resolved, false - after_create :ensure_storage_path_exist - after_create :create_project_feature, unless: :project_feature - after_save :update_project_statistics, if: :namespace_id_changed? + add_authentication_token_field :runners_token + before_save :ensure_runners_token - # set last_activity_at to the same as created_at + after_save :update_project_statistics, if: :namespace_id_changed? + after_create :create_project_feature, unless: :project_feature after_create :set_last_activity_at - def set_last_activity_at - update_column(:last_activity_at, self.created_at) - end - after_create :set_last_repository_updated_at - def set_last_repository_updated_at - update_column(:last_repository_updated_at, self.created_at) - end + after_update :update_forks_visibility_level before_destroy :remove_private_deploy_keys after_destroy -> { run_after_commit { remove_pages } } - # update visibility_level of forks - after_update :update_forks_visibility_level - after_validation :check_pending_delete - # Legacy Storage specific hooks - - after_save :ensure_storage_path_exist, if: :namespace_id_changed? + # Storage specific hooks + after_initialize :use_hashed_storage + after_create :ensure_storage_path_exists + after_save :ensure_storage_path_exists, if: :namespace_id_changed? acts_as_taggable @@ -238,9 +232,6 @@ class Project < ActiveRecord::Base presence: true, inclusion: { in: ->(_object) { Gitlab.config.repositories.storages.keys } } - add_authentication_token_field :runners_token - before_save :ensure_runners_token - mount_uploader :avatar, AvatarUploader has_many :uploads, as: :model, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent @@ -487,6 +478,10 @@ class Project < ActiveRecord::Base @repository ||= Repository.new(full_path, self, disk_path: disk_path) end + def reload_repository! + @repository = nil + end + def container_registry_url if Gitlab.config.registry.enabled "#{Gitlab.config.registry.host_port}/#{full_path.downcase}" @@ -1004,6 +999,19 @@ class Project < ActiveRecord::Base end end + def create_repository(force: false) + # Forked import is handled asynchronously + return if forked? && !force + + if gitlab_shell.add_repository(repository_storage_path, disk_path) + repository.after_create + true + else + errors.add(:base, 'Failed to create repository via gitlab-shell') + false + end + end + def hook_attrs(backward: true) attrs = { name: name, @@ -1086,6 +1094,7 @@ class Project < ActiveRecord::Base !!repository.exists? end + # update visibility_level of forks def update_forks_visibility_level return unless visibility_level < visibility_level_was @@ -1213,7 +1222,8 @@ class Project < ActiveRecord::Base end def pages_path - File.join(Settings.pages.path, disk_path) + # TODO: when we migrate Pages to work with new storage types, change here to use disk_path + File.join(Settings.pages.path, full_path) end def public_pages_path @@ -1252,6 +1262,50 @@ class Project < ActiveRecord::Base end end + def rename_repo + new_full_path = build_full_path + + Rails.logger.error "Attempting to rename #{full_path_was} -> #{new_full_path}" + + if has_container_registry_tags? + Rails.logger.error "Project #{full_path_was} cannot be renamed because container registry tags are present!" + + # we currently doesn't support renaming repository if it contains images in container registry + raise StandardError.new('Project cannot be renamed, because images are present in its container registry') + end + + expire_caches_before_rename(full_path_was) + + if storage.rename_repo + Gitlab::AppLogger.info "Project was renamed: #{full_path_was} -> #{new_full_path}" + rename_repo_notify! + after_rename_repo + else + Rails.logger.error "Repository could not be renamed: #{full_path_was} -> #{new_full_path}" + + # if we cannot move namespace directory we should rollback + # db changes in order to prevent out of sync between db and fs + raise StandardError.new('repository cannot be renamed') + end + end + + def rename_repo_notify! + send_move_instructions(full_path_was) + expires_full_path_cache + + self.old_path_with_namespace = full_path_was + SystemHooksService.new.execute_hooks_for(self, :rename) + + reload_repository! + end + + def after_rename_repo + path_before_change = previous_changes['path'].first + + Gitlab::UploadsTransfer.new.rename_project(path_before_change, self.path, namespace.full_path) + Gitlab::PagesTransfer.new.rename_project(path_before_change, self.path, namespace.full_path) + end + def running_or_pending_build_count(force: false) Rails.cache.fetch(['projects', id, 'running_or_pending_build_count'], force: force) do builds.running_or_pending.count(:all) @@ -1410,6 +1464,10 @@ class Project < ActiveRecord::Base end end + def full_path_was + File.join(namespace.full_path, previous_changes['path'].first) + end + alias_method :name_with_namespace, :full_name alias_method :human_name, :full_name # @deprecated cannot remove yet because it has an index with its name in elasticsearch @@ -1419,8 +1477,36 @@ class Project < ActiveRecord::Base Projects::ForksCountService.new(self).count end + def legacy_storage? + self.storage_version.nil? + end + private + def storage + @storage ||= + if self.storage_version && self.storage_version >= 1 + Storage::HashedProject.new(self) + else + Storage::LegacyProject.new(self) + end + end + + def use_hashed_storage + if self.new_record? && current_application_settings.hashed_storage_enabled + self.storage_version = LATEST_STORAGE_VERSION + end + end + + # set last_activity_at to the same as created_at + def set_last_activity_at + update_column(:last_activity_at, self.created_at) + end + + def set_last_repository_updated_at + update_column(:last_repository_updated_at, self.created_at) + end + def cross_namespace_reference?(from) case from when Project diff --git a/app/models/project_services/kubernetes_service.rb b/app/models/project_services/kubernetes_service.rb index dee99bbb859..8ba07173c74 100644 --- a/app/models/project_services/kubernetes_service.rb +++ b/app/models/project_services/kubernetes_service.rb @@ -24,6 +24,8 @@ class KubernetesService < DeploymentService validates :token end + before_validation :enforce_namespace_to_lower_case + validates :namespace, allow_blank: true, length: 1..63, @@ -207,4 +209,8 @@ class KubernetesService < DeploymentService max_session_time: current_application_settings.terminal_max_session_time } end + + def enforce_namespace_to_lower_case + self.namespace = self.namespace&.downcase + end end diff --git a/app/models/storage/hashed_project.rb b/app/models/storage/hashed_project.rb new file mode 100644 index 00000000000..fae1b64961a --- /dev/null +++ b/app/models/storage/hashed_project.rb @@ -0,0 +1,42 @@ +module Storage + class HashedProject + attr_accessor :project + delegate :gitlab_shell, :repository_storage_path, to: :project + + ROOT_PATH_PREFIX = '@hashed'.freeze + + def initialize(project) + @project = project + end + + # Base directory + # + # @return [String] directory where repository is stored + def base_dir + "#{ROOT_PATH_PREFIX}/#{disk_hash[0..1]}/#{disk_hash[2..3]}" if disk_hash + end + + # Disk path is used to build repository and project's wiki path on disk + # + # @return [String] combination of base_dir and the repository own name without `.git` or `.wiki.git` extensions + def disk_path + "#{base_dir}/#{disk_hash}" if disk_hash + end + + def ensure_storage_path_exists + gitlab_shell.add_namespace(repository_storage_path, base_dir) + end + + def rename_repo + true + end + + private + + # Generates the hash for the project path and name on disk + # If you need to refer to the repository on disk, use the `#disk_path` + def disk_hash + @disk_hash ||= Digest::SHA2.hexdigest(project.id.to_s) if project.id + end + end +end diff --git a/app/models/storage/legacy_project.rb b/app/models/storage/legacy_project.rb new file mode 100644 index 00000000000..9d9e5e1d352 --- /dev/null +++ b/app/models/storage/legacy_project.rb @@ -0,0 +1,51 @@ +module Storage + class LegacyProject + attr_accessor :project + delegate :namespace, :gitlab_shell, :repository_storage_path, to: :project + + def initialize(project) + @project = project + end + + # Base directory + # + # @return [String] directory where repository is stored + def base_dir + namespace.full_path + end + + # Disk path is used to build repository and project's wiki path on disk + # + # @return [String] combination of base_dir and the repository own name without `.git` or `.wiki.git` extensions + def disk_path + project.full_path + end + + def ensure_storage_path_exists + return unless namespace + + gitlab_shell.add_namespace(repository_storage_path, base_dir) + end + + def rename_repo + new_full_path = project.build_full_path + + if gitlab_shell.mv_repository(repository_storage_path, project.full_path_was, new_full_path) + # If repository moved successfully we need to send update instructions to users. + # However we cannot allow rollback since we moved repository + # So we basically we mute exceptions in next actions + begin + gitlab_shell.mv_repository(repository_storage_path, "#{project.full_path_was}.wiki", "#{new_full_path}.wiki") + return true + rescue => e + Rails.logger.error "Exception renaming #{project.full_path_was} -> #{new_full_path}: #{e}" + # Returning false does not rollback after_* transaction but gives + # us information about failing some of tasks + return false + end + end + + false + end + end +end diff --git a/app/policies/group_policy.rb b/app/policies/group_policy.rb index 6defab75fce..8ada661e571 100644 --- a/app/policies/group_policy.rb +++ b/app/policies/group_policy.rb @@ -13,6 +13,8 @@ class GroupPolicy < BasePolicy condition(:master) { access_level >= GroupMember::MASTER } condition(:reporter) { access_level >= GroupMember::REPORTER } + condition(:nested_groups_supported, scope: :global) { Group.supports_nested_groups? } + condition(:has_projects) do GroupProjectsFinder.new(group: @subject, current_user: @user).execute.any? end @@ -42,7 +44,7 @@ class GroupPolicy < BasePolicy enable :change_visibility_level end - rule { owner & can_create_group }.enable :create_subgroup + rule { owner & can_create_group & nested_groups_supported }.enable :create_subgroup rule { public_group | logged_in_viewable }.enable :view_globally diff --git a/app/services/groups/create_service.rb b/app/services/groups/create_service.rb index c4e9b8fd8e0..c7c27621085 100644 --- a/app/services/groups/create_service.rb +++ b/app/services/groups/create_service.rb @@ -13,9 +13,9 @@ module Groups return @group end - if @group.parent && !can?(current_user, :admin_group, @group.parent) + if @group.parent && !can?(current_user, :create_subgroup, @group.parent) @group.parent = nil - @group.errors.add(:parent_id, 'manage access required to create subgroup') + @group.errors.add(:parent_id, 'You don’t have permission to create a subgroup in this group.') return @group end diff --git a/app/services/groups/destroy_service.rb b/app/services/groups/destroy_service.rb index f565612a89d..e3f9d9ee95d 100644 --- a/app/services/groups/destroy_service.rb +++ b/app/services/groups/destroy_service.rb @@ -13,7 +13,7 @@ module Groups # Execute the destruction of the models immediately to ensure atomic cleanup. # Skip repository removal because we remove directory with namespace # that contain all these repositories - ::Projects::DestroyService.new(project, current_user, skip_repo: true).execute + ::Projects::DestroyService.new(project, current_user, skip_repo: project.legacy_storage?).execute end group.children.each do |group| diff --git a/app/services/users/destroy_service.rb b/app/services/users/destroy_service.rb index 9d7237c2fbb..8e20de8dfa5 100644 --- a/app/services/users/destroy_service.rb +++ b/app/services/users/destroy_service.rb @@ -35,16 +35,18 @@ module Users Groups::DestroyService.new(group, current_user).execute end + namespace = user.namespace + namespace.prepare_for_destroy + user.personal_projects.each do |project| # Skip repository removal because we remove directory with namespace # that contain all this repositories - ::Projects::DestroyService.new(project, current_user, skip_repo: true).execute + ::Projects::DestroyService.new(project, current_user, skip_repo: project.legacy_storage?).execute end MigrateToGhostUserService.new(user).execute unless options[:hard_delete] # Destroy the namespace after destroying the user since certain methods may depend on the namespace existing - namespace = user.namespace user_data = user.destroy namespace.really_destroy! diff --git a/app/views/admin/application_settings/_form.html.haml b/app/views/admin/application_settings/_form.html.haml index 8bf6556079b..959af5c0d13 100644 --- a/app/views/admin/application_settings/_form.html.haml +++ b/app/views/admin/application_settings/_form.html.haml @@ -362,7 +362,9 @@ %fieldset %legend Background Jobs %p - These settings require a restart to take effect. + These settings require a + = link_to 'restart', help_page_path('administration/restart_gitlab') + to take effect. .form-group .col-sm-offset-2.col-sm-10 .checkbox @@ -491,6 +493,16 @@ %fieldset %legend Repository Storage .form-group + .col-sm-offset-2.col-sm-10 + .checkbox + = f.label :hashed_storage_enabled do + = f.check_box :hashed_storage_enabled + Create new projects using hashed storage paths + .help-block + Enable immutable, hash-based paths and repository names to store repositories on disk. This prevents + repositories from having to be moved or renamed when the Project URL changes and may improve disk I/O performance. + %em (EXPERIMENTAL) + .form-group = f.label :repository_storages, 'Storage paths for new projects', class: 'control-label col-sm-2' .col-sm-10 = f.select :repository_storages, repository_storages_options_for_select, {include_hidden: false}, multiple: true, class: 'form-control' @@ -499,6 +511,7 @@ = succeed "." do = link_to "repository storages documentation", help_page_path("administration/repository_storages") + %fieldset %legend Repository Checks .form-group diff --git a/app/views/dashboard/issues.html.haml b/app/views/dashboard/issues.html.haml index 52e0012fd7d..9ac44674b73 100644 --- a/app/views/dashboard/issues.html.haml +++ b/app/views/dashboard/issues.html.haml @@ -8,14 +8,14 @@ - content_for :breadcrumbs_extra do = link_to params.merge(rss_url_options), class: 'btn has-tooltip append-right-10', title: 'Subscribe' do = icon('rss') - = render 'shared/new_project_item_select', path: 'issues/new', label: "New issue", with_feature_enabled: 'issues' + = render 'shared/new_project_item_select', path: 'issues/new', label: "New issue", with_feature_enabled: 'issues', type: :issues .top-area = render 'shared/issuable/nav', type: :issues .nav-controls{ class: ("visible-xs" if show_new_nav?) } = link_to params.merge(rss_url_options), class: 'btn has-tooltip', title: 'Subscribe' do = icon('rss') - = render 'shared/new_project_item_select', path: 'issues/new', label: "New issue", with_feature_enabled: 'issues' + = render 'shared/new_project_item_select', path: 'issues/new', label: "New issue", with_feature_enabled: 'issues', type: :issues = render 'shared/issuable/filter', type: :issues = render 'shared/issues' diff --git a/app/views/dashboard/merge_requests.html.haml b/app/views/dashboard/merge_requests.html.haml index c3fe14da2b2..960e1e55f36 100644 --- a/app/views/dashboard/merge_requests.html.haml +++ b/app/views/dashboard/merge_requests.html.haml @@ -4,12 +4,12 @@ - if show_new_nav? - content_for :breadcrumbs_extra do - = render 'shared/new_project_item_select', path: 'merge_requests/new', label: "New merge request", with_feature_enabled: 'merge_requests' + = render 'shared/new_project_item_select', path: 'merge_requests/new', label: "New merge request", with_feature_enabled: 'merge_requests', type: :merge_requests .top-area = render 'shared/issuable/nav', type: :merge_requests .nav-controls{ class: ("visible-xs" if show_new_nav?) } - = render 'shared/new_project_item_select', path: 'merge_requests/new', label: "New merge request", with_feature_enabled: 'merge_requests' + = render 'shared/new_project_item_select', path: 'merge_requests/new', label: "New merge request", with_feature_enabled: 'merge_requests', type: :merge_requests = render 'shared/issuable/filter', type: :merge_requests = render 'shared/merge_requests' diff --git a/app/views/dashboard/milestones/index.html.haml b/app/views/dashboard/milestones/index.html.haml index 37dbcaf5cb8..cb8bf57cba1 100644 --- a/app/views/dashboard/milestones/index.html.haml +++ b/app/views/dashboard/milestones/index.html.haml @@ -4,13 +4,13 @@ - if show_new_nav? - content_for :breadcrumbs_extra do - = render 'shared/new_project_item_select', path: 'milestones/new', label: 'New milestone', include_groups: true + = render 'shared/new_project_item_select', path: 'milestones/new', label: 'New milestone', include_groups: true, type: :milestones .top-area = render 'shared/milestones_filter', counts: @milestone_states .nav-controls{ class: ("visible-xs" if show_new_nav?) } - = render 'shared/new_project_item_select', path: 'milestones/new', label: 'New milestone', include_groups: true + = render 'shared/new_project_item_select', path: 'milestones/new', label: 'New milestone', include_groups: true, type: :milestones .milestones %ul.content-list diff --git a/app/views/groups/issues.html.haml b/app/views/groups/issues.html.haml index f83ebbf09ef..12bc092d216 100644 --- a/app/views/groups/issues.html.haml +++ b/app/views/groups/issues.html.haml @@ -12,7 +12,7 @@ - content_for :breadcrumbs_extra do = link_to params.merge(rss_url_options), class: 'btn btn-default append-right-10' do = icon('rss') - = render 'shared/new_project_item_select', path: 'issues/new', label: "New issue" + = render 'shared/new_project_item_select', path: 'issues/new', label: "New issue", type: :issues - if group_issues_exists .top-area @@ -22,7 +22,7 @@ = icon('rss') %span.icon-label Subscribe - = render 'shared/new_project_item_select', path: 'issues/new', label: "New issue" + = render 'shared/new_project_item_select', path: 'issues/new', label: "New issue", type: :issues = render 'shared/issuable/search_bar', type: :issues diff --git a/app/views/groups/merge_requests.html.haml b/app/views/groups/merge_requests.html.haml index 997c82c77d9..569eef46e6e 100644 --- a/app/views/groups/merge_requests.html.haml +++ b/app/views/groups/merge_requests.html.haml @@ -2,7 +2,7 @@ - if show_new_nav? && current_user - content_for :breadcrumbs_extra do - = render 'shared/new_project_item_select', path: 'merge_requests/new', label: "New merge request" + = render 'shared/new_project_item_select', path: 'merge_requests/new', label: "New merge request", type: :merge_requests - if @group_merge_requests.empty? = render 'shared/empty_states/merge_requests', project_select_button: true @@ -11,7 +11,7 @@ = render 'shared/issuable/nav', type: :merge_requests - if current_user .nav-controls{ class: ("visible-xs" if show_new_nav?) } - = render 'shared/new_project_item_select', path: 'merge_requests/new', label: "New merge request" + = render 'shared/new_project_item_select', path: 'merge_requests/new', label: "New merge request", type: :merge_requests = render 'shared/issuable/filter', type: :merge_requests diff --git a/app/views/import/gitlab_projects/new.html.haml b/app/views/import/gitlab_projects/new.html.haml index 008e8287aa3..5d68e1e2156 100644 --- a/app/views/import/gitlab_projects/new.html.haml +++ b/app/views/import/gitlab_projects/new.html.haml @@ -25,7 +25,7 @@ = hidden_field_tag :namespace_id, value: current_user.namespace_id .form-group.col-xs-12.col-sm-6.project-path = label_tag :path, 'Project name', class: 'label-light' - = text_field_tag :path, nil, placeholder: "my-awesome-project", class: "js-path-name form-control", tabindex: 2, autofocus: true, required: true + = text_field_tag :path, @path, placeholder: "my-awesome-project", class: "js-path-name form-control", tabindex: 2, autofocus: true, required: true .row .form-group.col-md-12 @@ -33,7 +33,6 @@ .row .form-group.col-sm-12 = hidden_field_tag :namespace_id, @namespace.id - = hidden_field_tag :path, @path = label_tag :file, 'GitLab project export', class: 'label-light' .form-group = file_field_tag :file, class: '' diff --git a/app/views/projects/edit.html.haml b/app/views/projects/edit.html.haml index 6178abe9160..9e26bdecd31 100644 --- a/app/views/projects/edit.html.haml +++ b/app/views/projects/edit.html.haml @@ -202,8 +202,6 @@ .sub-section.rename-respository %h4.warning-title Rename repository - %p - Export this project with all its related data in order to move your project to a new GitLab instance. Once the export is finished, you can import the file from the "New Project" page. = render 'projects/errors' = form_for([@project.namespace.becomes(Namespace), @project]) do |f| .form-group.project_name_holder diff --git a/app/views/shared/_group_form.html.haml b/app/views/shared/_group_form.html.haml index 8d5b5129454..2e1bd5a088c 100644 --- a/app/views/shared/_group_form.html.haml +++ b/app/views/shared/_group_form.html.haml @@ -1,6 +1,6 @@ - content_for :page_specific_javascripts do = page_specific_javascript_bundle_tag('group') -- parent = GroupFinder.new(current_user).execute(id: params[:parent_id] || @group.parent_id) +- parent = @group.parent - group_path = root_url - group_path << parent.full_path + '/' if parent @@ -13,13 +13,12 @@ %span>= root_url - if parent %strong= parent.full_path + '/' + = f.hidden_field :parent_id = f.text_field :path, placeholder: 'open-source', class: 'form-control', autofocus: local_assigns[:autofocus] || false, required: true, pattern: Gitlab::PathRegex::NAMESPACE_FORMAT_REGEX_JS, title: 'Please choose a group path with no special characters.', "data-bind-in" => "#{'create_chat_team' if Gitlab.config.mattermost.enabled}" - - if parent - = f.hidden_field :parent_id, value: parent.id - if @group.persisted? .alert.alert-warning.prepend-top-10 diff --git a/app/views/shared/_new_project_item_select.html.haml b/app/views/shared/_new_project_item_select.html.haml index 96502d7ce93..dc912d800cf 100644 --- a/app/views/shared/_new_project_item_select.html.haml +++ b/app/views/shared/_new_project_item_select.html.haml @@ -1,6 +1,6 @@ - if any_projects?(@projects) .project-item-select-holder.btn-group.pull-right - %a.btn.btn-new.new-project-item-link{ href: '', data: { label: local_assigns[:label] } } + %a.btn.btn-new.new-project-item-link{ href: '', data: { label: local_assigns[:label], type: local_assigns[:type] } } = icon('spinner spin') = project_select_tag :project_path, class: "project-item-select", data: { include_groups: local_assigns[:include_groups], order_by: 'last_activity_at', relative_path: local_assigns[:path] }, with_feature_enabled: local_assigns[:with_feature_enabled] %button.btn.btn-new.new-project-item-select-button diff --git a/app/views/shared/empty_states/_issues.html.haml b/app/views/shared/empty_states/_issues.html.haml index b0c0ab523c7..68737e8da66 100644 --- a/app/views/shared/empty_states/_issues.html.haml +++ b/app/views/shared/empty_states/_issues.html.haml @@ -15,7 +15,7 @@ Issues can be bugs, tasks or ideas to be discussed. Also, issues are searchable and filterable. - if project_select_button - = render 'shared/new_project_item_select', path: 'issues/new', label: 'New issue' + = render 'shared/new_project_item_select', path: 'issues/new', label: 'New issue', type: :issues - else = link_to 'New issue', button_path, class: 'btn btn-new', title: 'New issue', id: 'new_issue_link' - else diff --git a/app/views/shared/empty_states/_merge_requests.html.haml b/app/views/shared/empty_states/_merge_requests.html.haml index 3e64f403b8b..ff5741b6d61 100644 --- a/app/views/shared/empty_states/_merge_requests.html.haml +++ b/app/views/shared/empty_states/_merge_requests.html.haml @@ -14,7 +14,7 @@ %p Interested parties can even contribute by pushing commits if they want to. - if project_select_button - = render 'shared/new_project_item_select', path: 'merge_requests/new', label: 'New merge request' + = render 'shared/new_project_item_select', path: 'merge_requests/new', label: 'New merge request', type: :merge_requests - else = link_to 'New merge request', button_path, class: 'btn btn-new', title: 'New merge request', id: 'new_merge_request_link' - else diff --git a/app/workers/authorized_projects_worker.rb b/app/workers/authorized_projects_worker.rb index 13207a8bc71..be4c77503bb 100644 --- a/app/workers/authorized_projects_worker.rb +++ b/app/workers/authorized_projects_worker.rb @@ -4,18 +4,25 @@ class AuthorizedProjectsWorker # Schedules multiple jobs and waits for them to be completed. def self.bulk_perform_and_wait(args_list) - job_ids = bulk_perform_async(args_list) + waiter = Gitlab::JobWaiter.new(args_list.size) - Gitlab::JobWaiter.new(job_ids).wait + # Point all the bulk jobs at the same JobWaiter. Converts, [[1], [2], [3]] + # into [[1, "key"], [2, "key"], [3, "key"]] + waiting_args_list = args_list.map { |args| args << waiter.key } + bulk_perform_async(waiting_args_list) + + waiter.wait end def self.bulk_perform_async(args_list) Sidekiq::Client.push_bulk('class' => self, 'queue' => sidekiq_options['queue'], 'args' => args_list) end - def perform(user_id) + def perform(user_id, notify_key = nil) user = User.find_by(id: user_id) user&.refresh_authorized_projects + ensure + Gitlab::JobWaiter.notify(notify_key, jid) if notify_key end end diff --git a/changelogs/unreleased/10085-stop-encoding-user-name.yml b/changelogs/unreleased/10085-stop-encoding-user-name.yml deleted file mode 100644 index 8fab474e047..00000000000 --- a/changelogs/unreleased/10085-stop-encoding-user-name.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: "Insert user name directly without encoding" -merge_request: 10085 -author: Nathan Neulinger <nneul@neulinger.org> diff --git a/changelogs/unreleased/13247-api_project_events_target_iid.yml b/changelogs/unreleased/13247-api_project_events_target_iid.yml deleted file mode 100644 index 08a31039f77..00000000000 --- a/changelogs/unreleased/13247-api_project_events_target_iid.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Expose target_iid in Events API -merge_request: 13247 -author: sue445 diff --git a/changelogs/unreleased/13265-project_events_noteable_iid.yml b/changelogs/unreleased/13265-project_events_noteable_iid.yml deleted file mode 100644 index 54d538bb548..00000000000 --- a/changelogs/unreleased/13265-project_events_noteable_iid.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Expose noteable_iid in Note -merge_request: 13265 -author: sue445 diff --git a/changelogs/unreleased/1827-prevent-concurrent-editing-wiki.yml b/changelogs/unreleased/1827-prevent-concurrent-editing-wiki.yml deleted file mode 100644 index c8c2bb3eb4c..00000000000 --- a/changelogs/unreleased/1827-prevent-concurrent-editing-wiki.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Alert the user if a Wiki page changed while they were editing it in order to prevent overwriting changes. -merge_request: 9707 -author: Hiroyuki Sato diff --git a/changelogs/unreleased/19629-remove-inactive-tokens-list.yml b/changelogs/unreleased/19629-remove-inactive-tokens-list.yml deleted file mode 100644 index 414e3d49e29..00000000000 --- a/changelogs/unreleased/19629-remove-inactive-tokens-list.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Remove Inactive Personal Access Tokens list from Access Tokens page -merge_request: 12866 -author: diff --git a/changelogs/unreleased/20817-please-add-coordinator-url-to-admin-area-runner-page.yml b/changelogs/unreleased/20817-please-add-coordinator-url-to-admin-area-runner-page.yml deleted file mode 100644 index c4c3fc7ceb2..00000000000 --- a/changelogs/unreleased/20817-please-add-coordinator-url-to-admin-area-runner-page.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Add coordinator url to admin area runner page -merge_request: 11603 -author: diff --git a/changelogs/unreleased/22600-related-resources-uris-using-grape-source-helpers.yml b/changelogs/unreleased/22600-related-resources-uris-using-grape-source-helpers.yml deleted file mode 100644 index 837a34bd067..00000000000 --- a/changelogs/unreleased/22600-related-resources-uris-using-grape-source-helpers.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Declare related resources into V4 API entities -merge_request: -author: diff --git a/changelogs/unreleased/23036-replace-dashboard-event-filters-spinach.yml b/changelogs/unreleased/23036-replace-dashboard-event-filters-spinach.yml deleted file mode 100644 index 807cd097178..00000000000 --- a/changelogs/unreleased/23036-replace-dashboard-event-filters-spinach.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Replaces dashboard/event_filters.feature spinach with rspec -merge_request: 12651 -author: Alexander Randa (@randaalex) diff --git a/changelogs/unreleased/23036-replace-dashboard-spinach.yml b/changelogs/unreleased/23036-replace-dashboard-spinach.yml deleted file mode 100644 index b3197c4cfa6..00000000000 --- a/changelogs/unreleased/23036-replace-dashboard-spinach.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Replaces dashboard/dashboard.feature spinach with rspec -merge_request: 12876 -author: Alexander Randa (@randaalex) diff --git a/changelogs/unreleased/26372-duplicate-issue-slash-command.yml b/changelogs/unreleased/26372-duplicate-issue-slash-command.yml deleted file mode 100644 index 3108344e0bf..00000000000 --- a/changelogs/unreleased/26372-duplicate-issue-slash-command.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Added /duplicate quick action to close a duplicate issue -merge_request: 12845 -author: Ryan Scott diff --git a/changelogs/unreleased/27616-fix-contributions-graph-utc-offset-mysql.yml b/changelogs/unreleased/27616-fix-contributions-graph-utc-offset-mysql.yml deleted file mode 100644 index 1b3c3b8538d..00000000000 --- a/changelogs/unreleased/27616-fix-contributions-graph-utc-offset-mysql.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Fix timezone inconsistencies in user contribution graph -merge_request: 13208 -author: diff --git a/changelogs/unreleased/28202_decrease_abc_threshold_step2.yml b/changelogs/unreleased/28202_decrease_abc_threshold_step2.yml deleted file mode 100644 index b8f30b52b18..00000000000 --- a/changelogs/unreleased/28202_decrease_abc_threshold_step2.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Decrease ABC threshold to 56.96 -merge_request: 11227 -author: Maxim Rydkin diff --git a/changelogs/unreleased/28283-uuid-storage.yml b/changelogs/unreleased/28283-uuid-storage.yml new file mode 100644 index 00000000000..283e06d4b7f --- /dev/null +++ b/changelogs/unreleased/28283-uuid-storage.yml @@ -0,0 +1,4 @@ +--- +title: Hashed Storage support for Repositories (EXPERIMENTAL) +merge_request: 13246 +author: diff --git a/changelogs/unreleased/28472-ignore-auto-generated-mails.yml b/changelogs/unreleased/28472-ignore-auto-generated-mails.yml deleted file mode 100644 index af63b43e62e..00000000000 --- a/changelogs/unreleased/28472-ignore-auto-generated-mails.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Don't send rejection mails for all auto-generated mails -merge_request: 13254 -author: diff --git a/changelogs/unreleased/29289-project-destroy-clean-up-after-failure.yml b/changelogs/unreleased/29289-project-destroy-clean-up-after-failure.yml deleted file mode 100644 index 488b37ac37f..00000000000 --- a/changelogs/unreleased/29289-project-destroy-clean-up-after-failure.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Handle errors while a project is being deleted asynchronously. -merge_request: 11088 -author: diff --git a/changelogs/unreleased/29385-add_shrug_command.yml b/changelogs/unreleased/29385-add_shrug_command.yml deleted file mode 100644 index 14b8f486d5c..00000000000 --- a/changelogs/unreleased/29385-add_shrug_command.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Add /shrug and /tableflip commands -merge_request: 10068 -author: Alex Ives diff --git a/changelogs/unreleased/29901-refactor-initialization-dropzone_input-js.yml b/changelogs/unreleased/29901-refactor-initialization-dropzone_input-js.yml deleted file mode 100644 index 8850422fc88..00000000000 --- a/changelogs/unreleased/29901-refactor-initialization-dropzone_input-js.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: refactor initializations in dropzone_input.js -merge_request: 12768 -author: Brandon Everett diff --git a/changelogs/unreleased/30634-protected-pipeline.yml b/changelogs/unreleased/30634-protected-pipeline.yml deleted file mode 100644 index e46538e5b46..00000000000 --- a/changelogs/unreleased/30634-protected-pipeline.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Disallow running the pipeline if ref is protected and user cannot merge the - branch or create the tag -merge_request: 11910 -author: diff --git a/changelogs/unreleased/31129-jira-project-key-elim.yml b/changelogs/unreleased/31129-jira-project-key-elim.yml deleted file mode 100644 index bfa0e99f250..00000000000 --- a/changelogs/unreleased/31129-jira-project-key-elim.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Remove project_key from the Jira configuration -merge_request: 12050 -author: diff --git a/changelogs/unreleased/31207-clean-locked-merge-requests.yml b/changelogs/unreleased/31207-clean-locked-merge-requests.yml deleted file mode 100644 index 1f52987baef..00000000000 --- a/changelogs/unreleased/31207-clean-locked-merge-requests.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Unlock stuck merge request and set the proper state -merge_request: 13207 -author: diff --git a/changelogs/unreleased/31533-usage-data-projects-stats.yml b/changelogs/unreleased/31533-usage-data-projects-stats.yml deleted file mode 100644 index 11bb6118337..00000000000 --- a/changelogs/unreleased/31533-usage-data-projects-stats.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Add Slack and JIRA services counts to Usage Data -merge_request: -author: diff --git a/changelogs/unreleased/31571-don-t-let-webhooks-jobs-go-to-the-dead-jobs-queue.yml b/changelogs/unreleased/31571-don-t-let-webhooks-jobs-go-to-the-dead-jobs-queue.yml deleted file mode 100644 index 69900f0b314..00000000000 --- a/changelogs/unreleased/31571-don-t-let-webhooks-jobs-go-to-the-dead-jobs-queue.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Prevent web hook and project service background jobs from going to the dead - jobs queue -merge_request: -author: diff --git a/changelogs/unreleased/32483-jira-error.yml b/changelogs/unreleased/32483-jira-error.yml deleted file mode 100644 index 1c530ca5e0f..00000000000 --- a/changelogs/unreleased/32483-jira-error.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Display specific error message when JIRA test fails -merge_request: -author: diff --git a/changelogs/unreleased/32844-issuables-performance.yml b/changelogs/unreleased/32844-issuables-performance.yml deleted file mode 100644 index e9b21c1aa45..00000000000 --- a/changelogs/unreleased/32844-issuables-performance.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Move some code from services to workers in order to improve performance -merge_request: 13326 -author: diff --git a/changelogs/unreleased/33095-mr-widget-ui.yml b/changelogs/unreleased/33095-mr-widget-ui.yml deleted file mode 100644 index 9ce3086df27..00000000000 --- a/changelogs/unreleased/33095-mr-widget-ui.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: clean up merge request widget UI -merge_request: -author: diff --git a/changelogs/unreleased/33097-issue-tracker.yml b/changelogs/unreleased/33097-issue-tracker.yml deleted file mode 100644 index 0b13f7165db..00000000000 --- a/changelogs/unreleased/33097-issue-tracker.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Associate Issues tab only with internal issues tracker -merge_request: -author: diff --git a/changelogs/unreleased/33601-add-csrf-token-verification-to-api.yml b/changelogs/unreleased/33601-add-csrf-token-verification-to-api.yml deleted file mode 100644 index 88cfb99a73e..00000000000 --- a/changelogs/unreleased/33601-add-csrf-token-verification-to-api.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Add CSRF token verification to API -merge_request: 12154 -author: Vitaliy @blackst0ne Klachkov diff --git a/changelogs/unreleased/33620-remove-events-from-notification_settings.yml b/changelogs/unreleased/33620-remove-events-from-notification_settings.yml deleted file mode 100644 index f5f3ef3fb82..00000000000 --- a/changelogs/unreleased/33620-remove-events-from-notification_settings.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Remove events column from notification settings table -merge_request: -author: diff --git a/changelogs/unreleased/33741-clarify-k8s-service-keys.yml b/changelogs/unreleased/33741-clarify-k8s-service-keys.yml deleted file mode 100644 index 91142a0d580..00000000000 --- a/changelogs/unreleased/33741-clarify-k8s-service-keys.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Clarifies and rearranges the input variables on the kubernetes integration - page and adjusts the docs slightly to meet the same order -merge_request: !12188 -author: diff --git a/changelogs/unreleased/33770-respect-blockquote-line-breaks.yml b/changelogs/unreleased/33770-respect-blockquote-line-breaks.yml deleted file mode 100644 index 3a45ad88270..00000000000 --- a/changelogs/unreleased/33770-respect-blockquote-line-breaks.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Respect blockquote line breaks in markdown -merge_request: -author: diff --git a/changelogs/unreleased/33874_confi.yml b/changelogs/unreleased/33874_confi.yml deleted file mode 100644 index 940753d9aaa..00000000000 --- a/changelogs/unreleased/33874_confi.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Update confidential issue UI - add confidential visibility and settings to - sidebar -merge_request: -author: diff --git a/changelogs/unreleased/34027-add-icons-to-sidebar.yml b/changelogs/unreleased/34027-add-icons-to-sidebar.yml deleted file mode 100644 index f5b50ca1dee..00000000000 --- a/changelogs/unreleased/34027-add-icons-to-sidebar.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Add icons to contextual sidebars -merge_request: -author: diff --git a/changelogs/unreleased/34028-collapse-sidebar.yml b/changelogs/unreleased/34028-collapse-sidebar.yml deleted file mode 100644 index 468212240ac..00000000000 --- a/changelogs/unreleased/34028-collapse-sidebar.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Make contextual sidebar collapsible -merge_request: -author: diff --git a/changelogs/unreleased/34075-pipelines-count-mt.yml b/changelogs/unreleased/34075-pipelines-count-mt.yml deleted file mode 100644 index 3846e7b06a4..00000000000 --- a/changelogs/unreleased/34075-pipelines-count-mt.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Update Pipeline's badge count in Merge Request and Commits view to match real-time - content -merge_request: -author: diff --git a/changelogs/unreleased/34110-memory-usage-notice-doesn-t-link-anywhere.yml b/changelogs/unreleased/34110-memory-usage-notice-doesn-t-link-anywhere.yml deleted file mode 100644 index 1911705dd2b..00000000000 --- a/changelogs/unreleased/34110-memory-usage-notice-doesn-t-link-anywhere.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Added link to the MR widget that directs to the monitoring dashboard -merge_request: -author: diff --git a/changelogs/unreleased/34339-user_avatar-url-in-push-event-webhook-json-payload-is-relative-should-be-absolute.yml b/changelogs/unreleased/34339-user_avatar-url-in-push-event-webhook-json-payload-is-relative-should-be-absolute.yml deleted file mode 100644 index 13f28da8577..00000000000 --- a/changelogs/unreleased/34339-user_avatar-url-in-push-event-webhook-json-payload-is-relative-should-be-absolute.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Use full path of user's avatar in webhooks -merge_request: 13401 -author: Vitaliy @blackst0ne Klachkov diff --git a/changelogs/unreleased/34361-lazy-load-images-on-the-frontend.yml b/changelogs/unreleased/34361-lazy-load-images-on-the-frontend.yml deleted file mode 100644 index d188a558d38..00000000000 --- a/changelogs/unreleased/34361-lazy-load-images-on-the-frontend.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Lazy load images for better Frontend performance -merge_request: 12503 -author: diff --git a/changelogs/unreleased/34519-extend-api-group-secret-variable.yml b/changelogs/unreleased/34519-extend-api-group-secret-variable.yml deleted file mode 100644 index e0b625c392f..00000000000 --- a/changelogs/unreleased/34519-extend-api-group-secret-variable.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Extend API for Group Secret Variable -merge_request: 12936 -author: diff --git a/changelogs/unreleased/34527-make-edit-comment-button-always-available-outside-of-dropdown.yml b/changelogs/unreleased/34527-make-edit-comment-button-always-available-outside-of-dropdown.yml deleted file mode 100644 index 08171f6bcec..00000000000 --- a/changelogs/unreleased/34527-make-edit-comment-button-always-available-outside-of-dropdown.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: move edit comment button outside of dropdown -merge_request: -author: diff --git a/changelogs/unreleased/34533-speed-up-group-project-authorizations.yml b/changelogs/unreleased/34533-speed-up-group-project-authorizations.yml deleted file mode 100644 index ddaaf4a2507..00000000000 --- a/changelogs/unreleased/34533-speed-up-group-project-authorizations.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fix timeouts when creating projects in groups with many members -merge_request: 13508 -author: -type: fixed diff --git a/changelogs/unreleased/34534-update-vue-resource.yml b/changelogs/unreleased/34534-update-vue-resource.yml deleted file mode 100644 index 2d0af0c9bfe..00000000000 --- a/changelogs/unreleased/34534-update-vue-resource.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Updates vue resource and code according to breaking changes -merge_request: -author: diff --git a/changelogs/unreleased/34549-extract-devise-mappings-into-helper.yml b/changelogs/unreleased/34549-extract-devise-mappings-into-helper.yml deleted file mode 100644 index e843bbac239..00000000000 --- a/changelogs/unreleased/34549-extract-devise-mappings-into-helper.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Extract "@request.env[devise.mapping] = Devise.mappings[:user]" to a test helper -merge_request: 12742 -author: Jacopo Beschi @jacopo-beschi diff --git a/changelogs/unreleased/34563-usage-ping-github.yml b/changelogs/unreleased/34563-usage-ping-github.yml deleted file mode 100644 index 3ab982beea3..00000000000 --- a/changelogs/unreleased/34563-usage-ping-github.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Add GitHub imported projects count to usage data -merge_request: -author: diff --git a/changelogs/unreleased/34764-rename-to-overview.yml b/changelogs/unreleased/34764-rename-to-overview.yml deleted file mode 100644 index 5b9643285b7..00000000000 --- a/changelogs/unreleased/34764-rename-to-overview.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Rename about to overview for group and project page -merge_request: -author: diff --git a/changelogs/unreleased/34810-vue-pagination.yml b/changelogs/unreleased/34810-vue-pagination.yml deleted file mode 100644 index 5cd03518a98..00000000000 --- a/changelogs/unreleased/34810-vue-pagination.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Prevent disabled pagination button to be clicked -merge_request: -author: diff --git a/changelogs/unreleased/34831-remove-coffee-rails-gem.yml b/changelogs/unreleased/34831-remove-coffee-rails-gem.yml deleted file mode 100644 index b555f112b8d..00000000000 --- a/changelogs/unreleased/34831-remove-coffee-rails-gem.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Remove coffee-rails gem -merge_request: -author: Takuya Noguchi diff --git a/changelogs/unreleased/34858-bump-scss-lint-to-0-54-0.yml b/changelogs/unreleased/34858-bump-scss-lint-to-0-54-0.yml deleted file mode 100644 index e6cd834aed2..00000000000 --- a/changelogs/unreleased/34858-bump-scss-lint-to-0-54-0.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Bump scss-lint to 0.54.0 -merge_request: 12733 -author: Takuya Noguchi diff --git a/changelogs/unreleased/34867-remove-net-ssh-gem.yml b/changelogs/unreleased/34867-remove-net-ssh-gem.yml deleted file mode 100644 index f5648d62467..00000000000 --- a/changelogs/unreleased/34867-remove-net-ssh-gem.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Remove net-ssh gem -merge_request: -author: Takuya Noguchi diff --git a/changelogs/unreleased/34869-bump-rubocop-to-0-49-1-and-rubocop-rspec-to-1-15-1.yml b/changelogs/unreleased/34869-bump-rubocop-to-0-49-1-and-rubocop-rspec-to-1-15-1.yml deleted file mode 100644 index 0eb2d069719..00000000000 --- a/changelogs/unreleased/34869-bump-rubocop-to-0-49-1-and-rubocop-rspec-to-1-15-1.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Bump rubocop to 0.49.1 and rubocop-rspec to 1.15.1 -merge_request: -author: Takuya Noguchi diff --git a/changelogs/unreleased/34921-global-dropdown-ui-improvement.yml b/changelogs/unreleased/34921-global-dropdown-ui-improvement.yml deleted file mode 100644 index 6a17353ba3f..00000000000 --- a/changelogs/unreleased/34921-global-dropdown-ui-improvement.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Improve CSS for global nav dropdown UI -merge_request: 12772 -author: Takuya Noguchi diff --git a/changelogs/unreleased/34927-protect-manual-actions-on-tags.yml b/changelogs/unreleased/34927-protect-manual-actions-on-tags.yml deleted file mode 100644 index d996ae2826a..00000000000 --- a/changelogs/unreleased/34927-protect-manual-actions-on-tags.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Protect manual actions against protected tag too -merge_request: 12908 -author: diff --git a/changelogs/unreleased/34978-remove-public-ci-favicon-ico.yml b/changelogs/unreleased/34978-remove-public-ci-favicon-ico.yml deleted file mode 100644 index 25cc8b5e45f..00000000000 --- a/changelogs/unreleased/34978-remove-public-ci-favicon-ico.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Remove public/ci/favicon.ico -merge_request: 12803 -author: Takuya Noguchi diff --git a/changelogs/unreleased/35044-projects-logo-are-not-centered-vertically-on-projects-page.yml b/changelogs/unreleased/35044-projects-logo-are-not-centered-vertically-on-projects-page.yml deleted file mode 100644 index 9de4dbefd35..00000000000 --- a/changelogs/unreleased/35044-projects-logo-are-not-centered-vertically-on-projects-page.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Fix project logos that are not centered vertically on list pages -merge_request: 13124 -author: Florian Lemaitre diff --git a/changelogs/unreleased/35072-fix-pages-delete.yml b/changelogs/unreleased/35072-fix-pages-delete.yml deleted file mode 100644 index 21af2bde201..00000000000 --- a/changelogs/unreleased/35072-fix-pages-delete.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fix deleting GitLab Pages files when a project is removed -merge_request: 13631 -author: -type: fixed diff --git a/changelogs/unreleased/35098-raise-encoding-confidence-threshold.yml b/changelogs/unreleased/35098-raise-encoding-confidence-threshold.yml deleted file mode 100644 index 3cdb3011f5b..00000000000 --- a/changelogs/unreleased/35098-raise-encoding-confidence-threshold.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Raise guessed encoding confidence threshold to 50 -merge_request: 12990 -author: diff --git a/changelogs/unreleased/35136-barchart-not-display-label-at-0-hour.yml b/changelogs/unreleased/35136-barchart-not-display-label-at-0-hour.yml deleted file mode 100644 index ea8f31cca9d..00000000000 --- a/changelogs/unreleased/35136-barchart-not-display-label-at-0-hour.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Fix bar chart does not display label at 0 hour -merge_request: 35136 -author: Jason Dai diff --git a/changelogs/unreleased/35155-upgrade-fog-core-to-1-44-3-and-its-providers-to-the-latest.yml b/changelogs/unreleased/35155-upgrade-fog-core-to-1-44-3-and-its-providers-to-the-latest.yml deleted file mode 100644 index 9d9558347ba..00000000000 --- a/changelogs/unreleased/35155-upgrade-fog-core-to-1-44-3-and-its-providers-to-the-latest.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Bump fog-core to 1.44.3 and fog providers' plugins to latest -merge_request: 12897 -author: Takuya Noguchi diff --git a/changelogs/unreleased/35163-url-in-commit-message-can-be-broken-in-blame.yml b/changelogs/unreleased/35163-url-in-commit-message-can-be-broken-in-blame.yml deleted file mode 100644 index 4fd60a79782..00000000000 --- a/changelogs/unreleased/35163-url-in-commit-message-can-be-broken-in-blame.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Use only CSS to truncate commit message in blame -merge_request: 12900 -author: Takuya Noguchi diff --git a/changelogs/unreleased/35164-cycle-analytics-firefox.yml b/changelogs/unreleased/35164-cycle-analytics-firefox.yml deleted file mode 100644 index 0b7115136ca..00000000000 --- a/changelogs/unreleased/35164-cycle-analytics-firefox.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: allow closing Cycle Analytics intro box in firefox -merge_request: -author: diff --git a/changelogs/unreleased/35181-cannot-create-label-from-board-page.yml b/changelogs/unreleased/35181-cannot-create-label-from-board-page.yml deleted file mode 100644 index 4afe603720d..00000000000 --- a/changelogs/unreleased/35181-cannot-create-label-from-board-page.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Fix label creation from new list for subgroup projects -merge_request: -author: diff --git a/changelogs/unreleased/35191-prioritized-labels-for-non-member.yml b/changelogs/unreleased/35191-prioritized-labels-for-non-member.yml deleted file mode 100644 index fbe55d4c2b0..00000000000 --- a/changelogs/unreleased/35191-prioritized-labels-for-non-member.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Remove help message about prioritized labels for non-members -merge_request: 12912 -author: Takuya Noguchi diff --git a/changelogs/unreleased/35204-doc-api-ci-lint-typo.yml b/changelogs/unreleased/35204-doc-api-ci-lint-typo.yml deleted file mode 100644 index 45b6c57579b..00000000000 --- a/changelogs/unreleased/35204-doc-api-ci-lint-typo.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Add link to doc/api/ci/lint.md -merge_request: 12914 -author: Takuya Noguchi diff --git a/changelogs/unreleased/35225-transient-poll.yml b/changelogs/unreleased/35225-transient-poll.yml deleted file mode 100644 index 59e2e738c7b..00000000000 --- a/changelogs/unreleased/35225-transient-poll.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: fix transient js error in rspec tests -merge_request: -author: diff --git a/changelogs/unreleased/35253-desc-protected-branches-for-non-member.yml b/changelogs/unreleased/35253-desc-protected-branches-for-non-member.yml deleted file mode 100644 index 9b2a66da1c3..00000000000 --- a/changelogs/unreleased/35253-desc-protected-branches-for-non-member.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Hide description about protected branches to non-member -merge_request: 12945 -author: Takuya Noguchi diff --git a/changelogs/unreleased/35391-fix-star-i18n-in-js.yml b/changelogs/unreleased/35391-fix-star-i18n-in-js.yml deleted file mode 100644 index a6fd4dc89fd..00000000000 --- a/changelogs/unreleased/35391-fix-star-i18n-in-js.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Fix translations for Star/Unstar in JS file -merge_request: -author: diff --git a/changelogs/unreleased/35408-group-auto-avatars.yml b/changelogs/unreleased/35408-group-auto-avatars.yml deleted file mode 100644 index 77b644a7f94..00000000000 --- a/changelogs/unreleased/35408-group-auto-avatars.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Show auto-generated avatars for Groups without avatars -merge_request: 13188 -author: diff --git a/changelogs/unreleased/35483-improve-mobile-sidebar.yml b/changelogs/unreleased/35483-improve-mobile-sidebar.yml deleted file mode 100644 index eb3dab1da9e..00000000000 --- a/changelogs/unreleased/35483-improve-mobile-sidebar.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Improve mobile sidebar -merge_request: -author: diff --git a/changelogs/unreleased/35659-rename-pipeline.yml b/changelogs/unreleased/35659-rename-pipeline.yml deleted file mode 100644 index 0fe211868e4..00000000000 --- a/changelogs/unreleased/35659-rename-pipeline.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Rename Pipelines tab to CI / CD in new navigation -merge_request: -author: diff --git a/changelogs/unreleased/35695-comment-appears-in-a-wrong-place-after-changing-diff-view-to-inline.yml b/changelogs/unreleased/35695-comment-appears-in-a-wrong-place-after-changing-diff-view-to-inline.yml deleted file mode 100644 index 1c9ad20bc95..00000000000 --- a/changelogs/unreleased/35695-comment-appears-in-a-wrong-place-after-changing-diff-view-to-inline.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Fix display of new diff comments after changing b between diff views -merge_request: -author: diff --git a/changelogs/unreleased/35761-convdev-perc.yml b/changelogs/unreleased/35761-convdev-perc.yml deleted file mode 100644 index 319c4d18219..00000000000 --- a/changelogs/unreleased/35761-convdev-perc.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Store & use ConvDev percentages returned by the Version app -merge_request: -author: diff --git a/changelogs/unreleased/35769-fix-ruby-2-4-compatibility.yml b/changelogs/unreleased/35769-fix-ruby-2-4-compatibility.yml deleted file mode 100644 index ac480993d85..00000000000 --- a/changelogs/unreleased/35769-fix-ruby-2-4-compatibility.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Fix Issue board when using Ruby 2.4 -merge_request: 13220 -author: diff --git a/changelogs/unreleased/35815-webhook-log-encoding-error.yml b/changelogs/unreleased/35815-webhook-log-encoding-error.yml deleted file mode 100644 index 76ec235086c..00000000000 --- a/changelogs/unreleased/35815-webhook-log-encoding-error.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Fix encoding error for WebHook logging -merge_request: 13230 -author: Alexander Randa (@randaalex) diff --git a/changelogs/unreleased/35845-improve-subgroup-creation-permissions.yml b/changelogs/unreleased/35845-improve-subgroup-creation-permissions.yml new file mode 100644 index 00000000000..eac8dbe23c2 --- /dev/null +++ b/changelogs/unreleased/35845-improve-subgroup-creation-permissions.yml @@ -0,0 +1,5 @@ +--- +title: Improves subgroup creation permissions +merge_request: 13418 +author: +type: bugifx diff --git a/changelogs/unreleased/36185-or-separator.yml b/changelogs/unreleased/36185-or-separator.yml deleted file mode 100644 index 4e46e60ea1b..00000000000 --- a/changelogs/unreleased/36185-or-separator.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Align OR separator to center in new project page -merge_request: -author: diff --git a/changelogs/unreleased/3686_make_tarball_download_url.yml b/changelogs/unreleased/3686_make_tarball_download_url.yml deleted file mode 100644 index 4e75e52e3ac..00000000000 --- a/changelogs/unreleased/3686_make_tarball_download_url.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: repository archive download url now ends with selected file extension -merge_request: 13178 -author: haseebeqx diff --git a/changelogs/unreleased/5971-webhook-testing.yml b/changelogs/unreleased/5971-webhook-testing.yml deleted file mode 100644 index 58233091977..00000000000 --- a/changelogs/unreleased/5971-webhook-testing.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Allow testing any events for project hooks and system hooks -merge_request: 11728 -author: Alexander Randa (@randaalex) diff --git a/changelogs/unreleased/add-filtered-search-group-issues-ce.yml b/changelogs/unreleased/add-filtered-search-group-issues-ce.yml deleted file mode 100644 index f83f4173890..00000000000 --- a/changelogs/unreleased/add-filtered-search-group-issues-ce.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Add filtered search to group issue dashboard -merge_request: -author: diff --git a/changelogs/unreleased/add-star-for-action-scope.yml b/changelogs/unreleased/add-star-for-action-scope.yml deleted file mode 100644 index a8119a01ec4..00000000000 --- a/changelogs/unreleased/add-star-for-action-scope.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Add star for action scope, in order to delete image from registry -merge_request: 13248 -author: jean diff --git a/changelogs/unreleased/appearances-caching-and-schema.yml b/changelogs/unreleased/appearances-caching-and-schema.yml deleted file mode 100644 index 5743f6e0f2d..00000000000 --- a/changelogs/unreleased/appearances-caching-and-schema.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Cache Appearance instances in Redis -merge_request: -author: diff --git a/changelogs/unreleased/artifacts-download-dropdown-menu-is-too-narrow.yml b/changelogs/unreleased/artifacts-download-dropdown-menu-is-too-narrow.yml deleted file mode 100644 index 7d47c60e262..00000000000 --- a/changelogs/unreleased/artifacts-download-dropdown-menu-is-too-narrow.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Increase width of dropdown menus automatically -merge_request: 12809 -author: Thomas Wucher diff --git a/changelogs/unreleased/breadcrumbs-collapsed-title-width-fix.yml b/changelogs/unreleased/breadcrumbs-collapsed-title-width-fix.yml deleted file mode 100644 index 988fdacb5fd..00000000000 --- a/changelogs/unreleased/breadcrumbs-collapsed-title-width-fix.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Fixed breadcrumbs title aggressively collapsing -merge_request: -author: diff --git a/changelogs/unreleased/broadcast-messages-cache.yml b/changelogs/unreleased/broadcast-messages-cache.yml deleted file mode 100644 index a3c9e1ff465..00000000000 --- a/changelogs/unreleased/broadcast-messages-cache.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Better caching and indexing of broadcast messages -merge_request: -author: diff --git a/changelogs/unreleased/bump-omniauth-ldap-gem-version.yml b/changelogs/unreleased/bump-omniauth-ldap-gem-version.yml deleted file mode 100644 index 42e1c9e8f83..00000000000 --- a/changelogs/unreleased/bump-omniauth-ldap-gem-version.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Prevent LDAP login callback from being called with a GET request -merge_request: 13059 -author: diff --git a/changelogs/unreleased/bvl-add-all-settings-to-api.yml b/changelogs/unreleased/bvl-add-all-settings-to-api.yml deleted file mode 100644 index bfaf237a21c..00000000000 --- a/changelogs/unreleased/bvl-add-all-settings-to-api.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Make all application-settings accessible through the API -merge_request: 12851 -author: diff --git a/changelogs/unreleased/bvl-free-unused-names.yml b/changelogs/unreleased/bvl-free-unused-names.yml deleted file mode 100644 index 53acb95e5bb..00000000000 --- a/changelogs/unreleased/bvl-free-unused-names.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Free up some top level words, reject top level groups named like files in the - public folder -merge_request: 12932 -author: diff --git a/changelogs/unreleased/bvl-nfs-circuitbreaker.yml b/changelogs/unreleased/bvl-nfs-circuitbreaker.yml deleted file mode 100644 index 151854ed31f..00000000000 --- a/changelogs/unreleased/bvl-nfs-circuitbreaker.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Block access to failing repository storage -merge_request: 11449 -author: diff --git a/changelogs/unreleased/bvl-rollback-renamed-system-namespace.yml b/changelogs/unreleased/bvl-rollback-renamed-system-namespace.yml deleted file mode 100644 index a24cc7a1c43..00000000000 --- a/changelogs/unreleased/bvl-rollback-renamed-system-namespace.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Don't rename namespace called system when upgrading from 9.1.x to 9.5 -merge_request: 13228 -author: diff --git a/changelogs/unreleased/commits-list-page-limit.yml b/changelogs/unreleased/commits-list-page-limit.yml deleted file mode 100644 index 2fd54c5960a..00000000000 --- a/changelogs/unreleased/commits-list-page-limit.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fix commit list not loading the correct page when scrolling -merge_request: -author: -type: fixed diff --git a/changelogs/unreleased/diff-changed-files-dropdown.yml b/changelogs/unreleased/diff-changed-files-dropdown.yml deleted file mode 100644 index 2d2a26ffea2..00000000000 --- a/changelogs/unreleased/diff-changed-files-dropdown.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Moved diff changed files into a dropdown -merge_request: -author: diff --git a/changelogs/unreleased/dm-large-push-performance.yml b/changelogs/unreleased/dm-large-push-performance.yml deleted file mode 100644 index f5fe1bd3b28..00000000000 --- a/changelogs/unreleased/dm-large-push-performance.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Improve performance of large (initial) push into default branch -merge_request: -author: diff --git a/changelogs/unreleased/dont-use-limit-offset-when-counting-projects.yml b/changelogs/unreleased/dont-use-limit-offset-when-counting-projects.yml deleted file mode 100644 index 8ecea635ce5..00000000000 --- a/changelogs/unreleased/dont-use-limit-offset-when-counting-projects.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: "Improve performance of checking for projects on the projects dashboard" -merge_request: -author: diff --git a/changelogs/unreleased/dz-fix-calendar-today.yml b/changelogs/unreleased/dz-fix-calendar-today.yml deleted file mode 100644 index 5320d8b26b5..00000000000 --- a/changelogs/unreleased/dz-fix-calendar-today.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Fix today day highlight in calendar -merge_request: 13048 -author: diff --git a/changelogs/unreleased/eager-load-project-creators-for-project-dashboards.yml b/changelogs/unreleased/eager-load-project-creators-for-project-dashboards.yml deleted file mode 100644 index e550e0b2f44..00000000000 --- a/changelogs/unreleased/eager-load-project-creators-for-project-dashboards.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Eager load project creators for project dashboards -merge_request: -author: diff --git a/changelogs/unreleased/enable-scss-lint-bang-format.yml b/changelogs/unreleased/enable-scss-lint-bang-format.yml deleted file mode 100644 index 0b73760198e..00000000000 --- a/changelogs/unreleased/enable-scss-lint-bang-format.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Enable BangFormat in scss-lint [ci skip] -merge_request: 12815 -author: Takuya Noguchi diff --git a/changelogs/unreleased/enable-scss-lint-declaration-order.yml b/changelogs/unreleased/enable-scss-lint-declaration-order.yml deleted file mode 100644 index 7ac2f55592e..00000000000 --- a/changelogs/unreleased/enable-scss-lint-declaration-order.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Enable DeclarationOrder in scss-lint -merge_request: 12805 -author: Takuya Noguchi diff --git a/changelogs/unreleased/enable-scss-lint-import-path.yml b/changelogs/unreleased/enable-scss-lint-import-path.yml deleted file mode 100644 index d158cf5b5f3..00000000000 --- a/changelogs/unreleased/enable-scss-lint-import-path.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Enable ImportPath in scss-lint -merge_request: 12749 -author: Takuya Noguchi diff --git a/changelogs/unreleased/enable-scss-lint-property-spelling.yml b/changelogs/unreleased/enable-scss-lint-property-spelling.yml deleted file mode 100644 index c5a5a4dddb6..00000000000 --- a/changelogs/unreleased/enable-scss-lint-property-spelling.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Enable PropertySpelling in scss-lint -merge_request: 12752 -author: Takuya Noguchi diff --git a/changelogs/unreleased/enable-scss-lint-space-after-comma.yml b/changelogs/unreleased/enable-scss-lint-space-after-comma.yml deleted file mode 100644 index 210f34fbb87..00000000000 --- a/changelogs/unreleased/enable-scss-lint-space-after-comma.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Enable SpaceAfterComma in scss-lint -merge_request: 12734 -author: Takuya Noguchi diff --git a/changelogs/unreleased/enable-scss-lint-unnecessary-parent-reference.yml b/changelogs/unreleased/enable-scss-lint-unnecessary-parent-reference.yml deleted file mode 100644 index 59d5df56525..00000000000 --- a/changelogs/unreleased/enable-scss-lint-unnecessary-parent-reference.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Enable UnnecessaryParentReference in scss-lint -merge_request: 12738 -author: Takuya Noguchi diff --git a/changelogs/unreleased/ericy_ts-protected_branches_api.yml b/changelogs/unreleased/ericy_ts-protected_branches_api.yml deleted file mode 100644 index 4cd275c5e8f..00000000000 --- a/changelogs/unreleased/ericy_ts-protected_branches_api.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Add API for protected branches to allow for wildcard matching and no access - restrictions -merge_request: 12756 -author: Eric Yu diff --git a/changelogs/unreleased/feature-backup-custom-path.yml b/changelogs/unreleased/feature-backup-custom-path.yml deleted file mode 100644 index 1c5f25b3ee5..00000000000 --- a/changelogs/unreleased/feature-backup-custom-path.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Support custom directory in gitlab:backup:create task -merge_request: 12984 -author: Markus Koller diff --git a/changelogs/unreleased/feature-gb-auto-retry-failed-ci-job.yml b/changelogs/unreleased/feature-gb-auto-retry-failed-ci-job.yml deleted file mode 100644 index bdafc5929c0..00000000000 --- a/changelogs/unreleased/feature-gb-auto-retry-failed-ci-job.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Allow to configure automatic retry of a failed CI/CD job -merge_request: 12909 -author: diff --git a/changelogs/unreleased/feature-gpg-signed-commits.yml b/changelogs/unreleased/feature-gpg-signed-commits.yml deleted file mode 100644 index 99bc5a309ef..00000000000 --- a/changelogs/unreleased/feature-gpg-signed-commits.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: GPG signed commits integration -merge_request: 9546 -author: Alexis Reigel diff --git a/changelogs/unreleased/fix-500-error-when-rendering-avatar-for-deleted-project-creator.yml b/changelogs/unreleased/fix-500-error-when-rendering-avatar-for-deleted-project-creator.yml deleted file mode 100644 index be6f1ea00fb..00000000000 --- a/changelogs/unreleased/fix-500-error-when-rendering-avatar-for-deleted-project-creator.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Modify if condition to be more readable -merge_request: -author: diff --git a/changelogs/unreleased/fix-broadcast-message-caching.yml b/changelogs/unreleased/fix-broadcast-message-caching.yml new file mode 100644 index 00000000000..58ec1766cfd --- /dev/null +++ b/changelogs/unreleased/fix-broadcast-message-caching.yml @@ -0,0 +1,5 @@ +--- +title: Fix caching of future broadcast messages +merge_request: +author: +type: fixed diff --git a/changelogs/unreleased/fix-gb-handle-max-pages-artifacts-size-correctly.yml b/changelogs/unreleased/fix-gb-handle-max-pages-artifacts-size-correctly.yml deleted file mode 100644 index 3d9592bbf2a..00000000000 --- a/changelogs/unreleased/fix-gb-handle-max-pages-artifacts-size-correctly.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Handle maximum pages artifacts size correctly -merge_request: 13072 -author: diff --git a/changelogs/unreleased/fix-import-fork-mr.yml b/changelogs/unreleased/fix-import-fork-mr.yml new file mode 100644 index 00000000000..4e9cf7faae8 --- /dev/null +++ b/changelogs/unreleased/fix-import-fork-mr.yml @@ -0,0 +1,5 @@ +--- +title: Fix Import/Export issue to do with fork merge requests +merge_request: +author: +type: fixed diff --git a/changelogs/unreleased/fix-import-symbolink-links.yml b/changelogs/unreleased/fix-import-symbolink-links.yml deleted file mode 100644 index 36e73821bdc..00000000000 --- a/changelogs/unreleased/fix-import-symbolink-links.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Remove hidden symlinks from project import files -merge_request: -author: diff --git a/changelogs/unreleased/fix-replying-to-commit-comment-in-mr-from-fork.yml b/changelogs/unreleased/fix-replying-to-commit-comment-in-mr-from-fork.yml deleted file mode 100644 index f4136460626..00000000000 --- a/changelogs/unreleased/fix-replying-to-commit-comment-in-mr-from-fork.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Fix replying to commit comments on merge requests created from forks -merge_request: -author: diff --git a/changelogs/unreleased/fix-thread-safe-gpgme-tmp-directory.yml b/changelogs/unreleased/fix-thread-safe-gpgme-tmp-directory.yml deleted file mode 100644 index 66b5b6b4f47..00000000000 --- a/changelogs/unreleased/fix-thread-safe-gpgme-tmp-directory.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Make GPGME temporary directory handling thread safe -merge_request: 13481 -author: Alexis Reigel diff --git a/changelogs/unreleased/fixes-for-internal-auth-disabled.yml b/changelogs/unreleased/fixes-for-internal-auth-disabled.yml deleted file mode 100644 index 188d2770455..00000000000 --- a/changelogs/unreleased/fixes-for-internal-auth-disabled.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Fixes needed when GitLab sign-in is not enabled -merge_request: 12491 -author: Robin Bobbitt diff --git a/changelogs/unreleased/forks-count-cache.yml b/changelogs/unreleased/forks-count-cache.yml deleted file mode 100644 index da8c53c2abd..00000000000 --- a/changelogs/unreleased/forks-count-cache.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Cache the number of forks of a project -merge_request: 13535 -author: -type: other diff --git a/changelogs/unreleased/github.yml b/changelogs/unreleased/github.yml deleted file mode 100644 index 585b9b13b65..00000000000 --- a/changelogs/unreleased/github.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Reduce memory usage of the GitHub importer -merge_request: 12886 -author: diff --git a/changelogs/unreleased/group-milestone-references-system-notes.yml b/changelogs/unreleased/group-milestone-references-system-notes.yml deleted file mode 100644 index 58215352305..00000000000 --- a/changelogs/unreleased/group-milestone-references-system-notes.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Support Markdown references, autocomplete, and quick actions for group milestones -merge_request: -author: diff --git a/changelogs/unreleased/group-new-issue.yml b/changelogs/unreleased/group-new-issue.yml deleted file mode 100644 index 5480a44526b..00000000000 --- a/changelogs/unreleased/group-new-issue.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Cache recent projects for group-level new resource creation. -merge_request: !13058 -author: diff --git a/changelogs/unreleased/handle-reserved-words-for-oauth-usernames.yml b/changelogs/unreleased/handle-reserved-words-for-oauth-usernames.yml deleted file mode 100644 index 0d64844a2b8..00000000000 --- a/changelogs/unreleased/handle-reserved-words-for-oauth-usernames.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Uniquify reserved word usernames on OAuth user creation -merge_request: 13244 -author: Robin Bobbitt diff --git a/changelogs/unreleased/issue_31790.yml b/changelogs/unreleased/issue_31790.yml deleted file mode 100644 index df02cad423a..00000000000 --- a/changelogs/unreleased/issue_31790.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Fix API responses when dealing with txt files -merge_request: -author: diff --git a/changelogs/unreleased/issue_35580.yml b/changelogs/unreleased/issue_35580.yml deleted file mode 100644 index 3a94e771e25..00000000000 --- a/changelogs/unreleased/issue_35580.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Fix project milestones import when projects belongs to a group -merge_request: -author: diff --git a/changelogs/unreleased/memoize-user-personal-projects-count.yml b/changelogs/unreleased/memoize-user-personal-projects-count.yml deleted file mode 100644 index 3839a97f185..00000000000 --- a/changelogs/unreleased/memoize-user-personal-projects-count.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Memoize the number of personal projects a user has to reduce COUNT queries -merge_request: -author: diff --git a/changelogs/unreleased/merge-issuable-reopened-into-opened-state.yml b/changelogs/unreleased/merge-issuable-reopened-into-opened-state.yml deleted file mode 100644 index 5d7af8971e5..00000000000 --- a/changelogs/unreleased/merge-issuable-reopened-into-opened-state.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Merge issuable "reopened" state into "opened" -merge_request: -author: diff --git a/changelogs/unreleased/migrate-events-into-a-new-format.yml b/changelogs/unreleased/migrate-events-into-a-new-format.yml deleted file mode 100644 index 8a29f75323f..00000000000 --- a/changelogs/unreleased/migrate-events-into-a-new-format.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Migrate events into a new format to reduce the storage necessary and improve performance -merge_request: -author: diff --git a/changelogs/unreleased/mk-fix-wiki-backup.yml b/changelogs/unreleased/mk-fix-wiki-backup.yml deleted file mode 100644 index ba9c1e85955..00000000000 --- a/changelogs/unreleased/mk-fix-wiki-backup.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Fix improperly skipped backups of wikis. -merge_request: 13096 -author: diff --git a/changelogs/unreleased/mr-branch-link-use-tree.yml b/changelogs/unreleased/mr-branch-link-use-tree.yml deleted file mode 100644 index f4c4d9f5082..00000000000 --- a/changelogs/unreleased/mr-branch-link-use-tree.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: MR branch link now links to tree instead of commits -merge_request: -author: diff --git a/changelogs/unreleased/only-limit-fetch-when-requested.yml b/changelogs/unreleased/only-limit-fetch-when-requested.yml new file mode 100644 index 00000000000..d9acdf56511 --- /dev/null +++ b/changelogs/unreleased/only-limit-fetch-when-requested.yml @@ -0,0 +1,5 @@ +--- +title: Only require Sidekiq throttling library when enabled, to reduce cache misses +merge_request: +author: +type: fixed diff --git a/changelogs/unreleased/pagination-projects-explore.yml b/changelogs/unreleased/pagination-projects-explore.yml deleted file mode 100644 index dc9c4218793..00000000000 --- a/changelogs/unreleased/pagination-projects-explore.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Use Prev/Next pagination for exploring projects -merge_request: -author: diff --git a/changelogs/unreleased/pass-before-script-as-is.yml b/changelogs/unreleased/pass-before-script-as-is.yml deleted file mode 100644 index ac6513dcff6..00000000000 --- a/changelogs/unreleased/pass-before-script-as-is.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Pass before_script and script as-is preserving arrays -merge_request: -author: diff --git a/changelogs/unreleased/pawel-add-sidekiq-metrics-endpoint-32145.yml b/changelogs/unreleased/pawel-add-sidekiq-metrics-endpoint-32145.yml deleted file mode 100644 index 71eabdc16d2..00000000000 --- a/changelogs/unreleased/pawel-add-sidekiq-metrics-endpoint-32145.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Add Prometheus metrics exporter to Sidekiq -merge_request: 13082 -author: diff --git a/changelogs/unreleased/pawel-add_more_variables_to_additional_metrics-35267.yml b/changelogs/unreleased/pawel-add_more_variables_to_additional_metrics-35267.yml deleted file mode 100644 index c1e831306df..00000000000 --- a/changelogs/unreleased/pawel-add_more_variables_to_additional_metrics-35267.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Add support for kube_namespace in Metrics queries -merge_request: 16169 -author: diff --git a/changelogs/unreleased/post-upload-pack-opt-out.yml b/changelogs/unreleased/post-upload-pack-opt-out.yml deleted file mode 100644 index 302a99795a0..00000000000 --- a/changelogs/unreleased/post-upload-pack-opt-out.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Enable gitaly_post_upload_pack by default -merge_request: 13078 -author: diff --git a/changelogs/unreleased/rc-fix-branches-api-endpoint.yml b/changelogs/unreleased/rc-fix-branches-api-endpoint.yml deleted file mode 100644 index b36663bbe91..00000000000 --- a/changelogs/unreleased/rc-fix-branches-api-endpoint.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fix the /projects/:id/repository/branches endpoint to handle dots in the branch - name when the project full path contains a `/` -merge_request: 13115 -author: diff --git a/changelogs/unreleased/rc-fix-commits-api.yml b/changelogs/unreleased/rc-fix-commits-api.yml deleted file mode 100644 index 215429eaf6b..00000000000 --- a/changelogs/unreleased/rc-fix-commits-api.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fix the /projects/:id/repository/commits endpoint to handle dots in the ref - name when the project full path contains a `/` -merge_request: 13370 -author: diff --git a/changelogs/unreleased/rc-fix-tags-api.yml b/changelogs/unreleased/rc-fix-tags-api.yml deleted file mode 100644 index 0a7dd5ca6ab..00000000000 --- a/changelogs/unreleased/rc-fix-tags-api.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fix the /projects/:id/repository/tags endpoint to handle dots in the tag name - when the project full path contains a `/` -merge_request: 13368 -author: diff --git a/changelogs/unreleased/remove-nprogress-gleaning.yml b/changelogs/unreleased/remove-nprogress-gleaning.yml deleted file mode 100644 index 78e4dc82dd4..00000000000 --- a/changelogs/unreleased/remove-nprogress-gleaning.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Remove CSS for nprogress removed -merge_request: 12737 -author: Takuya Noguchi diff --git a/changelogs/unreleased/remove-redundant-query-when-retrieving-recent-pushes.yml b/changelogs/unreleased/remove-redundant-query-when-retrieving-recent-pushes.yml deleted file mode 100644 index 83934217e6a..00000000000 --- a/changelogs/unreleased/remove-redundant-query-when-retrieving-recent-pushes.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Remove redundant query when retrieving the most recent push of a user -merge_request: -author: diff --git a/changelogs/unreleased/reorganise-issues-indexes-for-sorting.yml b/changelogs/unreleased/reorganise-issues-indexes-for-sorting.yml deleted file mode 100644 index 5bfe55e562f..00000000000 --- a/changelogs/unreleased/reorganise-issues-indexes-for-sorting.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Re-organise "issues" indexes for faster ordering -merge_request: -author: diff --git a/changelogs/unreleased/replace_spinach_spec_browse_files.yml b/changelogs/unreleased/replace_spinach_spec_browse_files.yml deleted file mode 100644 index 7380d39fa9f..00000000000 --- a/changelogs/unreleased/replace_spinach_spec_browse_files.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Replace 'browse_files.feature' spinach test with an rspec analog -merge_request: 12251 -author: @blackst0ne diff --git a/changelogs/unreleased/request-store-wrap.yml b/changelogs/unreleased/request-store-wrap.yml deleted file mode 100644 index 8017054b77b..00000000000 --- a/changelogs/unreleased/request-store-wrap.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Add RequestCache which makes caching with RequestStore easier -merge_request: 12920 -author: diff --git a/changelogs/unreleased/restrict-haml-javascript.yml b/changelogs/unreleased/restrict-haml-javascript.yml deleted file mode 100644 index 3d0a52f416d..00000000000 --- a/changelogs/unreleased/restrict-haml-javascript.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Add custom linter for inline JavaScript to haml_lint -merge_request: 9742 -author: winniehell diff --git a/changelogs/unreleased/rs-alphanumeric-ssh-params.yml b/changelogs/unreleased/rs-alphanumeric-ssh-params.yml deleted file mode 100644 index 426b01cafad..00000000000 --- a/changelogs/unreleased/rs-alphanumeric-ssh-params.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Disallow Git URLs that include a username or hostname beginning with a non-alphanumeric - character -merge_request: -author: diff --git a/changelogs/unreleased/sh-structured-logging.yml b/changelogs/unreleased/sh-structured-logging.yml deleted file mode 100644 index d89eb93f689..00000000000 --- a/changelogs/unreleased/sh-structured-logging.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Add structured logging for Rails processes -merge_request: -author: diff --git a/changelogs/unreleased/skip-oauth-authorization-for-trusted-applications.yml b/changelogs/unreleased/skip-oauth-authorization-for-trusted-applications.yml deleted file mode 100644 index 7b4ae355978..00000000000 --- a/changelogs/unreleased/skip-oauth-authorization-for-trusted-applications.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Skip oAuth authorization for trusted applications -merge_request: -author: diff --git a/changelogs/unreleased/tc-api-root-merge-requests.yml b/changelogs/unreleased/tc-api-root-merge-requests.yml deleted file mode 100644 index 17456f943eb..00000000000 --- a/changelogs/unreleased/tc-api-root-merge-requests.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Add top-level merge_requests API endpoint -merge_request: 13060 -author: diff --git a/changelogs/unreleased/tc-git-tower-pagination-links.yml b/changelogs/unreleased/tc-git-tower-pagination-links.yml deleted file mode 100644 index b99ef8c3c4c..00000000000 --- a/changelogs/unreleased/tc-git-tower-pagination-links.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Improve API pagination headers when no record found -merge_request: 13629 -author: Jordan Patterson -type: fixed diff --git a/changelogs/unreleased/tc-issue-api-assignee.yml b/changelogs/unreleased/tc-issue-api-assignee.yml deleted file mode 100644 index 8d6360d5baf..00000000000 --- a/changelogs/unreleased/tc-issue-api-assignee.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Add author_id & assignee_id param to /issues API -merge_request: 13004 -author: diff --git a/changelogs/unreleased/tc-no-todo-service-select.yml b/changelogs/unreleased/tc-no-todo-service-select.yml deleted file mode 100644 index ddcae334aa7..00000000000 --- a/changelogs/unreleased/tc-no-todo-service-select.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Avoid plucking Todo ids in TodoService -merge_request: 10845 -author: diff --git a/changelogs/unreleased/toggle-new-project-import-description.yml b/changelogs/unreleased/toggle-new-project-import-description.yml deleted file mode 100644 index 8f0d09e0540..00000000000 --- a/changelogs/unreleased/toggle-new-project-import-description.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Toggle import description with import_sources_enabled -merge_request: 12691 -author: Brianna Kicia
\ No newline at end of file diff --git a/changelogs/unreleased/use-a-specialized-class-for-querying-events.yml b/changelogs/unreleased/use-a-specialized-class-for-querying-events.yml deleted file mode 100644 index 6c1ec10aa12..00000000000 --- a/changelogs/unreleased/use-a-specialized-class-for-querying-events.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Use a specialized class for querying events to improve performance -merge_request: -author: diff --git a/changelogs/unreleased/wiki_title.yml b/changelogs/unreleased/wiki_title.yml deleted file mode 100644 index 3ef5fa2969b..00000000000 --- a/changelogs/unreleased/wiki_title.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Allow wiki pages to be renamed in the UI -merge_request: 10069 -author: wendy0402 diff --git a/changelogs/unreleased/winh-derive-project-name.yml b/changelogs/unreleased/winh-derive-project-name.yml deleted file mode 100644 index 2244d21d768..00000000000 --- a/changelogs/unreleased/winh-derive-project-name.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Derive project path from import URL -merge_request: 13131 -author: diff --git a/changelogs/unreleased/zj-delete-mm-team.yml b/changelogs/unreleased/zj-delete-mm-team.yml deleted file mode 100644 index f0c782c4566..00000000000 --- a/changelogs/unreleased/zj-delete-mm-team.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Remove Mattermost team when deleting a group -merge_request: 11362 -author: diff --git a/changelogs/unreleased/zj-pipeline-badge-improvements.yml b/changelogs/unreleased/zj-pipeline-badge-improvements.yml deleted file mode 100644 index 735192ede2d..00000000000 --- a/changelogs/unreleased/zj-pipeline-badge-improvements.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Update build badges to be pipeline badges and display passing instead of success -merge_request: -author: diff --git a/changelogs/unreleased/zj-project-templates.yml b/changelogs/unreleased/zj-project-templates.yml deleted file mode 100644 index ab6e0f2d5f2..00000000000 --- a/changelogs/unreleased/zj-project-templates.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Projects can be created from templates -merge_request: 13108 -author: diff --git a/config/initializers/workhorse_multipart.rb b/config/initializers/workhorse_multipart.rb index 064e5964f09..4196e3a8f61 100644 --- a/config/initializers/workhorse_multipart.rb +++ b/config/initializers/workhorse_multipart.rb @@ -10,10 +10,8 @@ end # module Gitlab module StrongParameterScalars - GITLAB_PERMITTED_SCALAR_TYPES = [::UploadedFile].freeze - def permitted_scalar?(value) - super || GITLAB_PERMITTED_SCALAR_TYPES.any? { |type| value.is_a?(type) } + super || value.is_a?(::UploadedFile) end end end diff --git a/db/migrate/20170802013652_add_storage_fields_to_project.rb b/db/migrate/20170802013652_add_storage_fields_to_project.rb new file mode 100644 index 00000000000..c2381a9d0b2 --- /dev/null +++ b/db/migrate/20170802013652_add_storage_fields_to_project.rb @@ -0,0 +1,16 @@ +# See http://doc.gitlab.com/ce/development/migration_style_guide.html +# for more information on how to write migrations for GitLab. + +class AddStorageFieldsToProject < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + DOWNTIME = false + + def up + add_column :projects, :storage_version, :integer, limit: 2 + end + + def down + remove_column :projects, :storage_version + end +end diff --git a/db/migrate/20170807071105_add_hashed_storage_to_settings.rb b/db/migrate/20170807071105_add_hashed_storage_to_settings.rb new file mode 100644 index 00000000000..0846557add8 --- /dev/null +++ b/db/migrate/20170807071105_add_hashed_storage_to_settings.rb @@ -0,0 +1,18 @@ +# See http://doc.gitlab.com/ce/development/migration_style_guide.html +# for more information on how to write migrations for GitLab. + +class AddHashedStorageToSettings < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + DOWNTIME = false + + disable_ddl_transaction! + + def up + add_column_with_default :application_settings, :hashed_storage_enabled, :boolean, default: false + end + + def down + remove_columns :application_settings, :hashed_storage_enabled + end +end diff --git a/db/schema.rb b/db/schema.rb index c31bff3a8f2..cd488630237 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -128,6 +128,7 @@ ActiveRecord::Schema.define(version: 20170820100558) do t.integer "performance_bar_allowed_group_id" t.boolean "password_authentication_enabled" t.boolean "project_export_enabled", default: true, null: false + t.boolean "hashed_storage_enabled", default: false, null: false end create_table "audit_events", force: :cascade do |t| @@ -1208,6 +1209,7 @@ ActiveRecord::Schema.define(version: 20170820100558) do t.datetime "last_repository_updated_at" t.string "ci_config_path" t.text "delete_error" + t.integer "storage_version", limit: 2 end add_index "projects", ["ci_id"], name: "index_projects_on_ci_id", using: :btree diff --git a/doc/user/group/index.md b/doc/user/group/index.md index 9e168e830e5..fbc05261a32 100644 --- a/doc/user/group/index.md +++ b/doc/user/group/index.md @@ -55,6 +55,12 @@ By doing so: - John mentions everyone from his team with `@john-team` - John mentions only his marketing team with `@john-team/marketing` +## Issues and merge requests within a group + +Issues and merge requests are part of projects. For a given group, view all the +[issues](../project/issues/index.md#issues-per-group) and [merge requests](../project/merge_requests/index.md#merge-requests-per-group) across all the projects in that group, +together in a single list view. + ## Create a new group > **Notes:** diff --git a/doc/user/index.md b/doc/user/index.md index d664fd62754..e9ec603f2f1 100644 --- a/doc/user/index.md +++ b/doc/user/index.md @@ -126,6 +126,10 @@ are a tool for working faster and more effectively with your team, by listing all user or group mentions, as well as issues and merge requests you're assigned to. +## Search + +[Search and filter](search/index.md) through groups, projects, issues, merge requests, files, code, and more. + ## Snippets [Snippets](snippets.md) are code blocks that you want to store in GitLab, from which diff --git a/doc/user/project/issues/img/group_issues_list_view.png b/doc/user/project/issues/img/group_issues_list_view.png Binary files differnew file mode 100644 index 00000000000..5d20e8cbc89 --- /dev/null +++ b/doc/user/project/issues/img/group_issues_list_view.png diff --git a/doc/user/project/issues/img/issue_tracker.png b/doc/user/project/issues/img/issue_tracker.png Binary files differdeleted file mode 100755 index ab25cb64d13..00000000000 --- a/doc/user/project/issues/img/issue_tracker.png +++ /dev/null diff --git a/doc/user/project/issues/img/project_issues_list_view.png b/doc/user/project/issues/img/project_issues_list_view.png Binary files differnew file mode 100644 index 00000000000..2fcc9e8d9da --- /dev/null +++ b/doc/user/project/issues/img/project_issues_list_view.png diff --git a/doc/user/project/issues/index.md b/doc/user/project/issues/index.md index 1f78849a92c..20901e01f6e 100644 --- a/doc/user/project/issues/index.md +++ b/doc/user/project/issues/index.md @@ -7,7 +7,7 @@ of solving a problem. It allows you, your team, and your collaborators to share and discuss proposals before and while implementing them. -Issues and the GitLab Issue Tracker are available in all +GitLab Issues and the GitLab Issue Tracker are available in all [GitLab Products](https://about.gitlab.com/products/) as part of the [GitLab Workflow](https://about.gitlab.com/2016/10/25/gitlab-workflow-an-overview/). @@ -48,11 +48,27 @@ for feature proposals and another one for bug reports. ## Issue Tracker -The issue tracker is the collection of opened and closed issues created in a project. +The Issue Tracker is the collection of opened and closed issues created in a project. +It is available for all projects, from the moment the project is created. -![Issue tracker](img/issue_tracker.png) +Find the issue tracker by navigating to your **Project's homepage** > **Issues**. -Find the issue tracker by navigating to your **Project's Dashboard** > **Issues**. +### Issues per project + +When you access your project's issues, GitLab will present them in a list, +and you can use the tabs available to quickly filter by open and closed issues. + +![Project issues list view](img/project_issues_list_view.png) + +You can also [search and filter](../../search/index.md#issues-and-merge-requests-per-project) the results more deeply with GitLab's search capacities. + +### Issues per group + +View all the issues in a group (that is, all the issues across all projects in that +group) by navigating to **Group > Issues**. This view also has the open and closed +issue tabs. + +![Group Issues list view](img/group_issues_list_view.png) ## GitLab Issues Functionalities @@ -120,6 +136,12 @@ to find out more about this feature. With [GitLab Enterprise Edition Starter](https://about.gitlab.com/gitlab-ee/), you can also create various boards per project with [Multiple Issue Boards](https://docs.gitlab.com/ee/user/project/issue_board.html#multiple-issue-boards). +### External Issue Tracker + +Alternatively to GitLab's built-in Issue Tracker, you can also use an [external +tracker](../../../integration/external-issue-tracker.md) such as Jira, Redmine, +or Bugzilla. + ### Issue's API Read through the [API documentation](../../../api/issues.md). diff --git a/doc/user/project/merge_requests/img/group_merge_requests_list_view.png b/doc/user/project/merge_requests/img/group_merge_requests_list_view.png Binary files differnew file mode 100644 index 00000000000..02a88d0112f --- /dev/null +++ b/doc/user/project/merge_requests/img/group_merge_requests_list_view.png diff --git a/doc/user/project/merge_requests/img/project_merge_requests_list_view.png b/doc/user/project/merge_requests/img/project_merge_requests_list_view.png Binary files differnew file mode 100644 index 00000000000..702ec1a2949 --- /dev/null +++ b/doc/user/project/merge_requests/img/project_merge_requests_list_view.png diff --git a/doc/user/project/merge_requests/index.md b/doc/user/project/merge_requests/index.md index 9bdf2a998d3..285c40729fe 100644 --- a/doc/user/project/merge_requests/index.md +++ b/doc/user/project/merge_requests/index.md @@ -56,6 +56,23 @@ B. Consider you're a web developer writing a webpage for your company's: 1. Once approved, your merge request is [squashed and merged](https://docs.gitlab.com/ee/user/project/merge_requests/squash_and_merge.html), and [deployed to staging with GitLab Pages](https://about.gitlab.com/2016/08/26/ci-deployment-and-environments/) (Squash and Merge is available in GitLab Enterprise Edition Starter) 1. Your production team [cherry picks](#cherry-pick-changes) the merge commit into production +## Merge requests per project + +View all the merge requests within a project by navigating to **Project > Merge Requests**. + +When you access your project's merge requests, GitLab will present them in a list, +and you can use the tabs available to quickly filter by open and closed. You can also [search and filter the results](../../search/index.md#issues-and-merge-requests-per-project). + +![Project merge requests list view](img/project_merge_requests_list_view.png) + +## Merge requests per group + +View all the merge requests in a group (that is, all the merge requests across all projects in that +group) by navigating to **Group > Merge Requests**. This view also has the open, merged, and closed +merge request tabs, from which you can [search and filter the results](../../search/index.md#issues-and-merge-requests-per-group). + +![Group Issues list view](img/group_merge_requests_list_view.png) + ## Authorization for merge requests There are two main ways to have a merge request flow with GitLab: @@ -141,7 +158,6 @@ all your changes will be available to preview by anyone with the Review Apps lin [Read more about Review Apps.](../../../ci/review_apps/index.md) - ## Tips Here are some tips that will help you be more efficient with merge requests in @@ -230,4 +246,4 @@ git checkout origin/merge-requests/1 ``` [protected branches]: ../protected_branches.md -[ee]: https://about.gitlab.com/gitlab-ee/ "GitLab Enterprise Edition" +[ee]: https://about.gitlab.com/gitlab-ee/ "GitLab Enterprise Edition"
\ No newline at end of file diff --git a/doc/user/search/index.md b/doc/user/search/index.md index 79f34fd29ba..f5c7ce49e8e 100644 --- a/doc/user/search/index.md +++ b/doc/user/search/index.md @@ -27,7 +27,7 @@ on the search field on the top-right of your screen: ![shortcut to your issues and mrs](img/issues_mrs_shortcut.png) -## Issues and merge requests per project +### Issues and merge requests per project If you want to search for issues present in a specific project, navigate to a project's **Issues** tab, and click on the field **Search or filter results...**. It will @@ -40,7 +40,7 @@ The same process is valid for merge requests. Navigate to your project's **Merge and click **Search or filter results...**. Merge requests can be filtered by author, assignee, milestone, and label. -## Issues and merge requests per group +### Issues and merge requests per group Similar to **Issues and merge requests per project**, you can also search for issues within a group. Navigate to a group's **Issues** tab and query search results in @@ -48,6 +48,10 @@ the same way as you do for projects. ![filter issues in a group](img/group_issues_filter.png) +The same process is valid for merge requests. Navigate to your project's **Merge Requests** tab. +The search and filter UI currently uses dropdowns. In a future release, the same +dynamic UI as above will be carried over here. + ## Search history You can view recent searches by clicking on the little arrow-clock icon, which is to the left of the search input. Click the search entry to run that search again. This feature is available for issues and merge requests. Searches are stored locally in your browser. diff --git a/lib/backup/repository.rb b/lib/backup/repository.rb index 88821ae56e0..4e92be85110 100644 --- a/lib/backup/repository.rb +++ b/lib/backup/repository.rb @@ -75,7 +75,7 @@ module Backup path_to_project_repo = path_to_repo(project) path_to_project_bundle = path_to_bundle(project) - project.ensure_storage_path_exist + project.ensure_storage_path_exists cmd = if File.exist?(path_to_project_bundle) %W(#{Gitlab.config.git.bin_path} clone --bare #{path_to_project_bundle} #{path_to_project_repo}) diff --git a/lib/gitlab/gitaly_client/commit_service.rb b/lib/gitlab/gitaly_client/commit_service.rb index b36e81278d6..2d58fb0186e 100644 --- a/lib/gitlab/gitaly_client/commit_service.rb +++ b/lib/gitlab/gitaly_client/commit_service.rb @@ -80,8 +80,8 @@ module Gitlab def tree_entries(repository, revision, path) request = Gitaly::GetTreeEntriesRequest.new( repository: @gitaly_repo, - revision: revision, - path: path.presence || '.' + revision: GitalyClient.encode(revision), + path: path.present? ? GitalyClient.encode(path) : '.' ) response = GitalyClient.call(@repository.storage, :commit_service, :get_tree_entries, request) diff --git a/lib/gitlab/import_export/import_export.yml b/lib/gitlab/import_export/import_export.yml index 9d9ebcb389a..e5d4bb686e7 100644 --- a/lib/gitlab/import_export/import_export.yml +++ b/lib/gitlab/import_export/import_export.yml @@ -98,6 +98,7 @@ excluded_attributes: - :last_activity_at - :last_repository_updated_at - :last_repository_check_at + - :storage_version snippets: - :expired_at merge_request_diff: @@ -133,5 +134,7 @@ methods: - :utf8_diff merge_requests: - :diff_head_sha + - :source_branch_sha + - :target_branch_sha project: - :description_html diff --git a/lib/gitlab/import_export/merge_request_parser.rb b/lib/gitlab/import_export/merge_request_parser.rb index c20adc20bfd..81a213e8321 100644 --- a/lib/gitlab/import_export/merge_request_parser.rb +++ b/lib/gitlab/import_export/merge_request_parser.rb @@ -30,7 +30,7 @@ module Gitlab end def branch_exists?(branch_name) - @project.repository.branch_exists?(branch_name) + @project.repository.raw.branch_exists?(branch_name) end def fork_merge_request? diff --git a/lib/gitlab/job_waiter.rb b/lib/gitlab/job_waiter.rb index 208f0e1bbea..4d6bbda15f3 100644 --- a/lib/gitlab/job_waiter.rb +++ b/lib/gitlab/job_waiter.rb @@ -1,12 +1,31 @@ module Gitlab # JobWaiter can be used to wait for a number of Sidekiq jobs to complete. + # + # Its use requires the cooperation of the sidekiq jobs themselves. Set up the + # waiter, then start the jobs, passing them its `key`. Their `perform` methods + # should look like: + # + # def perform(args, notify_key) + # # do work + # ensure + # ::Gitlab::JobWaiter.notify(notify_key, jid) + # end + # + # The JobWaiter blocks popping items from a Redis array. All the sidekiq jobs + # push to that array when done. Once the waiter has popped `count` items, it + # knows all the jobs are done. class JobWaiter - # The sleep interval between checking keys, in seconds. - INTERVAL = 0.1 + def self.notify(key, jid) + Gitlab::Redis::SharedState.with { |redis| redis.lpush(key, jid) } + end + + attr_reader :key, :jobs_remaining, :finished - # jobs - The job IDs to wait for. - def initialize(jobs) - @jobs = jobs + # jobs_remaining - the number of jobs left to wait for + def initialize(jobs_remaining) + @key = "gitlab:job_waiter:#{SecureRandom.uuid}" + @jobs_remaining = jobs_remaining + @finished = [] end # Waits for all the jobs to be completed. @@ -15,13 +34,33 @@ module Gitlab # ensures we don't indefinitely block a caller in case a job takes # long to process, or is never processed. def wait(timeout = 10) - start = Time.current + deadline = Time.now.utc + timeout + + Gitlab::Redis::SharedState.with do |redis| + # Fallback key expiry: allow a long grace period to reduce the chance of + # a job pushing to an expired key and recreating it + redis.expire(key, [timeout * 2, 10.minutes.to_i].max) + + while jobs_remaining > 0 + # Redis will not take fractional seconds. Prefer waiting too long over + # not waiting long enough + seconds_left = (deadline - Time.now.utc).ceil - while (Time.current - start) <= timeout - break if SidekiqStatus.all_completed?(@jobs) + # Redis interprets 0 as "wait forever", so skip the final `blpop` call + break if seconds_left <= 0 - sleep(INTERVAL) # to not overload Redis too much. + list, jid = redis.blpop(key, timeout: seconds_left) + break unless list && jid # timed out + + @finished << jid + @jobs_remaining -= 1 + end + + # All jobs have finished, so expire the key immediately + redis.expire(key, 0) if jobs_remaining == 0 end + + finished end end end diff --git a/lib/gitlab/regex.rb b/lib/gitlab/regex.rb index 1adc5ec952a..58f6245579a 100644 --- a/lib/gitlab/regex.rb +++ b/lib/gitlab/regex.rb @@ -53,7 +53,8 @@ module Gitlab end def kubernetes_namespace_regex_message - "can contain only letters, digits or '-', and cannot start or end with '-'" + "can contain only lowercase letters, digits, and '-'. " \ + "Must start with a letter, and cannot end with '-'" end def environment_slug_regex diff --git a/lib/gitlab/sidekiq_throttler.rb b/lib/gitlab/sidekiq_throttler.rb index d4d39a888e7..5512afa45a8 100644 --- a/lib/gitlab/sidekiq_throttler.rb +++ b/lib/gitlab/sidekiq_throttler.rb @@ -3,6 +3,8 @@ module Gitlab class << self def execute! if Gitlab::CurrentSettings.sidekiq_throttling_enabled? + require 'sidekiq-limit_fetch' + Gitlab::CurrentSettings.current_application_settings.sidekiq_throttling_queues.each do |queue| Sidekiq::Queue[queue].limit = queue_limit end diff --git a/lib/tasks/gitlab/import.rake b/lib/tasks/gitlab/import.rake index 48bd9139ce8..6e10ba374bf 100644 --- a/lib/tasks/gitlab/import.rake +++ b/lib/tasks/gitlab/import.rake @@ -11,6 +11,12 @@ namespace :gitlab do # desc "GitLab | Import bare repositories from repositories -> storages into GitLab project instance" task repos: :environment do + if Project.current_application_settings.hashed_storage_enabled + puts 'Cannot import repositories when Hashed Storage is enabled'.color(:red) + + exit 1 + end + Gitlab.config.repositories.storages.each_value do |repository_storage| git_base_path = repository_storage['path'] repos_to_import = Dir.glob(git_base_path + '/**/*.git') diff --git a/spec/factories/projects.rb b/spec/factories/projects.rb index 4a2034b31b3..9ebda0ba03b 100644 --- a/spec/factories/projects.rb +++ b/spec/factories/projects.rb @@ -81,6 +81,10 @@ FactoryGirl.define do archived true end + trait :hashed do + storage_version Project::LATEST_STORAGE_VERSION + end + trait :access_requestable do request_access_enabled true end diff --git a/spec/features/groups_spec.rb b/spec/features/groups_spec.rb index e59a484d992..20f9818b08b 100644 --- a/spec/features/groups_spec.rb +++ b/spec/features/groups_spec.rb @@ -104,18 +104,15 @@ feature 'Group' do end context 'as group owner' do - let(:user) { create(:user) } + it 'creates a nested group' do + user = create(:user) - before do group.add_owner(user) sign_out(:user) sign_in(user) visit subgroups_group_path(group) click_link 'New Subgroup' - end - - it 'creates a nested group' do fill_in 'Group path', with: 'bar' click_button 'Create group' @@ -123,6 +120,16 @@ feature 'Group' do expect(page).to have_content("Group 'bar' was successfully created.") end end + + context 'when nested group feature is disabled' do + it 'renders 404' do + allow(Group).to receive(:supports_nested_groups?).and_return(false) + + visit subgroups_group_path(group) + + expect(page.status_code).to eq(404) + end + end end it 'checks permissions to avoid exposing groups by parent_id' do diff --git a/spec/features/projects/import_export/import_file_spec.rb b/spec/features/projects/import_export/import_file_spec.rb index 6a324d32ca7..9f2c86923b7 100644 --- a/spec/features/projects/import_export/import_file_spec.rb +++ b/spec/features/projects/import_export/import_file_spec.rb @@ -3,11 +3,13 @@ require 'spec_helper' feature 'Import/Export - project import integration test', js: true do include Select2Helper + let(:user) { create(:user) } let(:file) { File.join(Rails.root, 'spec', 'features', 'projects', 'import_export', 'test_project_export.tar.gz') } let(:export_path) { "#{Dir.tmpdir}/import_file_spec" } background do allow_any_instance_of(Gitlab::ImportExport).to receive(:storage_path).and_return(export_path) + gitlab_sign_in(user) end after do @@ -18,57 +20,67 @@ feature 'Import/Export - project import integration test', js: true do let(:user) { create(:admin) } let!(:namespace) { create(:namespace, name: "asd", owner: user) } - before do - gitlab_sign_in(user) - end + context 'prefilled the path' do + scenario 'user imports an exported project successfully' do + visit new_project_path - scenario 'user imports an exported project successfully' do - visit new_project_path + select2(namespace.id, from: '#project_namespace_id') + fill_in :project_path, with: 'test-project-path', visible: true + click_link 'GitLab export' - select2(namespace.id, from: '#project_namespace_id') - fill_in :project_path, with: 'test-project-path', visible: true - click_link 'GitLab export' + expect(page).to have_content('Import an exported GitLab project') + expect(URI.parse(current_url).query).to eq("namespace_id=#{namespace.id}&path=test-project-path") + expect(Gitlab::ImportExport).to receive(:import_upload_path).with(filename: /\A\h{32}_test-project-path\z/).and_call_original - expect(page).to have_content('Import an exported GitLab project') - expect(URI.parse(current_url).query).to eq("namespace_id=#{namespace.id}&path=test-project-path") - expect(Gitlab::ImportExport).to receive(:import_upload_path).with(filename: /\A\h{32}_test-project-path\z/).and_call_original + attach_file('file', file) - attach_file('file', file) + expect { click_on 'Import project' }.to change { Project.count }.by(1) - expect { click_on 'Import project' }.to change { Project.count }.from(0).to(1) - - project = Project.last - expect(project).not_to be_nil - expect(project.issues).not_to be_empty - expect(project.merge_requests).not_to be_empty - expect(project_hook_exists?(project)).to be true - expect(wiki_exists?(project)).to be true - expect(project.import_status).to eq('finished') + project = Project.last + expect(project).not_to be_nil + expect(project.issues).not_to be_empty + expect(project.merge_requests).not_to be_empty + expect(project_hook_exists?(project)).to be true + expect(wiki_exists?(project)).to be true + expect(project.import_status).to eq('finished') + end end - scenario 'invalid project' do - project = create(:project, namespace: namespace) + context 'path is not prefilled' do + scenario 'user imports an exported project successfully' do + visit new_project_path + click_link 'GitLab export' - visit new_project_path + fill_in :path, with: 'test-project-path', visible: true + attach_file('file', file) - select2(namespace.id, from: '#project_namespace_id') - fill_in :project_path, with: project.name, visible: true - click_link 'GitLab export' - attach_file('file', file) - click_on 'Import project' + expect { click_on 'Import project' }.to change { Project.count }.by(1) - page.within('.flash-container') do - expect(page).to have_content('Project could not be imported') + project = Project.last + expect(project).not_to be_nil + expect(page).to have_content("Project 'test-project-path' is being imported") end end end - context 'when limited to the default user namespace' do - let(:user) { create(:user) } - before do - gitlab_sign_in(user) + scenario 'invalid project' do + namespace = create(:namespace, name: "asd", owner: user) + project = create(:project, namespace: namespace) + + visit new_project_path + + select2(namespace.id, from: '#project_namespace_id') + fill_in :project_path, with: project.name, visible: true + click_link 'GitLab export' + attach_file('file', file) + click_on 'Import project' + + page.within('.flash-container') do + expect(page).to have_content('Project could not be imported') end + end + context 'when limited to the default user namespace' do scenario 'passes correct namespace ID in the URL' do visit new_project_path diff --git a/spec/javascripts/fixtures/project_select_combo_button.html.haml b/spec/javascripts/fixtures/project_select_combo_button.html.haml index 54bc1a59279..432cd5fcc74 100644 --- a/spec/javascripts/fixtures/project_select_combo_button.html.haml +++ b/spec/javascripts/fixtures/project_select_combo_button.html.haml @@ -1,6 +1,6 @@ .project-item-select-holder %input.project-item-select{ data: { group_id: '12345' , relative_path: 'issues/new' } } - %a.new-project-item-link{ data: { label: 'New issue' }, href: ''} + %a.new-project-item-link{ data: { label: 'New issue', type: 'issues' }, href: ''} %i.fa.fa-spinner.spin %a.new-project-item-select-button %i.fa.fa-caret-down diff --git a/spec/javascripts/project_select_combo_button_spec.js b/spec/javascripts/project_select_combo_button_spec.js index e10a5a3bef6..021804e0769 100644 --- a/spec/javascripts/project_select_combo_button_spec.js +++ b/spec/javascripts/project_select_combo_button_spec.js @@ -101,5 +101,40 @@ describe('Project Select Combo Button', function () { window.localStorage.clear(); }); }); + + describe('deriveTextVariants', function () { + beforeEach(function () { + this.mockExecutionContext = { + resourceType: '', + resourceLabel: '', + }; + + this.comboButton = new ProjectSelectComboButton(this.projectSelectInput); + + this.method = this.comboButton.deriveTextVariants.bind(this.mockExecutionContext); + }); + + it('correctly derives test variants for merge requests', function () { + this.mockExecutionContext.resourceType = 'merge_requests'; + this.mockExecutionContext.resourceLabel = 'New merge request'; + + const returnedVariants = this.method(); + + expect(returnedVariants.localStorageItemType).toBe('new-merge-request'); + expect(returnedVariants.defaultTextPrefix).toBe('New merge request'); + expect(returnedVariants.presetTextSuffix).toBe('merge request'); + }); + + it('correctly derives text variants for issues', function () { + this.mockExecutionContext.resourceType = 'issues'; + this.mockExecutionContext.resourceLabel = 'New issue'; + + const returnedVariants = this.method(); + + expect(returnedVariants.localStorageItemType).toBe('new-issue'); + expect(returnedVariants.defaultTextPrefix).toBe('New issue'); + expect(returnedVariants.presetTextSuffix).toBe('issue'); + }); + }); }); diff --git a/spec/lib/gitlab/gitaly_client/commit_service_spec.rb b/spec/lib/gitlab/gitaly_client/commit_service_spec.rb index 7fe698fcb18..2eaf4222964 100644 --- a/spec/lib/gitlab/gitaly_client/commit_service_spec.rb +++ b/spec/lib/gitlab/gitaly_client/commit_service_spec.rb @@ -111,6 +111,20 @@ describe Gitlab::GitalyClient::CommitService do client.tree_entries(repository, revision, path) end + + context 'with UTF-8 params strings' do + let(:revision) { "branch\u011F" } + let(:path) { "foo/\u011F.txt" } + + it 'handles string encodings correctly' do + expect_any_instance_of(Gitaly::CommitService::Stub) + .to receive(:get_tree_entries) + .with(gitaly_request_with_path(storage_name, relative_path), kind_of(Hash)) + .and_return([]) + + client.tree_entries(repository, revision, path) + end + end end describe '#find_commit' do diff --git a/spec/lib/gitlab/import_export/project.json b/spec/lib/gitlab/import_export/project.json index 4e631e13410..331b7cf2fea 100644 --- a/spec/lib/gitlab/import_export/project.json +++ b/spec/lib/gitlab/import_export/project.json @@ -2522,7 +2522,7 @@ "id": 27, "target_branch": "feature", "source_branch": "feature_conflict", - "source_project_id": 5, + "source_project_id": 999, "author_id": 1, "assignee_id": null, "title": "MR1", @@ -2536,6 +2536,9 @@ "position": 0, "updated_by_id": null, "merge_error": null, + "diff_head_sha": "HEAD", + "source_branch_sha": "ABCD", + "target_branch_sha": "DCBA", "merge_params": { "force_remove_source_branch": null }, 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 956f1d56eb4..c10427d798f 100644 --- a/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb +++ b/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb @@ -10,6 +10,13 @@ describe Gitlab::ImportExport::ProjectTreeRestorer do @shared = Gitlab::ImportExport::Shared.new(relative_path: "", project_path: 'path') allow(@shared).to receive(:export_path).and_return('spec/lib/gitlab/import_export/') @project = create(:project, :builds_disabled, :issues_disabled, name: 'project', path: 'project') + + allow(@project.repository).to receive(:fetch_ref).and_return(true) + allow(@project.repository.raw).to receive(:rugged_branch_exists?).and_return(false) + + expect_any_instance_of(Gitlab::Git::Repository).to receive(:create_branch).with('feature', 'DCBA') + allow_any_instance_of(Gitlab::Git::Repository).to receive(:create_branch) + project_tree_restorer = described_class.new(user: @user, shared: @shared, project: @project) @restored_project_json = project_tree_restorer.restore end diff --git a/spec/lib/gitlab/import_export/project_tree_saver_spec.rb b/spec/lib/gitlab/import_export/project_tree_saver_spec.rb index a278f89c1a1..065b0ec6658 100644 --- a/spec/lib/gitlab/import_export/project_tree_saver_spec.rb +++ b/spec/lib/gitlab/import_export/project_tree_saver_spec.rb @@ -11,6 +11,8 @@ describe Gitlab::ImportExport::ProjectTreeSaver do before do project.team << [user, :master] allow_any_instance_of(Gitlab::ImportExport).to receive(:storage_path).and_return(export_path) + allow_any_instance_of(MergeRequest).to receive(:source_branch_sha).and_return('ABCD') + allow_any_instance_of(MergeRequest).to receive(:target_branch_sha).and_return('DCBA') end after do @@ -43,6 +45,14 @@ describe Gitlab::ImportExport::ProjectTreeSaver do expect(saved_project_json['merge_requests'].first['milestone']).not_to be_empty end + it 'has merge request\'s source branch SHA' do + expect(saved_project_json['merge_requests'].first['source_branch_sha']).to eq('ABCD') + end + + it 'has merge request\'s target branch SHA' do + expect(saved_project_json['merge_requests'].first['target_branch_sha']).to eq('DCBA') + end + it 'has events' do expect(saved_project_json['merge_requests'].first['milestone']['events']).not_to be_empty end diff --git a/spec/lib/gitlab/job_waiter_spec.rb b/spec/lib/gitlab/job_waiter_spec.rb index 6186cec2689..b0b4fdc09bc 100644 --- a/spec/lib/gitlab/job_waiter_spec.rb +++ b/spec/lib/gitlab/job_waiter_spec.rb @@ -1,30 +1,39 @@ require 'spec_helper' describe Gitlab::JobWaiter do - describe '#wait' do - let(:waiter) { described_class.new(%w(a)) } - it 'returns when all jobs have been completed' do - expect(Gitlab::SidekiqStatus).to receive(:all_completed?).with(%w(a)) - .and_return(true) + describe '.notify' do + it 'pushes the jid to the named queue' do + key = 'gitlab:job_waiter:foo' + jid = 1 - expect(waiter).not_to receive(:sleep) + redis = double('redis') + expect(Gitlab::Redis::SharedState).to receive(:with).and_yield(redis) + expect(redis).to receive(:lpush).with(key, jid) - waiter.wait + described_class.notify(key, jid) end + end + + describe '#wait' do + let(:waiter) { described_class.new(2) } - it 'sleeps between checking the job statuses' do - expect(Gitlab::SidekiqStatus).to receive(:all_completed?) - .with(%w(a)) - .and_return(false, true) + it 'returns when all jobs have been completed' do + described_class.notify(waiter.key, 'a') + described_class.notify(waiter.key, 'b') - expect(waiter).to receive(:sleep).with(described_class::INTERVAL) + result = nil + expect { Timeout.timeout(1) { result = waiter.wait(2) } }.not_to raise_error - waiter.wait + expect(result).to contain_exactly('a', 'b') end - it 'returns when timing out' do - expect(waiter).not_to receive(:sleep) - waiter.wait(0) + it 'times out if not all jobs complete' do + described_class.notify(waiter.key, 'a') + + result = nil + expect { Timeout.timeout(2) { result = waiter.wait(1) } }.not_to raise_error + + expect(result).to contain_exactly('a') end end end diff --git a/spec/lib/gitlab/sidekiq_throttler_spec.rb b/spec/lib/gitlab/sidekiq_throttler_spec.rb index 6374ac80207..2dbb7bb7c34 100644 --- a/spec/lib/gitlab/sidekiq_throttler_spec.rb +++ b/spec/lib/gitlab/sidekiq_throttler_spec.rb @@ -1,28 +1,44 @@ require 'spec_helper' describe Gitlab::SidekiqThrottler do - before do - Sidekiq.options[:concurrency] = 35 - - stub_application_setting( - sidekiq_throttling_enabled: true, - sidekiq_throttling_factor: 0.1, - sidekiq_throttling_queues: %w[build project_cache] - ) - end - describe '#execute!' do - it 'sets limits on the selected queues' do - described_class.execute! + context 'when job throttling is enabled' do + before do + Sidekiq.options[:concurrency] = 35 + + stub_application_setting( + sidekiq_throttling_enabled: true, + sidekiq_throttling_factor: 0.1, + sidekiq_throttling_queues: %w[build project_cache] + ) + end + + it 'requires sidekiq-limit_fetch' do + expect(described_class).to receive(:require).with('sidekiq-limit_fetch').and_call_original + + described_class.execute! + end + + it 'sets limits on the selected queues' do + described_class.execute! + + expect(Sidekiq::Queue['build'].limit).to eq 4 + expect(Sidekiq::Queue['project_cache'].limit).to eq 4 + end + + it 'does not set limits on other queues' do + described_class.execute! - expect(Sidekiq::Queue['build'].limit).to eq 4 - expect(Sidekiq::Queue['project_cache'].limit).to eq 4 + expect(Sidekiq::Queue['merge'].limit).to be_nil + end end - it 'does not set limits on other queues' do - described_class.execute! + context 'when job throttling is disabled' do + it 'does not require sidekiq-limit_fetch' do + expect(described_class).not_to receive(:require).with('sidekiq-limit_fetch') - expect(Sidekiq::Queue['merge'].limit).to be_nil + described_class.execute! + end end end end diff --git a/spec/migrations/cleanup_namespaceless_pending_delete_projects_spec.rb b/spec/migrations/cleanup_namespaceless_pending_delete_projects_spec.rb index 12cac1d033d..b47f3314926 100644 --- a/spec/migrations/cleanup_namespaceless_pending_delete_projects_spec.rb +++ b/spec/migrations/cleanup_namespaceless_pending_delete_projects_spec.rb @@ -4,7 +4,7 @@ require Rails.root.join('db', 'post_migrate', '20170502101023_cleanup_namespacel describe CleanupNamespacelessPendingDeleteProjects do before do # Stub after_save callbacks that will fail when Project has no namespace - allow_any_instance_of(Project).to receive(:ensure_storage_path_exist).and_return(nil) + allow_any_instance_of(Project).to receive(:ensure_storage_path_exists).and_return(nil) allow_any_instance_of(Project).to receive(:update_project_statistics).and_return(nil) end diff --git a/spec/models/broadcast_message_spec.rb b/spec/models/broadcast_message_spec.rb index 3369aef1d3e..461e754dc1f 100644 --- a/spec/models/broadcast_message_spec.rb +++ b/spec/models/broadcast_message_spec.rb @@ -53,6 +53,29 @@ describe BroadcastMessage do 2.times { described_class.current } end + + it 'includes messages that need to be displayed in the future' do + create(:broadcast_message) + + future = create( + :broadcast_message, + starts_at: Time.now + 10.minutes, + ends_at: Time.now + 20.minutes + ) + + expect(described_class.current.length).to eq(1) + + Timecop.travel(future.starts_at) do + expect(described_class.current.length).to eq(2) + end + end + + it 'does not clear the cache if only a future message should be displayed' do + create(:broadcast_message, :future) + + expect(Rails.cache).not_to receive(:delete) + expect(described_class.current.length).to eq(0) + end end describe '#active?' do diff --git a/spec/models/project_services/kubernetes_service_spec.rb b/spec/models/project_services/kubernetes_service_spec.rb index 55b96a0c12e..b1743cd608e 100644 --- a/spec/models/project_services/kubernetes_service_spec.rb +++ b/spec/models/project_services/kubernetes_service_spec.rb @@ -38,7 +38,8 @@ describe KubernetesService, :use_clean_rails_memory_store_caching do 'a' * 63 => true, 'a' * 64 => false, 'a.b' => false, - 'a*b' => false + 'a*b' => false, + 'FOO' => true }.each do |namespace, validity| it "validates #{namespace} as #{validity ? 'valid' : 'invalid'}" do subject.namespace = namespace diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index 5e60511f3a8..2e613c44357 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -1251,60 +1251,6 @@ describe Project do end end - describe '#rename_repo' do - let(:project) { create(:project, :repository) } - let(:gitlab_shell) { Gitlab::Shell.new } - - before do - # Project#gitlab_shell returns a new instance of Gitlab::Shell on every - # call. This makes testing a bit easier. - allow(project).to receive(:gitlab_shell).and_return(gitlab_shell) - allow(project).to receive(:previous_changes).and_return('path' => ['foo']) - end - - it 'renames a repository' do - stub_container_registry_config(enabled: false) - - expect(gitlab_shell).to receive(:mv_repository) - .ordered - .with(project.repository_storage_path, "#{project.namespace.full_path}/foo", "#{project.full_path}") - .and_return(true) - - expect(gitlab_shell).to receive(:mv_repository) - .ordered - .with(project.repository_storage_path, "#{project.namespace.full_path}/foo.wiki", "#{project.full_path}.wiki") - .and_return(true) - - expect_any_instance_of(SystemHooksService) - .to receive(:execute_hooks_for) - .with(project, :rename) - - expect_any_instance_of(Gitlab::UploadsTransfer) - .to receive(:rename_project) - .with('foo', project.path, project.namespace.full_path) - - expect(project).to receive(:expire_caches_before_rename) - - expect(project).to receive(:expires_full_path_cache) - - project.rename_repo - end - - context 'container registry with images' do - let(:container_repository) { create(:container_repository) } - - before do - stub_container_registry_config(enabled: true) - stub_container_registry_tags(repository: :any, tags: ['tag']) - project.container_repositories << container_repository - end - - subject { project.rename_repo } - - it { expect {subject}.to raise_error(StandardError) } - end - end - describe '#expire_caches_before_rename' do let(:project) { create(:project, :repository) } let(:repo) { double(:repo, exists?: true) } @@ -2367,4 +2313,181 @@ describe Project do expect(project.forks_count).to eq(1) end end + + context 'legacy storage' do + let(:project) { create(:project, :repository) } + let(:gitlab_shell) { Gitlab::Shell.new } + + before do + allow(project).to receive(:gitlab_shell).and_return(gitlab_shell) + end + + describe '#base_dir' do + it 'returns base_dir based on namespace only' do + expect(project.base_dir).to eq(project.namespace.full_path) + end + end + + describe '#disk_path' do + it 'returns disk_path based on namespace and project path' do + expect(project.disk_path).to eq("#{project.namespace.full_path}/#{project.path}") + end + end + + describe '#ensure_storage_path_exists' do + it 'delegates to gitlab_shell to ensure namespace is created' do + expect(gitlab_shell).to receive(:add_namespace).with(project.repository_storage_path, project.base_dir) + + project.ensure_storage_path_exists + end + end + + describe '#legacy_storage?' do + it 'returns true when storage_version is nil' do + project = build(:project) + + expect(project.legacy_storage?).to be_truthy + end + end + + describe '#rename_repo' do + before do + # Project#gitlab_shell returns a new instance of Gitlab::Shell on every + # call. This makes testing a bit easier. + allow(project).to receive(:gitlab_shell).and_return(gitlab_shell) + allow(project).to receive(:previous_changes).and_return('path' => ['foo']) + end + + it 'renames a repository' do + stub_container_registry_config(enabled: false) + + expect(gitlab_shell).to receive(:mv_repository) + .ordered + .with(project.repository_storage_path, "#{project.namespace.full_path}/foo", "#{project.full_path}") + .and_return(true) + + expect(gitlab_shell).to receive(:mv_repository) + .ordered + .with(project.repository_storage_path, "#{project.namespace.full_path}/foo.wiki", "#{project.full_path}.wiki") + .and_return(true) + + expect_any_instance_of(SystemHooksService) + .to receive(:execute_hooks_for) + .with(project, :rename) + + expect_any_instance_of(Gitlab::UploadsTransfer) + .to receive(:rename_project) + .with('foo', project.path, project.namespace.full_path) + + expect(project).to receive(:expire_caches_before_rename) + + expect(project).to receive(:expires_full_path_cache) + + project.rename_repo + end + + context 'container registry with images' do + let(:container_repository) { create(:container_repository) } + + before do + stub_container_registry_config(enabled: true) + stub_container_registry_tags(repository: :any, tags: ['tag']) + project.container_repositories << container_repository + end + + subject { project.rename_repo } + + it { expect { subject }.to raise_error(StandardError) } + end + end + + describe '#pages_path' do + it 'returns a path where pages are stored' do + expect(project.pages_path).to eq(File.join(Settings.pages.path, project.namespace.full_path, project.path)) + end + end + end + + context 'hashed storage' do + let(:project) { create(:project, :repository) } + let(:gitlab_shell) { Gitlab::Shell.new } + let(:hash) { '6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b' } + + before do + stub_application_setting(hashed_storage_enabled: true) + allow(Digest::SHA2).to receive(:hexdigest) { hash } + allow(project).to receive(:gitlab_shell).and_return(gitlab_shell) + end + + describe '#base_dir' do + it 'returns base_dir based on hash of project id' do + expect(project.base_dir).to eq('@hashed/6b/86') + end + end + + describe '#disk_path' do + it 'returns disk_path based on hash of project id' do + hashed_path = '@hashed/6b/86/6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b' + + expect(project.disk_path).to eq(hashed_path) + end + end + + describe '#ensure_storage_path_exists' do + it 'delegates to gitlab_shell to ensure namespace is created' do + expect(gitlab_shell).to receive(:add_namespace).with(project.repository_storage_path, '@hashed/6b/86') + + project.ensure_storage_path_exists + end + end + + describe '#rename_repo' do + before do + # Project#gitlab_shell returns a new instance of Gitlab::Shell on every + # call. This makes testing a bit easier. + allow(project).to receive(:gitlab_shell).and_return(gitlab_shell) + allow(project).to receive(:previous_changes).and_return('path' => ['foo']) + end + + it 'renames a repository' do + stub_container_registry_config(enabled: false) + + expect(gitlab_shell).not_to receive(:mv_repository) + + expect_any_instance_of(SystemHooksService) + .to receive(:execute_hooks_for) + .with(project, :rename) + + expect_any_instance_of(Gitlab::UploadsTransfer) + .to receive(:rename_project) + .with('foo', project.path, project.namespace.full_path) + + expect(project).to receive(:expire_caches_before_rename) + + expect(project).to receive(:expires_full_path_cache) + + project.rename_repo + end + + context 'container registry with images' do + let(:container_repository) { create(:container_repository) } + + before do + stub_container_registry_config(enabled: true) + stub_container_registry_tags(repository: :any, tags: ['tag']) + project.container_repositories << container_repository + end + + subject { project.rename_repo } + + it { expect { subject }.to raise_error(StandardError) } + end + end + + describe '#pages_path' do + it 'returns a path where pages are stored' do + expect(project.pages_path).to eq(File.join(Settings.pages.path, project.namespace.full_path, project.path)) + end + end + end end diff --git a/spec/policies/group_policy_spec.rb b/spec/policies/group_policy_spec.rb index b17a93e3fbe..cf420ae3ea6 100644 --- a/spec/policies/group_policy_spec.rb +++ b/spec/policies/group_policy_spec.rb @@ -123,6 +123,36 @@ describe GroupPolicy do end end + describe 'when nested group support feature is disabled' do + before do + allow(Group).to receive(:supports_nested_groups?).and_return(false) + end + + context 'admin' do + let(:current_user) { admin } + + it 'allows every owner permission except creating subgroups' do + create_subgroup_permission = [:create_subgroup] + updated_owner_permissions = owner_permissions - create_subgroup_permission + + expect_disallowed(*create_subgroup_permission) + expect_allowed(*updated_owner_permissions) + end + end + + context 'owner' do + let(:current_user) { owner } + + it 'allows every owner permission except creating subgroups' do + create_subgroup_permission = [:create_subgroup] + updated_owner_permissions = owner_permissions - create_subgroup_permission + + expect_disallowed(*create_subgroup_permission) + expect_allowed(*updated_owner_permissions) + end + end + end + describe 'private nested group use the highest access level from the group and inherited permissions', :nested_groups do let(:nested_group) { create(:group, :private, parent: group) } diff --git a/spec/services/groups/create_service_spec.rb b/spec/services/groups/create_service_spec.rb index b2175717a70..6973e7ff990 100644 --- a/spec/services/groups/create_service_spec.rb +++ b/spec/services/groups/create_service_spec.rb @@ -32,12 +32,24 @@ describe Groups::CreateService, '#execute' do end it { is_expected.to be_persisted } + + context 'when nested groups feature is disabled' do + it 'does not save group and returns an error' do + allow(Group).to receive(:supports_nested_groups?).and_return(false) + + is_expected.not_to be_persisted + expect(subject.errors[:parent_id]).to include('You don’t have permission to create a subgroup in this group.') + expect(subject.parent_id).to be_nil + end + end end context 'as guest' do it 'does not save group and returns an error' do + allow(Group).to receive(:supports_nested_groups?).and_return(true) + is_expected.not_to be_persisted - expect(subject.errors[:parent_id].first).to eq('manage access required to create subgroup') + expect(subject.errors[:parent_id].first).to eq('You don’t have permission to create a subgroup in this group.') expect(subject.parent_id).to be_nil end end diff --git a/spec/services/groups/destroy_service_spec.rb b/spec/services/groups/destroy_service_spec.rb index 1b2ce3cd03e..ac4b9c02ba7 100644 --- a/spec/services/groups/destroy_service_spec.rb +++ b/spec/services/groups/destroy_service_spec.rb @@ -8,8 +8,8 @@ describe Groups::DestroyService do let!(:nested_group) { create(:group, parent: group) } let!(:project) { create(:project, namespace: group) } let!(:notification_setting) { create(:notification_setting, source: group)} - let!(:gitlab_shell) { Gitlab::Shell.new } - let!(:remove_path) { group.path + "+#{group.id}+deleted" } + let(:gitlab_shell) { Gitlab::Shell.new } + let(:remove_path) { group.path + "+#{group.id}+deleted" } before do group.add_user(user, Gitlab::Access::OWNER) @@ -134,4 +134,26 @@ describe Groups::DestroyService do it_behaves_like 'group destruction', false end + + describe 'repository removal' do + before do + destroy_group(group, user, false) + end + + context 'legacy storage' do + let!(:project) { create(:project, :empty_repo, namespace: group) } + + it 'removes repository' do + expect(gitlab_shell.exists?(project.repository_storage_path, "#{project.disk_path}.git")).to be_falsey + end + end + + context 'hashed storage' do + let!(:project) { create(:project, :hashed, :empty_repo, namespace: group) } + + it 'removes repository' do + expect(gitlab_shell.exists?(project.repository_storage_path, "#{project.disk_path}.git")).to be_falsey + end + end + end end diff --git a/spec/services/users/destroy_service_spec.rb b/spec/services/users/destroy_service_spec.rb index a82567f6f43..58a5bede3de 100644 --- a/spec/services/users/destroy_service_spec.rb +++ b/spec/services/users/destroy_service_spec.rb @@ -4,9 +4,10 @@ describe Users::DestroyService do describe "Deletes a user and all their personal projects" do let!(:user) { create(:user) } let!(:admin) { create(:admin) } - let!(:namespace) { create(:namespace, owner: user) } + let!(:namespace) { user.namespace } let!(:project) { create(:project, namespace: namespace) } let(:service) { described_class.new(admin) } + let(:gitlab_shell) { Gitlab::Shell.new } context 'no options are given' do it 'deletes the user' do @@ -14,7 +15,7 @@ describe Users::DestroyService do expect { user_data['email'].to eq(user.email) } expect { User.find(user.id) }.to raise_error(ActiveRecord::RecordNotFound) - expect { Namespace.with_deleted.find(user.namespace.id) }.to raise_error(ActiveRecord::RecordNotFound) + expect { Namespace.with_deleted.find(namespace.id) }.to raise_error(ActiveRecord::RecordNotFound) end it 'will delete the project' do @@ -165,5 +166,27 @@ describe Users::DestroyService do expect(Issue.exists?(issue.id)).to be_falsy end end + + describe "user personal's repository removal" do + before do + Sidekiq::Testing.inline! { service.execute(user) } + end + + context 'legacy storage' do + let!(:project) { create(:project, :empty_repo, namespace: user.namespace) } + + it 'removes repository' do + expect(gitlab_shell.exists?(project.repository_storage_path, "#{project.disk_path}.git")).to be_falsey + end + end + + context 'hashed storage' do + let!(:project) { create(:project, :empty_repo, :hashed, namespace: user.namespace) } + + it 'removes repository' do + expect(gitlab_shell.exists?(project.repository_storage_path, "#{project.disk_path}.git")).to be_falsey + end + end + end end end diff --git a/spec/workers/authorized_projects_worker_spec.rb b/spec/workers/authorized_projects_worker_spec.rb index 03b9b99e263..f8385ae7c72 100644 --- a/spec/workers/authorized_projects_worker_spec.rb +++ b/spec/workers/authorized_projects_worker_spec.rb @@ -29,21 +29,27 @@ describe AuthorizedProjectsWorker do end describe '#perform' do - subject { described_class.new } + let(:user) { create(:user) } - it "refreshes user's authorized projects" do - user = create(:user) + subject(:job) { described_class.new } + it "refreshes user's authorized projects" do expect_any_instance_of(User).to receive(:refresh_authorized_projects) - subject.perform(user.id) + job.perform(user.id) + end + + it 'notifies the JobWaiter when done if the key is provided' do + expect(Gitlab::JobWaiter).to receive(:notify).with('notify-key', job.jid) + + job.perform(user.id, 'notify-key') end context "when the user is not found" do it "does nothing" do expect_any_instance_of(User).not_to receive(:refresh_authorized_projects) - subject.perform(-1) + job.perform(-1) end end end diff --git a/spec/workers/namespaceless_project_destroy_worker_spec.rb b/spec/workers/namespaceless_project_destroy_worker_spec.rb index f2706254284..817e103fd9a 100644 --- a/spec/workers/namespaceless_project_destroy_worker_spec.rb +++ b/spec/workers/namespaceless_project_destroy_worker_spec.rb @@ -5,7 +5,7 @@ describe NamespacelessProjectDestroyWorker do before do # Stub after_save callbacks that will fail when Project has no namespace - allow_any_instance_of(Project).to receive(:ensure_storage_path_exist).and_return(nil) + allow_any_instance_of(Project).to receive(:ensure_storage_path_exists).and_return(nil) allow_any_instance_of(Project).to receive(:update_project_statistics).and_return(nil) end |