summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcia Ramos <virtua.creative@gmail.com>2018-09-24 18:32:21 +0100
committerMarcia Ramos <virtua.creative@gmail.com>2018-09-24 18:32:21 +0100
commit49364e69855f92b0eb0c8207a3349979970eb95f (patch)
tree395c873ff977f0478ba5042fe38b1ff33225514a
parenteee9b8d47c0fe94aa46679b435a082ad461e123b (diff)
parent62dde35069e430101e52359fbdba3fa14720195d (diff)
downloadgitlab-ce-49364e69855f92b0eb0c8207a3349979970eb95f.tar.gz
Merge branch 'master' of gitlab.com:gitlab-org/gitlab-ce into docs-50507-pages-overview
-rw-r--r--.eslintrc.yml21
-rw-r--r--.gitlab-ci.yml16
-rw-r--r--.rubocop.yml2
-rw-r--r--.rubocop_todo.yml14
-rw-r--r--CHANGELOG.md259
-rw-r--r--CONTRIBUTING.md2
-rw-r--r--Gemfile.rails5.lock2
-rw-r--r--PROCESS.md55
-rw-r--r--VERSION2
-rw-r--r--app/assets/images/cluster_app_logos/elasticsearch.pngbin0 -> 796 bytes
-rw-r--r--app/assets/images/cluster_app_logos/gitlab.pngbin0 -> 1757 bytes
-rw-r--r--app/assets/images/cluster_app_logos/helm.pngbin0 -> 1438 bytes
-rw-r--r--app/assets/images/cluster_app_logos/jeager.pngbin0 -> 2619 bytes
-rw-r--r--app/assets/images/cluster_app_logos/jupyterhub.pngbin0 -> 895 bytes
-rw-r--r--app/assets/images/cluster_app_logos/kubernetes.pngbin0 -> 1437 bytes
-rw-r--r--app/assets/images/cluster_app_logos/meltano.pngbin0 -> 580 bytes
-rw-r--r--app/assets/images/cluster_app_logos/prometheus.pngbin0 -> 923 bytes
-rw-r--r--app/assets/javascripts/badges/components/badge.vue2
-rw-r--r--app/assets/javascripts/behaviors/index.js6
-rw-r--r--app/assets/javascripts/behaviors/markdown/gfm_auto_complete.js19
-rw-r--r--app/assets/javascripts/behaviors/markdown/render_gfm.js2
-rw-r--r--app/assets/javascripts/behaviors/preview_markdown.js (renamed from app/assets/javascripts/preview_markdown.js)0
-rw-r--r--app/assets/javascripts/behaviors/shortcuts.js35
-rw-r--r--app/assets/javascripts/behaviors/shortcuts/shortcuts.js (renamed from app/assets/javascripts/shortcuts.js)6
-rw-r--r--app/assets/javascripts/behaviors/shortcuts/shortcuts_blob.js (renamed from app/assets/javascripts/shortcuts_blob.js)2
-rw-r--r--app/assets/javascripts/behaviors/shortcuts/shortcuts_find_file.js (renamed from app/assets/javascripts/shortcuts_find_file.js)0
-rw-r--r--app/assets/javascripts/behaviors/shortcuts/shortcuts_issuable.js (renamed from app/assets/javascripts/shortcuts_issuable.js)4
-rw-r--r--app/assets/javascripts/behaviors/shortcuts/shortcuts_navigation.js (renamed from app/assets/javascripts/shortcuts_navigation.js)2
-rw-r--r--app/assets/javascripts/behaviors/shortcuts/shortcuts_network.js (renamed from app/assets/javascripts/shortcuts_network.js)0
-rw-r--r--app/assets/javascripts/behaviors/shortcuts/shortcuts_wiki.js (renamed from app/assets/javascripts/shortcuts_wiki.js)2
-rw-r--r--app/assets/javascripts/boards/components/board_blank_state.vue2
-rw-r--r--app/assets/javascripts/boards/components/board_list.vue4
-rw-r--r--app/assets/javascripts/boards/components/board_new_issue.vue2
-rw-r--r--app/assets/javascripts/boards/components/issue_card_inner.vue4
-rw-r--r--app/assets/javascripts/boards/index.js6
-rw-r--r--app/assets/javascripts/clusters/components/application_row.vue137
-rw-r--r--app/assets/javascripts/clusters/components/applications.vue439
-rw-r--r--app/assets/javascripts/commons/polyfills.js2
-rw-r--r--app/assets/javascripts/commons/polyfills/element.js23
-rw-r--r--app/assets/javascripts/commons/polyfills/svg.js5
-rw-r--r--app/assets/javascripts/deploy_keys/components/key.vue10
-rw-r--r--app/assets/javascripts/diffs/components/diff_file_header.vue4
-rw-r--r--app/assets/javascripts/diffs/components/diff_gutter_avatars.vue2
-rw-r--r--app/assets/javascripts/diffs/components/diff_line_note_form.vue50
-rw-r--r--app/assets/javascripts/diffs/components/inline_diff_table_row.vue6
-rw-r--r--app/assets/javascripts/diffs/components/inline_diff_view.vue4
-rw-r--r--app/assets/javascripts/diffs/components/no_changes.vue2
-rw-r--r--app/assets/javascripts/diffs/components/parallel_diff_comment_row.vue4
-rw-r--r--app/assets/javascripts/diffs/components/parallel_diff_table_row.vue5
-rw-r--r--app/assets/javascripts/diffs/components/parallel_diff_view.vue2
-rw-r--r--app/assets/javascripts/diffs/constants.js1
-rw-r--r--app/assets/javascripts/diffs/store/actions.js40
-rw-r--r--app/assets/javascripts/diffs/store/mutations.js8
-rw-r--r--app/assets/javascripts/diffs/store/utils.js32
-rw-r--r--app/assets/javascripts/dispatcher.js89
-rw-r--r--app/assets/javascripts/dropzone_input.js2
-rw-r--r--app/assets/javascripts/environments/components/empty_state.vue2
-rw-r--r--app/assets/javascripts/environments/components/environments_app.vue2
-rw-r--r--app/assets/javascripts/environments/components/environments_table.vue4
-rw-r--r--app/assets/javascripts/filtered_search/admin_runners_filtered_search_token_keys.js2
-rw-r--r--app/assets/javascripts/filtered_search/components/recent_searches_dropdown_content.vue4
-rw-r--r--app/assets/javascripts/filtered_search/dropdown_hint.js2
-rw-r--r--app/assets/javascripts/filtered_search/issuable_filtered_search_token_keys.js6
-rw-r--r--app/assets/javascripts/frequent_items/components/frequent_items_list_item.vue2
-rw-r--r--app/assets/javascripts/groups/components/item_actions.vue4
-rw-r--r--app/assets/javascripts/ide/components/branches/search_list.vue2
-rw-r--r--app/assets/javascripts/ide/components/commit_sidebar/list.vue4
-rw-r--r--app/assets/javascripts/ide/components/file_finder/index.vue2
-rw-r--r--app/assets/javascripts/ide/components/file_finder/item.vue12
-rw-r--r--app/assets/javascripts/ide/components/file_row_extra.vue104
-rw-r--r--app/assets/javascripts/ide/components/ide_tree_list.vue12
-rw-r--r--app/assets/javascripts/ide/components/jobs/stage.vue2
-rw-r--r--app/assets/javascripts/ide/components/repo_file.vue227
-rw-r--r--app/assets/javascripts/ide/components/repo_file_status_icon.vue2
-rw-r--r--app/assets/javascripts/issuable_bulk_update_actions.js8
-rw-r--r--app/assets/javascripts/issuable_bulk_update_sidebar.js6
-rw-r--r--app/assets/javascripts/issue_show/components/edit_actions.vue2
-rw-r--r--app/assets/javascripts/issue_show/components/title.vue2
-rw-r--r--app/assets/javascripts/jobs/components/header.vue2
-rw-r--r--app/assets/javascripts/jobs/components/job_log_controllers.vue4
-rw-r--r--app/assets/javascripts/jobs/components/jobs_container.vue2
-rw-r--r--app/assets/javascripts/jobs/components/sidebar_details_block.vue2
-rw-r--r--app/assets/javascripts/labels_select.js4
-rw-r--r--app/assets/javascripts/lib/utils/common_utils.js67
-rw-r--r--app/assets/javascripts/lib/utils/navigation_utility.js (renamed from app/assets/javascripts/shortcuts_dashboard_navigation.js)2
-rw-r--r--app/assets/javascripts/main.js14
-rw-r--r--app/assets/javascripts/merge_request_tabs.js3
-rw-r--r--app/assets/javascripts/monitoring/components/dashboard.vue4
-rw-r--r--app/assets/javascripts/monitoring/components/graph/legend.vue4
-rw-r--r--app/assets/javascripts/notebook/index.vue4
-rw-r--r--app/assets/javascripts/notes/components/comment_form.vue2
-rw-r--r--app/assets/javascripts/notes/components/diff_file_header.vue2
-rw-r--r--app/assets/javascripts/notes/components/note_awards_list.vue2
-rw-r--r--app/assets/javascripts/notes/components/note_form.vue4
-rw-r--r--app/assets/javascripts/notes/components/noteable_discussion.vue4
-rw-r--r--app/assets/javascripts/notes/components/notes_app.vue4
-rw-r--r--app/assets/javascripts/notes/stores/actions.js22
-rw-r--r--app/assets/javascripts/notes/stores/mutations.js8
-rw-r--r--app/assets/javascripts/notes/stores/utils.js2
-rw-r--r--app/assets/javascripts/pages/admin/application_settings/index.js5
-rw-r--r--app/assets/javascripts/pages/admin/application_settings/metrics_and_profiling/index.js8
-rw-r--r--app/assets/javascripts/pages/admin/users/components/delete_user_modal.vue5
-rw-r--r--app/assets/javascripts/pages/groups/boards/index.js2
-rw-r--r--app/assets/javascripts/pages/groups/show/index.js2
-rw-r--r--app/assets/javascripts/pages/projects/activity/index.js2
-rw-r--r--app/assets/javascripts/pages/projects/artifacts/browse/index.js2
-rw-r--r--app/assets/javascripts/pages/projects/artifacts/file/index.js2
-rw-r--r--app/assets/javascripts/pages/projects/boards/index.js2
-rw-r--r--app/assets/javascripts/pages/projects/commit/show/index.js2
-rw-r--r--app/assets/javascripts/pages/projects/commits/show/index.js2
-rw-r--r--app/assets/javascripts/pages/projects/find_file/show/index.js2
-rw-r--r--app/assets/javascripts/pages/projects/index.js2
-rw-r--r--app/assets/javascripts/pages/projects/init_blob.js4
-rw-r--r--app/assets/javascripts/pages/projects/issues/form.js2
-rw-r--r--app/assets/javascripts/pages/projects/issues/index/index.js2
-rw-r--r--app/assets/javascripts/pages/projects/issues/show.js2
-rw-r--r--app/assets/javascripts/pages/projects/merge_requests/index/index.js2
-rw-r--r--app/assets/javascripts/pages/projects/merge_requests/init_merge_request.js2
-rw-r--r--app/assets/javascripts/pages/projects/merge_requests/init_merge_request_show.js2
-rw-r--r--app/assets/javascripts/pages/projects/network/show/index.js2
-rw-r--r--app/assets/javascripts/pages/projects/pipeline_schedules/shared/components/interval_pattern_input.vue2
-rw-r--r--app/assets/javascripts/pages/projects/shared/permissions/components/settings_panel.vue12
-rw-r--r--app/assets/javascripts/pages/projects/show/index.js2
-rw-r--r--app/assets/javascripts/pages/projects/tree/show/index.js2
-rw-r--r--app/assets/javascripts/pages/projects/wikis/index.js2
-rw-r--r--app/assets/javascripts/performance_bar/components/performance_bar_app.vue2
-rw-r--r--app/assets/javascripts/pipelines/components/graph/graph_component.vue2
-rw-r--r--app/assets/javascripts/pipelines/components/graph/job_component.vue4
-rw-r--r--app/assets/javascripts/pipelines/components/graph/stage_column_component.vue2
-rw-r--r--app/assets/javascripts/pipelines/components/nav_controls.vue2
-rw-r--r--app/assets/javascripts/pipelines/components/pipeline_url.vue8
-rw-r--r--app/assets/javascripts/pipelines/components/stage.vue2
-rw-r--r--app/assets/javascripts/registry/components/collapsible_container.vue2
-rw-r--r--app/assets/javascripts/registry/components/table_registry.vue2
-rw-r--r--app/assets/javascripts/reports/components/grouped_test_reports_app.vue4
-rw-r--r--app/assets/javascripts/reports/components/report_issues.vue4
-rw-r--r--app/assets/javascripts/search_autocomplete.js6
-rw-r--r--app/assets/javascripts/sidebar/components/time_tracking/time_tracker.vue4
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/deployment.vue2
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_merged.vue8
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_squash_before_merge.vue2
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/nothing_to_merge.vue2
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/ready_to_merge.vue6
-rw-r--r--app/assets/javascripts/vue_shared/components/bar_chart.vue2
-rw-r--r--app/assets/javascripts/vue_shared/components/file_row.vue210
-rw-r--r--app/assets/javascripts/vue_shared/components/header_ci_component.vue6
-rw-r--r--app/assets/javascripts/vue_shared/components/stacked_progress_bar.vue6
-rw-r--r--app/assets/javascripts/vue_shared/components/tooltip_on_truncate.vue2
-rw-r--r--app/assets/javascripts/vue_shared/components/user_avatar/user_avatar_link.vue2
-rw-r--r--app/assets/stylesheets/bootstrap_migration.scss1
-rw-r--r--app/assets/stylesheets/framework/buttons.scss8
-rw-r--r--app/assets/stylesheets/framework/filters.scss5
-rw-r--r--app/assets/stylesheets/framework/lists.scss1
-rw-r--r--app/assets/stylesheets/framework/responsive_tables.scss2
-rw-r--r--app/assets/stylesheets/framework/snippets.scss2
-rw-r--r--app/assets/stylesheets/page_bundles/ide.scss142
-rw-r--r--app/assets/stylesheets/page_bundles/xterm.scss (renamed from app/assets/stylesheets/pages/xterm.scss)2
-rw-r--r--app/assets/stylesheets/pages/boards.scss10
-rw-r--r--app/assets/stylesheets/pages/clusters.scss57
-rw-r--r--app/assets/stylesheets/pages/groups.scss4
-rw-r--r--app/assets/stylesheets/pages/issuable.scss8
-rw-r--r--app/assets/stylesheets/pages/members.scss2
-rw-r--r--app/assets/stylesheets/pages/merge_requests.scss2
-rw-r--r--app/assets/stylesheets/pages/note_form.scss2
-rw-r--r--app/assets/stylesheets/pages/search.scss2
-rw-r--r--app/controllers/abuse_reports_controller.rb2
-rw-r--r--app/controllers/admin/abuse_reports_controller.rb2
-rw-r--r--app/controllers/admin/appearances_controller.rb2
-rw-r--r--app/controllers/admin/application_controller.rb2
-rw-r--r--app/controllers/admin/application_settings_controller.rb34
-rw-r--r--app/controllers/admin/applications_controller.rb2
-rw-r--r--app/controllers/admin/background_jobs_controller.rb2
-rw-r--r--app/controllers/admin/broadcast_messages_controller.rb2
-rw-r--r--app/controllers/admin/dashboard_controller.rb2
-rw-r--r--app/controllers/admin/deploy_keys_controller.rb2
-rw-r--r--app/controllers/admin/gitaly_servers_controller.rb2
-rw-r--r--app/controllers/admin/groups_controller.rb2
-rw-r--r--app/controllers/admin/health_check_controller.rb2
-rw-r--r--app/controllers/admin/hook_logs_controller.rb2
-rw-r--r--app/controllers/admin/hooks_controller.rb2
-rw-r--r--app/controllers/admin/identities_controller.rb2
-rw-r--r--app/controllers/admin/impersonation_tokens_controller.rb2
-rw-r--r--app/controllers/admin/impersonations_controller.rb2
-rw-r--r--app/controllers/admin/jobs_controller.rb2
-rw-r--r--app/controllers/admin/keys_controller.rb2
-rw-r--r--app/controllers/admin/labels_controller.rb2
-rw-r--r--app/controllers/admin/logs_controller.rb2
-rw-r--r--app/controllers/admin/projects_controller.rb2
-rw-r--r--app/controllers/admin/requests_profiles_controller.rb2
-rw-r--r--app/controllers/admin/runner_projects_controller.rb2
-rw-r--r--app/controllers/admin/runners_controller.rb2
-rw-r--r--app/controllers/admin/spam_logs_controller.rb2
-rw-r--r--app/controllers/admin/system_info_controller.rb2
-rw-r--r--app/controllers/admin/users_controller.rb2
-rw-r--r--app/controllers/application_controller.rb2
-rw-r--r--app/controllers/autocomplete_controller.rb2
-rw-r--r--app/controllers/boards/application_controller.rb2
-rw-r--r--app/controllers/boards/issues_controller.rb2
-rw-r--r--app/controllers/boards/lists_controller.rb2
-rw-r--r--app/controllers/ci/lints_controller.rb2
-rw-r--r--app/controllers/concerns/accepts_pending_invitations.rb2
-rw-r--r--app/controllers/concerns/authenticates_with_two_factor.rb2
-rw-r--r--app/controllers/concerns/boards_responses.rb2
-rw-r--r--app/controllers/concerns/checks_collaboration.rb2
-rw-r--r--app/controllers/concerns/continue_params.rb2
-rw-r--r--app/controllers/concerns/controller_with_cross_project_access_check.rb2
-rw-r--r--app/controllers/concerns/creates_commit.rb4
-rw-r--r--app/controllers/concerns/cycle_analytics_params.rb2
-rw-r--r--app/controllers/concerns/diff_for_path.rb2
-rw-r--r--app/controllers/concerns/enforces_two_factor_authentication.rb2
-rw-r--r--app/controllers/concerns/group_tree.rb2
-rw-r--r--app/controllers/concerns/hooks_execution.rb2
-rw-r--r--app/controllers/concerns/internal_redirect.rb8
-rw-r--r--app/controllers/concerns/issuable_actions.rb2
-rw-r--r--app/controllers/concerns/issuable_collections.rb2
-rw-r--r--app/controllers/concerns/issues_action.rb2
-rw-r--r--app/controllers/concerns/issues_calendar.rb2
-rw-r--r--app/controllers/concerns/lfs_request.rb2
-rw-r--r--app/controllers/concerns/members_presentation.rb2
-rw-r--r--app/controllers/concerns/membership_actions.rb2
-rw-r--r--app/controllers/concerns/merge_requests_action.rb2
-rw-r--r--app/controllers/concerns/milestone_actions.rb2
-rw-r--r--app/controllers/concerns/notes_actions.rb50
-rw-r--r--app/controllers/concerns/oauth_applications.rb2
-rw-r--r--app/controllers/concerns/params_backward_compatibility.rb2
-rw-r--r--app/controllers/concerns/preview_markdown.rb2
-rw-r--r--app/controllers/concerns/renders_blob.rb2
-rw-r--r--app/controllers/concerns/renders_commits.rb2
-rw-r--r--app/controllers/concerns/renders_member_access.rb2
-rw-r--r--app/controllers/concerns/renders_notes.rb2
-rw-r--r--app/controllers/concerns/repository_settings_redirect.rb2
-rw-r--r--app/controllers/concerns/requires_whitelisted_monitoring_client.rb2
-rw-r--r--app/controllers/concerns/routable_actions.rb2
-rw-r--r--app/controllers/concerns/send_file_upload.rb2
-rw-r--r--app/controllers/concerns/service_params.rb2
-rw-r--r--app/controllers/concerns/snippets_actions.rb2
-rw-r--r--app/controllers/concerns/spammable_actions.rb2
-rw-r--r--app/controllers/concerns/todos_actions.rb2
-rw-r--r--app/controllers/concerns/toggle_award_emoji.rb2
-rw-r--r--app/controllers/concerns/toggle_subscription_action.rb2
-rw-r--r--app/controllers/concerns/uploads_actions.rb2
-rw-r--r--app/controllers/concerns/with_performance_bar.rb2
-rw-r--r--app/controllers/concerns/workhorse_request.rb2
-rw-r--r--app/controllers/confirmations_controller.rb4
-rw-r--r--app/controllers/dashboard_controller.rb2
-rw-r--r--app/controllers/graphql_controller.rb2
-rw-r--r--app/controllers/groups/labels_controller.rb5
-rw-r--r--app/controllers/groups_controller.rb2
-rw-r--r--app/controllers/health_check_controller.rb2
-rw-r--r--app/controllers/health_controller.rb2
-rw-r--r--app/controllers/help_controller.rb2
-rw-r--r--app/controllers/ide_controller.rb2
-rw-r--r--app/controllers/invites_controller.rb8
-rw-r--r--app/controllers/jwt_controller.rb2
-rw-r--r--app/controllers/koding_controller.rb2
-rw-r--r--app/controllers/metrics_controller.rb2
-rw-r--r--app/controllers/notification_settings_controller.rb2
-rw-r--r--app/controllers/oauth/applications_controller.rb2
-rw-r--r--app/controllers/omniauth_callbacks_controller.rb9
-rw-r--r--app/controllers/passwords_controller.rb2
-rw-r--r--app/controllers/profiles_controller.rb2
-rw-r--r--app/controllers/projects_controller.rb2
-rw-r--r--app/controllers/registrations_controller.rb2
-rw-r--r--app/controllers/root_controller.rb2
-rw-r--r--app/controllers/search_controller.rb2
-rw-r--r--app/controllers/sent_notifications_controller.rb2
-rw-r--r--app/controllers/sessions_controller.rb2
-rw-r--r--app/controllers/snippets_controller.rb2
-rw-r--r--app/controllers/uploads_controller.rb2
-rw-r--r--app/controllers/user_callouts_controller.rb2
-rw-r--r--app/controllers/users_controller.rb2
-rw-r--r--app/finders/group_labels_finder.rb17
-rw-r--r--app/finders/members_finder.rb2
-rw-r--r--app/finders/snippets_finder.rb4
-rw-r--r--app/finders/todos_finder.rb13
-rw-r--r--app/finders/union_finder.rb10
-rw-r--r--app/helpers/application_helper.rb17
-rw-r--r--app/helpers/application_settings_helper.rb4
-rw-r--r--app/helpers/ci_status_helper.rb5
-rw-r--r--app/helpers/services_helper.rb2
-rw-r--r--app/helpers/sorting_helper.rb11
-rw-r--r--app/helpers/tab_helper.rb16
-rw-r--r--app/mailers/previews/notify_preview.rb6
-rw-r--r--app/models/badge.rb2
-rw-r--r--app/models/ci/runner.rb17
-rw-r--r--app/models/concerns/from_union.rb51
-rw-r--r--app/models/concerns/mentionable.rb13
-rw-r--r--app/models/concerns/mentionable/reference_regexes.rb12
-rw-r--r--app/models/concerns/protected_ref_access.rb18
-rw-r--r--app/models/container_repository.rb2
-rw-r--r--app/models/dashboard_group_milestone.rb6
-rw-r--r--app/models/deploy_key.rb2
-rw-r--r--app/models/diff_note.rb2
-rw-r--r--app/models/epic.rb4
-rw-r--r--app/models/event.rb1
-rw-r--r--app/models/group.rb4
-rw-r--r--app/models/label.rb1
-rw-r--r--app/models/merge_request.rb15
-rw-r--r--app/models/milestone.rb5
-rw-r--r--app/models/namespace.rb1
-rw-r--r--app/models/network/commit.rb2
-rw-r--r--app/models/network/graph.rb4
-rw-r--r--app/models/note.rb1
-rw-r--r--app/models/project.rb24
-rw-r--r--app/models/project_authorization.rb8
-rw-r--r--app/models/project_services/asana_service.rb2
-rw-r--r--app/models/project_services/chat_message/merge_message.rb2
-rw-r--r--app/models/project_wiki.rb9
-rw-r--r--app/models/repository.rb1
-rw-r--r--app/models/snippet.rb1
-rw-r--r--app/models/todo.rb1
-rw-r--r--app/models/user.rb55
-rw-r--r--app/models/wiki_page.rb4
-rw-r--r--app/serializers/build_details_entity.rb18
-rw-r--r--app/services/boards/create_service.rb2
-rw-r--r--app/services/boards/issues/list_service.rb5
-rw-r--r--app/services/files/base_service.rb6
-rw-r--r--app/services/labels/transfer_service.rb14
-rw-r--r--app/services/merge_requests/reload_diffs_service.rb10
-rw-r--r--app/services/notes/build_service.rb6
-rw-r--r--app/services/projects/container_repository/destroy_service.rb2
-rw-r--r--app/services/projects/destroy_service.rb19
-rw-r--r--app/services/projects/update_remote_mirror_service.rb1
-rw-r--r--app/validators/url_validator.rb14
-rw-r--r--app/views/abuse_reports/new.html.haml2
-rw-r--r--app/views/admin/appearances/_form.html.haml8
-rw-r--r--app/views/admin/appearances/preview_sign_in.html.haml2
-rw-r--r--app/views/admin/application_settings/ci_cd.html.haml26
-rw-r--r--app/views/admin/application_settings/integrations.html.haml31
-rw-r--r--app/views/admin/application_settings/metrics_and_profiling.html.haml50
-rw-r--r--app/views/admin/application_settings/network.html.haml36
-rw-r--r--app/views/admin/application_settings/preferences.html.haml69
-rw-r--r--app/views/admin/application_settings/reporting.html.haml36
-rw-r--r--app/views/admin/application_settings/repository.html.haml36
-rw-r--r--app/views/admin/application_settings/show.html.haml306
-rw-r--r--app/views/admin/applications/_form.html.haml6
-rw-r--r--app/views/admin/broadcast_messages/_form.html.haml4
-rw-r--r--app/views/admin/dashboard/index.html.haml6
-rw-r--r--app/views/admin/deploy_keys/edit.html.haml2
-rw-r--r--app/views/admin/deploy_keys/index.html.haml2
-rw-r--r--app/views/admin/deploy_keys/new.html.haml2
-rw-r--r--app/views/admin/groups/_form.html.haml4
-rw-r--r--app/views/admin/groups/index.html.haml2
-rw-r--r--app/views/admin/groups/show.html.haml2
-rw-r--r--app/views/admin/hooks/edit.html.haml2
-rw-r--r--app/views/admin/hooks/index.html.haml2
-rw-r--r--app/views/admin/identities/_form.html.haml2
-rw-r--r--app/views/admin/identities/index.html.haml2
-rw-r--r--app/views/admin/labels/_form.html.haml2
-rw-r--r--app/views/admin/labels/index.html.haml2
-rw-r--r--app/views/admin/projects/index.html.haml2
-rw-r--r--app/views/admin/runners/_runner.html.haml104
-rw-r--r--app/views/admin/runners/_runner_table_cell.html.haml4
-rw-r--r--app/views/admin/runners/index.html.haml19
-rw-r--r--app/views/admin/services/_form.html.haml2
-rw-r--r--app/views/admin/users/_form.html.haml4
-rw-r--r--app/views/admin/users/index.html.haml2
-rw-r--r--app/views/ci/runner/_how_to_setup_runner.html.haml2
-rw-r--r--app/views/ci/runner/_how_to_setup_specific_runner.html.haml2
-rw-r--r--app/views/dashboard/_groups_head.html.haml2
-rw-r--r--app/views/dashboard/_projects_head.html.haml2
-rw-r--r--app/views/dashboard/_snippets_head.html.haml2
-rw-r--r--app/views/dashboard/snippets/index.html.haml2
-rw-r--r--app/views/devise/passwords/edit.html.haml6
-rw-r--r--app/views/devise/sessions/_new_base.html.haml6
-rw-r--r--app/views/devise/sessions/_new_crowd.html.haml2
-rw-r--r--app/views/devise/sessions/_new_ldap.html.haml6
-rw-r--r--app/views/devise/sessions/two_factor.html.haml2
-rw-r--r--app/views/devise/shared/_tabs_ldap.html.haml4
-rw-r--r--app/views/devise/shared/_tabs_normal.html.haml4
-rw-r--r--app/views/doorkeeper/applications/_form.html.haml2
-rw-r--r--app/views/doorkeeper/applications/index.html.haml3
-rw-r--r--app/views/groups/_group_admin_settings.html.haml4
-rw-r--r--app/views/groups/group_members/_new_group_member.html.haml2
-rw-r--r--app/views/groups/labels/index.html.haml2
-rw-r--r--app/views/groups/milestones/_form.html.haml4
-rw-r--r--app/views/groups/milestones/index.html.haml2
-rw-r--r--app/views/groups/new.html.haml2
-rw-r--r--app/views/groups/settings/_permissions.html.haml2
-rw-r--r--app/views/help/instance_configuration/_gitlab_pages.html.haml2
-rw-r--r--app/views/help/ui.html.haml2
-rw-r--r--app/views/import/fogbugz/new.html.haml2
-rw-r--r--app/views/import/fogbugz/new_user_map.html.haml2
-rw-r--r--app/views/import/gitea/new.html.haml2
-rw-r--r--app/views/import/gitlab_projects/new.html.haml2
-rw-r--r--app/views/import/google_code/new.html.haml2
-rw-r--r--app/views/import/google_code/new_user_map.html.haml2
-rw-r--r--app/views/layouts/nav/sidebar/_admin.html.haml52
-rw-r--r--app/views/layouts/nav/sidebar/_profile.html.haml23
-rw-r--r--app/views/layouts/nav/sidebar/_project.html.haml4
-rw-r--r--app/views/profiles/emails/index.html.haml2
-rw-r--r--app/views/profiles/gpg_keys/_form.html.haml2
-rw-r--r--app/views/profiles/keys/_form.html.haml8
-rw-r--r--app/views/profiles/keys/_key_details.html.haml2
-rw-r--r--app/views/profiles/passwords/edit.html.haml2
-rw-r--r--app/views/profiles/passwords/new.html.haml2
-rw-r--r--app/views/profiles/preferences/show.html.haml2
-rw-r--r--app/views/profiles/two_factor_auths/_codes.html.haml2
-rw-r--r--app/views/projects/_commit_button.html.haml2
-rw-r--r--app/views/projects/_fork_suggestion.html.haml2
-rw-r--r--app/views/projects/_new_project_fields.html.haml2
-rw-r--r--app/views/projects/_readme.html.haml2
-rw-r--r--app/views/projects/blob/_new_dir.html.haml2
-rw-r--r--app/views/projects/blob/_upload.html.haml2
-rw-r--r--app/views/projects/branches/index.html.haml2
-rw-r--r--app/views/projects/branches/new.html.haml2
-rw-r--r--app/views/projects/commit/_change.html.haml2
-rw-r--r--app/views/projects/compare/_form.html.haml2
-rw-r--r--app/views/projects/deploy_keys/_form.html.haml2
-rw-r--r--app/views/projects/deploy_keys/edit.html.haml2
-rw-r--r--app/views/projects/edit.html.haml6
-rw-r--r--app/views/projects/environments/_form.html.haml2
-rw-r--r--app/views/projects/forks/index.html.haml4
-rw-r--r--app/views/projects/hooks/_index.html.haml2
-rw-r--r--app/views/projects/hooks/edit.html.haml2
-rw-r--r--app/views/projects/imports/new.html.haml2
-rw-r--r--app/views/projects/issues/_issue.html.haml6
-rw-r--r--app/views/projects/issues/_nav_btns.html.haml2
-rw-r--r--app/views/projects/issues/show.html.haml2
-rw-r--r--app/views/projects/jobs/_header.html.haml2
-rw-r--r--app/views/projects/jobs/show.html.haml5
-rw-r--r--app/views/projects/labels/index.html.haml2
-rw-r--r--app/views/projects/mattermosts/_team_selection.html.haml2
-rw-r--r--app/views/projects/merge_requests/_merge_request.html.haml6
-rw-r--r--app/views/projects/merge_requests/_nav_btns.html.haml2
-rw-r--r--app/views/projects/merge_requests/creations/_new_compare.html.haml2
-rw-r--r--app/views/projects/merge_requests/diffs/_diffs.html.haml2
-rw-r--r--app/views/projects/milestones/_form.html.haml4
-rw-r--r--app/views/projects/milestones/index.html.haml2
-rw-r--r--app/views/projects/mirrors/_mirror_repos.html.haml2
-rw-r--r--app/views/projects/pages/show.html.haml2
-rw-r--r--app/views/projects/pages_domains/edit.html.haml2
-rw-r--r--app/views/projects/pages_domains/new.html.haml2
-rw-r--r--app/views/projects/pipeline_schedules/_form.html.haml2
-rw-r--r--app/views/projects/pipeline_schedules/index.html.haml2
-rw-r--r--app/views/projects/project_members/_new_project_group.html.haml2
-rw-r--r--app/views/projects/project_members/_new_project_member.html.haml2
-rw-r--r--app/views/projects/project_members/import.html.haml2
-rw-r--r--app/views/projects/protected_branches/shared/_create_protected_branch.html.haml2
-rw-r--r--app/views/projects/protected_tags/shared/_create_protected_tag.html.haml2
-rw-r--r--app/views/projects/releases/edit.html.haml2
-rw-r--r--app/views/projects/runners/_group_runners.html.haml2
-rw-r--r--app/views/projects/settings/ci_cd/_form.html.haml2
-rw-r--r--app/views/projects/snippets/_actions.html.haml2
-rw-r--r--app/views/projects/snippets/index.html.haml2
-rw-r--r--app/views/projects/tags/index.html.haml2
-rw-r--r--app/views/projects/tags/new.html.haml2
-rw-r--r--app/views/projects/triggers/_form.html.haml2
-rw-r--r--app/views/projects/update.js.haml2
-rw-r--r--app/views/projects/wikis/_form.html.haml4
-rw-r--r--app/views/projects/wikis/_main_links.html.haml2
-rw-r--r--app/views/projects/wikis/_new.html.haml2
-rw-r--r--app/views/projects/wikis/edit.html.haml2
-rw-r--r--app/views/shared/_new_project_item_select.html.haml4
-rw-r--r--app/views/shared/_personal_access_tokens_form.html.haml2
-rw-r--r--app/views/shared/_recaptcha_form.html.haml2
-rw-r--r--app/views/shared/_visibility_level.html.haml2
-rw-r--r--app/views/shared/empty_states/_labels.html.haml2
-rw-r--r--app/views/shared/empty_states/_merge_requests.html.haml2
-rw-r--r--app/views/shared/empty_states/_wikis.html.haml4
-rw-r--r--app/views/shared/issuable/_board_create_list_dropdown.html.haml2
-rw-r--r--app/views/shared/issuable/_form.html.haml4
-rw-r--r--app/views/shared/issuable/_search_bar.html.haml5
-rw-r--r--app/views/shared/issuable/_sidebar.html.haml2
-rw-r--r--app/views/shared/issuable/form/_title.html.haml2
-rw-r--r--app/views/shared/labels/_form.html.haml4
-rw-r--r--app/views/shared/notes/_comment_button.html.haml2
-rw-r--r--app/views/shared/notes/_edit_form.html.haml2
-rw-r--r--app/views/shared/runners/_form.html.haml2
-rw-r--r--app/views/shared/runners/_runner_description.html.haml2
-rw-r--r--app/views/shared/snippets/_form.html.haml4
-rw-r--r--app/views/snippets/_actions.html.haml2
-rw-r--r--app/views/snippets/new.html.haml3
-rw-r--r--app/workers/new_merge_request_worker.rb2
-rwxr-xr-xbin/pkgr_before_precompile.sh2
-rw-r--r--changelogs/archive.md16
-rw-r--r--changelogs/unreleased/#47282-Improving-Contributor-On-Boarding-Documentation.yml4
-rw-r--r--changelogs/unreleased/21305-breadcrumb-link-to-issues-on-new-issue-page.yml5
-rw-r--r--changelogs/unreleased/21326-avoid-nil-safe-message.yml5
-rw-r--r--changelogs/unreleased/21371-avatar-fix.yml5
-rw-r--r--changelogs/unreleased/24128-fix-comment-unresolve-discussions.yml5
-rw-r--r--changelogs/unreleased/25990-web-terminal-improvements.yml5
-rw-r--r--changelogs/unreleased/2747-protected-environments-backend-ce.yml5
-rw-r--r--changelogs/unreleased/28930-add-project-reference-filter.yml5
-rw-r--r--changelogs/unreleased/2934-create-new-project-re-add-project-name-field.yml5
-rw-r--r--changelogs/unreleased/29398-support-kubernetes-rbac-for-gitlab-managed-apps.yml5
-rw-r--r--changelogs/unreleased/36048-move-default-branch-settings-under-repository.yml5
-rw-r--r--changelogs/unreleased/36534-show-commit-behind-mr-api.yml5
-rw-r--r--changelogs/unreleased/37356-relative-submodule-link.yml5
-rw-r--r--changelogs/unreleased/38208-due-dates-system-notes.yml5
-rw-r--r--changelogs/unreleased/39665-restrict-issue-reopen.yml5
-rw-r--r--changelogs/unreleased/39923-automatically-disable-auto-devops-for-project.yml5
-rw-r--r--changelogs/unreleased/41040-long-webhook-url-problem.yml5
-rw-r--r--changelogs/unreleased/41292-users-stuck-on-a-redirect-loop-after-transferring-project.yml5
-rw-r--r--changelogs/unreleased/41441-add-target-branch-name-to-cherrypick-confirmation.yml5
-rw-r--r--changelogs/unreleased/41738-fix-sorting-issues-is-wrong-in-list-with-pagination.yml5
-rw-r--r--changelogs/unreleased/41996-copy-to-clipboard-tooltip-appears-under-modal.yml5
-rw-r--r--changelogs/unreleased/42754-runners-pagination.yml5
-rw-r--r--changelogs/unreleased/43096-controller-projects-issuescontroller-referenced_merge_requests-json-executes-more-than-100-sql-queries.yml5
-rw-r--r--changelogs/unreleased/43140-reduce-logs-tree-load.yml5
-rw-r--r--changelogs/unreleased/43625-increase-modal-checkout.yml5
-rw-r--r--changelogs/unreleased/44005-improve-handling-of-projects-shared-with-a-group.yml5
-rw-r--r--changelogs/unreleased/44704-improve-project-overview-ui.yml5
-rw-r--r--changelogs/unreleased/44768-lazy-load-xterm-css.yml5
-rw-r--r--changelogs/unreleased/44943-update-presentation-for-sso-providers-on-log-in-page.yml5
-rw-r--r--changelogs/unreleased/44998-split-admin-settings-into-multiple-sub-pages.yml5
-rw-r--r--changelogs/unreleased/45663-tag-quick-action-on-commit-comments.yml5
-rw-r--r--changelogs/unreleased/45754-issue-mr-and-archived-projects.yml5
-rw-r--r--changelogs/unreleased/45754-open-issues-from-archived-project-listed-in-group-issue-board.yml5
-rw-r--r--changelogs/unreleased/45938-postgres-timeout-when-counting-number-of-ci-builds-for-usage-ping.yml5
-rw-r--r--changelogs/unreleased/46340-remove-extra-spaces-from-mr-discussion-notes.yml5
-rw-r--r--changelogs/unreleased/46591-fix-ide-height-issues.yml5
-rw-r--r--changelogs/unreleased/46733-move-filter-dropdown-from-font-awesome-to-our-own-icons.yml5
-rw-r--r--changelogs/unreleased/47398-user-is-unable-revoke-a-authorized-application-unless-user-oauth-applications-is-checked-in-admin-settings.yml6
-rw-r--r--changelogs/unreleased/47440-recognize-unlicense-license-file.yml5
-rw-r--r--changelogs/unreleased/47752-buttons-on-new-file-page-wrap-outside-of-container-for-long-branch-names.yml5
-rw-r--r--changelogs/unreleased/47765-group-visibility-error-due-to-string-conversion.yml6
-rw-r--r--changelogs/unreleased/47845-propagate_failure_reason-to-job-webhook.yml5
-rw-r--r--changelogs/unreleased/47943-project-milestone-page-deprecation-message.yml5
-rw-r--r--changelogs/unreleased/48145-illustration.yml5
-rw-r--r--changelogs/unreleased/48167-fix-outdated-discussions-new-datastructure.yml5
-rw-r--r--changelogs/unreleased/48320-cancel-a-created-job.yml5
-rw-r--r--changelogs/unreleased/48778-remove-old-storage-logic-from-import-export.yml5
-rw-r--r--changelogs/unreleased/48869-wiki-slugs-with-spaces.yml5
-rw-r--r--changelogs/unreleased/48942-rename-backlog-list-to-open-issue-boards.yml5
-rw-r--r--changelogs/unreleased/48967-disable-statement-timeout.yml5
-rw-r--r--changelogs/unreleased/49110-update-mr-widget-styles.yml5
-rw-r--r--changelogs/unreleased/49292-add-group-name-badge-under-milestone.yml5
-rw-r--r--changelogs/unreleased/49632-clean-up-the-top-section-of-the-cluster-page.yml5
-rw-r--r--changelogs/unreleased/49644-make-margin-of-user-status-emoji-consistent.yml5
-rw-r--r--changelogs/unreleased/49770-fixes-input-alignment-on-user-admin-form-with-errors.yml5
-rw-r--r--changelogs/unreleased/49796-project-deletion-may-not-log-audit-events-during-group-deletion.yml5
-rw-r--r--changelogs/unreleased/49796-project-deletion-may-not-log-audit-events-during-user-deletion.yml5
-rw-r--r--changelogs/unreleased/49905-fix-checkboxes-runners.yml5
-rw-r--r--changelogs/unreleased/49953-add-user_show_add_ssh_key_message-setting.yml5
-rw-r--r--changelogs/unreleased/49993-fix-remember-sorting-issue-mr.yml5
-rw-r--r--changelogs/unreleased/50019-remove-redundant-header-from-metrics-page.yml5
-rw-r--r--changelogs/unreleased/50047-spam-logs-pagination.yml5
-rw-r--r--changelogs/unreleased/50063-add-missing-i18n-strings-to-issue-boards.yml5
-rw-r--r--changelogs/unreleased/50101-add-artifact-information-to-job-api.yml5
-rw-r--r--changelogs/unreleased/50101-aritfacts-block.yml5
-rw-r--r--changelogs/unreleased/50101-builds-dropdown.yml6
-rw-r--r--changelogs/unreleased/50101-commit-block.yml5
-rw-r--r--changelogs/unreleased/50101-empty-state-component.yml5
-rw-r--r--changelogs/unreleased/50101-env-block.yml5
-rw-r--r--changelogs/unreleased/50101-erased-block.yml5
-rw-r--r--changelogs/unreleased/50101-job-log-component.yml5
-rw-r--r--changelogs/unreleased/50101-stuck-component.yml5
-rw-r--r--changelogs/unreleased/50101-trigger.yml5
-rw-r--r--changelogs/unreleased/50101-truncated-job-information.yml5
-rw-r--r--changelogs/unreleased/50111-improve-design-of-cluster-apps-to-handle-larger-quantity.yml5
-rw-r--r--changelogs/unreleased/50126-blocked-user-card.yml5
-rw-r--r--changelogs/unreleased/50180-fa-icon-google-audit.yml5
-rw-r--r--changelogs/unreleased/50243-auto-devops-behind-a-proxy.yml6
-rw-r--r--changelogs/unreleased/50345-hashed-storage-feature-flag.yml5
-rw-r--r--changelogs/unreleased/50414-rubocop-rule-to-enforce-class-methods-over-module.yml5
-rw-r--r--changelogs/unreleased/50441-high-number-of-statement-timeouts-in-groupdestroyworker-due-to-sitestatistics.yml5
-rw-r--r--changelogs/unreleased/50452-breadcrumb-link-to-new-merge-requests.yml5
-rw-r--r--changelogs/unreleased/50524-artifacts-sm.yml5
-rw-r--r--changelogs/unreleased/50535-display-banner-to-notify-user-if-project-is-implicitly-opted-ado.yml5
-rw-r--r--changelogs/unreleased/50564-chat-service-refactoring.yml5
-rw-r--r--changelogs/unreleased/50567-remove-usage-ping-payload-from-cohorts-add-to-settings.yml5
-rw-r--r--changelogs/unreleased/50584-fix-ide-commit-twice.yml5
-rw-r--r--changelogs/unreleased/50657-migrate-issue-labels-and-milestone-to-related-mr-on-creation.yml5
-rw-r--r--changelogs/unreleased/50801-error-getting-performance-bar-results-for-uuid.yml5
-rw-r--r--changelogs/unreleased/50823-not-properly-filled-in-activity-RSS-feed-yml.yml5
-rw-r--r--changelogs/unreleased/50853-vendor-auto-devops-gitlab-ci-yml-to-resolve-redeploying-deleted-app-gives-helm-error.yml5
-rw-r--r--changelogs/unreleased/50879-unused-css-container-fluid.yml5
-rw-r--r--changelogs/unreleased/50930-update-rubyzip-to-1-2-2.yml5
-rw-r--r--changelogs/unreleased/50936-docs-run-review-cleanup-only-for-gitlab-org-repos.yml5
-rw-r--r--changelogs/unreleased/50944-unable-to-import-repository-undefined-method-import_file-for-nil-nilclass.yml5
-rw-r--r--changelogs/unreleased/50956-web-terminal.yml5
-rw-r--r--changelogs/unreleased/51050-fix.yml5
-rw-r--r--changelogs/unreleased/51092-fix-mr-diff-file-filter-clear-button.yml5
-rw-r--r--changelogs/unreleased/51117-send-terminal-path-in-job-api.yml5
-rw-r--r--changelogs/unreleased/51180-update-ffi-to-1-9-25.yml5
-rw-r--r--changelogs/unreleased/51273-expose-runners-for-build-in-job-api.yml5
-rw-r--r--changelogs/unreleased/51281-on-master-diff-view-contains-extra-and-signs.yml5
-rw-r--r--changelogs/unreleased/51282-link-to-user-snippets-on-new-user-snippet-page.yml5
-rw-r--r--changelogs/unreleased/51318-project-export-broken-when-avatar-is-set.yml5
-rw-r--r--changelogs/unreleased/51412-username-alignment-issue-on-mr-page.yml5
-rw-r--r--changelogs/unreleased/51549-runners-table.yml5
-rw-r--r--changelogs/unreleased/51564-fix-commit-email-usage.yml5
-rw-r--r--changelogs/unreleased/51571-wrapper-rake-task-uploads-migrate-os.yml5
-rw-r--r--changelogs/unreleased/51725-push-mirrors-default-branch-reset-to-master.yml5
-rw-r--r--changelogs/unreleased/6010_remove_gemnasium_service.yml5
-rw-r--r--changelogs/unreleased/6028-show-generic-percent-stacked-progress-bar.yml6
-rw-r--r--changelogs/unreleased/7573-show-click-to-expand-on-not-rendered-diffs.yml6
-rw-r--r--changelogs/unreleased/_acet-disable-ide-button.yml5
-rw-r--r--changelogs/unreleased/ab-49446-internal-ids-inconsistency.yml5
-rw-r--r--changelogs/unreleased/add-background-migration-for-legacy-traces.yml5
-rw-r--r--changelogs/unreleased/add-ci_archive_traces_cron_worker-to-gitlab-yml.yml5
-rw-r--r--changelogs/unreleased/add-most-stars-for-filter-option.yml5
-rw-r--r--changelogs/unreleased/add-rake-command-to-migrate-locally-persisted-archived-traces.yml5
-rw-r--r--changelogs/unreleased/add_google_noto_color_emoji_font.yml5
-rw-r--r--changelogs/unreleased/align-form-labels.yml5
-rw-r--r--changelogs/unreleased/an-ap_log_gitaly_calls.yml5
-rw-r--r--changelogs/unreleased/an-api-route-logger.yml5
-rw-r--r--changelogs/unreleased/api-empty-commit-message.yml5
-rw-r--r--changelogs/unreleased/api-empty-project-snippets.yml5
-rw-r--r--changelogs/unreleased/api-promote-find-branch.yml5
-rw-r--r--changelogs/unreleased/api-protected-tags.yml5
-rw-r--r--changelogs/unreleased/api-shared_group_expires-at.yml5
-rw-r--r--changelogs/unreleased/arguments-keyword-sast.yml5
-rw-r--r--changelogs/unreleased/ash-mckenzie-geo-git-push-ssh-proxy.yml5
-rw-r--r--changelogs/unreleased/auto-devops-gitlab-ci-glic-228.yml5
-rw-r--r--changelogs/unreleased/bvl-add-czech.yml5
-rw-r--r--changelogs/unreleased/bvl-add-galician.yml5
-rw-r--r--changelogs/unreleased/bvl-merge-base-api.yml5
-rw-r--r--changelogs/unreleased/bw-commonmark-for-files.yml5
-rw-r--r--changelogs/unreleased/ccr-43283_allow_author_upvote.yml5
-rw-r--r--changelogs/unreleased/ccr-48800-ping_for_boards.yml6
-rw-r--r--changelogs/unreleased/ccr-6699_image_for_object_error.yml6
-rw-r--r--changelogs/unreleased/ce-5666-optimize_querying_manageable_groups.yml5
-rw-r--r--changelogs/unreleased/ci-builds-status-index.yml5
-rw-r--r--changelogs/unreleased/dm-create-note-return-discussion.yml5
-rw-r--r--changelogs/unreleased/dz-fix-sql-error-admin-users-2fa.yml5
-rw-r--r--changelogs/unreleased/dz-group-labels-search.yml5
-rw-r--r--changelogs/unreleased/ee-6381-multiseries.yml5
-rw-r--r--changelogs/unreleased/emoji-cutoff-1px.yml5
-rw-r--r--changelogs/unreleased/expose-all-artifacts-sizes-in-jobs-api.yml5
-rw-r--r--changelogs/unreleased/expose-users-id-in-admin-users-show-page.yml5
-rw-r--r--changelogs/unreleased/feat-add-default-avatar-to-group.yml5
-rw-r--r--changelogs/unreleased/feat-update-contribution-calendar.yml5
-rw-r--r--changelogs/unreleased/feature--32877-add-default-field-branch-api.yml5
-rw-r--r--changelogs/unreleased/feature-gb-allow-to-extend-keys-in-gitlab-ci-yml.yml5
-rw-r--r--changelogs/unreleased/feature-git-v2-flag.yml5
-rw-r--r--changelogs/unreleased/feature-whitelist-new-users-as-internal.yml5
-rw-r--r--changelogs/unreleased/filter-web-hooks-by-branch.yml5
-rw-r--r--changelogs/unreleased/fix-api-group-createdat.yml5
-rw-r--r--changelogs/unreleased/fix-chat-notification-service-for-ee.yml5
-rw-r--r--changelogs/unreleased/fix-closing-issues.yml5
-rw-r--r--changelogs/unreleased/fix-download-dropdown-link.yml5
-rw-r--r--changelogs/unreleased/fix-help-text-font-color-in-merge-request-creation.yml5
-rw-r--r--changelogs/unreleased/fix-junit-parser.yml5
-rw-r--r--changelogs/unreleased/fix-labels-list-item-height-with-no-description.yml5
-rw-r--r--changelogs/unreleased/fix-leading-slash-in-redirects-plus-rubocop.yml5
-rw-r--r--changelogs/unreleased/fix-mr-title-fallback-logic.yml5
-rw-r--r--changelogs/unreleased/fix-namespace-upload.yml5
-rw-r--r--changelogs/unreleased/fix-namespace-uploader.yml5
-rw-r--r--changelogs/unreleased/fix-pipeline-fixture-seeder.yml5
-rw-r--r--changelogs/unreleased/fix_emojis_cutting_and_regressions.yml5
-rw-r--r--changelogs/unreleased/fix_event_api_permissions.yml5
-rw-r--r--changelogs/unreleased/fj-2635-enable-rss-for-tags.yml5
-rw-r--r--changelogs/unreleased/fj-33475-files-inside-wiki-repo.yml5
-rw-r--r--changelogs/unreleased/fj-47229-fix-logo-lfs-tracked.yml5
-rw-r--r--changelogs/unreleased/fj-51194-fix-wiki-attachments-with-whitespaces.yml5
-rw-r--r--changelogs/unreleased/fl-reduce-ee-conflicts-reports-code.yml5
-rw-r--r--changelogs/unreleased/force-post-migration-dir-schema-load.yml5
-rw-r--r--changelogs/unreleased/frozen-string-app-controller.yml5
-rw-r--r--changelogs/unreleased/frozen-string-enable-app-mailers.yml5
-rw-r--r--changelogs/unreleased/frozen-string-enable-app-models-even-more-still.yml5
-rw-r--r--changelogs/unreleased/frozen-string-enable-app-vestigial.yml5
-rw-r--r--changelogs/unreleased/gitaly-install-path.yml5
-rw-r--r--changelogs/unreleased/ide-commit-panel-improved.yml5
-rw-r--r--changelogs/unreleased/ide-delete-new-files-state.yml5
-rw-r--r--changelogs/unreleased/ide-file-templates.yml5
-rw-r--r--changelogs/unreleased/ide-header-buttons-tooltip.yml5
-rw-r--r--changelogs/unreleased/ide-job-top-bar-ui-polish.yml5
-rw-r--r--changelogs/unreleased/ide-multiple-file-uploads.yml5
-rw-r--r--changelogs/unreleased/ide-open-empty-merge-request.yml5
-rw-r--r--changelogs/unreleased/ide-row-hover-scroll.yml5
-rw-r--r--changelogs/unreleased/import-all-common-metrics-into-database.yml5
-rw-r--r--changelogs/unreleased/issue_36138.yml5
-rw-r--r--changelogs/unreleased/issue_50488.yml5
-rw-r--r--changelogs/unreleased/jprovazn-fix-form-uploads.yml5
-rw-r--r--changelogs/unreleased/label-event.yml6
-rw-r--r--changelogs/unreleased/limit-navbar-search-for-current-project-or-group-for-small-viewports.yml5
-rw-r--r--changelogs/unreleased/mk-bump-rainbow-gem.yml5
-rw-r--r--changelogs/unreleased/monaco-upgrade.yml5
-rw-r--r--changelogs/unreleased/mr-fixed-expanded-state-not-working.yml5
-rw-r--r--changelogs/unreleased/mr-legacy-diff-notes.yml5
-rw-r--r--changelogs/unreleased/n8rzz-consolidate-specs-testing-emoji-awards.yml6
-rw-r--r--changelogs/unreleased/osw-gitaly-diff-stats-client.yml5
-rw-r--r--changelogs/unreleased/osw-send-max-patch-bytes-to-gitaly.yml5
-rw-r--r--changelogs/unreleased/osw-use-diff-stats-rpc-on-comparison-views.yml5
-rw-r--r--changelogs/unreleased/osw-write-cache-upon-mr-creation-and-cache-refactoring.yml5
-rw-r--r--changelogs/unreleased/rails5-explicit-hashed-path-check.yml6
-rw-r--r--changelogs/unreleased/rails5-fix-duplicate-gpg-signature.yml5
-rw-r--r--changelogs/unreleased/rails5-fix-import-merge-request-creator.yml5
-rw-r--r--changelogs/unreleased/rails5-fix-job-artifact-hashed-path.yml6
-rw-r--r--changelogs/unreleased/rails5-include-opclasses-in-schema-dump.yml5
-rw-r--r--changelogs/unreleased/rails5-mysql-binary-column-index-length.yml5
-rw-r--r--changelogs/unreleased/rails5-silence-stream.yml5
-rw-r--r--changelogs/unreleased/rails5-update-gemfile-lock.yml5
-rw-r--r--changelogs/unreleased/rails5-verbose-query-logs.yml5
-rw-r--r--changelogs/unreleased/rd-26044-new-option-to-prevent-too-big-git-pushes.yml5
-rw-r--r--changelogs/unreleased/remove-background-migration-worker-feature-flag.yml5
-rw-r--r--changelogs/unreleased/remove-zebra-table-background.yml5
-rw-r--r--changelogs/unreleased/repopulate_site_statistics.yml5
-rw-r--r--changelogs/unreleased/runners-online.yml5
-rw-r--r--changelogs/unreleased/schema-changed-ee-backport.yml5
-rw-r--r--changelogs/unreleased/security-49085-persistent-xss-rendering.yml5
-rw-r--r--changelogs/unreleased/sh-add-ua-to-lograge-logs.yml5
-rw-r--r--changelogs/unreleased/sh-block-link-local-master.yml5
-rw-r--r--changelogs/unreleased/sh-bump-fog-google.yml5
-rw-r--r--changelogs/unreleased/sh-bump-gitlab-pages-v1-1-0.yml5
-rw-r--r--changelogs/unreleased/sh-bump-unauth-expiration.yml5
-rw-r--r--changelogs/unreleased/sh-delete-container-registry-async.yml5
-rw-r--r--changelogs/unreleased/sh-delete-tags-outside-transaction.yml5
-rw-r--r--changelogs/unreleased/sh-disable-sidekiq-session.yml5
-rw-r--r--changelogs/unreleased/sh-disable-unnecessary-avatar-revalidation.yml5
-rw-r--r--changelogs/unreleased/sh-fix-attachments-inline.yml5
-rw-r--r--changelogs/unreleased/sh-fix-bitbucket-cloud-importer-replies.yml5
-rw-r--r--changelogs/unreleased/sh-fix-confidential-note-option.yml5
-rw-r--r--changelogs/unreleased/sh-fix-dedupe-group-importer.yml5
-rw-r--r--changelogs/unreleased/sh-fix-error-500-updating-wikis.yml5
-rw-r--r--changelogs/unreleased/sh-fix-issue-50562.yml5
-rw-r--r--changelogs/unreleased/sh-improve-bitbucket-server-logging.yml5
-rw-r--r--changelogs/unreleased/sh-insert-git-data-in-separate-transaction.yml5
-rw-r--r--changelogs/unreleased/sh-limit-commit-renderering.yml5
-rw-r--r--changelogs/unreleased/sh-remove-orphaned-label-links.yml5
-rw-r--r--changelogs/unreleased/sh-sanitize-project-import-names.yml5
-rw-r--r--changelogs/unreleased/sh-send-put-headers-object-storage.yml5
-rw-r--r--changelogs/unreleased/sh-set-secure-cookies.yml5
-rw-r--r--changelogs/unreleased/skip-irrelevant-sql-commands-in-metrics.yml5
-rw-r--r--changelogs/unreleased/tc-api-fork-owners.yml5
-rw-r--r--changelogs/unreleased/tz-mr-incremental-rendering.yml4
-rw-r--r--changelogs/unreleased/update-gitlab-shell-8-3-3.yml5
-rw-r--r--changelogs/unreleased/update-gitlab-shell.yml5
-rw-r--r--changelogs/unreleased/update-padding-markdown.yml5
-rw-r--r--changelogs/unreleased/usage_consent.yml5
-rw-r--r--changelogs/unreleased/vendor-gitlab-ci-auto-devops-yml.yml5
-rw-r--r--changelogs/unreleased/visual-improvements-language-bar.yml5
-rw-r--r--changelogs/unreleased/winh-default-status-emoji.yml5
-rw-r--r--changelogs/unreleased/winh-move-badge-settings.yml5
-rw-r--r--changelogs/unreleased/zj-cleanup-port-gitaly.yml5
-rw-r--r--config/application.rb3
-rw-r--r--config/initializers/0_post_deployment_migrations.rb12
-rw-r--r--config/routes/admin.rb1
-rw-r--r--config/routes/instance_statistics.rb2
-rw-r--r--config/routes/wiki.rb2
-rw-r--r--danger/commit_messages/Dangerfile45
-rw-r--r--db/migrate/20180813101999_change_default_of_auto_devops_instance_wide.rb15
-rw-r--r--db/migrate/20180813102000_enable_auto_devops_instance_wide_for_everyone.rb15
-rw-r--r--db/schema.rb2
-rw-r--r--doc/README.md2
-rw-r--r--doc/administration/auth/ldap.md2
-rw-r--r--doc/administration/external_database.md2
-rw-r--r--doc/administration/gitaly/index.md6
-rw-r--r--doc/administration/high_availability/database.md2
-rw-r--r--doc/administration/high_availability/redis.md10
-rw-r--r--doc/administration/high_availability/redis_source.md4
-rw-r--r--doc/administration/job_artifacts.md1
-rw-r--r--doc/administration/operations/ssh_certificates.md4
-rw-r--r--doc/administration/raketasks/maintenance.md2
-rw-r--r--doc/administration/raketasks/uploads/migrate.md37
-rw-r--r--doc/administration/reply_by_email.md2
-rw-r--r--doc/administration/reply_by_email_postfix_setup.md2
-rw-r--r--doc/administration/uploads.md1
-rw-r--r--doc/api/protected_branches.md2
-rw-r--r--doc/api/settings.md2
-rw-r--r--doc/ci/autodeploy/quick_start_guide.md4
-rw-r--r--doc/ci/environments.md2
-rw-r--r--doc/ci/examples/devops_and_game_dev_with_gitlab_ci_cd/index.md2
-rw-r--r--doc/ci/examples/laravel_with_gitlab_and_envoy/index.md8
-rw-r--r--doc/ci/examples/php.md2
-rw-r--r--doc/ci/runners/README.md6
-rw-r--r--doc/ci/yaml/README.md11
-rw-r--r--doc/development/README.md12
-rw-r--r--doc/development/automatic_ce_ee_merge.md2
-rw-r--r--doc/development/contributing/issue_workflow.md2
-rw-r--r--doc/development/database_debugging.md2
-rw-r--r--doc/development/database_helpers.md63
-rw-r--r--doc/development/documentation/index.md16
-rw-r--r--doc/development/fe_guide/components.md2
-rw-r--r--doc/development/feature_flags.md7
-rw-r--r--doc/development/file_storage.md7
-rw-r--r--doc/development/i18n/proofreader.md1
-rw-r--r--doc/development/module_with_instance_variables.md2
-rw-r--r--doc/development/rake_tasks.md2
-rw-r--r--doc/development/rolling_out_changes_using_feature_flags.md153
-rw-r--r--doc/development/testing_guide/index.md6
-rw-r--r--doc/development/testing_guide/review_apps.md82
-rw-r--r--doc/development/ux_guide/users.md2
-rw-r--r--doc/install/azure/index.md12
-rw-r--r--doc/install/database_mysql.md2
-rw-r--r--doc/install/digitaloceandocker.md2
-rw-r--r--doc/install/installation.md2
-rw-r--r--doc/install/openshift_and_gitlab/index.md2
-rw-r--r--doc/install/relative_url.md2
-rw-r--r--doc/install/requirements.md12
-rw-r--r--doc/integration/gmail_action_buttons_for_gitlab.md2
-rw-r--r--doc/policy/maintenance.md2
-rw-r--r--doc/security/two_factor_authentication.md2
-rw-r--r--doc/topics/authentication/index.md2
-rw-r--r--doc/topics/autodevops/index.md20
-rw-r--r--doc/university/glossary/README.md4
-rw-r--r--doc/university/high-availability/aws/README.md2
-rw-r--r--doc/university/support/README.md2
-rw-r--r--doc/university/training/end-user/README.md2
-rw-r--r--doc/update/4.2-to-5.0.md2
-rw-r--r--doc/update/7.5-to-7.6.md2
-rw-r--r--doc/update/7.6-to-7.7.md2
-rw-r--r--doc/update/7.7-to-7.8.md2
-rw-r--r--doc/update/7.8-to-7.9.md2
-rw-r--r--doc/update/7.9-to-7.10.md2
-rw-r--r--doc/update/9.4-to-9.5.md2
-rw-r--r--doc/update/9.5-to-10.0.md2
-rw-r--r--doc/user/profile/account/delete_account.md3
-rw-r--r--doc/user/profile/account/two_factor_authentication.md2
-rw-r--r--doc/user/project/container_registry.md2
-rw-r--r--doc/user/project/cycle_analytics.md2
-rw-r--r--doc/user/project/integrations/hangouts_chat.md2
-rw-r--r--doc/user/project/integrations/img/webhooks_ssl.pngbin27790 -> 58529 bytes
-rw-r--r--doc/user/project/integrations/jira.md2
-rw-r--r--doc/user/project/integrations/mattermost.md2
-rw-r--r--doc/user/project/integrations/mattermost_slash_commands.md2
-rw-r--r--doc/user/project/integrations/microsoft_teams.md2
-rw-r--r--doc/user/project/integrations/mock_ci.md2
-rw-r--r--doc/user/project/integrations/prometheus.md2
-rw-r--r--doc/user/project/integrations/webhooks.md8
-rw-r--r--doc/user/project/issues/issues_functionalities.md2
-rw-r--r--doc/user/project/wiki/index.md13
-rw-r--r--doc/workflow/lfs/lfs_administration.md3
-rw-r--r--lib/api/protected_branches.rb4
-rw-r--r--lib/api/protected_tags.rb2
-rw-r--r--lib/extracts_path.rb2
-rw-r--r--lib/gitlab/auth/ldap/access.rb6
-rw-r--r--lib/gitlab/contributions_calendar.rb5
-rw-r--r--lib/gitlab/database.rb16
-rw-r--r--lib/gitlab/database/grant.rb6
-rw-r--r--lib/gitlab/database/subquery.rb16
-rw-r--r--lib/gitlab/diff/file.rb7
-rw-r--r--lib/gitlab/diff/file_collection/base.rb25
-rw-r--r--lib/gitlab/diff/position.rb6
-rw-r--r--lib/gitlab/git/diff_stats_collection.rb30
-rw-r--r--lib/gitlab/git/repository.rb14
-rw-r--r--lib/gitlab/gitaly_client.rb30
-rw-r--r--lib/gitlab/gitaly_client/commit_service.rb11
-rw-r--r--lib/gitlab/gitaly_client/storage_settings.rb2
-rw-r--r--lib/gitlab/group_hierarchy.rb8
-rw-r--r--lib/gitlab/project_authorizations/with_nested_groups.rb4
-rw-r--r--lib/gitlab/project_authorizations/without_nested_groups.rb4
-rw-r--r--lib/gitlab/template/finders/global_template_finder.rb2
-rw-r--r--lib/gitlab/template/finders/repo_template_finder.rb2
-rw-r--r--lib/gitlab/user_extractor.rb6
-rw-r--r--lib/support/nginx/gitlab4
-rw-r--r--lib/support/nginx/gitlab-ssl4
-rw-r--r--lib/tasks/gitlab/db.rake2
-rw-r--r--lib/tasks/gitlab/uploads/migrate.rake26
-rw-r--r--locale/ar_SA/gitlab.po10
-rw-r--r--locale/bg/gitlab.po10
-rw-r--r--locale/ca_ES/gitlab.po10
-rw-r--r--locale/cs_CZ/gitlab.po10
-rw-r--r--locale/da_DK/gitlab.po10
-rw-r--r--locale/de/gitlab.po10
-rw-r--r--locale/eo/gitlab.po10
-rw-r--r--locale/es/gitlab.po10
-rw-r--r--locale/et_EE/gitlab.po10
-rw-r--r--locale/fil_PH/gitlab.po10
-rw-r--r--locale/fr/gitlab.po10
-rw-r--r--locale/gitlab.pot52
-rw-r--r--locale/gl_ES/gitlab.po10
-rw-r--r--locale/he_IL/gitlab.po10
-rw-r--r--locale/id_ID/gitlab.po10
-rw-r--r--locale/it/gitlab.po10
-rw-r--r--locale/ja/gitlab.po10
-rw-r--r--locale/ko/gitlab.po10
-rw-r--r--locale/nl_NL/gitlab.po10
-rw-r--r--locale/pl_PL/gitlab.po10
-rw-r--r--locale/pt_BR/gitlab.po10
-rw-r--r--locale/ro_RO/gitlab.po10
-rw-r--r--locale/ru/gitlab.po10
-rw-r--r--locale/sq_AL/gitlab.po10
-rw-r--r--locale/tr_TR/gitlab.po10
-rw-r--r--locale/uk/gitlab.po10
-rw-r--r--locale/zh_CN/gitlab.po10
-rw-r--r--locale/zh_HK/gitlab.po10
-rw-r--r--locale/zh_TW/gitlab.po10
-rw-r--r--package.json22
-rw-r--r--qa/qa.rb2
-rw-r--r--qa/qa/factory/repository/project_push.rb18
-rw-r--r--qa/qa/factory/repository/push.rb18
-rw-r--r--qa/qa/factory/repository/wiki_push.rb4
-rw-r--r--qa/qa/factory/resource/branch.rb2
-rw-r--r--qa/qa/factory/resource/project.rb7
-rw-r--r--qa/qa/factory/resource/ssh_key.rb40
-rw-r--r--qa/qa/git/repository.rb37
-rw-r--r--qa/qa/page/admin/settings/main.rb4
-rw-r--r--qa/qa/page/main/login.rb54
-rw-r--r--qa/qa/page/menu/profile.rb7
-rw-r--r--qa/qa/page/menu/side.rb3
-rw-r--r--qa/qa/page/merge_request/show.rb20
-rw-r--r--qa/qa/page/profile/ssh_keys.rb34
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/repository/add_ssh_key_spec.rb31
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/repository/use_ssh_key_spec.rb40
-rw-r--r--rubocop/cop/avoid_route_redirect_leading_slash.rb52
-rw-r--r--rubocop/cop/gitlab/union.rb27
-rw-r--r--rubocop/cop/ruby_interpolation_in_translation.rb1
-rw-r--r--rubocop/rubocop.rb2
-rwxr-xr-xscripts/trigger-build210
-rwxr-xr-xscripts/trigger-build-docs6
-rw-r--r--spec/controllers/oauth/applications_controller_spec.rb34
-rw-r--r--spec/controllers/projects/jobs_controller_spec.rb49
-rw-r--r--spec/controllers/projects/notes_controller_spec.rb8
-rw-r--r--spec/factories/users.rb8
-rw-r--r--spec/features/admin/admin_runners_spec.rb4
-rw-r--r--spec/features/admin/admin_settings_spec.rb513
-rw-r--r--spec/features/admin/admin_uses_repository_checks_spec.rb2
-rw-r--r--spec/features/dashboard/group_spec.rb2
-rw-r--r--spec/features/dashboard/projects_spec.rb8
-rw-r--r--spec/features/issues/filtered_search/filter_issues_spec.rb2
-rw-r--r--spec/features/labels_hierarchy_spec.rb2
-rw-r--r--spec/features/merge_request/user_posts_diff_notes_spec.rb15
-rw-r--r--spec/features/merge_request/user_posts_notes_spec.rb4
-rw-r--r--spec/features/merge_request/user_resolves_conflicts_spec.rb18
-rw-r--r--spec/features/merge_request/user_resolves_diff_notes_and_discussions_resolve_spec.rb79
-rw-r--r--spec/features/projects/blobs/blob_show_spec.rb6
-rw-r--r--spec/features/projects/clusters/user_spec.rb1
-rw-r--r--spec/features/projects/members/invite_group_spec.rb4
-rw-r--r--spec/features/projects/pipelines/pipelines_spec.rb2
-rw-r--r--spec/features/projects/show/user_sees_setup_shortcut_buttons_spec.rb184
-rw-r--r--spec/features/runners_spec.rb4
-rw-r--r--spec/features/snippets/notes_on_personal_snippets_spec.rb2
-rw-r--r--spec/features/snippets/user_sees_breadcrumb_links.rb17
-rw-r--r--spec/finders/group_labels_finder_spec.rb33
-rw-r--r--spec/fixtures/api/schemas/job/job_details.json3
-rw-r--r--spec/fixtures/api/schemas/job/runners.json13
-rw-r--r--spec/helpers/application_helper_spec.rb63
-rw-r--r--spec/helpers/auto_devops_helper_spec.rb10
-rw-r--r--spec/helpers/tab_helper_spec.rb76
-rw-r--r--spec/javascripts/.eslintrc.yml6
-rw-r--r--spec/javascripts/behaviors/shortcuts/shortcuts_issuable_spec.js (renamed from spec/javascripts/shortcuts_issuable_spec.js)2
-rw-r--r--spec/javascripts/boards/board_blank_state_spec.js4
-rw-r--r--spec/javascripts/close_reopen_report_toggle_spec.js2
-rw-r--r--spec/javascripts/diffs/components/diff_line_note_form_spec.js29
-rw-r--r--spec/javascripts/diffs/store/actions_spec.js201
-rw-r--r--spec/javascripts/diffs/store/mutations_spec.js71
-rw-r--r--spec/javascripts/diffs/store/utils_spec.js124
-rw-r--r--spec/javascripts/ide/components/file_row_extra_spec.js159
-rw-r--r--spec/javascripts/ide/components/repo_file_spec.js145
-rw-r--r--spec/javascripts/issue_show/components/edit_actions_spec.js12
-rw-r--r--spec/javascripts/lib/utils/navigation_utility_spec.js (renamed from spec/javascripts/shortcuts_dashboard_navigation_spec.js)2
-rw-r--r--spec/javascripts/lib/utils/poll_spec.js2
-rw-r--r--spec/javascripts/notes/stores/mutation_spec.js35
-rw-r--r--spec/javascripts/right_sidebar_spec.js2
-rw-r--r--spec/javascripts/search_autocomplete_spec.js4
-rw-r--r--spec/javascripts/shortcuts_spec.js2
-rw-r--r--spec/javascripts/vue_shared/components/file_row_spec.js74
-rw-r--r--spec/lib/gitlab/auth/ldap/access_spec.rb10
-rw-r--r--spec/lib/gitlab/database/subquery_spec.rb17
-rw-r--r--spec/lib/gitlab/diff/file_collection/commit_spec.rb15
-rw-r--r--spec/lib/gitlab/diff/file_collection/compare_spec.rb29
-rw-r--r--spec/lib/gitlab/diff/file_collection/merge_request_diff_spec.rb8
-rw-r--r--spec/lib/gitlab/diff/file_spec.rb64
-rw-r--r--spec/lib/gitlab/git/diff_stats_collection_spec.rb26
-rw-r--r--spec/lib/gitlab/git/repository_spec.rb34
-rw-r--r--spec/lib/gitlab/gitaly_client/commit_service_spec.rb16
-rw-r--r--spec/lib/gitlab/middleware/read_only_spec.rb2
-rw-r--r--spec/models/ci/pipeline_spec.rb7
-rw-r--r--spec/models/concerns/from_union_spec.rb40
-rw-r--r--spec/models/instance_configuration_spec.rb2
-rw-r--r--spec/models/milestone_spec.rb18
-rw-r--r--spec/models/project_services/chat_message/merge_message_spec.rb17
-rw-r--r--spec/models/project_spec.rb58
-rw-r--r--spec/models/project_wiki_spec.rb29
-rw-r--r--spec/models/user_spec.rb28
-rw-r--r--spec/requests/api/pipelines_spec.rb16
-rw-r--r--spec/requests/openid_connect_spec.rb2
-rw-r--r--spec/rubocop/cop/avoid_route_redirect_leading_slash_spec.rb32
-rw-r--r--spec/rubocop/cop/gitlab/union_spec.rb25
-rw-r--r--spec/services/auth/container_registry_authentication_service_spec.rb2
-rw-r--r--spec/services/boards/issues/list_service_spec.rb12
-rw-r--r--spec/services/files/create_service_spec.rb16
-rw-r--r--spec/services/files/delete_service_spec.rb11
-rw-r--r--spec/services/files/update_service_spec.rb11
-rw-r--r--spec/services/git_push_service_spec.rb8
-rw-r--r--spec/services/groups/transfer_service_spec.rb2
-rw-r--r--spec/services/notes/build_service_spec.rb15
-rw-r--r--spec/services/projects/container_repository/destroy_service_spec.rb1
-rw-r--r--spec/services/projects/destroy_service_spec.rb2
-rw-r--r--spec/services/projects/update_remote_mirror_service_spec.rb30
-rw-r--r--spec/support/helpers/markdown_feature.rb8
-rw-r--r--spec/support/shared_examples/diff_file_collections.rb47
-rw-r--r--spec/tasks/gitlab/db_rake_spec.rb33
-rw-r--r--spec/validators/url_validator_spec.rb15
-rw-r--r--spec/views/help/index.html.haml_spec.rb4
-rw-r--r--vendor/gitlab-ci-yml/Auto-DevOps.gitlab-ci.yml4
-rw-r--r--yarn.lock505
980 files changed, 6638 insertions, 4309 deletions
diff --git a/.eslintrc.yml b/.eslintrc.yml
index ebf8048f19c..a954bb4ff37 100644
--- a/.eslintrc.yml
+++ b/.eslintrc.yml
@@ -56,6 +56,10 @@ rules:
component: always
svg: always
math: always
+ camelcase:
+ - error
+ - properties: never
+ ignoreDestructuring: true
## Conflicting rules with prettier:
space-before-function-paren: off
curly: off
@@ -63,7 +67,7 @@ rules:
function-paren-newline: off
object-curly-newline: off
padded-blocks: off
- # Disabled for now, to make the eslint 3 -> eslint 4 update smoother
+ # Disabled for now, to make the eslint 3 -> eslint 5 update smoother
## Indent rule. We are using the old for now: https://eslint.org/docs/user-guide/migrating-to-4.0.0#indent-rewrite
indent: off
indent-legacy:
@@ -78,3 +82,18 @@ rules:
FunctionExpression:
parameters: 1
body: 1
+ # Disabled for now, to make the airbnb-base 12.1.0 -> 13.1.0 update smoother
+ operator-linebreak: off
+ implicit-arrow-linebreak: off
+ no-else-return:
+ - error
+ - allowElseIf: true
+ import/no-useless-path-segments: off
+ lines-between-class-members: off
+ # Disabled for now, to make the plugin-vue 4.5 -> 5.0 update smoother
+ vue/html-closing-bracket-newline: off
+ vue/html-closing-bracket-spacing: off
+ vue/no-confusing-v-for-v-if: error
+ vue/no-unused-components: off
+ vue/no-use-v-if-with-v-for: off
+ vue/no-v-html: off
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index cc27ac3677b..90bc9f74ef3 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -130,7 +130,6 @@ stages:
.single-script-job: &single-script-job
image: ruby:2.4-alpine
- before_script: []
stage: test
cache: {}
dependencies: []
@@ -259,6 +258,7 @@ package-and-qa:
SCRIPT_NAME: trigger-build
retry: 0
script:
+ - gem install gitlab --no-document
- ./$SCRIPT_NAME omnibus
when: manual
only:
@@ -285,7 +285,7 @@ review-docs-deploy-manual:
<<: *review-docs
stage: build
script:
- - gem install gitlab --no-ri --no-rdoc
+ - gem install gitlab --no-document
- ./$SCRIPT_NAME deploy
when: manual
only:
@@ -299,7 +299,7 @@ review-docs-deploy:
<<: *review-docs
stage: post-test
script:
- - gem install gitlab --no-ri --no-rdoc
+ - gem install gitlab --no-document
- ./$SCRIPT_NAME deploy
only:
- /(^docs[\/-].*|.*-docs$)/@gitlab-org/gitlab-ce
@@ -314,7 +314,7 @@ review-docs-cleanup:
name: review-docs/$CI_COMMIT_REF_SLUG
action: stop
script:
- - gem install gitlab --no-ri --no-rdoc
+ - gem install gitlab --no-document
- ./$SCRIPT_NAME cleanup
when: manual
only:
@@ -327,14 +327,14 @@ review-docs-cleanup:
cloud-native-image:
image: ruby:2.4-alpine
before_script: []
- stage: build
+ stage: test
allow_failure: true
variables:
GIT_DEPTH: "1"
cache: {}
script:
- - gem install gitlab --no-ri --no-rdoc
- - BUILD_TRIGGER_TOKEN=$CI_JOB_TOKEN scripts/trigger-build cng
+ - gem install gitlab --no-document
+ - CNG_PROJECT_PATH="gitlab-org/build/CNG" BUILD_TRIGGER_TOKEN=$CI_JOB_TOKEN ./scripts/trigger-build cng
only:
- tags@gitlab-org/gitlab-ce
- tags@gitlab-org/gitlab-ee
@@ -366,7 +366,7 @@ update-tests-metadata:
- rspec_flaky/
policy: push
script:
- - retry gem install fog-aws mime-types activesupport --no-ri --no-rdoc
+ - retry gem install fog-aws mime-types activesupport --no-document
- scripts/merge-reports ${KNAPSACK_RSPEC_SUITE_REPORT_PATH} knapsack/${CI_PROJECT_NAME}/rspec-pg_node_*.json
- scripts/merge-reports ${FLAKY_RSPEC_SUITE_REPORT_PATH} rspec_flaky/all_*_*.json
- FLAKY_RSPEC_GENERATE_REPORT=1 scripts/prune-old-flaky-specs ${FLAKY_RSPEC_SUITE_REPORT_PATH}
diff --git a/.rubocop.yml b/.rubocop.yml
index 9858bbe0ddd..ce7be208186 100644
--- a/.rubocop.yml
+++ b/.rubocop.yml
@@ -111,7 +111,7 @@ Naming/FileName:
- XSRF
- XSS
-# Gitlab ###################################################################
+# GitLab ###################################################################
Gitlab/ModuleWithInstanceVariables:
Enable: true
diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml
index 54e3b8217d8..d8c4e965190 100644
--- a/.rubocop_todo.yml
+++ b/.rubocop_todo.yml
@@ -808,20 +808,6 @@ Style/UnlessElse:
Style/UnneededInterpolation:
Enabled: false
-# Offense count: 11
-# Cop supports --auto-correct.
-Style/ZeroLengthPredicate:
- Exclude:
- - 'app/models/deploy_key.rb'
- - 'app/models/network/commit.rb'
- - 'app/models/network/graph.rb'
- - 'app/models/project_services/asana_service.rb'
- - 'app/services/boards/create_service.rb'
- - 'app/services/merge_requests/conflicts/list_service.rb'
- - 'lib/declarative_policy/dsl.rb'
- - 'lib/extracts_path.rb'
- - 'lib/gitlab/git/repository.rb'
-
# Offense count: 22840
# Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns.
# URISchemes: http, https
diff --git a/CHANGELOG.md b/CHANGELOG.md
index c1d5a638cd0..e514a42108c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,253 @@
documentation](doc/development/changelog.md) for instructions on adding your own
entry.
+## 11.3.0 (2018-09-22)
+
+### Security (5 changes, 1 of them is from the community)
+
+- Disable the Sidekiq Admin Rack session. !21441
+- Set issuable_sort, diff_view, and perf_bar_enabled cookies to secure when possible. !21442
+- Update rubyzip to 1.2.2 (CVE-2018-1000544). !21460 (Takuya Noguchi)
+- Fixed persistent XSS rendering/escaping of diff location lines.
+- Block link-local addresses in URLBlocker.
+
+### Removed (1 change)
+
+- Remove Gemnasium service. !21185
+
+### Fixed (83 changes, 24 of them are from the community)
+
+- Hide PAT creation advice for HTTP clone if PAT exists. !18208 (George Thomas @thegeorgeous)
+- Allow spaces in wiki markdown links when using CommonMark. !20417
+- disable_statement_timeout no longer leak to other migrations. !20503
+- Events API now requires the read_user or api scope. !20627 (Warren Parad)
+- Fix If-Check the result that a function was executed several times. !20640 (Max Dicker)
+- Add migration to cleanup internal_ids inconsistency. !20926
+- Fix fallback logic for automatic MR title assignment. !20930 (Franz Liedke)
+- Fixed bug when the project logo file is stored in LFS. !20948
+- Fix buttons on the new file page wrapping outside of the container. !21015
+- Solve tooltip appears under modal. !21017
+- Fix Bitbucket Cloud importer omitting replies. !21076
+- Fix pipeline fixture seeder. !21088
+- Fix blocked user card style. !21095
+- Fix empty merge requests not opening in the Web IDE. !21102
+- Fix label list item container height when there is no label description. !21106
+- Fixes input alignment in user admin form with errors. !21108 (Jacopo Beschi @jacopo-beschi)
+- Rails5 fix specs duplicate key value violates unique constraint 'index_gpg_signatures_on_commit_sha'. !21119 (Jasper Maes)
+- Add gitlab theme to spam logs pagination. !21145
+- Split remembering sorting for issues and merge requests. !21153 (Jacopo Beschi @jacopo-beschi)
+- Fix git submodule link for subgroup projects with relative path. !21154
+- Fix: Project deletion may not log audit events during group deletion. !21162
+- Fix 1px cutoff of emojis. !21180 (gfyoung)
+- Auto-DevOps.gitlab-ci.yml: update glibc package to 2.28. !21191 (sgerrand)
+- Show google icon in audit log. !21207 (Jan Beckmann)
+- Fix bin/secpick error and security branch prefixing. !21210
+- Importing a project no longer fails when visibility level holds a string value type. !21242
+- Fix attachments not displaying inline with Google Cloud Storage. !21265
+- Fix IDE issues with persistent banners. !21283
+- Fix "Confidential comments" button not saving in project hooks. !21289
+- Bump fog-google to 1.7.0 and google-api-client to 0.23.0. !21295
+- Don't use arguments keyword in gettext script. !21296 (gfyoung)
+- Fix breadcrumb link to issues on new issue page. !21305 (J.D. Bean)
+- Show '< 1%' when percent value evaluated is less than 1 on Stacked Progress Bar. !21306
+- API: Catch empty commit messages. !21322 (Robert Schilling)
+- Fix SQL error when sorting 2FA-enabled users by name in admin area. !21324
+- API: Catch empty code content for project snippets. !21325 (Robert Schilling)
+- Avoid nil safe message. !21326 (Yi Siliang)
+- Allow date parameters on Issues, Notes, and Discussions API for group owners. !21342 (Florent Dubois)
+- Fix remote mirrors failing if Git remotes have not been added. !21351
+- Removing a group no longer triggers hooks for project deletion twice. !21366
+- Use slugs for default project path and sanitize names before import. !21367
+- Vertically centres landscape avatars. !21371 (Vicary Archangel)
+- Fix Web IDE unable to commit to same file twice. !21372
+- Fix project transfer name validation issues causing a redirect loop. !21408
+- Fix Error 500s due to encoding issues when Wiki hooks fire. !21414
+- Rails 5: include opclasses in rails 5 schema dump. !21416 (Jasper Maes)
+- Bump GitLab Pages to v1.1.0. !21419
+- Fix links in RSS feed elements. !21424 (Marc Schwede)
+- Allow gaps in multiseries metrics charts. !21427
+- Auto-DevOps.gitlab-ci.yml: fix redeploying deleted app gives helm error. !21429
+- Use sample data for push event when no commits created. !21440 (Takuya Noguchi)
+- Fix importers not assigning a new default group. !21456
+- Fix edge cases of JUnitParser. !21469
+- Fix breadcrumb link to merge requests on new merge request page. !21502 (J.D. Bean)
+- Handle database statement timeouts in usage ping. !21523
+- Handles exception during file upload - replaces the stack trace with a small error message. !21528
+- Fix closing issue default pattern. !21531 (Samuele Kaplun)
+- Fix outdated discussions being shown on Merge Request Changes tab. !21543
+- Remove orphaned label links. !21552
+- Delete a container registry asynchronously. !21553
+- Make MR diff file filter input Clear button functional. !21556
+- Replace white spaces in wiki attachments file names. !21569
+- API: Use find_branch! in all places. !21614 (Robert Schilling)
+- Fixes double +/- on inline diff view. !21634
+- Fix broken exports when they include a projet avatar. !21649
+- Fix workhorse temp path for namespace uploads. !21650
+- Fixed resolved discussions not toggling expanded state on changes tab. !21676
+- Update GitLab Shell to v8.3.2. !21701
+- Fix absent Click to Expand link on diffs not rendered on first load of Merge Requests Changes tab. !21716
+- Update GitLab Shell to v8.3.3. !21750
+- Fix import error when archive does not have the correct extension. !21765
+- Fixed IDE deleting new files creating wrong state.
+- Does not collapse runners section when using pagination.
+- Fix Emojis cutting in the right way. (Alexander Popov)
+- Fix NamespaceUploader.base_dir for remote uploads.
+- Increase width of checkout branch modal box.
+- Fixes SVGs for empty states in job page overflowing on mobile.
+- Fix checkboxes on runner admin settings - The labels are now clickable.
+- Fixed IDE file row scrolling into view when hovering.
+- Accept upload files in public/uplaods/tmp when using accelerated uploads.
+- Include correct CSS file for xterm in environments page.
+- Increase padding in code blocks.
+- Fix: Project deletion may not log audit events during user deletion.
+
+### Changed (32 changes, 5 of them are from the community)
+
+- Add default avatar to group. !17271 (George Tsiolis)
+- Allow project owners to set up forking relation through API. !18104
+- Limit navbar search for current project or group for small viewports. !18634 (George Tsiolis)
+- Add Noto Color Emoji font support. !19036 (Alexander Popov)
+- Update design of project overview page. !20536
+- Improve visuals of language bar on projects. !21006
+- Migrate NULL wiki_access_level to correct number so we count active wikis correctly. !21030
+- Support a custom action, such as proxying to another server, after /api/v4/internal/allowed check succeeds. !21034
+- Remove storage path dependency of gitaly install task. !21101
+- Support Kubernetes RBAC for GitLab Managed Apps when adding a existing cluster. !21127
+- Change 'Backlog' list title to 'Open' in Issue Boards. !21131
+- Enable Auto DevOps Instance Wide Default. !21157
+- Allow author to vote on their own issue and MRs. !21203
+- Truncate branch names and update "commits behind" text in MR page. !21206
+- Adds count for different board list types (label lists, assignee lists, and milestone lists) to usage statistics. !21208
+- Render files (`.md`) and wikis using CommonMark. !21228
+- Show deprecation message on project milestone page for category tabs. !21236
+- Remove redundant header from metrics page. !21282
+- Add default parameter to branches API. !21294 (Riccardo Padovani)
+- Restrict reopening locked issues for non authorized issue authors. !21299
+- Send back required object storage PUT headers in /uploads/authorize API. !21319
+- Display default status emoji if only message is entered. !21330
+- Move badge settings to general settings. !21333
+- Move project settings for default branch under "Repository". !21380
+- Import all common metrics into database. !21459
+- Improved commit panel in Web IDE. !21471
+- Administrative cleanup rake tasks now leverage Gitaly. !21588
+- Remove health check feature flag in BackgroundMigrationWorker.
+- Expose user's id in /admin/users/ show page. (Eva Kadlecova)
+- Improved styling of top bar in IDE job trace pane.
+- Make terminal button more visible.
+- Shows download artifacts button for pipelines on small screens.
+
+### Performance (13 changes, 2 of them are from the community)
+
+- Enable frozen string in rest of app/models/**/*.rb.
+- Add background migrations for legacy artifacts. !18615
+- Optimize querying User#manageable_groups. !21050
+- Incremental rendering with Vue on merge request page. !21063
+- Remove redundant ci_builds (status) index. !21070
+- Enable frozen in app/mailers/**/*.rb. !21147 (gfyoung)
+- Improve performance when fetching related merge requests for an issue. !21237
+- Speed up diff comparisons by limiting number of commit messages rendered. !21335
+- Write diff highlighting cache upon MR creation (refactors caching). !21489
+- Bulk-render commit titles in the tree view to improve performance. !21500
+- Enable frozen string in vestigial app files. (gfyoung)
+- Disable project avatar validation if avatar has not changed.
+- Bitbucket Server importer: Eliminate most idle-in-transaction issues.
+
+### Added (41 changes, 17 of them are from the community)
+
+- API: Protected tags. !14986 (Robert Schilling)
+- Include private contributions to contributions calendar. !17296 (George Tsiolis)
+- Add an option to whitelist users based on email address as internal when the "New user set to external" setting is enabled. !17711 (Roger Rüttimann)
+- Overhaul listing of projects in the group overview page. !20262
+- Add the ability to reference projects in comments and other markdown text. !20285 (Reuben Pereira)
+- Add branch filter to project webhooks. !20338 (Duana Saskia)
+- Allows to cancel a Created job. !20635 (Jacopo Beschi @jacopo-beschi)
+- First Improvements made to the contributor on-boarding experience. !20682 (Eddie Stubbington)
+- `/tag` quick action on Commit comments. !20694 (Peter Leitzen)
+- Allow admins to configure the maximum Git push size. !20758
+- Expose all artifacts sizes in jobs api. !20821 (Peter Marko)
+- Get the merge base of two refs through the API. !20929
+- Add ability to suppress the global "You won't be able to use SSH" message. !21027 (Ævar Arnfjörð Bjarmason)
+- API: Add expiration date for shared projects to the project entity. !21104 (Robert Schilling)
+- Added tooltips to tree list header. !21138
+- #47845 Add failure_reason to job webhook. !21143 (matemaciek)
+- Vendor Auto-DevOps.gitlab-ci.yml with new proxy env vars passed through to docker. !21159 (kinolaev)
+- Disable Auto DevOps for project upon first pipeline failure. !21172
+- Add rake command to migrate archived traces from local storage to object storage. !21193
+- Add Czech as an available language. !21201
+- Add Galician as an available language. !21202
+- Add support for extendable CI/CD config with. !21243
+- Disable Web IDE button if user is not allowed to push the source branch. !21288
+- Feature flag to disable Hashed Storage migration when renaming a repository. !21291
+- Store wiki uploads inside git repository. !21362
+- Adds Rubocop rule to enforce class_methods over module ClassMethods. !21379 (Jacopo Beschi @jacopo-beschi)
+- Merge request copies all associated issue labels and milestone on creation. !21383
+- Add group name badge under group milestone. !21384
+- Adds diverged_commits_count field to GET api/v4/projects/:project_id/merge_requests/:merge_request_iid. !21405 (Jacopo Beschi @jacopo-beschi)
+- Update Import/Export to only use new storage uploaders logic. !21409
+- Ask user explicitly about usage stats agreement on single user deployments. !21423
+- Added atom feed for tags. !21428
+- Add search to a group labels page. !21480
+- Display banner on project page if AutoDevOps is implicitly enabled. !21503
+- Recognize 'UNLICENSE' license files. !21508 (J.D. Bean)
+- Add git_v2 feature flag. !21520
+- Added file templates to the Web IDE.
+- Enabled multiple file uploads in the Web IDE.
+- Allow to delete group milestones.
+- Use separate model for tracking resource label changes and render label system notes based on data from this model.
+- Add system note when due date is changed. (Eva Kadlecova)
+
+### Other (48 changes, 16 of them are from the community)
+
+- Remove extra spaces from MR discussion notes. !18946 (Takuya Noguchi)
+- Add an example of the configuration of archive trace cron worker in gitlab.yml.example. !20583
+- Add target branch name to cherrypick confirmation message. !20846 (George Andrinopoulos)
+- CE Port of Protected Environments backend. !20859
+- Added missing i18n strings to issue boards lables dropdown. !21081
+- Combines emoji award spec files into single user_interacts_with_awards_in_issue_spec.rb file. !21126 (Nate Geslin)
+- Clarify current runners online text. !21151 (Ben Bodenmiller)
+- Rails5: Enable verbose query logs. !21231 (Jasper Maes)
+- Update presentation for SSO providers on log in page. !21233
+- Make margin of user status emoji consistent. !21268
+- Move usage ping payload from User Cohorts page to admin application settings. !21343
+- Add JSON logging for Bitbucket Server importer. !21378
+- Re-add project name field on "Create new project" page. !21386
+- Rails 5: replace removed silence_stream. !21387 (Jasper Maes)
+- Rails5 update Gemfile.rails5.lock. !21388 (Jasper Maes)
+- Rails5: fix can't quote ActiveSupport::HashWithIndifferentAccess. !21397 (Jasper Maes)
+- Don't show flash messages for performance bar errors. !21411
+- Backport schema_changed.sh from EE which prints the diff if the schema is different. !21422 (Jasper Maes)
+- Remove unused CSS part in mobile framework. !21439 (Takuya Noguchi)
+- Bump unauthenticated session time from 1 hour to 2 hours. !21453
+- Run review-docs-cleanup job for gitlab-org repos only. !21463 (Takuya Noguchi)
+- Rails 5: support schema t.index for mysql. !21485 (Jasper Maes)
+- Add route information to lograge structured logging for API logs. !21487
+- Add gitaly_calls attribute to API logs. !21496
+- Ignore irrelevant sql commands in metrics. !21498
+- Rails 5: fix hashed_path? method that looks up file_location that doesn't exist when running certain migration specs. !21510 (Jasper Maes)
+- Explicit hashed path check for trace, prevents background migration from accessing file_location column that doesn't exist. !21533 (Jasper Maes)
+- Add terminal_path to job API response. !21537
+- Add User-Agent to production_json.log. !21546
+- Make cluster page settings easier to read. !21550
+- Remove striped table styling of Find files and Admin Area Applications views. !21560 (Andreas Kämmerle)
+- Update ffi to 1.9.25. !21561 (Takuya Noguchi)
+- Send max_patch_bytes to Gitaly via Gitaly::CommitDiffRequest. !21575
+- Add margin between username and subsequent text in issuable header. !21697
+- Send artifact information in job API. !50460
+- Reduce differences between CE and EE code base in reports components.
+- Move project services log to a separate file.
+- Creates vue component for job log top bar with controllers.
+- Creates Vue component for trigger variables block in job log page.
+- Creates Vvue component for warning block about stuck runners.
+- Creates vue component for job log trace.
+- Creates vue component for erased block on job view.
+- Creates vue component for environments information in job log view.
+- Upgrade Monaco editor.
+- Creates empty state vue component for job view.
+- Creates vue component for commit block in job log page.
+- Creates vue components for stage dropdowns and job list container for job log view.
+- Creates Vue component for artifacts block on job page.
+
+
## 11.2.3 (2018-08-28)
### Fixed (1 change)
@@ -879,7 +1126,7 @@ entry.
- Use the default strings of timeago.js for timeago. !19350 (Takuya Noguchi)
- Update selenium-webdriver to 3.12.0. !19351 (Takuya Noguchi)
- Include username in output when testing SSH to GitLab. !19358
-- Update screenshot in Gitlab.com integration documentation. !19433 (Tuğçe Nur Taş)
+- Update screenshot in GitLab.com integration documentation. !19433 (Tuğçe Nur Taş)
- Users can accept terms during registration. !19583
- Fix issue count on sidebar.
- Add merge requests list endpoint for groups.
@@ -1009,7 +1256,7 @@ entry.
- Make toggle markdown preview shortcut only toggle selected field.
- Verifiy if pipeline has commit idetails and render information in MR widget when branch is deleted.
- Fixed inconsistent protected branch pill baseline.
-- Fix setting Gitlab metrics content types.
+- Fix setting GitLab metrics content types.
- Display only generic message on merge error to avoid exposing any potentially sensitive or user unfriendly backend messages.
- Fix label links update on project transfer.
- Breaks commit not found message in pipelines table.
@@ -1379,7 +1626,7 @@ entry.
- Add 'Assigned Issues' and 'Assigned Merge Requests' as dashboard view choices for users. !17860 (Elias Werberich)
- Extend API for importing a project export with overwrite support. !17883
- Create Deploy Tokens to allow permanent access to repository and registry. !17894
-- Detect commit message trailers and link users properly to their accounts on Gitlab. !17919 (cousine)
+- Detect commit message trailers and link users properly to their accounts on GitLab. !17919 (cousine)
- Adds cancel btn to new pages domain page. !18026 (Jacopo Beschi @jacopo-beschi)
- API: Add parameter merge_method to projects. !18031 (Jan Beckmann)
- Introduce simpler env vars for auto devops REPLICAS and CANARY_REPLICAS #41436. !18036
@@ -2827,7 +3074,7 @@ entry.
- [FIXED] Fix broken wiki pages that link to a wiki file. !15019
- [FIXED] Don't rename paths that were freed up when upgrading. !15029
- [FIXED] Fix bitbucket login. !15051
-- [FIXED] Update gitaly in Gitlab 10.1 to 0.43.1 for temp file cleanup. !15055
+- [FIXED] Update gitaly in GitLab 10.1 to 0.43.1 for temp file cleanup. !15055
- [FIXED] Use the correct visibility attribute for projects in system hooks. !15065
- [FIXED] Normalize LDAP DN when looking up identity.
- [FIXED] Adds callback functions for initial request in clusters page.
@@ -4537,7 +4784,7 @@ entry.
- Make user mentions case-insensitive. !10285 (blackst0ne)
- Update rugged to 0.25.1.1. !10286 (Elan Ruusamäe)
- Handle parsing OpenBSD ps output properly to display sidekiq infos on admin->monitoring->background. !10303 (Sebastian Reitenbach)
-- Log errors during generating of Gitlab Pages to debug log. !10335 (Danilo Bargen)
+- Log errors during generating of GitLab Pages to debug log. !10335 (Danilo Bargen)
- Update issue board cards design. !10353
- Tags can be protected, restricting creation of matching tags by user role. !10356
- Set GIT_TERMINAL_PROMPT env variable in initializer. !10372
@@ -4950,7 +5197,7 @@ entry.
- Restore keyboard shortcuts for "Activity" and "Charts". !9680
- Added commit array to Syshook json. !9685 (Gabriele Pongelli)
- Document ability to list issues with no labels using API. !9697 (Vignesh Ravichandran)
-- Fix typo in Gitlab config file. !9702 (medied)
+- Fix typo in GitLab config file. !9702 (medied)
- Fix json response in branches controller. !9710 (George Andrinopoulos)
- Refactor dropdown_assignee_spec. !9711 (George Andrinopoulos)
- Delete artifacts for pages unless expiry date is specified. !9716
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 0a828f42b52..8596037afa3 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -151,7 +151,7 @@ the remaining issues on the GitHub issue tracker.
## I want to contribute!
-If you want to contribute to GitLab, [issues in the `Backlog (Accepting merge requests)` milestone with small weight][https://gitlab.com/gitlab-org/gitlab-ce/issues?scope=all&utf8=✓&state=opened&assignee_id=0&milestone_title=Backlog%20(Accepting%20merge%20requests)]
+If you want to contribute to GitLab, [issues in the Backlog (Accepting merge requests)](https://gitlab.com/gitlab-org/gitlab-ce/issues?scope=all&utf8=✓&state=opened&assignee_id=0&milestone_title=Backlog%20&#40;Accepting%20merge%20requests&#41;)
are a great place to start. Issues with a lower weight (1 or 2) are deemed
suitable for beginners. These issues will be of reasonable size and challenge,
for anyone to start contributing to GitLab. If you have any questions or need help visit [Getting Help](https://about.gitlab.com/getting-help/#discussion) to
diff --git a/Gemfile.rails5.lock b/Gemfile.rails5.lock
index 48b1190fd56..aa6a32fa84e 100644
--- a/Gemfile.rails5.lock
+++ b/Gemfile.rails5.lock
@@ -128,7 +128,7 @@ GEM
coderay (1.1.2)
coercible (1.0.0)
descendants_tracker (~> 0.0.1)
- commonmarker (0.17.8)
+ commonmarker (0.17.13)
ruby-enum (~> 0.5)
concord (0.1.5)
adamantium (~> 0.2.0)
diff --git a/PROCESS.md b/PROCESS.md
index 583f36b820f..38ec01f9de0 100644
--- a/PROCESS.md
+++ b/PROCESS.md
@@ -74,14 +74,31 @@ star, smile, etc.). Some good tips about code reviews can be found in our
## Feature freeze on the 7th for the release on the 22nd
-After 7th at 23:59 (Pacific Time Zone) of each month, RC1 of the upcoming release (to be shipped on the 22nd) is created and deployed to GitLab.com and the stable branch for this release is frozen, which means master is no longer merged into it.
-Merge requests may still be merged into master during this period,
-but they will go into the _next_ release, unless they are manually cherry-picked into the stable branch.
+After 7th at 23:59 (Pacific Time Zone) of each month, RC1 of the upcoming
+release (to be shipped on the 22nd) is created and deployed to GitLab.com and
+the stable branch for this release is frozen, which means master is no longer
+merged into it. Merge requests may still be merged into master during this
+period, but they will go into the _next_ release, unless they are manually
+cherry-picked into the stable branch.
-By freezing the stable branches 2 weeks prior to a release, we reduce the risk of a last minute merge request potentially breaking things.
+By freezing the stable branches 2 weeks prior to a release, we reduce the risk
+of a last minute merge request potentially breaking things.
-Any release candidate that gets created after this date can become a final release,
-hence the name release candidate.
+Any release candidate that gets created after this date can become a final
+release, hence the name release candidate.
+
+### Feature flags
+
+Merge requests that make changes hidden behind a feature flag, or remove an
+existing feature flag because a feature is deemed stable, may be merged (and
+picked into the stable branches) up to the 19th of the month. Such merge
+requests should have the ~"feature flag" label assigned, and don't require a
+corresponding exception request to be created.
+
+While rare, release managers may decide to reject picking a change into a stable
+branch, even when feature flags are used. This might be necessary if the changes
+are deemed problematic, too invasive, or there simply isn't enough time to
+properly test how the changes behave on GitLab.com.
### Between the 1st and the 7th
@@ -223,36 +240,36 @@ Check [this guide](https://gitlab.com/gitlab-org/release/docs/blob/master/genera
A ~bug is a defect, error, failure which causes the system to behave incorrectly or prevents it from fulfilling the product requirements.
-The level of impact of a ~bug can vary from blocking a whole functionality
-or a feature usability bug. A bug should always be linked to a severity level.
+The level of impact of a ~bug can vary from blocking a whole functionality
+or a feature usability bug. A bug should always be linked to a severity level.
Refer to our [severity levels](../CONTRIBUTING.md#severity-labels)
-Whether the bug is also a regression or not, the triage process should start as soon as possible.
+Whether the bug is also a regression or not, the triage process should start as soon as possible.
Ensure that the Engineering Manager and/or the Product Manager for the relative area is involved to prioritize the work as needed.
### Regressions
A ~regression implies that a previously **verified working functionality** no longer works.
Regressions are a subset of bugs. We use the ~regression label to imply that the defect caused the functionality to regress.
-The label tells us that something worked before and it needs extra attention from Engineering and Product Managers to schedule/reschedule.
+The label tells us that something worked before and it needs extra attention from Engineering and Product Managers to schedule/reschedule.
-The regression label does not apply to ~bugs for new features for which functionality was **never verified as working**.
-These, by definition, are not regressions.
+The regression label does not apply to ~bugs for new features for which functionality was **never verified as working**.
+These, by definition, are not regressions.
A regression should always have the `regression:xx.x` label on it to designate when it was introduced.
-Regressions should be considered high priority issues that should be solved as soon as possible, especially if they have severe impact on users.
+Regressions should be considered high priority issues that should be solved as soon as possible, especially if they have severe impact on users.
### Managing bugs
-**Prioritization:** We give higher priority to regressions on features that worked in the last recent monthly release and the current release candidates.
-The two scenarios below can [bypass the exception request in the release process](https://gitlab.com/gitlab-org/release/docs/blob/master/general/exception-request/process.md#after-the-7th), where the affected regression version matches the current monthly release version.
+**Prioritization:** We give higher priority to regressions on features that worked in the last recent monthly release and the current release candidates.
+The two scenarios below can [bypass the exception request in the release process](https://gitlab.com/gitlab-org/release/docs/blob/master/general/exception-request/process.md#after-the-7th), where the affected regression version matches the current monthly release version.
* A regression which worked in the **Last monthly release**
* **Example:** In 11.0 we released a new `feature X` that is verified as working. Then in release 11.1 the feature no longer works, this is regression for 11.1. The issue should have the `regression:11.1` label.
* *Note:* When we say `the last recent monthly release`, this can refer to either the version currently running on GitLab.com, or the most recent version available in the package repositories.
* A regression which worked in the **Current release candidates**
* **Example:** In 11.1-RC3 we shipped a new feature which has been verified as working. Then in 11.1-RC5 the feature no longer works, this is regression for 11.1. The issue should have the `regression:11.1` label.
- * *Note:* Because GitLab.com runs release candidates of new releases, a regression can be reported in a release before its 'official' release date on the 22nd of the month.
+ * *Note:* Because GitLab.com runs release candidates of new releases, a regression can be reported in a release before its 'official' release date on the 22nd of the month.
When a bug is found:
1. Create an issue describing the problem in the most detailed way possible.
@@ -264,11 +281,11 @@ When a bug is found:
The counterpart Product Manager is included to weigh-in on prioritization as needed.
1. If the ~bug is **NOT** a regression:
1. The Engineering Manager decides which milestone the bug will be fixed. The appropriate milestone is applied.
-1. If the bug is a ~regression:
+1. If the bug is a ~regression:
1. Determine the release that the regression affects and add the corresponding `regression:xx.x` label.
1. If the affected release version can't be determined, add the generic ~regression label for the time being.
- 1. If the affected version `xx.x` in `regression:xx.x` is the **current release**, it's recommended to schedule the fix for the current milestone.
- 1. This falls under regressions which worked in the last release and the current RCs. More detailed explanations in the **Prioritization** section above.
+ 1. If the affected version `xx.x` in `regression:xx.x` is the **current release**, it's recommended to schedule the fix for the current milestone.
+ 1. This falls under regressions which worked in the last release and the current RCs. More detailed explanations in the **Prioritization** section above.
1. If the affected version `xx.x` in `regression:xx.x` is older than the **current release**
1. If the regression is an ~S1 severity, it's recommended to schedule the fix for the current milestone. We would like to fix the highest severity regression as soon as we can.
1. If the regression is an ~S2, ~S3 or ~S4 severity, the regression may be scheduled for later milestones at the discretion of the Engineering Manager and Product Manager.
diff --git a/VERSION b/VERSION
index e1ceae704b9..39a87ed80d7 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-11.3.0-pre
+11.4.0-pre
diff --git a/app/assets/images/cluster_app_logos/elasticsearch.png b/app/assets/images/cluster_app_logos/elasticsearch.png
new file mode 100644
index 00000000000..96e9e0ff934
--- /dev/null
+++ b/app/assets/images/cluster_app_logos/elasticsearch.png
Binary files differ
diff --git a/app/assets/images/cluster_app_logos/gitlab.png b/app/assets/images/cluster_app_logos/gitlab.png
new file mode 100644
index 00000000000..cb2195fc6a2
--- /dev/null
+++ b/app/assets/images/cluster_app_logos/gitlab.png
Binary files differ
diff --git a/app/assets/images/cluster_app_logos/helm.png b/app/assets/images/cluster_app_logos/helm.png
new file mode 100644
index 00000000000..2989cae7b93
--- /dev/null
+++ b/app/assets/images/cluster_app_logos/helm.png
Binary files differ
diff --git a/app/assets/images/cluster_app_logos/jeager.png b/app/assets/images/cluster_app_logos/jeager.png
new file mode 100644
index 00000000000..be5bf2a0c9c
--- /dev/null
+++ b/app/assets/images/cluster_app_logos/jeager.png
Binary files differ
diff --git a/app/assets/images/cluster_app_logos/jupyterhub.png b/app/assets/images/cluster_app_logos/jupyterhub.png
new file mode 100644
index 00000000000..80c7343067f
--- /dev/null
+++ b/app/assets/images/cluster_app_logos/jupyterhub.png
Binary files differ
diff --git a/app/assets/images/cluster_app_logos/kubernetes.png b/app/assets/images/cluster_app_logos/kubernetes.png
new file mode 100644
index 00000000000..4d774909c10
--- /dev/null
+++ b/app/assets/images/cluster_app_logos/kubernetes.png
Binary files differ
diff --git a/app/assets/images/cluster_app_logos/meltano.png b/app/assets/images/cluster_app_logos/meltano.png
new file mode 100644
index 00000000000..7a2d82fbe27
--- /dev/null
+++ b/app/assets/images/cluster_app_logos/meltano.png
Binary files differ
diff --git a/app/assets/images/cluster_app_logos/prometheus.png b/app/assets/images/cluster_app_logos/prometheus.png
new file mode 100644
index 00000000000..a8663449b88
--- /dev/null
+++ b/app/assets/images/cluster_app_logos/prometheus.png
Binary files differ
diff --git a/app/assets/javascripts/badges/components/badge.vue b/app/assets/javascripts/badges/components/badge.vue
index b08dc454d12..97232d7f783 100644
--- a/app/assets/javascripts/badges/components/badge.vue
+++ b/app/assets/javascripts/badges/components/badge.vue
@@ -103,8 +103,8 @@ export default {
</div>
<button
- v-tooltip
v-show="hasError"
+ v-tooltip
:title="s__('Badges|Reload badge image')"
class="btn btn-transparent btn-sm text-primary"
type="button"
diff --git a/app/assets/javascripts/behaviors/index.js b/app/assets/javascripts/behaviors/index.js
index 84fef4d8b4f..8c4eccc34a3 100644
--- a/app/assets/javascripts/behaviors/index.js
+++ b/app/assets/javascripts/behaviors/index.js
@@ -1,15 +1,19 @@
import './autosize';
import './bind_in_out';
import './markdown/render_gfm';
+import initGFMInput from './markdown/gfm_auto_complete';
import initCopyAsGFM from './markdown/copy_as_gfm';
import initCopyToClipboard from './copy_to_clipboard';
import './details_behavior';
import installGlEmojiElement from './gl_emoji';
import './quick_submit';
import './requires_input';
+import initPageShortcuts from './shortcuts';
import './toggler_behavior';
-import '../preview_markdown';
+import './preview_markdown';
installGlEmojiElement();
+initGFMInput();
initCopyAsGFM();
initCopyToClipboard();
+initPageShortcuts();
diff --git a/app/assets/javascripts/behaviors/markdown/gfm_auto_complete.js b/app/assets/javascripts/behaviors/markdown/gfm_auto_complete.js
new file mode 100644
index 00000000000..a303e504cc7
--- /dev/null
+++ b/app/assets/javascripts/behaviors/markdown/gfm_auto_complete.js
@@ -0,0 +1,19 @@
+import $ from 'jquery';
+import { convertPermissionToBoolean } from '~/lib/utils/common_utils';
+import GfmAutoComplete from '~/gfm_auto_complete';
+
+export default function initGFMInput() {
+ $('.js-gfm-input:not(.js-vue-textarea)').each((i, el) => {
+ const gfm = new GfmAutoComplete(gl.GfmAutoComplete && gl.GfmAutoComplete.dataSources);
+ const enableGFM = convertPermissionToBoolean(el.dataset.supportsAutocomplete);
+
+ gfm.setup($(el), {
+ emojis: true,
+ members: enableGFM,
+ issues: enableGFM,
+ milestones: enableGFM,
+ mergeRequests: enableGFM,
+ labels: enableGFM,
+ });
+ });
+}
diff --git a/app/assets/javascripts/behaviors/markdown/render_gfm.js b/app/assets/javascripts/behaviors/markdown/render_gfm.js
index dbff2bd4b10..429455f97ec 100644
--- a/app/assets/javascripts/behaviors/markdown/render_gfm.js
+++ b/app/assets/javascripts/behaviors/markdown/render_gfm.js
@@ -3,7 +3,7 @@ import syntaxHighlight from '~/syntax_highlight';
import renderMath from './render_math';
import renderMermaid from './render_mermaid';
-// Render Gitlab flavoured Markdown
+// Render GitLab flavoured Markdown
//
// Delegates to syntax highlight and render math & mermaid diagrams.
//
diff --git a/app/assets/javascripts/preview_markdown.js b/app/assets/javascripts/behaviors/preview_markdown.js
index 0964baf8954..0964baf8954 100644
--- a/app/assets/javascripts/preview_markdown.js
+++ b/app/assets/javascripts/behaviors/preview_markdown.js
diff --git a/app/assets/javascripts/behaviors/shortcuts.js b/app/assets/javascripts/behaviors/shortcuts.js
new file mode 100644
index 00000000000..7987a533ae5
--- /dev/null
+++ b/app/assets/javascripts/behaviors/shortcuts.js
@@ -0,0 +1,35 @@
+import Shortcuts from './shortcuts/shortcuts';
+
+export default function initPageShortcuts() {
+ const { page } = document.body.dataset;
+ const pagesWithCustomShortcuts = [
+ 'projects:activity',
+ 'projects:artifacts:browse',
+ 'projects:artifacts:file',
+ 'projects:blame:show',
+ 'projects:blob:show',
+ 'projects:commit:show',
+ 'projects:commits:show',
+ 'projects:find_file:show',
+ 'projects:issues:edit',
+ 'projects:issues:index',
+ 'projects:issues:new',
+ 'projects:issues:show',
+ 'projects:merge_requests:creations:diffs',
+ 'projects:merge_requests:creations:new',
+ 'projects:merge_requests:edit',
+ 'projects:merge_requests:index',
+ 'projects:merge_requests:show',
+ 'projects:network:show',
+ 'projects:show',
+ 'projects:tree:show',
+ 'groups:show',
+ ];
+
+ // the pages above have their own shortcuts sub-classes instantiated elsewhere
+ // TODO: replace this whitelist with something more automated/maintainable
+ if (page && !pagesWithCustomShortcuts.includes(page)) {
+ return new Shortcuts();
+ }
+ return false;
+}
diff --git a/app/assets/javascripts/shortcuts.js b/app/assets/javascripts/behaviors/shortcuts/shortcuts.js
index 99c71d6524a..6719bfd6d22 100644
--- a/app/assets/javascripts/shortcuts.js
+++ b/app/assets/javascripts/behaviors/shortcuts/shortcuts.js
@@ -1,9 +1,9 @@
import $ from 'jquery';
import Cookies from 'js-cookie';
import Mousetrap from 'mousetrap';
-import axios from './lib/utils/axios_utils';
-import { refreshCurrentPage, visitUrl } from './lib/utils/url_utility';
-import findAndFollowLink from './shortcuts_dashboard_navigation';
+import axios from '../../lib/utils/axios_utils';
+import { refreshCurrentPage, visitUrl } from '../../lib/utils/url_utility';
+import findAndFollowLink from '../../lib/utils/navigation_utility';
const defaultStopCallback = Mousetrap.stopCallback;
Mousetrap.stopCallback = (e, element, combo) => {
diff --git a/app/assets/javascripts/shortcuts_blob.js b/app/assets/javascripts/behaviors/shortcuts/shortcuts_blob.js
index 908b9cab93d..052e33b4a2b 100644
--- a/app/assets/javascripts/shortcuts_blob.js
+++ b/app/assets/javascripts/behaviors/shortcuts/shortcuts_blob.js
@@ -1,5 +1,5 @@
import Mousetrap from 'mousetrap';
-import { getLocationHash, visitUrl } from './lib/utils/url_utility';
+import { getLocationHash, visitUrl } from '../../lib/utils/url_utility';
import Shortcuts from './shortcuts';
const defaults = {
diff --git a/app/assets/javascripts/shortcuts_find_file.js b/app/assets/javascripts/behaviors/shortcuts/shortcuts_find_file.js
index 8658081c6c2..8658081c6c2 100644
--- a/app/assets/javascripts/shortcuts_find_file.js
+++ b/app/assets/javascripts/behaviors/shortcuts/shortcuts_find_file.js
diff --git a/app/assets/javascripts/shortcuts_issuable.js b/app/assets/javascripts/behaviors/shortcuts/shortcuts_issuable.js
index e9451be31fd..5e48bf5a35c 100644
--- a/app/assets/javascripts/shortcuts_issuable.js
+++ b/app/assets/javascripts/behaviors/shortcuts/shortcuts_issuable.js
@@ -1,9 +1,9 @@
import $ from 'jquery';
import Mousetrap from 'mousetrap';
import _ from 'underscore';
-import Sidebar from './right_sidebar';
+import Sidebar from '../../right_sidebar';
import Shortcuts from './shortcuts';
-import { CopyAsGFM } from './behaviors/markdown/copy_as_gfm';
+import { CopyAsGFM } from '../markdown/copy_as_gfm';
export default class ShortcutsIssuable extends Shortcuts {
constructor(isMergeRequest) {
diff --git a/app/assets/javascripts/shortcuts_navigation.js b/app/assets/javascripts/behaviors/shortcuts/shortcuts_navigation.js
index 6b595764bc5..fa9b2c9f755 100644
--- a/app/assets/javascripts/shortcuts_navigation.js
+++ b/app/assets/javascripts/behaviors/shortcuts/shortcuts_navigation.js
@@ -1,5 +1,5 @@
import Mousetrap from 'mousetrap';
-import findAndFollowLink from './shortcuts_dashboard_navigation';
+import findAndFollowLink from '../../lib/utils/navigation_utility';
import Shortcuts from './shortcuts';
export default class ShortcutsNavigation extends Shortcuts {
diff --git a/app/assets/javascripts/shortcuts_network.js b/app/assets/javascripts/behaviors/shortcuts/shortcuts_network.js
index a88c280fa3b..a88c280fa3b 100644
--- a/app/assets/javascripts/shortcuts_network.js
+++ b/app/assets/javascripts/behaviors/shortcuts/shortcuts_network.js
diff --git a/app/assets/javascripts/shortcuts_wiki.js b/app/assets/javascripts/behaviors/shortcuts/shortcuts_wiki.js
index 41865dcf4ba..8b7e6a56d25 100644
--- a/app/assets/javascripts/shortcuts_wiki.js
+++ b/app/assets/javascripts/behaviors/shortcuts/shortcuts_wiki.js
@@ -1,6 +1,6 @@
import Mousetrap from 'mousetrap';
import ShortcutsNavigation from './shortcuts_navigation';
-import findAndFollowLink from './shortcuts_dashboard_navigation';
+import findAndFollowLink from '../../lib/utils/navigation_utility';
export default class ShortcutsWiki extends ShortcutsNavigation {
constructor() {
diff --git a/app/assets/javascripts/boards/components/board_blank_state.vue b/app/assets/javascripts/boards/components/board_blank_state.vue
index 286529b4d13..cde22725a89 100644
--- a/app/assets/javascripts/boards/components/board_blank_state.vue
+++ b/app/assets/javascripts/boards/components/board_blank_state.vue
@@ -83,7 +83,7 @@ export default {
right on the way to making the most of your board.
</p>
<button
- class="btn btn-create btn-inverted btn-block"
+ class="btn btn-success btn-inverted btn-block"
type="button"
@click.stop="addDefaultLists">
Add default lists
diff --git a/app/assets/javascripts/boards/components/board_list.vue b/app/assets/javascripts/boards/components/board_list.vue
index 606c9e81db4..7ddb22ad824 100644
--- a/app/assets/javascripts/boards/components/board_list.vue
+++ b/app/assets/javascripts/boards/components/board_list.vue
@@ -231,14 +231,14 @@ export default {
<board-card
v-for="(issue, index) in issues"
ref="issue"
+ :key="issue.id"
:index="index"
:list="list"
:issue="issue"
:issue-link-base="issueLinkBase"
:group-id="groupId"
:root-path="rootPath"
- :disabled="disabled"
- :key="issue.id" />
+ :disabled="disabled" />
<li
v-if="showCount"
class="board-list-count text-center"
diff --git a/app/assets/javascripts/boards/components/board_new_issue.vue b/app/assets/javascripts/boards/components/board_new_issue.vue
index 1e3cd43d1f0..f248f53fa51 100644
--- a/app/assets/javascripts/boards/components/board_new_issue.vue
+++ b/app/assets/javascripts/boards/components/board_new_issue.vue
@@ -110,9 +110,9 @@ export default {
Title
</label>
<input
+ :id="list.id + '-title'"
ref="input"
v-model="title"
- :id="list.id + '-title'"
class="form-control"
type="text"
name="issue_title"
diff --git a/app/assets/javascripts/boards/components/issue_card_inner.vue b/app/assets/javascripts/boards/components/issue_card_inner.vue
index d50641dc3a9..f56d3fe000c 100644
--- a/app/assets/javascripts/boards/components/issue_card_inner.vue
+++ b/app/assets/javascripts/boards/components/issue_card_inner.vue
@@ -170,8 +170,8 @@
tooltip-placement="bottom"
/>
<span
- v-tooltip
v-if="shouldRenderCounter"
+ v-tooltip
:title="assigneeCounterTooltip"
class="avatar-counter"
>
@@ -184,10 +184,10 @@
class="board-card-footer"
>
<button
- v-tooltip
v-for="label in issue.labels"
v-if="showLabel(label)"
:key="label.id"
+ v-tooltip
:style="labelStyle(label)"
:title="label.description"
class="badge color-label"
diff --git a/app/assets/javascripts/boards/index.js b/app/assets/javascripts/boards/index.js
index bc263cbbfea..662363a6f26 100644
--- a/app/assets/javascripts/boards/index.js
+++ b/app/assets/javascripts/boards/index.js
@@ -9,7 +9,7 @@ import '~/vue_shared/models/assignee';
import FilteredSearchBoards from './filtered_search_boards';
import eventHub from './eventhub';
-import sidebarEventHub from '~/sidebar/event_hub'; // eslint-disable-line import/first
+import sidebarEventHub from '~/sidebar/event_hub';
import './models/issue';
import './models/list';
import './models/milestone';
@@ -24,7 +24,7 @@ import './components/board';
import './components/board_sidebar';
import './components/new_list_dropdown';
import BoardAddIssuesModal from './components/modal/index.vue';
-import '~/vue_shared/vue_resource_interceptor'; // eslint-disable-line import/first
+import '~/vue_shared/vue_resource_interceptor';
export default () => {
const $boardApp = document.getElementById('board-app');
@@ -229,7 +229,7 @@ export default () => {
template: `
<div class="board-extra-actions">
<button
- class="btn btn-create prepend-left-10"
+ class="btn btn-success prepend-left-10"
type="button"
data-placement="bottom"
ref="addIssuesButton"
diff --git a/app/assets/javascripts/clusters/components/application_row.vue b/app/assets/javascripts/clusters/components/application_row.vue
index 651f3b50236..0452729d3ff 100644
--- a/app/assets/javascripts/clusters/components/application_row.vue
+++ b/app/assets/javascripts/clusters/components/application_row.vue
@@ -2,6 +2,7 @@
/* eslint-disable vue/require-default-prop */
import { s__, sprintf } from '../../locale';
import eventHub from '../event_hub';
+ import identicon from '../../vue_shared/components/identicon.vue';
import loadingButton from '../../vue_shared/components/loading_button.vue';
import {
APPLICATION_STATUS,
@@ -13,6 +14,7 @@
export default {
components: {
loadingButton,
+ identicon,
},
props: {
id: {
@@ -31,6 +33,16 @@
type: String,
required: false,
},
+ logoUrl: {
+ type: String,
+ required: false,
+ default: null,
+ },
+ disabled: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
status: {
type: String,
required: false,
@@ -60,6 +72,18 @@
isKnownStatus() {
return Object.values(APPLICATION_STATUS).includes(this.status);
},
+ isInstalled() {
+ return (
+ this.status === APPLICATION_STATUS.INSTALLED || this.status === APPLICATION_STATUS.UPDATED
+ );
+ },
+ hasLogo() {
+ return !!this.logoUrl;
+ },
+ identiconId() {
+ // generate a deterministic integer id for the identicon background
+ return this.id.charCodeAt(0);
+ },
rowJsClass() {
return `js-cluster-application-row-${this.id}`;
},
@@ -128,37 +152,81 @@
<template>
<div
- :class="rowJsClass"
- class="gl-responsive-table-row gl-responsive-table-row-col-span"
+ :class="[
+ rowJsClass,
+ isInstalled && 'cluster-application-installed',
+ disabled && 'cluster-application-disabled'
+ ]"
+ class="cluster-application-row gl-responsive-table-row gl-responsive-table-row-col-span"
>
<div
class="gl-responsive-table-row-layout"
role="row"
>
- <a
- v-if="titleLink"
- :href="titleLink"
- target="blank"
- rel="noopener noreferrer"
+ <div
+ class="table-section append-right-8 section-align-top"
role="gridcell"
- class="table-section section-15 section-align-top js-cluster-application-title"
>
- {{ title }}
- </a>
- <span
- v-else
- class="table-section section-15 section-align-top js-cluster-application-title"
- >
- {{ title }}
- </span>
+ <img
+ v-if="hasLogo"
+ :src="logoUrl"
+ :alt="`${title} logo`"
+ class="cluster-application-logo avatar s40"
+ />
+ <identicon
+ v-else
+ :entity-id="identiconId"
+ :entity-name="title"
+ size-class="s40"
+ />
+ </div>
<div
- class="table-section section-wrap"
+ class="table-section cluster-application-description section-wrap"
role="gridcell"
>
+ <strong>
+ <a
+ v-if="titleLink"
+ :href="titleLink"
+ target="blank"
+ rel="noopener noreferrer"
+ class="js-cluster-application-title"
+ >
+ {{ title }}
+ </a>
+ <span
+ v-else
+ class="js-cluster-application-title"
+ >
+ {{ title }}
+ </span>
+ </strong>
<slot name="description"></slot>
+ <div
+ v-if="hasError || isUnknownStatus"
+ class="cluster-application-error text-danger prepend-top-10"
+ >
+ <p class="js-cluster-application-general-error-message append-bottom-0">
+ {{ generalErrorDescription }}
+ </p>
+ <ul v-if="statusReason || requestReason">
+ <li
+ v-if="statusReason"
+ class="js-cluster-application-status-error-message"
+ >
+ {{ statusReason }}
+ </li>
+ <li
+ v-if="requestReason"
+ class="js-cluster-application-request-error-message"
+ >
+ {{ requestReason }}
+ </li>
+ </ul>
+ </div>
</div>
<div
- :class="{ 'section-20': showManageButton, 'section-15': !showManageButton }"
+ :class="{ 'section-25': showManageButton, 'section-15': !showManageButton }"
class="table-section table-button-footer section-align-top"
role="gridcell"
>
@@ -168,6 +236,7 @@
>
<a
:href="manageLink"
+ :class="{ disabled: disabled }"
class="btn"
>
{{ manageButtonLabel }}
@@ -176,7 +245,7 @@
<div class="btn-group table-action-buttons">
<loading-button
:loading="installButtonLoading"
- :disabled="installButtonDisabled"
+ :disabled="disabled || installButtonDisabled"
:label="installButtonLabel"
class="js-cluster-application-install-button"
@click="installClicked"
@@ -184,35 +253,5 @@
</div>
</div>
</div>
- <div
- v-if="hasError || isUnknownStatus"
- class="gl-responsive-table-row-layout"
- role="row"
- >
- <div
- class="alert alert-danger alert-block append-bottom-0 clusters-error-alert"
- role="gridcell"
- >
- <div>
- <p class="js-cluster-application-general-error-message">
- {{ generalErrorDescription }}
- </p>
- <ul v-if="statusReason || requestReason">
- <li
- v-if="statusReason"
- class="js-cluster-application-status-error-message"
- >
- {{ statusReason }}
- </li>
- <li
- v-if="requestReason"
- class="js-cluster-application-request-error-message"
- >
- {{ requestReason }}
- </li>
- </ul>
- </div>
- </div>
- </div>
</div>
</template>
diff --git a/app/assets/javascripts/clusters/components/applications.vue b/app/assets/javascripts/clusters/components/applications.vue
index d708a9e595a..a1069985178 100644
--- a/app/assets/javascripts/clusters/components/applications.vue
+++ b/app/assets/javascripts/clusters/components/applications.vue
@@ -1,5 +1,14 @@
<script>
import _ from 'underscore';
+import helmInstallIllustration from '@gitlab-org/gitlab-svgs/illustrations/kubernetes-installation.svg';
+import elasticsearchLogo from 'images/cluster_app_logos/elasticsearch.png';
+import gitlabLogo from 'images/cluster_app_logos/gitlab.png';
+import helmLogo from 'images/cluster_app_logos/helm.png';
+import jeagerLogo from 'images/cluster_app_logos/jeager.png';
+import jupyterhubLogo from 'images/cluster_app_logos/jupyterhub.png';
+import kubernetesLogo from 'images/cluster_app_logos/kubernetes.png';
+import meltanoLogo from 'images/cluster_app_logos/meltano.png';
+import prometheusLogo from 'images/cluster_app_logos/prometheus.png';
import { s__, sprintf } from '../../locale';
import applicationRow from './application_row.vue';
import clipboardButton from '../../vue_shared/components/clipboard_button.vue';
@@ -37,21 +46,21 @@ export default {
default: '',
},
},
+ data: () => ({
+ elasticsearchLogo,
+ gitlabLogo,
+ helmLogo,
+ jeagerLogo,
+ jupyterhubLogo,
+ kubernetesLogo,
+ meltanoLogo,
+ prometheusLogo,
+ }),
computed: {
- generalApplicationDescription() {
- return sprintf(
- _.escape(
- s__(
- `ClusterIntegration|Install applications on your Kubernetes cluster.
- Read more about %{helpLink}`,
- ),
- ),
- {
- helpLink: `<a href="${this.helpPath}">
- ${_.escape(s__('ClusterIntegration|installing applications'))}
- </a>`,
- },
- false,
+ helmInstalled() {
+ return (
+ this.applications.helm.status === APPLICATION_STATUS.INSTALLED ||
+ this.applications.helm.status === APPLICATION_STATUS.UPDATED
);
},
ingressId() {
@@ -128,224 +137,240 @@ export default {
return this.applications.jupyter.hostname;
},
},
+ created() {
+ this.helmInstallIllustration = helmInstallIllustration;
+ },
};
</script>
<template>
- <section
- id="cluster-applications"
- class="settings no-animate expanded"
- >
- <div class="settings-header">
- <h4>
- {{ s__('ClusterIntegration|Applications') }}
- </h4>
- <p
- class="append-bottom-0"
- v-html="generalApplicationDescription"
- >
- </p>
- </div>
+ <section id="cluster-applications">
+ <h4>
+ {{ s__('ClusterIntegration|Applications') }}
+ </h4>
+ <p class="append-bottom-0">
+ {{ s__(`ClusterIntegration|Choose which applications to install on your Kubernetes cluster.
+ Helm Tiller is required to install any of the following applications.`) }}
+ <a :href="helpPath">
+ {{ __('More information') }}
+ </a>
+ </p>
- <div class="settings-content">
- <div class="append-bottom-20">
- <application-row
- id="helm"
- :title="applications.helm.title"
- :status="applications.helm.status"
- :status-reason="applications.helm.statusReason"
- :request-status="applications.helm.requestStatus"
- :request-reason="applications.helm.requestReason"
- title-link="https://docs.helm.sh/"
- >
- <div slot="description">
- {{ s__(`ClusterIntegration|Helm streamlines installing
- and managing Kubernetes applications.
- Tiller runs inside of your Kubernetes Cluster,
- and manages releases of your charts.`) }}
- </div>
- </application-row>
- <application-row
- :id="ingressId"
- :title="applications.ingress.title"
- :status="applications.ingress.status"
- :status-reason="applications.ingress.statusReason"
- :request-status="applications.ingress.requestStatus"
- :request-reason="applications.ingress.requestReason"
- title-link="https://kubernetes.io/docs/concepts/services-networking/ingress/"
+ <div class="cluster-application-list prepend-top-10">
+ <application-row
+ id="helm"
+ :logo-url="helmLogo"
+ :title="applications.helm.title"
+ :status="applications.helm.status"
+ :status-reason="applications.helm.statusReason"
+ :request-status="applications.helm.requestStatus"
+ :request-reason="applications.helm.requestReason"
+ class="rounded-top"
+ title-link="https://docs.helm.sh/"
+ >
+ <div slot="description">
+ {{ s__(`ClusterIntegration|Helm streamlines installing
+ and managing Kubernetes applications.
+ Tiller runs inside of your Kubernetes Cluster,
+ and manages releases of your charts.`) }}
+ </div>
+ </application-row>
+ <div
+ v-show="!helmInstalled"
+ class="cluster-application-warning"
+ >
+ <div
+ class="svg-container"
+ v-html="helmInstallIllustration"
>
- <div slot="description">
- <p>
- {{ s__(`ClusterIntegration|Ingress gives you a way to route
- requests to services based on the request host or path,
- centralizing a number of services into a single entrypoint.`) }}
- </p>
+ </div>
+ {{ s__(`ClusterIntegration|You must first install Helm Tiller before
+ installing the applications below`) }}
+ </div>
+ <application-row
+ :id="ingressId"
+ :logo-url="kubernetesLogo"
+ :title="applications.ingress.title"
+ :status="applications.ingress.status"
+ :status-reason="applications.ingress.statusReason"
+ :request-status="applications.ingress.requestStatus"
+ :request-reason="applications.ingress.requestReason"
+ :disabled="!helmInstalled"
+ title-link="https://kubernetes.io/docs/concepts/services-networking/ingress/"
+ >
+ <div slot="description">
+ <p>
+ {{ s__(`ClusterIntegration|Ingress gives you a way to route
+ requests to services based on the request host or path,
+ centralizing a number of services into a single entrypoint.`) }}
+ </p>
- <template v-if="ingressInstalled">
- <div class="form-group">
- <label for="ingress-ip-address">
- {{ s__('ClusterIntegration|Ingress IP Address') }}
- </label>
- <div
- v-if="ingressExternalIp"
- class="input-group"
- >
- <input
- id="ingress-ip-address"
- :value="ingressExternalIp"
- type="text"
- class="form-control js-ip-address"
- readonly
- />
- <span class="input-group-append">
- <clipboard-button
- :text="ingressExternalIp"
- :title="s__('ClusterIntegration|Copy Ingress IP Address to clipboard')"
- class="input-group-text js-clipboard-btn"
- />
- </span>
- </div>
+ <template v-if="ingressInstalled">
+ <div class="form-group">
+ <label for="ingress-ip-address">
+ {{ s__('ClusterIntegration|Ingress IP Address') }}
+ </label>
+ <div
+ v-if="ingressExternalIp"
+ class="input-group"
+ >
<input
- v-else
+ id="ingress-ip-address"
+ :value="ingressExternalIp"
type="text"
class="form-control js-ip-address"
readonly
- value="?"
/>
+ <span class="input-group-append">
+ <clipboard-button
+ :text="ingressExternalIp"
+ :title="s__('ClusterIntegration|Copy Ingress IP Address to clipboard')"
+ class="input-group-text js-clipboard-btn"
+ />
+ </span>
</div>
+ <input
+ v-else
+ type="text"
+ class="form-control js-ip-address"
+ readonly
+ value="?"
+ />
+ </div>
- <p
- v-if="!ingressExternalIp"
- class="settings-message js-no-ip-message"
- >
- {{ s__(`ClusterIntegration|The IP address is in
- the process of being assigned. Please check your Kubernetes
- cluster or Quotas on Google Kubernetes Engine if it takes a long time.`) }}
+ <p
+ v-if="!ingressExternalIp"
+ class="settings-message js-no-ip-message"
+ >
+ {{ s__(`ClusterIntegration|The IP address is in
+ the process of being assigned. Please check your Kubernetes
+ cluster or Quotas on Google Kubernetes Engine if it takes a long time.`) }}
- <a
- :href="ingressHelpPath"
- target="_blank"
- rel="noopener noreferrer"
- >
- {{ __('More information') }}
- </a>
- </p>
+ <a
+ :href="ingressHelpPath"
+ target="_blank"
+ rel="noopener noreferrer"
+ >
+ {{ __('More information') }}
+ </a>
+ </p>
- <p>
- {{ s__(`ClusterIntegration|Point a wildcard DNS to this
- generated IP address in order to access
- your application after it has been deployed.`) }}
- <a
- :href="ingressDnsHelpPath"
- target="_blank"
- rel="noopener noreferrer"
- >
- {{ __('More information') }}
- </a>
- </p>
+ <p>
+ {{ s__(`ClusterIntegration|Point a wildcard DNS to this
+ generated IP address in order to access
+ your application after it has been deployed.`) }}
+ <a
+ :href="ingressDnsHelpPath"
+ target="_blank"
+ rel="noopener noreferrer"
+ >
+ {{ __('More information') }}
+ </a>
+ </p>
- </template>
- <div
- v-else
- v-html="ingressDescription"
- >
- </div>
- </div>
- </application-row>
- <application-row
- id="prometheus"
- :title="applications.prometheus.title"
- :manage-link="managePrometheusPath"
- :status="applications.prometheus.status"
- :status-reason="applications.prometheus.statusReason"
- :request-status="applications.prometheus.requestStatus"
- :request-reason="applications.prometheus.requestReason"
- title-link="https://prometheus.io/docs/introduction/overview/"
- >
+ </template>
<div
- slot="description"
- v-html="prometheusDescription"
+ v-html="ingressDescription"
>
</div>
- </application-row>
- <application-row
- id="runner"
- :title="applications.runner.title"
- :status="applications.runner.status"
- :status-reason="applications.runner.statusReason"
- :request-status="applications.runner.requestStatus"
- :request-reason="applications.runner.requestReason"
- title-link="https://docs.gitlab.com/runner/"
- >
- <div slot="description">
- {{ s__(`ClusterIntegration|GitLab Runner connects to this
- project's repository and executes CI/CD jobs,
- pushing results back and deploying,
- applications to production.`) }}
- </div>
- </application-row>
- <application-row
- id="jupyter"
- :title="applications.jupyter.title"
- :status="applications.jupyter.status"
- :status-reason="applications.jupyter.statusReason"
- :request-status="applications.jupyter.requestStatus"
- :request-reason="applications.jupyter.requestReason"
- :install-application-request-params="{ hostname: applications.jupyter.hostname }"
- title-link="https://jupyterhub.readthedocs.io/en/stable/"
+ </div>
+ </application-row>
+ <application-row
+ id="prometheus"
+ :logo-url="prometheusLogo"
+ :title="applications.prometheus.title"
+ :manage-link="managePrometheusPath"
+ :status="applications.prometheus.status"
+ :status-reason="applications.prometheus.statusReason"
+ :request-status="applications.prometheus.requestStatus"
+ :request-reason="applications.prometheus.requestReason"
+ :disabled="!helmInstalled"
+ title-link="https://prometheus.io/docs/introduction/overview/"
+ >
+ <div
+ slot="description"
+ v-html="prometheusDescription"
>
- <div slot="description">
- <p>
- {{ s__(`ClusterIntegration|JupyterHub, a multi-user Hub, spawns,
- manages, and proxies multiple instances of the single-user
- Jupyter notebook server. JupyterHub can be used to serve
- notebooks to a class of students, a corporate data science group,
- or a scientific research group.`) }}
- </p>
+ </div>
+ </application-row>
+ <application-row
+ id="runner"
+ :logo-url="gitlabLogo"
+ :title="applications.runner.title"
+ :status="applications.runner.status"
+ :status-reason="applications.runner.statusReason"
+ :request-status="applications.runner.requestStatus"
+ :request-reason="applications.runner.requestReason"
+ :disabled="!helmInstalled"
+ title-link="https://docs.gitlab.com/runner/"
+ >
+ <div slot="description">
+ {{ s__(`ClusterIntegration|GitLab Runner connects to this
+ project's repository and executes CI/CD jobs,
+ pushing results back and deploying,
+ applications to production.`) }}
+ </div>
+ </application-row>
+ <application-row
+ id="jupyter"
+ :logo-url="jupyterhubLogo"
+ :title="applications.jupyter.title"
+ :status="applications.jupyter.status"
+ :status-reason="applications.jupyter.statusReason"
+ :request-status="applications.jupyter.requestStatus"
+ :request-reason="applications.jupyter.requestReason"
+ :install-application-request-params="{ hostname: applications.jupyter.hostname }"
+ :disabled="!helmInstalled"
+ class="hide-bottom-border rounded-bottom"
+ title-link="https://jupyterhub.readthedocs.io/en/stable/"
+ >
+ <div slot="description">
+ <p>
+ {{ s__(`ClusterIntegration|JupyterHub, a multi-user Hub, spawns,
+ manages, and proxies multiple instances of the single-user
+ Jupyter notebook server. JupyterHub can be used to serve
+ notebooks to a class of students, a corporate data science group,
+ or a scientific research group.`) }}
+ </p>
- <template v-if="ingressExternalIp">
- <div class="form-group">
- <label for="jupyter-hostname">
- {{ s__('ClusterIntegration|Jupyter Hostname') }}
- </label>
+ <template v-if="ingressExternalIp">
+ <div class="form-group">
+ <label for="jupyter-hostname">
+ {{ s__('ClusterIntegration|Jupyter Hostname') }}
+ </label>
- <div class="input-group">
- <input
- v-model="applications.jupyter.hostname"
- :readonly="jupyterInstalled"
- type="text"
- class="form-control js-hostname"
+ <div class="input-group">
+ <input
+ v-model="applications.jupyter.hostname"
+ :readonly="jupyterInstalled"
+ type="text"
+ class="form-control js-hostname"
+ />
+ <span
+ class="input-group-btn"
+ >
+ <clipboard-button
+ :text="jupyterHostname"
+ :title="s__('ClusterIntegration|Copy Jupyter Hostname to clipboard')"
+ class="js-clipboard-btn"
/>
- <span
- class="input-group-btn"
- >
- <clipboard-button
- :text="jupyterHostname"
- :title="s__('ClusterIntegration|Copy Jupyter Hostname to clipboard')"
- class="js-clipboard-btn"
- />
- </span>
- </div>
+ </span>
</div>
- <p v-if="ingressInstalled">
- {{ s__(`ClusterIntegration|Replace this with your own hostname if you want.
- If you do so, point hostname to Ingress IP Address from above.`) }}
- <a
- :href="ingressDnsHelpPath"
- target="_blank"
- rel="noopener noreferrer"
- >
- {{ __('More information') }}
- </a>
- </p>
- </template>
- </div>
- </application-row>
- <!--
- NOTE: Don't forget to update `clusters.scss`
- min-height for this block and uncomment `application_spec` tests
- -->
- </div>
+ </div>
+ <p v-if="ingressInstalled">
+ {{ s__(`ClusterIntegration|Replace this with your own hostname if you want.
+ If you do so, point hostname to Ingress IP Address from above.`) }}
+ <a
+ :href="ingressDnsHelpPath"
+ target="_blank"
+ rel="noopener noreferrer"
+ >
+ {{ __('More information') }}
+ </a>
+ </p>
+ </template>
+ </div>
+ </application-row>
</div>
</section>
</template>
diff --git a/app/assets/javascripts/commons/polyfills.js b/app/assets/javascripts/commons/polyfills.js
index 742cf490ad2..539d0d29e0d 100644
--- a/app/assets/javascripts/commons/polyfills.js
+++ b/app/assets/javascripts/commons/polyfills.js
@@ -14,10 +14,10 @@ import 'core-js/es6/map';
import 'core-js/es6/weak-map';
// Browser polyfills
-import 'classlist-polyfill';
import 'formdata-polyfill';
import './polyfills/custom_event';
import './polyfills/element';
import './polyfills/event';
import './polyfills/nodelist';
import './polyfills/request_idle_callback';
+import './polyfills/svg';
diff --git a/app/assets/javascripts/commons/polyfills/element.js b/app/assets/javascripts/commons/polyfills/element.js
index b593bde6aa2..dde5e8f54f9 100644
--- a/app/assets/javascripts/commons/polyfills/element.js
+++ b/app/assets/javascripts/commons/polyfills/element.js
@@ -1,12 +1,17 @@
-Element.prototype.closest = Element.prototype.closest ||
+// polyfill Element.classList and DOMTokenList with classList.js
+import 'classlist-polyfill';
+
+Element.prototype.closest =
+ Element.prototype.closest ||
function closest(selector, selectedElement = this) {
if (!selectedElement) return null;
- return selectedElement.matches(selector) ?
- selectedElement :
- Element.prototype.closest(selector, selectedElement.parentElement);
+ return selectedElement.matches(selector)
+ ? selectedElement
+ : Element.prototype.closest(selector, selectedElement.parentElement);
};
-Element.prototype.matches = Element.prototype.matches ||
+Element.prototype.matches =
+ Element.prototype.matches ||
Element.prototype.matchesSelector ||
Element.prototype.mozMatchesSelector ||
Element.prototype.msMatchesSelector ||
@@ -15,13 +20,15 @@ Element.prototype.matches = Element.prototype.matches ||
function matches(selector) {
const elms = (this.document || this.ownerDocument).querySelectorAll(selector);
let i = elms.length - 1;
- while (i >= 0 && elms.item(i) !== this) { i -= 1; }
+ while (i >= 0 && elms.item(i) !== this) {
+ i -= 1;
+ }
return i > -1;
};
// From the polyfill on MDN, https://developer.mozilla.org/en-US/docs/Web/API/ChildNode/remove#Polyfill
-((arr) => {
- arr.forEach((item) => {
+(arr => {
+ arr.forEach(item => {
if (Object.prototype.hasOwnProperty.call(item, 'remove')) {
return;
}
diff --git a/app/assets/javascripts/commons/polyfills/svg.js b/app/assets/javascripts/commons/polyfills/svg.js
new file mode 100644
index 00000000000..8648a568f6f
--- /dev/null
+++ b/app/assets/javascripts/commons/polyfills/svg.js
@@ -0,0 +1,5 @@
+import svg4everybody from 'svg4everybody';
+
+// polyfill support for external SVG file references via <use xlink:href>
+// @see https://css-tricks.com/svg-use-external-source/
+svg4everybody();
diff --git a/app/assets/javascripts/deploy_keys/components/key.vue b/app/assets/javascripts/deploy_keys/components/key.vue
index f66ca070445..c05b9b1de79 100644
--- a/app/assets/javascripts/deploy_keys/components/key.vue
+++ b/app/assets/javascripts/deploy_keys/components/key.vue
@@ -145,8 +145,8 @@ export default {
<icon :name="firstProject.can_push ? 'lock-open' : 'lock'"/>
</a>
<a
- v-tooltip
v-if="isExpandable"
+ v-tooltip
:title="restProjectsTooltip"
class="label deploy-project-label"
@click="toggleExpanded"
@@ -154,10 +154,10 @@ export default {
<span>{{ restProjectsLabel }}</span>
</a>
<a
- v-tooltip
v-for="deployKeysProject in restProjects"
v-else-if="isExpanded"
:key="deployKeysProject.project.full_path"
+ v-tooltip
:href="deployKeysProject.project.full_path"
:title="projectTooltipTitle(deployKeysProject)"
class="label deploy-project-label"
@@ -198,8 +198,8 @@ export default {
{{ __('Enable') }}
</action-btn>
<a
- v-tooltip
v-if="deployKey.can_edit"
+ v-tooltip
:href="editDeployKeyPath"
:title="__('Edit')"
class="btn btn-default text-secondary"
@@ -208,8 +208,8 @@ export default {
<icon name="pencil"/>
</a>
<action-btn
- v-tooltip
v-if="isRemovable"
+ v-tooltip
:deploy-key="deployKey"
:title="__('Remove')"
btn-css-class="btn-danger"
@@ -219,8 +219,8 @@ export default {
<icon name="remove"/>
</action-btn>
<action-btn
- v-tooltip
v-else-if="isEnabled"
+ v-tooltip
:deploy-key="deployKey"
:title="__('Disable')"
btn-css-class="btn-warning"
diff --git a/app/assets/javascripts/diffs/components/diff_file_header.vue b/app/assets/javascripts/diffs/components/diff_file_header.vue
index d3ffbe0415a..517fbf400e8 100644
--- a/app/assets/javascripts/diffs/components/diff_file_header.vue
+++ b/app/assets/javascripts/diffs/components/diff_file_header.vue
@@ -181,8 +181,8 @@ export default {
</span>
<strong
- v-tooltip
v-else
+ v-tooltip
:title="filePath"
class="file-title-name"
data-container="body"
@@ -255,8 +255,8 @@ export default {
</a>
<a
- v-tooltip
v-if="diffFile.externalUrl"
+ v-tooltip
:href="diffFile.externalUrl"
:title="`View on ${diffFile.formattedExternalUrl}`"
target="_blank"
diff --git a/app/assets/javascripts/diffs/components/diff_gutter_avatars.vue b/app/assets/javascripts/diffs/components/diff_gutter_avatars.vue
index a02c41f39ab..1b59777f901 100644
--- a/app/assets/javascripts/diffs/components/diff_gutter_avatars.vue
+++ b/app/assets/javascripts/diffs/components/diff_gutter_avatars.vue
@@ -87,8 +87,8 @@ export default {
@click.native="toggleDiscussions"
/>
<span
- v-gl-tooltip
v-if="moreText"
+ v-gl-tooltip
:title="moreText"
class="diff-comments-more-count js-diff-comment-avatar js-diff-comment-plus"
data-container="body"
diff --git a/app/assets/javascripts/diffs/components/diff_line_note_form.vue b/app/assets/javascripts/diffs/components/diff_line_note_form.vue
index a0dc381ccc7..bb9bb821de3 100644
--- a/app/assets/javascripts/diffs/components/diff_line_note_form.vue
+++ b/app/assets/javascripts/diffs/components/diff_line_note_form.vue
@@ -1,12 +1,9 @@
<script>
import { mapState, mapGetters, mapActions } from 'vuex';
-import createFlash from '~/flash';
import { s__ } from '~/locale';
import noteForm from '../../notes/components/note_form.vue';
-import { getNoteFormData } from '../store/utils';
import autosave from '../../notes/mixins/autosave';
import { DIFF_NOTE_TYPE } from '../constants';
-import { reduceDiscussionsToLineCodes } from '../../notes/stores/utils';
export default {
components: {
@@ -22,7 +19,7 @@ export default {
type: Object,
required: true,
},
- position: {
+ linePosition: {
type: String,
required: false,
default: '',
@@ -39,6 +36,16 @@ export default {
}),
...mapGetters('diffs', ['getDiffFileByHash']),
...mapGetters(['isLoggedIn', 'noteableType', 'getNoteableData', 'getNotesDataByProp']),
+ formData() {
+ return {
+ noteableData: this.noteableData,
+ noteableType: this.noteableType,
+ noteTargetLine: this.noteTargetLine,
+ diffViewType: this.diffViewType,
+ diffFile: this.getDiffFileByHash(this.diffFileHash),
+ linePosition: this.linePosition,
+ };
+ },
},
mounted() {
if (this.isLoggedIn) {
@@ -53,8 +60,7 @@ export default {
}
},
methods: {
- ...mapActions('diffs', ['cancelCommentForm', 'assignDiscussionsToDiff']),
- ...mapActions(['saveNote', 'refetchDiscussionById']),
+ ...mapActions('diffs', ['cancelCommentForm', 'assignDiscussionsToDiff', 'saveDiffDiscussion']),
handleCancelCommentForm(shouldConfirm, isDirty) {
if (shouldConfirm && isDirty) {
const msg = s__('Notes|Are you sure you want to cancel creating this comment?');
@@ -73,35 +79,9 @@ export default {
});
},
handleSaveNote(note) {
- const selectedDiffFile = this.getDiffFileByHash(this.diffFileHash);
- const postData = getNoteFormData({
- note,
- noteableData: this.noteableData,
- noteableType: this.noteableType,
- noteTargetLine: this.noteTargetLine,
- diffViewType: this.diffViewType,
- diffFile: selectedDiffFile,
- linePosition: this.position,
- });
-
- this.saveNote(postData)
- .then(result => {
- const endpoint = this.getNotesDataByProp('discussionsPath');
-
- this.refetchDiscussionById({ path: endpoint, discussionId: result.discussion_id })
- .then(selectedDiscussion => {
- const lineCodeDiscussions = reduceDiscussionsToLineCodes([selectedDiscussion]);
- this.assignDiscussionsToDiff(lineCodeDiscussions);
-
- this.handleCancelCommentForm();
- })
- .catch(() => {
- createFlash(s__('MergeRequests|Updating discussions failed'));
- });
- })
- .catch(() => {
- createFlash(s__('MergeRequests|Saving the comment failed'));
- });
+ return this.saveDiffDiscussion({ note, formData: this.formData }).then(() =>
+ this.handleCancelCommentForm(),
+ );
},
},
};
diff --git a/app/assets/javascripts/diffs/components/inline_diff_table_row.vue b/app/assets/javascripts/diffs/components/inline_diff_table_row.vue
index 0e306f39a9f..62fa34e835a 100644
--- a/app/assets/javascripts/diffs/components/inline_diff_table_row.vue
+++ b/app/assets/javascripts/diffs/components/inline_diff_table_row.vue
@@ -1,5 +1,5 @@
<script>
-import { mapGetters } from 'vuex';
+import { mapGetters, mapActions } from 'vuex';
import DiffTableCell from './diff_table_cell.vue';
import {
NEW_LINE_TYPE,
@@ -63,7 +63,11 @@ export default {
this.linePositionLeft = LINE_POSITION_LEFT;
this.linePositionRight = LINE_POSITION_RIGHT;
},
+ mounted() {
+ this.scrollToLineIfNeededInline(this.line);
+ },
methods: {
+ ...mapActions('diffs', ['scrollToLineIfNeededInline']),
handleMouseMove(e) {
// To show the comment icon on the gutter we need to know if we hover the line.
// Current table structure doesn't allow us to do this with CSS in both of the diff view types
diff --git a/app/assets/javascripts/diffs/components/inline_diff_view.vue b/app/assets/javascripts/diffs/components/inline_diff_view.vue
index 947e7c98fae..fbf9e77ac07 100644
--- a/app/assets/javascripts/diffs/components/inline_diff_view.vue
+++ b/app/assets/javascripts/diffs/components/inline_diff_view.vue
@@ -43,18 +43,18 @@ export default {
v-for="(line, index) in diffLines"
>
<inline-diff-table-row
+ :key="line.lineCode"
:file-hash="diffFile.fileHash"
:context-lines-path="diffFile.contextLinesPath"
:line="line"
:is-bottom="index + 1 === diffLinesLength"
- :key="line.lineCode"
/>
<inline-diff-comment-row
v-if="shouldRenderInlineCommentRow(line)"
+ :key="index"
:diff-file-hash="diffFile.fileHash"
:line="line"
:line-index="index"
- :key="index"
/>
</template>
</tbody>
diff --git a/app/assets/javascripts/diffs/components/no_changes.vue b/app/assets/javascripts/diffs/components/no_changes.vue
index d817157fbcd..6905630ad8c 100644
--- a/app/assets/javascripts/diffs/components/no_changes.vue
+++ b/app/assets/javascripts/diffs/components/no_changes.vue
@@ -38,7 +38,7 @@ export default {
<div class="text-center">
<a
:href="newBlobPath"
- class="btn btn-save"
+ class="btn btn-success"
>
{{ __('Create commit') }}
</a>
diff --git a/app/assets/javascripts/diffs/components/parallel_diff_comment_row.vue b/app/assets/javascripts/diffs/components/parallel_diff_comment_row.vue
index 26417c350cb..3339c56cbb6 100644
--- a/app/assets/javascripts/diffs/components/parallel_diff_comment_row.vue
+++ b/app/assets/javascripts/diffs/components/parallel_diff_comment_row.vue
@@ -92,7 +92,7 @@ export default {
:diff-file-hash="diffFileHash"
:line="line.left"
:note-target-line="line.left"
- position="left"
+ line-position="left"
/>
</td>
<td class="notes_line new"></td>
@@ -111,7 +111,7 @@ export default {
:diff-file-hash="diffFileHash"
:line="line.right"
:note-target-line="line.right"
- position="right"
+ line-position="right"
/>
</td>
</tr>
diff --git a/app/assets/javascripts/diffs/components/parallel_diff_table_row.vue b/app/assets/javascripts/diffs/components/parallel_diff_table_row.vue
index fb68d191091..fcc3b3e9117 100644
--- a/app/assets/javascripts/diffs/components/parallel_diff_table_row.vue
+++ b/app/assets/javascripts/diffs/components/parallel_diff_table_row.vue
@@ -1,4 +1,5 @@
<script>
+import { mapActions } from 'vuex';
import $ from 'jquery';
import DiffTableCell from './diff_table_cell.vue';
import {
@@ -64,7 +65,11 @@ export default {
this.oldLineType = OLD_LINE_TYPE;
this.parallelDiffViewType = PARALLEL_DIFF_VIEW_TYPE;
},
+ mounted() {
+ this.scrollToLineIfNeededParallel(this.line);
+ },
methods: {
+ ...mapActions('diffs', ['scrollToLineIfNeededParallel']),
handleMouseMove(e) {
const isHover = e.type === 'mouseover';
const hoveringCell = e.target.closest('td');
diff --git a/app/assets/javascripts/diffs/components/parallel_diff_view.vue b/app/assets/javascripts/diffs/components/parallel_diff_view.vue
index 501bd4450d8..3452f0d2b00 100644
--- a/app/assets/javascripts/diffs/components/parallel_diff_view.vue
+++ b/app/assets/javascripts/diffs/components/parallel_diff_view.vue
@@ -45,11 +45,11 @@ export default {
v-for="(line, index) in diffLines"
>
<parallel-diff-table-row
+ :key="index"
:file-hash="diffFile.fileHash"
:context-lines-path="diffFile.contextLinesPath"
:line="line"
:is-bottom="index + 1 === diffLinesLength"
- :key="index"
/>
<parallel-diff-comment-row
v-if="shouldRenderParallelCommentRow(line)"
diff --git a/app/assets/javascripts/diffs/constants.js b/app/assets/javascripts/diffs/constants.js
index f68afa44837..2795dddfc48 100644
--- a/app/assets/javascripts/diffs/constants.js
+++ b/app/assets/javascripts/diffs/constants.js
@@ -7,6 +7,7 @@ export const CONTEXT_LINE_TYPE = 'context';
export const EMPTY_CELL_TYPE = 'empty-cell';
export const COMMENT_FORM_TYPE = 'commentForm';
export const DIFF_NOTE_TYPE = 'DiffNote';
+export const LEGACY_DIFF_NOTE_TYPE = 'LegacyDiffNote';
export const NOTE_TYPE = 'Note';
export const NEW_LINE_TYPE = 'new';
export const OLD_LINE_TYPE = 'old';
diff --git a/app/assets/javascripts/diffs/store/actions.js b/app/assets/javascripts/diffs/store/actions.js
index 027df2ec841..98d8d5943f9 100644
--- a/app/assets/javascripts/diffs/store/actions.js
+++ b/app/assets/javascripts/diffs/store/actions.js
@@ -1,9 +1,12 @@
import Vue from 'vue';
import axios from '~/lib/utils/axios_utils';
import Cookies from 'js-cookie';
+import createFlash from '~/flash';
+import { s__ } from '~/locale';
import { handleLocationHash, historyPushState } from '~/lib/utils/common_utils';
-import { mergeUrlParams } from '~/lib/utils/url_utility';
-import { getDiffPositionByLineCode } from './utils';
+import { mergeUrlParams, getLocationHash } from '~/lib/utils/url_utility';
+import { reduceDiscussionsToLineCodes } from '../../notes/stores/utils';
+import { getDiffPositionByLineCode, getNoteFormData } from './utils';
import * as types from './mutation_types';
import {
PARALLEL_DIFF_VIEW_TYPE,
@@ -120,6 +123,25 @@ export const loadMoreLines = ({ commit }, options) => {
});
};
+export const scrollToLineIfNeededInline = (_, line) => {
+ const hash = getLocationHash();
+
+ if (hash && line.lineCode === hash) {
+ handleLocationHash();
+ }
+};
+
+export const scrollToLineIfNeededParallel = (_, line) => {
+ const hash = getLocationHash();
+
+ if (
+ hash &&
+ ((line.left && line.left.lineCode === hash) || (line.right && line.right.lineCode === hash))
+ ) {
+ handleLocationHash();
+ }
+};
+
export const loadCollapsedDiff = ({ commit }, file) =>
axios.get(file.loadCollapsedDiffUrl).then(res => {
commit(types.ADD_COLLAPSED_DIFFS, {
@@ -159,5 +181,19 @@ export const toggleFileDiscussions = ({ getters, dispatch }, diff) => {
});
};
+export const saveDiffDiscussion = ({ dispatch }, { note, formData }) => {
+ const postData = getNoteFormData({
+ note,
+ ...formData,
+ });
+
+ return dispatch('saveNote', postData, { root: true })
+ .then(result => dispatch('updateDiscussion', result.discussion, { root: true }))
+ .then(discussion =>
+ dispatch('assignDiscussionsToDiff', reduceDiscussionsToLineCodes([discussion])),
+ )
+ .catch(() => createFlash(s__('MergeRequests|Saving the comment failed')));
+};
+
// prevent babel-plugin-rewire from generating an invalid default during karma tests
export default () => {};
diff --git a/app/assets/javascripts/diffs/store/mutations.js b/app/assets/javascripts/diffs/store/mutations.js
index 6dc5bf16c65..59a2c09e54f 100644
--- a/app/assets/javascripts/diffs/store/mutations.js
+++ b/app/assets/javascripts/diffs/store/mutations.js
@@ -90,16 +90,18 @@ export default {
const firstDiscussion = discussions[0];
const isDiffDiscussion = firstDiscussion.diff_discussion;
const hasLineCode = firstDiscussion.line_code;
- const isResolvable = firstDiscussion.resolvable;
const diffPosition = diffPositionByLineCode[firstDiscussion.line_code];
if (
selectedFile &&
isDiffDiscussion &&
hasLineCode &&
- isResolvable &&
diffPosition &&
- isDiscussionApplicableToLine(firstDiscussion, diffPosition)
+ isDiscussionApplicableToLine({
+ discussion: firstDiscussion,
+ diffPosition,
+ latestDiff: state.latestDiff,
+ })
) {
const targetLine = selectedFile.parallelDiffLines.find(
line =>
diff --git a/app/assets/javascripts/diffs/store/utils.js b/app/assets/javascripts/diffs/store/utils.js
index b7e52a8f37f..631e3de311e 100644
--- a/app/assets/javascripts/diffs/store/utils.js
+++ b/app/assets/javascripts/diffs/store/utils.js
@@ -4,6 +4,7 @@ import {
LINE_POSITION_LEFT,
LINE_POSITION_RIGHT,
TEXT_DIFF_POSITION_TYPE,
+ LEGACY_DIFF_NOTE_TYPE,
DIFF_NOTE_TYPE,
NEW_LINE_TYPE,
OLD_LINE_TYPE,
@@ -54,13 +55,17 @@ export function getNoteFormData(params) {
note_project_id: '',
target_type: noteableData.targetType,
target_id: noteableData.id,
+ return_discussion: true,
note: {
note,
position,
noteable_type: noteableType,
noteable_id: noteableData.id,
commit_id: '',
- type: DIFF_NOTE_TYPE,
+ type:
+ diffFile.diffRefs.startSha && diffFile.diffRefs.headSha
+ ? DIFF_NOTE_TYPE
+ : LEGACY_DIFF_NOTE_TYPE,
line_code: noteTargetLine.lineCode,
},
};
@@ -230,7 +235,16 @@ export function getDiffPositionByLineCode(diffFiles) {
const { lineCode, oldLine, newLine } = line;
if (lineCode) {
- acc[lineCode] = { baseSha, headSha, startSha, newPath, oldPath, oldLine, newLine };
+ acc[lineCode] = {
+ baseSha,
+ headSha,
+ startSha,
+ newPath,
+ oldPath,
+ oldLine,
+ newLine,
+ lineCode,
+ };
}
});
}
@@ -241,9 +255,15 @@ export function getDiffPositionByLineCode(diffFiles) {
// This method will check whether the discussion is still applicable
// to the diff line in question regarding different versions of the MR
-export function isDiscussionApplicableToLine(discussion, diffPosition) {
- const originalRefs = convertObjectPropsToCamelCase(discussion.original_position.formatter);
- const refs = convertObjectPropsToCamelCase(discussion.position.formatter);
+export function isDiscussionApplicableToLine({ discussion, diffPosition, latestDiff }) {
+ const { lineCode, ...diffPositionCopy } = diffPosition;
- return _.isEqual(refs, diffPosition) || _.isEqual(originalRefs, diffPosition);
+ if (discussion.original_position && discussion.position) {
+ const originalRefs = convertObjectPropsToCamelCase(discussion.original_position.formatter);
+ const refs = convertObjectPropsToCamelCase(discussion.position.formatter);
+
+ return _.isEqual(refs, diffPositionCopy) || _.isEqual(originalRefs, diffPositionCopy);
+ }
+
+ return latestDiff && discussion.active && lineCode === discussion.line_code;
}
diff --git a/app/assets/javascripts/dispatcher.js b/app/assets/javascripts/dispatcher.js
deleted file mode 100644
index a5af37e80b6..00000000000
--- a/app/assets/javascripts/dispatcher.js
+++ /dev/null
@@ -1,89 +0,0 @@
-/* eslint-disable consistent-return, no-new */
-
-import $ from 'jquery';
-import GfmAutoComplete from './gfm_auto_complete';
-import { convertPermissionToBoolean } from './lib/utils/common_utils';
-import GlFieldErrors from './gl_field_errors';
-import Shortcuts from './shortcuts';
-import SearchAutocomplete from './search_autocomplete';
-import performanceBar from './performance_bar';
-
-function initSearch() {
- // Only when search form is present
- if ($('.search').length) {
- return new SearchAutocomplete();
- }
-}
-
-function initFieldErrors() {
- $('.gl-show-field-errors').each((i, form) => {
- new GlFieldErrors(form);
- });
-}
-
-function initPageShortcuts(page) {
- const pagesWithCustomShortcuts = [
- 'projects:activity',
- 'projects:artifacts:browse',
- 'projects:artifacts:file',
- 'projects:blame:show',
- 'projects:blob:show',
- 'projects:commit:show',
- 'projects:commits:show',
- 'projects:find_file:show',
- 'projects:issues:edit',
- 'projects:issues:index',
- 'projects:issues:new',
- 'projects:issues:show',
- 'projects:merge_requests:creations:diffs',
- 'projects:merge_requests:creations:new',
- 'projects:merge_requests:edit',
- 'projects:merge_requests:index',
- 'projects:merge_requests:show',
- 'projects:network:show',
- 'projects:show',
- 'projects:tree:show',
- 'groups:show',
- ];
-
- if (pagesWithCustomShortcuts.indexOf(page) === -1) {
- new Shortcuts();
- }
-}
-
-function initGFMInput() {
- $('.js-gfm-input:not(.js-vue-textarea)').each((i, el) => {
- const gfm = new GfmAutoComplete(
- gl.GfmAutoComplete && gl.GfmAutoComplete.dataSources,
- );
- const enableGFM = convertPermissionToBoolean(
- el.dataset.supportsAutocomplete,
- );
- gfm.setup($(el), {
- emojis: true,
- members: enableGFM,
- issues: enableGFM,
- milestones: enableGFM,
- mergeRequests: enableGFM,
- labels: enableGFM,
- });
- });
-}
-
-function initPerformanceBar() {
- if (document.querySelector('#js-peek')) {
- performanceBar({ container: '#js-peek' });
- }
-}
-
-export default () => {
- initSearch();
- initFieldErrors();
-
- const page = $('body').attr('data-page');
- if (page) {
- initPageShortcuts(page);
- initGFMInput();
- initPerformanceBar();
- }
-};
diff --git a/app/assets/javascripts/dropzone_input.js b/app/assets/javascripts/dropzone_input.js
index ff969bb94a4..d2778bcdf1c 100644
--- a/app/assets/javascripts/dropzone_input.js
+++ b/app/assets/javascripts/dropzone_input.js
@@ -1,7 +1,7 @@
import $ from 'jquery';
import Dropzone from 'dropzone';
import _ from 'underscore';
-import './preview_markdown';
+import './behaviors/preview_markdown';
import csrf from './lib/utils/csrf';
import axios from './lib/utils/axios_utils';
diff --git a/app/assets/javascripts/environments/components/empty_state.vue b/app/assets/javascripts/environments/components/empty_state.vue
index 00e63c3467a..cf78f89981e 100644
--- a/app/assets/javascripts/environments/components/empty_state.vue
+++ b/app/assets/javascripts/environments/components/empty_state.vue
@@ -35,7 +35,7 @@ code gets deployed, such as staging or production.`) }}
<a
v-if="canCreateEnvironment"
:href="newPath"
- class="btn btn-create js-new-environment-button"
+ class="btn btn-success js-new-environment-button"
>
{{ s__("Environments|New environment") }}
</a>
diff --git a/app/assets/javascripts/environments/components/environments_app.vue b/app/assets/javascripts/environments/components/environments_app.vue
index 8efdfb8abe0..e2ecf426e64 100644
--- a/app/assets/javascripts/environments/components/environments_app.vue
+++ b/app/assets/javascripts/environments/components/environments_app.vue
@@ -107,7 +107,7 @@
>
<a
:href="newEnvironmentPath"
- class="btn btn-create"
+ class="btn btn-success"
>
{{ s__("Environments|New environment") }}
</a>
diff --git a/app/assets/javascripts/environments/components/environments_table.vue b/app/assets/javascripts/environments/components/environments_table.vue
index a9d9d768c06..16abafebbc0 100644
--- a/app/assets/javascripts/environments/components/environments_table.vue
+++ b/app/assets/javascripts/environments/components/environments_table.vue
@@ -83,10 +83,10 @@ export default {
:model="model">
<div
is="environment-item"
+ :key="`environment-item-${i}`"
:model="model"
:can-create-deployment="canCreateDeployment"
:can-read-environment="canReadEnvironment"
- :key="`environment-item-${i}`"
/>
<template
@@ -102,10 +102,10 @@ export default {
<div
is="environment-item"
v-for="(children, index) in model.children"
+ :key="`env-item-${i}-${index}`"
:model="children"
:can-create-deployment="canCreateDeployment"
:can-read-environment="canReadEnvironment"
- :key="`env-item-${i}-${index}`"
/>
<div :key="`sub-div-${i}`">
diff --git a/app/assets/javascripts/filtered_search/admin_runners_filtered_search_token_keys.js b/app/assets/javascripts/filtered_search/admin_runners_filtered_search_token_keys.js
index 1f9c3f41e52..b4588cc1318 100644
--- a/app/assets/javascripts/filtered_search/admin_runners_filtered_search_token_keys.js
+++ b/app/assets/javascripts/filtered_search/admin_runners_filtered_search_token_keys.js
@@ -5,7 +5,7 @@ const tokenKeys = [{
type: 'string',
param: 'status',
symbol: '',
- icon: 'signal',
+ icon: 'messages',
tag: 'status',
}];
diff --git a/app/assets/javascripts/filtered_search/components/recent_searches_dropdown_content.vue b/app/assets/javascripts/filtered_search/components/recent_searches_dropdown_content.vue
index a8eb8d94be3..21b5ccdb613 100644
--- a/app/assets/javascripts/filtered_search/components/recent_searches_dropdown_content.vue
+++ b/app/assets/javascripts/filtered_search/components/recent_searches_dropdown_content.vue
@@ -72,8 +72,8 @@ export default {
@click="onItemActivated(item.text)">
<span>
<span
- v-for="(token, index) in item.tokens"
- :key="`dropdown-token-${index}`"
+ v-for="(token, tokenIndex) in item.tokens"
+ :key="`dropdown-token-${tokenIndex}`"
class="filtered-search-history-dropdown-token"
>
<span class="name">{{ token.prefix }}</span>
diff --git a/app/assets/javascripts/filtered_search/dropdown_hint.js b/app/assets/javascripts/filtered_search/dropdown_hint.js
index 184b34b7b5e..8aecf9725e6 100644
--- a/app/assets/javascripts/filtered_search/dropdown_hint.js
+++ b/app/assets/javascripts/filtered_search/dropdown_hint.js
@@ -62,7 +62,7 @@ export default class DropdownHint extends FilteredSearchDropdown {
renderContent() {
const dropdownData = this.tokenKeys.get()
.map(tokenKey => ({
- icon: `fa-${tokenKey.icon}`,
+ icon: `${gon.sprite_icons}#${tokenKey.icon}`,
hint: tokenKey.key,
tag: `:${tokenKey.tag}`,
type: tokenKey.type,
diff --git a/app/assets/javascripts/filtered_search/issuable_filtered_search_token_keys.js b/app/assets/javascripts/filtered_search/issuable_filtered_search_token_keys.js
index 6c9499864c5..cc7291c9f59 100644
--- a/app/assets/javascripts/filtered_search/issuable_filtered_search_token_keys.js
+++ b/app/assets/javascripts/filtered_search/issuable_filtered_search_token_keys.js
@@ -19,14 +19,14 @@ export const tokenKeys = [{
type: 'string',
param: 'title',
symbol: '%',
- icon: 'clock-o',
+ icon: 'clock',
tag: '%milestone',
}, {
key: 'label',
type: 'array',
param: 'name[]',
symbol: '~',
- icon: 'tag',
+ icon: 'labels',
tag: '~label',
}];
@@ -37,7 +37,7 @@ if (gon.current_user_id) {
type: 'string',
param: 'emoji',
symbol: '',
- icon: 'thumbs-up',
+ icon: 'thumb-up',
tag: 'emoji',
});
}
diff --git a/app/assets/javascripts/frequent_items/components/frequent_items_list_item.vue b/app/assets/javascripts/frequent_items/components/frequent_items_list_item.vue
index 1f1665ff7fe..2399ee15332 100644
--- a/app/assets/javascripts/frequent_items/components/frequent_items_list_item.vue
+++ b/app/assets/javascripts/frequent_items/components/frequent_items_list_item.vue
@@ -1,5 +1,5 @@
<script>
-/* eslint-disable vue/require-default-prop, vue/require-prop-types */
+/* eslint-disable vue/require-default-prop */
import Identicon from '../../vue_shared/components/identicon.vue';
export default {
diff --git a/app/assets/javascripts/groups/components/item_actions.vue b/app/assets/javascripts/groups/components/item_actions.vue
index 6e700b8bf8a..c1783d5ce25 100644
--- a/app/assets/javascripts/groups/components/item_actions.vue
+++ b/app/assets/javascripts/groups/components/item_actions.vue
@@ -46,8 +46,8 @@ export default {
<template>
<div class="controls">
<a
- v-tooltip
v-if="group.canEdit"
+ v-tooltip
:href="group.editPath"
:title="editBtnTitle"
:aria-label="editBtnTitle"
@@ -57,8 +57,8 @@ export default {
<icon name="settings"/>
</a>
<a
- v-tooltip
v-if="group.canLeave"
+ v-tooltip
:href="group.leavePath"
:title="leaveBtnTitle"
:aria-label="leaveBtnTitle"
diff --git a/app/assets/javascripts/ide/components/branches/search_list.vue b/app/assets/javascripts/ide/components/branches/search_list.vue
index bf0ff6e35ec..52ccc537c9d 100644
--- a/app/assets/javascripts/ide/components/branches/search_list.vue
+++ b/app/assets/javascripts/ide/components/branches/search_list.vue
@@ -60,8 +60,8 @@ export default {
<div class="position-relative">
<input
ref="searchInput"
- :placeholder="__('Search branches')"
v-model="search"
+ :placeholder="__('Search branches')"
type="search"
class="form-control dropdown-input-field"
@input="searchBranches"
diff --git a/app/assets/javascripts/ide/components/commit_sidebar/list.vue b/app/assets/javascripts/ide/components/commit_sidebar/list.vue
index 3fdd35ad228..3e3539e364b 100644
--- a/app/assets/javascripts/ide/components/commit_sidebar/list.vue
+++ b/app/assets/javascripts/ide/components/commit_sidebar/list.vue
@@ -113,8 +113,8 @@ export default {
</strong>
<div class="d-flex ml-auto">
<button
- v-tooltip
ref="actionBtn"
+ v-tooltip
:title="actionBtnText"
:aria-label="actionBtnText"
:disabled="!filesLength"
@@ -135,8 +135,8 @@ export default {
/>
</button>
<button
- v-tooltip
v-if="!stagedList"
+ v-tooltip
:title="__('Discard all changes')"
:aria-label="__('Discard all changes')"
:disabled="!filesLength"
diff --git a/app/assets/javascripts/ide/components/file_finder/index.vue b/app/assets/javascripts/ide/components/file_finder/index.vue
index 0ba33053717..760ed8654ee 100644
--- a/app/assets/javascripts/ide/components/file_finder/index.vue
+++ b/app/assets/javascripts/ide/components/file_finder/index.vue
@@ -174,8 +174,8 @@ export default {
<div class="dropdown-input">
<input
ref="searchInput"
- :placeholder="__('Search files')"
v-model="searchText"
+ :placeholder="__('Search files')"
type="search"
class="dropdown-input-field"
autocomplete="off"
diff --git a/app/assets/javascripts/ide/components/file_finder/item.vue b/app/assets/javascripts/ide/components/file_finder/item.vue
index f5252ce7706..a612739d641 100644
--- a/app/assets/javascripts/ide/components/file_finder/item.vue
+++ b/app/assets/javascripts/ide/components/file_finder/item.vue
@@ -78,10 +78,10 @@ export default {
class="diff-changed-file-name"
>
<span
- v-for="(char, index) in file.name.split('')"
- :key="index + char"
+ v-for="(char, charIndex) in file.name.split('')"
+ :key="charIndex + char"
:class="{
- highlighted: nameSearchTextOccurences.indexOf(index) >= 0,
+ highlighted: nameSearchTextOccurences.indexOf(charIndex) >= 0,
}"
v-text="char"
>
@@ -91,10 +91,10 @@ export default {
class="diff-changed-file-path prepend-top-5"
>
<span
- v-for="(char, index) in pathWithEllipsis.split('')"
- :key="index + char"
+ v-for="(char, charIndex) in pathWithEllipsis.split('')"
+ :key="charIndex + char"
:class="{
- highlighted: pathSearchTextOccurences.indexOf(index) >= 0,
+ highlighted: pathSearchTextOccurences.indexOf(charIndex) >= 0,
}"
v-text="char"
>
diff --git a/app/assets/javascripts/ide/components/file_row_extra.vue b/app/assets/javascripts/ide/components/file_row_extra.vue
new file mode 100644
index 00000000000..44a360ab909
--- /dev/null
+++ b/app/assets/javascripts/ide/components/file_row_extra.vue
@@ -0,0 +1,104 @@
+<script>
+import { mapGetters } from 'vuex';
+import { n__, __, sprintf } from '~/locale';
+import tooltip from '~/vue_shared/directives/tooltip';
+import Icon from '~/vue_shared/components/icon.vue';
+import NewDropdown from './new_dropdown/index.vue';
+import ChangedFileIcon from './changed_file_icon.vue';
+import MrFileIcon from './mr_file_icon.vue';
+
+export default {
+ name: 'FileRowExtra',
+ directives: {
+ tooltip,
+ },
+ components: {
+ Icon,
+ NewDropdown,
+ ChangedFileIcon,
+ MrFileIcon,
+ },
+ props: {
+ file: {
+ type: Object,
+ required: true,
+ },
+ mouseOver: {
+ type: Boolean,
+ required: true,
+ },
+ },
+ computed: {
+ ...mapGetters([
+ 'getChangesInFolder',
+ 'getUnstagedFilesCountForPath',
+ 'getStagedFilesCountForPath',
+ ]),
+ folderUnstagedCount() {
+ return this.getUnstagedFilesCountForPath(this.file.path);
+ },
+ folderStagedCount() {
+ return this.getStagedFilesCountForPath(this.file.path);
+ },
+ changesCount() {
+ return this.getChangesInFolder(this.file.path);
+ },
+ folderChangesTooltip() {
+ if (this.changesCount === 0) return undefined;
+
+ if (this.folderUnstagedCount > 0 && this.folderStagedCount === 0) {
+ return n__('%d unstaged change', '%d unstaged changes', this.folderUnstagedCount);
+ } else if (this.folderUnstagedCount === 0 && this.folderStagedCount > 0) {
+ return n__('%d staged change', '%d staged changes', this.folderStagedCount);
+ }
+
+ return sprintf(__('%{unstaged} unstaged and %{staged} staged changes'), {
+ unstaged: this.folderUnstagedCount,
+ staged: this.folderStagedCount,
+ });
+ },
+ showTreeChangesCount() {
+ return this.file.type === 'tree' && this.changesCount > 0 && !this.file.opened;
+ },
+ showChangedFileIcon() {
+ return this.file.changed || this.file.tempFile || this.file.staged;
+ },
+ },
+};
+</script>
+
+<template>
+ <div class="float-right ide-file-icon-holder">
+ <mr-file-icon
+ v-if="file.mrChange"
+ />
+ <span
+ v-if="showTreeChangesCount"
+ class="ide-tree-changes"
+ >
+ {{ changesCount }}
+ <icon
+ v-tooltip
+ :title="folderChangesTooltip"
+ :size="12"
+ data-container="body"
+ data-placement="right"
+ name="file-modified"
+ css-classes="prepend-left-5 ide-file-modified"
+ />
+ </span>
+ <changed-file-icon
+ v-else-if="showChangedFileIcon"
+ :file="file"
+ :show-tooltip="true"
+ :show-staged-icon="true"
+ :force-modified-icon="true"
+ />
+ <new-dropdown
+ :type="file.type"
+ :path="file.path"
+ :mouse-over="mouseOver"
+ class="prepend-left-8"
+ />
+ </div>
+</template>
diff --git a/app/assets/javascripts/ide/components/ide_tree_list.vue b/app/assets/javascripts/ide/components/ide_tree_list.vue
index 00ae5ea2c15..e658d1bf956 100644
--- a/app/assets/javascripts/ide/components/ide_tree_list.vue
+++ b/app/assets/javascripts/ide/components/ide_tree_list.vue
@@ -2,15 +2,16 @@
import { mapActions, mapGetters, mapState } from 'vuex';
import Icon from '~/vue_shared/components/icon.vue';
import SkeletonLoadingContainer from '~/vue_shared/components/skeleton_loading_container.vue';
-import RepoFile from './repo_file.vue';
+import FileRow from '~/vue_shared/components/file_row.vue';
import NavDropdown from './nav_dropdown.vue';
+import FileRowExtra from './file_row_extra.vue';
export default {
components: {
Icon,
- RepoFile,
SkeletonLoadingContainer,
NavDropdown,
+ FileRow,
},
props: {
viewerType: {
@@ -34,8 +35,9 @@ export default {
this.updateViewer(this.viewerType);
},
methods: {
- ...mapActions(['updateViewer']),
+ ...mapActions(['updateViewer', 'toggleTreeOpen']),
},
+ FileRowExtra,
};
</script>
@@ -63,11 +65,13 @@ export default {
<div
class="ide-tree-body h-100"
>
- <repo-file
+ <file-row
v-for="file in currentTree.tree"
:key="file.key"
:file="file"
:level="0"
+ :extra-component="$options.FileRowExtra"
+ @toggleTreeOpen="toggleTreeOpen"
/>
</div>
</template>
diff --git a/app/assets/javascripts/ide/components/jobs/stage.vue b/app/assets/javascripts/ide/components/jobs/stage.vue
index 1c474acb4b2..ec168d36b9e 100644
--- a/app/assets/javascripts/ide/components/jobs/stage.vue
+++ b/app/assets/javascripts/ide/components/jobs/stage.vue
@@ -69,8 +69,8 @@ export default {
:size="24"
/>
<strong
- v-tooltip="showTooltip"
ref="stageTitle"
+ v-tooltip="showTooltip"
:title="showTooltip ? stage.name : null"
data-container="body"
class="prepend-left-8 ide-stage-title"
diff --git a/app/assets/javascripts/ide/components/repo_file.vue b/app/assets/javascripts/ide/components/repo_file.vue
deleted file mode 100644
index 110eda83bb4..00000000000
--- a/app/assets/javascripts/ide/components/repo_file.vue
+++ /dev/null
@@ -1,227 +0,0 @@
-<script>
-import { mapActions, mapGetters } from 'vuex';
-import { n__, __, sprintf } from '~/locale';
-import tooltip from '~/vue_shared/directives/tooltip';
-import SkeletonLoadingContainer from '~/vue_shared/components/skeleton_loading_container.vue';
-import Icon from '~/vue_shared/components/icon.vue';
-import FileIcon from '~/vue_shared/components/file_icon.vue';
-import router from '../ide_router';
-import NewDropdown from './new_dropdown/index.vue';
-import FileStatusIcon from './repo_file_status_icon.vue';
-import ChangedFileIcon from './changed_file_icon.vue';
-import MrFileIcon from './mr_file_icon.vue';
-
-export default {
- name: 'RepoFile',
- directives: {
- tooltip,
- },
- components: {
- SkeletonLoadingContainer,
- NewDropdown,
- FileStatusIcon,
- FileIcon,
- ChangedFileIcon,
- MrFileIcon,
- Icon,
- },
- props: {
- file: {
- type: Object,
- required: true,
- },
- level: {
- type: Number,
- required: true,
- },
- },
- data() {
- return {
- mouseOver: false,
- };
- },
- computed: {
- ...mapGetters([
- 'getChangesInFolder',
- 'getUnstagedFilesCountForPath',
- 'getStagedFilesCountForPath',
- ]),
- folderUnstagedCount() {
- return this.getUnstagedFilesCountForPath(this.file.path);
- },
- folderStagedCount() {
- return this.getStagedFilesCountForPath(this.file.path);
- },
- changesCount() {
- return this.getChangesInFolder(this.file.path);
- },
- folderChangesTooltip() {
- if (this.changesCount === 0) return undefined;
-
- if (this.folderUnstagedCount > 0 && this.folderStagedCount === 0) {
- return n__('%d unstaged change', '%d unstaged changes', this.folderUnstagedCount);
- } else if (this.folderUnstagedCount === 0 && this.folderStagedCount > 0) {
- return n__('%d staged change', '%d staged changes', this.folderStagedCount);
- }
-
- return sprintf(__('%{unstaged} unstaged and %{staged} staged changes'), {
- unstaged: this.folderUnstagedCount,
- staged: this.folderStagedCount,
- });
- },
- isTree() {
- return this.file.type === 'tree';
- },
- isBlob() {
- return this.file.type === 'blob';
- },
- levelIndentation() {
- return {
- marginLeft: `${this.level * 16}px`,
- };
- },
- fileClass() {
- return {
- 'file-open': this.isBlob && this.file.opened,
- 'file-active': this.isBlob && this.file.active,
- folder: this.isTree,
- 'is-open': this.file.opened,
- };
- },
- showTreeChangesCount() {
- return this.isTree && this.changesCount > 0 && !this.file.opened;
- },
- showChangedFileIcon() {
- return this.file.changed || this.file.tempFile || this.file.staged;
- },
- },
- watch: {
- 'file.active': function fileActiveWatch(active) {
- if (this.file.type === 'blob' && active) {
- this.scrollIntoView();
- }
- },
- },
- mounted() {
- if (this.hasPathAtCurrentRoute()) {
- this.scrollIntoView(true);
- }
- },
- methods: {
- ...mapActions(['toggleTreeOpen']),
- clickFile() {
- // Manual Action if a tree is selected/opened
- if (this.isTree && this.hasUrlAtCurrentRoute()) {
- this.toggleTreeOpen(this.file.path);
- }
-
- router.push(`/project${this.file.url}`);
- },
- scrollIntoView(isInit = false) {
- const block = isInit && this.isTree ? 'center' : 'nearest';
-
- this.$el.scrollIntoView({
- behavior: 'smooth',
- block,
- });
- },
- hasPathAtCurrentRoute() {
- if (!this.$router || !this.$router.currentRoute) {
- return false;
- }
-
- // - strip route up to "/-/" and ending "/"
- const routePath = this.$router.currentRoute.path
- .replace(/^.*?[/]-[/]/g, '')
- .replace(/[/]$/g, '');
-
- // - strip ending "/"
- const filePath = this.file.path.replace(/[/]$/g, '');
-
- return filePath === routePath;
- },
- hasUrlAtCurrentRoute() {
- return this.$router.currentRoute.path === `/project${this.file.url}`;
- },
- toggleHover(over) {
- this.mouseOver = over;
- },
- },
-};
-</script>
-
-<template>
- <div>
- <div
- :class="fileClass"
- class="file"
- role="button"
- @click="clickFile"
- @mouseover="toggleHover(true)"
- @mouseout="toggleHover(false)"
- >
- <div
- class="file-name"
- >
- <span
- :style="levelIndentation"
- class="ide-file-name str-truncated"
- >
- <file-icon
- :file-name="file.name"
- :loading="file.loading"
- :folder="isTree"
- :opened="file.opened"
- :size="16"
- />
- {{ file.name }}
- <file-status-icon
- :file="file"
- />
- </span>
- <span class="float-right ide-file-icon-holder">
- <mr-file-icon
- v-if="file.mrChange"
- />
- <span
- v-if="showTreeChangesCount"
- class="ide-tree-changes"
- >
- {{ changesCount }}
- <icon
- v-tooltip
- :title="folderChangesTooltip"
- :size="12"
- data-container="body"
- data-placement="right"
- name="file-modified"
- css-classes="prepend-left-5 ide-file-modified"
- />
- </span>
- <changed-file-icon
- v-else-if="showChangedFileIcon"
- :file="file"
- :show-tooltip="true"
- :show-staged-icon="true"
- :force-modified-icon="true"
- class="float-right"
- />
- </span>
- <new-dropdown
- :type="file.type"
- :path="file.path"
- :mouse-over="mouseOver"
- class="float-right prepend-left-8"
- />
- </div>
- </div>
- <template v-if="file.opened">
- <repo-file
- v-for="childFile in file.tree"
- :key="childFile.key"
- :file="childFile"
- :level="level + 1"
- />
- </template>
- </div>
-</template>
diff --git a/app/assets/javascripts/ide/components/repo_file_status_icon.vue b/app/assets/javascripts/ide/components/repo_file_status_icon.vue
index 76a3333be50..97589e116c5 100644
--- a/app/assets/javascripts/ide/components/repo_file_status_icon.vue
+++ b/app/assets/javascripts/ide/components/repo_file_status_icon.vue
@@ -26,8 +26,8 @@ export default {
<template>
<span
- v-tooltip
v-if="file.file_lock"
+ v-tooltip
:title="lockTooltip"
data-container="body"
>
diff --git a/app/assets/javascripts/issuable_bulk_update_actions.js b/app/assets/javascripts/issuable_bulk_update_actions.js
index 35eaf21a836..9e848699163 100644
--- a/app/assets/javascripts/issuable_bulk_update_actions.js
+++ b/app/assets/javascripts/issuable_bulk_update_actions.js
@@ -36,7 +36,7 @@ export default {
},
getSelectedIssues() {
- return this.issues.has('.selected_issue:checked');
+ return this.issues.has('.selected-issuable:checked');
},
getLabelsFromSelection() {
@@ -110,7 +110,7 @@ export default {
getOriginalCommonIds() {
const labelIds = [];
- this.getElement('.selected_issue:checked').each((i, el) => {
+ this.getElement('.selected-issuable:checked').each((i, el) => {
labelIds.push(this.getElement(`#${this.prefixId}${el.dataset.id}`).data('labels'));
});
return _.intersection.apply(this, labelIds);
@@ -119,7 +119,7 @@ export default {
// From issuable's initial bulk selection
getOriginalMarkedIds() {
const labelIds = [];
- this.getElement('.selected_issue:checked').each((i, el) => {
+ this.getElement('.selected-issuable:checked').each((i, el) => {
labelIds.push(this.getElement(`#${this.prefixId}${el.dataset.id}`).data('labels'));
});
return _.intersection.apply(this, labelIds);
@@ -132,7 +132,7 @@ export default {
let issuableLabels = [];
// Collect unique label IDs for all checked issues
- this.getElement('.selected_issue:checked').each((i, el) => {
+ this.getElement('.selected-issuable:checked').each((i, el) => {
issuableLabels = this.getElement(`#${this.prefixId}${el.dataset.id}`).data('labels');
issuableLabels.forEach((labelId) => {
// Store unique IDs
diff --git a/app/assets/javascripts/issuable_bulk_update_sidebar.js b/app/assets/javascripts/issuable_bulk_update_sidebar.js
index 2307c8e0d85..74150ce3a8b 100644
--- a/app/assets/javascripts/issuable_bulk_update_sidebar.js
+++ b/app/assets/javascripts/issuable_bulk_update_sidebar.js
@@ -30,7 +30,7 @@ export default class IssuableBulkUpdateSidebar {
this.$otherFilters = $('.issues-other-filters');
this.$checkAllContainer = $('.check-all-holder');
this.$issueChecks = $('.issue-check');
- this.$issuesList = $('.selected_issue');
+ this.$issuesList = $('.selected-issuable');
this.$issuableIdsInput = $('#update_issuable_ids');
}
@@ -55,7 +55,7 @@ export default class IssuableBulkUpdateSidebar {
}
updateFormState() {
- const noCheckedIssues = !$('.selected_issue:checked').length;
+ const noCheckedIssues = !$('.selected-issuable:checked').length;
this.toggleSubmitButtonDisabled(noCheckedIssues);
this.updateSelectedIssuableIds();
@@ -123,7 +123,7 @@ export default class IssuableBulkUpdateSidebar {
}
static getCheckedIssueIds() {
- const $checkedIssues = $('.selected_issue:checked');
+ const $checkedIssues = $('.selected-issuable:checked');
if ($checkedIssues.length > 0) {
return $.map($checkedIssues, value => $(value).data('id'));
diff --git a/app/assets/javascripts/issue_show/components/edit_actions.vue b/app/assets/javascripts/issue_show/components/edit_actions.vue
index 597c6d69a81..7fd3ea61aa7 100644
--- a/app/assets/javascripts/issue_show/components/edit_actions.vue
+++ b/app/assets/javascripts/issue_show/components/edit_actions.vue
@@ -53,7 +53,7 @@
<button
:class="{ disabled: formState.updateLoading || !isSubmitEnabled }"
:disabled="formState.updateLoading || !isSubmitEnabled"
- class="btn btn-save float-left"
+ class="btn btn-success float-left"
type="submit"
@click.prevent="updateIssuable">
Save changes
diff --git a/app/assets/javascripts/issue_show/components/title.vue b/app/assets/javascripts/issue_show/components/title.vue
index b5e8e0ea44b..cf99e9a9cd8 100644
--- a/app/assets/javascripts/issue_show/components/title.vue
+++ b/app/assets/javascripts/issue_show/components/title.vue
@@ -76,8 +76,8 @@ export default {
>
</h2>
<button
- v-tooltip
v-if="showInlineEditButton && canUpdate"
+ v-tooltip
type="button"
class="btn btn-default btn-edit btn-svg js-issuable-edit"
title="Edit title and description"
diff --git a/app/assets/javascripts/jobs/components/header.vue b/app/assets/javascripts/jobs/components/header.vue
index 3e49b04e44e..63324e68d68 100644
--- a/app/assets/javascripts/jobs/components/header.vue
+++ b/app/assets/javascripts/jobs/components/header.vue
@@ -57,7 +57,7 @@ export default {
actions.push({
label: 'New issue',
path: this.job.new_issue_path,
- cssClass: 'js-new-issue btn btn-new btn-inverted d-none d-md-block d-lg-block d-xl-block',
+ cssClass: 'js-new-issue btn btn-success btn-inverted d-none d-md-block d-lg-block d-xl-block',
type: 'link',
});
}
diff --git a/app/assets/javascripts/jobs/components/job_log_controllers.vue b/app/assets/javascripts/jobs/components/job_log_controllers.vue
index 513851e376f..2cbf0f85266 100644
--- a/app/assets/javascripts/jobs/components/job_log_controllers.vue
+++ b/app/assets/javascripts/jobs/components/job_log_controllers.vue
@@ -78,8 +78,8 @@
<div class="controllers float-right">
<!-- links -->
<a
- v-tooltip
v-if="rawTracePath"
+ v-tooltip
:title="s__('Job|Show complete raw')"
:href="rawTracePath"
class="js-raw-link-controller controllers-buttons"
@@ -89,8 +89,8 @@
</a>
<button
- v-tooltip
v-if="canEraseJob"
+ v-tooltip
:title="s__('Job|Erase job log')"
type="button"
class="js-erase-link controllers-buttons"
diff --git a/app/assets/javascripts/jobs/components/jobs_container.vue b/app/assets/javascripts/jobs/components/jobs_container.vue
index b81109bdd06..93e2292ff84 100644
--- a/app/assets/javascripts/jobs/components/jobs_container.vue
+++ b/app/assets/javascripts/jobs/components/jobs_container.vue
@@ -25,9 +25,9 @@
class="build-job"
>
<a
- v-tooltip
v-for="job in jobs"
:key="job.id"
+ v-tooltip
:href="job.path"
:title="job.tooltip"
:class="{ active: job.active, retried: job.retried }"
diff --git a/app/assets/javascripts/jobs/components/sidebar_details_block.vue b/app/assets/javascripts/jobs/components/sidebar_details_block.vue
index 1210ccd038a..80c2a5fb48b 100644
--- a/app/assets/javascripts/jobs/components/sidebar_details_block.vue
+++ b/app/assets/javascripts/jobs/components/sidebar_details_block.vue
@@ -130,7 +130,7 @@ export default {
<a
v-if="job.new_issue_path"
:href="job.new_issue_path"
- class="js-new-issue btn btn-new btn-inverted"
+ class="js-new-issue btn btn-success btn-inverted"
>
{{ __('New issue') }}
</a>
diff --git a/app/assets/javascripts/labels_select.js b/app/assets/javascripts/labels_select.js
index 6499b919787..1c7bca78df3 100644
--- a/app/assets/javascripts/labels_select.js
+++ b/app/assets/javascripts/labels_select.js
@@ -449,11 +449,11 @@ export default class LabelsSelect {
}
bindEvents() {
- return $('body').on('change', '.selected_issue', this.onSelectCheckboxIssue);
+ return $('body').on('change', '.selected-issuable', this.onSelectCheckboxIssue);
}
// eslint-disable-next-line class-methods-use-this
onSelectCheckboxIssue() {
- if ($('.selected_issue:checked').length) {
+ if ($('.selected-issuable:checked').length) {
return;
}
return $('.issues-bulk-update .labels-filter .dropdown-toggle-text').text('Label');
diff --git a/app/assets/javascripts/lib/utils/common_utils.js b/app/assets/javascripts/lib/utils/common_utils.js
index 0849d97bc1a..30925940807 100644
--- a/app/assets/javascripts/lib/utils/common_utils.js
+++ b/app/assets/javascripts/lib/utils/common_utils.js
@@ -56,7 +56,8 @@ export const rstrip = val => {
return val;
};
-export const updateTooltipTitle = ($tooltipEl, newTitle) => $tooltipEl.attr('title', newTitle).tooltip('_fixTitle');
+export const updateTooltipTitle = ($tooltipEl, newTitle) =>
+ $tooltipEl.attr('title', newTitle).tooltip('_fixTitle');
export const disableButtonIfEmptyField = (fieldSelector, buttonSelector, eventName = 'input') => {
const field = $(fieldSelector);
@@ -86,6 +87,7 @@ export const handleLocationHash = () => {
const fixedTabs = document.querySelector('.js-tabs-affix');
const fixedDiffStats = document.querySelector('.js-diff-files-changed');
const fixedNav = document.querySelector('.navbar-gitlab');
+ const performanceBar = document.querySelector('#js-peek');
let adjustment = 0;
if (fixedNav) adjustment -= fixedNav.offsetHeight;
@@ -102,6 +104,10 @@ export const handleLocationHash = () => {
adjustment -= fixedDiffStats.offsetHeight;
}
+ if (performanceBar) {
+ adjustment -= performanceBar.offsetHeight;
+ }
+
window.scrollBy(0, adjustment);
};
@@ -131,21 +137,20 @@ export const parseUrlPathname = url => {
return parsedUrl.pathname.charAt(0) === '/' ? parsedUrl.pathname : `/${parsedUrl.pathname}`;
};
-const splitPath = (path = '') => path
- .replace(/^\?/, '')
- .split('&');
+const splitPath = (path = '') => path.replace(/^\?/, '').split('&');
-export const urlParamsToArray = (path = '') => splitPath(path)
- .filter(param => param.length > 0)
- .map(param => {
- const split = param.split('=');
- return [decodeURI(split[0]), split[1]].join('=');
- });
+export const urlParamsToArray = (path = '') =>
+ splitPath(path)
+ .filter(param => param.length > 0)
+ .map(param => {
+ const split = param.split('=');
+ return [decodeURI(split[0]), split[1]].join('=');
+ });
export const getUrlParamsArray = () => urlParamsToArray(window.location.search);
-export const urlParamsToObject = (path = '') => splitPath(path)
- .reduce((dataParam, filterParam) => {
+export const urlParamsToObject = (path = '') =>
+ splitPath(path).reduce((dataParam, filterParam) => {
if (filterParam === '') {
return dataParam;
}
@@ -216,7 +221,7 @@ export const getParameterByName = (name, urlToParse) => {
return decodeURIComponent(results[2].replace(/\+/g, ' '));
};
-const handleSelectedRange = (range) => {
+const handleSelectedRange = range => {
const container = range.commonAncestorContainer;
// add context to fragment if needed
if (container.tagName === 'OL') {
@@ -453,7 +458,7 @@ export const backOff = (fn, timeout = 60000) => {
export const createOverlayIcon = (iconPath, overlayPath) => {
const faviconImage = document.createElement('img');
- return new Promise((resolve) => {
+ return new Promise(resolve => {
faviconImage.onload = () => {
const size = 32;
@@ -464,13 +469,29 @@ export const createOverlayIcon = (iconPath, overlayPath) => {
const context = canvas.getContext('2d');
context.clearRect(0, 0, size, size);
context.drawImage(
- faviconImage, 0, 0, faviconImage.width, faviconImage.height, 0, 0, size, size,
+ faviconImage,
+ 0,
+ 0,
+ faviconImage.width,
+ faviconImage.height,
+ 0,
+ 0,
+ size,
+ size,
);
const overlayImage = document.createElement('img');
overlayImage.onload = () => {
context.drawImage(
- overlayImage, 0, 0, overlayImage.width, overlayImage.height, 0, 0, size, size,
+ overlayImage,
+ 0,
+ 0,
+ overlayImage.width,
+ overlayImage.height,
+ 0,
+ 0,
+ size,
+ size,
);
const faviconWithOverlayUrl = canvas.toDataURL();
@@ -483,17 +504,21 @@ export const createOverlayIcon = (iconPath, overlayPath) => {
});
};
-export const setFaviconOverlay = (overlayPath) => {
+export const setFaviconOverlay = overlayPath => {
const faviconEl = document.getElementById('favicon');
- if (!faviconEl) { return null; }
+ if (!faviconEl) {
+ return null;
+ }
const iconPath = faviconEl.getAttribute('data-original-href');
- return createOverlayIcon(iconPath, overlayPath).then(faviconWithOverlayUrl => faviconEl.setAttribute('href', faviconWithOverlayUrl));
+ return createOverlayIcon(iconPath, overlayPath).then(faviconWithOverlayUrl =>
+ faviconEl.setAttribute('href', faviconWithOverlayUrl),
+ );
};
-export const setFavicon = (faviconPath) => {
+export const setFavicon = faviconPath => {
const faviconEl = document.getElementById('favicon');
if (faviconEl && faviconPath) {
faviconEl.setAttribute('href', faviconPath);
@@ -518,7 +543,7 @@ export const setCiStatusFavicon = pageUrl =>
}
return resetFavicon();
})
- .catch((error) => {
+ .catch(error => {
resetFavicon();
throw error;
});
diff --git a/app/assets/javascripts/shortcuts_dashboard_navigation.js b/app/assets/javascripts/lib/utils/navigation_utility.js
index 9f69f110d06..1579b225e44 100644
--- a/app/assets/javascripts/shortcuts_dashboard_navigation.js
+++ b/app/assets/javascripts/lib/utils/navigation_utility.js
@@ -1,4 +1,4 @@
-import { visitUrl } from './lib/utils/url_utility';
+import { visitUrl } from './url_utility';
/**
* Helper function that finds the href of the fiven selector and updates the location.
diff --git a/app/assets/javascripts/main.js b/app/assets/javascripts/main.js
index c5a5f64abac..e8aac51a299 100644
--- a/app/assets/javascripts/main.js
+++ b/app/assets/javascripts/main.js
@@ -2,7 +2,6 @@
import jQuery from 'jquery';
import Cookies from 'js-cookie';
-import svg4everybody from 'svg4everybody';
// bootstrap webpack, common libs, polyfills, and behaviors
import './webpack';
@@ -25,11 +24,12 @@ import initLayoutNav from './layout_nav';
import './feature_highlight/feature_highlight_options';
import LazyLoader from './lazy_loader';
import initLogoAnimation from './logo';
-import './milestone_select';
import './frequent_items';
import initBreadcrumbs from './breadcrumb';
-import initDispatcher from './dispatcher';
import initUsagePingConsent from './usage_ping_consent';
+import initPerformanceBar from './performance_bar';
+import initSearchAutocomplete from './search_autocomplete';
+import GlFieldErrors from './gl_field_errors';
// expose jQuery as global (TODO: remove these)
window.jQuery = jQuery;
@@ -41,8 +41,6 @@ if (process.env.NODE_ENV !== 'production' && gon && gon.test_env) {
import(/* webpackMode: "eager" */ './test_utils/');
}
-svg4everybody();
-
document.addEventListener('beforeunload', () => {
// Unbind scroll events
$(document).off('scroll');
@@ -81,6 +79,9 @@ document.addEventListener('DOMContentLoaded', () => {
initLogoAnimation();
initUsagePingConsent();
+ if (document.querySelector('.search')) initSearchAutocomplete();
+ if (document.querySelector('#js-peek')) initPerformanceBar({ container: '#js-peek' });
+
// Set the default path for all cookies to GitLab's root directory
Cookies.defaults.path = gon.relative_url_root || '/';
@@ -270,5 +271,6 @@ document.addEventListener('DOMContentLoaded', () => {
});
}
- initDispatcher();
+ // initialize field errors
+ $('.gl-show-field-errors').each((i, form) => new GlFieldErrors(form));
});
diff --git a/app/assets/javascripts/merge_request_tabs.js b/app/assets/javascripts/merge_request_tabs.js
index 53d7504de35..763429d7242 100644
--- a/app/assets/javascripts/merge_request_tabs.js
+++ b/app/assets/javascripts/merge_request_tabs.js
@@ -115,8 +115,9 @@ export default class MergeRequestTabs {
this.mergeRequestTabs &&
this.mergeRequestTabs.querySelector(`a[data-action='${action}']`) &&
this.mergeRequestTabs.querySelector(`a[data-action='${action}']`).click
- )
+ ) {
this.mergeRequestTabs.querySelector(`a[data-action='${action}']`).click();
+ }
this.initAffix();
}
diff --git a/app/assets/javascripts/monitoring/components/dashboard.vue b/app/assets/javascripts/monitoring/components/dashboard.vue
index ae96ac3b80c..a07a0ecfc76 100644
--- a/app/assets/javascripts/monitoring/components/dashboard.vue
+++ b/app/assets/javascripts/monitoring/components/dashboard.vue
@@ -214,8 +214,8 @@ export default {
:show-panels="showPanels"
>
<graph
- v-for="(graphData, index) in groupData.metrics"
- :key="index"
+ v-for="(graphData, graphIndex) in groupData.metrics"
+ :key="graphIndex"
:graph-data="graphData"
:hover-data="hoverData"
:update-aspect-ratio="updateAspectRatio"
diff --git a/app/assets/javascripts/monitoring/components/graph/legend.vue b/app/assets/javascripts/monitoring/components/graph/legend.vue
index 3276f3a1ceb..ef18ae5c2c8 100644
--- a/app/assets/javascripts/monitoring/components/graph/legend.vue
+++ b/app/assets/javascripts/monitoring/components/graph/legend.vue
@@ -58,8 +58,8 @@ export default {
</td>
<template v-for="(track, trackIndex) in series.tracksLegend">
<track-line
- :track="track"
- :key="`track-line-${trackIndex}`"/>
+ :key="`track-line-${trackIndex}`"
+ :track="track"/>
<td :key="`track-info-${trackIndex}`">
<track-info
:track="track"
diff --git a/app/assets/javascripts/notebook/index.vue b/app/assets/javascripts/notebook/index.vue
index e2e3b08c77f..f241df9620d 100644
--- a/app/assets/javascripts/notebook/index.vue
+++ b/app/assets/javascripts/notebook/index.vue
@@ -51,10 +51,10 @@
<template>
<div v-if="hasNotebook">
<component
- v-for="(cell, index) in cells"
:is="cellType(cell.cell_type)"
- :cell="cell"
+ v-for="(cell, index) in cells"
:key="index"
+ :cell="cell"
:code-css-class="codeCssClass" />
</div>
</template>
diff --git a/app/assets/javascripts/notes/components/comment_form.vue b/app/assets/javascripts/notes/components/comment_form.vue
index 6612bc44e0b..7735133c470 100644
--- a/app/assets/javascripts/notes/components/comment_form.vue
+++ b/app/assets/javascripts/notes/components/comment_form.vue
@@ -374,7 +374,7 @@ js-gfm-input js-autosize markdown-area js-vue-textarea"
append-right-10 comment-type-dropdown js-comment-type-dropdown droplab-dropdown">
<button
:disabled="isSubmitButtonDisabled"
- class="btn btn-create comment-btn js-comment-button js-comment-submit-button"
+ class="btn btn-success comment-btn js-comment-button js-comment-submit-button"
type="submit"
@click.prevent="handleSave()">
{{ __(commentButtonTitle) }}
diff --git a/app/assets/javascripts/notes/components/diff_file_header.vue b/app/assets/javascripts/notes/components/diff_file_header.vue
index fc7b52be241..4fd93304a03 100644
--- a/app/assets/javascripts/notes/components/diff_file_header.vue
+++ b/app/assets/javascripts/notes/components/diff_file_header.vue
@@ -41,8 +41,8 @@ export default {
</div>
<template v-else>
<component
- ref="titleWrapper"
:is="titleTag"
+ ref="titleWrapper"
:href="diffFile.discussionPath"
>
<span v-html="diffFile.blobIcon"></span>
diff --git a/app/assets/javascripts/notes/components/note_awards_list.vue b/app/assets/javascripts/notes/components/note_awards_list.vue
index 051b17e9aa9..c68860d98ae 100644
--- a/app/assets/javascripts/notes/components/note_awards_list.vue
+++ b/app/assets/javascripts/notes/components/note_awards_list.vue
@@ -182,9 +182,9 @@ export default {
<div class="note-awards">
<div class="awards js-awards-block">
<button
- v-tooltip
v-for="(awardList, awardName, index) in groupedAwards"
:key="index"
+ v-tooltip
:class="getAwardClassBindings(awardList)"
:title="awardTitle(awardList)"
class="btn award-control"
diff --git a/app/assets/javascripts/notes/components/note_form.vue b/app/assets/javascripts/notes/components/note_form.vue
index c41ed070383..2d47d55f33c 100644
--- a/app/assets/javascripts/notes/components/note_form.vue
+++ b/app/assets/javascripts/notes/components/note_form.vue
@@ -171,8 +171,8 @@ export default {
id="note_note"
ref="textarea"
slot="textarea"
- :data-supports-quick-actions="!isEditing"
v-model="updatedNoteBody"
+ :data-supports-quick-actions="!isEditing"
name="note[note]"
class="note-textarea js-gfm-input js-note-text
js-autosize markdown-area js-vue-issue-note-form js-vue-textarea"
@@ -188,7 +188,7 @@ js-autosize markdown-area js-vue-issue-note-form js-vue-textarea"
<button
:disabled="isDisabled"
type="button"
- class="js-vue-issue-save btn btn-save js-comment-button "
+ class="js-vue-issue-save btn btn-success js-comment-button "
@click="handleUpdate()">
{{ saveButtonTitle }}
</button>
diff --git a/app/assets/javascripts/notes/components/noteable_discussion.vue b/app/assets/javascripts/notes/components/noteable_discussion.vue
index afe86911230..6ede7562edf 100644
--- a/app/assets/javascripts/notes/components/noteable_discussion.vue
+++ b/app/assets/javascripts/notes/components/noteable_discussion.vue
@@ -348,10 +348,10 @@ Please check your network connection and try again.`;
<div class="discussion-notes">
<ul class="notes">
<component
- v-for="note in discussion.notes"
:is="componentName(note)"
- :note="componentData(note)"
+ v-for="note in discussion.notes"
:key="note.id"
+ :note="componentData(note)"
@handleDeleteNote="deleteNoteHandler"
/>
</ul>
diff --git a/app/assets/javascripts/notes/components/notes_app.vue b/app/assets/javascripts/notes/components/notes_app.vue
index 42c87fdf54a..d8e8efb982a 100644
--- a/app/assets/javascripts/notes/components/notes_app.vue
+++ b/app/assets/javascripts/notes/components/notes_app.vue
@@ -187,10 +187,10 @@ export default {
class="notes main-notes-list timeline"
>
<component
- v-for="discussion in allDiscussions"
:is="getComponentName(discussion)"
- v-bind="getComponentData(discussion)"
+ v-for="discussion in allDiscussions"
:key="discussion.id"
+ v-bind="getComponentData(discussion)"
/>
</ul>
diff --git a/app/assets/javascripts/notes/stores/actions.js b/app/assets/javascripts/notes/stores/actions.js
index 68df63b8539..320dfa47d5a 100644
--- a/app/assets/javascripts/notes/stores/actions.js
+++ b/app/assets/javascripts/notes/stores/actions.js
@@ -44,23 +44,11 @@ export const fetchDiscussions = ({ commit }, path) =>
commit(types.SET_INITIAL_DISCUSSIONS, discussions);
});
-export const refetchDiscussionById = ({ commit, state }, { path, discussionId }) =>
- new Promise(resolve => {
- service
- .fetchDiscussions(path)
- .then(res => res.json())
- .then(discussions => {
- const selectedDiscussion = discussions.find(discussion => discussion.id === discussionId);
- if (selectedDiscussion) {
- commit(types.UPDATE_DISCUSSION, selectedDiscussion);
- // We need to refetch as it is now the transformed one in state
- const discussion = utils.findNoteObjectById(state.discussions, discussionId);
-
- resolve(discussion);
- }
- })
- .catch(() => {});
- });
+export const updateDiscussion = ({ commit, state }, discussion) => {
+ commit(types.UPDATE_DISCUSSION, discussion);
+
+ return utils.findNoteObjectById(state.discussions, discussion.id);
+};
export const deleteNote = ({ commit, dispatch }, note) =>
service.deleteNote(note.path).then(() => {
diff --git a/app/assets/javascripts/notes/stores/mutations.js b/app/assets/javascripts/notes/stores/mutations.js
index 16bb54be126..73e55705f39 100644
--- a/app/assets/javascripts/notes/stores/mutations.js
+++ b/app/assets/javascripts/notes/stores/mutations.js
@@ -4,7 +4,8 @@ import * as constants from '../constants';
import { isInMRPage } from '../../lib/utils/common_utils';
export default {
- [types.ADD_NEW_NOTE](state, note) {
+ [types.ADD_NEW_NOTE](state, data) {
+ const note = data.discussion ? data.discussion.notes[0] : data;
const { discussion_id, type } = note;
const [exists] = state.discussions.filter(n => n.id === note.discussion_id);
const isDiscussion = type === constants.DISCUSSION_NOTE || type === constants.DIFF_NOTE;
@@ -100,7 +101,10 @@ export default {
discussionsData.forEach(discussion => {
if (discussion.diff_file) {
- Object.assign(discussion, { fileHash: discussion.diff_file.file_hash });
+ Object.assign(discussion, {
+ fileHash: discussion.diff_file.file_hash,
+ truncated_diff_lines: discussion.truncated_diff_lines || [],
+ });
}
// To support legacy notes, should be very rare case.
diff --git a/app/assets/javascripts/notes/stores/utils.js b/app/assets/javascripts/notes/stores/utils.js
index 8ccbdb4c130..0e41ff03d67 100644
--- a/app/assets/javascripts/notes/stores/utils.js
+++ b/app/assets/javascripts/notes/stores/utils.js
@@ -27,7 +27,7 @@ export const getQuickActionText = note => {
export const reduceDiscussionsToLineCodes = selectedDiscussions =>
selectedDiscussions.reduce((acc, note) => {
- if (note.diff_discussion && note.line_code && note.resolvable) {
+ if (note.diff_discussion && note.line_code) {
// For context about line notes: there might be multiple notes with the same line code
const items = acc[note.line_code] || [];
items.push(note);
diff --git a/app/assets/javascripts/pages/admin/application_settings/index.js b/app/assets/javascripts/pages/admin/application_settings/index.js
index 069f8ce55d0..47bd70537f1 100644
--- a/app/assets/javascripts/pages/admin/application_settings/index.js
+++ b/app/assets/javascripts/pages/admin/application_settings/index.js
@@ -1,13 +1,8 @@
import initSettingsPanels from '~/settings_panels';
import projectSelect from '~/project_select';
-import UsagePingPayload from './usage_ping_payload';
document.addEventListener('DOMContentLoaded', () => {
// Initialize expandable settings panels
initSettingsPanels();
projectSelect();
- new UsagePingPayload(
- document.querySelector('.js-usage-ping-payload-trigger'),
- document.querySelector('.js-usage-ping-payload'),
- ).init();
});
diff --git a/app/assets/javascripts/pages/admin/application_settings/metrics_and_profiling/index.js b/app/assets/javascripts/pages/admin/application_settings/metrics_and_profiling/index.js
new file mode 100644
index 00000000000..c40503603be
--- /dev/null
+++ b/app/assets/javascripts/pages/admin/application_settings/metrics_and_profiling/index.js
@@ -0,0 +1,8 @@
+import UsagePingPayload from './../usage_ping_payload';
+
+document.addEventListener('DOMContentLoaded', () => {
+ new UsagePingPayload(
+ document.querySelector('.js-usage-ping-payload-trigger'),
+ document.querySelector('.js-usage-ping-payload'),
+ ).init();
+});
diff --git a/app/assets/javascripts/pages/admin/users/components/delete_user_modal.vue b/app/assets/javascripts/pages/admin/users/components/delete_user_modal.vue
index d6aa4bb95d2..8d5efcdcd96 100644
--- a/app/assets/javascripts/pages/admin/users/components/delete_user_modal.vue
+++ b/app/assets/javascripts/pages/admin/users/components/delete_user_modal.vue
@@ -155,10 +155,7 @@
/>
</form>
</template>
- <template
- slot="secondary-button"
- slot-scope="props"
- >
+ <template slot="secondary-button">
<button
:disabled="!canSubmit"
type="button"
diff --git a/app/assets/javascripts/pages/groups/boards/index.js b/app/assets/javascripts/pages/groups/boards/index.js
index 5cfe8723204..79c3be771d0 100644
--- a/app/assets/javascripts/pages/groups/boards/index.js
+++ b/app/assets/javascripts/pages/groups/boards/index.js
@@ -1,5 +1,5 @@
import UsersSelect from '~/users_select';
-import ShortcutsNavigation from '~/shortcuts_navigation';
+import ShortcutsNavigation from '~/behaviors/shortcuts/shortcuts_navigation';
import initBoards from '~/boards';
document.addEventListener('DOMContentLoaded', () => {
diff --git a/app/assets/javascripts/pages/groups/show/index.js b/app/assets/javascripts/pages/groups/show/index.js
index 5b8c2ae7e81..3a45fd70d02 100644
--- a/app/assets/javascripts/pages/groups/show/index.js
+++ b/app/assets/javascripts/pages/groups/show/index.js
@@ -6,7 +6,7 @@ import NewGroupChild from '~/groups/new_group_child';
import notificationsDropdown from '~/notifications_dropdown';
import NotificationsForm from '~/notifications_form';
import ProjectsList from '~/projects_list';
-import ShortcutsNavigation from '~/shortcuts_navigation';
+import ShortcutsNavigation from '~/behaviors/shortcuts/shortcuts_navigation';
import GroupTabs from './group_tabs';
document.addEventListener('DOMContentLoaded', () => {
diff --git a/app/assets/javascripts/pages/projects/activity/index.js b/app/assets/javascripts/pages/projects/activity/index.js
index 5543ad82428..d39ea3d10bf 100644
--- a/app/assets/javascripts/pages/projects/activity/index.js
+++ b/app/assets/javascripts/pages/projects/activity/index.js
@@ -1,5 +1,5 @@
import Activities from '~/activities';
-import ShortcutsNavigation from '~/shortcuts_navigation';
+import ShortcutsNavigation from '~/behaviors/shortcuts/shortcuts_navigation';
document.addEventListener('DOMContentLoaded', () => {
new Activities(); // eslint-disable-line no-new
diff --git a/app/assets/javascripts/pages/projects/artifacts/browse/index.js b/app/assets/javascripts/pages/projects/artifacts/browse/index.js
index ea7458fe9b8..26dc90a56d7 100644
--- a/app/assets/javascripts/pages/projects/artifacts/browse/index.js
+++ b/app/assets/javascripts/pages/projects/artifacts/browse/index.js
@@ -1,5 +1,5 @@
import BuildArtifacts from '~/build_artifacts';
-import ShortcutsNavigation from '~/shortcuts_navigation';
+import ShortcutsNavigation from '~/behaviors/shortcuts/shortcuts_navigation';
document.addEventListener('DOMContentLoaded', () => {
new ShortcutsNavigation(); // eslint-disable-line no-new
diff --git a/app/assets/javascripts/pages/projects/artifacts/file/index.js b/app/assets/javascripts/pages/projects/artifacts/file/index.js
index 8484e5e9848..249900d6cb7 100644
--- a/app/assets/javascripts/pages/projects/artifacts/file/index.js
+++ b/app/assets/javascripts/pages/projects/artifacts/file/index.js
@@ -1,5 +1,5 @@
import BlobViewer from '~/blob/viewer/index';
-import ShortcutsNavigation from '~/shortcuts_navigation';
+import ShortcutsNavigation from '~/behaviors/shortcuts/shortcuts_navigation';
document.addEventListener('DOMContentLoaded', () => {
new ShortcutsNavigation(); // eslint-disable-line no-new
diff --git a/app/assets/javascripts/pages/projects/boards/index.js b/app/assets/javascripts/pages/projects/boards/index.js
index 5cfe8723204..79c3be771d0 100644
--- a/app/assets/javascripts/pages/projects/boards/index.js
+++ b/app/assets/javascripts/pages/projects/boards/index.js
@@ -1,5 +1,5 @@
import UsersSelect from '~/users_select';
-import ShortcutsNavigation from '~/shortcuts_navigation';
+import ShortcutsNavigation from '~/behaviors/shortcuts/shortcuts_navigation';
import initBoards from '~/boards';
document.addEventListener('DOMContentLoaded', () => {
diff --git a/app/assets/javascripts/pages/projects/commit/show/index.js b/app/assets/javascripts/pages/projects/commit/show/index.js
index 2e23cce11ce..f477424811d 100644
--- a/app/assets/javascripts/pages/projects/commit/show/index.js
+++ b/app/assets/javascripts/pages/projects/commit/show/index.js
@@ -3,7 +3,7 @@
import $ from 'jquery';
import Diff from '~/diff';
import ZenMode from '~/zen_mode';
-import ShortcutsNavigation from '~/shortcuts_navigation';
+import ShortcutsNavigation from '~/behaviors/shortcuts/shortcuts_navigation';
import MiniPipelineGraph from '~/mini_pipeline_graph_dropdown';
import initNotes from '~/init_notes';
import initChangesDropdown from '~/init_changes_dropdown';
diff --git a/app/assets/javascripts/pages/projects/commits/show/index.js b/app/assets/javascripts/pages/projects/commits/show/index.js
index 3682020579b..ad671ce9351 100644
--- a/app/assets/javascripts/pages/projects/commits/show/index.js
+++ b/app/assets/javascripts/pages/projects/commits/show/index.js
@@ -1,6 +1,6 @@
import CommitsList from '~/commits';
import GpgBadges from '~/gpg_badges';
-import ShortcutsNavigation from '~/shortcuts_navigation';
+import ShortcutsNavigation from '~/behaviors/shortcuts/shortcuts_navigation';
document.addEventListener('DOMContentLoaded', () => {
new CommitsList(document.querySelector('.js-project-commits-show').dataset.commitsLimit); // eslint-disable-line no-new
diff --git a/app/assets/javascripts/pages/projects/find_file/show/index.js b/app/assets/javascripts/pages/projects/find_file/show/index.js
index 24630c2aa05..388d7d7bdda 100644
--- a/app/assets/javascripts/pages/projects/find_file/show/index.js
+++ b/app/assets/javascripts/pages/projects/find_file/show/index.js
@@ -1,6 +1,6 @@
import $ from 'jquery';
import ProjectFindFile from '~/project_find_file';
-import ShortcutsFindFile from '~/shortcuts_find_file';
+import ShortcutsFindFile from '~/behaviors/shortcuts/shortcuts_find_file';
document.addEventListener('DOMContentLoaded', () => {
const findElement = document.querySelector('.js-file-finder');
diff --git a/app/assets/javascripts/pages/projects/index.js b/app/assets/javascripts/pages/projects/index.js
index 9c074b74c3b..5659e13981a 100644
--- a/app/assets/javascripts/pages/projects/index.js
+++ b/app/assets/javascripts/pages/projects/index.js
@@ -1,7 +1,7 @@
import initDismissableCallout from '~/dismissable_callout';
import initGkeDropdowns from '~/projects/gke_cluster_dropdowns';
import Project from './project';
-import ShortcutsNavigation from '../../shortcuts_navigation';
+import ShortcutsNavigation from '../../behaviors/shortcuts/shortcuts_navigation';
document.addEventListener('DOMContentLoaded', () => {
const { page } = document.body.dataset;
diff --git a/app/assets/javascripts/pages/projects/init_blob.js b/app/assets/javascripts/pages/projects/init_blob.js
index 56ab3fcdfcb..bc08ccf3584 100644
--- a/app/assets/javascripts/pages/projects/init_blob.js
+++ b/app/assets/javascripts/pages/projects/init_blob.js
@@ -1,7 +1,7 @@
import LineHighlighter from '~/line_highlighter';
import BlobLinePermalinkUpdater from '~/blob/blob_line_permalink_updater';
-import ShortcutsNavigation from '~/shortcuts_navigation';
-import ShortcutsBlob from '~/shortcuts_blob';
+import ShortcutsNavigation from '~/behaviors/shortcuts/shortcuts_navigation';
+import ShortcutsBlob from '~/behaviors/shortcuts/shortcuts_blob';
import BlobForkSuggestion from '~/blob/blob_fork_suggestion';
import initBlobBundle from '~/blob_edit/blob_bundle';
diff --git a/app/assets/javascripts/pages/projects/issues/form.js b/app/assets/javascripts/pages/projects/issues/form.js
index b2b8e5d2300..197bfa8a394 100644
--- a/app/assets/javascripts/pages/projects/issues/form.js
+++ b/app/assets/javascripts/pages/projects/issues/form.js
@@ -5,7 +5,7 @@ import GLForm from '~/gl_form';
import IssuableForm from '~/issuable_form';
import LabelsSelect from '~/labels_select';
import MilestoneSelect from '~/milestone_select';
-import ShortcutsNavigation from '~/shortcuts_navigation';
+import ShortcutsNavigation from '~/behaviors/shortcuts/shortcuts_navigation';
import IssuableTemplateSelectors from '~/templates/issuable_template_selectors';
export default () => {
diff --git a/app/assets/javascripts/pages/projects/issues/index/index.js b/app/assets/javascripts/pages/projects/issues/index/index.js
index 23edbdc5cad..a56c0bb6be8 100644
--- a/app/assets/javascripts/pages/projects/issues/index/index.js
+++ b/app/assets/javascripts/pages/projects/issues/index/index.js
@@ -1,7 +1,7 @@
/* eslint-disable no-new */
import IssuableIndex from '~/issuable_index';
-import ShortcutsNavigation from '~/shortcuts_navigation';
+import ShortcutsNavigation from '~/behaviors/shortcuts/shortcuts_navigation';
import UsersSelect from '~/users_select';
import initFilteredSearch from '~/pages/search/init_filtered_search';
import IssuableFilteredSearchTokenKeys from '~/filtered_search/issuable_filtered_search_token_keys';
diff --git a/app/assets/javascripts/pages/projects/issues/show.js b/app/assets/javascripts/pages/projects/issues/show.js
index 500fbd27340..74b3a515e84 100644
--- a/app/assets/javascripts/pages/projects/issues/show.js
+++ b/app/assets/javascripts/pages/projects/issues/show.js
@@ -1,6 +1,6 @@
import initIssuableSidebar from '~/init_issuable_sidebar';
import Issue from '~/issue';
-import ShortcutsIssuable from '~/shortcuts_issuable';
+import ShortcutsIssuable from '~/behaviors/shortcuts/shortcuts_issuable';
import ZenMode from '~/zen_mode';
import '~/notes/index';
import '~/issue_show/index';
diff --git a/app/assets/javascripts/pages/projects/merge_requests/index/index.js b/app/assets/javascripts/pages/projects/merge_requests/index/index.js
index 1fad0fb7297..3647048a872 100644
--- a/app/assets/javascripts/pages/projects/merge_requests/index/index.js
+++ b/app/assets/javascripts/pages/projects/merge_requests/index/index.js
@@ -1,5 +1,5 @@
import IssuableIndex from '~/issuable_index';
-import ShortcutsNavigation from '~/shortcuts_navigation';
+import ShortcutsNavigation from '~/behaviors/shortcuts/shortcuts_navigation';
import UsersSelect from '~/users_select';
import initFilteredSearch from '~/pages/search/init_filtered_search';
import IssuableFilteredSearchTokenKeys from '~/filtered_search/issuable_filtered_search_token_keys';
diff --git a/app/assets/javascripts/pages/projects/merge_requests/init_merge_request.js b/app/assets/javascripts/pages/projects/merge_requests/init_merge_request.js
index 3a3c21f2202..e3971618da5 100644
--- a/app/assets/javascripts/pages/projects/merge_requests/init_merge_request.js
+++ b/app/assets/javascripts/pages/projects/merge_requests/init_merge_request.js
@@ -2,7 +2,7 @@
import $ from 'jquery';
import Diff from '~/diff';
-import ShortcutsNavigation from '~/shortcuts_navigation';
+import ShortcutsNavigation from '~/behaviors/shortcuts/shortcuts_navigation';
import GLForm from '~/gl_form';
import IssuableForm from '~/issuable_form';
import LabelsSelect from '~/labels_select';
diff --git a/app/assets/javascripts/pages/projects/merge_requests/init_merge_request_show.js b/app/assets/javascripts/pages/projects/merge_requests/init_merge_request_show.js
index 26ead75cec4..7bfb83a2204 100644
--- a/app/assets/javascripts/pages/projects/merge_requests/init_merge_request_show.js
+++ b/app/assets/javascripts/pages/projects/merge_requests/init_merge_request_show.js
@@ -1,6 +1,6 @@
import ZenMode from '~/zen_mode';
import initIssuableSidebar from '~/init_issuable_sidebar';
-import ShortcutsIssuable from '~/shortcuts_issuable';
+import ShortcutsIssuable from '~/behaviors/shortcuts/shortcuts_issuable';
import { handleLocationHash } from '~/lib/utils/common_utils';
import howToMerge from '~/how_to_merge';
import initPipelines from '~/commit/pipelines/pipelines_bundle';
diff --git a/app/assets/javascripts/pages/projects/network/show/index.js b/app/assets/javascripts/pages/projects/network/show/index.js
index a0b14fed10f..9f05f63b742 100644
--- a/app/assets/javascripts/pages/projects/network/show/index.js
+++ b/app/assets/javascripts/pages/projects/network/show/index.js
@@ -1,5 +1,5 @@
import $ from 'jquery';
-import ShortcutsNetwork from '../../../../shortcuts_network';
+import ShortcutsNetwork from '~/behaviors/shortcuts/shortcuts_network';
import Network from '../network';
document.addEventListener('DOMContentLoaded', () => {
diff --git a/app/assets/javascripts/pages/projects/pipeline_schedules/shared/components/interval_pattern_input.vue b/app/assets/javascripts/pages/projects/pipeline_schedules/shared/components/interval_pattern_input.vue
index 0d05668b285..ef53d67e7cb 100644
--- a/app/assets/javascripts/pages/projects/pipeline_schedules/shared/components/interval_pattern_input.vue
+++ b/app/assets/javascripts/pages/projects/pipeline_schedules/shared/components/interval_pattern_input.vue
@@ -147,8 +147,8 @@
<div class="cron-interval-input-wrapper">
<input
id="schedule_cron"
- :placeholder="__('Define a custom pattern with cron syntax')"
v-model="cronInterval"
+ :placeholder="__('Define a custom pattern with cron syntax')"
:name="inputNameAttribute"
:disabled="!isEditable"
class="form-control inline cron-interval-input"
diff --git a/app/assets/javascripts/pages/projects/shared/permissions/components/settings_panel.vue b/app/assets/javascripts/pages/projects/shared/permissions/components/settings_panel.vue
index ae88b765abf..875f6928bed 100644
--- a/app/assets/javascripts/pages/projects/shared/permissions/components/settings_panel.vue
+++ b/app/assets/javascripts/pages/projects/shared/permissions/components/settings_panel.vue
@@ -240,8 +240,8 @@
help-text="Lightweight issue tracking system for this project"
>
<project-feature-setting
- :options="featureAccessLevelOptions"
v-model="issuesAccessLevel"
+ :options="featureAccessLevelOptions"
name="project[project_feature_attributes][issues_access_level]"
/>
</project-setting-row>
@@ -250,8 +250,8 @@
help-text="View and edit files in this project"
>
<project-feature-setting
- :options="featureAccessLevelOptions"
v-model="repositoryAccessLevel"
+ :options="featureAccessLevelOptions"
name="project[project_feature_attributes][repository_access_level]"
/>
</project-setting-row>
@@ -261,8 +261,8 @@
help-text="Submit changes to be merged upstream"
>
<project-feature-setting
- :options="repoFeatureAccessLevelOptions"
v-model="mergeRequestsAccessLevel"
+ :options="repoFeatureAccessLevelOptions"
:disabled-input="!repositoryEnabled"
name="project[project_feature_attributes][merge_requests_access_level]"
/>
@@ -272,8 +272,8 @@
help-text="Build, test, and deploy your changes"
>
<project-feature-setting
- :options="repoFeatureAccessLevelOptions"
v-model="buildsAccessLevel"
+ :options="repoFeatureAccessLevelOptions"
:disabled-input="!repositoryEnabled"
name="project[project_feature_attributes][builds_access_level]"
/>
@@ -308,8 +308,8 @@
help-text="Pages for project documentation"
>
<project-feature-setting
- :options="featureAccessLevelOptions"
v-model="wikiAccessLevel"
+ :options="featureAccessLevelOptions"
name="project[project_feature_attributes][wiki_access_level]"
/>
</project-setting-row>
@@ -318,8 +318,8 @@
help-text="Share code pastes with others out of Git repository"
>
<project-feature-setting
- :options="featureAccessLevelOptions"
v-model="snippetsAccessLevel"
+ :options="featureAccessLevelOptions"
name="project[project_feature_attributes][snippets_access_level]"
/>
</project-setting-row>
diff --git a/app/assets/javascripts/pages/projects/show/index.js b/app/assets/javascripts/pages/projects/show/index.js
index 0507f67843f..7302c1ab202 100644
--- a/app/assets/javascripts/pages/projects/show/index.js
+++ b/app/assets/javascripts/pages/projects/show/index.js
@@ -1,6 +1,6 @@
import $ from 'jquery';
import initBlob from '~/blob_edit/blob_bundle';
-import ShortcutsNavigation from '~/shortcuts_navigation';
+import ShortcutsNavigation from '~/behaviors/shortcuts/shortcuts_navigation';
import NotificationsForm from '~/notifications_form';
import UserCallout from '~/user_callout';
import TreeView from '~/tree';
diff --git a/app/assets/javascripts/pages/projects/tree/show/index.js b/app/assets/javascripts/pages/projects/tree/show/index.js
index 33d69d891d8..400aed35e32 100644
--- a/app/assets/javascripts/pages/projects/tree/show/index.js
+++ b/app/assets/javascripts/pages/projects/tree/show/index.js
@@ -4,7 +4,7 @@ import initBlob from '~/blob_edit/blob_bundle';
import commitPipelineStatus from '~/projects/tree/components/commit_pipeline_status_component.vue';
import GpgBadges from '~/gpg_badges';
import TreeView from '../../../../tree';
-import ShortcutsNavigation from '../../../../shortcuts_navigation';
+import ShortcutsNavigation from '../../../../behaviors/shortcuts/shortcuts_navigation';
import BlobViewer from '../../../../blob/viewer';
import NewCommitForm from '../../../../new_commit_form';
import { ajaxGet } from '../../../../lib/utils/common_utils';
diff --git a/app/assets/javascripts/pages/projects/wikis/index.js b/app/assets/javascripts/pages/projects/wikis/index.js
index b0a323a71cd..c2629090f01 100644
--- a/app/assets/javascripts/pages/projects/wikis/index.js
+++ b/app/assets/javascripts/pages/projects/wikis/index.js
@@ -2,8 +2,8 @@ import $ from 'jquery';
import Vue from 'vue';
import Translate from '~/vue_shared/translate';
import csrf from '~/lib/utils/csrf';
+import ShortcutsWiki from '~/behaviors/shortcuts/shortcuts_wiki';
import Wikis from './wikis';
-import ShortcutsWiki from '../../../shortcuts_wiki';
import ZenMode from '../../../zen_mode';
import GLForm from '../../../gl_form';
import deleteWikiModal from './components/delete_wiki_modal.vue';
diff --git a/app/assets/javascripts/performance_bar/components/performance_bar_app.vue b/app/assets/javascripts/performance_bar/components/performance_bar_app.vue
index 0fdb0a080cf..7836d4f3b09 100644
--- a/app/assets/javascripts/performance_bar/components/performance_bar_app.vue
+++ b/app/assets/javascripts/performance_bar/components/performance_bar_app.vue
@@ -130,8 +130,8 @@ export default {
</div>
<simple-metric
v-for="metric in $options.simpleMetrics"
- :current-request="currentRequest"
:key="metric"
+ :current-request="currentRequest"
:metric="metric"
/>
<div
diff --git a/app/assets/javascripts/pipelines/components/graph/graph_component.vue b/app/assets/javascripts/pipelines/components/graph/graph_component.vue
index e27f195c9b0..9b4ba0c1a9a 100644
--- a/app/assets/javascripts/pipelines/components/graph/graph_component.vue
+++ b/app/assets/javascripts/pipelines/components/graph/graph_component.vue
@@ -68,9 +68,9 @@ export default {
class="stage-column-list">
<stage-column-component
v-for="(stage, index) in graph"
+ :key="stage.name"
:title="capitalizeStageName(stage.name)"
:jobs="stage.groups"
- :key="stage.name"
:stage-connector-class="stageConnectorClass(index, stage)"
:is-first-column="isFirstColumn(index)"
@refreshPipelineGraph="refreshPipelineGraph"
diff --git a/app/assets/javascripts/pipelines/components/graph/job_component.vue b/app/assets/javascripts/pipelines/components/graph/job_component.vue
index 9ac16b7e541..a1504592bbc 100644
--- a/app/assets/javascripts/pipelines/components/graph/job_component.vue
+++ b/app/assets/javascripts/pipelines/components/graph/job_component.vue
@@ -98,8 +98,8 @@ export default {
<template>
<div class="ci-job-component">
<a
- v-tooltip
v-if="status.has_details"
+ v-tooltip
:href="status.details_path"
:title="tooltipText"
:class="cssClassJobName"
@@ -115,8 +115,8 @@ export default {
</a>
<div
- v-tooltip
v-else
+ v-tooltip
:title="tooltipText"
:class="cssClassJobName"
class="js-job-component-tooltip non-details-job-component"
diff --git a/app/assets/javascripts/pipelines/components/graph/stage_column_component.vue b/app/assets/javascripts/pipelines/components/graph/stage_column_component.vue
index e7b2de52f76..567ea119343 100644
--- a/app/assets/javascripts/pipelines/components/graph/stage_column_component.vue
+++ b/app/assets/javascripts/pipelines/components/graph/stage_column_component.vue
@@ -62,9 +62,9 @@ export default {
<ul>
<li
v-for="(job, index) in jobs"
+ :id="jobId(job)"
:key="job.id"
:class="buildConnnectorClass(index)"
- :id="jobId(job)"
class="build"
>
diff --git a/app/assets/javascripts/pipelines/components/nav_controls.vue b/app/assets/javascripts/pipelines/components/nav_controls.vue
index 9501afb7493..efb80d3a3c0 100644
--- a/app/assets/javascripts/pipelines/components/nav_controls.vue
+++ b/app/assets/javascripts/pipelines/components/nav_controls.vue
@@ -43,7 +43,7 @@ export default {
<a
v-if="newPipelinePath"
:href="newPipelinePath"
- class="btn btn-create js-run-pipeline"
+ class="btn btn-success js-run-pipeline"
>
{{ s__('Pipelines|Run Pipeline') }}
</a>
diff --git a/app/assets/javascripts/pipelines/components/pipeline_url.vue b/app/assets/javascripts/pipelines/components/pipeline_url.vue
index 75db1e9ae7c..40df07650c9 100644
--- a/app/assets/javascripts/pipelines/components/pipeline_url.vue
+++ b/app/assets/javascripts/pipelines/components/pipeline_url.vue
@@ -67,29 +67,29 @@ export default {
</span>
<div class="label-container">
<span
- v-tooltip
v-if="pipeline.flags.latest"
+ v-tooltip
class="js-pipeline-url-latest badge badge-success"
title="Latest pipeline for this branch">
latest
</span>
<span
- v-tooltip
v-if="pipeline.flags.yaml_errors"
+ v-tooltip
:title="pipeline.yaml_errors"
class="js-pipeline-url-yaml badge badge-danger">
yaml invalid
</span>
<span
- v-tooltip
v-if="pipeline.flags.failure_reason"
+ v-tooltip
:title="pipeline.failure_reason"
class="js-pipeline-url-failure badge badge-danger">
error
</span>
<a
- v-popover="popoverOptions"
v-if="pipeline.flags.auto_devops"
+ v-popover="popoverOptions"
tabindex="0"
class="js-pipeline-url-autodevops badge badge-info autodevops-badge"
role="button">
diff --git a/app/assets/javascripts/pipelines/components/stage.vue b/app/assets/javascripts/pipelines/components/stage.vue
index 3e13bad9a0b..47c15b1a9c4 100644
--- a/app/assets/javascripts/pipelines/components/stage.vue
+++ b/app/assets/javascripts/pipelines/components/stage.vue
@@ -155,9 +155,9 @@ export default {
<template>
<div class="dropdown">
<button
- v-tooltip
id="stageDropdown"
ref="dropdown"
+ v-tooltip
:class="triggerButtonClass"
:title="stage.title"
class="mini-pipeline-graph-dropdown-toggle js-builds-dropdown-button"
diff --git a/app/assets/javascripts/registry/components/collapsible_container.vue b/app/assets/javascripts/registry/components/collapsible_container.vue
index d4c4d779d44..d9bf41924d1 100644
--- a/app/assets/javascripts/registry/components/collapsible_container.vue
+++ b/app/assets/javascripts/registry/components/collapsible_container.vue
@@ -88,8 +88,8 @@
<div class="controls d-none d-sm-block float-right">
<button
- v-tooltip
v-if="repo.canDelete"
+ v-tooltip
:title="s__('ContainerRegistry|Remove repository')"
:aria-label="s__('ContainerRegistry|Remove repository')"
type="button"
diff --git a/app/assets/javascripts/registry/components/table_registry.vue b/app/assets/javascripts/registry/components/table_registry.vue
index 9f4973c3490..fafb35bd69a 100644
--- a/app/assets/javascripts/registry/components/table_registry.vue
+++ b/app/assets/javascripts/registry/components/table_registry.vue
@@ -118,8 +118,8 @@
<td class="content">
<button
- v-tooltip
v-if="item.canDelete"
+ v-tooltip
:title="s__('ContainerRegistry|Remove tag')"
:aria-label="s__('ContainerRegistry|Remove tag')"
type="button"
diff --git a/app/assets/javascripts/reports/components/grouped_test_reports_app.vue b/app/assets/javascripts/reports/components/grouped_test_reports_app.vue
index 7b37f4e9a97..fb8c6402d02 100644
--- a/app/assets/javascripts/reports/components/grouped_test_reports_app.vue
+++ b/app/assets/javascripts/reports/components/grouped_test_reports_app.vue
@@ -92,16 +92,16 @@
v-for="(report, i) in reports"
>
<summary-row
+ :key="`summary-row-${i}`"
:summary="reportText(report)"
:status-icon="getReportIcon(report)"
- :key="`summary-row-${i}`"
/>
<issues-list
v-if="shouldRenderIssuesList(report)"
+ :key="`issues-list-${i}`"
:unresolved-issues="report.existing_failures"
:new-issues="report.new_failures"
:resolved-issues="report.resolved_failures"
- :key="`issues-list-${i}`"
:component="$options.componentNames.TestIssueBody"
class="report-block-group-list"
/>
diff --git a/app/assets/javascripts/reports/components/report_issues.vue b/app/assets/javascripts/reports/components/report_issues.vue
index c553a374f66..a2a03945ae3 100644
--- a/app/assets/javascripts/reports/components/report_issues.vue
+++ b/app/assets/javascripts/reports/components/report_issues.vue
@@ -37,8 +37,8 @@ export default {
<ul class="report-block-list">
<li
v-for="(issue, index) in issues"
- :class="{ 'is-dismissed': issue.isDismissed }"
:key="index"
+ :class="{ 'is-dismissed': issue.isDismissed }"
class="report-block-list-issue"
>
<issue-status-icon
@@ -47,8 +47,8 @@ export default {
/>
<component
- v-if="component"
:is="component"
+ v-if="component"
:issue="issue"
:status="issue.status || status"
:is-new="isNew"
diff --git a/app/assets/javascripts/search_autocomplete.js b/app/assets/javascripts/search_autocomplete.js
index aec09b8bc0a..50dd3c12382 100644
--- a/app/assets/javascripts/search_autocomplete.js
+++ b/app/assets/javascripts/search_autocomplete.js
@@ -68,7 +68,7 @@ function setSearchOptions() {
}
}
-export default class SearchAutocomplete {
+export class SearchAutocomplete {
constructor({ wrap, optsEl, autocompletePath, projectId, projectRef } = {}) {
setSearchOptions();
this.bindEventContext();
@@ -499,3 +499,7 @@ export default class SearchAutocomplete {
this.dropdownMenu.toggleClass('fade-out', !this.isScrolledUp());
}
}
+
+export default function initSearchAutocomplete(opts) {
+ return new SearchAutocomplete(opts);
+}
diff --git a/app/assets/javascripts/sidebar/components/time_tracking/time_tracker.vue b/app/assets/javascripts/sidebar/components/time_tracking/time_tracker.vue
index ca3b9338c29..2ee3e1f322e 100644
--- a/app/assets/javascripts/sidebar/components/time_tracking/time_tracker.vue
+++ b/app/assets/javascripts/sidebar/components/time_tracking/time_tracker.vue
@@ -19,19 +19,23 @@ export default {
TimeTrackingHelpState,
},
props: {
+ // eslint-disable-next-line vue/prop-name-casing
time_estimate: {
type: Number,
required: true,
},
+ // eslint-disable-next-line vue/prop-name-casing
time_spent: {
type: Number,
required: true,
},
+ // eslint-disable-next-line vue/prop-name-casing
human_time_estimate: {
type: String,
required: false,
default: '',
},
+ // eslint-disable-next-line vue/prop-name-casing
human_time_spent: {
type: String,
required: false,
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/deployment.vue b/app/assets/javascripts/vue_merge_request_widget/components/deployment.vue
index d530ab2767b..70518ad73e8 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/deployment.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/deployment.vue
@@ -106,8 +106,8 @@ export default {
</tooltip-on-truncate>
</template>
<span
- v-tooltip
v-if="hasDeploymentTime"
+ v-tooltip
:title="deployment.deployed_at_formatted"
class="js-deploy-time"
>
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_merged.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_merged.vue
index 2f2394371ef..8184ef33022 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_merged.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_merged.vue
@@ -114,8 +114,8 @@
:date-readable="mr.metrics.readableMergedAt"
/>
<a
- v-tooltip
v-if="mr.canRevertInCurrentMR"
+ v-tooltip
:title="revertTitle"
class="btn btn-close btn-sm"
href="#modal-revert-commit"
@@ -125,8 +125,8 @@
{{ revertLabel }}
</a>
<a
- v-tooltip
v-else-if="mr.revertInForkPath"
+ v-tooltip
:href="mr.revertInForkPath"
:title="revertTitle"
class="btn btn-close btn-sm"
@@ -135,8 +135,8 @@
{{ revertLabel }}
</a>
<a
- v-tooltip
v-if="mr.canCherryPickInCurrentMR"
+ v-tooltip
:title="cherryPickTitle"
class="btn btn-default btn-sm"
href="#modal-cherry-pick-commit"
@@ -146,8 +146,8 @@
{{ cherryPickLabel }}
</a>
<a
- v-tooltip
v-else-if="mr.cherryPickInForkPath"
+ v-tooltip
:href="mr.cherryPickInForkPath"
:title="cherryPickTitle"
class="btn btn-default btn-sm"
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_squash_before_merge.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_squash_before_merge.vue
index 25c1044fe2b..25ad329e196 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_squash_before_merge.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_squash_before_merge.vue
@@ -37,8 +37,8 @@ export default {
<div class="accept-control inline">
<label class="merge-param-checkbox">
<input
- :disabled="isMergeButtonDisabled"
v-model="squashBeforeMerge"
+ :disabled="isMergeButtonDisabled"
type="checkbox"
name="squash"
class="qa-squash-checkbox"
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/nothing_to_merge.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/nothing_to_merge.vue
index 086dbabe77e..e73b7e410d5 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/states/nothing_to_merge.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/states/nothing_to_merge.vue
@@ -37,7 +37,7 @@ export default {
<a
v-if="mr.newBlobPath"
:href="mr.newBlobPath"
- class="btn btn-inverted btn-save">
+ class="btn btn-inverted btn-success">
Create file
</a>
</div>
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 a5ca7b719a1..23c3284cd21 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
@@ -255,7 +255,7 @@ export default {
data-toggle="dropdown"
aria-label="Select merge moment">
<i
- class="fa fa-chevron-down"
+ class="fa fa-chevron-down qa-merge-moment-dropdown"
aria-hidden="true"
></i>
</button>
@@ -265,7 +265,7 @@ export default {
role="menu">
<li>
<a
- class="merge_when_pipeline_succeeds"
+ class="merge_when_pipeline_succeeds qa-merge-when-pipeline-succeeds-option"
href="#"
@click.prevent="handleMergeButtonClick(true)">
<span class="media">
@@ -279,7 +279,7 @@ export default {
</li>
<li>
<a
- class="accept-merge-request"
+ class="accept-merge-request qa-merge-immediately-option"
href="#"
@click.prevent="handleMergeButtonClick(false, true)">
<span class="media">
diff --git a/app/assets/javascripts/vue_shared/components/bar_chart.vue b/app/assets/javascripts/vue_shared/components/bar_chart.vue
index 3ced4eb691a..33af7a7f1df 100644
--- a/app/assets/javascripts/vue_shared/components/bar_chart.vue
+++ b/app/assets/javascripts/vue_shared/components/bar_chart.vue
@@ -291,8 +291,8 @@ export default {
<template
v-for="(data, index) in graphData">
<rect
- v-tooltip
:key="index"
+ v-tooltip
:width="xScale.bandwidth()"
:x="xScale(data.name)"
:y="yScale(data.value)"
diff --git a/app/assets/javascripts/vue_shared/components/file_row.vue b/app/assets/javascripts/vue_shared/components/file_row.vue
new file mode 100644
index 00000000000..c797ad62a5d
--- /dev/null
+++ b/app/assets/javascripts/vue_shared/components/file_row.vue
@@ -0,0 +1,210 @@
+<script>
+import Icon from '~/vue_shared/components/icon.vue';
+import FileIcon from '~/vue_shared/components/file_icon.vue';
+
+export default {
+ name: 'FileRow',
+ components: {
+ FileIcon,
+ Icon,
+ },
+ props: {
+ file: {
+ type: Object,
+ required: true,
+ },
+ level: {
+ type: Number,
+ required: true,
+ },
+ extraComponent: {
+ type: Object,
+ required: false,
+ default: null,
+ },
+ },
+ data() {
+ return {
+ mouseOver: false,
+ };
+ },
+ computed: {
+ isTree() {
+ return this.file.type === 'tree';
+ },
+ isBlob() {
+ return this.file.type === 'blob';
+ },
+ levelIndentation() {
+ return {
+ marginLeft: `${this.level * 16}px`,
+ };
+ },
+ fileClass() {
+ return {
+ 'file-open': this.isBlob && this.file.opened,
+ 'is-active': this.isBlob && this.file.active,
+ folder: this.isTree,
+ 'is-open': this.file.opened,
+ };
+ },
+ },
+ watch: {
+ 'file.active': function fileActiveWatch(active) {
+ if (this.file.type === 'blob' && active) {
+ this.scrollIntoView();
+ }
+ },
+ },
+ mounted() {
+ if (this.hasPathAtCurrentRoute()) {
+ this.scrollIntoView(true);
+ }
+ },
+ methods: {
+ toggleTreeOpen(path) {
+ this.$emit('toggleTreeOpen', path);
+ },
+ clickFile() {
+ // Manual Action if a tree is selected/opened
+ if (this.isTree && this.hasUrlAtCurrentRoute()) {
+ this.toggleTreeOpen(this.file.path);
+ }
+
+ if (this.$router) this.$router.push(`/project${this.file.url}`);
+ },
+ scrollIntoView(isInit = false) {
+ const block = isInit && this.isTree ? 'center' : 'nearest';
+
+ this.$el.scrollIntoView({
+ behavior: 'smooth',
+ block,
+ });
+ },
+ hasPathAtCurrentRoute() {
+ if (!this.$router || !this.$router.currentRoute) {
+ return false;
+ }
+
+ // - strip route up to "/-/" and ending "/"
+ const routePath = this.$router.currentRoute.path
+ .replace(/^.*?[/]-[/]/g, '')
+ .replace(/[/]$/g, '');
+
+ // - strip ending "/"
+ const filePath = this.file.path.replace(/[/]$/g, '');
+
+ return filePath === routePath;
+ },
+ hasUrlAtCurrentRoute() {
+ if (!this.$router || !this.$router.currentRoute) return true;
+
+ return this.$router.currentRoute.path === `/project${this.file.url}`;
+ },
+ toggleHover(over) {
+ this.mouseOver = over;
+ },
+ },
+};
+</script>
+
+<template>
+ <div>
+ <div
+ :class="fileClass"
+ class="file-row"
+ role="button"
+ @click="clickFile"
+ @mouseover="toggleHover(true)"
+ @mouseout="toggleHover(false)"
+ >
+ <div
+ class="file-row-name-container"
+ >
+ <span
+ :style="levelIndentation"
+ class="file-row-name str-truncated"
+ >
+ <file-icon
+ :file-name="file.name"
+ :loading="file.loading"
+ :folder="isTree"
+ :opened="file.opened"
+ :size="16"
+ />
+ {{ file.name }}
+ </span>
+ <component
+ :is="extraComponent"
+ v-if="extraComponent"
+ :file="file"
+ :mouse-over="mouseOver"
+ />
+ </div>
+ </div>
+ <template v-if="file.opened">
+ <file-row
+ v-for="childFile in file.tree"
+ :key="childFile.key"
+ :file="childFile"
+ :level="level + 1"
+ :extra-component="extraComponent"
+ @toggleTreeOpen="toggleTreeOpen"
+ />
+ </template>
+ </div>
+</template>
+
+<style>
+.file-row {
+ display: flex;
+ align-items: center;
+ height: 32px;
+ padding: 4px 8px;
+ margin-left: -8px;
+ margin-right: -8px;
+ border-radius: 3px;
+ text-align: left;
+ cursor: pointer;
+}
+
+.file-row:hover,
+.file-row:focus {
+ background: #f2f2f2;
+}
+
+.file-row:active {
+ background: #dfdfdf;
+}
+
+.file-row.is-active {
+ background: #f2f2f2;
+}
+
+.file-row-name-container {
+ display: flex;
+ width: 100%;
+ align-items: center;
+ overflow: visible;
+}
+
+.file-row-name {
+ display: inline-block;
+ flex: 1;
+ max-width: inherit;
+ height: 18px;
+ line-height: 16px;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
+.file-row-name svg {
+ margin-right: 2px;
+ vertical-align: middle;
+}
+
+.file-row-name .loading-container {
+ display: inline-block;
+ margin-right: 4px;
+}
+</style>
diff --git a/app/assets/javascripts/vue_shared/components/header_ci_component.vue b/app/assets/javascripts/vue_shared/components/header_ci_component.vue
index 18f5ce53bb1..b371b6adf7e 100644
--- a/app/assets/javascripts/vue_shared/components/header_ci_component.vue
+++ b/app/assets/javascripts/vue_shared/components/header_ci_component.vue
@@ -126,18 +126,18 @@ export default {
>
<a
v-if="action.type === 'link'"
+ :key="i"
:href="action.path"
:class="action.cssClass"
- :key="i"
>
{{ action.label }}
</a>
<a
v-else-if="action.type === 'ujs-link'"
+ :key="i"
:href="action.path"
:class="action.cssClass"
- :key="i"
data-method="post"
rel="nofollow"
>
@@ -146,9 +146,9 @@ export default {
<button
v-else-if="action.type === 'button'"
+ :key="i"
:disabled="action.isLoading"
:class="action.cssClass"
- :key="i"
type="button"
@click="onClickAction(action)"
>
diff --git a/app/assets/javascripts/vue_shared/components/stacked_progress_bar.vue b/app/assets/javascripts/vue_shared/components/stacked_progress_bar.vue
index 78fde463507..cd3ee544344 100644
--- a/app/assets/javascripts/vue_shared/components/stacked_progress_bar.vue
+++ b/app/assets/javascripts/vue_shared/components/stacked_progress_bar.vue
@@ -99,8 +99,8 @@ export default {
{{ __("Not available") }}
</span>
<span
- v-tooltip
v-if="successPercent"
+ v-tooltip
:title="successTooltip"
:style="successBarStyle"
class="status-green"
@@ -109,8 +109,8 @@ export default {
{{ successPercent }}%
</span>
<span
- v-tooltip
v-if="neutralPercent"
+ v-tooltip
:title="neutralTooltip"
:style="neutralBarStyle"
class="status-neutral"
@@ -119,8 +119,8 @@ export default {
{{ neutralPercent }}%
</span>
<span
- v-tooltip
v-if="failurePercent"
+ v-tooltip
:title="failureTooltip"
:style="failureBarStyle"
class="status-red"
diff --git a/app/assets/javascripts/vue_shared/components/tooltip_on_truncate.vue b/app/assets/javascripts/vue_shared/components/tooltip_on_truncate.vue
index 125826da6c3..d5b58574123 100644
--- a/app/assets/javascripts/vue_shared/components/tooltip_on_truncate.vue
+++ b/app/assets/javascripts/vue_shared/components/tooltip_on_truncate.vue
@@ -51,8 +51,8 @@ export default {
<template>
<span
- v-tooltip
v-if="showTooltip"
+ v-tooltip
:title="title"
:data-placement="placement"
class="js-show-tooltip"
diff --git a/app/assets/javascripts/vue_shared/components/user_avatar/user_avatar_link.vue b/app/assets/javascripts/vue_shared/components/user_avatar/user_avatar_link.vue
index 01c36fec41a..08e102e57c3 100644
--- a/app/assets/javascripts/vue_shared/components/user_avatar/user_avatar_link.vue
+++ b/app/assets/javascripts/vue_shared/components/user_avatar/user_avatar_link.vue
@@ -94,8 +94,8 @@ export default {
:tooltip-text="avatarTooltipText"
:tooltip-placement="tooltipPlacement"
/><span
- v-tooltip
v-if="shouldShowUsername"
+ v-tooltip
:title="tooltipText"
:tooltip-placement="tooltipPlacement"
>{{ username }}</span>
diff --git a/app/assets/stylesheets/bootstrap_migration.scss b/app/assets/stylesheets/bootstrap_migration.scss
index c91f5e279ea..af73954bd2e 100644
--- a/app/assets/stylesheets/bootstrap_migration.scss
+++ b/app/assets/stylesheets/bootstrap_migration.scss
@@ -93,7 +93,6 @@ hr {
}
.form-group.row .col-form-label {
- padding-top: 0;
// Bootstrap 4 aligns labels to the left
// for horizontal forms
@include media-breakpoint-up(md) {
diff --git a/app/assets/stylesheets/framework/buttons.scss b/app/assets/stylesheets/framework/buttons.scss
index ab62ca07573..686ce0c63a4 100644
--- a/app/assets/stylesheets/framework/buttons.scss
+++ b/app/assets/stylesheets/framework/buttons.scss
@@ -147,18 +147,12 @@
}
&.btn-success,
- &.btn-new,
- &.btn-create,
- &.btn-save,
&.btn-register {
@include btn-green;
}
&.btn-inverted {
- &.btn-success,
- &.btn-new,
- &.btn-create,
- &.btn-save {
+ &.btn-success {
@include btn-outline($white-light, $green-600, $green-500, $green-500, $white-light, $green-600, $green-600, $green-700);
}
diff --git a/app/assets/stylesheets/framework/filters.scss b/app/assets/stylesheets/framework/filters.scss
index e9b074236cc..d5693a5d1a1 100644
--- a/app/assets/stylesheets/framework/filters.scss
+++ b/app/assets/stylesheets/framework/filters.scss
@@ -389,9 +389,8 @@
.btn {
text-overflow: ellipsis;
- .fa {
- width: 15px;
- line-height: $line-height-base;
+ svg {
+ margin-right: $gl-padding-8;
}
.dropdown-label-box {
diff --git a/app/assets/stylesheets/framework/lists.scss b/app/assets/stylesheets/framework/lists.scss
index fdc0454d837..d9d4a210f5f 100644
--- a/app/assets/stylesheets/framework/lists.scss
+++ b/app/assets/stylesheets/framework/lists.scss
@@ -111,6 +111,7 @@ ul.content-list {
border-color: $white-normal;
font-size: $gl-font-size;
color: $gl-text-color;
+ word-break: break-word;
&.no-description {
.title {
diff --git a/app/assets/stylesheets/framework/responsive_tables.scss b/app/assets/stylesheets/framework/responsive_tables.scss
index 764bebd82c6..fc185ccfaad 100644
--- a/app/assets/stylesheets/framework/responsive_tables.scss
+++ b/app/assets/stylesheets/framework/responsive_tables.scss
@@ -39,7 +39,7 @@
.table-section {
white-space: nowrap;
- $section-widths: 10 15 20 25 30 40 50 100;
+ $section-widths: 5 10 15 20 25 30 40 50 100;
@each $width in $section-widths {
&.section-#{$width} {
flex: 0 0 #{$width + '%'};
diff --git a/app/assets/stylesheets/framework/snippets.scss b/app/assets/stylesheets/framework/snippets.scss
index 7152ef9bcfd..36ab38f1c9d 100644
--- a/app/assets/stylesheets/framework/snippets.scss
+++ b/app/assets/stylesheets/framework/snippets.scss
@@ -45,7 +45,7 @@
}
}
-.snippet-scope-menu .btn-new {
+.snippet-scope-menu .btn-success {
margin-top: 15px;
}
diff --git a/app/assets/stylesheets/page_bundles/ide.scss b/app/assets/stylesheets/page_bundles/ide.scss
index 45df8391f9a..65f0a0d18e2 100644
--- a/app/assets/stylesheets/page_bundles/ide.scss
+++ b/app/assets/stylesheets/page_bundles/ide.scss
@@ -53,83 +53,9 @@ $ide-commit-header-height: 48px;
flex: 1;
min-height: 0; // firefox fix
- .file {
- height: 32px;
- cursor: pointer;
-
- &.file-active {
- background: $theme-gray-100;
- }
-
- .ide-file-name {
- flex: 1;
- white-space: nowrap;
- text-overflow: ellipsis;
- max-width: inherit;
- line-height: 16px;
- display: inline-block;
- height: 18px;
-
- svg {
- vertical-align: middle;
- margin-right: 2px;
- }
-
- .loading-container {
- margin-right: 4px;
- display: inline-block;
- }
- }
-
- .ide-file-icon-holder {
- display: flex;
- align-items: center;
- color: $theme-gray-700;
- }
-
- .ide-file-changed-icon {
- margin-left: auto;
-
- > svg {
- display: block;
- }
- }
-
- .ide-new-btn {
- display: none;
-
- .btn {
- padding: 2px 5px;
- }
- }
-
- &:hover,
- &:focus {
- .ide-new-btn {
- display: block;
- }
- }
-
- .folder-icon {
- fill: $gl-text-color-secondary;
- }
- }
-
a {
color: $gl-text-color;
}
-
- th {
- position: sticky;
- top: 0;
- }
-}
-
-.file-name {
- display: flex;
- overflow: visible;
- align-items: center;
- width: 100%;
}
.multi-file-loading-container {
@@ -625,8 +551,7 @@ $ide-commit-header-height: 48px;
}
}
-.multi-file-commit-list-path,
-.ide-file-list .file {
+.multi-file-commit-list-path {
display: flex;
align-items: center;
margin-left: -$grid-size;
@@ -634,28 +559,14 @@ $ide-commit-header-height: 48px;
padding: $grid-size / 2 $grid-size;
border-radius: $border-radius-default;
text-align: left;
-
- &:hover,
- &:focus {
- background: $theme-gray-100;
- }
-
- &:active {
- background: $theme-gray-200;
- }
-}
-
-.multi-file-commit-list-path {
cursor: pointer;
height: $ide-commit-row-height;
padding-right: 0;
- &.is-active {
- background-color: $white-normal;
- }
-
&:hover,
&:focus {
+ background: $theme-gray-100;
+
outline: 0;
.multi-file-discard-btn {
@@ -665,6 +576,14 @@ $ide-commit-header-height: 48px;
}
}
+ &:active {
+ background: $theme-gray-200;
+ }
+
+ &.is-active {
+ background-color: $white-normal;
+ }
+
svg {
min-width: 16px;
vertical-align: middle;
@@ -1398,9 +1317,17 @@ $ide-commit-header-height: 48px;
}
}
-.ide-new-btn .dropdown.show .ide-entry-dropdown-toggle {
- color: $white-normal;
- background-color: $blue-500;
+.ide-new-btn {
+ display: none;
+
+ .btn {
+ padding: 2px 5px;
+ }
+
+ .dropdown.show .ide-entry-dropdown-toggle {
+ color: $white-normal;
+ background-color: $blue-500;
+ }
}
.ide-preview-header {
@@ -1465,3 +1392,28 @@ $ide-commit-header-height: 48px;
width: $ide-commit-row-height;
height: $ide-commit-row-height;
}
+
+.ide-file-icon-holder {
+ display: flex;
+ align-items: center;
+ color: $theme-gray-700;
+}
+
+.ide-file-changed-icon {
+ margin-left: auto;
+
+ > svg {
+ display: block;
+ }
+}
+
+.file-row:hover,
+.file-row:focus {
+ .ide-new-btn {
+ display: block;
+ }
+
+ .folder-icon {
+ fill: $gl-text-color-secondary;
+ }
+}
diff --git a/app/assets/stylesheets/pages/xterm.scss b/app/assets/stylesheets/page_bundles/xterm.scss
index 7d40c61da26..7f040ac9b96 100644
--- a/app/assets/stylesheets/pages/xterm.scss
+++ b/app/assets/stylesheets/page_bundles/xterm.scss
@@ -1,3 +1,5 @@
+@import 'framework/variables';
+
.build-page {
// color codes are based on http://en.wikipedia.org/wiki/File:Xterm_256color_chart.svg
// see also: https://gist.github.com/jasonm23/2868981
diff --git a/app/assets/stylesheets/pages/boards.scss b/app/assets/stylesheets/pages/boards.scss
index 69d7de886b4..48db91a5786 100644
--- a/app/assets/stylesheets/pages/boards.scss
+++ b/app/assets/stylesheets/pages/boards.scss
@@ -136,15 +136,23 @@
right: 0;
bottom: 0;
left: 0;
+
+ button {
+ display: none;
+ }
}
.board-title {
padding: 0;
border-bottom: 0;
+ justify-content: center;
> span {
+ width: 100%;
+ margin-top: -12px;
display: block;
- transform: rotate(90deg) translate(35px, 10px);
+ transform: rotate(90deg) translate(35px, 0);
+ overflow: initial;
}
}
diff --git a/app/assets/stylesheets/pages/clusters.scss b/app/assets/stylesheets/pages/clusters.scss
index 0f22fe21143..71a3fd544f2 100644
--- a/app/assets/stylesheets/pages/clusters.scss
+++ b/app/assets/stylesheets/pages/clusters.scss
@@ -4,9 +4,60 @@
}
}
-.cluster-applications-table {
- // Wait for the Vue to kick-in and render the applications block
- min-height: 628px;
+.cluster-application-row {
+ background: $gray-lighter;
+
+ &.cluster-application-installed {
+ background: none;
+ }
+
+ .settings-message {
+ padding: $gl-vert-padding $gl-padding-8;
+ }
+}
+
+@media (min-width: map-get($grid-breakpoints, md)) {
+ .cluster-application-list {
+ border: 1px solid $border-color;
+ border-radius: $border-radius-default;
+ }
+
+ .cluster-application-row {
+ border-bottom: 1px solid $border-color;
+ padding: $gl-padding;
+ }
+}
+
+.cluster-application-logo {
+ border: 3px solid $white-light;
+ box-shadow: 0 0 0 1px $gray-normal;
+
+ &.avatar:hover {
+ border-color: $white-light;
+ }
+}
+
+.cluster-application-warning {
+ font-weight: bold;
+ text-align: center;
+ padding: $gl-padding;
+ border-bottom: 1px solid $white-normal;
+
+ .svg-container {
+ display: inline-block;
+ vertical-align: middle;
+ margin-right: $gl-padding-8;
+ width: 40px;
+ height: 40px;
+ }
+}
+
+.cluster-application-description {
+ flex: 1;
+}
+
+.cluster-application-disabled {
+ opacity: 0.5;
}
.clusters-dropdown-menu {
diff --git a/app/assets/stylesheets/pages/groups.scss b/app/assets/stylesheets/pages/groups.scss
index 394c99268be..fe792a53b44 100644
--- a/app/assets/stylesheets/pages/groups.scss
+++ b/app/assets/stylesheets/pages/groups.scss
@@ -106,7 +106,7 @@
&,
.dropdown,
.dropdown .dropdown-toggle,
- .btn-new {
+ .btn-success {
display: block;
}
@@ -118,7 +118,7 @@
.group-filter-form,
.dropdown .dropdown-toggle,
- .btn-new {
+ .btn-success {
width: 100%;
}
diff --git a/app/assets/stylesheets/pages/issuable.scss b/app/assets/stylesheets/pages/issuable.scss
index 57539212e0c..62a9f97caa9 100644
--- a/app/assets/stylesheets/pages/issuable.scss
+++ b/app/assets/stylesheets/pages/issuable.scss
@@ -726,13 +726,13 @@
display: flex;
}
- .issue-info-container {
+ .issuable-info-container {
-webkit-flex: 1;
flex: 1;
display: flex;
padding-right: $gl-padding;
- .issue-main-info {
+ .issuable-main-info {
flex: 1 auto;
margin-right: 10px;
}
@@ -768,7 +768,7 @@
margin-bottom: 10px;
min-width: 15px;
- .selected_issue {
+ .selected-issuable {
vertical-align: text-top;
}
}
@@ -800,7 +800,7 @@
}
.issuable-list li,
-.issue-info-container .controls {
+.issuable-info-container .controls {
.avatar-counter {
display: inline-block;
vertical-align: middle;
diff --git a/app/assets/stylesheets/pages/members.scss b/app/assets/stylesheets/pages/members.scss
index 5fdb2b4a90a..99609a96976 100644
--- a/app/assets/stylesheets/pages/members.scss
+++ b/app/assets/stylesheets/pages/members.scss
@@ -4,7 +4,7 @@
}
.users-project-form {
- .btn-create {
+ .btn-success {
margin-right: 10px;
}
}
diff --git a/app/assets/stylesheets/pages/merge_requests.scss b/app/assets/stylesheets/pages/merge_requests.scss
index 9d46c2cf4fa..97b131687d3 100644
--- a/app/assets/stylesheets/pages/merge_requests.scss
+++ b/app/assets/stylesheets/pages/merge_requests.scss
@@ -460,7 +460,7 @@
display: -webkit-flex;
display: flex;
- .issue-info-container {
+ .issuable-info-container {
-webkit-flex: 1;
flex: 1;
}
diff --git a/app/assets/stylesheets/pages/note_form.scss b/app/assets/stylesheets/pages/note_form.scss
index ac7b701c2e2..4268e194ed7 100644
--- a/app/assets/stylesheets/pages/note_form.scss
+++ b/app/assets/stylesheets/pages/note_form.scss
@@ -2,7 +2,7 @@
* Note Form
*/
.comment-btn {
- @extend .btn-create;
+ @extend .btn-success;
}
.diff-file .diff-content {
diff --git a/app/assets/stylesheets/pages/search.scss b/app/assets/stylesheets/pages/search.scss
index 77119aea9e2..04151b1cd59 100644
--- a/app/assets/stylesheets/pages/search.scss
+++ b/app/assets/stylesheets/pages/search.scss
@@ -218,7 +218,7 @@ input[type='checkbox']:hover {
}
.btn-search,
- .btn-new {
+ .btn-success {
width: 100%;
margin-top: 5px;
diff --git a/app/controllers/abuse_reports_controller.rb b/app/controllers/abuse_reports_controller.rb
index 51547ed7eaf..68e14f0c2e5 100644
--- a/app/controllers/abuse_reports_controller.rb
+++ b/app/controllers/abuse_reports_controller.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
class AbuseReportsController < ApplicationController
before_action :set_user, only: [:new]
diff --git a/app/controllers/admin/abuse_reports_controller.rb b/app/controllers/admin/abuse_reports_controller.rb
index 68a49f0749f..d5537023b26 100644
--- a/app/controllers/admin/abuse_reports_controller.rb
+++ b/app/controllers/admin/abuse_reports_controller.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
class Admin::AbuseReportsController < Admin::ApplicationController
# rubocop: disable CodeReuse/ActiveRecord
def index
diff --git a/app/controllers/admin/appearances_controller.rb b/app/controllers/admin/appearances_controller.rb
index 9aaec905734..fdd3b4126ff 100644
--- a/app/controllers/admin/appearances_controller.rb
+++ b/app/controllers/admin/appearances_controller.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
class Admin::AppearancesController < Admin::ApplicationController
before_action :set_appearance, except: :create
diff --git a/app/controllers/admin/application_controller.rb b/app/controllers/admin/application_controller.rb
index a4648b33cfa..ef182b981f1 100644
--- a/app/controllers/admin/application_controller.rb
+++ b/app/controllers/admin/application_controller.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
# Provides a base class for Admin controllers to subclass
#
# Automatically sets the layout and ensures an administrator is logged in
diff --git a/app/controllers/admin/application_settings_controller.rb b/app/controllers/admin/application_settings_controller.rb
index 869213d61f1..875e46969fe 100644
--- a/app/controllers/admin/application_settings_controller.rb
+++ b/app/controllers/admin/application_settings_controller.rb
@@ -1,9 +1,39 @@
+# frozen_string_literal: true
+
class Admin::ApplicationSettingsController < Admin::ApplicationController
+ include InternalRedirect
before_action :set_application_setting
def show
end
+ def integrations
+ end
+
+ def repository
+ end
+
+ def templates
+ end
+
+ def ci_cd
+ end
+
+ def reporting
+ end
+
+ def metrics_and_profiling
+ end
+
+ def network
+ end
+
+ def geo
+ end
+
+ def preferences
+ end
+
def update
successful = ApplicationSettings::UpdateService
.new(@application_setting, current_user, application_setting_params)
@@ -13,10 +43,12 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
session[:ask_for_usage_stats_consent] = current_user.requires_usage_stats_consent?
end
+ redirect_path = referer_path(request) || admin_application_settings_path
+
respond_to do |format|
if successful
format.json { head :ok }
- format.html { redirect_to admin_application_settings_path, notice: 'Application settings saved successfully' }
+ format.html { redirect_to redirect_path, notice: 'Application settings saved successfully' }
else
format.json { head :bad_request }
format.html { render :show }
diff --git a/app/controllers/admin/applications_controller.rb b/app/controllers/admin/applications_controller.rb
index daa21d1be93..00d2cc01192 100644
--- a/app/controllers/admin/applications_controller.rb
+++ b/app/controllers/admin/applications_controller.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
class Admin::ApplicationsController < Admin::ApplicationController
include OauthApplications
diff --git a/app/controllers/admin/background_jobs_controller.rb b/app/controllers/admin/background_jobs_controller.rb
index 5f90ad7137d..7701f2e645b 100644
--- a/app/controllers/admin/background_jobs_controller.rb
+++ b/app/controllers/admin/background_jobs_controller.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
class Admin::BackgroundJobsController < Admin::ApplicationController
def show
ps_output, _ = Gitlab::Popen.popen(%W(ps ww -U #{Gitlab.config.gitlab.user} -o pid,pcpu,pmem,stat,start,command))
diff --git a/app/controllers/admin/broadcast_messages_controller.rb b/app/controllers/admin/broadcast_messages_controller.rb
index b2fbbfc3e64..a91d9a534cd 100644
--- a/app/controllers/admin/broadcast_messages_controller.rb
+++ b/app/controllers/admin/broadcast_messages_controller.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
class Admin::BroadcastMessagesController < Admin::ApplicationController
include BroadcastMessagesHelper
diff --git a/app/controllers/admin/dashboard_controller.rb b/app/controllers/admin/dashboard_controller.rb
index 5dc3e6c2990..b5fb5511638 100644
--- a/app/controllers/admin/dashboard_controller.rb
+++ b/app/controllers/admin/dashboard_controller.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
class Admin::DashboardController < Admin::ApplicationController
include CountHelper
diff --git a/app/controllers/admin/deploy_keys_controller.rb b/app/controllers/admin/deploy_keys_controller.rb
index 5c2025c1988..49ce275ad14 100644
--- a/app/controllers/admin/deploy_keys_controller.rb
+++ b/app/controllers/admin/deploy_keys_controller.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
class Admin::DeployKeysController < Admin::ApplicationController
before_action :deploy_keys, only: [:index]
before_action :deploy_key, only: [:destroy, :edit, :update]
diff --git a/app/controllers/admin/gitaly_servers_controller.rb b/app/controllers/admin/gitaly_servers_controller.rb
index 11c4dfe3d8d..0a5566bfe70 100644
--- a/app/controllers/admin/gitaly_servers_controller.rb
+++ b/app/controllers/admin/gitaly_servers_controller.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
class Admin::GitalyServersController < Admin::ApplicationController
def index
@gitaly_servers = Gitaly::Server.all
diff --git a/app/controllers/admin/groups_controller.rb b/app/controllers/admin/groups_controller.rb
index 2a47f01c6ad..46e85e1424f 100644
--- a/app/controllers/admin/groups_controller.rb
+++ b/app/controllers/admin/groups_controller.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
class Admin::GroupsController < Admin::ApplicationController
include MembersPresentation
diff --git a/app/controllers/admin/health_check_controller.rb b/app/controllers/admin/health_check_controller.rb
index 61247b280b3..44864f9c7d0 100644
--- a/app/controllers/admin/health_check_controller.rb
+++ b/app/controllers/admin/health_check_controller.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
class Admin::HealthCheckController < Admin::ApplicationController
def show
@errors = HealthCheck::Utils.process_checks(['standard'])
diff --git a/app/controllers/admin/hook_logs_controller.rb b/app/controllers/admin/hook_logs_controller.rb
index 3017f96c26f..8301b3aa880 100644
--- a/app/controllers/admin/hook_logs_controller.rb
+++ b/app/controllers/admin/hook_logs_controller.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
class Admin::HookLogsController < Admin::ApplicationController
include HooksExecution
diff --git a/app/controllers/admin/hooks_controller.rb b/app/controllers/admin/hooks_controller.rb
index a98c355c7ba..d0abdec50ae 100644
--- a/app/controllers/admin/hooks_controller.rb
+++ b/app/controllers/admin/hooks_controller.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
class Admin::HooksController < Admin::ApplicationController
include HooksExecution
diff --git a/app/controllers/admin/identities_controller.rb b/app/controllers/admin/identities_controller.rb
index 57ad7389a23..b51c2f678ca 100644
--- a/app/controllers/admin/identities_controller.rb
+++ b/app/controllers/admin/identities_controller.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
class Admin::IdentitiesController < Admin::ApplicationController
before_action :user
before_action :identity, except: [:index, :new, :create]
diff --git a/app/controllers/admin/impersonation_tokens_controller.rb b/app/controllers/admin/impersonation_tokens_controller.rb
index 9ebba88ef16..f5825ecb19a 100644
--- a/app/controllers/admin/impersonation_tokens_controller.rb
+++ b/app/controllers/admin/impersonation_tokens_controller.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
class Admin::ImpersonationTokensController < Admin::ApplicationController
before_action :user
diff --git a/app/controllers/admin/impersonations_controller.rb b/app/controllers/admin/impersonations_controller.rb
index d2f947d2c66..08d7e3b4fa2 100644
--- a/app/controllers/admin/impersonations_controller.rb
+++ b/app/controllers/admin/impersonations_controller.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
class Admin::ImpersonationsController < Admin::ApplicationController
skip_before_action :authenticate_admin!
before_action :authenticate_impersonator!
diff --git a/app/controllers/admin/jobs_controller.rb b/app/controllers/admin/jobs_controller.rb
index 788693c62c4..0c1afdc3d3b 100644
--- a/app/controllers/admin/jobs_controller.rb
+++ b/app/controllers/admin/jobs_controller.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
class Admin::JobsController < Admin::ApplicationController
# rubocop: disable CodeReuse/ActiveRecord
def index
diff --git a/app/controllers/admin/keys_controller.rb b/app/controllers/admin/keys_controller.rb
index 0400a3b2f3b..4e9262ccc96 100644
--- a/app/controllers/admin/keys_controller.rb
+++ b/app/controllers/admin/keys_controller.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
class Admin::KeysController < Admin::ApplicationController
before_action :user, only: [:show, :destroy]
diff --git a/app/controllers/admin/labels_controller.rb b/app/controllers/admin/labels_controller.rb
index 7eb8f758807..aa5eae7a474 100644
--- a/app/controllers/admin/labels_controller.rb
+++ b/app/controllers/admin/labels_controller.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
class Admin::LabelsController < Admin::ApplicationController
before_action :set_label, only: [:show, :edit, :update, :destroy]
diff --git a/app/controllers/admin/logs_controller.rb b/app/controllers/admin/logs_controller.rb
index 7248edb64e1..06b0e6a15a3 100644
--- a/app/controllers/admin/logs_controller.rb
+++ b/app/controllers/admin/logs_controller.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
class Admin::LogsController < Admin::ApplicationController
before_action :loggers
diff --git a/app/controllers/admin/projects_controller.rb b/app/controllers/admin/projects_controller.rb
index 5cb08c9787b..550f29a58d2 100644
--- a/app/controllers/admin/projects_controller.rb
+++ b/app/controllers/admin/projects_controller.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
class Admin::ProjectsController < Admin::ApplicationController
include MembersPresentation
diff --git a/app/controllers/admin/requests_profiles_controller.rb b/app/controllers/admin/requests_profiles_controller.rb
index a478176e138..64d74ae4231 100644
--- a/app/controllers/admin/requests_profiles_controller.rb
+++ b/app/controllers/admin/requests_profiles_controller.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
class Admin::RequestsProfilesController < Admin::ApplicationController
def index
@profile_token = Gitlab::RequestProfiler.profile_token
diff --git a/app/controllers/admin/runner_projects_controller.rb b/app/controllers/admin/runner_projects_controller.rb
index 51d5799cd89..774ce04d079 100644
--- a/app/controllers/admin/runner_projects_controller.rb
+++ b/app/controllers/admin/runner_projects_controller.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
class Admin::RunnerProjectsController < Admin::ApplicationController
before_action :project, only: [:create]
diff --git a/app/controllers/admin/runners_controller.rb b/app/controllers/admin/runners_controller.rb
index 911603bac17..0b6ff491c66 100644
--- a/app/controllers/admin/runners_controller.rb
+++ b/app/controllers/admin/runners_controller.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
class Admin::RunnersController < Admin::ApplicationController
before_action :runner, except: :index
diff --git a/app/controllers/admin/spam_logs_controller.rb b/app/controllers/admin/spam_logs_controller.rb
index 8df35d25303..18d22c95b61 100644
--- a/app/controllers/admin/spam_logs_controller.rb
+++ b/app/controllers/admin/spam_logs_controller.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
class Admin::SpamLogsController < Admin::ApplicationController
# rubocop: disable CodeReuse/ActiveRecord
def index
diff --git a/app/controllers/admin/system_info_controller.rb b/app/controllers/admin/system_info_controller.rb
index 99039724521..244fc2b31bb 100644
--- a/app/controllers/admin/system_info_controller.rb
+++ b/app/controllers/admin/system_info_controller.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
class Admin::SystemInfoController < Admin::ApplicationController
EXCLUDED_MOUNT_OPTIONS = [
'nobrowse',
diff --git a/app/controllers/admin/users_controller.rb b/app/controllers/admin/users_controller.rb
index 85bdc85c55b..b783c0e2a6f 100644
--- a/app/controllers/admin/users_controller.rb
+++ b/app/controllers/admin/users_controller.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
class Admin::UsersController < Admin::ApplicationController
before_action :user, except: [:index, :new, :create]
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 7e2b2cf3ad3..838527aaa41 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'gon'
require 'fogbugz'
diff --git a/app/controllers/autocomplete_controller.rb b/app/controllers/autocomplete_controller.rb
index 9e30b982b06..3766b64a091 100644
--- a/app/controllers/autocomplete_controller.rb
+++ b/app/controllers/autocomplete_controller.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
class AutocompleteController < ApplicationController
skip_before_action :authenticate_user!, only: [:users, :award_emojis]
diff --git a/app/controllers/boards/application_controller.rb b/app/controllers/boards/application_controller.rb
index b2675025fc0..eab908ba5ed 100644
--- a/app/controllers/boards/application_controller.rb
+++ b/app/controllers/boards/application_controller.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module Boards
class ApplicationController < ::ApplicationController
respond_to :json
diff --git a/app/controllers/boards/issues_controller.rb b/app/controllers/boards/issues_controller.rb
index 071906f1e91..4f3d737e3ce 100644
--- a/app/controllers/boards/issues_controller.rb
+++ b/app/controllers/boards/issues_controller.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module Boards
class IssuesController < Boards::ApplicationController
include BoardsResponses
diff --git a/app/controllers/boards/lists_controller.rb b/app/controllers/boards/lists_controller.rb
index e8b5934f2a9..ccd02144671 100644
--- a/app/controllers/boards/lists_controller.rb
+++ b/app/controllers/boards/lists_controller.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module Boards
class ListsController < Boards::ApplicationController
include BoardsResponses
diff --git a/app/controllers/ci/lints_controller.rb b/app/controllers/ci/lints_controller.rb
index 738a6a5173e..99ce24bd435 100644
--- a/app/controllers/ci/lints_controller.rb
+++ b/app/controllers/ci/lints_controller.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module Ci
class LintsController < ::ApplicationController
before_action :authenticate_user!
diff --git a/app/controllers/concerns/accepts_pending_invitations.rb b/app/controllers/concerns/accepts_pending_invitations.rb
index 6e8aef52b52..cb66c1a055d 100644
--- a/app/controllers/concerns/accepts_pending_invitations.rb
+++ b/app/controllers/concerns/accepts_pending_invitations.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module AcceptsPendingInvitations
extend ActiveSupport::Concern
diff --git a/app/controllers/concerns/authenticates_with_two_factor.rb b/app/controllers/concerns/authenticates_with_two_factor.rb
index 961f121548b..5507328f8ae 100644
--- a/app/controllers/concerns/authenticates_with_two_factor.rb
+++ b/app/controllers/concerns/authenticates_with_two_factor.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
# == AuthenticatesWithTwoFactor
#
# Controller concern to handle two-factor authentication
diff --git a/app/controllers/concerns/boards_responses.rb b/app/controllers/concerns/boards_responses.rb
index da830ec2cb1..b7e4f9b81f1 100644
--- a/app/controllers/concerns/boards_responses.rb
+++ b/app/controllers/concerns/boards_responses.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module BoardsResponses
include Gitlab::Utils::StrongMemoize
diff --git a/app/controllers/concerns/checks_collaboration.rb b/app/controllers/concerns/checks_collaboration.rb
index 81367663a06..1fa82f7dcd4 100644
--- a/app/controllers/concerns/checks_collaboration.rb
+++ b/app/controllers/concerns/checks_collaboration.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module ChecksCollaboration
def can_collaborate_with_project?(project, ref: nil)
return true if can?(current_user, :push_code, project)
diff --git a/app/controllers/concerns/continue_params.rb b/app/controllers/concerns/continue_params.rb
index 8b7355974df..f0e6adf4dec 100644
--- a/app/controllers/concerns/continue_params.rb
+++ b/app/controllers/concerns/continue_params.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module ContinueParams
include InternalRedirect
extend ActiveSupport::Concern
diff --git a/app/controllers/concerns/controller_with_cross_project_access_check.rb b/app/controllers/concerns/controller_with_cross_project_access_check.rb
index a45c3384578..3f72f092683 100644
--- a/app/controllers/concerns/controller_with_cross_project_access_check.rb
+++ b/app/controllers/concerns/controller_with_cross_project_access_check.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module ControllerWithCrossProjectAccessCheck
extend ActiveSupport::Concern
diff --git a/app/controllers/concerns/creates_commit.rb b/app/controllers/concerns/creates_commit.rb
index 709c8aaf337..b3777fd2b0f 100644
--- a/app/controllers/concerns/creates_commit.rb
+++ b/app/controllers/concerns/creates_commit.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module CreatesCommit
extend ActiveSupport::Concern
include Gitlab::Utils::StrongMemoize
@@ -65,7 +67,7 @@ module CreatesCommit
flash[:notice] = nil
else
target = different_project? ? "project" : "branch"
- flash[:notice] << " You can now submit a merge request to get this change into the original #{target}."
+ flash[:notice] = flash[:notice] + " You can now submit a merge request to get this change into the original #{target}."
end
end
end
diff --git a/app/controllers/concerns/cycle_analytics_params.rb b/app/controllers/concerns/cycle_analytics_params.rb
index 1ab107168c0..c1ef848e1e7 100644
--- a/app/controllers/concerns/cycle_analytics_params.rb
+++ b/app/controllers/concerns/cycle_analytics_params.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module CycleAnalyticsParams
extend ActiveSupport::Concern
diff --git a/app/controllers/concerns/diff_for_path.rb b/app/controllers/concerns/diff_for_path.rb
index d5388c4cd20..6be7a2a18a2 100644
--- a/app/controllers/concerns/diff_for_path.rb
+++ b/app/controllers/concerns/diff_for_path.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module DiffForPath
extend ActiveSupport::Concern
diff --git a/app/controllers/concerns/enforces_two_factor_authentication.rb b/app/controllers/concerns/enforces_two_factor_authentication.rb
index 69e5cbed343..71bdef8ce03 100644
--- a/app/controllers/concerns/enforces_two_factor_authentication.rb
+++ b/app/controllers/concerns/enforces_two_factor_authentication.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
# == EnforcesTwoFactorAuthentication
#
# Controller concern to enforce two-factor authentication requirements
diff --git a/app/controllers/concerns/group_tree.rb b/app/controllers/concerns/group_tree.rb
index c363cad0ffa..4f56346832c 100644
--- a/app/controllers/concerns/group_tree.rb
+++ b/app/controllers/concerns/group_tree.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module GroupTree
# rubocop:disable Gitlab/ModuleWithInstanceVariables
# rubocop: disable CodeReuse/ActiveRecord
diff --git a/app/controllers/concerns/hooks_execution.rb b/app/controllers/concerns/hooks_execution.rb
index a22e46b4860..e8add1f4055 100644
--- a/app/controllers/concerns/hooks_execution.rb
+++ b/app/controllers/concerns/hooks_execution.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module HooksExecution
extend ActiveSupport::Concern
diff --git a/app/controllers/concerns/internal_redirect.rb b/app/controllers/concerns/internal_redirect.rb
index 10b9852e329..6785e6972d0 100644
--- a/app/controllers/concerns/internal_redirect.rb
+++ b/app/controllers/concerns/internal_redirect.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module InternalRedirect
extend ActiveSupport::Concern
@@ -36,4 +38,10 @@ module InternalRedirect
path_with_query = [uri.path, uri.query].compact.join('?')
[path_with_query, uri.fragment].compact.join("#")
end
+
+ def referer_path(request)
+ return unless request.referer.presence
+
+ URI(request.referer).path
+ end
end
diff --git a/app/controllers/concerns/issuable_actions.rb b/app/controllers/concerns/issuable_actions.rb
index e723107bd7f..07e01e903ea 100644
--- a/app/controllers/concerns/issuable_actions.rb
+++ b/app/controllers/concerns/issuable_actions.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module IssuableActions
extend ActiveSupport::Concern
diff --git a/app/controllers/concerns/issuable_collections.rb b/app/controllers/concerns/issuable_collections.rb
index d29154d5c60..5217b4be928 100644
--- a/app/controllers/concerns/issuable_collections.rb
+++ b/app/controllers/concerns/issuable_collections.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module IssuableCollections
extend ActiveSupport::Concern
include CookiesHelper
diff --git a/app/controllers/concerns/issues_action.rb b/app/controllers/concerns/issues_action.rb
index 9d58656773d..a75590457d6 100644
--- a/app/controllers/concerns/issues_action.rb
+++ b/app/controllers/concerns/issues_action.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module IssuesAction
extend ActiveSupport::Concern
include IssuableCollections
diff --git a/app/controllers/concerns/issues_calendar.rb b/app/controllers/concerns/issues_calendar.rb
index 76e1d1ff4e8..1fdfde4c869 100644
--- a/app/controllers/concerns/issues_calendar.rb
+++ b/app/controllers/concerns/issues_calendar.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module IssuesCalendar
extend ActiveSupport::Concern
diff --git a/app/controllers/concerns/lfs_request.rb b/app/controllers/concerns/lfs_request.rb
index 4584ff782a3..9576eb14fdd 100644
--- a/app/controllers/concerns/lfs_request.rb
+++ b/app/controllers/concerns/lfs_request.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
# This concern assumes:
# - a `#project` accessor
# - a `#user` accessor
diff --git a/app/controllers/concerns/members_presentation.rb b/app/controllers/concerns/members_presentation.rb
index e146e7574aa..c6c3598a976 100644
--- a/app/controllers/concerns/members_presentation.rb
+++ b/app/controllers/concerns/members_presentation.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module MembersPresentation
extend ActiveSupport::Concern
diff --git a/app/controllers/concerns/membership_actions.rb b/app/controllers/concerns/membership_actions.rb
index 94a352c0bcc..ca713192c9e 100644
--- a/app/controllers/concerns/membership_actions.rb
+++ b/app/controllers/concerns/membership_actions.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module MembershipActions
include MembersPresentation
extend ActiveSupport::Concern
diff --git a/app/controllers/concerns/merge_requests_action.rb b/app/controllers/concerns/merge_requests_action.rb
index b70db99b157..285f2c3a8a0 100644
--- a/app/controllers/concerns/merge_requests_action.rb
+++ b/app/controllers/concerns/merge_requests_action.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module MergeRequestsAction
extend ActiveSupport::Concern
include IssuableCollections
diff --git a/app/controllers/concerns/milestone_actions.rb b/app/controllers/concerns/milestone_actions.rb
index d92cf8b4894..eccbe35577b 100644
--- a/app/controllers/concerns/milestone_actions.rb
+++ b/app/controllers/concerns/milestone_actions.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module MilestoneActions
extend ActiveSupport::Concern
diff --git a/app/controllers/concerns/notes_actions.rb b/app/controllers/concerns/notes_actions.rb
index b63f2eb85f0..3a45d6205ab 100644
--- a/app/controllers/concerns/notes_actions.rb
+++ b/app/controllers/concerns/notes_actions.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module NotesActions
include RendersNotes
include Gitlab::Utils::StrongMemoize
@@ -41,12 +43,26 @@ module NotesActions
@note = Notes::CreateService.new(note_project, current_user, create_params).execute
- if @note.is_a?(Note)
- prepare_notes_for_rendering([@note], noteable)
- end
-
respond_to do |format|
- format.json { render json: note_json(@note) }
+ format.json do
+ json = {
+ commands_changes: @note.commands_changes
+ }
+
+ if @note.persisted? && return_discussion?
+ json[:valid] = true
+
+ discussion = @note.discussion
+ prepare_notes_for_rendering(discussion.notes)
+ json[:discussion] = discussion_serializer.represent(discussion, context: self)
+ else
+ prepare_notes_for_rendering([@note])
+
+ json.merge!(note_json(@note))
+ end
+
+ render json: json
+ end
format.html { redirect_back_or_default }
end
end
@@ -55,10 +71,7 @@ module NotesActions
# rubocop:disable Gitlab/ModuleWithInstanceVariables
def update
@note = Notes::UpdateService.new(project, current_user, note_params).execute(note)
-
- if @note.is_a?(Note)
- prepare_notes_for_rendering([@note])
- end
+ prepare_notes_for_rendering([@note])
respond_to do |format|
format.json { render json: note_json(@note) }
@@ -89,14 +102,17 @@ module NotesActions
end
def note_json(note)
- attrs = {
- commands_changes: note.commands_changes
- }
+ attrs = {}
if note.persisted?
attrs[:valid] = true
- if use_note_serializer?
+ if return_discussion?
+ discussion = note.discussion
+ prepare_notes_for_rendering(discussion.notes)
+
+ attrs[:discussion] = discussion_serializer.represent(discussion, context: self)
+ elsif use_note_serializer?
attrs.merge!(note_serializer.represent(note))
else
attrs.merge!(
@@ -216,6 +232,10 @@ module NotesActions
ProjectNoteSerializer.new(project: project, noteable: noteable, current_user: current_user)
end
+ def discussion_serializer
+ DiscussionSerializer.new(project: project, noteable: noteable, current_user: current_user, note_entity: ProjectNoteEntity)
+ end
+
def note_project
strong_memoize(:note_project) do
next nil unless project
@@ -235,6 +255,10 @@ module NotesActions
end
end
+ def return_discussion?
+ Gitlab::Utils.to_boolean(params[:return_discussion])
+ end
+
def use_note_serializer?
return false if params['html']
diff --git a/app/controllers/concerns/oauth_applications.rb b/app/controllers/concerns/oauth_applications.rb
index f0a68f23566..d97e22df472 100644
--- a/app/controllers/concerns/oauth_applications.rb
+++ b/app/controllers/concerns/oauth_applications.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module OauthApplications
extend ActiveSupport::Concern
diff --git a/app/controllers/concerns/params_backward_compatibility.rb b/app/controllers/concerns/params_backward_compatibility.rb
index b0e3d9c7b34..c972d6e3161 100644
--- a/app/controllers/concerns/params_backward_compatibility.rb
+++ b/app/controllers/concerns/params_backward_compatibility.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module ParamsBackwardCompatibility
private
diff --git a/app/controllers/concerns/preview_markdown.rb b/app/controllers/concerns/preview_markdown.rb
index 99123fcb3b0..c61b9fabe9e 100644
--- a/app/controllers/concerns/preview_markdown.rb
+++ b/app/controllers/concerns/preview_markdown.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module PreviewMarkdown
extend ActiveSupport::Concern
diff --git a/app/controllers/concerns/renders_blob.rb b/app/controllers/concerns/renders_blob.rb
index ba7adcfea86..b8026c7a01d 100644
--- a/app/controllers/concerns/renders_blob.rb
+++ b/app/controllers/concerns/renders_blob.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module RendersBlob
extend ActiveSupport::Concern
diff --git a/app/controllers/concerns/renders_commits.rb b/app/controllers/concerns/renders_commits.rb
index b1c9b1e532f..f48e0586211 100644
--- a/app/controllers/concerns/renders_commits.rb
+++ b/app/controllers/concerns/renders_commits.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module RendersCommits
def limited_commits(commits)
if commits.size > MergeRequestDiff::COMMITS_SAFE_SIZE
diff --git a/app/controllers/concerns/renders_member_access.rb b/app/controllers/concerns/renders_member_access.rb
index c5b77dacb26..955ac1a1bc8 100644
--- a/app/controllers/concerns/renders_member_access.rb
+++ b/app/controllers/concerns/renders_member_access.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module RendersMemberAccess
def prepare_groups_for_rendering(groups)
preload_max_member_access_for_collection(Group, groups)
diff --git a/app/controllers/concerns/renders_notes.rb b/app/controllers/concerns/renders_notes.rb
index c5f23e33424..ce36da6b715 100644
--- a/app/controllers/concerns/renders_notes.rb
+++ b/app/controllers/concerns/renders_notes.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module RendersNotes
# rubocop:disable Gitlab/ModuleWithInstanceVariables
def prepare_notes_for_rendering(notes, noteable = nil)
diff --git a/app/controllers/concerns/repository_settings_redirect.rb b/app/controllers/concerns/repository_settings_redirect.rb
index f3db3cd563b..0f18735c29e 100644
--- a/app/controllers/concerns/repository_settings_redirect.rb
+++ b/app/controllers/concerns/repository_settings_redirect.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module RepositorySettingsRedirect
extend ActiveSupport::Concern
diff --git a/app/controllers/concerns/requires_whitelisted_monitoring_client.rb b/app/controllers/concerns/requires_whitelisted_monitoring_client.rb
index 88d1b34bb06..426f224d26b 100644
--- a/app/controllers/concerns/requires_whitelisted_monitoring_client.rb
+++ b/app/controllers/concerns/requires_whitelisted_monitoring_client.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module RequiresWhitelistedMonitoringClient
extend ActiveSupport::Concern
diff --git a/app/controllers/concerns/routable_actions.rb b/app/controllers/concerns/routable_actions.rb
index 0931bdf4c04..88939b002b2 100644
--- a/app/controllers/concerns/routable_actions.rb
+++ b/app/controllers/concerns/routable_actions.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module RoutableActions
extend ActiveSupport::Concern
diff --git a/app/controllers/concerns/send_file_upload.rb b/app/controllers/concerns/send_file_upload.rb
index 382ec91f771..0bb7b7efed0 100644
--- a/app/controllers/concerns/send_file_upload.rb
+++ b/app/controllers/concerns/send_file_upload.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module SendFileUpload
def send_upload(file_upload, send_params: {}, redirect_params: {}, attachment: nil, disposition: 'attachment')
if attachment
diff --git a/app/controllers/concerns/service_params.rb b/app/controllers/concerns/service_params.rb
index c1acb50b76c..8bd93a349ef 100644
--- a/app/controllers/concerns/service_params.rb
+++ b/app/controllers/concerns/service_params.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module ServiceParams
extend ActiveSupport::Concern
diff --git a/app/controllers/concerns/snippets_actions.rb b/app/controllers/concerns/snippets_actions.rb
index 120614739aa..8c22490700c 100644
--- a/app/controllers/concerns/snippets_actions.rb
+++ b/app/controllers/concerns/snippets_actions.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module SnippetsActions
extend ActiveSupport::Concern
diff --git a/app/controllers/concerns/spammable_actions.rb b/app/controllers/concerns/spammable_actions.rb
index 922aa58a00f..c3a1b12af84 100644
--- a/app/controllers/concerns/spammable_actions.rb
+++ b/app/controllers/concerns/spammable_actions.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module SpammableActions
extend ActiveSupport::Concern
diff --git a/app/controllers/concerns/todos_actions.rb b/app/controllers/concerns/todos_actions.rb
index c0acdb3498d..78b65f7961b 100644
--- a/app/controllers/concerns/todos_actions.rb
+++ b/app/controllers/concerns/todos_actions.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module TodosActions
extend ActiveSupport::Concern
diff --git a/app/controllers/concerns/toggle_award_emoji.rb b/app/controllers/concerns/toggle_award_emoji.rb
index ae0b815f85e..97b343f8b1a 100644
--- a/app/controllers/concerns/toggle_award_emoji.rb
+++ b/app/controllers/concerns/toggle_award_emoji.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module ToggleAwardEmoji
extend ActiveSupport::Concern
diff --git a/app/controllers/concerns/toggle_subscription_action.rb b/app/controllers/concerns/toggle_subscription_action.rb
index 776583579e8..e613bfaeef2 100644
--- a/app/controllers/concerns/toggle_subscription_action.rb
+++ b/app/controllers/concerns/toggle_subscription_action.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module ToggleSubscriptionAction
extend ActiveSupport::Concern
diff --git a/app/controllers/concerns/uploads_actions.rb b/app/controllers/concerns/uploads_actions.rb
index 56772df21d7..7a1c7abfb8f 100644
--- a/app/controllers/concerns/uploads_actions.rb
+++ b/app/controllers/concerns/uploads_actions.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module UploadsActions
extend ActiveSupport::Concern
diff --git a/app/controllers/concerns/with_performance_bar.rb b/app/controllers/concerns/with_performance_bar.rb
index 6a8b1a4de7b..c12839c7bbd 100644
--- a/app/controllers/concerns/with_performance_bar.rb
+++ b/app/controllers/concerns/with_performance_bar.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module WithPerformanceBar
extend ActiveSupport::Concern
diff --git a/app/controllers/concerns/workhorse_request.rb b/app/controllers/concerns/workhorse_request.rb
index 43c0f1b173c..028f10e866a 100644
--- a/app/controllers/concerns/workhorse_request.rb
+++ b/app/controllers/concerns/workhorse_request.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module WorkhorseRequest
extend ActiveSupport::Concern
diff --git a/app/controllers/confirmations_controller.rb b/app/controllers/confirmations_controller.rb
index 7bc46a6ccc0..2c4aab67448 100644
--- a/app/controllers/confirmations_controller.rb
+++ b/app/controllers/confirmations_controller.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
class ConfirmationsController < Devise::ConfirmationsController
include AcceptsPendingInvitations
@@ -20,7 +22,7 @@ class ConfirmationsController < Devise::ConfirmationsController
after_sign_in(resource)
else
Gitlab::AppLogger.info("Email Confirmed: username=#{resource.username} email=#{resource.email} ip=#{request.remote_ip}")
- flash[:notice] += " Please sign in."
+ flash[:notice] = flash[:notice] + " Please sign in."
new_session_path(:user, anchor: 'login-pane')
end
end
diff --git a/app/controllers/dashboard_controller.rb b/app/controllers/dashboard_controller.rb
index ff133001b84..241753a505a 100644
--- a/app/controllers/dashboard_controller.rb
+++ b/app/controllers/dashboard_controller.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
class DashboardController < Dashboard::ApplicationController
include IssuesAction
include MergeRequestsAction
diff --git a/app/controllers/graphql_controller.rb b/app/controllers/graphql_controller.rb
index 0a1cf169aca..a1ec144410b 100644
--- a/app/controllers/graphql_controller.rb
+++ b/app/controllers/graphql_controller.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
class GraphqlController < ApplicationController
# Unauthenticated users have access to the API for public data
skip_before_action :authenticate_user!
diff --git a/app/controllers/groups/labels_controller.rb b/app/controllers/groups/labels_controller.rb
index 059cf160fa2..ae31313db64 100644
--- a/app/controllers/groups/labels_controller.rb
+++ b/app/controllers/groups/labels_controller.rb
@@ -10,10 +10,7 @@ class Groups::LabelsController < Groups::ApplicationController
def index
respond_to do |format|
format.html do
- @labels = @group.labels
- .optionally_search(params[:search])
- .order_by(sort)
- .page(params[:page])
+ @labels = GroupLabelsFinder.new(@group, params.merge(sort: sort)).execute
end
format.json do
render json: LabelSerializer.new.represent_appearance(available_labels)
diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb
index 8b46eedae79..062c8c4e9e1 100644
--- a/app/controllers/groups_controller.rb
+++ b/app/controllers/groups_controller.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
class GroupsController < Groups::ApplicationController
include API::Helpers::RelatedResourcesHelpers
include IssuesAction
diff --git a/app/controllers/health_check_controller.rb b/app/controllers/health_check_controller.rb
index c3d18991fd4..a2abed7ba4e 100644
--- a/app/controllers/health_check_controller.rb
+++ b/app/controllers/health_check_controller.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
class HealthCheckController < HealthCheck::HealthCheckController
include RequiresWhitelistedMonitoringClient
end
diff --git a/app/controllers/health_controller.rb b/app/controllers/health_controller.rb
index 3fedd5bfb29..ab4bc911e17 100644
--- a/app/controllers/health_controller.rb
+++ b/app/controllers/health_controller.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
class HealthController < ActionController::Base
protect_from_forgery with: :exception, except: :storage_check, prepend: true
include RequiresWhitelistedMonitoringClient
diff --git a/app/controllers/help_controller.rb b/app/controllers/help_controller.rb
index a394521698c..e5a1fc9d6ff 100644
--- a/app/controllers/help_controller.rb
+++ b/app/controllers/help_controller.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
class HelpController < ApplicationController
skip_before_action :authenticate_user!
diff --git a/app/controllers/ide_controller.rb b/app/controllers/ide_controller.rb
index 96bb2237d90..eeeebe430a7 100644
--- a/app/controllers/ide_controller.rb
+++ b/app/controllers/ide_controller.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
class IdeController < ApplicationController
layout 'fullscreen'
diff --git a/app/controllers/invites_controller.rb b/app/controllers/invites_controller.rb
index 025d8270b7c..315d1375e02 100644
--- a/app/controllers/invites_controller.rb
+++ b/app/controllers/invites_controller.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
class InvitesController < ApplicationController
before_action :member
skip_before_action :authenticate_user!, only: :decline
@@ -50,9 +52,9 @@ class InvitesController < ApplicationController
def authenticate_user!
return if current_user
- notice = "To accept this invitation, sign in"
- notice << " or create an account" if Gitlab::CurrentSettings.allow_signup?
- notice << "."
+ notice = ["To accept this invitation, sign in"]
+ notice << "or create an account" if Gitlab::CurrentSettings.allow_signup?
+ notice = notice.join(' ') + "."
store_location_for :user, request.fullpath
redirect_to new_user_session_path, notice: notice
diff --git a/app/controllers/jwt_controller.rb b/app/controllers/jwt_controller.rb
index d172aee5436..f9008a5b67e 100644
--- a/app/controllers/jwt_controller.rb
+++ b/app/controllers/jwt_controller.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
class JwtController < ApplicationController
skip_before_action :authenticate_user!
skip_before_action :verify_authenticity_token
diff --git a/app/controllers/koding_controller.rb b/app/controllers/koding_controller.rb
index 745abf3c0f5..72aa9d4f17f 100644
--- a/app/controllers/koding_controller.rb
+++ b/app/controllers/koding_controller.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
class KodingController < ApplicationController
before_action :check_integration!
layout 'koding'
diff --git a/app/controllers/metrics_controller.rb b/app/controllers/metrics_controller.rb
index 0400ffcfee5..7353be478e1 100644
--- a/app/controllers/metrics_controller.rb
+++ b/app/controllers/metrics_controller.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
class MetricsController < ActionController::Base
include RequiresWhitelistedMonitoringClient
diff --git a/app/controllers/notification_settings_controller.rb b/app/controllers/notification_settings_controller.rb
index 461f26561f1..84dce74ace8 100644
--- a/app/controllers/notification_settings_controller.rb
+++ b/app/controllers/notification_settings_controller.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
class NotificationSettingsController < ApplicationController
before_action :authenticate_user!
diff --git a/app/controllers/oauth/applications_controller.rb b/app/controllers/oauth/applications_controller.rb
index a1fe02dc852..9e700f648f4 100644
--- a/app/controllers/oauth/applications_controller.rb
+++ b/app/controllers/oauth/applications_controller.rb
@@ -4,7 +4,7 @@ class Oauth::ApplicationsController < Doorkeeper::ApplicationsController
include PageLayoutHelper
include OauthApplications
- before_action :verify_user_oauth_applications_enabled
+ before_action :verify_user_oauth_applications_enabled, except: :index
before_action :authenticate_user!
before_action :add_gon_variables
before_action :load_scopes, only: [:index, :create, :edit]
diff --git a/app/controllers/omniauth_callbacks_controller.rb b/app/controllers/omniauth_callbacks_controller.rb
index 1547d4b5972..30be50d4595 100644
--- a/app/controllers/omniauth_callbacks_controller.rb
+++ b/app/controllers/omniauth_callbacks_controller.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
class OmniauthCallbacksController < Devise::OmniauthCallbacksController
include AuthenticatesWithTwoFactor
include Devise::Controllers::Rememberable
@@ -135,14 +137,13 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController
def handle_signup_error
label = Gitlab::Auth::OAuth::Provider.label_for(oauth['provider'])
- message = "Signing in using your #{label} account without a pre-existing GitLab account is not allowed."
+ message = ["Signing in using your #{label} account without a pre-existing GitLab account is not allowed."]
if Gitlab::CurrentSettings.allow_signup?
- message << " Create a GitLab account first, and then connect it to your #{label} account."
+ message << "Create a GitLab account first, and then connect it to your #{label} account."
end
- flash[:notice] = message
-
+ flash[:notice] = message.join(' ')
redirect_to new_user_session_path
end
diff --git a/app/controllers/passwords_controller.rb b/app/controllers/passwords_controller.rb
index a1bcf206b65..2912a22411e 100644
--- a/app/controllers/passwords_controller.rb
+++ b/app/controllers/passwords_controller.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
class PasswordsController < Devise::PasswordsController
skip_before_action :require_no_authentication, only: [:edit, :update]
diff --git a/app/controllers/profiles_controller.rb b/app/controllers/profiles_controller.rb
index a43d47797f1..15248d2d08f 100644
--- a/app/controllers/profiles_controller.rb
+++ b/app/controllers/profiles_controller.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
class ProfilesController < Profiles::ApplicationController
include ActionView::Helpers::SanitizeHelper
diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb
index 64d9b16a041..7352c5e9bec 100644
--- a/app/controllers/projects_controller.rb
+++ b/app/controllers/projects_controller.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
class ProjectsController < Projects::ApplicationController
include API::Helpers::RelatedResourcesHelpers
include IssuableCollections
diff --git a/app/controllers/registrations_controller.rb b/app/controllers/registrations_controller.rb
index e6d6965036e..8b8d87524a8 100644
--- a/app/controllers/registrations_controller.rb
+++ b/app/controllers/registrations_controller.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
class RegistrationsController < Devise::RegistrationsController
include Recaptcha::Verify
include AcceptsPendingInvitations
diff --git a/app/controllers/root_controller.rb b/app/controllers/root_controller.rb
index 651b82f04f4..ebf70f25bda 100644
--- a/app/controllers/root_controller.rb
+++ b/app/controllers/root_controller.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
# RootController
#
# This controller exists solely to handle requests to `root_url`. When a user is
diff --git a/app/controllers/search_controller.rb b/app/controllers/search_controller.rb
index a928758f325..1b22907c10f 100644
--- a/app/controllers/search_controller.rb
+++ b/app/controllers/search_controller.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
class SearchController < ApplicationController
include ControllerWithCrossProjectAccessCheck
include SearchHelper
diff --git a/app/controllers/sent_notifications_controller.rb b/app/controllers/sent_notifications_controller.rb
index 93a71103a09..2b76921ebd8 100644
--- a/app/controllers/sent_notifications_controller.rb
+++ b/app/controllers/sent_notifications_controller.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
class SentNotificationsController < ApplicationController
skip_before_action :authenticate_user!
diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb
index 9f2e66dea90..643eb75c83c 100644
--- a/app/controllers/sessions_controller.rb
+++ b/app/controllers/sessions_controller.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
class SessionsController < Devise::SessionsController
include InternalRedirect
include AuthenticatesWithTwoFactor
diff --git a/app/controllers/snippets_controller.rb b/app/controllers/snippets_controller.rb
index 19d865900e9..694c3a59e2b 100644
--- a/app/controllers/snippets_controller.rb
+++ b/app/controllers/snippets_controller.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
class SnippetsController < ApplicationController
include RendersNotes
include ToggleAwardEmoji
diff --git a/app/controllers/uploads_controller.rb b/app/controllers/uploads_controller.rb
index 3d227b0a955..fa5d84633b5 100644
--- a/app/controllers/uploads_controller.rb
+++ b/app/controllers/uploads_controller.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
class UploadsController < ApplicationController
include UploadsActions
diff --git a/app/controllers/user_callouts_controller.rb b/app/controllers/user_callouts_controller.rb
index b8d2deba93b..ebf1dd8ca02 100644
--- a/app/controllers/user_callouts_controller.rb
+++ b/app/controllers/user_callouts_controller.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
class UserCalloutsController < ApplicationController
def create
if ensure_callout.persisted?
diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb
index 2f65f4a7403..e509098d778 100644
--- a/app/controllers/users_controller.rb
+++ b/app/controllers/users_controller.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
class UsersController < ApplicationController
include RoutableActions
include RendersMemberAccess
diff --git a/app/finders/group_labels_finder.rb b/app/finders/group_labels_finder.rb
new file mode 100644
index 00000000000..903023033ed
--- /dev/null
+++ b/app/finders/group_labels_finder.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class GroupLabelsFinder
+ attr_reader :group, :params
+
+ def initialize(group, params = {})
+ @group = group
+ @params = params
+ end
+
+ def execute
+ group.labels
+ .optionally_search(params[:search])
+ .order_by(params[:sort])
+ .page(params[:page])
+ end
+end
diff --git a/app/finders/members_finder.rb b/app/finders/members_finder.rb
index 48777838d60..f90a7868102 100644
--- a/app/finders/members_finder.rb
+++ b/app/finders/members_finder.rb
@@ -18,7 +18,7 @@ class MembersFinder
group_members = GroupMembersFinder.new(group).execute(include_descendants: include_descendants) # rubocop: disable CodeReuse/Finder
group_members = group_members.non_invite
- union = Gitlab::SQL::Union.new([project_members, group_members], remove_duplicates: false)
+ union = Gitlab::SQL::Union.new([project_members, group_members], remove_duplicates: false) # rubocop: disable Gitlab/Union
sql = distinct_on(union)
diff --git a/app/finders/snippets_finder.rb b/app/finders/snippets_finder.rb
index 715dffb972f..3528e4228b2 100644
--- a/app/finders/snippets_finder.rb
+++ b/app/finders/snippets_finder.rb
@@ -89,9 +89,7 @@ class SnippetsFinder < UnionFinder
# We use a UNION here instead of OR clauses since this results in better
# performance.
- union = Gitlab::SQL::Union.new([authorized_projects.select('projects.id'), visible_projects.select('projects.id')])
-
- Project.from("(#{union.to_sql}) AS #{Project.table_name}")
+ Project.from_union([authorized_projects, visible_projects])
end
# rubocop: enable CodeReuse/ActiveRecord
diff --git a/app/finders/todos_finder.rb b/app/finders/todos_finder.rb
index 0d9f16fdce7..74baf79e4f2 100644
--- a/app/finders/todos_finder.rb
+++ b/app/finders/todos_finder.rb
@@ -164,16 +164,13 @@ class TodosFinder
# rubocop: disable CodeReuse/ActiveRecord
def by_group(items)
- if group?
- groups = group.self_and_descendants
- project_todos = items.where(project_id: Project.where(group: groups).select(:id))
- group_todos = items.where(group_id: groups.select(:id))
+ return items unless group?
- union = Gitlab::SQL::Union.new([project_todos, group_todos])
- items = Todo.from("(#{union.to_sql}) #{Todo.table_name}")
- end
+ groups = group.self_and_descendants
+ project_todos = items.where(project_id: Project.where(group: groups).select(:id))
+ group_todos = items.where(group_id: groups.select(:id))
- items
+ Todo.from_union([project_todos, group_todos])
end
# rubocop: enable CodeReuse/ActiveRecord
diff --git a/app/finders/union_finder.rb b/app/finders/union_finder.rb
index 798c3eba0f3..c3b02f7e52f 100644
--- a/app/finders/union_finder.rb
+++ b/app/finders/union_finder.rb
@@ -1,15 +1,15 @@
# frozen_string_literal: true
class UnionFinder
- # rubocop: disable CodeReuse/ActiveRecord
def find_union(segments, klass)
- if segments.length > 1
- union = Gitlab::SQL::Union.new(segments.map { |s| s.select(:id) })
+ unless klass < FromUnion
+ raise TypeError, "#{klass.inspect} must include the FromUnion module"
+ end
- klass.where("#{klass.table_name}.id IN (#{union.to_sql})")
+ if segments.length > 1
+ klass.from_union(segments)
else
segments.first
end
end
- # rubocop: enable CodeReuse/ActiveRecord
end
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index bb401b03709..32fc8e5e9ce 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -7,13 +7,21 @@ module ApplicationHelper
# See https://docs.gitlab.com/ee/development/ee_features.html#code-in-app-views
# rubocop: disable CodeReuse/ActiveRecord
def render_if_exists(partial, locals = {})
- render(partial, locals) if lookup_context.exists?(partial, [], true)
+ render(partial, locals) if partial_exists?(partial)
+ end
+
+ def partial_exists?(partial)
+ lookup_context.exists?(partial, [], true)
+ end
+
+ def template_exists?(template)
+ lookup_context.exists?(template, [], false)
end
# rubocop: enable CodeReuse/ActiveRecord
# Check if a particular controller is the current one
#
- # args - One or more controller names to check
+ # args - One or more controller names to check (using path notation when inside namespaces)
#
# Examples
#
@@ -21,6 +29,11 @@ module ApplicationHelper
# current_controller?(:tree) # => true
# current_controller?(:commits) # => false
# current_controller?(:commits, :tree) # => true
+ #
+ # # On Admin::ApplicationController
+ # current_controller?(:application) # => true
+ # current_controller?('admin/application') # => true
+ # current_controller?('gitlab/application') # => false
def current_controller?(*args)
args.any? do |v|
v.to_s.downcase == controller.controller_name || v.to_s.downcase == controller.controller_path
diff --git a/app/helpers/application_settings_helper.rb b/app/helpers/application_settings_helper.rb
index 3ebf0162cb6..dc393968786 100644
--- a/app/helpers/application_settings_helper.rb
+++ b/app/helpers/application_settings_helper.rb
@@ -264,4 +264,8 @@ module ApplicationSettingsHelper
:web_ide_clientside_preview_enabled
]
end
+
+ def expanded_by_default?
+ Rails.env.test?
+ end
end
diff --git a/app/helpers/ci_status_helper.rb b/app/helpers/ci_status_helper.rb
index f8d36dce45d..136772e1ec3 100644
--- a/app/helpers/ci_status_helper.rb
+++ b/app/helpers/ci_status_helper.rb
@@ -123,11 +123,6 @@ module CiStatusHelper
render_status_with_link('pipeline', pipeline.status, path, tooltip_placement: tooltip_placement)
end
- def no_runners_for_project?(project)
- project.runners.blank? &&
- Ci::Runner.instance_type.blank?
- end
-
def render_status_with_link(type, status, path = nil, tooltip_placement: 'left', cssclass: '', container: 'body', icon_size: 16)
klass = "ci-status-link ci-status-icon-#{status.dasherize} #{cssclass}"
title = "#{type.titleize}: #{ci_label_for_status(status)}"
diff --git a/app/helpers/services_helper.rb b/app/helpers/services_helper.rb
index 8b554e1aaa9..d4b50b7ecfb 100644
--- a/app/helpers/services_helper.rb
+++ b/app/helpers/services_helper.rb
@@ -32,7 +32,7 @@ module ServicesHelper
end
def service_save_button(service)
- button_tag(class: 'btn btn-save', type: 'submit', disabled: service.deprecated?) do
+ button_tag(class: 'btn btn-success', type: 'submit', disabled: service.deprecated?) do
icon('spinner spin', class: 'hidden js-btn-spinner') +
content_tag(:span, 'Save changes', class: 'js-btn-label')
end
diff --git a/app/helpers/sorting_helper.rb b/app/helpers/sorting_helper.rb
index 0c59bdd6abb..53bd43d4861 100644
--- a/app/helpers/sorting_helper.rb
+++ b/app/helpers/sorting_helper.rb
@@ -35,7 +35,8 @@ module SortingHelper
sort_value_name => sort_title_name,
sort_value_oldest_activity => sort_title_oldest_activity,
sort_value_oldest_created => sort_title_oldest_created,
- sort_value_recently_created => sort_title_recently_created
+ sort_value_recently_created => sort_title_recently_created,
+ sort_value_most_stars => sort_title_most_stars
}
if current_controller?('admin/projects')
@@ -246,6 +247,10 @@ module SortingHelper
s_('SortOptions|Last Contact')
end
+ def sort_title_most_stars
+ s_('SortOptions|Most stars')
+ end
+
# Values.
def sort_value_access_level_asc
'access_level_asc'
@@ -370,4 +375,8 @@ module SortingHelper
def sort_value_contacted_date
'contacted_asc'
end
+
+ def sort_value_most_stars
+ 'stars_desc'
+ end
end
diff --git a/app/helpers/tab_helper.rb b/app/helpers/tab_helper.rb
index e310fda51d7..d91f0f78db7 100644
--- a/app/helpers/tab_helper.rb
+++ b/app/helpers/tab_helper.rb
@@ -8,7 +8,7 @@ module TabHelper
# element is the value passed to the block.
#
# options - The options hash used to determine if the element is "active" (default: {})
- # :controller - One or more controller names to check (optional).
+ # :controller - One or more controller names to check, use path notation when namespaced (optional).
# :action - One or more action names to check (optional).
# :path - A shorthand path, such as 'dashboard#index', to check (optional).
# :html_options - Extra options to be passed to the list element (optional).
@@ -42,6 +42,20 @@ module TabHelper
# nav_link(controller: :tree, html_options: {class: 'home'}) { "Hello" }
# # => '<li class="home active">Hello</li>'
#
+ # # For namespaced controllers like Admin::AppearancesController#show
+ #
+ # # Controller and namespace matches
+ # nav_link(controller: 'admin/appearances') { "Hello" }
+ # # => '<li class="active">Hello</li>'
+ #
+ # # Controller and namespace matches but action doesn't
+ # nav_link(controller: 'admin/appearances', action: :edit) { "Hello" }
+ # # => '<li>Hello</li>'
+ #
+ # # Shorthand path with namespace
+ # nav_link(path: 'admin/appearances#show') { "Hello"}
+ # # => '<li class="active">Hello</li>'
+ #
# Returns a list item element String
def nav_link(options = {}, &block)
klass = active_nav_link?(options) ? 'active' : ''
diff --git a/app/mailers/previews/notify_preview.rb b/app/mailers/previews/notify_preview.rb
index c133f4e6dbb..2f5b5483e9d 100644
--- a/app/mailers/previews/notify_preview.rb
+++ b/app/mailers/previews/notify_preview.rb
@@ -9,7 +9,7 @@ class NotifyPreview < ActionMailer::Preview
In this notification email, we expect to see:
- The note contents (that's what you're looking at)
- - A link to view this note on Gitlab
+ - A link to view this note on GitLab
- An explanation for why the user is receiving this notification
MD
@@ -26,7 +26,7 @@ class NotifyPreview < ActionMailer::Preview
- A line saying who started this discussion
- The note contents (that's what you're looking at)
- - A link to view this discussion on Gitlab
+ - A link to view this discussion on GitLab
- An explanation for why the user is receiving this notification
MD
@@ -44,7 +44,7 @@ class NotifyPreview < ActionMailer::Preview
- A line saying who started this discussion and on what file
- The diff
- The note contents (that's what you're looking at)
- - A link to view this discussion on Gitlab
+ - A link to view this discussion on GitLab
- An explanation for why the user is receiving this notification
MD
diff --git a/app/models/badge.rb b/app/models/badge.rb
index 7e3b6b659e4..f016654206b 100644
--- a/app/models/badge.rb
+++ b/app/models/badge.rb
@@ -1,6 +1,8 @@
# frozen_string_literal: true
class Badge < ActiveRecord::Base
+ include FromUnion
+
# This structure sets the placeholders that the urls
# can have. This hash also sets which action to ask when
# the placeholder is found.
diff --git a/app/models/ci/runner.rb b/app/models/ci/runner.rb
index eabb41c29d7..3e815937f4b 100644
--- a/app/models/ci/runner.rb
+++ b/app/models/ci/runner.rb
@@ -7,6 +7,7 @@ module Ci
include IgnorableColumn
include RedisCacheable
include ChronicDurationAttribute
+ include FromUnion
RUNNER_QUEUE_EXPIRY_TIME = 60.minutes
ONLINE_CONTACT_TIMEOUT = 1.hour
@@ -57,18 +58,26 @@ module Ci
}
scope :owned_or_instance_wide, -> (project_id) do
- union = Gitlab::SQL::Union.new(
- [belonging_to_project(project_id), belonging_to_parent_group_of_project(project_id), instance_type],
+ from_union(
+ [
+ belonging_to_project(project_id),
+ belonging_to_parent_group_of_project(project_id),
+ instance_type
+ ],
remove_duplicates: false
)
- from("(#{union.to_sql}) ci_runners")
end
scope :assignable_for, ->(project) do
# FIXME: That `to_sql` is needed to workaround a weird Rails bug.
# Without that, placeholders would miss one and couldn't match.
+ #
+ # We use "unscoped" here so that any current Ci::Runner filters don't
+ # apply to the inner query, which is not necessary.
+ exclude_runners = unscoped { project.runners.select(:id) }.to_sql
+
where(locked: false)
- .where.not("ci_runners.id IN (#{project.runners.select(:id).to_sql})")
+ .where.not("ci_runners.id IN (#{exclude_runners})")
.project_type
end
diff --git a/app/models/concerns/from_union.rb b/app/models/concerns/from_union.rb
new file mode 100644
index 00000000000..9b8595b1211
--- /dev/null
+++ b/app/models/concerns/from_union.rb
@@ -0,0 +1,51 @@
+# frozen_string_literal: true
+
+module FromUnion
+ extend ActiveSupport::Concern
+
+ class_methods do
+ # Produces a query that uses a FROM to select data using a UNION.
+ #
+ # Using a FROM for a UNION has in the past lead to better query plans. As
+ # such, we generally recommend this pattern instead of using a WHERE IN.
+ #
+ # Example:
+ # users = User.from_union([User.where(id: 1), User.where(id: 2)])
+ #
+ # This would produce the following SQL query:
+ #
+ # SELECT *
+ # FROM (
+ # SELECT *
+ # FROM users
+ # WHERE id = 1
+ #
+ # UNION
+ #
+ # SELECT *
+ # FROM users
+ # WHERE id = 2
+ # ) users;
+ #
+ # members - An Array of ActiveRecord::Relation objects to use in the UNION.
+ #
+ # remove_duplicates - A boolean indicating if duplicate entries should be
+ # removed. Defaults to true.
+ #
+ # alias_as - The alias to use for the sub query. Defaults to the name of the
+ # table of the current model.
+ # rubocop: disable Gitlab/Union
+ def from_union(members, remove_duplicates: true, alias_as: table_name)
+ union = Gitlab::SQL::Union
+ .new(members, remove_duplicates: remove_duplicates)
+ .to_sql
+
+ # This pattern is necessary as a bug in Rails 4 can cause the use of
+ # `from("string here").includes(:foo)` to break ActiveRecord. This is
+ # fixed in https://github.com/rails/rails/pull/25374, which is released as
+ # part of Rails 5.
+ from([Arel.sql("(#{union}) #{alias_as}")])
+ end
+ # rubocop: enable Gitlab/Union
+ end
+end
diff --git a/app/models/concerns/mentionable.rb b/app/models/concerns/mentionable.rb
index 393607e82c4..298d0d42d90 100644
--- a/app/models/concerns/mentionable.rb
+++ b/app/models/concerns/mentionable.rb
@@ -61,7 +61,7 @@ module Mentionable
cache_key: [self, attr],
author: author,
skip_project_check: skip_project_check?
- )
+ ).merge(mentionable_params)
extractor.analyze(text, options)
end
@@ -86,12 +86,11 @@ module Mentionable
return [] unless matches_cross_reference_regex?
refs = all_references(current_user)
- refs = (refs.issues + refs.merge_requests + refs.commits)
# We're using this method instead of Array diffing because that requires
# both of the object's `hash` values to be the same, which may not be the
# case for otherwise identical Commit objects.
- refs.reject { |ref| ref == local_reference }
+ extracted_mentionables(refs).reject { |ref| ref == local_reference }
end
# Uses regex to quickly determine if mentionables might be referenced
@@ -134,6 +133,10 @@ module Mentionable
private
+ def extracted_mentionables(refs)
+ refs.issues + refs.merge_requests + refs.commits
+ end
+
# Returns a Hash of changed mentionable fields
#
# Preference is given to the `changes` Hash, but falls back to
@@ -161,4 +164,8 @@ module Mentionable
def skip_project_check?
false
end
+
+ def mentionable_params
+ {}
+ end
end
diff --git a/app/models/concerns/mentionable/reference_regexes.rb b/app/models/concerns/mentionable/reference_regexes.rb
index f6fd28bac33..fe8fbb71184 100644
--- a/app/models/concerns/mentionable/reference_regexes.rb
+++ b/app/models/concerns/mentionable/reference_regexes.rb
@@ -5,13 +5,19 @@ module Mentionable
def self.reference_pattern(link_patterns, issue_pattern)
Regexp.union(link_patterns,
issue_pattern,
- Commit.reference_pattern,
- MergeRequest.reference_pattern)
+ *other_patterns)
+ end
+
+ def self.other_patterns
+ [
+ Commit.reference_pattern,
+ MergeRequest.reference_pattern
+ ]
end
DEFAULT_PATTERN = begin
issue_pattern = Issue.reference_pattern
- link_patterns = Regexp.union([Issue, Commit, MergeRequest].map(&:link_reference_pattern))
+ link_patterns = Regexp.union([Issue, Commit, MergeRequest, Epic].map(&:link_reference_pattern).compact)
reference_pattern(link_patterns, issue_pattern)
end
diff --git a/app/models/concerns/protected_ref_access.rb b/app/models/concerns/protected_ref_access.rb
index efa666fb3f2..583751ea6ac 100644
--- a/app/models/concerns/protected_ref_access.rb
+++ b/app/models/concerns/protected_ref_access.rb
@@ -3,18 +3,22 @@
module ProtectedRefAccess
extend ActiveSupport::Concern
- ALLOWED_ACCESS_LEVELS = [
- Gitlab::Access::MAINTAINER,
- Gitlab::Access::DEVELOPER,
- Gitlab::Access::NO_ACCESS
- ].freeze
-
HUMAN_ACCESS_LEVELS = {
Gitlab::Access::MAINTAINER => "Maintainers".freeze,
Gitlab::Access::DEVELOPER => "Developers + Maintainers".freeze,
Gitlab::Access::NO_ACCESS => "No one".freeze
}.freeze
+ class_methods do
+ def allowed_access_levels
+ [
+ Gitlab::Access::MAINTAINER,
+ Gitlab::Access::DEVELOPER,
+ Gitlab::Access::NO_ACCESS
+ ]
+ end
+ end
+
included do
scope :master, -> { maintainer } # @deprecated
scope :maintainer, -> { where(access_level: Gitlab::Access::MAINTAINER) }
@@ -26,7 +30,7 @@ module ProtectedRefAccess
scope :for_group, -> { where.not(group_id: nil) }
validates :access_level, presence: true, if: :role?, inclusion: {
- in: ALLOWED_ACCESS_LEVELS
+ in: self.allowed_access_levels
}
end
diff --git a/app/models/container_repository.rb b/app/models/container_repository.rb
index 93ca3a5daf4..2c08a8e1acf 100644
--- a/app/models/container_repository.rb
+++ b/app/models/container_repository.rb
@@ -8,8 +8,6 @@ class ContainerRepository < ActiveRecord::Base
delegate :client, to: :registry
- before_destroy :delete_tags!
-
# rubocop: disable CodeReuse/ServiceClass
def registry
@registry ||= begin
diff --git a/app/models/dashboard_group_milestone.rb b/app/models/dashboard_group_milestone.rb
index 067e14dda1c..32e8104125c 100644
--- a/app/models/dashboard_group_milestone.rb
+++ b/app/models/dashboard_group_milestone.rb
@@ -13,7 +13,11 @@ class DashboardGroupMilestone < GlobalMilestone
end
def self.build_collection(groups)
- MilestonesFinder.new(group_ids: groups.select(:id)).execute.map { |m| new(m) } # rubocop: disable CodeReuse/Finder
+ Milestone.of_groups(groups.select(:id))
+ .reorder_by_due_date_asc
+ .order_by_name_asc
+ .active
+ .map { |m| new(m) }
end
override :group_milestone?
diff --git a/app/models/deploy_key.rb b/app/models/deploy_key.rb
index fd5d7726fb6..db501b4b506 100644
--- a/app/models/deploy_key.rb
+++ b/app/models/deploy_key.rb
@@ -18,7 +18,7 @@ class DeployKey < Key
end
def orphaned?
- self.deploy_keys_projects.length == 0
+ self.deploy_keys_projects.empty?
end
def almost_orphaned?
diff --git a/app/models/diff_note.rb b/app/models/diff_note.rb
index 716cf6574d3..047d353b4b5 100644
--- a/app/models/diff_note.rb
+++ b/app/models/diff_note.rb
@@ -131,7 +131,7 @@ class DiffNote < Note
# As an extra benefit, the returned `diff_file` already
# has `highlighted_diff_lines` data set from Redis on
# `Diff::FileCollection::MergeRequestDiff`.
- noteable.diffs(paths: original_position.paths, expanded: true).diff_files.first
+ noteable.diffs(original_position.diff_options).diff_files.first
else
original_position.diff_file(self.project.repository)
end
diff --git a/app/models/epic.rb b/app/models/epic.rb
index f027993376c..ccd10593434 100644
--- a/app/models/epic.rb
+++ b/app/models/epic.rb
@@ -3,6 +3,10 @@
# Placeholder class for model that is implemented in EE
# It reserves '&' as a reference prefix, but the table does not exists in CE
class Epic < ActiveRecord::Base
+ def self.link_reference_pattern
+ nil
+ end
+
def self.reference_prefix
'&'
end
diff --git a/app/models/event.rb b/app/models/event.rb
index 041dac6941b..596155a9525 100644
--- a/app/models/event.rb
+++ b/app/models/event.rb
@@ -3,6 +3,7 @@
class Event < ActiveRecord::Base
include Sortable
include IgnorableColumn
+ include FromUnion
default_scope { reorder(nil) }
CREATED = 1
diff --git a/app/models/group.rb b/app/models/group.rb
index 024e77188b8..62af20d2142 100644
--- a/app/models/group.rb
+++ b/app/models/group.rb
@@ -304,14 +304,12 @@ class Group < Namespace
# 3. They belong to a sub-group or project in such sub-group
# 4. They belong to an ancestor group
def direct_and_indirect_users
- union = Gitlab::SQL::Union.new([
+ User.from_union([
User
.where(id: direct_and_indirect_members.select(:user_id))
.reorder(nil),
project_users_with_descendants
])
-
- User.from("(#{union.to_sql}) #{User.table_name}")
end
# Returns all users that are members of projects
diff --git a/app/models/label.rb b/app/models/label.rb
index 8dc7ded53ad..9ef57a05b3e 100644
--- a/app/models/label.rb
+++ b/app/models/label.rb
@@ -7,6 +7,7 @@ class Label < ActiveRecord::Base
include Gitlab::SQL::Pattern
include OptionallySearch
include Sortable
+ include FromUnion
# Represents a "No Label" state used for filtering Issues and Merge
# Requests that have no label assigned.
diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb
index e19bf62dcd0..dd5d494997d 100644
--- a/app/models/merge_request.rb
+++ b/app/models/merge_request.rb
@@ -14,6 +14,7 @@ class MergeRequest < ActiveRecord::Base
include Gitlab::Utils::StrongMemoize
include LabelEventable
include ReactiveCaching
+ include FromUnion
self.reactive_cache_key = ->(model) { [model.project.id, model.iid] }
self.reactive_cache_refresh_interval = 10.minutes
@@ -237,11 +238,10 @@ class MergeRequest < ActiveRecord::Base
def self.in_projects(relation)
# unscoping unnecessary conditions that'll be applied
# when executing `where("merge_requests.id IN (#{union.to_sql})")`
- source = unscoped.where(source_project_id: relation).select(:id)
- target = unscoped.where(target_project_id: relation).select(:id)
- union = Gitlab::SQL::Union.new([source, target])
+ source = unscoped.where(source_project_id: relation)
+ target = unscoped.where(target_project_id: relation)
- where("merge_requests.id IN (#{union.to_sql})") # rubocop:disable GitlabSecurity/SqlInjection
+ from_union([source, target])
end
# This is used after project import, to reset the IDs to the correct
@@ -740,11 +740,8 @@ class MergeRequest < ActiveRecord::Base
# compared to using OR statements. We're using UNION ALL since the queries
# used won't produce any duplicates (e.g. a note for a commit can't also be
# a note for an MR).
- union = Gitlab::SQL::Union
- .new([notes, commit_notes], remove_duplicates: false)
- .to_sql
-
- Note.from("(#{union}) #{Note.table_name}")
+ Note
+ .from_union([notes, commit_notes], remove_duplicates: false)
.includes(:noteable)
end
diff --git a/app/models/milestone.rb b/app/models/milestone.rb
index cb1def1b422..892a680f221 100644
--- a/app/models/milestone.rb
+++ b/app/models/milestone.rb
@@ -46,6 +46,9 @@ class Milestone < ActiveRecord::Base
where(conditions.reduce(:or))
end
+ scope :order_by_name_asc, -> { order(Arel::Nodes::Ascending.new(arel_table[:title].lower)) }
+ scope :reorder_by_due_date_asc, -> { reorder(Gitlab::Database.nulls_last_order('due_date', 'ASC')) }
+
validates :group, presence: true, unless: :project
validates :project, presence: true, unless: :group
@@ -149,7 +152,7 @@ class Milestone < ActiveRecord::Base
sorted =
case method.to_s
when 'due_date_asc'
- reorder(Gitlab::Database.nulls_last_order('due_date', 'ASC'))
+ reorder_by_due_date_asc
when 'due_date_desc'
reorder(Gitlab::Database.nulls_last_order('due_date', 'DESC'))
when 'name_asc'
diff --git a/app/models/namespace.rb b/app/models/namespace.rb
index 76920c3c039..0289f29211d 100644
--- a/app/models/namespace.rb
+++ b/app/models/namespace.rb
@@ -11,6 +11,7 @@ class Namespace < ActiveRecord::Base
include Gitlab::SQL::Pattern
include IgnorableColumn
include FeatureGate
+ include FromUnion
ignore_column :deleted_at
diff --git a/app/models/network/commit.rb b/app/models/network/commit.rb
index 6c5a4c56377..1b2369aab18 100644
--- a/app/models/network/commit.rb
+++ b/app/models/network/commit.rb
@@ -18,7 +18,7 @@ module Network
end
def space
- if @spaces.size > 0
+ if @spaces.present?
@spaces.first
else
0
diff --git a/app/models/network/graph.rb b/app/models/network/graph.rb
index 1431dfefc55..6da3bb7bfb7 100644
--- a/app/models/network/graph.rb
+++ b/app/models/network/graph.rb
@@ -81,7 +81,7 @@ module Network
skip = 0
while offset == -1
tmp_commits = find_commits(skip)
- if tmp_commits.size > 0
+ if tmp_commits.present?
index = tmp_commits.index do |c|
c.id == @commit.id
end
@@ -218,7 +218,7 @@ module Network
def get_space_base(leaves)
space_base = 1
parents = leaves.last.parents(@map)
- if parents.size > 0
+ if parents.present?
if parents.first.space > 0
space_base = parents.first.space
end
diff --git a/app/models/note.rb b/app/models/note.rb
index 4429c1dcb07..bea02d69b65 100644
--- a/app/models/note.rb
+++ b/app/models/note.rb
@@ -17,6 +17,7 @@ class Note < ActiveRecord::Base
include Editable
include Gitlab::SQL::Pattern
include ThrottledTouch
+ include FromUnion
module SpecialRole
FIRST_TIME_CONTRIBUTOR = :first_time_contributor
diff --git a/app/models/project.rb b/app/models/project.rb
index c37915e111f..0a5099b27b1 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -29,6 +29,7 @@ class Project < ActiveRecord::Base
include BatchDestroyDependentAssociations
include FeatureGate
include OptionallySearch
+ include FromUnion
extend Gitlab::Cache::RequestCache
extend Gitlab::ConfigHelper
@@ -330,7 +331,7 @@ class Project < ActiveRecord::Base
# last_activity_at is throttled every minute, but last_repository_updated_at is updated with every push
scope :sorted_by_activity, -> { reorder("GREATEST(COALESCE(last_activity_at, '1970-01-01'), COALESCE(last_repository_updated_at, '1970-01-01')) DESC") }
- scope :sorted_by_stars, -> { reorder('projects.star_count DESC') }
+ scope :sorted_by_stars, -> { reorder(star_count: :desc) }
scope :in_namespace, ->(namespace_ids) { where(namespace_id: namespace_ids) }
scope :personal, ->(user) { where(namespace_id: user.namespace_id) }
@@ -480,6 +481,8 @@ class Project < ActiveRecord::Base
reorder(last_activity_at: :desc)
when 'latest_activity_asc'
reorder(last_activity_at: :asc)
+ when 'stars_desc'
+ sorted_by_stars
else
order_by(method)
end
@@ -1493,8 +1496,7 @@ class Project < ActiveRecord::Base
end
def all_runners
- union = Gitlab::SQL::Union.new([runners, group_runners, shared_runners])
- Ci::Runner.from("(#{union.to_sql}) ci_runners")
+ Ci::Runner.from_union([runners, group_runners, shared_runners])
end
def active_runners
@@ -2022,12 +2024,10 @@ class Project < ActiveRecord::Base
def badges
return project_badges unless group
- group_badges_rel = GroupBadge.where(group: group.self_and_ancestors)
-
- union = Gitlab::SQL::Union.new([project_badges.select(:id),
- group_badges_rel.select(:id)])
-
- Badge.where("id IN (#{union.to_sql})") # rubocop:disable GitlabSecurity/SqlInjection
+ Badge.from_union([
+ project_badges,
+ GroupBadge.where(group: group.self_and_ancestors)
+ ])
end
def merge_requests_allowing_push_to_user(user)
@@ -2078,12 +2078,6 @@ class Project < ActiveRecord::Base
auto_cancel_pending_pipelines == 'enabled'
end
- # Update the default branch querying the remote to determine its HEAD
- def update_root_ref(remote_name)
- root_ref = repository.find_remote_root_ref(remote_name)
- change_head(root_ref) if root_ref.present? && root_ref != default_branch
- end
-
private
# rubocop: disable CodeReuse/ServiceClass
diff --git a/app/models/project_authorization.rb b/app/models/project_authorization.rb
index 746bb4584c9..2c590008db2 100644
--- a/app/models/project_authorization.rb
+++ b/app/models/project_authorization.rb
@@ -1,6 +1,8 @@
# frozen_string_literal: true
class ProjectAuthorization < ActiveRecord::Base
+ include FromUnion
+
belongs_to :user
belongs_to :project
@@ -8,9 +10,9 @@ class ProjectAuthorization < ActiveRecord::Base
validates :access_level, inclusion: { in: Gitlab::Access.all_values }, presence: true
validates :user, uniqueness: { scope: [:project, :access_level] }, presence: true
- def self.select_from_union(union)
- select(['project_id', 'MAX(access_level) AS access_level'])
- .from("(#{union.to_sql}) #{ProjectAuthorization.table_name}")
+ def self.select_from_union(relations)
+ from_union(relations)
+ .select(['project_id', 'MAX(access_level) AS access_level'])
.group(:project_id)
end
diff --git a/app/models/project_services/asana_service.rb b/app/models/project_services/asana_service.rb
index 568f870c2db..cc5f1207653 100644
--- a/app/models/project_services/asana_service.rb
+++ b/app/models/project_services/asana_service.rb
@@ -65,7 +65,7 @@ http://app.asana.com/-/account_api'
# check the branch restriction is poplulated and branch is not included
branch = Gitlab::Git.ref_name(data[:ref])
branch_restriction = restrict_to_branch.to_s
- if branch_restriction.length > 0 && branch_restriction.index(branch).nil?
+ if branch_restriction.present? && branch_restriction.index(branch).nil?
return
end
diff --git a/app/models/project_services/chat_message/merge_message.rb b/app/models/project_services/chat_message/merge_message.rb
index cc88d57faf8..6b7a35aaa75 100644
--- a/app/models/project_services/chat_message/merge_message.rb
+++ b/app/models/project_services/chat_message/merge_message.rb
@@ -26,7 +26,7 @@ module ChatMessage
def activity
{
- title: "Merge Request #{state} by #{user_combined_name}",
+ title: "Merge Request #{state_or_action_text} by #{user_combined_name}",
subtitle: "in #{project_link}",
text: merge_request_link,
image: user_avatar
diff --git a/app/models/project_wiki.rb b/app/models/project_wiki.rb
index f4b3421f04b..559e4f99294 100644
--- a/app/models/project_wiki.rb
+++ b/app/models/project_wiki.rb
@@ -80,7 +80,7 @@ class ProjectWiki
pages(limit: 1).empty?
end
- # Returns an Array of Gitlab WikiPage instances or an
+ # Returns an Array of GitLab WikiPage instances or an
# empty Array if this Wiki has no pages.
def pages(limit: 0)
wiki.pages(limit: limit).map { |page| WikiPage.new(self, page, true) }
@@ -184,11 +184,12 @@ class ProjectWiki
def commit_details(action, message = nil, title = nil)
commit_message = message || default_message(action, title)
+ git_user = Gitlab::Git::User.from_gitlab(@user)
Gitlab::Git::Wiki::CommitDetails.new(@user.id,
- @user.username,
- @user.name,
- @user.email,
+ git_user.username,
+ git_user.name,
+ git_user.email,
commit_message)
end
diff --git a/app/models/repository.rb b/app/models/repository.rb
index ad65881ff43..12fbf7d5d1d 100644
--- a/app/models/repository.rb
+++ b/app/models/repository.rb
@@ -24,7 +24,6 @@ class Repository
delegate :ref_name_for_sha, to: :raw_repository
delegate :bundle_to_disk, to: :raw_repository
- delegate :find_remote_root_ref, to: :raw_repository
CreateTreeError = Class.new(StandardError)
diff --git a/app/models/snippet.rb b/app/models/snippet.rb
index 5b394e3fa79..e9533ee7c77 100644
--- a/app/models/snippet.rb
+++ b/app/models/snippet.rb
@@ -12,6 +12,7 @@ class Snippet < ActiveRecord::Base
include Spammable
include Editable
include Gitlab::SQL::Pattern
+ include FromUnion
cache_markdown_field :title, pipeline: :single_line
cache_markdown_field :description
diff --git a/app/models/todo.rb b/app/models/todo.rb
index 48d92ad04b3..265fb932f7c 100644
--- a/app/models/todo.rb
+++ b/app/models/todo.rb
@@ -2,6 +2,7 @@
class Todo < ActiveRecord::Base
include Sortable
+ include FromUnion
ASSIGNED = 1
MENTIONED = 2
diff --git a/app/models/user.rb b/app/models/user.rb
index d68108a8e8e..eeac87e2e52 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -20,6 +20,7 @@ class User < ActiveRecord::Base
include BlocksJsonSerialization
include WithUploads
include OptionallySearch
+ include FromUnion
DEFAULT_NOTIFICATION_LEVEL = :participating
@@ -286,11 +287,9 @@ class User < ActiveRecord::Base
# user_id - The ID of the user to include.
def self.union_with_user(user_id = nil)
if user_id.present?
- union = Gitlab::SQL::Union.new([all, User.unscoped.where(id: user_id)])
-
# We use "unscoped" here so that any inner conditions are not repeated for
# the outer query, which would be redundant.
- User.unscoped.from("(#{union.to_sql}) #{User.table_name}")
+ User.unscoped.from_union([all, User.unscoped.where(id: user_id)])
else
all
end
@@ -354,9 +353,8 @@ class User < ActiveRecord::Base
emails = joins(:emails).where(emails: { email: email })
emails = emails.confirmed if confirmed
- union = Gitlab::SQL::Union.new([users, emails])
- from("(#{union.to_sql}) #{table_name}")
+ from_union([users, emails])
end
def filter(filter_name)
@@ -635,7 +633,7 @@ class User < ActiveRecord::Base
# possibility of the commit_email column not existing.
def commit_email
- return unless has_attribute?(:commit_email)
+ return self.email unless has_attribute?(:commit_email)
# The commit email is the same as the primary email if undefined
super.presence || self.email
@@ -676,10 +674,10 @@ class User < ActiveRecord::Base
# Returns the groups a user has access to, either through a membership or a project authorization
def authorized_groups
- union = Gitlab::SQL::Union
- .new([groups.select(:id), authorized_projects.select(:namespace_id)])
-
- Group.where("namespaces.id IN (#{union.to_sql})") # rubocop:disable GitlabSecurity/SqlInjection
+ Group.from_union([
+ groups,
+ authorized_projects.joins(:namespace).select('namespaces.*')
+ ])
end
# Returns the groups a user is a member of, either directly or through a parent group
@@ -744,7 +742,15 @@ class User < ActiveRecord::Base
end
def owned_projects
- @owned_projects ||= Project.from("(#{owned_projects_union.to_sql}) AS projects")
+ @owned_projects ||= Project.from_union(
+ [
+ Project.where(namespace: namespace),
+ Project.joins(:project_authorizations)
+ .where("projects.namespace_id <> ?", namespace.id)
+ .where(project_authorizations: { user_id: id, access_level: Gitlab::Access::OWNER })
+ ],
+ remove_duplicates: false
+ )
end
# Returns projects which user can admin issues on (for example to move an issue to that project).
@@ -1138,17 +1144,17 @@ class User < ActiveRecord::Base
def ci_owned_runners
@ci_owned_runners ||= begin
- project_runner_ids = Ci::RunnerProject
+ project_runners = Ci::RunnerProject
.where(project: authorized_projects(Gitlab::Access::MAINTAINER))
- .select(:runner_id)
+ .joins(:runner)
+ .select('ci_runners.*')
- group_runner_ids = Ci::RunnerNamespace
+ group_runners = Ci::RunnerNamespace
.where(namespace_id: owned_or_maintainers_groups.select(:id))
- .select(:runner_id)
+ .joins(:runner)
+ .select('ci_runners.*')
- union = Gitlab::SQL::Union.new([project_runner_ids, group_runner_ids])
-
- Ci::Runner.where("ci_runners.id IN (#{union.to_sql})") # rubocop:disable GitlabSecurity/SqlInjection
+ Ci::Runner.from_union([project_runners, group_runners])
end
end
@@ -1176,13 +1182,13 @@ class User < ActiveRecord::Base
def assigned_open_merge_requests_count(force: false)
Rails.cache.fetch(['users', id, 'assigned_open_merge_requests_count'], force: force, expires_in: 20.minutes) do
- MergeRequestsFinder.new(self, assignee_id: self.id, state: 'opened').execute.count
+ MergeRequestsFinder.new(self, assignee_id: self.id, state: 'opened', non_archived: true).execute.count
end
end
def assigned_open_issues_count(force: false)
Rails.cache.fetch(['users', id, 'assigned_open_issues_count'], force: force, expires_in: 20.minutes) do
- IssuesFinder.new(self, assignee_id: self.id, state: 'opened').execute.count
+ IssuesFinder.new(self, assignee_id: self.id, state: 'opened', non_archived: true).execute.count
end
end
@@ -1380,15 +1386,6 @@ class User < ActiveRecord::Base
Gitlab::CurrentSettings.usage_stats_set_by_user_id == self.id
end
- def owned_projects_union
- Gitlab::SQL::Union.new([
- Project.where(namespace: namespace),
- Project.joins(:project_authorizations)
- .where("projects.namespace_id <> ?", namespace.id)
- .where(project_authorizations: { user_id: id, access_level: Gitlab::Access::OWNER })
- ], remove_duplicates: false)
- end
-
# Added according to https://github.com/plataformatec/devise/blob/7df57d5081f9884849ca15e4fde179ef164a575f/README.md#activejob-integration
def send_devise_notification(notification, *args)
return true unless can?(:receive_notifications)
diff --git a/app/models/wiki_page.rb b/app/models/wiki_page.rb
index 33790afc35e..102907a8bd3 100644
--- a/app/models/wiki_page.rb
+++ b/app/models/wiki_page.rb
@@ -51,7 +51,7 @@ class WikiPage
validates :title, presence: true
validates :content, presence: true
- # The Gitlab ProjectWiki instance.
+ # The GitLab ProjectWiki instance.
attr_reader :wiki
# The raw Gitlab::Git::WikiPage instance.
@@ -127,7 +127,7 @@ class WikiPage
version.try(:message)
end
- # The Gitlab Commit instance for this page.
+ # The GitLab Commit instance for this page.
def version
return nil unless persisted?
diff --git a/app/serializers/build_details_entity.rb b/app/serializers/build_details_entity.rb
index ab9861c58c4..00a441a9a1e 100644
--- a/app/serializers/build_details_entity.rb
+++ b/app/serializers/build_details_entity.rb
@@ -79,6 +79,20 @@ class BuildDetailsEntity < JobEntity
expose :trigger_variables, as: :variables, using: TriggerVariableEntity
end
+ expose :runners do
+ expose :online do |build|
+ build.any_runners_online?
+ end
+
+ expose :available do |build|
+ project.any_runners?
+ end
+
+ expose :settings_path, if: -> (*) { can_admin_build? } do |build|
+ project_runners_path(project)
+ end
+ end
+
private
def build_failed_issue_options
@@ -97,4 +111,8 @@ class BuildDetailsEntity < JobEntity
def can_create_build_terminal?
can?(current_user, :create_build_terminal, build) && build.has_terminal?
end
+
+ def can_admin_build?
+ can?(request.current_user, :admin_build, project)
+ end
end
diff --git a/app/services/boards/create_service.rb b/app/services/boards/create_service.rb
index 4caf5ffa3cb..1b796cef3e2 100644
--- a/app/services/boards/create_service.rb
+++ b/app/services/boards/create_service.rb
@@ -9,7 +9,7 @@ module Boards
private
def can_create_board?
- parent.boards.size == 0
+ parent.boards.empty?
end
def create_board!
diff --git a/app/services/boards/issues/list_service.rb b/app/services/boards/issues/list_service.rb
index 4e352f2dc63..0b69661bbd0 100644
--- a/app/services/boards/issues/list_service.rb
+++ b/app/services/boards/issues/list_service.rb
@@ -56,6 +56,7 @@ module Boards
set_parent
set_state
set_scope
+ set_non_archived
params
end
@@ -76,6 +77,10 @@ module Boards
params[:include_subgroups] = board.group_board?
end
+ def set_non_archived
+ params[:non_archived] = parent.is_a?(Group)
+ end
+
# rubocop: disable CodeReuse/ActiveRecord
def board_label_ids
@board_label_ids ||= board.lists.movable.pluck(:label_id)
diff --git a/app/services/files/base_service.rb b/app/services/files/base_service.rb
index fc7b236f7da..39e614d6569 100644
--- a/app/services/files/base_service.rb
+++ b/app/services/files/base_service.rb
@@ -7,8 +7,10 @@ module Files
def initialize(*args)
super
- @author_email = params[:author_email] || current_user&.email
- @author_name = params[:author_name] || current_user&.name
+ git_user = Gitlab::Git::User.from_gitlab(current_user) if current_user.present?
+
+ @author_email = params[:author_email] || git_user&.email
+ @author_name = params[:author_name] || git_user&.name
@commit_message = params[:commit_message]
@last_commit_sha = params[:last_commit_sha]
diff --git a/app/services/labels/transfer_service.rb b/app/services/labels/transfer_service.rb
index aec0282b31b..52360f775dc 100644
--- a/app/services/labels/transfer_service.rb
+++ b/app/services/labels/transfer_service.rb
@@ -34,13 +34,13 @@ module Labels
# rubocop: disable CodeReuse/ActiveRecord
def labels_to_transfer
- label_ids = []
- label_ids << group_labels_applied_to_issues.select(:id)
- label_ids << group_labels_applied_to_merge_requests.select(:id)
-
- union = Gitlab::SQL::Union.new(label_ids)
-
- Label.where("labels.id IN (#{union.to_sql})").reorder(nil).uniq # rubocop:disable GitlabSecurity/SqlInjection
+ Label
+ .from_union([
+ group_labels_applied_to_issues,
+ group_labels_applied_to_merge_requests
+ ])
+ .reorder(nil)
+ .uniq
end
# rubocop: enable CodeReuse/ActiveRecord
diff --git a/app/services/merge_requests/reload_diffs_service.rb b/app/services/merge_requests/reload_diffs_service.rb
index c350b14d12b..b4d48fe92ad 100644
--- a/app/services/merge_requests/reload_diffs_service.rb
+++ b/app/services/merge_requests/reload_diffs_service.rb
@@ -31,7 +31,7 @@ module MergeRequests
def clear_cache(new_diff)
# Executing the iteration we cache highlighted diffs for each diff file of
# MergeRequestDiff.
- new_diff.diffs_collection.write_cache
+ cacheable_collection(new_diff).write_cache
# Remove cache for all diffs on this MR. Do not use the association on the
# model, as that will interfere with other actions happening when
@@ -39,9 +39,15 @@ module MergeRequests
MergeRequestDiff.where(merge_request: merge_request).each do |merge_request_diff|
next if merge_request_diff == new_diff
- merge_request_diff.diffs_collection.clear_cache
+ cacheable_collection(merge_request_diff).clear_cache
end
end
# rubocop: enable CodeReuse/ActiveRecord
+
+ def cacheable_collection(diff)
+ # There are scenarios where we don't need to request Diff Stats.
+ # Mainly when clearing / writing diff caches.
+ diff.diffs(include_stats: false)
+ end
end
end
diff --git a/app/services/notes/build_service.rb b/app/services/notes/build_service.rb
index df5fe65de3c..7b92fe6fe14 100644
--- a/app/services/notes/build_service.rb
+++ b/app/services/notes/build_service.rb
@@ -3,6 +3,7 @@
module Notes
class BuildService < ::BaseService
def execute
+ should_resolve = false
in_reply_to_discussion_id = params.delete(:in_reply_to_discussion_id)
if in_reply_to_discussion_id.present?
@@ -15,12 +16,17 @@ module Notes
end
params.merge!(discussion.reply_attributes)
+ should_resolve = discussion.resolved?
end
note = Note.new(params)
note.project = project
note.author = current_user
+ if should_resolve
+ note.resolve_without_save(current_user)
+ end
+
note
end
diff --git a/app/services/projects/container_repository/destroy_service.rb b/app/services/projects/container_repository/destroy_service.rb
index a8e7eab6068..1f5af7970d6 100644
--- a/app/services/projects/container_repository/destroy_service.rb
+++ b/app/services/projects/container_repository/destroy_service.rb
@@ -6,6 +6,8 @@ module Projects
def execute(container_repository)
return false unless can?(current_user, :update_container_image, project)
+ # Delete tags outside of the transaction to avoid hitting an idle-in-transaction timeout
+ container_repository.delete_tags!
container_repository.destroy
end
end
diff --git a/app/services/projects/destroy_service.rb b/app/services/projects/destroy_service.rb
index 5090ebf8f51..210571b6b4e 100644
--- a/app/services/projects/destroy_service.rb
+++ b/app/services/projects/destroy_service.rb
@@ -133,11 +133,11 @@ module Projects
end
def attempt_destroy_transaction(project)
- Project.transaction do
- unless remove_legacy_registry_tags
- raise_error('Failed to remove some tags in project container registry. Please try again or contact administrator.')
- end
+ unless remove_registry_tags
+ raise_error('Failed to remove some tags in project container registry. Please try again or contact administrator.')
+ end
+ Project.transaction do
log_destroy_event
trash_repositories!
@@ -156,6 +156,17 @@ module Projects
log_info("Attempting to destroy #{project.full_path} (#{project.id})")
end
+ def remove_registry_tags
+ return false unless remove_legacy_registry_tags
+
+ project.container_repositories.find_each do |container_repository|
+ service = Projects::ContainerRepository::DestroyService.new(project, current_user)
+ service.execute(container_repository)
+ end
+
+ true
+ end
+
##
# This method makes sure that we correctly remove registry tags
# for legacy image repository (when repository path equals project path).
diff --git a/app/services/projects/update_remote_mirror_service.rb b/app/services/projects/update_remote_mirror_service.rb
index 85b9eb02803..9d0877d1ab2 100644
--- a/app/services/projects/update_remote_mirror_service.rb
+++ b/app/services/projects/update_remote_mirror_service.rb
@@ -12,7 +12,6 @@ module Projects
begin
remote_mirror.ensure_remote!
repository.fetch_remote(remote_mirror.remote_name, no_tags: true)
- project.update_root_ref(remote_mirror.remote_name)
opts = {}
if remote_mirror.only_protected_branches?
diff --git a/app/validators/url_validator.rb b/app/validators/url_validator.rb
index faaf1283078..216acf79cbd 100644
--- a/app/validators/url_validator.rb
+++ b/app/validators/url_validator.rb
@@ -41,12 +41,13 @@ class UrlValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
@record = record
- if value.present?
- value.strip!
- else
+ unless value.present?
record.errors.add(attribute, 'must be a valid URL')
+ return
end
+ value = strip_value!(record, attribute, value)
+
Gitlab::UrlBlocker.validate!(value, blocker_args)
rescue Gitlab::UrlBlocker::BlockedUrlError => e
record.errors.add(attribute, "is blocked: #{e.message}")
@@ -54,6 +55,13 @@ class UrlValidator < ActiveModel::EachValidator
private
+ def strip_value!(record, attribute, value)
+ new_value = value.strip
+ return value if new_value == value
+
+ record.public_send("#{attribute}=", new_value) # rubocop:disable GitlabSecurity/PublicSend
+ end
+
def default_options
# By default the validator doesn't block any url based on the ip address
{
diff --git a/app/views/abuse_reports/new.html.haml b/app/views/abuse_reports/new.html.haml
index 278ad210543..391115a67b5 100644
--- a/app/views/abuse_reports/new.html.haml
+++ b/app/views/abuse_reports/new.html.haml
@@ -19,4 +19,4 @@
Explain the problem with this user. If appropriate, provide a link to the relevant issue or comment.
.form-actions
- = f.submit "Send report", class: "btn btn-create"
+ = f.submit "Send report", class: "btn btn-success"
diff --git a/app/views/admin/appearances/_form.html.haml b/app/views/admin/appearances/_form.html.haml
index a0861870ba4..cb67079853e 100644
--- a/app/views/admin/appearances/_form.html.haml
+++ b/app/views/admin/appearances/_form.html.haml
@@ -5,7 +5,7 @@
%legend
Navigation bar:
.form-group.row
- = f.label :header_logo, 'Header logo', class: 'col-sm-2 col-form-label'
+ = f.label :header_logo, 'Header logo', class: 'col-sm-2 col-form-label pt-0'
.col-sm-10
- if @appearance.header_logo?
= image_tag @appearance.header_logo_url, class: 'appearance-light-logo-preview'
@@ -22,7 +22,7 @@
%legend
Favicon:
.form-group.row
- = f.label :favicon, 'Favicon', class: 'col-sm-2 col-form-label'
+ = f.label :favicon, 'Favicon', class: 'col-sm-2 col-form-label pt-0'
.col-sm-10
- if @appearance.favicon?
= image_tag @appearance.favicon_url, class: 'appearance-light-logo-preview'
@@ -51,7 +51,7 @@
.hint
Description parsed with #{link_to "GitLab Flavored Markdown", help_page_path('user/markdown'), target: '_blank'}.
.form-group.row
- = f.label :logo, class: 'col-sm-2 col-form-label'
+ = f.label :logo, class: 'col-sm-2 col-form-label pt-0'
.col-sm-10
- if @appearance.logo?
= image_tag @appearance.logo_url, class: 'appearance-logo-preview'
@@ -75,7 +75,7 @@
Guidelines parsed with #{link_to "GitLab Flavored Markdown", help_page_path('user/markdown'), target: '_blank'}.
.form-actions
- = f.submit 'Save', class: 'btn btn-save append-right-10'
+ = f.submit 'Save', class: 'btn btn-success append-right-10'
- if @appearance.persisted?
Preview last save:
= link_to 'Sign-in page', preview_sign_in_admin_appearances_path, class: 'btn', target: '_blank', rel: 'noopener noreferrer'
diff --git a/app/views/admin/appearances/preview_sign_in.html.haml b/app/views/admin/appearances/preview_sign_in.html.haml
index 1af7dd5bb67..2cd95071c73 100644
--- a/app/views/admin/appearances/preview_sign_in.html.haml
+++ b/app/views/admin/appearances/preview_sign_in.html.haml
@@ -8,5 +8,5 @@
= label_tag :password
= password_field_tag :password, nil, class: "form-control bottom", title: 'This field is required.'
.form-group
- = button_tag "Sign in", class: "btn-create btn"
+ = button_tag "Sign in", class: "btn-success btn"
diff --git a/app/views/admin/application_settings/ci_cd.html.haml b/app/views/admin/application_settings/ci_cd.html.haml
new file mode 100644
index 00000000000..db24c9982f7
--- /dev/null
+++ b/app/views/admin/application_settings/ci_cd.html.haml
@@ -0,0 +1,26 @@
+- breadcrumb_title _("CI/CD")
+- page_title _("CI/CD")
+- @content_class = "limit-container-width" unless fluid_layout
+
+%section.settings.as-ci-cd.no-animate#js-ci-cd-settings{ class: ('expanded' if expanded_by_default?) }
+ .settings-header
+ %h4
+ = _('Continuous Integration and Deployment')
+ %button.btn.btn-default.js-settings-toggle{ type: 'button' }
+ = expanded_by_default? ? _('Collapse') : _('Expand')
+ %p
+ = _('Auto DevOps, runners and job artifacts')
+ .settings-content
+ = render 'ci_cd'
+
+- if Gitlab.config.registry.enabled
+ %section.settings.as-registry.no-animate#js-registry-settings{ class: ('expanded' if expanded_by_default?) }
+ .settings-header
+ %h4
+ = _('Container Registry')
+ %button.btn.btn-default.js-settings-toggle{ type: 'button' }
+ = expanded_by_default? ? _('Collapse') : _('Expand')
+ %p
+ = _('Various container registry settings.')
+ .settings-content
+ = render 'registry'
diff --git a/app/views/admin/application_settings/integrations.html.haml b/app/views/admin/application_settings/integrations.html.haml
new file mode 100644
index 00000000000..310e86b1377
--- /dev/null
+++ b/app/views/admin/application_settings/integrations.html.haml
@@ -0,0 +1,31 @@
+- breadcrumb_title _("Integrations")
+- page_title _("Integrations")
+- @content_class = "limit-container-width" unless fluid_layout
+
+= render_if_exists 'admin/application_settings/elasticsearch_form', expanded: expanded_by_default?
+
+%section.settings.as-plantuml.no-animate#js-plantuml-settings{ class: ('expanded' if expanded_by_default?) }
+ .settings-header
+ %h4
+ = _('PlantUML')
+ %button.btn.btn-default.js-settings-toggle{ type: 'button' }
+ = expanded_by_default? ? _('Collapse') : _('Expand')
+ %p
+ = _('Allow rendering of PlantUML diagrams in Asciidoc documents.')
+ .settings-content
+ = render 'plantuml'
+
+= render_if_exists 'admin/application_settings/slack', expanded: expanded_by_default?
+
+%section.settings.as-third-party-offers.no-animate#js-third-party-offers-settings{ class: ('expanded' if expanded_by_default?) }
+ .settings-header
+ %h4
+ = _('Third party offers')
+ %button.btn.btn-default.js-settings-toggle{ type: 'button' }
+ = expanded_by_default? ? _('Collapse') : _('Expand')
+ %p
+ = _('Control the display of third party offers.')
+ .settings-content
+ = render 'third_party_offers', application_setting: @application_setting
+
+= render_if_exists 'admin/application_settings/snowplow', expanded: expanded_by_default?
diff --git a/app/views/admin/application_settings/metrics_and_profiling.html.haml b/app/views/admin/application_settings/metrics_and_profiling.html.haml
new file mode 100644
index 00000000000..f50aca32bdf
--- /dev/null
+++ b/app/views/admin/application_settings/metrics_and_profiling.html.haml
@@ -0,0 +1,50 @@
+- breadcrumb_title _("Metrics and profiling")
+- page_title _("Metrics and profiling")
+- @content_class = "limit-container-width" unless fluid_layout
+
+%section.settings.as-influx.no-animate#js-influx-settings{ class: ('expanded' if expanded_by_default?) }
+ .settings-header
+ %h4
+ = _('Metrics - Influx')
+ %button.btn.btn-default.js-settings-toggle{ type: 'button' }
+ = expanded_by_default? ? _('Collapse') : _('Expand')
+ %p
+ = _('Enable and configure InfluxDB metrics.')
+ .settings-content
+ = render 'influx'
+
+%section.settings.as-prometheus.no-animate#js-prometheus-settings{ class: ('expanded' if expanded_by_default?) }
+ .settings-header
+ %h4
+ = _('Metrics - Prometheus')
+ %button.btn.btn-default.js-settings-toggle{ type: 'button' }
+ = expanded_by_default? ? _('Collapse') : _('Expand')
+ %p
+ = _('Enable and configure Prometheus metrics.')
+ .settings-content
+ = render 'prometheus'
+
+%section.settings.as-performance-bar.no-animate#js-performance-bar-settings{ class: ('expanded' if expanded_by_default?) }
+ .settings-header
+ %h4
+ = _('Profiling - Performance bar')
+ %button.btn.btn-default.js-settings-toggle{ type: 'button' }
+ = expanded_by_default? ? _('Collapse') : _('Expand')
+ %p
+ = _('Enable the Performance Bar for a given group.')
+ = link_to icon('question-circle'), help_page_path('administration/monitoring/performance/performance_bar')
+ .settings-content
+ = render 'performance_bar'
+
+%section.settings.as-usage.no-animate#js-usage-settings{ class: ('expanded' if expanded_by_default?) }
+ .settings-header#usage-statistics
+ %h4
+ = _('Usage statistics')
+ %button.btn.btn-default.js-settings-toggle{ type: 'button' }
+ = expanded_by_default? ? _('Collapse') : _('Expand')
+ %p
+ = _('Enable or disable version check and usage ping.')
+ .settings-content
+ = render 'usage'
+
+= render_if_exists 'admin/application_settings/pseudonymizer_settings', expanded: expanded_by_default?
diff --git a/app/views/admin/application_settings/network.html.haml b/app/views/admin/application_settings/network.html.haml
new file mode 100644
index 00000000000..26fd745f45f
--- /dev/null
+++ b/app/views/admin/application_settings/network.html.haml
@@ -0,0 +1,36 @@
+- breadcrumb_title _("Network")
+- page_title _("Network")
+- @content_class = "limit-container-width" unless fluid_layout
+
+%section.settings.as-performance.no-animate#js-performance-settings{ class: ('expanded' if expanded_by_default?) }
+ .settings-header
+ %h4
+ = _('Performance optimization')
+ %button.btn.btn-default.js-settings-toggle{ type: 'button' }
+ = expanded_by_default? ? _('Collapse') : _('Expand')
+ %p
+ = _('Various settings that affect GitLab performance.')
+ .settings-content
+ = render 'performance'
+
+%section.settings.as-ip-limits.no-animate#js-ip-limits-settings{ class: ('expanded' if expanded_by_default?) }
+ .settings-header
+ %h4
+ = _('User and IP Rate Limits')
+ %button.btn.btn-default.js-settings-toggle{ type: 'button' }
+ = expanded_by_default? ? _('Collapse') : _('Expand')
+ %p
+ = _('Configure limits for web and API requests.')
+ .settings-content
+ = render 'ip_limits'
+
+%section.settings.as-outbound.no-animate#js-outbound-settings{ class: ('expanded' if expanded_by_default?) }
+ .settings-header
+ %h4
+ = _('Outbound requests')
+ %button.btn.btn-default.js-settings-toggle{ type: 'button' }
+ = expanded_by_default? ? _('Collapse') : _('Expand')
+ %p
+ = _('Allow requests to the local network from hooks and services.')
+ .settings-content
+ = render 'outbound'
diff --git a/app/views/admin/application_settings/preferences.html.haml b/app/views/admin/application_settings/preferences.html.haml
new file mode 100644
index 00000000000..75f76eea3b4
--- /dev/null
+++ b/app/views/admin/application_settings/preferences.html.haml
@@ -0,0 +1,69 @@
+- breadcrumb_title _("Preferences")
+- page_title _("Preferences")
+- @content_class = "limit-container-width" unless fluid_layout
+
+%section.settings.as-email.no-animate#js-email-settings{ class: ('expanded' if expanded_by_default?) }
+ .settings-header
+ %h4
+ = _('Email')
+ %button.btn.btn-default.js-settings-toggle{ type: 'button' }
+ = expanded_by_default? ? _('Collapse') : _('Expand')
+ %p
+ = _('Various email settings.')
+ .settings-content
+ = render 'email'
+
+%section.settings.as-help-page.no-animate#js-help-settings{ class: ('expanded' if expanded_by_default?) }
+ .settings-header
+ %h4
+ = _('Help page')
+ %button.btn.btn-default.js-settings-toggle{ type: 'button' }
+ = expanded_by_default? ? _('Collapse') : _('Expand')
+ %p
+ = _('Help page text and support page url.')
+ .settings-content
+ = render 'help_page'
+
+%section.settings.as-pages.no-animate#js-pages-settings{ class: ('expanded' if expanded_by_default?) }
+ .settings-header
+ %h4
+ = _('Pages')
+ %button.btn.btn-default.js-settings-toggle{ type: 'button' }
+ = expanded_by_default? ? _('Collapse') : _('Expand')
+ %p
+ = _('Size and domain settings for static websites')
+ .settings-content
+ = render 'pages'
+
+%section.settings.as-realtime.no-animate#js-realtime-settings{ class: ('expanded' if expanded_by_default?) }
+ .settings-header
+ %h4
+ = _('Real-time features')
+ %button.btn.btn-default.js-settings-toggle{ type: 'button' }
+ = expanded_by_default? ? _('Collapse') : _('Expand')
+ %p
+ = _('Change this value to influence how frequently the GitLab UI polls for updates.')
+ .settings-content
+ = render 'realtime'
+
+%section.settings.as-background.no-animate#js-background-settings{ class: ('expanded' if expanded_by_default?) }
+ .settings-header
+ %h4
+ = _('Background jobs')
+ %button.btn.btn-default.js-settings-toggle{ type: 'button' }
+ = expanded_by_default? ? _('Collapse') : _('Expand')
+ %p
+ = _('Configure Sidekiq job throttling.')
+ .settings-content
+ = render 'background_jobs'
+
+%section.settings.as-gitaly.no-animate#js-gitaly-settings{ class: ('expanded' if expanded_by_default?) }
+ .settings-header
+ %h4
+ = _('Gitaly')
+ %button.btn.btn-default.js-settings-toggle{ type: 'button' }
+ = expanded_by_default? ? _('Collapse') : _('Expand')
+ %p
+ = _('Configure Gitaly timeouts.')
+ .settings-content
+ = render 'gitaly'
diff --git a/app/views/admin/application_settings/reporting.html.haml b/app/views/admin/application_settings/reporting.html.haml
new file mode 100644
index 00000000000..1c2d9ccdb2d
--- /dev/null
+++ b/app/views/admin/application_settings/reporting.html.haml
@@ -0,0 +1,36 @@
+- breadcrumb_title _("Reporting")
+- page_title _("Reporting")
+- @content_class = "limit-container-width" unless fluid_layout
+
+%section.settings.as-spam.no-animate#js-spam-settings{ class: ('expanded' if expanded_by_default?) }
+ .settings-header
+ %h4
+ = _('Spam and Anti-bot Protection')
+ %button.btn.btn-default.js-settings-toggle{ type: 'button' }
+ = expanded_by_default? ? _('Collapse') : _('Expand')
+ %p
+ = _('Enable reCAPTCHA or Akismet and set IP limits.')
+ .settings-content
+ = render 'spam'
+
+%section.settings.as-abuse.no-animate#js-abuse-settings{ class: ('expanded' if expanded_by_default?) }
+ .settings-header
+ %h4
+ = _('Abuse reports')
+ %button.btn.btn-default.js-settings-toggle{ type: 'button' }
+ = expanded_by_default? ? _('Collapse') : _('Expand')
+ %p
+ = _('Set notification email for abuse reports.')
+ .settings-content
+ = render 'abuse'
+
+%section.settings.as-logging.no-animate#js-logging-settings{ class: ('expanded' if expanded_by_default?) }
+ .settings-header
+ %h4
+ = _('Error Reporting and Logging')
+ %button.btn.btn-default.js-settings-toggle{ type: 'button' }
+ = expanded_by_default? ? _('Collapse') : _('Expand')
+ %p
+ = _('Enable Sentry for error reporting and logging.')
+ .settings-content
+ = render 'logging'
diff --git a/app/views/admin/application_settings/repository.html.haml b/app/views/admin/application_settings/repository.html.haml
new file mode 100644
index 00000000000..d8029e0c54a
--- /dev/null
+++ b/app/views/admin/application_settings/repository.html.haml
@@ -0,0 +1,36 @@
+- breadcrumb_title _("Repository")
+- page_title _("Repository")
+- @content_class = "limit-container-width" unless fluid_layout
+
+%section.settings.as-mirror.no-animate#js-mirror-settings{ class: ('expanded' if expanded_by_default?) }
+ .settings-header
+ %h4
+ = _('Repository mirror')
+ %button.btn.js-settings-toggle{ type: 'button' }
+ = expanded_by_default? ? 'Collapse' : 'Expand'
+ %p
+ = _('Configure push mirrors.')
+ .settings-content
+ = render partial: 'repository_mirrors_form'
+
+%section.settings.as-repository-storage.no-animate#js-repository-storage-settings{ class: ('expanded' if expanded_by_default?) }
+ .settings-header
+ %h4
+ = _('Repository storage')
+ %button.btn.btn-default.js-settings-toggle{ type: 'button' }
+ = expanded_by_default? ? _('Collapse') : _('Expand')
+ %p
+ = _('Configure storage path and circuit breaker settings.')
+ .settings-content
+ = render 'repository_storage'
+
+%section.settings.as-repository-check.no-animate#js-repository-check-settings{ class: ('expanded' if expanded_by_default?) }
+ .settings-header
+ %h4
+ = _('Repository maintenance')
+ %button.btn.btn-default.js-settings-toggle{ type: 'button' }
+ = expanded_by_default? ? _('Collapse') : _('Expand')
+ %p
+ = _('Configure automatic git checks and housekeeping on repositories.')
+ .settings-content
+ = render 'repository_check'
diff --git a/app/views/admin/application_settings/show.html.haml b/app/views/admin/application_settings/show.html.haml
index 194a8157013..e2043183a97 100644
--- a/app/views/admin/application_settings/show.html.haml
+++ b/app/views/admin/application_settings/show.html.haml
@@ -1,359 +1,93 @@
-- breadcrumb_title "Settings"
-- page_title "Settings"
+- breadcrumb_title _("Settings")
+- page_title _("Settings")
- @content_class = "limit-container-width" unless fluid_layout
-- expanded = Rails.env.test?
-%section.settings.as-visibility-access.no-animate#js-visibility-settings{ class: ('expanded' if expanded) }
+%section.settings.as-visibility-access.no-animate#js-visibility-settings{ class: ('expanded' if expanded_by_default?) }
.settings-header
%h4
= _('Visibility and access controls')
%button.btn.js-settings-toggle{ type: 'button' }
- = expanded ? _('Collapse') : _('Expand')
+ = expanded_by_default? ? _('Collapse') : _('Expand')
%p
= _('Set default and restrict visibility levels. Configure import sources and git access protocol.')
.settings-content
= render 'visibility_and_access'
-%section.settings.as-account-limit.no-animate#js-account-settings{ class: ('expanded' if expanded) }
+%section.settings.as-account-limit.no-animate#js-account-settings{ class: ('expanded' if expanded_by_default?) }
.settings-header
%h4
= _('Account and limit')
%button.btn.js-settings-toggle{ type: 'button' }
- = expanded ? _('Collapse') : _('Expand')
+ = expanded_by_default? ? _('Collapse') : _('Expand')
%p
= _('Session expiration, projects limit and attachment size.')
.settings-content
= render 'account_and_limit'
-%section.settings.as-signup.no-animate#js-signup-settings{ class: ('expanded' if expanded) }
+%section.settings.as-signup.no-animate#js-signup-settings{ class: ('expanded' if expanded_by_default?) }
.settings-header
%h4
= _('Sign-up restrictions')
%button.btn.js-settings-toggle{ type: 'button' }
- = expanded ? _('Collapse') : _('Expand')
+ = expanded_by_default? ? _('Collapse') : _('Expand')
%p
= _('Configure the way a user creates a new account.')
.settings-content
= render 'signup'
-%section.settings.as-signin.no-animate#js-signin-settings{ class: ('expanded' if expanded) }
+%section.settings.as-signin.no-animate#js-signin-settings{ class: ('expanded' if expanded_by_default?) }
.settings-header
%h4
= _('Sign-in restrictions')
%button.btn.js-settings-toggle{ type: 'button' }
- = expanded ? _('Collapse') : _('Expand')
+ = expanded_by_default? ? _('Collapse') : _('Expand')
%p
= _('Set requirements for a user to sign-in. Enable mandatory two-factor authentication.')
.settings-content
= render 'signin'
-%section.settings.as-terms.no-animate#js-terms-settings{ class: ('expanded' if expanded) }
+%section.qa-terms-settings.settings.as-terms.no-animate#js-terms-settings{ class: ('expanded' if expanded_by_default?) }
.settings-header
%h4
= _('Terms of Service and Privacy Policy')
%button.btn.btn-default.js-settings-toggle{ type: 'button' }
- = expanded ? _('Collapse') : _('Expand')
+ = expanded_by_default? ? _('Collapse') : _('Expand')
%p
= _('Include a Terms of Service agreement and Privacy Policy that all users must accept.')
.settings-content
= render 'terms'
-%section.settings.as-help-page.no-animate#js-help-settings{ class: ('expanded' if expanded) }
- .settings-header
- %h4
- = _('Help page')
- %button.btn.btn-default.js-settings-toggle{ type: 'button' }
- = expanded ? _('Collapse') : _('Expand')
- %p
- = _('Help page text and support page url.')
- .settings-content
- = render 'help_page'
-
-%section.settings.as-pages.no-animate#js-pages-settings{ class: ('expanded' if expanded) }
- .settings-header
- %h4
- = _('Pages')
- %button.btn.btn-default.js-settings-toggle{ type: 'button' }
- = expanded ? _('Collapse') : _('Expand')
- %p
- = _('Size and domain settings for static websites')
- .settings-content
- = render 'pages'
-
-%section.settings.as-ci-cd.no-animate#js-ci-cd-settings{ class: ('expanded' if expanded) }
- .settings-header
- %h4
- = _('Continuous Integration and Deployment')
- %button.btn.btn-default.js-settings-toggle{ type: 'button' }
- = expanded ? _('Collapse') : _('Expand')
- %p
- = _('Auto DevOps, runners and job artifacts')
- .settings-content
- = render 'ci_cd'
-
-%section.settings.as-influx.no-animate#js-influx-settings{ class: ('expanded' if expanded) }
- .settings-header
- %h4
- = _('Metrics - Influx')
- %button.btn.btn-default.js-settings-toggle{ type: 'button' }
- = expanded ? _('Collapse') : _('Expand')
- %p
- = _('Enable and configure InfluxDB metrics.')
- .settings-content
- = render 'influx'
-
-%section.settings.as-prometheus.no-animate#js-prometheus-settings{ class: ('expanded' if expanded) }
- .settings-header
- %h4
- = _('Metrics - Prometheus')
- %button.btn.btn-default.js-settings-toggle{ type: 'button' }
- = expanded ? _('Collapse') : _('Expand')
- %p
- = _('Enable and configure Prometheus metrics.')
- .settings-content
- = render 'prometheus'
-
-%section.settings.as-performance-bar.no-animate#js-performance-bar-settings{ class: ('expanded' if expanded) }
- .settings-header
- %h4
- = _('Profiling - Performance bar')
- %button.btn.btn-default.js-settings-toggle{ type: 'button' }
- = expanded ? _('Collapse') : _('Expand')
- %p
- = _('Enable the Performance Bar for a given group.')
- = link_to icon('question-circle'), help_page_path('administration/monitoring/performance/performance_bar')
- .settings-content
- = render 'performance_bar'
-
-%section.settings.as-background.no-animate#js-background-settings{ class: ('expanded' if expanded) }
- .settings-header
- %h4
- = _('Background jobs')
- %button.btn.btn-default.js-settings-toggle{ type: 'button' }
- = expanded ? _('Collapse') : _('Expand')
- %p
- = _('Configure Sidekiq job throttling.')
- .settings-content
- = render 'background_jobs'
-
-%section.settings.as-spam.no-animate#js-spam-settings{ class: ('expanded' if expanded) }
- .settings-header
- %h4
- = _('Spam and Anti-bot Protection')
- %button.btn.btn-default.js-settings-toggle{ type: 'button' }
- = expanded ? _('Collapse') : _('Expand')
- %p
- = _('Enable reCAPTCHA or Akismet and set IP limits.')
- .settings-content
- = render 'spam'
-
-%section.settings.as-abuse.no-animate#js-abuse-settings{ class: ('expanded' if expanded) }
- .settings-header
- %h4
- = _('Abuse reports')
- %button.btn.btn-default.js-settings-toggle{ type: 'button' }
- = expanded ? _('Collapse') : _('Expand')
- %p
- = _('Set notification email for abuse reports.')
- .settings-content
- = render 'abuse'
-
-%section.settings.as-logging.no-animate#js-logging-settings{ class: ('expanded' if expanded) }
- .settings-header
- %h4
- = _('Error Reporting and Logging')
- %button.btn.btn-default.js-settings-toggle{ type: 'button' }
- = expanded ? _('Collapse') : _('Expand')
- %p
- = _('Enable Sentry for error reporting and logging.')
- .settings-content
- = render 'logging'
-
-%section.qa-repository-storage-settings.settings.as-repository-storage.no-animate#js-repository-storage-settings{ class: ('expanded' if expanded) }
- .settings-header
- %h4
- = _('Repository storage')
- %button.btn.btn-default.js-settings-toggle{ type: 'button' }
- = expanded ? _('Collapse') : _('Expand')
- %p
- = _('Configure storage path and circuit breaker settings.')
- .settings-content
- = render 'repository_storage'
-
-%section.settings.as-repository-check.no-animate#js-repository-check-settings{ class: ('expanded' if expanded) }
- .settings-header
- %h4
- = _('Repository maintenance')
- %button.btn.btn-default.js-settings-toggle{ type: 'button' }
- = expanded ? _('Collapse') : _('Expand')
- %p
- = _('Configure automatic git checks and housekeeping on repositories.')
- .settings-content
- = render 'repository_check'
-
-- if Gitlab.config.registry.enabled
- %section.settings.as-registry.no-animate#js-registry-settings{ class: ('expanded' if expanded) }
- .settings-header
- %h4
- = _('Container Registry')
- %button.btn.btn-default.js-settings-toggle{ type: 'button' }
- = expanded ? _('Collapse') : _('Expand')
- %p
- = _('Various container registry settings.')
- .settings-content
- = render 'registry'
-
- if koding_enabled?
- %section.settings.as-koding.no-animate#js-koding-settings{ class: ('expanded' if expanded) }
+ %section.settings.as-koding.no-animate#js-koding-settings{ class: ('expanded' if expanded_by_default?) }
.settings-header
%h4
= _('Koding')
%button.btn.btn-default.js-settings-toggle{ type: 'button' }
- = expanded ? _('Collapse') : _('Expand')
+ = expanded_by_default? ? _('Collapse') : _('Expand')
%p
= _('Online IDE integration settings.')
.settings-content
= render 'koding'
-%section.settings.as-plantuml.no-animate#js-plantuml-settings{ class: ('expanded' if expanded) }
- .settings-header
- %h4
- = _('PlantUML')
- %button.btn.btn-default.js-settings-toggle{ type: 'button' }
- = expanded ? _('Collapse') : _('Expand')
- %p
- = _('Allow rendering of PlantUML diagrams in Asciidoc documents.')
- .settings-content
- = render 'plantuml'
-
-%section.settings.as-usage.no-animate#js-usage-settings{ class: ('expanded' if expanded) }
- .settings-header#usage-statistics
- %h4
- = _('Usage statistics')
- %button.btn.btn-default.js-settings-toggle{ type: 'button' }
- = expanded ? _('Collapse') : _('Expand')
- %p
- = _('Enable or disable version check and usage ping.')
- .settings-content
- = render 'usage'
-
-%section.settings.as-email.no-animate#js-email-settings{ class: ('expanded' if expanded) }
- .settings-header
- %h4
- = _('Email')
- %button.btn.btn-default.js-settings-toggle{ type: 'button' }
- = expanded ? _('Collapse') : _('Expand')
- %p
- = _('Various email settings.')
- .settings-content
- = render 'email'
-
-%section.settings.as-gitaly.no-animate#js-gitaly-settings{ class: ('expanded' if expanded) }
- .settings-header
- %h4
- = _('Gitaly')
- %button.btn.btn-default.js-settings-toggle{ type: 'button' }
- = expanded ? _('Collapse') : _('Expand')
- %p
- = _('Configure Gitaly timeouts.')
- .settings-content
- = render 'gitaly'
+= render_if_exists 'admin/application_settings/external_authorization_service_form', expanded: expanded_by_default?
-%section.settings.as-terminal.no-animate#js-terminal-settings{ class: ('expanded' if expanded) }
+%section.settings.as-terminal.no-animate#js-terminal-settings{ class: ('expanded' if expanded_by_default?) }
.settings-header
%h4
= _('Web terminal')
%button.btn.btn-default.js-settings-toggle{ type: 'button' }
- = expanded ? _('Collapse') : _('Expand')
+ = expanded_by_default? ? _('Collapse') : _('Expand')
%p
= _('Set max session time for web terminal.')
.settings-content
= render 'terminal'
-%section.settings.as-realtime.no-animate#js-realtime-settings{ class: ('expanded' if expanded) }
- .settings-header
- %h4
- = _('Real-time features')
- %button.btn.btn-default.js-settings-toggle{ type: 'button' }
- = expanded ? _('Collapse') : _('Expand')
- %p
- = _('Change this value to influence how frequently the GitLab UI polls for updates.')
- .settings-content
- = render 'realtime'
-
-%section.settings.as-performance.no-animate#js-performance-settings{ class: ('expanded' if expanded) }
- .settings-header
- %h4
- = _('Performance optimization')
- %button.btn.btn-default.js-settings-toggle{ type: 'button' }
- = expanded ? _('Collapse') : _('Expand')
- %p
- = _('Various settings that affect GitLab performance.')
- .settings-content
- = render 'performance'
-
-%section.settings.as-ip-limits.no-animate#js-ip-limits-settings{ class: ('expanded' if expanded) }
- .settings-header
- %h4
- = _('User and IP Rate Limits')
- %button.btn.btn-default.js-settings-toggle{ type: 'button' }
- = expanded ? _('Collapse') : _('Expand')
- %p
- = _('Configure limits for web and API requests.')
- .settings-content
- = render 'ip_limits'
-
-%section.settings.as-outbound.no-animate#js-outbound-settings{ class: ('expanded' if expanded) }
- .settings-header
- %h4
- = _('Outbound requests')
- %button.btn.btn-default.js-settings-toggle{ type: 'button' }
- = expanded ? _('Collapse') : _('Expand')
- %p
- = _('Allow requests to the local network from hooks and services.')
- .settings-content
- = render 'outbound'
-
-%section.settings.as-mirror.no-animate#js-mirror-settings{ class: ('expanded' if expanded) }
- .settings-header
- %h4
- = _('Repository mirror')
- %button.btn.js-settings-toggle{ type: 'button' }
- = expanded ? 'Collapse' : 'Expand'
- %p
- = _('Configure push mirrors.')
- .settings-content
- = render partial: 'repository_mirrors_form'
-
-= render_if_exists 'admin/application_settings/geo', expanded: expanded
-
-= render_if_exists 'admin/application_settings/external_authorization_service_form', expanded: expanded
-
-= render_if_exists 'admin/application_settings/elasticsearch_form', expanded: expanded
-
-= render_if_exists 'admin/application_settings/slack', expanded: expanded
-
-= render_if_exists 'admin/application_settings/templates', expanded: expanded
-
-%section.settings.as-third-party-offers.no-animate#js-third-party-offers-settings{ class: ('expanded' if expanded) }
- .settings-header
- %h4
- = _('Third party offers')
- %button.btn.btn-default.js-settings-toggle{ type: 'button' }
- = expanded ? _('Collapse') : _('Expand')
- %p
- = _('Control the display of third party offers.')
- .settings-content
- = render 'third_party_offers', application_setting: @application_setting
-
-= render_if_exists 'admin/application_settings/custom_templates_form', expanded: expanded
-
-%section.settings.no-animate#js-web-ide-settings{ class: ('expanded' if expanded) }
+%section.settings.no-animate#js-web-ide-settings{ class: ('expanded' if expanded_by_default?) }
.settings-header
%h4
= _('Web IDE')
%button.btn.btn-default.js-settings-toggle{ type: 'button' }
- = expanded ? _('Collapse') : _('Expand')
+ = expanded_by_default? ? _('Collapse') : _('Expand')
%p
= _('Manage Web IDE features')
.settings-content
@@ -370,5 +104,3 @@
= s_('IDE|Allow live previews of JavaScript projects in the Web IDE using CodeSandbox client side evaluation.')
= f.submit _('Save changes'), class: "btn btn-success"
-
-= render_if_exists 'admin/application_settings/pseudonymizer_settings', expanded: expanded
diff --git a/app/views/admin/applications/_form.html.haml b/app/views/admin/applications/_form.html.haml
index 7f14cddebd8..12690343f6e 100644
--- a/app/views/admin/applications/_form.html.haml
+++ b/app/views/admin/applications/_form.html.haml
@@ -21,17 +21,17 @@
for local tests
= content_tag :div, class: 'form-group row' do
- = f.label :trusted, class: 'col-sm-2 col-form-label'
+ = f.label :trusted, class: 'col-sm-2 col-form-label pt-0'
.col-sm-10
= f.check_box :trusted
%span.form-text.text-muted
Trusted applications are automatically authorized on GitLab OAuth flow.
.form-group.row
- = f.label :scopes, class: 'col-sm-2 col-form-label'
+ = f.label :scopes, class: 'col-sm-2 col-form-label pt-0'
.col-sm-10
= render 'shared/tokens/scopes_form', prefix: 'doorkeeper_application', token: application, scopes: @scopes
.form-actions
- = f.submit 'Submit', class: "btn btn-save wide"
+ = f.submit 'Submit', class: "btn btn-success wide"
= link_to "Cancel", admin_applications_path, class: "btn btn-cancel"
diff --git a/app/views/admin/broadcast_messages/_form.html.haml b/app/views/admin/broadcast_messages/_form.html.haml
index 7f34357f147..c465d9f51d6 100644
--- a/app/views/admin/broadcast_messages/_form.html.haml
+++ b/app/views/admin/broadcast_messages/_form.html.haml
@@ -36,6 +36,6 @@
= f.datetime_select :ends_at, {}, class: 'form-control form-control-inline'
.form-actions
- if @broadcast_message.persisted?
- = f.submit "Update broadcast message", class: "btn btn-create"
+ = f.submit "Update broadcast message", class: "btn btn-success"
- else
- = f.submit "Add broadcast message", class: "btn btn-create"
+ = f.submit "Add broadcast message", class: "btn btn-success"
diff --git a/app/views/admin/dashboard/index.html.haml b/app/views/admin/dashboard/index.html.haml
index fac61f9d249..85c04f8a01d 100644
--- a/app/views/admin/dashboard/index.html.haml
+++ b/app/views/admin/dashboard/index.html.haml
@@ -14,7 +14,7 @@
Projects:
= approximate_count_with_delimiters(@counts, Project)
%hr
- = link_to('New project', new_project_path, class: "btn btn-new")
+ = link_to('New project', new_project_path, class: "btn btn-success")
.col-sm-4
.info-well.dark-well
.well-segment.well-centered
@@ -24,7 +24,7 @@
= approximate_count_with_delimiters(@counts, User)
= render_if_exists 'admin/dashboard/users_statistics'
%hr
- = link_to 'New user', new_admin_user_path, class: "btn btn-new"
+ = link_to 'New user', new_admin_user_path, class: "btn btn-success"
.col-sm-4
.info-well.dark-well
.well-segment.well-centered
@@ -33,7 +33,7 @@
Groups:
= approximate_count_with_delimiters(@counts, Group)
%hr
- = link_to 'New group', new_admin_group_path, class: "btn btn-new"
+ = link_to 'New group', new_admin_group_path, class: "btn btn-success"
.row
.col-md-4
.info-well
diff --git a/app/views/admin/deploy_keys/edit.html.haml b/app/views/admin/deploy_keys/edit.html.haml
index b50adef362f..7c04ef03947 100644
--- a/app/views/admin/deploy_keys/edit.html.haml
+++ b/app/views/admin/deploy_keys/edit.html.haml
@@ -6,5 +6,5 @@
= form_for [:admin, @deploy_key], html: { class: 'deploy-key-form' } do |f|
= render partial: 'shared/deploy_keys/form', locals: { form: f, deploy_key: @deploy_key }
.form-actions
- = f.submit 'Save changes', class: 'btn-save btn'
+ = f.submit 'Save changes', class: 'btn-success btn'
= link_to 'Cancel', admin_deploy_keys_path, class: 'btn btn-cancel'
diff --git a/app/views/admin/deploy_keys/index.html.haml b/app/views/admin/deploy_keys/index.html.haml
index 52ab8bae119..01013be06d6 100644
--- a/app/views/admin/deploy_keys/index.html.haml
+++ b/app/views/admin/deploy_keys/index.html.haml
@@ -3,7 +3,7 @@
%h3.page-title.deploy-keys-title
Public deploy keys (#{@deploy_keys.count})
.float-right
- = link_to 'New deploy key', new_admin_deploy_key_path, class: 'btn btn-new btn-sm btn-inverted'
+ = link_to 'New deploy key', new_admin_deploy_key_path, class: 'btn btn-success btn-sm btn-inverted'
- if @deploy_keys.any?
.table-holder.deploy-keys-list
diff --git a/app/views/admin/deploy_keys/new.html.haml b/app/views/admin/deploy_keys/new.html.haml
index d4f8e340b69..9a563a5bc78 100644
--- a/app/views/admin/deploy_keys/new.html.haml
+++ b/app/views/admin/deploy_keys/new.html.haml
@@ -6,5 +6,5 @@
= form_for [:admin, @deploy_key], html: { class: 'deploy-key-form' } do |f|
= render partial: 'shared/deploy_keys/form', locals: { form: f, deploy_key: @deploy_key }
.form-actions
- = f.submit 'Create', class: 'btn-create btn'
+ = f.submit 'Create', class: 'btn-success btn'
= link_to 'Cancel', admin_deploy_keys_path, class: 'btn btn-cancel'
diff --git a/app/views/admin/groups/_form.html.haml b/app/views/admin/groups/_form.html.haml
index a3773e90cfb..2a117c1414e 100644
--- a/app/views/admin/groups/_form.html.haml
+++ b/app/views/admin/groups/_form.html.haml
@@ -26,12 +26,12 @@
.alert.alert-info
= render 'shared/group_tips'
.form-actions
- = f.submit _('Create group'), class: "btn btn-create"
+ = f.submit _('Create group'), class: "btn btn-success"
= link_to _('Cancel'), admin_groups_path, class: "btn btn-cancel"
- else
.form-actions
- = f.submit _('Save changes'), class: "btn btn-save"
+ = f.submit _('Save changes'), class: "btn btn-success"
= link_to _('Cancel'), admin_group_path(@group), class: "btn btn-cancel"
= render_if_exists 'ldap_group_links/ldap_syncrhonizations', group: @group
diff --git a/app/views/admin/groups/index.html.haml b/app/views/admin/groups/index.html.haml
index 6a9b85b4109..cb833ffd9ac 100644
--- a/app/views/admin/groups/index.html.haml
+++ b/app/views/admin/groups/index.html.haml
@@ -12,7 +12,7 @@
= search_field_tag :name, project_name, class: "form-control search-text-input js-search-input", autofocus: true, spellcheck: false, placeholder: 'Search by name'
= icon("search", class: "search-icon")
= render "shared/groups/dropdown", options_hash: admin_groups_sort_options_hash
- = link_to new_admin_group_path, class: "btn btn-new" do
+ = link_to new_admin_group_path, class: "btn btn-success" do
= _('New group')
%ul.content-list
= render @groups
diff --git a/app/views/admin/groups/show.html.haml b/app/views/admin/groups/show.html.haml
index 72b068ea6b5..0c683f86252 100644
--- a/app/views/admin/groups/show.html.haml
+++ b/app/views/admin/groups/show.html.haml
@@ -111,7 +111,7 @@
.prepend-top-10
= select_tag :access_level, options_for_select(GroupMember.access_level_roles), class: "project-access-select select2"
%hr
- = button_tag _('Add users to group'), class: "btn btn-create"
+ = button_tag _('Add users to group'), class: "btn btn-success"
= render 'shared/members/requests', membership_source: @group, requesters: @requesters, force_mobile_view: true
.card
diff --git a/app/views/admin/hooks/edit.html.haml b/app/views/admin/hooks/edit.html.haml
index b9a650e1f1f..486d0477f20 100644
--- a/app/views/admin/hooks/edit.html.haml
+++ b/app/views/admin/hooks/edit.html.haml
@@ -12,7 +12,7 @@
= form_for @hook, as: :hook, url: admin_hook_path do |f|
= render partial: 'form', locals: { form: f, hook: @hook }
.form-actions
- = f.submit 'Save changes', class: 'btn btn-create'
+ = f.submit 'Save changes', class: 'btn btn-success'
= render 'shared/web_hooks/test_button', triggers: SystemHook.triggers, hook: @hook
= link_to 'Remove', admin_hook_path(@hook), method: :delete, class: 'btn btn-remove float-right', data: { confirm: 'Are you sure?' }
diff --git a/app/views/admin/hooks/index.html.haml b/app/views/admin/hooks/index.html.haml
index 87f9b0e86a7..5d462d7b732 100644
--- a/app/views/admin/hooks/index.html.haml
+++ b/app/views/admin/hooks/index.html.haml
@@ -10,7 +10,7 @@
.col-lg-8.append-bottom-default
= form_for @hook, as: :hook, url: admin_hooks_path do |f|
= render partial: 'form', locals: { form: f, hook: @hook }
- = f.submit 'Add system hook', class: 'btn btn-create'
+ = f.submit 'Add system hook', class: 'btn btn-success'
%hr
diff --git a/app/views/admin/identities/_form.html.haml b/app/views/admin/identities/_form.html.haml
index 946d868da01..3ab7990d9e2 100644
--- a/app/views/admin/identities/_form.html.haml
+++ b/app/views/admin/identities/_form.html.haml
@@ -12,5 +12,5 @@
= f.text_field :extern_uid, class: 'form-control', required: true
.form-actions
- = f.submit _('Save changes'), class: "btn btn-save"
+ = f.submit _('Save changes'), class: "btn btn-success"
diff --git a/app/views/admin/identities/index.html.haml b/app/views/admin/identities/index.html.haml
index df3df159947..9543bbcf977 100644
--- a/app/views/admin/identities/index.html.haml
+++ b/app/views/admin/identities/index.html.haml
@@ -3,7 +3,7 @@
- page_title _("Identities"), @user.name, _("Users")
= render 'admin/users/head'
-= link_to _('New identity'), new_admin_user_identity_path, class: 'float-right btn btn-new'
+= link_to _('New identity'), new_admin_user_identity_path, class: 'float-right btn btn-success'
- if @identities.present?
.table-holder
%table.table
diff --git a/app/views/admin/labels/_form.html.haml b/app/views/admin/labels/_form.html.haml
index ee2d4c8430a..5e7b4817461 100644
--- a/app/views/admin/labels/_form.html.haml
+++ b/app/views/admin/labels/_form.html.haml
@@ -27,5 +27,5 @@
&nbsp;
.form-actions
- = f.submit _('Save'), class: 'btn btn-save js-save-button'
+ = f.submit _('Save'), class: 'btn btn-success js-save-button'
= link_to _("Cancel"), admin_labels_path, class: 'btn btn-cancel'
diff --git a/app/views/admin/labels/index.html.haml b/app/views/admin/labels/index.html.haml
index f1b8658f84e..5a5b3d18c5f 100644
--- a/app/views/admin/labels/index.html.haml
+++ b/app/views/admin/labels/index.html.haml
@@ -1,7 +1,7 @@
- page_title _("Labels")
%div
- = link_to new_admin_label_path, class: "float-right btn btn-nr btn-new" do
+ = link_to new_admin_label_path, class: "float-right btn btn-nr btn-success" do
= _('New label')
%h3.page-title
= _('Labels')
diff --git a/app/views/admin/projects/index.html.haml b/app/views/admin/projects/index.html.haml
index 57de792f92d..46bb57c78a8 100644
--- a/app/views/admin/projects/index.html.haml
+++ b/app/views/admin/projects/index.html.haml
@@ -21,7 +21,7 @@
= dropdown_content
= dropdown_loading
= render 'shared/projects/dropdown'
- = link_to new_project_path, class: 'btn btn-new' do
+ = link_to new_project_path, class: 'btn btn-success' do
New Project
= button_tag "Search", class: "btn btn-primary btn-search hide"
diff --git a/app/views/admin/runners/_runner.html.haml b/app/views/admin/runners/_runner.html.haml
index 9c15226f0ec..e4fc2985087 100644
--- a/app/views/admin/runners/_runner.html.haml
+++ b/app/views/admin/runners/_runner.html.haml
@@ -1,47 +1,65 @@
.gl-responsive-table-row{ id: dom_id(runner) }
- = render layout: 'runner_table_cell', locals: { label: _('Type') } do
- - if runner.instance_type?
- %span.badge.badge-success shared
- - elsif runner.group_type?
- %span.badge.badge-success group
- - else
- %span.badge.badge-info specific
- - if runner.locked?
- %span.badge.badge-warning locked
- - unless runner.active?
- %span.badge.badge-danger paused
-
- = render layout: 'runner_table_cell', locals: { label: _('Runner token') } do
- = link_to runner.short_sha, admin_runner_path(runner)
-
- = render layout: 'runner_table_cell', locals: { label: _('Description') } do
- = runner.description
-
- = render layout: 'runner_table_cell', locals: { label: _('Version') } do
- = runner.version
-
- = render layout: 'runner_table_cell', locals: { label: _('IP Address') } do
- = runner.ip_address
-
- = render layout: 'runner_table_cell', locals: { label: _('Projects') } do
- - if runner.instance_type? || runner.group_type?
- = _('n/a')
- - else
- = runner.projects.count(:all)
-
- = render layout: 'runner_table_cell', locals: { label: _('Jobs') } do
- = runner.builds.count(:all)
-
- = render layout: 'runner_table_cell', locals: { label: _('Tags') } do
- - runner.tag_list.sort.each do |tag|
- %span.badge.badge-primary
- = tag
-
- = render layout: 'runner_table_cell', locals: { label: _('Last contact') } do
- - if runner.contacted_at
- = time_ago_with_tooltip runner.contacted_at
- - else
- = _('Never')
+ .table-section.section-10.section-wrap
+ .table-mobile-header{ role: 'rowheader' }= _('Type')
+ .table-mobile-content
+ - if runner.instance_type?
+ %span.badge.badge-success shared
+ - elsif runner.group_type?
+ %span.badge.badge-success group
+ - else
+ %span.badge.badge-info specific
+ - if runner.locked?
+ %span.badge.badge-warning locked
+ - unless runner.active?
+ %span.badge.badge-danger paused
+
+ .table-section.section-10
+ .table-mobile-header{ role: 'rowheader' }= _('Runner token')
+ .table-mobile-content
+ = link_to runner.short_sha, admin_runner_path(runner)
+
+ .table-section.section-15
+ .table-mobile-header{ role: 'rowheader' }= _('Description')
+ .table-mobile-content.str-truncated.has-tooltip{ title: runner.description }
+ = runner.description
+
+ .table-section.section-15
+ .table-mobile-header{ role: 'rowheader' }= _('Version')
+ .table-mobile-content.str-truncated.has-tooltip{ title: runner.version }
+ = runner.version
+
+ .table-section.section-10
+ .table-mobile-header{ role: 'rowheader' }= _('IP Address')
+ .table-mobile-content
+ = runner.ip_address
+
+ .table-section.section-5
+ .table-mobile-header{ role: 'rowheader' }= _('Projects')
+ .table-mobile-content
+ - if runner.instance_type? || runner.group_type?
+ = _('n/a')
+ - else
+ = runner.projects.count(:all)
+
+ .table-section.section-5
+ .table-mobile-header{ role: 'rowheader' }= _('Jobs')
+ .table-mobile-content
+ = runner.builds.count(:all)
+
+ .table-section.section-10.section-wrap
+ .table-mobile-header{ role: 'rowheader' }= _('Tags')
+ .table-mobile-content
+ - runner.tag_list.sort.each do |tag|
+ %span.badge.badge-primary
+ = tag
+
+ .table-section.section-10
+ .table-mobile-header{ role: 'rowheader' }= _('Last contact')
+ .table-mobile-content
+ - if runner.contacted_at
+ = time_ago_with_tooltip runner.contacted_at
+ - else
+ = _('Never')
.table-section.table-button-footer.section-10
.btn-group.table-action-buttons
diff --git a/app/views/admin/runners/_runner_table_cell.html.haml b/app/views/admin/runners/_runner_table_cell.html.haml
deleted file mode 100644
index 78526ee6d23..00000000000
--- a/app/views/admin/runners/_runner_table_cell.html.haml
+++ /dev/null
@@ -1,4 +0,0 @@
-.table-section.section-10
- .table-mobile-header{ role: 'rowheader' }= label
- .table-mobile-content
- = yield
diff --git a/app/views/admin/runners/index.html.haml b/app/views/admin/runners/index.html.haml
index 4dc076c95c5..ee2e1703fdb 100644
--- a/app/views/admin/runners/index.html.haml
+++ b/app/views/admin/runners/index.html.haml
@@ -4,7 +4,7 @@
%div{ class: container_class }
.bs-callout
%p
- = (_"A 'Runner' is a process which runs a job. You can setup as many Runners as you need.")
+ = (_"A 'Runner' is a process which runs a job. You can set up as many Runners as you need.")
%br
= _('Runners can be placed on separate users, servers, even on your local machine.')
%br
@@ -69,7 +69,7 @@
%ul{ data: { dropdown: true } }
%li.filter-dropdown-item{ data: { action: 'submit' } }
= button_tag class: %w[btn btn-link] do
- = icon('search')
+ = sprite_icon('search')
%span
= _('Press Enter or click to search')
%ul.filter-dropdown{ data: { dynamic: true, dropdown: true } }
@@ -77,7 +77,8 @@
= button_tag class: %w[btn btn-link] do
-# Encapsulate static class name `{{icon}}` inside #{} to bypass
-# haml lint's ClassAttributeWithStaticValue
- %i.fa{ class: "#{'{{icon}}'}" }
+ %svg
+ %use{ 'xlink:href': "#{'{{icon}}'}" }
%span.js-filter-hint
{{hint}}
%span.js-filter-tag.dropdown-light-content
@@ -97,8 +98,16 @@
.runners-content.content-list
.table-holder
.gl-responsive-table-row.table-row-header{ role: 'row' }
- - [_('Type'), _('Runner token'), _('Description'), _('Version'), _('IP Address'), _('Projects'), _('Jobs'), _('Tags'), _('Last contact')].each do |label|
- .table-section.section-10{ role: 'rowheader' }= label
+ .table-section.section-10{ role: 'rowheader' }= _('Type')
+ .table-section.section-10{ role: 'rowheader' }= _('Runner token')
+ .table-section.section-15{ role: 'rowheader' }= _('Description')
+ .table-section.section-15{ role: 'rowheader' }= _('Version')
+ .table-section.section-10{ role: 'rowheader' }= _('IP Address')
+ .table-section.section-5{ role: 'rowheader' }= _('Projects')
+ .table-section.section-5{ role: 'rowheader' }= _('Jobs')
+ .table-section.section-10{ role: 'rowheader' }= _('Tags')
+ .table-section.section-10{ role: 'rowheader' }= _('Last contact')
+ .table-section.section-10{ role: 'rowheader' }
- @runners.each do |runner|
= render 'admin/runners/runner', runner: runner
diff --git a/app/views/admin/services/_form.html.haml b/app/views/admin/services/_form.html.haml
index 993006e8745..1798b44bbb7 100644
--- a/app/views/admin/services/_form.html.haml
+++ b/app/views/admin/services/_form.html.haml
@@ -7,4 +7,4 @@
= render 'shared/service_settings', form: form, subject: @service
.footer-block.row-content-block
- = form.submit 'Save', class: 'btn btn-save'
+ = form.submit 'Save', class: 'btn btn-success'
diff --git a/app/views/admin/users/_form.html.haml b/app/views/admin/users/_form.html.haml
index 7f21bdb91c8..296ef073144 100644
--- a/app/views/admin/users/_form.html.haml
+++ b/app/views/admin/users/_form.html.haml
@@ -75,8 +75,8 @@
.form-actions
- if @user.new_record?
- = f.submit 'Create user', class: "btn btn-create"
+ = f.submit 'Create user', class: "btn btn-success"
= link_to 'Cancel', admin_users_path, class: "btn btn-cancel"
- else
- = f.submit 'Save changes', class: "btn btn-save"
+ = f.submit 'Save changes', class: "btn btn-success"
= link_to 'Cancel', admin_user_path(@user), class: "btn btn-cancel"
diff --git a/app/views/admin/users/index.html.haml b/app/views/admin/users/index.html.haml
index faeb82656ba..f910e90d6ca 100644
--- a/app/views/admin/users/index.html.haml
+++ b/app/views/admin/users/index.html.haml
@@ -31,7 +31,7 @@
= sort_title_recently_updated
= link_to admin_users_path(sort: sort_value_oldest_updated, filter: params[:filter]) do
= sort_title_oldest_updated
- = link_to 'New user', new_admin_user_path, class: 'btn btn-new btn-search'
+ = link_to 'New user', new_admin_user_path, class: 'btn btn-success btn-search'
.top-area.scrolling-tabs-container.inner-page-scroll-tabs
.fade-left
diff --git a/app/views/ci/runner/_how_to_setup_runner.html.haml b/app/views/ci/runner/_how_to_setup_runner.html.haml
index c26eb873718..b1b142460b0 100644
--- a/app/views/ci/runner/_how_to_setup_runner.html.haml
+++ b/app/views/ci/runner/_how_to_setup_runner.html.haml
@@ -1,6 +1,6 @@
- link = link_to _("Install GitLab Runner"), 'https://docs.gitlab.com/runner/install/', target: '_blank'
.append-bottom-10
- %h4= _("Setup a %{type} Runner manually") % { type: type }
+ %h4= _("Set up a %{type} Runner manually") % { type: type }
%ol
%li
diff --git a/app/views/ci/runner/_how_to_setup_specific_runner.html.haml b/app/views/ci/runner/_how_to_setup_specific_runner.html.haml
index e765a353fe4..afe57bdfa01 100644
--- a/app/views/ci/runner/_how_to_setup_specific_runner.html.haml
+++ b/app/views/ci/runner/_how_to_setup_specific_runner.html.haml
@@ -1,6 +1,6 @@
.bs-callout.help-callout
.append-bottom-10
- %h4= _('Setup a specific Runner automatically')
+ %h4= _('Set up a specific Runner automatically')
%p
- link_to_help_page = link_to(_('Learn more about Kubernetes'),
diff --git a/app/views/dashboard/_groups_head.html.haml b/app/views/dashboard/_groups_head.html.haml
index d8f1e50544c..727784141bb 100644
--- a/app/views/dashboard/_groups_head.html.haml
+++ b/app/views/dashboard/_groups_head.html.haml
@@ -10,4 +10,4 @@
= render 'shared/groups/search_form'
= render 'shared/groups/dropdown'
- if current_user.can_create_group?
- = link_to _("New group"), new_group_path, class: "btn btn-new"
+ = link_to _("New group"), new_group_path, class: "btn btn-success"
diff --git a/app/views/dashboard/_projects_head.html.haml b/app/views/dashboard/_projects_head.html.haml
index 9b1d9b659f9..69a2e408073 100644
--- a/app/views/dashboard/_projects_head.html.haml
+++ b/app/views/dashboard/_projects_head.html.haml
@@ -19,4 +19,4 @@
= render 'shared/projects/search_form'
= render 'shared/projects/dropdown'
- if current_user.can_create_project?
- = link_to "New project", new_project_path, class: "btn btn-new"
+ = link_to "New project", new_project_path, class: "btn btn-success"
diff --git a/app/views/dashboard/_snippets_head.html.haml b/app/views/dashboard/_snippets_head.html.haml
index e7e323a8683..4f38339b87a 100644
--- a/app/views/dashboard/_snippets_head.html.haml
+++ b/app/views/dashboard/_snippets_head.html.haml
@@ -9,4 +9,4 @@
- if current_user
.nav-controls.d-none.d-sm-block
- = link_to "New snippet", new_snippet_path, class: "btn btn-new", title: "New snippet"
+ = link_to "New snippet", new_snippet_path, class: "btn btn-success", title: "New snippet"
diff --git a/app/views/dashboard/snippets/index.html.haml b/app/views/dashboard/snippets/index.html.haml
index 4391624196b..b11dc2c8e9b 100644
--- a/app/views/dashboard/snippets/index.html.haml
+++ b/app/views/dashboard/snippets/index.html.haml
@@ -7,7 +7,7 @@
.d-block.d-sm-none
&nbsp;
- = link_to new_snippet_path, class: "btn btn-new btn-block", title: "New snippet" do
+ = link_to new_snippet_path, class: "btn btn-success btn-block", title: "New snippet" do
New snippet
= render partial: 'snippets/snippets', locals: { link_project: true }
diff --git a/app/views/devise/passwords/edit.html.haml b/app/views/devise/passwords/edit.html.haml
index 35dafb3e980..4b8ad5acd5b 100644
--- a/app/views/devise/passwords/edit.html.haml
+++ b/app/views/devise/passwords/edit.html.haml
@@ -7,12 +7,12 @@
= f.hidden_field :reset_password_token
.form-group
= f.label 'New password', for: "user_password"
- = f.password_field :password, class: "form-control top", required: true, title: 'This field is required'
+ = f.password_field :password, class: "form-control top qa-password-field", required: true, title: 'This field is required'
.form-group
= f.label 'Confirm new password', for: "user_password_confirmation"
- = f.password_field :password_confirmation, class: "form-control bottom", title: 'This field is required', required: true
+ = f.password_field :password_confirmation, class: "form-control bottom qa-password-confirmation", title: 'This field is required', required: true
.clearfix
- = f.submit "Change your password", class: "btn btn-primary"
+ = f.submit "Change your password", class: "btn btn-primary qa-change-password-button"
.clearfix.prepend-top-20
%p
diff --git a/app/views/devise/sessions/_new_base.html.haml b/app/views/devise/sessions/_new_base.html.haml
index 17a9c8df872..7dacd0b1d72 100644
--- a/app/views/devise/sessions/_new_base.html.haml
+++ b/app/views/devise/sessions/_new_base.html.haml
@@ -1,10 +1,10 @@
= form_for(resource, as: resource_name, url: session_path(resource_name), html: { class: 'new_user gl-show-field-errors', 'aria-live' => 'assertive'}) do |f|
.form-group
= f.label "Username or email", for: "user_login", class: 'label-bold'
- = f.text_field :login, class: "form-control top", autofocus: "autofocus", autocapitalize: "off", autocorrect: "off", required: true, title: "This field is required."
+ = f.text_field :login, class: "form-control top qa-login-field", autofocus: "autofocus", autocapitalize: "off", autocorrect: "off", required: true, title: "This field is required."
.form-group
= f.label :password, class: 'label-bold'
- = f.password_field :password, class: "form-control bottom", required: true, title: "This field is required."
+ = f.password_field :password, class: "form-control bottom qa-password-field", required: true, title: "This field is required."
- if devise_mapping.rememberable?
.remember-me
%label{ for: "user_remember_me" }
@@ -17,4 +17,4 @@
= recaptcha_tags
.submit-container.move-submit-down
- = f.submit "Sign in", class: "btn btn-save"
+ = f.submit "Sign in", class: "btn btn-success qa-sign-in-button"
diff --git a/app/views/devise/sessions/_new_crowd.html.haml b/app/views/devise/sessions/_new_crowd.html.haml
index 36ff42090be..131544ac0c0 100644
--- a/app/views/devise/sessions/_new_crowd.html.haml
+++ b/app/views/devise/sessions/_new_crowd.html.haml
@@ -10,4 +10,4 @@
%label{ for: "remember_me" }
= check_box_tag :remember_me, '1', false, id: 'remember_me'
%span Remember me
- = submit_tag "Sign in", class: "btn-save btn"
+ = submit_tag "Sign in", class: "btn-success btn"
diff --git a/app/views/devise/sessions/_new_ldap.html.haml b/app/views/devise/sessions/_new_ldap.html.haml
index 6bf7349f602..796c0cadda8 100644
--- a/app/views/devise/sessions/_new_ldap.html.haml
+++ b/app/views/devise/sessions/_new_ldap.html.haml
@@ -1,13 +1,13 @@
= form_tag(omniauth_callback_path(:user, server['provider_name']), id: 'new_ldap_user', class: "gl-show-field-errors") do
.form-group
= label_tag :username, "#{server['label']} Username"
- = text_field_tag :username, nil, { class: "form-control top", title: "This field is required.", autofocus: "autofocus", required: true }
+ = text_field_tag :username, nil, { class: "form-control top qa-username-field", title: "This field is required.", autofocus: "autofocus", required: true }
.form-group
= label_tag :password
- = password_field_tag :password, nil, { class: "form-control bottom", title: "This field is required.", required: true }
+ = password_field_tag :password, nil, { class: "form-control bottom qa-password-field", title: "This field is required.", required: true }
- if devise_mapping.rememberable?
.remember-me
%label{ for: "remember_me" }
= check_box_tag :remember_me, '1', false, id: 'remember_me'
%span Remember me
- = submit_tag "Sign in", class: "btn-save btn"
+ = submit_tag "Sign in", class: "btn-success btn qa-sign-in-button"
diff --git a/app/views/devise/sessions/two_factor.html.haml b/app/views/devise/sessions/two_factor.html.haml
index ba168c4eab8..fefdf5f9531 100644
--- a/app/views/devise/sessions/two_factor.html.haml
+++ b/app/views/devise/sessions/two_factor.html.haml
@@ -11,7 +11,7 @@
= f.text_field :otp_attempt, class: 'form-control', required: true, autofocus: true, autocomplete: 'off', title: 'This field is required.'
%p.form-text.text-muted.hint Enter the code from the two-factor app on your mobile device. If you've lost your device, you may enter one of your recovery codes.
.prepend-top-20
- = f.submit "Verify code", class: "btn btn-save"
+ = f.submit "Verify code", class: "btn btn-success"
- if @user.two_factor_u2f_enabled?
= render "u2f/authenticate", locals: { params: params, resource: resource, resource_name: resource_name }
diff --git a/app/views/devise/shared/_tabs_ldap.html.haml b/app/views/devise/shared/_tabs_ldap.html.haml
index 58c585a29ff..3764e86dd8b 100644
--- a/app/views/devise/shared/_tabs_ldap.html.haml
+++ b/app/views/devise/shared/_tabs_ldap.html.haml
@@ -4,10 +4,10 @@
= link_to "Crowd", "#crowd", class: 'nav-link active', 'data-toggle' => 'tab'
- @ldap_servers.each_with_index do |server, i|
%li.nav-item
- = link_to server['label'], "##{server['provider_name']}", class: "nav-link #{active_when(i.zero? && !crowd_enabled?)}", 'data-toggle' => 'tab'
+ = link_to server['label'], "##{server['provider_name']}", class: "nav-link #{active_when(i.zero? && !crowd_enabled?)} qa-ldap-tab", 'data-toggle' => 'tab'
- if password_authentication_enabled_for_web?
%li.nav-item
- = link_to 'Standard', '#login-pane', class: 'nav-link', 'data-toggle' => 'tab'
+ = link_to 'Standard', '#login-pane', class: 'nav-link qa-standard-tab', 'data-toggle' => 'tab'
- if allow_signup?
%li.nav-item
= link_to 'Register', '#register-pane', class: 'nav-link', 'data-toggle' => 'tab'
diff --git a/app/views/devise/shared/_tabs_normal.html.haml b/app/views/devise/shared/_tabs_normal.html.haml
index 284d4fa1b89..8745a4e9d3e 100644
--- a/app/views/devise/shared/_tabs_normal.html.haml
+++ b/app/views/devise/shared/_tabs_normal.html.haml
@@ -1,6 +1,6 @@
%ul.nav-links.new-session-tabs.nav-tabs.nav{ role: 'tablist' }
%li.nav-item{ role: 'presentation' }
- %a.nav-link.active{ href: '#login-pane', data: { toggle: 'tab' }, role: 'tab' } Sign in
+ %a.nav-link.qa-sign-in-tab.active{ href: '#login-pane', data: { toggle: 'tab' }, role: 'tab' } Sign in
- if allow_signup?
%li.nav-item{ role: 'presentation' }
- %a.nav-link{ href: '#register-pane', data: { toggle: 'tab' }, role: 'tab' } Register
+ %a.nav-link.qa-register-tab{ href: '#register-pane', data: { toggle: 'tab' }, role: 'tab' } Register
diff --git a/app/views/doorkeeper/applications/_form.html.haml b/app/views/doorkeeper/applications/_form.html.haml
index 0bc057a8864..78904f550c7 100644
--- a/app/views/doorkeeper/applications/_form.html.haml
+++ b/app/views/doorkeeper/applications/_form.html.haml
@@ -20,4 +20,4 @@
= render 'shared/tokens/scopes_form', prefix: 'doorkeeper_application', token: application, scopes: @scopes
.prepend-top-default
- = f.submit _('Save application'), class: "btn btn-create"
+ = f.submit _('Save application'), class: "btn btn-success"
diff --git a/app/views/doorkeeper/applications/index.html.haml b/app/views/doorkeeper/applications/index.html.haml
index b11f441b3ba..1f5c70a6c6e 100644
--- a/app/views/doorkeeper/applications/index.html.haml
+++ b/app/views/doorkeeper/applications/index.html.haml
@@ -16,6 +16,9 @@
= _('Add new application')
= render 'form', application: @application
%hr
+ - else
+ .bs-callout.bs-callout-disabled
+ = _('Adding new applications is disabled in your GitLab instance. Please contact your GitLab administrator to get the permission')
- if user_oauth_applications?
.oauth-applications
%h5
diff --git a/app/views/groups/_group_admin_settings.html.haml b/app/views/groups/_group_admin_settings.html.haml
index 935a8889d79..ff59013ed67 100644
--- a/app/views/groups/_group_admin_settings.html.haml
+++ b/app/views/groups/_group_admin_settings.html.haml
@@ -1,5 +1,5 @@
.form-group.row
- = f.label :lfs_enabled, 'Large File Storage', class: 'col-form-label col-sm-2'
+ = f.label :lfs_enabled, 'Large File Storage', class: 'col-form-label col-sm-2 pt-0'
.col-sm-10
.form-check
= f.check_box :lfs_enabled, checked: @group.lfs_enabled?, class: 'form-check-input'
@@ -11,7 +11,7 @@
%span.descr This setting can be overridden in each project.
.form-group.row
- = f.label :require_two_factor_authentication, 'Two-factor authentication', class: 'col-form-label col-sm-2'
+ = f.label :require_two_factor_authentication, 'Two-factor authentication', class: 'col-form-label col-sm-2 pt-0'
.col-sm-10
.form-check
= f.check_box :require_two_factor_authentication, class: 'form-check-input'
diff --git a/app/views/groups/group_members/_new_group_member.html.haml b/app/views/groups/group_members/_new_group_member.html.haml
index aa03f8365f9..04683ec5a9a 100644
--- a/app/views/groups/group_members/_new_group_member.html.haml
+++ b/app/views/groups/group_members/_new_group_member.html.haml
@@ -19,4 +19,4 @@
On this date, the member(s) will automatically lose access to this group and all of its projects.
.col-md-2
- = f.submit 'Add to group', class: "btn btn-create btn-block"
+ = f.submit 'Add to group', class: "btn btn-success btn-block"
diff --git a/app/views/groups/labels/index.html.haml b/app/views/groups/labels/index.html.haml
index 86178eb2ffd..003bd25dd06 100644
--- a/app/views/groups/labels/index.html.haml
+++ b/app/views/groups/labels/index.html.haml
@@ -7,7 +7,7 @@
- if can_admin_label
- content_for(:header_content) do
.nav-controls
- = link_to _('New label'), new_group_label_path(@group), class: "btn btn-new"
+ = link_to _('New label'), new_group_label_path(@group), class: "btn btn-success"
- if @labels.exists? || search.present?
#promote-label-modal
diff --git a/app/views/groups/milestones/_form.html.haml b/app/views/groups/milestones/_form.html.haml
index 6d35457a0ec..39e3af5f6d2 100644
--- a/app/views/groups/milestones/_form.html.haml
+++ b/app/views/groups/milestones/_form.html.haml
@@ -19,9 +19,9 @@
.form-actions
- if @milestone.new_record?
- = f.submit 'Create milestone', class: "btn-create btn"
+ = f.submit 'Create milestone', class: "btn-success btn"
= link_to "Cancel", group_milestones_path(@group), class: "btn btn-cancel"
- else
- = f.submit 'Update milestone', class: "btn-create btn"
+ = f.submit 'Update milestone', class: "btn-success btn"
= link_to "Cancel", group_milestone_path(@group, @milestone), class: "btn btn-cancel"
diff --git a/app/views/groups/milestones/index.html.haml b/app/views/groups/milestones/index.html.haml
index b6424df55cd..af4fe8f2ef8 100644
--- a/app/views/groups/milestones/index.html.haml
+++ b/app/views/groups/milestones/index.html.haml
@@ -6,7 +6,7 @@
.nav-controls
= render 'shared/milestones_sort_dropdown'
- if can?(current_user, :admin_milestone, @group)
- = link_to "New milestone", new_group_milestone_path(@group), class: "btn btn-new"
+ = link_to "New milestone", new_group_milestone_path(@group), class: "btn btn-success"
.milestones
%ul.content-list
diff --git a/app/views/groups/new.html.haml b/app/views/groups/new.html.haml
index 53f54db1ddf..683129fdf6e 100644
--- a/app/views/groups/new.html.haml
+++ b/app/views/groups/new.html.haml
@@ -36,5 +36,5 @@
= render 'shared/group_tips'
.form-actions
- = f.submit 'Create group', class: "btn btn-create"
+ = f.submit 'Create group', class: "btn btn-success"
= link_to 'Cancel', dashboard_groups_path, class: 'btn btn-cancel'
diff --git a/app/views/groups/settings/_permissions.html.haml b/app/views/groups/settings/_permissions.html.haml
index ffce2d4b14f..8dc88ec446c 100644
--- a/app/views/groups/settings/_permissions.html.haml
+++ b/app/views/groups/settings/_permissions.html.haml
@@ -10,7 +10,7 @@
= render 'shared/allow_request_access', form: f
.form-group.row
- %label.col-form-label.col-sm-2
+ %label.col-form-label.col-sm-2.pt-0
= s_('GroupSettings|Share with group lock')
.col-sm-10
.form-check
diff --git a/app/views/help/instance_configuration/_gitlab_pages.html.haml b/app/views/help/instance_configuration/_gitlab_pages.html.haml
index bdd77730dcc..94c25edaf82 100644
--- a/app/views/help/instance_configuration/_gitlab_pages.html.haml
+++ b/app/views/help/instance_configuration/_gitlab_pages.html.haml
@@ -8,7 +8,7 @@
%p
Below are the settings for
- = succeed('.') { link_to('Gitlab Pages', gitlab_pages[:url], target: '_blank') }
+ = succeed('.') { link_to('GitLab Pages', gitlab_pages[:url], target: '_blank') }
.table-responsive
%table
%thead
diff --git a/app/views/help/ui.html.haml b/app/views/help/ui.html.haml
index b32b602ceb3..506f580b246 100644
--- a/app/views/help/ui.html.haml
+++ b/app/views/help/ui.html.haml
@@ -189,7 +189,7 @@
%li
= link_to 'Sort by date', '#'
- = link_to 'New issue', '#', class: 'btn btn-new btn-inverted'
+ = link_to 'New issue', '#', class: 'btn btn-success btn-inverted'
.lead
Only nav links without button and search
diff --git a/app/views/import/fogbugz/new.html.haml b/app/views/import/fogbugz/new.html.haml
index b54b1af1e0c..626080c284b 100644
--- a/app/views/import/fogbugz/new.html.haml
+++ b/app/views/import/fogbugz/new.html.haml
@@ -21,4 +21,4 @@
.col-md-4
= password_field_tag :password, nil, class: 'form-control'
.form-actions
- = submit_tag _('Continue to the next step'), class: 'btn btn-create'
+ = submit_tag _('Continue to the next step'), class: 'btn btn-success'
diff --git a/app/views/import/fogbugz/new_user_map.html.haml b/app/views/import/fogbugz/new_user_map.html.haml
index ff2f989c509..8ed9dc68bb3 100644
--- a/app/views/import/fogbugz/new_user_map.html.haml
+++ b/app/views/import/fogbugz/new_user_map.html.haml
@@ -39,4 +39,4 @@
scope: :all, email_user: true, selected: user[:gitlab_user])
.form-actions
- = submit_tag _('Continue to the next step'), class: 'btn btn-create'
+ = submit_tag _('Continue to the next step'), class: 'btn btn-success'
diff --git a/app/views/import/gitea/new.html.haml b/app/views/import/gitea/new.html.haml
index 2b3102f9af9..a88b04eccbb 100644
--- a/app/views/import/gitea/new.html.haml
+++ b/app/views/import/gitea/new.html.haml
@@ -19,4 +19,4 @@
.col-sm-4
= text_field_tag :personal_access_token, nil, class: 'form-control'
.form-actions
- = submit_tag _('List Your Gitea Repositories'), class: 'btn btn-create'
+ = submit_tag _('List Your Gitea Repositories'), class: 'btn btn-success'
diff --git a/app/views/import/gitlab_projects/new.html.haml b/app/views/import/gitlab_projects/new.html.haml
index c4218f3d787..877d945a09b 100644
--- a/app/views/import/gitlab_projects/new.html.haml
+++ b/app/views/import/gitlab_projects/new.html.haml
@@ -41,5 +41,5 @@
= file_field_tag :file, class: ''
.row
.form-actions.col-sm-12
- = submit_tag _('Import project'), class: 'btn btn-create'
+ = submit_tag _('Import project'), class: 'btn btn-success'
= link_to _('Cancel'), new_project_path, class: 'btn btn-cancel'
diff --git a/app/views/import/google_code/new.html.haml b/app/views/import/google_code/new.html.haml
index fd6e4726fc5..7a6ad28f0aa 100644
--- a/app/views/import/google_code/new.html.haml
+++ b/app/views/import/google_code/new.html.haml
@@ -59,4 +59,4 @@
= _('Yes, let me map Google Code users to full names or GitLab users.')
%li
%p
- = submit_tag _('Continue to the next step'), class: "btn btn-create"
+ = submit_tag _('Continue to the next step'), class: "btn btn-success"
diff --git a/app/views/import/google_code/new_user_map.html.haml b/app/views/import/google_code/new_user_map.html.haml
index baaaf6bdc63..f523b993aa7 100644
--- a/app/views/import/google_code/new_user_map.html.haml
+++ b/app/views/import/google_code/new_user_map.html.haml
@@ -33,4 +33,4 @@
= text_area_tag :user_map, JSON.pretty_generate(@user_map), class: 'form-control', rows: 15
.form-actions
- = submit_tag _('Continue to the next step'), class: "btn btn-create"
+ = submit_tag _('Continue to the next step'), class: "btn btn-success"
diff --git a/app/views/layouts/nav/sidebar/_admin.html.haml b/app/views/layouts/nav/sidebar/_admin.html.haml
index ff25b040913..f912a32ee1a 100644
--- a/app/views/layouts/nav/sidebar/_admin.html.haml
+++ b/app/views/layouts/nav/sidebar/_admin.html.haml
@@ -7,14 +7,14 @@
.sidebar-context-title
= _('Admin Area')
%ul.sidebar-top-level-items
- = nav_link(controller: %w(dashboard admin projects users groups jobs runners gitaly_servers), html_options: {class: 'home'}) do
+ = nav_link(controller: %w(dashboard admin admin/projects users groups jobs runners gitaly_servers), html_options: {class: 'home'}) do
= link_to admin_root_path, class: 'shortcuts-tree' do
.nav-icon-container
= sprite_icon('overview')
%span.nav-item-name
= _('Overview')
%ul.sidebar-sub-level-items
- = nav_link(controller: %w(dashboard admin projects users groups jobs runners gitaly_servers), html_options: { class: "fly-out-top-item" } ) do
+ = nav_link(controller: %w(dashboard admin admin/projects users groups jobs runners gitaly_servers), html_options: { class: "fly-out-top-item" } ) do
= link_to admin_root_path do
%strong.fly-out-top-item-name
= _('Overview')
@@ -23,7 +23,7 @@
= link_to admin_root_path, title: _('Overview') do
%span
= _('Dashboard')
- = nav_link(controller: [:admin, :projects]) do
+ = nav_link(controller: [:admin, 'admin/projects']) do
= link_to admin_projects_path, title: _('Projects') do
%span
= _('Projects')
@@ -199,10 +199,54 @@
= sprite_icon('settings')
%span.nav-item-name
= _('Settings')
- %ul.sidebar-sub-level-items.is-fly-out-only
+
+ %ul.sidebar-sub-level-items
= nav_link(controller: :application_settings, html_options: { class: "fly-out-top-item" } ) do
= link_to admin_application_settings_path do
%strong.fly-out-top-item-name
= _('Settings')
+ %li.divider.fly-out-top-item
+ = nav_link(path: 'application_settings#show') do
+ = link_to admin_application_settings_path, title: _('General') do
+ %span
+ = _('General')
+ = nav_link(path: 'application_settings#integrations') do
+ = link_to integrations_admin_application_settings_path, title: _('Integrations') do
+ %span
+ = _('Integrations')
+ = nav_link(path: 'application_settings#repository') do
+ = link_to repository_admin_application_settings_path, title: _('Repository') do
+ %span
+ = _('Repository')
+ - if template_exists?('admin/application_settings/templates')
+ = nav_link(path: 'application_settings#templates') do
+ = link_to templates_admin_application_settings_path, title: _('Templates') do
+ %span
+ = _('Templates')
+ = nav_link(path: 'application_settings#ci_cd') do
+ = link_to ci_cd_admin_application_settings_path, title: _('CI/CD') do
+ %span
+ = _('CI/CD')
+ = nav_link(path: 'application_settings#reporting') do
+ = link_to reporting_admin_application_settings_path, title: _('Reporting') do
+ %span
+ = _('Reporting')
+ = nav_link(path: 'application_settings#metrics_and_profiling') do
+ = link_to metrics_and_profiling_admin_application_settings_path, title: _('Metrics and profiling') do
+ %span
+ = _('Metrics and profiling')
+ = nav_link(path: 'application_settings#network') do
+ = link_to network_admin_application_settings_path, title: _('Network') do
+ %span
+ = _('Network')
+ - if template_exists?('admin/application_settings/geo')
+ = nav_link(path: 'application_settings#geo') do
+ = link_to geo_admin_application_settings_path, title: _('Geo') do
+ %span
+ = _('Geo')
+ = nav_link(path: 'application_settings#preferences') do
+ = link_to preferences_admin_application_settings_path, title: _('Preferences') do
+ %span
+ = _('Preferences')
= render 'shared/sidebar_toggle_button'
diff --git a/app/views/layouts/nav/sidebar/_profile.html.haml b/app/views/layouts/nav/sidebar/_profile.html.haml
index d65f153b451..69167edb1df 100644
--- a/app/views/layouts/nav/sidebar/_profile.html.haml
+++ b/app/views/layouts/nav/sidebar/_profile.html.haml
@@ -28,18 +28,17 @@
= link_to profile_account_path do
%strong.fly-out-top-item-name
= _('Account')
- - if Gitlab::CurrentSettings.user_oauth_applications?
- = nav_link(controller: 'oauth/applications') do
- = link_to applications_profile_path do
- .nav-icon-container
- = sprite_icon('applications')
- %span.nav-item-name
- = _('Applications')
- %ul.sidebar-sub-level-items.is-fly-out-only
- = nav_link(controller: 'oauth/applications', html_options: { class: "fly-out-top-item" } ) do
- = link_to applications_profile_path do
- %strong.fly-out-top-item-name
- = _('Applications')
+ = nav_link(controller: 'oauth/applications') do
+ = link_to applications_profile_path do
+ .nav-icon-container
+ = sprite_icon('applications')
+ %span.nav-item-name
+ = _('Applications')
+ %ul.sidebar-sub-level-items.is-fly-out-only
+ = nav_link(controller: 'oauth/applications', html_options: { class: "fly-out-top-item" } ) do
+ = link_to applications_profile_path do
+ %strong.fly-out-top-item-name
+ = _('Applications')
= nav_link(controller: :chat_names) do
= link_to profile_chat_names_path do
.nav-icon-container
diff --git a/app/views/layouts/nav/sidebar/_project.html.haml b/app/views/layouts/nav/sidebar/_project.html.haml
index 30e0e9fca27..25cd53b378a 100644
--- a/app/views/layouts/nav/sidebar/_project.html.haml
+++ b/app/views/layouts/nav/sidebar/_project.html.haml
@@ -158,7 +158,7 @@
- if project_nav_tab? :pipelines
= nav_link(controller: [:pipelines, :builds, :jobs, :pipeline_schedules, :artifacts]) do
- = link_to project_pipelines_path(@project), class: 'shortcuts-pipelines' do
+ = link_to project_pipelines_path(@project), class: 'shortcuts-pipelines qa-link-pipelines' do
.nav-icon-container
= sprite_icon('rocket')
%span.nav-item-name
@@ -245,7 +245,7 @@
= link_to _('Auto DevOps'), help_page_path('topics/autodevops/index.md')
%span= _('uses Kubernetes clusters to deploy your code!')
%hr
- %button.btn.btn-create.btn-sm.dismiss-feature-highlight{ type: 'button' }
+ %button.btn.btn-success.btn-sm.dismiss-feature-highlight{ type: 'button' }
%span= _("Got it!")
= sprite_icon('thumb-up')
diff --git a/app/views/profiles/emails/index.html.haml b/app/views/profiles/emails/index.html.haml
index c8faf2b3af3..1823f191fb3 100644
--- a/app/views/profiles/emails/index.html.haml
+++ b/app/views/profiles/emails/index.html.haml
@@ -15,7 +15,7 @@
= f.label :email, class: 'label-bold'
= f.text_field :email, class: 'form-control'
.prepend-top-default
- = f.submit 'Add email address', class: 'btn btn-create'
+ = f.submit 'Add email address', class: 'btn btn-success'
%hr
%h4.prepend-top-0
Linked emails (#{@emails.count + 1})
diff --git a/app/views/profiles/gpg_keys/_form.html.haml b/app/views/profiles/gpg_keys/_form.html.haml
index aa9b0aad034..6c4cb614a2b 100644
--- a/app/views/profiles/gpg_keys/_form.html.haml
+++ b/app/views/profiles/gpg_keys/_form.html.haml
@@ -7,4 +7,4 @@
= f.text_area :key, class: "form-control", rows: 8, required: true, placeholder: "Don't paste the private part of the GPG key. Paste the public part which begins with '-----BEGIN PGP PUBLIC KEY BLOCK-----'."
.prepend-top-default
- = f.submit 'Add key', class: "btn btn-create"
+ = f.submit 'Add key', class: "btn btn-success"
diff --git a/app/views/profiles/keys/_form.html.haml b/app/views/profiles/keys/_form.html.haml
index 5207921d6fe..21eef08983c 100644
--- a/app/views/profiles/keys/_form.html.haml
+++ b/app/views/profiles/keys/_form.html.haml
@@ -5,10 +5,10 @@
.form-group
= f.label :key, class: 'label-bold'
%p= _("Paste your public SSH key, which is usually contained in the file '~/.ssh/id_rsa.pub' and begins with 'ssh-rsa'. Don't use your private SSH key.")
- = f.text_area :key, class: "form-control js-add-ssh-key-validation-input", rows: 8, required: true, placeholder: s_('Profiles|Typically starts with "ssh-rsa …"')
+ = f.text_area :key, class: "form-control js-add-ssh-key-validation-input qa-key-public-key-field", rows: 8, required: true, placeholder: s_('Profiles|Typically starts with "ssh-rsa …"')
.form-group
= f.label :title, class: 'label-bold'
- = f.text_field :title, class: "form-control input-lg", required: true, placeholder: s_('Profiles|e.g. My MacBook key')
+ = f.text_field :title, class: "form-control input-lg qa-key-title-field", required: true, placeholder: s_('Profiles|e.g. My MacBook key')
%p.form-text.text-muted= _('Name your individual key via a title')
.js-add-ssh-key-validation-warning.hide
@@ -16,7 +16,7 @@
%strong= _('Oops, are you sure?')
%p= s_("Profiles|This doesn't look like a public SSH key, are you sure you want to add it?")
- %button.btn.btn-create.js-add-ssh-key-validation-confirm-submit= _("Yes, add it")
+ %button.btn.btn-success.js-add-ssh-key-validation-confirm-submit= _("Yes, add it")
.prepend-top-default
- = f.submit s_('Profiles|Add key'), class: "btn btn-create js-add-ssh-key-validation-original-submit"
+ = f.submit s_('Profiles|Add key'), class: "btn btn-success js-add-ssh-key-validation-original-submit qa-add-key-button"
diff --git a/app/views/profiles/keys/_key_details.html.haml b/app/views/profiles/keys/_key_details.html.haml
index 2ac514d3f6f..88473c7f72d 100644
--- a/app/views/profiles/keys/_key_details.html.haml
+++ b/app/views/profiles/keys/_key_details.html.haml
@@ -24,4 +24,4 @@
= @key.key
.col-md-12
.float-right
- = link_to 'Remove', path_to_key(@key, is_admin), data: {confirm: 'Are you sure?'}, method: :delete, class: "btn btn-remove delete-key"
+ = link_to 'Remove', path_to_key(@key, is_admin), data: {confirm: 'Are you sure?'}, method: :delete, class: "btn btn-remove delete-key qa-delete-key-button"
diff --git a/app/views/profiles/passwords/edit.html.haml b/app/views/profiles/passwords/edit.html.haml
index 9c8cc9c059b..0b4b9841ea1 100644
--- a/app/views/profiles/passwords/edit.html.haml
+++ b/app/views/profiles/passwords/edit.html.haml
@@ -29,6 +29,6 @@
= f.label :password_confirmation, class: 'label-bold'
= f.password_field :password_confirmation, required: true, class: 'form-control'
.prepend-top-default.append-bottom-default
- = f.submit 'Save password', class: "btn btn-create append-right-10"
+ = f.submit 'Save password', class: "btn btn-success append-right-10"
- unless @user.password_automatically_set?
= link_to "I forgot my password", reset_profile_password_path, method: :put, class: "account-btn-link"
diff --git a/app/views/profiles/passwords/new.html.haml b/app/views/profiles/passwords/new.html.haml
index d98f09e2415..d265f3c44ba 100644
--- a/app/views/profiles/passwords/new.html.haml
+++ b/app/views/profiles/passwords/new.html.haml
@@ -22,4 +22,4 @@
.col-sm-10
= f.password_field :password_confirmation, required: true, class: 'form-control'
.form-actions
- = f.submit 'Set new password', class: "btn btn-create"
+ = f.submit 'Set new password', class: "btn btn-success"
diff --git a/app/views/profiles/preferences/show.html.haml b/app/views/profiles/preferences/show.html.haml
index fd6dd74e1c5..156c0d05b02 100644
--- a/app/views/profiles/preferences/show.html.haml
+++ b/app/views/profiles/preferences/show.html.haml
@@ -58,4 +58,4 @@
.form-text.text-muted
Choose what content you want to see on a project’s overview page
.form-group
- = f.submit 'Save changes', class: 'btn btn-save'
+ = f.submit 'Save changes', class: 'btn btn-success'
diff --git a/app/views/profiles/two_factor_auths/_codes.html.haml b/app/views/profiles/two_factor_auths/_codes.html.haml
index 30a22099bbc..fb4fff12027 100644
--- a/app/views/profiles/two_factor_auths/_codes.html.haml
+++ b/app/views/profiles/two_factor_auths/_codes.html.haml
@@ -12,4 +12,4 @@
.d-flex
= link_to 'Proceed', profile_account_path, class: 'btn btn-success append-right-10'
- = link_to 'Download codes', "data:text/plain;charset=utf-8,#{URI.encode(@codes.join("\n"))}", download: "gitlab-recovery-codes.txt", class: 'btn btn-default'
+ = link_to 'Download codes', "data:text/plain;charset=utf-8,#{CGI.escape(@codes.join("\n"))}", download: "gitlab-recovery-codes.txt", class: 'btn btn-default'
diff --git a/app/views/projects/_commit_button.html.haml b/app/views/projects/_commit_button.html.haml
index b387e38c1a6..1e27c71d20d 100644
--- a/app/views/projects/_commit_button.html.haml
+++ b/app/views/projects/_commit_button.html.haml
@@ -1,5 +1,5 @@
.form-actions
- = button_tag 'Commit changes', class: 'btn commit-btn js-commit-button btn-create'
+ = button_tag 'Commit changes', class: 'btn commit-btn js-commit-button btn-success'
= link_to 'Cancel', cancel_path,
class: 'btn btn-cancel', data: {confirm: leave_edit_message}
diff --git a/app/views/projects/_fork_suggestion.html.haml b/app/views/projects/_fork_suggestion.html.haml
index c855bfaf067..0b616a0c1ce 100644
--- a/app/views/projects/_fork_suggestion.html.haml
+++ b/app/views/projects/_fork_suggestion.html.haml
@@ -6,6 +6,6 @@
edit
files in this project directly. Please fork this project,
make your changes there, and submit a merge request.
- = link_to 'Fork', nil, method: :post, class: 'js-fork-suggestion-button btn btn-grouped btn-inverted btn-new'
+ = link_to 'Fork', nil, method: :post, class: 'js-fork-suggestion-button btn btn-grouped btn-inverted btn-success'
%button.js-cancel-fork-suggestion-button.btn.btn-grouped{ type: 'button' }
Cancel
diff --git a/app/views/projects/_new_project_fields.html.haml b/app/views/projects/_new_project_fields.html.haml
index 001e65c0f66..db07c475866 100644
--- a/app/views/projects/_new_project_fields.html.haml
+++ b/app/views/projects/_new_project_fields.html.haml
@@ -60,5 +60,5 @@
.option-description
Allows you to immediately clone this project’s repository. Skip this if you plan to push up an existing repository.
-= f.submit 'Create project', class: "btn btn-create project-submit", tabindex: 4
+= f.submit 'Create project', class: "btn btn-success project-submit", tabindex: 4
= link_to 'Cancel', dashboard_projects_path, class: 'btn btn-cancel'
diff --git a/app/views/projects/_readme.html.haml b/app/views/projects/_readme.html.haml
index 705338c083e..32624ac225b 100644
--- a/app/views/projects/_readme.html.haml
+++ b/app/views/projects/_readme.html.haml
@@ -20,4 +20,4 @@
distributed with computer software, forming part of its documentation.
GitLab will render it here instead of this message.
%p
- = link_to "Add Readme", @project.add_readme_path, class: 'btn btn-new'
+ = link_to "Add Readme", @project.add_readme_path, class: 'btn btn-success'
diff --git a/app/views/projects/blob/_new_dir.html.haml b/app/views/projects/blob/_new_dir.html.haml
index 6f3a691518b..e9010dc63fc 100644
--- a/app/views/projects/blob/_new_dir.html.haml
+++ b/app/views/projects/blob/_new_dir.html.haml
@@ -15,7 +15,7 @@
= render 'shared/new_commit_form', placeholder: _("Add new directory")
.form-actions
- = submit_tag _("Create directory"), class: 'btn btn-create'
+ = submit_tag _("Create directory"), class: 'btn btn-success'
= link_to "Cancel", '#', class: "btn btn-cancel", "data-dismiss" => "modal"
= render 'shared/projects/edit_information'
diff --git a/app/views/projects/blob/_upload.html.haml b/app/views/projects/blob/_upload.html.haml
index 0a5c73c9037..d2b3c8ef96b 100644
--- a/app/views/projects/blob/_upload.html.haml
+++ b/app/views/projects/blob/_upload.html.haml
@@ -20,7 +20,7 @@
= render 'shared/new_commit_form', placeholder: placeholder
.form-actions
- = button_tag class: 'btn btn-create btn-upload-file', id: 'submit-all', type: 'button' do
+ = button_tag class: 'btn btn-success btn-upload-file', id: 'submit-all', type: 'button' do
= icon('spin spinner', class: 'js-loading-icon hidden' )
= button_title
= link_to _("Cancel"), '#', class: "btn btn-cancel", "data-dismiss" => "modal"
diff --git a/app/views/projects/branches/index.html.haml b/app/views/projects/branches/index.html.haml
index d6568c9f64a..ca867961f6b 100644
--- a/app/views/projects/branches/index.html.haml
+++ b/app/views/projects/branches/index.html.haml
@@ -41,7 +41,7 @@
data: { confirm: s_('Branches|Deleting the merged branches cannot be undone. Are you sure?'),
container: 'body' } do
= s_('Branches|Delete merged branches')
- = link_to new_project_branch_path(@project), class: 'btn btn-create' do
+ = link_to new_project_branch_path(@project), class: 'btn btn-success' do
= s_('Branches|New branch')
- if can?(current_user, :admin_project, @project)
diff --git a/app/views/projects/branches/new.html.haml b/app/views/projects/branches/new.html.haml
index 65b414c8af2..500536a5dbc 100644
--- a/app/views/projects/branches/new.html.haml
+++ b/app/views/projects/branches/new.html.haml
@@ -26,7 +26,7 @@
= render 'shared/ref_dropdown', dropdown_class: 'wide'
.form-text.text-muted Existing branch name, tag, or commit SHA
.form-actions
- = button_tag 'Create branch', class: 'btn btn-create', tabindex: 3
+ = button_tag 'Create branch', class: 'btn btn-success', tabindex: 3
= link_to 'Cancel', project_branches_path(@project), class: 'btn btn-cancel'
-# haml-lint:disable InlineJavaScript
%script#availableRefs{ type: "application/json" }= @project.repository.ref_names.to_json.html_safe
diff --git a/app/views/projects/commit/_change.html.haml b/app/views/projects/commit/_change.html.haml
index afd70ef5774..e71615dd1c5 100644
--- a/app/views/projects/commit/_change.html.haml
+++ b/app/views/projects/commit/_change.html.haml
@@ -33,7 +33,7 @@
- else
= hidden_field_tag 'create_merge_request', 1, id: nil
.form-actions
- = submit_tag label, class: 'btn btn-create'
+ = submit_tag label, class: 'btn btn-success'
= link_to _("Cancel"), '#', class: "btn btn-cancel", "data-dismiss" => "modal"
= render 'shared/projects/edit_information'
diff --git a/app/views/projects/compare/_form.html.haml b/app/views/projects/compare/_form.html.haml
index 07112c98804..d24ee4a3251 100644
--- a/app/views/projects/compare/_form.html.haml
+++ b/app/views/projects/compare/_form.html.haml
@@ -22,7 +22,7 @@
.dropdown-toggle-text.str-truncated= params[:from] || _("Select branch/tag")
= render 'shared/ref_dropdown'
&nbsp;
- = button_tag s_("CompareBranches|Compare"), class: "btn btn-create commits-compare-btn"
+ = button_tag s_("CompareBranches|Compare"), class: "btn btn-success commits-compare-btn"
- if @merge_request.present?
= link_to _("View open merge request"), project_merge_request_path(@project, @merge_request), class: 'prepend-left-10 btn'
- elsif create_mr_button?
diff --git a/app/views/projects/deploy_keys/_form.html.haml b/app/views/projects/deploy_keys/_form.html.haml
index f8ab0c1ec54..568930595a2 100644
--- a/app/views/projects/deploy_keys/_form.html.haml
+++ b/app/views/projects/deploy_keys/_form.html.haml
@@ -21,4 +21,4 @@
Allow this key to push to repository as well? (Default only allows pull access.)
.form-group.row
- = f.submit "Add key", class: "btn-create btn"
+ = f.submit "Add key", class: "btn-success btn"
diff --git a/app/views/projects/deploy_keys/edit.html.haml b/app/views/projects/deploy_keys/edit.html.haml
index e009b6fef0e..3e7872ebc1c 100644
--- a/app/views/projects/deploy_keys/edit.html.haml
+++ b/app/views/projects/deploy_keys/edit.html.haml
@@ -6,5 +6,5 @@
= form_for [@project.namespace.becomes(Namespace), @project, @deploy_key], html: { class: 'js-requires-input' } do |f|
= render partial: 'shared/deploy_keys/form', locals: { form: f, deploy_key: @deploy_key }
.form-actions
- = f.submit 'Save changes', class: 'btn-save btn'
+ = f.submit 'Save changes', class: 'btn-success btn'
= link_to 'Cancel', project_settings_repository_path(@project), class: 'btn btn-cancel'
diff --git a/app/views/projects/edit.html.haml b/app/views/projects/edit.html.haml
index acdde9e0f70..96ab582b050 100644
--- a/app/views/projects/edit.html.haml
+++ b/app/views/projects/edit.html.haml
@@ -59,7 +59,7 @@
- if @project.avatar?
%hr
= link_to _('Remove avatar'), project_avatar_path(@project), data: { confirm: _("Avatar will be removed. Are you sure?") }, method: :delete, class: "btn btn-danger btn-inverted"
- = f.submit 'Save changes', class: "btn btn-success js-btn-save-general-project-settings"
+ = f.submit 'Save changes', class: "btn btn-success js-btn-success-general-project-settings"
%section.settings.sharing-permissions.no-animate#js-shared-permissions{ class: ('expanded' if expanded) }
.settings-header
@@ -75,7 +75,7 @@
-# haml-lint:disable InlineJavaScript
%script.js-project-permissions-form-data{ type: "application/json" }= project_permissions_panel_data_json(@project)
.js-project-permissions-form
- = f.submit 'Save changes', class: "btn btn-save"
+ = f.submit 'Save changes', class: "btn btn-success"
= render_if_exists 'projects/issues_settings'
@@ -93,7 +93,7 @@
= form_for [@project.namespace.becomes(Namespace), @project], remote: true, html: { multipart: true, class: "merge-request-settings-form" }, authenticity_token: true do |f|
%input{ name: 'update_section', type: 'hidden', value: 'js-merge-request-settings' }
= render 'projects/merge_request_settings', form: f
- = f.submit 'Save changes', class: "btn btn-save qa-save-merge-request-changes"
+ = f.submit 'Save changes', class: "btn btn-success qa-save-merge-request-changes"
= render_if_exists 'projects/service_desk_settings'
diff --git a/app/views/projects/environments/_form.html.haml b/app/views/projects/environments/_form.html.haml
index 0586dbdf0e2..f942b936037 100644
--- a/app/views/projects/environments/_form.html.haml
+++ b/app/views/projects/environments/_form.html.haml
@@ -18,5 +18,5 @@
= f.url_field :external_url, class: 'form-control'
.form-actions
- = f.submit 'Save', class: 'btn btn-save'
+ = f.submit 'Save', class: 'btn btn-success'
= link_to 'Cancel', project_environments_path(@project), class: 'btn btn-cancel'
diff --git a/app/views/projects/forks/index.html.haml b/app/views/projects/forks/index.html.haml
index 57afc7ac9c3..b44ea89510b 100644
--- a/app/views/projects/forks/index.html.haml
+++ b/app/views/projects/forks/index.html.haml
@@ -30,11 +30,11 @@
- if current_user && can?(current_user, :fork_project, @project)
- if current_user.already_forked?(@project) && current_user.manageable_namespaces.size < 2
- = link_to namespace_project_path(current_user, current_user.fork_of(@project)), title: 'Go to your fork', class: 'btn btn-new' do
+ = link_to namespace_project_path(current_user, current_user.fork_of(@project)), title: 'Go to your fork', class: 'btn btn-success' do
= sprite_icon('fork', size: 12)
%span Fork
- else
- = link_to new_project_fork_path(@project), title: "Fork project", class: 'btn btn-new' do
+ = link_to new_project_fork_path(@project), title: "Fork project", class: 'btn btn-success' do
= sprite_icon('fork', size: 12)
%span Fork
diff --git a/app/views/projects/hooks/_index.html.haml b/app/views/projects/hooks/_index.html.haml
index 5990582fd55..0ab7863b77c 100644
--- a/app/views/projects/hooks/_index.html.haml
+++ b/app/views/projects/hooks/_index.html.haml
@@ -9,7 +9,7 @@
.col-lg-8.append-bottom-default
= form_for @hook, as: :hook, url: polymorphic_path([@project.namespace.becomes(Namespace), @project, :hooks]) do |f|
= render partial: 'shared/web_hooks/form', locals: { form: f, hook: @hook }
- = f.submit 'Add webhook', class: 'btn btn-create'
+ = f.submit 'Add webhook', class: 'btn btn-success'
%hr
%h5.prepend-top-default
diff --git a/app/views/projects/hooks/edit.html.haml b/app/views/projects/hooks/edit.html.haml
index c31aef60453..57311284e11 100644
--- a/app/views/projects/hooks/edit.html.haml
+++ b/app/views/projects/hooks/edit.html.haml
@@ -11,7 +11,7 @@
= form_for [@project.namespace.becomes(Namespace), @project, @hook], as: :hook, url: project_hook_path(@project, @hook) do |f|
= render partial: 'shared/web_hooks/form', locals: { form: f, hook: @hook }
- = f.submit 'Save changes', class: 'btn btn-create'
+ = f.submit 'Save changes', class: 'btn btn-success'
= render 'shared/web_hooks/test_button', triggers: ProjectHook.triggers, hook: @hook
= link_to 'Remove', project_hook_path(@project, @hook), method: :delete, class: 'btn btn-remove float-right', data: { confirm: 'Are you sure?' }
diff --git a/app/views/projects/imports/new.html.haml b/app/views/projects/imports/new.html.haml
index 8ce822c43b7..1c50cfbde85 100644
--- a/app/views/projects/imports/new.html.haml
+++ b/app/views/projects/imports/new.html.haml
@@ -16,4 +16,4 @@
= render "shared/import_form", f: f
.form-actions
- = f.submit 'Start import', class: "btn btn-create", tabindex: 4
+ = f.submit 'Start import', class: "btn btn-success", tabindex: 4
diff --git a/app/views/projects/issues/_issue.html.haml b/app/views/projects/issues/_issue.html.haml
index 8a14146cb87..31c72f2f759 100644
--- a/app/views/projects/issues/_issue.html.haml
+++ b/app/views/projects/issues/_issue.html.haml
@@ -2,9 +2,9 @@
.issue-box
- if @can_bulk_update
.issue-check.hidden
- = check_box_tag dom_id(issue, "selected"), nil, false, 'data-id' => issue.id, class: "selected_issue"
- .issue-info-container
- .issue-main-info
+ = check_box_tag dom_id(issue, "selected"), nil, false, 'data-id' => issue.id, class: "selected-issuable"
+ .issuable-info-container
+ .issuable-main-info
.issue-title.title
%span.issue-title-text
- if issue.confidential?
diff --git a/app/views/projects/issues/_nav_btns.html.haml b/app/views/projects/issues/_nav_btns.html.haml
index 0dd2d2e6c5d..e4a0d4b8479 100644
--- a/app/views/projects/issues/_nav_btns.html.haml
+++ b/app/views/projects/issues/_nav_btns.html.haml
@@ -6,6 +6,6 @@
= link_to "New issue", new_project_issue_path(@project,
issue: { assignee_id: finder.assignee.try(:id),
milestone_id: finder.milestones.first.try(:id) }),
- class: "btn btn-new",
+ class: "btn btn-success",
title: "New issue",
id: "new_issue_link"
diff --git a/app/views/projects/issues/show.html.haml b/app/views/projects/issues/show.html.haml
index b81d1a188f0..c39fd0063be 100644
--- a/app/views/projects/issues/show.html.haml
+++ b/app/views/projects/issues/show.html.haml
@@ -55,7 +55,7 @@
- if can_report_spam
= link_to 'Submit as spam', mark_as_spam_project_issue_path(@project, @issue), method: :post, class: 'd-none d-sm-none d-md-block btn btn-grouped btn-spam', title: 'Submit as spam'
- if can_create_issue
- = link_to new_project_issue_path(@project), class: 'd-none d-sm-none d-md-block btn btn-grouped new-issue-link btn-new btn-inverted', title: 'New issue', id: 'new_issue_link' do
+ = link_to new_project_issue_path(@project), class: 'd-none d-sm-none d-md-block btn btn-grouped new-issue-link btn-success btn-inverted', title: 'New issue', id: 'new_issue_link' do
New issue
.issue-details.issuable-details
diff --git a/app/views/projects/jobs/_header.html.haml b/app/views/projects/jobs/_header.html.haml
index b83e8dddccb..e7245622b80 100644
--- a/app/views/projects/jobs/_header.html.haml
+++ b/app/views/projects/jobs/_header.html.haml
@@ -24,7 +24,7 @@
- if show_controls
.nav-controls
- if can?(current_user, :create_issue, @project) && @build.failed?
- = link_to "New issue", new_project_issue_path(@project, issue: build_failed_issue_options), class: 'btn btn-new btn-inverted'
+ = link_to "New issue", new_project_issue_path(@project, issue: build_failed_issue_options), class: 'btn btn-success btn-inverted'
- if can?(current_user, :update_build, @build) && @build.retryable?
= link_to "Retry job", retry_project_job_path(@project, @build), class: 'btn btn-inverted-secondary', method: :post
%button.btn.btn-default.float-right.d-block.d-sm-none.d-md-none.build-gutter-toggle.js-sidebar-build-toggle{ role: "button", type: "button" }
diff --git a/app/views/projects/jobs/show.html.haml b/app/views/projects/jobs/show.html.haml
index 078f40c4477..5321bc46e73 100644
--- a/app/views/projects/jobs/show.html.haml
+++ b/app/views/projects/jobs/show.html.haml
@@ -3,6 +3,9 @@
- breadcrumb_title "##{@build.id}"
- page_title "#{@build.name} (##{@build.id})", "Jobs"
+- content_for :page_specific_javascripts do
+ = stylesheet_link_tag 'page_bundles/xterm'
+
%div{ class: container_class }
.build-page.js-build-page
#js-build-header-vue
@@ -10,7 +13,7 @@
- unless @build.any_runners_online?
.bs-callout.bs-callout-warning.js-build-stuck
%p
- - if no_runners_for_project?(@build.project)
+ - if @project.any_runners?
This job is stuck, because the project doesn't have any runners online assigned to it.
- elsif @build.tags.any?
This job is stuck, because you don't have any active runners online with any of these tags assigned to them:
diff --git a/app/views/projects/labels/index.html.haml b/app/views/projects/labels/index.html.haml
index 1bfd8a85f0f..683dda4f166 100644
--- a/app/views/projects/labels/index.html.haml
+++ b/app/views/projects/labels/index.html.haml
@@ -6,7 +6,7 @@
- if can_admin_label
- content_for(:header_content) do
.nav-controls
- = link_to _('New label'), new_project_label_path(@project), class: "btn btn-new"
+ = link_to _('New label'), new_project_label_path(@project), class: "btn btn-success"
- if @labels.exists? || @prioritized_labels.exists? || search.present?
#promote-label-modal
diff --git a/app/views/projects/mattermosts/_team_selection.html.haml b/app/views/projects/mattermosts/_team_selection.html.haml
index 37c09f12f63..d0a7f89df31 100644
--- a/app/views/projects/mattermosts/_team_selection.html.haml
+++ b/app/views/projects/mattermosts/_team_selection.html.haml
@@ -43,4 +43,4 @@
.clearfix
.float-right
= link_to 'Cancel', edit_project_service_path(@project, @service), class: 'btn btn-lg'
- = f.submit 'Install', class: 'btn btn-save btn-lg'
+ = f.submit 'Install', class: 'btn btn-success btn-lg'
diff --git a/app/views/projects/merge_requests/_merge_request.html.haml b/app/views/projects/merge_requests/_merge_request.html.haml
index cd3d896fff2..faa070d0389 100644
--- a/app/views/projects/merge_requests/_merge_request.html.haml
+++ b/app/views/projects/merge_requests/_merge_request.html.haml
@@ -1,10 +1,10 @@
%li{ id: dom_id(merge_request), class: mr_css_classes(merge_request), data: { labels: merge_request.label_ids, id: merge_request.id } }
- if @can_bulk_update
.issue-check.hidden
- = check_box_tag dom_id(merge_request, "selected"), nil, false, 'data-id' => merge_request.id, class: "selected_issue"
+ = check_box_tag dom_id(merge_request, "selected"), nil, false, 'data-id' => merge_request.id, class: "selected-issuable"
- .issue-info-container
- .issue-main-info
+ .issuable-info-container
+ .issuable-main-info
.merge-request-title.title
%span.merge-request-title-text
= link_to merge_request.title, merge_request_path(merge_request)
diff --git a/app/views/projects/merge_requests/_nav_btns.html.haml b/app/views/projects/merge_requests/_nav_btns.html.haml
index e73dab8ad4a..b7498216334 100644
--- a/app/views/projects/merge_requests/_nav_btns.html.haml
+++ b/app/views/projects/merge_requests/_nav_btns.html.haml
@@ -1,5 +1,5 @@
- if @can_bulk_update
= button_tag "Edit merge requests", class: "btn append-right-10 js-bulk-update-toggle"
- if merge_project
- = link_to new_merge_request_path, class: "btn btn-new", title: "New merge request" do
+ = link_to new_merge_request_path, class: "btn btn-success", title: "New merge request" do
New merge request
diff --git a/app/views/projects/merge_requests/creations/_new_compare.html.haml b/app/views/projects/merge_requests/creations/_new_compare.html.haml
index afa7eb06cb4..1fd71a38472 100644
--- a/app/views/projects/merge_requests/creations/_new_compare.html.haml
+++ b/app/views/projects/merge_requests/creations/_new_compare.html.haml
@@ -61,4 +61,4 @@
- if @merge_request.errors.any?
= form_errors(@merge_request)
- = f.submit 'Compare branches and continue', class: "btn btn-new mr-compare-btn"
+ = f.submit 'Compare branches and continue', class: "btn btn-success mr-compare-btn"
diff --git a/app/views/projects/merge_requests/diffs/_diffs.html.haml b/app/views/projects/merge_requests/diffs/_diffs.html.haml
index bf3df0abf86..9ebd91dea0b 100644
--- a/app/views/projects/merge_requests/diffs/_diffs.html.haml
+++ b/app/views/projects/merge_requests/diffs/_diffs.html.haml
@@ -14,7 +14,7 @@
%span.ref-name= @merge_request.source_branch
and
%span.ref-name= @merge_request.target_branch
- .text-center= link_to 'Create commit', project_new_blob_path(@project, @merge_request.source_branch), class: 'btn btn-save'
+ .text-center= link_to 'Create commit', project_new_blob_path(@project, @merge_request.source_branch), class: 'btn btn-success'
- else
- diff_viewable = @merge_request_diff ? @merge_request_diff.viewable? : true
- if diff_viewable
diff --git a/app/views/projects/milestones/_form.html.haml b/app/views/projects/milestones/_form.html.haml
index 28f0a167128..ebd3229e42b 100644
--- a/app/views/projects/milestones/_form.html.haml
+++ b/app/views/projects/milestones/_form.html.haml
@@ -20,8 +20,8 @@
.form-actions
- if @milestone.new_record?
- = f.submit 'Create milestone', class: "btn-create btn qa-milestone-create-button"
+ = f.submit 'Create milestone', class: "btn-success btn qa-milestone-create-button"
= link_to "Cancel", project_milestones_path(@project), class: "btn btn-cancel"
- else
- = f.submit 'Save changes', class: "btn-save btn"
+ = f.submit 'Save changes', class: "btn-success btn"
= link_to "Cancel", project_milestone_path(@project, @milestone), class: "btn btn-cancel"
diff --git a/app/views/projects/milestones/index.html.haml b/app/views/projects/milestones/index.html.haml
index 26d2ea8447b..57f3c640696 100644
--- a/app/views/projects/milestones/index.html.haml
+++ b/app/views/projects/milestones/index.html.haml
@@ -8,7 +8,7 @@
.nav-controls
= render 'shared/milestones_sort_dropdown'
- if can?(current_user, :admin_milestone, @project)
- = link_to new_project_milestone_path(@project), class: "btn btn-new qa-new-project-milestone", title: 'New milestone' do
+ = link_to new_project_milestone_path(@project), class: "btn btn-success qa-new-project-milestone", title: 'New milestone' do
New milestone
.milestones
diff --git a/app/views/projects/mirrors/_mirror_repos.html.haml b/app/views/projects/mirrors/_mirror_repos.html.haml
index c6764c7607a..d523df1cd90 100644
--- a/app/views/projects/mirrors/_mirror_repos.html.haml
+++ b/app/views/projects/mirrors/_mirror_repos.html.haml
@@ -32,7 +32,7 @@
= link_to icon('question-circle'), help_page_path('user/project/protected_branches')
.panel-footer
- = f.submit _('Mirror repository'), class: 'btn btn-create', name: :update_remote_mirror
+ = f.submit _('Mirror repository'), class: 'btn btn-success', name: :update_remote_mirror
.panel.panel-default
.table-responsive
diff --git a/app/views/projects/pages/show.html.haml b/app/views/projects/pages/show.html.haml
index 7e1a3b9bea6..88ab486a248 100644
--- a/app/views/projects/pages/show.html.haml
+++ b/app/views/projects/pages/show.html.haml
@@ -4,7 +4,7 @@
Pages
- if can?(current_user, :update_pages, @project) && (Gitlab.config.pages.external_http || Gitlab.config.pages.external_https)
- = link_to new_project_pages_domain_path(@project), class: 'btn btn-new float-right', title: 'New Domain' do
+ = link_to new_project_pages_domain_path(@project), class: 'btn btn-success float-right', title: 'New Domain' do
New Domain
%p.light
diff --git a/app/views/projects/pages_domains/edit.html.haml b/app/views/projects/pages_domains/edit.html.haml
index ee70de22f13..342b1482df7 100644
--- a/app/views/projects/pages_domains/edit.html.haml
+++ b/app/views/projects/pages_domains/edit.html.haml
@@ -8,4 +8,4 @@
= form_for [@project.namespace.becomes(Namespace), @project, @domain], html: { class: 'fieldset-form' } do |f|
= render 'form', { f: f }
.form-actions
- = f.submit 'Save Changes', class: "btn btn-save"
+ = f.submit 'Save Changes', class: "btn btn-success"
diff --git a/app/views/projects/pages_domains/new.html.haml b/app/views/projects/pages_domains/new.html.haml
index 376ce3f68aa..94ad1470052 100644
--- a/app/views/projects/pages_domains/new.html.haml
+++ b/app/views/projects/pages_domains/new.html.haml
@@ -7,6 +7,6 @@
= form_for [@project.namespace.becomes(Namespace), @project, @domain], html: { class: 'fieldset-form' } do |f|
= render 'form', { f: f }
.form-actions
- = f.submit 'Create New Domain', class: "btn btn-save"
+ = f.submit 'Create New Domain', class: "btn btn-success"
.float-right
= link_to _('Cancel'), project_pages_path(@project), class: 'btn btn-cancel'
diff --git a/app/views/projects/pipeline_schedules/_form.html.haml b/app/views/projects/pipeline_schedules/_form.html.haml
index 9a981d53ab6..259979417e0 100644
--- a/app/views/projects/pipeline_schedules/_form.html.haml
+++ b/app/views/projects/pipeline_schedules/_form.html.haml
@@ -39,5 +39,5 @@
= f.check_box :active, required: false, value: @schedule.active?
= _('Active')
.footer-block.row-content-block
- = f.submit _('Save pipeline schedule'), class: 'btn btn-create', tabindex: 3
+ = f.submit _('Save pipeline schedule'), class: 'btn btn-success', tabindex: 3
= link_to _('Cancel'), pipeline_schedules_path(@project), class: 'btn btn-cancel'
diff --git a/app/views/projects/pipeline_schedules/index.html.haml b/app/views/projects/pipeline_schedules/index.html.haml
index 3677666070e..0580c15ad15 100644
--- a/app/views/projects/pipeline_schedules/index.html.haml
+++ b/app/views/projects/pipeline_schedules/index.html.haml
@@ -11,7 +11,7 @@
- if can?(current_user, :create_pipeline_schedule, @project)
.nav-controls
- = link_to new_project_pipeline_schedule_path(@project), class: 'btn btn-create' do
+ = link_to new_project_pipeline_schedule_path(@project), class: 'btn btn-success' do
%span= _('New schedule')
- if @schedules.present?
diff --git a/app/views/projects/project_members/_new_project_group.html.haml b/app/views/projects/project_members/_new_project_group.html.haml
index 7de24ec5ad2..74570769117 100644
--- a/app/views/projects/project_members/_new_project_group.html.haml
+++ b/app/views/projects/project_members/_new_project_group.html.haml
@@ -17,4 +17,4 @@
.clearable-input
= text_field_tag :expires_at, nil, class: 'form-control js-access-expiration-date-groups', placeholder: _('Expiration date'), id: 'expires_at_groups'
%i.clear-icon.js-clear-input
- = submit_tag _("Invite"), class: "btn btn-create"
+ = submit_tag _("Invite"), class: "btn btn-success"
diff --git a/app/views/projects/project_members/_new_project_member.html.haml b/app/views/projects/project_members/_new_project_member.html.haml
index 6272687be1c..517fd249f6e 100644
--- a/app/views/projects/project_members/_new_project_member.html.haml
+++ b/app/views/projects/project_members/_new_project_member.html.haml
@@ -17,5 +17,5 @@
= label_tag :expires_at, 'Access expiration date', class: 'label-bold'
= text_field_tag :expires_at, nil, class: 'form-control js-access-expiration-date', placeholder: 'Expiration date'
%i.clear-icon.js-clear-input
- = f.submit "Add to project", class: "btn btn-create"
+ = f.submit "Add to project", class: "btn btn-success"
= link_to "Import", import_project_project_members_path(@project), class: "btn btn-default", title: "Import members from another project"
diff --git a/app/views/projects/project_members/import.html.haml b/app/views/projects/project_members/import.html.haml
index 6a52e72bfd8..8b93e81cd31 100644
--- a/app/views/projects/project_members/import.html.haml
+++ b/app/views/projects/project_members/import.html.haml
@@ -11,5 +11,5 @@
.col-sm-10= select_tag(:source_project_id, options_from_collection_for_select(@projects, :id, :name_with_namespace), prompt: "Select project", class: "select2 lg", required: true)
.form-actions
- = button_tag 'Import project members', class: "btn btn-create"
+ = button_tag 'Import project members', class: "btn btn-success"
= link_to "Cancel", project_project_members_path(@project), class: "btn btn-cancel"
diff --git a/app/views/projects/protected_branches/shared/_create_protected_branch.html.haml b/app/views/projects/protected_branches/shared/_create_protected_branch.html.haml
index df2dcf19ed4..c3b8f2f8964 100644
--- a/app/views/projects/protected_branches/shared/_create_protected_branch.html.haml
+++ b/app/views/projects/protected_branches/shared/_create_protected_branch.html.haml
@@ -30,4 +30,4 @@
= yield :push_access_levels
.card-footer
- = f.submit 'Protect', class: 'btn-create btn', disabled: true
+ = f.submit 'Protect', class: 'btn-success btn', disabled: true
diff --git a/app/views/projects/protected_tags/shared/_create_protected_tag.html.haml b/app/views/projects/protected_tags/shared/_create_protected_tag.html.haml
index f98781b77f4..b274c73d035 100644
--- a/app/views/projects/protected_tags/shared/_create_protected_tag.html.haml
+++ b/app/views/projects/protected_tags/shared/_create_protected_tag.html.haml
@@ -26,4 +26,4 @@
= yield :create_access_levels
.card-footer
- = f.submit 'Protect', class: 'btn-create btn', disabled: true
+ = f.submit 'Protect', class: 'btn-success btn', disabled: true
diff --git a/app/views/projects/releases/edit.html.haml b/app/views/projects/releases/edit.html.haml
index 8093cc2c2d7..52c6c7ec424 100644
--- a/app/views/projects/releases/edit.html.haml
+++ b/app/views/projects/releases/edit.html.haml
@@ -19,5 +19,5 @@
= render 'shared/notes/hints'
.error-alert
.prepend-top-default
- = f.submit 'Save changes', class: 'btn btn-save'
+ = f.submit 'Save changes', class: 'btn btn-success'
= link_to "Cancel", project_tag_path(@project, @tag.name), class: "btn btn-default btn-cancel"
diff --git a/app/views/projects/runners/_group_runners.html.haml b/app/views/projects/runners/_group_runners.html.haml
index 86de71c732b..a6c16c70313 100644
--- a/app/views/projects/runners/_group_runners.html.haml
+++ b/app/views/projects/runners/_group_runners.html.haml
@@ -28,7 +28,7 @@
- group_link = link_to _('Group CI/CD settings'), group_settings_ci_cd_path(@project.group)
= _('Group maintainers can register group runners in the %{link}').html_safe % { link: group_link }
- else
- = _('Ask your group maintainer to setup a group Runner.')
+ = _('Ask your group maintainer to set up a group Runner.')
- else
%h4.underlined-title
diff --git a/app/views/projects/settings/ci_cd/_form.html.haml b/app/views/projects/settings/ci_cd/_form.html.haml
index 9134257b631..ae923d8e6dc 100644
--- a/app/views/projects/settings/ci_cd/_form.html.haml
+++ b/app/views/projects/settings/ci_cd/_form.html.haml
@@ -121,7 +121,7 @@
go test -cover (Go)
%code coverage: \d+.\d+% of statements
- = f.submit _('Save changes'), class: "btn btn-save"
+ = f.submit _('Save changes'), class: "btn btn-success"
%hr
diff --git a/app/views/projects/snippets/_actions.html.haml b/app/views/projects/snippets/_actions.html.haml
index 4a3aa3dc626..ea963510a68 100644
--- a/app/views/projects/snippets/_actions.html.haml
+++ b/app/views/projects/snippets/_actions.html.haml
@@ -8,7 +8,7 @@
= link_to project_snippet_path(@project, @snippet), method: :delete, data: { confirm: _("Are you sure?") }, class: "btn btn-grouped btn-inverted btn-remove", title: _('Delete Snippet') do
= _('Delete')
- if can?(current_user, :create_project_snippet, @project)
- = link_to new_project_snippet_path(@project), class: 'btn btn-grouped btn-inverted btn-create', title: _("New snippet") do
+ = link_to new_project_snippet_path(@project), class: 'btn btn-grouped btn-inverted btn-success', title: _("New snippet") do
= _('New snippet')
- if @snippet.submittable_as_spam_by?(current_user)
= link_to _('Submit as spam'), mark_as_spam_project_snippet_path(@project, @snippet), method: :post, class: 'btn btn-grouped btn-spam', title: _('Submit as spam')
diff --git a/app/views/projects/snippets/index.html.haml b/app/views/projects/snippets/index.html.haml
index 1c4c73dc776..a4974d89c1a 100644
--- a/app/views/projects/snippets/index.html.haml
+++ b/app/views/projects/snippets/index.html.haml
@@ -7,6 +7,6 @@
.nav-controls
- if can?(current_user, :create_project_snippet, @project)
- = link_to _("New snippet"), new_project_snippet_path(@project), class: "btn btn-new", title: _("New snippet")
+ = link_to _("New snippet"), new_project_snippet_path(@project), class: "btn btn-success", title: _("New snippet")
= render 'snippets/snippets'
diff --git a/app/views/projects/tags/index.html.haml b/app/views/projects/tags/index.html.haml
index 20b4705521c..37535370940 100644
--- a/app/views/projects/tags/index.html.haml
+++ b/app/views/projects/tags/index.html.haml
@@ -25,7 +25,7 @@
%li
= link_to title, filter_tags_path(sort: value), class: ("is-active" if @sort == value)
- if can?(current_user, :push_code, @project)
- = link_to new_project_tag_path(@project), class: 'btn btn-create new-tag-btn' do
+ = link_to new_project_tag_path(@project), class: 'btn btn-success new-tag-btn' do
= s_('TagsPage|New tag')
= link_to project_tags_path(@project, rss_url_options), title: _("Tags feed"), class: 'btn rss-btn has-tooltip' do
= icon("rss")
diff --git a/app/views/projects/tags/new.html.haml b/app/views/projects/tags/new.html.haml
index da822ac5675..24724394259 100644
--- a/app/views/projects/tags/new.html.haml
+++ b/app/views/projects/tags/new.html.haml
@@ -41,7 +41,7 @@
.form-text.text-muted
= s_('TagsPage|Optionally, add release notes to the tag. They will be stored in the GitLab database and displayed on the tags page.')
.form-actions
- = button_tag s_('TagsPage|Create tag'), class: 'btn btn-create'
+ = button_tag s_('TagsPage|Create tag'), class: 'btn btn-success'
= link_to s_('TagsPage|Cancel'), project_tags_path(@project), class: 'btn btn-cancel'
-# haml-lint:disable InlineJavaScript
%script#availableRefs{ type: "application/json" }= @project.repository.ref_names.to_json.html_safe
diff --git a/app/views/projects/triggers/_form.html.haml b/app/views/projects/triggers/_form.html.haml
index 1a5fc56f429..a9abfac239c 100644
--- a/app/views/projects/triggers/_form.html.haml
+++ b/app/views/projects/triggers/_form.html.haml
@@ -8,4 +8,4 @@
.form-group
= f.label :key, "Description", class: "label-bold"
= f.text_field :description, class: "form-control", required: true, title: 'Trigger description is required.', placeholder: "Trigger description"
- = f.submit btn_text, class: "btn btn-save"
+ = f.submit btn_text, class: "btn btn-success"
diff --git a/app/views/projects/update.js.haml b/app/views/projects/update.js.haml
index e8681da6528..70f1bf8ef46 100644
--- a/app/views/projects/update.js.haml
+++ b/app/views/projects/update.js.haml
@@ -7,4 +7,4 @@
$(".project-edit-errors").html("#{escape_javascript(render('errors'))}");
$('.save-project-loader').hide();
$('.project-edit-container').show();
- $('.edit-project .js-btn-save-general-project-settings').enable();
+ $('.edit-project .js-btn-success-general-project-settings').enable();
diff --git a/app/views/projects/wikis/_form.html.haml b/app/views/projects/wikis/_form.html.haml
index 35872d70db4..7d8826e540c 100644
--- a/app/views/projects/wikis/_form.html.haml
+++ b/app/views/projects/wikis/_form.html.haml
@@ -51,10 +51,10 @@
.form-actions
- if @page && @page.persisted?
- = f.submit _("Save changes"), class: 'btn-save btn'
+ = f.submit _("Save changes"), class: 'btn-success btn'
.float-right
= link_to _("Cancel"), project_wiki_path(@project, @page), class: 'btn btn-cancel btn-grouped'
- else
- = f.submit s_("Wiki|Create page"), class: 'btn-create btn'
+ = f.submit s_("Wiki|Create page"), class: 'btn-success btn'
.float-right
= link_to _("Cancel"), project_wiki_path(@project, :home), class: 'btn btn-cancel'
diff --git a/app/views/projects/wikis/_main_links.html.haml b/app/views/projects/wikis/_main_links.html.haml
index 8d91f411f89..643b51e01d1 100644
--- a/app/views/projects/wikis/_main_links.html.haml
+++ b/app/views/projects/wikis/_main_links.html.haml
@@ -1,6 +1,6 @@
- if (@page && @page.persisted?)
- if can?(current_user, :create_wiki, @project)
- = link_to '#modal-new-wiki', class: "add-new-wiki btn btn-new", "data-toggle" => "modal" do
+ = link_to '#modal-new-wiki', class: "add-new-wiki btn btn-success", "data-toggle" => "modal" do
= s_("Wiki|New page")
= link_to project_wiki_history_path(@project, @page), class: "btn" do
= s_("Wiki|Page history")
diff --git a/app/views/projects/wikis/_new.html.haml b/app/views/projects/wikis/_new.html.haml
index 38382aae67c..dc12e368b35 100644
--- a/app/views/projects/wikis/_new.html.haml
+++ b/app/views/projects/wikis/_new.html.haml
@@ -15,4 +15,4 @@
= icon('lightbulb-o')
= s_("WikiNewPageTip|Tip: You can specify the full path for the new file. We will automatically create any missing directories.")
.form-actions
- = button_tag s_("Wiki|Create page"), class: "build-new-wiki btn btn-create"
+ = button_tag s_("Wiki|Create page"), class: "build-new-wiki btn btn-success"
diff --git a/app/views/projects/wikis/edit.html.haml b/app/views/projects/wikis/edit.html.haml
index e12b8f2858c..80aa1500d53 100644
--- a/app/views/projects/wikis/edit.html.haml
+++ b/app/views/projects/wikis/edit.html.haml
@@ -22,7 +22,7 @@
.nav-controls
- if can?(current_user, :create_wiki, @project)
- = link_to '#modal-new-wiki', class: "add-new-wiki btn btn-new", "data-toggle" => "modal" do
+ = link_to '#modal-new-wiki', class: "add-new-wiki btn btn-success", "data-toggle" => "modal" do
= s_("Wiki|New page")
- if @page.persisted?
= link_to project_wiki_history_path(@project, @page), class: "btn" do
diff --git a/app/views/shared/_new_project_item_select.html.haml b/app/views/shared/_new_project_item_select.html.haml
index d38d161047b..9bc67a7c715 100644
--- a/app/views/shared/_new_project_item_select.html.haml
+++ b/app/views/shared/_new_project_item_select.html.haml
@@ -1,7 +1,7 @@
- if any_projects?(@projects)
.project-item-select-holder.btn-group
- %a.btn.btn-new.new-project-item-link.qa-new-project-item-link{ href: '', data: { label: local_assigns[:label], type: local_assigns[:type] } }
+ %a.btn.btn-success.new-project-item-link.qa-new-project-item-link{ href: '', data: { label: local_assigns[:label], type: local_assigns[:type] } }
= icon('spinner spin')
= project_select_tag :project_path, class: "project-item-select", data: { include_groups: local_assigns[:include_groups], order_by: 'last_activity_at', relative_path: local_assigns[:path] }, with_feature_enabled: local_assigns[:with_feature_enabled]
- %button.btn.btn-new.new-project-item-select-button.qa-new-project-item-select-button
+ %button.btn.btn-success.new-project-item-select-button.qa-new-project-item-select-button
= icon('caret-down')
diff --git a/app/views/shared/_personal_access_tokens_form.html.haml b/app/views/shared/_personal_access_tokens_form.html.haml
index 58d310fac16..f4df7bdcd83 100644
--- a/app/views/shared/_personal_access_tokens_form.html.haml
+++ b/app/views/shared/_personal_access_tokens_form.html.haml
@@ -26,4 +26,4 @@
= render 'shared/tokens/scopes_form', prefix: 'personal_access_token', token: token, scopes: scopes
.prepend-top-default
- = f.submit "Create #{type} token", class: "btn btn-create"
+ = f.submit "Create #{type} token", class: "btn btn-success"
diff --git a/app/views/shared/_recaptcha_form.html.haml b/app/views/shared/_recaptcha_form.html.haml
index a0ba1afc284..10f358402c1 100644
--- a/app/views/shared/_recaptcha_form.html.haml
+++ b/app/views/shared/_recaptcha_form.html.haml
@@ -17,4 +17,4 @@
- if has_submit
.row-content-block.footer-block
- = f.submit "Submit #{humanized_resource_name}", class: 'btn btn-create'
+ = f.submit "Submit #{humanized_resource_name}", class: 'btn btn-success'
diff --git a/app/views/shared/_visibility_level.html.haml b/app/views/shared/_visibility_level.html.haml
index 01ce1225b8d..ba37b37a3b1 100644
--- a/app/views/shared/_visibility_level.html.haml
+++ b/app/views/shared/_visibility_level.html.haml
@@ -2,7 +2,7 @@
.form-group.row.visibility-level-setting
- if with_label
- = f.label :visibility_level, class: 'col-form-label col-sm-2' do
+ = f.label :visibility_level, class: 'col-form-label col-sm-2 pt-0' do
Visibility Level
= link_to icon('question-circle'), help_page_path("public_access/public_access")
%div{ :class => (with_label ? "col-sm-10" : "col-sm-12") }
diff --git a/app/views/shared/empty_states/_labels.html.haml b/app/views/shared/empty_states/_labels.html.haml
index e8749ee3956..b629ceafeb3 100644
--- a/app/views/shared/empty_states/_labels.html.haml
+++ b/app/views/shared/empty_states/_labels.html.haml
@@ -7,5 +7,5 @@
%h4= _("Labels can be applied to issues and merge requests to categorize them.")
%p= _("You can also star a label to make it a priority label.")
- if can?(current_user, :admin_label, @project)
- = link_to _('New label'), new_project_label_path(@project), class: 'btn btn-new', title: _('New label'), id: 'new_label_link'
+ = link_to _('New label'), new_project_label_path(@project), class: 'btn btn-success', title: _('New label'), id: 'new_label_link'
= link_to _('Generate a default set of labels'), generate_project_labels_path(@project), method: :post, class: 'btn btn-success btn-inverted', title: _('Generate a default set of labels'), id: 'generate_labels_link'
diff --git a/app/views/shared/empty_states/_merge_requests.html.haml b/app/views/shared/empty_states/_merge_requests.html.haml
index 186139f3526..421a1b2415b 100644
--- a/app/views/shared/empty_states/_merge_requests.html.haml
+++ b/app/views/shared/empty_states/_merge_requests.html.haml
@@ -17,7 +17,7 @@
- if project_select_button
= render 'shared/new_project_item_select', path: 'merge_requests/new', label: _('New merge request'), type: :merge_requests, with_feature_enabled: 'merge_requests'
- else
- = link_to _('New merge request'), button_path, class: 'btn btn-new', title: _('New merge request'), id: 'new_merge_request_link'
+ = link_to _('New merge request'), button_path, class: 'btn btn-success', title: _('New merge request'), id: 'new_merge_request_link'
- else
%h4.text-center
= _("There are no merge requests to show")
diff --git a/app/views/shared/empty_states/_wikis.html.haml b/app/views/shared/empty_states/_wikis.html.haml
index f1a41074c28..5351c9ce6a4 100644
--- a/app/views/shared/empty_states/_wikis.html.haml
+++ b/app/views/shared/empty_states/_wikis.html.haml
@@ -2,7 +2,7 @@
- if can?(current_user, :create_wiki, @project)
- create_path = project_wiki_path(@project, params[:id], { view: 'create' })
- - create_link = link_to s_('WikiEmpty|Create your first page'), create_path, class: 'btn btn-new', title: s_('WikiEmpty|Create your first page')
+ - create_link = link_to s_('WikiEmpty|Create your first page'), create_path, class: 'btn btn-success', title: s_('WikiEmpty|Create your first page')
= render layout: layout_path, locals: { image_path: 'illustrations/wiki_login_empty.svg' } do
%h4
@@ -13,7 +13,7 @@
- elsif can?(current_user, :read_issue, @project)
- issues_link = link_to s_('WikiEmptyIssueMessage|issue tracker'), project_issues_path(@project)
- - new_issue_link = link_to s_('WikiEmpty|Suggest wiki improvement'), new_project_issue_path(@project), class: 'btn btn-new', title: s_('WikiEmptyIssueMessage|Suggest wiki improvement')
+ - new_issue_link = link_to s_('WikiEmpty|Suggest wiki improvement'), new_project_issue_path(@project), class: 'btn btn-success', title: s_('WikiEmptyIssueMessage|Suggest wiki improvement')
= render layout: layout_path, locals: { image_path: 'illustrations/wiki_logout_empty.svg' } do
%h4
diff --git a/app/views/shared/issuable/_board_create_list_dropdown.html.haml b/app/views/shared/issuable/_board_create_list_dropdown.html.haml
index 23b2e1b91e5..4597d9439fa 100644
--- a/app/views/shared/issuable/_board_create_list_dropdown.html.haml
+++ b/app/views/shared/issuable/_board_create_list_dropdown.html.haml
@@ -1,5 +1,5 @@
.dropdown.prepend-left-10#js-add-list
- %button.btn.btn-create.btn-inverted.js-new-board-list{ type: "button", data: board_list_data }
+ %button.btn.btn-success.btn-inverted.js-new-board-list{ type: "button", data: board_list_data }
Add list
.dropdown-menu.dropdown-menu-paging.dropdown-menu-right.dropdown-menu-issues-board-new.dropdown-menu-selectable.js-tab-container-labels
= render partial: "shared/issuable/label_page_default", locals: { show_footer: true, show_create: true, show_boards_content: true, title: "Add list" }
diff --git a/app/views/shared/issuable/_form.html.haml b/app/views/shared/issuable/_form.html.haml
index b49e47a7266..5b28a43a361 100644
--- a/app/views/shared/issuable/_form.html.haml
+++ b/app/views/shared/issuable/_form.html.haml
@@ -69,9 +69,9 @@
%span.append-right-10
- if issuable.new_record?
- = form.submit "Submit #{issuable.class.model_name.human.downcase}", class: 'btn btn-create qa-issuable-create-button'
+ = form.submit "Submit #{issuable.class.model_name.human.downcase}", class: 'btn btn-success qa-issuable-create-button'
- else
- = form.submit 'Save changes', class: 'btn btn-save'
+ = form.submit 'Save changes', class: 'btn btn-success'
- if !issuable.persisted? && !issuable.project.empty_repo? && (guide_url = issuable.project.present.contribution_guide_path)
.inline.prepend-top-10
diff --git a/app/views/shared/issuable/_search_bar.html.haml b/app/views/shared/issuable/_search_bar.html.haml
index 9ce7f6fe269..659e03fd67d 100644
--- a/app/views/shared/issuable/_search_bar.html.haml
+++ b/app/views/shared/issuable/_search_bar.html.haml
@@ -34,7 +34,7 @@
%ul{ data: { dropdown: true } }
%li.filter-dropdown-item{ data: { action: 'submit' } }
%button.btn.btn-link
- = icon('search')
+ = sprite_icon('search')
%span
Press Enter or click to search
%ul.filter-dropdown{ data: { dynamic: true, dropdown: true } }
@@ -42,7 +42,8 @@
%button.btn.btn-link
-# Encapsulate static class name `{{icon}}` inside #{} to bypass
-# haml lint's ClassAttributeWithStaticValue
- %i.fa{ class: "#{'{{icon}}'}" }
+ %svg
+ %use{ 'xlink:href': "#{'{{icon}}'}" }
%span.js-filter-hint
{{hint}}
%span.js-filter-tag.dropdown-light-content
diff --git a/app/views/shared/issuable/_sidebar.html.haml b/app/views/shared/issuable/_sidebar.html.haml
index 0ca35ea1298..32b609eed0d 100644
--- a/app/views/shared/issuable/_sidebar.html.haml
+++ b/app/views/shared/issuable/_sidebar.html.haml
@@ -159,7 +159,7 @@
= dropdown_content
= dropdown_loading
= dropdown_footer add_content_class: true do
- %button.btn.btn-new.sidebar-move-issue-confirmation-button.js-move-issue-confirmation-button{ disabled: true }
+ %button.btn.btn-success.sidebar-move-issue-confirmation-button.js-move-issue-confirmation-button{ disabled: true }
= _('Move')
= icon('spinner spin', class: 'sidebar-move-issue-confirmation-loading-icon')
diff --git a/app/views/shared/issuable/form/_title.html.haml b/app/views/shared/issuable/form/_title.html.haml
index e49bdec386a..56c4b021eab 100644
--- a/app/views/shared/issuable/form/_title.html.haml
+++ b/app/views/shared/issuable/form/_title.html.haml
@@ -9,7 +9,7 @@
autocomplete: 'off', class: 'form-control pad qa-issuable-form-title', placeholder: _('Title')
- if issuable.respond_to?(:work_in_progress?)
- %p.form-text.text-muted
+ .form-text.text-muted
.js-wip-explanation
%a.js-toggle-wip{ href: '', tabindex: -1 }
Remove the
diff --git a/app/views/shared/labels/_form.html.haml b/app/views/shared/labels/_form.html.haml
index 2bf5efae1e6..335c34a4632 100644
--- a/app/views/shared/labels/_form.html.haml
+++ b/app/views/shared/labels/_form.html.haml
@@ -28,7 +28,7 @@
.form-actions
- if @label.persisted?
- = f.submit 'Save changes', class: 'btn btn-save js-save-button'
+ = f.submit 'Save changes', class: 'btn btn-success js-save-button'
- else
- = f.submit 'Create label', class: 'btn btn-create js-save-button'
+ = f.submit 'Create label', class: 'btn btn-success js-save-button'
= link_to 'Cancel', back_path, class: 'btn btn-cancel'
diff --git a/app/views/shared/notes/_comment_button.html.haml b/app/views/shared/notes/_comment_button.html.haml
index ed336df4e9d..0674c822d63 100644
--- a/app/views/shared/notes/_comment_button.html.haml
+++ b/app/views/shared/notes/_comment_button.html.haml
@@ -1,7 +1,7 @@
- noteable_name = @note.noteable.human_class_name
.float-left.btn-group.append-right-10.droplab-dropdown.comment-type-dropdown.js-comment-type-dropdown
- %input.btn.btn-nr.btn-create.comment-btn.js-comment-button.js-comment-submit-button{ type: 'submit', value: 'Comment' }
+ %input.btn.btn-nr.btn-success.comment-btn.js-comment-button.js-comment-submit-button{ type: 'submit', value: 'Comment' }
- if @note.can_be_discussion_note?
= button_tag type: 'button', class: 'btn btn-nr dropdown-toggle comment-btn js-note-new-discussion js-disable-on-submit', data: { 'dropdown-trigger' => '#resolvable-comment-menu' }, 'aria-label' => 'Open comment type dropdown' do
diff --git a/app/views/shared/notes/_edit_form.html.haml b/app/views/shared/notes/_edit_form.html.haml
index 71a5b94e958..fec966069b9 100644
--- a/app/views/shared/notes/_edit_form.html.haml
+++ b/app/views/shared/notes/_edit_form.html.haml
@@ -9,6 +9,6 @@
.note-form-actions.clearfix
.settings-message.note-edit-warning.js-finish-edit-warning
Finish editing this message first!
- = submit_tag 'Save comment', class: 'btn btn-nr btn-save js-comment-save-button'
+ = submit_tag 'Save comment', class: 'btn btn-nr btn-success js-comment-save-button'
%button.btn.btn-nr.btn-cancel.note-edit-cancel{ type: 'button' }
Cancel
diff --git a/app/views/shared/runners/_form.html.haml b/app/views/shared/runners/_form.html.haml
index fa93307be31..daf08d9bb2c 100644
--- a/app/views/shared/runners/_form.html.haml
+++ b/app/views/shared/runners/_form.html.haml
@@ -51,6 +51,6 @@
= _('Tags')
.col-sm-10
= f.text_field :tag_list, value: runner.tag_list.sort.join(', '), class: 'form-control'
- .form-text.text-muted= _('You can setup jobs to only use Runners with specific tags. Separate tags with commas.')
+ .form-text.text-muted= _('You can set up jobs to only use Runners with specific tags. Separate tags with commas.')
.form-actions
= f.submit _('Save changes'), class: 'btn btn-success'
diff --git a/app/views/shared/runners/_runner_description.html.haml b/app/views/shared/runners/_runner_description.html.haml
index da5c032add5..5935750ca06 100644
--- a/app/views/shared/runners/_runner_description.html.haml
+++ b/app/views/shared/runners/_runner_description.html.haml
@@ -1,6 +1,6 @@
.light.prepend-top-default
%p
- = _("A 'Runner' is a process which runs a job. You can setup as many Runners as you need.")
+ = _("A 'Runner' is a process which runs a job. You can set up as many Runners as you need.")
%br
= _('Runners can be placed on separate users, servers, and even on your local machine.')
diff --git a/app/views/shared/snippets/_form.html.haml b/app/views/shared/snippets/_form.html.haml
index 5e5c050d5c3..1b66d3acd40 100644
--- a/app/views/shared/snippets/_form.html.haml
+++ b/app/views/shared/snippets/_form.html.haml
@@ -32,9 +32,9 @@
.form-actions
- if @snippet.new_record?
- = f.submit 'Create snippet', class: "btn-create btn"
+ = f.submit 'Create snippet', class: "btn-success btn"
- else
- = f.submit 'Save changes', class: "btn-save btn"
+ = f.submit 'Save changes', class: "btn-success btn"
- if @snippet.project_id
= link_to "Cancel", project_snippets_path(@project), class: "btn btn-cancel"
diff --git a/app/views/snippets/_actions.html.haml b/app/views/snippets/_actions.html.haml
index ae69d0d07c7..0ce13ee7a53 100644
--- a/app/views/snippets/_actions.html.haml
+++ b/app/views/snippets/_actions.html.haml
@@ -7,7 +7,7 @@
- if can?(current_user, :admin_personal_snippet, @snippet)
= link_to snippet_path(@snippet), method: :delete, data: { confirm: "Are you sure?" }, class: "btn btn-grouped btn-inverted btn-remove", title: 'Delete Snippet' do
Delete
- = link_to new_snippet_path, class: "btn btn-grouped btn-inverted btn-create", title: "New snippet" do
+ = link_to new_snippet_path, class: "btn btn-grouped btn-inverted btn-success", title: "New snippet" do
New snippet
- if @snippet.submittable_as_spam_by?(current_user)
= link_to 'Submit as spam', mark_as_spam_snippet_path(@snippet), method: :post, class: 'btn btn-grouped btn-spam', title: 'Submit as spam'
diff --git a/app/views/snippets/new.html.haml b/app/views/snippets/new.html.haml
index f01915107e3..c8a5e199674 100644
--- a/app/views/snippets/new.html.haml
+++ b/app/views/snippets/new.html.haml
@@ -1,5 +1,6 @@
- @hide_top_links = true
-- breadcrumb_title "Snippets"
+- add_to_breadcrumbs "Snippets", dashboard_snippets_path
+- breadcrumb_title "New"
- page_title "New Snippet"
%h3.page-title
New Snippet
diff --git a/app/workers/new_merge_request_worker.rb b/app/workers/new_merge_request_worker.rb
index 62f9d9b6f57..fa48c1b29a8 100644
--- a/app/workers/new_merge_request_worker.rb
+++ b/app/workers/new_merge_request_worker.rb
@@ -10,7 +10,7 @@ class NewMergeRequestWorker
EventCreateService.new.open_mr(issuable, user)
NotificationService.new.new_merge_request(issuable, user)
- issuable.diffs.write_cache
+ issuable.diffs(include_stats: false).write_cache
issuable.create_cross_references!(user)
end
diff --git a/bin/pkgr_before_precompile.sh b/bin/pkgr_before_precompile.sh
index 5a2007f4ab0..54ff32c711b 100755
--- a/bin/pkgr_before_precompile.sh
+++ b/bin/pkgr_before_precompile.sh
@@ -6,7 +6,7 @@ for file in config/*.yml.example; do
cp ${file} config/$(basename ${file} .example)
done
-# Allow to override the Gitlab URL from an environment variable, as this will avoid having to change the configuration file for simple deployments.
+# Allow to override the GitLab URL from an environment variable, as this will avoid having to change the configuration file for simple deployments.
config=$(echo '<% gitlab_url = URI(ENV["GITLAB_URL"] || "http://localhost:80") %>' | cat - config/gitlab.yml)
echo "$config" > config/gitlab.yml
sed -i "s/host: localhost/host: <%= gitlab_url.host %>/" config/gitlab.yml
diff --git a/changelogs/archive.md b/changelogs/archive.md
index fe461a6ac5e..b57440f7dc6 100644
--- a/changelogs/archive.md
+++ b/changelogs/archive.md
@@ -739,7 +739,7 @@
- Update duration at the end of pipeline
- ExpireBuildArtifactsWorker query builds table without ordering enqueuing one job per build to cleanup
- Add group level labels. (!6425)
-- Add an example for testing a phoenix application with Gitlab CI in the docs (Manthan Mallikarjun)
+- Add an example for testing a phoenix application with GitLab CI in the docs (Manthan Mallikarjun)
- Cancelled pipelines could be retried. !6927
- Updating verbiage on git basics to be more intuitive
- Fix project_feature record not generated on project creation
@@ -768,7 +768,7 @@
- Log LDAP lookup errors and don't swallow unrelated exceptions. !6103 (Markus Koller)
- Replace unique keyframes mixin with keyframe mixin with specific names (ClemMakesApps)
- Add more tests for calendar contribution (ClemMakesApps)
-- Update Gitlab Shell to fix some problems with moving projects between storages
+- Update GitLab Shell to fix some problems with moving projects between storages
- Cache rendered markdown in the database, rather than Redis
- Add todo toggle event (ClemMakesApps)
- Avoid database queries on Banzai::ReferenceParser::BaseParser for nodes without references
@@ -815,7 +815,7 @@
- Replace static issue fixtures by script !6059 (winniehell)
- Append issue template to existing description !6149 (Joseph Frazier)
- Trending projects now only show public projects and the list of projects is cached for a day
-- Memoize Gitlab Shell's secret token (!6599, Justin DiPierro)
+- Memoize GitLab Shell's secret token (!6599, Justin DiPierro)
- Revoke button in Applications Settings underlines on hover.
- Use higher size on Gitlab::Redis connection pool on Sidekiq servers
- Add missing values to linter !6276 (Katarzyna Kobierska Ula Budziszewska)
@@ -930,7 +930,7 @@
## 8.12.3
- - Update Gitlab Shell to support low IO priority for storage moves
+ - Update GitLab Shell to support low IO priority for storage moves
## 8.12.2
@@ -1001,7 +1001,7 @@
- Added ability to specify URL in environment configuration in gitlab-ci.yml
- Escape search term before passing it to Regexp.new !6241 (winniehell)
- Fix pinned sidebar behavior in smaller viewports !6169
- - Fix file permissions change when updating a file on the Gitlab UI !5979
+ - Fix file permissions change when updating a file on the GitLab UI !5979
- Added horizontal padding on build page sidebar on code coverage block. !6196 (Vitaly Baev)
- Change merge_error column from string to text type
- Fix issue with search filter labels not displaying
@@ -1688,7 +1688,7 @@
- Fix commit avatar alignment in compare view. !5128
- Fix broken migration in MySQL. !5005
- Overwrite Host and X-Forwarded-Host headers in NGINX !5213
- - Keeps issue number when importing from Gitlab.com
+ - Keeps issue number when importing from GitLab.com
- Add Pending tab for Builds (Katarzyna Kobierska, Urszula Budziszewska)
## 8.9.5
@@ -4786,7 +4786,7 @@
## 3.1.0
- Updated gems
-- Services: Gitlab CI integration
+- Services: GitLab CI integration
- Events filter on dashboard
- Own namespace for redis/resque
- Optimized commit diff views
@@ -4869,7 +4869,7 @@
## 2.8.0
-- Gitlab Flavored Markdown
+- GitLab Flavored Markdown
- Bulk issues update
- Issues API
- Cucumber coverage increased
diff --git a/changelogs/unreleased/#47282-Improving-Contributor-On-Boarding-Documentation.yml b/changelogs/unreleased/#47282-Improving-Contributor-On-Boarding-Documentation.yml
deleted file mode 100644
index f7521ff9225..00000000000
--- a/changelogs/unreleased/#47282-Improving-Contributor-On-Boarding-Documentation.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-title: First Improvements made to the contributor on-boarding experience.
-merge_request: 20682
-author: Eddie Stubbington
-type: added
diff --git a/changelogs/unreleased/21305-breadcrumb-link-to-issues-on-new-issue-page.yml b/changelogs/unreleased/21305-breadcrumb-link-to-issues-on-new-issue-page.yml
deleted file mode 100644
index 8e8c3cf53b4..00000000000
--- a/changelogs/unreleased/21305-breadcrumb-link-to-issues-on-new-issue-page.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: "Fix breadcrumb link to issues on new issue page"
-merge_request: 21305
-author: J.D. Bean
-type: fixed
diff --git a/changelogs/unreleased/21326-avoid-nil-safe-message.yml b/changelogs/unreleased/21326-avoid-nil-safe-message.yml
deleted file mode 100644
index ca1a89191a8..00000000000
--- a/changelogs/unreleased/21326-avoid-nil-safe-message.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: "Avoid nil safe message"
-merge_request: 21326
-author: Yi Siliang
-type: fixed
diff --git a/changelogs/unreleased/21371-avatar-fix.yml b/changelogs/unreleased/21371-avatar-fix.yml
deleted file mode 100644
index 6e00a4ba360..00000000000
--- a/changelogs/unreleased/21371-avatar-fix.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: "Vertically centres landscape avatars."
-merge_request: 21371
-author: Vicary Archangel
-type: fixed
diff --git a/changelogs/unreleased/24128-fix-comment-unresolve-discussions.yml b/changelogs/unreleased/24128-fix-comment-unresolve-discussions.yml
new file mode 100644
index 00000000000..d835d25f39b
--- /dev/null
+++ b/changelogs/unreleased/24128-fix-comment-unresolve-discussions.yml
@@ -0,0 +1,5 @@
+---
+title: Fix resolved discussions being unresolved when commented on
+merge_request: 21881
+author:
+type: fixed
diff --git a/changelogs/unreleased/25990-web-terminal-improvements.yml b/changelogs/unreleased/25990-web-terminal-improvements.yml
deleted file mode 100644
index 99a4a82ea66..00000000000
--- a/changelogs/unreleased/25990-web-terminal-improvements.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Make terminal button more visible
-merge_request:
-author:
-type: changed
diff --git a/changelogs/unreleased/2747-protected-environments-backend-ce.yml b/changelogs/unreleased/2747-protected-environments-backend-ce.yml
deleted file mode 100644
index dcec74a33a7..00000000000
--- a/changelogs/unreleased/2747-protected-environments-backend-ce.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: CE Port of Protected Environments backend
-merge_request: 20859
-author:
-type: other
diff --git a/changelogs/unreleased/28930-add-project-reference-filter.yml b/changelogs/unreleased/28930-add-project-reference-filter.yml
deleted file mode 100644
index c7679c5fe76..00000000000
--- a/changelogs/unreleased/28930-add-project-reference-filter.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Add the ability to reference projects in comments and other markdown text.
-merge_request: 20285
-author: Reuben Pereira
-type: added
diff --git a/changelogs/unreleased/2934-create-new-project-re-add-project-name-field.yml b/changelogs/unreleased/2934-create-new-project-re-add-project-name-field.yml
deleted file mode 100644
index ad9136b69c2..00000000000
--- a/changelogs/unreleased/2934-create-new-project-re-add-project-name-field.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Re-add project name field on "Create new project" page
-merge_request: 21386
-author:
-type: other
diff --git a/changelogs/unreleased/29398-support-kubernetes-rbac-for-gitlab-managed-apps.yml b/changelogs/unreleased/29398-support-kubernetes-rbac-for-gitlab-managed-apps.yml
deleted file mode 100644
index c182946b299..00000000000
--- a/changelogs/unreleased/29398-support-kubernetes-rbac-for-gitlab-managed-apps.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Support Kubernetes RBAC for GitLab Managed Apps when adding a existing cluster
-merge_request: 21127
-author:
-type: changed
diff --git a/changelogs/unreleased/36048-move-default-branch-settings-under-repository.yml b/changelogs/unreleased/36048-move-default-branch-settings-under-repository.yml
deleted file mode 100644
index c5788a40dba..00000000000
--- a/changelogs/unreleased/36048-move-default-branch-settings-under-repository.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Move project settings for default branch under "Repository"
-merge_request: 21380
-author:
-type: changed
diff --git a/changelogs/unreleased/36534-show-commit-behind-mr-api.yml b/changelogs/unreleased/36534-show-commit-behind-mr-api.yml
deleted file mode 100644
index 06471146fa3..00000000000
--- a/changelogs/unreleased/36534-show-commit-behind-mr-api.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Adds diverged_commits_count field to GET api/v4/projects/:project_id/merge_requests/:merge_request_iid
-merge_request: 21405
-author: Jacopo Beschi @jacopo-beschi
-type: added
diff --git a/changelogs/unreleased/37356-relative-submodule-link.yml b/changelogs/unreleased/37356-relative-submodule-link.yml
deleted file mode 100644
index 99d1577609d..00000000000
--- a/changelogs/unreleased/37356-relative-submodule-link.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix git submodule link for subgroup projects with relative path
-merge_request: 21154
-author:
-type: fixed
diff --git a/changelogs/unreleased/38208-due-dates-system-notes.yml b/changelogs/unreleased/38208-due-dates-system-notes.yml
deleted file mode 100644
index 60e09ff64de..00000000000
--- a/changelogs/unreleased/38208-due-dates-system-notes.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Add system note when due date is changed
-merge_request:
-author: Eva Kadlecova
-type: added
diff --git a/changelogs/unreleased/39665-restrict-issue-reopen.yml b/changelogs/unreleased/39665-restrict-issue-reopen.yml
deleted file mode 100644
index 204baafb700..00000000000
--- a/changelogs/unreleased/39665-restrict-issue-reopen.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Restrict reopening locked issues for non authorized issue authors
-merge_request: 21299
-author:
-type: changed
diff --git a/changelogs/unreleased/39923-automatically-disable-auto-devops-for-project.yml b/changelogs/unreleased/39923-automatically-disable-auto-devops-for-project.yml
deleted file mode 100644
index 76b411e9e8c..00000000000
--- a/changelogs/unreleased/39923-automatically-disable-auto-devops-for-project.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Disable Auto DevOps for project upon first pipeline failure
-merge_request: 21172
-author:
-type: added
diff --git a/changelogs/unreleased/41040-long-webhook-url-problem.yml b/changelogs/unreleased/41040-long-webhook-url-problem.yml
new file mode 100644
index 00000000000..4057e1ff325
--- /dev/null
+++ b/changelogs/unreleased/41040-long-webhook-url-problem.yml
@@ -0,0 +1,5 @@
+---
+title: Fix long webhook URL overflow for custom integration.
+merge_request:
+author: Kukovskii Vladimir
+type: fixed
diff --git a/changelogs/unreleased/41292-users-stuck-on-a-redirect-loop-after-transferring-project.yml b/changelogs/unreleased/41292-users-stuck-on-a-redirect-loop-after-transferring-project.yml
deleted file mode 100644
index 830c02510f2..00000000000
--- a/changelogs/unreleased/41292-users-stuck-on-a-redirect-loop-after-transferring-project.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix project transfer name validation issues causing a redirect loop
-merge_request: 21408
-author:
-type: fixed
diff --git a/changelogs/unreleased/41441-add-target-branch-name-to-cherrypick-confirmation.yml b/changelogs/unreleased/41441-add-target-branch-name-to-cherrypick-confirmation.yml
deleted file mode 100644
index c23676a3104..00000000000
--- a/changelogs/unreleased/41441-add-target-branch-name-to-cherrypick-confirmation.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Add target branch name to cherrypick confirmation message
-merge_request: 20846
-author: George Andrinopoulos
-type: other
diff --git a/changelogs/unreleased/41738-fix-sorting-issues-is-wrong-in-list-with-pagination.yml b/changelogs/unreleased/41738-fix-sorting-issues-is-wrong-in-list-with-pagination.yml
deleted file mode 100644
index bc0150c6586..00000000000
--- a/changelogs/unreleased/41738-fix-sorting-issues-is-wrong-in-list-with-pagination.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: "Fix If-Check the result that a function was executed several times"
-merge_request: 20640
-author: Max Dicker
-type: fixed
diff --git a/changelogs/unreleased/41996-copy-to-clipboard-tooltip-appears-under-modal.yml b/changelogs/unreleased/41996-copy-to-clipboard-tooltip-appears-under-modal.yml
deleted file mode 100644
index e452a91d8b7..00000000000
--- a/changelogs/unreleased/41996-copy-to-clipboard-tooltip-appears-under-modal.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Solve tooltip appears under modal
-merge_request: 21017
-author:
-type: fixed
diff --git a/changelogs/unreleased/42754-runners-pagination.yml b/changelogs/unreleased/42754-runners-pagination.yml
deleted file mode 100644
index 8e77b857538..00000000000
--- a/changelogs/unreleased/42754-runners-pagination.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Does not collapse runners section when using pagination
-merge_request:
-author:
-type: fixed
diff --git a/changelogs/unreleased/43096-controller-projects-issuescontroller-referenced_merge_requests-json-executes-more-than-100-sql-queries.yml b/changelogs/unreleased/43096-controller-projects-issuescontroller-referenced_merge_requests-json-executes-more-than-100-sql-queries.yml
deleted file mode 100644
index f4744c868ef..00000000000
--- a/changelogs/unreleased/43096-controller-projects-issuescontroller-referenced_merge_requests-json-executes-more-than-100-sql-queries.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Improve performance when fetching related merge requests for an issue
-merge_request: 21237
-author:
-type: performance
diff --git a/changelogs/unreleased/43140-reduce-logs-tree-load.yml b/changelogs/unreleased/43140-reduce-logs-tree-load.yml
deleted file mode 100644
index 5b0f1996bb3..00000000000
--- a/changelogs/unreleased/43140-reduce-logs-tree-load.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Bulk-render commit titles in the tree view to improve performance
-merge_request: 21500
-author:
-type: performance
diff --git a/changelogs/unreleased/43625-increase-modal-checkout.yml b/changelogs/unreleased/43625-increase-modal-checkout.yml
deleted file mode 100644
index 877550924c1..00000000000
--- a/changelogs/unreleased/43625-increase-modal-checkout.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Increase width of checkout branch modal box
-merge_request:
-author:
-type: fixed
diff --git a/changelogs/unreleased/44005-improve-handling-of-projects-shared-with-a-group.yml b/changelogs/unreleased/44005-improve-handling-of-projects-shared-with-a-group.yml
deleted file mode 100644
index a828ee36eb4..00000000000
--- a/changelogs/unreleased/44005-improve-handling-of-projects-shared-with-a-group.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Overhaul listing of projects in the group overview page
-merge_request: 20262
-author:
-type: added
diff --git a/changelogs/unreleased/44704-improve-project-overview-ui.yml b/changelogs/unreleased/44704-improve-project-overview-ui.yml
deleted file mode 100644
index 6fb8359f2dc..00000000000
--- a/changelogs/unreleased/44704-improve-project-overview-ui.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Update design of project overview page
-merge_request: 20536
-author:
-type: changed
diff --git a/changelogs/unreleased/44768-lazy-load-xterm-css.yml b/changelogs/unreleased/44768-lazy-load-xterm-css.yml
new file mode 100644
index 00000000000..85f7b1984e0
--- /dev/null
+++ b/changelogs/unreleased/44768-lazy-load-xterm-css.yml
@@ -0,0 +1,5 @@
+---
+title: Lazy load xterm custom colors css
+merge_request:
+author:
+type: performance
diff --git a/changelogs/unreleased/44943-update-presentation-for-sso-providers-on-log-in-page.yml b/changelogs/unreleased/44943-update-presentation-for-sso-providers-on-log-in-page.yml
deleted file mode 100644
index a378aaec750..00000000000
--- a/changelogs/unreleased/44943-update-presentation-for-sso-providers-on-log-in-page.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Update presentation for SSO providers on log in page
-merge_request: 21233
-author:
-type: other
diff --git a/changelogs/unreleased/44998-split-admin-settings-into-multiple-sub-pages.yml b/changelogs/unreleased/44998-split-admin-settings-into-multiple-sub-pages.yml
new file mode 100644
index 00000000000..4b398e9419d
--- /dev/null
+++ b/changelogs/unreleased/44998-split-admin-settings-into-multiple-sub-pages.yml
@@ -0,0 +1,5 @@
+---
+title: Split admin settings into multiple sub pages
+merge_request: 21467
+author:
+type: other
diff --git a/changelogs/unreleased/45663-tag-quick-action-on-commit-comments.yml b/changelogs/unreleased/45663-tag-quick-action-on-commit-comments.yml
deleted file mode 100644
index 6d664511e6e..00000000000
--- a/changelogs/unreleased/45663-tag-quick-action-on-commit-comments.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: "`/tag` quick action on Commit comments"
-merge_request: 20694
-author: Peter Leitzen
-type: added
diff --git a/changelogs/unreleased/45754-issue-mr-and-archived-projects.yml b/changelogs/unreleased/45754-issue-mr-and-archived-projects.yml
new file mode 100644
index 00000000000..d81f47d9654
--- /dev/null
+++ b/changelogs/unreleased/45754-issue-mr-and-archived-projects.yml
@@ -0,0 +1,5 @@
+---
+title: Issue and MR count now ignores archived projects
+merge_request: 21721
+author:
+type: fixed
diff --git a/changelogs/unreleased/45754-open-issues-from-archived-project-listed-in-group-issue-board.yml b/changelogs/unreleased/45754-open-issues-from-archived-project-listed-in-group-issue-board.yml
new file mode 100644
index 00000000000..34394396020
--- /dev/null
+++ b/changelogs/unreleased/45754-open-issues-from-archived-project-listed-in-group-issue-board.yml
@@ -0,0 +1,5 @@
+---
+title: No longer show open issues from archived projects in group issue board
+merge_request: 21721
+author:
+type: fixed
diff --git a/changelogs/unreleased/45938-postgres-timeout-when-counting-number-of-ci-builds-for-usage-ping.yml b/changelogs/unreleased/45938-postgres-timeout-when-counting-number-of-ci-builds-for-usage-ping.yml
deleted file mode 100644
index f3016a639d9..00000000000
--- a/changelogs/unreleased/45938-postgres-timeout-when-counting-number-of-ci-builds-for-usage-ping.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Handle database statement timeouts in usage ping
-merge_request: 21523
-author:
-type: fixed
diff --git a/changelogs/unreleased/46340-remove-extra-spaces-from-mr-discussion-notes.yml b/changelogs/unreleased/46340-remove-extra-spaces-from-mr-discussion-notes.yml
deleted file mode 100644
index b93d2378d85..00000000000
--- a/changelogs/unreleased/46340-remove-extra-spaces-from-mr-discussion-notes.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Remove extra spaces from MR discussion notes
-merge_request: 18946
-author: Takuya Noguchi
-type: other
diff --git a/changelogs/unreleased/46591-fix-ide-height-issues.yml b/changelogs/unreleased/46591-fix-ide-height-issues.yml
deleted file mode 100644
index d161bda6ab1..00000000000
--- a/changelogs/unreleased/46591-fix-ide-height-issues.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix IDE issues with persistent banners
-merge_request: 21283
-author:
-type: fixed
diff --git a/changelogs/unreleased/46733-move-filter-dropdown-from-font-awesome-to-our-own-icons.yml b/changelogs/unreleased/46733-move-filter-dropdown-from-font-awesome-to-our-own-icons.yml
new file mode 100644
index 00000000000..07549781330
--- /dev/null
+++ b/changelogs/unreleased/46733-move-filter-dropdown-from-font-awesome-to-our-own-icons.yml
@@ -0,0 +1,5 @@
+---
+title: Updated icons used in filtered search dropdowns
+merge_request: 21694
+author:
+type: changed
diff --git a/changelogs/unreleased/47398-user-is-unable-revoke-a-authorized-application-unless-user-oauth-applications-is-checked-in-admin-settings.yml b/changelogs/unreleased/47398-user-is-unable-revoke-a-authorized-application-unless-user-oauth-applications-is-checked-in-admin-settings.yml
new file mode 100644
index 00000000000..e0dc26301d4
--- /dev/null
+++ b/changelogs/unreleased/47398-user-is-unable-revoke-a-authorized-application-unless-user-oauth-applications-is-checked-in-admin-settings.yml
@@ -0,0 +1,6 @@
+---
+title: Allow user to revoke an authorized application even if User OAuth applications
+ setting is disabled in admin settings
+merge_request: 21835
+author:
+type: changed
diff --git a/changelogs/unreleased/47440-recognize-unlicense-license-file.yml b/changelogs/unreleased/47440-recognize-unlicense-license-file.yml
deleted file mode 100644
index 3521dd613b0..00000000000
--- a/changelogs/unreleased/47440-recognize-unlicense-license-file.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Recognize 'UNLICENSE' license files
-merge_request: 21508
-author: J.D. Bean
-type: added
diff --git a/changelogs/unreleased/47752-buttons-on-new-file-page-wrap-outside-of-container-for-long-branch-names.yml b/changelogs/unreleased/47752-buttons-on-new-file-page-wrap-outside-of-container-for-long-branch-names.yml
deleted file mode 100644
index 81ca632947d..00000000000
--- a/changelogs/unreleased/47752-buttons-on-new-file-page-wrap-outside-of-container-for-long-branch-names.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix buttons on the new file page wrapping outside of the container
-merge_request: 21015
-author:
-type: fixed
diff --git a/changelogs/unreleased/47765-group-visibility-error-due-to-string-conversion.yml b/changelogs/unreleased/47765-group-visibility-error-due-to-string-conversion.yml
deleted file mode 100644
index ad09527b329..00000000000
--- a/changelogs/unreleased/47765-group-visibility-error-due-to-string-conversion.yml
+++ /dev/null
@@ -1,6 +0,0 @@
----
-title: Importing a project no longer fails when visibility level holds a string value
- type
-merge_request: 21242
-author:
-type: fixed
diff --git a/changelogs/unreleased/47845-propagate_failure_reason-to-job-webhook.yml b/changelogs/unreleased/47845-propagate_failure_reason-to-job-webhook.yml
deleted file mode 100644
index 3f85f75bef4..00000000000
--- a/changelogs/unreleased/47845-propagate_failure_reason-to-job-webhook.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: "#47845 Add failure_reason to job webhook"
-merge_request: 21143
-author: matemaciek
-type: added
diff --git a/changelogs/unreleased/47943-project-milestone-page-deprecation-message.yml b/changelogs/unreleased/47943-project-milestone-page-deprecation-message.yml
deleted file mode 100644
index b9f68e1c46c..00000000000
--- a/changelogs/unreleased/47943-project-milestone-page-deprecation-message.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Show deprecation message on project milestone page for category tabs
-merge_request: 21236
-author:
-type: changed
diff --git a/changelogs/unreleased/48145-illustration.yml b/changelogs/unreleased/48145-illustration.yml
deleted file mode 100644
index 7d84075c2b3..00000000000
--- a/changelogs/unreleased/48145-illustration.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fixes SVGs for empty states in job page overflowing on mobile
-merge_request:
-author:
-type: fixed
diff --git a/changelogs/unreleased/48167-fix-outdated-discussions-new-datastructure.yml b/changelogs/unreleased/48167-fix-outdated-discussions-new-datastructure.yml
deleted file mode 100644
index a8fcce2eeb8..00000000000
--- a/changelogs/unreleased/48167-fix-outdated-discussions-new-datastructure.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix outdated discussions being shown on Merge Request Changes tab
-merge_request: 21543
-author:
-type: fixed
diff --git a/changelogs/unreleased/48320-cancel-a-created-job.yml b/changelogs/unreleased/48320-cancel-a-created-job.yml
deleted file mode 100644
index 3e7a9e9ae52..00000000000
--- a/changelogs/unreleased/48320-cancel-a-created-job.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Allows to cancel a Created job
-merge_request: 20635
-author: Jacopo Beschi @jacopo-beschi
-type: added
diff --git a/changelogs/unreleased/48778-remove-old-storage-logic-from-import-export.yml b/changelogs/unreleased/48778-remove-old-storage-logic-from-import-export.yml
deleted file mode 100644
index 4ddbc118e86..00000000000
--- a/changelogs/unreleased/48778-remove-old-storage-logic-from-import-export.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Update Import/Export to only use new storage uploaders logic
-merge_request: 21409
-author:
-type: added
diff --git a/changelogs/unreleased/48869-wiki-slugs-with-spaces.yml b/changelogs/unreleased/48869-wiki-slugs-with-spaces.yml
deleted file mode 100644
index 88ba8028e2c..00000000000
--- a/changelogs/unreleased/48869-wiki-slugs-with-spaces.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Allow spaces in wiki markdown links when using CommonMark
-merge_request: 20417
-author:
-type: fixed
diff --git a/changelogs/unreleased/48942-rename-backlog-list-to-open-issue-boards.yml b/changelogs/unreleased/48942-rename-backlog-list-to-open-issue-boards.yml
deleted file mode 100644
index 26851fc2dec..00000000000
--- a/changelogs/unreleased/48942-rename-backlog-list-to-open-issue-boards.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Change 'Backlog' list title to 'Open' in Issue Boards
-merge_request: 21131
-author:
-type: changed
diff --git a/changelogs/unreleased/48967-disable-statement-timeout.yml b/changelogs/unreleased/48967-disable-statement-timeout.yml
deleted file mode 100644
index 2da800ed41e..00000000000
--- a/changelogs/unreleased/48967-disable-statement-timeout.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: disable_statement_timeout no longer leak to other migrations
-merge_request: 20503
-author:
-type: fixed
diff --git a/changelogs/unreleased/49110-update-mr-widget-styles.yml b/changelogs/unreleased/49110-update-mr-widget-styles.yml
deleted file mode 100644
index e54866a0908..00000000000
--- a/changelogs/unreleased/49110-update-mr-widget-styles.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Truncate branch names and update "commits behind" text in MR page
-merge_request: 21206
-author:
-type: changed
diff --git a/changelogs/unreleased/49292-add-group-name-badge-under-milestone.yml b/changelogs/unreleased/49292-add-group-name-badge-under-milestone.yml
deleted file mode 100644
index 69089cfe357..00000000000
--- a/changelogs/unreleased/49292-add-group-name-badge-under-milestone.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Add group name badge under group milestone
-merge_request: 21384
-author:
-type: added
diff --git a/changelogs/unreleased/49632-clean-up-the-top-section-of-the-cluster-page.yml b/changelogs/unreleased/49632-clean-up-the-top-section-of-the-cluster-page.yml
deleted file mode 100644
index eae5da45524..00000000000
--- a/changelogs/unreleased/49632-clean-up-the-top-section-of-the-cluster-page.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Make cluster page settings easier to read
-merge_request: 21550
-author:
-type: other
diff --git a/changelogs/unreleased/49644-make-margin-of-user-status-emoji-consistent.yml b/changelogs/unreleased/49644-make-margin-of-user-status-emoji-consistent.yml
deleted file mode 100644
index a2ae582fb1c..00000000000
--- a/changelogs/unreleased/49644-make-margin-of-user-status-emoji-consistent.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Make margin of user status emoji consistent
-merge_request: 21268
-author:
-type: other
diff --git a/changelogs/unreleased/49770-fixes-input-alignment-on-user-admin-form-with-errors.yml b/changelogs/unreleased/49770-fixes-input-alignment-on-user-admin-form-with-errors.yml
deleted file mode 100644
index 00e1f6e638a..00000000000
--- a/changelogs/unreleased/49770-fixes-input-alignment-on-user-admin-form-with-errors.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fixes input alignment in user admin form with errors
-merge_request: 21108
-author: Jacopo Beschi @jacopo-beschi
-type: fixed
diff --git a/changelogs/unreleased/49796-project-deletion-may-not-log-audit-events-during-group-deletion.yml b/changelogs/unreleased/49796-project-deletion-may-not-log-audit-events-during-group-deletion.yml
deleted file mode 100644
index bb7633abdb1..00000000000
--- a/changelogs/unreleased/49796-project-deletion-may-not-log-audit-events-during-group-deletion.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: 'Fix: Project deletion may not log audit events during group deletion'
-merge_request: 21162
-author:
-type: fixed
diff --git a/changelogs/unreleased/49796-project-deletion-may-not-log-audit-events-during-user-deletion.yml b/changelogs/unreleased/49796-project-deletion-may-not-log-audit-events-during-user-deletion.yml
deleted file mode 100644
index a8e3d590a4a..00000000000
--- a/changelogs/unreleased/49796-project-deletion-may-not-log-audit-events-during-user-deletion.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: 'Fix: Project deletion may not log audit events during user deletion'
-merge_request:
-author:
-type: fixed
diff --git a/changelogs/unreleased/49905-fix-checkboxes-runners.yml b/changelogs/unreleased/49905-fix-checkboxes-runners.yml
deleted file mode 100644
index af40e5348b8..00000000000
--- a/changelogs/unreleased/49905-fix-checkboxes-runners.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix checkboxes on runner admin settings - The labels are now clickable
-merge_request:
-author:
-type: fixed
diff --git a/changelogs/unreleased/49953-add-user_show_add_ssh_key_message-setting.yml b/changelogs/unreleased/49953-add-user_show_add_ssh_key_message-setting.yml
deleted file mode 100644
index 82423092792..00000000000
--- a/changelogs/unreleased/49953-add-user_show_add_ssh_key_message-setting.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Add ability to suppress the global "You won't be able to use SSH" message
-merge_request: 21027
-author: Ævar Arnfjörð Bjarmason
-type: added
diff --git a/changelogs/unreleased/49993-fix-remember-sorting-issue-mr.yml b/changelogs/unreleased/49993-fix-remember-sorting-issue-mr.yml
deleted file mode 100644
index df05bf3f3e2..00000000000
--- a/changelogs/unreleased/49993-fix-remember-sorting-issue-mr.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Split remembering sorting for issues and merge requests
-merge_request: 21153
-author: Jacopo Beschi @jacopo-beschi
-type: fixed
diff --git a/changelogs/unreleased/50019-remove-redundant-header-from-metrics-page.yml b/changelogs/unreleased/50019-remove-redundant-header-from-metrics-page.yml
deleted file mode 100644
index 8057819b223..00000000000
--- a/changelogs/unreleased/50019-remove-redundant-header-from-metrics-page.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Remove redundant header from metrics page
-merge_request: 21282
-author:
-type: changed
diff --git a/changelogs/unreleased/50047-spam-logs-pagination.yml b/changelogs/unreleased/50047-spam-logs-pagination.yml
deleted file mode 100644
index ca5f432cd8c..00000000000
--- a/changelogs/unreleased/50047-spam-logs-pagination.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Add gitlab theme to spam logs pagination
-merge_request: 21145
-author:
-type: fixed
diff --git a/changelogs/unreleased/50063-add-missing-i18n-strings-to-issue-boards.yml b/changelogs/unreleased/50063-add-missing-i18n-strings-to-issue-boards.yml
deleted file mode 100644
index ca17a41d611..00000000000
--- a/changelogs/unreleased/50063-add-missing-i18n-strings-to-issue-boards.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Added missing i18n strings to issue boards lables dropdown
-merge_request: 21081
-author:
-type: other
diff --git a/changelogs/unreleased/50101-add-artifact-information-to-job-api.yml b/changelogs/unreleased/50101-add-artifact-information-to-job-api.yml
deleted file mode 100644
index f98d111a337..00000000000
--- a/changelogs/unreleased/50101-add-artifact-information-to-job-api.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Send artifact information in job API
-merge_request: 50460
-author:
-type: other
diff --git a/changelogs/unreleased/50101-aritfacts-block.yml b/changelogs/unreleased/50101-aritfacts-block.yml
deleted file mode 100644
index 435e9d9d486..00000000000
--- a/changelogs/unreleased/50101-aritfacts-block.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Creates Vue component for artifacts block on job page
-merge_request:
-author:
-type: other
diff --git a/changelogs/unreleased/50101-builds-dropdown.yml b/changelogs/unreleased/50101-builds-dropdown.yml
deleted file mode 100644
index 9194b0e0d31..00000000000
--- a/changelogs/unreleased/50101-builds-dropdown.yml
+++ /dev/null
@@ -1,6 +0,0 @@
----
-title: Creates vue components for stage dropdowns and job list container for job log
- view
-merge_request:
-author:
-type: other
diff --git a/changelogs/unreleased/50101-commit-block.yml b/changelogs/unreleased/50101-commit-block.yml
deleted file mode 100644
index f6bad4c8154..00000000000
--- a/changelogs/unreleased/50101-commit-block.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Creates vue component for commit block in job log page
-merge_request:
-author:
-type: other
diff --git a/changelogs/unreleased/50101-empty-state-component.yml b/changelogs/unreleased/50101-empty-state-component.yml
deleted file mode 100644
index ee99b65d964..00000000000
--- a/changelogs/unreleased/50101-empty-state-component.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Creates empty state vue component for job view
-merge_request:
-author:
-type: other
diff --git a/changelogs/unreleased/50101-env-block.yml b/changelogs/unreleased/50101-env-block.yml
deleted file mode 100644
index 11e603e7a79..00000000000
--- a/changelogs/unreleased/50101-env-block.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Creates vue component for environments information in job log view
-merge_request:
-author:
-type: other
diff --git a/changelogs/unreleased/50101-erased-block.yml b/changelogs/unreleased/50101-erased-block.yml
deleted file mode 100644
index 5a5c9bc0fc4..00000000000
--- a/changelogs/unreleased/50101-erased-block.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Creates vue component for erased block on job view
-merge_request:
-author:
-type: other
diff --git a/changelogs/unreleased/50101-job-log-component.yml b/changelogs/unreleased/50101-job-log-component.yml
deleted file mode 100644
index 0759e7cfbd9..00000000000
--- a/changelogs/unreleased/50101-job-log-component.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Creates vue component for job log trace
-merge_request:
-author:
-type: other
diff --git a/changelogs/unreleased/50101-stuck-component.yml b/changelogs/unreleased/50101-stuck-component.yml
deleted file mode 100644
index bfe4009a2b3..00000000000
--- a/changelogs/unreleased/50101-stuck-component.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Creates Vvue component for warning block about stuck runners
-merge_request:
-author:
-type: other
diff --git a/changelogs/unreleased/50101-trigger.yml b/changelogs/unreleased/50101-trigger.yml
deleted file mode 100644
index df4243afa63..00000000000
--- a/changelogs/unreleased/50101-trigger.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Creates Vue component for trigger variables block in job log page
-merge_request:
-author:
-type: other
diff --git a/changelogs/unreleased/50101-truncated-job-information.yml b/changelogs/unreleased/50101-truncated-job-information.yml
deleted file mode 100644
index b873b8b7bf6..00000000000
--- a/changelogs/unreleased/50101-truncated-job-information.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Creates vue component for job log top bar with controllers
-merge_request:
-author:
-type: other
diff --git a/changelogs/unreleased/50111-improve-design-of-cluster-apps-to-handle-larger-quantity.yml b/changelogs/unreleased/50111-improve-design-of-cluster-apps-to-handle-larger-quantity.yml
new file mode 100644
index 00000000000..438c847327a
--- /dev/null
+++ b/changelogs/unreleased/50111-improve-design-of-cluster-apps-to-handle-larger-quantity.yml
@@ -0,0 +1,5 @@
+---
+title: Improve install flow of Kubernetes cluster apps
+merge_request: 21567
+author:
+type: changed
diff --git a/changelogs/unreleased/50126-blocked-user-card.yml b/changelogs/unreleased/50126-blocked-user-card.yml
deleted file mode 100644
index a42d62e5530..00000000000
--- a/changelogs/unreleased/50126-blocked-user-card.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix blocked user card style
-merge_request: 21095
-author:
-type: fixed
diff --git a/changelogs/unreleased/50180-fa-icon-google-audit.yml b/changelogs/unreleased/50180-fa-icon-google-audit.yml
deleted file mode 100644
index fb1771a7570..00000000000
--- a/changelogs/unreleased/50180-fa-icon-google-audit.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Show google icon in audit log
-merge_request: 21207
-author: Jan Beckmann
-type: fixed
diff --git a/changelogs/unreleased/50243-auto-devops-behind-a-proxy.yml b/changelogs/unreleased/50243-auto-devops-behind-a-proxy.yml
deleted file mode 100644
index 0f6208d0c7a..00000000000
--- a/changelogs/unreleased/50243-auto-devops-behind-a-proxy.yml
+++ /dev/null
@@ -1,6 +0,0 @@
----
-title: Vendor Auto-DevOps.gitlab-ci.yml with new proxy env vars passed through to
- docker
-merge_request: 21159
-author: kinolaev
-type: added
diff --git a/changelogs/unreleased/50345-hashed-storage-feature-flag.yml b/changelogs/unreleased/50345-hashed-storage-feature-flag.yml
deleted file mode 100644
index 4c5182b843b..00000000000
--- a/changelogs/unreleased/50345-hashed-storage-feature-flag.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Feature flag to disable Hashed Storage migration when renaming a repository
-merge_request: 21291
-author:
-type: added
diff --git a/changelogs/unreleased/50414-rubocop-rule-to-enforce-class-methods-over-module.yml b/changelogs/unreleased/50414-rubocop-rule-to-enforce-class-methods-over-module.yml
deleted file mode 100644
index 1694fb2376d..00000000000
--- a/changelogs/unreleased/50414-rubocop-rule-to-enforce-class-methods-over-module.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Adds Rubocop rule to enforce class_methods over module ClassMethods
-merge_request: 21379
-author: Jacopo Beschi @jacopo-beschi
-type: added
diff --git a/changelogs/unreleased/50441-high-number-of-statement-timeouts-in-groupdestroyworker-due-to-sitestatistics.yml b/changelogs/unreleased/50441-high-number-of-statement-timeouts-in-groupdestroyworker-due-to-sitestatistics.yml
deleted file mode 100644
index 3e360f8d6bb..00000000000
--- a/changelogs/unreleased/50441-high-number-of-statement-timeouts-in-groupdestroyworker-due-to-sitestatistics.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Removing a group no longer triggers hooks for project deletion twice
-merge_request: 21366
-author:
-type: fixed
diff --git a/changelogs/unreleased/50452-breadcrumb-link-to-new-merge-requests.yml b/changelogs/unreleased/50452-breadcrumb-link-to-new-merge-requests.yml
deleted file mode 100644
index 4738f7652a4..00000000000
--- a/changelogs/unreleased/50452-breadcrumb-link-to-new-merge-requests.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: "Fix breadcrumb link to merge requests on new merge request page"
-merge_request: 21502
-author: J.D. Bean
-type: fixed
diff --git a/changelogs/unreleased/50524-artifacts-sm.yml b/changelogs/unreleased/50524-artifacts-sm.yml
deleted file mode 100644
index 22bd097f911..00000000000
--- a/changelogs/unreleased/50524-artifacts-sm.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Shows download artifacts button for pipelines on small screens
-merge_request:
-author:
-type: changed
diff --git a/changelogs/unreleased/50535-display-banner-to-notify-user-if-project-is-implicitly-opted-ado.yml b/changelogs/unreleased/50535-display-banner-to-notify-user-if-project-is-implicitly-opted-ado.yml
deleted file mode 100644
index 23d4d504f04..00000000000
--- a/changelogs/unreleased/50535-display-banner-to-notify-user-if-project-is-implicitly-opted-ado.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Display banner on project page if AutoDevOps is implicitly enabled
-merge_request: 21503
-author:
-type: added
diff --git a/changelogs/unreleased/50564-chat-service-refactoring.yml b/changelogs/unreleased/50564-chat-service-refactoring.yml
deleted file mode 100644
index aec5e8fab0a..00000000000
--- a/changelogs/unreleased/50564-chat-service-refactoring.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Use sample data for push event when no commits created
-merge_request: 21440
-author: Takuya Noguchi
-type: fixed
diff --git a/changelogs/unreleased/50567-remove-usage-ping-payload-from-cohorts-add-to-settings.yml b/changelogs/unreleased/50567-remove-usage-ping-payload-from-cohorts-add-to-settings.yml
deleted file mode 100644
index 2a6666e362c..00000000000
--- a/changelogs/unreleased/50567-remove-usage-ping-payload-from-cohorts-add-to-settings.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Move usage ping payload from User Cohorts page to admin application settings
-merge_request: 21343
-author:
-type: other
diff --git a/changelogs/unreleased/50584-fix-ide-commit-twice.yml b/changelogs/unreleased/50584-fix-ide-commit-twice.yml
deleted file mode 100644
index 92b292cf4ab..00000000000
--- a/changelogs/unreleased/50584-fix-ide-commit-twice.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix Web IDE unable to commit to same file twice
-merge_request: 21372
-author:
-type: fixed
diff --git a/changelogs/unreleased/50657-migrate-issue-labels-and-milestone-to-related-mr-on-creation.yml b/changelogs/unreleased/50657-migrate-issue-labels-and-milestone-to-related-mr-on-creation.yml
deleted file mode 100644
index 65419d3ac77..00000000000
--- a/changelogs/unreleased/50657-migrate-issue-labels-and-milestone-to-related-mr-on-creation.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Merge request copies all associated issue labels and milestone on creation
-merge_request: 21383
-author:
-type: added
diff --git a/changelogs/unreleased/50801-error-getting-performance-bar-results-for-uuid.yml b/changelogs/unreleased/50801-error-getting-performance-bar-results-for-uuid.yml
deleted file mode 100644
index 6e57a215367..00000000000
--- a/changelogs/unreleased/50801-error-getting-performance-bar-results-for-uuid.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Don't show flash messages for performance bar errors
-merge_request: 21411
-author:
-type: other
diff --git a/changelogs/unreleased/50823-not-properly-filled-in-activity-RSS-feed-yml.yml b/changelogs/unreleased/50823-not-properly-filled-in-activity-RSS-feed-yml.yml
deleted file mode 100644
index 924e8867701..00000000000
--- a/changelogs/unreleased/50823-not-properly-filled-in-activity-RSS-feed-yml.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix links in RSS feed elements
-merge_request: 21424
-author: Marc Schwede
-type: fixed
diff --git a/changelogs/unreleased/50853-vendor-auto-devops-gitlab-ci-yml-to-resolve-redeploying-deleted-app-gives-helm-error.yml b/changelogs/unreleased/50853-vendor-auto-devops-gitlab-ci-yml-to-resolve-redeploying-deleted-app-gives-helm-error.yml
deleted file mode 100644
index 37922eb82f6..00000000000
--- a/changelogs/unreleased/50853-vendor-auto-devops-gitlab-ci-yml-to-resolve-redeploying-deleted-app-gives-helm-error.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: 'Auto-DevOps.gitlab-ci.yml: fix redeploying deleted app gives helm error'
-merge_request: 21429
-author:
-type: fixed
diff --git a/changelogs/unreleased/50879-unused-css-container-fluid.yml b/changelogs/unreleased/50879-unused-css-container-fluid.yml
deleted file mode 100644
index 3f706472523..00000000000
--- a/changelogs/unreleased/50879-unused-css-container-fluid.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Remove unused CSS part in mobile framework
-merge_request: 21439
-author: Takuya Noguchi
-type: other
diff --git a/changelogs/unreleased/50930-update-rubyzip-to-1-2-2.yml b/changelogs/unreleased/50930-update-rubyzip-to-1-2-2.yml
deleted file mode 100644
index be5cc60df64..00000000000
--- a/changelogs/unreleased/50930-update-rubyzip-to-1-2-2.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Update rubyzip to 1.2.2 (CVE-2018-1000544)
-merge_request: 21460
-author: Takuya Noguchi
-type: security
diff --git a/changelogs/unreleased/50936-docs-run-review-cleanup-only-for-gitlab-org-repos.yml b/changelogs/unreleased/50936-docs-run-review-cleanup-only-for-gitlab-org-repos.yml
deleted file mode 100644
index 87265506e24..00000000000
--- a/changelogs/unreleased/50936-docs-run-review-cleanup-only-for-gitlab-org-repos.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Run review-docs-cleanup job for gitlab-org repos only
-merge_request: 21463
-author: Takuya Noguchi
-type: other
diff --git a/changelogs/unreleased/50944-unable-to-import-repository-undefined-method-import_file-for-nil-nilclass.yml b/changelogs/unreleased/50944-unable-to-import-repository-undefined-method-import_file-for-nil-nilclass.yml
deleted file mode 100644
index ac18565090a..00000000000
--- a/changelogs/unreleased/50944-unable-to-import-repository-undefined-method-import_file-for-nil-nilclass.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix import error when archive does not have the correct extension
-merge_request: 21765
-author:
-type: fixed
diff --git a/changelogs/unreleased/50956-web-terminal.yml b/changelogs/unreleased/50956-web-terminal.yml
deleted file mode 100644
index 73317b0224c..00000000000
--- a/changelogs/unreleased/50956-web-terminal.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Include correct CSS file for xterm in environments page
-merge_request:
-author:
-type: fixed
diff --git a/changelogs/unreleased/51050-fix.yml b/changelogs/unreleased/51050-fix.yml
new file mode 100644
index 00000000000..b58f9ae34f8
--- /dev/null
+++ b/changelogs/unreleased/51050-fix.yml
@@ -0,0 +1,5 @@
+---
+title: Fix broken styling when issue board is collapsed
+merge_request: 21868
+author: Andrea Leone
+type: fixed
diff --git a/changelogs/unreleased/51092-fix-mr-diff-file-filter-clear-button.yml b/changelogs/unreleased/51092-fix-mr-diff-file-filter-clear-button.yml
deleted file mode 100644
index cb5ab15d285..00000000000
--- a/changelogs/unreleased/51092-fix-mr-diff-file-filter-clear-button.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Make MR diff file filter input Clear button functional
-merge_request: 21556
-author:
-type: fixed
diff --git a/changelogs/unreleased/51117-send-terminal-path-in-job-api.yml b/changelogs/unreleased/51117-send-terminal-path-in-job-api.yml
deleted file mode 100644
index f6faa9549be..00000000000
--- a/changelogs/unreleased/51117-send-terminal-path-in-job-api.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Add terminal_path to job API response
-merge_request: 21537
-author:
-type: other
diff --git a/changelogs/unreleased/51180-update-ffi-to-1-9-25.yml b/changelogs/unreleased/51180-update-ffi-to-1-9-25.yml
deleted file mode 100644
index 67354d6a610..00000000000
--- a/changelogs/unreleased/51180-update-ffi-to-1-9-25.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Update ffi to 1.9.25
-merge_request: 21561
-author: Takuya Noguchi
-type: other
diff --git a/changelogs/unreleased/51273-expose-runners-for-build-in-job-api.yml b/changelogs/unreleased/51273-expose-runners-for-build-in-job-api.yml
new file mode 100644
index 00000000000..df43f1dfbae
--- /dev/null
+++ b/changelogs/unreleased/51273-expose-runners-for-build-in-job-api.yml
@@ -0,0 +1,5 @@
+---
+title: Expose project runners in job API
+merge_request: 21618
+author:
+type: other
diff --git a/changelogs/unreleased/51281-on-master-diff-view-contains-extra-and-signs.yml b/changelogs/unreleased/51281-on-master-diff-view-contains-extra-and-signs.yml
deleted file mode 100644
index 2ca74b4bc48..00000000000
--- a/changelogs/unreleased/51281-on-master-diff-view-contains-extra-and-signs.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fixes double +/- on inline diff view
-merge_request: 21634
-author:
-type: fixed
diff --git a/changelogs/unreleased/51282-link-to-user-snippets-on-new-user-snippet-page.yml b/changelogs/unreleased/51282-link-to-user-snippets-on-new-user-snippet-page.yml
new file mode 100644
index 00000000000..1d2075ae549
--- /dev/null
+++ b/changelogs/unreleased/51282-link-to-user-snippets-on-new-user-snippet-page.yml
@@ -0,0 +1,5 @@
+---
+title: Add link to User Snippets in breadcrumbs of New User Snippet page
+merge_request:
+author: J.D. Bean
+type: add
diff --git a/changelogs/unreleased/51318-project-export-broken-when-avatar-is-set.yml b/changelogs/unreleased/51318-project-export-broken-when-avatar-is-set.yml
deleted file mode 100644
index c0f7e88f2b7..00000000000
--- a/changelogs/unreleased/51318-project-export-broken-when-avatar-is-set.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix broken exports when they include a projet avatar
-merge_request: 21649
-author:
-type: fixed
diff --git a/changelogs/unreleased/51412-username-alignment-issue-on-mr-page.yml b/changelogs/unreleased/51412-username-alignment-issue-on-mr-page.yml
deleted file mode 100644
index 5d245f672f2..00000000000
--- a/changelogs/unreleased/51412-username-alignment-issue-on-mr-page.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Add margin between username and subsequent text in issuable header
-merge_request: 21697
-author:
-type: other
diff --git a/changelogs/unreleased/51549-runners-table.yml b/changelogs/unreleased/51549-runners-table.yml
new file mode 100644
index 00000000000..fe36bfc1b30
--- /dev/null
+++ b/changelogs/unreleased/51549-runners-table.yml
@@ -0,0 +1,5 @@
+---
+title: Fixes admin runners table not wrapping content
+merge_request:
+author:
+type: fixed
diff --git a/changelogs/unreleased/51564-fix-commit-email-usage.yml b/changelogs/unreleased/51564-fix-commit-email-usage.yml
new file mode 100644
index 00000000000..2f1b042ae8a
--- /dev/null
+++ b/changelogs/unreleased/51564-fix-commit-email-usage.yml
@@ -0,0 +1,5 @@
+---
+title: Respect the user commit email in more places
+merge_request: 21773
+author:
+type: fixed
diff --git a/changelogs/unreleased/51571-wrapper-rake-task-uploads-migrate-os.yml b/changelogs/unreleased/51571-wrapper-rake-task-uploads-migrate-os.yml
new file mode 100644
index 00000000000..50710ca0aa8
--- /dev/null
+++ b/changelogs/unreleased/51571-wrapper-rake-task-uploads-migrate-os.yml
@@ -0,0 +1,5 @@
+---
+title: Add wrapper rake task to migrate all uploads to OS
+merge_request: 21779
+author:
+type: other
diff --git a/changelogs/unreleased/51725-push-mirrors-default-branch-reset-to-master.yml b/changelogs/unreleased/51725-push-mirrors-default-branch-reset-to-master.yml
new file mode 100644
index 00000000000..b3caa119253
--- /dev/null
+++ b/changelogs/unreleased/51725-push-mirrors-default-branch-reset-to-master.yml
@@ -0,0 +1,5 @@
+---
+title: Doesn't synchronize the default branch for push mirrors
+merge_request: 21861
+author:
+type: fixed
diff --git a/changelogs/unreleased/6010_remove_gemnasium_service.yml b/changelogs/unreleased/6010_remove_gemnasium_service.yml
deleted file mode 100644
index 900e84c9eed..00000000000
--- a/changelogs/unreleased/6010_remove_gemnasium_service.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Remove Gemnasium service
-merge_request: 21185
-author:
-type: removed
diff --git a/changelogs/unreleased/6028-show-generic-percent-stacked-progress-bar.yml b/changelogs/unreleased/6028-show-generic-percent-stacked-progress-bar.yml
deleted file mode 100644
index 94098dd0144..00000000000
--- a/changelogs/unreleased/6028-show-generic-percent-stacked-progress-bar.yml
+++ /dev/null
@@ -1,6 +0,0 @@
----
-title: Show '< 1%' when percent value evaluated is less than 1 on Stacked Progress
- Bar
-merge_request: 21306
-author:
-type: fixed
diff --git a/changelogs/unreleased/7573-show-click-to-expand-on-not-rendered-diffs.yml b/changelogs/unreleased/7573-show-click-to-expand-on-not-rendered-diffs.yml
deleted file mode 100644
index 4611a1f1f29..00000000000
--- a/changelogs/unreleased/7573-show-click-to-expand-on-not-rendered-diffs.yml
+++ /dev/null
@@ -1,6 +0,0 @@
----
-title: Fix absent Click to Expand link on diffs not rendered on first load of Merge
- Requests Changes tab
-merge_request: 21716
-author:
-type: fixed
diff --git a/changelogs/unreleased/_acet-disable-ide-button.yml b/changelogs/unreleased/_acet-disable-ide-button.yml
deleted file mode 100644
index 2fff3847052..00000000000
--- a/changelogs/unreleased/_acet-disable-ide-button.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Disable Web IDE button if user is not allowed to push the source branch.
-merge_request: 21288
-author:
-type: added
diff --git a/changelogs/unreleased/ab-49446-internal-ids-inconsistency.yml b/changelogs/unreleased/ab-49446-internal-ids-inconsistency.yml
deleted file mode 100644
index bfea57d79e0..00000000000
--- a/changelogs/unreleased/ab-49446-internal-ids-inconsistency.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Add migration to cleanup internal_ids inconsistency.
-merge_request: 20926
-author:
-type: fixed
diff --git a/changelogs/unreleased/add-background-migration-for-legacy-traces.yml b/changelogs/unreleased/add-background-migration-for-legacy-traces.yml
deleted file mode 100644
index 3d5a0b4e452..00000000000
--- a/changelogs/unreleased/add-background-migration-for-legacy-traces.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Add background migrations for legacy artifacts
-merge_request: 18615
-author:
-type: performance
diff --git a/changelogs/unreleased/add-ci_archive_traces_cron_worker-to-gitlab-yml.yml b/changelogs/unreleased/add-ci_archive_traces_cron_worker-to-gitlab-yml.yml
deleted file mode 100644
index d963dc5bac3..00000000000
--- a/changelogs/unreleased/add-ci_archive_traces_cron_worker-to-gitlab-yml.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Add an example of the configuration of archive trace cron worker in gitlab.yml.example
-merge_request: 20583
-author:
-type: other
diff --git a/changelogs/unreleased/add-most-stars-for-filter-option.yml b/changelogs/unreleased/add-most-stars-for-filter-option.yml
new file mode 100644
index 00000000000..be95d6db55f
--- /dev/null
+++ b/changelogs/unreleased/add-most-stars-for-filter-option.yml
@@ -0,0 +1,5 @@
+---
+title: Allows to sort projects by most stars
+merge_request: 21762
+author: Jacopo Beschi @jacopo-beschi
+type: added
diff --git a/changelogs/unreleased/add-rake-command-to-migrate-locally-persisted-archived-traces.yml b/changelogs/unreleased/add-rake-command-to-migrate-locally-persisted-archived-traces.yml
deleted file mode 100644
index b82344e3c9c..00000000000
--- a/changelogs/unreleased/add-rake-command-to-migrate-locally-persisted-archived-traces.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Add rake command to migrate archived traces from local storage to object storage
-merge_request: 21193
-author:
-type: added
diff --git a/changelogs/unreleased/add_google_noto_color_emoji_font.yml b/changelogs/unreleased/add_google_noto_color_emoji_font.yml
deleted file mode 100644
index 9ba46262767..00000000000
--- a/changelogs/unreleased/add_google_noto_color_emoji_font.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Add Noto Color Emoji font support
-merge_request: 19036
-author: Alexander Popov
-type: changed
diff --git a/changelogs/unreleased/align-form-labels.yml b/changelogs/unreleased/align-form-labels.yml
new file mode 100644
index 00000000000..fd781e3b910
--- /dev/null
+++ b/changelogs/unreleased/align-form-labels.yml
@@ -0,0 +1,5 @@
+---
+title: Align form labels following Bootstrap 4 docs
+merge_request: 21752
+author:
+type: fixed
diff --git a/changelogs/unreleased/an-ap_log_gitaly_calls.yml b/changelogs/unreleased/an-ap_log_gitaly_calls.yml
deleted file mode 100644
index 65bac55a73e..00000000000
--- a/changelogs/unreleased/an-ap_log_gitaly_calls.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Add gitaly_calls attribute to API logs
-merge_request: 21496
-author:
-type: other
diff --git a/changelogs/unreleased/an-api-route-logger.yml b/changelogs/unreleased/an-api-route-logger.yml
deleted file mode 100644
index cca3ef44f36..00000000000
--- a/changelogs/unreleased/an-api-route-logger.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Add route information to lograge structured logging for API logs
-merge_request: 21487
-author:
-type: other
diff --git a/changelogs/unreleased/api-empty-commit-message.yml b/changelogs/unreleased/api-empty-commit-message.yml
deleted file mode 100644
index 34ddc020644..00000000000
--- a/changelogs/unreleased/api-empty-commit-message.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: 'API: Catch empty commit messages'
-merge_request: 21322
-author: Robert Schilling
-type: fixed
diff --git a/changelogs/unreleased/api-empty-project-snippets.yml b/changelogs/unreleased/api-empty-project-snippets.yml
deleted file mode 100644
index 7b8c7c9e48d..00000000000
--- a/changelogs/unreleased/api-empty-project-snippets.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: 'API: Catch empty code content for project snippets'
-merge_request: 21325
-author: Robert Schilling
-type: fixed
diff --git a/changelogs/unreleased/api-promote-find-branch.yml b/changelogs/unreleased/api-promote-find-branch.yml
deleted file mode 100644
index cfa767809b2..00000000000
--- a/changelogs/unreleased/api-promote-find-branch.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: 'API: Use find_branch! in all places'
-merge_request: 21614
-author: Robert Schilling
-type: fixed
diff --git a/changelogs/unreleased/api-protected-tags.yml b/changelogs/unreleased/api-protected-tags.yml
deleted file mode 100644
index 6e7ecf24b6e..00000000000
--- a/changelogs/unreleased/api-protected-tags.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: 'API: Protected tags'
-merge_request: 14986
-author: Robert Schilling
-type: added
diff --git a/changelogs/unreleased/api-shared_group_expires-at.yml b/changelogs/unreleased/api-shared_group_expires-at.yml
deleted file mode 100644
index 3d569de65fa..00000000000
--- a/changelogs/unreleased/api-shared_group_expires-at.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: 'API: Add expiration date for shared projects to the project entity'
-merge_request: 21104
-author: Robert Schilling
-type: added
diff --git a/changelogs/unreleased/arguments-keyword-sast.yml b/changelogs/unreleased/arguments-keyword-sast.yml
deleted file mode 100644
index 2ecbc5e8174..00000000000
--- a/changelogs/unreleased/arguments-keyword-sast.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Don't use arguments keyword in gettext script
-merge_request: 21296
-author: gfyoung
-type: fixed
diff --git a/changelogs/unreleased/ash-mckenzie-geo-git-push-ssh-proxy.yml b/changelogs/unreleased/ash-mckenzie-geo-git-push-ssh-proxy.yml
deleted file mode 100644
index c145c744cef..00000000000
--- a/changelogs/unreleased/ash-mckenzie-geo-git-push-ssh-proxy.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: 'Support a custom action, such as proxying to another server, after /api/v4/internal/allowed check succeeds'
-merge_request: 21034
-author:
-type: changed
diff --git a/changelogs/unreleased/auto-devops-gitlab-ci-glic-228.yml b/changelogs/unreleased/auto-devops-gitlab-ci-glic-228.yml
deleted file mode 100644
index a1625193189..00000000000
--- a/changelogs/unreleased/auto-devops-gitlab-ci-glic-228.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: 'Auto-DevOps.gitlab-ci.yml: update glibc package to 2.28'
-merge_request: 21191
-author: sgerrand
-type: fixed
diff --git a/changelogs/unreleased/bvl-add-czech.yml b/changelogs/unreleased/bvl-add-czech.yml
deleted file mode 100644
index 49e0e4a74b7..00000000000
--- a/changelogs/unreleased/bvl-add-czech.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Add Czech as an available language.
-merge_request: 21201
-author:
-type: added
diff --git a/changelogs/unreleased/bvl-add-galician.yml b/changelogs/unreleased/bvl-add-galician.yml
deleted file mode 100644
index e7035901ace..00000000000
--- a/changelogs/unreleased/bvl-add-galician.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Add Galician as an available language.
-merge_request: 21202
-author:
-type: added
diff --git a/changelogs/unreleased/bvl-merge-base-api.yml b/changelogs/unreleased/bvl-merge-base-api.yml
deleted file mode 100644
index 78fb3ce0897..00000000000
--- a/changelogs/unreleased/bvl-merge-base-api.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Get the merge base of two refs through the API
-merge_request: 20929
-author:
-type: added
diff --git a/changelogs/unreleased/bw-commonmark-for-files.yml b/changelogs/unreleased/bw-commonmark-for-files.yml
deleted file mode 100644
index f932ccb704f..00000000000
--- a/changelogs/unreleased/bw-commonmark-for-files.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Render files (`.md`) and wikis using CommonMark
-merge_request: 21228
-author:
-type: changed
diff --git a/changelogs/unreleased/ccr-43283_allow_author_upvote.yml b/changelogs/unreleased/ccr-43283_allow_author_upvote.yml
deleted file mode 100644
index 12ef6e3f790..00000000000
--- a/changelogs/unreleased/ccr-43283_allow_author_upvote.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Allow author to vote on their own issue and MRs
-merge_request: 21203
-author:
-type: changed
diff --git a/changelogs/unreleased/ccr-48800-ping_for_boards.yml b/changelogs/unreleased/ccr-48800-ping_for_boards.yml
deleted file mode 100644
index c08578cddba..00000000000
--- a/changelogs/unreleased/ccr-48800-ping_for_boards.yml
+++ /dev/null
@@ -1,6 +0,0 @@
----
-title: Adds count for different board list types (label lists, assignee lists, and
- milestone lists) to usage statistics.
-merge_request: 21208
-author:
-type: changed
diff --git a/changelogs/unreleased/ccr-6699_image_for_object_error.yml b/changelogs/unreleased/ccr-6699_image_for_object_error.yml
deleted file mode 100644
index dec1adaceff..00000000000
--- a/changelogs/unreleased/ccr-6699_image_for_object_error.yml
+++ /dev/null
@@ -1,6 +0,0 @@
----
-title: Handles exception during file upload - replaces the stack trace with a small
- error message.
-merge_request: 21528
-author:
-type: fixed
diff --git a/changelogs/unreleased/ce-5666-optimize_querying_manageable_groups.yml b/changelogs/unreleased/ce-5666-optimize_querying_manageable_groups.yml
deleted file mode 100644
index 0c6a1071cdd..00000000000
--- a/changelogs/unreleased/ce-5666-optimize_querying_manageable_groups.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Optimize querying User#manageable_groups
-merge_request: 21050
-author:
-type: performance
diff --git a/changelogs/unreleased/ci-builds-status-index.yml b/changelogs/unreleased/ci-builds-status-index.yml
deleted file mode 100644
index 8b7252f09e5..00000000000
--- a/changelogs/unreleased/ci-builds-status-index.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Remove redundant ci_builds (status) index
-merge_request: 21070
-author:
-type: performance
diff --git a/changelogs/unreleased/dm-create-note-return-discussion.yml b/changelogs/unreleased/dm-create-note-return-discussion.yml
new file mode 100644
index 00000000000..49ab5c0ca14
--- /dev/null
+++ b/changelogs/unreleased/dm-create-note-return-discussion.yml
@@ -0,0 +1,5 @@
+---
+title: Increase performance when creating discussions on diff
+merge_request:
+author:
+type: performance
diff --git a/changelogs/unreleased/dz-fix-sql-error-admin-users-2fa.yml b/changelogs/unreleased/dz-fix-sql-error-admin-users-2fa.yml
deleted file mode 100644
index 67926f3738a..00000000000
--- a/changelogs/unreleased/dz-fix-sql-error-admin-users-2fa.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix SQL error when sorting 2FA-enabled users by name in admin area
-merge_request: 21324
-author:
-type: fixed
diff --git a/changelogs/unreleased/dz-group-labels-search.yml b/changelogs/unreleased/dz-group-labels-search.yml
deleted file mode 100644
index bb4719df22d..00000000000
--- a/changelogs/unreleased/dz-group-labels-search.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Add search to a group labels page
-merge_request: 21480
-author:
-type: added
diff --git a/changelogs/unreleased/ee-6381-multiseries.yml b/changelogs/unreleased/ee-6381-multiseries.yml
deleted file mode 100644
index a749e31d27c..00000000000
--- a/changelogs/unreleased/ee-6381-multiseries.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Allow gaps in multiseries metrics charts
-merge_request: 21427
-author:
-type: fixed
diff --git a/changelogs/unreleased/emoji-cutoff-1px.yml b/changelogs/unreleased/emoji-cutoff-1px.yml
deleted file mode 100644
index 815d9c177e8..00000000000
--- a/changelogs/unreleased/emoji-cutoff-1px.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix 1px cutoff of emojis
-merge_request: 21180
-author: gfyoung
-type: fixed
diff --git a/changelogs/unreleased/expose-all-artifacts-sizes-in-jobs-api.yml b/changelogs/unreleased/expose-all-artifacts-sizes-in-jobs-api.yml
deleted file mode 100644
index 1453d39934b..00000000000
--- a/changelogs/unreleased/expose-all-artifacts-sizes-in-jobs-api.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Expose all artifacts sizes in jobs api
-merge_request: 20821
-author: Peter Marko
-type: added
diff --git a/changelogs/unreleased/expose-users-id-in-admin-users-show-page.yml b/changelogs/unreleased/expose-users-id-in-admin-users-show-page.yml
deleted file mode 100644
index 0b8ae527214..00000000000
--- a/changelogs/unreleased/expose-users-id-in-admin-users-show-page.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Expose user's id in /admin/users/ show page
-merge_request:
-author: Eva Kadlecova
-type: changed
diff --git a/changelogs/unreleased/feat-add-default-avatar-to-group.yml b/changelogs/unreleased/feat-add-default-avatar-to-group.yml
deleted file mode 100644
index 56d8f2ccd6d..00000000000
--- a/changelogs/unreleased/feat-add-default-avatar-to-group.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Add default avatar to group
-merge_request: 17271
-author: George Tsiolis
-type: changed
diff --git a/changelogs/unreleased/feat-update-contribution-calendar.yml b/changelogs/unreleased/feat-update-contribution-calendar.yml
deleted file mode 100644
index 4ada8b1fcd5..00000000000
--- a/changelogs/unreleased/feat-update-contribution-calendar.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Include private contributions to contributions calendar
-merge_request: 17296
-author: George Tsiolis
-type: added
diff --git a/changelogs/unreleased/feature--32877-add-default-field-branch-api.yml b/changelogs/unreleased/feature--32877-add-default-field-branch-api.yml
deleted file mode 100644
index a99ecc9a67e..00000000000
--- a/changelogs/unreleased/feature--32877-add-default-field-branch-api.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Add default parameter to branches API
-merge_request: 21294
-author: Riccardo Padovani
-type: changed
diff --git a/changelogs/unreleased/feature-gb-allow-to-extend-keys-in-gitlab-ci-yml.yml b/changelogs/unreleased/feature-gb-allow-to-extend-keys-in-gitlab-ci-yml.yml
deleted file mode 100644
index b46dfd47e7a..00000000000
--- a/changelogs/unreleased/feature-gb-allow-to-extend-keys-in-gitlab-ci-yml.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Add support for extendable CI/CD config with
-merge_request: 21243
-author:
-type: added
diff --git a/changelogs/unreleased/feature-git-v2-flag.yml b/changelogs/unreleased/feature-git-v2-flag.yml
deleted file mode 100644
index c105c477666..00000000000
--- a/changelogs/unreleased/feature-git-v2-flag.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Add git_v2 feature flag
-merge_request: 21520
-author:
-type: added
diff --git a/changelogs/unreleased/feature-whitelist-new-users-as-internal.yml b/changelogs/unreleased/feature-whitelist-new-users-as-internal.yml
deleted file mode 100644
index 7a3bd11c119..00000000000
--- a/changelogs/unreleased/feature-whitelist-new-users-as-internal.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Add an option to whitelist users based on email address as internal when the "New user set to external" setting is enabled.
-merge_request: 17711
-author: Roger Rüttimann
-type: added
diff --git a/changelogs/unreleased/filter-web-hooks-by-branch.yml b/changelogs/unreleased/filter-web-hooks-by-branch.yml
deleted file mode 100644
index 7bd2c191d7f..00000000000
--- a/changelogs/unreleased/filter-web-hooks-by-branch.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Add branch filter to project webhooks
-merge_request: 20338
-author: Duana Saskia
-type: added
diff --git a/changelogs/unreleased/fix-api-group-createdat.yml b/changelogs/unreleased/fix-api-group-createdat.yml
deleted file mode 100644
index e628facf1bf..00000000000
--- a/changelogs/unreleased/fix-api-group-createdat.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Allow date parameters on Issues, Notes, and Discussions API for group owners
-merge_request: 21342
-author: Florent Dubois
-type: fixed
diff --git a/changelogs/unreleased/fix-chat-notification-service-for-ee.yml b/changelogs/unreleased/fix-chat-notification-service-for-ee.yml
new file mode 100644
index 00000000000..b69d08b95db
--- /dev/null
+++ b/changelogs/unreleased/fix-chat-notification-service-for-ee.yml
@@ -0,0 +1,5 @@
+---
+title: Fix activity titles for MRs in chat notification services
+merge_request: 21834
+author:
+type: fixed
diff --git a/changelogs/unreleased/fix-closing-issues.yml b/changelogs/unreleased/fix-closing-issues.yml
deleted file mode 100644
index ba80f371580..00000000000
--- a/changelogs/unreleased/fix-closing-issues.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix closing issue default pattern
-merge_request: 21531
-author: Samuele Kaplun
-type: fixed
diff --git a/changelogs/unreleased/fix-download-dropdown-link.yml b/changelogs/unreleased/fix-download-dropdown-link.yml
deleted file mode 100644
index 998476b07bd..00000000000
--- a/changelogs/unreleased/fix-download-dropdown-link.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Hide PAT creation advice for HTTP clone if PAT exists
-merge_request: 18208
-author: George Thomas @thegeorgeous
-type: fixed
diff --git a/changelogs/unreleased/fix-help-text-font-color-in-merge-request-creation.yml b/changelogs/unreleased/fix-help-text-font-color-in-merge-request-creation.yml
new file mode 100644
index 00000000000..4ac192cd056
--- /dev/null
+++ b/changelogs/unreleased/fix-help-text-font-color-in-merge-request-creation.yml
@@ -0,0 +1,5 @@
+---
+title: Fix wrong text color of help text in merge request creation
+merge_request:
+author: Gerard Montemayor
+type: fixed
diff --git a/changelogs/unreleased/fix-junit-parser.yml b/changelogs/unreleased/fix-junit-parser.yml
deleted file mode 100644
index e0a9ad8f210..00000000000
--- a/changelogs/unreleased/fix-junit-parser.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix edge cases of JUnitParser
-merge_request: 21469
-author:
-type: fixed
diff --git a/changelogs/unreleased/fix-labels-list-item-height-with-no-description.yml b/changelogs/unreleased/fix-labels-list-item-height-with-no-description.yml
deleted file mode 100644
index d215d034917..00000000000
--- a/changelogs/unreleased/fix-labels-list-item-height-with-no-description.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix label list item container height when there is no label description
-merge_request: 21106
-author:
-type: fixed
diff --git a/changelogs/unreleased/fix-leading-slash-in-redirects-plus-rubocop.yml b/changelogs/unreleased/fix-leading-slash-in-redirects-plus-rubocop.yml
new file mode 100644
index 00000000000..38b2486a475
--- /dev/null
+++ b/changelogs/unreleased/fix-leading-slash-in-redirects-plus-rubocop.yml
@@ -0,0 +1,5 @@
+---
+title: Fix leading slash in redirects and add rubocop cop
+merge_request: 21828
+author: Sanad Liaquat
+type: fixed
diff --git a/changelogs/unreleased/fix-mr-title-fallback-logic.yml b/changelogs/unreleased/fix-mr-title-fallback-logic.yml
deleted file mode 100644
index 5056c38573b..00000000000
--- a/changelogs/unreleased/fix-mr-title-fallback-logic.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix fallback logic for automatic MR title assignment
-merge_request: 20930
-author: Franz Liedke
-type: fixed
diff --git a/changelogs/unreleased/fix-namespace-upload.yml b/changelogs/unreleased/fix-namespace-upload.yml
deleted file mode 100644
index 383d79a998f..00000000000
--- a/changelogs/unreleased/fix-namespace-upload.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix workhorse temp path for namespace uploads
-merge_request: 21650
-author:
-type: fixed
diff --git a/changelogs/unreleased/fix-namespace-uploader.yml b/changelogs/unreleased/fix-namespace-uploader.yml
deleted file mode 100644
index 081adc9a6f1..00000000000
--- a/changelogs/unreleased/fix-namespace-uploader.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix NamespaceUploader.base_dir for remote uploads
-merge_request:
-author:
-type: fixed
diff --git a/changelogs/unreleased/fix-pipeline-fixture-seeder.yml b/changelogs/unreleased/fix-pipeline-fixture-seeder.yml
deleted file mode 100644
index 02b83062e07..00000000000
--- a/changelogs/unreleased/fix-pipeline-fixture-seeder.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix pipeline fixture seeder
-merge_request: 21088
-author:
-type: fixed
diff --git a/changelogs/unreleased/fix_emojis_cutting_and_regressions.yml b/changelogs/unreleased/fix_emojis_cutting_and_regressions.yml
deleted file mode 100644
index a9c1b88a61c..00000000000
--- a/changelogs/unreleased/fix_emojis_cutting_and_regressions.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix Emojis cutting in the right way
-merge_request:
-author: Alexander Popov
-type: fixed
diff --git a/changelogs/unreleased/fix_event_api_permissions.yml b/changelogs/unreleased/fix_event_api_permissions.yml
deleted file mode 100644
index dee280e93ad..00000000000
--- a/changelogs/unreleased/fix_event_api_permissions.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: 'Events API now requires the read_user or api scope.'
-merge_request: 20627
-author: Warren Parad
-type: fixed
diff --git a/changelogs/unreleased/fj-2635-enable-rss-for-tags.yml b/changelogs/unreleased/fj-2635-enable-rss-for-tags.yml
deleted file mode 100644
index ee197572385..00000000000
--- a/changelogs/unreleased/fj-2635-enable-rss-for-tags.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Added atom feed for tags
-merge_request: 21428
-author:
-type: added
diff --git a/changelogs/unreleased/fj-33475-files-inside-wiki-repo.yml b/changelogs/unreleased/fj-33475-files-inside-wiki-repo.yml
deleted file mode 100644
index 8c1f0e3dbf2..00000000000
--- a/changelogs/unreleased/fj-33475-files-inside-wiki-repo.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Store wiki uploads inside git repository
-merge_request: 21362
-author:
-type: added
diff --git a/changelogs/unreleased/fj-47229-fix-logo-lfs-tracked.yml b/changelogs/unreleased/fj-47229-fix-logo-lfs-tracked.yml
deleted file mode 100644
index ed2af81f779..00000000000
--- a/changelogs/unreleased/fj-47229-fix-logo-lfs-tracked.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fixed bug when the project logo file is stored in LFS
-merge_request: 20948
-author:
-type: fixed
diff --git a/changelogs/unreleased/fj-51194-fix-wiki-attachments-with-whitespaces.yml b/changelogs/unreleased/fj-51194-fix-wiki-attachments-with-whitespaces.yml
deleted file mode 100644
index a6464807e01..00000000000
--- a/changelogs/unreleased/fj-51194-fix-wiki-attachments-with-whitespaces.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Replace white spaces in wiki attachments file names
-merge_request: 21569
-author:
-type: fixed
diff --git a/changelogs/unreleased/fl-reduce-ee-conflicts-reports-code.yml b/changelogs/unreleased/fl-reduce-ee-conflicts-reports-code.yml
deleted file mode 100644
index 068681dfe19..00000000000
--- a/changelogs/unreleased/fl-reduce-ee-conflicts-reports-code.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Reduce differences between CE and EE code base in reports components
-merge_request:
-author:
-type: other
diff --git a/changelogs/unreleased/force-post-migration-dir-schema-load.yml b/changelogs/unreleased/force-post-migration-dir-schema-load.yml
new file mode 100644
index 00000000000..19119515929
--- /dev/null
+++ b/changelogs/unreleased/force-post-migration-dir-schema-load.yml
@@ -0,0 +1,5 @@
+---
+title: Ensure the schema is loaded with post_migrations included
+merge_request: 21689
+author:
+type: changed
diff --git a/changelogs/unreleased/frozen-string-app-controller.yml b/changelogs/unreleased/frozen-string-app-controller.yml
new file mode 100644
index 00000000000..95fea4eae63
--- /dev/null
+++ b/changelogs/unreleased/frozen-string-app-controller.yml
@@ -0,0 +1,5 @@
+---
+title: Enable frozen string in app/controllers/**/*.rb
+merge_request: gfyoung
+author:
+type: performance
diff --git a/changelogs/unreleased/frozen-string-enable-app-mailers.yml b/changelogs/unreleased/frozen-string-enable-app-mailers.yml
deleted file mode 100644
index 2cd247ca76c..00000000000
--- a/changelogs/unreleased/frozen-string-enable-app-mailers.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Enable frozen in app/mailers/**/*.rb
-merge_request: 21147
-author: gfyoung
-type: performance
diff --git a/changelogs/unreleased/frozen-string-enable-app-models-even-more-still.yml b/changelogs/unreleased/frozen-string-enable-app-models-even-more-still.yml
deleted file mode 100644
index a77f3baeed3..00000000000
--- a/changelogs/unreleased/frozen-string-enable-app-models-even-more-still.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Enable frozen string in rest of app/models/**/*.rb
-merge_request: gfyoung
-author:
-type: performance
diff --git a/changelogs/unreleased/frozen-string-enable-app-vestigial.yml b/changelogs/unreleased/frozen-string-enable-app-vestigial.yml
deleted file mode 100644
index 8cb7bd43784..00000000000
--- a/changelogs/unreleased/frozen-string-enable-app-vestigial.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Enable frozen string in vestigial app files
-merge_request:
-author: gfyoung
-type: performance
diff --git a/changelogs/unreleased/gitaly-install-path.yml b/changelogs/unreleased/gitaly-install-path.yml
deleted file mode 100644
index 4b24cd81dc7..00000000000
--- a/changelogs/unreleased/gitaly-install-path.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Remove storage path dependency of gitaly install task
-merge_request: 21101
-author:
-type: changed
diff --git a/changelogs/unreleased/ide-commit-panel-improved.yml b/changelogs/unreleased/ide-commit-panel-improved.yml
deleted file mode 100644
index 245214185e5..00000000000
--- a/changelogs/unreleased/ide-commit-panel-improved.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Improved commit panel in Web IDE
-merge_request: 21471
-author:
-type: changed
diff --git a/changelogs/unreleased/ide-delete-new-files-state.yml b/changelogs/unreleased/ide-delete-new-files-state.yml
deleted file mode 100644
index 500115d19d0..00000000000
--- a/changelogs/unreleased/ide-delete-new-files-state.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fixed IDE deleting new files creating wrong state
-merge_request:
-author:
-type: fixed
diff --git a/changelogs/unreleased/ide-file-templates.yml b/changelogs/unreleased/ide-file-templates.yml
deleted file mode 100644
index 68983670b25..00000000000
--- a/changelogs/unreleased/ide-file-templates.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Added file templates to the Web IDE
-merge_request:
-author:
-type: added
diff --git a/changelogs/unreleased/ide-header-buttons-tooltip.yml b/changelogs/unreleased/ide-header-buttons-tooltip.yml
deleted file mode 100644
index 4c8f6fd554f..00000000000
--- a/changelogs/unreleased/ide-header-buttons-tooltip.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Added tooltips to tree list header
-merge_request: 21138
-author:
-type: added
diff --git a/changelogs/unreleased/ide-job-top-bar-ui-polish.yml b/changelogs/unreleased/ide-job-top-bar-ui-polish.yml
deleted file mode 100644
index d917c14e5f8..00000000000
--- a/changelogs/unreleased/ide-job-top-bar-ui-polish.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Improved styling of top bar in IDE job trace pane
-merge_request:
-author:
-type: changed
diff --git a/changelogs/unreleased/ide-multiple-file-uploads.yml b/changelogs/unreleased/ide-multiple-file-uploads.yml
deleted file mode 100644
index 6bb73739864..00000000000
--- a/changelogs/unreleased/ide-multiple-file-uploads.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Enabled multiple file uploads in the Web IDE
-merge_request:
-author:
-type: added
diff --git a/changelogs/unreleased/ide-open-empty-merge-request.yml b/changelogs/unreleased/ide-open-empty-merge-request.yml
deleted file mode 100644
index 05f2de5d31c..00000000000
--- a/changelogs/unreleased/ide-open-empty-merge-request.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix empty merge requests not opening in the Web IDE
-merge_request: 21102
-author:
-type: fixed
diff --git a/changelogs/unreleased/ide-row-hover-scroll.yml b/changelogs/unreleased/ide-row-hover-scroll.yml
deleted file mode 100644
index 24c273b4f25..00000000000
--- a/changelogs/unreleased/ide-row-hover-scroll.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fixed IDE file row scrolling into view when hovering
-merge_request:
-author:
-type: fixed
diff --git a/changelogs/unreleased/import-all-common-metrics-into-database.yml b/changelogs/unreleased/import-all-common-metrics-into-database.yml
deleted file mode 100644
index 524112fe115..00000000000
--- a/changelogs/unreleased/import-all-common-metrics-into-database.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Import all common metrics into database
-merge_request: 21459
-author:
-type: changed
diff --git a/changelogs/unreleased/issue_36138.yml b/changelogs/unreleased/issue_36138.yml
deleted file mode 100644
index 2fb2eea65f5..00000000000
--- a/changelogs/unreleased/issue_36138.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Allow to delete group milestones
-merge_request:
-author:
-type: added
diff --git a/changelogs/unreleased/issue_50488.yml b/changelogs/unreleased/issue_50488.yml
deleted file mode 100644
index dad7ae55a0d..00000000000
--- a/changelogs/unreleased/issue_50488.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Move project services log to a separate file
-merge_request:
-author:
-type: other
diff --git a/changelogs/unreleased/jprovazn-fix-form-uploads.yml b/changelogs/unreleased/jprovazn-fix-form-uploads.yml
deleted file mode 100644
index 8bcee335e93..00000000000
--- a/changelogs/unreleased/jprovazn-fix-form-uploads.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Accept upload files in public/uplaods/tmp when using accelerated uploads.
-merge_request:
-author:
-type: fixed
diff --git a/changelogs/unreleased/label-event.yml b/changelogs/unreleased/label-event.yml
deleted file mode 100644
index e543abe5649..00000000000
--- a/changelogs/unreleased/label-event.yml
+++ /dev/null
@@ -1,6 +0,0 @@
----
-title: Use separate model for tracking resource label changes and render label system
- notes based on data from this model.
-merge_request:
-author:
-type: added
diff --git a/changelogs/unreleased/limit-navbar-search-for-current-project-or-group-for-small-viewports.yml b/changelogs/unreleased/limit-navbar-search-for-current-project-or-group-for-small-viewports.yml
deleted file mode 100644
index 09d97d200de..00000000000
--- a/changelogs/unreleased/limit-navbar-search-for-current-project-or-group-for-small-viewports.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Limit navbar search for current project or group for small viewports
-merge_request: 18634
-author: George Tsiolis
-type: changed
diff --git a/changelogs/unreleased/mk-bump-rainbow-gem.yml b/changelogs/unreleased/mk-bump-rainbow-gem.yml
deleted file mode 100644
index 31c003fb4d9..00000000000
--- a/changelogs/unreleased/mk-bump-rainbow-gem.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix bin/secpick error and security branch prefixing
-merge_request: 21210
-author:
-type: fixed
diff --git a/changelogs/unreleased/monaco-upgrade.yml b/changelogs/unreleased/monaco-upgrade.yml
deleted file mode 100644
index ec441ba182b..00000000000
--- a/changelogs/unreleased/monaco-upgrade.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Upgrade Monaco editor
-merge_request:
-author:
-type: other
diff --git a/changelogs/unreleased/mr-fixed-expanded-state-not-working.yml b/changelogs/unreleased/mr-fixed-expanded-state-not-working.yml
deleted file mode 100644
index b8bf8306546..00000000000
--- a/changelogs/unreleased/mr-fixed-expanded-state-not-working.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fixed resolved discussions not toggling expanded state on changes tab
-merge_request: 21676
-author:
-type: fixed
diff --git a/changelogs/unreleased/mr-legacy-diff-notes.yml b/changelogs/unreleased/mr-legacy-diff-notes.yml
new file mode 100644
index 00000000000..bca5ac8297f
--- /dev/null
+++ b/changelogs/unreleased/mr-legacy-diff-notes.yml
@@ -0,0 +1,5 @@
+---
+title: Correctly show legacy diff notes in the merge request changes tab
+merge_request: 21652
+author:
+type: fixed
diff --git a/changelogs/unreleased/n8rzz-consolidate-specs-testing-emoji-awards.yml b/changelogs/unreleased/n8rzz-consolidate-specs-testing-emoji-awards.yml
deleted file mode 100644
index bcf3d2c8e16..00000000000
--- a/changelogs/unreleased/n8rzz-consolidate-specs-testing-emoji-awards.yml
+++ /dev/null
@@ -1,6 +0,0 @@
----
-title: Combines emoji award spec files into single user_interacts_with_awards_in_issue_spec.rb
- file
-merge_request: 21126
-author: Nate Geslin
-type: other
diff --git a/changelogs/unreleased/osw-gitaly-diff-stats-client.yml b/changelogs/unreleased/osw-gitaly-diff-stats-client.yml
new file mode 100644
index 00000000000..9f280162409
--- /dev/null
+++ b/changelogs/unreleased/osw-gitaly-diff-stats-client.yml
@@ -0,0 +1,5 @@
+---
+title: Add Gitaly diff stats RPC client
+merge_request: 21732
+author:
+type: changed
diff --git a/changelogs/unreleased/osw-send-max-patch-bytes-to-gitaly.yml b/changelogs/unreleased/osw-send-max-patch-bytes-to-gitaly.yml
deleted file mode 100644
index 3c50448e3ff..00000000000
--- a/changelogs/unreleased/osw-send-max-patch-bytes-to-gitaly.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Send max_patch_bytes to Gitaly via Gitaly::CommitDiffRequest
-merge_request: 21575
-author:
-type: other
diff --git a/changelogs/unreleased/osw-use-diff-stats-rpc-on-comparison-views.yml b/changelogs/unreleased/osw-use-diff-stats-rpc-on-comparison-views.yml
new file mode 100644
index 00000000000..c71d4e58d6f
--- /dev/null
+++ b/changelogs/unreleased/osw-use-diff-stats-rpc-on-comparison-views.yml
@@ -0,0 +1,5 @@
+---
+title: Use stats RPC when comparing diffs
+merge_request: 21778
+author:
+type: fixed
diff --git a/changelogs/unreleased/osw-write-cache-upon-mr-creation-and-cache-refactoring.yml b/changelogs/unreleased/osw-write-cache-upon-mr-creation-and-cache-refactoring.yml
deleted file mode 100644
index 4fba33decfa..00000000000
--- a/changelogs/unreleased/osw-write-cache-upon-mr-creation-and-cache-refactoring.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Write diff highlighting cache upon MR creation (refactors caching)
-merge_request: 21489
-author:
-type: performance
diff --git a/changelogs/unreleased/rails5-explicit-hashed-path-check.yml b/changelogs/unreleased/rails5-explicit-hashed-path-check.yml
deleted file mode 100644
index 93fe4a38411..00000000000
--- a/changelogs/unreleased/rails5-explicit-hashed-path-check.yml
+++ /dev/null
@@ -1,6 +0,0 @@
----
-title: Explicit hashed path check for trace, prevents background migration from accessing
- file_location column that doesn't exist
-merge_request: 21533
-author: Jasper Maes
-type: other
diff --git a/changelogs/unreleased/rails5-fix-duplicate-gpg-signature.yml b/changelogs/unreleased/rails5-fix-duplicate-gpg-signature.yml
deleted file mode 100644
index e31768773b1..00000000000
--- a/changelogs/unreleased/rails5-fix-duplicate-gpg-signature.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Rails5 fix specs duplicate key value violates unique constraint 'index_gpg_signatures_on_commit_sha'
-merge_request: 21119
-author: Jasper Maes
-type: fixed
diff --git a/changelogs/unreleased/rails5-fix-import-merge-request-creator.yml b/changelogs/unreleased/rails5-fix-import-merge-request-creator.yml
deleted file mode 100644
index 661bd748333..00000000000
--- a/changelogs/unreleased/rails5-fix-import-merge-request-creator.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: 'Rails5: fix can''t quote ActiveSupport::HashWithIndifferentAccess'
-merge_request: 21397
-author: Jasper Maes
-type: other
diff --git a/changelogs/unreleased/rails5-fix-job-artifact-hashed-path.yml b/changelogs/unreleased/rails5-fix-job-artifact-hashed-path.yml
deleted file mode 100644
index a70bfafb1c9..00000000000
--- a/changelogs/unreleased/rails5-fix-job-artifact-hashed-path.yml
+++ /dev/null
@@ -1,6 +0,0 @@
----
-title: 'Rails 5: fix hashed_path? method that looks up file_location that doesn''t
- exist when running certain migration specs'
-merge_request: 21510
-author: Jasper Maes
-type: other
diff --git a/changelogs/unreleased/rails5-include-opclasses-in-schema-dump.yml b/changelogs/unreleased/rails5-include-opclasses-in-schema-dump.yml
deleted file mode 100644
index 2dea84bc266..00000000000
--- a/changelogs/unreleased/rails5-include-opclasses-in-schema-dump.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: 'Rails 5: include opclasses in rails 5 schema dump'
-merge_request: 21416
-author: Jasper Maes
-type: fixed
diff --git a/changelogs/unreleased/rails5-mysql-binary-column-index-length.yml b/changelogs/unreleased/rails5-mysql-binary-column-index-length.yml
deleted file mode 100644
index c4eb0ddac4c..00000000000
--- a/changelogs/unreleased/rails5-mysql-binary-column-index-length.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: 'Rails 5: support schema t.index for mysql'
-merge_request: 21485
-author: Jasper Maes
-type: other
diff --git a/changelogs/unreleased/rails5-silence-stream.yml b/changelogs/unreleased/rails5-silence-stream.yml
deleted file mode 100644
index df4fd14a077..00000000000
--- a/changelogs/unreleased/rails5-silence-stream.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: 'Rails 5: replace removed silence_stream'
-merge_request: 21387
-author: Jasper Maes
-type: other
diff --git a/changelogs/unreleased/rails5-update-gemfile-lock.yml b/changelogs/unreleased/rails5-update-gemfile-lock.yml
deleted file mode 100644
index 3891b16e2b8..00000000000
--- a/changelogs/unreleased/rails5-update-gemfile-lock.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Rails5 update Gemfile.rails5.lock
-merge_request: 21388
-author: Jasper Maes
-type: other
diff --git a/changelogs/unreleased/rails5-verbose-query-logs.yml b/changelogs/unreleased/rails5-verbose-query-logs.yml
deleted file mode 100644
index 7585e75d30b..00000000000
--- a/changelogs/unreleased/rails5-verbose-query-logs.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: 'Rails5: Enable verbose query logs'
-merge_request: 21231
-author: Jasper Maes
-type: other
diff --git a/changelogs/unreleased/rd-26044-new-option-to-prevent-too-big-git-pushes.yml b/changelogs/unreleased/rd-26044-new-option-to-prevent-too-big-git-pushes.yml
deleted file mode 100644
index f464b6dda5b..00000000000
--- a/changelogs/unreleased/rd-26044-new-option-to-prevent-too-big-git-pushes.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Allow admins to configure the maximum Git push size
-merge_request: 20758
-author:
-type: added
diff --git a/changelogs/unreleased/remove-background-migration-worker-feature-flag.yml b/changelogs/unreleased/remove-background-migration-worker-feature-flag.yml
deleted file mode 100644
index 429ab6c59e3..00000000000
--- a/changelogs/unreleased/remove-background-migration-worker-feature-flag.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Remove health check feature flag in BackgroundMigrationWorker
-merge_request:
-author:
-type: changed
diff --git a/changelogs/unreleased/remove-zebra-table-background.yml b/changelogs/unreleased/remove-zebra-table-background.yml
deleted file mode 100644
index dafba72035d..00000000000
--- a/changelogs/unreleased/remove-zebra-table-background.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Remove striped table styling of Find files and Admin Area Applications views
-merge_request: 21560
-author: Andreas Kämmerle
-type: other
diff --git a/changelogs/unreleased/repopulate_site_statistics.yml b/changelogs/unreleased/repopulate_site_statistics.yml
deleted file mode 100644
index 1961088061d..00000000000
--- a/changelogs/unreleased/repopulate_site_statistics.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Migrate NULL wiki_access_level to correct number so we count active wikis correctly
-merge_request: 21030
-author:
-type: changed
diff --git a/changelogs/unreleased/runners-online.yml b/changelogs/unreleased/runners-online.yml
deleted file mode 100644
index a732d9cb723..00000000000
--- a/changelogs/unreleased/runners-online.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Clarify current runners online text
-merge_request: 21151
-author: Ben Bodenmiller
-type: other
diff --git a/changelogs/unreleased/schema-changed-ee-backport.yml b/changelogs/unreleased/schema-changed-ee-backport.yml
deleted file mode 100644
index f3b16fc0c27..00000000000
--- a/changelogs/unreleased/schema-changed-ee-backport.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Backport schema_changed.sh from EE which prints the diff if the schema is different
-merge_request: 21422
-author: Jasper Maes
-type: other
diff --git a/changelogs/unreleased/security-49085-persistent-xss-rendering.yml b/changelogs/unreleased/security-49085-persistent-xss-rendering.yml
deleted file mode 100644
index dc15d356c1c..00000000000
--- a/changelogs/unreleased/security-49085-persistent-xss-rendering.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fixed persistent XSS rendering/escaping of diff location lines
-merge_request:
-author:
-type: security
diff --git a/changelogs/unreleased/sh-add-ua-to-lograge-logs.yml b/changelogs/unreleased/sh-add-ua-to-lograge-logs.yml
deleted file mode 100644
index eec55bd3a24..00000000000
--- a/changelogs/unreleased/sh-add-ua-to-lograge-logs.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Add User-Agent to production_json.log
-merge_request: 21546
-author:
-type: other
diff --git a/changelogs/unreleased/sh-block-link-local-master.yml b/changelogs/unreleased/sh-block-link-local-master.yml
deleted file mode 100644
index 0a6017479af..00000000000
--- a/changelogs/unreleased/sh-block-link-local-master.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Block link-local addresses in URLBlocker
-merge_request:
-author:
-type: security
diff --git a/changelogs/unreleased/sh-bump-fog-google.yml b/changelogs/unreleased/sh-bump-fog-google.yml
deleted file mode 100644
index b5fa55e53a5..00000000000
--- a/changelogs/unreleased/sh-bump-fog-google.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Bump fog-google to 1.7.0 and google-api-client to 0.23.0
-merge_request: 21295
-author:
-type: fixed
diff --git a/changelogs/unreleased/sh-bump-gitlab-pages-v1-1-0.yml b/changelogs/unreleased/sh-bump-gitlab-pages-v1-1-0.yml
deleted file mode 100644
index bc5b6b36ac5..00000000000
--- a/changelogs/unreleased/sh-bump-gitlab-pages-v1-1-0.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Bump GitLab Pages to v1.1.0
-merge_request: 21419
-author:
-type: fixed
diff --git a/changelogs/unreleased/sh-bump-unauth-expiration.yml b/changelogs/unreleased/sh-bump-unauth-expiration.yml
deleted file mode 100644
index 107069f3b30..00000000000
--- a/changelogs/unreleased/sh-bump-unauth-expiration.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Bump unauthenticated session time from 1 hour to 2 hours
-merge_request: 21453
-author:
-type: other
diff --git a/changelogs/unreleased/sh-delete-container-registry-async.yml b/changelogs/unreleased/sh-delete-container-registry-async.yml
deleted file mode 100644
index dfe0e812112..00000000000
--- a/changelogs/unreleased/sh-delete-container-registry-async.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Delete a container registry asynchronously
-merge_request: 21553
-author:
-type: fixed
diff --git a/changelogs/unreleased/sh-delete-tags-outside-transaction.yml b/changelogs/unreleased/sh-delete-tags-outside-transaction.yml
new file mode 100644
index 00000000000..974da70251e
--- /dev/null
+++ b/changelogs/unreleased/sh-delete-tags-outside-transaction.yml
@@ -0,0 +1,5 @@
+---
+title: Delete container repository tags outside of transaction
+merge_request: 21679
+author:
+type: fixed
diff --git a/changelogs/unreleased/sh-disable-sidekiq-session.yml b/changelogs/unreleased/sh-disable-sidekiq-session.yml
deleted file mode 100644
index d018bbed841..00000000000
--- a/changelogs/unreleased/sh-disable-sidekiq-session.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Disable the Sidekiq Admin Rack session
-merge_request: 21441
-author:
-type: security
diff --git a/changelogs/unreleased/sh-disable-unnecessary-avatar-revalidation.yml b/changelogs/unreleased/sh-disable-unnecessary-avatar-revalidation.yml
deleted file mode 100644
index 386410484fe..00000000000
--- a/changelogs/unreleased/sh-disable-unnecessary-avatar-revalidation.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Disable project avatar validation if avatar has not changed
-merge_request:
-author:
-type: performance
diff --git a/changelogs/unreleased/sh-fix-attachments-inline.yml b/changelogs/unreleased/sh-fix-attachments-inline.yml
deleted file mode 100644
index 2926edca97a..00000000000
--- a/changelogs/unreleased/sh-fix-attachments-inline.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix attachments not displaying inline with Google Cloud Storage
-merge_request: 21265
-author:
-type: fixed
diff --git a/changelogs/unreleased/sh-fix-bitbucket-cloud-importer-replies.yml b/changelogs/unreleased/sh-fix-bitbucket-cloud-importer-replies.yml
deleted file mode 100644
index 3f7044833f1..00000000000
--- a/changelogs/unreleased/sh-fix-bitbucket-cloud-importer-replies.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix Bitbucket Cloud importer omitting replies
-merge_request: 21076
-author:
-type: fixed
diff --git a/changelogs/unreleased/sh-fix-confidential-note-option.yml b/changelogs/unreleased/sh-fix-confidential-note-option.yml
deleted file mode 100644
index 14d70281760..00000000000
--- a/changelogs/unreleased/sh-fix-confidential-note-option.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix "Confidential comments" button not saving in project hooks
-merge_request: 21289
-author:
-type: fixed
diff --git a/changelogs/unreleased/sh-fix-dedupe-group-importer.yml b/changelogs/unreleased/sh-fix-dedupe-group-importer.yml
deleted file mode 100644
index 1b874c64718..00000000000
--- a/changelogs/unreleased/sh-fix-dedupe-group-importer.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix importers not assigning a new default group
-merge_request: 21456
-author:
-type: fixed
diff --git a/changelogs/unreleased/sh-fix-error-500-updating-wikis.yml b/changelogs/unreleased/sh-fix-error-500-updating-wikis.yml
deleted file mode 100644
index d80d4952ba5..00000000000
--- a/changelogs/unreleased/sh-fix-error-500-updating-wikis.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix Error 500s due to encoding issues when Wiki hooks fire
-merge_request: 21414
-author:
-type: fixed
diff --git a/changelogs/unreleased/sh-fix-issue-50562.yml b/changelogs/unreleased/sh-fix-issue-50562.yml
deleted file mode 100644
index a207dd28622..00000000000
--- a/changelogs/unreleased/sh-fix-issue-50562.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix remote mirrors failing if Git remotes have not been added
-merge_request: 21351
-author:
-type: fixed
diff --git a/changelogs/unreleased/sh-improve-bitbucket-server-logging.yml b/changelogs/unreleased/sh-improve-bitbucket-server-logging.yml
deleted file mode 100644
index c94ff959f1c..00000000000
--- a/changelogs/unreleased/sh-improve-bitbucket-server-logging.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Add JSON logging for Bitbucket Server importer
-merge_request: 21378
-author:
-type: other
diff --git a/changelogs/unreleased/sh-insert-git-data-in-separate-transaction.yml b/changelogs/unreleased/sh-insert-git-data-in-separate-transaction.yml
deleted file mode 100644
index 116929b2f53..00000000000
--- a/changelogs/unreleased/sh-insert-git-data-in-separate-transaction.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: 'Bitbucket Server importer: Eliminate most idle-in-transaction issues'
-merge_request:
-author:
-type: performance
diff --git a/changelogs/unreleased/sh-limit-commit-renderering.yml b/changelogs/unreleased/sh-limit-commit-renderering.yml
deleted file mode 100644
index c44c67bcc90..00000000000
--- a/changelogs/unreleased/sh-limit-commit-renderering.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Speed up diff comparisons by limiting number of commit messages rendered
-merge_request: 21335
-author:
-type: performance
diff --git a/changelogs/unreleased/sh-remove-orphaned-label-links.yml b/changelogs/unreleased/sh-remove-orphaned-label-links.yml
deleted file mode 100644
index b035b57ff1b..00000000000
--- a/changelogs/unreleased/sh-remove-orphaned-label-links.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Remove orphaned label links
-merge_request: 21552
-author:
-type: fixed
diff --git a/changelogs/unreleased/sh-sanitize-project-import-names.yml b/changelogs/unreleased/sh-sanitize-project-import-names.yml
deleted file mode 100644
index 6e0284bda08..00000000000
--- a/changelogs/unreleased/sh-sanitize-project-import-names.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Use slugs for default project path and sanitize names before import
-merge_request: 21367
-author:
-type: fixed
diff --git a/changelogs/unreleased/sh-send-put-headers-object-storage.yml b/changelogs/unreleased/sh-send-put-headers-object-storage.yml
deleted file mode 100644
index cbd8b6deb5b..00000000000
--- a/changelogs/unreleased/sh-send-put-headers-object-storage.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Send back required object storage PUT headers in /uploads/authorize API
-merge_request: 21319
-author:
-type: changed
diff --git a/changelogs/unreleased/sh-set-secure-cookies.yml b/changelogs/unreleased/sh-set-secure-cookies.yml
deleted file mode 100644
index da741288b42..00000000000
--- a/changelogs/unreleased/sh-set-secure-cookies.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Set issuable_sort, diff_view, and perf_bar_enabled cookies to secure when possible
-merge_request: 21442
-author:
-type: security
diff --git a/changelogs/unreleased/skip-irrelevant-sql-commands-in-metrics.yml b/changelogs/unreleased/skip-irrelevant-sql-commands-in-metrics.yml
deleted file mode 100644
index 56d236d0029..00000000000
--- a/changelogs/unreleased/skip-irrelevant-sql-commands-in-metrics.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Ignore irrelevant sql commands in metrics
-merge_request: 21498
-author:
-type: other
diff --git a/changelogs/unreleased/tc-api-fork-owners.yml b/changelogs/unreleased/tc-api-fork-owners.yml
deleted file mode 100644
index feaa3c1705e..00000000000
--- a/changelogs/unreleased/tc-api-fork-owners.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Allow project owners to set up forking relation through API
-merge_request: 18104
-author:
-type: changed
diff --git a/changelogs/unreleased/tz-mr-incremental-rendering.yml b/changelogs/unreleased/tz-mr-incremental-rendering.yml
deleted file mode 100644
index a35fa200363..00000000000
--- a/changelogs/unreleased/tz-mr-incremental-rendering.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-title: Incremental rendering with Vue on merge request page
-merge_request: 21063
-author:
-type: performance
diff --git a/changelogs/unreleased/update-gitlab-shell-8-3-3.yml b/changelogs/unreleased/update-gitlab-shell-8-3-3.yml
deleted file mode 100644
index 3f9cca59528..00000000000
--- a/changelogs/unreleased/update-gitlab-shell-8-3-3.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Update GitLab Shell to v8.3.3
-merge_request: 21750
-author:
-type: fixed
diff --git a/changelogs/unreleased/update-gitlab-shell.yml b/changelogs/unreleased/update-gitlab-shell.yml
deleted file mode 100644
index f5d0e30a7be..00000000000
--- a/changelogs/unreleased/update-gitlab-shell.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Update GitLab Shell to v8.3.2
-merge_request: 21701
-author:
-type: fixed
diff --git a/changelogs/unreleased/update-padding-markdown.yml b/changelogs/unreleased/update-padding-markdown.yml
deleted file mode 100644
index 51037200bd1..00000000000
--- a/changelogs/unreleased/update-padding-markdown.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Increase padding in code blocks
-merge_request:
-author:
-type: fixed
diff --git a/changelogs/unreleased/usage_consent.yml b/changelogs/unreleased/usage_consent.yml
deleted file mode 100644
index 56e00879b9a..00000000000
--- a/changelogs/unreleased/usage_consent.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Ask user explicitly about usage stats agreement on single user deployments.
-merge_request: 21423
-author:
-type: added
diff --git a/changelogs/unreleased/vendor-gitlab-ci-auto-devops-yml.yml b/changelogs/unreleased/vendor-gitlab-ci-auto-devops-yml.yml
new file mode 100644
index 00000000000..98d0e24c00a
--- /dev/null
+++ b/changelogs/unreleased/vendor-gitlab-ci-auto-devops-yml.yml
@@ -0,0 +1,5 @@
+---
+title: Make AutoDevOps work behind proxy
+merge_request: 21775
+author: Sergej - @kinolaev
+type: other
diff --git a/changelogs/unreleased/visual-improvements-language-bar.yml b/changelogs/unreleased/visual-improvements-language-bar.yml
deleted file mode 100644
index 23cae22b962..00000000000
--- a/changelogs/unreleased/visual-improvements-language-bar.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Improve visuals of language bar on projects
-merge_request: 21006
-author:
-type: changed
diff --git a/changelogs/unreleased/winh-default-status-emoji.yml b/changelogs/unreleased/winh-default-status-emoji.yml
deleted file mode 100644
index 00cca4db0a6..00000000000
--- a/changelogs/unreleased/winh-default-status-emoji.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Display default status emoji if only message is entered
-merge_request: 21330
-author:
-type: changed
diff --git a/changelogs/unreleased/winh-move-badge-settings.yml b/changelogs/unreleased/winh-move-badge-settings.yml
deleted file mode 100644
index 9638ba04c1e..00000000000
--- a/changelogs/unreleased/winh-move-badge-settings.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Move badge settings to general settings
-merge_request: 21333
-author:
-type: changed
diff --git a/changelogs/unreleased/zj-cleanup-port-gitaly.yml b/changelogs/unreleased/zj-cleanup-port-gitaly.yml
deleted file mode 100644
index 25e13b0fd50..00000000000
--- a/changelogs/unreleased/zj-cleanup-port-gitaly.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Administrative cleanup rake tasks now leverage Gitaly
-merge_request: 21588
-author:
-type: changed
diff --git a/config/application.rb b/config/application.rb
index f3c53fa63f3..9074cf02c46 100644
--- a/config/application.rb
+++ b/config/application.rb
@@ -134,6 +134,7 @@ module Gitlab
config.assets.precompile << "notify.css"
config.assets.precompile << "mailers/*.css"
config.assets.precompile << "page_bundles/ide.css"
+ config.assets.precompile << "page_bundles/xterm.css"
config.assets.precompile << "performance_bar.css"
config.assets.precompile << "lib/ace.js"
config.assets.precompile << "test.css"
@@ -204,7 +205,7 @@ module Gitlab
ENV['GITLAB_PATH_OUTSIDE_HOOK'] = ENV['PATH']
ENV['GIT_TERMINAL_PROMPT'] = '0'
- # Gitlab Read-only middleware support
+ # GitLab Read-only middleware support
config.middleware.insert_after ActionDispatch::Flash, ::Gitlab::Middleware::ReadOnly
config.generators do |g|
diff --git a/config/initializers/0_post_deployment_migrations.rb b/config/initializers/0_post_deployment_migrations.rb
index 3d81b869b52..2d647f72840 100644
--- a/config/initializers/0_post_deployment_migrations.rb
+++ b/config/initializers/0_post_deployment_migrations.rb
@@ -1,14 +1,4 @@
# Post deployment migrations are included by default. This file must be loaded
# before other initializers as Rails may otherwise memoize a list of migrations
# excluding the post deployment migrations.
-unless ENV['SKIP_POST_DEPLOYMENT_MIGRATIONS']
- Rails.application.config.paths['db'].each do |db_path|
- path = Rails.root.join(db_path, 'post_migrate').to_s
-
- Rails.application.config.paths['db/migrate'] << path
-
- # Rails memoizes migrations at certain points where it won't read the above
- # path just yet. As such we must also update the following list of paths.
- ActiveRecord::Migrator.migrations_paths << path
- end
-end
+Gitlab::Database.add_post_migrate_path_to_rails
diff --git a/config/routes/admin.rb b/config/routes/admin.rb
index fa1f79a90be..7489b01ded6 100644
--- a/config/routes/admin.rb
+++ b/config/routes/admin.rb
@@ -110,6 +110,7 @@ namespace :admin do
put :reset_runners_token
put :reset_health_check_token
put :clear_repository_check_states
+ get :integrations, :repository, :templates, :ci_cd, :reporting, :metrics_and_profiling, :network, :geo, :preferences
end
resources :labels
diff --git a/config/routes/instance_statistics.rb b/config/routes/instance_statistics.rb
index 824ef47cda3..1102ef6b017 100644
--- a/config/routes/instance_statistics.rb
+++ b/config/routes/instance_statistics.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
namespace :instance_statistics do
- root to: redirect('/-/instance_statistics/conversational_development_index')
+ root to: redirect('-/instance_statistics/conversational_development_index')
resources :cohorts, only: :index
resources :conversational_development_index, only: :index
diff --git a/config/routes/wiki.rb b/config/routes/wiki.rb
index cd3828b743c..1a07b1c206b 100644
--- a/config/routes/wiki.rb
+++ b/config/routes/wiki.rb
@@ -2,7 +2,7 @@ scope(controller: :wikis) do
scope(path: 'wikis', as: :wikis) do
get :git_access
get :pages
- get '/', to: redirect('/%{namespace_id}/%{project_id}/wikis/home')
+ get '/', to: redirect('%{namespace_id}/%{project_id}/wikis/home')
post '/', to: 'wikis#create'
end
diff --git a/danger/commit_messages/Dangerfile b/danger/commit_messages/Dangerfile
index e982e8ed7c5..c5ebb9b457e 100644
--- a/danger/commit_messages/Dangerfile
+++ b/danger/commit_messages/Dangerfile
@@ -1,5 +1,7 @@
# frozen_string_literal: true
+require 'json'
+
# rubocop: disable Style/SignalException
# rubocop: disable Metrics/CyclomaticComplexity
# rubocop: disable Metrics/PerceivedComplexity
@@ -8,10 +10,38 @@
# https://github.com/jonallured/danger-commit_lint because its output is not
# very helpful, and it doesn't offer the means of ignoring merge commits.
+class EmojiChecker
+ DIGESTS = File.expand_path('../../fixtures/emojis/digests.json', __dir__)
+ ALIASES = File.expand_path('../../fixtures/emojis/aliases.json', __dir__)
+
+ # A regex that indicates a piece of text _might_ include an Emoji. The regex
+ # alone is not enough, as we'd match `:foo:bar:baz`. Instead, we use this
+ # regex to save us from having to check for all possible emoji names when we
+ # know one definitely is not included.
+ LIKELY_EMOJI = /:[\+a-z0-9_\-]+:/
+
+ def initialize
+ names = JSON.parse(File.read(DIGESTS)).keys +
+ JSON.parse(File.read(ALIASES)).keys
+
+ @emoji = names.map { |name| ":#{name}:" }
+ end
+
+ def includes_emoji?(text)
+ return false unless text.match?(LIKELY_EMOJI)
+
+ @emoji.any? { |emoji| text.include?(emoji) }
+ end
+end
+
def fail_commit(commit, message)
fail("#{commit.sha}: #{message}")
end
+def warn_commit(commit, message)
+ warn("#{commit.sha}: #{message}")
+end
+
def lines_changed_in_commit(commit)
commit.diff_parent.stats[:total][:lines]
end
@@ -33,6 +63,7 @@ end
def lint_commits(commits)
failures = false
+ emoji_checker = EmojiChecker.new
unicode_emoji_regex = %r((
[\u{1F300}-\u{1F5FF}] |
@@ -60,13 +91,21 @@ def lint_commits(commits)
failures = true
end
- if subject.length > 50
+ if subject.length > 72
fail_commit(
commit,
- 'The commit subject may not be longer than 50 characters'
+ 'The commit subject may not be longer than 72 characters'
)
failures = true
+ elsif subject.length > 50
+ warn_commit(
+ commit,
+ "This commit's subject line could be improved. " \
+ 'Commit subjects are ideally no longer than roughly 50 characters, ' \
+ 'though we allow up to 72 characters in the subject. ' \
+ 'If possible, try to reduce the length of the subject to roughly 50 characters.'
+ )
end
unless subject_starts_with_capital?(subject)
@@ -117,7 +156,7 @@ def lint_commits(commits)
failures = true
end
- if commit.message.match?(/:[\+a-z0-9_\-]+:/)
+ if emoji_checker.includes_emoji?(commit.message)
fail_commit(
commit,
'Avoid the use of Markdown Emoji such as `:+1:`. ' \
diff --git a/db/migrate/20180813101999_change_default_of_auto_devops_instance_wide.rb b/db/migrate/20180813101999_change_default_of_auto_devops_instance_wide.rb
new file mode 100644
index 00000000000..05d1124f5c4
--- /dev/null
+++ b/db/migrate/20180813101999_change_default_of_auto_devops_instance_wide.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class ChangeDefaultOfAutoDevopsInstanceWide < ActiveRecord::Migration
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ def up
+ change_column_default :application_settings, :auto_devops_enabled, true
+ end
+
+ def down
+ change_column_default :application_settings, :auto_devops_enabled, false
+ end
+end
diff --git a/db/migrate/20180813102000_enable_auto_devops_instance_wide_for_everyone.rb b/db/migrate/20180813102000_enable_auto_devops_instance_wide_for_everyone.rb
new file mode 100644
index 00000000000..21fb62806b3
--- /dev/null
+++ b/db/migrate/20180813102000_enable_auto_devops_instance_wide_for_everyone.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class EnableAutoDevopsInstanceWideForEveryone < ActiveRecord::Migration
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ def up
+ execute "UPDATE application_settings SET auto_devops_enabled = true"
+ end
+
+ def down
+ # No way to know here what their previous setting was...
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 95df735cd37..b299cde4898 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -141,7 +141,7 @@ ActiveRecord::Schema.define(version: 20180907015926) do
t.integer "performance_bar_allowed_group_id"
t.boolean "hashed_storage_enabled", default: false, null: false
t.boolean "project_export_enabled", default: true, null: false
- t.boolean "auto_devops_enabled", default: false, null: false
+ t.boolean "auto_devops_enabled", default: true, null: false
t.integer "circuitbreaker_failure_count_threshold", default: 3
t.integer "circuitbreaker_failure_reset_time", default: 1800
t.integer "circuitbreaker_storage_timeout", default: 15
diff --git a/doc/README.md b/doc/README.md
index 4248f62c08c..7548240bfef 100644
--- a/doc/README.md
+++ b/doc/README.md
@@ -191,7 +191,7 @@ instant how code changes impact your production environment.
### User account
- [User account](user/profile/index.md): Manage your account
- - [Authentication](topics/authentication/index.md): Account security with two-factor authentication, setup your ssh keys and deploy keys for secure access to your projects.
+ - [Authentication](topics/authentication/index.md): Account security with two-factor authentication, set up your ssh keys and deploy keys for secure access to your projects.
- [Profile settings](user/profile/index.md#profile-settings): Manage your profile settings, two factor authentication and more.
- [User permissions](user/permissions.md): Learn what each role in a project (external/guest/reporter/developer/maintainer/owner) can do.
diff --git a/doc/administration/auth/ldap.md b/doc/administration/auth/ldap.md
index 5c7392b99d0..67635d2e6ab 100644
--- a/doc/administration/auth/ldap.md
+++ b/doc/administration/auth/ldap.md
@@ -132,7 +132,7 @@ main:
## Enables SSL certificate verification if encryption method is
## "start_tls" or "simple_tls". Defaults to true since GitLab 10.0 for
## security. This may break installations upon upgrade to 10.0, that did
- ## not know their LDAP SSL certificates were not setup properly.
+ ## not know their LDAP SSL certificates were not set up properly.
##
verify_certificates: true
diff --git a/doc/administration/external_database.md b/doc/administration/external_database.md
index 31199f2cdc7..ec2d30c82d1 100644
--- a/doc/administration/external_database.md
+++ b/doc/administration/external_database.md
@@ -9,7 +9,7 @@ separate from the GitLab Omnibus package.
If you use a cloud-managed service, or provide your own PostgreSQL instance:
-1. Setup PostgreSQL according to the
+1. Set up PostgreSQL according to the
[database requirements document](../install/requirements.md#database).
1. Set up a `gitlab` username with a password of your choice. The `gitlab` user
needs privileges to create the `gitlabhq_production` database.
diff --git a/doc/administration/gitaly/index.md b/doc/administration/gitaly/index.md
index 964758837e5..49c6902bc42 100644
--- a/doc/administration/gitaly/index.md
+++ b/doc/administration/gitaly/index.md
@@ -101,6 +101,12 @@ documentation on configuring Gitaly
authentication](https://gitlab.com/gitlab-org/gitaly/blob/master/doc/configuration/README.md#authentication)
.
+Gitaly must trigger some callbacks to GitLab via GitLab Shell. As a result,
+the GitLab Shell secret must be the same between the other GitLab servers and
+the Gitaly server. The easiest way to accomplish this is to copy `/etc/gitlab/gitlab-secrets.json`
+from an existing GitLab server to the Gitaly server. Without this shared secret,
+Git operations in GitLab will result in an API error.
+
> **NOTE:** In most or all cases the storage paths below end in `/repositories` which is
different than `path` in `git_data_dirs` of Omnibus installations. Check the
directory layout on your Gitaly server to be sure.
diff --git a/doc/administration/high_availability/database.md b/doc/administration/high_availability/database.md
index b5124b1d540..c1eeb40b98f 100644
--- a/doc/administration/high_availability/database.md
+++ b/doc/administration/high_availability/database.md
@@ -13,7 +13,7 @@ Database Service (RDS) that runs PostgreSQL.
If you use a cloud-managed service, or provide your own PostgreSQL:
-1. Setup PostgreSQL according to the
+1. Set up PostgreSQL according to the
[database requirements document](../../install/requirements.md#database).
1. Set up a `gitlab` username with a password of your choice. The `gitlab` user
needs privileges to create the `gitlabhq_production` database.
diff --git a/doc/administration/high_availability/redis.md b/doc/administration/high_availability/redis.md
index e05bebbef18..b5d1ff698c6 100644
--- a/doc/administration/high_availability/redis.md
+++ b/doc/administration/high_availability/redis.md
@@ -81,7 +81,7 @@ When a **Master** fails to respond, it's the application's responsibility
(in our case GitLab) to handle timeout and reconnect (querying a **Sentinel**
for a new **Master**).
-To get a better understanding on how to correctly setup Sentinel, please read
+To get a better understanding on how to correctly set up Sentinel, please read
the [Redis Sentinel documentation](http://redis.io/topics/sentinel) first, as
failing to configure it correctly can lead to data loss or can bring your
whole cluster down, invalidating the failover effort.
@@ -217,7 +217,7 @@ Pick the one that suits your needs.
and configure Sentinel, jump directly to the Sentinel section in the
[Redis HA installation from source](redis_source.md#step-3-configuring-the-redis-sentinel-instances) documentation.
- [Omnibus GitLab **Enterprise Edition** (EE) package][ee]: Both Redis and Sentinel
- are bundled in the package, so you can use the EE package to setup the whole
+ are bundled in the package, so you can use the EE package to set up the whole
Redis HA infrastructure (master, slave and Sentinel) which is described in
this document.
- If you have installed GitLab using the Omnibus GitLab packages (CE or EE),
@@ -228,7 +228,7 @@ Pick the one that suits your needs.
## Configuring Redis HA
-This is the section where we install and setup the new Redis instances.
+This is the section where we install and set up the new Redis instances.
> **Notes:**
> - We assume that you have installed GitLab and all HA components from scratch. If you
@@ -370,7 +370,7 @@ You must have at least `3` Redis Sentinel servers, and they need to
be each in an independent machine. You can configure them in the same
machines where you've configured the other Redis servers.
-With GitLab Enterprise Edition, you can use the Omnibus package to setup
+With GitLab Enterprise Edition, you can use the Omnibus package to set up
multiple machines with the Sentinel daemon.
---
@@ -535,7 +535,7 @@ In this example we consider that all servers have an internal network
interface with IPs in the `10.0.0.x` range, and that they can connect
to each other using these IPs.
-In a real world usage, you would also setup firewall rules to prevent
+In a real world usage, you would also set up firewall rules to prevent
unauthorized access from other machines and block traffic from the
outside (Internet).
diff --git a/doc/administration/high_availability/redis_source.md b/doc/administration/high_availability/redis_source.md
index 8b7a515a076..5823c575251 100644
--- a/doc/administration/high_availability/redis_source.md
+++ b/doc/administration/high_availability/redis_source.md
@@ -24,7 +24,7 @@ the Omnibus Redis HA documentation.
## Configuring your own Redis server
-This is the section where we install and setup the new Redis instances.
+This is the section where we install and set up the new Redis instances.
### Prerequisites
@@ -204,7 +204,7 @@ In this example we consider that all servers have an internal network
interface with IPs in the `10.0.0.x` range, and that they can connect
to each other using these IPs.
-In a real world usage, you would also setup firewall rules to prevent
+In a real world usage, you would also set up firewall rules to prevent
unauthorized access from other machines, and block traffic from the
outside ([Internet][it]).
diff --git a/doc/administration/job_artifacts.md b/doc/administration/job_artifacts.md
index 1f3bc611cdf..757865ea2c5 100644
--- a/doc/administration/job_artifacts.md
+++ b/doc/administration/job_artifacts.md
@@ -127,6 +127,7 @@ The connection settings match those provided by [Fog](https://github.com/fog), a
| `host` | S3 compatible host for when not using AWS, e.g. `localhost` or `storage.example.com` | s3.amazonaws.com |
| `endpoint` | Can be used when configuring an S3 compatible service such as [Minio](https://www.minio.io), by entering a URL such as `http://127.0.0.1:9000` | (optional) |
| `path_style` | Set to true to use `host/bucket_name/object` style paths instead of `bucket_name.host/object`. Leave as false for AWS S3 | false |
+| `use_iam_profile` | Set to true to use IAM profile instead of access keys | false
**In Omnibus installations:**
diff --git a/doc/administration/operations/ssh_certificates.md b/doc/administration/operations/ssh_certificates.md
index 9edccd25ced..b00301fec1c 100644
--- a/doc/administration/operations/ssh_certificates.md
+++ b/doc/administration/operations/ssh_certificates.md
@@ -31,7 +31,7 @@ uploading user SSH keys to GitLab entirely.
## Setting up SSH certificate lookup via GitLab Shell
-How to fully setup SSH certificates is outside the scope of this
+How to fully set up SSH certificates is outside the scope of this
document. See [OpenSSH's
PROTOCOL.certkeys](https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/PROTOCOL.certkeys?annotate=HEAD)
for how it works, and e.g. [RedHat's documentation about
@@ -132,7 +132,7 @@ message about this being an invalid user.
## Interaction with the `authorized_keys` file
SSH certificates can be used in conjunction with the `authorized_keys`
-file, and if setup as configured above the `authorized_keys` file will
+file, and if set up as configured above the `authorized_keys` file will
still serve as a fallback.
This is because if the `AuthorizedPrincipalsCommand` can't
diff --git a/doc/administration/raketasks/maintenance.md b/doc/administration/raketasks/maintenance.md
index 2b4252a7b1d..d3ce7b6f2df 100644
--- a/doc/administration/raketasks/maintenance.md
+++ b/doc/administration/raketasks/maintenance.md
@@ -56,7 +56,7 @@ Runs the following rake tasks:
- `gitlab:sidekiq:check`
- `gitlab:app:check`
-It will check that each component was setup according to the installation guide and suggest fixes for issues found.
+It will check that each component was set up according to the installation guide and suggest fixes for issues found.
You may also have a look at our Trouble Shooting Guides:
- [Trouble Shooting Guide (GitLab)](http://docs.gitlab.com/ee/README.html#troubleshooting)
diff --git a/doc/administration/raketasks/uploads/migrate.md b/doc/administration/raketasks/uploads/migrate.md
index 0cd33ffc122..b5c40478ea5 100644
--- a/doc/administration/raketasks/uploads/migrate.md
+++ b/doc/administration/raketasks/uploads/migrate.md
@@ -7,10 +7,32 @@ After [configuring the object storage](../../uploads.md#using-object-storage) fo
>**Note:**
All of the processing will be done in a background worker and requires **no downtime**.
-This tasks uses 3 parameters to find uploads to migrate.
+### All-in-one rake task
+
+GitLab provides a wrapper rake task that migrates all uploaded files - avatars,
+logos, attachments, favicon, etc. - to object storage in one go. Under the hood,
+it invokes individual rake tasks to migrate files falling under each of this
+category one by one. The specifications of these individual rake tasks are
+described in the next section.
+
+**Omnibus Installation**
+
+```bash
+gitlab-rake "gitlab:uploads:migrate:all"
+```
+
+**Source Installation**
+
+```bash
+sudo RAILS_ENV=production -u git -H bundle exec rake gitlab:uploads:migrate:all
+```
+
+### Individual rake tasks
>**Note:**
-These parameters are mainly internal to GitLab's structure, you may want to refer to the task list instead below.
+If you already ran the rake task mentioned above, no need to run these individual rake tasks as that has been done automatically.
+
+The rake task uses 3 parameters to find uploads to migrate.
Parameter | Type | Description
--------- | ---- | -----------
@@ -18,6 +40,9 @@ Parameter | Type | Description
`model_class` | string | Type of the model to migrate from
`mount_point` | string/symbol | Name of the model's column on which the uploader is mounted on.
+>**Note:**
+These parameters are mainly internal to GitLab's structure, you may want to refer to the task list instead below.
+
This task also accepts some environment variables which you can use to override
certain values:
@@ -25,7 +50,7 @@ Variable | Type | Description
-------- | ---- | -----------
`BATCH` | integer | Specifies the size of the batch. Defaults to 200.
-** Omnibus Installation**
+**Omnibus Installation**
```bash
# gitlab-rake gitlab:uploads:migrate[uploader_class, model_class, mount_point]
@@ -40,6 +65,9 @@ gitlab-rake "gitlab:uploads:migrate[AttachmentUploader, Note, :attachment]"
gitlab-rake "gitlab:uploads:migrate[AttachmentUploader, Appearance, :logo]"
gitlab-rake "gitlab:uploads:migrate[AttachmentUploader, Appearance, :header_logo]"
+# Favicon
+gitlab-rake "gitlab:uploads:migrate[FaviconUploader, Appearance, :favicon]"
+
# Markdown
gitlab-rake "gitlab:uploads:migrate[FileUploader, Project]"
gitlab-rake "gitlab:uploads:migrate[PersonalFileUploader, Snippet]"
@@ -65,6 +93,9 @@ sudo -u git -H bundle exec rake "gitlab:uploads:migrate[AttachmentUploader, Note
sudo -u git -H bundle exec rake "gitlab:uploads:migrate[AttachmentUploader, Appearance, :logo]"
sudo -u git -H bundle exec rake "gitlab:uploads:migrate[AttachmentUploader, Appearance, :header_logo]"
+# Favicon
+sudo -u git -H bundle exec rake "gitlab:uploads:migrate[FaviconUploader, Appearance, :favicon]"
+
# Markdown
sudo -u git -H bundle exec rake "gitlab:uploads:migrate[FileUploader, Project]"
sudo -u git -H bundle exec rake "gitlab:uploads:migrate[PersonalFileUploader, Snippet]"
diff --git a/doc/administration/reply_by_email.md b/doc/administration/reply_by_email.md
index 426245c7aca..6d7069dd461 100644
--- a/doc/administration/reply_by_email.md
+++ b/doc/administration/reply_by_email.md
@@ -5,7 +5,7 @@ replying to notification emails.
## Requirement
-Make sure [incoming email](incoming_email.md) is setup.
+Make sure [incoming email](incoming_email.md) is set up.
## How it works?
diff --git a/doc/administration/reply_by_email_postfix_setup.md b/doc/administration/reply_by_email_postfix_setup.md
index 3e8b78e56d5..d1a03219542 100644
--- a/doc/administration/reply_by_email_postfix_setup.md
+++ b/doc/administration/reply_by_email_postfix_setup.md
@@ -245,7 +245,7 @@ Courier, which we will install later to add IMAP authentication, requires mailbo
220 gitlab.example.com ESMTP Postfix (Ubuntu)
```
- If you get a `Connection refused` error instead, make sure your firewall is setup to allow inbound traffic on port 25.
+ If you get a `Connection refused` error instead, make sure your firewall is set up to allow inbound traffic on port 25.
1. Send the `incoming` user a dummy email to test SMTP, by entering the following into the SMTP prompt:
diff --git a/doc/administration/uploads.md b/doc/administration/uploads.md
index 467deb43644..ce83da16067 100644
--- a/doc/administration/uploads.md
+++ b/doc/administration/uploads.md
@@ -86,6 +86,7 @@ The connection settings match those provided by [Fog](https://github.com/fog), a
| `host` | S3 compatible host for when not using AWS, e.g. `localhost` or `storage.example.com` | s3.amazonaws.com |
| `endpoint` | Can be used when configuring an S3 compatible service such as [Minio](https://www.minio.io), by entering a URL such as `http://127.0.0.1:9000` | (optional) |
| `path_style` | Set to true to use `host/bucket_name/object` style paths instead of `bucket_name.host/object`. Leave as false for AWS S3 | false |
+| `use_iam_profile` | Set to true to use IAM profile instead of access keys | false
**In Omnibus installations:**
diff --git a/doc/api/protected_branches.md b/doc/api/protected_branches.md
index f6813f27dc0..ed8837574a0 100644
--- a/doc/api/protected_branches.md
+++ b/doc/api/protected_branches.md
@@ -4,7 +4,7 @@
**Valid access levels**
-The access levels are defined in the `ProtectedRefAccess::ALLOWED_ACCESS_LEVELS` constant. Currently, these levels are recognized:
+The access levels are defined in the `ProtectedRefAccess.allowed_access_levels` method. Currently, these levels are recognized:
```
0 => No access
30 => Developer access
diff --git a/doc/api/settings.md b/doc/api/settings.md
index 83fa9b055d1..d64d65b22f2 100644
--- a/doc/api/settings.md
+++ b/doc/api/settings.md
@@ -193,7 +193,7 @@ are listed in the descriptions of the relevant settings.
| `metrics_port` | integer | required by: `metrics_enabled` | The UDP port to use for connecting to InfluxDB. |
| `metrics_sample_interval` | integer | required by: `metrics_enabled` | The sampling interval in seconds. |
| `metrics_timeout` | integer | required by: `metrics_enabled` | The amount of seconds after which InfluxDB will time out. |
-| `mirror_available` | boolean | no | Allow mirrors to be setup for projects. If disabled, only admins will be able to setup mirrors in projects. |
+| `mirror_available` | boolean | no | Allow mirrors to be set up for projects. If disabled, only admins will be able to set up mirrors in projects. |
| `pages_domain_verification_enabled` | boolean | no | Require users to prove ownership of custom domains. Domain verification is an essential security measure for public GitLab sites. Users are required to demonstrate they control a domain before it is enabled. |
| `password_authentication_enabled_for_git` | boolean | no | Enable authentication for Git over HTTP(S) via a GitLab account password. Default is `true`. |
| `password_authentication_enabled_for_web` | boolean | no | Enable authentication for the web interface via a GitLab account password. Default is `true`. |
diff --git a/doc/ci/autodeploy/quick_start_guide.md b/doc/ci/autodeploy/quick_start_guide.md
index cc6c9ec0e0a..3836216e951 100644
--- a/doc/ci/autodeploy/quick_start_guide.md
+++ b/doc/ci/autodeploy/quick_start_guide.md
@@ -11,7 +11,7 @@ We made a minimal [Ruby application](https://gitlab.com/gitlab-examples/minimal-
Let’s start by forking our sample application. Go to [the project page](https://gitlab.com/gitlab-examples/minimal-ruby-app) and press the `Fork` button. Soon you should have a project under your namespace with the necessary files.
-## Setup your own cluster on Google Kubernetes Engine
+## Set up your own cluster on Google Kubernetes Engine
If you do not already have a Google Cloud account, create one at https://console.cloud.google.com.
@@ -71,7 +71,7 @@ Use this IP address to configure your DNS. This part heavily depends on your pre
Use `nslookup minimal-ruby-app-staging.<yourdomain>` to confirm that domain is assigned to the cluster IP.
-## Setup Auto Deploy
+## Set up Auto Deploy
Visit the home page of your GitLab.com project and press "Set up Auto Deploy" button.
diff --git a/doc/ci/environments.md b/doc/ci/environments.md
index f1e5b00e927..4d740c32fd6 100644
--- a/doc/ci/environments.md
+++ b/doc/ci/environments.md
@@ -370,7 +370,7 @@ review_app:
url: https://$CI_COMMIT_REF_SLUG.example.com
```
-It is assumed that the user has already setup NGINX and GitLab Runner in the
+It is assumed that the user has already set up NGINX and GitLab Runner in the
server this job will run on.
>**Note:**
diff --git a/doc/ci/examples/devops_and_game_dev_with_gitlab_ci_cd/index.md b/doc/ci/examples/devops_and_game_dev_with_gitlab_ci_cd/index.md
index c226b5bfb71..b75ed87bc91 100644
--- a/doc/ci/examples/devops_and_game_dev_with_gitlab_ci_cd/index.md
+++ b/doc/ci/examples/devops_and_game_dev_with_gitlab_ci_cd/index.md
@@ -520,7 +520,7 @@ a lot of breathing room in quickly getting changes to players.
Here are some ideas to further investigate that can speed up or improve your pipeline:
- [Yarn](https://yarnpkg.com) instead of npm
-- Setup a custom [Docker](../../../ci/docker/using_docker_images.md#define-image-and-services-from-gitlab-ci-yml) image that can preload dependencies and tools (like AWS CLI)
+- Set up a custom [Docker](../../../ci/docker/using_docker_images.md#define-image-and-services-from-gitlab-ci-yml) image that can preload dependencies and tools (like AWS CLI)
- Forward a [custom domain](http://docs.aws.amazon.com/AmazonS3/latest/dev/website-hosting-custom-domain-walkthrough.html) to your game's S3 static website
- Combine jobs if you find it unnecessary for a small project
- Avoid the queues and set up your own [custom GitLab CI/CD runner](https://about.gitlab.com/2016/03/01/gitlab-runner-with-docker/)
diff --git a/doc/ci/examples/laravel_with_gitlab_and_envoy/index.md b/doc/ci/examples/laravel_with_gitlab_and_envoy/index.md
index 39c65399332..ab429e0ded3 100644
--- a/doc/ci/examples/laravel_with_gitlab_and_envoy/index.md
+++ b/doc/ci/examples/laravel_with_gitlab_and_envoy/index.md
@@ -13,7 +13,7 @@ date: 2017-08-31
GitLab features our applications with Continuous Integration, and it is possible to easily deploy the new code changes to the production server whenever we want.
-In this tutorial, we'll show you how to initialize a [Laravel](http://laravel.com/) application and setup our [Envoy](https://laravel.com/docs/envoy) tasks, then we'll jump into see how to test and deploy it with [GitLab CI/CD](../README.md) via [Continuous Delivery](https://about.gitlab.com/2016/08/05/continuous-integration-delivery-and-deployment-with-gitlab/).
+In this tutorial, we'll show you how to initialize a [Laravel](http://laravel.com/) application and set up our [Envoy](https://laravel.com/docs/envoy) tasks, then we'll jump into see how to test and deploy it with [GitLab CI/CD](../README.md) via [Continuous Delivery](https://about.gitlab.com/2016/08/05/continuous-integration-delivery-and-deployment-with-gitlab/).
We assume you have a basic experience with Laravel, Linux servers,
and you know how to use GitLab.
@@ -23,7 +23,7 @@ It has a great community with a [fantastic documentation](https://laravel.com/do
Aside from the usual routing, controllers, requests, responses, views, and (blade) templates, out of the box Laravel provides plenty of additional services such as cache, events, localization, authentication and many others.
We will use [Envoy](https://laravel.com/docs/master/envoy) as an SSH task runner based on PHP.
-It uses a clean, minimal [Blade syntax](https://laravel.com/docs/blade) to setup tasks that can run on remote servers, such as, cloning your project from the repository, installing the Composer dependencies, and running [Artisan commands](https://laravel.com/docs/artisan).
+It uses a clean, minimal [Blade syntax](https://laravel.com/docs/blade) to set up tasks that can run on remote servers, such as, cloning your project from the repository, installing the Composer dependencies, and running [Artisan commands](https://laravel.com/docs/artisan).
## Initialize our Laravel app on GitLab
@@ -372,7 +372,7 @@ At the end, our `Envoy.blade.php` file will look like this:
One more thing we should do before any deployment is to manually copy our application `storage` folder to the `/var/www/app` directory on the server for the first time.
You might want to create another Envoy task to do that for you.
-We also create the `.env` file in the same path to setup our production environment variables for Laravel.
+We also create the `.env` file in the same path to set up our production environment variables for Laravel.
These are persistent data and will be shared to every new release.
Now, we would need to deploy our app by running `envoy run deploy`, but it won't be necessary since GitLab can handle that for us with CI's [environments](../../environments.md), which will be described [later](#setting-up-gitlab-ci-cd) in this tutorial.
@@ -587,7 +587,7 @@ unit_test:
script:
# Install app dependencies
- composer install
- # Setup .env
+ # Set up .env
- cp .env.example .env
# Generate an environment key
- php artisan key:generate
diff --git a/doc/ci/examples/php.md b/doc/ci/examples/php.md
index a2ba29a4ee2..df4805ea7ac 100644
--- a/doc/ci/examples/php.md
+++ b/doc/ci/examples/php.md
@@ -199,7 +199,7 @@ pecl install <extension>
```
It's not advised to add this to `.gitlab-ci.yml`. You should execute this
-command once, only to setup the build environment.
+command once, only to set up the build environment.
## Extend your tests
diff --git a/doc/ci/runners/README.md b/doc/ci/runners/README.md
index 7859d2ec631..83e0fa34ad6 100644
--- a/doc/ci/runners/README.md
+++ b/doc/ci/runners/README.md
@@ -29,7 +29,7 @@ are:
- **Specific Runners** are useful for jobs that have special requirements or for
projects with a specific demand. If a job has certain requirements, you can set
up the specific Runner with this in mind, while not having to do this for all
- Runners. For example, if you want to deploy a certain project, you can setup
+ Runners. For example, if you want to deploy a certain project, you can set up
a specific Runner to have the right credentials for this. The [usage of tags](#using-tags)
may be useful in this case. Specific Runners process jobs using a [FIFO] queue.
- **Group Runners** are useful when you have multiple projects under one group
@@ -222,7 +222,7 @@ should keep in mind.
### Using tags
-You must setup a Runner to be able to run all the different types of jobs
+You must set up a Runner to be able to run all the different types of jobs
that it may encounter on the projects it's shared over. This would be
problematic for large amounts of projects, if it wasn't for tags.
@@ -298,7 +298,7 @@ and using more secure [Runner Executors](https://docs.gitlab.com/runner/executor
### Forks
Whenever a project is forked, it copies the settings of the jobs that relate
-to it. This means that if you have shared Runners setup for a project and
+to it. This means that if you have shared Runners set up for a project and
someone forks that project, the shared Runners will also serve jobs of this
project.
diff --git a/doc/ci/yaml/README.md b/doc/ci/yaml/README.md
index 41de9a50efc..31a065bc196 100644
--- a/doc/ci/yaml/README.md
+++ b/doc/ci/yaml/README.md
@@ -1231,13 +1231,16 @@ rspec:
```
The collected JUnit reports will be uploaded to GitLab as an artifact and will
-be automatically [shown in merge requests](../junit_test_reports.md).
+be automatically shown in merge requests.
+
+For more examples, see [JUnit test reports](../junit_test_reports.md).
NOTE: **Note:**
In case the JUnit tool you use exports to multiple XML files, you can specify
-multiple test report paths within a single job
-(`junit: [rspec-1.xml, rspec-2.xml, rspec-3.xml]`) and they will be automatically
-concatenated into a single file.
+multiple test report paths within a single job and they will be automatically
+concatenated into a single file. Use a filename pattern (`junit: rspec-*.xml`),
+an array of filenames (`junit: [rspec-1.xml, rspec-2.xml, rspec-3.xml]`), or a
+combination thereof (`junit: [rspec.xml, test-results/TEST-*.xml]`).
## `dependencies`
diff --git a/doc/development/README.md b/doc/development/README.md
index efe37b8ba0b..43d3865da0e 100644
--- a/doc/development/README.md
+++ b/doc/development/README.md
@@ -7,7 +7,7 @@ description: 'Learn how to contribute to GitLab.'
## Get started!
-- Setup GitLab's development environment with [GitLab Development Kit (GDK)](https://gitlab.com/gitlab-org/gitlab-development-kit/blob/master/doc/howto/README.md)
+- Set up GitLab's development environment with [GitLab Development Kit (GDK)](https://gitlab.com/gitlab-org/gitlab-development-kit/blob/master/doc/howto/README.md)
- [GitLab contributing guide](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CONTRIBUTING.md)
- [Architecture](architecture.md) of GitLab
- [Rake tasks](rake_tasks.md) for development
@@ -53,11 +53,14 @@ description: 'Learn how to contribute to GitLab.'
## Performance guides
-- [Instrumentation](instrumentation.md)
-- [Performance guidelines](performance.md)
+- [Instrumentation](instrumentation.md) for Ruby code running in production
+ environments
+- [Performance guidelines](performance.md) for writing code, benchmarks, and
+ certain patterns to avoid
- [Merge request performance guidelines](merge_request_performance_guidelines.md)
for ensuring merge requests do not negatively impact GitLab performance
-- [Profiling](profiling.md) for profiling a URL
+- [Profiling](profiling.md) a URL, measuring performance using Sherlock, or
+ tracking down N+1 queries using Bullet
## Database guides
@@ -91,6 +94,7 @@ description: 'Learn how to contribute to GitLab.'
- [Verifying database capabilities](verifying_database_capabilities.md)
- [Database Debugging and Troubleshooting](database_debugging.md)
- [Query Count Limits](query_count_limits.md)
+- [Database helper modules](database_helpers.md)
## Testing guides
diff --git a/doc/development/automatic_ce_ee_merge.md b/doc/development/automatic_ce_ee_merge.md
index f6509b5c1dd..9dd78806a12 100644
--- a/doc/development/automatic_ce_ee_merge.md
+++ b/doc/development/automatic_ce_ee_merge.md
@@ -63,7 +63,7 @@ EE version of your CE merge request.
For each commit (except on `master`), the `ee_compat_check` CI job tries to
detect if the current branch's changes will conflict during the CE->EE merge.
-The job reports what files are conflicting and how to setup a merge request
+The job reports what files are conflicting and how to set up a merge request
against EE.
#### How the job works
diff --git a/doc/development/contributing/issue_workflow.md b/doc/development/contributing/issue_workflow.md
index 08042fa2aec..edd2d063458 100644
--- a/doc/development/contributing/issue_workflow.md
+++ b/doc/development/contributing/issue_workflow.md
@@ -224,7 +224,7 @@ on those issues. Please select someone with relevant experience from the
the commit history for the affected files to find someone.
We also use [GitLab Triage] to automate some triaging policies. This is
-currently setup as a [scheduled pipeline] running on [quality/triage-ops]
+currently set up as a [scheduled pipeline] running on [quality/triage-ops]
project.
[described in our handbook]: https://about.gitlab.com/handbook/engineering/issue-triage/
diff --git a/doc/development/database_debugging.md b/doc/development/database_debugging.md
index 9c31265e417..b2c804b2ff0 100644
--- a/doc/development/database_debugging.md
+++ b/doc/development/database_debugging.md
@@ -33,7 +33,7 @@ If your test DB is giving you problems, it is safe to nuke it because it doesn't
- `bundle exec rake db:migrate RAILS_ENV=development`: Execute any pending migrations that you may have picked up from a MR
- `bundle exec rake db:migrate:status RAILS_ENV=development`: Check if all migrations are `up` or `down`
- `bundle exec rake db:migrate:down VERSION=20170926203418 RAILS_ENV=development`: Tear down a migration
- - `bundle exec rake db:migrate:up VERSION=20170926203418 RAILS_ENV=development`: Setup a migration
+ - `bundle exec rake db:migrate:up VERSION=20170926203418 RAILS_ENV=development`: Set up a migration
- `bundle exec rake db:migrate:redo VERSION=20170926203418 RAILS_ENV=development`: Re-run a specific migration
diff --git a/doc/development/database_helpers.md b/doc/development/database_helpers.md
new file mode 100644
index 00000000000..21e4e725de6
--- /dev/null
+++ b/doc/development/database_helpers.md
@@ -0,0 +1,63 @@
+# Database helpers
+
+There are a number of useful helper modules defined in `/lib/gitlab/database/`.
+
+## Subquery
+
+In some cases it is not possible to perform an operation on a query.
+For example:
+
+```ruby
+Geo::EventLog.where('id < 100').limit(10).delete_all
+```
+
+Will give this error:
+
+> ActiveRecord::ActiveRecordError: delete_all doesn't support limit
+
+One solution would be to wrap it in another `where`:
+
+```ruby
+Geo::EventLog.where(id: Geo::EventLog.where('id < 100').limit(10)).delete_all
+```
+
+This works with PostgreSQL, but with MySQL it gives this error:
+
+> ActiveRecord::StatementInvalid: Mysql2::Error: This version of MySQL
+> doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'
+
+Also, that query doesn't have very good performance. Using a
+`INNER JOIN` with itself is better.
+
+So instead of this query:
+
+```sql
+SELECT geo_event_log.*
+FROM geo_event_log
+WHERE geo_event_log.id IN
+ (SELECT geo_event_log.id
+ FROM geo_event_log
+ WHERE (id < 100)
+ LIMIT 10)
+```
+
+It's better to write:
+
+```sql
+SELECT geo_event_log.*
+FROM geo_event_log
+INNER JOIN
+ (SELECT geo_event_log.*
+ FROM geo_event_log
+ WHERE (id < 100)
+ LIMIT 10) t2 ON geo_event_log.id = t2.id
+```
+
+And this is where `Gitlab::Database::Subquery.self_join` can help
+you. So you can rewrite the above statement as:
+
+```ruby
+Gitlab::Database::Subquery.self_join(Geo::EventLog.where('id < 100').limit(10)).delete_all
+```
+
+And this also works with MySQL, so you don't need to worry about that.
diff --git a/doc/development/documentation/index.md b/doc/development/documentation/index.md
index 7ac211ed550..d6ae4cb39f0 100644
--- a/doc/development/documentation/index.md
+++ b/doc/development/documentation/index.md
@@ -411,6 +411,22 @@ The following GitLab features are used among others:
Every GitLab instance includes the documentation, which is available from `/help`
(`http://my-instance.com/help`), e.g., <https://gitlab.com/help>.
+The documentation available online on docs.gitlab.com is continuously
+deployed every hour from the `master` branch of CE, EE, Omnibus, and Runner. Therefore,
+once a merge request gets merged, it will be available online on the same day,
+but they will be shipped (and available on `/help`) within the milestone assigned
+to the MR.
+
+For instance, let's say your merge request has a milestone set to 11.3, which
+will be released on 2018-09-22. If it gets merged on 2018-09-15, it will be
+available online on 2018-09-15, but, as the feature freeze date has passed, if
+the MR does not have a "pick into 11.3" label, the milestone has to be changed
+to 11.4 and it will be shipped with all GitLab packages only on 2018-10-22,
+with GitLab 11.4. Meaning, it will only be available under `/help` from GitLab
+11.4 onwards, but available on docs.gitlab.com on the same day it was merged.
+
+### Linking to `/help`
+
When you're building a new feature, you may need to link the documentation
from GitLab, the application. This is normally done in files inside the
`app/views/` directory with the help of the `help_page_path` helper method.
diff --git a/doc/development/fe_guide/components.md b/doc/development/fe_guide/components.md
index 66a8abe42f7..ee0c2d534ff 100644
--- a/doc/development/fe_guide/components.md
+++ b/doc/development/fe_guide/components.md
@@ -42,7 +42,7 @@ See also the [corresponding UX guide](../ux_guide/components.md#dropdowns).
See also the [corresponding UX guide](../ux_guide/components.md#modals).
-We have a reusable Vue component for modals: [vue_shared/components/gl-modal.vue](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/app/assets/javascripts/vue_shared/components/gl-modal.vue)
+We have a reusable Vue component for modals: [vue_shared/components/gl_modal.vue](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/app/assets/javascripts/vue_shared/components/gl_modal.vue)
Here is an example of how to use it:
diff --git a/doc/development/feature_flags.md b/doc/development/feature_flags.md
index 6f757f1ce7b..417298205f5 100644
--- a/doc/development/feature_flags.md
+++ b/doc/development/feature_flags.md
@@ -65,13 +65,18 @@ In the rare case that you need the feature flag to be on automatically, use
Feature.enabled?(:feature_flag, project, default_enabled: true)
```
+For more information about rolling out changes using feature flags, refer to the
+[Rolling out changes using feature flags](rolling_out_changes_using_feature_flags.md)
+guide.
+
### Specs
In the test environment `Feature.enabled?` is stubbed to always respond to `true`,
so we make sure behavior under feature flag doesn't go untested in some non-specific
contexts.
-If you need to test the feature flag in a different state, you need to stub it with:
+Whenever a feature flag is present, make sure to test _both_ states of the
+feature flag. You can stub a feature flag as follows:
```ruby
stub_feature_flags(my_feature_flag: false)
diff --git a/doc/development/file_storage.md b/doc/development/file_storage.md
index fdbd7f1fa37..6e014e8c751 100644
--- a/doc/development/file_storage.md
+++ b/doc/development/file_storage.md
@@ -45,6 +45,11 @@ In the case of Issues/MR/Notes Markdown attachments, there is a different approa
instead of basing the path into a mutable variable `:project_path_with_namespace`, it's possible to use the
hash of the project ID instead, if project migrates to the new approach (introduced in 10.2).
+> Note: We provide an [all-in-one rake task] to migrate all uploads to object
+> storage in one go. If a new Uploader class or model type is introduced, make
+> sure you add a rake task invocation corresponding to it to the [category
+> list].
+
### Path segments
Files are stored at multiple locations and use different path schemes.
@@ -137,3 +142,5 @@ end
[CarrierWave]: https://github.com/carrierwaveuploader/carrierwave
[Hashed Storage]: ../administration/repository_storage_types.md
+[all-in-one rake task]: ../administration/raketasks/uploads/migrate.md
+[category list]: https://gitlab.com/gitlab-org/gitlab-ce/blob/master/lib/tasks/gitlab/uploads/migrate.rake
diff --git a/doc/development/i18n/proofreader.md b/doc/development/i18n/proofreader.md
index 7054ff39da0..5e13c725e15 100644
--- a/doc/development/i18n/proofreader.md
+++ b/doc/development/i18n/proofreader.md
@@ -30,6 +30,7 @@ are very appreciative of the work done by translators and proofreaders!
- Korean
- Chang-Ho Cha - [GitLab](https://gitlab.com/changho-cha), [Crowdin](https://crowdin.com/profile/zzazang)
- Huang Tao - [GitLab](https://gitlab.com/htve), [Crowdin](https://crowdin.com/profile/htve)
+ - Ji Hun Oh - [GitLab](https://gitlab.com/Baw-Appie), [Crowdin](https://crowdin.com/profile/BawAppie)
- Polish
- Filip Mech - [GitLab](https://gitlab.com/mehenz), [Crowdin](https://crowdin.com/profile/mehenz)
- Portuguese, Brazilian
diff --git a/doc/development/module_with_instance_variables.md b/doc/development/module_with_instance_variables.md
index 48a1b7f847e..7bdfa04fc57 100644
--- a/doc/development/module_with_instance_variables.md
+++ b/doc/development/module_with_instance_variables.md
@@ -60,7 +60,7 @@ as long as it's contained in the same module; that is, no other modules or
objects are touching them, then it would be an acceptable use.
We especially allow the case where a single instance variable is used with
-`||=` to setup the value. This would look like:
+`||=` to set up the value. This would look like:
``` ruby
module M
diff --git a/doc/development/rake_tasks.md b/doc/development/rake_tasks.md
index fc51b74da1d..2ad748d4802 100644
--- a/doc/development/rake_tasks.md
+++ b/doc/development/rake_tasks.md
@@ -1,6 +1,6 @@
# Rake tasks for developers
-## Setup db with developer seeds
+## Set up db with developer seeds
Note that if your db user does not have advanced privileges you must create the db manually before running this command.
diff --git a/doc/development/rolling_out_changes_using_feature_flags.md b/doc/development/rolling_out_changes_using_feature_flags.md
new file mode 100644
index 00000000000..905aa26a40b
--- /dev/null
+++ b/doc/development/rolling_out_changes_using_feature_flags.md
@@ -0,0 +1,153 @@
+# Rolling out changes using feature flags
+
+[Feature flags](feature_flags.md) can be used to gradually roll out changes, be
+it a new feature, or a performance improvement. By using feature flags, we can
+comfortably measure the impact of our changes, while still being able to easily
+disable those changes, without having to revert an entire release.
+
+## When to use feature flags
+
+Starting with GitLab 11.4, developers are required to use feature flags for
+non-trivial changes. Such changes include:
+
+* New features (e.g. a new merge request widget, epics, etc).
+* Complex performance improvements that may require additional testing in
+ production, such as rewriting complex queries.
+* Invasive changes to the user interface, such as a new navigation bar or the
+ removal of a sidebar.
+* Adding support for importing projects from a third-party service.
+
+In all cases, those working on the changes can best decide if a feature flag is
+necessary. For example, changing the color of a button doesn't need a feature
+flag, while changing the navigation bar definitely needs one. In case you are
+uncertain if a feature flag is necessary, simply ask about this in the merge
+request, and those reviewing the changes will likely provide you with an answer.
+
+When using a feature flag for UI elements, make sure to _also_ use a feature
+flag for the underlying backend code, if there is any. This ensures there is
+absolutely no way to use the feature until it is enabled.
+
+## The cost of feature flags
+
+When reading the above, one might be tempted to think this procedure is going to
+add a lot of work. Fortunately, this is not the case, and we'll show why. For
+this example we'll specify the cost of the work to do as a number, ranging from
+0 to infinity. The greater the number, the more expensive the work is. The cost
+does _not_ translate to time, it's just a way of measuring complexity of one
+change relative to another.
+
+Let's say we are building a new feature, and we have determined that the cost of
+this is 10. We have also determined that the cost of adding a feature flag check
+in a variety of places is 1. If we do not use feature flags, and our feature
+works as intended, our total cost is 10. This however is the best case scenario.
+Optimising for the best case scenario is guaranteed to lead to trouble, whereas
+optimising for the worst case scenario is almost always better.
+
+To illustrate this, let's say our feature causes an outage, and there's no
+immediate way to resolve it. This means we'd have to take the following steps to
+resolve the outage:
+
+1. Revert the release.
+1. Perform any cleanups that might be necessary, depending on the changes that
+ were made.
+1. Revert the commit, ensuring the "master" branch remains stable. This is
+ especially necessary if solving the problem can take days or even weeks.
+1. Pick the revert commit into the appropriate stable branches, ensuring we
+ don't block any future releases until the problem is resolved.
+
+As history has shown, these steps are time consuming, complex, often involve
+many developers, and worst of all: our users will have a bad experience using
+GitLab.com until the problem is resolved.
+
+Now let's say that all of this has an associated cost of 10. This means that in
+the worst case scenario, which we should optimise for, our total cost is now 20.
+
+If we had used a feature flag, things would have been very different. We don't
+need to revert a release, and because feature flags are disabled by default we
+don't need to revert and pick any Git commits. In fact, all we have to do is
+disable the feature, and _maybe_ perform some cleanup. Let's say that the cost
+of this is 1. In this case, our best case cost is 11: 10 to build the feature,
+and 1 to add the feature flag. The worst case cost is now 12: 10 to build the
+feature, 1 to add the feature flag, and 1 to disable it.
+
+Here we can see that in the best case scenario the work necessary is only a tiny
+bit more compared to not using a feature flag. Meanwhile, the process of
+reverting our changes has been made significantly cheaper, to the point of being
+trivial.
+
+In other words, feature flags do not slow down the development process. Instead,
+they speed up the process as managing incidents now becomes _much_ easier. Once
+continuous deployments are easier to perform, the time to iterate on a feature
+is reduced even further, as you no longer need to wait weeks before your changes
+are available on GitLab.com.
+
+## Rolling out changes
+
+The procedure of using feature flags is straightforward, and similar to not
+using them. You add the necessary tests (make sure to test both the on and off
+states of your feature flag(s)), make sure they all pass, have the code
+reviewed, etc. You then submit your merge request, and add the ~"feature flag"
+label. This label is used to signal to release managers that your changes are
+hidden behind a feature flag and that it is safe to pick the MR into a stable
+branch, without the need for an exception request.
+
+When the changes are deployed it is time to start rolling out the feature to our
+users. The exact procedure of rolling out a change is unspecified, as this can
+vary from change to change. However, in general we recommend rolling out changes
+incrementally, instead of enabling them for everybody right away. We also
+recommend you to _not_ enable a feature _before_ the code is being deployed.
+This allows you to separate rolling out a feature from a deploy, making it
+easier to measure the impact of both separately.
+
+GitLab's feature library (using
+[Flipper](https://github.com/jnunemaker/flipper), and covered in the [Feature
+Flags](feature_flags.md) guide) supports rolling out changes to a percentage of
+users. This in turn can be controlled using [GitLab
+chatops](https://docs.gitlab.com/ee/ci/chatops/).
+
+For example, to enable a feature for 25% of all users, run the following in
+Slack:
+
+```
+/chatops run feature set new_navigation_bar 25
+```
+
+This will enable the feature for GitLab.com, with `new_navigation_bar` being the
+name of the feature. We can also enable the feature for <https://dev.gitlab.org>
+or <https://staging.gitlab.com>:
+
+```
+/chatops run feature set new_navigation_bar 25 --dev
+/chatops run feature set new_navigation_bar 25 --staging
+```
+
+If you are not certain what percentages to use, simply use the following steps:
+
+1. 25%
+1. 50%
+1. 75%
+1. 100%
+
+Between every step you'll want to wait a little while and monitor the
+appropriate graphs on <https://dashboards.gitlab.net>. The exact time to wait
+may differ. For some features a few minutes is enough, while for others you may
+want to wait several hours or even days. This is entirely up to you, just make
+sure it is clearly communicated to your team, and the Production team if you
+anticipate any potential problems.
+
+Once a change is deemed stable, submit a new merge request to remove the
+feature flag. This ensures the change is available to all users and self-hosted
+instances. Make sure to add the ~"feature flag" label to this merge request so
+release managers are aware the changes are hidden behind a feature flag. If the
+merge request has to be picked into a stable branch (e.g. after the 7th), make
+sure to also add the appropriate "Pick into X" label (e.g. "Pick into 11.4").
+
+One might be tempted to think this will delay the release of a feature by at
+least one month (= one release). This is not the case. A feature flag does not
+have to stick around for a specific amount of time (e.g. at least one release),
+instead they should stick around until the feature is deemed stable. Stable
+means it works on GitLab.com without causing any problems, such as outages. In
+most cases this will translate to a feature (with a feature flag) being shipped
+in RC1, followed by the feature flag being removed in RC2. This in turn means
+the feature will be stable by the time we publish a stable package around the
+22nd of the month.
diff --git a/doc/development/testing_guide/index.md b/doc/development/testing_guide/index.md
index 0cd63a54b55..67e4cfeda0e 100644
--- a/doc/development/testing_guide/index.md
+++ b/doc/development/testing_guide/index.md
@@ -59,6 +59,12 @@ parallelization, monitoring.
---
+## [Review apps](review_apps.md)
+
+How review apps are set up for GitLab CE/EE and how to use them.
+
+---
+
## [Testing Rake tasks](testing_rake_tasks.md)
Everything you should know about how to test Rake tasks.
diff --git a/doc/development/testing_guide/review_apps.md b/doc/development/testing_guide/review_apps.md
new file mode 100644
index 00000000000..38ea2f1dde1
--- /dev/null
+++ b/doc/development/testing_guide/review_apps.md
@@ -0,0 +1,82 @@
+# Review apps
+
+We currently have review apps available as a manual job in EE pipelines. Here is
+[the first implementation](https://gitlab.com/gitlab-org/gitlab-ee/merge_requests/6259).
+
+That said, [the Quality team is working](https://gitlab.com/gitlab-org/gitlab-ee/merge_requests/6665)
+on making Review Apps automatically deployed by each pipeline, both in CE and EE.
+
+## How does it work?
+
+1. On every EE [pipeline][gitlab-pipeline] during the `test` stage, you can
+ start the [`review` job][review-job]
+1. The `review` job [triggers a pipeline][cng-pipeline] in the
+ [`CNG-mirror`][cng-mirror] [^1] project
+1. The `CNG-mirror` pipeline creates the Docker images of each component (e.g. `gitlab-rails-ee`,
+ `gitlab-shell`, `gitaly` etc.) based on the commit from the
+ [GitLab pipeline][gitlab-pipeline] and store them in its
+ [registry][cng-mirror-registry]
+1. Once all images are built, the review app is deployed using
+ [the official GitLab Helm chart][helm-chart] [^2] to the
+ [`review-apps-ee` Kubernetes cluster on GCP][review-apps-ee]
+ - The actual scripts used to deploy the review app can be found at
+ [`scripts/review_apps/review-apps.sh`][review-apps.sh]
+ - These scripts are basically
+ [our official Auto DevOps scripts][Auto-DevOps.gitlab-ci.yml] where the
+ default CNG images are overriden with the images built and stored in the
+ [`CNG-mirror` project's registry][cng-mirror-registry]
+1. Once the `review` job succeeds, you should be able to use your review app
+ thanks to the direct link to it from the MR widget. The default username is
+ `root` and its password can be found in the 1Password secure note named
+ **gitlab-{ce,ee} review app's root password**.
+
+**Additional notes:**
+
+- The Kubernetes cluster is connected to the `gitlab-ee` project using [GitLab's
+ Kubernetes integration][gitlab-k8s-integration]. This basically allows to have
+ a link to the review app directly from the merge request widget.
+- The manual `stop_review` in the `post-cleanup` stage can be used to stop a
+ review app manually, and is also started by GitLab once a branch is deleted
+- [TBD] Review apps are cleaned up regularly using a pipeline schedule that runs
+ the [`scripts/review_apps/automated_cleanup.rb`][automated_cleanup.rb] script
+
+[^1]: We use the `CNG-mirror` project so that the `CNG`, (**C**loud **N**ative **G**itLab), project's registry is
+ not overloaded with a lot of transient Docker images.
+[^2]: Since we're using [the official GitLab Helm chart][helm-chart], this means
+ you get the a dedicated environment for your branch that's very close to what it
+ would look in production
+
+## Frequently Asked Questions
+
+**Will it be too much to trigger CNG image builds on every test run? This could create thousands of unused docker images.**
+
+ > We have to start somewhere and improve later. If we see this getting out of hand, we will revisit.
+
+**How big is the Kubernetes cluster?**
+
+ > The cluster is currently setup with a single pool of preemptible
+ nodes, with a minimum of 1 node and a maximum of 30 nodes.
+
+**What are the machine running on the cluster?**
+
+ > We're currently using `n1-standard-4` (4 vCPUs, 15 GB memory) machines.
+
+**How do we secure this from abuse? Apps are open to the world so we need to find a way to limit it to only us.**
+
+ > This won't work for forks. We will add a root password to 1password shared vault.
+
+[gitlab-pipeline]: https://gitlab.com/gitlab-org/gitlab-ee/pipelines/29302122
+[review-job]: https://gitlab.com/gitlab-org/gitlab-ee/-/jobs/94294136
+[cng-mirror]: https://gitlab.com/gitlab-org/build/CNG-mirror
+[cng-pipeline]: https://gitlab.com/gitlab-org/build/CNG-mirror/pipelines/29307727
+[cng-mirror-registry]: https://gitlab.com/gitlab-org/build/CNG-mirror/container_registry
+[helm-chart]: https://gitlab.com/charts/gitlab/
+[review-apps-ee]: https://console.cloud.google.com/kubernetes/clusters/details/us-central1-b/review-apps-ee?project=gitlab-review-apps
+[review-apps.sh]: https://gitlab.com/gitlab-org/gitlab-ee/blob/master/scripts/review_apps/review-apps.sh
+[automated_cleanup.rb]: https://gitlab.com/gitlab-org/gitlab-ee/blob/master/scripts/review_apps/automated_cleanup.rb
+[Auto-DevOps.gitlab-ci.yml]: https://gitlab.com/gitlab-org/gitlab-ci-yml/blob/master/Auto-DevOps.gitlab-ci.yml
+[gitlab-k8s-integration]: https://docs.gitlab.com/ee/user/project/clusters/index.html
+
+---
+
+[Return to Testing documentation](index.md)
diff --git a/doc/development/ux_guide/users.md b/doc/development/ux_guide/users.md
index 6afb33cfc36..08f393132e8 100644
--- a/doc/development/ux_guide/users.md
+++ b/doc/development/ux_guide/users.md
@@ -154,7 +154,7 @@ He credits himself as being entirely responsible for moving his company to GitLa
#### Updating to the latest release
Matthieu introduced his company to GitLab. He is responsible for maintaining and managing the company's installation in addition to his day job. He feels updates are too frequent and he doesn't always have sufficient time to update GitLab. As a result, he's not up to date with releases.
-Matthieu tried to set up automatic updates, however, as he isn't a Systems Administrator, he wasn't confident in his set-up. He feels he should be able to "upgrade without users even noticing" but hasn't figured out how to do this yet. Matthieu would like the "update process to be triggered from the Admin Panel, perhaps accompanied with a changelog and the option to skip updates."
+Matthieu tried to set up automatic updates, however, as he isn't a Systems Administrator, he wasn't confident in his setup. He feels he should be able to "upgrade without users even noticing" but hasn't figured out how to do this yet. Matthieu would like the "update process to be triggered from the Admin Panel, perhaps accompanied with a changelog and the option to skip updates."
Matthieu is looking for confirmation that his update procedure is "secure and efficient" so more tutorials related to this topic would be useful to him.
diff --git a/doc/install/azure/index.md b/doc/install/azure/index.md
index 570bd18c172..7835401cc0b 100644
--- a/doc/install/azure/index.md
+++ b/doc/install/azure/index.md
@@ -74,7 +74,7 @@ The first items we need to configure are the basic settings of the underlying vi
> **Note:** if you're unsure which authentication type to use, select **Password**
1. If you chose **SSH public key** - enter your `SSH public key` into the field provided
- _(read the [SSH documentation][GitLab-Docs-SSH] to learn more about how to setup SSH
+ _(read the [SSH documentation][GitLab-Docs-SSH] to learn more about how to set up SSH
public keys)_
1. If you chose **Password** - enter the password you wish to use _(this is the password that you
will use later in this tutorial to [SSH] into the VM, so make sure it's a strong password/passphrase)_
@@ -154,7 +154,7 @@ on the Azure Dashboard (you may need to refresh the page):
The new VM can also be accessed by clicking the `All resources` or `Virtual machines` icons in the
Azure Portal sidebar navigation menu.
-## Setup a domain name
+## Set up a domain name
The VM will have a public IP address (static by default), but Azure allows us to assign a friendly
DNS name to the VM, so let's go ahead and do that.
@@ -296,7 +296,7 @@ homepage for the project:
![GitLab - Empty Project](img/gitlab-project-home-empty.png)
If you scroll further down the project's home page, you'll see some basic instructions on how to
-setup a local clone of your new repository and push and pull from it:
+set up a local clone of your new repository and push and pull from it:
![GitLab - Empty Project - Basic Instructions](img/gitlab-project-home-instructions.png)
@@ -347,7 +347,7 @@ If you're running [SSH] from the command-line (terminal), then type in the follo
connect to your VM, substituting `username` and `your-azure-domain-name.com` for the correct values.
Again, remember that your Azure VM domain name will be the one you
-[setup previously in the tutorial](#set-up-a-domain-name). If you didn't setup a domain name for
+[set up previously in the tutorial](#set-up-a-domain-name). If you didn't set up a domain name for
your VM, you can use the IP address in its place in the following command:
```bash
@@ -401,7 +401,7 @@ is now showing **"up-to-date"**:
Naturally, we believe that GitLab is a great git repository tool. However, GitLab is a whole lot
more than that too. GitLab unifies issues, code review, CI and CD into a single UI, helping you to
move faster from idea to production, and in this tutorial we showed you how quick and easy it is to
-setup and run your own instance of GitLab on Azure, Microsoft's cloud service.
+set up and run your own instance of GitLab on Azure, Microsoft's cloud service.
Azure is a great way to experiment with GitLab, and if you decide (as we hope) that GitLab is for
you, you can continue to use Azure as your secure, scalable cloud provider or of course run GitLab
@@ -424,7 +424,7 @@ Check out our other [Technical Articles][GitLab-Technical-Articles] or browse th
- [Azure - Properly Shutdown an Azure VM][Azure-Properly-Shutdown-VM]
- [SSH], [PuTTY] and [Using SSH in PuTTY][Using-SSH-In-Putty]
-[Original-Blog-Post]: https://about.gitlab.com/2016/07/13/how-to-setup-a-gitlab-instance-on-microsoft-azure/ "How to Setup a GitLab Instance on Microsoft Azure"
+[Original-Blog-Post]: https://about.gitlab.com/2016/07/13/how-to-setup-a-gitlab-instance-on-microsoft-azure/ "How to Set up a GitLab Instance on Microsoft Azure"
[GitLab-Docs]: https://docs.gitlab.com/ce/README.html "GitLab Documentation"
[GitLab-Technical-Articles]: https://docs.gitlab.com/ce/articles/index.html "GitLab Technical Articles"
[GitLab-Docs-SSH]: https://docs.gitlab.com/ce/ssh/README.html "GitLab Documentation: SSH"
diff --git a/doc/install/database_mysql.md b/doc/install/database_mysql.md
index 4cf18f53239..acaed53e052 100644
--- a/doc/install/database_mysql.md
+++ b/doc/install/database_mysql.md
@@ -79,7 +79,7 @@ After installation or upgrade, remember to [convert any new tables](#tables-and-
---
-GitLab 8.14 has introduced [a feature](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/7420) requiring `utf8mb4` encoding to be supported in your GitLab MySQL Database, which is not the case if you have setup your database before GitLab 8.16.
+GitLab 8.14 has introduced [a feature](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/7420) requiring `utf8mb4` encoding to be supported in your GitLab MySQL Database, which is not the case if you have set up your database before GitLab 8.16.
Follow the below instructions to ensure you use the most up to date requirements for your GitLab MySQL Database.
diff --git a/doc/install/digitaloceandocker.md b/doc/install/digitaloceandocker.md
index 8efc0530b8a..676392eacf2 100644
--- a/doc/install/digitaloceandocker.md
+++ b/doc/install/digitaloceandocker.md
@@ -87,7 +87,7 @@ You can add this to your `~/.bash_profile` file to ensure the `docker` client us
+ Container name: `gitlab-test-8.10`
+ GitLab version: **EE** `8.10.8-ee.0`
-##### Setup container settings
+##### Set up container settings
```
export SSH_PORT=2222
diff --git a/doc/install/installation.md b/doc/install/installation.md
index 85431a80a81..7df81fbc46f 100644
--- a/doc/install/installation.md
+++ b/doc/install/installation.md
@@ -515,7 +515,7 @@ Make GitLab start on boot:
sudo update-rc.d gitlab defaults 21
-### Setup Logrotate
+### Set up Logrotate
sudo cp lib/support/logrotate/gitlab /etc/logrotate.d/gitlab
diff --git a/doc/install/openshift_and_gitlab/index.md b/doc/install/openshift_and_gitlab/index.md
index 70bc3ff770f..5c8a830ac8f 100644
--- a/doc/install/openshift_and_gitlab/index.md
+++ b/doc/install/openshift_and_gitlab/index.md
@@ -80,7 +80,7 @@ This will download the VirtualBox image and fire up the VM with some preconfigur
values as you can see in the Vagrantfile. As you may have noticed, you need
plenty of RAM (5GB in our example), so make sure you have enough.
-Now that OpenShift is setup, let's see how the web console looks like.
+Now that OpenShift is set up, let's see how the web console looks like.
### Explore the OpenShift web console
diff --git a/doc/install/relative_url.md b/doc/install/relative_url.md
index 2f5d4142d04..5f129fd3bd1 100644
--- a/doc/install/relative_url.md
+++ b/doc/install/relative_url.md
@@ -124,5 +124,5 @@ To disable the relative URL:
1. Follow the same as above starting from 2. and set up the
GitLab URL to one that doesn't contain a relative path.
-[omnibus-rel]: http://docs.gitlab.com/omnibus/settings/configuration.html#configuring-a-relative-url-for-gitlab "How to setup relative URL in Omnibus GitLab"
+[omnibus-rel]: http://docs.gitlab.com/omnibus/settings/configuration.html#configuring-a-relative-url-for-gitlab "How to set up relative URL in Omnibus GitLab"
[restart gitlab]: ../administration/restart_gitlab.md#installations-from-source "How to restart GitLab"
diff --git a/doc/install/requirements.md b/doc/install/requirements.md
index 5531dcde4e9..13a6a1c68ad 100644
--- a/doc/install/requirements.md
+++ b/doc/install/requirements.md
@@ -27,7 +27,7 @@ Please see the [installation from source guide](installation.md) and the [instal
### Non-Unix operating systems such as Windows
-GitLab is developed for Unix operating systems.
+GitLab is developed for Unix operating systems.
It does **not** run on Windows, and we have no plans to support it in the near future. For the latest development status view this [issue](https://gitlab.com/gitlab-org/gitlab-ce/issues/46567).
Please consider using a virtual machine to run GitLab.
@@ -103,19 +103,21 @@ features of GitLab work with MySQL/MariaDB:
1. MySQL support for subgroups was [dropped with GitLab 9.3][post].
See [issue #30472][30472] for more information.
-1. GitLab Geo does [not support MySQL](https://docs.gitlab.com/ee/gitlab-geo/database.html#mysql-replication).
-1. [Zero downtime migrations][zero] do not work with MySQL
+1. Geo does [not support MySQL](https://docs.gitlab.com/ee/administration/geo/replication/database.html#mysql-replication). This means no supported Disaster Recovery solution if using MySQL. **[PREMIUM ONLY]**
+1. [Zero downtime migrations][../update/README.md#upgrading-without-downtime] do not work with MySQL.
1. GitLab [optimizes the loading of dashboard events](https://gitlab.com/gitlab-org/gitlab-ce/issues/31806) using [PostgreSQL LATERAL JOINs](https://blog.heapanalytics.com/postgresqls-powerful-new-join-type-lateral/).
1. In general, SQL optimized for PostgreSQL may run much slower in MySQL due to
differences in query planners. For example, subqueries that work well in PostgreSQL
- may not be [performant in MySQL](https://dev.mysql.com/doc/refman/5.7/en/optimizing-subqueries.html)
+ may not be [performant in MySQL](https://dev.mysql.com/doc/refman/5.7/en/optimizing-subqueries.html).
+1. Binary column index length is limited to 20 bytes. This is accomplished with [a hack](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/config/initializers/mysql_set_length_for_binary_indexes.rb).
+1. MySQL requires a variety of hacks to increase limits on various columns, [for example](https://gitlab.com/gitlab-org/gitlab-ce/issues/49583).
+1. [The milestone filter runs slower queries on MySQL](https://gitlab.com/gitlab-org/gitlab-ce/issues/51173#note_99391731).
1. We expect this list to grow over time.
Existing users using GitLab with MySQL/MariaDB are advised to
[migrate to PostgreSQL](../update/mysql_to_postgresql.md) instead.
[30472]: https://gitlab.com/gitlab-org/gitlab-ce/issues/30472
-[zero]: ../update/README.md#upgrading-without-downtime
[post]: https://about.gitlab.com/2017/06/22/gitlab-9-3-released/#dropping-support-for-subgroups-in-mysql
### PostgreSQL Requirements
diff --git a/doc/integration/gmail_action_buttons_for_gitlab.md b/doc/integration/gmail_action_buttons_for_gitlab.md
index 05a91d9bef9..c19320471e3 100644
--- a/doc/integration/gmail_action_buttons_for_gitlab.md
+++ b/doc/integration/gmail_action_buttons_for_gitlab.md
@@ -2,7 +2,7 @@
GitLab supports [Google actions in email](https://developers.google.com/gmail/markup/actions/actions-overview).
-If correctly setup, emails that require an action will be marked in Gmail.
+If correctly set up, emails that require an action will be marked in Gmail.
![gmail_actions_button.png](img/gmail_action_buttons_for_gitlab.png)
diff --git a/doc/policy/maintenance.md b/doc/policy/maintenance.md
index 7f028565412..fc7b97b3cc2 100644
--- a/doc/policy/maintenance.md
+++ b/doc/policy/maintenance.md
@@ -44,7 +44,7 @@ This decision is made on a case-by-case basis.
## Upgrade recommendations
-We encourage everyone to run the [latest stable release](https://about.gitlab.com/blog/categories/release/) to ensure that you can
+We encourage everyone to run the [latest stable release](https://about.gitlab.com/blog/categories/releases/) to ensure that you can
easily upgrade to the most secure and feature-rich GitLab experience. In order
to make sure you can easily run the most recent stable release, we are working
hard to keep the update process simple and reliable.
diff --git a/doc/security/two_factor_authentication.md b/doc/security/two_factor_authentication.md
index f02f7b807cf..cd290a80314 100644
--- a/doc/security/two_factor_authentication.md
+++ b/doc/security/two_factor_authentication.md
@@ -11,7 +11,7 @@ You can read more about it here:
## Enforcing 2FA for all users
Users on GitLab, can enable it without any admin's intervention. If you want to
-enforce everyone to setup 2FA, you can choose from two different ways:
+enforce everyone to set up 2FA, you can choose from two different ways:
1. Enforce on next login
2. Suggest on next login, but allow a grace period before enforcing.
diff --git a/doc/topics/authentication/index.md b/doc/topics/authentication/index.md
index a8aa11265d0..a645f65938f 100644
--- a/doc/topics/authentication/index.md
+++ b/doc/topics/authentication/index.md
@@ -44,6 +44,6 @@ This page gathers all the resources for the topic **Authentication** within GitL
- [Kanboard Plugin GitLab Authentication](https://kanboard.net/plugin/gitlab-auth)
- [Jenkins GitLab OAuth Plugin](https://wiki.jenkins-ci.org/display/JENKINS/GitLab+OAuth+Plugin)
-- [Setup Gitlab CE with Active Directory authentication](https://www.caseylabs.com/setup-gitlab-ce-with-active-directory-authentication/)
+- [Set up Gitlab CE with Active Directory authentication](https://www.caseylabs.com/setup-gitlab-ce-with-active-directory-authentication/)
- [How to customize GitLab to support OpenID authentication](http://eric.van-der-vlist.com/blog/2013/11/23/how-to-customize-gitlab-to-support-openid-authentication/)
- [Openshift - Configuring Authentication and User Agent](https://docs.openshift.org/latest/install_config/configuring_authentication.html#GitLab)
diff --git a/doc/topics/autodevops/index.md b/doc/topics/autodevops/index.md
index e778f1d83df..421b5411a07 100644
--- a/doc/topics/autodevops/index.md
+++ b/doc/topics/autodevops/index.md
@@ -71,11 +71,6 @@ For an overview on the creation of Auto DevOps, read the blog post [From 2/3 of
## Requirements
-TIP: **Tip:**
-For self-hosted installations, the easiest way to make use of Auto DevOps is to
-install GitLab inside a Kubernetes cluster using the [GitLab Omnibus Helm Chart]
-which automatically installs and configures everything you need!
-
To make full use of Auto DevOps, you will need:
1. **GitLab Runner** (needed for all stages) - Your Runner needs to be
@@ -101,10 +96,6 @@ To make full use of Auto DevOps, you will need:
Kubernetes cluster using the
[`nginx-ingress`](https://github.com/kubernetes/charts/tree/master/stable/nginx-ingress)
Helm chart.
- 1. **Wildcard TLS termination** - You can deploy the
- [`kube-lego`](https://github.com/kubernetes/charts/tree/master/stable/kube-lego)
- Helm chart to your Kubernetes cluster to automatically issue certificates
- for your domains using Let's Encrypt.
1. **Prometheus** (needed for Auto Monitoring) - To enable Auto Monitoring, you
will need Prometheus installed somewhere (inside or outside your cluster) and
configured to scrape your Kubernetes cluster. To get response metrics
@@ -148,11 +139,6 @@ Auto DevOps base domain to `1.2.3.4.nip.io`.
Once set up, all requests will hit the load balancer, which in turn will route
them to the Kubernetes pods that run your application(s).
-NOTE: **Note:**
-If GitLab is installed using the [GitLab Omnibus Helm Chart], there are two
-options: provide a static IP, or have one assigned. For more information see the
-relevant docs on the [network prerequisites](../../install/kubernetes/gitlab_omnibus.md#networking-prerequisites).
-
## Using multiple Kubernetes clusters **[PREMIUM]**
When using Auto DevOps, you may want to deploy different environments to
@@ -482,10 +468,7 @@ The metrics include:
- **Response Metrics:** latency, throughput, error rate
- **System Metrics:** CPU utilization, memory utilization
-If GitLab has been deployed using the [GitLab Omnibus Helm Chart], no
-configuration is required.
-
-If you have installed GitLab using a different method, you need to:
+In order to make use of monitoring you need to:
1. [Deploy Prometheus](../../user/project/integrations/prometheus.md#configuring-your-own-prometheus-server-within-kubernetes) into your Kubernetes cluster
1. If you would like response metrics, ensure you are running at least version
@@ -850,6 +833,5 @@ curl --data "value=true" --header "PRIVATE-TOKEN: personal_access_token" https:/
[container-registry]: ../../user/project/container_registry.md
[postgresql]: https://www.postgresql.org/
[Auto DevOps template]: https://gitlab.com/gitlab-org/gitlab-ci-yml/blob/master/Auto-DevOps.gitlab-ci.yml
-[GitLab Omnibus Helm Chart]: ../../install/kubernetes/gitlab_omnibus.md
[ee]: https://about.gitlab.com/pricing/
[ce-19507]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/19507
diff --git a/doc/university/glossary/README.md b/doc/university/glossary/README.md
index 89516dba60b..6ff27e495fb 100644
--- a/doc/university/glossary/README.md
+++ b/doc/university/glossary/README.md
@@ -395,7 +395,7 @@ Allow you to [organize issues](../../user/project/milestones/index.md) and merge
### Mirror Repositories
-A project that is setup to automatically have its branches, tags, and commits [updated from an upstream repository](https://docs.gitlab.com/ee/workflow/repository_mirroring.html). This is useful when a repository you're interested in is located on a different server, and you want to be able to browse its content and activity using the familiar GitLab interface.
+A project that is set up to automatically have its branches, tags, and commits [updated from an upstream repository](https://docs.gitlab.com/ee/workflow/repository_mirroring.html). This is useful when a repository you're interested in is located on a different server, and you want to be able to browse its content and activity using the familiar GitLab interface.
### MIT License
@@ -673,7 +673,7 @@ Version control is a system that records changes to a file or set of files over
### Virtual Private Cloud (VPC)
-A [VPC](https://docs.gitlab.com/ce/university/glossary/README.html#virtual-private-cloud-vpc) is an on demand configurable pool of shared computing resources allocated within a public cloud environment, providing some isolation between the different users using the resources. GitLab users need to create a new Amazon VPC in order to [setup High Availability](https://docs.gitlab.com/ce/university/high-availability/aws/).
+A [VPC](https://docs.gitlab.com/ce/university/glossary/README.html#virtual-private-cloud-vpc) is an on demand configurable pool of shared computing resources allocated within a public cloud environment, providing some isolation between the different users using the resources. GitLab users need to create a new Amazon VPC in order to [set up High Availability](https://docs.gitlab.com/ce/university/high-availability/aws/).
### Virtual private server (VPS)
diff --git a/doc/university/high-availability/aws/README.md b/doc/university/high-availability/aws/README.md
index 1bff1488746..0a7ce922de1 100644
--- a/doc/university/high-availability/aws/README.md
+++ b/doc/university/high-availability/aws/README.md
@@ -286,7 +286,7 @@ to make the EFS integration easier to manage.
gitlab_rails['redis_port'] = 6379
Finally run reconfigure, you might find it useful to run a check and
-a service status to make sure everything has been setup correctly.
+a service status to make sure everything has been set up correctly.
sudo gitlab-ctl reconfigure
sudo gitlab-rake gitlab:check
diff --git a/doc/university/support/README.md b/doc/university/support/README.md
index 0cbae71d1f5..805af253367 100644
--- a/doc/university/support/README.md
+++ b/doc/university/support/README.md
@@ -37,7 +37,7 @@ Continue to look over remaining portions of the [University Overview](../README.
Get your development machine ready to familiarize yourself with the codebase, the components, and to be prepared to reproduce issues that our users encounter
- Install the [GDK](https://gitlab.com/gitlab-org/gitlab-development-kit)
- - [Setup OpenLDAP as part of this](https://gitlab.com/gitlab-org/gitlab-development-kit#openldap)
+ - [Set up OpenLDAP as part of this](https://gitlab.com/gitlab-org/gitlab-development-kit#openldap)
#### Become comfortable with the Installation processes that we support
diff --git a/doc/university/training/end-user/README.md b/doc/university/training/end-user/README.md
index 9b8a8db58e2..e5eb5d97e3b 100644
--- a/doc/university/training/end-user/README.md
+++ b/doc/university/training/end-user/README.md
@@ -80,7 +80,7 @@ git config --global user.name "Your Name"
git config --global user.email you@example.com
```
-- If you don't use the global flag you can setup a different author for
+- If you don't use the global flag you can set up a different author for
each project
- Check settings with:
diff --git a/doc/update/4.2-to-5.0.md b/doc/update/4.2-to-5.0.md
index 311664b2bc1..d292327efbd 100644
--- a/doc/update/4.2-to-5.0.md
+++ b/doc/update/4.2-to-5.0.md
@@ -32,7 +32,7 @@ cd /home/git/
sudo -u git -H git clone https://github.com/gitlabhq/gitlab-shell.git /home/git/gitlab-shell
```
-## 3. setup gitlab-shell
+## 3. set up gitlab-shell
```bash
# chmod all repos and files under git
diff --git a/doc/update/7.5-to-7.6.md b/doc/update/7.5-to-7.6.md
index f0dfb177b79..0d45a9528b9 100644
--- a/doc/update/7.5-to-7.6.md
+++ b/doc/update/7.5-to-7.6.md
@@ -82,7 +82,7 @@ git diff origin/7-5-stable:config/gitlab.yml.example origin/7-6-stable:config/gi
* HTTP setups: Make `/etc/nginx/sites-available/gitlab` the same as [`lib/support/nginx/gitlab`][nginx] but with your settings
* HTTPS setups: Make `/etc/nginx/sites-available/gitlab-ssl` the same as [`lib/support/nginx/gitlab-ssl`][nginx-ssl] but with your setting
-#### Setup time zone (optional)
+#### Set up time zone (optional)
Consider setting the time zone in `gitlab.yml` otherwise GitLab will default to UTC. If you set a time zone previously in [`application.rb`][app] (unlikely), unset it.
diff --git a/doc/update/7.6-to-7.7.md b/doc/update/7.6-to-7.7.md
index 85de6b0c546..5e0b2ca7bcd 100644
--- a/doc/update/7.6-to-7.7.md
+++ b/doc/update/7.6-to-7.7.md
@@ -82,7 +82,7 @@ git diff origin/7-6-stable:config/gitlab.yml.example origin/7-7-stable:config/gi
* HTTP setups: Make `/etc/nginx/sites-available/gitlab` the same as [`lib/support/nginx/gitlab`][nginx] but with your settings
* HTTPS setups: Make `/etc/nginx/sites-available/gitlab-ssl` the same as [`lib/support/nginx/gitlab-ssl`][nginx-ssl] but with your setting
-#### Setup time zone (optional)
+#### Set up time zone (optional)
Consider setting the time zone in `gitlab.yml` otherwise GitLab will default to UTC. If you set a time zone previously in [`application.rb`][app] (unlikely), unset it.
diff --git a/doc/update/7.7-to-7.8.md b/doc/update/7.7-to-7.8.md
index 7cee5f79a13..f5b1ebf0a9c 100644
--- a/doc/update/7.7-to-7.8.md
+++ b/doc/update/7.7-to-7.8.md
@@ -83,7 +83,7 @@ git diff origin/7-7-stable:config/gitlab.yml.example origin/7-8-stable:config/gi
* HTTPS setups: Make `/etc/nginx/sites-available/gitlab-ssl` the same as [`lib/support/nginx/gitlab-ssl`][nginx-ssl] but with your settings.
* A new `location /uploads/` section has been added that needs to have the same content as the existing `location @gitlab` section.
-#### Setup time zone (optional)
+#### Set up time zone (optional)
Consider setting the time zone in `gitlab.yml` otherwise GitLab will default to UTC. If you set a time zone previously in [`application.rb`][app] (unlikely), unset it.
diff --git a/doc/update/7.8-to-7.9.md b/doc/update/7.8-to-7.9.md
index 5a8b689dbc1..0db7698936b 100644
--- a/doc/update/7.8-to-7.9.md
+++ b/doc/update/7.8-to-7.9.md
@@ -85,7 +85,7 @@ git diff origin/7-8-stable:config/gitlab.yml.example origin/7-9-stable:config/gi
* HTTPS setups: Make `/etc/nginx/sites-available/gitlab-ssl` the same as [`lib/support/nginx/gitlab-ssl`][nginx-ssl] but with your settings.
* A new `location /uploads/` section has been added that needs to have the same content as the existing `location @gitlab` section.
-#### Setup time zone (optional)
+#### Set up time zone (optional)
Consider setting the time zone in `gitlab.yml` otherwise GitLab will default to UTC. If you set a time zone previously in [`application.rb`][app] (unlikely), unset it.
diff --git a/doc/update/7.9-to-7.10.md b/doc/update/7.9-to-7.10.md
index 99df51dbb99..782fb0736e6 100644
--- a/doc/update/7.9-to-7.10.md
+++ b/doc/update/7.9-to-7.10.md
@@ -81,7 +81,7 @@ git diff origin/7-9-stable:config/gitlab.yml.example origin/7-10-stable:config/g
* HTTPS setups: Make `/etc/nginx/sites-available/gitlab-ssl` the same as [`lib/support/nginx/gitlab-ssl`][nginx-ssl] but with your settings.
* A new `location /uploads/` section has been added that needs to have the same content as the existing `location @gitlab` section.
-#### Setup time zone (optional)
+#### Set up time zone (optional)
Consider setting the time zone in `gitlab.yml` otherwise GitLab will default to UTC. If you set a time zone previously in [`application.rb`][app] (unlikely), unset it.
diff --git a/doc/update/9.4-to-9.5.md b/doc/update/9.4-to-9.5.md
index 1bfc1167c36..6a655f77a55 100644
--- a/doc/update/9.4-to-9.5.md
+++ b/doc/update/9.4-to-9.5.md
@@ -154,7 +154,7 @@ sudo -u git -H make
#### New Gitaly configuration options required
-In order to function Gitaly needs some additional configuration information. Below we assume you installed Gitaly in `/home/git/gitaly` and GitLab Shell in `/home/git/gitlab-shell'.
+In order to function Gitaly needs some additional configuration information. Below we assume you installed Gitaly in `/home/git/gitaly` and GitLab Shell in `/home/git/gitlab-shell`.
```shell
echo '
diff --git a/doc/update/9.5-to-10.0.md b/doc/update/9.5-to-10.0.md
index 8d1cf0f737b..7790d192a82 100644
--- a/doc/update/9.5-to-10.0.md
+++ b/doc/update/9.5-to-10.0.md
@@ -154,7 +154,7 @@ sudo -u git -H make
#### New Gitaly configuration options required
-In order to function Gitaly needs some additional configuration information. Below we assume you installed Gitaly in `/home/git/gitaly` and GitLab Shell in `/home/git/gitlab-shell'.
+In order to function Gitaly needs some additional configuration information. Below we assume you installed Gitaly in `/home/git/gitaly` and GitLab Shell in `/home/git/gitlab-shell`.
```shell
echo '
diff --git a/doc/user/profile/account/delete_account.md b/doc/user/profile/account/delete_account.md
index 910bd20f882..49f0ce2cd79 100644
--- a/doc/user/profile/account/delete_account.md
+++ b/doc/user/profile/account/delete_account.md
@@ -1,5 +1,8 @@
# Deleting a User Account
+NOTE: **Note:**
+Deleting a user will delete all projects in that user namespace.
+
- As a user, you can delete your own account by navigating to **Settings** > **Account** and selecting **Delete account**
- As an admin, you can delete a user account by navigating to the **Admin Area**, selecting the **Users** tab, selecting a user, and clicking on **Delete user**
diff --git a/doc/user/profile/account/two_factor_authentication.md b/doc/user/profile/account/two_factor_authentication.md
index 8838efb18fe..e5411662511 100644
--- a/doc/user/profile/account/two_factor_authentication.md
+++ b/doc/user/profile/account/two_factor_authentication.md
@@ -69,7 +69,7 @@ of recovery codes.
1. Go to **Account**.
1. Click **Enable Two-Factor Authentication**.
1. Plug in your U2F device.
-1. Click on **Setup New U2F Device**.
+1. Click on **Set up New U2F Device**.
1. A light will start blinking on your device. Activate it by pressing its button.
You will see a message indicating that your device was successfully set up.
diff --git a/doc/user/project/container_registry.md b/doc/user/project/container_registry.md
index df850d4f68d..82cafcf432a 100644
--- a/doc/user/project/container_registry.md
+++ b/doc/user/project/container_registry.md
@@ -245,7 +245,7 @@ This will run mitmproxy on port `9000`. In another window, run:
curl --proxy http://localhost:9000 https://httpbin.org/status/200
```
-If everything is setup correctly, you will see information on the mitmproxy window and
+If everything is set up correctly, you will see information on the mitmproxy window and
no errors from the curl commands.
#### Running the Docker daemon with a proxy
diff --git a/doc/user/project/cycle_analytics.md b/doc/user/project/cycle_analytics.md
index 7e788ae6220..ea843054f8e 100644
--- a/doc/user/project/cycle_analytics.md
+++ b/doc/user/project/cycle_analytics.md
@@ -154,7 +154,7 @@ You can [read more about permissions][permissions] in general.
Learn more about Cycle Analytics in the following resources:
-- [Cycle Analytics feature page](https://about.gitlab.com/solutions/cycle-analytics/)
+- [Cycle Analytics feature page](https://about.gitlab.com/features/cycle-analytics/)
- [Cycle Analytics feature preview](https://about.gitlab.com/2016/09/16/feature-preview-introducing-cycle-analytics/)
- [Cycle Analytics feature highlight](https://about.gitlab.com/2016/09/21/cycle-analytics-feature-highlight/)
diff --git a/doc/user/project/integrations/hangouts_chat.md b/doc/user/project/integrations/hangouts_chat.md
index 47525617d95..20a71da927c 100644
--- a/doc/user/project/integrations/hangouts_chat.md
+++ b/doc/user/project/integrations/hangouts_chat.md
@@ -15,7 +15,7 @@ See also [the Hangouts Chat documentation for configuring incoming webhooks](htt
## On GitLab
-When you have the **Webhook URL** for your Hangouts Chat room webhook, you can setup the GitLab service.
+When you have the **Webhook URL** for your Hangouts Chat room webhook, you can set up the GitLab service.
1. Navigate to the [Integrations page](project_services.md#accessing-the-project-services) in your project's settings, i.e. **Project > Settings > Integrations**.
1. Select the **Hangouts Chat** project service to configure it.
diff --git a/doc/user/project/integrations/img/webhooks_ssl.png b/doc/user/project/integrations/img/webhooks_ssl.png
index f023e9665f2..e5777a2e99b 100644
--- a/doc/user/project/integrations/img/webhooks_ssl.png
+++ b/doc/user/project/integrations/img/webhooks_ssl.png
Binary files differ
diff --git a/doc/user/project/integrations/jira.md b/doc/user/project/integrations/jira.md
index b3821cf8391..ba8b79b911b 100644
--- a/doc/user/project/integrations/jira.md
+++ b/doc/user/project/integrations/jira.md
@@ -49,7 +49,7 @@ We have split this stage in steps so it is easier to follow.
1. The next step is to create a new user (e.g., `gitlab`) who has write access
to projects in JIRA. Enter the user's name and a _valid_ e-mail address
- since JIRA sends a verification e-mail to set-up the password.
+ since JIRA sends a verification e-mail to set up the password.
_**Note:** JIRA creates the username automatically by using the e-mail
prefix. You can change it later if you want._
diff --git a/doc/user/project/integrations/mattermost.md b/doc/user/project/integrations/mattermost.md
index 3e77823a6aa..89de1fe4dcb 100644
--- a/doc/user/project/integrations/mattermost.md
+++ b/doc/user/project/integrations/mattermost.md
@@ -38,7 +38,7 @@ At the end, fill in your Mattermost details:
| Field | Description |
| ----- | ----------- |
-| **Webhook** | The incoming webhook URL which you have to setup on Mattermost, it will be something like: http://mattermost.example/hooks/5xo… |
+| **Webhook** | The incoming webhook URL which you have to set up on Mattermost, it will be something like: http://mattermost.example/hooks/5xo… |
| **Username** | Optional username which can be on messages sent to Mattermost. Fill this in if you want to change the username of the bot. |
| **Notify only broken pipelines** | If you choose to enable the **Pipeline** event and you want to be only notified about failed pipelines. |
diff --git a/doc/user/project/integrations/mattermost_slash_commands.md b/doc/user/project/integrations/mattermost_slash_commands.md
index 488f61c77a3..e031dcad2c3 100644
--- a/doc/user/project/integrations/mattermost_slash_commands.md
+++ b/doc/user/project/integrations/mattermost_slash_commands.md
@@ -102,7 +102,7 @@ in a new slash command.
![Mattermost add command configuration](img/mattermost_slash_command_configuration.png)
-1. After you setup all the values, copy the token (we will use it below) and
+1. After you set up all the values, copy the token (we will use it below) and
click **Done**.
![Mattermost slash command token](img/mattermost_slash_command_token.png)
diff --git a/doc/user/project/integrations/microsoft_teams.md b/doc/user/project/integrations/microsoft_teams.md
index 140c6738a49..ca32689910c 100644
--- a/doc/user/project/integrations/microsoft_teams.md
+++ b/doc/user/project/integrations/microsoft_teams.md
@@ -25,7 +25,7 @@ At the end fill in your Microsoft Teams details:
| Field | Description |
| ----- | ----------- |
-| **Webhook** | The incoming webhook URL which you have to setup on Microsoft Teams. |
+| **Webhook** | The incoming webhook URL which you have to set up on Microsoft Teams. |
| **Notify only broken pipelines** | If you choose to enable the **Pipeline** event and you want to be only notified about failed pipelines. |
After you are all done, click **Save changes** for the changes to take effect.
diff --git a/doc/user/project/integrations/mock_ci.md b/doc/user/project/integrations/mock_ci.md
index 6aefe5dbded..8b1908c46fe 100644
--- a/doc/user/project/integrations/mock_ci.md
+++ b/doc/user/project/integrations/mock_ci.md
@@ -2,7 +2,7 @@
**NB: This service is only listed if you are in a development environment!**
-To setup the mock CI service server, respond to the following endpoints
+To set up the mock CI service server, respond to the following endpoints
- `commit_status`: `#{project.namespace.path}/#{project.path}/status/#{sha}.json`
- Have your service return `200 { status: ['failed'|'canceled'|'running'|'pending'|'success'|'success_with_warnings'|'skipped'|'not_found'] }`
diff --git a/doc/user/project/integrations/prometheus.md b/doc/user/project/integrations/prometheus.md
index f687027e8c8..0b61a41aab0 100644
--- a/doc/user/project/integrations/prometheus.md
+++ b/doc/user/project/integrations/prometheus.md
@@ -8,7 +8,7 @@ within the GitLab interface.
![Environment Dashboard](img/prometheus_dashboard.png)
-There are two ways to setup Prometheus integration, depending on where your apps are running:
+There are two ways to set up Prometheus integration, depending on where your apps are running:
* For deployments on Kubernetes, GitLab can automatically [deploy and manage Prometheus](#managed-prometheus-on-kubernetes)
* For other deployment targets, simply [specify the Prometheus server](#manual-configuration-of-prometheus).
diff --git a/doc/user/project/integrations/webhooks.md b/doc/user/project/integrations/webhooks.md
index 6104eadde35..e22f8e976be 100644
--- a/doc/user/project/integrations/webhooks.md
+++ b/doc/user/project/integrations/webhooks.md
@@ -57,6 +57,14 @@ You can turn this off in the webhook settings in your GitLab projects.
![SSL Verification](img/webhooks_ssl.png)
+## Branch filtering
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-ce/issues/20338) in GitLab 11.3.
+
+Push events can be filtered by branch using a branch name or wildcard pattern
+to limit which push events are sent to your webhook endpoint. By default the
+field is blank causing all push events to be sent to your webhook endpoint.
+
## Events
Below are described the supported events.
diff --git a/doc/user/project/issues/issues_functionalities.md b/doc/user/project/issues/issues_functionalities.md
index 46f25417fde..631f511b5fa 100644
--- a/doc/user/project/issues/issues_functionalities.md
+++ b/doc/user/project/issues/issues_functionalities.md
@@ -69,7 +69,7 @@ Learn more on the [Time Tracking documentation](../../../workflow/time_tracking.
#### 6. Due date
When you work on a tight schedule, and it's important to
-have a way to setup a deadline for implementations and for solving
+have a way to set up a deadline for implementations and for solving
problems. This can be facilitated by the [due date](due_dates.md)). Due dates
can be changed as many times as needed.
diff --git a/doc/user/project/wiki/index.md b/doc/user/project/wiki/index.md
index ad0ef60373c..127a30d6669 100644
--- a/doc/user/project/wiki/index.md
+++ b/doc/user/project/wiki/index.md
@@ -40,11 +40,6 @@ support Markdown, RDoc and AsciiDoc. For Markdown based pages, all the
[Markdown features](../../markdown.md) are supported and for links there is
some [wiki specific](../../markdown.md#wiki-specific-markdown) behavior.
->**Note:**
-The wiki is based on a Git repository and contains only text files. Uploading
-files via the web interface will upload them in GitLab itself, and they will
-not be available if you clone the wiki repo locally.
-
In the web interface the commit message is optional, but the GitLab Wiki is
based on Git and needs a commit message, so one will be created for you if you
do not enter one.
@@ -53,6 +48,14 @@ When you're ready, click the **Create page** and the new page will be created.
![New page](img/wiki_create_new_page.png)
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-ce/issues/33475) in GitLab 11.3.
+
+Starting with GitLab 11.3, any file that is uploaded to the wiki via GitLab's
+interface will be stored in the wiki Git repository, and it will be available
+if you clone the wiki repository locally. All uploaded files prior to GitLab
+11.3 are stored in GitLab itself. If you want them to be part of the wiki's Git
+repository, you will have to upload them again.
+
## Editing a wiki page
To edit a page, simply click on the **Edit** button. From there on, you can
diff --git a/doc/workflow/lfs/lfs_administration.md b/doc/workflow/lfs/lfs_administration.md
index 3f9ffedd61a..ec5943fd51b 100644
--- a/doc/workflow/lfs/lfs_administration.md
+++ b/doc/workflow/lfs/lfs_administration.md
@@ -54,7 +54,7 @@ to offload local hard disk R/W operations, and free up disk space significantly.
GitLab is tightly integrated with `Fog`, so you can refer to its [documentation](http://fog.io/about/provider_documentation.html)
to check which storage services can be integrated with GitLab.
You can also use external object storage in a private local network. For example,
-[Minio](https://www.minio.io/) is a standalone object storage service, is easy to setup, and works well with GitLab instances.
+[Minio](https://www.minio.io/) is a standalone object storage service, is easy to set up, and works well with GitLab instances.
GitLab provides two different options for the uploading mechanism: "Direct upload" and "Background upload".
@@ -95,6 +95,7 @@ Here is a configuration example with S3.
| `host` | S3 compatible host for when not using AWS, e.g. `localhost` or `storage.example.com` | s3.amazonaws.com |
| `endpoint` | Can be used when configuring an S3 compatible service such as [Minio](https://www.minio.io), by entering a URL such as `http://127.0.0.1:9000` | (optional) |
| `path_style` | Set to true to use `host/bucket_name/object` style paths instead of `bucket_name.host/object`. Leave as false for AWS S3 | false |
+| `use_iam_profile` | Set to true to use IAM profile instead of access keys | false
Here is a configuration example with GCS.
diff --git a/lib/api/protected_branches.rb b/lib/api/protected_branches.rb
index e569fad8663..804f6fa9b73 100644
--- a/lib/api/protected_branches.rb
+++ b/lib/api/protected_branches.rb
@@ -44,10 +44,10 @@ module API
params do
requires :name, type: String, desc: 'The name of the protected branch'
optional :push_access_level, type: Integer,
- values: ProtectedRefAccess::ALLOWED_ACCESS_LEVELS,
+ values: ProtectedBranch::PushAccessLevel.allowed_access_levels,
desc: 'Access levels allowed to push (defaults: `40`, maintainer access level)'
optional :merge_access_level, type: Integer,
- values: ProtectedRefAccess::ALLOWED_ACCESS_LEVELS,
+ values: ProtectedBranch::MergeAccessLevel.allowed_access_levels,
desc: 'Access levels allowed to merge (defaults: `40`, maintainer access level)'
end
# rubocop: disable CodeReuse/ActiveRecord
diff --git a/lib/api/protected_tags.rb b/lib/api/protected_tags.rb
index 219d51a2bc5..e406344e42d 100644
--- a/lib/api/protected_tags.rb
+++ b/lib/api/protected_tags.rb
@@ -47,7 +47,7 @@ module API
params do
requires :name, type: String, desc: 'The name of the protected tag'
optional :create_access_level, type: Integer, default: Gitlab::Access::MAINTAINER,
- values: ProtectedRefAccess::ALLOWED_ACCESS_LEVELS,
+ values: ProtectedTag::CreateAccessLevel.allowed_access_levels,
desc: 'Access levels allowed to create (defaults: `40`, maintainer access level)'
end
post ':id/protected_tags' do
diff --git a/lib/extracts_path.rb b/lib/extracts_path.rb
index e8dbde176ef..e02d403f7b1 100644
--- a/lib/extracts_path.rb
+++ b/lib/extracts_path.rb
@@ -54,7 +54,7 @@ module ExtractsPath
valid_refs = ref_names.select { |v| id.start_with?("#{v}/") }
- if valid_refs.length == 0
+ if valid_refs.empty?
# No exact ref match, so just try our best
pair = id.match(%r{([^/]+)(.*)}).captures
else
diff --git a/lib/gitlab/auth/ldap/access.rb b/lib/gitlab/auth/ldap/access.rb
index eeab7791643..f323d2e0f7a 100644
--- a/lib/gitlab/auth/ldap/access.rb
+++ b/lib/gitlab/auth/ldap/access.rb
@@ -92,12 +92,12 @@ module Gitlab
if provider
Gitlab::AppLogger.info(
"LDAP account \"#{ldap_identity.extern_uid}\" #{reason}, " \
- "blocking Gitlab user \"#{user.name}\" (#{user.email})"
+ "blocking GitLab user \"#{user.name}\" (#{user.email})"
)
else
Gitlab::AppLogger.info(
"Account is not provided by LDAP, " \
- "blocking Gitlab user \"#{user.name}\" (#{user.email})"
+ "blocking GitLab user \"#{user.name}\" (#{user.email})"
)
end
end
@@ -107,7 +107,7 @@ module Gitlab
Gitlab::AppLogger.info(
"LDAP account \"#{ldap_identity.extern_uid}\" #{reason}, " \
- "unblocking Gitlab user \"#{user.name}\" (#{user.email})"
+ "unblocking GitLab user \"#{user.name}\" (#{user.email})"
)
end
end
diff --git a/lib/gitlab/contributions_calendar.rb b/lib/gitlab/contributions_calendar.rb
index 3236abfa43f..1ffc2639237 100644
--- a/lib/gitlab/contributions_calendar.rb
+++ b/lib/gitlab/contributions_calendar.rb
@@ -30,8 +30,9 @@ module Gitlab
note_events = event_counts(date_from, :merge_requests)
.having(action: [Event::COMMENTED])
- union = Gitlab::SQL::Union.new([repo_events, issue_events, mr_events, note_events])
- events = Event.find_by_sql(union.to_sql).map(&:attributes)
+ events = Event
+ .from_union([repo_events, issue_events, mr_events, note_events])
+ .map(&:attributes)
@activity_dates = events.each_with_object(Hash.new {|h, k| h[k] = 0 }) do |event, activities|
activities[event["date"]] += event["total_amount"]
diff --git a/lib/gitlab/database.rb b/lib/gitlab/database.rb
index 8eacad078c8..42f9605f5ac 100644
--- a/lib/gitlab/database.rb
+++ b/lib/gitlab/database.rb
@@ -249,5 +249,21 @@ module Gitlab
end
private_class_method :database_version
+
+ def self.add_post_migrate_path_to_rails(force: false)
+ return if ENV['SKIP_POST_DEPLOYMENT_MIGRATIONS'] && !force
+
+ Rails.application.config.paths['db'].each do |db_path|
+ path = Rails.root.join(db_path, 'post_migrate').to_s
+
+ unless Rails.application.config.paths['db/migrate'].include? path
+ Rails.application.config.paths['db/migrate'] << path
+
+ # Rails memoizes migrations at certain points where it won't read the above
+ # path just yet. As such we must also update the following list of paths.
+ ActiveRecord::Migrator.migrations_paths << path
+ end
+ end
+ end
end
end
diff --git a/lib/gitlab/database/grant.rb b/lib/gitlab/database/grant.rb
index d32837f5793..7d334a79009 100644
--- a/lib/gitlab/database/grant.rb
+++ b/lib/gitlab/database/grant.rb
@@ -2,6 +2,8 @@ module Gitlab
module Database
# Model that can be used for querying permissions of a SQL user.
class Grant < ActiveRecord::Base
+ include FromUnion
+
self.table_name =
if Database.postgresql?
'information_schema.role_table_grants'
@@ -42,9 +44,7 @@ module Gitlab
.where("GRANTEE = CONCAT('\\'', REPLACE(CURRENT_USER(), '@', '\\'@\\''), '\\'')")
]
- union = SQL::Union.new(queries).to_sql
-
- Grant.from("(#{union}) privs").any?
+ Grant.from_union(queries, alias_as: 'privs').any?
end
end
end
diff --git a/lib/gitlab/database/subquery.rb b/lib/gitlab/database/subquery.rb
new file mode 100644
index 00000000000..2a6f39c6a27
--- /dev/null
+++ b/lib/gitlab/database/subquery.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Database
+ module Subquery
+ class << self
+ def self_join(relation)
+ t = relation.arel_table
+ t2 = relation.arel.as('t2')
+
+ relation.unscoped.joins(t.join(t2).on(t[:id].eq(t2[:id])).join_sources.first)
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/diff/file.rb b/lib/gitlab/diff/file.rb
index d2ca7a070fa..fb117baca9e 100644
--- a/lib/gitlab/diff/file.rb
+++ b/lib/gitlab/diff/file.rb
@@ -20,8 +20,9 @@ module Gitlab
DiffViewer::Image
].sort_by { |v| v.binary? ? 0 : 1 }.freeze
- def initialize(diff, repository:, diff_refs: nil, fallback_diff_refs: nil)
+ def initialize(diff, repository:, diff_refs: nil, fallback_diff_refs: nil, stats: nil)
@diff = diff
+ @stats = stats
@repository = repository
@diff_refs = diff_refs
@fallback_diff_refs = fallback_diff_refs
@@ -165,11 +166,11 @@ module Gitlab
end
def added_lines
- diff_lines.count(&:added?)
+ @stats&.additions || diff_lines.count(&:added?)
end
def removed_lines
- diff_lines.count(&:removed?)
+ @stats&.deletions || diff_lines.count(&:removed?)
end
def file_identifier
diff --git a/lib/gitlab/diff/file_collection/base.rb b/lib/gitlab/diff/file_collection/base.rb
index 2acb0e43b69..b79ff771a2b 100644
--- a/lib/gitlab/diff/file_collection/base.rb
+++ b/lib/gitlab/diff/file_collection/base.rb
@@ -2,23 +2,27 @@ module Gitlab
module Diff
module FileCollection
class Base
+ include Gitlab::Utils::StrongMemoize
+
attr_reader :project, :diff_options, :diff_refs, :fallback_diff_refs, :diffable
delegate :count, :size, :real_size, to: :diff_files
def self.default_options
- ::Commit.max_diff_options.merge(ignore_whitespace_change: false, expanded: false)
+ ::Commit.max_diff_options.merge(ignore_whitespace_change: false, expanded: false, include_stats: true)
end
def initialize(diffable, project:, diff_options: nil, diff_refs: nil, fallback_diff_refs: nil)
diff_options = self.class.default_options.merge(diff_options || {})
@diffable = diffable
+ @include_stats = diff_options.delete(:include_stats)
@diffs = diffable.raw_diffs(diff_options)
@project = project
@diff_options = diff_options
@diff_refs = diff_refs
@fallback_diff_refs = fallback_diff_refs
+ @repository = project.repository
end
def diff_files
@@ -43,10 +47,27 @@ module Gitlab
private
+ def diff_stats_collection
+ strong_memoize(:diff_stats) do
+ # There are scenarios where we don't need to request Diff Stats,
+ # when caching for instance.
+ next unless @include_stats
+ next unless diff_refs
+
+ @repository.diff_stats(diff_refs.base_sha, diff_refs.head_sha)
+ end
+ end
+
def decorate_diff!(diff)
return diff if diff.is_a?(File)
- Gitlab::Diff::File.new(diff, repository: project.repository, diff_refs: diff_refs, fallback_diff_refs: fallback_diff_refs)
+ stats = diff_stats_collection&.find_by_path(diff.new_path)
+
+ Gitlab::Diff::File.new(diff,
+ repository: project.repository,
+ diff_refs: diff_refs,
+ fallback_diff_refs: fallback_diff_refs,
+ stats: stats)
end
end
end
diff --git a/lib/gitlab/diff/position.rb b/lib/gitlab/diff/position.rb
index 978962ab2eb..4b6016e00bc 100644
--- a/lib/gitlab/diff/position.rb
+++ b/lib/gitlab/diff/position.rb
@@ -116,6 +116,10 @@ module Gitlab
end
end
+ def diff_options
+ { paths: paths, expanded: true, include_stats: false }
+ end
+
def diff_line(repository)
@diff_line ||= diff_file(repository)&.line_for_position(self)
end
@@ -130,7 +134,7 @@ module Gitlab
return unless diff_refs.complete?
return unless comparison = diff_refs.compare_in(repository.project)
- comparison.diffs(paths: paths, expanded: true).diff_files.first
+ comparison.diffs(diff_options).diff_files.first
end
def get_formatter_class(type)
diff --git a/lib/gitlab/git/diff_stats_collection.rb b/lib/gitlab/git/diff_stats_collection.rb
new file mode 100644
index 00000000000..d4033f56387
--- /dev/null
+++ b/lib/gitlab/git/diff_stats_collection.rb
@@ -0,0 +1,30 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Git
+ class DiffStatsCollection
+ include Gitlab::Utils::StrongMemoize
+ include Enumerable
+
+ def initialize(diff_stats)
+ @collection = diff_stats
+ end
+
+ def each(&block)
+ @collection.each(&block)
+ end
+
+ def find_by_path(path)
+ indexed_by_path[path]
+ end
+
+ private
+
+ def indexed_by_path
+ strong_memoize(:indexed_by_path) do
+ index_by { |stats| stats.path }
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/git/repository.rb b/lib/gitlab/git/repository.rb
index 1b8d320ff3b..3d5a63bdbac 100644
--- a/lib/gitlab/git/repository.rb
+++ b/lib/gitlab/git/repository.rb
@@ -438,6 +438,16 @@ module Gitlab
Gitlab::Git::DiffCollection.new(iterator, options)
end
+ def diff_stats(left_id, right_id)
+ stats = wrapped_gitaly_errors do
+ gitaly_commit_client.diff_stats(left_id, right_id)
+ end
+
+ Gitlab::Git::DiffStatsCollection.new(stats)
+ rescue CommandError, TypeError
+ Gitlab::Git::DiffStatsCollection.new([])
+ end
+
# Returns a RefName for a given SHA
def ref_name_for_sha(ref_path, sha)
raise ArgumentError, "sha can't be empty" unless sha.present?
@@ -581,10 +591,6 @@ module Gitlab
end
end
- def user_to_committer(user)
- Gitlab::Git.committer_hash(email: user.email, name: user.name)
- end
-
# Delete the specified branch from the repository
def delete_branch(branch_name)
wrapped_gitaly_errors do
diff --git a/lib/gitlab/gitaly_client.rb b/lib/gitlab/gitaly_client.rb
index 12307338972..302341d9541 100644
--- a/lib/gitlab/gitaly_client.rb
+++ b/lib/gitlab/gitaly_client.rb
@@ -174,10 +174,29 @@ module Gitlab
end
private_class_method :current_transaction_labels
+ # For some time related tasks we can't rely on `Time.now` since it will be
+ # affected by Timecop in some tests, and the clock of some gitaly-related
+ # components (grpc's c-core and gitaly server) use system time instead of
+ # timecop's time, so tests will fail.
+ # `Time.at(Process.clock_gettime(Process::CLOCK_REALTIME))` will circumvent
+ # timecop.
+ def self.real_time
+ Time.at(Process.clock_gettime(Process::CLOCK_REALTIME))
+ end
+ private_class_method :real_time
+
+ def self.authorization_token(storage)
+ token = token(storage).to_s
+ issued_at = real_time.to_i.to_s
+ hmac = OpenSSL::HMAC.hexdigest(OpenSSL::Digest::SHA256.new, token, issued_at)
+
+ "v2.#{hmac}.#{issued_at}"
+ end
+ private_class_method :authorization_token
+
def self.request_kwargs(storage, timeout, remote_storage: nil)
- encoded_token = Base64.strict_encode64(token(storage).to_s)
metadata = {
- 'authorization' => "Bearer #{encoded_token}",
+ 'authorization' => "Bearer #{authorization_token(storage)}",
'client_name' => CLIENT_NAME
}
@@ -195,12 +214,7 @@ module Gitlab
return result unless timeout > 0
- # Do not use `Time.now` for deadline calculation, since it
- # will be affected by Timecop in some tests, but grpc's c-core
- # uses system time instead of timecop's time, so tests will fail
- # `Time.at(Process.clock_gettime(Process::CLOCK_REALTIME))` will
- # circumvent timecop
- deadline = Time.at(Process.clock_gettime(Process::CLOCK_REALTIME)) + timeout
+ deadline = real_time + timeout
result[:deadline] = deadline
result
diff --git a/lib/gitlab/gitaly_client/commit_service.rb b/lib/gitlab/gitaly_client/commit_service.rb
index f65d7383dc7..6c95abdcb4b 100644
--- a/lib/gitlab/gitaly_client/commit_service.rb
+++ b/lib/gitlab/gitaly_client/commit_service.rb
@@ -172,6 +172,17 @@ module Gitlab
consume_commits_response(response)
end
+ def diff_stats(left_commit_sha, right_commit_sha)
+ request = Gitaly::DiffStatsRequest.new(
+ repository: @gitaly_repo,
+ left_commit_id: left_commit_sha,
+ right_commit_id: right_commit_sha
+ )
+
+ response = GitalyClient.call(@repository.storage, :diff_service, :diff_stats, request, timeout: GitalyClient.medium_timeout)
+ response.flat_map(&:stats)
+ end
+
def find_all_commits(opts = {})
request = Gitaly::FindAllCommitsRequest.new(
repository: @gitaly_repo,
diff --git a/lib/gitlab/gitaly_client/storage_settings.rb b/lib/gitlab/gitaly_client/storage_settings.rb
index 8e530de174d..26d1f53f26c 100644
--- a/lib/gitlab/gitaly_client/storage_settings.rb
+++ b/lib/gitlab/gitaly_client/storage_settings.rb
@@ -13,7 +13,7 @@ module Gitlab
Storage is invalid because it has no `path` key.
For source installations, update your config/gitlab.yml Refer to gitlab.yml.example for an updated example.
- If you're using the Gitlab Development Kit, you can update your configuration running `gdk reconfigure`.
+ If you're using the GitLab Development Kit, you can update your configuration running `gdk reconfigure`.
MSG
# This class will give easily recognizable NoMethodErrors
diff --git a/lib/gitlab/group_hierarchy.rb b/lib/gitlab/group_hierarchy.rb
index b74e7b10448..8fbfa1a86bf 100644
--- a/lib/gitlab/group_hierarchy.rb
+++ b/lib/gitlab/group_hierarchy.rb
@@ -89,14 +89,14 @@ module Gitlab
ancestors_table = ancestors.alias_to(groups_table)
descendants_table = descendants.alias_to(groups_table)
- union = SQL::Union.new([model.unscoped.from(ancestors_table),
- model.unscoped.from(descendants_table)])
-
relation = model
.unscoped
.with
.recursive(ancestors.to_arel, descendants.to_arel)
- .from("(#{union.to_sql}) #{model.table_name}")
+ .from_union([
+ model.unscoped.from(ancestors_table),
+ model.unscoped.from(descendants_table)
+ ])
read_only(relation)
end
diff --git a/lib/gitlab/project_authorizations/with_nested_groups.rb b/lib/gitlab/project_authorizations/with_nested_groups.rb
index e3da1634fa5..448c3f3a7d8 100644
--- a/lib/gitlab/project_authorizations/with_nested_groups.rb
+++ b/lib/gitlab/project_authorizations/with_nested_groups.rb
@@ -49,13 +49,11 @@ module Gitlab
.where('p_ns.share_with_group_lock IS FALSE')
]
- union = Gitlab::SQL::Union.new(relations)
-
ProjectAuthorization
.unscoped
.with
.recursive(cte.to_arel)
- .select_from_union(union)
+ .select_from_union(relations)
end
private
diff --git a/lib/gitlab/project_authorizations/without_nested_groups.rb b/lib/gitlab/project_authorizations/without_nested_groups.rb
index 7d0c00c7f36..ed2287dcc7e 100644
--- a/lib/gitlab/project_authorizations/without_nested_groups.rb
+++ b/lib/gitlab/project_authorizations/without_nested_groups.rb
@@ -24,11 +24,9 @@ module Gitlab
user.groups.joins(:shared_projects).select_for_project_authorization
]
- union = Gitlab::SQL::Union.new(relations)
-
ProjectAuthorization
.unscoped
- .select_from_union(union)
+ .select_from_union(relations)
end
end
end
diff --git a/lib/gitlab/template/finders/global_template_finder.rb b/lib/gitlab/template/finders/global_template_finder.rb
index 831da45191f..b08d9a99e99 100644
--- a/lib/gitlab/template/finders/global_template_finder.rb
+++ b/lib/gitlab/template/finders/global_template_finder.rb
@@ -1,4 +1,4 @@
-# Searches and reads file present on Gitlab installation directory
+# Searches and reads file present on GitLab installation directory
module Gitlab
module Template
module Finders
diff --git a/lib/gitlab/template/finders/repo_template_finder.rb b/lib/gitlab/template/finders/repo_template_finder.rb
index 29bc2393ff9..9140ace879f 100644
--- a/lib/gitlab/template/finders/repo_template_finder.rb
+++ b/lib/gitlab/template/finders/repo_template_finder.rb
@@ -1,4 +1,4 @@
-# Searches and reads files present on each Gitlab project repository
+# Searches and reads files present on each GitLab project repository
module Gitlab
module Template
module Finders
diff --git a/lib/gitlab/user_extractor.rb b/lib/gitlab/user_extractor.rb
index 09652a4fb5e..bd0d24e4369 100644
--- a/lib/gitlab/user_extractor.rb
+++ b/lib/gitlab/user_extractor.rb
@@ -18,7 +18,7 @@ module Gitlab
def users
return User.none unless @text.present?
- @users ||= User.from("(#{union.to_sql}) users")
+ @users ||= User.from_union(union_relations)
end
# rubocop: enable CodeReuse/ActiveRecord
@@ -43,13 +43,13 @@ module Gitlab
private
- def union
+ def union_relations
relations = []
relations << User.by_any_email(emails) if emails.any?
relations << User.by_username(usernames) if usernames.any?
- Gitlab::SQL::Union.new(relations)
+ relations
end
end
end
diff --git a/lib/support/nginx/gitlab b/lib/support/nginx/gitlab
index 72eb8adcce2..fc984d737d5 100644
--- a/lib/support/nginx/gitlab
+++ b/lib/support/nginx/gitlab
@@ -17,7 +17,7 @@
## See installation.md#using-https for additional HTTPS configuration details.
upstream gitlab-workhorse {
- # Gitlab socket file,
+ # GitLab socket file,
# for Omnibus this would be: unix:/var/opt/gitlab/gitlab-workhorse/socket
server unix:/home/git/gitlab/tmp/sockets/gitlab-workhorse.socket fail_timeout=0;
}
@@ -112,7 +112,7 @@ server {
error_page 502 /502.html;
error_page 503 /503.html;
location ~ ^/(404|422|500|502|503)\.html$ {
- # Location to the Gitlab's public directory,
+ # Location to the GitLab's public directory,
# for Omnibus this would be: /opt/gitlab/embedded/service/gitlab-rails/public.
root /home/git/gitlab/public;
internal;
diff --git a/lib/support/nginx/gitlab-ssl b/lib/support/nginx/gitlab-ssl
index 2e3799d5e1b..ba01e250bbb 100644
--- a/lib/support/nginx/gitlab-ssl
+++ b/lib/support/nginx/gitlab-ssl
@@ -21,7 +21,7 @@
## See installation.md#using-https for additional HTTPS configuration details.
upstream gitlab-workhorse {
- # Gitlab socket file,
+ # GitLab socket file,
# for Omnibus this would be: unix:/var/opt/gitlab/gitlab-workhorse/socket
server unix:/home/git/gitlab/tmp/sockets/gitlab-workhorse.socket fail_timeout=0;
}
@@ -162,7 +162,7 @@ server {
error_page 502 /502.html;
error_page 503 /503.html;
location ~ ^/(404|422|500|502|503)\.html$ {
- # Location to the Gitlab's public directory,
+ # Location to the GitLab's public directory,
# for Omnibus this would be: /opt/gitlab/embedded/service/gitlab-rails/public
root /home/git/gitlab/public;
internal;
diff --git a/lib/tasks/gitlab/db.rake b/lib/tasks/gitlab/db.rake
index 69166851816..74cd70c6e9f 100644
--- a/lib/tasks/gitlab/db.rake
+++ b/lib/tasks/gitlab/db.rake
@@ -51,6 +51,8 @@ namespace :gitlab do
if ActiveRecord::Base.connection.tables.count > 1
Rake::Task['db:migrate'].invoke
else
+ # Add post-migrate paths to ensure we mark all migrations as up
+ Gitlab::Database.add_post_migrate_path_to_rails(force: true)
Rake::Task['db:schema:load'].invoke
Rake::Task['db:seed_fu'].invoke
end
diff --git a/lib/tasks/gitlab/uploads/migrate.rake b/lib/tasks/gitlab/uploads/migrate.rake
index f548a266b99..1c93609a006 100644
--- a/lib/tasks/gitlab/uploads/migrate.rake
+++ b/lib/tasks/gitlab/uploads/migrate.rake
@@ -1,6 +1,30 @@
namespace :gitlab do
namespace :uploads do
- desc 'GitLab | Uploads | Migrate the uploaded files to object storage'
+ namespace :migrate do
+ desc "GitLab | Uploads | Migrate all uploaded files to object storage"
+ task all: :environment do
+ categories = [%w(AvatarUploader Project :avatar),
+ %w(AvatarUploader Group :avatar),
+ %w(AvatarUploader User :avatar),
+ %w(AttachmentUploader Note :attachment),
+ %w(AttachmentUploader Appearance :logo),
+ %w(AttachmentUploader Appearance :header_logo),
+ %w(FaviconUploader Appearance :favicon),
+ %w(FileUploader Project),
+ %w(PersonalFileUploader Snippet),
+ %w(NamespaceFileUploader Snippet),
+ %w(FileUploader MergeRequest)]
+
+ categories.each do |args|
+ Rake::Task["gitlab:uploads:migrate"].invoke(*args)
+ Rake::Task["gitlab:uploads:migrate"].reenable
+ end
+ end
+ end
+
+ # The following is the actual rake task that migrates uploads of specified
+ # category to object storage
+ desc 'GitLab | Uploads | Migrate the uploaded files of specified type to object storage'
task :migrate, [:uploader_class, :model_class, :mounted_as] => :environment do |task, args|
batch_size = ENV.fetch('BATCH', 200).to_i
@to_store = ObjectStorage::Store::REMOTE
diff --git a/locale/ar_SA/gitlab.po b/locale/ar_SA/gitlab.po
index a9a1e87c479..662e69e27c6 100644
--- a/locale/ar_SA/gitlab.po
+++ b/locale/ar_SA/gitlab.po
@@ -444,7 +444,7 @@ msgstr ""
msgid "<strong>Removes</strong> source branch"
msgstr ""
-msgid "A 'Runner' is a process which runs a job. You can setup as many Runners as you need."
+msgid "A 'Runner' is a process which runs a job. You can set up as many Runners as you need."
msgstr ""
msgid "A collection of graphs regarding Continuous Integration"
@@ -891,7 +891,7 @@ msgstr ""
msgid "Ascending"
msgstr ""
-msgid "Ask your group maintainer to setup a group Runner."
+msgid "Ask your group maintainer to set up a group Runner."
msgstr ""
msgid "Assertion consumer service URL"
@@ -6702,10 +6702,10 @@ msgstr ""
msgid "Settings"
msgstr ""
-msgid "Setup a %{type} Runner manually"
+msgid "Set up a %{type} Runner manually"
msgstr ""
-msgid "Setup a specific Runner automatically"
+msgid "Set up a specific Runner automatically"
msgstr ""
msgid "Share"
@@ -8316,7 +8316,7 @@ msgstr ""
msgid "You can resolve the merge conflict using either the Interactive mode, by choosing %{use_ours} or %{use_theirs} buttons, or by editing the files directly. Commit these changes into %{branch_name}"
msgstr ""
-msgid "You can setup jobs to only use Runners with specific tags. Separate tags with commas."
+msgid "You can set up jobs to only use Runners with specific tags. Separate tags with commas."
msgstr ""
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
diff --git a/locale/bg/gitlab.po b/locale/bg/gitlab.po
index 8aae50168be..dc4d2618ab7 100644
--- a/locale/bg/gitlab.po
+++ b/locale/bg/gitlab.po
@@ -308,7 +308,7 @@ msgstr ""
msgid "<strong>Removes</strong> source branch"
msgstr ""
-msgid "A 'Runner' is a process which runs a job. You can setup as many Runners as you need."
+msgid "A 'Runner' is a process which runs a job. You can set up as many Runners as you need."
msgstr ""
msgid "A collection of graphs regarding Continuous Integration"
@@ -755,7 +755,7 @@ msgstr ""
msgid "Ascending"
msgstr ""
-msgid "Ask your group maintainer to setup a group Runner."
+msgid "Ask your group maintainer to set up a group Runner."
msgstr ""
msgid "Assertion consumer service URL"
@@ -6510,10 +6510,10 @@ msgstr "зададете парола"
msgid "Settings"
msgstr ""
-msgid "Setup a %{type} Runner manually"
+msgid "Set up a %{type} Runner manually"
msgstr ""
-msgid "Setup a specific Runner automatically"
+msgid "Set up a specific Runner automatically"
msgstr ""
msgid "Share"
@@ -8108,7 +8108,7 @@ msgstr ""
msgid "You can resolve the merge conflict using either the Interactive mode, by choosing %{use_ours} or %{use_theirs} buttons, or by editing the files directly. Commit these changes into %{branch_name}"
msgstr ""
-msgid "You can setup jobs to only use Runners with specific tags. Separate tags with commas."
+msgid "You can set up jobs to only use Runners with specific tags. Separate tags with commas."
msgstr ""
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
diff --git a/locale/ca_ES/gitlab.po b/locale/ca_ES/gitlab.po
index 2bdf9db1fb5..6bfe59669b5 100644
--- a/locale/ca_ES/gitlab.po
+++ b/locale/ca_ES/gitlab.po
@@ -308,7 +308,7 @@ msgstr ""
msgid "<strong>Removes</strong> source branch"
msgstr ""
-msgid "A 'Runner' is a process which runs a job. You can setup as many Runners as you need."
+msgid "A 'Runner' is a process which runs a job. You can set up as many Runners as you need."
msgstr ""
msgid "A collection of graphs regarding Continuous Integration"
@@ -755,7 +755,7 @@ msgstr ""
msgid "Ascending"
msgstr ""
-msgid "Ask your group maintainer to setup a group Runner."
+msgid "Ask your group maintainer to set up a group Runner."
msgstr ""
msgid "Assertion consumer service URL"
@@ -6510,10 +6510,10 @@ msgstr ""
msgid "Settings"
msgstr ""
-msgid "Setup a %{type} Runner manually"
+msgid "Set up a %{type} Runner manually"
msgstr ""
-msgid "Setup a specific Runner automatically"
+msgid "Set up a specific Runner automatically"
msgstr ""
msgid "Share"
@@ -8108,7 +8108,7 @@ msgstr ""
msgid "You can resolve the merge conflict using either the Interactive mode, by choosing %{use_ours} or %{use_theirs} buttons, or by editing the files directly. Commit these changes into %{branch_name}"
msgstr ""
-msgid "You can setup jobs to only use Runners with specific tags. Separate tags with commas."
+msgid "You can set up jobs to only use Runners with specific tags. Separate tags with commas."
msgstr ""
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
diff --git a/locale/cs_CZ/gitlab.po b/locale/cs_CZ/gitlab.po
index 98eb5b1aba6..0e349d2b12a 100644
--- a/locale/cs_CZ/gitlab.po
+++ b/locale/cs_CZ/gitlab.po
@@ -376,7 +376,7 @@ msgstr ""
msgid "<strong>Removes</strong> source branch"
msgstr ""
-msgid "A 'Runner' is a process which runs a job. You can setup as many Runners as you need."
+msgid "A 'Runner' is a process which runs a job. You can set up as many Runners as you need."
msgstr ""
msgid "A collection of graphs regarding Continuous Integration"
@@ -823,7 +823,7 @@ msgstr "Artefakty"
msgid "Ascending"
msgstr ""
-msgid "Ask your group maintainer to setup a group Runner."
+msgid "Ask your group maintainer to set up a group Runner."
msgstr ""
msgid "Assertion consumer service URL"
@@ -6606,10 +6606,10 @@ msgstr ""
msgid "Settings"
msgstr ""
-msgid "Setup a %{type} Runner manually"
+msgid "Set up a %{type} Runner manually"
msgstr ""
-msgid "Setup a specific Runner automatically"
+msgid "Set up a specific Runner automatically"
msgstr ""
msgid "Share"
@@ -8212,7 +8212,7 @@ msgstr ""
msgid "You can resolve the merge conflict using either the Interactive mode, by choosing %{use_ours} or %{use_theirs} buttons, or by editing the files directly. Commit these changes into %{branch_name}"
msgstr ""
-msgid "You can setup jobs to only use Runners with specific tags. Separate tags with commas."
+msgid "You can set up jobs to only use Runners with specific tags. Separate tags with commas."
msgstr ""
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
diff --git a/locale/da_DK/gitlab.po b/locale/da_DK/gitlab.po
index d1757972cfe..c32bf9eb38d 100644
--- a/locale/da_DK/gitlab.po
+++ b/locale/da_DK/gitlab.po
@@ -308,7 +308,7 @@ msgstr ""
msgid "<strong>Removes</strong> source branch"
msgstr ""
-msgid "A 'Runner' is a process which runs a job. You can setup as many Runners as you need."
+msgid "A 'Runner' is a process which runs a job. You can set up as many Runners as you need."
msgstr ""
msgid "A collection of graphs regarding Continuous Integration"
@@ -755,7 +755,7 @@ msgstr ""
msgid "Ascending"
msgstr ""
-msgid "Ask your group maintainer to setup a group Runner."
+msgid "Ask your group maintainer to set up a group Runner."
msgstr ""
msgid "Assertion consumer service URL"
@@ -6510,10 +6510,10 @@ msgstr ""
msgid "Settings"
msgstr ""
-msgid "Setup a %{type} Runner manually"
+msgid "Set up a %{type} Runner manually"
msgstr ""
-msgid "Setup a specific Runner automatically"
+msgid "Set up a specific Runner automatically"
msgstr ""
msgid "Share"
@@ -8108,7 +8108,7 @@ msgstr ""
msgid "You can resolve the merge conflict using either the Interactive mode, by choosing %{use_ours} or %{use_theirs} buttons, or by editing the files directly. Commit these changes into %{branch_name}"
msgstr ""
-msgid "You can setup jobs to only use Runners with specific tags. Separate tags with commas."
+msgid "You can set up jobs to only use Runners with specific tags. Separate tags with commas."
msgstr ""
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
diff --git a/locale/de/gitlab.po b/locale/de/gitlab.po
index 562251fa483..71e6504e306 100644
--- a/locale/de/gitlab.po
+++ b/locale/de/gitlab.po
@@ -308,7 +308,7 @@ msgstr ""
msgid "<strong>Removes</strong> source branch"
msgstr ""
-msgid "A 'Runner' is a process which runs a job. You can setup as many Runners as you need."
+msgid "A 'Runner' is a process which runs a job. You can set up as many Runners as you need."
msgstr ""
msgid "A collection of graphs regarding Continuous Integration"
@@ -755,7 +755,7 @@ msgstr ""
msgid "Ascending"
msgstr ""
-msgid "Ask your group maintainer to setup a group Runner."
+msgid "Ask your group maintainer to set up a group Runner."
msgstr ""
msgid "Assertion consumer service URL"
@@ -6510,10 +6510,10 @@ msgstr "ein Passwort festlegst"
msgid "Settings"
msgstr "Einstellungen"
-msgid "Setup a %{type} Runner manually"
+msgid "Set up a %{type} Runner manually"
msgstr ""
-msgid "Setup a specific Runner automatically"
+msgid "Set up a specific Runner automatically"
msgstr ""
msgid "Share"
@@ -8108,7 +8108,7 @@ msgstr ""
msgid "You can resolve the merge conflict using either the Interactive mode, by choosing %{use_ours} or %{use_theirs} buttons, or by editing the files directly. Commit these changes into %{branch_name}"
msgstr ""
-msgid "You can setup jobs to only use Runners with specific tags. Separate tags with commas."
+msgid "You can set up jobs to only use Runners with specific tags. Separate tags with commas."
msgstr ""
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
diff --git a/locale/eo/gitlab.po b/locale/eo/gitlab.po
index 8aff5c0a62b..456235b2fa6 100644
--- a/locale/eo/gitlab.po
+++ b/locale/eo/gitlab.po
@@ -308,7 +308,7 @@ msgstr ""
msgid "<strong>Removes</strong> source branch"
msgstr ""
-msgid "A 'Runner' is a process which runs a job. You can setup as many Runners as you need."
+msgid "A 'Runner' is a process which runs a job. You can set up as many Runners as you need."
msgstr ""
msgid "A collection of graphs regarding Continuous Integration"
@@ -755,7 +755,7 @@ msgstr ""
msgid "Ascending"
msgstr ""
-msgid "Ask your group maintainer to setup a group Runner."
+msgid "Ask your group maintainer to set up a group Runner."
msgstr ""
msgid "Assertion consumer service URL"
@@ -6510,10 +6510,10 @@ msgstr "kreos pasvorton"
msgid "Settings"
msgstr ""
-msgid "Setup a %{type} Runner manually"
+msgid "Set up a %{type} Runner manually"
msgstr ""
-msgid "Setup a specific Runner automatically"
+msgid "Set up a specific Runner automatically"
msgstr ""
msgid "Share"
@@ -8108,7 +8108,7 @@ msgstr ""
msgid "You can resolve the merge conflict using either the Interactive mode, by choosing %{use_ours} or %{use_theirs} buttons, or by editing the files directly. Commit these changes into %{branch_name}"
msgstr ""
-msgid "You can setup jobs to only use Runners with specific tags. Separate tags with commas."
+msgid "You can set up jobs to only use Runners with specific tags. Separate tags with commas."
msgstr ""
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
diff --git a/locale/es/gitlab.po b/locale/es/gitlab.po
index ef26024bd48..eba59fdd3d8 100644
--- a/locale/es/gitlab.po
+++ b/locale/es/gitlab.po
@@ -308,7 +308,7 @@ msgstr ""
msgid "<strong>Removes</strong> source branch"
msgstr ""
-msgid "A 'Runner' is a process which runs a job. You can setup as many Runners as you need."
+msgid "A 'Runner' is a process which runs a job. You can set up as many Runners as you need."
msgstr ""
msgid "A collection of graphs regarding Continuous Integration"
@@ -755,7 +755,7 @@ msgstr "Artefactos"
msgid "Ascending"
msgstr ""
-msgid "Ask your group maintainer to setup a group Runner."
+msgid "Ask your group maintainer to set up a group Runner."
msgstr ""
msgid "Assertion consumer service URL"
@@ -6510,10 +6510,10 @@ msgstr "establecer una contraseña"
msgid "Settings"
msgstr "Configuración"
-msgid "Setup a %{type} Runner manually"
+msgid "Set up a %{type} Runner manually"
msgstr ""
-msgid "Setup a specific Runner automatically"
+msgid "Set up a specific Runner automatically"
msgstr ""
msgid "Share"
@@ -8108,7 +8108,7 @@ msgstr ""
msgid "You can resolve the merge conflict using either the Interactive mode, by choosing %{use_ours} or %{use_theirs} buttons, or by editing the files directly. Commit these changes into %{branch_name}"
msgstr ""
-msgid "You can setup jobs to only use Runners with specific tags. Separate tags with commas."
+msgid "You can set up jobs to only use Runners with specific tags. Separate tags with commas."
msgstr ""
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
diff --git a/locale/et_EE/gitlab.po b/locale/et_EE/gitlab.po
index 2fdb8197acd..dbaff32f1b5 100644
--- a/locale/et_EE/gitlab.po
+++ b/locale/et_EE/gitlab.po
@@ -308,7 +308,7 @@ msgstr ""
msgid "<strong>Removes</strong> source branch"
msgstr ""
-msgid "A 'Runner' is a process which runs a job. You can setup as many Runners as you need."
+msgid "A 'Runner' is a process which runs a job. You can set up as many Runners as you need."
msgstr ""
msgid "A collection of graphs regarding Continuous Integration"
@@ -755,7 +755,7 @@ msgstr ""
msgid "Ascending"
msgstr ""
-msgid "Ask your group maintainer to setup a group Runner."
+msgid "Ask your group maintainer to set up a group Runner."
msgstr ""
msgid "Assertion consumer service URL"
@@ -6510,10 +6510,10 @@ msgstr ""
msgid "Settings"
msgstr ""
-msgid "Setup a %{type} Runner manually"
+msgid "Set up a %{type} Runner manually"
msgstr ""
-msgid "Setup a specific Runner automatically"
+msgid "Set up a specific Runner automatically"
msgstr ""
msgid "Share"
@@ -8108,7 +8108,7 @@ msgstr ""
msgid "You can resolve the merge conflict using either the Interactive mode, by choosing %{use_ours} or %{use_theirs} buttons, or by editing the files directly. Commit these changes into %{branch_name}"
msgstr ""
-msgid "You can setup jobs to only use Runners with specific tags. Separate tags with commas."
+msgid "You can set up jobs to only use Runners with specific tags. Separate tags with commas."
msgstr ""
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
diff --git a/locale/fil_PH/gitlab.po b/locale/fil_PH/gitlab.po
index 58254366594..20943d89ea0 100644
--- a/locale/fil_PH/gitlab.po
+++ b/locale/fil_PH/gitlab.po
@@ -308,7 +308,7 @@ msgstr ""
msgid "<strong>Removes</strong> source branch"
msgstr ""
-msgid "A 'Runner' is a process which runs a job. You can setup as many Runners as you need."
+msgid "A 'Runner' is a process which runs a job. You can set up as many Runners as you need."
msgstr ""
msgid "A collection of graphs regarding Continuous Integration"
@@ -755,7 +755,7 @@ msgstr ""
msgid "Ascending"
msgstr ""
-msgid "Ask your group maintainer to setup a group Runner."
+msgid "Ask your group maintainer to set up a group Runner."
msgstr ""
msgid "Assertion consumer service URL"
@@ -6510,10 +6510,10 @@ msgstr ""
msgid "Settings"
msgstr ""
-msgid "Setup a %{type} Runner manually"
+msgid "Set up a %{type} Runner manually"
msgstr ""
-msgid "Setup a specific Runner automatically"
+msgid "Set up a specific Runner automatically"
msgstr ""
msgid "Share"
@@ -8108,7 +8108,7 @@ msgstr ""
msgid "You can resolve the merge conflict using either the Interactive mode, by choosing %{use_ours} or %{use_theirs} buttons, or by editing the files directly. Commit these changes into %{branch_name}"
msgstr ""
-msgid "You can setup jobs to only use Runners with specific tags. Separate tags with commas."
+msgid "You can set up jobs to only use Runners with specific tags. Separate tags with commas."
msgstr ""
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
diff --git a/locale/fr/gitlab.po b/locale/fr/gitlab.po
index 84bc10a9cd2..c0ce98832de 100644
--- a/locale/fr/gitlab.po
+++ b/locale/fr/gitlab.po
@@ -308,7 +308,7 @@ msgstr "<strong>%{pushes}</strong> poussées Git, plus de <strong>%{commits}</s
msgid "<strong>Removes</strong> source branch"
msgstr "<strong>Supprime</strong> la branche source"
-msgid "A 'Runner' is a process which runs a job. You can setup as many Runners as you need."
+msgid "A 'Runner' is a process which runs a job. You can set up as many Runners as you need."
msgstr "Un « exécuteur » est un processus qui exécute une tâche. Vous pouvez configurer autant d’exécuteurs que nécessaire."
msgid "A collection of graphs regarding Continuous Integration"
@@ -755,7 +755,7 @@ msgstr "Artéfacts"
msgid "Ascending"
msgstr "Croissant"
-msgid "Ask your group maintainer to setup a group Runner."
+msgid "Ask your group maintainer to set up a group Runner."
msgstr "Demandez au responsable du groupe de configurer un exécuteur de groupe."
msgid "Assertion consumer service URL"
@@ -6510,10 +6510,10 @@ msgstr "définir un mot de passe"
msgid "Settings"
msgstr "Paramètres"
-msgid "Setup a %{type} Runner manually"
+msgid "Set up a %{type} Runner manually"
msgstr ""
-msgid "Setup a specific Runner automatically"
+msgid "Set up a specific Runner automatically"
msgstr "Configurer automatiquement un exécuteur spécifique"
msgid "Share"
@@ -8108,7 +8108,7 @@ msgstr "Vous ne pouvez modifier des fichiers que dans une branche"
msgid "You can resolve the merge conflict using either the Interactive mode, by choosing %{use_ours} or %{use_theirs} buttons, or by editing the files directly. Commit these changes into %{branch_name}"
msgstr "Vous pouvez résoudre le conflit de fusion Git soit en mode interactif, en cliquant sur les boutons « %{use_ours} » ou « %{use_theirs} », soit en modifiant directement les fichiers. Valider ces modifications dans la branche « %{branch_name} »"
-msgid "You can setup jobs to only use Runners with specific tags. Separate tags with commas."
+msgid "You can set up jobs to only use Runners with specific tags. Separate tags with commas."
msgstr ""
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index db372811db3..d0e8937fdfc 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -250,7 +250,7 @@ msgstr ""
msgid "<strong>Removes</strong> source branch"
msgstr ""
-msgid "A 'Runner' is a process which runs a job. You can setup as many Runners as you need."
+msgid "A 'Runner' is a process which runs a job. You can set up as many Runners as you need."
msgstr ""
msgid "A collection of graphs regarding Continuous Integration"
@@ -355,6 +355,9 @@ msgstr ""
msgid "Add users to group"
msgstr ""
+msgid "Adding new applications is disabled in your GitLab instance. Please contact your GitLab administrator to get the permission"
+msgstr ""
+
msgid "Admin Area"
msgstr ""
@@ -637,7 +640,7 @@ msgstr ""
msgid "Artifacts"
msgstr ""
-msgid "Ask your group maintainer to setup a group Runner."
+msgid "Ask your group maintainer to set up a group Runner."
msgstr ""
msgid "Assign custom color like #FF0000"
@@ -1050,6 +1053,9 @@ msgstr ""
msgid "CI / CD Settings"
msgstr ""
+msgid "CI/CD"
+msgstr ""
+
msgid "CI/CD configuration"
msgstr ""
@@ -1353,6 +1359,9 @@ msgstr ""
msgid "ClusterIntegration|Certificate Authority bundle (PEM format)"
msgstr ""
+msgid "ClusterIntegration|Choose which applications to install on your Kubernetes cluster. Helm Tiller is required to install any of the following applications."
+msgstr ""
+
msgid "ClusterIntegration|Choose which of your environments will use this cluster."
msgstr ""
@@ -1443,9 +1452,6 @@ msgstr ""
msgid "ClusterIntegration|Install"
msgstr ""
-msgid "ClusterIntegration|Install applications on your Kubernetes cluster. Read more about %{helpLink}"
-msgstr ""
-
msgid "ClusterIntegration|Installed"
msgstr ""
@@ -1653,6 +1659,9 @@ msgstr ""
msgid "ClusterIntegration|With a Kubernetes cluster associated to this project, you can use review apps, deploy your applications, run your pipelines, and much more in an easy way."
msgstr ""
+msgid "ClusterIntegration|You must first install Helm Tiller before installing the applications below"
+msgstr ""
+
msgid "ClusterIntegration|Your account must have %{link_to_kubernetes_engine}"
msgstr ""
@@ -1671,9 +1680,6 @@ msgstr ""
msgid "ClusterIntegration|help page"
msgstr ""
-msgid "ClusterIntegration|installing applications"
-msgstr ""
-
msgid "ClusterIntegration|meets the requirements"
msgstr ""
@@ -2841,6 +2847,9 @@ msgstr ""
msgid "Generate a default set of labels"
msgstr ""
+msgid "Geo"
+msgstr ""
+
msgid "Git"
msgstr ""
@@ -3681,9 +3690,6 @@ msgstr ""
msgid "MergeRequests|Toggle comments for this file"
msgstr ""
-msgid "MergeRequests|Updating discussions failed"
-msgstr ""
-
msgid "MergeRequests|View file @ %{commitId}"
msgstr ""
@@ -3708,6 +3714,9 @@ msgstr ""
msgid "Metrics - Prometheus"
msgstr ""
+msgid "Metrics and profiling"
+msgstr ""
+
msgid "Metrics|Check out the CI/CD documentation on deploying to an environment"
msgstr ""
@@ -4995,6 +5004,9 @@ msgstr ""
msgid "Reply to this email directly or %{view_it_on_gitlab}."
msgstr ""
+msgid "Reporting"
+msgstr ""
+
msgid "Reports|%{failedString} and %{resolvedString}"
msgstr ""
@@ -5363,19 +5375,19 @@ msgstr ""
msgid "Set up Koding"
msgstr ""
-msgid "Set up your project to automatically push and/or pull changes to/from another repository. Branches, tags, and commits will be synced automatically."
+msgid "Set up a %{type} Runner manually"
msgstr ""
-msgid "SetPasswordToCloneLink|set a password"
+msgid "Set up a specific Runner automatically"
msgstr ""
-msgid "Settings"
+msgid "Set up your project to automatically push and/or pull changes to/from another repository. Branches, tags, and commits will be synced automatically."
msgstr ""
-msgid "Setup a %{type} Runner manually"
+msgid "SetPasswordToCloneLink|set a password"
msgstr ""
-msgid "Setup a specific Runner automatically"
+msgid "Settings"
msgstr ""
msgid "Share"
@@ -5536,6 +5548,9 @@ msgstr ""
msgid "SortOptions|Most popular"
msgstr ""
+msgid "SortOptions|Most stars"
+msgstr ""
+
msgid "SortOptions|Name"
msgstr ""
@@ -5796,6 +5811,9 @@ msgstr ""
msgid "Template"
msgstr ""
+msgid "Templates"
+msgstr ""
+
msgid "Terms of Service Agreement and Privacy Policy"
msgstr ""
@@ -6799,7 +6817,7 @@ msgstr ""
msgid "You can resolve the merge conflict using either the Interactive mode, by choosing %{use_ours} or %{use_theirs} buttons, or by editing the files directly. Commit these changes into %{branch_name}"
msgstr ""
-msgid "You can setup jobs to only use Runners with specific tags. Separate tags with commas."
+msgid "You can set up jobs to only use Runners with specific tags. Separate tags with commas."
msgstr ""
msgid "You cannot write to this read-only GitLab instance."
diff --git a/locale/gl_ES/gitlab.po b/locale/gl_ES/gitlab.po
index 5caaba0ee8f..5574ed0613f 100644
--- a/locale/gl_ES/gitlab.po
+++ b/locale/gl_ES/gitlab.po
@@ -308,7 +308,7 @@ msgstr ""
msgid "<strong>Removes</strong> source branch"
msgstr ""
-msgid "A 'Runner' is a process which runs a job. You can setup as many Runners as you need."
+msgid "A 'Runner' is a process which runs a job. You can set up as many Runners as you need."
msgstr ""
msgid "A collection of graphs regarding Continuous Integration"
@@ -755,7 +755,7 @@ msgstr ""
msgid "Ascending"
msgstr ""
-msgid "Ask your group maintainer to setup a group Runner."
+msgid "Ask your group maintainer to set up a group Runner."
msgstr ""
msgid "Assertion consumer service URL"
@@ -6510,10 +6510,10 @@ msgstr ""
msgid "Settings"
msgstr ""
-msgid "Setup a %{type} Runner manually"
+msgid "Set up a %{type} Runner manually"
msgstr ""
-msgid "Setup a specific Runner automatically"
+msgid "Set up a specific Runner automatically"
msgstr ""
msgid "Share"
@@ -8108,7 +8108,7 @@ msgstr ""
msgid "You can resolve the merge conflict using either the Interactive mode, by choosing %{use_ours} or %{use_theirs} buttons, or by editing the files directly. Commit these changes into %{branch_name}"
msgstr ""
-msgid "You can setup jobs to only use Runners with specific tags. Separate tags with commas."
+msgid "You can set up jobs to only use Runners with specific tags. Separate tags with commas."
msgstr ""
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
diff --git a/locale/he_IL/gitlab.po b/locale/he_IL/gitlab.po
index 308d138a534..4eeac683e67 100644
--- a/locale/he_IL/gitlab.po
+++ b/locale/he_IL/gitlab.po
@@ -376,7 +376,7 @@ msgstr ""
msgid "<strong>Removes</strong> source branch"
msgstr ""
-msgid "A 'Runner' is a process which runs a job. You can setup as many Runners as you need."
+msgid "A 'Runner' is a process which runs a job. You can set up as many Runners as you need."
msgstr ""
msgid "A collection of graphs regarding Continuous Integration"
@@ -823,7 +823,7 @@ msgstr ""
msgid "Ascending"
msgstr ""
-msgid "Ask your group maintainer to setup a group Runner."
+msgid "Ask your group maintainer to set up a group Runner."
msgstr ""
msgid "Assertion consumer service URL"
@@ -6606,10 +6606,10 @@ msgstr ""
msgid "Settings"
msgstr ""
-msgid "Setup a %{type} Runner manually"
+msgid "Set up a %{type} Runner manually"
msgstr ""
-msgid "Setup a specific Runner automatically"
+msgid "Set up a specific Runner automatically"
msgstr ""
msgid "Share"
@@ -8212,7 +8212,7 @@ msgstr ""
msgid "You can resolve the merge conflict using either the Interactive mode, by choosing %{use_ours} or %{use_theirs} buttons, or by editing the files directly. Commit these changes into %{branch_name}"
msgstr ""
-msgid "You can setup jobs to only use Runners with specific tags. Separate tags with commas."
+msgid "You can set up jobs to only use Runners with specific tags. Separate tags with commas."
msgstr ""
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
diff --git a/locale/id_ID/gitlab.po b/locale/id_ID/gitlab.po
index ee5305c8ec8..e185f4f71b7 100644
--- a/locale/id_ID/gitlab.po
+++ b/locale/id_ID/gitlab.po
@@ -274,7 +274,7 @@ msgstr ""
msgid "<strong>Removes</strong> source branch"
msgstr ""
-msgid "A 'Runner' is a process which runs a job. You can setup as many Runners as you need."
+msgid "A 'Runner' is a process which runs a job. You can set up as many Runners as you need."
msgstr ""
msgid "A collection of graphs regarding Continuous Integration"
@@ -721,7 +721,7 @@ msgstr ""
msgid "Ascending"
msgstr ""
-msgid "Ask your group maintainer to setup a group Runner."
+msgid "Ask your group maintainer to set up a group Runner."
msgstr ""
msgid "Assertion consumer service URL"
@@ -6462,10 +6462,10 @@ msgstr ""
msgid "Settings"
msgstr ""
-msgid "Setup a %{type} Runner manually"
+msgid "Set up a %{type} Runner manually"
msgstr ""
-msgid "Setup a specific Runner automatically"
+msgid "Set up a specific Runner automatically"
msgstr ""
msgid "Share"
@@ -8056,7 +8056,7 @@ msgstr ""
msgid "You can resolve the merge conflict using either the Interactive mode, by choosing %{use_ours} or %{use_theirs} buttons, or by editing the files directly. Commit these changes into %{branch_name}"
msgstr ""
-msgid "You can setup jobs to only use Runners with specific tags. Separate tags with commas."
+msgid "You can set up jobs to only use Runners with specific tags. Separate tags with commas."
msgstr ""
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
diff --git a/locale/it/gitlab.po b/locale/it/gitlab.po
index 50d627ea6de..a4e20f4fe65 100644
--- a/locale/it/gitlab.po
+++ b/locale/it/gitlab.po
@@ -308,7 +308,7 @@ msgstr ""
msgid "<strong>Removes</strong> source branch"
msgstr ""
-msgid "A 'Runner' is a process which runs a job. You can setup as many Runners as you need."
+msgid "A 'Runner' is a process which runs a job. You can set up as many Runners as you need."
msgstr ""
msgid "A collection of graphs regarding Continuous Integration"
@@ -755,7 +755,7 @@ msgstr "Artefatti"
msgid "Ascending"
msgstr ""
-msgid "Ask your group maintainer to setup a group Runner."
+msgid "Ask your group maintainer to set up a group Runner."
msgstr ""
msgid "Assertion consumer service URL"
@@ -6510,10 +6510,10 @@ msgstr "imposta una password"
msgid "Settings"
msgstr "Impostazioni"
-msgid "Setup a %{type} Runner manually"
+msgid "Set up a %{type} Runner manually"
msgstr ""
-msgid "Setup a specific Runner automatically"
+msgid "Set up a specific Runner automatically"
msgstr ""
msgid "Share"
@@ -8108,7 +8108,7 @@ msgstr ""
msgid "You can resolve the merge conflict using either the Interactive mode, by choosing %{use_ours} or %{use_theirs} buttons, or by editing the files directly. Commit these changes into %{branch_name}"
msgstr ""
-msgid "You can setup jobs to only use Runners with specific tags. Separate tags with commas."
+msgid "You can set up jobs to only use Runners with specific tags. Separate tags with commas."
msgstr ""
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
diff --git a/locale/ja/gitlab.po b/locale/ja/gitlab.po
index 9864aded546..f1d84529a25 100644
--- a/locale/ja/gitlab.po
+++ b/locale/ja/gitlab.po
@@ -274,7 +274,7 @@ msgstr "<strong>%{pushes}</strong>回ã®ãƒ—ッシュã€<strong>%{commits}</stron
msgid "<strong>Removes</strong> source branch"
msgstr "ソースブランãƒã‚’<strong>削除</strong>"
-msgid "A 'Runner' is a process which runs a job. You can setup as many Runners as you need."
+msgid "A 'Runner' is a process which runs a job. You can set up as many Runners as you need."
msgstr "「Runnerã€ã¯ã‚¸ãƒ§ãƒ–を実行ã™ã‚‹ãƒ—ロセスã§ã™ã€‚å¿…è¦ãªæ•°ã® Runner ã‚’ä»»æ„ã«ã‚»ãƒƒãƒˆã‚¢ãƒƒãƒ—ã§ãã¾ã™ã€‚"
msgid "A collection of graphs regarding Continuous Integration"
@@ -721,7 +721,7 @@ msgstr "アーティファクト"
msgid "Ascending"
msgstr "昇順"
-msgid "Ask your group maintainer to setup a group Runner."
+msgid "Ask your group maintainer to set up a group Runner."
msgstr "グループ Runner ã®è¨­å®šã¯ã€ã‚°ãƒ«ãƒ¼ãƒ—ã® Maintainer ã«ä¾é ¼ã—ã¦ãã ã•ã„。"
msgid "Assertion consumer service URL"
@@ -6462,10 +6462,10 @@ msgstr "パスワードを設定"
msgid "Settings"
msgstr "設定"
-msgid "Setup a %{type} Runner manually"
+msgid "Set up a %{type} Runner manually"
msgstr ""
-msgid "Setup a specific Runner automatically"
+msgid "Set up a specific Runner automatically"
msgstr ""
msgid "Share"
@@ -8056,7 +8056,7 @@ msgstr "ファイルを編集ã™ã‚‹ã«ã¯ã€ã©ã“ã‹ã®ãƒ–ランãƒã«ã„ãªã‘
msgid "You can resolve the merge conflict using either the Interactive mode, by choosing %{use_ours} or %{use_theirs} buttons, or by editing the files directly. Commit these changes into %{branch_name}"
msgstr ""
-msgid "You can setup jobs to only use Runners with specific tags. Separate tags with commas."
+msgid "You can set up jobs to only use Runners with specific tags. Separate tags with commas."
msgstr ""
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
diff --git a/locale/ko/gitlab.po b/locale/ko/gitlab.po
index 6528dd0235a..416e0712a75 100644
--- a/locale/ko/gitlab.po
+++ b/locale/ko/gitlab.po
@@ -274,7 +274,7 @@ msgstr ""
msgid "<strong>Removes</strong> source branch"
msgstr ""
-msgid "A 'Runner' is a process which runs a job. You can setup as many Runners as you need."
+msgid "A 'Runner' is a process which runs a job. You can set up as many Runners as you need."
msgstr "'러너(Runner)'는 ìž‘ì—…ì„ ì‹¤í–‰í•˜ëŠ” 프로세스입니다. 필요한 ë§Œí¼ ëŸ¬ë„ˆë¥¼ ì…‹ì—…í•  수 있습니다."
msgid "A collection of graphs regarding Continuous Integration"
@@ -721,7 +721,7 @@ msgstr ""
msgid "Ascending"
msgstr ""
-msgid "Ask your group maintainer to setup a group Runner."
+msgid "Ask your group maintainer to set up a group Runner."
msgstr "그룹 관리ìžì—게 그룹 Runner 를 설정하ë„ë¡ ìš”ì²­í•˜ì„¸ìš”"
msgid "Assertion consumer service URL"
@@ -6462,10 +6462,10 @@ msgstr "패스워드 설정"
msgid "Settings"
msgstr "설정"
-msgid "Setup a %{type} Runner manually"
+msgid "Set up a %{type} Runner manually"
msgstr ""
-msgid "Setup a specific Runner automatically"
+msgid "Set up a specific Runner automatically"
msgstr "특정 Runner ìžë™ 설정"
msgid "Share"
@@ -8056,7 +8056,7 @@ msgstr ""
msgid "You can resolve the merge conflict using either the Interactive mode, by choosing %{use_ours} or %{use_theirs} buttons, or by editing the files directly. Commit these changes into %{branch_name}"
msgstr ""
-msgid "You can setup jobs to only use Runners with specific tags. Separate tags with commas."
+msgid "You can set up jobs to only use Runners with specific tags. Separate tags with commas."
msgstr ""
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
diff --git a/locale/nl_NL/gitlab.po b/locale/nl_NL/gitlab.po
index e210fbb6acb..8234f120676 100644
--- a/locale/nl_NL/gitlab.po
+++ b/locale/nl_NL/gitlab.po
@@ -308,7 +308,7 @@ msgstr ""
msgid "<strong>Removes</strong> source branch"
msgstr ""
-msgid "A 'Runner' is a process which runs a job. You can setup as many Runners as you need."
+msgid "A 'Runner' is a process which runs a job. You can set up as many Runners as you need."
msgstr ""
msgid "A collection of graphs regarding Continuous Integration"
@@ -755,7 +755,7 @@ msgstr ""
msgid "Ascending"
msgstr ""
-msgid "Ask your group maintainer to setup a group Runner."
+msgid "Ask your group maintainer to set up a group Runner."
msgstr ""
msgid "Assertion consumer service URL"
@@ -6510,10 +6510,10 @@ msgstr ""
msgid "Settings"
msgstr ""
-msgid "Setup a %{type} Runner manually"
+msgid "Set up a %{type} Runner manually"
msgstr ""
-msgid "Setup a specific Runner automatically"
+msgid "Set up a specific Runner automatically"
msgstr ""
msgid "Share"
@@ -8108,7 +8108,7 @@ msgstr ""
msgid "You can resolve the merge conflict using either the Interactive mode, by choosing %{use_ours} or %{use_theirs} buttons, or by editing the files directly. Commit these changes into %{branch_name}"
msgstr ""
-msgid "You can setup jobs to only use Runners with specific tags. Separate tags with commas."
+msgid "You can set up jobs to only use Runners with specific tags. Separate tags with commas."
msgstr ""
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
diff --git a/locale/pl_PL/gitlab.po b/locale/pl_PL/gitlab.po
index c619c74fa81..6cc1b4472c7 100644
--- a/locale/pl_PL/gitlab.po
+++ b/locale/pl_PL/gitlab.po
@@ -376,7 +376,7 @@ msgstr ""
msgid "<strong>Removes</strong> source branch"
msgstr ""
-msgid "A 'Runner' is a process which runs a job. You can setup as many Runners as you need."
+msgid "A 'Runner' is a process which runs a job. You can set up as many Runners as you need."
msgstr ""
msgid "A collection of graphs regarding Continuous Integration"
@@ -823,7 +823,7 @@ msgstr ""
msgid "Ascending"
msgstr ""
-msgid "Ask your group maintainer to setup a group Runner."
+msgid "Ask your group maintainer to set up a group Runner."
msgstr ""
msgid "Assertion consumer service URL"
@@ -6606,10 +6606,10 @@ msgstr ""
msgid "Settings"
msgstr ""
-msgid "Setup a %{type} Runner manually"
+msgid "Set up a %{type} Runner manually"
msgstr ""
-msgid "Setup a specific Runner automatically"
+msgid "Set up a specific Runner automatically"
msgstr ""
msgid "Share"
@@ -8212,7 +8212,7 @@ msgstr ""
msgid "You can resolve the merge conflict using either the Interactive mode, by choosing %{use_ours} or %{use_theirs} buttons, or by editing the files directly. Commit these changes into %{branch_name}"
msgstr ""
-msgid "You can setup jobs to only use Runners with specific tags. Separate tags with commas."
+msgid "You can set up jobs to only use Runners with specific tags. Separate tags with commas."
msgstr ""
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
diff --git a/locale/pt_BR/gitlab.po b/locale/pt_BR/gitlab.po
index 9eb6ac8906b..a0e18f2be2f 100644
--- a/locale/pt_BR/gitlab.po
+++ b/locale/pt_BR/gitlab.po
@@ -308,7 +308,7 @@ msgstr "<strong>%{pushes}</strong> pushes, mais que <strong>%{commits}</strong>
msgid "<strong>Removes</strong> source branch"
msgstr "<strong>Remover</strong> branch de origem"
-msgid "A 'Runner' is a process which runs a job. You can setup as many Runners as you need."
+msgid "A 'Runner' is a process which runs a job. You can set up as many Runners as you need."
msgstr "'Runner' é um processo que executa um job. Você pode configurar quantos Runners você precisar."
msgid "A collection of graphs regarding Continuous Integration"
@@ -755,7 +755,7 @@ msgstr "Artefatos"
msgid "Ascending"
msgstr "Ascendente"
-msgid "Ask your group maintainer to setup a group Runner."
+msgid "Ask your group maintainer to set up a group Runner."
msgstr "Solicite a um mantenedor do grupo para configurar um Runner de grupo."
msgid "Assertion consumer service URL"
@@ -6510,10 +6510,10 @@ msgstr "defina uma senha"
msgid "Settings"
msgstr "Configurações"
-msgid "Setup a %{type} Runner manually"
+msgid "Set up a %{type} Runner manually"
msgstr ""
-msgid "Setup a specific Runner automatically"
+msgid "Set up a specific Runner automatically"
msgstr "Configurar um Runner específico automaticamente"
msgid "Share"
@@ -8108,7 +8108,7 @@ msgstr "Você só pode editar arquivos quando estiver em um branch"
msgid "You can resolve the merge conflict using either the Interactive mode, by choosing %{use_ours} or %{use_theirs} buttons, or by editing the files directly. Commit these changes into %{branch_name}"
msgstr "Você pode resolver o conflito de merge usando o modo Interativo, escolhendo os botões %{use_ours} ou %{use_theirs} ou editando os arquivos diretamente. Confirme essas alterações em %{branch_name}"
-msgid "You can setup jobs to only use Runners with specific tags. Separate tags with commas."
+msgid "You can set up jobs to only use Runners with specific tags. Separate tags with commas."
msgstr ""
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
diff --git a/locale/ro_RO/gitlab.po b/locale/ro_RO/gitlab.po
index 4ac7b482d51..f333a5aeba1 100644
--- a/locale/ro_RO/gitlab.po
+++ b/locale/ro_RO/gitlab.po
@@ -342,7 +342,7 @@ msgstr ""
msgid "<strong>Removes</strong> source branch"
msgstr ""
-msgid "A 'Runner' is a process which runs a job. You can setup as many Runners as you need."
+msgid "A 'Runner' is a process which runs a job. You can set up as many Runners as you need."
msgstr ""
msgid "A collection of graphs regarding Continuous Integration"
@@ -789,7 +789,7 @@ msgstr ""
msgid "Ascending"
msgstr ""
-msgid "Ask your group maintainer to setup a group Runner."
+msgid "Ask your group maintainer to set up a group Runner."
msgstr ""
msgid "Assertion consumer service URL"
@@ -6558,10 +6558,10 @@ msgstr ""
msgid "Settings"
msgstr ""
-msgid "Setup a %{type} Runner manually"
+msgid "Set up a %{type} Runner manually"
msgstr ""
-msgid "Setup a specific Runner automatically"
+msgid "Set up a specific Runner automatically"
msgstr ""
msgid "Share"
@@ -8160,7 +8160,7 @@ msgstr ""
msgid "You can resolve the merge conflict using either the Interactive mode, by choosing %{use_ours} or %{use_theirs} buttons, or by editing the files directly. Commit these changes into %{branch_name}"
msgstr ""
-msgid "You can setup jobs to only use Runners with specific tags. Separate tags with commas."
+msgid "You can set up jobs to only use Runners with specific tags. Separate tags with commas."
msgstr ""
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
diff --git a/locale/ru/gitlab.po b/locale/ru/gitlab.po
index 8fd8001f30c..4b66d59bebd 100644
--- a/locale/ru/gitlab.po
+++ b/locale/ru/gitlab.po
@@ -376,7 +376,7 @@ msgstr ""
msgid "<strong>Removes</strong> source branch"
msgstr "<strong>УдалÑет</strong> иÑходную ветку"
-msgid "A 'Runner' is a process which runs a job. You can setup as many Runners as you need."
+msgid "A 'Runner' is a process which runs a job. You can set up as many Runners as you need."
msgstr "«Runner» - Ñто процеÑÑ, который выполнÑет задание (обработчиков заданий). Ð’Ñ‹ можете наÑтроить Ñтолько таких процеÑÑов, Ñколько вам нужно."
msgid "A collection of graphs regarding Continuous Integration"
@@ -823,7 +823,7 @@ msgstr "Ðртефакты"
msgid "Ascending"
msgstr ""
-msgid "Ask your group maintainer to setup a group Runner."
+msgid "Ask your group maintainer to set up a group Runner."
msgstr ""
msgid "Assertion consumer service URL"
@@ -6606,10 +6606,10 @@ msgstr "уÑтановите пароль"
msgid "Settings"
msgstr "ÐаÑтройки"
-msgid "Setup a %{type} Runner manually"
+msgid "Set up a %{type} Runner manually"
msgstr ""
-msgid "Setup a specific Runner automatically"
+msgid "Set up a specific Runner automatically"
msgstr "ÐаÑтроить конкретный обработчик заданий автоматичеÑки"
msgid "Share"
@@ -8212,7 +8212,7 @@ msgstr ""
msgid "You can resolve the merge conflict using either the Interactive mode, by choosing %{use_ours} or %{use_theirs} buttons, or by editing the files directly. Commit these changes into %{branch_name}"
msgstr ""
-msgid "You can setup jobs to only use Runners with specific tags. Separate tags with commas."
+msgid "You can set up jobs to only use Runners with specific tags. Separate tags with commas."
msgstr ""
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
diff --git a/locale/sq_AL/gitlab.po b/locale/sq_AL/gitlab.po
index 6fe5001d729..762d4ef53a7 100644
--- a/locale/sq_AL/gitlab.po
+++ b/locale/sq_AL/gitlab.po
@@ -308,7 +308,7 @@ msgstr ""
msgid "<strong>Removes</strong> source branch"
msgstr ""
-msgid "A 'Runner' is a process which runs a job. You can setup as many Runners as you need."
+msgid "A 'Runner' is a process which runs a job. You can set up as many Runners as you need."
msgstr ""
msgid "A collection of graphs regarding Continuous Integration"
@@ -755,7 +755,7 @@ msgstr ""
msgid "Ascending"
msgstr ""
-msgid "Ask your group maintainer to setup a group Runner."
+msgid "Ask your group maintainer to set up a group Runner."
msgstr ""
msgid "Assertion consumer service URL"
@@ -6510,10 +6510,10 @@ msgstr ""
msgid "Settings"
msgstr ""
-msgid "Setup a %{type} Runner manually"
+msgid "Set up a %{type} Runner manually"
msgstr ""
-msgid "Setup a specific Runner automatically"
+msgid "Set up a specific Runner automatically"
msgstr ""
msgid "Share"
@@ -8108,7 +8108,7 @@ msgstr ""
msgid "You can resolve the merge conflict using either the Interactive mode, by choosing %{use_ours} or %{use_theirs} buttons, or by editing the files directly. Commit these changes into %{branch_name}"
msgstr ""
-msgid "You can setup jobs to only use Runners with specific tags. Separate tags with commas."
+msgid "You can set up jobs to only use Runners with specific tags. Separate tags with commas."
msgstr ""
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
diff --git a/locale/tr_TR/gitlab.po b/locale/tr_TR/gitlab.po
index a3dd9cb738e..e7e44caf077 100644
--- a/locale/tr_TR/gitlab.po
+++ b/locale/tr_TR/gitlab.po
@@ -308,7 +308,7 @@ msgstr ""
msgid "<strong>Removes</strong> source branch"
msgstr ""
-msgid "A 'Runner' is a process which runs a job. You can setup as many Runners as you need."
+msgid "A 'Runner' is a process which runs a job. You can set up as many Runners as you need."
msgstr ""
msgid "A collection of graphs regarding Continuous Integration"
@@ -755,7 +755,7 @@ msgstr ""
msgid "Ascending"
msgstr ""
-msgid "Ask your group maintainer to setup a group Runner."
+msgid "Ask your group maintainer to set up a group Runner."
msgstr ""
msgid "Assertion consumer service URL"
@@ -6510,10 +6510,10 @@ msgstr ""
msgid "Settings"
msgstr ""
-msgid "Setup a %{type} Runner manually"
+msgid "Set up a %{type} Runner manually"
msgstr ""
-msgid "Setup a specific Runner automatically"
+msgid "Set up a specific Runner automatically"
msgstr ""
msgid "Share"
@@ -8108,7 +8108,7 @@ msgstr ""
msgid "You can resolve the merge conflict using either the Interactive mode, by choosing %{use_ours} or %{use_theirs} buttons, or by editing the files directly. Commit these changes into %{branch_name}"
msgstr ""
-msgid "You can setup jobs to only use Runners with specific tags. Separate tags with commas."
+msgid "You can set up jobs to only use Runners with specific tags. Separate tags with commas."
msgstr ""
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
diff --git a/locale/uk/gitlab.po b/locale/uk/gitlab.po
index 2f965fc0ff0..c8f5cf5cae8 100644
--- a/locale/uk/gitlab.po
+++ b/locale/uk/gitlab.po
@@ -376,7 +376,7 @@ msgstr "<strong>%{pushes}</strong> відправок (push), більше ніÐ
msgid "<strong>Removes</strong> source branch"
msgstr "<strong>ВидалÑÑ”</strong> гілку-джерело"
-msgid "A 'Runner' is a process which runs a job. You can setup as many Runners as you need."
+msgid "A 'Runner' is a process which runs a job. You can set up as many Runners as you need."
msgstr "'Runner' — це процеÑ, Ñкий виконує завданнÑ. Ви можете Ñтворити потрібну кількіÑÑ‚ÑŒ Runner'ів."
msgid "A collection of graphs regarding Continuous Integration"
@@ -823,7 +823,7 @@ msgstr "Ðртефакти"
msgid "Ascending"
msgstr "За зроÑтаннÑм"
-msgid "Ask your group maintainer to setup a group Runner."
+msgid "Ask your group maintainer to set up a group Runner."
msgstr "ПопроÑÑ–Ñ‚ÑŒ керівника групи, щоб налаштувати груповий Runner."
msgid "Assertion consumer service URL"
@@ -6606,10 +6606,10 @@ msgstr "вÑтановити пароль"
msgid "Settings"
msgstr "ÐалаштуваннÑ"
-msgid "Setup a %{type} Runner manually"
+msgid "Set up a %{type} Runner manually"
msgstr ""
-msgid "Setup a specific Runner automatically"
+msgid "Set up a specific Runner automatically"
msgstr "Ðвтоматично налаштувати Ñпецифічний runner"
msgid "Share"
@@ -8212,7 +8212,7 @@ msgstr "Ви можете редагувати файли, лише перебу
msgid "You can resolve the merge conflict using either the Interactive mode, by choosing %{use_ours} or %{use_theirs} buttons, or by editing the files directly. Commit these changes into %{branch_name}"
msgstr "Ви можете розв’Ñзати цей конфлікт Ð·Ð»Ð¸Ñ‚Ñ‚Ñ Ð·Ð° допомогою інтерактивного режиму (викориÑтовуючи кнопки %{use_ours} та %{use_theirs}), або безпоÑередньо редагуючи файли. Закомітити зміни у %{branch_name}"
-msgid "You can setup jobs to only use Runners with specific tags. Separate tags with commas."
+msgid "You can set up jobs to only use Runners with specific tags. Separate tags with commas."
msgstr ""
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
diff --git a/locale/zh_CN/gitlab.po b/locale/zh_CN/gitlab.po
index 969ce34ac5c..e93bfd7cfb8 100644
--- a/locale/zh_CN/gitlab.po
+++ b/locale/zh_CN/gitlab.po
@@ -274,7 +274,7 @@ msgstr "<strong>%{pushes}</strong> 个推é€ï¼Œè¶…å‰ <strong>%{people}</strong>
msgid "<strong>Removes</strong> source branch"
msgstr "<strong>删除</strong>æºåˆ†æ”¯"
-msgid "A 'Runner' is a process which runs a job. You can setup as many Runners as you need."
+msgid "A 'Runner' is a process which runs a job. You can set up as many Runners as you need."
msgstr "Runner是一个执行任务的进程。您å¯ä»¥æ ¹æ®éœ€è¦é…置任æ„æ•°é‡çš„Runner。"
msgid "A collection of graphs regarding Continuous Integration"
@@ -721,7 +721,7 @@ msgstr "产物"
msgid "Ascending"
msgstr "å‡åºæŽ’列"
-msgid "Ask your group maintainer to setup a group Runner."
+msgid "Ask your group maintainer to set up a group Runner."
msgstr "请群组维护者é…置一个群组级 Runner。"
msgid "Assertion consumer service URL"
@@ -6462,10 +6462,10 @@ msgstr "设置密ç "
msgid "Settings"
msgstr "设置"
-msgid "Setup a %{type} Runner manually"
+msgid "Set up a %{type} Runner manually"
msgstr ""
-msgid "Setup a specific Runner automatically"
+msgid "Set up a specific Runner automatically"
msgstr "自动创建专用Runner"
msgid "Share"
@@ -8056,7 +8056,7 @@ msgstr "åªèƒ½åœ¨åˆ†æ”¯ä¸Šç¼–辑文件"
msgid "You can resolve the merge conflict using either the Interactive mode, by choosing %{use_ours} or %{use_theirs} buttons, or by editing the files directly. Commit these changes into %{branch_name}"
msgstr "您å¯ä»¥ä½¿ç”¨äº¤äº’模å¼ï¼Œé€šè¿‡é€‰æ‹© %{use_ours} 或 %{use_theirs} 按钮æ¥è§£å†³åˆå¹¶å†²çªã€‚也å¯ä»¥é€šè¿‡ç›´æŽ¥ç¼–辑文件æ¥è§£å†³åˆå¹¶å†²çªã€‚然åŽå°†è¿™äº›æ›´æ”¹æ交到 %{branch_name}"
-msgid "You can setup jobs to only use Runners with specific tags. Separate tags with commas."
+msgid "You can set up jobs to only use Runners with specific tags. Separate tags with commas."
msgstr ""
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
diff --git a/locale/zh_HK/gitlab.po b/locale/zh_HK/gitlab.po
index 424ca95d24c..49fbfc224e4 100644
--- a/locale/zh_HK/gitlab.po
+++ b/locale/zh_HK/gitlab.po
@@ -274,7 +274,7 @@ msgstr ""
msgid "<strong>Removes</strong> source branch"
msgstr ""
-msgid "A 'Runner' is a process which runs a job. You can setup as many Runners as you need."
+msgid "A 'Runner' is a process which runs a job. You can set up as many Runners as you need."
msgstr ""
msgid "A collection of graphs regarding Continuous Integration"
@@ -721,7 +721,7 @@ msgstr ""
msgid "Ascending"
msgstr ""
-msgid "Ask your group maintainer to setup a group Runner."
+msgid "Ask your group maintainer to set up a group Runner."
msgstr ""
msgid "Assertion consumer service URL"
@@ -6462,10 +6462,10 @@ msgstr "設置密碼"
msgid "Settings"
msgstr ""
-msgid "Setup a %{type} Runner manually"
+msgid "Set up a %{type} Runner manually"
msgstr ""
-msgid "Setup a specific Runner automatically"
+msgid "Set up a specific Runner automatically"
msgstr ""
msgid "Share"
@@ -8056,7 +8056,7 @@ msgstr ""
msgid "You can resolve the merge conflict using either the Interactive mode, by choosing %{use_ours} or %{use_theirs} buttons, or by editing the files directly. Commit these changes into %{branch_name}"
msgstr ""
-msgid "You can setup jobs to only use Runners with specific tags. Separate tags with commas."
+msgid "You can set up jobs to only use Runners with specific tags. Separate tags with commas."
msgstr ""
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
diff --git a/locale/zh_TW/gitlab.po b/locale/zh_TW/gitlab.po
index d7ca7996926..5c9746ad6b4 100644
--- a/locale/zh_TW/gitlab.po
+++ b/locale/zh_TW/gitlab.po
@@ -274,7 +274,7 @@ msgstr "æŽ¨é€ <strong>%{pushes}</strong> 個,<strong>%{people}</strong> 個è²
msgid "<strong>Removes</strong> source branch"
msgstr "<strong>刪除</strong>來æºåˆ†æ”¯"
-msgid "A 'Runner' is a process which runs a job. You can setup as many Runners as you need."
+msgid "A 'Runner' is a process which runs a job. You can set up as many Runners as you need."
msgstr "一個「執行器ã€æ˜¯ä¸€å€‹åŸ·è¡Œå·¥ä½œçš„進程。你å¯ä»¥å®‰è£ä½ éœ€è¦çš„多個執行器。"
msgid "A collection of graphs regarding Continuous Integration"
@@ -721,7 +721,7 @@ msgstr "產物"
msgid "Ascending"
msgstr "é †åº"
-msgid "Ask your group maintainer to setup a group Runner."
+msgid "Ask your group maintainer to set up a group Runner."
msgstr "è©¢å•æ‚¨çš„群組維護者以安è£ç¾¤çµ„執行器。"
msgid "Assertion consumer service URL"
@@ -6462,10 +6462,10 @@ msgstr "設定密碼"
msgid "Settings"
msgstr "設定"
-msgid "Setup a %{type} Runner manually"
+msgid "Set up a %{type} Runner manually"
msgstr ""
-msgid "Setup a specific Runner automatically"
+msgid "Set up a specific Runner automatically"
msgstr "自動設置特定的執行器"
msgid "Share"
@@ -8056,7 +8056,7 @@ msgstr "您åªèƒ½åœ¨åˆ†æ”¯ä¸Šç·¨è¼¯æ–‡ä»¶"
msgid "You can resolve the merge conflict using either the Interactive mode, by choosing %{use_ours} or %{use_theirs} buttons, or by editing the files directly. Commit these changes into %{branch_name}"
msgstr "您å¯ä»¥é€éŽä½¿ç”¨äº’動模å¼é¸æ“‡ %{use_ours} 或 %{use_theirs} 按鈕ã€æˆ–者是直接編輯檔案來解決åˆä½µè¡çªï¼Œä¸¦å°‡é€™äº›è®Šæ›´æ交到 %{branch_name}。"
-msgid "You can setup jobs to only use Runners with specific tags. Separate tags with commas."
+msgid "You can set up jobs to only use Runners with specific tags. Separate tags with commas."
msgstr ""
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
diff --git a/package.json b/package.json
index 4a479b6fb2a..cc6bbdd351e 100644
--- a/package.json
+++ b/package.json
@@ -19,7 +19,7 @@
},
"dependencies": {
"@gitlab-org/gitlab-svgs": "^1.29.0",
- "@gitlab-org/gitlab-ui": "^1.5.0",
+ "@gitlab-org/gitlab-ui": "^1.5.1",
"autosize": "^4.0.0",
"axios": "^0.17.1",
"babel-core": "^6.26.3",
@@ -110,22 +110,22 @@
},
"devDependencies": {
"axios-mock-adapter": "^1.15.0",
- "babel-eslint": "^8.2.3",
+ "babel-eslint": "^9.0.0",
"babel-plugin-istanbul": "^4.1.6",
"babel-plugin-rewire": "^1.1.0",
"babel-template": "^6.26.0",
"babel-types": "^6.26.0",
"chalk": "^2.4.1",
"commander": "^2.15.1",
- "eslint": "~4.12.1",
- "eslint-config-airbnb-base": "^12.1.0",
- "eslint-import-resolver-webpack": "^0.10.0",
- "eslint-plugin-filenames": "^1.2.0",
- "eslint-plugin-html": "4.0.3",
- "eslint-plugin-import": "^2.12.0",
- "eslint-plugin-jasmine": "^2.1.0",
- "eslint-plugin-promise": "^3.8.0",
- "eslint-plugin-vue": "^4.5.0",
+ "eslint": "~5.6.0",
+ "eslint-config-airbnb-base": "^13.1.0",
+ "eslint-import-resolver-webpack": "^0.10.1",
+ "eslint-plugin-filenames": "^1.3.2",
+ "eslint-plugin-html": "4.0.5",
+ "eslint-plugin-import": "^2.14.0",
+ "eslint-plugin-jasmine": "^2.10.1",
+ "eslint-plugin-promise": "^4.0.1",
+ "eslint-plugin-vue": "^5.0.0-beta.3",
"gettext-extractor": "^3.3.2",
"gettext-extractor-vue": "^4.0.1",
"ignore": "^3.3.7",
diff --git a/qa/qa.rb b/qa/qa.rb
index cb3202c8e1c..952084085d5 100644
--- a/qa/qa.rb
+++ b/qa/qa.rb
@@ -57,6 +57,7 @@ module QA
autoload :Wiki, 'qa/factory/resource/wiki'
autoload :File, 'qa/factory/resource/file'
autoload :Fork, 'qa/factory/resource/fork'
+ autoload :SSHKey, 'qa/factory/resource/ssh_key'
end
module Repository
@@ -217,6 +218,7 @@ module QA
module Profile
autoload :PersonalAccessTokens, 'qa/page/profile/personal_access_tokens'
+ autoload :SSHKeys, 'qa/page/profile/ssh_keys'
end
module Issuable
diff --git a/qa/qa/factory/repository/project_push.rb b/qa/qa/factory/repository/project_push.rb
index 4f78098d348..167f47c9141 100644
--- a/qa/qa/factory/repository/project_push.rb
+++ b/qa/qa/factory/repository/project_push.rb
@@ -11,7 +11,9 @@ module QA
factory.output
end
- product(:project) { |factory| factory.project }
+ product :project do |factory|
+ factory.project
+ end
def initialize
@file_name = 'file.txt'
@@ -21,8 +23,8 @@ module QA
@new_branch = true
end
- def repository_uri
- @repository_uri ||= begin
+ def repository_http_uri
+ @repository_http_uri ||= begin
project.visit!
Page::Project::Show.act do
choose_repository_clone_http
@@ -30,6 +32,16 @@ module QA
end
end
end
+
+ def repository_ssh_uri
+ @repository_ssh_uri ||= begin
+ project.visit!
+ Page::Project::Show.act do
+ choose_repository_clone_ssh
+ repository_location.uri
+ end
+ end
+ end
end
end
end
diff --git a/qa/qa/factory/repository/push.rb b/qa/qa/factory/repository/push.rb
index 5b7ebf6c41f..6c5088f1da5 100644
--- a/qa/qa/factory/repository/push.rb
+++ b/qa/qa/factory/repository/push.rb
@@ -5,8 +5,8 @@ module QA
module Repository
class Push < Factory::Base
attr_accessor :file_name, :file_content, :commit_message,
- :branch_name, :new_branch, :output, :repository_uri,
- :user
+ :branch_name, :new_branch, :output, :repository_http_uri,
+ :repository_ssh_uri, :ssh_key, :user
attr_writer :remote_branch
@@ -16,7 +16,8 @@ module QA
@commit_message = "This is a test commit"
@branch_name = 'master'
@new_branch = true
- @repository_uri = ""
+ @repository_http_uri = ""
+ @ssh_key = nil
end
def remote_branch
@@ -31,9 +32,14 @@ module QA
def fabricate!
Git::Repository.perform do |repository|
- repository.uri = repository_uri
+ if ssh_key
+ repository.uri = repository_ssh_uri
+ repository.use_ssh_key(ssh_key)
+ else
+ repository.uri = repository_http_uri
+ repository.use_default_credentials
+ end
- repository.use_default_credentials
username = 'GitLab QA'
email = 'root@gitlab.com'
@@ -63,6 +69,8 @@ module QA
repository.commit(commit_message)
@output = repository.push_changes("#{branch_name}:#{remote_branch}")
+
+ repository.delete_ssh_key
end
end
end
diff --git a/qa/qa/factory/repository/wiki_push.rb b/qa/qa/factory/repository/wiki_push.rb
index fb7c2bb660d..ecc6cc18c88 100644
--- a/qa/qa/factory/repository/wiki_push.rb
+++ b/qa/qa/factory/repository/wiki_push.rb
@@ -16,8 +16,8 @@ module QA
@new_branch = false
end
- def repository_uri
- @repository_uri ||= begin
+ def repository_http_uri
+ @repository_http_uri ||= begin
wiki.visit!
Page::Project::Wiki::Show.act do
go_to_clone_repository
diff --git a/qa/qa/factory/resource/branch.rb b/qa/qa/factory/resource/branch.rb
index bc252bf3148..60539992073 100644
--- a/qa/qa/factory/resource/branch.rb
+++ b/qa/qa/factory/resource/branch.rb
@@ -64,7 +64,7 @@ module QA
end
page.wait(reload: false) do
- !page.first('.btn-create').disabled?
+ !page.first('.btn-success').disabled?
end
page.protect_branch
diff --git a/qa/qa/factory/resource/project.rb b/qa/qa/factory/resource/project.rb
index 7fff22b5468..90db26ab3ab 100644
--- a/qa/qa/factory/resource/project.rb
+++ b/qa/qa/factory/resource/project.rb
@@ -20,6 +20,13 @@ module QA
end
end
+ product :repository_http_location do
+ Page::Project::Show.act do
+ choose_repository_clone_http
+ repository_location
+ end
+ end
+
def initialize
@description = 'My awesome project'
end
diff --git a/qa/qa/factory/resource/ssh_key.rb b/qa/qa/factory/resource/ssh_key.rb
new file mode 100644
index 00000000000..6c872f32d16
--- /dev/null
+++ b/qa/qa/factory/resource/ssh_key.rb
@@ -0,0 +1,40 @@
+# frozen_string_literal: true
+
+module QA
+ module Factory
+ module Resource
+ class SSHKey < Factory::Base
+ extend Forwardable
+
+ attr_accessor :title
+ attr_reader :private_key, :public_key, :fingerprint
+ def_delegators :key, :private_key, :public_key, :fingerprint
+
+ product :private_key do |factory|
+ factory.private_key
+ end
+
+ product :title do |factory|
+ factory.title
+ end
+
+ product :fingerprint do |factory|
+ factory.fingerprint
+ end
+
+ def key
+ @key ||= Runtime::Key::RSA.new
+ end
+
+ def fabricate!
+ Page::Menu::Main.act { go_to_profile_settings }
+ Page::Menu::Profile.act { click_ssh_keys }
+
+ Page::Profile::SSHKeys.perform do |page|
+ page.add_key(public_key, title)
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/git/repository.rb b/qa/qa/git/repository.rb
index faecacd45ec..14cb8125fdb 100644
--- a/qa/qa/git/repository.rb
+++ b/qa/qa/git/repository.rb
@@ -7,6 +7,10 @@ module QA
class Repository
include Scenario::Actable
+ def initialize
+ @ssh_cmd = ""
+ end
+
def self.perform(*args)
Dir.mktmpdir do |dir|
Dir.chdir(dir) { super }
@@ -38,7 +42,7 @@ module QA
end
def clone(opts = '')
- run_and_redact_credentials("git clone #{opts} #{@uri} ./")
+ run_and_redact_credentials(build_git_command("git clone #{opts} #{@uri} ./"))
end
def checkout(branch_name)
@@ -58,6 +62,10 @@ module QA
`git config user.email #{email}`
end
+ def configure_ssh_command(command)
+ @ssh_cmd = "GIT_SSH_COMMAND='#{command}'"
+ end
+
def commit_file(name, contents, message)
add_file(name, contents)
commit(message)
@@ -74,7 +82,7 @@ module QA
end
def push_changes(branch = 'master')
- output, _ = run_and_redact_credentials("git push #{@uri} #{branch}")
+ output, _ = run_and_redact_credentials(build_git_command("git push #{@uri} #{branch}"))
output
end
@@ -83,6 +91,31 @@ module QA
`git log --oneline`.split("\n")
end
+ def use_ssh_key(key)
+ @private_key_file = Tempfile.new("id_#{SecureRandom.hex(8)}")
+ File.binwrite(@private_key_file, key.private_key)
+ File.chmod(0700, @private_key_file)
+
+ @known_hosts_file = Tempfile.new("known_hosts_#{SecureRandom.hex(8)}")
+ keyscan_params = ['-H']
+ keyscan_params << "-p #{@uri.port}" if @uri.port
+ keyscan_params << @uri.host
+ run_and_redact_credentials("ssh-keyscan #{keyscan_params.join(' ')} >> #{@known_hosts_file.path}")
+
+ configure_ssh_command("ssh -i #{@private_key_file.path} -o UserKnownHostsFile=#{@known_hosts_file.path}")
+ end
+
+ def delete_ssh_key
+ return unless @private_key_file
+
+ @private_key_file.close(true)
+ @known_hosts_file.close(true)
+ end
+
+ def build_git_command(command_str)
+ [@ssh_cmd, command_str].compact.join(' ')
+ end
+
private
# Since the remote URL contains the credentials, and git occasionally
diff --git a/qa/qa/page/admin/settings/main.rb b/qa/qa/page/admin/settings/main.rb
index db3387b4557..73034ffe0d8 100644
--- a/qa/qa/page/admin/settings/main.rb
+++ b/qa/qa/page/admin/settings/main.rb
@@ -6,11 +6,11 @@ module QA
include QA::Page::Settings::Common
view 'app/views/admin/application_settings/show.html.haml' do
- element :repository_storage_settings
+ element :terms_settings
end
def expand_repository_storage(&block)
- expand_section(:repository_storage_settings) do
+ expand_section(:terms_settings) do
RepositoryStorage.perform(&block)
end
end
diff --git a/qa/qa/page/main/login.rb b/qa/qa/page/main/login.rb
index 08cf8da34fd..e9e49964e63 100644
--- a/qa/qa/page/main/login.rb
+++ b/qa/qa/page/main/login.rb
@@ -3,31 +3,31 @@ module QA
module Main
class Login < Page::Base
view 'app/views/devise/passwords/edit.html.haml' do
- element :password_field, 'password_field :password'
- element :password_confirmation, 'password_field :password_confirmation'
- element :change_password_button, 'submit "Change your password"'
+ element :password_field
+ element :password_confirmation
+ element :change_password_button
end
view 'app/views/devise/sessions/_new_base.html.haml' do
- element :login_field, 'text_field :login'
- element :password_field, 'password_field :password'
- element :sign_in_button, 'submit "Sign in"'
+ element :login_field
+ element :password_field
+ element :sign_in_button
end
view 'app/views/devise/sessions/_new_ldap.html.haml' do
- element :username_field, 'text_field_tag :username'
- element :password_field, 'password_field_tag :password'
- element :sign_in_button, 'submit_tag "Sign in"'
+ element :username_field
+ element :password_field
+ element :sign_in_button
end
view 'app/views/devise/shared/_tabs_ldap.html.haml' do
- element :ldap_tab, "link_to server['label']"
- element :standard_tab, "link_to 'Standard'"
+ element :ldap_tab
+ element :standard_tab
end
view 'app/views/devise/shared/_tabs_normal.html.haml' do
- element :sign_in_tab, /nav-link.*login-pane.*Sign in/
- element :register_tab, /nav-link.*register-pane.*Register/
+ element :sign_in_tab
+ element :register_tab
end
def initialize
@@ -66,6 +66,8 @@ module QA
end
using_wait_time 0 do
+ set_initial_password_if_present
+
sign_in_using_gitlab_credentials(admin)
end
@@ -85,19 +87,19 @@ module QA
end
def switch_to_sign_in_tab
- click_on 'Sign in'
+ click_element :sign_in_tab
end
def switch_to_register_tab
- click_on 'Register'
+ click_element :register_tab
end
def switch_to_ldap_tab
- click_on 'LDAP'
+ click_element :ldap_tab
end
def switch_to_standard_tab
- click_on 'Standard'
+ click_element :standard_tab
end
private
@@ -105,26 +107,26 @@ module QA
def sign_in_using_ldap_credentials
switch_to_ldap_tab
- fill_in :username, with: Runtime::User.ldap_username
- fill_in :password, with: Runtime::User.ldap_password
- click_button 'Sign in'
+ fill_element :username_field, Runtime::User.ldap_username
+ fill_element :password_field, Runtime::User.ldap_password
+ click_element :sign_in_button
end
def sign_in_using_gitlab_credentials(user)
switch_to_sign_in_tab unless sign_in_tab?
switch_to_standard_tab if ldap_tab?
- fill_in :user_login, with: user.username
- fill_in :user_password, with: user.password
- click_button 'Sign in'
+ fill_element :login_field, user.username
+ fill_element :password_field, user.password
+ click_element :sign_in_button
end
def set_initial_password_if_present
return unless page.has_content?('Change your password')
- fill_in :user_password, with: Runtime::User.password
- fill_in :user_password_confirmation, with: Runtime::User.password
- click_button 'Change your password'
+ fill_element :password_field, Runtime::User.password
+ fill_element :password_confirmation, Runtime::User.password
+ click_element :change_password_button
end
end
end
diff --git a/qa/qa/page/menu/profile.rb b/qa/qa/page/menu/profile.rb
index 95e88d863e4..7e24fa85c33 100644
--- a/qa/qa/page/menu/profile.rb
+++ b/qa/qa/page/menu/profile.rb
@@ -6,6 +6,7 @@ module QA
element :access_token_link, 'link_to profile_personal_access_tokens_path'
element :access_token_title, 'Access Tokens'
element :top_level_items, '.sidebar-top-level-items'
+ element :ssh_keys, 'SSH Keys'
end
def click_access_tokens
@@ -14,6 +15,12 @@ module QA
end
end
+ def click_ssh_keys
+ within_sidebar do
+ click_link('SSH Keys')
+ end
+ end
+
private
def within_sidebar
diff --git a/qa/qa/page/menu/side.rb b/qa/qa/page/menu/side.rb
index 354ccec2a5a..a1eedfea42e 100644
--- a/qa/qa/page/menu/side.rb
+++ b/qa/qa/page/menu/side.rb
@@ -6,6 +6,7 @@ module QA
element :settings_item
element :settings_link, 'link_to edit_project_path'
element :repository_link, "title: _('Repository')"
+ element :link_pipelines
element :pipelines_settings_link, "title: _('CI / CD')"
element :operations_kubernetes_link, "title: _('Kubernetes')"
element :issues_link, /link_to.*shortcuts-issues/
@@ -49,7 +50,7 @@ module QA
def click_ci_cd_pipelines
within_sidebar do
- click_link('CI / CD')
+ click_element :link_pipelines
end
end
diff --git a/qa/qa/page/merge_request/show.rb b/qa/qa/page/merge_request/show.rb
index c200f14f4fb..befb7c1809a 100644
--- a/qa/qa/page/merge_request/show.rb
+++ b/qa/qa/page/merge_request/show.rb
@@ -5,6 +5,9 @@ module QA
view 'app/assets/javascripts/vue_merge_request_widget/components/states/ready_to_merge.vue' do
element :merge_button
element :fast_forward_message, 'Fast-forward merge without a merge commit'
+ element :merge_moment_dropdown
+ element :merge_when_pipeline_succeeds_option
+ element :merge_immediately_option
end
view 'app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_merged.vue' do
@@ -27,7 +30,20 @@ module QA
def has_merge_button?
refresh
- has_selector?('.accept-merge-request')
+ has_css?(element_selector_css(:merge_button))
+ end
+
+ def has_merge_options?
+ has_css?(element_selector_css(:merge_moment_dropdown))
+ end
+
+ def merge_immediately
+ if has_merge_options?
+ click_element :merge_moment_dropdown
+ click_element :merge_immediately_option
+ else
+ click_element :merge_button
+ end
end
def rebase!
@@ -59,7 +75,7 @@ module QA
!first(element_selector_css(:merge_button)).disabled?
end
- click_element :merge_button
+ merge_immediately
wait(reload: false) do
has_text?('The changes were merged into')
diff --git a/qa/qa/page/profile/ssh_keys.rb b/qa/qa/page/profile/ssh_keys.rb
new file mode 100644
index 00000000000..ce1813b14d0
--- /dev/null
+++ b/qa/qa/page/profile/ssh_keys.rb
@@ -0,0 +1,34 @@
+# frozen_string_literal: true
+
+module QA
+ module Page
+ module Profile
+ class SSHKeys < Page::Base
+ view 'app/views/profiles/keys/_form.html.haml' do
+ element :key_title_field
+ element :key_public_key_field
+ element :add_key_button
+ end
+
+ view 'app/views/profiles/keys/_key_details.html.haml' do
+ element :delete_key_button
+ end
+
+ def add_key(public_key, title)
+ fill_element :key_public_key_field, public_key
+ fill_element :key_title_field, title
+
+ click_element :add_key_button
+ end
+
+ def remove_key(title)
+ click_link(title)
+
+ accept_alert do
+ click_element :delete_key_button
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/add_ssh_key_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/add_ssh_key_spec.rb
new file mode 100644
index 00000000000..84f663c4866
--- /dev/null
+++ b/qa/qa/specs/features/browser_ui/3_create/repository/add_ssh_key_spec.rb
@@ -0,0 +1,31 @@
+# frozen_string_literal: true
+
+module QA
+ context :create do
+ describe 'SSH keys support' do
+ let(:key_title) { "key for ssh tests #{Time.now.to_f}" }
+
+ it 'user adds and then removes an SSH key' do
+ Runtime::Browser.visit(:gitlab, Page::Main::Login)
+ Page::Main::Login.act { sign_in_using_credentials }
+
+ key = Factory::Resource::SSHKey.fabricate! do |resource|
+ resource.title = key_title
+ end
+
+ expect(page).to have_content("Title: #{key_title}")
+ expect(page).to have_content(key.fingerprint)
+
+ Page::Menu::Main.act { go_to_profile_settings }
+ Page::Menu::Profile.act { click_ssh_keys }
+
+ Page::Profile::SSHKeys.perform do |ssh_keys|
+ ssh_keys.remove_key(key_title)
+ end
+
+ expect(page).not_to have_content("Title: #{key_title}")
+ expect(page).not_to have_content(key.fingerprint)
+ end
+ end
+ end
+end
diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/use_ssh_key_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/use_ssh_key_spec.rb
new file mode 100644
index 00000000000..7c989bfd8cc
--- /dev/null
+++ b/qa/qa/specs/features/browser_ui/3_create/repository/use_ssh_key_spec.rb
@@ -0,0 +1,40 @@
+# frozen_string_literal: true
+
+module QA
+ context :create do
+ describe 'SSH key support' do
+ # Note: If you run this test against GDK make sure you've enabled sshd
+ # See: https://gitlab.com/gitlab-org/gitlab-qa/blob/master/docs/run_qa_against_gdk.md
+
+ let(:key_title) { "key for ssh tests #{Time.now.to_f}" }
+
+ it 'user adds an ssh key and pushes code to the repository' do
+ Runtime::Browser.visit(:gitlab, Page::Main::Login)
+ Page::Main::Login.act { sign_in_using_credentials }
+
+ key = Factory::Resource::SSHKey.fabricate! do |resource|
+ resource.title = key_title
+ end
+
+ Factory::Repository::ProjectPush.fabricate! do |push|
+ push.ssh_key = key
+ push.file_name = 'README.md'
+ push.file_content = '# Test Use SSH Key'
+ push.commit_message = 'Add README.md'
+ end
+
+ Page::Project::Show.act { wait_for_push }
+
+ expect(page).to have_content('README.md')
+ expect(page).to have_content('Test Use SSH Key')
+
+ Page::Menu::Main.act { go_to_profile_settings }
+ Page::Menu::Profile.act { click_ssh_keys }
+
+ Page::Profile::SSHKeys.perform do |ssh_keys|
+ ssh_keys.remove_key(key_title)
+ end
+ end
+ end
+ end
+end
diff --git a/rubocop/cop/avoid_route_redirect_leading_slash.rb b/rubocop/cop/avoid_route_redirect_leading_slash.rb
new file mode 100644
index 00000000000..7ac1c881269
--- /dev/null
+++ b/rubocop/cop/avoid_route_redirect_leading_slash.rb
@@ -0,0 +1,52 @@
+# frozen_string_literal: true
+
+module RuboCop
+ module Cop
+ # Checks for a leading '/' in route redirects
+ # For more information see: https://gitlab.com/gitlab-org/gitlab-ce/issues/50645
+ #
+ # @example
+ # # bad
+ # root to: redirect('/-/instance/statistics/conversational_development_index')
+ #
+ # # good
+ # root to: redirect('-/instance/statistics/conversational_development_index')
+ #
+
+ class AvoidRouteRedirectLeadingSlash < RuboCop::Cop::Cop
+ MSG = 'Do not use a leading "/" in route redirects'
+
+ def_node_matcher :leading_slash_in_redirect?, <<~PATTERN
+ (send nil? :redirect (str #has_leading_slash?))
+ PATTERN
+
+ def on_send(node)
+ return unless in_routes?(node)
+ return unless leading_slash_in_redirect?(node)
+
+ add_offense(node)
+ end
+
+ def has_leading_slash?(str)
+ str.start_with?("/")
+ end
+
+ def in_routes?(node)
+ path = node.location.expression.source_buffer.name
+ dirname = File.dirname(path)
+ filename = File.basename(path)
+ dirname.end_with?('config/routes') || filename.end_with?('routes.rb')
+ end
+
+ def autocorrect(node)
+ lambda do |corrector|
+ corrector.replace(node.loc.expression, remove_leading_slash(node))
+ end
+ end
+
+ def remove_leading_slash(node)
+ node.source.sub('/', '')
+ end
+ end
+ end
+end
diff --git a/rubocop/cop/gitlab/union.rb b/rubocop/cop/gitlab/union.rb
new file mode 100644
index 00000000000..09541d8af3b
--- /dev/null
+++ b/rubocop/cop/gitlab/union.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+require_relative '../../spec_helpers'
+
+module RuboCop
+ module Cop
+ module Gitlab
+ # Cop that disallows the use of `Gitlab::SQL::Union`, in favour of using
+ # the `FromUnion` module.
+ class Union < RuboCop::Cop::Cop
+ include SpecHelpers
+
+ MSG = 'Use the `FromUnion` concern, instead of using `Gitlab::SQL::Union` directly'
+
+ def_node_matcher :raw_union?, <<~PATTERN
+ (send (const (const (const nil? :Gitlab) :SQL) :Union) :new ...)
+ PATTERN
+
+ def on_send(node)
+ return unless raw_union?(node)
+ return if in_spec?(node)
+
+ add_offense(node, location: :expression)
+ end
+ end
+ end
+ end
+end
diff --git a/rubocop/cop/ruby_interpolation_in_translation.rb b/rubocop/cop/ruby_interpolation_in_translation.rb
index b9411fcfd6c..c431b4a1977 100644
--- a/rubocop/cop/ruby_interpolation_in_translation.rb
+++ b/rubocop/cop/ruby_interpolation_in_translation.rb
@@ -6,7 +6,6 @@ module RuboCop
MSG = "Don't use ruby interpolation \#{} inside translated strings, instead use \%{}"
TRANSLATION_METHODS = ':_ :s_ :N_ :n_'
- RUBY_INTERPOLATION_REGEX = /.*\#\{.*\}/
def_node_matcher :translation_method?, <<~PATTERN
(send nil? {#{TRANSLATION_METHODS}} $dstr ...)
diff --git a/rubocop/rubocop.rb b/rubocop/rubocop.rb
index 46bd7d3bec6..ff929c7b6ce 100644
--- a/rubocop/rubocop.rb
+++ b/rubocop/rubocop.rb
@@ -3,9 +3,11 @@ require_relative 'cop/gitlab/module_with_instance_variables'
require_relative 'cop/gitlab/predicate_memoization'
require_relative 'cop/gitlab/httparty'
require_relative 'cop/gitlab/finder_with_find_by'
+require_relative 'cop/gitlab/union'
require_relative 'cop/include_sidekiq_worker'
require_relative 'cop/avoid_return_from_blocks'
require_relative 'cop/avoid_break_from_strong_memoize'
+require_relative 'cop/avoid_route_redirect_leading_slash'
require_relative 'cop/line_break_around_conditional_block'
require_relative 'cop/prefer_class_methods_over_module'
require_relative 'cop/migration/add_column'
diff --git a/scripts/trigger-build b/scripts/trigger-build
index 798bf1e82b7..0b5fd5995dd 100755
--- a/scripts/trigger-build
+++ b/scripts/trigger-build
@@ -1,122 +1,144 @@
#!/usr/bin/env ruby
-require 'net/http'
-require 'json'
-require 'cgi'
+require 'gitlab'
+
+#
+# Configure credentials to be used with gitlab gem
+#
+Gitlab.configure do |config|
+ config.endpoint = 'https://gitlab.com/api/v4'
+ config.private_token = ENV['GITLAB_QA_ACCESS_TOKEN'] # gitlab-qa bot access token
+end
module Trigger
- OMNIBUS_PROJECT_PATH = 'gitlab-org/omnibus-gitlab'.freeze
- CNG_PROJECT_PATH = 'gitlab-org/build/CNG'.freeze
TOKEN = ENV['BUILD_TRIGGER_TOKEN']
def self.ee?
ENV['CI_PROJECT_NAME'] == 'gitlab-ee' || File.exist?('CHANGELOG-EE.md')
end
- class Omnibus
- def initialize
- @uri = URI("https://gitlab.com/api/v4/projects/#{CGI.escape(Trigger::OMNIBUS_PROJECT_PATH)}/trigger/pipeline")
- @params = env_params.merge(file_params).merge(token: Trigger::TOKEN)
+ class Base
+ def initialize(api_token)
+ Gitlab.private_token = api_token
end
- def invoke!
- res = Net::HTTP.post_form(@uri, @params)
- id = JSON.parse(res.body)['id']
- project = Trigger::OMNIBUS_PROJECT_PATH
+ def invoke!(post_comment: false)
+ pipeline = Gitlab.run_trigger(
+ downstream_project_path,
+ Trigger::TOKEN,
+ ref,
+ variables)
- if id
- puts "Triggered https://gitlab.com/#{project}/pipelines/#{id}"
- puts "Waiting for downstream pipeline status"
- else
- raise "Trigger failed! The response from the trigger is: #{res.body}"
- end
+ puts "Triggered #{pipeline.web_url}"
+ puts "Waiting for downstream pipeline status"
- Trigger::Pipeline.new(project, id)
+ begin
+ Trigger::CommitComment.post!(downstream_project_path, pipeline) if post_comment
+ rescue Gitlab::Error::Error => error
+ puts "Ignoring the following error: #{error}"
+ end
+ Trigger::Pipeline.new(downstream_project_path, pipeline.id)
end
private
- def env_params
+ # Must be overriden
+ def downstream_project_path
+ raise NotImplementedError
+ end
+
+ # Must be overriden
+ def ref
+ raise NotImplementedError
+ end
+
+ # Can be overriden
+ def extra_variables
+ {}
+ end
+
+ # Can be overriden
+ def version_param_value(version_file)
+ File.read(version_file).strip
+ end
+
+ def variables
+ base_variables.merge(extra_variables).merge(version_file_variables)
+ end
+
+ def base_variables
{
- "ref" => ENV["OMNIBUS_BRANCH"] || "master",
- "variables[GITLAB_VERSION]" => ENV["CI_COMMIT_SHA"],
- "variables[ALTERNATIVE_SOURCES]" => true,
- "variables[ee]" => Trigger.ee? ? 'true' : 'false',
- "variables[TRIGGERED_USER]" => ENV["GITLAB_USER_NAME"],
- "variables[TRIGGER_SOURCE]" => "https://gitlab.com/gitlab-org/#{ENV['CI_PROJECT_NAME']}/-/jobs/#{ENV['CI_JOB_ID']}"
+ 'TRIGGERED_USER' => ENV['GITLAB_USER_NAME'],
+ 'TRIGGER_SOURCE' => ENV['CI_JOB_URL']
}
end
- def file_params
- Hash.new.tap do |params|
- Dir.glob("*_VERSION").each do |version_file|
- params["variables[#{version_file}]"] = File.read(version_file).strip
- end
+ # Read version files from all components
+ def version_file_variables
+ Dir.glob("*_VERSION").each_with_object({}) do |version_file, params|
+ params[version_file] = version_param_value(version_file)
end
end
end
- class CNG
- def initialize
- @uri = URI("https://gitlab.com/api/v4/projects/#{CGI.escape(Trigger::CNG_PROJECT_PATH)}/trigger/pipeline")
- @ref_name = ENV['CI_COMMIT_REF_NAME']
- @username = ENV['GITLAB_USER_NAME']
- @project_name = ENV['CI_PROJECT_NAME']
- @job_id = ENV['CI_JOB_ID']
- @params = env_params.merge(file_params).merge(token: Trigger::TOKEN)
- end
-
- #
- # Trigger a pipeline
- #
- def invoke!
- res = Net::HTTP.post_form(@uri, @params)
- id = JSON.parse(res.body)['id']
- project = Trigger::CNG_PROJECT_PATH
-
- if id
- puts "Triggered https://gitlab.com/#{project}/pipelines/#{id}"
- puts "Waiting for downstream pipeline status"
- else
- raise "Trigger failed! The response from the trigger is: #{res.body}"
- end
+ class Omnibus < Base
+ private
- Trigger::Pipeline.new(project, id)
+ def downstream_project_path
+ 'gitlab-org/omnibus-gitlab'.freeze
end
+ def ref
+ ENV['OMNIBUS_BRANCH'] || 'master'
+ end
+
+ def extra_variables
+ {
+ 'GITLAB_VERSION' => ENV['CI_COMMIT_SHA'],
+ 'ALTERNATIVE_SOURCES' => 'true',
+ 'ee' => Trigger.ee? ? 'true' : 'false'
+ }
+ end
+ end
+
+ class CNG < Base
private
- def env_params
- params = {
- "ref" => ENV["CNG_BRANCH"] || "master",
- "variables[TRIGGERED_USER]" => @username,
- "variables[TRIGGER_SOURCE]" => "https://gitlab.com/gitlab-org/#{@project_name}/-/jobs/#{@job_id}"
+ def downstream_project_path
+ ENV['CNG_PROJECT_PATH'] || 'gitlab-org/build/CNG-mirror'
+ end
+
+ def ref
+ ENV['CNG_BRANCH'] || 'master'
+ end
+
+ def extra_variables
+ edition = Trigger.ee? ? 'EE' : 'CE'
+
+ {
+ "GITLAB_#{edition}_VERSION" => ENV['CI_COMMIT_REF_NAME'],
+ "#{edition}_PIPELINE" => 'true'
}
+ end
- if Trigger.ee?
- params["variables[GITLAB_EE_VERSION]"] = @ref_name
- params["variables[EE_PIPELINE]"] = 'true'
+ def version_param_value(_version_file)
+ raw_version = super
+
+ # if the version matches semver format, treat it as a tag and prepend `v`
+ if raw_version =~ Regexp.compile(/^\d+\.\d+\.\d+(-rc\d+)?(-ee)?$/)
+ "v#{raw_version}"
else
- params["variables[GITLAB_CE_VERSION]"] = @ref_name
- params["variables[CE_PIPELINE]"] = 'true'
+ raw_version
end
-
- params
end
+ end
- # Read version files from all components
- def file_params
- Dir.glob("*_VERSION").each_with_object({}) do |version_file, params|
- raw_version = File.read(version_file).strip
- # if the version matches semver format, treat it as a tag and prepend `v`
- version = if raw_version =~ Regexp.compile(/^\d+\.\d+\.\d+(-rc\d+)?(-ee)?$/)
- "v#{raw_version}"
- else
- raw_version
- end
-
- params["variables[#{version_file}]"] = version
- end
+ class CommitComment
+ def self.post!(downstream_project_path, downstream_pipeline)
+ Gitlab.create_commit_comment(
+ ENV['CI_PROJECT_PATH'],
+ ENV['CI_COMMIT_SHA'],
+ "The [`#{ENV['CI_JOB_NAME']}`](#{ENV['CI_JOB_URL']}) job from pipeline #{ENV['CI_PIPELINE_URL']} triggered #{downstream_pipeline.web_url} downstream.")
end
end
@@ -124,9 +146,15 @@ module Trigger
INTERVAL = 60 # seconds
MAX_DURATION = 3600 * 3 # 3 hours
+ attr_reader :project, :id
+
def initialize(project, id)
+ @project = project
+ @id = id
@start = Time.now.to_i
- @uri = URI("https://gitlab.com/api/v4/projects/#{CGI.escape(project)}/pipelines/#{id}")
+
+ # gitlab-bot's token "GitLab multi-project pipeline polling"
+ Gitlab.private_token = ENV['GITLAB_BOT_MULTI_PROJECT_PIPELINE_POLLING_TOKEN']
end
def wait!
@@ -157,15 +185,9 @@ module Trigger
end
def status
- req = Net::HTTP::Get.new(@uri)
- req['PRIVATE-TOKEN'] = ENV['GITLAB_QA_ACCESS_TOKEN']
-
- res = Net::HTTP.start(@uri.hostname, @uri.port, use_ssl: true) do |http|
- http.request(req)
- end
-
- JSON.parse(res.body)['status'].to_s.to_sym
- rescue JSON::ParserError
+ Gitlab.pipeline(project, id).status.to_sym
+ rescue Gitlab::Error::Error => error
+ puts "Ignoring the following error: #{error}"
# Ignore GitLab API hiccups. If GitLab is really down, we'll hit the job
# timeout anyway.
:running
@@ -175,9 +197,9 @@ end
case ARGV[0]
when 'omnibus'
- Trigger::Omnibus.new.invoke!.wait!
+ Trigger::Omnibus.new(ENV['GITLAB_QA_ACCESS_TOKEN']).invoke!(post_comment: true).wait!
when 'cng'
- Trigger::CNG.new.invoke!.wait!
+ Trigger::CNG.new(ENV['GITLAB_QA_ACCESS_TOKEN']).invoke!.wait!
else
puts "Please provide a valid option:
omnibus - Triggers a pipeline that builds the omnibus-gitlab package
diff --git a/scripts/trigger-build-docs b/scripts/trigger-build-docs
index 9ee35684509..dfc8ee6050a 100755
--- a/scripts/trigger-build-docs
+++ b/scripts/trigger-build-docs
@@ -6,8 +6,8 @@ require 'gitlab'
# Configure credentials to be used with gitlab gem
#
Gitlab.configure do |config|
- config.endpoint = 'https://gitlab.com/api/v4'
- config.private_token = ENV["DOCS_API_TOKEN"] # GitLab Docs bot access token with Developer access to gitlab-docs
+ config.endpoint = 'https://gitlab.com/api/v4'
+ config.private_token = ENV["DOCS_API_TOKEN"] # GitLab Docs bot access token with Developer access to gitlab-docs
end
#
@@ -99,7 +99,7 @@ def trigger_pipeline
puts "=> Follow the status of the triggered pipeline:"
puts ""
- puts "https://gitlab.com/gitlab-com/gitlab-docs/pipelines/#{pipeline.id}"
+ puts pipeline.web_url
puts ""
puts "=> In a few minutes, you will be able to preview your changes under the following URL:"
puts ""
diff --git a/spec/controllers/oauth/applications_controller_spec.rb b/spec/controllers/oauth/applications_controller_spec.rb
index 1195f44f37d..ace8a954e92 100644
--- a/spec/controllers/oauth/applications_controller_spec.rb
+++ b/spec/controllers/oauth/applications_controller_spec.rb
@@ -15,14 +15,44 @@ describe Oauth::ApplicationsController do
expect(response).to have_gitlab_http_status(200)
end
- it 'redirects back to profile page if OAuth applications are disabled' do
- allow(Gitlab::CurrentSettings.current_application_settings).to receive(:user_oauth_applications?).and_return(false)
+ it 'shows list of applications' do
+ disable_user_oauth
get :index
+ expect(response).to have_gitlab_http_status(200)
+ end
+ end
+
+ describe 'POST #create' do
+ it 'creates an application' do
+ post :create, oauth_params
+
+ expect(response).to have_gitlab_http_status(302)
+ expect(response).to redirect_to(oauth_application_path(Doorkeeper::Application.last))
+ end
+
+ it 'redirects back to profile page if OAuth applications are disabled' do
+ disable_user_oauth
+
+ post :create, oauth_params
+
expect(response).to have_gitlab_http_status(302)
expect(response).to redirect_to(profile_path)
end
end
end
+
+ def disable_user_oauth
+ allow(Gitlab::CurrentSettings.current_application_settings).to receive(:user_oauth_applications?).and_return(false)
+ end
+
+ def oauth_params
+ {
+ doorkeeper_application: {
+ name: 'foo',
+ redirect_uri: 'http://example.org'
+ }
+ }
+ end
end
diff --git a/spec/controllers/projects/jobs_controller_spec.rb b/spec/controllers/projects/jobs_controller_spec.rb
index 19c46e2f309..c82c85970dc 100644
--- a/spec/controllers/projects/jobs_controller_spec.rb
+++ b/spec/controllers/projects/jobs_controller_spec.rb
@@ -288,6 +288,55 @@ describe Projects::JobsController, :clean_gitlab_redis_shared_state do
end
end
end
+
+ context 'when no runners are available' do
+ let(:runner) { create(:ci_runner, :instance, active: false) }
+ let(:job) { create(:ci_build, :pending, pipeline: pipeline, runner: runner) }
+
+ it 'exposes needed information' do
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(response).to match_response_schema('job/job_details')
+ expect(json_response['runners']['online']).to be false
+ expect(json_response['runners']['available']).to be false
+ end
+ end
+
+ context 'when no runner is online' do
+ let(:runner) { create(:ci_runner, :instance) }
+ let(:job) { create(:ci_build, :pending, pipeline: pipeline, runner: runner) }
+
+ it 'exposes needed information' do
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(response).to match_response_schema('job/job_details')
+ expect(json_response['runners']['online']).to be false
+ expect(json_response['runners']['available']).to be true
+ end
+ end
+
+ context 'settings_path' do
+ context 'when user is developer' do
+ it 'settings_path is not available' do
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(response).to match_response_schema('job/job_details')
+ expect(json_response['runners']).not_to have_key('settings_path')
+ end
+ end
+
+ context 'when user is maintainer' do
+ let(:user) { create(:user, :admin) }
+
+ before do
+ project.add_maintainer(user)
+ sign_in(user)
+ end
+
+ it 'settings_path is available' do
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(response).to match_response_schema('job/job_details')
+ expect(json_response['runners']['settings_path']).to match(/runners/)
+ end
+ end
+ end
end
context 'when requesting JSON job is triggered' do
diff --git a/spec/controllers/projects/notes_controller_spec.rb b/spec/controllers/projects/notes_controller_spec.rb
index 81badaac76b..e48c9dea976 100644
--- a/spec/controllers/projects/notes_controller_spec.rb
+++ b/spec/controllers/projects/notes_controller_spec.rb
@@ -207,6 +207,14 @@ describe Projects::NotesController do
expect(response).to have_gitlab_http_status(200)
end
+ it 'returns discussion JSON when the return_discussion param is set' do
+ post :create, request_params.merge(format: :json, return_discussion: 'true')
+
+ expect(response).to have_gitlab_http_status(200)
+ expect(json_response).to have_key 'discussion'
+ expect(json_response['discussion']['notes'][0]['note']).to eq(request_params[:note][:note])
+ end
+
context 'when merge_request_diff_head_sha present' do
before do
service_params = {
diff --git a/spec/factories/users.rb b/spec/factories/users.rb
index 59db8cdc34b..a47bd7cafca 100644
--- a/spec/factories/users.rb
+++ b/spec/factories/users.rb
@@ -58,6 +58,14 @@ FactoryBot.define do
project_view :readme
end
+ trait :commit_email do
+ after(:create) do |user, evaluator|
+ additional = create(:email, :confirmed, user: user, email: "commit-#{user.email}")
+
+ user.update!(commit_email: additional.email)
+ end
+ end
+
factory :omniauth_user do
transient do
extern_uid '123456'
diff --git a/spec/features/admin/admin_runners_spec.rb b/spec/features/admin/admin_runners_spec.rb
index 026dea8d22c..a6ab6a5696a 100644
--- a/spec/features/admin/admin_runners_spec.rb
+++ b/spec/features/admin/admin_runners_spec.rb
@@ -19,7 +19,7 @@ describe "Admin Runners" do
create(:ci_build, pipeline: pipeline, runner_id: runner.id)
visit admin_runners_path
- expect(page).to have_text "Setup a shared Runner manually"
+ expect(page).to have_text "Set up a shared Runner manually"
expect(page).to have_text "Runners currently online: 1"
end
@@ -125,7 +125,7 @@ describe "Admin Runners" do
end
it 'has all necessary texts including no runner message' do
- expect(page).to have_text "Setup a shared Runner manually"
+ expect(page).to have_text "Set up a shared Runner manually"
expect(page).to have_text "Runners currently online: 0"
expect(page).to have_text 'No runners found'
end
diff --git a/spec/features/admin/admin_settings_spec.rb b/spec/features/admin/admin_settings_spec.rb
index 3c65b5898b4..3fb818af8f0 100644
--- a/spec/features/admin/admin_settings_spec.rb
+++ b/spec/features/admin/admin_settings_spec.rb
@@ -9,340 +9,375 @@ describe 'Admin updates settings' do
before do
stub_env('IN_MEMORY_APPLICATION_SETTINGS', 'false')
sign_in(admin)
- visit admin_application_settings_path
end
- it 'Change visibility settings' do
- page.within('.as-visibility-access') do
- choose "application_setting_default_project_visibility_20"
- click_button 'Save changes'
+ context 'General page' do
+ before do
+ visit admin_application_settings_path
end
- expect(page).to have_content "Application settings saved successfully"
- end
+ it 'Change visibility settings' do
+ page.within('.as-visibility-access') do
+ choose "application_setting_default_project_visibility_20"
+ click_button 'Save changes'
+ end
- it 'Uncheck all restricted visibility levels' do
- page.within('.as-visibility-access') do
- find('#application_setting_visibility_level_0').set(false)
- find('#application_setting_visibility_level_10').set(false)
- find('#application_setting_visibility_level_20').set(false)
- click_button 'Save changes'
+ expect(page).to have_content "Application settings saved successfully"
end
- expect(page).to have_content "Application settings saved successfully"
- expect(find('#application_setting_visibility_level_0')).not_to be_checked
- expect(find('#application_setting_visibility_level_10')).not_to be_checked
- expect(find('#application_setting_visibility_level_20')).not_to be_checked
- end
+ it 'Uncheck all restricted visibility levels' do
+ page.within('.as-visibility-access') do
+ find('#application_setting_visibility_level_0').set(false)
+ find('#application_setting_visibility_level_10').set(false)
+ find('#application_setting_visibility_level_20').set(false)
+ click_button 'Save changes'
+ end
+
+ expect(page).to have_content "Application settings saved successfully"
+ expect(find('#application_setting_visibility_level_0')).not_to be_checked
+ expect(find('#application_setting_visibility_level_10')).not_to be_checked
+ expect(find('#application_setting_visibility_level_20')).not_to be_checked
+ end
+
+ it 'Modify import sources' do
+ expect(Gitlab::CurrentSettings.import_sources).not_to be_empty
+
+ page.within('.as-visibility-access') do
+ Gitlab::ImportSources.options.map do |name, _|
+ uncheck name
+ end
+
+ click_button 'Save changes'
+ end
- it 'Modify import sources' do
- expect(Gitlab::CurrentSettings.import_sources).not_to be_empty
+ expect(page).to have_content "Application settings saved successfully"
+ expect(Gitlab::CurrentSettings.import_sources).to be_empty
- page.within('.as-visibility-access') do
- Gitlab::ImportSources.options.map do |name, _|
- uncheck name
+ page.within('.as-visibility-access') do
+ check "Repo by URL"
+ click_button 'Save changes'
end
- click_button 'Save changes'
+ expect(page).to have_content "Application settings saved successfully"
+ expect(Gitlab::CurrentSettings.import_sources).to eq(['git'])
end
- expect(page).to have_content "Application settings saved successfully"
- expect(Gitlab::CurrentSettings.import_sources).to be_empty
+ it 'Change Visibility and Access Controls' do
+ page.within('.as-visibility-access') do
+ uncheck 'Project export enabled'
+ click_button 'Save changes'
+ end
- page.within('.as-visibility-access') do
- check "Repo by URL"
- click_button 'Save changes'
+ expect(Gitlab::CurrentSettings.project_export_enabled).to be_falsey
+ expect(page).to have_content "Application settings saved successfully"
end
- expect(page).to have_content "Application settings saved successfully"
- expect(Gitlab::CurrentSettings.import_sources).to eq(['git'])
- end
+ it 'Change Keys settings' do
+ page.within('.as-visibility-access') do
+ select 'Are forbidden', from: 'RSA SSH keys'
+ select 'Are allowed', from: 'DSA SSH keys'
+ select 'Must be at least 384 bits', from: 'ECDSA SSH keys'
+ select 'Are forbidden', from: 'ED25519 SSH keys'
+ click_on 'Save changes'
+ end
+
+ forbidden = ApplicationSetting::FORBIDDEN_KEY_VALUE.to_s
- it 'Change Visibility and Access Controls' do
- page.within('.as-visibility-access') do
- uncheck 'Project export enabled'
- click_button 'Save changes'
+ expect(page).to have_content 'Application settings saved successfully'
+ expect(find_field('RSA SSH keys').value).to eq(forbidden)
+ expect(find_field('DSA SSH keys').value).to eq('0')
+ expect(find_field('ECDSA SSH keys').value).to eq('384')
+ expect(find_field('ED25519 SSH keys').value).to eq(forbidden)
end
- expect(Gitlab::CurrentSettings.project_export_enabled).to be_falsey
- expect(page).to have_content "Application settings saved successfully"
- end
+ it 'Change Account and Limit Settings' do
+ page.within('.as-account-limit') do
+ uncheck 'Gravatar enabled'
+ click_button 'Save changes'
+ end
- it 'Change Account and Limit Settings' do
- page.within('.as-account-limit') do
- uncheck 'Gravatar enabled'
- click_button 'Save changes'
+ expect(Gitlab::CurrentSettings.gravatar_enabled).to be_falsey
+ expect(page).to have_content "Application settings saved successfully"
end
- expect(Gitlab::CurrentSettings.gravatar_enabled).to be_falsey
- expect(page).to have_content "Application settings saved successfully"
- end
+ it 'Change New users set to external', :js do
+ user_internal_regex = find('#application_setting_user_default_internal_regex', visible: :all)
- it 'Change New users set to external', :js do
- user_internal_regex = find('#application_setting_user_default_internal_regex', visible: :all)
+ expect(user_internal_regex).to be_readonly
+ expect(user_internal_regex['placeholder']).to eq 'To define internal users, first enable new users set to external'
- expect(user_internal_regex).to be_readonly
- expect(user_internal_regex['placeholder']).to eq 'To define internal users, first enable new users set to external'
+ check 'application_setting_user_default_external'
- check 'application_setting_user_default_external'
+ expect(user_internal_regex).not_to be_readonly
+ expect(user_internal_regex['placeholder']).to eq 'Regex pattern'
+ end
- expect(user_internal_regex).not_to be_readonly
- expect(user_internal_regex['placeholder']).to eq 'Regex pattern'
- end
+ it 'Change Sign-in restrictions' do
+ page.within('.as-signin') do
+ fill_in 'Home page URL', with: 'https://about.gitlab.com/'
+ click_button 'Save changes'
+ end
- it 'Change Sign-in restrictions' do
- page.within('.as-signin') do
- fill_in 'Home page URL', with: 'https://about.gitlab.com/'
- click_button 'Save changes'
+ expect(Gitlab::CurrentSettings.home_page_url).to eq "https://about.gitlab.com/"
+ expect(page).to have_content "Application settings saved successfully"
end
- expect(Gitlab::CurrentSettings.home_page_url).to eq "https://about.gitlab.com/"
- expect(page).to have_content "Application settings saved successfully"
- end
+ it 'Terms of Service' do
+ # Already have the admin accept terms, so they don't need to accept in this spec.
+ _existing_terms = create(:term)
+ accept_terms(admin)
- it 'Terms of Service' do
- # Already have the admin accept terms, so they don't need to accept in this spec.
- _existing_terms = create(:term)
- accept_terms(admin)
+ page.within('.as-terms') do
+ check 'Require all users to accept Terms of Service and Privacy Policy when they access GitLab.'
+ fill_in 'Terms of Service Agreement', with: 'Be nice!'
+ click_button 'Save changes'
+ end
- page.within('.as-terms') do
- check 'Require all users to accept Terms of Service and Privacy Policy when they access GitLab.'
- fill_in 'Terms of Service Agreement', with: 'Be nice!'
- click_button 'Save changes'
+ expect(Gitlab::CurrentSettings.enforce_terms).to be(true)
+ expect(Gitlab::CurrentSettings.terms).to eq 'Be nice!'
+ expect(page).to have_content 'Application settings saved successfully'
end
- expect(Gitlab::CurrentSettings.enforce_terms).to be(true)
- expect(Gitlab::CurrentSettings.terms).to eq 'Be nice!'
- expect(page).to have_content 'Application settings saved successfully'
- end
+ it 'Modify oauth providers' do
+ expect(Gitlab::CurrentSettings.disabled_oauth_sign_in_sources).to be_empty
- it 'Modify oauth providers' do
- expect(Gitlab::CurrentSettings.disabled_oauth_sign_in_sources).to be_empty
+ page.within('.as-signin') do
+ uncheck 'Google'
+ click_button 'Save changes'
+ end
- page.within('.as-signin') do
- uncheck 'Google'
- click_button 'Save changes'
- end
+ expect(page).to have_content "Application settings saved successfully"
+ expect(Gitlab::CurrentSettings.disabled_oauth_sign_in_sources).to include('google_oauth2')
- expect(page).to have_content "Application settings saved successfully"
- expect(Gitlab::CurrentSettings.disabled_oauth_sign_in_sources).to include('google_oauth2')
+ page.within('.as-signin') do
+ check "Google"
+ click_button 'Save changes'
+ end
- page.within('.as-signin') do
- check "Google"
- click_button 'Save changes'
+ expect(page).to have_content "Application settings saved successfully"
+ expect(Gitlab::CurrentSettings.disabled_oauth_sign_in_sources).not_to include('google_oauth2')
end
- expect(page).to have_content "Application settings saved successfully"
- expect(Gitlab::CurrentSettings.disabled_oauth_sign_in_sources).not_to include('google_oauth2')
- end
+ it 'Oauth providers do not raise validation errors when saving unrelated changes' do
+ expect(Gitlab::CurrentSettings.disabled_oauth_sign_in_sources).to be_empty
- it 'Oauth providers do not raise validation errors when saving unrelated changes' do
- expect(Gitlab::CurrentSettings.disabled_oauth_sign_in_sources).to be_empty
+ page.within('.as-signin') do
+ uncheck 'Google'
+ click_button 'Save changes'
+ end
- page.within('.as-signin') do
- uncheck 'Google'
- click_button 'Save changes'
- end
+ expect(page).to have_content "Application settings saved successfully"
+ expect(Gitlab::CurrentSettings.disabled_oauth_sign_in_sources).to include('google_oauth2')
- expect(page).to have_content "Application settings saved successfully"
- expect(Gitlab::CurrentSettings.disabled_oauth_sign_in_sources).to include('google_oauth2')
+ # Remove google_oauth2 from the Omniauth strategies
+ allow(Devise).to receive(:omniauth_providers).and_return([])
- # Remove google_oauth2 from the Omniauth strategies
- allow(Devise).to receive(:omniauth_providers).and_return([])
+ # Save an unrelated setting
+ page.within('.as-terms') do
+ click_button 'Save changes'
+ end
- # Save an unrelated setting
- page.within('.as-ci-cd') do
- click_button 'Save changes'
+ expect(page).to have_content "Application settings saved successfully"
+ expect(Gitlab::CurrentSettings.disabled_oauth_sign_in_sources).to include('google_oauth2')
end
- expect(page).to have_content "Application settings saved successfully"
- expect(Gitlab::CurrentSettings.disabled_oauth_sign_in_sources).to include('google_oauth2')
- end
+ it 'Configure web terminal' do
+ page.within('.as-terminal') do
+ fill_in 'Max session time', with: 15
+ click_button 'Save changes'
+ end
- it 'Change Help page' do
- page.within('.as-help-page') do
- fill_in 'Help page text', with: 'Example text'
- check 'Hide marketing-related entries from help'
- fill_in 'Support page URL', with: 'http://example.com/help'
- click_button 'Save changes'
+ expect(page).to have_content "Application settings saved successfully"
+ expect(Gitlab::CurrentSettings.terminal_max_session_time).to eq(15)
end
-
- expect(Gitlab::CurrentSettings.help_page_text).to eq "Example text"
- expect(Gitlab::CurrentSettings.help_page_hide_commercial_content).to be_truthy
- expect(Gitlab::CurrentSettings.help_page_support_url).to eq "http://example.com/help"
- expect(page).to have_content "Application settings saved successfully"
end
- it 'Change Pages settings' do
- page.within('.as-pages') do
- fill_in 'Maximum size of pages (MB)', with: 15
- check 'Require users to prove ownership of custom domains'
- click_button 'Save changes'
+ context 'Integrations page' do
+ before do
+ visit integrations_admin_application_settings_path
end
- expect(Gitlab::CurrentSettings.max_pages_size).to eq 15
- expect(Gitlab::CurrentSettings.pages_domain_verification_enabled?).to be_truthy
- expect(page).to have_content "Application settings saved successfully"
- end
+ it 'Enable hiding third party offers' do
+ page.within('.as-third-party-offers') do
+ check 'Do not display offers from third parties within GitLab'
+ click_button 'Save changes'
+ end
- it 'Change CI/CD settings' do
- page.within('.as-ci-cd') do
- check 'Default to Auto DevOps pipeline for all projects'
- fill_in 'Auto devops domain', with: 'domain.com'
- click_button 'Save changes'
+ expect(page).to have_content "Application settings saved successfully"
+ expect(Gitlab::CurrentSettings.hide_third_party_offers).to be true
end
- expect(Gitlab::CurrentSettings.auto_devops_enabled?).to be true
- expect(Gitlab::CurrentSettings.auto_devops_domain).to eq('domain.com')
- expect(page).to have_content "Application settings saved successfully"
- end
+ it 'Change Slack Notifications Service template settings' do
+ first(:link, 'Service Templates').click
+ click_link 'Slack notifications'
+ fill_in 'Webhook', with: 'http://localhost'
+ fill_in 'Username', with: 'test_user'
+ fill_in 'service_push_channel', with: '#test_channel'
+ page.check('Notify only broken pipelines')
+ page.check('Notify only default branch')
- it 'Change Influx settings' do
- page.within('.as-influx') do
- check 'Enable InfluxDB Metrics'
- click_button 'Save changes'
- end
+ check_all_events
+ click_on 'Save'
- expect(Gitlab::CurrentSettings.metrics_enabled?).to be true
- expect(page).to have_content "Application settings saved successfully"
- end
+ expect(page).to have_content 'Application settings saved successfully'
- it 'Change Prometheus settings' do
- page.within('.as-prometheus') do
- check 'Enable Prometheus Metrics'
- click_button 'Save changes'
- end
+ click_link 'Slack notifications'
- expect(Gitlab::CurrentSettings.prometheus_metrics_enabled?).to be true
- expect(page).to have_content "Application settings saved successfully"
+ page.all('input[type=checkbox]').each do |checkbox|
+ expect(checkbox).to be_checked
+ end
+ expect(find_field('Webhook').value).to eq 'http://localhost'
+ expect(find_field('Username').value).to eq 'test_user'
+ expect(find('#service_push_channel').value).to eq '#test_channel'
+ end
end
- it 'Change Performance bar settings' do
- group = create(:group)
+ context 'CI/CD page' do
+ it 'Change CI/CD settings' do
+ visit ci_cd_admin_application_settings_path
+
+ page.within('.as-ci-cd') do
+ check 'Default to Auto DevOps pipeline for all projects'
+ fill_in 'Auto devops domain', with: 'domain.com'
+ click_button 'Save changes'
+ end
- page.within('.as-performance-bar') do
- check 'Enable the Performance Bar'
- fill_in 'Allowed group', with: group.path
- click_on 'Save changes'
+ expect(Gitlab::CurrentSettings.auto_devops_enabled?).to be true
+ expect(Gitlab::CurrentSettings.auto_devops_domain).to eq('domain.com')
+ expect(page).to have_content "Application settings saved successfully"
end
+ end
- expect(page).to have_content "Application settings saved successfully"
- expect(find_field('Enable the Performance Bar')).to be_checked
- expect(find_field('Allowed group').value).to eq group.path
+ context 'Reporting page' do
+ it 'Change Spam settings' do
+ visit reporting_admin_application_settings_path
- page.within('.as-performance-bar') do
- uncheck 'Enable the Performance Bar'
- click_on 'Save changes'
- end
+ page.within('.as-spam') do
+ check 'Enable reCAPTCHA'
+ fill_in 'reCAPTCHA Site Key', with: 'key'
+ fill_in 'reCAPTCHA Private Key', with: 'key'
+ fill_in 'IPs per user', with: 15
+ click_button 'Save changes'
+ end
- expect(page).to have_content 'Application settings saved successfully'
- expect(find_field('Enable the Performance Bar')).not_to be_checked
- expect(find_field('Allowed group').value).to be_nil
+ expect(page).to have_content "Application settings saved successfully"
+ expect(Gitlab::CurrentSettings.recaptcha_enabled).to be true
+ expect(Gitlab::CurrentSettings.unique_ips_limit_per_user).to eq(15)
+ end
end
- it 'Change Background jobs settings' do
- page.within('.as-background') do
- fill_in 'Throttling Factor', with: 1
- click_button 'Save changes'
+ context 'Metrics and profiling page' do
+ before do
+ visit metrics_and_profiling_admin_application_settings_path
end
- expect(Gitlab::CurrentSettings.sidekiq_throttling_factor).to eq(1)
- expect(page).to have_content "Application settings saved successfully"
- end
+ it 'Change Influx settings' do
+ page.within('.as-influx') do
+ check 'Enable InfluxDB Metrics'
+ click_button 'Save changes'
+ end
- it 'Change Spam settings' do
- page.within('.as-spam') do
- check 'Enable reCAPTCHA'
- fill_in 'reCAPTCHA Site Key', with: 'key'
- fill_in 'reCAPTCHA Private Key', with: 'key'
- fill_in 'IPs per user', with: 15
- click_button 'Save changes'
+ expect(Gitlab::CurrentSettings.metrics_enabled?).to be true
+ expect(page).to have_content "Application settings saved successfully"
end
- expect(page).to have_content "Application settings saved successfully"
- expect(Gitlab::CurrentSettings.recaptcha_enabled).to be true
- expect(Gitlab::CurrentSettings.unique_ips_limit_per_user).to eq(15)
- end
+ it 'Change Prometheus settings' do
+ page.within('.as-prometheus') do
+ check 'Enable Prometheus Metrics'
+ click_button 'Save changes'
+ end
- it 'Configure web terminal' do
- page.within('.as-terminal') do
- fill_in 'Max session time', with: 15
- click_button 'Save changes'
+ expect(Gitlab::CurrentSettings.prometheus_metrics_enabled?).to be true
+ expect(page).to have_content "Application settings saved successfully"
end
- expect(page).to have_content "Application settings saved successfully"
- expect(Gitlab::CurrentSettings.terminal_max_session_time).to eq(15)
- end
+ it 'Change Performance bar settings' do
+ group = create(:group)
- it 'Enable outbound requests' do
- page.within('.as-outbound') do
- check 'Allow requests to the local network from hooks and services'
- click_button 'Save changes'
- end
+ page.within('.as-performance-bar') do
+ check 'Enable the Performance Bar'
+ fill_in 'Allowed group', with: group.path
+ click_on 'Save changes'
+ end
- expect(page).to have_content "Application settings saved successfully"
- expect(Gitlab::CurrentSettings.allow_local_requests_from_hooks_and_services).to be true
- end
+ expect(page).to have_content "Application settings saved successfully"
+ expect(find_field('Enable the Performance Bar')).to be_checked
+ expect(find_field('Allowed group').value).to eq group.path
+
+ page.within('.as-performance-bar') do
+ uncheck 'Enable the Performance Bar'
+ click_on 'Save changes'
+ end
- it 'Enable hiding third party offers' do
- page.within('.as-third-party-offers') do
- check 'Do not display offers from third parties within GitLab'
- click_button 'Save changes'
+ expect(page).to have_content 'Application settings saved successfully'
+ expect(find_field('Enable the Performance Bar')).not_to be_checked
+ expect(find_field('Allowed group').value).to be_nil
end
- expect(page).to have_content "Application settings saved successfully"
- expect(Gitlab::CurrentSettings.hide_third_party_offers).to be true
- end
+ it 'loads usage ping payload on click', :js do
+ expect(page).to have_button 'Preview payload'
- it 'Change Slack Notifications Service template settings' do
- first(:link, 'Service Templates').click
- click_link 'Slack notifications'
- fill_in 'Webhook', with: 'http://localhost'
- fill_in 'Username', with: 'test_user'
- fill_in 'service_push_channel', with: '#test_channel'
- page.check('Notify only broken pipelines')
- page.check('Notify only default branch')
+ find('.js-usage-ping-payload-trigger').click
- check_all_events
- click_on 'Save'
+ expect(page).to have_selector '.js-usage-ping-payload'
+ expect(page).to have_button 'Hide payload'
+ end
+ end
- expect(page).to have_content 'Application settings saved successfully'
+ context 'Network page' do
+ it 'Enable outbound requests' do
+ visit network_admin_application_settings_path
- click_link 'Slack notifications'
+ page.within('.as-outbound') do
+ check 'Allow requests to the local network from hooks and services'
+ click_button 'Save changes'
+ end
- page.all('input[type=checkbox]').each do |checkbox|
- expect(checkbox).to be_checked
+ expect(page).to have_content "Application settings saved successfully"
+ expect(Gitlab::CurrentSettings.allow_local_requests_from_hooks_and_services).to be true
end
- expect(find_field('Webhook').value).to eq 'http://localhost'
- expect(find_field('Username').value).to eq 'test_user'
- expect(find('#service_push_channel').value).to eq '#test_channel'
end
- it 'Change Keys settings' do
- page.within('.as-visibility-access') do
- select 'Are forbidden', from: 'RSA SSH keys'
- select 'Are allowed', from: 'DSA SSH keys'
- select 'Must be at least 384 bits', from: 'ECDSA SSH keys'
- select 'Are forbidden', from: 'ED25519 SSH keys'
- click_on 'Save changes'
+ context 'Preferences page' do
+ before do
+ visit preferences_admin_application_settings_path
end
- forbidden = ApplicationSetting::FORBIDDEN_KEY_VALUE.to_s
+ it 'Change Help page' do
+ page.within('.as-help-page') do
+ fill_in 'Help page text', with: 'Example text'
+ check 'Hide marketing-related entries from help'
+ fill_in 'Support page URL', with: 'http://example.com/help'
+ click_button 'Save changes'
+ end
- expect(page).to have_content 'Application settings saved successfully'
- expect(find_field('RSA SSH keys').value).to eq(forbidden)
- expect(find_field('DSA SSH keys').value).to eq('0')
- expect(find_field('ECDSA SSH keys').value).to eq('384')
- expect(find_field('ED25519 SSH keys').value).to eq(forbidden)
- end
+ expect(Gitlab::CurrentSettings.help_page_text).to eq "Example text"
+ expect(Gitlab::CurrentSettings.help_page_hide_commercial_content).to be_truthy
+ expect(Gitlab::CurrentSettings.help_page_support_url).to eq "http://example.com/help"
+ expect(page).to have_content "Application settings saved successfully"
+ end
+
+ it 'Change Pages settings' do
+ page.within('.as-pages') do
+ fill_in 'Maximum size of pages (MB)', with: 15
+ check 'Require users to prove ownership of custom domains'
+ click_button 'Save changes'
+ end
- it 'loads usage ping payload on click', :js do
- expect(page).to have_button 'Preview payload'
+ expect(Gitlab::CurrentSettings.max_pages_size).to eq 15
+ expect(Gitlab::CurrentSettings.pages_domain_verification_enabled?).to be_truthy
+ expect(page).to have_content "Application settings saved successfully"
+ end
- find('.js-usage-ping-payload-trigger').click
+ it 'Change Background jobs settings' do
+ page.within('.as-background') do
+ fill_in 'Throttling Factor', with: 1
+ click_button 'Save changes'
+ end
- expect(page).to have_selector '.js-usage-ping-payload'
- expect(page).to have_button 'Hide payload'
+ expect(Gitlab::CurrentSettings.sidekiq_throttling_factor).to eq(1)
+ expect(page).to have_content "Application settings saved successfully"
+ end
end
def check_all_events
diff --git a/spec/features/admin/admin_uses_repository_checks_spec.rb b/spec/features/admin/admin_uses_repository_checks_spec.rb
index e658f1b6738..d04bb9acd9e 100644
--- a/spec/features/admin/admin_uses_repository_checks_spec.rb
+++ b/spec/features/admin/admin_uses_repository_checks_spec.rb
@@ -33,7 +33,7 @@ describe 'Admin uses repository checks' do
end
it 'to clear all repository checks', :js do
- visit admin_application_settings_path
+ visit repository_admin_application_settings_path
expect(RepositoryCheck::ClearWorker).to receive(:perform_async)
diff --git a/spec/features/dashboard/group_spec.rb b/spec/features/dashboard/group_spec.rb
index 1c7932e7964..e57fcde8b2c 100644
--- a/spec/features/dashboard/group_spec.rb
+++ b/spec/features/dashboard/group_spec.rb
@@ -13,7 +13,7 @@ RSpec.describe 'Dashboard Group' do
it 'creates new group', :js do
visit dashboard_groups_path
- find('.btn-new').click
+ find('.btn-success').click
new_path = 'Samurai'
new_description = 'Tokugawa Shogunate'
diff --git a/spec/features/dashboard/projects_spec.rb b/spec/features/dashboard/projects_spec.rb
index 4daacc61d85..975b7944741 100644
--- a/spec/features/dashboard/projects_spec.rb
+++ b/spec/features/dashboard/projects_spec.rb
@@ -103,6 +103,14 @@ describe 'Dashboard Projects' do
expect(page).not_to have_content(project.name)
expect(page).to have_content(project3.name)
end
+
+ it 'sorts projects by most stars when sorting by most stars' do
+ project_with_most_stars = create(:project, namespace: user.namespace, star_count: 10)
+
+ visit dashboard_projects_path(sort: :stars_desc)
+
+ expect(first('.project-row')).to have_content(project_with_most_stars.title)
+ end
end
context 'when on Starred projects tab' do
diff --git a/spec/features/issues/filtered_search/filter_issues_spec.rb b/spec/features/issues/filtered_search/filter_issues_spec.rb
index d4949de3f27..35d57b3896d 100644
--- a/spec/features/issues/filtered_search/filter_issues_spec.rb
+++ b/spec/features/issues/filtered_search/filter_issues_spec.rb
@@ -265,7 +265,7 @@ describe 'Filter issues', :js do
context 'issue label clicked' do
it 'filters and displays in search bar' do
- find('.issues-list .issue .issue-main-info .issuable-info a .badge', text: multiple_words_label.title).click
+ find('.issues-list .issue .issuable-main-info .issuable-info a .badge', text: multiple_words_label.title).click
expect_issues_list_count(1)
expect_tokens([label_token("\"#{multiple_words_label.title}\"")])
diff --git a/spec/features/labels_hierarchy_spec.rb b/spec/features/labels_hierarchy_spec.rb
index 6f917f522bc..09904cb907f 100644
--- a/spec/features/labels_hierarchy_spec.rb
+++ b/spec/features/labels_hierarchy_spec.rb
@@ -156,7 +156,7 @@ describe 'Labels Hierarchy', :js, :nested_groups do
find('a.label-item', text: parent_group_label.title).click
find('a.label-item', text: project_label_1.title).click
- find('.btn-create').click
+ find('.btn-success').click
expect(page.find('.issue-details h2.title')).to have_content('new created issue')
expect(page).to have_selector('span.badge', text: grandparent_group_label.title)
diff --git a/spec/features/merge_request/user_posts_diff_notes_spec.rb b/spec/features/merge_request/user_posts_diff_notes_spec.rb
index b6ed3686de2..fa148715855 100644
--- a/spec/features/merge_request/user_posts_diff_notes_spec.rb
+++ b/spec/features/merge_request/user_posts_diff_notes_spec.rb
@@ -200,23 +200,20 @@ describe 'Merge request > User posts diff notes', :js do
end
context 'with a new line' do
- # TODO: https://gitlab.com/gitlab-org/gitlab-ce/issues/48034
- xit 'allows commenting' do
- should_allow_commenting(find('[id="2f6fcd96b88b36ce98c38da085c795a27d92a3dd_10_9"]').find(:xpath, '..'))
+ it 'allows commenting' do
+ should_allow_commenting(find('[id="2f6fcd96b88b36ce98c38da085c795a27d92a3dd_10_9"]'))
end
end
context 'with an old line' do
- # TODO: https://gitlab.com/gitlab-org/gitlab-ce/issues/48034
- xit 'allows commenting' do
- should_allow_commenting(find('[id="6eb14e00385d2fb284765eb1cd8d420d33d63fc9_22_22"]').find(:xpath, '..'))
+ it 'allows commenting' do
+ should_allow_commenting(find('[id="6eb14e00385d2fb284765eb1cd8d420d33d63fc9_22_22"]'))
end
end
context 'with an unchanged line' do
- # TODO: https://gitlab.com/gitlab-org/gitlab-ce/issues/48034
- xit 'allows commenting' do
- should_allow_commenting(find('[id="2f6fcd96b88b36ce98c38da085c795a27d92a3dd_7_7"]').find(:xpath, '..'))
+ it 'allows commenting' do
+ should_allow_commenting(find('[id="2f6fcd96b88b36ce98c38da085c795a27d92a3dd_7_7"]'))
end
end
diff --git a/spec/features/merge_request/user_posts_notes_spec.rb b/spec/features/merge_request/user_posts_notes_spec.rb
index 260c5f9c28b..ee5f5377ca6 100644
--- a/spec/features/merge_request/user_posts_notes_spec.rb
+++ b/spec/features/merge_request/user_posts_notes_spec.rb
@@ -111,7 +111,7 @@ describe 'Merge request > User posts notes', :js do
it 'allows using markdown buttons after saving a note and then trying to edit it again' do
page.within('.current-note-edit-form') do
fill_in 'note[note]', with: 'This is the new content'
- find('.btn-save').click
+ find('.btn-success').click
end
find('.note').hover
@@ -129,7 +129,7 @@ describe 'Merge request > User posts notes', :js do
it 'appends the edited at time to the note' do
page.within('.current-note-edit-form') do
fill_in 'note[note]', with: 'Some new content'
- find('.btn-save').click
+ find('.btn-success').click
end
page.within("#note_#{note.id}") do
diff --git a/spec/features/merge_request/user_resolves_conflicts_spec.rb b/spec/features/merge_request/user_resolves_conflicts_spec.rb
index 629052442b4..50c723776a3 100644
--- a/spec/features/merge_request/user_resolves_conflicts_spec.rb
+++ b/spec/features/merge_request/user_resolves_conflicts_spec.rb
@@ -44,9 +44,7 @@ describe 'Merge request > User resolves conflicts', :js do
within find('.diff-file', text: 'files/ruby/regex.rb') do
expect(page).to have_selector('.line_content.new', text: "def username_regexp")
- expect(page).not_to have_selector('.line_content.new', text: "def username_regex")
expect(page).to have_selector('.line_content.new', text: "def project_name_regexp")
- expect(page).not_to have_selector('.line_content.new', text: "def project_name_regex")
expect(page).to have_selector('.line_content.new', text: "def path_regexp")
expect(page).to have_selector('.line_content.new', text: "def archive_formats_regexp")
expect(page).to have_selector('.line_content.new', text: "def git_reference_regexp")
@@ -110,12 +108,8 @@ describe 'Merge request > User resolves conflicts', :js do
click_link('conflicts', href: %r{/conflicts\Z})
end
- # TODO: https://gitlab.com/gitlab-org/gitlab-ce/issues/48034
- # include_examples "conflicts are resolved in Interactive mode"
- # include_examples "conflicts are resolved in Edit inline mode"
-
- it 'prevents RSpec/EmptyExampleGroup' do
- end
+ include_examples "conflicts are resolved in Interactive mode"
+ include_examples "conflicts are resolved in Edit inline mode"
end
context 'in Parallel view mode' do
@@ -124,12 +118,8 @@ describe 'Merge request > User resolves conflicts', :js do
click_button 'Side-by-side'
end
- # TODO: https://gitlab.com/gitlab-org/gitlab-ce/issues/48034
- # include_examples "conflicts are resolved in Interactive mode"
- # include_examples "conflicts are resolved in Edit inline mode"
-
- it 'prevents RSpec/EmptyExampleGroup' do
- end
+ include_examples "conflicts are resolved in Interactive mode"
+ include_examples "conflicts are resolved in Edit inline mode"
end
end
diff --git a/spec/features/merge_request/user_resolves_diff_notes_and_discussions_resolve_spec.rb b/spec/features/merge_request/user_resolves_diff_notes_and_discussions_resolve_spec.rb
index 2d268ecab58..8a16c011067 100644
--- a/spec/features/merge_request/user_resolves_diff_notes_and_discussions_resolve_spec.rb
+++ b/spec/features/merge_request/user_resolves_diff_notes_and_discussions_resolve_spec.rb
@@ -139,44 +139,64 @@ describe 'Merge request > User resolves diff notes and discussions', :js do
expect(find('.diffs .diff-file .notes_holder')).to be_visible
end
end
- end
- it 'allows user to resolve from reply form without a comment' do
- page.within '.diff-content' do
- click_button 'Reply...'
+ describe 'reply form' do
+ before do
+ click_button 'Toggle discussion'
- click_button 'Resolve discussion'
- end
+ page.within '.diff-content' do
+ click_button 'Reply...'
+ end
+ end
- page.within '.line-resolve-all-container' do
- expect(page).to have_content('1/1 discussion resolved')
- expect(page).to have_selector('.line-resolve-btn.is-active')
- end
- end
+ it 'allows user to comment' do
+ page.within '.diff-content' do
+ find('.js-note-text').set 'testing'
- it 'allows user to unresolve from reply form without a comment' do
- page.within '.diff-content' do
- click_button 'Resolve discussion'
- sleep 1
+ click_button 'Comment'
- click_button 'Reply...'
+ wait_for_requests
+ end
- click_button 'Unresolve discussion'
- end
+ page.within '.line-resolve-all-container' do
+ expect(page).to have_content('1/1 discussion resolved')
+ end
+ end
- page.within '.line-resolve-all-container' do
- expect(page).to have_content('0/1 discussion resolved')
- expect(page).not_to have_selector('.line-resolve-btn.is-active')
+ it 'allows user to unresolve from reply form without a comment' do
+ page.within '.diff-content' do
+ click_button 'Unresolve discussion'
+
+ wait_for_requests
+ end
+
+ page.within '.line-resolve-all-container' do
+ expect(page).to have_content('0/1 discussion resolved')
+ expect(page).not_to have_selector('.line-resolve-btn.is-active')
+ end
+ end
+
+ it 'allows user to comment & unresolve discussion' do
+ page.within '.diff-content' do
+ find('.js-note-text').set 'testing'
+
+ click_button 'Comment & unresolve discussion'
+
+ wait_for_requests
+ end
+
+ page.within '.line-resolve-all-container' do
+ expect(page).to have_content('0/1 discussion resolved')
+ end
+ end
end
end
- it 'allows user to comment & resolve discussion' do
+ it 'allows user to resolve from reply form without a comment' do
page.within '.diff-content' do
click_button 'Reply...'
- find('.js-note-text').set 'testing'
-
- click_button 'Comment & resolve discussion'
+ click_button 'Resolve discussion'
end
page.within '.line-resolve-all-container' do
@@ -185,19 +205,18 @@ describe 'Merge request > User resolves diff notes and discussions', :js do
end
end
- it 'allows user to comment & unresolve discussion' do
+ it 'allows user to comment & resolve discussion' do
page.within '.diff-content' do
- click_button 'Resolve discussion'
-
click_button 'Reply...'
find('.js-note-text').set 'testing'
- click_button 'Comment & unresolve discussion'
+ click_button 'Comment & resolve discussion'
end
page.within '.line-resolve-all-container' do
- expect(page).to have_content('0/1 discussion resolved')
+ expect(page).to have_content('1/1 discussion resolved')
+ expect(page).to have_selector('.line-resolve-btn.is-active')
end
end
diff --git a/spec/features/projects/blobs/blob_show_spec.rb b/spec/features/projects/blobs/blob_show_spec.rb
index 2ba4d4918ff..e2f9e7e9cc5 100644
--- a/spec/features/projects/blobs/blob_show_spec.rb
+++ b/spec/features/projects/blobs/blob_show_spec.rb
@@ -533,7 +533,7 @@ describe 'File blob', :js do
expect(page).to have_content('This project is licensed under the MIT License.')
# shows a learn more link
- expect(page).to have_link('Learn more', 'http://choosealicense.com/licenses/mit/')
+ expect(page).to have_link('Learn more', href: 'http://choosealicense.com/licenses/mit/')
end
end
end
@@ -566,10 +566,10 @@ describe 'File blob', :js do
expect(page).to have_content('This project manages its dependencies using RubyGems and defines a gem named activerecord.')
# shows a link to the gem
- expect(page).to have_link('activerecord', 'https://rubygems.org/gems/activerecord')
+ expect(page).to have_link('activerecord', href: 'https://rubygems.org/gems/activerecord')
# shows a learn more link
- expect(page).to have_link('Learn more', 'http://choosealicense.com/licenses/mit/')
+ expect(page).to have_link('Learn more', href: 'https://rubygems.org/')
end
end
end
diff --git a/spec/features/projects/clusters/user_spec.rb b/spec/features/projects/clusters/user_spec.rb
index 00941efc8c8..2b4998ed5ac 100644
--- a/spec/features/projects/clusters/user_spec.rb
+++ b/spec/features/projects/clusters/user_spec.rb
@@ -86,7 +86,6 @@ describe 'User Cluster', :js do
context 'when user disables the cluster' do
before do
page.find(:css, '.js-cluster-enable-toggle-area .js-project-feature-toggle').click
- fill_in 'cluster_name', with: 'dev-cluster'
page.within('#cluster-integration') { click_button 'Save changes' }
end
diff --git a/spec/features/projects/members/invite_group_spec.rb b/spec/features/projects/members/invite_group_spec.rb
index 0fb3eb20b5b..fceead0b45e 100644
--- a/spec/features/projects/members/invite_group_spec.rb
+++ b/spec/features/projects/members/invite_group_spec.rb
@@ -40,7 +40,7 @@ describe 'Project > Members > Invite group', :js do
select2 group_to_share_with.id, from: '#link_group_id'
page.find('body').click
- find('.btn-create').click
+ find('.btn-success').click
page.within('.project-members-groups') do
expect(page).to have_content(group_to_share_with.name)
@@ -122,7 +122,7 @@ describe 'Project > Members > Invite group', :js do
fill_in 'expires_at_groups', with: (Time.now + 4.5.days).strftime('%Y-%m-%d')
click_on 'invite-group-tab'
- find('.btn-create').click
+ find('.btn-success').click
end
it 'the group link shows the expiration time with a warning class' do
diff --git a/spec/features/projects/pipelines/pipelines_spec.rb b/spec/features/projects/pipelines/pipelines_spec.rb
index 26a92f14787..41822babbc9 100644
--- a/spec/features/projects/pipelines/pipelines_spec.rb
+++ b/spec/features/projects/pipelines/pipelines_spec.rb
@@ -9,6 +9,7 @@ describe 'Pipelines', :js do
before do
sign_in(user)
project.add_developer(user)
+ project.update!(auto_devops_attributes: { enabled: false })
end
describe 'GET /:project/pipelines' do
@@ -641,6 +642,7 @@ describe 'Pipelines', :js do
context 'when user is not logged in' do
before do
+ project.update!(auto_devops_attributes: { enabled: false })
visit project_pipelines_path(project)
end
diff --git a/spec/features/projects/show/user_sees_setup_shortcut_buttons_spec.rb b/spec/features/projects/show/user_sees_setup_shortcut_buttons_spec.rb
index b8326edd4fd..6fe21579e8e 100644
--- a/spec/features/projects/show/user_sees_setup_shortcut_buttons_spec.rb
+++ b/spec/features/projects/show/user_sees_setup_shortcut_buttons_spec.rb
@@ -28,8 +28,6 @@ describe 'Projects > Show > User sees setup shortcut buttons' do
end
it '"Auto DevOps enabled" button not linked' do
- project.create_auto_devops!(enabled: true)
-
visit project_path(project)
page.within('.project-stats') do
@@ -65,19 +63,23 @@ describe 'Projects > Show > User sees setup shortcut buttons' do
end
describe 'Auto DevOps button' do
- it '"Enable Auto DevOps" button linked to settings page' do
- page.within('.project-stats') do
- expect(page).to have_link('Enable Auto DevOps', href: project_settings_ci_cd_path(project, anchor: 'autodevops-settings'))
+ context 'when Auto DevOps is enabled' do
+ it '"Auto DevOps enabled" anchor linked to settings page' do
+ visit project_path(project)
+
+ page.within('.project-stats') do
+ expect(page).to have_link('Auto DevOps enabled', href: project_settings_ci_cd_path(project, anchor: 'autodevops-settings'))
+ end
end
end
- it '"Auto DevOps enabled" anchor linked to settings page' do
- project.create_auto_devops!(enabled: true)
-
- visit project_path(project)
+ context 'when Auto DevOps is not enabled' do
+ let(:project) { create(:project, :public, :empty_repo, auto_devops_attributes: { enabled: false }) }
- page.within('.project-stats') do
- expect(page).to have_link('Auto DevOps enabled', href: project_settings_ci_cd_path(project, anchor: 'autodevops-settings'))
+ it '"Enable Auto DevOps" button linked to settings page' do
+ page.within('.project-stats') do
+ expect(page).to have_link('Enable Auto DevOps', href: project_settings_ci_cd_path(project, anchor: 'autodevops-settings'))
+ end
end
end
end
@@ -113,27 +115,31 @@ describe 'Projects > Show > User sees setup shortcut buttons' do
visit project_path(project)
end
- it 'no Auto DevOps button if can not manage pipelines' do
- page.within('.project-stats') do
- expect(page).not_to have_link('Enable Auto DevOps')
- expect(page).not_to have_link('Auto DevOps enabled')
+ context 'when Auto DevOps is enabled' do
+ it '"Auto DevOps enabled" button not linked' do
+ visit project_path(project)
+
+ page.within('.project-stats') do
+ expect(page).to have_text('Auto DevOps enabled')
+ end
end
end
- it '"Auto DevOps enabled" button not linked' do
- project.create_auto_devops!(enabled: true)
-
- visit project_path(project)
+ context 'when Auto DevOps is not enabled' do
+ let(:project) { create(:project, :public, :repository, auto_devops_attributes: { enabled: false }) }
- page.within('.project-stats') do
- expect(page).to have_text('Auto DevOps enabled')
+ it 'no Auto DevOps button if can not manage pipelines' do
+ page.within('.project-stats') do
+ expect(page).not_to have_link('Enable Auto DevOps')
+ expect(page).not_to have_link('Auto DevOps enabled')
+ end
end
- end
- it 'no Kubernetes cluster button if can not manage clusters' do
- page.within('.project-stats') do
- expect(page).not_to have_link('Add Kubernetes cluster')
- expect(page).not_to have_link('Kubernetes configured')
+ it 'no Kubernetes cluster button if can not manage clusters' do
+ page.within('.project-stats') do
+ expect(page).not_to have_link('Add Kubernetes cluster')
+ expect(page).not_to have_link('Kubernetes configured')
+ end
end
end
end
@@ -222,97 +228,105 @@ describe 'Projects > Show > User sees setup shortcut buttons' do
end
describe 'GitLab CI configuration button' do
- it '"Set up CI/CD" button linked to new file populated for a .gitlab-ci.yml' do
- visit project_path(project)
-
- expect(project.repository.gitlab_ci_yml).to be_nil
+ context 'when Auto DevOps is enabled' do
+ it 'no "Set up CI/CD" button if the project has Auto DevOps enabled' do
+ visit project_path(project)
- page.within('.project-stats') do
- expect(page).to have_link('Set up CI/CD', href: presenter.add_ci_yml_path)
+ page.within('.project-stats') do
+ expect(page).not_to have_link('Set up CI/CD')
+ end
end
end
- it 'no "Set up CI/CD" button if the project already has a .gitlab-ci.yml' do
- Files::CreateService.new(
- project,
- project.creator,
- start_branch: 'master',
- branch_name: 'master',
- commit_message: "Add .gitlab-ci.yml",
- file_path: '.gitlab-ci.yml',
- file_content: File.read(Rails.root.join('spec/support/gitlab_stubs/gitlab_ci.yml'))
- ).execute
+ context 'when Auto DevOps is not enabled' do
+ let(:project) { create(:project, :public, :repository, auto_devops_attributes: { enabled: false }) }
- expect(project.repository.gitlab_ci_yml).not_to be_nil
+ it '"Set up CI/CD" button linked to new file populated for a .gitlab-ci.yml' do
+ visit project_path(project)
- visit project_path(project)
+ expect(project.repository.gitlab_ci_yml).to be_nil
- page.within('.project-stats') do
- expect(page).not_to have_link('Set up CI/CD')
+ page.within('.project-stats') do
+ expect(page).to have_link('Set up CI/CD', href: presenter.add_ci_yml_path)
+ end
end
- end
- it 'no "Set up CI/CD" button if the project has Auto DevOps enabled' do
- project.create_auto_devops!(enabled: true)
+ it 'no "Set up CI/CD" button if the project already has a .gitlab-ci.yml' do
+ Files::CreateService.new(
+ project,
+ project.creator,
+ start_branch: 'master',
+ branch_name: 'master',
+ commit_message: "Add .gitlab-ci.yml",
+ file_path: '.gitlab-ci.yml',
+ file_content: File.read(Rails.root.join('spec/support/gitlab_stubs/gitlab_ci.yml'))
+ ).execute
- visit project_path(project)
+ expect(project.repository.gitlab_ci_yml).not_to be_nil
- page.within('.project-stats') do
- expect(page).not_to have_link('Set up CI/CD')
+ visit project_path(project)
+
+ page.within('.project-stats') do
+ expect(page).not_to have_link('Set up CI/CD')
+ end
end
end
end
describe 'Auto DevOps button' do
- it '"Enable Auto DevOps" button linked to settings page' do
- visit project_path(project)
+ context 'when Auto DevOps is enabled' do
+ it '"Auto DevOps enabled" anchor linked to settings page' do
+ visit project_path(project)
- page.within('.project-stats') do
- expect(page).to have_link('Enable Auto DevOps', href: project_settings_ci_cd_path(project, anchor: 'autodevops-settings'))
+ page.within('.project-stats') do
+ expect(page).to have_link('Auto DevOps enabled', href: project_settings_ci_cd_path(project, anchor: 'autodevops-settings'))
+ end
end
end
- it '"Enable Auto DevOps" button linked to settings page' do
- project.create_auto_devops!(enabled: true)
+ context 'when Auto DevOps is not enabled' do
+ let(:project) { create(:project, :public, :repository, auto_devops_attributes: { enabled: false }) }
- visit project_path(project)
+ it '"Enable Auto DevOps" button linked to settings page' do
+ visit project_path(project)
- page.within('.project-stats') do
- expect(page).to have_link('Auto DevOps enabled', href: project_settings_ci_cd_path(project, anchor: 'autodevops-settings'))
+ page.within('.project-stats') do
+ expect(page).to have_link('Enable Auto DevOps', href: project_settings_ci_cd_path(project, anchor: 'autodevops-settings'))
+ end
end
- end
- it 'no Auto DevOps button if Auto DevOps callout is shown' do
- allow_any_instance_of(AutoDevopsHelper).to receive(:show_auto_devops_callout?).and_return(true)
+ it 'no Auto DevOps button if Auto DevOps callout is shown' do
+ allow_any_instance_of(AutoDevopsHelper).to receive(:show_auto_devops_callout?).and_return(true)
- visit project_path(project)
+ visit project_path(project)
- expect(page).to have_selector('.js-autodevops-banner')
+ expect(page).to have_selector('.js-autodevops-banner')
- page.within('.project-stats') do
- expect(page).not_to have_link('Enable Auto DevOps')
- expect(page).not_to have_link('Auto DevOps enabled')
+ page.within('.project-stats') do
+ expect(page).not_to have_link('Enable Auto DevOps')
+ expect(page).not_to have_link('Auto DevOps enabled')
+ end
end
- end
- it 'no "Enable Auto DevOps" button when .gitlab-ci.yml already exists' do
- Files::CreateService.new(
- project,
- project.creator,
- start_branch: 'master',
- branch_name: 'master',
- commit_message: "Add .gitlab-ci.yml",
- file_path: '.gitlab-ci.yml',
- file_content: File.read(Rails.root.join('spec/support/gitlab_stubs/gitlab_ci.yml'))
- ).execute
+ it 'no "Enable Auto DevOps" button when .gitlab-ci.yml already exists' do
+ Files::CreateService.new(
+ project,
+ project.creator,
+ start_branch: 'master',
+ branch_name: 'master',
+ commit_message: "Add .gitlab-ci.yml",
+ file_path: '.gitlab-ci.yml',
+ file_content: File.read(Rails.root.join('spec/support/gitlab_stubs/gitlab_ci.yml'))
+ ).execute
- expect(project.repository.gitlab_ci_yml).not_to be_nil
+ expect(project.repository.gitlab_ci_yml).not_to be_nil
- visit project_path(project)
+ visit project_path(project)
- page.within('.project-stats') do
- expect(page).not_to have_link('Enable Auto DevOps')
- expect(page).not_to have_link('Auto DevOps enabled')
+ page.within('.project-stats') do
+ expect(page).not_to have_link('Enable Auto DevOps')
+ expect(page).not_to have_link('Auto DevOps enabled')
+ end
end
end
end
diff --git a/spec/features/runners_spec.rb b/spec/features/runners_spec.rb
index 0c6cf3dc477..cb7a912946c 100644
--- a/spec/features/runners_spec.rb
+++ b/spec/features/runners_spec.rb
@@ -198,7 +198,7 @@ describe 'Runners' do
expect(page).to have_content 'This group does not provide any group Runners yet'
expect(page).to have_content 'Group maintainers can register group runners in the Group CI/CD settings'
- expect(page).not_to have_content 'Ask your group maintainer to setup a group Runner'
+ expect(page).not_to have_content 'Ask your group maintainer to set up a group Runner'
end
end
end
@@ -224,7 +224,7 @@ describe 'Runners' do
expect(page).to have_content 'This group does not provide any group Runners yet.'
expect(page).not_to have_content 'Group maintainers can register group runners in the Group CI/CD settings'
- expect(page).to have_content 'Ask your group maintainer to setup a group Runner.'
+ expect(page).to have_content 'Ask your group maintainer to set up a group Runner.'
end
end
diff --git a/spec/features/snippets/notes_on_personal_snippets_spec.rb b/spec/features/snippets/notes_on_personal_snippets_spec.rb
index 1442e011d52..eeacaf5f72a 100644
--- a/spec/features/snippets/notes_on_personal_snippets_spec.rb
+++ b/spec/features/snippets/notes_on_personal_snippets_spec.rb
@@ -103,7 +103,7 @@ describe 'Comments on personal snippets', :js do
page.within('.current-note-edit-form') do
fill_in 'note[note]', with: 'new content'
- find('.btn-save').click
+ find('.btn-success').click
end
page.within("#notes-list li#note_#{snippet_notes[0].id}") do
diff --git a/spec/features/snippets/user_sees_breadcrumb_links.rb b/spec/features/snippets/user_sees_breadcrumb_links.rb
new file mode 100644
index 00000000000..696f2b93390
--- /dev/null
+++ b/spec/features/snippets/user_sees_breadcrumb_links.rb
@@ -0,0 +1,17 @@
+require 'rails_helper'
+
+describe 'New user snippet breadcrumbs' do
+ let(:user) { create(:user) }
+
+ before do
+ sign_in(user)
+ visit new_snippet_path
+ end
+
+ it 'display a link to user snippets and new user snippet pages' do
+ page.within '.breadcrumbs' do
+ expect(find_link('Snippets')[:href]).to end_with(dashboard_snippets_path)
+ expect(find_link('New')[:href]).to end_with(new_snippet_path)
+ end
+ end
+end
diff --git a/spec/finders/group_labels_finder_spec.rb b/spec/finders/group_labels_finder_spec.rb
new file mode 100644
index 00000000000..ef68fc105e4
--- /dev/null
+++ b/spec/finders/group_labels_finder_spec.rb
@@ -0,0 +1,33 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe GroupLabelsFinder, '#execute' do
+ let!(:group) { create(:group) }
+ let!(:label1) { create(:group_label, title: 'Foo', description: 'Lorem ipsum', group: group) }
+ let!(:label2) { create(:group_label, title: 'Bar', description: 'Fusce consequat', group: group) }
+
+ it 'returns all group labels sorted by name if no params' do
+ result = described_class.new(group).execute
+
+ expect(result.to_a).to match_array([label2, label1])
+ end
+
+ it 'returns all group labels sorted by name desc' do
+ result = described_class.new(group, sort: 'name_desc').execute
+
+ expect(result.to_a).to match_array([label2, label1])
+ end
+
+ it 'returns group labels that march search' do
+ result = described_class.new(group, search: 'Foo').execute
+
+ expect(result.to_a).to match_array([label1])
+ end
+
+ it 'returns second page of labels' do
+ result = described_class.new(group, page: '2').execute
+
+ expect(result.to_a).to match_array([])
+ end
+end
diff --git a/spec/fixtures/api/schemas/job/job_details.json b/spec/fixtures/api/schemas/job/job_details.json
index 78c0fdf83b9..cd67d3e4160 100644
--- a/spec/fixtures/api/schemas/job/job_details.json
+++ b/spec/fixtures/api/schemas/job/job_details.json
@@ -8,6 +8,7 @@
"terminal_path": { "type": "string" },
"trigger": { "$ref": "trigger.json" },
"deployment_status": { "$ref": "deployment_status.json" },
- "runner": { "$ref": "runner.json" }
+ "runner": { "$ref": "runner.json" },
+ "runners": { "type": "runners.json" }
}
}
diff --git a/spec/fixtures/api/schemas/job/runners.json b/spec/fixtures/api/schemas/job/runners.json
new file mode 100644
index 00000000000..bebb0c88652
--- /dev/null
+++ b/spec/fixtures/api/schemas/job/runners.json
@@ -0,0 +1,13 @@
+{
+ "type": "object",
+ "required": [
+ "online",
+ "available"
+ ],
+ "properties": {
+ "online": { "type": "boolean" },
+ "available": { "type": "boolean" },
+ "settings_path": { "type": "string" }
+ },
+ "additionalProperties": false
+}
diff --git a/spec/helpers/application_helper_spec.rb b/spec/helpers/application_helper_spec.rb
index 14297a1a544..1238cfbd1e7 100644
--- a/spec/helpers/application_helper_spec.rb
+++ b/spec/helpers/application_helper_spec.rb
@@ -3,48 +3,66 @@ require 'spec_helper'
describe ApplicationHelper do
describe 'current_controller?' do
- it 'returns true when controller matches argument' do
+ before do
stub_controller_name('foo')
+ end
- expect(helper.current_controller?(:foo)).to eq true
+ it 'returns true when controller matches argument' do
+ expect(helper.current_controller?(:foo)).to be_truthy
end
it 'returns false when controller does not match argument' do
- stub_controller_name('foo')
-
- expect(helper.current_controller?(:bar)).to eq false
+ expect(helper.current_controller?(:bar)).to be_falsey
end
it 'takes any number of arguments' do
- stub_controller_name('foo')
+ expect(helper.current_controller?(:baz, :bar)).to be_falsey
+ expect(helper.current_controller?(:baz, :bar, :foo)).to be_truthy
+ end
+
+ context 'when namespaced' do
+ before do
+ stub_controller_path('bar/foo')
+ end
+
+ it 'returns true when controller matches argument' do
+ expect(helper.current_controller?(:foo)).to be_truthy
+ end
- expect(helper.current_controller?(:baz, :bar)).to eq false
- expect(helper.current_controller?(:baz, :bar, :foo)).to eq true
+ it 'returns true when controller and namespace matches argument in path notation' do
+ expect(helper.current_controller?('bar/foo')).to be_truthy
+ end
+
+ it 'returns false when namespace doesnt match' do
+ expect(helper.current_controller?('foo/foo')).to be_falsey
+ end
end
def stub_controller_name(value)
allow(helper.controller).to receive(:controller_name).and_return(value)
end
+
+ def stub_controller_path(value)
+ allow(helper.controller).to receive(:controller_path).and_return(value)
+ end
end
describe 'current_action?' do
- it 'returns true when action matches' do
+ before do
stub_action_name('foo')
+ end
- expect(helper.current_action?(:foo)).to eq true
+ it 'returns true when action matches' do
+ expect(helper.current_action?(:foo)).to be_truthy
end
it 'returns false when action does not match' do
- stub_action_name('foo')
-
- expect(helper.current_action?(:bar)).to eq false
+ expect(helper.current_action?(:bar)).to be_falsey
end
it 'takes any number of arguments' do
- stub_action_name('foo')
-
- expect(helper.current_action?(:baz, :bar)).to eq false
- expect(helper.current_action?(:baz, :bar, :foo)).to eq true
+ expect(helper.current_action?(:baz, :bar)).to be_falsey
+ expect(helper.current_action?(:baz, :bar, :foo)).to be_truthy
end
def stub_action_name(value)
@@ -100,8 +118,7 @@ describe ApplicationHelper do
end
it 'accepts a custom html_class' do
- expect(element(html_class: 'custom_class').attr('class'))
- .to eq 'js-timeago custom_class'
+ expect(element(html_class: 'custom_class').attr('class')).to eq 'js-timeago custom_class'
end
it 'accepts a custom tooltip placement' do
@@ -114,6 +131,7 @@ describe ApplicationHelper do
it 'add class for the short format' do
timeago_element = element(short_format: 'short')
+
expect(timeago_element.attr('class')).to eq 'js-short-timeago'
expect(timeago_element.next_element).to eq nil
end
@@ -128,11 +146,9 @@ describe ApplicationHelper do
context 'when alternate support url is specified' do
let(:alternate_url) { 'http://company.example.com/getting-help' }
- before do
+ it 'returns the alternate support url' do
stub_application_setting(help_page_support_url: alternate_url)
- end
- it 'returns the alternate support url' do
expect(helper.support_url).to eq(alternate_url)
end
end
@@ -155,9 +171,12 @@ describe ApplicationHelper do
describe '#autocomplete_data_sources' do
let(:project) { create(:project) }
let(:noteable_type) { Issue }
+
it 'returns paths for autocomplete_sources_controller' do
sources = helper.autocomplete_data_sources(project, noteable_type)
+
expect(sources.keys).to match_array([:members, :issues, :mergeRequests, :labels, :milestones, :commands])
+
sources.keys.each do |key|
expect(sources[key]).not_to be_nil
end
diff --git a/spec/helpers/auto_devops_helper_spec.rb b/spec/helpers/auto_devops_helper_spec.rb
index 1950c2b129b..75c30dbfe48 100644
--- a/spec/helpers/auto_devops_helper_spec.rb
+++ b/spec/helpers/auto_devops_helper_spec.rb
@@ -16,7 +16,15 @@ describe AutoDevopsHelper do
subject { helper.show_auto_devops_callout?(project) }
- context 'when all conditions are met' do
+ context 'when auto devops is implicitly enabled' do
+ it { is_expected.to eq(false) }
+ end
+
+ context 'when auto devops is not implicitly enabled' do
+ before do
+ Gitlab::CurrentSettings.update!(auto_devops_enabled: false)
+ end
+
it { is_expected.to eq(true) }
end
diff --git a/spec/helpers/tab_helper_spec.rb b/spec/helpers/tab_helper_spec.rb
index b473c0a7416..9abf63d4bd4 100644
--- a/spec/helpers/tab_helper_spec.rb
+++ b/spec/helpers/tab_helper_spec.rb
@@ -9,31 +9,71 @@ describe TabHelper do
allow(self).to receive(:action_name).and_return('foo')
end
- it "captures block output" do
- expect(nav_link { "Testing Blocks" }).to match(/Testing Blocks/)
+ context 'with the content of the li' do
+ it "captures block output" do
+ expect(nav_link { "Testing Blocks" }).to match(/Testing Blocks/)
+ end
end
- it "performs checks on the current controller" do
- expect(nav_link(controller: :foo)).to match(/<li class="active">/)
- expect(nav_link(controller: :bar)).not_to match(/active/)
- expect(nav_link(controller: [:foo, :bar])).to match(/active/)
- end
+ context 'with controller param' do
+ it "performs checks on the current controller" do
+ expect(nav_link(controller: :foo)).to match(/<li class="active">/)
+ expect(nav_link(controller: :bar)).not_to match(/active/)
+ expect(nav_link(controller: [:foo, :bar])).to match(/active/)
+ end
+
+ context 'with action param' do
+ it "performs checks on both controller and action when both are present" do
+ expect(nav_link(controller: :bar, action: :foo)).not_to match(/active/)
+ expect(nav_link(controller: :foo, action: :bar)).not_to match(/active/)
+ expect(nav_link(controller: :foo, action: :foo)).to match(/active/)
+ end
+ end
+
+ context 'with namespace in path notation' do
+ before do
+ allow(controller).to receive(:controller_path).and_return('bar/foo')
+ end
- it "performs checks on the current action" do
- expect(nav_link(action: :foo)).to match(/<li class="active">/)
- expect(nav_link(action: :bar)).not_to match(/active/)
- expect(nav_link(action: [:foo, :bar])).to match(/active/)
+ it 'performs checks on both controller and namespace' do
+ expect(nav_link(controller: 'foo/foo')).not_to match(/active/)
+ expect(nav_link(controller: 'bar/foo')).to match(/active/)
+ end
+
+ context 'with action param' do
+ it "performs checks on both namespace, controller and action when they are all present" do
+ expect(nav_link(controller: 'foo/foo', action: :foo)).not_to match(/active/)
+ expect(nav_link(controller: 'bar/foo', action: :bar)).not_to match(/active/)
+ expect(nav_link(controller: 'bar/foo', action: :foo)).to match(/active/)
+ end
+ end
+ end
end
- it "performs checks on both controller and action when both are present" do
- expect(nav_link(controller: :bar, action: :foo)).not_to match(/active/)
- expect(nav_link(controller: :foo, action: :bar)).not_to match(/active/)
- expect(nav_link(controller: :foo, action: :foo)).to match(/active/)
+ context 'with action param' do
+ it "performs checks on the current action" do
+ expect(nav_link(action: :foo)).to match(/<li class="active">/)
+ expect(nav_link(action: :bar)).not_to match(/active/)
+ expect(nav_link(action: [:foo, :bar])).to match(/active/)
+ end
end
- it "accepts a path shorthand" do
- expect(nav_link(path: 'foo#bar')).not_to match(/active/)
- expect(nav_link(path: 'foo#foo')).to match(/active/)
+ context 'with path param' do
+ it "accepts a path shorthand" do
+ expect(nav_link(path: 'foo#bar')).not_to match(/active/)
+ expect(nav_link(path: 'foo#foo')).to match(/active/)
+ end
+
+ context 'with namespace' do
+ before do
+ allow(controller).to receive(:controller_path).and_return('bar/foo')
+ end
+
+ it 'accepts a path shorthand with namespace' do
+ expect(nav_link(path: 'bar/foo#foo')).to match(/active/)
+ expect(nav_link(path: 'foo/foo#foo')).not_to match(/active/)
+ end
+ end
end
it "passes extra html options to the list element" do
diff --git a/spec/javascripts/.eslintrc.yml b/spec/javascripts/.eslintrc.yml
index 5525c9f5bd0..9b2c84ce9f5 100644
--- a/spec/javascripts/.eslintrc.yml
+++ b/spec/javascripts/.eslintrc.yml
@@ -35,3 +35,9 @@ rules:
- error
- ignore:
- 'fixtures/blob'
+ # Temporarily disabled to facilitate an upgrade to eslint-plugin-jasmine
+ jasmine/new-line-before-expect: off
+ jasmine/new-line-between-declarations: off
+ jasmine/no-promise-without-done-fail: off
+ jasmine/prefer-jasmine-matcher: off
+ jasmine/prefer-toHaveBeenCalledWith: off
diff --git a/spec/javascripts/shortcuts_issuable_spec.js b/spec/javascripts/behaviors/shortcuts/shortcuts_issuable_spec.js
index a4753ab7cde..01b5bc112b2 100644
--- a/spec/javascripts/shortcuts_issuable_spec.js
+++ b/spec/javascripts/behaviors/shortcuts/shortcuts_issuable_spec.js
@@ -1,6 +1,6 @@
import $ from 'jquery';
import initCopyAsGFM from '~/behaviors/markdown/copy_as_gfm';
-import ShortcutsIssuable from '~/shortcuts_issuable';
+import ShortcutsIssuable from '~/behaviors/shortcuts/shortcuts_issuable';
initCopyAsGFM();
diff --git a/spec/javascripts/boards/board_blank_state_spec.js b/spec/javascripts/boards/board_blank_state_spec.js
index 89a4fae4b59..0e4e1697fd0 100644
--- a/spec/javascripts/boards/board_blank_state_spec.js
+++ b/spec/javascripts/boards/board_blank_state_spec.js
@@ -64,7 +64,7 @@ describe('Boards blank state', () => {
});
it('creates pre-defined labels', (done) => {
- vm.$el.querySelector('.btn-create').click();
+ vm.$el.querySelector('.btn-success').click();
setTimeout(() => {
expect(gl.issueBoards.BoardsStore.state.lists.length).toBe(2);
@@ -78,7 +78,7 @@ describe('Boards blank state', () => {
it('resets the store if request fails', (done) => {
fail = true;
- vm.$el.querySelector('.btn-create').click();
+ vm.$el.querySelector('.btn-success').click();
setTimeout(() => {
expect(gl.issueBoards.BoardsStore.welcomeIsHidden()).toBeFalsy();
diff --git a/spec/javascripts/close_reopen_report_toggle_spec.js b/spec/javascripts/close_reopen_report_toggle_spec.js
index 925e959c85a..412abe2cbf8 100644
--- a/spec/javascripts/close_reopen_report_toggle_spec.js
+++ b/spec/javascripts/close_reopen_report_toggle_spec.js
@@ -1,3 +1,5 @@
+/* eslint-disable jasmine/no-unsafe-spy */
+
import CloseReopenReportToggle from '~/close_reopen_report_toggle';
import DropLab from '~/droplab/drop_lab';
diff --git a/spec/javascripts/diffs/components/diff_line_note_form_spec.js b/spec/javascripts/diffs/components/diff_line_note_form_spec.js
index 6fe5fdaf7f9..f31fc1f0e2b 100644
--- a/spec/javascripts/diffs/components/diff_line_note_form_spec.js
+++ b/spec/javascripts/diffs/components/diff_line_note_form_spec.js
@@ -69,22 +69,21 @@ describe('DiffLineNoteForm', () => {
describe('saveNoteForm', () => {
it('should call saveNote action with proper params', done => {
- let isPromiseCalled = false;
- const formDataSpy = spyOnDependency(DiffLineNoteForm, 'getNoteFormData').and.returnValue({
- postData: 1,
- });
- const saveNoteSpy = spyOn(component, 'saveNote').and.returnValue(
- new Promise(() => {
- isPromiseCalled = true;
- done();
- }),
+ const saveDiffDiscussionSpy = spyOn(component, 'saveDiffDiscussion').and.returnValue(
+ Promise.resolve(),
);
-
- component.handleSaveNote('note body');
-
- expect(formDataSpy).toHaveBeenCalled();
- expect(saveNoteSpy).toHaveBeenCalled();
- expect(isPromiseCalled).toEqual(true);
+ spyOnProperty(component, 'formData').and.returnValue('formData');
+
+ component
+ .handleSaveNote('note body')
+ .then(() => {
+ expect(saveDiffDiscussionSpy).toHaveBeenCalledWith({
+ note: 'note body',
+ formData: 'formData',
+ });
+ })
+ .then(done)
+ .catch(done.fail);
});
});
});
diff --git a/spec/javascripts/diffs/store/actions_spec.js b/spec/javascripts/diffs/store/actions_spec.js
index cfb8f862598..05b39bad6ea 100644
--- a/spec/javascripts/diffs/store/actions_spec.js
+++ b/spec/javascripts/diffs/store/actions_spec.js
@@ -5,7 +5,24 @@ import {
INLINE_DIFF_VIEW_TYPE,
PARALLEL_DIFF_VIEW_TYPE,
} from '~/diffs/constants';
-import * as actions from '~/diffs/store/actions';
+import actions, {
+ setBaseConfig,
+ fetchDiffFiles,
+ assignDiscussionsToDiff,
+ removeDiscussionsFromDiff,
+ startRenderDiffsQueue,
+ setInlineDiffViewType,
+ setParallelDiffViewType,
+ showCommentForm,
+ cancelCommentForm,
+ loadMoreLines,
+ scrollToLineIfNeededInline,
+ scrollToLineIfNeededParallel,
+ loadCollapsedDiff,
+ expandAllFiles,
+ toggleFileDiscussions,
+ saveDiffDiscussion,
+} from '~/diffs/store/actions';
import * as types from '~/diffs/store/mutation_types';
import { reduceDiscussionsToLineCodes } from '~/notes/stores/utils';
import axios from '~/lib/utils/axios_utils';
@@ -37,7 +54,7 @@ describe('DiffsStoreActions', () => {
const projectPath = '/root/project';
testAction(
- actions.setBaseConfig,
+ setBaseConfig,
{ endpoint, projectPath },
{ endpoint: '', projectPath: '' },
[{ type: types.SET_BASE_CONFIG, payload: { endpoint, projectPath } }],
@@ -55,7 +72,7 @@ describe('DiffsStoreActions', () => {
mock.onGet(endpoint).reply(200, res);
testAction(
- actions.fetchDiffFiles,
+ fetchDiffFiles,
{},
{ endpoint },
[
@@ -139,7 +156,7 @@ describe('DiffsStoreActions', () => {
const discussions = reduceDiscussionsToLineCodes([singleDiscussion]);
testAction(
- actions.assignDiscussionsToDiff,
+ assignDiscussionsToDiff,
discussions,
state,
[
@@ -157,6 +174,7 @@ describe('DiffsStoreActions', () => {
newPath: 'file1',
oldLine: 5,
oldPath: 'file2',
+ lineCode: 'ABC_1_1',
},
},
},
@@ -207,7 +225,7 @@ describe('DiffsStoreActions', () => {
};
testAction(
- actions.removeDiscussionsFromDiff,
+ removeDiscussionsFromDiff,
singleDiscussion,
state,
[
@@ -228,7 +246,7 @@ describe('DiffsStoreActions', () => {
});
describe('startRenderDiffsQueue', () => {
- it('should set all files to RENDER_FILE', done => {
+ it('should set all files to RENDER_FILE', () => {
const state = {
diffFiles: [
{
@@ -251,24 +269,17 @@ describe('DiffsStoreActions', () => {
});
};
- actions
- .startRenderDiffsQueue({ state, commit: pseudoCommit })
- .then(() => {
- expect(state.diffFiles[0].renderIt).toBeTruthy();
- expect(state.diffFiles[1].renderIt).toBeTruthy();
+ startRenderDiffsQueue({ state, commit: pseudoCommit });
- done();
- })
- .catch(() => {
- done.fail();
- });
+ expect(state.diffFiles[0].renderIt).toBe(true);
+ expect(state.diffFiles[1].renderIt).toBe(true);
});
});
describe('setInlineDiffViewType', () => {
it('should set diff view type to inline and also set the cookie properly', done => {
testAction(
- actions.setInlineDiffViewType,
+ setInlineDiffViewType,
null,
{},
[{ type: types.SET_DIFF_VIEW_TYPE, payload: INLINE_DIFF_VIEW_TYPE }],
@@ -286,7 +297,7 @@ describe('DiffsStoreActions', () => {
describe('setParallelDiffViewType', () => {
it('should set diff view type to parallel and also set the cookie properly', done => {
testAction(
- actions.setParallelDiffViewType,
+ setParallelDiffViewType,
null,
{},
[{ type: types.SET_DIFF_VIEW_TYPE, payload: PARALLEL_DIFF_VIEW_TYPE }],
@@ -306,7 +317,7 @@ describe('DiffsStoreActions', () => {
const payload = { lineCode: 'lineCode' };
testAction(
- actions.showCommentForm,
+ showCommentForm,
payload,
{},
[{ type: types.ADD_COMMENT_FORM_LINE, payload }],
@@ -321,7 +332,7 @@ describe('DiffsStoreActions', () => {
const payload = { lineCode: 'lineCode' };
testAction(
- actions.cancelCommentForm,
+ cancelCommentForm,
payload,
{},
[{ type: types.REMOVE_COMMENT_FORM_LINE, payload }],
@@ -343,7 +354,7 @@ describe('DiffsStoreActions', () => {
mock.onGet(endpoint).reply(200, contextLines);
testAction(
- actions.loadMoreLines,
+ loadMoreLines,
options,
{},
[
@@ -369,7 +380,7 @@ describe('DiffsStoreActions', () => {
mock.onGet(file.loadCollapsedDiffUrl).reply(200, data);
testAction(
- actions.loadCollapsedDiff,
+ loadCollapsedDiff,
file,
{},
[
@@ -390,7 +401,7 @@ describe('DiffsStoreActions', () => {
describe('expandAllFiles', () => {
it('should change the collapsed prop from the diffFiles', done => {
testAction(
- actions.expandAllFiles,
+ expandAllFiles,
null,
{},
[
@@ -414,7 +425,7 @@ describe('DiffsStoreActions', () => {
const dispatch = jasmine.createSpy('dispatch');
- actions.toggleFileDiscussions({ getters, dispatch });
+ toggleFileDiscussions({ getters, dispatch });
expect(dispatch).toHaveBeenCalledWith(
'collapseDiscussion',
@@ -432,7 +443,7 @@ describe('DiffsStoreActions', () => {
const dispatch = jasmine.createSpy();
- actions.toggleFileDiscussions({ getters, dispatch });
+ toggleFileDiscussions({ getters, dispatch });
expect(dispatch).toHaveBeenCalledWith(
'expandDiscussion',
@@ -450,7 +461,7 @@ describe('DiffsStoreActions', () => {
const dispatch = jasmine.createSpy();
- actions.toggleFileDiscussions({ getters, dispatch });
+ toggleFileDiscussions({ getters, dispatch });
expect(dispatch).toHaveBeenCalledWith(
'expandDiscussion',
@@ -459,4 +470,142 @@ describe('DiffsStoreActions', () => {
);
});
});
+
+ describe('scrollToLineIfNeededInline', () => {
+ const lineMock = {
+ lineCode: 'ABC_123',
+ };
+
+ it('should not call handleLocationHash when there is not hash', () => {
+ window.location.hash = '';
+
+ const handleLocationHashSpy = spyOnDependency(actions, 'handleLocationHash').and.stub();
+
+ scrollToLineIfNeededInline({}, lineMock);
+
+ expect(handleLocationHashSpy).not.toHaveBeenCalled();
+ });
+
+ it('should not call handleLocationHash when the hash does not match any line', () => {
+ window.location.hash = 'XYZ_456';
+
+ const handleLocationHashSpy = spyOnDependency(actions, 'handleLocationHash').and.stub();
+
+ scrollToLineIfNeededInline({}, lineMock);
+
+ expect(handleLocationHashSpy).not.toHaveBeenCalled();
+ });
+
+ it('should call handleLocationHash only when the hash matches a line', () => {
+ window.location.hash = 'ABC_123';
+
+ const handleLocationHashSpy = spyOnDependency(actions, 'handleLocationHash').and.stub();
+
+ scrollToLineIfNeededInline(
+ {},
+ {
+ lineCode: 'ABC_456',
+ },
+ );
+ scrollToLineIfNeededInline({}, lineMock);
+ scrollToLineIfNeededInline(
+ {},
+ {
+ lineCode: 'XYZ_456',
+ },
+ );
+
+ expect(handleLocationHashSpy).toHaveBeenCalled();
+ expect(handleLocationHashSpy).toHaveBeenCalledTimes(1);
+ });
+ });
+
+ describe('scrollToLineIfNeededParallel', () => {
+ const lineMock = {
+ left: null,
+ right: {
+ lineCode: 'ABC_123',
+ },
+ };
+
+ it('should not call handleLocationHash when there is not hash', () => {
+ window.location.hash = '';
+
+ const handleLocationHashSpy = spyOnDependency(actions, 'handleLocationHash').and.stub();
+
+ scrollToLineIfNeededParallel({}, lineMock);
+
+ expect(handleLocationHashSpy).not.toHaveBeenCalled();
+ });
+
+ it('should not call handleLocationHash when the hash does not match any line', () => {
+ window.location.hash = 'XYZ_456';
+
+ const handleLocationHashSpy = spyOnDependency(actions, 'handleLocationHash').and.stub();
+
+ scrollToLineIfNeededParallel({}, lineMock);
+
+ expect(handleLocationHashSpy).not.toHaveBeenCalled();
+ });
+
+ it('should call handleLocationHash only when the hash matches a line', () => {
+ window.location.hash = 'ABC_123';
+
+ const handleLocationHashSpy = spyOnDependency(actions, 'handleLocationHash').and.stub();
+
+ scrollToLineIfNeededParallel(
+ {},
+ {
+ left: null,
+ right: {
+ lineCode: 'ABC_456',
+ },
+ },
+ );
+ scrollToLineIfNeededParallel({}, lineMock);
+ scrollToLineIfNeededParallel(
+ {},
+ {
+ left: null,
+ right: {
+ lineCode: 'XYZ_456',
+ },
+ },
+ );
+
+ expect(handleLocationHashSpy).toHaveBeenCalled();
+ expect(handleLocationHashSpy).toHaveBeenCalledTimes(1);
+ });
+ });
+
+ describe('saveDiffDiscussion', () => {
+ beforeEach(() => {
+ spyOnDependency(actions, 'getNoteFormData').and.returnValue('testData');
+ spyOnDependency(actions, 'reduceDiscussionsToLineCodes').and.returnValue('discussions');
+ });
+
+ it('dispatches actions', done => {
+ const dispatch = jasmine.createSpy('dispatch').and.callFake(name => {
+ switch (name) {
+ case 'saveNote':
+ return Promise.resolve({
+ discussion: 'test',
+ });
+ case 'updateDiscussion':
+ return Promise.resolve('discussion');
+ default:
+ return Promise.resolve({});
+ }
+ });
+
+ saveDiffDiscussion({ dispatch }, { note: {}, formData: {} })
+ .then(() => {
+ expect(dispatch.calls.argsFor(0)).toEqual(['saveNote', 'testData', { root: true }]);
+ expect(dispatch.calls.argsFor(1)).toEqual(['updateDiscussion', 'test', { root: true }]);
+ expect(dispatch.calls.argsFor(2)).toEqual(['assignDiscussionsToDiff', 'discussions']);
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+ });
});
diff --git a/spec/javascripts/diffs/store/mutations_spec.js b/spec/javascripts/diffs/store/mutations_spec.js
index 7eeca6712cc..9a5d8dfbd15 100644
--- a/spec/javascripts/diffs/store/mutations_spec.js
+++ b/spec/javascripts/diffs/store/mutations_spec.js
@@ -162,6 +162,7 @@ describe('DiffsStoreMutations', () => {
};
const state = {
+ latestDiff: true,
diffFiles: [
{
fileHash: 'ABC',
@@ -229,6 +230,76 @@ describe('DiffsStoreMutations', () => {
expect(state.diffFiles[0].highlightedDiffLines[0].discussions.length).toEqual(2);
expect(state.diffFiles[0].highlightedDiffLines[0].discussions[1].id).toEqual(2);
});
+
+ it('should add legacy discussions to the given line', () => {
+ const diffPosition = {
+ baseSha: 'ed13df29948c41ba367caa757ab3ec4892509910',
+ headSha: 'b921914f9a834ac47e6fd9420f78db0f83559130',
+ newLine: null,
+ newPath: '500-lines-4.txt',
+ oldLine: 5,
+ oldPath: '500-lines-4.txt',
+ startSha: 'ed13df29948c41ba367caa757ab3ec4892509910',
+ lineCode: 'ABC_1',
+ };
+
+ const state = {
+ latestDiff: true,
+ diffFiles: [
+ {
+ fileHash: 'ABC',
+ parallelDiffLines: [
+ {
+ left: {
+ lineCode: 'ABC_1',
+ discussions: [],
+ },
+ right: {
+ lineCode: 'ABC_1',
+ discussions: [],
+ },
+ },
+ ],
+ highlightedDiffLines: [
+ {
+ lineCode: 'ABC_1',
+ discussions: [],
+ },
+ ],
+ },
+ ],
+ };
+ const discussions = [
+ {
+ id: 1,
+ line_code: 'ABC_1',
+ diff_discussion: true,
+ active: true,
+ },
+ {
+ id: 2,
+ line_code: 'ABC_1',
+ diff_discussion: true,
+ active: true,
+ },
+ ];
+
+ const diffPositionByLineCode = {
+ ABC_1: diffPosition,
+ };
+
+ mutations[types.SET_LINE_DISCUSSIONS_FOR_FILE](state, {
+ fileHash: 'ABC',
+ discussions,
+ diffPositionByLineCode,
+ });
+
+ expect(state.diffFiles[0].parallelDiffLines[0].left.discussions.length).toEqual(2);
+ expect(state.diffFiles[0].parallelDiffLines[0].left.discussions[1].id).toEqual(2);
+
+ expect(state.diffFiles[0].highlightedDiffLines[0].discussions.length).toEqual(2);
+ expect(state.diffFiles[0].highlightedDiffLines[0].discussions[1].id).toEqual(2);
+ });
});
describe('REMOVE_LINE_DISCUSSIONS', () => {
diff --git a/spec/javascripts/diffs/store/utils_spec.js b/spec/javascripts/diffs/store/utils_spec.js
index 4b5cf450c68..897cd1483aa 100644
--- a/spec/javascripts/diffs/store/utils_spec.js
+++ b/spec/javascripts/diffs/store/utils_spec.js
@@ -3,6 +3,7 @@ import {
LINE_POSITION_LEFT,
LINE_POSITION_RIGHT,
TEXT_DIFF_POSITION_TYPE,
+ LEGACY_DIFF_NOTE_TYPE,
DIFF_NOTE_TYPE,
NEW_LINE_TYPE,
OLD_LINE_TYPE,
@@ -135,6 +136,7 @@ describe('DiffsStoreUtils', () => {
note_project_id: '',
target_type: options.noteableType,
target_id: options.noteableData.id,
+ return_discussion: true,
note: {
noteable_type: options.noteableType,
noteable_id: options.noteableData.id,
@@ -151,6 +153,65 @@ describe('DiffsStoreUtils', () => {
data: postData,
});
});
+
+ it('should create legacy note form data', () => {
+ const diffFile = getDiffFileMock();
+ delete diffFile.diffRefs.startSha;
+ delete diffFile.diffRefs.headSha;
+
+ noteableDataMock.targetType = MERGE_REQUEST_NOTEABLE_TYPE;
+
+ const options = {
+ note: 'Hello world!',
+ noteableData: noteableDataMock,
+ noteableType: MERGE_REQUEST_NOTEABLE_TYPE,
+ diffFile,
+ noteTargetLine: {
+ lineCode: '1c497fbb3a46b78edf04cc2a2fa33f67e3ffbe2a_1_3',
+ metaData: null,
+ newLine: 3,
+ oldLine: 1,
+ },
+ diffViewType: PARALLEL_DIFF_VIEW_TYPE,
+ linePosition: LINE_POSITION_LEFT,
+ };
+
+ const position = JSON.stringify({
+ base_sha: diffFile.diffRefs.baseSha,
+ start_sha: undefined,
+ head_sha: undefined,
+ old_path: diffFile.oldPath,
+ new_path: diffFile.newPath,
+ position_type: TEXT_DIFF_POSITION_TYPE,
+ old_line: options.noteTargetLine.oldLine,
+ new_line: options.noteTargetLine.newLine,
+ });
+
+ const postData = {
+ view: options.diffViewType,
+ line_type: options.linePosition === LINE_POSITION_RIGHT ? NEW_LINE_TYPE : OLD_LINE_TYPE,
+ merge_request_diff_head_sha: undefined,
+ in_reply_to_discussion_id: '',
+ note_project_id: '',
+ target_type: options.noteableType,
+ target_id: options.noteableData.id,
+ return_discussion: true,
+ note: {
+ noteable_type: options.noteableType,
+ noteable_id: options.noteableData.id,
+ commit_id: '',
+ type: LEGACY_DIFF_NOTE_TYPE,
+ line_code: options.noteTargetLine.lineCode,
+ note: options.note,
+ position,
+ },
+ };
+
+ expect(utils.getNoteFormData(options)).toEqual({
+ endpoint: options.noteableData.create_note_path,
+ data: postData,
+ });
+ });
});
describe('addLineReferences', () => {
@@ -291,13 +352,72 @@ describe('DiffsStoreUtils', () => {
it('returns true when the discussion is up to date', () => {
expect(
- utils.isDiscussionApplicableToLine(discussions.upToDateDiscussion1, diffPosition),
+ utils.isDiscussionApplicableToLine({
+ discussion: discussions.upToDateDiscussion1,
+ diffPosition,
+ latestDiff: true,
+ }),
).toBe(true);
});
it('returns false when the discussion is not up to date', () => {
expect(
- utils.isDiscussionApplicableToLine(discussions.outDatedDiscussion1, diffPosition),
+ utils.isDiscussionApplicableToLine({
+ discussion: discussions.outDatedDiscussion1,
+ diffPosition,
+ latestDiff: true,
+ }),
+ ).toBe(false);
+ });
+
+ it('returns true when line codes match and discussion does not contain position and is not active', () => {
+ const discussion = { ...discussions.outDatedDiscussion1, line_code: 'ABC_1', active: false };
+ delete discussion.original_position;
+ delete discussion.position;
+
+ expect(
+ utils.isDiscussionApplicableToLine({
+ discussion,
+ diffPosition: {
+ ...diffPosition,
+ lineCode: 'ABC_1',
+ },
+ latestDiff: true,
+ }),
+ ).toBe(false);
+ });
+
+ it('returns true when line codes match and discussion does not contain position and is active', () => {
+ const discussion = { ...discussions.outDatedDiscussion1, line_code: 'ABC_1', active: true };
+ delete discussion.original_position;
+ delete discussion.position;
+
+ expect(
+ utils.isDiscussionApplicableToLine({
+ discussion,
+ diffPosition: {
+ ...diffPosition,
+ lineCode: 'ABC_1',
+ },
+ latestDiff: true,
+ }),
+ ).toBe(true);
+ });
+
+ it('returns false when not latest diff', () => {
+ const discussion = { ...discussions.outDatedDiscussion1, line_code: 'ABC_1', active: true };
+ delete discussion.original_position;
+ delete discussion.position;
+
+ expect(
+ utils.isDiscussionApplicableToLine({
+ discussion,
+ diffPosition: {
+ ...diffPosition,
+ lineCode: 'ABC_1',
+ },
+ latestDiff: false,
+ }),
).toBe(false);
});
});
diff --git a/spec/javascripts/ide/components/file_row_extra_spec.js b/spec/javascripts/ide/components/file_row_extra_spec.js
new file mode 100644
index 00000000000..60dabe28045
--- /dev/null
+++ b/spec/javascripts/ide/components/file_row_extra_spec.js
@@ -0,0 +1,159 @@
+import Vue from 'vue';
+import { createStore } from '~/ide/stores';
+import { createComponentWithStore } from 'spec/helpers/vue_mount_component_helper';
+import FileRowExtra from '~/ide/components/file_row_extra.vue';
+import { file, resetStore } from '../helpers';
+
+describe('IDE extra file row component', () => {
+ let Component;
+ let vm;
+ let unstagedFilesCount = 0;
+ let stagedFilesCount = 0;
+ let changesCount = 0;
+
+ beforeAll(() => {
+ Component = Vue.extend(FileRowExtra);
+ });
+
+ beforeEach(() => {
+ vm = createComponentWithStore(Component, createStore(), {
+ file: {
+ ...file('test'),
+ },
+ mouseOver: false,
+ });
+
+ spyOnProperty(vm, 'getUnstagedFilesCountForPath').and.returnValue(() => unstagedFilesCount);
+ spyOnProperty(vm, 'getStagedFilesCountForPath').and.returnValue(() => stagedFilesCount);
+ spyOnProperty(vm, 'getChangesInFolder').and.returnValue(() => changesCount);
+
+ vm.$mount();
+ });
+
+ afterEach(() => {
+ vm.$destroy();
+ resetStore(vm.$store);
+
+ stagedFilesCount = 0;
+ unstagedFilesCount = 0;
+ changesCount = 0;
+ });
+
+ describe('folderChangesTooltip', () => {
+ it('returns undefined when changes count is 0', () => {
+ expect(vm.folderChangesTooltip).toBe(undefined);
+ });
+
+ it('returns unstaged changes text', () => {
+ changesCount = 1;
+ unstagedFilesCount = 1;
+
+ expect(vm.folderChangesTooltip).toBe('1 unstaged change');
+ });
+
+ it('returns staged changes text', () => {
+ changesCount = 1;
+ stagedFilesCount = 1;
+
+ expect(vm.folderChangesTooltip).toBe('1 staged change');
+ });
+
+ it('returns staged and unstaged changes text', () => {
+ changesCount = 1;
+ stagedFilesCount = 1;
+ unstagedFilesCount = 1;
+
+ expect(vm.folderChangesTooltip).toBe('1 unstaged and 1 staged changes');
+ });
+ });
+
+ describe('show tree changes count', () => {
+ it('does not show for blobs', () => {
+ vm.file.type = 'blob';
+
+ expect(vm.$el.querySelector('.ide-tree-changes')).toBe(null);
+ });
+
+ it('does not show when changes count is 0', () => {
+ vm.file.type = 'tree';
+
+ expect(vm.$el.querySelector('.ide-tree-changes')).toBe(null);
+ });
+
+ it('does not show when tree is open', done => {
+ vm.file.type = 'tree';
+ vm.file.opened = true;
+ changesCount = 1;
+
+ vm.$nextTick(() => {
+ expect(vm.$el.querySelector('.ide-tree-changes')).toBe(null);
+
+ done();
+ });
+ });
+
+ it('shows for trees with changes', done => {
+ vm.file.type = 'tree';
+ vm.file.opened = false;
+ changesCount = 1;
+
+ vm.$nextTick(() => {
+ expect(vm.$el.querySelector('.ide-tree-changes')).not.toBe(null);
+
+ done();
+ });
+ });
+ });
+
+ describe('changes file icon', () => {
+ it('hides when file is not changed', () => {
+ expect(vm.$el.querySelector('.ide-file-changed-icon')).toBe(null);
+ });
+
+ it('shows when file is changed', done => {
+ vm.file.changed = true;
+
+ vm.$nextTick(() => {
+ expect(vm.$el.querySelector('.ide-file-changed-icon')).not.toBe(null);
+
+ done();
+ });
+ });
+
+ it('shows when file is staged', done => {
+ vm.file.staged = true;
+
+ vm.$nextTick(() => {
+ expect(vm.$el.querySelector('.ide-file-changed-icon')).not.toBe(null);
+
+ done();
+ });
+ });
+
+ it('shows when file is a tempFile', done => {
+ vm.file.tempFile = true;
+
+ vm.$nextTick(() => {
+ expect(vm.$el.querySelector('.ide-file-changed-icon')).not.toBe(null);
+
+ done();
+ });
+ });
+ });
+
+ describe('merge request icon', () => {
+ it('hides when not a merge request change', () => {
+ expect(vm.$el.querySelector('.ic-git-merge')).toBe(null);
+ });
+
+ it('shows when a merge request change', done => {
+ vm.file.mrChange = true;
+
+ vm.$nextTick(() => {
+ expect(vm.$el.querySelector('.ic-git-merge')).not.toBe(null);
+
+ done();
+ });
+ });
+ });
+});
diff --git a/spec/javascripts/ide/components/repo_file_spec.js b/spec/javascripts/ide/components/repo_file_spec.js
deleted file mode 100644
index fc639a672e2..00000000000
--- a/spec/javascripts/ide/components/repo_file_spec.js
+++ /dev/null
@@ -1,145 +0,0 @@
-import Vue from 'vue';
-import store from '~/ide/stores';
-import repoFile from '~/ide/components/repo_file.vue';
-import router from '~/ide/ide_router';
-import { createComponentWithStore } from '../../helpers/vue_mount_component_helper';
-import { file } from '../helpers';
-
-describe('RepoFile', () => {
- let vm;
-
- function createComponent(propsData) {
- const RepoFile = Vue.extend(repoFile);
-
- vm = createComponentWithStore(RepoFile, store, propsData);
-
- vm.$mount();
- }
-
- afterEach(() => {
- vm.$destroy();
- });
-
- it('renders link, icon and name', () => {
- createComponent({
- file: file('t4'),
- level: 0,
- });
-
- const name = vm.$el.querySelector('.ide-file-name');
-
- expect(name.href).toMatch('');
- expect(name.textContent.trim()).toEqual(vm.file.name);
- });
-
- it('fires clickFile when the link is clicked', done => {
- spyOn(router, 'push');
- createComponent({
- file: file('t3'),
- level: 0,
- });
-
- vm.$el.querySelector('.file-name').click();
-
- setTimeout(() => {
- expect(router.push).toHaveBeenCalledWith(`/project${vm.file.url}`);
-
- done();
- });
- });
-
- describe('folder', () => {
- it('renders changes count inside folder', () => {
- const f = {
- ...file('folder'),
- path: 'testing',
- type: 'tree',
- branchId: 'master',
- projectId: 'project',
- };
-
- store.state.changedFiles.push({
- ...file('fileName'),
- path: 'testing/fileName',
- });
-
- createComponent({
- file: f,
- level: 0,
- });
-
- const treeChangesEl = vm.$el.querySelector('.ide-tree-changes');
-
- expect(treeChangesEl).not.toBeNull();
- expect(treeChangesEl.textContent).toContain('1');
- });
-
- it('renders action dropdown', done => {
- createComponent({
- file: {
- ...file('t4'),
- type: 'tree',
- branchId: 'master',
- projectId: 'project',
- },
- level: 0,
- });
-
- setTimeout(() => {
- expect(vm.$el.querySelector('.ide-new-btn')).not.toBeNull();
-
- done();
- });
- });
- });
-
- describe('locked file', () => {
- let f;
-
- beforeEach(() => {
- f = file('locked file');
- f.file_lock = {
- user: {
- name: 'testuser',
- updated_at: new Date(),
- },
- };
-
- createComponent({
- file: f,
- level: 0,
- });
- });
-
- it('renders lock icon', () => {
- expect(vm.$el.querySelector('.file-status-icon')).not.toBeNull();
- });
-
- it('renders a tooltip', () => {
- expect(
- vm.$el.querySelector('.ide-file-name span:nth-child(2)').dataset.originalTitle,
- ).toContain('Locked by testuser');
- });
- });
-
- it('calls scrollIntoView if made active', done => {
- createComponent({
- file: {
- ...file(),
- type: 'blob',
- active: false,
- },
- level: 0,
- });
-
- spyOn(vm, 'scrollIntoView');
-
- vm.file.active = true;
-
- vm.$nextTick(() => {
- expect(vm.scrollIntoView).toHaveBeenCalled();
-
- done();
- });
- });
-});
diff --git a/spec/javascripts/issue_show/components/edit_actions_spec.js b/spec/javascripts/issue_show/components/edit_actions_spec.js
index d779ab7bb31..a3772285527 100644
--- a/spec/javascripts/issue_show/components/edit_actions_spec.js
+++ b/spec/javascripts/issue_show/components/edit_actions_spec.js
@@ -54,7 +54,7 @@ describe('Edit Actions components', () => {
Vue.nextTick(() => {
expect(
- vm.$el.querySelector('.btn-save').getAttribute('disabled'),
+ vm.$el.querySelector('.btn-success').getAttribute('disabled'),
).toBe('disabled');
done();
@@ -72,7 +72,7 @@ describe('Edit Actions components', () => {
describe('updateIssuable', () => {
it('sends update.issauble event when clicking save button', () => {
- vm.$el.querySelector('.btn-save').click();
+ vm.$el.querySelector('.btn-success').click();
expect(
eventHub.$emit,
@@ -80,11 +80,11 @@ describe('Edit Actions components', () => {
});
it('shows loading icon after clicking save button', (done) => {
- vm.$el.querySelector('.btn-save').click();
+ vm.$el.querySelector('.btn-success').click();
Vue.nextTick(() => {
expect(
- vm.$el.querySelector('.btn-save .fa'),
+ vm.$el.querySelector('.btn-success .fa'),
).not.toBeNull();
done();
@@ -92,11 +92,11 @@ describe('Edit Actions components', () => {
});
it('disabled button after clicking save button', (done) => {
- vm.$el.querySelector('.btn-save').click();
+ vm.$el.querySelector('.btn-success').click();
Vue.nextTick(() => {
expect(
- vm.$el.querySelector('.btn-save').getAttribute('disabled'),
+ vm.$el.querySelector('.btn-success').getAttribute('disabled'),
).toBe('disabled');
done();
diff --git a/spec/javascripts/shortcuts_dashboard_navigation_spec.js b/spec/javascripts/lib/utils/navigation_utility_spec.js
index 7cb201e01d8..be620e4a27c 100644
--- a/spec/javascripts/shortcuts_dashboard_navigation_spec.js
+++ b/spec/javascripts/lib/utils/navigation_utility_spec.js
@@ -1,4 +1,4 @@
-import findAndFollowLink from '~/shortcuts_dashboard_navigation';
+import findAndFollowLink from '~/lib/utils/navigation_utility';
describe('findAndFollowLink', () => {
it('visits a link when the selector exists', () => {
diff --git a/spec/javascripts/lib/utils/poll_spec.js b/spec/javascripts/lib/utils/poll_spec.js
index 523f4997bc0..b28a052902e 100644
--- a/spec/javascripts/lib/utils/poll_spec.js
+++ b/spec/javascripts/lib/utils/poll_spec.js
@@ -1,3 +1,5 @@
+/* eslint-disable jasmine/no-unsafe-spy */
+
import Poll from '~/lib/utils/poll';
import { successCodes } from '~/lib/utils/http_status';
diff --git a/spec/javascripts/notes/stores/mutation_spec.js b/spec/javascripts/notes/stores/mutation_spec.js
index 6b7f61468d5..1ecfe914859 100644
--- a/spec/javascripts/notes/stores/mutation_spec.js
+++ b/spec/javascripts/notes/stores/mutation_spec.js
@@ -156,6 +156,41 @@ describe('Notes Store mutations', () => {
expect(state.discussions[2].notes[0].note).toBe(legacyNote.notes[1].note);
expect(state.discussions.length).toEqual(3);
});
+
+ it('adds truncated_diff_lines if discussion is a diffFile', () => {
+ const state = {
+ discussions: [],
+ };
+
+ mutations.SET_INITIAL_DISCUSSIONS(state, [
+ {
+ ...note,
+ diff_file: {
+ file_hash: 'a',
+ },
+ truncated_diff_lines: ['a'],
+ },
+ ]);
+
+ expect(state.discussions[0].truncated_diff_lines).toEqual(['a']);
+ });
+
+ it('adds empty truncated_diff_lines when not in discussion', () => {
+ const state = {
+ discussions: [],
+ };
+
+ mutations.SET_INITIAL_DISCUSSIONS(state, [
+ {
+ ...note,
+ diff_file: {
+ file_hash: 'a',
+ },
+ },
+ ]);
+
+ expect(state.discussions[0].truncated_diff_lines).toEqual([]);
+ });
});
describe('SET_LAST_FETCHED_AT', () => {
diff --git a/spec/javascripts/right_sidebar_spec.js b/spec/javascripts/right_sidebar_spec.js
index 6d49536a712..c7190ea9960 100644
--- a/spec/javascripts/right_sidebar_spec.js
+++ b/spec/javascripts/right_sidebar_spec.js
@@ -1,4 +1,4 @@
-/* eslint-disable no-var, one-var, one-var-declaration-per-line, no-return-assign, vars-on-top, max-len */
+/* eslint-disable no-var, one-var, one-var-declaration-per-line, no-return-assign, vars-on-top, jasmine/no-unsafe-spy, max-len */
import $ from 'jquery';
import MockAdapter from 'axios-mock-adapter';
diff --git a/spec/javascripts/search_autocomplete_spec.js b/spec/javascripts/search_autocomplete_spec.js
index 86c001678c5..646d843162c 100644
--- a/spec/javascripts/search_autocomplete_spec.js
+++ b/spec/javascripts/search_autocomplete_spec.js
@@ -2,7 +2,7 @@
import $ from 'jquery';
import '~/gl_dropdown';
-import SearchAutocomplete from '~/search_autocomplete';
+import initSearchAutocomplete from '~/search_autocomplete';
import '~/lib/utils/common_utils';
describe('Search autocomplete dropdown', () => {
@@ -132,7 +132,7 @@ describe('Search autocomplete dropdown', () => {
window.gon.current_user_id = userId;
window.gon.current_username = userName;
- return (widget = new SearchAutocomplete());
+ return (widget = initSearchAutocomplete());
});
afterEach(function() {
diff --git a/spec/javascripts/shortcuts_spec.js b/spec/javascripts/shortcuts_spec.js
index 94cded7ee37..3ca6ecaa938 100644
--- a/spec/javascripts/shortcuts_spec.js
+++ b/spec/javascripts/shortcuts_spec.js
@@ -1,5 +1,5 @@
import $ from 'jquery';
-import Shortcuts from '~/shortcuts';
+import Shortcuts from '~/behaviors/shortcuts/shortcuts';
describe('Shortcuts', () => {
const fixtureName = 'snippets/show.html.raw';
diff --git a/spec/javascripts/vue_shared/components/file_row_spec.js b/spec/javascripts/vue_shared/components/file_row_spec.js
new file mode 100644
index 00000000000..9914c0b70f3
--- /dev/null
+++ b/spec/javascripts/vue_shared/components/file_row_spec.js
@@ -0,0 +1,74 @@
+import Vue from 'vue';
+import FileRow from '~/vue_shared/components/file_row.vue';
+import { file } from 'spec/ide/helpers';
+import mountComponent from '../../helpers/vue_mount_component_helper';
+
+describe('RepoFile', () => {
+ let vm;
+
+ function createComponent(propsData) {
+ const FileRowComponent = Vue.extend(FileRow);
+
+ vm = mountComponent(FileRowComponent, propsData);
+ }
+
+ afterEach(() => {
+ vm.$destroy();
+ });
+
+ it('renders name', () => {
+ createComponent({
+ file: file('t4'),
+ level: 0,
+ });
+
+ const name = vm.$el.querySelector('.file-row-name');
+
+ expect(name.textContent.trim()).toEqual(vm.file.name);
+ });
+
+ it('emits toggleTreeOpen on click', () => {
+ createComponent({
+ file: {
+ ...file('t3'),
+ type: 'tree',
+ },
+ level: 0,
+ });
+ spyOn(vm, '$emit').and.stub();
+
+ vm.$el.querySelector('.file-row').click();
+
+ expect(vm.$emit).toHaveBeenCalledWith('toggleTreeOpen', vm.file.path);
+ });
+
+ it('calls scrollIntoView if made active', done => {
+ createComponent({
+ file: {
+ ...file(),
+ type: 'blob',
+ active: false,
+ },
+ level: 0,
+ });
+
+ spyOn(vm, 'scrollIntoView').and.stub();
+
+ vm.file.active = true;
+
+ vm.$nextTick(() => {
+ expect(vm.scrollIntoView).toHaveBeenCalled();
+
+ done();
+ });
+ });
+
+ it('indents row based on level', () => {
+ createComponent({
+ file: file('t4'),
+ level: 2,
+ });
+
+ expect(vm.$el.querySelector('.file-row-name').style.marginLeft).toBe('32px');
+ });
+});
diff --git a/spec/lib/gitlab/auth/ldap/access_spec.rb b/spec/lib/gitlab/auth/ldap/access_spec.rb
index 7800c543cdb..662f899180b 100644
--- a/spec/lib/gitlab/auth/ldap/access_spec.rb
+++ b/spec/lib/gitlab/auth/ldap/access_spec.rb
@@ -48,7 +48,7 @@ describe Gitlab::Auth::LDAP::Access do
it 'logs the reason' do
expect(Gitlab::AppLogger).to receive(:info).with(
"LDAP account \"123456\" does not exist anymore, " \
- "blocking Gitlab user \"#{user.name}\" (#{user.email})"
+ "blocking GitLab user \"#{user.name}\" (#{user.email})"
)
access.allowed?
@@ -79,7 +79,7 @@ describe Gitlab::Auth::LDAP::Access do
it 'logs the reason' do
expect(Gitlab::AppLogger).to receive(:info).with(
"LDAP account \"123456\" is disabled in Active Directory, " \
- "blocking Gitlab user \"#{user.name}\" (#{user.email})"
+ "blocking GitLab user \"#{user.name}\" (#{user.email})"
)
access.allowed?
@@ -123,7 +123,7 @@ describe Gitlab::Auth::LDAP::Access do
it 'logs the reason' do
expect(Gitlab::AppLogger).to receive(:info).with(
"LDAP account \"123456\" is not disabled anymore, " \
- "unblocking Gitlab user \"#{user.name}\" (#{user.email})"
+ "unblocking GitLab user \"#{user.name}\" (#{user.email})"
)
access.allowed?
@@ -161,7 +161,7 @@ describe Gitlab::Auth::LDAP::Access do
it 'logs the reason' do
expect(Gitlab::AppLogger).to receive(:info).with(
"LDAP account \"123456\" does not exist anymore, " \
- "blocking Gitlab user \"#{user.name}\" (#{user.email})"
+ "blocking GitLab user \"#{user.name}\" (#{user.email})"
)
access.allowed?
@@ -183,7 +183,7 @@ describe Gitlab::Auth::LDAP::Access do
it 'logs the reason' do
expect(Gitlab::AppLogger).to receive(:info).with(
"LDAP account \"123456\" is available again, " \
- "unblocking Gitlab user \"#{user.name}\" (#{user.email})"
+ "unblocking GitLab user \"#{user.name}\" (#{user.email})"
)
access.allowed?
diff --git a/spec/lib/gitlab/database/subquery_spec.rb b/spec/lib/gitlab/database/subquery_spec.rb
new file mode 100644
index 00000000000..70380e02f16
--- /dev/null
+++ b/spec/lib/gitlab/database/subquery_spec.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Database::Subquery do
+ describe '.self_join' do
+ set(:project) { create(:project) }
+
+ it 'allows you to delete_all rows with WHERE and LIMIT' do
+ events = create_list(:event, 8, project: project)
+
+ expect do
+ described_class.self_join(Event.where('id < ?', events[5]).recent.limit(2)).delete_all
+ end.to change { Event.count }.by(-2)
+ end
+ end
+end
diff --git a/spec/lib/gitlab/diff/file_collection/commit_spec.rb b/spec/lib/gitlab/diff/file_collection/commit_spec.rb
new file mode 100644
index 00000000000..6d1b66deb6a
--- /dev/null
+++ b/spec/lib/gitlab/diff/file_collection/commit_spec.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::Diff::FileCollection::Commit do
+ let(:project) { create(:project, :repository) }
+
+ it_behaves_like 'diff statistics' do
+ let(:collection_default_args) do
+ { diff_options: {} }
+ end
+ let(:diffable) { project.commit }
+ let(:stub_path) { 'bar/branch-test.txt' }
+ end
+end
diff --git a/spec/lib/gitlab/diff/file_collection/compare_spec.rb b/spec/lib/gitlab/diff/file_collection/compare_spec.rb
new file mode 100644
index 00000000000..f330f299ac1
--- /dev/null
+++ b/spec/lib/gitlab/diff/file_collection/compare_spec.rb
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::Diff::FileCollection::Compare do
+ include RepoHelpers
+
+ let(:project) { create(:project, :repository) }
+ let(:commit) { project.commit }
+ let(:start_commit) { sample_image_commit }
+ let(:head_commit) { sample_commit }
+ let(:raw_compare) do
+ Gitlab::Git::Compare.new(project.repository.raw_repository,
+ start_commit.id,
+ head_commit.id)
+ end
+
+ it_behaves_like 'diff statistics' do
+ let(:collection_default_args) do
+ {
+ project: diffable.project,
+ diff_options: {},
+ diff_refs: diffable.diff_refs
+ }
+ end
+ let(:diffable) { Compare.new(raw_compare, project) }
+ let(:stub_path) { '.gitignore' }
+ end
+end
diff --git a/spec/lib/gitlab/diff/file_collection/merge_request_diff_spec.rb b/spec/lib/gitlab/diff/file_collection/merge_request_diff_spec.rb
index 79287021981..4578da70bfc 100644
--- a/spec/lib/gitlab/diff/file_collection/merge_request_diff_spec.rb
+++ b/spec/lib/gitlab/diff/file_collection/merge_request_diff_spec.rb
@@ -29,6 +29,14 @@ describe Gitlab::Diff::FileCollection::MergeRequestDiff do
expect(mr_diff.cache_key).not_to eq(key)
end
+ it_behaves_like 'diff statistics' do
+ let(:collection_default_args) do
+ { diff_options: {} }
+ end
+ let(:diffable) { merge_request.merge_request_diff }
+ let(:stub_path) { '.gitignore' }
+ end
+
shared_examples 'initializes a DiffCollection' do
it 'returns a valid instance of a DiffCollection' do
expect(diff_files).to be_a(Gitlab::Git::DiffCollection)
diff --git a/spec/lib/gitlab/diff/file_spec.rb b/spec/lib/gitlab/diff/file_spec.rb
index ebeb05d6e02..2f51642b58e 100644
--- a/spec/lib/gitlab/diff/file_spec.rb
+++ b/spec/lib/gitlab/diff/file_spec.rb
@@ -186,6 +186,70 @@ describe Gitlab::Diff::File do
end
end
+ context 'diff file stats' do
+ let(:diff_file) do
+ described_class.new(diff,
+ diff_refs: commit.diff_refs,
+ repository: project.repository,
+ stats: stats)
+ end
+
+ let(:raw_diff) do
+ <<~EOS
+ --- a/files/ruby/popen.rb
+ +++ b/files/ruby/popen.rb
+ @@ -6,12 +6,18 @@ module Popen
+
+ def popen(cmd, path=nil)
+ unless cmd.is_a?(Array)
+ - raise "System commands must be given as an array of strings"
+ + raise RuntimeError, "System commands must be given as an array of strings"
+ + # foobar
+ end
+ EOS
+ end
+
+ describe '#added_lines' do
+ context 'when stats argument given' do
+ let(:stats) { double(Gitaly::DiffStats, additions: 10, deletions: 15) }
+
+ it 'returns added lines from stats' do
+ expect(diff_file.added_lines).to eq(stats.additions)
+ end
+ end
+
+ context 'when stats argument not given' do
+ let(:stats) { nil }
+
+ it 'returns added lines by parsing raw diff' do
+ allow(diff_file).to receive(:raw_diff) { raw_diff }
+
+ expect(diff_file.added_lines).to eq(2)
+ end
+ end
+ end
+
+ describe '#removed_lines' do
+ context 'when stats argument given' do
+ let(:stats) { double(Gitaly::DiffStats, additions: 10, deletions: 15) }
+
+ it 'returns removed lines from stats' do
+ expect(diff_file.removed_lines).to eq(stats.deletions)
+ end
+ end
+
+ context 'when stats argument not given' do
+ let(:stats) { nil }
+
+ it 'returns removed lines by parsing raw diff' do
+ allow(diff_file).to receive(:raw_diff) { raw_diff }
+
+ expect(diff_file.removed_lines).to eq(1)
+ end
+ end
+ end
+ end
+
describe '#simple_viewer' do
context 'when the file is not diffable' do
before do
diff --git a/spec/lib/gitlab/git/diff_stats_collection_spec.rb b/spec/lib/gitlab/git/diff_stats_collection_spec.rb
new file mode 100644
index 00000000000..89927cbb3a6
--- /dev/null
+++ b/spec/lib/gitlab/git/diff_stats_collection_spec.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+require "spec_helper"
+
+describe Gitlab::Git::DiffStatsCollection do
+ let(:stats_a) do
+ double(Gitaly::DiffStats, additions: 10, deletions: 15, path: 'foo')
+ end
+
+ let(:stats_b) do
+ double(Gitaly::DiffStats, additions: 5, deletions: 1, path: 'bar')
+ end
+
+ let(:diff_stats) { [stats_a, stats_b] }
+ let(:collection) { described_class.new(diff_stats) }
+
+ describe '.find_by_path' do
+ it 'returns stats by path when found' do
+ expect(collection.find_by_path('foo')).to eq(stats_a)
+ end
+
+ it 'returns nil when stats is not found by path' do
+ expect(collection.find_by_path('no-file')).to be_nil
+ end
+ end
+end
diff --git a/spec/lib/gitlab/git/repository_spec.rb b/spec/lib/gitlab/git/repository_spec.rb
index ce4caf0c27d..d02536a2fb4 100644
--- a/spec/lib/gitlab/git/repository_spec.rb
+++ b/spec/lib/gitlab/git/repository_spec.rb
@@ -1112,6 +1112,40 @@ describe Gitlab::Git::Repository, :seed_helper do
end
end
+ describe '#diff_stats' do
+ let(:left_commit_id) { 'feature' }
+ let(:right_commit_id) { 'master' }
+
+ it 'returns a DiffStatsCollection' do
+ collection = repository.diff_stats(left_commit_id, right_commit_id)
+
+ expect(collection).to be_a(Gitlab::Git::DiffStatsCollection)
+ expect(collection).to be_a(Enumerable)
+ end
+
+ it 'yields Gitaly::DiffStats objects' do
+ collection = repository.diff_stats(left_commit_id, right_commit_id)
+
+ expect(collection.to_a).to all(be_a(Gitaly::DiffStats))
+ end
+
+ it 'returns no Gitaly::DiffStats when SHAs are invalid' do
+ collection = repository.diff_stats('foo', 'bar')
+
+ expect(collection).to be_a(Gitlab::Git::DiffStatsCollection)
+ expect(collection).to be_a(Enumerable)
+ expect(collection.to_a).to be_empty
+ end
+
+ it 'returns no Gitaly::DiffStats when there is a nil SHA' do
+ collection = repository.diff_stats(nil, 'master')
+
+ expect(collection).to be_a(Gitlab::Git::DiffStatsCollection)
+ expect(collection).to be_a(Enumerable)
+ expect(collection.to_a).to be_empty
+ end
+ end
+
describe "#ls_files" do
let(:master_file_paths) { repository.ls_files("master") }
let(:utf8_file_paths) { repository.ls_files("ls-files-utf8") }
diff --git a/spec/lib/gitlab/gitaly_client/commit_service_spec.rb b/spec/lib/gitlab/gitaly_client/commit_service_spec.rb
index bcdf12a00a0..d7bd757149d 100644
--- a/spec/lib/gitlab/gitaly_client/commit_service_spec.rb
+++ b/spec/lib/gitlab/gitaly_client/commit_service_spec.rb
@@ -118,6 +118,22 @@ describe Gitlab::GitalyClient::CommitService do
end
end
+ describe '#diff_stats' do
+ let(:left_commit_id) { 'master' }
+ let(:right_commit_id) { 'cfe32cf61b73a0d5e9f13e774abde7ff789b1660' }
+
+ it 'sends an RPC request' do
+ request = Gitaly::DiffStatsRequest.new(repository: repository_message,
+ left_commit_id: left_commit_id,
+ right_commit_id: right_commit_id)
+
+ expect_any_instance_of(Gitaly::DiffService::Stub).to receive(:diff_stats)
+ .with(request, kind_of(Hash)).and_return([])
+
+ described_class.new(repository).diff_stats(left_commit_id, right_commit_id)
+ end
+ end
+
describe '#tree_entries' do
let(:path) { '/' }
diff --git a/spec/lib/gitlab/middleware/read_only_spec.rb b/spec/lib/gitlab/middleware/read_only_spec.rb
index 8fbeaa065fa..ac3bc6b2dfe 100644
--- a/spec/lib/gitlab/middleware/read_only_spec.rb
+++ b/spec/lib/gitlab/middleware/read_only_spec.rb
@@ -34,7 +34,7 @@ describe Gitlab::Middleware::ReadOnly do
end
end
- context 'normal requests to a read-only Gitlab instance' do
+ context 'normal requests to a read-only GitLab instance' do
let(:fake_app) { lambda { |env| [200, { 'Content-Type' => 'text/plain' }, ['OK']] } }
before do
diff --git a/spec/models/ci/pipeline_spec.rb b/spec/models/ci/pipeline_spec.rb
index 2216705c032..4755702c0e9 100644
--- a/spec/models/ci/pipeline_spec.rb
+++ b/spec/models/ci/pipeline_spec.rb
@@ -1151,7 +1151,11 @@ describe Ci::Pipeline, :mailer do
end
describe '#set_config_source' do
- context 'when pipelines does not contain needed data' do
+ context 'when pipelines does not contain needed data and auto devops is disabled' do
+ before do
+ stub_application_setting(auto_devops_enabled: false)
+ end
+
it 'defines source to be unknown' do
pipeline.set_config_source
@@ -1196,7 +1200,6 @@ describe Ci::Pipeline, :mailer do
context 'auto devops enabled' do
before do
- stub_application_setting(auto_devops_enabled: true)
allow(project).to receive(:ci_config_path) { 'custom' }
end
diff --git a/spec/models/concerns/from_union_spec.rb b/spec/models/concerns/from_union_spec.rb
new file mode 100644
index 00000000000..ee427a667c6
--- /dev/null
+++ b/spec/models/concerns/from_union_spec.rb
@@ -0,0 +1,40 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe FromUnion do
+ describe '.from_union' do
+ let(:model) do
+ Class.new(ActiveRecord::Base) do
+ self.table_name = 'users'
+
+ include FromUnion
+ end
+ end
+
+ it 'selects from the results of the UNION' do
+ query = model.from_union([model.where(id: 1), model.where(id: 2)])
+
+ expect(query.to_sql).to match(/FROM \(SELECT.+UNION.+SELECT.+\) users/m)
+ end
+
+ it 'supports the use of a custom alias for the sub query' do
+ query = model.from_union(
+ [model.where(id: 1), model.where(id: 2)],
+ alias_as: 'kittens'
+ )
+
+ expect(query.to_sql).to match(/FROM \(SELECT.+UNION.+SELECT.+\) kittens/m)
+ end
+
+ it 'supports keeping duplicate rows' do
+ query = model.from_union(
+ [model.where(id: 1), model.where(id: 2)],
+ remove_duplicates: false
+ )
+
+ expect(query.to_sql)
+ .to match(/FROM \(SELECT.+UNION ALL.+SELECT.+\) users/m)
+ end
+ end
+end
diff --git a/spec/models/instance_configuration_spec.rb b/spec/models/instance_configuration_spec.rb
index 8548fff5c76..34db94920f3 100644
--- a/spec/models/instance_configuration_spec.rb
+++ b/spec/models/instance_configuration_spec.rb
@@ -52,7 +52,7 @@ RSpec.describe InstanceConfiguration do
expect(gitlab_pages).to eq(Settings.pages.symbolize_keys)
end
- it 'returns the Gitlab\'s pages host ip address' do
+ it 'returns the GitLab\'s pages host ip address' do
expect(gitlab_pages.keys).to include(:ip_address)
end
diff --git a/spec/models/milestone_spec.rb b/spec/models/milestone_spec.rb
index 55b984faecf..27d4e622710 100644
--- a/spec/models/milestone_spec.rb
+++ b/spec/models/milestone_spec.rb
@@ -95,6 +95,24 @@ describe Milestone do
end
end
+ describe '.order_by_name_asc' do
+ it 'sorts by name ascending' do
+ milestone1 = create(:milestone, title: 'Foo')
+ milestone2 = create(:milestone, title: 'Bar')
+
+ expect(described_class.order_by_name_asc).to eq([milestone2, milestone1])
+ end
+ end
+
+ describe '.reorder_by_due_date_asc' do
+ it 'reorders the input relation' do
+ milestone1 = create(:milestone, due_date: Date.new(2018, 9, 30))
+ milestone2 = create(:milestone, due_date: Date.new(2018, 10, 20))
+
+ expect(described_class.reorder_by_due_date_asc).to eq([milestone1, milestone2])
+ end
+ end
+
describe "#percent_complete" do
it "does not count open issues" do
milestone.issues << issue
diff --git a/spec/models/project_services/chat_message/merge_message_spec.rb b/spec/models/project_services/chat_message/merge_message_spec.rb
index 96496295825..7997b5bb6b9 100644
--- a/spec/models/project_services/chat_message/merge_message_spec.rb
+++ b/spec/models/project_services/chat_message/merge_message_spec.rb
@@ -27,6 +27,23 @@ describe ChatMessage::MergeMessage do
}
end
+ # Integration point in EE
+ context 'when state is overridden' do
+ it 'respects the overridden state' do
+ allow(subject).to receive(:state_or_action_text) { 'devoured' }
+
+ aggregate_failures do
+ expect(subject.summary).not_to include('opened')
+ expect(subject.summary).to include('devoured')
+
+ activity_title = subject.activity[:title]
+
+ expect(activity_title).not_to include('opened')
+ expect(activity_title).to include('devoured')
+ end
+ end
+ end
+
context 'without markdown' do
let(:color) { '#345' }
diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb
index dfe2de71a76..afc9ea1917e 100644
--- a/spec/models/project_spec.rb
+++ b/spec/models/project_spec.rb
@@ -1072,6 +1072,18 @@ describe Project do
it { expect(project.builds_enabled?).to be_truthy }
end
+ describe '.sort_by_attribute' do
+ it 'reorders the input relation by start count desc' do
+ project1 = create(:project, star_count: 2)
+ project2 = create(:project, star_count: 1)
+ project3 = create(:project)
+
+ projects = described_class.sort_by_attribute(:stars_desc)
+
+ expect(projects).to eq([project1, project2, project3])
+ end
+ end
+
describe '.with_shared_runners' do
subject { described_class.with_shared_runners }
@@ -3229,17 +3241,17 @@ describe Project do
expect(repository).to receive(:gitlab_ci_yml) { nil }
end
- it "CI is not available" do
- expect(project).not_to have_ci
+ it "CI is available" do
+ expect(project).to have_ci
end
- context 'when auto devops is enabled' do
+ context 'when auto devops is disabled' do
before do
- stub_application_setting(auto_devops_enabled: true)
+ stub_application_setting(auto_devops_enabled: false)
end
- it "CI is available" do
- expect(project).to have_ci
+ it "CI is not available" do
+ expect(project).not_to have_ci
end
end
end
@@ -3983,40 +3995,6 @@ describe Project do
end
end
- describe '#update_root_ref' do
- let(:project) { create(:project, :repository) }
-
- it 'updates the default branch when HEAD has changed' do
- stub_find_remote_root_ref(project, ref: 'feature')
-
- expect { project.update_root_ref('origin') }
- .to change { project.default_branch }
- .from('master')
- .to('feature')
- end
-
- it 'does not update the default branch when HEAD does not change' do
- stub_find_remote_root_ref(project, ref: 'master')
-
- expect { project.update_root_ref('origin') }
- .not_to change { project.default_branch }
- end
-
- it 'does not update the default branch when HEAD does not exist' do
- stub_find_remote_root_ref(project, ref: 'foo')
-
- expect { project.update_root_ref('origin') }
- .not_to change { project.default_branch }
- end
-
- def stub_find_remote_root_ref(project, ref:)
- allow(project.repository)
- .to receive(:find_remote_root_ref)
- .with('origin')
- .and_return(ref)
- end
- end
-
def rugged_config
Gitlab::GitalyClient::StorageSettings.allow_disk_access do
project.repository.rugged.config
diff --git a/spec/models/project_wiki_spec.rb b/spec/models/project_wiki_spec.rb
index 528f5b610d7..f38fc191943 100644
--- a/spec/models/project_wiki_spec.rb
+++ b/spec/models/project_wiki_spec.rb
@@ -2,12 +2,13 @@
require "spec_helper"
describe ProjectWiki do
- let(:project) { create(:project, :wiki_repo) }
+ let(:user) { create(:user, :commit_email) }
+ let(:project) { create(:project, :wiki_repo, namespace: user.namespace) }
let(:repository) { project.repository }
- let(:user) { project.owner }
let(:gitlab_shell) { Gitlab::Shell.new }
let(:project_wiki) { described_class.new(project, user) }
let(:raw_repository) { Gitlab::Git::Repository.new(project.repository_storage, subject.disk_path + '.git', 'foo') }
+ let(:commit) { project_wiki.repository.head_commit }
subject { project_wiki }
@@ -276,6 +277,14 @@ describe ProjectWiki do
expect(subject.pages.first.page.version.message).to eq("commit message")
end
+ it 'sets the correct commit email' do
+ subject.create_page('test page', 'content')
+
+ expect(user.commit_email).not_to eq(user.email)
+ expect(commit.author_email).to eq(user.commit_email)
+ expect(commit.committer_email).to eq(user.commit_email)
+ end
+
it 'updates project activity' do
subject.create_page('Test Page', 'This is content')
@@ -320,6 +329,12 @@ describe ProjectWiki do
expect(@page.version.message).to eq("updated page")
end
+ it 'sets the correct commit email' do
+ expect(user.commit_email).not_to eq(user.email)
+ expect(commit.author_email).to eq(user.commit_email)
+ expect(commit.committer_email).to eq(user.commit_email)
+ end
+
it 'updates project activity' do
subject.update_page(
@gitlab_git_wiki_page,
@@ -347,6 +362,14 @@ describe ProjectWiki do
expect(subject.pages.count).to eq(0)
end
+ it 'sets the correct commit email' do
+ subject.delete_page(@page)
+
+ expect(user.commit_email).not_to eq(user.email)
+ expect(commit.author_email).to eq(user.commit_email)
+ expect(commit.committer_email).to eq(user.commit_email)
+ end
+
it 'updates project activity' do
subject.delete_page(@page)
@@ -420,7 +443,7 @@ describe ProjectWiki do
end
def commit_details
- Gitlab::Git::Wiki::CommitDetails.new(user.id, user.username, user.name, user.email, "test commit")
+ Gitlab::Git::Wiki::CommitDetails.new(user.id, user.username, user.name, user.commit_email, "test commit")
end
def create_page(name, content)
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index 27aec49e348..99d17f563d9 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -2543,6 +2543,34 @@ describe User do
end
end
+ describe '#assigned_open_merge_requests_count' do
+ it 'returns number of open merge requests from non-archived projects' do
+ user = create(:user)
+ project = create(:project, :public)
+ archived_project = create(:project, :public, :archived)
+
+ create(:merge_request, source_project: project, author: user, assignee: user)
+ create(:merge_request, :closed, source_project: project, author: user, assignee: user)
+ create(:merge_request, source_project: archived_project, author: user, assignee: user)
+
+ expect(user.assigned_open_merge_requests_count(force: true)).to eq 1
+ end
+ end
+
+ describe '#assigned_open_issues_count' do
+ it 'returns number of open issues from non-archived projects' do
+ user = create(:user)
+ project = create(:project, :public)
+ archived_project = create(:project, :public, :archived)
+
+ create(:issue, project: project, author: user, assignees: [user])
+ create(:issue, :closed, project: project, author: user, assignees: [user])
+ create(:issue, project: archived_project, author: user, assignees: [user])
+
+ expect(user.assigned_open_issues_count(force: true)).to eq 1
+ end
+ end
+
describe '#personal_projects_count' do
it 'returns the number of personal projects using a single query' do
user = build(:user)
diff --git a/spec/requests/api/pipelines_spec.rb b/spec/requests/api/pipelines_spec.rb
index 342a97b6a69..f0e1992bccd 100644
--- a/spec/requests/api/pipelines_spec.rb
+++ b/spec/requests/api/pipelines_spec.rb
@@ -370,12 +370,18 @@ describe API::Pipelines do
end
context 'without gitlab-ci.yml' do
- it 'fails to create pipeline' do
- post api("/projects/#{project.id}/pipeline", user), ref: project.default_branch
+ context 'without auto devops enabled' do
+ before do
+ project.update!(auto_devops_attributes: { enabled: false })
+ end
- expect(response).to have_gitlab_http_status(400)
- expect(json_response['message']['base'].first).to eq 'Missing .gitlab-ci.yml file'
- expect(json_response).not_to be_an Array
+ it 'fails to create pipeline' do
+ post api("/projects/#{project.id}/pipeline", user), ref: project.default_branch
+
+ expect(response).to have_gitlab_http_status(400)
+ expect(json_response['message']['base'].first).to eq 'Missing .gitlab-ci.yml file'
+ expect(json_response).not_to be_an Array
+ end
end
end
end
diff --git a/spec/requests/openid_connect_spec.rb b/spec/requests/openid_connect_spec.rb
index b14d4b8fb6e..b1cf7a531f4 100644
--- a/spec/requests/openid_connect_spec.rb
+++ b/spec/requests/openid_connect_spec.rb
@@ -121,7 +121,7 @@ describe 'OpenID Connect requests' do
expect(@payload).to match(a_hash_including(id_token_claims))
end
- it 'includes the Gitlab root URL' do
+ it 'includes the GitLab root URL' do
expect(@payload['iss']).to eq Gitlab.config.gitlab.url
end
diff --git a/spec/rubocop/cop/avoid_route_redirect_leading_slash_spec.rb b/spec/rubocop/cop/avoid_route_redirect_leading_slash_spec.rb
new file mode 100644
index 00000000000..c9eb61ccc72
--- /dev/null
+++ b/spec/rubocop/cop/avoid_route_redirect_leading_slash_spec.rb
@@ -0,0 +1,32 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require 'rubocop'
+require_relative '../../../rubocop/cop/avoid_route_redirect_leading_slash'
+
+describe RuboCop::Cop::AvoidRouteRedirectLeadingSlash do
+ include CopHelper
+
+ subject(:cop) { described_class.new }
+
+ before do
+ allow(cop).to receive(:in_routes?).and_return(true)
+ end
+
+ it 'registers an offense when redirect has a leading slash' do
+ expect_offense(<<~PATTERN.strip_indent)
+ root to: redirect("/-/route")
+ ^^^^^^^^^^^^^^^^^^^^ Do not use a leading "/" in route redirects
+ PATTERN
+ end
+
+ it 'does not register an offense when redirect does not have a leading slash' do
+ expect_no_offenses(<<~PATTERN.strip_indent)
+ root to: redirect("-/route")
+ PATTERN
+ end
+
+ it 'autocorrect `/-/route` to `-/route`' do
+ expect(autocorrect_source('redirect("/-/route")')).to eq('redirect("-/route")')
+ end
+end
diff --git a/spec/rubocop/cop/gitlab/union_spec.rb b/spec/rubocop/cop/gitlab/union_spec.rb
new file mode 100644
index 00000000000..5b06f30b25f
--- /dev/null
+++ b/spec/rubocop/cop/gitlab/union_spec.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require 'rubocop'
+require 'rubocop/rspec/support'
+require_relative '../../../../rubocop/cop/gitlab/union'
+
+describe RuboCop::Cop::Gitlab::Union do
+ include CopHelper
+
+ subject(:cop) { described_class.new }
+
+ it 'flags the use of Gitlab::SQL::Union.new' do
+ expect_offense(<<~SOURCE)
+ Gitlab::SQL::Union.new([foo])
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use the `FromUnion` concern, instead of using `Gitlab::SQL::Union` directly
+ SOURCE
+ end
+
+ it 'does not flag the use of Gitlab::SQL::Union in a spec' do
+ allow(cop).to receive(:in_spec?).and_return(true)
+
+ expect_no_offenses('Gitlab::SQL::Union.new([foo])')
+ end
+end
diff --git a/spec/services/auth/container_registry_authentication_service_spec.rb b/spec/services/auth/container_registry_authentication_service_spec.rb
index c7f88e45c84..f2e9799452a 100644
--- a/spec/services/auth/container_registry_authentication_service_spec.rb
+++ b/spec/services/auth/container_registry_authentication_service_spec.rb
@@ -145,7 +145,7 @@ describe Auth::ContainerRegistryAuthenticationService do
{ scopes: ["registry:catalog:*"] }
end
- context 'disallow browsing for users without Gitlab admin rights' do
+ context 'disallow browsing for users without GitLab admin rights' do
it_behaves_like 'an inaccessible'
it_behaves_like 'not a container repository factory'
end
diff --git a/spec/services/boards/issues/list_service_spec.rb b/spec/services/boards/issues/list_service_spec.rb
index 27a7bf0e605..010679b5360 100644
--- a/spec/services/boards/issues/list_service_spec.rb
+++ b/spec/services/boards/issues/list_service_spec.rb
@@ -24,7 +24,7 @@ describe Boards::Issues::ListService do
let!(:opened_issue1) { create(:labeled_issue, project: project, milestone: m1, title: 'Issue 1', labels: [bug]) }
let!(:opened_issue2) { create(:labeled_issue, project: project, milestone: m2, title: 'Issue 2', labels: [p2]) }
- let!(:reopened_issue1) { create(:issue, :opened, project: project, title: 'Issue 3' ) }
+ let!(:reopened_issue1) { create(:issue, :opened, project: project, title: 'Reopened Issue 1' ) }
let!(:list1_issue1) { create(:labeled_issue, project: project, milestone: m1, labels: [p2, development]) }
let!(:list1_issue2) { create(:labeled_issue, project: project, milestone: m2, labels: [development]) }
@@ -44,12 +44,19 @@ describe Boards::Issues::ListService do
end
it_behaves_like 'issues list service'
+
+ context 'when project is archived' do
+ let(:project) { create(:project, :archived) }
+
+ it_behaves_like 'issues list service'
+ end
end
context 'when parent is a group' do
let(:user) { create(:user) }
let(:project) { create(:project, :empty_repo, namespace: group) }
let(:project1) { create(:project, :empty_repo, namespace: group) }
+ let(:project_archived) { create(:project, :empty_repo, :archived, namespace: group) }
let(:m1) { create(:milestone, group: group) }
let(:m2) { create(:milestone, group: group) }
@@ -77,7 +84,8 @@ describe Boards::Issues::ListService do
let!(:opened_issue1) { create(:labeled_issue, project: project, milestone: m1, title: 'Issue 1', labels: [bug]) }
let!(:opened_issue2) { create(:labeled_issue, project: project, milestone: m2, title: 'Issue 2', labels: [p2, p2_project]) }
- let!(:reopened_issue1) { create(:issue, state: 'opened', project: project, title: 'Issue 3', closed_at: Time.now ) }
+ let!(:opened_issue3) { create(:labeled_issue, project: project_archived, milestone: m1, title: 'Issue 3', labels: [bug]) }
+ let!(:reopened_issue1) { create(:issue, state: 'opened', project: project, title: 'Reopened Issue 1', closed_at: Time.now ) }
let!(:list1_issue1) { create(:labeled_issue, project: project, milestone: m1, labels: [p2, p2_project, development]) }
let!(:list1_issue2) { create(:labeled_issue, project: project, milestone: m2, labels: [development]) }
diff --git a/spec/services/files/create_service_spec.rb b/spec/services/files/create_service_spec.rb
index 30d94e4318d..751b7160276 100644
--- a/spec/services/files/create_service_spec.rb
+++ b/spec/services/files/create_service_spec.rb
@@ -3,7 +3,7 @@ require "spec_helper"
describe Files::CreateService do
let(:project) { create(:project, :repository) }
let(:repository) { project.repository }
- let(:user) { create(:user) }
+ let(:user) { create(:user, :commit_email) }
let(:file_content) { 'Test file content' }
let(:branch_name) { project.default_branch }
let(:start_branch) { branch_name }
@@ -20,6 +20,8 @@ describe Files::CreateService do
}
end
+ let(:commit) { repository.head_commit }
+
subject { described_class.new(project, user, commit_params) }
before do
@@ -75,4 +77,16 @@ describe Files::CreateService do
end
end
end
+
+ context 'commit attribute' do
+ let(:file_path) { 'test-commit-attributes.txt' }
+
+ it 'uses the commit email' do
+ subject.execute
+
+ expect(user.commit_email).not_to eq(user.email)
+ expect(commit.author_email).to eq(user.commit_email)
+ expect(commit.committer_email).to eq(user.commit_email)
+ end
+ end
end
diff --git a/spec/services/files/delete_service_spec.rb b/spec/services/files/delete_service_spec.rb
index 73566afe8c8..309802ce733 100644
--- a/spec/services/files/delete_service_spec.rb
+++ b/spec/services/files/delete_service_spec.rb
@@ -4,10 +4,11 @@ describe Files::DeleteService do
subject { described_class.new(project, user, commit_params) }
let(:project) { create(:project, :repository) }
- let(:user) { create(:user) }
+ let(:user) { create(:user, :commit_email) }
let(:file_path) { 'files/ruby/popen.rb' }
let(:branch_name) { project.default_branch }
let(:last_commit_sha) { nil }
+ let(:commit) { project.repository.head_commit }
let(:commit_params) do
{
@@ -34,6 +35,14 @@ describe Files::DeleteService do
expect(blob).to be_nil
end
+
+ it 'uses the commit email' do
+ subject.execute
+
+ expect(user.commit_email).not_to eq(user.email)
+ expect(commit.author_email).to eq(user.commit_email)
+ expect(commit.committer_email).to eq(user.commit_email)
+ end
end
before do
diff --git a/spec/services/files/update_service_spec.rb b/spec/services/files/update_service_spec.rb
index e01fe487ffa..23db35c2418 100644
--- a/spec/services/files/update_service_spec.rb
+++ b/spec/services/files/update_service_spec.rb
@@ -4,11 +4,12 @@ describe Files::UpdateService do
subject { described_class.new(project, user, commit_params) }
let(:project) { create(:project, :repository) }
- let(:user) { create(:user) }
+ let(:user) { create(:user, :commit_email) }
let(:file_path) { 'files/ruby/popen.rb' }
let(:new_contents) { 'New Content' }
let(:branch_name) { project.default_branch }
let(:last_commit_sha) { nil }
+ let(:commit) { project.repository.commit }
let(:commit_params) do
{
@@ -54,6 +55,14 @@ describe Files::UpdateService do
expect(results.data).to eq(new_contents)
end
+
+ it 'uses the commit email' do
+ subject.execute
+
+ expect(user.commit_email).not_to eq(user.email)
+ expect(commit.author_email).to eq(user.commit_email)
+ expect(commit.committer_email).to eq(user.commit_email)
+ end
end
context "when the last_commit_sha is not supplied" do
diff --git a/spec/services/git_push_service_spec.rb b/spec/services/git_push_service_spec.rb
index d4528256640..45ef26aebbd 100644
--- a/spec/services/git_push_service_spec.rb
+++ b/spec/services/git_push_service_spec.rb
@@ -246,13 +246,15 @@ describe GitPushService, services: true do
describe 'system hooks' do
let!(:push_data) { push_data_from_service(project, user, oldrev, newrev, ref) }
- let(:system_hooks_service) { SystemHooksService.new }
+ let!(:system_hooks_service) { SystemHooksService.new }
it "sends a system hook after pushing a branch" do
- expect(SystemHooksService).to receive(:new).and_return(system_hooks_service)
- expect(system_hooks_service).to receive(:execute_hooks).with(push_data, :push_hooks)
+ allow(SystemHooksService).to receive(:new).and_return(system_hooks_service)
+ allow(system_hooks_service).to receive(:execute_hooks)
execute_service(project, user, oldrev, newrev, ref)
+
+ expect(system_hooks_service).to have_received(:execute_hooks).with(push_data, :push_hooks)
end
end
end
diff --git a/spec/services/groups/transfer_service_spec.rb b/spec/services/groups/transfer_service_spec.rb
index 999677cfaaa..d71ccfb4334 100644
--- a/spec/services/groups/transfer_service_spec.rb
+++ b/spec/services/groups/transfer_service_spec.rb
@@ -22,7 +22,7 @@ describe Groups::TransferService, :postgresql do
end
end
- context "when there's an exception on Gitlab shell directories" do
+ context "when there's an exception on GitLab shell directories" do
let(:new_parent_group) { create(:group, :public) }
before do
diff --git a/spec/services/notes/build_service_spec.rb b/spec/services/notes/build_service_spec.rb
index 6e1c1fe6c02..ff85c261cd4 100644
--- a/spec/services/notes/build_service_spec.rb
+++ b/spec/services/notes/build_service_spec.rb
@@ -4,6 +4,8 @@ describe Notes::BuildService do
let(:note) { create(:discussion_note_on_issue) }
let(:project) { note.project }
let(:author) { note.author }
+ let(:merge_request) { create(:merge_request, source_project: project) }
+ let(:mr_note) { create(:discussion_note_on_merge_request, noteable: merge_request, project: project, author: author) }
describe '#execute' do
context 'when in_reply_to_discussion_id is specified' do
@@ -12,6 +14,19 @@ describe Notes::BuildService do
new_note = described_class.new(project, author, note: 'Test', in_reply_to_discussion_id: note.discussion_id).execute
expect(new_note).to be_valid
expect(new_note.in_reply_to?(note)).to be_truthy
+ expect(new_note.resolved?).to be_falsey
+ end
+
+ context 'when discussion is resolved' do
+ before do
+ mr_note.resolve!(author)
+ end
+
+ it 'resolves the note' do
+ new_note = described_class.new(project, author, note: 'Test', in_reply_to_discussion_id: mr_note.discussion_id).execute
+ expect(new_note).to be_valid
+ expect(new_note.resolved?).to be_truthy
+ end
end
end
diff --git a/spec/services/projects/container_repository/destroy_service_spec.rb b/spec/services/projects/container_repository/destroy_service_spec.rb
index 307ccc88865..affcc66d2bb 100644
--- a/spec/services/projects/container_repository/destroy_service_spec.rb
+++ b/spec/services/projects/container_repository/destroy_service_spec.rb
@@ -33,6 +33,7 @@ describe Projects::ContainerRepository::DestroyService do
end
it 'deletes the repository' do
+ expect(repository).to receive(:delete_tags!).and_call_original
expect { described_class.new(project, user).execute(repository) }.to change { ContainerRepository.all.count }.by(-1)
end
end
diff --git a/spec/services/projects/destroy_service_spec.rb b/spec/services/projects/destroy_service_spec.rb
index e428808ab68..beff499f2be 100644
--- a/spec/services/projects/destroy_service_spec.rb
+++ b/spec/services/projects/destroy_service_spec.rb
@@ -204,7 +204,7 @@ describe Projects::DestroyService do
context 'when image repository deletion fails' do
it 'raises an exception' do
expect_any_instance_of(ContainerRepository)
- .to receive(:delete_tags!).and_return(false)
+ .to receive(:delete_tags!).and_raise(RuntimeError)
expect(destroy_project(project, user)).to be false
end
diff --git a/spec/services/projects/update_remote_mirror_service_spec.rb b/spec/services/projects/update_remote_mirror_service_spec.rb
index 56a36432462..cd903bfe8a5 100644
--- a/spec/services/projects/update_remote_mirror_service_spec.rb
+++ b/spec/services/projects/update_remote_mirror_service_spec.rb
@@ -17,7 +17,6 @@ describe Projects::UpdateRemoteMirrorService do
it "ensures the remote exists" do
stub_fetch_remote(project, remote_name: remote_name)
- stub_find_remote_root_ref(project, remote_name: remote_name)
expect(remote_mirror).to receive(:ensure_remote!)
@@ -25,8 +24,6 @@ describe Projects::UpdateRemoteMirrorService do
end
it "fetches the remote repository" do
- stub_find_remote_root_ref(project, remote_name: remote_name)
-
expect(project.repository)
.to receive(:fetch_remote)
.with(remote_mirror.remote_name, no_tags: true)
@@ -34,26 +31,8 @@ describe Projects::UpdateRemoteMirrorService do
service.execute(remote_mirror)
end
- it "updates the default branch when HEAD has changed" do
- stub_fetch_remote(project, remote_name: remote_name)
- stub_find_remote_root_ref(project, remote_name: remote_name, ref: "existing-branch")
-
- expect { service.execute(remote_mirror) }
- .to change { project.default_branch }
- .from("master")
- .to("existing-branch")
- end
-
- it "does not update the default branch when HEAD does not change" do
- stub_fetch_remote(project, remote_name: remote_name)
- stub_find_remote_root_ref(project, remote_name: remote_name, ref: "master")
-
- expect { service.execute(remote_mirror) }.not_to change { project.default_branch }
- end
-
it "returns success when updated succeeds" do
stub_fetch_remote(project, remote_name: remote_name)
- stub_find_remote_root_ref(project, remote_name: remote_name)
result = service.execute(remote_mirror)
@@ -63,7 +42,6 @@ describe Projects::UpdateRemoteMirrorService do
context 'when syncing all branches' do
it "push all the branches the first time" do
stub_fetch_remote(project, remote_name: remote_name)
- stub_find_remote_root_ref(project, remote_name: remote_name)
expect(remote_mirror).to receive(:update_repository).with({})
@@ -74,7 +52,6 @@ describe Projects::UpdateRemoteMirrorService do
context 'when only syncing protected branches' do
it "sync updated protected branches" do
stub_fetch_remote(project, remote_name: remote_name)
- stub_find_remote_root_ref(project, remote_name: remote_name)
protected_branch = create_protected_branch(project)
remote_mirror.only_protected_branches = true
@@ -92,13 +69,6 @@ describe Projects::UpdateRemoteMirrorService do
end
end
- def stub_find_remote_root_ref(project, ref: 'master', remote_name:)
- allow(project.repository)
- .to receive(:find_remote_root_ref)
- .with(remote_name)
- .and_return(ref)
- end
-
def stub_fetch_remote(project, remote_name:)
allow(project.repository)
.to receive(:fetch_remote)
diff --git a/spec/support/helpers/markdown_feature.rb b/spec/support/helpers/markdown_feature.rb
index 346f5b1cc4d..96401379cf0 100644
--- a/spec/support/helpers/markdown_feature.rb
+++ b/spec/support/helpers/markdown_feature.rb
@@ -10,6 +10,12 @@
class MarkdownFeature
include FactoryBot::Syntax::Methods
+ attr_reader :fixture_path
+
+ def initialize(fixture_path = Rails.root.join('spec/fixtures/markdown.md.erb'))
+ @fixture_path = fixture_path
+ end
+
def user
@user ||= create(:user)
end
@@ -122,7 +128,7 @@ class MarkdownFeature
end
def raw_markdown
- markdown = File.read(Rails.root.join('spec/fixtures/markdown.md.erb'))
+ markdown = File.read(fixture_path)
ERB.new(markdown).result(binding)
end
end
diff --git a/spec/support/shared_examples/diff_file_collections.rb b/spec/support/shared_examples/diff_file_collections.rb
new file mode 100644
index 00000000000..55ce160add0
--- /dev/null
+++ b/spec/support/shared_examples/diff_file_collections.rb
@@ -0,0 +1,47 @@
+# frozen_string_literal: true
+
+shared_examples 'diff statistics' do |test_include_stats_flag: true|
+ def stub_stats_find_by_path(path, stats_mock)
+ expect_next_instance_of(Gitlab::Git::DiffStatsCollection) do |collection|
+ allow(collection).to receive(:find_by_path).and_call_original
+ expect(collection).to receive(:find_by_path).with(path).and_return(stats_mock)
+ end
+ end
+
+ context 'when should request diff stats' do
+ it 'Repository#diff_stats is called' do
+ subject = described_class.new(diffable, collection_default_args)
+
+ expect(diffable.project.repository)
+ .to receive(:diff_stats)
+ .with(diffable.diff_refs.base_sha, diffable.diff_refs.head_sha)
+ .and_call_original
+
+ subject.diff_files
+ end
+
+ it 'Gitlab::Diff::File is initialized with diff stats' do
+ subject = described_class.new(diffable, collection_default_args)
+
+ stats_mock = double(Gitaly::DiffStats, path: '.gitignore', additions: 758, deletions: 120)
+ stub_stats_find_by_path(stub_path, stats_mock)
+
+ diff_file = subject.diff_files.find { |file| file.new_path == stub_path }
+
+ expect(diff_file.added_lines).to eq(stats_mock.additions)
+ expect(diff_file.removed_lines).to eq(stats_mock.deletions)
+ end
+ end
+
+ context 'when should not request diff stats' do
+ it 'Repository#diff_stats is not called' do
+ collection_default_args[:diff_options][:include_stats] = false
+
+ subject = described_class.new(diffable, collection_default_args)
+
+ expect(diffable.project.repository).not_to receive(:diff_stats)
+
+ subject.diff_files
+ end
+ end
+end
diff --git a/spec/tasks/gitlab/db_rake_spec.rb b/spec/tasks/gitlab/db_rake_spec.rb
index b81aea23306..5818892d56a 100644
--- a/spec/tasks/gitlab/db_rake_spec.rb
+++ b/spec/tasks/gitlab/db_rake_spec.rb
@@ -61,6 +61,39 @@ describe 'gitlab:db namespace rake task' do
expect(Rake::Task['db:migrate']).not_to receive(:invoke)
expect { run_rake_task('gitlab:db:configure') }.to raise_error(RuntimeError, 'error')
end
+
+ context 'SKIP_POST_DEPLOYMENT_MIGRATIONS environment variable set' do
+ let(:rails_paths) { { 'db' => ['db'], 'db/migrate' => ['db/migrate'] } }
+
+ before do
+ allow(ENV).to receive(:[]).and_call_original
+ allow(ENV).to receive(:[]).with('SKIP_POST_DEPLOYMENT_MIGRATIONS').and_return true
+
+ # Our environment has already been loaded, so we need to pretend like post_migrations were not
+ allow(Rails.application.config).to receive(:paths).and_return(rails_paths)
+ allow(ActiveRecord::Migrator).to receive(:migrations_paths).and_return(rails_paths['db/migrate'].dup)
+ end
+
+ it 'adds post deployment migrations before schema load if the schema is not already loaded' do
+ allow(ActiveRecord::Base.connection).to receive(:tables).and_return([])
+ expect(Gitlab::Database).to receive(:add_post_migrate_path_to_rails).and_call_original
+ expect(Rake::Task['db:schema:load']).to receive(:invoke)
+ expect(Rake::Task['db:seed_fu']).to receive(:invoke)
+ expect(Rake::Task['db:migrate']).not_to receive(:invoke)
+ expect { run_rake_task('gitlab:db:configure') }.not_to raise_error
+ expect(rails_paths['db/migrate'].include?(File.join(Rails.root, 'db', 'post_migrate'))).to be(true)
+ end
+
+ it 'ignores post deployment migrations when schema has already been loaded' do
+ allow(ActiveRecord::Base.connection).to receive(:tables).and_return(%w[table1 table2])
+ expect(Rake::Task['db:migrate']).to receive(:invoke)
+ expect(Gitlab::Database).not_to receive(:add_post_migrate_path_to_rails)
+ expect(Rake::Task['db:schema:load']).not_to receive(:invoke)
+ expect(Rake::Task['db:seed_fu']).not_to receive(:invoke)
+ expect { run_rake_task('gitlab:db:configure') }.not_to raise_error
+ expect(rails_paths['db/migrate'].include?(File.join(Rails.root, 'db', 'post_migrate'))).to be(false)
+ end
+ end
end
def run_rake_task(task_name)
diff --git a/spec/validators/url_validator_spec.rb b/spec/validators/url_validator_spec.rb
index 93fe013d11c..ab6100509a6 100644
--- a/spec/validators/url_validator_spec.rb
+++ b/spec/validators/url_validator_spec.rb
@@ -24,6 +24,21 @@ describe UrlValidator do
expect(badge.errors.empty?).to be true
end
+
+ it 'strips urls' do
+ badge.link_url = "\n\r\n\nhttps://127.0.0.1\r\n\r\n\n\n\n"
+
+ # It's unusual for a validator to modify its arguments. Some extensions,
+ # such as attr_encrypted, freeze the string to signal that modifications
+ # will not be persisted, so freeze this string to ensure the scheme is
+ # compatible with them.
+ badge.link_url.freeze
+
+ subject
+
+ expect(badge.errors).to be_empty
+ expect(badge.link_url).to eq('https://127.0.0.1')
+ end
end
context 'when allow_localhost is set to false' do
diff --git a/spec/views/help/index.html.haml_spec.rb b/spec/views/help/index.html.haml_spec.rb
index 836d452304c..4b4de540d9e 100644
--- a/spec/views/help/index.html.haml_spec.rb
+++ b/spec/views/help/index.html.haml_spec.rb
@@ -21,7 +21,7 @@ describe 'help/index' do
render
expect(rendered).to match '8.0.2'
- expect(rendered).to have_link('abcdefg', 'https://gitlab.com/gitlab-org/gitlab-ce/commits/abcdefg')
+ expect(rendered).to have_link('abcdefg', href: 'https://gitlab.com/gitlab-org/gitlab-ce/commits/abcdefg')
end
end
@@ -29,7 +29,7 @@ describe 'help/index' do
it 'is visible to guests' do
render
- expect(rendered).to have_link(nil, help_instance_configuration_url)
+ expect(rendered).to have_link(nil, href: help_instance_configuration_url)
end
end
diff --git a/vendor/gitlab-ci-yml/Auto-DevOps.gitlab-ci.yml b/vendor/gitlab-ci-yml/Auto-DevOps.gitlab-ci.yml
index a191f1f59bf..33ae9c6ad7e 100644
--- a/vendor/gitlab-ci-yml/Auto-DevOps.gitlab-ci.yml
+++ b/vendor/gitlab-ci-yml/Auto-DevOps.gitlab-ci.yml
@@ -635,8 +635,8 @@ rollout 100%:
function install_dependencies() {
apk add -U openssl curl tar gzip bash ca-certificates git
- wget -q -O /etc/apk/keys/sgerrand.rsa.pub https://alpine-pkgs.sgerrand.com/sgerrand.rsa.pub
- wget https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.28-r0/glibc-2.28-r0.apk
+ curl -L -o /etc/apk/keys/sgerrand.rsa.pub https://alpine-pkgs.sgerrand.com/sgerrand.rsa.pub
+ curl -L -O https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.28-r0/glibc-2.28-r0.apk
apk add glibc-2.28-r0.apk
rm glibc-2.28-r0.apk
diff --git a/yarn.lock b/yarn.lock
index fe4702f3a78..3870e4da965 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2,89 +2,91 @@
# yarn lockfile v1
-"@babel/code-frame@7.0.0-beta.44":
- version "7.0.0-beta.44"
- resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0-beta.44.tgz#2a02643368de80916162be70865c97774f3adbd9"
+"@babel/code-frame@^7.0.0":
+ version "7.0.0"
+ resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0.tgz#06e2ab19bdb535385559aabb5ba59729482800f8"
dependencies:
- "@babel/highlight" "7.0.0-beta.44"
+ "@babel/highlight" "^7.0.0"
-"@babel/generator@7.0.0-beta.44":
- version "7.0.0-beta.44"
- resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.0.0-beta.44.tgz#c7e67b9b5284afcf69b309b50d7d37f3e5033d42"
+"@babel/generator@^7.0.0":
+ version "7.0.0"
+ resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.0.0.tgz#1efd58bffa951dc846449e58ce3a1d7f02d393aa"
dependencies:
- "@babel/types" "7.0.0-beta.44"
+ "@babel/types" "^7.0.0"
jsesc "^2.5.1"
- lodash "^4.2.0"
+ lodash "^4.17.10"
source-map "^0.5.0"
trim-right "^1.0.1"
-"@babel/helper-function-name@7.0.0-beta.44":
- version "7.0.0-beta.44"
- resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.0.0-beta.44.tgz#e18552aaae2231100a6e485e03854bc3532d44dd"
+"@babel/helper-function-name@^7.1.0":
+ version "7.1.0"
+ resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz#a0ceb01685f73355d4360c1247f582bfafc8ff53"
dependencies:
- "@babel/helper-get-function-arity" "7.0.0-beta.44"
- "@babel/template" "7.0.0-beta.44"
- "@babel/types" "7.0.0-beta.44"
+ "@babel/helper-get-function-arity" "^7.0.0"
+ "@babel/template" "^7.1.0"
+ "@babel/types" "^7.0.0"
-"@babel/helper-get-function-arity@7.0.0-beta.44":
- version "7.0.0-beta.44"
- resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0-beta.44.tgz#d03ca6dd2b9f7b0b1e6b32c56c72836140db3a15"
+"@babel/helper-get-function-arity@^7.0.0":
+ version "7.0.0"
+ resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz#83572d4320e2a4657263734113c42868b64e49c3"
dependencies:
- "@babel/types" "7.0.0-beta.44"
+ "@babel/types" "^7.0.0"
-"@babel/helper-split-export-declaration@7.0.0-beta.44":
- version "7.0.0-beta.44"
- resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0-beta.44.tgz#c0b351735e0fbcb3822c8ad8db4e583b05ebd9dc"
+"@babel/helper-split-export-declaration@^7.0.0":
+ version "7.0.0"
+ resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0.tgz#3aae285c0311c2ab095d997b8c9a94cad547d813"
dependencies:
- "@babel/types" "7.0.0-beta.44"
+ "@babel/types" "^7.0.0"
-"@babel/highlight@7.0.0-beta.44":
- version "7.0.0-beta.44"
- resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.0.0-beta.44.tgz#18c94ce543916a80553edcdcf681890b200747d5"
+"@babel/highlight@^7.0.0":
+ version "7.0.0"
+ resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.0.0.tgz#f710c38c8d458e6dd9a201afb637fcb781ce99e4"
dependencies:
chalk "^2.0.0"
esutils "^2.0.2"
- js-tokens "^3.0.0"
-
-"@babel/template@7.0.0-beta.44":
- version "7.0.0-beta.44"
- resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.0.0-beta.44.tgz#f8832f4fdcee5d59bf515e595fc5106c529b394f"
- dependencies:
- "@babel/code-frame" "7.0.0-beta.44"
- "@babel/types" "7.0.0-beta.44"
- babylon "7.0.0-beta.44"
- lodash "^4.2.0"
-
-"@babel/traverse@7.0.0-beta.44":
- version "7.0.0-beta.44"
- resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.0.0-beta.44.tgz#a970a2c45477ad18017e2e465a0606feee0d2966"
- dependencies:
- "@babel/code-frame" "7.0.0-beta.44"
- "@babel/generator" "7.0.0-beta.44"
- "@babel/helper-function-name" "7.0.0-beta.44"
- "@babel/helper-split-export-declaration" "7.0.0-beta.44"
- "@babel/types" "7.0.0-beta.44"
- babylon "7.0.0-beta.44"
+ js-tokens "^4.0.0"
+
+"@babel/parser@^7.0.0", "@babel/parser@^7.1.0":
+ version "7.1.0"
+ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.1.0.tgz#a7cd42cb3c12aec52e24375189a47b39759b783e"
+
+"@babel/template@^7.1.0":
+ version "7.1.0"
+ resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.1.0.tgz#58cc9572e1bfe24fe1537fdf99d839d53e517e22"
+ dependencies:
+ "@babel/code-frame" "^7.0.0"
+ "@babel/parser" "^7.1.0"
+ "@babel/types" "^7.0.0"
+
+"@babel/traverse@^7.0.0":
+ version "7.1.0"
+ resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.1.0.tgz#503ec6669387efd182c3888c4eec07bcc45d91b2"
+ dependencies:
+ "@babel/code-frame" "^7.0.0"
+ "@babel/generator" "^7.0.0"
+ "@babel/helper-function-name" "^7.1.0"
+ "@babel/helper-split-export-declaration" "^7.0.0"
+ "@babel/parser" "^7.1.0"
+ "@babel/types" "^7.0.0"
debug "^3.1.0"
globals "^11.1.0"
- invariant "^2.2.0"
- lodash "^4.2.0"
+ lodash "^4.17.10"
-"@babel/types@7.0.0-beta.44":
- version "7.0.0-beta.44"
- resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.0.0-beta.44.tgz#6b1b164591f77dec0a0342aca995f2d046b3a757"
+"@babel/types@^7.0.0":
+ version "7.0.0"
+ resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.0.0.tgz#6e191793d3c854d19c6749989e3bc55f0e962118"
dependencies:
esutils "^2.0.2"
- lodash "^4.2.0"
+ lodash "^4.17.10"
to-fast-properties "^2.0.0"
"@gitlab-org/gitlab-svgs@^1.23.0", "@gitlab-org/gitlab-svgs@^1.29.0":
version "1.29.0"
resolved "https://registry.yarnpkg.com/@gitlab-org/gitlab-svgs/-/gitlab-svgs-1.29.0.tgz#03b65b513f9099bbda6ecf94d673a2952f8c6c70"
-"@gitlab-org/gitlab-ui@^1.5.0":
- version "1.5.0"
- resolved "https://registry.yarnpkg.com/@gitlab-org/gitlab-ui/-/gitlab-ui-1.5.0.tgz#320ba164ba8812ff64f94b1cae79a7b749f5bc03"
+"@gitlab-org/gitlab-ui@^1.5.1":
+ version "1.5.1"
+ resolved "https://registry.yarnpkg.com/@gitlab-org/gitlab-ui/-/gitlab-ui-1.5.1.tgz#82bc8583e24edfbaab5f1b6e88bf1a8056d7b528"
dependencies:
"@gitlab-org/gitlab-svgs" "^1.23.0"
bootstrap-vue "^2.0.0-rc.11"
@@ -289,40 +291,40 @@ acorn-dynamic-import@^3.0.0:
dependencies:
acorn "^5.0.0"
-acorn-jsx@^3.0.0:
- version "3.0.1"
- resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-3.0.1.tgz#afdf9488fb1ecefc8348f6fb22f464e32a58b36b"
+acorn-jsx@^4.1.1:
+ version "4.1.1"
+ resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-4.1.1.tgz#e8e41e48ea2fe0c896740610ab6a4ffd8add225e"
dependencies:
- acorn "^3.0.4"
-
-acorn@^3.0.4:
- version "3.3.0"
- resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a"
+ acorn "^5.0.3"
-acorn@^5.0.0, acorn@^5.3.0, acorn@^5.5.0, acorn@^5.6.2:
+acorn@^5.0.0, acorn@^5.3.0, acorn@^5.6.2:
version "5.7.1"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.1.tgz#f095829297706a7c9776958c0afc8930a9b9d9d8"
+acorn@^5.0.3, acorn@^5.6.0:
+ version "5.7.3"
+ resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.3.tgz#67aa231bf8812974b85235a96771eb6bd07ea279"
+
after@0.8.2:
version "0.8.2"
resolved "https://registry.yarnpkg.com/after/-/after-0.8.2.tgz#fedb394f9f0e02aa9768e702bda23b505fae7e1f"
-ajv-keywords@^2.1.0:
- version "2.1.1"
- resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-2.1.1.tgz#617997fc5f60576894c435f940d819e135b80762"
+ajv-keywords@^3.0.0:
+ version "3.2.0"
+ resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.2.0.tgz#e86b819c602cf8821ad637413698f1dec021847a"
ajv-keywords@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.1.0.tgz#ac2b27939c543e95d2c06e7f7f5c27be4aa543be"
-ajv@^5.2.3, ajv@^5.3.0:
- version "5.5.2"
- resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.2.tgz#73b5eeca3fab653e3d3f9422b341ad42205dc965"
+ajv@^6.0.1, ajv@^6.5.3:
+ version "6.5.3"
+ resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.5.3.tgz#71a569d189ecf4f4f321224fecb166f071dd90f9"
dependencies:
- co "^4.6.0"
- fast-deep-equal "^1.0.0"
+ fast-deep-equal "^2.0.1"
fast-json-stable-stringify "^2.0.0"
- json-schema-traverse "^0.3.0"
+ json-schema-traverse "^0.4.1"
+ uri-js "^4.2.2"
ajv@^6.1.0:
version "6.1.1"
@@ -532,7 +534,7 @@ axios@^0.17.1:
follow-redirects "^1.2.5"
is-buffer "^1.1.5"
-babel-code-frame@^6.22.0, babel-code-frame@^6.26.0:
+babel-code-frame@^6.26.0:
version "6.26.0"
resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b"
dependencies:
@@ -564,15 +566,15 @@ babel-core@^6.26.0, babel-core@^6.26.3:
slash "^1.0.0"
source-map "^0.5.7"
-babel-eslint@^8.2.3:
- version "8.2.3"
- resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-8.2.3.tgz#1a2e6681cc9bc4473c32899e59915e19cd6733cf"
+babel-eslint@^9.0.0:
+ version "9.0.0"
+ resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-9.0.0.tgz#7d9445f81ed9f60aff38115f838970df9f2b6220"
dependencies:
- "@babel/code-frame" "7.0.0-beta.44"
- "@babel/traverse" "7.0.0-beta.44"
- "@babel/types" "7.0.0-beta.44"
- babylon "7.0.0-beta.44"
- eslint-scope "~3.7.1"
+ "@babel/code-frame" "^7.0.0"
+ "@babel/parser" "^7.0.0"
+ "@babel/traverse" "^7.0.0"
+ "@babel/types" "^7.0.0"
+ eslint-scope "3.7.1"
eslint-visitor-keys "^1.0.0"
babel-generator@^6.18.0, babel-generator@^6.26.0:
@@ -1138,10 +1140,6 @@ babel-types@^6.18.0, babel-types@^6.19.0, babel-types@^6.24.1, babel-types@^6.26
lodash "^4.17.4"
to-fast-properties "^1.0.3"
-babylon@7.0.0-beta.44:
- version "7.0.0-beta.44"
- resolved "https://registry.yarnpkg.com/babylon/-/babylon-7.0.0-beta.44.tgz#89159e15e6e30c5096e22d738d8c0af8a0e8ca1d"
-
babylon@^6.18.0:
version "6.18.0"
resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3"
@@ -1646,10 +1644,6 @@ clone-response@1.0.2:
dependencies:
mimic-response "^1.0.0"
-co@^4.6.0:
- version "4.6.0"
- resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184"
-
code-point-at@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77"
@@ -1753,7 +1747,7 @@ concat-map@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
-concat-stream@^1.5.0, concat-stream@^1.6.0:
+concat-stream@^1.5.0:
version "1.6.2"
resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34"
dependencies:
@@ -1896,7 +1890,7 @@ cropper@^2.3.0:
dependencies:
jquery ">= 1.9.1"
-cross-spawn@^5.0.1, cross-spawn@^5.1.0:
+cross-spawn@^5.0.1:
version "5.1.0"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449"
dependencies:
@@ -2243,7 +2237,13 @@ debug@2.6.9, debug@^2.1.2, debug@^2.2.0, debug@^2.3.3, debug@^2.6.6, debug@^2.6.
dependencies:
ms "2.0.0"
-debug@^3.0.1, debug@^3.1.0, debug@~3.1.0:
+debug@^3.1.0:
+ version "3.2.5"
+ resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.5.tgz#c2418fbfd7a29f4d4f70ff4cea604d4b64c46407"
+ dependencies:
+ ms "^2.1.1"
+
+debug@~3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261"
dependencies:
@@ -2286,11 +2286,10 @@ default-require-extensions@^1.0.0:
strip-bom "^2.0.0"
define-properties@^1.1.2:
- version "1.1.2"
- resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.2.tgz#83a73f2fea569898fb737193c8f873caf6d45c94"
+ version "1.1.3"
+ resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1"
dependencies:
- foreach "^2.0.5"
- object-keys "^1.0.8"
+ object-keys "^1.0.12"
define-property@^0.2.5:
version "0.2.5"
@@ -2411,7 +2410,7 @@ doctrine@1.5.0:
esutils "^2.0.2"
isarray "^1.0.0"
-doctrine@^2.0.2:
+doctrine@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d"
dependencies:
@@ -2610,6 +2609,16 @@ error-ex@^1.2.0:
dependencies:
is-arrayish "^0.2.1"
+es-abstract@^1.6.1:
+ version "1.12.0"
+ resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.12.0.tgz#9dbbdd27c6856f0001421ca18782d786bf8a6165"
+ dependencies:
+ es-to-primitive "^1.1.1"
+ function-bind "^1.1.1"
+ has "^1.0.1"
+ is-callable "^1.1.3"
+ is-regex "^1.0.4"
+
es-abstract@^1.7.0:
version "1.10.0"
resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.10.0.tgz#1ecb36c197842a00d8ee4c2dfd8646bb97d60864"
@@ -2651,11 +2660,13 @@ escodegen@1.8.x:
optionalDependencies:
source-map "~0.2.0"
-eslint-config-airbnb-base@^12.1.0:
- version "12.1.0"
- resolved "https://registry.yarnpkg.com/eslint-config-airbnb-base/-/eslint-config-airbnb-base-12.1.0.tgz#386441e54a12ccd957b0a92564a4bafebd747944"
+eslint-config-airbnb-base@^13.1.0:
+ version "13.1.0"
+ resolved "https://registry.yarnpkg.com/eslint-config-airbnb-base/-/eslint-config-airbnb-base-13.1.0.tgz#b5a1b480b80dfad16433d6c4ad84e6605052c05c"
dependencies:
eslint-restricted-globals "^0.1.1"
+ object.assign "^4.1.0"
+ object.entries "^1.0.4"
eslint-import-resolver-node@^0.3.1:
version "0.3.2"
@@ -2664,9 +2675,9 @@ eslint-import-resolver-node@^0.3.1:
debug "^2.6.9"
resolve "^1.5.0"
-eslint-import-resolver-webpack@^0.10.0:
- version "0.10.0"
- resolved "https://registry.yarnpkg.com/eslint-import-resolver-webpack/-/eslint-import-resolver-webpack-0.10.0.tgz#b6f2468dc3e8b4ea076e5d75bece8da932789b07"
+eslint-import-resolver-webpack@^0.10.1:
+ version "0.10.1"
+ resolved "https://registry.yarnpkg.com/eslint-import-resolver-webpack/-/eslint-import-resolver-webpack-0.10.1.tgz#4cbceed2c0c43e488a74775c30861e58e00fb290"
dependencies:
array-find "^1.0.0"
debug "^2.6.8"
@@ -2686,24 +2697,24 @@ eslint-module-utils@^2.2.0:
debug "^2.6.8"
pkg-dir "^1.0.0"
-eslint-plugin-filenames@^1.2.0:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/eslint-plugin-filenames/-/eslint-plugin-filenames-1.2.0.tgz#aee9c1c90189c95d2e49902c160eceefecd99f53"
+eslint-plugin-filenames@^1.3.2:
+ version "1.3.2"
+ resolved "https://registry.yarnpkg.com/eslint-plugin-filenames/-/eslint-plugin-filenames-1.3.2.tgz#7094f00d7aefdd6999e3ac19f72cea058e590cf7"
dependencies:
lodash.camelcase "4.3.0"
lodash.kebabcase "4.1.1"
lodash.snakecase "4.1.1"
lodash.upperfirst "4.3.1"
-eslint-plugin-html@4.0.3:
- version "4.0.3"
- resolved "https://registry.yarnpkg.com/eslint-plugin-html/-/eslint-plugin-html-4.0.3.tgz#97d52dcf9e22724505d02719fbd02754013c8a17"
+eslint-plugin-html@4.0.5:
+ version "4.0.5"
+ resolved "https://registry.yarnpkg.com/eslint-plugin-html/-/eslint-plugin-html-4.0.5.tgz#e8ec7e16485124460f3bff312016feb0a54d9659"
dependencies:
htmlparser2 "^3.8.2"
-eslint-plugin-import@^2.12.0:
- version "2.12.0"
- resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.12.0.tgz#dad31781292d6664b25317fd049d2e2b2f02205d"
+eslint-plugin-import@^2.14.0:
+ version "2.14.0"
+ resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.14.0.tgz#6b17626d2e3e6ad52cfce8807a845d15e22111a8"
dependencies:
contains-path "^0.1.0"
debug "^2.6.8"
@@ -2716,83 +2727,95 @@ eslint-plugin-import@^2.12.0:
read-pkg-up "^2.0.0"
resolve "^1.6.0"
-eslint-plugin-jasmine@^2.1.0:
- version "2.2.0"
- resolved "https://registry.yarnpkg.com/eslint-plugin-jasmine/-/eslint-plugin-jasmine-2.2.0.tgz#7135879383c39a667c721d302b9f20f0389543de"
+eslint-plugin-jasmine@^2.10.1:
+ version "2.10.1"
+ resolved "https://registry.yarnpkg.com/eslint-plugin-jasmine/-/eslint-plugin-jasmine-2.10.1.tgz#5733b709e751f4bc40e31e1c16989bd2cdfbec97"
-eslint-plugin-promise@^3.8.0:
- version "3.8.0"
- resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-3.8.0.tgz#65ebf27a845e3c1e9d6f6a5622ddd3801694b621"
+eslint-plugin-promise@^4.0.1:
+ version "4.0.1"
+ resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-4.0.1.tgz#2d074b653f35a23d1ba89d8e976a985117d1c6a2"
-eslint-plugin-vue@^4.5.0:
- version "4.5.0"
- resolved "https://registry.yarnpkg.com/eslint-plugin-vue/-/eslint-plugin-vue-4.5.0.tgz#09d6597f4849e31a3846c2c395fccf17685b69c3"
+eslint-plugin-vue@^5.0.0-beta.3:
+ version "5.0.0-beta.3"
+ resolved "https://registry.yarnpkg.com/eslint-plugin-vue/-/eslint-plugin-vue-5.0.0-beta.3.tgz#f3fa9f109b76e20fc1e45a71ce7c6d567118924e"
dependencies:
- vue-eslint-parser "^2.0.3"
+ vue-eslint-parser "^3.2.1"
eslint-restricted-globals@^0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/eslint-restricted-globals/-/eslint-restricted-globals-0.1.1.tgz#35f0d5cbc64c2e3ed62e93b4b1a7af05ba7ed4d7"
-eslint-scope@^3.7.1, eslint-scope@~3.7.1:
+eslint-scope@3.7.1, eslint-scope@^3.7.1:
version "3.7.1"
resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-3.7.1.tgz#3d63c3edfda02e06e01a452ad88caacc7cdcb6e8"
dependencies:
esrecurse "^4.1.0"
estraverse "^4.1.1"
+eslint-scope@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.0.tgz#50bf3071e9338bcdc43331794a0cb533f0136172"
+ dependencies:
+ esrecurse "^4.1.0"
+ estraverse "^4.1.1"
+
+eslint-utils@^1.3.1:
+ version "1.3.1"
+ resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.3.1.tgz#9a851ba89ee7c460346f97cf8939c7298827e512"
+
eslint-visitor-keys@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#3f3180fb2e291017716acb4c9d6d5b5c34a6a81d"
-eslint@~4.12.1:
- version "4.12.1"
- resolved "https://registry.yarnpkg.com/eslint/-/eslint-4.12.1.tgz#5ec1973822b4a066b353770c3c6d69a2a188e880"
+eslint@~5.6.0:
+ version "5.6.0"
+ resolved "https://registry.yarnpkg.com/eslint/-/eslint-5.6.0.tgz#b6f7806041af01f71b3f1895cbb20971ea4b6223"
dependencies:
- ajv "^5.3.0"
- babel-code-frame "^6.22.0"
+ "@babel/code-frame" "^7.0.0"
+ ajv "^6.5.3"
chalk "^2.1.0"
- concat-stream "^1.6.0"
- cross-spawn "^5.1.0"
- debug "^3.0.1"
- doctrine "^2.0.2"
- eslint-scope "^3.7.1"
- espree "^3.5.2"
- esquery "^1.0.0"
- estraverse "^4.2.0"
+ cross-spawn "^6.0.5"
+ debug "^3.1.0"
+ doctrine "^2.1.0"
+ eslint-scope "^4.0.0"
+ eslint-utils "^1.3.1"
+ eslint-visitor-keys "^1.0.0"
+ espree "^4.0.0"
+ esquery "^1.0.1"
esutils "^2.0.2"
file-entry-cache "^2.0.0"
functional-red-black-tree "^1.0.1"
glob "^7.1.2"
- globals "^11.0.1"
- ignore "^3.3.3"
+ globals "^11.7.0"
+ ignore "^4.0.6"
imurmurhash "^0.1.4"
- inquirer "^3.0.6"
- is-resolvable "^1.0.0"
- js-yaml "^3.9.1"
+ inquirer "^6.1.0"
+ is-resolvable "^1.1.0"
+ js-yaml "^3.12.0"
json-stable-stringify-without-jsonify "^1.0.1"
levn "^0.3.0"
- lodash "^4.17.4"
- minimatch "^3.0.2"
+ lodash "^4.17.5"
+ minimatch "^3.0.4"
mkdirp "^0.5.1"
natural-compare "^1.4.0"
optionator "^0.8.2"
path-is-inside "^1.0.2"
pluralize "^7.0.0"
progress "^2.0.0"
+ regexpp "^2.0.0"
require-uncached "^1.0.3"
- semver "^5.3.0"
+ semver "^5.5.1"
strip-ansi "^4.0.0"
- strip-json-comments "~2.0.1"
- table "^4.0.1"
- text-table "~0.2.0"
+ strip-json-comments "^2.0.1"
+ table "^4.0.3"
+ text-table "^0.2.0"
-espree@^3.5.2:
- version "3.5.4"
- resolved "https://registry.yarnpkg.com/espree/-/espree-3.5.4.tgz#b0f447187c8a8bed944b815a660bddf5deb5d1a7"
+espree@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/espree/-/espree-4.0.0.tgz#253998f20a0f82db5d866385799d912a83a36634"
dependencies:
- acorn "^5.5.0"
- acorn-jsx "^3.0.0"
+ acorn "^5.6.0"
+ acorn-jsx "^4.1.1"
esprima@2.7.x, esprima@^2.7.1:
version "2.7.3"
@@ -2802,7 +2825,7 @@ esprima@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.0.tgz#4499eddcd1110e0b218bacf2fa7f7f59f55ca804"
-esquery@^1.0.0:
+esquery@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.0.1.tgz#406c51658b1f5991a5f9b62b1dc25b00e3e5c708"
dependencies:
@@ -2818,7 +2841,7 @@ estraverse@^1.9.1:
version "1.9.3"
resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-1.9.3.tgz#af67f2dc922582415950926091a4005d29c9bb44"
-estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1, estraverse@^4.2.0:
+estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1:
version "4.2.0"
resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13"
@@ -2965,7 +2988,7 @@ extend@^3.0.0:
version "3.0.1"
resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444"
-external-editor@^2.0.1, external-editor@^2.0.4:
+external-editor@^2.0.1:
version "2.2.0"
resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-2.2.0.tgz#045511cfd8d133f3846673d1047c154e214ad3d5"
dependencies:
@@ -2998,6 +3021,10 @@ fast-deep-equal@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz#96256a3bc975595eb36d82e9929d060d893439ff"
+fast-deep-equal@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49"
+
fast-json-stable-stringify@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2"
@@ -3125,10 +3152,6 @@ for-in@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80"
-foreach@^2.0.5:
- version "2.0.5"
- resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99"
-
formdata-polyfill@^3.0.11:
version "3.0.11"
resolved "https://registry.yarnpkg.com/formdata-polyfill/-/formdata-polyfill-3.0.11.tgz#c82b4b4bea3356c0a6752219e54ce1edb2a7fb5b"
@@ -3190,7 +3213,7 @@ fsevents@^1.2.2:
nan "^2.9.2"
node-pre-gyp "^0.10.0"
-function-bind@^1.0.2, function-bind@^1.1.1:
+function-bind@^1.0.2, function-bind@^1.1.0, function-bind@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
@@ -3289,10 +3312,14 @@ global-modules-path@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/global-modules-path/-/global-modules-path-2.1.0.tgz#923ec524e8726bb0c1a4ed4b8e21e1ff80c88bbb"
-globals@^11.0.1, globals@^11.1.0:
+globals@^11.1.0:
version "11.5.0"
resolved "https://registry.yarnpkg.com/globals/-/globals-11.5.0.tgz#6bc840de6771173b191f13d3a9c94d441ee92642"
+globals@^11.7.0:
+ version "11.7.0"
+ resolved "https://registry.yarnpkg.com/globals/-/globals-11.7.0.tgz#a583faa43055b1aca771914bf68258e2fc125673"
+
globals@^9.18.0:
version "9.18.0"
resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a"
@@ -3421,6 +3448,10 @@ has-symbol-support-x@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/has-symbol-support-x/-/has-symbol-support-x-1.3.0.tgz#588bd6927eaa0e296afae24160659167fc2be4f8"
+has-symbols@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.0.tgz#ba1a8f1af2a0fc39650f5c850367704122063b44"
+
has-to-string-tag-x@^1.2.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/has-to-string-tag-x/-/has-to-string-tag-x-1.3.0.tgz#78e3d98c3c0ec9413e970eb8d766249a1e13058f"
@@ -3610,10 +3641,14 @@ ignore-walk@^3.0.1:
dependencies:
minimatch "^3.0.4"
-ignore@^3.3.3, ignore@^3.3.7:
+ignore@^3.3.7:
version "3.3.8"
resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.8.tgz#3f8e9c35d38708a3a7e0e9abb6c73e7ee7707b2b"
+ignore@^4.0.6:
+ version "4.0.6"
+ resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc"
+
immediate@~3.0.5:
version "3.0.6"
resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.0.6.tgz#9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b"
@@ -3691,28 +3726,27 @@ inquirer@3.0.6:
strip-ansi "^3.0.0"
through "^2.3.6"
-inquirer@^3.0.6:
- version "3.3.0"
- resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-3.3.0.tgz#9dd2f2ad765dcab1ff0443b491442a20ba227dc9"
+inquirer@^6.0.0:
+ version "6.0.0"
+ resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.0.0.tgz#e8c20303ddc15bbfc2c12a6213710ccd9e1413d8"
dependencies:
ansi-escapes "^3.0.0"
chalk "^2.0.0"
cli-cursor "^2.1.0"
cli-width "^2.0.0"
- external-editor "^2.0.4"
+ external-editor "^3.0.0"
figures "^2.0.0"
lodash "^4.3.0"
mute-stream "0.0.7"
run-async "^2.2.0"
- rx-lite "^4.0.8"
- rx-lite-aggregates "^4.0.8"
+ rxjs "^6.1.0"
string-width "^2.1.0"
strip-ansi "^4.0.0"
through "^2.3.6"
-inquirer@^6.0.0:
- version "6.0.0"
- resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.0.0.tgz#e8c20303ddc15bbfc2c12a6213710ccd9e1413d8"
+inquirer@^6.1.0:
+ version "6.2.0"
+ resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.2.0.tgz#51adcd776f661369dc1e894859c2560a224abdd8"
dependencies:
ansi-escapes "^3.0.0"
chalk "^2.0.0"
@@ -3720,7 +3754,7 @@ inquirer@^6.0.0:
cli-width "^2.0.0"
external-editor "^3.0.0"
figures "^2.0.0"
- lodash "^4.3.0"
+ lodash "^4.17.10"
mute-stream "0.0.7"
run-async "^2.2.0"
rxjs "^6.1.0"
@@ -3745,7 +3779,7 @@ into-stream@^3.1.0:
from2 "^2.1.1"
p-is-promise "^1.1.0"
-invariant@^2.2.0, invariant@^2.2.2:
+invariant@^2.2.2:
version "2.2.2"
resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.2.tgz#9e1f56ac0acdb6bf303306f338be3b204ae60360"
dependencies:
@@ -3796,8 +3830,8 @@ is-builtin-module@^1.0.0:
builtin-modules "^1.0.0"
is-callable@^1.1.1, is-callable@^1.1.3:
- version "1.1.3"
- resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.3.tgz#86eb75392805ddc33af71c92a0eedf74ee7604b2"
+ version "1.1.4"
+ resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75"
is-data-descriptor@^0.1.4:
version "0.1.4"
@@ -3952,11 +3986,9 @@ is-regex@^1.0.4:
dependencies:
has "^1.0.1"
-is-resolvable@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.0.0.tgz#8df57c61ea2e3c501408d100fb013cf8d6e0cc62"
- dependencies:
- tryit "^1.0.1"
+is-resolvable@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88"
is-retry-allowed@^1.0.0, is-retry-allowed@^1.1.0:
version "1.1.0"
@@ -4145,13 +4177,24 @@ js-tokens@^3.0.0, js-tokens@^3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b"
-js-yaml@3.x, js-yaml@^3.7.0, js-yaml@^3.9.1:
+js-tokens@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
+
+js-yaml@3.x:
version "3.11.0"
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.11.0.tgz#597c1a8bd57152f26d622ce4117851a51f5ebaef"
dependencies:
argparse "^1.0.7"
esprima "^4.0.0"
+js-yaml@^3.12.0, js-yaml@^3.7.0:
+ version "3.12.0"
+ resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.12.0.tgz#eaed656ec8344f10f527c6bfa1b6e2244de167d1"
+ dependencies:
+ argparse "^1.0.7"
+ esprima "^4.0.0"
+
jsesc@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b"
@@ -4176,6 +4219,10 @@ json-schema-traverse@^0.3.0:
version "0.3.1"
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz#349a6d44c53a51de89b40805c5d5e59b417d3340"
+json-schema-traverse@^0.4.1:
+ version "0.4.1"
+ resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660"
+
json-stable-stringify-without-jsonify@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651"
@@ -4441,7 +4488,7 @@ lodash@4.17.4:
version "4.17.4"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae"
-lodash@^4.0.0, lodash@^4.11.1, lodash@^4.17.10, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.0, lodash@^4.3.0, lodash@^4.5.0:
+lodash@^4.0.0, lodash@^4.11.1, lodash@^4.17.10, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.3.0, lodash@^4.5.0:
version "4.17.10"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.10.tgz#1b7793cf7259ea38fb3661d4d38b3260af8ae4e7"
@@ -4755,6 +4802,10 @@ ms@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
+ms@^2.1.1:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a"
+
multicast-dns-service-types@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz#899f11d9686e5e05cb91b35d5f0e63b773cfc901"
@@ -4976,9 +5027,9 @@ object-copy@^0.1.0:
define-property "^0.2.5"
kind-of "^3.0.3"
-object-keys@^1.0.8:
- version "1.0.11"
- resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.0.11.tgz#c54601778ad560f1142ce0e01bcca8b56d13426d"
+object-keys@^1.0.11, object-keys@^1.0.12:
+ version "1.0.12"
+ resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.0.12.tgz#09c53855377575310cca62f55bb334abff7b3ed2"
object-visit@^1.0.0:
version "1.0.1"
@@ -4986,6 +5037,24 @@ object-visit@^1.0.0:
dependencies:
isobject "^3.0.0"
+object.assign@^4.1.0:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.0.tgz#968bf1100d7956bb3ca086f006f846b3bc4008da"
+ dependencies:
+ define-properties "^1.1.2"
+ function-bind "^1.1.1"
+ has-symbols "^1.0.0"
+ object-keys "^1.0.11"
+
+object.entries@^1.0.4:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.0.4.tgz#1bf9a4dd2288f5b33f3a993d257661f05d161a5f"
+ dependencies:
+ define-properties "^1.1.2"
+ es-abstract "^1.6.1"
+ function-bind "^1.1.0"
+ has "^1.0.1"
+
object.pick@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747"
@@ -5473,6 +5542,10 @@ punycode@1.3.2, punycode@^1.2.4:
version "1.3.2"
resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d"
+punycode@^2.1.0:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
+
qjobs@^1.1.4:
version "1.2.0"
resolved "https://registry.yarnpkg.com/qjobs/-/qjobs-1.2.0.tgz#c45e9c61800bd087ef88d7e256423bdd49e5d071"
@@ -5650,6 +5723,10 @@ regex-not@^1.0.0, regex-not@^1.0.2:
extend-shallow "^3.0.2"
safe-regex "^1.1.0"
+regexpp@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.0.tgz#b2a7534a85ca1b033bcf5ce9ff8e56d4e0755365"
+
regexpu-core@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-1.0.0.tgz#86a763f58ee4d7c2f6b102e4764050de7ed90c6b"
@@ -5814,16 +5891,6 @@ rw@1:
version "1.3.3"
resolved "https://registry.yarnpkg.com/rw/-/rw-1.3.3.tgz#3f862dfa91ab766b14885ef4d01124bfda074fb4"
-rx-lite-aggregates@^4.0.8:
- version "4.0.8"
- resolved "https://registry.yarnpkg.com/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz#753b87a89a11c95467c4ac1626c4efc4e05c67be"
- dependencies:
- rx-lite "*"
-
-rx-lite@*, rx-lite@^4.0.8:
- version "4.0.8"
- resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-4.0.8.tgz#0b1e11af8bc44836f04a6407e92da42467b79444"
-
rx@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/rx/-/rx-4.1.0.tgz#a5f13ff79ef3b740fe30aa803fb09f98805d4782"
@@ -5899,10 +5966,14 @@ semver-diff@^2.0.0:
dependencies:
semver "^5.0.3"
-"semver@2 || 3 || 4 || 5", semver@^5.0.3, semver@^5.1.0, semver@^5.3.0, semver@^5.5.0:
+"semver@2 || 3 || 4 || 5", semver@^5.0.3, semver@^5.1.0, semver@^5.5.0:
version "5.5.0"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab"
+semver@^5.3.0, semver@^5.5.1:
+ version "5.5.1"
+ resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.1.tgz#7dfdd8814bdb7cabc7be0fb1d734cfb66c940477"
+
send@0.16.1:
version "0.16.1"
resolved "https://registry.yarnpkg.com/send/-/send-0.16.1.tgz#a70e1ca21d1382c11d0d9f6231deb281080d7ab3"
@@ -6370,7 +6441,7 @@ strip-indent@^1.0.1:
dependencies:
get-stdin "^4.0.1"
-strip-json-comments@~2.0.1:
+strip-json-comments@^2.0.1, strip-json-comments@~2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a"
@@ -6401,12 +6472,12 @@ svg4everybody@2.1.9:
version "2.1.9"
resolved "https://registry.yarnpkg.com/svg4everybody/-/svg4everybody-2.1.9.tgz#5bd9f6defc133859a044646d4743fabc28db7e2d"
-table@^4.0.1:
- version "4.0.2"
- resolved "https://registry.yarnpkg.com/table/-/table-4.0.2.tgz#a33447375391e766ad34d3486e6e2aedc84d2e36"
+table@^4.0.3:
+ version "4.0.3"
+ resolved "http://registry.npmjs.org/table/-/table-4.0.3.tgz#00b5e2b602f1794b9acaf9ca908a76386a7813bc"
dependencies:
- ajv "^5.2.3"
- ajv-keywords "^2.1.0"
+ ajv "^6.0.1"
+ ajv-keywords "^3.0.0"
chalk "^2.1.0"
lodash "^4.17.4"
slice-ansi "1.0.0"
@@ -6448,7 +6519,7 @@ test-exclude@^4.2.1:
read-pkg-up "^1.0.1"
require-main-filename "^1.0.1"
-text-table@~0.2.0:
+text-table@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
@@ -6569,10 +6640,6 @@ tryer@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/tryer/-/tryer-1.0.0.tgz#027b69fa823225e551cace3ef03b11f6ab37c1d7"
-tryit@^1.0.1:
- version "1.0.3"
- resolved "https://registry.yarnpkg.com/tryit/-/tryit-1.0.3.tgz#393be730a9446fd1ead6da59a014308f36c289cb"
-
tslib@^1.9.0:
version "1.9.3"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286"
@@ -6713,6 +6780,12 @@ update-notifier@^2.3.0:
semver-diff "^2.0.0"
xdg-basedir "^3.0.0"
+uri-js@^4.2.2:
+ version "4.2.2"
+ resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0"
+ dependencies:
+ punycode "^2.1.0"
+
urix@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72"
@@ -6828,16 +6901,16 @@ void-elements@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec"
-vue-eslint-parser@^2.0.3:
- version "2.0.3"
- resolved "https://registry.yarnpkg.com/vue-eslint-parser/-/vue-eslint-parser-2.0.3.tgz#c268c96c6d94cfe3d938a5f7593959b0ca3360d1"
+vue-eslint-parser@^3.2.1:
+ version "3.2.2"
+ resolved "https://registry.yarnpkg.com/vue-eslint-parser/-/vue-eslint-parser-3.2.2.tgz#47c971ee4c39b0ee7d7f5e154cb621beb22f7a34"
dependencies:
debug "^3.1.0"
- eslint-scope "^3.7.1"
+ eslint-scope "^4.0.0"
eslint-visitor-keys "^1.0.0"
- espree "^3.5.2"
- esquery "^1.0.0"
- lodash "^4.17.4"
+ espree "^4.0.0"
+ esquery "^1.0.1"
+ lodash "^4.17.10"
vue-functional-data-merge@^2.0.5:
version "2.0.6"