diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-05-17 03:10:45 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-05-17 03:10:45 +0000 |
commit | 158548078665a076f33ed161967f030653586f24 (patch) | |
tree | 15f969bc601269d1ff183a70a14998eaad9b8a9e | |
parent | 541b6cf72fe31f266b1dac57c0da76967fecf38e (diff) | |
download | gitlab-ce-158548078665a076f33ed161967f030653586f24.tar.gz |
Add latest changes from gitlab-org/gitlab@master
24 files changed, 211 insertions, 74 deletions
diff --git a/app/assets/stylesheets/framework/lists.scss b/app/assets/stylesheets/framework/lists.scss index df2ba718c72..a3e8b2c245c 100644 --- a/app/assets/stylesheets/framework/lists.scss +++ b/app/assets/stylesheets/framework/lists.scss @@ -146,7 +146,7 @@ ul.content-list { > .btn, > .btn-group, > .dropdown.inline { - margin-right: $gl-padding-top; + margin-right: $grid-size; display: inline-block; margin-top: 3px; margin-bottom: 4px; diff --git a/app/assets/stylesheets/framework/secondary_navigation_elements.scss b/app/assets/stylesheets/framework/secondary_navigation_elements.scss index 27b7cac2df5..f904ef11f5b 100644 --- a/app/assets/stylesheets/framework/secondary_navigation_elements.scss +++ b/app/assets/stylesheets/framework/secondary_navigation_elements.scss @@ -182,6 +182,11 @@ width: 100%; } + /* This resets the width of the control so that the search button doesn't wrap */ + .gl-search-box-by-click .form-control { + width: 1%; + } + .dropdown-menu-toggle { margin-bottom: 0; } diff --git a/app/channels/issues_channel.rb b/app/channels/issues_channel.rb deleted file mode 100644 index 5f3909b7716..00000000000 --- a/app/channels/issues_channel.rb +++ /dev/null @@ -1,13 +0,0 @@ -# frozen_string_literal: true - -class IssuesChannel < ApplicationCable::Channel - def subscribed - project = Project.find_by_full_path(params[:project_path]) - return reject unless project - - issue = project.issues.find_by_iid(params[:iid]) - return reject unless issue && Ability.allowed?(current_user, :read_issue, issue) - - stream_for issue - end -end diff --git a/app/services/issues/update_service.rb b/app/services/issues/update_service.rb index 19365374e10..899e03d1570 100644 --- a/app/services/issues/update_service.rb +++ b/app/services/issues/update_service.rb @@ -42,10 +42,6 @@ module Issues ).execute(spam_params: spam_params) end - def after_update(issue) - IssuesChannel.broadcast_to(issue, event: 'updated') if Gitlab::ActionCable::Config.in_app? || Feature.enabled?(:broadcast_issue_updates, issue.project) - end - def handle_changes(issue, options) old_associations = options.fetch(:old_associations, {}) old_labels = old_associations.fetch(:labels, []) diff --git a/app/services/projects/update_statistics_service.rb b/app/services/projects/update_statistics_service.rb index a0793cff2df..71f5a8e633d 100644 --- a/app/services/projects/update_statistics_service.rb +++ b/app/services/projects/update_statistics_service.rb @@ -2,18 +2,49 @@ module Projects class UpdateStatisticsService < BaseService + include ::Gitlab::Utils::StrongMemoize + + STAT_TO_CACHED_METHOD = { + repository_size: :size, + commit_count: :commit_count + }.freeze + def execute return unless project Gitlab::AppLogger.info("Updating statistics for project #{project.id}") - project.statistics.refresh!(only: statistics.map(&:to_sym)) + expire_repository_caches + expire_wiki_caches + project.statistics.refresh!(only: statistics) end private + def expire_repository_caches + if statistics.empty? + project.repository.expire_statistics_caches + elsif method_caches_to_expire.present? + project.repository.expire_method_caches(method_caches_to_expire) + end + end + + def expire_wiki_caches + return unless project.wiki_enabled? && statistics.include?(:wiki_size) + + project.wiki.repository.expire_method_caches([:size]) + end + + def method_caches_to_expire + strong_memoize(:method_caches_to_expire) do + statistics.map { |stat| STAT_TO_CACHED_METHOD[stat] }.compact + end + end + def statistics - params[:statistics] + strong_memoize(:statistics) do + params[:statistics]&.map(&:to_sym) + end end end end diff --git a/app/views/projects/buttons/_download.html.haml b/app/views/projects/buttons/_download.html.haml index 3071e5ea5f8..2f89a3f62ed 100644 --- a/app/views/projects/buttons/_download.html.haml +++ b/app/views/projects/buttons/_download.html.haml @@ -4,9 +4,9 @@ - archive_prefix = "#{project.path}-#{ref.tr('/', '-')}" .project-action-button.dropdown.inline> %button.gl-button.btn.btn-default.has-tooltip{ title: s_('DownloadSource|Download'), 'data-toggle' => 'dropdown', 'aria-label' => s_('DownloadSource|Download'), 'data-display' => 'static', data: { qa_selector: 'download_source_code_button' } } - = sprite_icon('download') + = sprite_icon('download', css_class: 'gl-icon') %span.sr-only= _('Select Archive Format') - = sprite_icon("chevron-down") + = sprite_icon('chevron-down', css_class: 'gl-icon') .dropdown-menu.dropdown-menu-right{ role: 'menu' } %section %h5.m-0.dropdown-bold-header= _('Download source code') diff --git a/app/views/projects/buttons/_remove_tag.html.haml b/app/views/projects/buttons/_remove_tag.html.haml index cdf6336a259..58af0d91f30 100644 --- a/app/views/projects/buttons/_remove_tag.html.haml +++ b/app/views/projects/buttons/_remove_tag.html.haml @@ -2,5 +2,5 @@ - tag = local_assigns.fetch(:tag, nil) - return unless project && tag -%button{ type: "button", class: "js-remove-tag js-confirm-modal-button gl-button btn btn-danger btn-icon has-tooltip gl-ml-3 #{protected_tag?(project, tag) ? 'disabled' : ''}", title: s_('TagsPage|Delete tag'), data: { container: 'body', path: project_tag_path(@project, tag.name), modal_attributes: delete_tag_modal_attributes(tag.name) } } - = sprite_icon("remove") +%button{ type: "button", class: "js-remove-tag js-confirm-modal-button gl-button btn btn-default btn-icon has-tooltip gl-ml-3\! #{protected_tag?(project, tag) ? 'disabled' : ''}", title: s_('TagsPage|Delete tag'), data: { container: 'body', path: project_tag_path(@project, tag.name), modal_attributes: delete_tag_modal_attributes(tag.name) } } + = sprite_icon('remove', css_class: 'gl-icon') diff --git a/app/views/projects/tags/_tag.html.haml b/app/views/projects/tags/_tag.html.haml index a178ec6979a..83a3cac487f 100644 --- a/app/views/projects/tags/_tag.html.haml +++ b/app/views/projects/tags/_tag.html.haml @@ -42,5 +42,5 @@ - if can?(current_user, :admin_tag, @project) = link_to edit_project_tag_release_path(@project, tag.name), class: 'btn gl-button btn-default btn-icon btn-edit has-tooltip', title: s_('TagsPage|Edit release notes'), data: { container: "body" } do - = sprite_icon("pencil") + = sprite_icon('pencil', css_class: 'gl-icon') = render 'projects/buttons/remove_tag', project: @project, tag: tag diff --git a/app/views/projects/tags/index.html.haml b/app/views/projects/tags/index.html.haml index 5065a784b09..79205a51d71 100644 --- a/app/views/projects/tags/index.html.haml +++ b/app/views/projects/tags/index.html.haml @@ -10,11 +10,11 @@ .nav-controls #js-tags-sort-dropdown{ data: { filter_tags_path: filter_tags_path, sort_options: tags_sort_options_hash.to_json } } + = link_to project_tags_path(@project, rss_url_options), title: _("Tags feed"), class: 'btn gl-button btn-default btn-icon has-tooltip gl-ml-auto' do + = sprite_icon('rss', css_class: 'gl-icon qa-rss-icon') - if can?(current_user, :admin_tag, @project) = link_to new_project_tag_path(@project), class: 'btn gl-button btn-confirm', data: { qa_selector: "new_tag_button" } do = s_('TagsPage|New tag') - = link_to project_tags_path(@project, rss_url_options), title: _("Tags feed"), class: 'btn gl-button btn-default btn-icon d-none d-sm-inline-block has-tooltip' do - = sprite_icon('rss', css_class: 'qa-rss-icon') = render_if_exists 'projects/commits/mirror_status' diff --git a/app/views/projects/tags/new.html.haml b/app/views/projects/tags/new.html.haml index 2ef1891089f..fe00772d1d6 100644 --- a/app/views/projects/tags/new.html.haml +++ b/app/views/projects/tags/new.html.haml @@ -51,7 +51,7 @@ = render layout: 'shared/md_preview', locals: { url: preview_markdown_path(@project), referenced_users: true } do = render 'shared/zen', attr: :release_description, classes: 'note-textarea', placeholder: s_('TagsPage|Write your release notes or drag files here…'), current_text: @release_description, qa_selector: 'release_notes_field' = render 'shared/notes/hints' - .form-actions - = button_tag s_('TagsPage|Create tag'), class: 'gl-button btn btn-confirm', data: { qa_selector: "create_tag_button" } + .form-actions.gl-display-flex + = button_tag s_('TagsPage|Create tag'), class: 'gl-button btn btn-confirm gl-mr-3', data: { qa_selector: "create_tag_button" } = link_to s_('TagsPage|Cancel'), project_tags_path(@project), class: 'gl-button btn btn-default btn-cancel' %script#availableRefs{ type: "application/json" }= @project.repository.ref_names.to_json.html_safe diff --git a/app/views/projects/tags/releases/edit.html.haml b/app/views/projects/tags/releases/edit.html.haml index f181212b328..88594209c3b 100644 --- a/app/views/projects/tags/releases/edit.html.haml +++ b/app/views/projects/tags/releases/edit.html.haml @@ -14,6 +14,6 @@ = render 'shared/zen', f: f, attr: :description, classes: 'note-textarea', placeholder: "Write your release notes or drag files here…" = render 'shared/notes/hints' .error-alert - .gl-mt-3 - = f.submit 'Save changes', class: 'btn gl-button btn-confirm' + .gl-mt-5.gl-display-flex + = f.submit 'Save changes', class: 'btn gl-button btn-confirm gl-mr-3' = link_to "Cancel", project_tag_path(@project, @tag.name), class: "btn gl-button btn-default btn-cancel" diff --git a/changelogs/unreleased/273322-fy21q4-foundations-kr2-audit-and-update-buttons-on-projects-tagsco.yml b/changelogs/unreleased/273322-fy21q4-foundations-kr2-audit-and-update-buttons-on-projects-tagsco.yml new file mode 100644 index 00000000000..26d57a08cab --- /dev/null +++ b/changelogs/unreleased/273322-fy21q4-foundations-kr2-audit-and-update-buttons-on-projects-tagsco.yml @@ -0,0 +1,6 @@ +--- +title: Update button styles, spacing, variants and responsive behavior for the Tags + page. +merge_request: 61413 +author: +type: other diff --git a/changelogs/unreleased/324206-processing-package-scope-removal.yml b/changelogs/unreleased/324206-processing-package-scope-removal.yml new file mode 100644 index 00000000000..b1962fb34e7 --- /dev/null +++ b/changelogs/unreleased/324206-processing-package-scope-removal.yml @@ -0,0 +1,5 @@ +--- +title: Update temporary NuGet packages to have processing status +merge_request: 61724 +author: +type: other diff --git a/changelogs/unreleased/sh-flush-statistics-cache.yml b/changelogs/unreleased/sh-flush-statistics-cache.yml new file mode 100644 index 00000000000..16cc9f538ce --- /dev/null +++ b/changelogs/unreleased/sh-flush-statistics-cache.yml @@ -0,0 +1,5 @@ +--- +title: Flush statistics cache anytime it is updated +merge_request: 52938 +author: +type: fixed diff --git a/db/post_migrate/20210513155447_add_temporary_package_index_for_nuget_data_migration.rb b/db/post_migrate/20210513155447_add_temporary_package_index_for_nuget_data_migration.rb new file mode 100644 index 00000000000..b43abab2a96 --- /dev/null +++ b/db/post_migrate/20210513155447_add_temporary_package_index_for_nuget_data_migration.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +class AddTemporaryPackageIndexForNugetDataMigration < ActiveRecord::Migration[6.0] + include Gitlab::Database::MigrationHelpers + + INDEX_NAME = 'tmp_index_packages_on_id_where_nuget_default_temp_package' + INDEX_CONDITION = "package_type = 4 AND name = 'NuGet.Temporary.Package' AND status = 0" + + disable_ddl_transaction! + + def up + # this index is used in 20210513155546_backfill_nuget_temporary_packages_to_processing_status + add_concurrent_index :packages_packages, :id, where: INDEX_CONDITION, name: INDEX_NAME + end + + def down + remove_concurrent_index_by_name :packages_packages, INDEX_NAME + end +end diff --git a/db/post_migrate/20210513155546_backfill_nuget_temporary_packages_to_processing_status.rb b/db/post_migrate/20210513155546_backfill_nuget_temporary_packages_to_processing_status.rb new file mode 100644 index 00000000000..8124f94b519 --- /dev/null +++ b/db/post_migrate/20210513155546_backfill_nuget_temporary_packages_to_processing_status.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +class BackfillNugetTemporaryPackagesToProcessingStatus < ActiveRecord::Migration[6.0] + include Gitlab::Database::MigrationHelpers + + disable_ddl_transaction! + + class Package < ActiveRecord::Base + include EachBatch + + self.table_name = 'packages_packages' + + scope :nuget_temporary_packages, -> do + # 4 is nuget package type, 0 is default status + where(package_type: 4, name: 'NuGet.Temporary.Package', status: 0) + end + end + + def up + Package.nuget_temporary_packages.each_batch(of: 100) do |batch| + # 2 is processing status + batch.update_all(status: 2) + end + end + + def down + # no-op + end +end diff --git a/db/post_migrate/20210513155635_remove_temporary_package_index_for_nuget_data_migration.rb b/db/post_migrate/20210513155635_remove_temporary_package_index_for_nuget_data_migration.rb new file mode 100644 index 00000000000..eb0abba5112 --- /dev/null +++ b/db/post_migrate/20210513155635_remove_temporary_package_index_for_nuget_data_migration.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +class RemoveTemporaryPackageIndexForNugetDataMigration < ActiveRecord::Migration[6.0] + include Gitlab::Database::MigrationHelpers + + INDEX_NAME = 'tmp_index_packages_on_id_where_nuget_default_temp_package' + INDEX_CONDITION = "package_type = 4 AND name = 'NuGet.Temporary.Package' AND status = 0" + + disable_ddl_transaction! + + def up + # this index was used in 20210513155546_backfill_nuget_temporary_packages_to_processing_status + remove_concurrent_index_by_name :packages_packages, INDEX_NAME + end + + def down + add_concurrent_index :packages_packages, :id, where: INDEX_CONDITION, name: INDEX_NAME + end +end diff --git a/db/schema_migrations/20210513155447 b/db/schema_migrations/20210513155447 new file mode 100644 index 00000000000..c2fd6c22a05 --- /dev/null +++ b/db/schema_migrations/20210513155447 @@ -0,0 +1 @@ +1f5ea8527107d4cffac535b9ae3e532a98ebd69a8711abdbe68b12fe005dfbb5
\ No newline at end of file diff --git a/db/schema_migrations/20210513155546 b/db/schema_migrations/20210513155546 new file mode 100644 index 00000000000..97f9dc2b3c0 --- /dev/null +++ b/db/schema_migrations/20210513155546 @@ -0,0 +1 @@ +44abbe007dae17982f923b1b15fd0534d3d3a7fd154cd9e4b5409f86030de2f7
\ No newline at end of file diff --git a/db/schema_migrations/20210513155635 b/db/schema_migrations/20210513155635 new file mode 100644 index 00000000000..57da33a0bd2 --- /dev/null +++ b/db/schema_migrations/20210513155635 @@ -0,0 +1 @@ +d1fccf214f2e237482fc4d9e2b5d5ea6e9241ad4ace8739e7b799555afafa215
\ No newline at end of file diff --git a/spec/channels/issues_channel_spec.rb b/spec/channels/issues_channel_spec.rb deleted file mode 100644 index 4c860402f03..00000000000 --- a/spec/channels/issues_channel_spec.rb +++ /dev/null @@ -1,36 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -RSpec.describe IssuesChannel do - let_it_be(:issue) { create(:issue) } - - it 'rejects when project path is invalid' do - subscribe(project_path: 'invalid_project_path', iid: issue.iid) - - expect(subscription).to be_rejected - end - - it 'rejects when iid is invalid' do - subscribe(project_path: issue.project.full_path, iid: non_existing_record_iid) - - expect(subscription).to be_rejected - end - - it 'rejects when the user does not have access' do - stub_action_cable_connection current_user: nil - - subscribe(project_path: issue.project.full_path, iid: issue.iid) - - expect(subscription).to be_rejected - end - - it 'subscribes to a stream when the user has access' do - stub_action_cable_connection current_user: issue.author - - subscribe(project_path: issue.project.full_path, iid: issue.iid) - - expect(subscription).to be_confirmed - expect(subscription).to have_stream_for(issue) - end -end diff --git a/spec/migrations/backfill_nuget_temporary_packages_to_processing_status_spec.rb b/spec/migrations/backfill_nuget_temporary_packages_to_processing_status_spec.rb new file mode 100644 index 00000000000..574020e52d5 --- /dev/null +++ b/spec/migrations/backfill_nuget_temporary_packages_to_processing_status_spec.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +require 'spec_helper' + +require_migration! + +RSpec.describe BackfillNugetTemporaryPackagesToProcessingStatus, :migration do + let(:namespaces) { table(:namespaces) } + let(:projects) { table(:projects) } + let(:packages) { table(:packages_packages) } + + before do + namespace = namespaces.create!(id: 123, name: 'test_namespace', path: 'test_namespace') + project = projects.create!(id: 111, name: 'sample_project', path: 'sample_project', namespace_id: namespace.id) + + packages.create!(name: 'NuGet.Temporary.Package', version: '0.1.1', package_type: 4, status: 0, project_id: project.id) + packages.create!(name: 'foo', version: '0.1.1', package_type: 4, status: 0, project_id: project.id) + packages.create!(name: 'NuGet.Temporary.Package', version: '0.1.1', package_type: 4, status: 2, project_id: project.id) + packages.create!(name: 'NuGet.Temporary.Package', version: '0.1.1', package_type: 1, status: 2, project_id: project.id) + packages.create!(name: 'NuGet.Temporary.Package', version: '0.1.1', package_type: 1, status: 0, project_id: project.id) + end + + it 'updates the applicable packages to processing status', :aggregate_failures do + expect(packages.where(status: 0).count).to eq(3) + expect(packages.where(status: 2).count).to eq(2) + expect(packages.where(name: 'NuGet.Temporary.Package', package_type: 4, status: 0).count).to eq(1) + + migrate! + + expect(packages.where(status: 0).count).to eq(2) + expect(packages.where(status: 2).count).to eq(3) + expect(packages.where(name: 'NuGet.Temporary.Package', package_type: 4, status: 0).count).to eq(0) + end +end diff --git a/spec/services/issues/update_service_spec.rb b/spec/services/issues/update_service_spec.rb index 2bb62f49bd0..7490ad5b2b3 100644 --- a/spec/services/issues/update_service_spec.rb +++ b/spec/services/issues/update_service_spec.rb @@ -1024,10 +1024,8 @@ RSpec.describe Issues::UpdateService, :mailer do stub_feature_flags(broadcast_issue_updates: feature_flag_enabled) if should_broadcast - expect(IssuesChannel).to receive(:broadcast_to).with(issue, event: 'updated') expect(GraphqlTriggers).to receive(:issuable_assignees_updated).with(issue) else - expect(IssuesChannel).not_to receive(:broadcast_to) expect(GraphqlTriggers).not_to receive(:issuable_assignees_updated).with(issue) end diff --git a/spec/services/projects/update_statistics_service_spec.rb b/spec/services/projects/update_statistics_service_spec.rb index 92e97186be3..6987185b549 100644 --- a/spec/services/projects/update_statistics_service_spec.rb +++ b/spec/services/projects/update_statistics_service_spec.rb @@ -3,6 +3,8 @@ require 'spec_helper' RSpec.describe Projects::UpdateStatisticsService do + using RSpec::Parameterized::TableSyntax + let(:service) { described_class.new(project, nil, statistics: statistics)} let(:statistics) { %w(repository_size) } @@ -18,12 +20,46 @@ RSpec.describe Projects::UpdateStatisticsService do end context 'with an existing project' do - let(:project) { create(:project) } + let_it_be(:project) { create(:project) } + + where(:statistics, :method_caches) do + [] | %i(size commit_count) + ['repository_size'] | [:size] + [:repository_size] | [:size] + [:lfs_objects_size] | nil + [:commit_count] | [:commit_count] # rubocop:disable Lint/BinaryOperatorWithIdenticalOperands + [:repository_size, :commit_count] | %i(size commit_count) + [:repository_size, :commit_count, :lfs_objects_size] | %i(size commit_count) + end + + with_them do + it 'refreshes the project statistics' do + expect(project.statistics).to receive(:refresh!).with(only: statistics.map(&:to_sym)).and_call_original + + service.execute + end + + it 'invalidates the method caches after a refresh' do + expect(project.wiki.repository).not_to receive(:expire_method_caches) + + if method_caches.present? + expect(project.repository).to receive(:expire_method_caches).with(method_caches).and_call_original + else + expect(project.repository).not_to receive(:expire_method_caches) + end + + service.execute + end + end + end + + context 'with an existing project with a Wiki' do + let(:project) { create(:project, :repository, :wiki_enabled) } + let(:statistics) { [:wiki_size] } - it 'refreshes the project statistics' do - expect_any_instance_of(ProjectStatistics).to receive(:refresh!) - .with(only: statistics.map(&:to_sym)) - .and_call_original + it 'invalidates and refreshes Wiki size' do + expect(project.statistics).to receive(:refresh!).with(only: statistics).and_call_original + expect(project.wiki.repository).to receive(:expire_method_caches).with(%i(size)).and_call_original service.execute end |