Merge branch 'master' into sh-headless-chrome-support

This commit is contained in:
Stan Hu 2017-08-23 22:38:14 -07:00
commit 55e5c84e2c
298 changed files with 2017 additions and 1151 deletions

View file

@ -6,6 +6,7 @@
},
"extends": "airbnb-base",
"globals": {
"__webpack_public_path__": true,
"_": false,
"gl": false,
"gon": false,

View file

@ -2,6 +2,180 @@
documentation](doc/development/changelog.md) for instructions on adding your own
entry.
## 9.5.1 (2017-08-23)
- [FIXED] Fix merge request pipeline status when pipeline has errors. !13664
- [FIXED] Commit rows would occasionally render with the wrong language.
- [FIXED] Fix caching of future broadcast messages.
- [FIXED] Only require Sidekiq throttling library when enabled, to reduce cache misses.
- Raise Housekeeping timeout to 24 hours. !13719
## 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

View file

@ -396,12 +396,12 @@ gem 'net-ssh', '~> 4.1.0'
# Required for ED25519 SSH host key support
group :ed25519 do
gem 'rbnacl-libsodium'
gem 'rbnacl', '~> 3.2'
gem 'rbnacl', '~> 4.0'
gem 'bcrypt_pbkdf', '~> 1.0'
end
# Gitaly GRPC client
gem 'gitaly', '~> 0.29.0'
gem 'gitaly', '~> 0.30.0'
gem 'toml-rb', '~> 0.3.15', require: false

View file

@ -204,7 +204,7 @@ GEM
multi_json
fast_gettext (1.4.0)
ffaker (2.4.0)
ffi (1.9.10)
ffi (1.9.18)
flay (2.8.1)
erubis (~> 2.7.0)
path_expander (~> 1.0)
@ -276,7 +276,7 @@ GEM
po_to_json (>= 1.0.0)
rails (>= 3.2.0)
gherkin-ruby (0.3.2)
gitaly (0.29.0)
gitaly (0.30.0)
google-protobuf (~> 3.1)
grpc (~> 1.0)
github-linguist (4.7.6)
@ -679,7 +679,7 @@ GEM
rake (12.0.0)
rblineprof (0.3.6)
debugger-ruby_core_source (~> 1.3)
rbnacl (3.4.0)
rbnacl (4.0.2)
ffi
rbnacl-libsodium (1.0.11)
rbnacl (>= 3.0.1)
@ -1016,7 +1016,7 @@ DEPENDENCIES
gettext (~> 3.2.2)
gettext_i18n_rails (~> 1.8.0)
gettext_i18n_rails_js (~> 1.2.0)
gitaly (~> 0.29.0)
gitaly (~> 0.30.0)
github-linguist (~> 4.7.0)
gitlab-flowdock-git-hook (~> 1.0.1)
gitlab-markup (~> 1.5.1)
@ -1103,7 +1103,7 @@ DEPENDENCIES
rainbow (~> 2.2)
raindrops (~> 0.18)
rblineprof (~> 0.3.6)
rbnacl (~> 3.2)
rbnacl (~> 4.0)
rbnacl-libsodium
rdoc (~> 4.2)
re2 (~> 1.1.1)

View file

@ -1 +1 @@
9.5.0-pre
9.6.0-pre

View file

@ -1,13 +1,11 @@
/* eslint-disable no-underscore-dangle, camelcase */
/* global __webpack_public_path__ */
import monacoContext from 'monaco-editor/dev/vs/loader';
monacoContext.require.config({
paths: {
vs: `${__webpack_public_path__}monaco-editor/vs`,
vs: `${__webpack_public_path__}monaco-editor/vs`, // eslint-disable-line camelcase
},
});
// eslint-disable-next-line no-underscore-dangle
window.__monaco_context__ = monacoContext;
export default monacoContext.require;

View file

@ -5,5 +5,5 @@
*/
if (gon && gon.webpack_public_path) {
__webpack_public_path__ = gon.webpack_public_path; // eslint-disable-line
__webpack_public_path__ = gon.webpack_public_path; // eslint-disable-line camelcase
}

View file

