From a373ecffca1512404cb4f237399e3bf275d87f69 Mon Sep 17 00:00:00 2001 From: GitLab Bot Date: Fri, 9 Jul 2021 12:08:17 +0000 Subject: [PATCH] Add latest changes from gitlab-org/gitlab@master --- .gitlab/ci/review.gitlab-ci.yml | 8 +- .gitlab/ci/rules.gitlab-ci.yml | 2 +- GITALY_SERVER_VERSION | 2 +- Gemfile | 2 +- Gemfile.lock | 9 +- .../blob/components/blob_header_filepath.vue | 2 +- .../commit/pipelines/pipelines_bundle.js | 6 +- .../diffs/components/diff_file_header.vue | 2 +- .../components/stacktrace_entry.vue | 2 +- app/assets/javascripts/issuable_context.js | 30 ++- .../components/issuable_show_root.vue | 6 +- .../components/issuable_sidebar_root.vue | 23 +- .../javascripts/issuable_sidebar/constants.js | 1 + .../queries/update_issue.mutation.graphql | 4 + .../merge_conflict_resolver_app.vue | 2 +- app/assets/javascripts/merge_request.js | 8 - app/assets/javascripts/merge_request_tabs.js | 11 +- .../components/constants.js | 2 +- .../queries/updateStatus.mutation.graphql | 3 +- .../components/states/ready_to_merge.vue | 1 - .../vue_shared/components/file_icon.vue | 1 - app/controllers/search_controller.rb | 11 + app/finders/concerns/merged_at_filter.rb | 20 +- app/helpers/issuables_helper.rb | 9 + app/helpers/search_helper.rb | 2 +- app/helpers/sorting_helper.rb | 8 +- app/helpers/sorting_titles_values_helper.rb | 24 ++ app/models/issue.rb | 19 +- app/models/merge_request.rb | 5 + app/views/search/_results.html.haml | 24 +- app/views/search/results/_timeout.html.haml | 10 + app/views/shared/issuable/_sidebar.html.haml | 2 +- .../shared/issuable/_sort_dropdown.html.haml | 2 + .../cleanup_container_repository_worker.rb | 10 +- .../container_expiration_policy_worker.rb | 21 ++ ...anup_status_project_id_start_date_index.rb | 24 ++ db/schema_migrations/20210705130919 | 1 + db/structure.sql | 2 +- doc/development/code_review.md | 1 + doc/development/pipelines.md | 2 +- doc/integration/jira/dvcs.md | 3 +- .../admin_area/custom_project_templates.md | 29 +-- doc/user/search/index.md | 6 +- .../sidekiq_client_middleware.rb | 26 +- .../sidekiq_server_middleware.rb | 36 ++- locale/gitlab.pot | 66 +++-- scripts/review_apps/review-apps.sh | 6 +- .../user_lists_merge_requests_spec.rb | 16 +- .../search/user_searches_for_code_spec.rb | 1 + .../search/user_searches_for_comments_spec.rb | 2 + .../search/user_searches_for_commits_spec.rb | 2 + .../search/user_searches_for_issues_spec.rb | 1 + .../user_searches_for_merge_requests_spec.rb | 1 + .../user_searches_for_milestones_spec.rb | 1 + .../search/user_searches_for_projects_spec.rb | 1 + .../search/user_searches_for_users_spec.rb | 2 + .../user_searches_for_wiki_pages_spec.rb | 1 + .../blob_header_filepath_spec.js.snap | 2 +- .../components/issuable_show_root_spec.js | 8 - .../components/issuable_sidebar_root_spec.js | 228 ++++++------------ .../sidekiq_client_middleware_spec.rb | 61 +++-- .../sidekiq_server_middleware_spec.rb | 104 ++++---- .../sidekiq_middleware/server_metrics_spec.rb | 10 +- spec/models/issue_spec.rb | 52 +++- spec/models/merge_request_spec.rb | 16 ++ .../search/search_timeouts_shared_examples.rb | 21 ++ spec/tooling/danger/feature_flag_spec.rb | 2 +- ...leanup_container_repository_worker_spec.rb | 45 ++-- ...container_expiration_policy_worker_spec.rb | 35 ++- tooling/danger/feature_flag.rb | 3 +- 70 files changed, 677 insertions(+), 434 deletions(-) create mode 100644 app/assets/javascripts/issuable_sidebar/constants.js create mode 100644 app/views/search/results/_timeout.html.haml create mode 100644 db/migrate/20210705130919_create_container_repos_on_exp_cleanup_status_project_id_start_date_index.rb create mode 100644 db/schema_migrations/20210705130919 create mode 100644 spec/support/shared_examples/features/search/search_timeouts_shared_examples.rb diff --git a/.gitlab/ci/review.gitlab-ci.yml b/.gitlab/ci/review.gitlab-ci.yml index 0b6675ab84f..b7a4ef45240 100644 --- a/.gitlab/ci/review.gitlab-ci.yml +++ b/.gitlab/ci/review.gitlab-ci.yml @@ -94,13 +94,13 @@ review-deploy: before_script: - *base-before_script -review-stop-failed-deployment: +review-delete-deployment: extends: - .review-stop-base - - .review:rules:review-stop-failed-deployment + - .review:rules:review-delete-deployment stage: prepare script: - - delete_failed_release + - delete_release review-stop: extends: @@ -108,7 +108,7 @@ review-stop: - .review:rules:review-stop stage: post-qa script: - - delete_release + - delete_k8s_release_namespace .review-qa-base: extends: diff --git a/.gitlab/ci/rules.gitlab-ci.yml b/.gitlab/ci/rules.gitlab-ci.yml index 55ebd3ba038..b9cf5a7d5bd 100644 --- a/.gitlab/ci/rules.gitlab-ci.yml +++ b/.gitlab/ci/rules.gitlab-ci.yml @@ -1180,7 +1180,7 @@ - <<: *if-dot-com-gitlab-org-schedule allow_failure: true -.review:rules:review-stop-failed-deployment: +.review:rules:review-delete-deployment: rules: - <<: *if-not-ee when: never diff --git a/GITALY_SERVER_VERSION b/GITALY_SERVER_VERSION index af8db279ebd..28c55f889ba 100644 --- a/GITALY_SERVER_VERSION +++ b/GITALY_SERVER_VERSION @@ -1 +1 @@ -fef798978197809e268e5395838b4f4eeb4288e9 +49893735ed64feebc208f4efe90bebbb8bbb02ad diff --git a/Gemfile b/Gemfile index 5a52a7e13ad..52bbd458808 100644 --- a/Gemfile +++ b/Gemfile @@ -394,7 +394,7 @@ group :development, :test do end group :development, :test, :danger do - gem 'gitlab-dangerfiles', '~> 2.1.2', require: false + gem 'gitlab-dangerfiles', '~> 2.2.1', require: false end group :development, :test, :coverage do diff --git a/Gemfile.lock b/Gemfile.lock index 9237261d7c1..44422535cc9 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -229,7 +229,7 @@ GEM css_parser (1.7.0) addressable daemons (1.3.1) - danger (8.2.3) + danger (8.3.1) claide (~> 1.0) claide-plugins (>= 0.9.2) colored2 (~> 3.1) @@ -468,8 +468,9 @@ GEM terminal-table (~> 1.5, >= 1.5.1) gitlab-chronic (0.10.5) numerizer (~> 0.2) - gitlab-dangerfiles (2.1.2) - danger-gitlab + gitlab-dangerfiles (2.2.1) + danger (>= 8.3.1) + danger-gitlab (>= 8.0.0) gitlab-experiment (0.6.1) activesupport (>= 3.0) request_store (>= 1.0) @@ -1488,7 +1489,7 @@ DEPENDENCIES gitaly (~> 14.1.0.pre.rc2) github-markup (~> 1.7.0) gitlab-chronic (~> 0.10.5) - gitlab-dangerfiles (~> 2.1.2) + gitlab-dangerfiles (~> 2.2.1) gitlab-experiment (~> 0.6.1) gitlab-fog-azure-rm (~> 1.1.1) gitlab-labkit (~> 0.18.0) diff --git a/app/assets/javascripts/blob/components/blob_header_filepath.vue b/app/assets/javascripts/blob/components/blob_header_filepath.vue index 99fe3938046..cb441a7e491 100644 --- a/app/assets/javascripts/blob/components/blob_header_filepath.vue +++ b/app/assets/javascripts/blob/components/blob_header_filepath.vue @@ -29,7 +29,7 @@ export default { - - diff --git a/app/assets/javascripts/issuable_sidebar/constants.js b/app/assets/javascripts/issuable_sidebar/constants.js new file mode 100644 index 00000000000..4f4b6341a1c --- /dev/null +++ b/app/assets/javascripts/issuable_sidebar/constants.js @@ -0,0 +1 @@ +export const USER_COLLAPSED_GUTTER_COOKIE = 'collapsed_gutter'; diff --git a/app/assets/javascripts/issue_show/queries/update_issue.mutation.graphql b/app/assets/javascripts/issue_show/queries/update_issue.mutation.graphql index 9c28fdded21..ec8d8f32d8b 100644 --- a/app/assets/javascripts/issue_show/queries/update_issue.mutation.graphql +++ b/app/assets/javascripts/issue_show/queries/update_issue.mutation.graphql @@ -1,5 +1,9 @@ mutation updateIssue($input: UpdateIssueInput!) { updateIssue(input: $input) { + issuable: issue { + id + state + } errors } } diff --git a/app/assets/javascripts/merge_conflicts/merge_conflict_resolver_app.vue b/app/assets/javascripts/merge_conflicts/merge_conflict_resolver_app.vue index 3e31e2e93ae..5fcc778a714 100644 --- a/app/assets/javascripts/merge_conflicts/merge_conflict_resolver_app.vue +++ b/app/assets/javascripts/merge_conflicts/merge_conflict_resolver_app.vue @@ -120,7 +120,7 @@ export default { >
- + {{ file.filePath }}
diff --git a/app/assets/javascripts/merge_request.js b/app/assets/javascripts/merge_request.js index feaf8b0d996..0ddb2c2334c 100644 --- a/app/assets/javascripts/merge_request.js +++ b/app/assets/javascripts/merge_request.js @@ -148,14 +148,6 @@ MergeRequest.prototype.initCommitMessageListeners = function () { }); }; -MergeRequest.setStatusBoxToMerged = function () { - $('.detail-page-header .status-box') - .removeClass('status-box-open') - .addClass('status-box-mr-merged') - .find('span') - .text(__('Merged')); -}; - MergeRequest.decreaseCounter = function (by = 1) { const $el = $('.js-merge-counter'); const count = Math.max(parseInt($el.text().replace(/[^\d]/, ''), 10) - by, 0); diff --git a/app/assets/javascripts/merge_request_tabs.js b/app/assets/javascripts/merge_request_tabs.js index 602d6ef611f..c3c3aacae35 100644 --- a/app/assets/javascripts/merge_request_tabs.js +++ b/app/assets/javascripts/merge_request_tabs.js @@ -3,9 +3,7 @@ import { GlBreakpointInstance as bp } from '@gitlab/ui/dist/utils'; import $ from 'jquery'; import Cookies from 'js-cookie'; import Vue from 'vue'; -import CommitPipelinesTable from '~/commit/pipelines/pipelines_table.vue'; import createEventHub from '~/helpers/event_hub_factory'; -import initAddContextCommitsTriggers from './add_context_commits_modal'; import BlobForkSuggestion from './blob/blob_fork_suggestion'; import Diff from './diff'; import createFlash from './flash'; @@ -341,8 +339,10 @@ export default class MergeRequestTabs { this.scrollToContainerElement('#commits'); this.toggleLoading(false); - initAddContextCommitsTriggers(); + + return import('./add_context_commits_modal'); }) + .then((m) => m.default()) .catch(() => { this.toggleLoading(false); createFlash({ @@ -356,13 +356,16 @@ export default class MergeRequestTabs { const { mrWidgetData } = gl; this.commitPipelinesTable = new Vue({ + components: { + CommitPipelinesTable: () => import('~/commit/pipelines/pipelines_table.vue'), + }, provide: { artifactsEndpoint: pipelineTableViewEl.dataset.artifactsEndpoint, artifactsEndpointPlaceholder: pipelineTableViewEl.dataset.artifactsEndpointPlaceholder, targetProjectFullPath: mrWidgetData?.target_project_full_path || '', }, render(createElement) { - return createElement(CommitPipelinesTable, { + return createElement('commit-pipelines-table', { props: { endpoint: pipelineTableViewEl.dataset.endpoint, emptyStateSvgPath: pipelineTableViewEl.dataset.emptyStateSvgPath, diff --git a/app/assets/javascripts/security_configuration/components/constants.js b/app/assets/javascripts/security_configuration/components/constants.js index ea2053b3326..874d51a3577 100644 --- a/app/assets/javascripts/security_configuration/components/constants.js +++ b/app/assets/javascripts/security_configuration/components/constants.js @@ -77,7 +77,7 @@ export const CONTAINER_SCANNING_CONFIG_HELP_PATH = helpPagePath( { anchor: 'configuration' }, ); -export const CLUSTER_IMAGE_SCANNING_NAME = __('ciReport|Cluster Image Scanning'); +export const CLUSTER_IMAGE_SCANNING_NAME = s__('ciReport|Cluster Image Scanning'); export const CLUSTER_IMAGE_SCANNING_DESCRIPTION = __( 'Check your Kubernetes cluster images for known vulnerabilities.', ); diff --git a/app/assets/javascripts/sidebar/queries/updateStatus.mutation.graphql b/app/assets/javascripts/sidebar/queries/updateStatus.mutation.graphql index b45b6b46c8f..28a47735143 100644 --- a/app/assets/javascripts/sidebar/queries/updateStatus.mutation.graphql +++ b/app/assets/javascripts/sidebar/queries/updateStatus.mutation.graphql @@ -1,6 +1,7 @@ mutation($projectPath: ID!, $iid: String!, $healthStatus: HealthStatus) { updateIssue(input: { projectPath: $projectPath, iid: $iid, healthStatus: $healthStatus }) { - issue { + issuable: issue { + id healthStatus } errors diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/ready_to_merge.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/ready_to_merge.vue index 7ab8da93a57..2d0b7fe46a6 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/states/ready_to_merge.vue +++ b/app/assets/javascripts/vue_merge_request_widget/components/states/ready_to_merge.vue @@ -412,7 +412,6 @@ export default { // If state is merged we should update the widget and stop the polling eventHub.$emit('MRWidgetUpdateRequested'); eventHub.$emit('FetchActionsContent'); - MergeRequest.setStatusBoxToMerged(); MergeRequest.hideCloseButton(); MergeRequest.decreaseCounter(); stopPolling(); diff --git a/app/assets/javascripts/vue_shared/components/file_icon.vue b/app/assets/javascripts/vue_shared/components/file_icon.vue index 2e7c10636a2..276fb35b51f 100644 --- a/app/assets/javascripts/vue_shared/components/file_icon.vue +++ b/app/assets/javascripts/vue_shared/components/file_icon.vue @@ -95,7 +95,6 @@ export default { :name="folderIconName" :size="size" class="folder-icon" - use-deprecated-sizes data-qa-selector="folder_icon_content" /> diff --git a/app/controllers/search_controller.rb b/app/controllers/search_controller.rb index ac6239615b4..4160b528301 100644 --- a/app/controllers/search_controller.rb +++ b/app/controllers/search_controller.rb @@ -16,6 +16,8 @@ class SearchController < ApplicationController search_term_present && !params[:project_id].present? end + rescue_from ActiveRecord::QueryCanceled, with: :render_timeout + layout 'search' feature_category :global_search @@ -150,6 +152,15 @@ class SearchController < ApplicationController redirect_to new_user_session_path, alert: _('You must be logged in to search across all of GitLab') end + + def render_timeout(exception) + raise exception unless action_name.to_sym == :show + + log_exception(exception) + + @timeout = true + render status: :request_timeout + end end SearchController.prepend_mod_with('SearchController') diff --git a/app/finders/concerns/merged_at_filter.rb b/app/finders/concerns/merged_at_filter.rb index e44354f36d1..581bcca3c25 100644 --- a/app/finders/concerns/merged_at_filter.rb +++ b/app/finders/concerns/merged_at_filter.rb @@ -10,7 +10,7 @@ module MergedAtFilter mr_metrics_scope = mr_metrics_scope.merged_after(merged_after) if merged_after.present? mr_metrics_scope = mr_metrics_scope.merged_before(merged_before) if merged_before.present? - join_metrics(items, mr_metrics_scope) + items.join_metrics.merge(mr_metrics_scope) end def merged_after @@ -20,22 +20,4 @@ module MergedAtFilter def merged_before params[:merged_before] end - - # rubocop: disable CodeReuse/ActiveRecord - # - # This join optimizes merged_at queries when the finder is invoked for a project by moving - # the target_project_id condition from merge_requests table to merge_request_metrics table. - def join_metrics(items, mr_metrics_scope) - scope = if project_id = items.where_values_hash["target_project_id"] - # removing the original merge_requests.target_project_id condition - items = items.unscope(where: :target_project_id) - # adding the target_project_id condition to merge_request_metrics - items.join_metrics(project_id) - else - items.join_metrics - end - - scope.merge(mr_metrics_scope) - end - # rubocop: enable CodeReuse/ActiveRecord end diff --git a/app/helpers/issuables_helper.rb b/app/helpers/issuables_helper.rb index c40feb42eea..d8ba530f3f6 100644 --- a/app/helpers/issuables_helper.rb +++ b/app/helpers/issuables_helper.rb @@ -425,6 +425,15 @@ module IssuablesHelper } end + def sidebar_status_data(issuable_sidebar, project) + { + iid: issuable_sidebar[:iid], + issuable_type: issuable_sidebar[:type], + full_path: project.full_path, + can_edit: issuable_sidebar.dig(:current_user, :can_edit).to_s + } + end + def parent @project || @group end diff --git a/app/helpers/search_helper.rb b/app/helpers/search_helper.rb index 04cc6886eb1..1cbde1871d4 100644 --- a/app/helpers/search_helper.rb +++ b/app/helpers/search_helper.rb @@ -301,7 +301,7 @@ module SearchHelper if @scope == scope li_class = 'active' - count = @search_results.formatted_count(scope) + count = @timeout ? 0 : @search_results.formatted_count(scope) else badge_class = 'js-search-count hidden' badge_data = { url: search_count_path(search_params) } diff --git a/app/helpers/sorting_helper.rb b/app/helpers/sorting_helper.rb index 9a0c82ddbb5..da32dfb0b9b 100644 --- a/app/helpers/sorting_helper.rb +++ b/app/helpers/sorting_helper.rb @@ -26,6 +26,9 @@ module SortingHelper sort_value_recently_updated => sort_title_recently_updated, sort_value_popularity => sort_title_popularity, sort_value_priority => sort_title_priority, + sort_value_merged_date => sort_title_merged_date, + sort_value_merged_recently => sort_title_merged_recently, + sort_value_merged_earlier => sort_title_merged_earlier, sort_value_upvotes => sort_title_upvotes, sort_value_contacted_date => sort_title_contacted_date, sort_value_relative_position => sort_title_relative_position, @@ -178,6 +181,7 @@ module SortingHelper sort_value_oldest_updated => sort_value_recently_updated, sort_value_milestone_later => sort_value_milestone, sort_value_due_date_later => sort_value_due_date, + sort_value_merged_recently => sort_value_merged_date, sort_value_least_popular => sort_value_popularity } end @@ -190,6 +194,8 @@ module SortingHelper sort_value_milestone => sort_value_milestone_later, sort_value_due_date => sort_value_due_date_later, sort_value_due_date_soon => sort_value_due_date_later, + sort_value_merged_date => sort_value_merged_recently, + sort_value_merged_earlier => sort_value_merged_recently, sort_value_popularity => sort_value_least_popular, sort_value_most_popular => sort_value_least_popular }.merge(issuable_sort_option_overrides) @@ -210,7 +216,7 @@ module SortingHelper def sort_direction_icon(sort_value) case sort_value - when sort_value_milestone, sort_value_due_date, /_asc\z/ + when sort_value_milestone, sort_value_due_date, sort_value_merged_date, /_asc\z/ 'sort-lowest' else 'sort-highest' diff --git a/app/helpers/sorting_titles_values_helper.rb b/app/helpers/sorting_titles_values_helper.rb index b1921983104..9b839f4e9bc 100644 --- a/app/helpers/sorting_titles_values_helper.rb +++ b/app/helpers/sorting_titles_values_helper.rb @@ -26,6 +26,18 @@ module SortingTitlesValuesHelper s_('SortOptions|Label priority') end + def sort_title_merged_date + s_('SortOptions|Merged date') + end + + def sort_title_merged_recently + s_('SortOptions|Merged recently') + end + + def sort_title_merged_earlier + s_('SortOptions|Merged earlier') + end + def sort_title_largest_group s_('SortOptions|Largest group') end @@ -175,6 +187,18 @@ module SortingTitlesValuesHelper 'label_priority' end + def sort_value_merged_date + 'merged_at' + end + + def sort_value_merged_recently + 'merged_at_desc' + end + + def sort_value_merged_earlier + 'merged_at_asc' + end + def sort_value_largest_group 'storage_size_desc' end diff --git a/app/models/issue.rb b/app/models/issue.rb index 5ed8a119035..3b236620ed6 100644 --- a/app/models/issue.rb +++ b/app/models/issue.rb @@ -426,8 +426,15 @@ class Issue < ApplicationRecord end def check_for_spam? - publicly_visible? && - (title_changed? || description_changed? || confidential_changed?) + # content created via support bots is always checked for spam, EVEN if + # the issue is not publicly visible and/or confidential + return true if author.support_bot? && spammable_attribute_changed? + + # Only check for spam on issues which are publicly visible (and thus indexed in search engines) + return false unless publicly_visible? + + # Only check for spam if certain attributes have changed + spammable_attribute_changed? end def as_json(options = {}) @@ -515,6 +522,14 @@ class Issue < ApplicationRecord private + def spammable_attribute_changed? + title_changed? || + description_changed? || + # NOTE: We need to check them for spam when issues are made non-confidential, because spam + # may have been added while they were confidential and thus not being checked for spam. + confidential_changed?(from: true, to: false) + end + # Ensure that the metrics association is safely created and respecting the unique constraint on issue_id override :ensure_metrics def ensure_metrics diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb index fcbf1202e69..06512d2fdb9 100644 --- a/app/models/merge_request.rb +++ b/app/models/merge_request.rb @@ -300,6 +300,11 @@ class MergeRequest < ApplicationRecord query = joins(:metrics) + if !target_project_id && self.where_values_hash["target_project_id"] + target_project_id = self.where_values_hash["target_project_id"] + query = query.unscope(where: :target_project_id) + end + project_condition = if target_project_id MergeRequest::Metrics.arel_table[:target_project_id].eq(target_project_id) else diff --git a/app/views/search/_results.html.haml b/app/views/search/_results.html.haml index 4ba906dd02f..d5d3cd753f3 100644 --- a/app/views/search/_results.html.haml +++ b/app/views/search/_results.html.haml @@ -1,20 +1,16 @@ - search_bar_classes = 'search-sidebar gl-display-flex gl-flex-direction-column gl-mr-4' += render_if_exists 'shared/promotions/promote_advanced_search' += render partial: 'search/results_status', locals: { search_service: @search_service } unless @search_objects.to_a.empty? -- if @search_objects.to_a.empty? - .gl-md-display-flex - - if %w(issues merge_requests).include?(@scope) - #js-search-sidebar{ class: search_bar_classes } - .gl-w-full.gl-flex-grow-1.gl-overflow-x-hidden +.results.gl-md-display-flex.gl-mt-3 + - if %w(issues merge_requests).include?(@scope) + #js-search-sidebar{ class: search_bar_classes } + .gl-w-full.gl-flex-grow-1.gl-overflow-x-hidden + - if @timeout + = render partial: "search/results/timeout" + - elsif @search_objects.to_a.empty? = render partial: "search/results/empty" - = render_if_exists 'shared/promotions/promote_advanced_search' -- else - = render partial: 'search/results_status', locals: { search_service: @search_service } - = render_if_exists 'shared/promotions/promote_advanced_search' - - .results.gl-md-display-flex.gl-mt-3 - - if %w(issues merge_requests).include?(@scope) - #js-search-sidebar{ class: search_bar_classes } - .gl-w-full.gl-flex-grow-1.gl-overflow-x-hidden + - else - if @scope == 'commits' %ul.content-list.commit-list = render partial: "search/results/commit", collection: @search_objects diff --git a/app/views/search/results/_timeout.html.haml b/app/views/search/results/_timeout.html.haml new file mode 100644 index 00000000000..740e2bedd54 --- /dev/null +++ b/app/views/search/results/_timeout.html.haml @@ -0,0 +1,10 @@ +.gl-display-flex.gl-flex-direction-column.gl-align-items-center + %div + .svg-content.svg-150 + = image_tag 'illustrations/search-timeout-md.svg' + %div + %h4.gl-text-center.gl-font-weight-bold= _('Your search timed out') + %p.gl-text-center= _('To resolve this, try to:') + %ul + %li= html_escape(_('Refine your search criteria (select a %{strong_open}group%{strong_close} and %{strong_open}project%{strong_close} when possible)')) % { strong_open: ''.html_safe, strong_close: ''.html_safe } + %li= html_escape(_('Use double quotes for multiple keywords, such as %{code_open}"your search"%{code_close}')) % { code_open: ''.html_safe, code_close: ''.html_safe } diff --git a/app/views/shared/issuable/_sidebar.html.haml b/app/views/shared/issuable/_sidebar.html.haml index 5156ad96684..82f03421799 100644 --- a/app/views/shared/issuable/_sidebar.html.haml +++ b/app/views/shared/issuable/_sidebar.html.haml @@ -58,7 +58,7 @@ #js-severity - if issuable_sidebar.dig(:features_available, :health_status) - .js-sidebar-status-entry-point + .js-sidebar-status-entry-point{ data: sidebar_status_data(issuable_sidebar, @project) } - if issuable_sidebar.has_key?(:confidential) %script#js-confidential-issue-data{ type: "application/json" }= { is_confidential: issuable_sidebar[:confidential], is_editable: can_edit_issuable }.to_json.html_safe diff --git a/app/views/shared/issuable/_sort_dropdown.html.haml b/app/views/shared/issuable/_sort_dropdown.html.haml index 9e3caf62d77..caf271e9ee9 100644 --- a/app/views/shared/issuable/_sort_dropdown.html.haml +++ b/app/views/shared/issuable/_sort_dropdown.html.haml @@ -1,6 +1,7 @@ - sort_value = @sort - sort_title = issuable_sort_option_title(sort_value) - viewing_issues = controller.controller_name == 'issues' || controller.action_name == 'issues' +- viewing_merge_requests = controller.controller_name == 'merge_requests' .dropdown.inline.gl-ml-3.issue-sort-dropdown .btn-group{ role: 'group' } @@ -17,6 +18,7 @@ = sortable_item(sort_title_due_date, page_filter_path(sort: sort_value_due_date), sort_title) if viewing_issues = sortable_item(sort_title_popularity, page_filter_path(sort: sort_value_popularity), sort_title) = sortable_item(sort_title_label_priority, page_filter_path(sort: sort_value_label_priority), sort_title) + = sortable_item(sort_title_merged_date, page_filter_path(sort: sort_value_merged_date), sort_title) if viewing_merge_requests = sortable_item(sort_title_relative_position, page_filter_path(sort: sort_value_relative_position), sort_title) if viewing_issues = render_if_exists('shared/ee/issuable/sort_dropdown', viewing_issues: viewing_issues, sort_title: sort_title) = issuable_sort_direction_button(sort_value) diff --git a/app/workers/container_expiration_policies/cleanup_container_repository_worker.rb b/app/workers/container_expiration_policies/cleanup_container_repository_worker.rb index 3027d46b8b1..33dda6a8f0c 100644 --- a/app/workers/container_expiration_policies/cleanup_container_repository_worker.rb +++ b/app/workers/container_expiration_policies/cleanup_container_repository_worker.rb @@ -49,15 +49,11 @@ module ContainerExpirationPolicies end def remaining_work_count - total_count = cleanup_scheduled_count + cleanup_unfinished_count + count = cleanup_scheduled_count - log_info( - cleanup_scheduled_count: cleanup_scheduled_count, - cleanup_unfinished_count: cleanup_unfinished_count, - cleanup_total_count: total_count - ) + return count if count > max_running_jobs - total_count + count + cleanup_unfinished_count end private diff --git a/app/workers/container_expiration_policy_worker.rb b/app/workers/container_expiration_policy_worker.rb index 8fc139ac87c..a35ca5d184e 100644 --- a/app/workers/container_expiration_policy_worker.rb +++ b/app/workers/container_expiration_policy_worker.rb @@ -17,6 +17,7 @@ class ContainerExpirationPolicyWorker # rubocop:disable Scalability/IdempotentWo process_stale_ongoing_cleanups disable_policies_without_container_repositories throttling_enabled? ? perform_throttled : perform_unthrottled + log_counts end private @@ -28,6 +29,26 @@ class ContainerExpirationPolicyWorker # rubocop:disable Scalability/IdempotentWo end end + def log_counts + use_replica_if_available do + required_count = ContainerRepository.requiring_cleanup.count + unfinished_count = ContainerRepository.with_unfinished_cleanup.count + + log_extra_metadata_on_done(:cleanup_required_count, required_count) + log_extra_metadata_on_done(:cleanup_unfinished_count, unfinished_count) + log_extra_metadata_on_done(:cleanup_total_count, required_count + unfinished_count) + end + end + + # data_consistency :delayed not used as this is a cron job and those jobs are + # not perfomed with a delay + # https://gitlab.com/gitlab-org/gitlab/-/merge_requests/63635#note_603771207 + def use_replica_if_available(&blk) + return yield unless ::Gitlab::Database::LoadBalancing.enable? + + ::Gitlab::Database::LoadBalancing::Session.current.use_replicas_for_read_queries(&blk) + end + def process_stale_ongoing_cleanups threshold = delete_tags_service_timeout.seconds + 30.minutes ContainerRepository.with_stale_ongoing_cleanup(threshold.ago) diff --git a/db/migrate/20210705130919_create_container_repos_on_exp_cleanup_status_project_id_start_date_index.rb b/db/migrate/20210705130919_create_container_repos_on_exp_cleanup_status_project_id_start_date_index.rb new file mode 100644 index 00000000000..a6983c2d599 --- /dev/null +++ b/db/migrate/20210705130919_create_container_repos_on_exp_cleanup_status_project_id_start_date_index.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +# See https://docs.gitlab.com/ee/development/migration_style_guide.html +# for more information on how to write migrations for GitLab. + +class CreateContainerReposOnExpCleanupStatusProjectIdStartDateIndex < ActiveRecord::Migration[6.1] + include Gitlab::Database::MigrationHelpers + + DOWNTIME = false + OLD_INDEX_NAME = 'idx_container_repositories_on_exp_cleanup_status_and_start_date' + NEW_INDEX_NAME = 'idx_container_repos_on_exp_cleanup_status_project_id_start_date' + + disable_ddl_transaction! + + def up + add_concurrent_index(:container_repositories, [:expiration_policy_cleanup_status, :project_id, :expiration_policy_started_at], name: NEW_INDEX_NAME) + remove_concurrent_index(:container_repositories, [:expiration_policy_cleanup_status, :expiration_policy_started_at], name: OLD_INDEX_NAME) + end + + def down + add_concurrent_index(:container_repositories, [:expiration_policy_cleanup_status, :expiration_policy_started_at], name: OLD_INDEX_NAME) + remove_concurrent_index(:container_repositories, [:expiration_policy_cleanup_status, :project_id, :expiration_policy_started_at], name: NEW_INDEX_NAME) + end +end diff --git a/db/schema_migrations/20210705130919 b/db/schema_migrations/20210705130919 new file mode 100644 index 00000000000..9e0b9ffe69a --- /dev/null +++ b/db/schema_migrations/20210705130919 @@ -0,0 +1 @@ +c33dd2c63d5a8c6e3c2f49e640b1780734b4bfca88378fac67ea5f5bd24fb2b4 \ No newline at end of file diff --git a/db/structure.sql b/db/structure.sql index 2861a545945..21dd89ceedc 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -22536,7 +22536,7 @@ CREATE INDEX idx_container_exp_policies_on_project_id_next_run_at ON container_e CREATE INDEX idx_container_exp_policies_on_project_id_next_run_at_enabled ON container_expiration_policies USING btree (project_id, next_run_at, enabled); -CREATE INDEX idx_container_repositories_on_exp_cleanup_status_and_start_date ON container_repositories USING btree (expiration_policy_cleanup_status, expiration_policy_started_at); +CREATE INDEX idx_container_repos_on_exp_cleanup_status_project_id_start_date ON container_repositories USING btree (expiration_policy_cleanup_status, project_id, expiration_policy_started_at); CREATE INDEX idx_deployment_clusters_on_cluster_id_and_kubernetes_namespace ON deployment_clusters USING btree (cluster_id, kubernetes_namespace); diff --git a/doc/development/code_review.md b/doc/development/code_review.md index 000c909664a..20530d805ca 100644 --- a/doc/development/code_review.md +++ b/doc/development/code_review.md @@ -74,6 +74,7 @@ page, with these behaviors: 1. It doesn't pick people whose Slack or [GitLab status](../user/profile/index.md#set-your-current-status): - contains the string 'OOO', 'PTO', 'Parental Leave', or 'Friends and Family' - emoji is `:palm_tree:`, `:beach:`, `:beach_umbrella:`, `:beach_with_umbrella:`, `:ferris_wheel:`, `:thermometer:`, `:face_with_thermometer:`, `:red_circle:`, `:bulb:`, `:sun_with_face:`. + - GitLab user busy indicator is set to true 1. [Trainee maintainers](https://about.gitlab.com/handbook/engineering/workflow/code-review/#trainee-maintainer) are three times as likely to be picked as other reviewers. 1. Team members whose Slack or [GitLab status](../user/profile/index.md#set-your-current-status) emoji diff --git a/doc/development/pipelines.md b/doc/development/pipelines.md index dd51d981658..b58e644d639 100644 --- a/doc/development/pipelines.md +++ b/doc/development/pipelines.md @@ -92,7 +92,7 @@ graph RL; click 1-5 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=6914312&udv=0" 1-6["setup-test-env (4 minutes)"]; click 1-6 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=6914315&udv=0" - 1-7["review-stop-failed-deployment"]; + 1-7["review-delete-deployment"]; 1-8["dependency_scanning"]; 1-9["qa:internal, qa:internal-as-if-foss"]; 1-11["qa:selectors, qa:selectors-as-if-foss"]; diff --git a/doc/integration/jira/dvcs.md b/doc/integration/jira/dvcs.md index dc23765337b..046dd125cd1 100644 --- a/doc/integration/jira/dvcs.md +++ b/doc/integration/jira/dvcs.md @@ -77,6 +77,7 @@ your integration. - *For GitLab versions 13.0 and later* **and** *Jira versions 8.14 and later,* use the generated `Redirect URL` from [Linking GitLab accounts with Jira](https://confluence.atlassian.com/adminjiraserver/linking-gitlab-accounts-1027142272.html). + - *For GitLab versions 13.0 and later* **and** *Jira Cloud,* use `https:///login/oauth/callback`. - *For GitLab versions 11.3 and later,* use `https:///login/oauth/callback`. If you use GitLab.com, the URL is `https://gitlab.com/login/oauth/callback`. - *For GitLab versions 11.2 and earlier,* use @@ -89,7 +90,7 @@ your integration. ## Configure Jira for DVCS -If you use Jira Cloud and GitLab.com, use the [GitLab for Jira app](connect-app.md) +If you use Jira Cloud, use the [GitLab for Jira app](connect-app.md) unless you specifically need the DVCS Connector. Configure this connection when you want to import all GitLab commits and branches, diff --git a/doc/user/admin_area/custom_project_templates.md b/doc/user/admin_area/custom_project_templates.md index 6cf3c5bbd7d..12d143b3a13 100644 --- a/doc/user/admin_area/custom_project_templates.md +++ b/doc/user/admin_area/custom_project_templates.md @@ -9,36 +9,33 @@ type: reference > [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/6860) in [GitLab Premium](https://about.gitlab.com/pricing/) 11.2. -GitLab administrators can configure the group where all the custom project -templates are sourced. +GitLab administrators can set a group to be the source of project templates that are +selectable when a new project is created on the instance. These templates can be selected +when you go to **New project > Create from template** and select the **Instance** tab. -Every project directly under the group namespace will be -available to the user if they have access to them. For example: +Every project in the group, but not its subgroups, can be selected when a new project +is created, based on the user's access permissions: -- Public projects, in the group will be available to every signed-in user, if all enabled [project features](../project/settings/index.md#sharing-and-permissions) +- Public projects can be selected by any signed-in user as a template for a new project, + if all enabled [project features](../project/settings/index.md#sharing-and-permissions) except for GitLab Pages are set to **Everyone With Access**. -- Private projects will be available only if the user is a member of the project. +- Private projects can be selected only by users who are members of the projects. Repository and database information that are copied over to each new project are -identical to the data exported with the -[GitLab Project Import/Export](../project/settings/import_export.md). +identical to the data exported with the [GitLab Project Import/Export](../project/settings/import_export.md). -NOTE: -To set project templates at a group level, -see [Custom group-level project templates](../group/custom_project_templates.md). +To set project templates at the group level, see [Custom group-level project templates](../group/custom_project_templates.md). -## Configuring +## Select instance-level project template group -GitLab administrators can configure a GitLab group that serves as template -source for an entire GitLab instance: +To select the group to use as the source for the project templates: 1. On the top bar, navigate to **Menu > Admin > Settings > Templates**. 1. Expand **Custom project templates**. 1. Select a group to use. 1. Select **Save changes**. -NOTE: -Projects below subgroups of the template group are **not** supported. +Projects in subgroups of the template group are **not** included in the template list.