@ -13,6 +13,9 @@
img {
/*max-width: 100%;*/
margin: 0 0 8px;
}
img.lazy {
min-width: 200px;
min-height: 100px;
background-color: $gray-lightest;

View file

@ -286,6 +286,9 @@
.gpg-status-box {
padding: 2px 10px;
margin-right: $gl-padding;
&:empty {
display: none;
}
@ -314,7 +317,6 @@
&.valid {
svg {
border: 1px solid $brand-success;
fill: $brand-success;
}
}
@ -322,7 +324,6 @@
&.invalid {
svg {
border: 1px solid $common-gray-light;
fill: $common-gray-light;
}
}

View file

@ -1,2 +1,11 @@
class Admin::LogsController < Admin::ApplicationController
def show
@loggers = [
Gitlab::AppLogger,
Gitlab::GitLogger,
Gitlab::EnvironmentLogger,
Gitlab::SidekiqLogger,
Gitlab::RepositoryCheckLogger
]
end
end

View file

@ -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

View file

@ -4,7 +4,6 @@ class Projects::ServicesController < Projects::ApplicationController
# Authorize
before_action :authorize_admin_project!
before_action :service, only: [:edit, :update, :test]
before_action :update_service, only: [:update, :test]
respond_to :html
@ -14,6 +13,8 @@ class Projects::ServicesController < Projects::ApplicationController
end
def update
@service.attributes = service_params[:service]
if @service.save(context: :manual_change)
redirect_to(project_settings_integrations_path(@project), notice: success_message)
else
@ -24,7 +25,7 @@ class Projects::ServicesController < Projects::ApplicationController
def test
message = {}
if @service.can_test?
if @service.can_test? && @service.update_attributes(service_params[:service])
data = @service.test_data(project, current_user)
outcome = @service.test(data)
@ -50,10 +51,6 @@ class Projects::ServicesController < Projects::ApplicationController
end
end
def update_service
@service.assign_attributes(service_params[:service])
end
def service
@service ||= @project.find_or_initialize_service(params[:id])
end

View file

@ -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,

View file

@ -12,11 +12,18 @@ module AvatarsHelper
avatar_size = options[:size] || 16
user_name = options[:user].try(:name) || options[:user_name]
avatar_url = options[:url] || avatar_icon(options[:user] || options[:user_email], avatar_size)
data_attributes = { container: 'body' }
has_tooltip = options[:has_tooltip].nil? ? true : options[:has_tooltip]
data_attributes = {}
css_class = %W[avatar s#{avatar_size}].push(*options[:css_class])
if has_tooltip
css_class.push('has-tooltip')
data_attributes = { container: 'body' }
end
image_tag(
avatar_url,
class: %W[avatar has-tooltip s#{avatar_size}].push(*options[:css_class]),
class: css_class,
alt: "#{user_name}'s avatar",
title: user_name,
data: data_attributes,

View file

@ -114,7 +114,7 @@ module CommitsHelper
end
def commit_signature_badge_classes(additional_classes)
%w(btn status-box gpg-status-box) + Array(additional_classes)
%w(btn gpg-status-box) + Array(additional_classes)
end
protected

View file

@ -181,6 +181,7 @@ module EventsHelper
end
def event_commit_title(message)
message ||= ''
(message.split("\n").first || "").truncate(70)
rescue
"--broken encoding"

View file

@ -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

View file

@ -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

View file

@ -406,7 +406,7 @@ class Event < ActiveRecord::Base
def body?
if push?
push_with_commits? || rm_ref?
push_with_commits?
elsif note?
true
else

View file

@ -50,7 +50,10 @@ class Issue < ActiveRecord::Base
scope :preload_associations, -> { preload(:labels, project: :namespace) }
scope :public_only, -> { where(confidential: false) }
after_save :expire_etag_cache
after_commit :update_project_counter_caches, on: :destroy
attr_spammable :title, spam_title: true
attr_spammable :description, spam_description: true
@ -266,6 +269,10 @@ class Issue < ActiveRecord::Base
end
end
def update_project_counter_caches
Projects::OpenIssuesCountService.new(project).refresh_cache
end
private
# Returns `true` if the given User can read the current Issue.

View file

@ -31,6 +31,7 @@ class MergeRequest < ActiveRecord::Base
after_create :ensure_merge_request_diff, unless: :importing?
after_update :reload_diff_if_branch_changed
after_commit :update_project_counter_caches, on: :destroy
# When this attribute is true some MR validation is ignored
# It allows us to close or modify broken merge requests
@ -936,6 +937,10 @@ class MergeRequest < ActiveRecord::Base
true
end
def update_project_counter_caches
Projects::OpenMergeRequestsCountService.new(target_project).refresh_cache
end
private
def write_ref

View file

@ -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
add_authentication_token_field :runners_token
before_save :ensure_runners_token
after_save :update_project_statistics, if: :namespace_id_changed?
# set last_activity_at to the same as created_at
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,12 +999,25 @@ 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,
description: description,
web_url: web_url,
avatar_url: avatar_url,
avatar_url: avatar_url(only_path: false),
git_ssh_url: ssh_url_to_repo,
git_http_url: http_url_to_repo,
namespace: namespace.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
@ -1158,7 +1167,11 @@ class Project < ActiveRecord::Base
end
def open_issues_count
issues.opened.count
Projects::OpenIssuesCountService.new(self).count
end
def open_merge_requests_count
Projects::OpenMergeRequestsCountService.new(self).count
end
def visibility_level_allowed_as_fork?(level = self.visibility_level)
@ -1213,7 +1226,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 +1266,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 +1468,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 +1481,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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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 dont have permission to create a subgroup in this group.')
return @group
end

View file

@ -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|

View file

@ -0,0 +1,45 @@
module Groups
class NestedCreateService < Groups::BaseService
attr_reader :group_path
def initialize(user, params)
@current_user, @params = user, params.dup
@group_path = @params.delete(:group_path)
end
def execute
return nil unless group_path
if group = Group.find_by_full_path(group_path)
return group
end
create_group_path
end
private
def create_group_path
group_path_segments = group_path.split('/')
last_group = nil
partial_path_segments = []
while subgroup_name = group_path_segments.shift
partial_path_segments << subgroup_name
partial_path = partial_path_segments.join('/')
new_params = params.reverse_merge(
path: subgroup_name,
name: subgroup_name,
parent: last_group
)
new_params[:visibility_level] ||= Gitlab::CurrentSettings.current_application_settings.default_group_visibility
last_group = Group.find_by_full_path(partial_path) || Groups::CreateService.new(current_user, new_params).execute
end
last_group
end
end
end

View file

@ -192,6 +192,8 @@ class IssuableBaseService < BaseService
def after_create(issuable)
# To be overridden by subclasses
issuable.update_project_counter_caches
end
def before_update(issuable)
@ -200,6 +202,8 @@ class IssuableBaseService < BaseService
def after_update(issuable)
# To be overridden by subclasses
issuable.update_project_counter_caches
end
def update(issuable)

View file

@ -27,6 +27,8 @@ module Issues
todo_service.new_issue(issuable, current_user)
user_agent_detail_service.create
resolve_discussions_with_issue(issuable)
super
end
def resolve_discussions_with_issue(issue)

View file

@ -28,6 +28,8 @@ module MergeRequests
todo_service.new_merge_request(issuable, current_user)
issuable.cache_merge_request_closes_issues!(current_user)
update_merge_requests_head_pipeline(issuable)
super
end
private

View file

@ -0,0 +1,43 @@
module Projects
# Base class for the various service classes that count project data (e.g.
# issues or forks).
class CountService
def initialize(project)
@project = project
end
def relation_for_count
raise(
NotImplementedError,
'"relation_for_count" must be implemented and return an ActiveRecord::Relation'
)
end
def count
Rails.cache.fetch(cache_key) { uncached_count }
end
def refresh_cache
Rails.cache.write(cache_key, uncached_count)
end
def uncached_count
relation_for_count.count
end
def delete_cache
Rails.cache.delete(cache_key)
end
def cache_key_name
raise(
NotImplementedError,
'"cache_key_name" must be implemented and return a String'
)
end
def cache_key
['projects', @project.id, cache_key_name]
end
end
end

View file

@ -1,30 +1,12 @@
module Projects
# Service class for getting and caching the number of forks of a project.
class ForksCountService
def initialize(project)
@project = project
class ForksCountService < CountService
def relation_for_count
@project.forks
end
def count
Rails.cache.fetch(cache_key) { uncached_count }
end
def refresh_cache
Rails.cache.write(cache_key, uncached_count)
end
def delete_cache
Rails.cache.delete(cache_key)
end
private
def uncached_count
@project.forks.count
end
def cache_key
['projects', @project.id, 'forks_count']
def cache_key_name
'forks_count'
end
end
end

View file

@ -9,7 +9,8 @@ module Projects
class HousekeepingService < BaseService
include Gitlab::CurrentSettings
LEASE_TIMEOUT = 3600
# Timeout set to 24h
LEASE_TIMEOUT = 86400
class LeaseTaken < StandardError
def to_s

View file

@ -0,0 +1,15 @@
module Projects
# Service class for counting and caching the number of open issues of a
# project.
class OpenIssuesCountService < CountService
def relation_for_count
# We don't include confidential issues in this number since this would
# expose the number of confidential issues to non project members.
@project.issues.opened.public_only
end
def cache_key_name
'open_issues_count'
end
end
end

View file

@ -0,0 +1,13 @@
module Projects
# Service class for counting and caching the number of open merge requests of
# a project.
class OpenMergeRequestsCountService < CountService
def relation_for_count
@project.merge_requests.opened
end
def cache_key_name
'open_merge_requests_count'
end
end
end

View file

@ -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!

View file

@ -492,6 +492,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
@ -501,6 +511,7 @@
= succeed "." do
= link_to "repository storages documentation", help_page_path("administration/repository_storages")
%fieldset
%legend Repository Checks
.form-group

View file

@ -1,25 +1,21 @@
- @no_container = true
- page_title "Logs"
- loggers = [Gitlab::GitLogger, Gitlab::AppLogger,
Gitlab::EnvironmentLogger, Gitlab::SidekiqLogger,
Gitlab::RepositoryCheckLogger]
= render 'admin/monitoring/head'
%div{ class: container_class }
%ul.nav-links.log-tabs
- loggers.each do |klass|
%li{ class: active_when(klass == Gitlab::GitLogger) }>
= link_to klass::file_name, "##{klass::file_name_noext}",
'data-toggle' => 'tab'
- @loggers.each do |klass|
%li{ class: active_when(klass == @loggers.first) }>
= link_to klass.file_name, "##{klass.file_name_noext}", data: { toggle: 'tab' }
.row-content-block
To prevent performance issues admin logs output the last 2000 lines
.tab-content
- loggers.each do |klass|
.tab-pane{ class: active_when(klass == Gitlab::GitLogger), id: klass::file_name_noext }
- @loggers.each do |klass|
.tab-pane{ class: active_when(klass == @loggers.first), id: klass.file_name_noext }
.file-holder#README
.js-file-title.file-title
%i.fa.fa-file
= klass::file_name
= klass.file_name
.pull-right
= link_to '#', class: 'log-bottom' do
%i.fa.fa-arrow-down

View file

@ -5,9 +5,10 @@
%i
at
= event.created_at.to_s(:short)
%blockquote= markdown(escape_once(event.commit_title), pipeline: :atom, project: event.project, author: event.author)
- if event.commits_count > 1
%p
%i
\... and
= pluralize(event.commits_count - 1, "more commit")
- unless event.rm_ref?
%blockquote= markdown(escape_once(event.commit_title), pipeline: :atom, project: event.project, author: event.author)
- if event.commits_count > 1
%p
%i
\... and
= pluralize(event.commits_count - 1, "more commit")

View file

@ -41,7 +41,3 @@
%li.commits-stat
= link_to create_mr_path(project.default_branch, event.ref_name, project) do
Create Merge Request
- elsif event.rm_ref?
.event-body
%ul.well-list.event_commits
= render "events/commit", project: project, event: event

View file

@ -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: ''

View file

@ -86,7 +86,8 @@
%span.nav-item-name
Issues
- if @project.issues_enabled?
%span.badge.count.issue_counter= number_with_delimiter(IssuesFinder.new(current_user, project_id: @project.id).execute.opened.count)
%span.badge.count.issue_counter
= number_with_delimiter(@project.open_issues_count)
%ul.sidebar-sub-level-items
= nav_link(controller: :issues) do
@ -116,7 +117,8 @@
= custom_icon('mr_bold')
%span.nav-item-name
Merge Requests
%span.badge.count.merge_counter.js-merge-counter= number_with_delimiter(MergeRequestsFinder.new(current_user, project_id: @project.id).execute.opened.count)
%span.badge.count.merge_counter.js-merge-counter
= number_with_delimiter(@project.open_merge_requests_count)
- if project_nav_tab? :pipelines
= nav_link(controller: [:pipelines, :builds, :jobs, :pipeline_schedules, :environments, :artifacts]) do

View file

@ -28,7 +28,8 @@
%span
Issues
- if @project.issues_enabled?
%span.badge.count.issue_counter= number_with_delimiter(issuables_count_for_state(:issues, :opened, finder: IssuesFinder.new(current_user, project_id: @project.id)))
%span.badge.count.issue_counter
= number_with_delimiter(@project.open_issues_count)
- if project_nav_tab? :merge_requests
- controllers = [:merge_requests, 'projects/merge_requests/conflicts']
@ -37,7 +38,8 @@
= link_to project_merge_requests_path(@project), title: 'Merge Requests', class: 'shortcuts-merge_requests' do
%span
Merge Requests
%span.badge.count.merge_counter.js-merge-counter= number_with_delimiter(issuables_count_for_state(:merge_requests, :opened, finder: MergeRequestsFinder.new(current_user, project_id: @project.id)))
%span.badge.count.merge_counter.js-merge-counter
= number_with_delimiter(@project.open_merge_requests_count)
- if project_nav_tab? :pipelines
= nav_link(controller: [:pipelines, :builds, :environments, :artifacts]) do

View file

@ -1,6 +1,6 @@
.project-templates-buttons.import-buttons{ data: { toggle: "buttons" } }
.btn.blank-option.active
%input{ type: "radio", autocomplete: "off", name: "project_templates", id: "blank", checked: "true" }
%input{ type: "radio", autocomplete: "off", name: "project[template_name]", id: "blank", checked: "true", value: "" }
= icon('file-o', class: 'btn-template-icon')
Blank
- Gitlab::ProjectTemplate.all.each do |template|

View file

@ -37,14 +37,14 @@
.commit-actions.hidden-xs
- if commit.status(ref)
= render_commit_status(commit, ref: ref)
- if request.xhr?
= render partial: 'projects/commit/signature', object: commit.signature
- else
= render partial: 'projects/commit/ajax_signature', locals: { commit: commit }
- if commit.status(ref)
= render_commit_status(commit, ref: ref)
= link_to commit.short_id, project_commit_path(project, commit), class: "commit-sha btn btn-transparent"
= clipboard_button(text: commit.id, title: _("Copy commit SHA to clipboard"))
= link_to_browse_code(project, commit)

View file

@ -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

View file

@ -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

View file

@ -1 +1,2 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 14 14"><g fill-rule="evenodd"><path fill-rule="nonzero" d="m0 7c0-3.866 3.142-7 7-7 3.866 0 7 3.142 7 7 0 3.866-3.142 7-7 7-3.866 0-7-3.142-7-7m1 0c0 3.309 2.69 6 6 6 3.309 0 6-2.69 6-6 0-3.309-2.69-6-6-6-3.309 0-6 2.69-6 6"/><path d="m7 6h-2.702c-.154 0-.298.132-.298.295v1.41c0 .164.133.295.298.295h2.702v1.694c0 .18.095.209.213.09l2.539-2.568c.115-.116.118-.312 0-.432l-2.539-2.568c-.115-.116-.213-.079-.213.09v1.694"/></g></svg>
<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m9 6h-7a2 2 0 1 0 0 4h7v2.586a1 1 0 0 0 1.707.707l4.586-4.586a1 1 0 0 0 0-1.414l-4.586-4.586a1 1 0 0 0 -1.707.707z" fill-rule="evenodd"/></svg>

Before

Width:  |  Height:  |  Size: 486 B

After

Width:  |  Height:  |  Size: 237 B

View file

@ -1 +1,2 @@
<svg width="1792" height="1792" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path d="M1472 930v318q0 119-84.5 203.5t-203.5 84.5h-832q-119 0-203.5-84.5t-84.5-203.5v-832q0-119 84.5-203.5t203.5-84.5h832q63 0 117 25 15 7 18 23 3 17-9 29l-49 49q-10 10-23 10-3 0-9-2-23-6-45-6h-832q-66 0-113 47t-47 113v832q0 66 47 113t113 47h832q66 0 113-47t47-113v-254q0-13 9-22l64-64q10-10 23-10 6 0 12 3 20 8 20 29zm231-489l-814 814q-24 24-57 24t-57-24l-430-430q-24-24-24-57t24-57l110-110q24-24 57-24t57 24l263 263 647-647q24-24 57-24t57 24l110 110q24 24 24 57t-24 57z"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path d="M7.536 8.657l2.828-2.829a1 1 0 0 1 1.414 1.415l-3.535 3.535a.997.997 0 0 1-1.415 0l-2.12-2.121A1 1 0 0 1 6.12 7.243l1.415 1.414zM3 0h10a3 3 0 0 1 3 3v10a3 3 0 0 1-3 3H3a3 3 0 0 1-3-3V3a3 3 0 0 1 3-3zm0 2a1 1 0 0 0-1 1v10a1 1 0 0 0 1 1h10a1 1 0 0 0 1-1V3a1 1 0 0 0-1-1H3z"/></svg>

Before

Width:  |  Height:  |  Size: 574 B

After

Width:  |  Height:  |  Size: 373 B

View file

@ -1 +1 @@
<svg width="1792" height="1792" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path d="M1024 544v448q0 14-9 23t-23 9h-320q-14 0-23-9t-9-23v-64q0-14 9-23t23-9h224v-352q0-14 9-23t23-9h64q14 0 23 9t9 23zm416 352q0-148-73-273t-198-198-273-73-273 73-198 198-73 273 73 273 198 198 273 73 273-73 198-198 73-273zm224 0q0 209-103 385.5t-279.5 279.5-385.5 103-385.5-103-279.5-279.5-103-385.5 103-385.5 279.5-279.5 385.5-103 385.5 103 279.5 279.5 103 385.5z"/></svg>
<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M9 7h1c.552 0 1 .448 1 1s-.448 1-1 1H8c-.276 0-.526-.112-.707-.293S7 8.277 7 8V5c0-.552.448-1 1-1s1 .448 1 1zm-1 9c-4.418 0-8-3.582-8-8s3.582-8 8-8 8 3.582 8 8-3.582 8-8 8zm0-2c3.314 0 6-2.686 6-6s-2.686-6-6-6-6 2.686-6 6 2.686 6 6 6z"/></svg>

Before

Width:  |  Height:  |  Size: 469 B

After

Width:  |  Height:  |  Size: 336 B

View file

@ -1,3 +1,2 @@
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="14" height="14" viewBox="0 0 14 14">
<path d="M13 12.75v-8.5q0-0.102-0.074-0.176t-0.176-0.074h-8.5q-0.102 0-0.176 0.074t-0.074 0.176v8.5q0 0.102 0.074 0.176t0.176 0.074h8.5q0.102 0 0.176-0.074t0.074-0.176zM14 4.25v8.5q0 0.516-0.367 0.883t-0.883 0.367h-8.5q-0.516 0-0.883-0.367t-0.367-0.883v-8.5q0-0.516 0.367-0.883t0.883-0.367h8.5q0.516 0 0.883 0.367t0.367 0.883zM11 1.25v1.25h-1v-1.25q0-0.102-0.074-0.176t-0.176-0.074h-8.5q-0.102 0-0.176 0.074t-0.074 0.176v8.5q0 0.102 0.074 0.176t0.176 0.074h1.25v1h-1.25q-0.516 0-0.883-0.367t-0.367-0.883v-8.5q0-0.516 0.367-0.883t0.883-0.367h8.5q0.516 0 0.883 0.367t0.367 0.883z"></path>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path d="M10.874 2H12a3 3 0 0 1 3 3v8a3 3 0 0 1-3 3h-2c-.918 0-1.74-.413-2.29-1.063a3.987 3.987 0 0 0 1.988-.984A1 1 0 0 0 10 14h2a1 1 0 0 0 1-1V5a1 1 0 0 0-1-1h-1V3c0-.345-.044-.68-.126-1zM4 0h3a3 3 0 0 1 3 3v8a3 3 0 0 1-3 3H4a3 3 0 0 1-3-3V3a3 3 0 0 1 3-3zm0 2a1 1 0 0 0-1 1v8a1 1 0 0 0 1 1h3a1 1 0 0 0 1-1V3a1 1 0 0 0-1-1H4z"/></svg>

Before

Width:  |  Height:  |  Size: 735 B

After

Width:  |  Height:  |  Size: 421 B

View file

@ -1 +1,2 @@
<svg width="1792" height="1792" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path d="M672 1472q0-40-28-68t-68-28-68 28-28 68 28 68 68 28 68-28 28-68zm0-1152q0-40-28-68t-68-28-68 28-28 68 28 68 68 28 68-28 28-68zm640 128q0-40-28-68t-68-28-68 28-28 68 28 68 68 28 68-28 28-68zm96 0q0 52-26 96.5t-70 69.5q-2 287-226 414-68 38-203 81-128 40-169.5 71t-41.5 100v26q44 25 70 69.5t26 96.5q0 80-56 136t-136 56-136-56-56-136q0-52 26-96.5t70-69.5v-820q-44-25-70-69.5t-26-96.5q0-80 56-136t136-56 136 56 56 136q0 52-26 96.5t-70 69.5v497q54-26 154-57 55-17 87.5-29.5t70.5-31 59-39.5 40.5-51 28-69.5 8.5-91.5q-44-25-70-69.5t-26-96.5q0-80 56-136t136-56 136 56 56 136z"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path d="M6 11.978v.29a2 2 0 1 1-2 0V3.732a2 2 0 1 1 2 0v3.849c.592-.491 1.31-.854 2.15-1.081 1.308-.353 1.875-.882 1.893-1.743a2 2 0 1 1 2.002-.051C12.053 6.54 10.857 7.84 8.67 8.43 7.056 8.867 6.195 9.98 6 11.978zM5 3a1 1 0 1 0 0-2 1 1 0 0 0 0 2zm6 1a1 1 0 1 0 0-2 1 1 0 0 0 0 2zM5 15a1 1 0 1 0 0-2 1 1 0 0 0 0 2z"/></svg>

Before

Width:  |  Height:  |  Size: 676 B

After

Width:  |  Height:  |  Size: 409 B

View file

@ -1 +1,2 @@
<svg width="1792" height="1792" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path d="M896 384q-204 0-381.5 69.5t-282 187.5-104.5 255q0 112 71.5 213.5t201.5 175.5l87 50-27 96q-24 91-70 172 152-63 275-171l43-38 57 6q69 8 130 8 204 0 381.5-69.5t282-187.5 104.5-255-104.5-255-282-187.5-381.5-69.5zm896 512q0 174-120 321.5t-326 233-450 85.5q-70 0-145-8-198 175-460 242-49 14-114 22h-5q-15 0-27-10.5t-16-27.5v-1q-3-4-.5-12t2-10 4.5-9.5l6-9 7-8.5 8-9q7-8 31-34.5t34.5-38 31-39.5 32.5-51 27-59 26-76q-157-89-247.5-220t-90.5-281q0-174 120-321.5t326-233 450-85.5 450 85.5 326 233 120 321.5z"/></svg>
<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1.707 15.707c-.63.63-1.707.184-1.707-.707v-12a3 3 0 0 1 3-3h10a3 3 0 0 1 3 3v6a3 3 0 0 1 -3 3h-7.586zm.293-3.121 2.293-2.293a1 1 0 0 1 .707-.293h8a1 1 0 0 0 1-1v-6a1 1 0 0 0 -1-1h-10a1 1 0 0 0 -1 1z"/></svg>

Before

Width:  |  Height:  |  Size: 605 B

After

Width:  |  Height:  |  Size: 303 B

View file

@ -1 +1,2 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 18" enable-background="new 0 0 36 18"><path d="m34 7h-7.2c-.9-4-4.5-7-8.8-7s-7.9 3-8.8 7h-7.2c-1.1 0-2 .9-2 2 0 1.1.9 2 2 2h7.2c.9 4 4.5 7 8.8 7s7.9-3 8.8-7h7.2c1.1 0 2-.9 2-2 0-1.1-.9-2-2-2m-16 7c-2.8 0-5-2.2-5-5s2.2-5 5-5 5 2.2 5 5-2.2 5-5 5"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path d="M8 10a2 2 0 1 0 0-4 2 2 0 0 0 0 4zm3.876-1.008a4.002 4.002 0 0 1-7.752 0A1.01 1.01 0 0 1 4 9H1a1 1 0 1 1 0-2h3c.042 0 .083.003.124.008a4.002 4.002 0 0 1 7.752 0A1.01 1.01 0 0 1 12 7h3a1 1 0 0 1 0 2h-3a1.01 1.01 0 0 1-.124-.008z"/></svg>

Before

Width:  |  Height:  |  Size: 309 B

After

Width:  |  Height:  |  Size: 330 B

View file

@ -1 +1,2 @@
<svg width="1792" height="1792" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path d="M888 1184l116-116-152-152-116 116v56h96v96h56zm440-720q-16-16-33 1l-350 350q-17 17-1 33t33-1l350-350q17-17 1-33zm80 594v190q0 119-84.5 203.5t-203.5 84.5h-832q-119 0-203.5-84.5t-84.5-203.5v-832q0-119 84.5-203.5t203.5-84.5h832q63 0 117 25 15 7 18 23 3 17-9 29l-49 49q-14 14-32 8-23-6-45-6h-832q-66 0-113 47t-47 113v832q0 66 47 113t113 47h832q66 0 113-47t47-113v-126q0-13 9-22l64-64q15-15 35-7t20 29zm-96-738l288 288-672 672h-288v-288zm444 132l-92 92-288-288 92-92q28-28 68-28t68 28l152 152q28 28 28 68t-28 68z"/></svg>
<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m13.436 1.413 1.415 1.414a1 1 0 0 1 0 1.414l-10.316 10.315a1 1 0 0 1 -.703.293l-2.407.008-.008-2.421a1 1 0 0 1 .293-.71l10.312-10.314a1 1 0 0 1 1.414 0zm-9.608 12.436 10.315-10.315-1.413-1.414-10.313 10.312.005 1.422zm7.486-10.313 1.414 1.414-7.778 7.778-1.407.007-.007-1.421zm1.414-1.415 1.414 1.415-.707.707-1.414-1.415z"/></svg>

Before

Width:  |  Height:  |  Size: 617 B

After

Width:  |  Height:  |  Size: 426 B

View file

@ -1 +1,2 @@
<svg width="1792" height="1792" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path d="M1664 960q-152-236-381-353 61 104 61 225 0 185-131.5 316.5t-316.5 131.5-316.5-131.5-131.5-316.5q0-121 61-225-229 117-381 353 133 205 333.5 326.5t434.5 121.5 434.5-121.5 333.5-326.5zm-720-384q0-20-14-34t-34-14q-125 0-214.5 89.5t-89.5 214.5q0 20 14 34t34 14 34-14 14-34q0-86 61-147t147-61q20 0 34-14t14-34zm848 384q0 34-20 69-140 230-376.5 368.5t-499.5 138.5-499.5-139-376.5-368q-20-35-20-69t20-69q140-229 376.5-368t499.5-139 499.5 139 376.5 368q20 35 20 69z"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path d="M8 14C4.816 14 2.253 12.284.393 8.981a2 2 0 0 1 0-1.962C2.253 3.716 4.816 2 8 2s5.747 1.716 7.607 5.019a2 2 0 0 1 0 1.962C13.747 12.284 11.184 14 8 14zm0-2c2.41 0 4.338-1.29 5.864-4C12.338 5.29 10.411 4 8 4 5.59 4 3.662 5.29 2.136 8 3.662 10.71 5.589 12 8 12zm0-1a3 3 0 1 1 0-6 3 3 0 0 1 0 6zm1-3a1 1 0 1 0 0-2 1 1 0 0 0 0 2z"/></svg>

Before

Width:  |  Height:  |  Size: 566 B

After

Width:  |  Height:  |  Size: 428 B

View file

@ -1 +1,2 @@
<svg width="1792" height="1792" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path d="M555 1335l78-141q-87-63-136-159t-49-203q0-121 61-225-229 117-381 353 167 258 427 375zm389-759q0-20-14-34t-34-14q-125 0-214.5 89.5t-89.5 214.5q0 20 14 34t34 14 34-14 14-34q0-86 61-147t147-61q20 0 34-14t14-34zm363-191q0 7-1 9-105 188-315 566t-316 567l-49 89q-10 16-28 16-12 0-134-70-16-10-16-28 0-12 44-87-143-65-263.5-173t-208.5-245q-20-31-20-69t20-69q153-235 380-371t496-136q89 0 180 17l54-97q10-16 28-16 5 0 18 6t31 15.5 33 18.5 31.5 18.5 19.5 11.5q16 10 16 27zm37 447q0 139-79 253.5t-209 164.5l280-502q8 45 8 84zm448 128q0 35-20 69-39 64-109 145-150 172-347.5 267t-419.5 95l74-132q212-18 392.5-137t301.5-307q-115-179-282-294l63-112q95 64 182.5 153t144.5 184q20 34 20 69z"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path d="M13.618 2.62L1.62 14.619a1 1 0 0 1-.985-1.668l1.525-1.526C1.516 10.742.926 9.927.393 8.981a2 2 0 0 1 0-1.962C2.253 3.716 4.816 2 8 2c1.074 0 2.076.195 3.006.58l.944-.944a1 1 0 0 1 1.668.985zM8.068 11a3 3 0 0 0 2.931-2.932l-2.931 2.931zm-3.02-2.462a3 3 0 0 1 3.49-3.49l.884-.884A6.044 6.044 0 0 0 8 4C5.59 4 3.662 5.29 2.136 8c.445.79.924 1.46 1.439 2.011l1.473-1.473zm.421 5.06l1.658-1.658c.283.04.575.06.873.06 2.41 0 4.338-1.29 5.864-4a11.023 11.023 0 0 0-1.133-1.664l1.418-1.418a12.799 12.799 0 0 1 1.458 2.1 2 2 0 0 1 0 1.963C13.747 12.284 11.184 14 8 14a7.883 7.883 0 0 1-2.53-.402z"/></svg>

Before

Width:  |  Height:  |  Size: 782 B

After

Width:  |  Height:  |  Size: 690 B

View file

@ -1 +1,2 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path d="m2 3c.552 0 1-.448 1-1 0-.552-.448-1-1-1-.552 0-1 .448-1 1 0 .552.448 1 1 1m.761.85c.154 2.556 1.987 4.692 4.45 5.255.328-.655 1.01-1.105 1.789-1.105 1.105 0 2 .895 2 2 0 1.105-.895 2-2 2-.89 0-1.645-.582-1.904-1.386-1.916-.376-3.548-1.5-4.596-3.044v4.493c.863.222 1.5 1.01 1.5 1.937 0 1.105-.895 2-2 2-1.105 0-2-.895-2-2 0-.74.402-1.387 1-1.732v-8.535c-.598-.346-1-.992-1-1.732 0-1.105.895-2 2-2 1.105 0 2 .895 2 2 0 .835-.512 1.551-1.239 1.85m6.239 7.15c.552 0 1-.448 1-1 0-.552-.448-1-1-1-.552 0-1 .448-1 1 0 .552.448 1 1 1m-7 4c.552 0 1-.448 1-1 0-.552-.448-1-1-1-.552 0-1 .448-1 1 0 .552.448 1 1 1" transform="translate(3)"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path d="M11 12.268V5a1 1 0 0 0-1-1v1a.5.5 0 0 1-.8.4l-2.667-2a.5.5 0 0 1 0-.8L9.2.6a.5.5 0 0 1 .8.4v1a3 3 0 0 1 3 3v7.268a2 2 0 1 1-2 0zm-6 0a2 2 0 1 1-2 0V4.732a2 2 0 1 1 2 0v7.536zM4 4a1 1 0 1 0 0-2 1 1 0 0 0 0 2zm0 11a1 1 0 1 0 0-2 1 1 0 0 0 0 2zm8 0a1 1 0 1 0 0-2 1 1 0 0 0 0 2z"/></svg>

Before

Width:  |  Height:  |  Size: 706 B

After

Width:  |  Height:  |  Size: 377 B

View file

@ -1 +1,2 @@
<svg width="1792" height="1792" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path d="M491 1536l91-91-235-235-91 91v107h128v128h107zm523-928q0-22-22-22-10 0-17 7l-542 542q-7 7-7 17 0 22 22 22 10 0 17-7l542-542q7-7 7-17zm-54-192l416 416-832 832h-416v-416zm683 96q0 53-37 90l-166 166-416-416 166-165q36-38 90-38 53 0 91 38l235 234q37 39 37 91z"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path d="M13.02 1.293l1.414 1.414a1 1 0 0 1 0 1.414L4.119 14.436a1 1 0 0 1-.704.293l-2.407.008L1 12.316a1 1 0 0 1 .293-.71L11.605 1.292a1 1 0 0 1 1.414 0zm-1.416 1.415l-.707.707L12.31 4.83l.707-.707-1.414-1.415zM3.411 13.73l1.123-1.122H3.12v-1.415L2 12.312l.005 1.422 1.406-.005z"/></svg>

Before

Width:  |  Height:  |  Size: 365 B

After

Width:  |  Height:  |  Size: 373 B

View file

@ -1 +1,2 @@
<svg width="1792" height="1792" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path d="M666 481q-60 92-137 273-22-45-37-72.5t-40.5-63.5-51-56.5-63-35-81.5-14.5h-224q-14 0-23-9t-9-23v-192q0-14 9-23t23-9h224q250 0 410 225zm1126 799q0 14-9 23l-320 320q-9 9-23 9-13 0-22.5-9.5t-9.5-22.5v-192q-32 0-85 .5t-81 1-73-1-71-5-64-10.5-63-18.5-58-28.5-59-40-55-53.5-56-69.5q59-93 136-273 22 45 37 72.5t40.5 63.5 51 56.5 63 35 81.5 14.5h256v-192q0-14 9-23t23-9q12 0 24 10l319 319q9 9 9 23zm0-896q0 14-9 23l-320 320q-9 9-23 9-13 0-22.5-9.5t-9.5-22.5v-192h-256q-48 0-87 15t-69 45-51 61.5-45 77.5q-32 62-78 171-29 66-49.5 111t-54 105-64 100-74 83-90 68.5-106.5 42-128 16.5h-224q-14 0-23-9t-9-23v-192q0-14 9-23t23-9h224q48 0 87-15t69-45 51-61.5 45-77.5q32-62 78-171 29-66 49.5-111t54-105 64-100 74-83 90-68.5 106.5-42 128-16.5h256v-192q0-14 9-23t23-9q12 0 24 10l319 319q9 9 9 23z"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path d="M1.707 15.707C1.077 16.337 0 15.891 0 15V3a3 3 0 0 1 3-3h10a3 3 0 0 1 3 3v6a3 3 0 0 1-3 3H5.414l-3.707 3.707zM2 12.586l2.293-2.293A1 1 0 0 1 5 10h8a1 1 0 0 0 1-1V3a1 1 0 0 0-1-1H3a1 1 0 0 0-1 1v9.586zM5 7a1 1 0 1 1 0-2 1 1 0 0 1 0 2zm3 0a1 1 0 1 1 0-2 1 1 0 0 1 0 2zm3 0a1 1 0 1 1 0-2 1 1 0 0 1 0 2z"/></svg>

Before

Width:  |  Height:  |  Size: 885 B

After

Width:  |  Height:  |  Size: 402 B

View file

@ -1 +1 @@
<svg width="14" height="14" viewBox="0 0 14 14" xmlns="http://www.w3.org/2000/svg"><path d="M0 7c0-3.866 3.142-7 7-7 3.866 0 7 3.142 7 7 0 3.866-3.142 7-7 7-3.866 0-7-3.142-7-7z"/><path d="M1 7c0 3.309 2.69 6 6 6 3.309 0 6-2.69 6-6 0-3.309-2.69-6-6-6-3.309 0-6 2.69-6 6z" fill="#FFF"/><rect x="3.36" y="6.16" width="7.28" height="1.68" rx=".84"/></svg>
<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M7.536 8.657l2.828-2.83c.39-.39 1.024-.39 1.414 0 .39.392.39 1.025 0 1.416l-3.535 3.535c-.196.195-.452.293-.707.293-.256 0-.512-.097-.708-.292l-2.12-2.12c-.39-.392-.39-1.025 0-1.415s1.023-.39 1.413 0zM8 16c-4.418 0-8-3.582-8-8s3.582-8 8-8 8 3.582 8 8-3.582 8-8 8zm0-2c3.314 0 6-2.686 6-6s-2.686-6-6-6-6 2.686-6 6 2.686 6 6 6z"/></svg>

Before

Width:  |  Height:  |  Size: 353 B

After

Width:  |  Height:  |  Size: 427 B

View file

@ -1 +1,2 @@
<svg width="1792" height="1792" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path d="M384 448q0-53-37.5-90.5t-90.5-37.5-90.5 37.5-37.5 90.5 37.5 90.5 90.5 37.5 90.5-37.5 37.5-90.5zm1067 576q0 53-37 90l-491 492q-39 37-91 37-53 0-90-37l-715-716q-38-37-64.5-101t-26.5-117v-416q0-52 38-90t90-38h416q53 0 117 26.5t102 64.5l715 714q37 39 37 91zm384 0q0 53-37 90l-491 492q-39 37-91 37-36 0-59-14t-53-45l470-470q37-37 37-90 0-52-37-91l-715-714q-38-38-102-64.5t-117-26.5h224q53 0 117 26.5t102 64.5l715 714q37 39 37 91z"/></svg>
<svg viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="m7.222.222c1.657 0 3 1.343 3 3v8.327c0 .631-.298 1.226-.805 1.603l-3 2.237c-.709.529-1.682.529-2.391 0l-3-2.237c-.506-.377-.805-.972-.805-1.603v-8.327c0-1.657 1.343-3 3-3h4m-5 3v8.08c0 .158.075.306.201.401l2.5 1.864c.177.132.42.132.598 0l2.5-1.864c.127-.094.201-.243.201-.401v-8.08c0-.552-.448-1-1-1h-4c-.552 0-1 .448-1 1m2.778 7.778c-.552 0-1-.448-1-1s .448-1 1-1 1 .448 1 1-.448 1-1 1" transform="matrix(-.70711 .70711 -.70711 -.70711 17.05 9.767)"/></svg>

Before

Width:  |  Height:  |  Size: 534 B

After

Width:  |  Height:  |  Size: 529 B

View file

@ -1 +1 @@
<svg width="1792" height="1792" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path d="M1600 1405q0 120-73 189.5t-194 69.5h-874q-121 0-194-69.5t-73-189.5q0-53 3.5-103.5t14-109 26.5-108.5 43-97.5 62-81 85.5-53.5 111.5-20q9 0 42 21.5t74.5 48 108 48 133.5 21.5 133.5-21.5 108-48 74.5-48 42-21.5q61 0 111.5 20t85.5 53.5 62 81 43 97.5 26.5 108.5 14 109 3.5 103.5zm-320-893q0 159-112.5 271.5t-271.5 112.5-271.5-112.5-112.5-271.5 112.5-271.5 271.5-112.5 271.5 112.5 112.5 271.5z"/></svg>
<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M8 7C6.343 7 5 5.657 5 4s1.343-3 3-3 3 1.343 3 3-1.343 3-3 3zm0 8c-6.888 0-6.976-.78-6.976-2.52S2.144 8 8 8s6.976 2.692 6.976 4.48S14.888 15 8 15z" fill-rule="evenodd"/></svg>

Before

Width:  |  Height:  |  Size: 494 B

After

Width:  |  Height:  |  Size: 268 B

View file

@ -4,7 +4,7 @@
%li.filter-dropdown-item{ class: ('js-current-user' if user == current_user) }
%button.btn.btn-link.dropdown-user{ type: :button }
.avatar-container.s40
= user_avatar_without_link(user: user, lazy: avatar[:lazy], url: avatar[:url], size: 40).gsub('/images/{{avatar_url}}','{{avatar_url}}').html_safe
= user_avatar_without_link(user: user, lazy: avatar[:lazy], url: avatar[:url], size: 40, has_tooltip: false).gsub('/images/{{avatar_url}}','{{avatar_url}}').html_safe
.dropdown-user-details
%span
= user.name

View file

@ -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

View file

@ -18,7 +18,8 @@ class NamespacelessProjectDestroyWorker
rescue ActiveRecord::RecordNotFound
return
end
return unless project.namespace_id.nil? # Reject doing anything for projects that *do* have a namespace
return if project.namespace # Reject doing anything for projects that *do* have a namespace
project.team.truncate

View file

@ -1,4 +0,0 @@
---
title: "Insert user name directly without encoding"
merge_request: 10085
author: Nathan Neulinger <nneul@neulinger.org>

View file

@ -1,4 +0,0 @@
---
title: Expose target_iid in Events API
merge_request: 13247
author: sue445

View file

@ -1,4 +0,0 @@
---
title: Expose noteable_iid in Note
merge_request: 13265
author: sue445

View file

@ -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

View file

@ -1,4 +0,0 @@
---
title: Remove Inactive Personal Access Tokens list from Access Tokens page
merge_request: 12866
author:

View file

@ -1,4 +0,0 @@
---
title: Add coordinator url to admin area runner page
merge_request: 11603
author:

View file

@ -1,4 +0,0 @@
---
title: Declare related resources into V4 API entities
merge_request:
author:

View file

@ -1,4 +0,0 @@
---
title: Replaces dashboard/event_filters.feature spinach with rspec
merge_request: 12651
author: Alexander Randa (@randaalex)

View file

@ -1,4 +0,0 @@
---
title: Replaces dashboard/dashboard.feature spinach with rspec
merge_request: 12876
author: Alexander Randa (@randaalex)

View file

@ -1,4 +0,0 @@
---
title: Added /duplicate quick action to close a duplicate issue
merge_request: 12845
author: Ryan Scott

View file

@ -1,4 +0,0 @@
---
title: Fix timezone inconsistencies in user contribution graph
merge_request: 13208
author:

View file

@ -1,4 +0,0 @@
---
title: Decrease ABC threshold to 56.96
merge_request: 11227
author: Maxim Rydkin

View file

@ -0,0 +1,4 @@
---
title: Hashed Storage support for Repositories (EXPERIMENTAL)
merge_request: 13246
author:

View file

@ -1,4 +0,0 @@
---
title: Don't send rejection mails for all auto-generated mails
merge_request: 13254
author:

View file

@ -1,4 +0,0 @@
---
title: Handle errors while a project is being deleted asynchronously.
merge_request: 11088
author:

View file

@ -1,4 +0,0 @@
---
title: Add /shrug and /tableflip commands
merge_request: 10068
author: Alex Ives

View file

@ -1,4 +0,0 @@
---
title: refactor initializations in dropzone_input.js
merge_request: 12768
author: Brandon Everett

View file

@ -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:

View file

@ -1,4 +0,0 @@
---
title: Remove project_key from the Jira configuration
merge_request: 12050
author:

View file

@ -1,4 +0,0 @@
---
title: Unlock stuck merge request and set the proper state
merge_request: 13207
author:

View file

@ -1,4 +0,0 @@
---
title: Add Slack and JIRA services counts to Usage Data
merge_request:
author:

View file

@ -1,5 +0,0 @@
---
title: Prevent web hook and project service background jobs from going to the dead
jobs queue
merge_request:
author:

View file

@ -1,4 +0,0 @@
---
title: Display specific error message when JIRA test fails
merge_request:
author:

View file

@ -1,4 +0,0 @@
---
title: Move some code from services to workers in order to improve performance
merge_request: 13326
author:

View file

@ -1,4 +0,0 @@
---
title: clean up merge request widget UI
merge_request:
author:

View file

@ -1,4 +0,0 @@
---
title: Associate Issues tab only with internal issues tracker
merge_request:
author:

View file

@ -1,4 +0,0 @@
---
title: Add CSRF token verification to API
merge_request: 12154
author: Vitaliy @blackst0ne Klachkov

View file

@ -1,4 +0,0 @@
---
title: Remove events column from notification settings table
merge_request:
author:

View file

@ -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:

View file

@ -1,4 +0,0 @@
---
title: Respect blockquote line breaks in markdown
merge_request:
author:

View file

@ -1,5 +0,0 @@
---
title: Update confidential issue UI - add confidential visibility and settings to
sidebar
merge_request:
author:

View file

@ -1,4 +0,0 @@
---
title: Add icons to contextual sidebars
merge_request:
author:

Some files were not shown because too many files have changed in this diff Show more