summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitlab-ci.yml3
-rw-r--r--CHANGELOG.md283
-rw-r--r--CONTRIBUTING.md8
-rw-r--r--Gemfile1
-rw-r--r--Gemfile.lock3
-rw-r--r--app/assets/images/icon-merge-request-unmerged.svg2
-rw-r--r--app/assets/javascripts/activities.js3
-rw-r--r--app/assets/javascripts/awards_handler.js2
-rw-r--r--app/assets/javascripts/behaviors/toggler_behavior.js2
-rw-r--r--app/assets/javascripts/boards/boards_bundle.js7
-rw-r--r--app/assets/javascripts/boards/components/board.js2
-rw-r--r--app/assets/javascripts/boards/components/board_blank_state.js4
-rw-r--r--app/assets/javascripts/boards/components/board_card.js1
-rw-r--r--app/assets/javascripts/boards/components/board_delete.js3
-rw-r--r--app/assets/javascripts/boards/components/board_list.js4
-rw-r--r--app/assets/javascripts/boards/components/board_sidebar.js3
-rw-r--r--app/assets/javascripts/boards/components/issue_card_inner.js2
-rw-r--r--app/assets/javascripts/boards/components/modal/empty_state.js3
-rw-r--r--app/assets/javascripts/boards/components/modal/footer.js3
-rw-r--r--app/assets/javascripts/boards/components/modal/index.js3
-rw-r--r--app/assets/javascripts/boards/components/modal/list.js4
-rw-r--r--app/assets/javascripts/boards/components/modal/lists_dropdown.js3
-rw-r--r--app/assets/javascripts/boards/components/modal/tabs.js3
-rw-r--r--app/assets/javascripts/boards/components/sidebar/remove_issue.js4
-rw-r--r--app/assets/javascripts/boards/filters/due_date_filters.js3
-rw-r--r--app/assets/javascripts/boards/models/issue.js3
-rw-r--r--app/assets/javascripts/boards/services/board_service.js3
-rw-r--r--app/assets/javascripts/boards/stores/boards_store.js3
-rw-r--r--app/assets/javascripts/commit/pipelines/pipelines_bundle.js6
-rw-r--r--app/assets/javascripts/cycle_analytics/components/stage_code_component.js3
-rw-r--r--app/assets/javascripts/cycle_analytics/components/stage_issue_component.js3
-rw-r--r--app/assets/javascripts/cycle_analytics/components/stage_production_component.js3
-rw-r--r--app/assets/javascripts/cycle_analytics/components/stage_review_component.js3
-rw-r--r--app/assets/javascripts/cycle_analytics/components/total_time_component.js3
-rw-r--r--app/assets/javascripts/cycle_analytics/cycle_analytics_bundle.js7
-rw-r--r--app/assets/javascripts/diff_notes/components/comment_resolve_btn.js3
-rw-r--r--app/assets/javascripts/diff_notes/components/diff_note_avatars.js4
-rw-r--r--app/assets/javascripts/diff_notes/components/jump_to_discussion.js3
-rw-r--r--app/assets/javascripts/diff_notes/components/new_issue_for_discussion.js3
-rw-r--r--app/assets/javascripts/diff_notes/components/resolve_btn.js3
-rw-r--r--app/assets/javascripts/diff_notes/components/resolve_count.js3
-rw-r--r--app/assets/javascripts/diff_notes/components/resolve_discussion_btn.js2
-rw-r--r--app/assets/javascripts/diff_notes/diff_notes_bundle.js4
-rw-r--r--app/assets/javascripts/diff_notes/models/discussion.js3
-rw-r--r--app/assets/javascripts/diff_notes/services/resolve.js7
-rw-r--r--app/assets/javascripts/diff_notes/stores/comments.js3
-rw-r--r--app/assets/javascripts/dispatcher.js2
-rw-r--r--app/assets/javascripts/filtered_search/filtered_search_manager.js2
-rw-r--r--app/assets/javascripts/issuable/time_tracking/components/collapsed_state.js2
-rw-r--r--app/assets/javascripts/issuable/time_tracking/components/comparison_pane.js3
-rw-r--r--app/assets/javascripts/issuable/time_tracking/components/estimate_only_pane.js3
-rw-r--r--app/assets/javascripts/issuable/time_tracking/components/help_state.js3
-rw-r--r--app/assets/javascripts/issuable/time_tracking/components/no_tracking_pane.js3
-rw-r--r--app/assets/javascripts/issuable/time_tracking/components/spent_only_pane.js3
-rw-r--r--app/assets/javascripts/issuable/time_tracking/components/time_tracker.js2
-rw-r--r--app/assets/javascripts/issuable/time_tracking/time_tracking_bundle.js7
-rw-r--r--app/assets/javascripts/issuable_context.js3
-rw-r--r--app/assets/javascripts/lib/utils/poll.js62
-rw-r--r--app/assets/javascripts/main.js2
-rw-r--r--app/assets/javascripts/merge_conflicts/components/diff_file_editor.js3
-rw-r--r--app/assets/javascripts/merge_conflicts/components/inline_conflict_lines.js3
-rw-r--r--app/assets/javascripts/merge_conflicts/components/parallel_conflict_lines.js3
-rw-r--r--app/assets/javascripts/merge_conflicts/merge_conflict_store.js5
-rw-r--r--app/assets/javascripts/merge_conflicts/merge_conflicts_bundle.js4
-rw-r--r--app/assets/javascripts/merge_request_tabs.js4
-rw-r--r--app/assets/javascripts/milestone_select.js3
-rw-r--r--app/assets/javascripts/monitoring/prometheus_graph.js14
-rw-r--r--app/assets/javascripts/notes.js4
-rw-r--r--app/assets/javascripts/project.js3
-rw-r--r--app/assets/javascripts/render_gfm.js3
-rw-r--r--app/assets/javascripts/render_math.js4
-rw-r--r--app/assets/javascripts/right_sidebar.js3
-rw-r--r--app/assets/javascripts/shortcuts.js4
-rw-r--r--app/assets/javascripts/shortcuts_dashboard_navigation.js3
-rw-r--r--app/assets/javascripts/shortcuts_navigation.js3
-rw-r--r--app/assets/javascripts/subscription.js2
-rw-r--r--app/assets/javascripts/user.js3
-rw-r--r--app/assets/javascripts/user_callout.js6
-rw-r--r--app/assets/javascripts/user_tabs.js21
-rw-r--r--app/assets/javascripts/users_select.js3
-rw-r--r--app/assets/javascripts/vue_pipelines_index/index.js4
-rw-r--r--app/assets/javascripts/vue_shared/common_vue.js6
-rw-r--r--app/assets/javascripts/vue_shared/vue_resource_interceptor.js11
-rw-r--r--app/assets/stylesheets/framework/awards.scss9
-rw-r--r--app/assets/stylesheets/framework/layout.scss4
-rw-r--r--app/assets/stylesheets/framework/variables.scss3
-rw-r--r--app/assets/stylesheets/pages/issuable.scss2
-rw-r--r--app/assets/stylesheets/pages/issues.scss8
-rw-r--r--app/controllers/application_controller.rb7
-rw-r--r--app/controllers/dashboard/todos_controller.rb2
-rw-r--r--app/controllers/import/bitbucket_controller.rb8
-rw-r--r--app/controllers/projects/application_controller.rb5
-rw-r--r--app/controllers/projects/blob_controller.rb5
-rw-r--r--app/controllers/projects/deploy_keys_controller.rb4
-rw-r--r--app/controllers/projects/issues_controller.rb9
-rw-r--r--app/controllers/projects/settings/members_controller.rb1
-rw-r--r--app/controllers/projects/tree_controller.rb1
-rw-r--r--app/controllers/users_controller.rb4
-rw-r--r--app/finders/todos_finder.rb12
-rw-r--r--app/helpers/todos_helper.rb10
-rw-r--r--app/models/concerns/issuable.rb1
-rw-r--r--app/models/concerns/spammable.rb2
-rw-r--r--app/models/group.rb2
-rw-r--r--app/models/issue.rb3
-rw-r--r--app/models/merge_request.rb5
-rw-r--r--app/models/namespace.rb2
-rw-r--r--app/models/project.rb2
-rw-r--r--app/models/project_services/chat_notification_service.rb27
-rw-r--r--app/models/project_services/mattermost_service.rb16
-rw-r--r--app/models/project_services/prometheus_service.rb8
-rw-r--r--app/models/project_services/slack_service.rb16
-rw-r--r--app/models/route.rb4
-rw-r--r--app/models/snippet.rb3
-rw-r--r--app/models/user.rb2
-rw-r--r--app/services/boards/issues/list_service.rb2
-rw-r--r--app/services/spam_check_service.rb3
-rw-r--r--app/views/admin/dashboard/index.html.haml30
-rw-r--r--app/views/award_emoji/_awards_block.html.haml6
-rw-r--r--app/views/ci/status/_graph_badge.html.haml4
-rw-r--r--app/views/dashboard/todos/index.html.haml13
-rw-r--r--app/views/help/_shortcuts.html.haml6
-rw-r--r--app/views/layouts/header/_default.html.haml2
-rw-r--r--app/views/profiles/preferences/show.html.haml10
-rw-r--r--app/views/projects/edit.html.haml2
-rw-r--r--app/views/projects/environments/metrics.html.haml4
-rw-r--r--app/views/projects/merge_requests/_new_compare.html.haml2
-rw-r--r--app/views/projects/notes/_note.html.haml2
-rw-r--r--app/views/projects/services/_index.html.haml2
-rw-r--r--app/views/projects/stage/_in_stage_group.html.haml2
-rwxr-xr-xbin/with_env16
-rw-r--r--changelogs/unreleased/1051-api-create-users-without-password.yml4
-rw-r--r--changelogs/unreleased/12726-preserve-issues-after-deleting-users.yml4
-rw-r--r--changelogs/unreleased/1363-redo-mailroom-support.yml4
-rw-r--r--changelogs/unreleased/1381-present-commits-pagination-headers-correctly.yml4
-rw-r--r--changelogs/unreleased/14492-change-fork-endpoint.yml4
-rw-r--r--changelogs/unreleased/14748-runner-version-in-admin-views.yml4
-rw-r--r--changelogs/unreleased/1648-remove-remnants-of-git-annex-from-ce.yml4
-rw-r--r--changelogs/unreleased/18962-update-issues-button-jumps.yml4
-rw-r--r--changelogs/unreleased/19302-wiki-page-delete-does-not-trigger-the-webhook.yml4
-rw-r--r--changelogs/unreleased/1937-https-clone-url-username.yml4
-rw-r--r--changelogs/unreleased/19497-hide-relevant-info-when-project-issues-are-disabled.yml4
-rw-r--r--changelogs/unreleased/20495-plus-icon-button.yml4
-rw-r--r--changelogs/unreleased/20732_member_exists_409.yml4
-rw-r--r--changelogs/unreleased/21240_snippets_line_ending.yml4
-rw-r--r--changelogs/unreleased/21605-allow-html5-details.yml4
-rw-r--r--changelogs/unreleased/22018-api-milestone-merge-requests.yml4
-rw-r--r--changelogs/unreleased/22132-rename-branch-name-params-to-branch.yml4
-rw-r--r--changelogs/unreleased/22466-task-list-alignment.yml4
-rw-r--r--changelogs/unreleased/22562-todos-filters.yml4
-rw-r--r--changelogs/unreleased/22645-add-discussion-contribs-to-calendar.yml4
-rw-r--r--changelogs/unreleased/22818-licence-gitignore-and-yml-endpoints-removal.yml4
-rw-r--r--changelogs/unreleased/22951-fix-todos-api-endpoint-error-for-commits.yml4
-rw-r--r--changelogs/unreleased/23061-consolidate-project-lists.yml4
-rw-r--r--changelogs/unreleased/23062-allow-git-log-to-accept-follow-and-skip.yml4
-rw-r--r--changelogs/unreleased/23104-remove-public-param-for-projects.yml4
-rw-r--r--changelogs/unreleased/23535-folders-in-wiki-repository.yml4
-rw-r--r--changelogs/unreleased/23819-fix-milestone-counters-to-top-right-of-panel-headings.yml4
-rw-r--r--changelogs/unreleased/23948-assign-to-me.yml4
-rw-r--r--changelogs/unreleased/23993-drop-ci_projects.yml6
-rw-r--r--changelogs/unreleased/24215-closed-issues-board.yml4
-rw-r--r--changelogs/unreleased/24333-close-issues-with-merge-request-title-ui.yml5
-rw-r--r--changelogs/unreleased/24683-sidebar-spinners.yml4
-rw-r--r--changelogs/unreleased/24976-start-of-line-mention.yml4
-rw-r--r--changelogs/unreleased/24998-fix-typo-gitlab-config-file.yml4
-rw-r--r--changelogs/unreleased/25367-add-impersonation-token.yml4
-rw-r--r--changelogs/unreleased/25437-just-emoji.yml4
-rw-r--r--changelogs/unreleased/25465-todo-done-clicking-is-kind-of-unsafe.yml4
-rw-r--r--changelogs/unreleased/25503_issues_finder_performance.yml4
-rw-r--r--changelogs/unreleased/25709-diff-file-overflow.yml4
-rw-r--r--changelogs/unreleased/25920-create-issue-from-failing-build.yml4
-rw-r--r--changelogs/unreleased/26087-asciidoc-cicd-badges-snippet.yml4
-rw-r--r--changelogs/unreleased/26136-list-repository-tree-api-doc.yml4
-rw-r--r--changelogs/unreleased/26206-fix-download-dropdown.yml4
-rw-r--r--changelogs/unreleased/26286-most-recent-activity-profile-header.yml4
-rw-r--r--changelogs/unreleased/26287-link-branch-in-calendar-activity.yml4
-rw-r--r--changelogs/unreleased/2629-show-public-rss-feeds-to-anonymous-users.yml4
-rw-r--r--changelogs/unreleased/26315-unify-labels-filter-behavior.yml4
-rw-r--r--changelogs/unreleased/26348-cleanup-navigation-order-groups.yml4
-rw-r--r--changelogs/unreleased/26348-cleanup-navigation-order.yml4
-rw-r--r--changelogs/unreleased/26371-native-emojis-v3-code.yml4
-rw-r--r--changelogs/unreleased/26379-iid-param.yml4
-rw-r--r--changelogs/unreleased/26500-informative-slack-notifications.yml4
-rw-r--r--changelogs/unreleased/26651-cannot-move-project-into-group.yml4
-rw-r--r--changelogs/unreleased/26703-todos-count.yml4
-rw-r--r--changelogs/unreleased/26705-filter-todos-by-manual-add.yml4
-rw-r--r--changelogs/unreleased/26732-combine-deploy-keys-and-push-rules-and-mirror-repository-and-protect-branches-settings-pages.yml5
-rw-r--r--changelogs/unreleased/26744-add-omniauth-oauth2-generic-strategy.yml3
-rw-r--r--changelogs/unreleased/26790-label-color-todos.yml4
-rw-r--r--changelogs/unreleased/26847-api-pipelines-use-basic.yml4
-rw-r--r--changelogs/unreleased/26875-builds-api-endpoint-skipped-scope.yml4
-rw-r--r--changelogs/unreleased/26900-pipelines-tabs.yml4
-rw-r--r--changelogs/unreleased/26957-tanuki-anim-hang.yml4
-rw-r--r--changelogs/unreleased/27032-add-a-house-keeping-api-call.yml4
-rw-r--r--changelogs/unreleased/27142-api-replace-destroy-with-stop-environment.yml4
-rw-r--r--changelogs/unreleased/27287-label-dropdown-error-messages.yml4
-rw-r--r--changelogs/unreleased/27336-add-environment-url-link-to-terminal-page.yml4
-rw-r--r--changelogs/unreleased/27354-navigation-new-button.yml4
-rw-r--r--changelogs/unreleased/27376-cache-default-branch-pipeline-on-project.yml4
-rw-r--r--changelogs/unreleased/27452-update-issue-count.yml4
-rw-r--r--changelogs/unreleased/27501-api-use-visibility-everywhere.yml4
-rw-r--r--changelogs/unreleased/27503-feature-status-aria-labels.yml4
-rw-r--r--changelogs/unreleased/27520-option-to-prevent-signing-in-from-multiple-ips.yml4
-rw-r--r--changelogs/unreleased/27523-make-stuck-build-detection-more-performant.yml4
-rw-r--r--changelogs/unreleased/27530-fix-job-dropdown-pipeline-console-error.yml4
-rw-r--r--changelogs/unreleased/27532_api_changes.yml4
-rw-r--r--changelogs/unreleased/27568-refactor-very-slow-dropdown-asignee-spec.yml4
-rw-r--r--changelogs/unreleased/27608-fixes-markdown-in-activity-feed-is-light-gray.yml4
-rw-r--r--changelogs/unreleased/27610-issue-number-alignment.yml4
-rw-r--r--changelogs/unreleased/27631-fix-small-height-of-activity-header-page.yml4
-rw-r--r--changelogs/unreleased/27726-fix-dropdown-width-in-admin-project-page.yml4
-rw-r--r--changelogs/unreleased/27762-add-default-artifacts-expiration.yml4
-rw-r--r--changelogs/unreleased/27778-a11y-sidebar.yml5
-rw-r--r--changelogs/unreleased/27783-fix-fe-doc-broken-link.yml4
-rw-r--r--changelogs/unreleased/27840-improve-search-bar-experience.yml4
-rw-r--r--changelogs/unreleased/27920-both-wip-messages-showing.yml4
-rw-r--r--changelogs/unreleased/27924-set-max-width-mini-pipeline-text.yml4
-rw-r--r--changelogs/unreleased/27934-left-align-logo.yml4
-rw-r--r--changelogs/unreleased/27936-make-all-uploads-require-revalidation-on-each-browser-fetch.yml4
-rw-r--r--changelogs/unreleased/27978-improve-task-list-ux.yml4
-rw-r--r--changelogs/unreleased/27994-fix-mr-widget-jump.yml4
-rw-r--r--changelogs/unreleased/28010-mr-merge-button-default-to-danger.yml4
-rw-r--r--changelogs/unreleased/28019-make-builds-show-faster.yml4
-rw-r--r--changelogs/unreleased/28058-hide-emails-in-atom-feeds.yml4
-rw-r--r--changelogs/unreleased/28082-deleted-branch-event-404.yml4
-rw-r--r--changelogs/unreleased/28142-overlap-bugs.yml4
-rw-r--r--changelogs/unreleased/28176_merge_widget_fix.yml4
-rw-r--r--changelogs/unreleased/28186-long-group-names-overflow-out-of-todos-view.yml4
-rw-r--r--changelogs/unreleased/28204-option-to-disable-webpack-dev-server-livereload.yml4
-rw-r--r--changelogs/unreleased/28229-pipelines-loading-icon.yml5
-rw-r--r--changelogs/unreleased/28236-browse-button-dropping.yml4
-rw-r--r--changelogs/unreleased/28247-timeloops-bug.yml4
-rw-r--r--changelogs/unreleased/28253-fix-buid-scroll-button-position.yml4
-rw-r--r--changelogs/unreleased/28257-issues-iids.yml4
-rw-r--r--changelogs/unreleased/28262-horizontal-scrolling-issue-on-long-project-names.yml4
-rw-r--r--changelogs/unreleased/28277-document-u2f-limitations-with-multiple-urls.yml4
-rw-r--r--changelogs/unreleased/28303-change-development-tanuki-favicon-colors-to-match-logo.yml4
-rw-r--r--changelogs/unreleased/28329-allow-slash-in-slash-command-args.yml4
-rw-r--r--changelogs/unreleased/28353-little-grammar-issue.yml4
-rw-r--r--changelogs/unreleased/28366-renamed-file-tooltip-contains-html.yml4
-rw-r--r--changelogs/unreleased/28367-fix-unfold-diff-line-number-copy-paste.yml4
-rw-r--r--changelogs/unreleased/28389-ux-problem-with-pipeline-coverage-placeholder.yml4
-rw-r--r--changelogs/unreleased/28410-dropdown-styling.yml4
-rw-r--r--changelogs/unreleased/28447-hybrid-repository-storages.yml4
-rw-r--r--changelogs/unreleased/28450-test-compiling-frontend-assets-for-production-in-ci.yml4
-rw-r--r--changelogs/unreleased/28458-present-gitlab-version-for-v4-changes-on-docs.yml4
-rw-r--r--changelogs/unreleased/28462-fix-delimiter-removes-issue-in-todo-counter.yml4
-rw-r--r--changelogs/unreleased/28499-fix-large-text-tooltip-in-diff-file-name.yml4
-rw-r--r--changelogs/unreleased/28516-default-kubernetes-namespace.yml4
-rw-r--r--changelogs/unreleased/28524-gitlab-ci-yml-coverage-key-is-unknown.yml4
-rw-r--r--changelogs/unreleased/28538-restore-nav-shortcuts.yml4
-rw-r--r--changelogs/unreleased/28598-narrow-environment-payload-by-using-basic-project.yml4
-rw-r--r--changelogs/unreleased/28655-current-path-text-is-not-updated-after-setting-the-new-username.yml4
-rw-r--r--changelogs/unreleased/28696-improve-grammar-gitlab-flow-doc.yml4
-rw-r--r--changelogs/unreleased/28704-fullscreen-zen-mode-is-broken.yml4
-rw-r--r--changelogs/unreleased/28713-fe-style-guide.yml4
-rw-r--r--changelogs/unreleased/28723-consistent-handling-indexof.yml4
-rw-r--r--changelogs/unreleased/28805-download-archive-with-branch-like-feature-xxxx-add-extra-directory-level.yml4
-rw-r--r--changelogs/unreleased/28807-search-for-milestone-by-title-in-rest-api.yml4
-rw-r--r--changelogs/unreleased/28835-jobs-head.yml4
-rw-r--r--changelogs/unreleased/28837-remove-help-duplicate.yml4
-rw-r--r--changelogs/unreleased/28865-filter-by-authorized-projects-in-v4.yml4
-rw-r--r--changelogs/unreleased/28890-allow-creating-mr-without-target-branch-in-url.yml5
-rw-r--r--changelogs/unreleased/28893-highlighted-diff-doesn-t-stay-highlighted-on-refresh.yml4
-rw-r--r--changelogs/unreleased/28898-fix-search-branches-in-cherry-picking.yml4
-rw-r--r--changelogs/unreleased/28935-make-logo-smaller.yml4
-rw-r--r--changelogs/unreleased/29043-upgrade-vue-and-remove-warnings.yml4
-rw-r--r--changelogs/unreleased/29263-merge-button-color.yml4
-rw-r--r--changelogs/unreleased/29428-new-directory-from-existing-branch.yml4
-rw-r--r--changelogs/unreleased/29483-spam-check-only-title-and-description.yml4
-rw-r--r--changelogs/unreleased/29550-fix-quick-submit-on-preview.yml4
-rw-r--r--changelogs/unreleased/29555-align-all-todo.yml4
-rw-r--r--changelogs/unreleased/29565-name-of-the-uncompressed-folder-of-a-tag-archive-changed.yml4
-rw-r--r--changelogs/unreleased/29575-polling.yml4
-rw-r--r--changelogs/unreleased/29604-v3-fix-branch-creation.yml4
-rw-r--r--changelogs/unreleased/3440-remove-hsts-header.yml4
-rw-r--r--changelogs/unreleased/3874-correctly-return-json-on-delete-responses.yml4
-rw-r--r--changelogs/unreleased/6073_project_api.yml4
-rw-r--r--changelogs/unreleased/9381-authentiq-backchannel-logout.yml4
-rw-r--r--changelogs/unreleased/add-auto-submited-header.yml4
-rw-r--r--changelogs/unreleased/add-changelog-filtered-search-visual-tokens.yml4
-rw-r--r--changelogs/unreleased/add-filtered-search-to-mr.yml4
-rw-r--r--changelogs/unreleased/add-frequently-used-emojis-back-to-menu.yml4
-rw-r--r--changelogs/unreleased/add-git-version-to-system-info.yml4
-rw-r--r--changelogs/unreleased/add-kube-ca-pem-file-deprecate-kube-ca-pem.yml4
-rw-r--r--changelogs/unreleased/add-pipeline-triggers.yml4
-rw-r--r--changelogs/unreleased/add-test-backoff-util.yml4
-rw-r--r--changelogs/unreleased/add-todos-shortcut.yml4
-rw-r--r--changelogs/unreleased/add-yarn-documentation.yml4
-rw-r--r--changelogs/unreleased/add_mr_info_to_issues_list.yml4
-rw-r--r--changelogs/unreleased/alphabetically_sort_tags_on_runner_list.yml4
-rw-r--r--changelogs/unreleased/api-drop-subscribed.yml5
-rw-r--r--changelogs/unreleased/api-empty-return.yml4
-rw-r--r--changelogs/unreleased/api-entities.yml4
-rw-r--r--changelogs/unreleased/api-notes-entity-fields.yml4
-rw-r--r--changelogs/unreleased/api-post-block.yml4
-rw-r--r--changelogs/unreleased/api-project-issues-404.yml4
-rw-r--r--changelogs/unreleased/api-remove-deploy-key-disable.yml4
-rw-r--r--changelogs/unreleased/api-remove-owned-groups.yml4
-rw-r--r--changelogs/unreleased/api-star-restful.yml4
-rw-r--r--changelogs/unreleased/api-subscription-restful.yml4
-rw-r--r--changelogs/unreleased/api-todos-restful.yml4
-rw-r--r--changelogs/unreleased/artifactsdoc.yml4
-rw-r--r--changelogs/unreleased/backup_storage_class.yml4
-rw-r--r--changelogs/unreleased/beautiful-karma-output.yml4
-rw-r--r--changelogs/unreleased/branch_deletion.yml4
-rw-r--r--changelogs/unreleased/bypass-email-domain-validation-when-created-by-admin.yml4
-rw-r--r--changelogs/unreleased/cleaner-additional-award-emoji-button.yml4
-rw-r--r--changelogs/unreleased/clear-connections-before-starting-sidekiq.yml4
-rw-r--r--changelogs/unreleased/commons-chunk-plugin.yml5
-rw-r--r--changelogs/unreleased/copy-branch-to-clipboard.yml4
-rw-r--r--changelogs/unreleased/cover-my-karma.yml4
-rw-r--r--changelogs/unreleased/create_branch_repo_less.yml4
-rw-r--r--changelogs/unreleased/dashboard-filter-search-keep-params.yml4
-rw-r--r--changelogs/unreleased/delete-artifacts-for-pages.yml4
-rw-r--r--changelogs/unreleased/diff-make-obvious-cant-comment.yml4
-rw-r--r--changelogs/unreleased/dm-group-reference-full-name.yml4
-rw-r--r--changelogs/unreleased/dynamic-header-fixture.yml4
-rw-r--r--changelogs/unreleased/dynamic-project-title-fixture.yml4
-rw-r--r--changelogs/unreleased/dz-blacklist--names.yml4
-rw-r--r--changelogs/unreleased/dz-change-project-view.yml4
-rw-r--r--changelogs/unreleased/dz-create-nested-groups-via-ui.yml4
-rw-r--r--changelogs/unreleased/dz-dashboard-groups-search.yml4
-rw-r--r--changelogs/unreleased/dz-nested-groups-api.yml4
-rw-r--r--changelogs/unreleased/dz-nested-groups-members.yml4
-rw-r--r--changelogs/unreleased/dz-nested-groups-restrictions.yml4
-rw-r--r--changelogs/unreleased/dz-refactor-full-path.yml4
-rw-r--r--changelogs/unreleased/etag-notes-polling.yml4
-rw-r--r--changelogs/unreleased/expose-pagination-headers.yml4
-rw-r--r--changelogs/unreleased/fe-paginated-environments-api-add-subview.yml4
-rw-r--r--changelogs/unreleased/feature-brand-logo-in-emails.yml4
-rw-r--r--changelogs/unreleased/feature-github-find-users-by-email.yml4
-rw-r--r--changelogs/unreleased/feature-openid-connect.yml4
-rw-r--r--changelogs/unreleased/feature-runner-jobs-v4-api.yml4
-rw-r--r--changelogs/unreleased/feature-runners-registration-deletion-v4-api.yml4
-rw-r--r--changelogs/unreleased/feature-syshook_commits.yml4
-rw-r--r--changelogs/unreleased/filter-bar-fix-ie.yml4
-rw-r--r--changelogs/unreleased/fix-cycle-analytics-events-limit.yml4
-rw-r--r--changelogs/unreleased/fix-gb-deprecate-ci-config-types.yml4
-rw-r--r--changelogs/unreleased/fix-gb-notification-settings-when-no-repository.yml4
-rw-r--r--changelogs/unreleased/fix-gb-passed-with-warnings-status-on-mysql.yml4
-rw-r--r--changelogs/unreleased/fix-gb-pipeline-retry-builds-started.yml4
-rw-r--r--changelogs/unreleased/fix-gb-pipeline-retry-cancel-buttons-consistency.yml4
-rw-r--r--changelogs/unreleased/fix-gb-remove-deprecated-ci-build-status-badge.yml4
-rw-r--r--changelogs/unreleased/fix-gb-update-commit-status-api.yml4
-rw-r--r--changelogs/unreleased/fix-mentioned-issues-for-external-trackers.yml4
-rw-r--r--changelogs/unreleased/fix-prometheus-including-d3-main-bundle.yml4
-rw-r--r--changelogs/unreleased/fix-slow-queries-for-branches-index.yml4
-rw-r--r--changelogs/unreleased/fix_issue_from_milestone.yml4
-rw-r--r--changelogs/unreleased/fixes-namespace-api-documentation.yml4
-rw-r--r--changelogs/unreleased/format-timeago-date.yml4
-rw-r--r--changelogs/unreleased/gfm-autocomplete-fixes.yml4
-rw-r--r--changelogs/unreleased/gitaly-post-receive.yml4
-rw-r--r--changelogs/unreleased/group-memebrs-owner-level.yml4
-rw-r--r--changelogs/unreleased/instrument-in-karma.yml4
-rw-r--r--changelogs/unreleased/introduce-pipeline-triggers.yml4
-rw-r--r--changelogs/unreleased/issue-boards-cant-drag-fix.yml4
-rw-r--r--changelogs/unreleased/issue-descrpiption-spinner-off.yml4
-rw-r--r--changelogs/unreleased/issue-newproj-layout.yml4
-rw-r--r--changelogs/unreleased/issue-tags-layout.yml4
-rw-r--r--changelogs/unreleased/issue_16834.yml4
-rw-r--r--changelogs/unreleased/issue_24815.yml4
-rw-r--r--changelogs/unreleased/issue_25900.yml4
-rw-r--r--changelogs/unreleased/issue_26701.yml4
-rw-r--r--changelogs/unreleased/list_issues_with_no_labels.yml4
-rw-r--r--changelogs/unreleased/lnovy-gitlab-ce-empty-variables.yml4
-rw-r--r--changelogs/unreleased/long-file-name-overflow.yml4
-rw-r--r--changelogs/unreleased/migrate-pipeline-events-and-email-service.yml4
-rw-r--r--changelogs/unreleased/mock-ci-service.yml4
-rw-r--r--changelogs/unreleased/move_tags_service_to_namespace.yml4
-rw-r--r--changelogs/unreleased/moving-issue-with-two-list-labels.yml4
-rw-r--r--changelogs/unreleased/mr-diff-comment-button.yml4
-rw-r--r--changelogs/unreleased/new-branch-fixture.yml4
-rw-r--r--changelogs/unreleased/only-create-unmergeable-todo-once.yml4
-rw-r--r--changelogs/unreleased/only-yield-valid-reference-matches.yml4
-rw-r--r--changelogs/unreleased/pages-0-4-0.yml4
-rw-r--r--changelogs/unreleased/paginate-all-the-things.yml4
-rw-r--r--changelogs/unreleased/pass in current_user in MergeRequest and MergeRequestsHelper.yml4
-rw-r--r--changelogs/unreleased/pass_coverage_value_to_commit_status_api.yml4
-rw-r--r--changelogs/unreleased/pipeline-blocking-actions.yml4
-rw-r--r--changelogs/unreleased/pipelines-build-tooltip.yml4
-rw-r--r--changelogs/unreleased/priority-to-label-priority.yml4
-rw-r--r--changelogs/unreleased/protected-branch-dropdown-titles.yml4
-rw-r--r--changelogs/unreleased/quick-submit-fixture.yml4
-rw-r--r--changelogs/unreleased/removal_of_unused_parameter.yml4
-rw-r--r--changelogs/unreleased/remove-es6-extension.yml4
-rw-r--r--changelogs/unreleased/remove-inactive-default-email-services.yml4
-rw-r--r--changelogs/unreleased/remove-jquery-ui-datepicker.yml4
-rw-r--r--changelogs/unreleased/remove-jquery-ui-plugins.yml4
-rw-r--r--changelogs/unreleased/remove-jquery-ui-sortable.yml4
-rw-r--r--changelogs/unreleased/remove-new-relic-gem.yml4
-rw-r--r--changelogs/unreleased/remove-readme-option.yml4
-rw-r--r--changelogs/unreleased/remove-subscribe-label-tooltip.yml4
-rw-r--r--changelogs/unreleased/remove-unused-ci-tables.yml4
-rw-r--r--changelogs/unreleased/rename-ci_commits-to-ci_pipeline.yml4
-rw-r--r--changelogs/unreleased/rename-retry-failed-pipeline-to-retry.yml4
-rw-r--r--changelogs/unreleased/rename_delete_services.yml4
-rw-r--r--changelogs/unreleased/rename_files_delete_service.yml4
-rw-r--r--changelogs/unreleased/replace-npm-with-yarn.yml4
-rw-r--r--changelogs/unreleased/replace_closing_mr_icon.yml4
-rw-r--r--changelogs/unreleased/requires-input-fixture.yml4
-rw-r--r--changelogs/unreleased/rfr-20170307-change-default-project-number-limit.yml4
-rw-r--r--changelogs/unreleased/routes-lower-case.yml4
-rw-r--r--changelogs/unreleased/rss-btn-alignment-fix.yml4
-rw-r--r--changelogs/unreleased/seed-abuse-reports.yml4
-rw-r--r--changelogs/unreleased/set-default-cache-key-for-jobs.yml4
-rw-r--r--changelogs/unreleased/settings-tab.yml4
-rw-r--r--changelogs/unreleased/sh-bump-hashie-to-3-5-5.yml4
-rw-r--r--changelogs/unreleased/sh-delete-user-permission-check.yml4
-rw-r--r--changelogs/unreleased/snippets-search.yml4
-rw-r--r--changelogs/unreleased/sort-builds-in-stage-dropdown.yml4
-rw-r--r--changelogs/unreleased/ssh-key-paste.yml4
-rw-r--r--changelogs/unreleased/ssrf-protections.yml4
-rw-r--r--changelogs/unreleased/static-navbar.yml4
-rw-r--r--changelogs/unreleased/task_list_refactor.yml4
-rw-r--r--changelogs/unreleased/tc-api-pipeline-jobs.yml4
-rw-r--r--changelogs/unreleased/tc-fix-project-create-500.yml4
-rw-r--r--changelogs/unreleased/time-tracking-color-not-consistent.yml4
-rw-r--r--changelogs/unreleased/unified-member-api-response.yml4
-rw-r--r--changelogs/unreleased/update-ace.yml4
-rw-r--r--changelogs/unreleased/update-vue-2-1.yml4
-rw-r--r--changelogs/unreleased/use-redis-channel-to-post-runner-notifcations.yml4
-rw-r--r--changelogs/unreleased/user-calendar-border.yml4
-rw-r--r--changelogs/unreleased/user-callouts.yml4
-rw-r--r--changelogs/unreleased/workhorse-1-4-0.yml4
-rw-r--r--changelogs/unreleased/zj-builds-to-jobs-api.yml4
-rw-r--r--changelogs/unreleased/zj-chat-notification-default-branch.yml4
-rw-r--r--changelogs/unreleased/zj-variables-build-job.yml4
-rw-r--r--config/environments/test.rb3
-rw-r--r--config/gitlab.yml.example2
-rw-r--r--config/webpack.config.js4
-rw-r--r--db/migrate/20170317203554_index_routes_path_for_like.rb4
-rw-r--r--doc/administration/gitaly/index.md86
-rw-r--r--doc/administration/high_availability/nfs.md2
-rw-r--r--doc/api/pipeline_triggers.md10
-rw-r--r--doc/development/README.md2
-rw-r--r--doc/development/ci_setup.md2
-rw-r--r--doc/development/fe_guide/accessibility.md13
-rw-r--r--doc/development/fe_guide/architecture.md22
-rw-r--r--doc/development/fe_guide/design_patterns.md78
-rw-r--r--doc/development/fe_guide/index.md92
-rw-r--r--doc/development/fe_guide/performance.md95
-rw-r--r--doc/development/fe_guide/security.md92
-rw-r--r--doc/development/fe_guide/style_guide_js.md408
-rw-r--r--doc/development/fe_guide/style_guide_scss.md (renamed from doc/development/scss_styleguide.md)56
-rw-r--r--doc/development/fe_guide/testing.md129
-rw-r--r--doc/development/fe_guide/vue.md104
-rw-r--r--doc/development/frontend.md511
-rw-r--r--doc/development/rake_tasks.md14
-rw-r--r--doc/development/testing.md11
-rw-r--r--doc/install/installation.md33
-rw-r--r--doc/profile/README.md6
-rw-r--r--doc/profile/preferences.md37
-rw-r--r--doc/update/8.13-to-8.14.md2
-rw-r--r--doc/update/8.17-to-9.0.md87
-rw-r--r--doc/user/profile/preferences.md64
-rw-r--r--doc/workflow/shortcuts.md1
-rw-r--r--lib/gitlab/etag_caching/store.rb2
-rw-r--r--lib/gitlab/gitaly_client.rb7
-rw-r--r--lib/gitlab/testing/request_blocker_middleware.rb61
-rwxr-xr-xlib/support/init.d/gitlab67
-rw-r--r--lib/support/init.d/gitlab.default.example4
-rw-r--r--lib/tasks/gitlab/assets.rake8
-rw-r--r--lib/tasks/gitlab/gitaly.rake23
-rw-r--r--lib/tasks/gitlab/task_helpers.rb2
-rw-r--r--package.json2
-rw-r--r--spec/controllers/import/bitbucket_controller_spec.rb11
-rw-r--r--spec/controllers/projects/issues_controller_spec.rb23
-rw-r--r--spec/factories/merge_requests.rb1
-rw-r--r--spec/features/admin/admin_settings_spec.rb1
-rw-r--r--spec/features/dashboard/shortcuts_spec.rb5
-rw-r--r--spec/features/merge_requests/create_new_mr_spec.rb6
-rw-r--r--spec/features/merge_requests/merge_immediately_with_pipeline_spec.rb2
-rw-r--r--spec/features/participants_autocomplete_spec.rb95
-rw-r--r--spec/features/projects/blobs/user_create_spec.rb18
-rw-r--r--spec/features/projects/deploy_keys_spec.rb26
-rw-r--r--spec/features/projects/group_links_spec.rb24
-rw-r--r--spec/features/projects/user_create_dir_spec.rb72
-rw-r--r--spec/features/users/projects_spec.rb31
-rw-r--r--spec/helpers/todos_helper_spec.rb34
-rw-r--r--spec/javascripts/boards/board_card_spec.js3
-rw-r--r--spec/javascripts/boards/boards_store_spec.js5
-rw-r--r--spec/javascripts/boards/issue_card_spec.js3
-rw-r--r--spec/javascripts/boards/list_spec.js3
-rw-r--r--spec/javascripts/boards/modal_store_spec.js1
-rw-r--r--spec/javascripts/filtered_search/filtered_search_manager_spec.js2
-rw-r--r--spec/javascripts/issuable_time_tracker_spec.js6
-rw-r--r--spec/javascripts/lib/utils/common_utils_spec.js67
-rw-r--r--spec/javascripts/lib/utils/poll_spec.js127
-rw-r--r--spec/javascripts/test_bundle.js3
-rw-r--r--spec/javascripts/user_callout_spec.js18
-rw-r--r--spec/mailers/emails/profile_spec.rb10
-rw-r--r--spec/mailers/notify_spec.rb380
-rw-r--r--spec/models/concerns/issuable_spec.rb28
-rw-r--r--spec/models/issue_spec.rb37
-rw-r--r--spec/models/namespace_spec.rb4
-rw-r--r--spec/models/project_spec.rb7
-rw-r--r--spec/models/route_spec.rb20
-rw-r--r--spec/models/snippet_spec.rb43
-rw-r--r--spec/services/boards/issues/list_service_spec.rb3
-rw-r--r--spec/services/issuable/bulk_update_service_spec.rb2
-rw-r--r--spec/services/spam_service_spec.rb71
-rw-r--r--spec/spec_helper.rb3
-rw-r--r--spec/support/notify_shared_examples.rb140
-rw-r--r--spec/support/prometheus_helpers.rb4
-rw-r--r--spec/support/slack_mattermost_notifications_shared_examples.rb19
-rw-r--r--spec/support/target_branch_helpers.rb16
-rw-r--r--spec/support/wait_for_requests.rb32
-rw-r--r--spec/support/wait_for_vue_resource.rb2
-rw-r--r--spec/tasks/gitlab/gitaly_rake_spec.rb78
-rw-r--r--spec/tasks/gitlab/workhorse_rake_spec.rb3
-rw-r--r--tmp/sockets/private/.gitkeep0
-rw-r--r--vendor/assets/javascripts/js.cookie.js156
-rw-r--r--yarn.lock6
513 files changed, 3305 insertions, 2634 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 34c10b3b77f..24627b5faca 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -19,7 +19,7 @@ before_script:
- source ./scripts/prepare_build.sh
- cp config/gitlab.yml.example config/gitlab.yml
- bundle --version
- - '[ "$USE_BUNDLE_INSTALL" != "true" ] || retry bundle install --without postgres production --jobs $(nproc) $FLAGS'
+ - '[ "$USE_BUNDLE_INSTALL" != "true" ] || retry bundle install --without postgres production --jobs $(nproc) --clean $FLAGS'
- retry gem install knapsack
- '[ "$SETUP_DB" != "true" ] || bundle exec rake db:drop db:create db:schema:load db:migrate add_limits_mysql'
@@ -333,6 +333,7 @@ migration paths:
- bundle install --without postgres production --jobs $(nproc) $FLAGS --retry=3
- bundle exec rake db:drop db:create db:schema:load db:seed_fu
- git checkout $CI_COMMIT_SHA
+ - bundle install --without postgres production --jobs $(nproc) $FLAGS --retry=3
- source scripts/prepare_build.sh
- bundle exec rake db:migrate
diff --git a/CHANGELOG.md b/CHANGELOG.md
index da1898e3770..4291eca8dc7 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,289 @@
documentation](doc/development/changelog.md) for instructions on adding your own
entry.
+## 9.0.0 (2017-03-22)
+
+- Fix inconsistent naming for services that delete things. !5803 (dixpac)
+- UI: Allow a project variable to be set to an empty value. !6044 (Lukáš Nový)
+- Align task list checkboxes. !6487 (Jared Deckard <jared.deckard@gmail.com>)
+- SanitizationFilter allows html5 details and summary tags. !6568
+- on branch deletion show loading icon and disabled the button. !6761 (wendy0402)
+- Use an entity for RepoBranch commits and enhance RepoCommit. !7138 (Ben Boeckel)
+- Deleting a user doesn't delete issues they've created/are assigned to. !7393
+- Fix position of counter in milestone panels. !7842 (Andrew Smith (EspadaV8))
+- Added a feature to create a 'directly addressed' Todo when mentioned in the beginning of a line. !7926 (Ershad Kunnakkadan)
+- Implement OpenID Connect identity provider. !8018 (Markus Koller)
+- Show directory hierarchy when listing wiki pages. !8133 (Alex Braha Stoll)
+- Migrate SlackService and MattermostService from build_events to pipeline_events, and migrate BuildsEmailService to PipelinesEmailService. Update Hipchat to use pipeline events rather than build events. !8196
+- Execute web hooks for WikiPage delete operation. !8198
+- Added external environment link to web terminal view. !8303
+- Responsive title in diffs inline, side by side, with and without sidebar. !8475
+- Bypass email domain validation when a user is created by an admin. !8575 (Reza Mohammadi @remohammadi)
+- API: Paginate all endpoints that return an array. !8606 (Robert Schilling)
+- pass in current_user in MergeRequest and MergeRequestsHelper. !8624 (Dongqing Hu)
+- Add user & build links in Slack Notifications. !8641 (Poornima M)
+- Todo done clicking is kind of unusable. !8691 (Jacopo Beschi @jacopo-beschi)
+- Filter todos by manual add. !8691 (Jacopo Beschi @jacopo-beschi)
+- Add runner version to /admin/runners view. !8733 (Jonathon Reinhart)
+- API: remove `public` param for projects. !8736
+- Allow creating nested groups via UI. !8786
+- API: Add environment stop action. !8808
+- Add discussion events to contributions calendar. !8821
+- Unify issues search behavior by always filtering when ALL labels matches. !8849
+- V3 deprecated templates endpoints removal. !8853
+- Expose pipelines as PipelineBasic `api/v3/projects/:id/pipelines`. !8875
+- Alphabetically sort tags on runner list. !8922 (blackst0ne)
+- Added documentation for permalinks to most recent build artifacts. !8934 (Christian Godenschwager)
+- Standardize branch name params as branch on V4 API. !8936
+- Move /projects/fork/:id to /projects/:id/fork. !8940
+- Fix small height of activity header page. !8952 (Pavel Sorokin)
+- Optionally make users created via the API set their password. !8957 (Joost Rijneveld)
+- GitHub Importer - Find users based on GitHub email address. !8958
+- API: Consolidate /projects endpoint. !8962
+- Add filtered search visual tokens. !8969
+- Store group and project full name and full path in routes table. !8979
+- Add internal API to notify Gitaly of post receive. !8983
+- Remove inactive default email services. !8987
+- Option to prevent signing in from multiple ips. !8998
+- Download snippets with LF line-endings by default. !8999
+- Fixes dropdown width in admin project page. !9002
+- fixes issue number alignment problem in MR and issue list. !9020
+- Fix CI/CD pipeline retry and take stages order into account. !9021
+- Make stuck builds detection more performant. !9025
+- Filter by projects in the end of search. !9030
+- Add nested groups to the API. !9034
+- Use ETag to improve performance of issue notes polling. !9036
+- Add the oauth2_generic OmniAuth strategy. !9048 (Joe Marty)
+- Brand header logo for pipeline emails. !9049 (Alexis Reigel)
+- replace npm with yarn and add yarn.lock. !9055
+- Fix displaying error messages for create label dropdown. !9058 (Tom Koole)
+- Set dropdown height fixed to 250px and make it scrollable. !9063
+- Update API docs for new namespace format. !9073 (Markus Koller)
+- Replace static fixture for behaviors/quick_submit_spec.js. !9086 (winniehell)
+- Use iids as filter parameter. !9096
+- Manage user personal access tokens through api and add impersonation tokens. !9099 (Simon Vocella)
+- Added the ability to copy a branch name to the clipboard. !9103 (Glenn Sayers)
+- Rename Files::DeleteService to Files::DestroyService. !9110 (dixpac)
+- Fixes FE Doc broken link. !9120
+- Add git version to gitlab:env:info. !9128 (Semyon Pupkov)
+- Replace static fixture for new_branch_spec.js. !9131 (winniehell)
+- Reintroduce coverage report for JavaScript. !9133 (winniehell)
+- Fix MR widget jump. !9146
+- Avoid calling Build#trace_with_state for performance. !9149 (Takuya Noguchi)
+- fix background color for labels mention in todo. !9155 (mhasbini)
+- Replace static fixture for behaviors/requires_input_spec.js. !9162 (winniehell)
+- Added AsciiDoc Snippet to CI/CD Badges. !9164 (Jan Christophersen)
+- Make Karma output look nicer for CI. !9165 (winniehell)
+- show 99+ for large count in todos notification bell. !9171 (mhasbini)
+- Replace static fixture for header_spec.js. !9174 (winniehell)
+- Replace static fixture for project_title_spec.js. !9175 (winniehell)
+- Fixes markdown in activity-feed is gray. !9179
+- Show notifications settings dropdown even if repository feature is disabled. !9180
+- Fixes job dropdown action throws error in js console. !9182
+- Set maximum width for mini pipeline graph text so it is not truncated to early. !9188
+- Added 'Most Recent Activity' header to the User Profile page. !9189 (Jan Christophersen)
+- Show Issues mentioned / being closed from a Merge Requests title below the 'Accept Merge Request' button. !9194 (Jan Christophersen)
+- Stop linking to deleted Branches in Activity tabs. !9203 (Jan Christophersen)
+- Make it possible to pass coverage value to commit status API. !9214 (wendy0402)
+- Add admin setting for default artifacts expiration. !9219
+- add :iids param to IssuableFinder (resolve technical dept). !9222 (mhasbini)
+- Add Links to Branches in Calendar Activity. !9224 (Jan Christophersen)
+- Fix pipeline retry and cancel buttons on pipeline details page. !9225
+- Remove es6 file extension from JavaScript files. !9241 (winniehell)
+- Add Runner's registration/deletion v4 API. !9246
+- Add merge request count to each issue on issues list. !9252 (blackst0ne)
+- Fix error in MR widget after /merge slash command. !9259
+- Clean-up Project navigation order. !9272
+- Add Runner's jobs v4 API. !9273
+- Add pipeline trigger API with user permissions. !9277
+- Enhanced filter issues layout for better mobile experiance. !9280 (Pratik Borsadiya)
+- Move babel config for instanbul to karma config. !9286 (winniehell)
+- Document U2F limitations with multiple URLs. !9300
+- Wrap long Project and Group titles. !9301
+- Clean-up Groups navigation order. !9309
+- Truncate long Todo titles for non-mobile screens. !9311
+- add rake tasks to handle yarn dependencies and update documentation. !9316
+- API: - Make subscription API more RESTful. Use `post ":project_id/:subscribable_type/:subscribable_id/subscribe"` to subscribe and `post ":project_id/:subscribable_type/:subscribable_id/unsubscribe"` to unsubscribe from a resource. !9325 (Robert Schilling)
+- API: Moved `DELETE /projects/:id/star` to `POST /projects/:id/unstar`. !9328 (Robert Schilling)
+- API: Use `visibility` as string parameter everywhere. !9337
+- Add the Username to the HTTP(S) clone URL of a Repository. !9347 (Jan Christophersen)
+- Add spec for todo with target_type Commit. !9351 (George Andrinopoulos)
+- API: Remove `DELETE projects/:id/deploy_keys/:key_id/disable`. !9365 (Robert Schilling)
+- Fixes includes line number during unfold copy n paste in parallel diff view. !9365
+- API: Use POST to (un)block a user. !9371 (Robert Schilling)
+- Remove markup that was showing in tooltip for renamed files. !9374
+- Drop unused ci_projects table and some unused project_id columns, then rename gl_project_id to project_id. Stop exporting job trace when exporting projects. !9378 (David Wagner)
+- Adds remote logout functionality to the Authentiq OAuth provider. !9381 (Alexandros Keramidas)
+- Introduce /award slash command; Allow posting of just an emoji in comment. !9382 (mhasbini)
+- API: Remove deprecated fields Notes#upvotes and Notes#downvotes. !9384 (Robert Schilling)
+- Redo internals of Incoming Mail Support. !9385
+- update Vue to v2.1.10. !9386
+- Add button to create issue for failing build. !9391 (Alex Sanford)
+- test compiling production assets and generate webpack bundle report in CI. !9396
+- API: Return 204 for all delete endpoints. !9397 (Robert Schilling)
+- Add KUBE_CA_PEM_FILE, deprecate KUBE_CA_PEM. !9398
+- API: Use POST requests to mark todos as done. !9410 (Robert Schilling)
+- API project create: Make name or path required. !9416
+- Add housekeeping endpoint for Projects API. !9421
+- Fixes delimiter removes when todo marked as done. !9435
+- Document when current coverage configuration option was introduced. !9443
+- Uploaded files which content can change now require revalidation on each page load. !9453
+- Only add a newline in the Markdown Editor if the current line is not empty. !9455 (Jan Christophersen)
+- Rename builds to job for the v4 API. !9463
+- API: Remove /groups/owned endpoint. !9505 (Robert Schilling)
+- API: Return 400 for all validation erros in the mebers API. !9523 (Robert Schilling)
+- Fixes large file name tooltip cutoff in diff header. !9529
+- Keep consistent in handling indexOf results. !9531 (Takuya Noguchi)
+- Make documentation of list repository tree API call more detailed. !9532 (Marius Kleiner)
+- Fix Sort dropdown reflow issue. !9533 (Jarkko Tuunanen)
+- Improve grammar in GitLab flow documentation. !9552 (infogrind)
+- Change default project view for user from readme to files view. !9584
+- Make it possible to configure blocking manual actions. !9585
+- Show public RSS feeds to anonymous users. !9596 (Michael Kozono)
+- Update storage settings to allow extra values per repository storage. !9597
+- Enable filtering milestones by search criteria in the API. !9606
+- Ensure archive download is only one directory deep. !9616
+- Fix updaing commit status when using optional attributes. !9618
+- Add filter and sorting to dashboard groups page. !9619
+- Remove deprecated build status badge and related services. !9620
+- Remove the newrelic gem. !9622 (Robert Schilling)
+- Rename table ci_commits to ci_pipelines. !9638
+- Remove various unused CI tables and columns. !9639
+- Use webpack CommonsChunkPlugin to place common javascript libraries in their own bundles. !9647
+- CORS: Whitelist pagination headers. !9651 (Robert Schilling)
+- Remove "subscribed" field from API responses returning list of issues or merge requests. !9661
+- Highlight line number if specified on diff pages when page loads. !9664
+- Set default cache key to "default" for jobs. !9666
+- Set max height to screen height for Zen mode. !9667
+- GET 'projects/:id/repository/commits' endpoint improvements. !9679 (George Andrinopoulos, Jordan Ryan Reuter)
+- 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 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
+- Use gitlab-workhorse 1.4.0. !9724
+- Add GET /projects/:id/pipelines/:pipeline_id/jobs endpoint. !9727
+- Restrict nested group names to prevent ambiguous routes. !9738
+- Rename job environment variables to new terminology. !9756
+- Deprecate usage of `types` configuration entry to describe CI/CD stages. !9766
+- Moved project settings from the gear drop-down menu to a tab. !9786
+- Fix "passed with warnings" stage status on MySQL installations. !9802
+- Fix for creating a project through API when import_url is nil. !9841
+- Use GitLab Pages v0.4.0. !9896
+- Reserve few project and nested group paths that have wildcard routes associated. !9898
+- Speed up project dashboard by caching pipeline status and eager loading routes. !9903
+- Fixes n+1 query for tags and branches index page. !9905
+- Hide ancestor groups in the share group dropdown list. !9965
+- Allow creating merge request even if target branch is not specified in query params. !9968
+- Removed d3 from the main application.js bundle. !10062
+- Return 404 in project issues API endpoint when project cannot be found. !10093
+- Fix positioning of `Scroll to top` button.
+- Add limit to the number of events showed in cycle analytics.
+- Only run timeago loops after rendering timeago components.
+- Increase right side of file header to button stays on same line.
+- Centers loading icon vertically and horizontally in pipelines table in commit view.
+- Fix issues mentioned but not closed for external issue trackers.
+- fix milestone does not automatically assign when create issue from milestone.
+- Re-add Assign to me link to Merge Request and Issues.
+- Format timeago date to short format.
+- Fix errors in slash commands matcher, add simple test coverage. (YarNayar)
+- Make Git history follow renames again by performing the --skip in Ruby.
+- Added option to update to owner for group members.
+- Pick up option from GDK to disable webpack dev server livereload.
+- Introduce Pipeline Triggers that are user-aware.
+- Fixed loading spinner position on issue template toggle.
+- Removed duplicate "Visibility Level" label on New Project page. (Robert Marcano)
+- Fix 'New Tag' layout on Tags page. (Robert Marcano)
+- Update API endpoints for raw files.
+- Fix issuable stale object error handler for js when updating tasklists.
+- Gather issuable metadata to avoid n+1 queries on index view.
+- Remove JIRA closed status icon.
+- Fix z index issues with sidebar.
+- Fixed long file names overflowing under action buttons.
+- Only show public emails in atom feeds.
+- Add Mock CI service/integration for development.
+- Move tag services to Tags namespace. (dixpac)
+- Set Auto-Submitted header to mails. (Semyon Pupkov)
+- Improved diff comment button UX.
+- Adds API endpoint to fetch all merge request for a single milestone. (Joren De Groof)
+- Only create unmergeable todos once when MR fails to merge.
+- Only yield valid references in ReferenceFilter.references_in.
+- Add member: Always return 409 when a member exists.
+- Remove plus icon from MR button on compare view.
+- Re-add the New Project button in nav bar.
+- Default to subtle MR mege button until CI status is available.
+- Rename priority sorting option to label priority.
+- Added headers to protected branch access dropdowns.
+- Hide issue info when project issues are disabled. (George Andrinopoulos)
+- removed unused parameter 'status_only: true'.
+- Left align logo.
+- Replaced jQuery UI datepicker.
+- Removed jQuery UI highlight & autocomplete.
+- Replaced jQuery UI sortable.
+- Remove readme-only project view preference.
+- Remove tooltips from label subscription buttons.
+- Rename retry failed button on pipeline page to just retry.
+- Align bulk update issues button to the right.
+- Remove remnants of git annex support.
+- Dispatch needed JS when creating a new MR in diff view.
+- Change project count limit from 10 to 100000.
+- Remove repeated routes.path check for postgresql database. (mhasbini)
+- Fixed RSS button alignment on activity pages.
+- Seed abuse reports for development.
+- Bump Hashie to 3.5.5 and omniauth to 1.4.2 to eliminate warning noise.
+- Add user deletion permission check in `Users::DestroyService`.
+- Fix snippets search result spacing.
+- Sort builds in stage dropdown.
+- SSH key field updates title after pasting key.
+- To protect against Server-side Request Forgery project import URLs are now prohibited against localhost or the server IP except for the assigned instance URL and port. Imports are also prohibited from ports below 1024 with the exception of ports 22, 80, and 443.
+- Remove fixed positioning from top nav.
+- Deduplicate markdown task lists.
+- update issue count when closing/reopening an issue.
+- Update code editor (ACE) to 1.2.6, to fix input problems with compose key.
+- Improves a11y in sidebar by adding aria-hidden attributes in i tags and by fixing two broken aria-hidden attributes.
+- Use redis channel to post notifications.
+- Removed top border from user contribution calendar.
+- Added user callouts to the projects dashboard and user profile.
+- Removes label when moving issue to another list that it is currently in.
+- Return 202 with JSON body on async removals on V4 API.
+- Add filtered search to MR page.
+- Add frequently used emojis back to awards menu.
+- don't animate logo when downloading files.
+- Stop setting Strict-Transport-Securty header from within the app.
+- Use "branch_name" instead "branch" on V3 branch creation API.
+- Fix archive prefix bug for refs containing dots.
+- ensure MR widget dropdown is same color as button.
+- Adds Pending and Finished tabs to pipelines page.
+- Decrease tanuki logo size.
+- Add all available statuses to scope filter for project builds endpoint. (George Andrinopoulos)
+- Add filter param for project membership for current_user in API v4.
+- Remove help link from right dropdown.
+- Fix jobs table header height.
+- Combined deploy keys, push rules, protect branches and mirror repository settings options into a single one called Repository.
+- Add storage class configuration option for Amazon S3 remote backups. (Jon Keys)
+- Specify in the documentation that only projects owners can transfer projects.
+- Use native unicode emojis.
+- Clear ActiveRecord connections before starting Sidekiq.
+- Update account view to display new username.
+- Narrow environment payload by using basic project details resource.
+- Creating a new branch from an issue will automatically initialize a repository if one doesn't already exist.
+- Dashboard project search keeps selected sort & filters.
+- Visually show expanded diff lines cant have comments.
+- Use full group name in GFM group reference title.
+- Make a default namespace of Kubernetes service to contain project ID.
+- Present GitLab version for each V3 to V4 API change on v3_to_v4.md.
+- Add badges to global dropdown.
+- Changed coverage reg expression placeholder text to be more like a placeholder.
+- Show members of parent groups on project members page.
+- Fix grammer issue in admin/runners.
+- Allow slashes in slash command arguments.
+- Adds paginationd and folders view to environments table.
+- hide loading spinners for server-rendered sidebar fields.
+- Change development tanuki favicon colors to match logo color order.
+- API issues - support filtering by iids.
+
## 8.17.4 (2017-03-19)
- Only show public emails in atom feeds.
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index a285e8ab74f..275c0cd1777 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -82,7 +82,7 @@ If a contributor is no longer actively working on a submitted merge request
we can decide that the merge request will be finished by one of our
[Merge request coaches][team] or close the merge request. We make this decision
based on how important the change is for our product vision. If a Merge request
-coach is going to finish the merge request we assign the
+coach is going to finish the merge request we assign the
~"coach will finish" label.
## Helping others
@@ -479,8 +479,7 @@ merge request:
1. [Rails](https://github.com/bbatsov/rails-style-guide)
1. [Newlines styleguide][newlines-styleguide]
1. [Testing](doc/development/testing.md)
-1. [JavaScript (ES6)](https://github.com/airbnb/javascript)
-1. [JavaScript (ES5)](https://github.com/airbnb/javascript/tree/es5-deprecated/es5)
+1. [JavaScript styleguide][js-styleguide]
1. [SCSS styleguide][scss-styleguide]
1. [Shell commands](doc/development/shell_commands.md) created by GitLab
contributors to enhance security
@@ -549,7 +548,8 @@ available at [http://contributor-covenant.org/version/1/1/0/](http://contributor
[rss-naming]: https://github.com/bbatsov/ruby-style-guide/blob/master/README.md#naming
[changelog]: doc/development/changelog.md "Generate a changelog entry"
[doc-styleguide]: doc/development/doc_styleguide.md "Documentation styleguide"
-[scss-styleguide]: doc/development/scss_styleguide.md "SCSS styleguide"
+[js-styleguide]: doc/development/fe_guide/style_guide_js.md "JavaScript styleguide"
+[scss-styleguide]: doc/development/fe_guide/style_guide_scss.md "SCSS styleguide"
[newlines-styleguide]: doc/development/newlines_styleguide.md "Newlines styleguide"
[UX Guide for GitLab]: http://docs.gitlab.com/ce/development/ux_guide/
[license-finder-doc]: doc/development/licensing.md
diff --git a/Gemfile b/Gemfile
index 6af27ce0f3e..38158387642 100644
--- a/Gemfile
+++ b/Gemfile
@@ -327,6 +327,7 @@ group :test do
gem 'test_after_commit', '~> 1.1'
gem 'sham_rack', '~> 1.3.6'
gem 'timecop', '~> 0.8.0'
+ gem 'concurrent-ruby', '~> 1.0.5'
end
gem 'octokit', '~> 4.6.2'
diff --git a/Gemfile.lock b/Gemfile.lock
index 043ca4f8800..07be5d7aded 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -128,7 +128,7 @@ GEM
execjs
coffee-script-source (1.10.0)
colorize (0.7.7)
- concurrent-ruby (1.0.4)
+ concurrent-ruby (1.0.5)
connection_pool (2.2.1)
crack (0.4.3)
safe_yaml (~> 1.0.0)
@@ -868,6 +868,7 @@ DEPENDENCIES
chronic (~> 0.10.2)
chronic_duration (~> 0.10.6)
coffee-rails (~> 4.1.0)
+ concurrent-ruby (~> 1.0.5)
connection_pool (~> 2.0)
creole (~> 0.5.0)
d3_rails (~> 3.5.0)
diff --git a/app/assets/images/icon-merge-request-unmerged.svg b/app/assets/images/icon-merge-request-unmerged.svg
index c4d8e65122d..d53a7470243 100644
--- a/app/assets/images/icon-merge-request-unmerged.svg
+++ b/app/assets/images/icon-merge-request-unmerged.svg
@@ -1 +1 @@
-<svg width="12" height="15" viewBox="0 0 12 15" xmlns="http://www.w3.org/2000/svg"><path d="M10.267 11.028V5.167c-.028-.728-.318-1.372-.878-1.923-.56-.55-1.194-.85-1.922-.877h-.934V.5l-2.8 2.8 2.8 2.8V4.233h.934a.976.976 0 0 1 .644.29.88.88 0 0 1 .289.644v5.861a1.86 1.86 0 0 0 .933 3.472 1.86 1.86 0 0 0 .934-3.472zM3.733 3.3a1.86 1.86 0 0 0-1.866-1.867 1.86 1.86 0 0 0-.934 3.472v6.123a1.86 1.86 0 0 0 .933 3.472 1.86 1.86 0 0 0 .934-3.472V4.905c.55-.317.933-.914.933-1.605z" fill-rule="nonzero"/></svg>
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path d="m5 5.563v4.875c1.024.4 1.75 1.397 1.75 2.563 0 1.519-1.231 2.75-2.75 2.75-1.519 0-2.75-1.231-2.75-2.75 0-1.166.726-2.162 1.75-2.563v-4.875c-1.024-.4-1.75-1.397-1.75-2.563 0-1.519 1.231-2.75 2.75-2.75 1.519 0 2.75 1.231 2.75 2.75 0 1.166-.726 2.162-1.75 2.563m-1 8.687c.69 0 1.25-.56 1.25-1.25 0-.69-.56-1.25-1.25-1.25-.69 0-1.25.56-1.25 1.25 0 .69.56 1.25 1.25 1.25m0-10c.69 0 1.25-.56 1.25-1.25 0-.69-.56-1.25-1.25-1.25-.69 0-1.25.56-1.25 1.25 0 .69.56 1.25 1.25 1.25"/><path d="m10.501 2c1.381.001 2.499 1.125 2.499 2.506v5.931c1.024.4 1.75 1.397 1.75 2.563 0 1.519-1.231 2.75-2.75 2.75-1.519 0-2.75-1.231-2.75-2.75 0-1.166.726-2.162 1.75-2.563v-5.931c0-.279-.225-.506-.499-.506v.926c0 .346-.244.474-.569.271l-2.952-1.844c-.314-.196-.325-.507 0-.71l2.952-1.844c.314-.196.569-.081.569.271v.93m1.499 12.25c.69 0 1.25-.56 1.25-1.25 0-.69-.56-1.25-1.25-1.25-.69 0-1.25.56-1.25 1.25 0 .69.56 1.25 1.25 1.25"/></svg> \ No newline at end of file
diff --git a/app/assets/javascripts/activities.js b/app/assets/javascripts/activities.js
index aebda7780e1..d816df831eb 100644
--- a/app/assets/javascripts/activities.js
+++ b/app/assets/javascripts/activities.js
@@ -1,6 +1,7 @@
/* eslint-disable no-param-reassign, class-methods-use-this */
/* global Pager */
-/* global Cookies */
+
+import Cookies from 'js-cookie';
class Activities {
constructor() {
diff --git a/app/assets/javascripts/awards_handler.js b/app/assets/javascripts/awards_handler.js
index 9349918f7a0..c743dd551d7 100644
--- a/app/assets/javascripts/awards_handler.js
+++ b/app/assets/javascripts/awards_handler.js
@@ -1,4 +1,4 @@
-/* global Cookies */
+import Cookies from 'js-cookie';
import emojiMap from 'emojis/digests.json';
import emojiAliases from 'emojis/aliases.json';
diff --git a/app/assets/javascripts/behaviors/toggler_behavior.js b/app/assets/javascripts/behaviors/toggler_behavior.js
index 92f3bb3ff52..86927314dd4 100644
--- a/app/assets/javascripts/behaviors/toggler_behavior.js
+++ b/app/assets/javascripts/behaviors/toggler_behavior.js
@@ -24,7 +24,7 @@
$('body').on('click', '.js-toggle-button', function(e) {
toggleContainer($(this).closest('.js-toggle-container'));
- const targetTag = e.target.tagName.toLowerCase();
+ const targetTag = e.currentTarget.tagName.toLowerCase();
if (targetTag === 'a' || targetTag === 'button') {
e.preventDefault();
}
diff --git a/app/assets/javascripts/boards/boards_bundle.js b/app/assets/javascripts/boards/boards_bundle.js
index 3874c2819a5..149bfbc8e8b 100644
--- a/app/assets/javascripts/boards/boards_bundle.js
+++ b/app/assets/javascripts/boards/boards_bundle.js
@@ -1,12 +1,11 @@
/* eslint-disable one-var, quote-props, comma-dangle, space-before-function-paren */
-/* global Vue */
/* global BoardService */
+import Vue from 'vue';
+import VueResource from 'vue-resource';
import FilteredSearchBoards from './filtered_search_boards';
import eventHub from './eventhub';
-window.Vue = require('vue');
-window.Vue.use(require('vue-resource'));
require('./models/issue');
require('./models/label');
require('./models/list');
@@ -24,6 +23,8 @@ require('./components/new_list_dropdown');
require('./components/modal/index');
require('../vue_shared/vue_resource_interceptor');
+Vue.use(VueResource);
+
$(() => {
const $boardApp = document.getElementById('board-app');
const Store = gl.issueBoards.BoardsStore;
diff --git a/app/assets/javascripts/boards/components/board.js b/app/assets/javascripts/boards/components/board.js
index 67c0c419713..35b3205cca7 100644
--- a/app/assets/javascripts/boards/components/board.js
+++ b/app/assets/javascripts/boards/components/board.js
@@ -1,7 +1,7 @@
/* eslint-disable comma-dangle, space-before-function-paren, one-var */
-/* global Vue */
/* global Sortable */
+import Vue from 'vue';
import boardBlankState from './board_blank_state';
require('./board_delete');
diff --git a/app/assets/javascripts/boards/components/board_blank_state.js b/app/assets/javascripts/boards/components/board_blank_state.js
index 52893d4642b..3fc68457961 100644
--- a/app/assets/javascripts/boards/components/board_blank_state.js
+++ b/app/assets/javascripts/boards/components/board_blank_state.js
@@ -1,5 +1,7 @@
/* global ListLabel */
-/* global Cookies */
+
+import Cookies from 'js-cookie';
+
const Store = gl.issueBoards.BoardsStore;
export default {
diff --git a/app/assets/javascripts/boards/components/board_card.js b/app/assets/javascripts/boards/components/board_card.js
index 4b72090df31..9320848bcca 100644
--- a/app/assets/javascripts/boards/components/board_card.js
+++ b/app/assets/javascripts/boards/components/board_card.js
@@ -1,4 +1,3 @@
-/* global Vue */
require('./issue_card_inner');
const Store = gl.issueBoards.BoardsStore;
diff --git a/app/assets/javascripts/boards/components/board_delete.js b/app/assets/javascripts/boards/components/board_delete.js
index 861600424a5..af621cfd57f 100644
--- a/app/assets/javascripts/boards/components/board_delete.js
+++ b/app/assets/javascripts/boards/components/board_delete.js
@@ -1,5 +1,6 @@
/* eslint-disable comma-dangle, space-before-function-paren, no-alert */
-/* global Vue */
+
+import Vue from 'vue';
(() => {
window.gl = window.gl || {};
diff --git a/app/assets/javascripts/boards/components/board_list.js b/app/assets/javascripts/boards/components/board_list.js
index 1330d4ae840..86e6c26e570 100644
--- a/app/assets/javascripts/boards/components/board_list.js
+++ b/app/assets/javascripts/boards/components/board_list.js
@@ -1,7 +1,7 @@
/* eslint-disable comma-dangle, space-before-function-paren, max-len */
-/* global Vue */
/* global Sortable */
+import Vue from 'vue';
import boardNewIssue from './board_new_issue';
import boardCard from './board_card';
@@ -48,7 +48,7 @@ import boardCard from './board_card';
this.list.getIssues(false);
}
- if (this.scrollHeight() > this.listHeight()) {
+ if (this.scrollHeight() > Math.ceil(this.listHeight())) {
this.showCount = true;
} else {
this.showCount = false;
diff --git a/app/assets/javascripts/boards/components/board_sidebar.js b/app/assets/javascripts/boards/components/board_sidebar.js
index dfc6eed785c..3c080008244 100644
--- a/app/assets/javascripts/boards/components/board_sidebar.js
+++ b/app/assets/javascripts/boards/components/board_sidebar.js
@@ -1,10 +1,11 @@
/* eslint-disable comma-dangle, space-before-function-paren, no-new */
-/* global Vue */
/* global IssuableContext */
/* global MilestoneSelect */
/* global LabelsSelect */
/* global Sidebar */
+import Vue from 'vue';
+
require('./sidebar/remove_issue');
(() => {
diff --git a/app/assets/javascripts/boards/components/issue_card_inner.js b/app/assets/javascripts/boards/components/issue_card_inner.js
index 69e30cec4c5..ba44dc5ed94 100644
--- a/app/assets/javascripts/boards/components/issue_card_inner.js
+++ b/app/assets/javascripts/boards/components/issue_card_inner.js
@@ -1,4 +1,4 @@
-/* global Vue */
+import Vue from 'vue';
import eventHub from '../eventhub';
(() => {
diff --git a/app/assets/javascripts/boards/components/modal/empty_state.js b/app/assets/javascripts/boards/components/modal/empty_state.js
index e6973c3fd59..823319df6e7 100644
--- a/app/assets/javascripts/boards/components/modal/empty_state.js
+++ b/app/assets/javascripts/boards/components/modal/empty_state.js
@@ -1,4 +1,5 @@
-/* global Vue */
+import Vue from 'vue';
+
(() => {
const ModalStore = gl.issueBoards.ModalStore;
diff --git a/app/assets/javascripts/boards/components/modal/footer.js b/app/assets/javascripts/boards/components/modal/footer.js
index 1cbc422c961..887ce373096 100644
--- a/app/assets/javascripts/boards/components/modal/footer.js
+++ b/app/assets/javascripts/boards/components/modal/footer.js
@@ -1,7 +1,8 @@
/* eslint-disable no-new */
-/* global Vue */
/* global Flash */
+import Vue from 'vue';
+
require('./lists_dropdown');
(() => {
diff --git a/app/assets/javascripts/boards/components/modal/index.js b/app/assets/javascripts/boards/components/modal/index.js
index 4240c97617d..4800407be1c 100644
--- a/app/assets/javascripts/boards/components/modal/index.js
+++ b/app/assets/javascripts/boards/components/modal/index.js
@@ -1,5 +1,6 @@
-/* global Vue */
/* global ListIssue */
+
+import Vue from 'vue';
import queryData from '../../utils/query_data';
require('./header');
diff --git a/app/assets/javascripts/boards/components/modal/list.js b/app/assets/javascripts/boards/components/modal/list.js
index 3730c1ecaeb..aba56d4aa31 100644
--- a/app/assets/javascripts/boards/components/modal/list.js
+++ b/app/assets/javascripts/boards/components/modal/list.js
@@ -1,6 +1,8 @@
-/* global Vue */
/* global ListIssue */
/* global bp */
+
+import Vue from 'vue';
+
(() => {
const ModalStore = gl.issueBoards.ModalStore;
diff --git a/app/assets/javascripts/boards/components/modal/lists_dropdown.js b/app/assets/javascripts/boards/components/modal/lists_dropdown.js
index 3c05120a2da..9e9ed46ab8d 100644
--- a/app/assets/javascripts/boards/components/modal/lists_dropdown.js
+++ b/app/assets/javascripts/boards/components/modal/lists_dropdown.js
@@ -1,4 +1,5 @@
-/* global Vue */
+import Vue from 'vue';
+
(() => {
const ModalStore = gl.issueBoards.ModalStore;
diff --git a/app/assets/javascripts/boards/components/modal/tabs.js b/app/assets/javascripts/boards/components/modal/tabs.js
index 1cd6ca0ee88..23cb1b13d11 100644
--- a/app/assets/javascripts/boards/components/modal/tabs.js
+++ b/app/assets/javascripts/boards/components/modal/tabs.js
@@ -1,4 +1,5 @@
-/* global Vue */
+import Vue from 'vue';
+
(() => {
const ModalStore = gl.issueBoards.ModalStore;
diff --git a/app/assets/javascripts/boards/components/sidebar/remove_issue.js b/app/assets/javascripts/boards/components/sidebar/remove_issue.js
index e74935e1cb0..d8322b34d44 100644
--- a/app/assets/javascripts/boards/components/sidebar/remove_issue.js
+++ b/app/assets/javascripts/boards/components/sidebar/remove_issue.js
@@ -1,6 +1,8 @@
/* eslint-disable no-new */
-/* global Vue */
/* global Flash */
+
+import Vue from 'vue';
+
(() => {
const Store = gl.issueBoards.BoardsStore;
diff --git a/app/assets/javascripts/boards/filters/due_date_filters.js b/app/assets/javascripts/boards/filters/due_date_filters.js
index 03425bb145b..70132dbfa6f 100644
--- a/app/assets/javascripts/boards/filters/due_date_filters.js
+++ b/app/assets/javascripts/boards/filters/due_date_filters.js
@@ -1,6 +1,7 @@
-/* global Vue */
/* global dateFormat */
+import Vue from 'vue';
+
Vue.filter('due-date', (value) => {
const date = new Date(value);
return dateFormat(date, 'mmm d, yyyy', true);
diff --git a/app/assets/javascripts/boards/models/issue.js b/app/assets/javascripts/boards/models/issue.js
index ca5e6fa7e9d..d6175069e37 100644
--- a/app/assets/javascripts/boards/models/issue.js
+++ b/app/assets/javascripts/boards/models/issue.js
@@ -1,9 +1,10 @@
/* eslint-disable no-unused-vars, space-before-function-paren, arrow-body-style, arrow-parens, comma-dangle, max-len */
-/* global Vue */
/* global ListLabel */
/* global ListMilestone */
/* global ListUser */
+import Vue from 'vue';
+
class ListIssue {
constructor (obj) {
this.globalId = obj.id;
diff --git a/app/assets/javascripts/boards/services/board_service.js b/app/assets/javascripts/boards/services/board_service.js
index e54102814d6..db9bced2f89 100644
--- a/app/assets/javascripts/boards/services/board_service.js
+++ b/app/assets/javascripts/boards/services/board_service.js
@@ -1,5 +1,6 @@
/* eslint-disable space-before-function-paren, comma-dangle, no-param-reassign, camelcase, max-len, no-unused-vars */
-/* global Vue */
+
+import Vue from 'vue';
class BoardService {
constructor (root, bulkUpdatePath, boardId) {
diff --git a/app/assets/javascripts/boards/stores/boards_store.js b/app/assets/javascripts/boards/stores/boards_store.js
index 28ecb322df7..8912f234aa6 100644
--- a/app/assets/javascripts/boards/stores/boards_store.js
+++ b/app/assets/javascripts/boards/stores/boards_store.js
@@ -1,7 +1,8 @@
/* eslint-disable comma-dangle, space-before-function-paren, one-var, no-shadow, dot-notation, max-len */
-/* global Cookies */
/* global List */
+import Cookies from 'js-cookie';
+
(() => {
window.gl = window.gl || {};
window.gl.issueBoards = window.gl.issueBoards || {};
diff --git a/app/assets/javascripts/commit/pipelines/pipelines_bundle.js b/app/assets/javascripts/commit/pipelines/pipelines_bundle.js
index a9f2d462c31..a92e068ca5a 100644
--- a/app/assets/javascripts/commit/pipelines/pipelines_bundle.js
+++ b/app/assets/javascripts/commit/pipelines/pipelines_bundle.js
@@ -1,8 +1,10 @@
/* eslint-disable no-param-reassign */
+
+import Vue from 'vue';
+import VueResource from 'vue-resource';
import CommitPipelinesTable from './pipelines_table';
-window.Vue = require('vue');
-window.Vue.use(require('vue-resource'));
+Vue.use(VueResource);
/**
* Commits View > Pipelines Tab > Pipelines Table.
diff --git a/app/assets/javascripts/cycle_analytics/components/stage_code_component.js b/app/assets/javascripts/cycle_analytics/components/stage_code_component.js
index b83a4c63fad..9947f355aca 100644
--- a/app/assets/javascripts/cycle_analytics/components/stage_code_component.js
+++ b/app/assets/javascripts/cycle_analytics/components/stage_code_component.js
@@ -1,5 +1,6 @@
/* eslint-disable no-param-reassign */
-/* global Vue */
+
+import Vue from 'vue';
((global) => {
global.cycleAnalytics = global.cycleAnalytics || {};
diff --git a/app/assets/javascripts/cycle_analytics/components/stage_issue_component.js b/app/assets/javascripts/cycle_analytics/components/stage_issue_component.js
index cb1687dcc7a..6ad4805e8c5 100644
--- a/app/assets/javascripts/cycle_analytics/components/stage_issue_component.js
+++ b/app/assets/javascripts/cycle_analytics/components/stage_issue_component.js
@@ -1,5 +1,6 @@
/* eslint-disable no-param-reassign */
-/* global Vue */
+
+import Vue from 'vue';
((global) => {
global.cycleAnalytics = global.cycleAnalytics || {};
diff --git a/app/assets/javascripts/cycle_analytics/components/stage_production_component.js b/app/assets/javascripts/cycle_analytics/components/stage_production_component.js
index 73f4205b578..da80450a32c 100644
--- a/app/assets/javascripts/cycle_analytics/components/stage_production_component.js
+++ b/app/assets/javascripts/cycle_analytics/components/stage_production_component.js
@@ -1,5 +1,6 @@
/* eslint-disable no-param-reassign */
-/* global Vue */
+
+import Vue from 'vue';
((global) => {
global.cycleAnalytics = global.cycleAnalytics || {};
diff --git a/app/assets/javascripts/cycle_analytics/components/stage_review_component.js b/app/assets/javascripts/cycle_analytics/components/stage_review_component.js
index 501ffb1fac9..2200f43914f 100644
--- a/app/assets/javascripts/cycle_analytics/components/stage_review_component.js
+++ b/app/assets/javascripts/cycle_analytics/components/stage_review_component.js
@@ -1,5 +1,6 @@
/* eslint-disable no-param-reassign */
-/* global Vue */
+
+import Vue from 'vue';
((global) => {
global.cycleAnalytics = global.cycleAnalytics || {};
diff --git a/app/assets/javascripts/cycle_analytics/components/total_time_component.js b/app/assets/javascripts/cycle_analytics/components/total_time_component.js
index 0d85e1a4678..b4442ea5566 100644
--- a/app/assets/javascripts/cycle_analytics/components/total_time_component.js
+++ b/app/assets/javascripts/cycle_analytics/components/total_time_component.js
@@ -1,5 +1,6 @@
/* eslint-disable no-param-reassign */
-/* global Vue */
+
+import Vue from 'vue';
((global) => {
global.cycleAnalytics = global.cycleAnalytics || {};
diff --git a/app/assets/javascripts/cycle_analytics/cycle_analytics_bundle.js b/app/assets/javascripts/cycle_analytics/cycle_analytics_bundle.js
index beff293b587..ae17d05e679 100644
--- a/app/assets/javascripts/cycle_analytics/cycle_analytics_bundle.js
+++ b/app/assets/javascripts/cycle_analytics/cycle_analytics_bundle.js
@@ -1,9 +1,8 @@
-/* global Vue */
-/* global Cookies */
/* global Flash */
-window.Vue = require('vue');
-window.Cookies = require('js-cookie');
+import Vue from 'vue';
+import Cookies from 'js-cookie';
+
require('./components/stage_code_component');
require('./components/stage_issue_component');
require('./components/stage_plan_component');
diff --git a/app/assets/javascripts/diff_notes/components/comment_resolve_btn.js b/app/assets/javascripts/diff_notes/components/comment_resolve_btn.js
index d948dff58ec..fc2f20e3bcb 100644
--- a/app/assets/javascripts/diff_notes/components/comment_resolve_btn.js
+++ b/app/assets/javascripts/diff_notes/components/comment_resolve_btn.js
@@ -1,6 +1,7 @@
/* eslint-disable comma-dangle, object-shorthand, func-names, no-else-return, quotes, no-lonely-if, max-len */
/* global CommentsStore */
-const Vue = require('vue');
+
+import Vue from 'vue';
(() => {
const CommentAndResolveBtn = Vue.extend({
diff --git a/app/assets/javascripts/diff_notes/components/diff_note_avatars.js b/app/assets/javascripts/diff_notes/components/diff_note_avatars.js
index dd7081aefb7..0297add94d5 100644
--- a/app/assets/javascripts/diff_notes/components/diff_note_avatars.js
+++ b/app/assets/javascripts/diff_notes/components/diff_note_avatars.js
@@ -1,4 +1,6 @@
-/* global CommentsStore Cookies notes */
+/* global CommentsStore */
+/* global notes */
+
import Vue from 'vue';
import collapseIcon from '../icons/collapse_icon.svg';
diff --git a/app/assets/javascripts/diff_notes/components/jump_to_discussion.js b/app/assets/javascripts/diff_notes/components/jump_to_discussion.js
index 283dc330cad..8edc45130fc 100644
--- a/app/assets/javascripts/diff_notes/components/jump_to_discussion.js
+++ b/app/assets/javascripts/diff_notes/components/jump_to_discussion.js
@@ -1,7 +1,8 @@
/* eslint-disable comma-dangle, object-shorthand, func-names, no-else-return, guard-for-in, no-restricted-syntax, one-var, space-before-function-paren, no-lonely-if, no-continue, brace-style, max-len, quotes */
/* global DiscussionMixins */
/* global CommentsStore */
-const Vue = require('vue');
+
+import Vue from 'vue';
(() => {
const JumpToDiscussion = Vue.extend({
diff --git a/app/assets/javascripts/diff_notes/components/new_issue_for_discussion.js b/app/assets/javascripts/diff_notes/components/new_issue_for_discussion.js
index e86bef47172..8eb0e10b832 100644
--- a/app/assets/javascripts/diff_notes/components/new_issue_for_discussion.js
+++ b/app/assets/javascripts/diff_notes/components/new_issue_for_discussion.js
@@ -1,6 +1,7 @@
-/* global Vue */
/* global CommentsStore */
+import Vue from 'vue';
+
(() => {
const NewIssueForDiscussion = Vue.extend({
props: {
diff --git a/app/assets/javascripts/diff_notes/components/resolve_btn.js b/app/assets/javascripts/diff_notes/components/resolve_btn.js
index fbd980f0fce..312f38ce241 100644
--- a/app/assets/javascripts/diff_notes/components/resolve_btn.js
+++ b/app/assets/javascripts/diff_notes/components/resolve_btn.js
@@ -2,7 +2,8 @@
/* global CommentsStore */
/* global ResolveService */
/* global Flash */
-const Vue = require('vue');
+
+import Vue from 'vue';
(() => {
const ResolveBtn = Vue.extend({
diff --git a/app/assets/javascripts/diff_notes/components/resolve_count.js b/app/assets/javascripts/diff_notes/components/resolve_count.js
index de9367f2136..27147ac6b5c 100644
--- a/app/assets/javascripts/diff_notes/components/resolve_count.js
+++ b/app/assets/javascripts/diff_notes/components/resolve_count.js
@@ -1,7 +1,8 @@
/* eslint-disable comma-dangle, object-shorthand, func-names, no-param-reassign */
/* global DiscussionMixins */
/* global CommentsStore */
-const Vue = require('vue');
+
+import Vue from 'vue';
((w) => {
w.ResolveCount = Vue.extend({
diff --git a/app/assets/javascripts/diff_notes/components/resolve_discussion_btn.js b/app/assets/javascripts/diff_notes/components/resolve_discussion_btn.js
index 7c5fcd04d2d..a964b7d0c6b 100644
--- a/app/assets/javascripts/diff_notes/components/resolve_discussion_btn.js
+++ b/app/assets/javascripts/diff_notes/components/resolve_discussion_btn.js
@@ -2,7 +2,7 @@
/* global CommentsStore */
/* global ResolveService */
-const Vue = require('vue');
+import Vue from 'vue';
(() => {
const ResolveDiscussionBtn = Vue.extend({
diff --git a/app/assets/javascripts/diff_notes/diff_notes_bundle.js b/app/assets/javascripts/diff_notes/diff_notes_bundle.js
index 4f6b86a917c..b6b47e2da6f 100644
--- a/app/assets/javascripts/diff_notes/diff_notes_bundle.js
+++ b/app/assets/javascripts/diff_notes/diff_notes_bundle.js
@@ -1,8 +1,8 @@
/* eslint-disable func-names, comma-dangle, new-cap, no-new, max-len */
-/* global Vue */
/* global ResolveCount */
-const Vue = require('vue');
+import Vue from 'vue';
+
require('./models/discussion');
require('./models/note');
require('./stores/comments');
diff --git a/app/assets/javascripts/diff_notes/models/discussion.js b/app/assets/javascripts/diff_notes/models/discussion.js
index dce1a9b58bd..dc43e4b2cc7 100644
--- a/app/assets/javascripts/diff_notes/models/discussion.js
+++ b/app/assets/javascripts/diff_notes/models/discussion.js
@@ -1,7 +1,8 @@
/* eslint-disable space-before-function-paren, camelcase, guard-for-in, no-restricted-syntax, no-unused-vars, max-len */
-/* global Vue */
/* global NoteModel */
+import Vue from 'vue';
+
class DiscussionModel {
constructor (discussionId) {
this.id = discussionId;
diff --git a/app/assets/javascripts/diff_notes/services/resolve.js b/app/assets/javascripts/diff_notes/services/resolve.js
index 090c454e9e4..bfa4fc9037a 100644
--- a/app/assets/javascripts/diff_notes/services/resolve.js
+++ b/app/assets/javascripts/diff_notes/services/resolve.js
@@ -2,10 +2,13 @@
/* global Flash */
/* global CommentsStore */
-const Vue = window.Vue = require('vue');
-window.Vue.use(require('vue-resource'));
+import Vue from 'vue';
+import VueResource from 'vue-resource';
+
require('../../vue_shared/vue_resource_interceptor');
+Vue.use(VueResource);
+
(() => {
window.gl = window.gl || {};
diff --git a/app/assets/javascripts/diff_notes/stores/comments.js b/app/assets/javascripts/diff_notes/stores/comments.js
index 69c4d7a8434..e6cbda56c91 100644
--- a/app/assets/javascripts/diff_notes/stores/comments.js
+++ b/app/assets/javascripts/diff_notes/stores/comments.js
@@ -1,7 +1,8 @@
/* eslint-disable object-shorthand, func-names, camelcase, no-restricted-syntax, guard-for-in, comma-dangle, max-len, no-param-reassign */
-/* global Vue */
/* global DiscussionModel */
+import Vue from 'vue';
+
((w) => {
w.CommentsStore = {
state: {},
diff --git a/app/assets/javascripts/dispatcher.js b/app/assets/javascripts/dispatcher.js
index 3557f6f617e..d1a662459e1 100644
--- a/app/assets/javascripts/dispatcher.js
+++ b/app/assets/javascripts/dispatcher.js
@@ -41,9 +41,9 @@ import GroupsList from './groups_list';
import ProjectsList from './projects_list';
import MiniPipelineGraph from './mini_pipeline_graph_dropdown';
import BlobLinePermalinkUpdater from './blob/blob_line_permalink_updater';
+import UserCallout from './user_callout';
const ShortcutsBlob = require('./shortcuts_blob');
-const UserCallout = require('./user_callout');
(function() {
var Dispatcher;
diff --git a/app/assets/javascripts/filtered_search/filtered_search_manager.js b/app/assets/javascripts/filtered_search/filtered_search_manager.js
index c6bb7fda8f2..22352950452 100644
--- a/app/assets/javascripts/filtered_search/filtered_search_manager.js
+++ b/app/assets/javascripts/filtered_search/filtered_search_manager.js
@@ -384,7 +384,7 @@ import FilteredSearchContainer from './container';
paths.push(`search=${sanitized}`);
}
- const parameterizedUrl = `?scope=all&utf8=✓&${paths.join('&')}`;
+ const parameterizedUrl = `?scope=all&utf8=%E2%9C%93&${paths.join('&')}`;
if (this.updateObject) {
this.updateObject(parameterizedUrl);
diff --git a/app/assets/javascripts/issuable/time_tracking/components/collapsed_state.js b/app/assets/javascripts/issuable/time_tracking/components/collapsed_state.js
index 357b3487ca9..aec13e78f42 100644
--- a/app/assets/javascripts/issuable/time_tracking/components/collapsed_state.js
+++ b/app/assets/javascripts/issuable/time_tracking/components/collapsed_state.js
@@ -1,4 +1,4 @@
-/* global Vue */
+import Vue from 'vue';
import stopwatchSvg from 'icons/_icon_stopwatch.svg';
require('../../../lib/utils/pretty_time');
diff --git a/app/assets/javascripts/issuable/time_tracking/components/comparison_pane.js b/app/assets/javascripts/issuable/time_tracking/components/comparison_pane.js
index 750468c679b..c55e263f6f4 100644
--- a/app/assets/javascripts/issuable/time_tracking/components/comparison_pane.js
+++ b/app/assets/javascripts/issuable/time_tracking/components/comparison_pane.js
@@ -1,4 +1,5 @@
-/* global Vue */
+import Vue from 'vue';
+
require('../../../lib/utils/pretty_time');
(() => {
diff --git a/app/assets/javascripts/issuable/time_tracking/components/estimate_only_pane.js b/app/assets/javascripts/issuable/time_tracking/components/estimate_only_pane.js
index 309e9f2f9ef..a7fbd704c40 100644
--- a/app/assets/javascripts/issuable/time_tracking/components/estimate_only_pane.js
+++ b/app/assets/javascripts/issuable/time_tracking/components/estimate_only_pane.js
@@ -1,4 +1,5 @@
-/* global Vue */
+import Vue from 'vue';
+
(() => {
Vue.component('time-tracking-estimate-only-pane', {
name: 'time-tracking-estimate-only-pane',
diff --git a/app/assets/javascripts/issuable/time_tracking/components/help_state.js b/app/assets/javascripts/issuable/time_tracking/components/help_state.js
index d7ced6d7151..344b29ebea4 100644
--- a/app/assets/javascripts/issuable/time_tracking/components/help_state.js
+++ b/app/assets/javascripts/issuable/time_tracking/components/help_state.js
@@ -1,4 +1,5 @@
-/* global Vue */
+import Vue from 'vue';
+
(() => {
Vue.component('time-tracking-help-state', {
name: 'time-tracking-help-state',
diff --git a/app/assets/javascripts/issuable/time_tracking/components/no_tracking_pane.js b/app/assets/javascripts/issuable/time_tracking/components/no_tracking_pane.js
index 1d2ca643b5b..b081adf5e64 100644
--- a/app/assets/javascripts/issuable/time_tracking/components/no_tracking_pane.js
+++ b/app/assets/javascripts/issuable/time_tracking/components/no_tracking_pane.js
@@ -1,4 +1,5 @@
-/* global Vue */
+import Vue from 'vue';
+
(() => {
Vue.component('time-tracking-no-tracking-pane', {
name: 'time-tracking-no-tracking-pane',
diff --git a/app/assets/javascripts/issuable/time_tracking/components/spent_only_pane.js b/app/assets/javascripts/issuable/time_tracking/components/spent_only_pane.js
index ed283fec3c3..edb9169112f 100644
--- a/app/assets/javascripts/issuable/time_tracking/components/spent_only_pane.js
+++ b/app/assets/javascripts/issuable/time_tracking/components/spent_only_pane.js
@@ -1,4 +1,5 @@
-/* global Vue */
+import Vue from 'vue';
+
(() => {
Vue.component('time-tracking-spent-only-pane', {
name: 'time-tracking-spent-only-pane',
diff --git a/app/assets/javascripts/issuable/time_tracking/components/time_tracker.js b/app/assets/javascripts/issuable/time_tracking/components/time_tracker.js
index 1fae2d62b14..0213522f551 100644
--- a/app/assets/javascripts/issuable/time_tracking/components/time_tracker.js
+++ b/app/assets/javascripts/issuable/time_tracking/components/time_tracker.js
@@ -1,4 +1,4 @@
-/* global Vue */
+import Vue from 'vue';
require('./help_state');
require('./collapsed_state');
diff --git a/app/assets/javascripts/issuable/time_tracking/time_tracking_bundle.js b/app/assets/javascripts/issuable/time_tracking/time_tracking_bundle.js
index 0134b7cb6f3..1689a69e1ed 100644
--- a/app/assets/javascripts/issuable/time_tracking/time_tracking_bundle.js
+++ b/app/assets/javascripts/issuable/time_tracking/time_tracking_bundle.js
@@ -1,11 +1,12 @@
-/* global Vue */
+import Vue from 'vue';
+import VueResource from 'vue-resource';
-window.Vue = require('vue');
-window.Vue.use(require('vue-resource'));
require('./components/time_tracker');
require('../../smart_interval');
require('../../subbable_resource');
+Vue.use(VueResource);
+
(() => {
/* This Vue instance represents what will become the parent instance for the
* sidebar. It will be responsible for managing `issuable` state and propagating
diff --git a/app/assets/javascripts/issuable_context.js b/app/assets/javascripts/issuable_context.js
index 115312d4b83..834b98e8601 100644
--- a/app/assets/javascripts/issuable_context.js
+++ b/app/assets/javascripts/issuable_context.js
@@ -1,8 +1,9 @@
/* eslint-disable func-names, space-before-function-paren, wrap-iife, no-new, comma-dangle, quotes, prefer-arrow-callback, consistent-return, one-var, no-var, one-var-declaration-per-line, no-underscore-dangle, max-len */
/* global UsersSelect */
-/* global Cookies */
/* global bp */
+import Cookies from 'js-cookie';
+
(function() {
this.IssuableContext = (function() {
function IssuableContext(currentUser) {
diff --git a/app/assets/javascripts/lib/utils/poll.js b/app/assets/javascripts/lib/utils/poll.js
new file mode 100644
index 00000000000..938cf9912a8
--- /dev/null
+++ b/app/assets/javascripts/lib/utils/poll.js
@@ -0,0 +1,62 @@
+import httpStatusCodes from './http_status';
+
+/**
+ * Polling utility for handling realtime updates.
+ * Service for vue resouce and method need to be provided as props
+ *
+ * @example
+ * new poll({
+ * resource: resource,
+ * method: 'name',
+ * data: {page: 1, scope: 'all'},
+ * successCallback: () => {},
+ * errorCallback: () => {},
+ * }).makeRequest();
+ *
+ * this.service = new BoardsService(endpoint);
+ * new poll({
+ * resource: this.service,
+ * method: 'get',
+ * data: {page: 1, scope: 'all'},
+ * successCallback: () => {},
+ * errorCallback: () => {},
+ * }).makeRequest();
+ *
+ *
+ * 1. Checks for response and headers before start polling
+ * 2. Interval is provided by `Poll-Interval` header.
+ * 3. If `Poll-Interval` is -1, we stop polling
+ * 4. If HTTP response is 200, we poll.
+ * 5. If HTTP response is different from 200, we stop polling.
+ *
+ */
+export default class Poll {
+ constructor(options = {}) {
+ this.options = options;
+ this.options.data = options.data || {};
+
+ this.intervalHeader = 'POLL-INTERVAL';
+ }
+
+ checkConditions(response) {
+ const headers = gl.utils.normalizeHeaders(response.headers);
+ const pollInterval = headers[this.intervalHeader];
+
+ if (pollInterval > 0 && response.status === httpStatusCodes.OK) {
+ this.options.successCallback(response);
+ setTimeout(() => {
+ this.makeRequest();
+ }, pollInterval);
+ } else {
+ this.options.successCallback(response);
+ }
+ }
+
+ makeRequest() {
+ const { resource, method, data, errorCallback } = this.options;
+
+ return resource[method](data)
+ .then(response => this.checkConditions(response))
+ .catch(error => errorCallback(error));
+ }
+}
diff --git a/app/assets/javascripts/main.js b/app/assets/javascripts/main.js
index 81d5748191d..b1ca0dc091d 100644
--- a/app/assets/javascripts/main.js
+++ b/app/assets/javascripts/main.js
@@ -1,6 +1,5 @@
/* eslint-disable func-names, space-before-function-paren, no-var, quotes, consistent-return, prefer-arrow-callback, comma-dangle, object-shorthand, no-new, max-len, no-multi-spaces, import/newline-after-import, import/first */
/* global bp */
-/* global Cookies */
/* global Flash */
/* global ConfirmDangerModal */
/* global Aside */
@@ -24,7 +23,6 @@ import './extensions/array';
window.jQuery = jQuery;
window.$ = jQuery;
window._ = _;
-window.Cookies = Cookies;
window.Pikaday = Pikaday;
window.Dropzone = Dropzone;
window.Sortable = Sortable;
diff --git a/app/assets/javascripts/merge_conflicts/components/diff_file_editor.js b/app/assets/javascripts/merge_conflicts/components/diff_file_editor.js
index c7e78fed8fe..645045fea88 100644
--- a/app/assets/javascripts/merge_conflicts/components/diff_file_editor.js
+++ b/app/assets/javascripts/merge_conflicts/components/diff_file_editor.js
@@ -1,8 +1,9 @@
/* eslint-disable comma-dangle, quote-props, no-useless-computed-key, object-shorthand, no-new, no-param-reassign, max-len */
-/* global Vue */
/* global ace */
/* global Flash */
+import Vue from 'vue';
+
((global) => {
global.mergeConflicts = global.mergeConflicts || {};
diff --git a/app/assets/javascripts/merge_conflicts/components/inline_conflict_lines.js b/app/assets/javascripts/merge_conflicts/components/inline_conflict_lines.js
index 240c8f98932..56d6678e1bd 100644
--- a/app/assets/javascripts/merge_conflicts/components/inline_conflict_lines.js
+++ b/app/assets/javascripts/merge_conflicts/components/inline_conflict_lines.js
@@ -1,5 +1,6 @@
/* eslint-disable no-param-reassign, comma-dangle */
-/* global Vue */
+
+import Vue from 'vue';
((global) => {
global.mergeConflicts = global.mergeConflicts || {};
diff --git a/app/assets/javascripts/merge_conflicts/components/parallel_conflict_lines.js b/app/assets/javascripts/merge_conflicts/components/parallel_conflict_lines.js
index 97753c50b60..0fc4a13450a 100644
--- a/app/assets/javascripts/merge_conflicts/components/parallel_conflict_lines.js
+++ b/app/assets/javascripts/merge_conflicts/components/parallel_conflict_lines.js
@@ -1,5 +1,6 @@
/* eslint-disable no-param-reassign, comma-dangle */
-/* global Vue */
+
+import Vue from 'vue';
((global) => {
global.mergeConflicts = global.mergeConflicts || {};
diff --git a/app/assets/javascripts/merge_conflicts/merge_conflict_store.js b/app/assets/javascripts/merge_conflicts/merge_conflict_store.js
index 74587df22c5..c4e379a4a0b 100644
--- a/app/assets/javascripts/merge_conflicts/merge_conflict_store.js
+++ b/app/assets/javascripts/merge_conflicts/merge_conflict_store.js
@@ -1,6 +1,7 @@
/* eslint-disable comma-dangle, object-shorthand, no-param-reassign, camelcase, no-nested-ternary, no-continue, max-len */
-/* global Cookies */
-/* global Vue */
+
+import Vue from 'vue';
+import Cookies from 'js-cookie';
((global) => {
global.mergeConflicts = global.mergeConflicts || {};
diff --git a/app/assets/javascripts/merge_conflicts/merge_conflicts_bundle.js b/app/assets/javascripts/merge_conflicts/merge_conflicts_bundle.js
index 653e52fb6bf..15992460146 100644
--- a/app/assets/javascripts/merge_conflicts/merge_conflicts_bundle.js
+++ b/app/assets/javascripts/merge_conflicts/merge_conflicts_bundle.js
@@ -1,8 +1,8 @@
/* eslint-disable new-cap, comma-dangle, no-new */
-/* global Vue */
/* global Flash */
-window.Vue = require('vue');
+import Vue from 'vue';
+
require('./merge_conflict_store');
require('./merge_conflict_service');
require('./mixins/line_conflict_utils');
diff --git a/app/assets/javascripts/merge_request_tabs.js b/app/assets/javascripts/merge_request_tabs.js
index 190336dbd20..d9692269c38 100644
--- a/app/assets/javascripts/merge_request_tabs.js
+++ b/app/assets/javascripts/merge_request_tabs.js
@@ -1,10 +1,10 @@
/* eslint-disable no-new, class-methods-use-this */
/* global Breakpoints */
-/* global Cookies */
/* global Flash */
+import Cookies from 'js-cookie';
+
require('./breakpoints');
-window.Cookies = require('js-cookie');
require('./flash');
/* eslint-disable max-len */
diff --git a/app/assets/javascripts/milestone_select.js b/app/assets/javascripts/milestone_select.js
index 40e977df693..ac4fad88fe5 100644
--- a/app/assets/javascripts/milestone_select.js
+++ b/app/assets/javascripts/milestone_select.js
@@ -1,8 +1,9 @@
/* eslint-disable func-names, space-before-function-paren, wrap-iife, no-var, no-underscore-dangle, prefer-arrow-callback, max-len, one-var, one-var-declaration-per-line, no-unused-vars, object-shorthand, comma-dangle, no-else-return, no-self-compare, consistent-return, no-param-reassign, no-shadow */
-/* global Vue */
/* global Issuable */
/* global ListMilestone */
+import Vue from 'vue';
+
(function() {
this.MilestoneSelect = (function() {
function MilestoneSelect(currentProject, els) {
diff --git a/app/assets/javascripts/monitoring/prometheus_graph.js b/app/assets/javascripts/monitoring/prometheus_graph.js
index fcffc11a2df..844a0785bc9 100644
--- a/app/assets/javascripts/monitoring/prometheus_graph.js
+++ b/app/assets/javascripts/monitoring/prometheus_graph.js
@@ -1,4 +1,4 @@
-/* eslint-disable no-new */
+/* eslint-disable no-new*/
/* global Flash */
import d3 from 'd3';
@@ -180,7 +180,7 @@ class PrometheusGraph {
// Metric Usage
axisLabelContainer.append('rect')
.attr('x', this.originalWidth - 170)
- .attr('y', (this.originalHeight / 2) - 80)
+ .attr('y', (this.originalHeight / 2) - 60)
.style('fill', graphSpecifics.area_fill_color)
.attr('width', 20)
.attr('height', 35);
@@ -188,13 +188,13 @@ class PrometheusGraph {
axisLabelContainer.append('text')
.attr('class', 'label-axis-text')
.attr('x', this.originalWidth - 140)
- .attr('y', (this.originalHeight / 2) - 65)
- .text(graphSpecifics.graph_legend_title);
+ .attr('y', (this.originalHeight / 2) - 50)
+ .text('Average');
axisLabelContainer.append('text')
.attr('class', 'text-metric-usage')
.attr('x', this.originalWidth - 140)
- .attr('y', (this.originalHeight / 2) - 50);
+ .attr('y', (this.originalHeight / 2) - 25);
}
handleMouseOverGraph(x, y, valuesToPlot, chart, prometheusGraphContainer, key) {
@@ -263,12 +263,12 @@ class PrometheusGraph {
cpu_values: {
area_fill_color: '#edf3fc',
line_color: '#5b99f7',
- graph_legend_title: 'CPU Usage (Cores)',
+ graph_legend_title: 'CPU utilization (%)',
},
memory_values: {
area_fill_color: '#fca326',
line_color: '#fc6d26',
- graph_legend_title: 'Memory Usage (MB)',
+ graph_legend_title: 'Memory usage (MB)',
},
};
diff --git a/app/assets/javascripts/notes.js b/app/assets/javascripts/notes.js
index 47cc34e7a20..1d563c63f39 100644
--- a/app/assets/javascripts/notes.js
+++ b/app/assets/javascripts/notes.js
@@ -1,14 +1,14 @@
/* eslint-disable no-restricted-properties, func-names, space-before-function-paren, no-var, prefer-rest-params, wrap-iife, no-use-before-define, camelcase, no-unused-expressions, quotes, max-len, one-var, one-var-declaration-per-line, default-case, prefer-template, consistent-return, no-alert, no-return-assign, no-param-reassign, prefer-arrow-callback, no-else-return, comma-dangle, no-new, brace-style, no-lonely-if, vars-on-top, no-unused-vars, no-sequences, no-shadow, newline-per-chained-call, no-useless-escape */
/* global Flash */
/* global Autosave */
-/* global Cookies */
/* global ResolveService */
/* global mrRefreshWidgetUrl */
+import Cookies from 'js-cookie';
+
require('./autosave');
window.autosize = require('vendor/autosize');
window.Dropzone = require('dropzone');
-window.Cookies = require('js-cookie');
require('./dropzone_input');
require('./gfm_auto_complete');
require('vendor/jquery.caret'); // required by jquery.atwho
diff --git a/app/assets/javascripts/project.js b/app/assets/javascripts/project.js
index db7ceaa2421..f944fcc5a58 100644
--- a/app/assets/javascripts/project.js
+++ b/app/assets/javascripts/project.js
@@ -1,7 +1,8 @@
/* eslint-disable func-names, space-before-function-paren, wrap-iife, no-var, quotes, consistent-return, no-new, prefer-arrow-callback, no-return-assign, one-var, one-var-declaration-per-line, object-shorthand, comma-dangle, no-else-return, newline-per-chained-call, no-shadow, vars-on-top, prefer-template, max-len */
-/* global Cookies */
/* global ProjectSelect */
+import Cookies from 'js-cookie';
+
(function() {
this.Project = (function() {
function Project() {
diff --git a/app/assets/javascripts/render_gfm.js b/app/assets/javascripts/render_gfm.js
index 48cae8a4fa9..ea91aaa10a6 100644
--- a/app/assets/javascripts/render_gfm.js
+++ b/app/assets/javascripts/render_gfm.js
@@ -1,4 +1,5 @@
-/* eslint-disable func-names, space-before-function-paren, consistent-return, no-var, no-undef, no-else-return, prefer-arrow-callback, max-len */
+/* eslint-disable func-names, space-before-function-paren, consistent-return, no-var, no-else-return, prefer-arrow-callback, max-len */
+
// Render Gitlab flavoured Markdown
//
// Delegates to syntax highlight and render math
diff --git a/app/assets/javascripts/render_math.js b/app/assets/javascripts/render_math.js
index 76c61c001ba..8b3fee49cb9 100644
--- a/app/assets/javascripts/render_math.js
+++ b/app/assets/javascripts/render_math.js
@@ -1,4 +1,6 @@
-/* eslint-disable func-names, space-before-function-paren, consistent-return, no-var, no-undef, no-else-return, prefer-arrow-callback, max-len, no-console */
+/* eslint-disable func-names, space-before-function-paren, consistent-return, no-var, no-else-return, prefer-arrow-callback, max-len, no-console */
+/* global katex */
+
// Renders math using KaTeX in any element with the
// `js-render-math` class
//
diff --git a/app/assets/javascripts/right_sidebar.js b/app/assets/javascripts/right_sidebar.js
index 903862cac6b..7298a7d5347 100644
--- a/app/assets/javascripts/right_sidebar.js
+++ b/app/assets/javascripts/right_sidebar.js
@@ -1,5 +1,6 @@
/* eslint-disable func-names, space-before-function-paren, no-var, prefer-rest-params, wrap-iife, no-unused-vars, consistent-return, one-var, one-var-declaration-per-line, quotes, prefer-template, object-shorthand, comma-dangle, no-else-return, no-param-reassign, max-len */
-/* global Cookies */
+
+import Cookies from 'js-cookie';
(function() {
var bind = function(fn, me) { return function() { return fn.apply(me, arguments); }; };
diff --git a/app/assets/javascripts/shortcuts.js b/app/assets/javascripts/shortcuts.js
index 81766f4bd55..fd5097696ad 100644
--- a/app/assets/javascripts/shortcuts.js
+++ b/app/assets/javascripts/shortcuts.js
@@ -33,6 +33,10 @@
};
Shortcuts.prototype.toggleMarkdownPreview = function(e) {
+ // Check if short-cut was triggered while in Write Mode
+ if ($(e.target).hasClass('js-note-text')) {
+ $('.js-md-preview-button').focus();
+ }
return $(document).triggerHandler('markdown-preview:toggle', [e]);
};
diff --git a/app/assets/javascripts/shortcuts_dashboard_navigation.js b/app/assets/javascripts/shortcuts_dashboard_navigation.js
index e7baea894f6..4f1a19924a4 100644
--- a/app/assets/javascripts/shortcuts_dashboard_navigation.js
+++ b/app/assets/javascripts/shortcuts_dashboard_navigation.js
@@ -22,6 +22,9 @@ require('./shortcuts');
Mousetrap.bind('g m', function() {
return ShortcutsDashboardNavigation.findAndFollowLink('.dashboard-shortcuts-merge_requests');
});
+ Mousetrap.bind('g t', function() {
+ return ShortcutsDashboardNavigation.findAndFollowLink('.shortcuts-todos');
+ });
Mousetrap.bind('g p', function() {
return ShortcutsDashboardNavigation.findAndFollowLink('.dashboard-shortcuts-projects');
});
diff --git a/app/assets/javascripts/shortcuts_navigation.js b/app/assets/javascripts/shortcuts_navigation.js
index 09a58cad2b2..3f5d6724417 100644
--- a/app/assets/javascripts/shortcuts_navigation.js
+++ b/app/assets/javascripts/shortcuts_navigation.js
@@ -43,6 +43,9 @@ require('./shortcuts');
Mousetrap.bind('g m', function() {
return ShortcutsNavigation.findAndFollowLink('.shortcuts-merge_requests');
});
+ Mousetrap.bind('g t', function() {
+ return ShortcutsNavigation.findAndFollowLink('.shortcuts-todos');
+ });
Mousetrap.bind('g w', function() {
return ShortcutsNavigation.findAndFollowLink('.shortcuts-wiki');
});
diff --git a/app/assets/javascripts/subscription.js b/app/assets/javascripts/subscription.js
index 62d1604fe9e..9c307915ec4 100644
--- a/app/assets/javascripts/subscription.js
+++ b/app/assets/javascripts/subscription.js
@@ -1,4 +1,4 @@
-/* global Vue */
+import Vue from 'vue';
(() => {
class Subscription {
diff --git a/app/assets/javascripts/user.js b/app/assets/javascripts/user.js
index 059e6c628b3..19c9efe7fbd 100644
--- a/app/assets/javascripts/user.js
+++ b/app/assets/javascripts/user.js
@@ -1,5 +1,6 @@
/* eslint-disable class-methods-use-this, comma-dangle, arrow-parens, no-param-reassign */
-/* global Cookies */
+
+import Cookies from 'js-cookie';
((global) => {
global.User = class {
diff --git a/app/assets/javascripts/user_callout.js b/app/assets/javascripts/user_callout.js
index 99419e85b20..b27d252a3ef 100644
--- a/app/assets/javascripts/user_callout.js
+++ b/app/assets/javascripts/user_callout.js
@@ -1,4 +1,4 @@
-/* global Cookies */
+import Cookies from 'js-cookie';
const userCalloutElementName = '.user-callout';
const closeButton = '.close-user-callout';
@@ -27,7 +27,7 @@ const USER_CALLOUT_TEMPLATE = `
</div>
</div>`;
-class UserCallout {
+export default class UserCallout {
constructor() {
this.isCalloutDismissed = Cookies.get(USER_CALLOUT_COOKIE);
this.userCalloutBody = $(userCalloutElementName);
@@ -56,5 +56,3 @@ class UserCallout {
}
}
}
-
-module.exports = UserCallout;
diff --git a/app/assets/javascripts/user_tabs.js b/app/assets/javascripts/user_tabs.js
index 465618e3d53..5db0d936ad8 100644
--- a/app/assets/javascripts/user_tabs.js
+++ b/app/assets/javascripts/user_tabs.js
@@ -1,4 +1,4 @@
-/* eslint-disable max-len, space-before-function-paren, no-underscore-dangle, consistent-return, comma-dangle, no-unused-vars, dot-notation, no-new, no-return-assign, camelcase, no-param-reassign */
+/* eslint-disable max-len, space-before-function-paren, no-underscore-dangle, consistent-return, comma-dangle, no-unused-vars, dot-notation, no-new, no-return-assign, camelcase, no-param-reassign, class-methods-use-this */
/*
UserTabs
@@ -82,8 +82,19 @@ content on the Users#show page.
}
bindEvents() {
- return this.$parentEl.off('shown.bs.tab', '.nav-links a[data-toggle="tab"]')
+ this.changeProjectsPageWrapper = this.changeProjectsPage.bind(this);
+
+ this.$parentEl.off('shown.bs.tab', '.nav-links a[data-toggle="tab"]')
.on('shown.bs.tab', '.nav-links a[data-toggle="tab"]', event => this.tabShown(event));
+
+ this.$parentEl.on('click', '.gl-pagination a', this.changeProjectsPageWrapper);
+ }
+
+ changeProjectsPage(e) {
+ e.preventDefault();
+
+ $('.tab-pane.active').empty();
+ this.loadTab($(e.target).attr('href'), this.getCurrentAction());
}
tabShown(event) {
@@ -119,7 +130,7 @@ content on the Users#show page.
complete: () => this.toggleLoading(false),
dataType: 'json',
type: 'GET',
- url: `${source}.json`,
+ url: source,
success: (data) => {
const tabSelector = `div#${action}`;
this.$parentEl.find(tabSelector).html(data.html);
@@ -153,6 +164,10 @@ content on the Users#show page.
}, document.title, new_state);
return new_state;
}
+
+ getCurrentAction() {
+ return this.$parentEl.find('.nav-links .active a').data('action');
+ }
}
global.UserTabs = UserTabs;
})(window.gl || (window.gl = {}));
diff --git a/app/assets/javascripts/users_select.js b/app/assets/javascripts/users_select.js
index eb897e9dfe9..48e20cf501f 100644
--- a/app/assets/javascripts/users_select.js
+++ b/app/assets/javascripts/users_select.js
@@ -1,8 +1,9 @@
/* eslint-disable func-names, space-before-function-paren, one-var, no-var, prefer-rest-params, wrap-iife, quotes, max-len, one-var-declaration-per-line, vars-on-top, prefer-arrow-callback, consistent-return, comma-dangle, object-shorthand, no-shadow, no-unused-vars, no-else-return, no-self-compare, prefer-template, no-unused-expressions, no-lonely-if, yoda, prefer-spread, no-void, camelcase, no-param-reassign */
-/* global Vue */
/* global Issuable */
/* global ListUser */
+import Vue from 'vue';
+
(function() {
var bind = function(fn, me) { return function() { return fn.apply(me, arguments); }; },
slice = [].slice;
diff --git a/app/assets/javascripts/vue_pipelines_index/index.js b/app/assets/javascripts/vue_pipelines_index/index.js
index b4e2d3a1143..104154a715b 100644
--- a/app/assets/javascripts/vue_pipelines_index/index.js
+++ b/app/assets/javascripts/vue_pipelines_index/index.js
@@ -1,10 +1,8 @@
+import Vue from 'vue';
import PipelinesStore from './stores/pipelines_store';
import PipelinesComponent from './pipelines';
import '../vue_shared/vue_resource_interceptor';
-const Vue = window.Vue = require('vue');
-window.Vue.use(require('vue-resource'));
-
$(() => new Vue({
el: document.querySelector('.vue-pipelines-index'),
diff --git a/app/assets/javascripts/vue_shared/common_vue.js b/app/assets/javascripts/vue_shared/common_vue.js
new file mode 100644
index 00000000000..eb2a6071fda
--- /dev/null
+++ b/app/assets/javascripts/vue_shared/common_vue.js
@@ -0,0 +1,6 @@
+import Vue from 'vue';
+import './vue_resource_interceptor';
+
+if (process.env.NODE_ENV !== 'production') {
+ Vue.config.productionTip = false;
+}
diff --git a/app/assets/javascripts/vue_shared/vue_resource_interceptor.js b/app/assets/javascripts/vue_shared/vue_resource_interceptor.js
index f1c1e553b16..d5f87588c28 100644
--- a/app/assets/javascripts/vue_shared/vue_resource_interceptor.js
+++ b/app/assets/javascripts/vue_shared/vue_resource_interceptor.js
@@ -1,20 +1,23 @@
-/* eslint-disable no-param-reassign, no-plusplus */
import Vue from 'vue';
import VueResource from 'vue-resource';
Vue.use(VueResource);
+// Maintain a global counter for active requests
+// see: spec/support/wait_for_vue_resource.rb
Vue.http.interceptors.push((request, next) => {
- Vue.activeResources = Vue.activeResources ? Vue.activeResources + 1 : 1;
+ window.activeVueResources = window.activeVueResources || 0;
+ window.activeVueResources += 1;
next(() => {
- Vue.activeResources--;
+ window.activeVueResources -= 1;
});
});
+// Inject CSRF token so we don't break any tests.
Vue.http.interceptors.push((request, next) => {
- // needed in order to not break the tests.
if ($.rails) {
+ // eslint-disable-next-line no-param-reassign
request.headers['X-CSRF-Token'] = $.rails.csrfToken();
}
next();
diff --git a/app/assets/stylesheets/framework/awards.scss b/app/assets/stylesheets/framework/awards.scss
index 546718ddaf8..1ae144fb471 100644
--- a/app/assets/stylesheets/framework/awards.scss
+++ b/app/assets/stylesheets/framework/awards.scss
@@ -92,6 +92,10 @@
.award-menu-holder {
display: inline-block;
position: relative;
+
+ .tooltip {
+ white-space: nowrap;
+ }
}
.award-control {
@@ -124,6 +128,10 @@
&:focus {
outline: 0;
}
+
+ .award-control-icon {
+ margin: 0;
+ }
}
&.is-loading {
@@ -153,6 +161,7 @@
.award-control-icon {
color: $border-gray-normal;
margin-top: 1px;
+ padding: 0 2px;
}
.award-control-text {
diff --git a/app/assets/stylesheets/framework/layout.scss b/app/assets/stylesheets/framework/layout.scss
index 0a42b17c1f5..4d5a2ca52f0 100644
--- a/app/assets/stylesheets/framework/layout.scss
+++ b/app/assets/stylesheets/framework/layout.scss
@@ -23,6 +23,10 @@ body {
}
}
+.content-wrapper {
+ padding-bottom: 100px;
+}
+
.container {
padding-top: 0;
z-index: 5;
diff --git a/app/assets/stylesheets/framework/variables.scss b/app/assets/stylesheets/framework/variables.scss
index 6841adb637e..82c9c76c4c0 100644
--- a/app/assets/stylesheets/framework/variables.scss
+++ b/app/assets/stylesheets/framework/variables.scss
@@ -44,7 +44,7 @@ $orange-light: #fc8a51;
$orange-normal: darken($orange-light, $darken-normal-factor);
$orange-dark: darken($orange-light, $darken-dark-factor);
-$red-light: #e52c5a;
+$red-light: #eb4d5c;
$red-normal: darken($red-light, $darken-normal-factor);
$red-dark: darken($red-light, $darken-dark-factor);
@@ -84,7 +84,6 @@ $warning-message-border: #f0e2bb;
*/
$border-color: #e5e5e5;
$focus-border-color: #3aabf0;
-$sidebar-collapsed-icon-color: #999;
$well-expand-item: #e8f2f7;
$well-inner-border: #eef0f2;
$well-light-border: #f1f1f1;
diff --git a/app/assets/stylesheets/pages/issuable.scss b/app/assets/stylesheets/pages/issuable.scss
index 4426169ef5a..ddc0e78c7b6 100644
--- a/app/assets/stylesheets/pages/issuable.scss
+++ b/app/assets/stylesheets/pages/issuable.scss
@@ -498,7 +498,7 @@
svg {
width: 16px;
height: 16px;
- fill: $sidebar-collapsed-icon-color;
+ fill: $issuable-sidebar-color;
}
&:hover svg {
diff --git a/app/assets/stylesheets/pages/issues.scss b/app/assets/stylesheets/pages/issues.scss
index cb7ebd61504..b27741a928d 100644
--- a/app/assets/stylesheets/pages/issues.scss
+++ b/app/assets/stylesheets/pages/issues.scss
@@ -46,6 +46,10 @@ ul.related-merge-requests > li {
.merge-request-id {
flex-shrink: 0;
}
+
+ .merge-request-info {
+ margin-left: 5px;
+ }
}
.merge-requests-title,
@@ -58,10 +62,6 @@ ul.related-merge-requests > li {
display: inline-block;
}
-.merge-request-info {
- margin-left: 5px;
-}
-
.merge-request-status {
font-size: 13px;
padding: 0 5px;
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index b7ce081a5cd..6a6e335d314 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -64,8 +64,11 @@ class ApplicationController < ActionController::Base
# This filter handles both private tokens and personal access tokens
def authenticate_user_from_private_token!
- token_string = params[:private_token].presence || request.headers['PRIVATE-TOKEN'].presence
- user = User.find_by_authentication_token(token_string) || User.find_by_personal_access_token(token_string)
+ token = params[:private_token].presence || request.headers['PRIVATE-TOKEN'].presence
+
+ return unless token.present?
+
+ user = User.find_by_authentication_token(token) || User.find_by_personal_access_token(token)
if user && can?(user, :log_in)
# Notice we are passing store false, so the user is not
diff --git a/app/controllers/dashboard/todos_controller.rb b/app/controllers/dashboard/todos_controller.rb
index 096de8032ae..498690e8f11 100644
--- a/app/controllers/dashboard/todos_controller.rb
+++ b/app/controllers/dashboard/todos_controller.rb
@@ -51,7 +51,7 @@ class Dashboard::TodosController < Dashboard::ApplicationController
private
def find_todos
- @todos ||= TodosFinder.new(current_user, params.merge(include_associations: true)).execute
+ @todos ||= TodosFinder.new(current_user, params).execute
end
def todos_counts
diff --git a/app/controllers/import/bitbucket_controller.rb b/app/controllers/import/bitbucket_controller.rb
index 8e42cdf415f..5ad1e116e4e 100644
--- a/app/controllers/import/bitbucket_controller.rb
+++ b/app/controllers/import/bitbucket_controller.rb
@@ -44,15 +44,15 @@ class Import::BitbucketController < Import::BaseController
repo_owner = repo.owner
repo_owner = current_user.username if repo_owner == bitbucket_client.user.username
- @target_namespace = params[:new_namespace].presence || repo_owner
+ namespace_path = params[:new_namespace].presence || repo_owner
- namespace = find_or_create_namespace(@target_namespace, current_user)
+ @target_namespace = find_or_create_namespace(namespace_path, current_user)
- if current_user.can?(:create_projects, namespace)
+ if current_user.can?(:create_projects, @target_namespace)
# The token in a session can be expired, we need to get most recent one because
# Bitbucket::Connection class refreshes it.
session[:bitbucket_token] = bitbucket_client.connection.token
- @project = Gitlab::BitbucketImport::ProjectCreator.new(repo, @project_name, namespace, current_user, credentials).execute
+ @project = Gitlab::BitbucketImport::ProjectCreator.new(repo, @project_name, @target_namespace, current_user, credentials).execute
else
render 'unauthorized'
end
diff --git a/app/controllers/projects/application_controller.rb b/app/controllers/projects/application_controller.rb
index e2f81b09adc..f1a93ccb3ad 100644
--- a/app/controllers/projects/application_controller.rb
+++ b/app/controllers/projects/application_controller.rb
@@ -89,4 +89,9 @@ class Projects::ApplicationController < ApplicationController
def builds_enabled
return render_404 unless @project.feature_available?(:builds, current_user)
end
+
+ def update_ref
+ branch_exists = @repository.find_branch(@target_branch)
+ @ref = @target_branch if branch_exists
+ end
end
diff --git a/app/controllers/projects/blob_controller.rb b/app/controllers/projects/blob_controller.rb
index 52fc67d162c..80a95c6158b 100644
--- a/app/controllers/projects/blob_controller.rb
+++ b/app/controllers/projects/blob_controller.rb
@@ -89,11 +89,6 @@ class Projects::BlobController < Projects::ApplicationController
private
- def update_ref
- branch_exists = @repository.find_branch(@target_branch)
- @ref = @target_branch if branch_exists
- end
-
def blob
@blob ||= Blob.decorate(@repository.blob_at(@commit.id, @path))
diff --git a/app/controllers/projects/deploy_keys_controller.rb b/app/controllers/projects/deploy_keys_controller.rb
index 1502b734f37..d0c44e297e3 100644
--- a/app/controllers/projects/deploy_keys_controller.rb
+++ b/app/controllers/projects/deploy_keys_controller.rb
@@ -31,8 +31,10 @@ class Projects::DeployKeysController < Projects::ApplicationController
end
def disable
- @project.deploy_keys_projects.find_by(deploy_key_id: params[:id]).destroy
+ deploy_key_project = @project.deploy_keys_projects.find_by(deploy_key_id: params[:id])
+ return render_404 unless deploy_key_project
+ deploy_key_project.destroy!
redirect_to_repository_settings(@project)
end
diff --git a/app/controllers/projects/issues_controller.rb b/app/controllers/projects/issues_controller.rb
index cdb5b4173d3..0d6d9f492c1 100644
--- a/app/controllers/projects/issues_controller.rb
+++ b/app/controllers/projects/issues_controller.rb
@@ -148,7 +148,14 @@ class Projects::IssuesController < Projects::ApplicationController
end
format.json do
- render json: @issue.to_json(include: { milestone: {}, assignee: { only: [:name, :username], methods: [:avatar_url] }, labels: { methods: :text_color } }, methods: [:task_status, :task_status_short])
+ if @issue.valid?
+ render json: @issue.to_json(methods: [:task_status, :task_status_short],
+ include: { milestone: {},
+ assignee: { only: [:name, :username], methods: [:avatar_url] },
+ labels: { methods: :text_color } })
+ else
+ render json: { errors: @issue.errors.full_messages }, status: :unprocessable_entity
+ end
end
end
diff --git a/app/controllers/projects/settings/members_controller.rb b/app/controllers/projects/settings/members_controller.rb
index cbfa2afa959..54f9dceddef 100644
--- a/app/controllers/projects/settings/members_controller.rb
+++ b/app/controllers/projects/settings/members_controller.rb
@@ -9,6 +9,7 @@ module Projects
@skip_groups = @group_links.pluck(:group_id)
@skip_groups << @project.namespace_id unless @project.personal?
+ @skip_groups += @project.group.ancestors.pluck(:id) if @project.group
@project_members = MembersFinder.new(@project, current_user).execute
diff --git a/app/controllers/projects/tree_controller.rb b/app/controllers/projects/tree_controller.rb
index 4f094146348..637b61504d8 100644
--- a/app/controllers/projects/tree_controller.rb
+++ b/app/controllers/projects/tree_controller.rb
@@ -34,6 +34,7 @@ class Projects::TreeController < Projects::ApplicationController
def create_dir
return render_404 unless @commit_params.values.all?
+ update_ref
create_commit(Files::CreateDirService, success_notice: "The directory has been successfully created.",
success_path: namespace_project_tree_path(@project.namespace, @project, File.join(@target_branch, @dir_name)),
failure_path: namespace_project_tree_path(@project.namespace, @project, @ref))
diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb
index 6e29f1e8a65..2683614d2e8 100644
--- a/app/controllers/users_controller.rb
+++ b/app/controllers/users_controller.rb
@@ -39,7 +39,7 @@ class UsersController < ApplicationController
format.html { render 'show' }
format.json do
render json: {
- html: view_to_html_string("shared/projects/_list", projects: @projects, remote: true)
+ html: view_to_html_string("shared/projects/_list", projects: @projects)
}
end
end
@@ -65,7 +65,7 @@ class UsersController < ApplicationController
format.html { render 'show' }
format.json do
render json: {
- html: view_to_html_string("snippets/_snippets", collection: @snippets, remote: true)
+ html: view_to_html_string("snippets/_snippets", collection: @snippets)
}
end
end
diff --git a/app/finders/todos_finder.rb b/app/finders/todos_finder.rb
index 13d33a1c31b..b7f091f334d 100644
--- a/app/finders/todos_finder.rb
+++ b/app/finders/todos_finder.rb
@@ -24,7 +24,6 @@ class TodosFinder
def execute
items = current_user.todos
- items = include_associations(items)
items = by_action_id(items)
items = by_action(items)
items = by_author(items)
@@ -39,17 +38,6 @@ class TodosFinder
private
- def include_associations(items)
- return items unless params[:include_associations]
-
- items.includes(
- [
- target: { project: [:route, namespace: :route] },
- author: { namespace: :route },
- ]
- )
- end
-
def action_id?
action_id.present? && Todo::ACTION_NAMES.has_key?(action_id.to_i)
end
diff --git a/app/helpers/todos_helper.rb b/app/helpers/todos_helper.rb
index 847a8fdfca6..4f5adf623f2 100644
--- a/app/helpers/todos_helper.rb
+++ b/app/helpers/todos_helper.rb
@@ -39,13 +39,9 @@ module TodosHelper
namespace_project_commit_path(todo.project.namespace.becomes(Namespace), todo.project,
todo.target, anchor: anchor)
else
- if todo.build_failed?
- # associated namespace and route would be loaded from the db again if todo.project was used
- project = todo.target.project
- path = [:pipelines, project.namespace.becomes(Namespace), project, todo.target]
- else
- path = [todo.target]
- end
+ path = [todo.project.namespace.becomes(Namespace), todo.project, todo.target]
+
+ path.unshift(:pipelines) if todo.build_failed?
polymorphic_path(path, anchor: anchor)
end
diff --git a/app/models/concerns/issuable.rb b/app/models/concerns/issuable.rb
index e7bd20b322a..4d54426b79e 100644
--- a/app/models/concerns/issuable.rb
+++ b/app/models/concerns/issuable.rb
@@ -50,6 +50,7 @@ module Issuable
:email,
:public_email,
to: :author,
+ allow_nil: true,
prefix: true
delegate :name,
diff --git a/app/models/concerns/spammable.rb b/app/models/concerns/spammable.rb
index 107e6764ba2..647a6cad3d7 100644
--- a/app/models/concerns/spammable.rb
+++ b/app/models/concerns/spammable.rb
@@ -41,7 +41,7 @@ module Spammable
def check_for_spam
error_msg = if Gitlab::Recaptcha.enabled?
"Your #{spammable_entity_type} has been recognized as spam. "\
- "You can still submit it by solving Captcha."
+ "Please, change the content or solve the reCAPTCHA to proceed."
else
"Your #{spammable_entity_type} has been recognized as spam and has been discarded."
end
diff --git a/app/models/group.rb b/app/models/group.rb
index bd0ecae3da4..60274386103 100644
--- a/app/models/group.rb
+++ b/app/models/group.rb
@@ -207,7 +207,7 @@ class Group < Namespace
end
def members_with_parents
- GroupMember.non_request.where(source_id: ancestors.map(&:id).push(id))
+ GroupMember.non_request.where(source_id: ancestors.pluck(:id).push(id))
end
def users_with_parents
diff --git a/app/models/issue.rb b/app/models/issue.rb
index 602eed86d9e..10a5d9d2a24 100644
--- a/app/models/issue.rb
+++ b/app/models/issue.rb
@@ -211,9 +211,8 @@ class Issue < ActiveRecord::Base
due_date.try(:past?) || false
end
- # Only issues on public projects should be checked for spam
def check_for_spam?
- project.public?
+ project.public? && (title_changed? || description_changed?)
end
def as_json(options = {})
diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb
index cef8ad76b07..4759829a15c 100644
--- a/app/models/merge_request.rb
+++ b/app/models/merge_request.rb
@@ -7,7 +7,6 @@ class MergeRequest < ActiveRecord::Base
belongs_to :target_project, class_name: "Project"
belongs_to :source_project, class_name: "Project"
- belongs_to :project, foreign_key: :target_project_id
belongs_to :merge_user, class_name: "User"
has_many :merge_request_diffs, dependent: :destroy
@@ -541,6 +540,10 @@ class MergeRequest < ActiveRecord::Base
target_project != source_project
end
+ def project
+ target_project
+ end
+
# If the merge request closes any issues, save this information in the
# `MergeRequestsClosingIssues` model. This is a performance optimization.
# Calculating this information for a number of merge requests requires
diff --git a/app/models/namespace.rb b/app/models/namespace.rb
index d350f1d6770..826ded22ae5 100644
--- a/app/models/namespace.rb
+++ b/app/models/namespace.rb
@@ -195,7 +195,7 @@ class Namespace < ActiveRecord::Base
# Scopes the model on direct and indirect children of the record
def descendants
- self.class.joins(:route).where('routes.path LIKE ?', "#{route.path}/%").reorder('routes.path ASC')
+ self.class.joins(:route).merge(Route.inside_path(route.path)).reorder('routes.path ASC')
end
def user_ids_for_project_authorizations
diff --git a/app/models/project.rb b/app/models/project.rb
index da4704554b3..04641dd58a0 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -238,7 +238,7 @@ class Project < ActiveRecord::Base
# We need routes alias rs for JOIN so it does not conflict with
# includes(:route) which we use in ProjectsFinder.
joins("INNER JOIN routes rs ON rs.source_id = projects.id AND rs.source_type = 'Project'").
- where('rs.path LIKE ?', "#{path}/%")
+ where('rs.path LIKE ?', "#{sanitize_sql_like(path)}/%")
end
# "enabled" here means "not disabled". It includes private features!
diff --git a/app/models/project_services/chat_notification_service.rb b/app/models/project_services/chat_notification_service.rb
index 200be99f36b..75834103db5 100644
--- a/app/models/project_services/chat_notification_service.rb
+++ b/app/models/project_services/chat_notification_service.rb
@@ -6,7 +6,7 @@ class ChatNotificationService < Service
default_value_for :category, 'chat'
prop_accessor :webhook, :username, :channel
- boolean_accessor :notify_only_broken_pipelines
+ boolean_accessor :notify_only_broken_pipelines, :notify_only_default_branch
validates :webhook, presence: true, url: true, if: :activated?
@@ -17,6 +17,7 @@ class ChatNotificationService < Service
if properties.nil?
self.properties = {}
self.notify_only_broken_pipelines = true
+ self.notify_only_default_branch = true
end
end
@@ -29,6 +30,19 @@ class ChatNotificationService < Service
pipeline wiki_page]
end
+ def fields
+ default_fields + build_event_channels
+ end
+
+ def default_fields
+ [
+ { type: 'text', name: 'webhook', placeholder: "e.g. #{webhook_placeholder}" },
+ { type: 'text', name: 'username', placeholder: 'e.g. GitLab' },
+ { type: 'checkbox', name: 'notify_only_broken_pipelines' },
+ { type: 'checkbox', name: 'notify_only_default_branch' },
+ ]
+ end
+
def execute(data)
return unless supported_events.include?(data[:object_kind])
return unless webhook.present?
@@ -123,6 +137,17 @@ class ChatNotificationService < Service
end
def should_pipeline_be_notified?(data)
+ notify_for_ref?(data) && notify_for_pipeline?(data)
+ end
+
+ def notify_for_ref?(data)
+ return true if data[:object_attributes][:tag]
+ return true unless notify_only_default_branch
+
+ data[:object_attributes][:ref] == project.default_branch
+ end
+
+ def notify_for_pipeline?(data)
case data[:object_attributes][:status]
when 'success'
!notify_only_broken_pipelines?
diff --git a/app/models/project_services/mattermost_service.rb b/app/models/project_services/mattermost_service.rb
index 1156d050622..0362ed172c7 100644
--- a/app/models/project_services/mattermost_service.rb
+++ b/app/models/project_services/mattermost_service.rb
@@ -22,19 +22,11 @@ class MattermostService < ChatNotificationService
</ol>'
end
- def fields
- default_fields + build_event_channels
- end
-
- def default_fields
- [
- { type: 'text', name: 'webhook', placeholder: 'e.g. http://mattermost_host/hooks/…' },
- { type: 'text', name: 'username', placeholder: 'e.g. GitLab' },
- { type: 'checkbox', name: 'notify_only_broken_pipelines' },
- ]
- end
-
def default_channel_placeholder
"Channel handle (e.g. town-square)"
end
+
+ def webhook_placeholder
+ 'http://mattermost.example.com/hooks/…'
+ end
end
diff --git a/app/models/project_services/prometheus_service.rb b/app/models/project_services/prometheus_service.rb
index 4d7c81a721f..5cff9a42484 100644
--- a/app/models/project_services/prometheus_service.rb
+++ b/app/models/project_services/prometheus_service.rb
@@ -74,16 +74,16 @@ class PrometheusService < MonitoringService
def calculate_reactive_cache(environment_slug)
return unless active? && project && !project.pending_delete?
- memory_query = %{sum(container_memory_usage_bytes{container_name="app",environment="#{environment_slug}"})/1024/1024}
- cpu_query = %{sum(rate(container_cpu_usage_seconds_total{container_name="app",environment="#{environment_slug}"}[2m]))}
+ memory_query = %{(sum(container_memory_usage_bytes{container_name="app",environment="#{environment_slug}"}) / count(container_memory_usage_bytes{container_name="app",environment="#{environment_slug}"})) /1024/1024}
+ cpu_query = %{sum(rate(container_cpu_usage_seconds_total{container_name="app",environment="#{environment_slug}"}[2m])) / count(container_cpu_usage_seconds_total{container_name="app",environment="#{environment_slug}"}) * 100}
{
success: true,
metrics: {
- # Memory used in MB
+ # Average Memory used in MB
memory_values: client.query_range(memory_query, start: 8.hours.ago),
memory_current: client.query(memory_query),
- # CPU Usage rate in cores.
+ # Average CPU Utilization
cpu_values: client.query_range(cpu_query, start: 8.hours.ago),
cpu_current: client.query(cpu_query)
},
diff --git a/app/models/project_services/slack_service.rb b/app/models/project_services/slack_service.rb
index b657db6f9ee..71da0af75f6 100644
--- a/app/models/project_services/slack_service.rb
+++ b/app/models/project_services/slack_service.rb
@@ -21,19 +21,11 @@ class SlackService < ChatNotificationService
</ol>'
end
- def fields
- default_fields + build_event_channels
- end
-
- def default_fields
- [
- { type: 'text', name: 'webhook', placeholder: 'e.g. https://hooks.slack.com/services/…' },
- { type: 'text', name: 'username', placeholder: 'e.g. GitLab' },
- { type: 'checkbox', name: 'notify_only_broken_pipelines' },
- ]
- end
-
def default_channel_placeholder
"Channel name (e.g. general)"
end
+
+ def webhook_placeholder
+ 'https://hooks.slack.com/services/…'
+ end
end
diff --git a/app/models/route.rb b/app/models/route.rb
index 41e6eb7cb73..4b3efab5c3c 100644
--- a/app/models/route.rb
+++ b/app/models/route.rb
@@ -10,9 +10,11 @@ class Route < ActiveRecord::Base
after_update :rename_descendants
+ scope :inside_path, -> (path) { where('routes.path LIKE ?', "#{sanitize_sql_like(path)}/%") }
+
def rename_descendants
if path_changed? || name_changed?
- descendants = Route.where('path LIKE ?', "#{path_was}/%")
+ descendants = self.class.inside_path(path_was)
descendants.each do |route|
attributes = {}
diff --git a/app/models/snippet.rb b/app/models/snippet.rb
index dbd564e5e7d..30aca62499c 100644
--- a/app/models/snippet.rb
+++ b/app/models/snippet.rb
@@ -132,7 +132,8 @@ class Snippet < ActiveRecord::Base
end
def check_for_spam?
- public?
+ visibility_level_changed?(to: Snippet::PUBLIC) ||
+ (public? && (title_changed? || content_changed?))
end
def spammable_entity_type
diff --git a/app/models/user.rb b/app/models/user.rb
index 8c7ad5d5174..5d19d873f43 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -324,6 +324,8 @@ class User < ActiveRecord::Base
end
def find_by_personal_access_token(token_string)
+ return unless token_string
+
PersonalAccessTokensFinder.new(state: 'active').find_by(token: token_string)&.user
end
diff --git a/app/services/boards/issues/list_service.rb b/app/services/boards/issues/list_service.rb
index 83f51947bd4..cb6d30396ec 100644
--- a/app/services/boards/issues/list_service.rb
+++ b/app/services/boards/issues/list_service.rb
@@ -3,7 +3,7 @@ module Boards
class ListService < BaseService
def execute
issues = IssuesFinder.new(current_user, filter_params).execute
- issues = without_board_labels(issues) unless movable_list?
+ issues = without_board_labels(issues) unless list
issues = with_list_label(issues) if movable_list?
issues.order_by_position_and_priority
end
diff --git a/app/services/spam_check_service.rb b/app/services/spam_check_service.rb
index 023e0824e85..11030bee8f1 100644
--- a/app/services/spam_check_service.rb
+++ b/app/services/spam_check_service.rb
@@ -14,6 +14,9 @@ module SpamCheckService
@spam_log_id = params.delete(:spam_log_id)
end
+ # In order to be proceed to the spam check process, @spammable has to be
+ # a dirty instance, which means it should be already assigned with the new
+ # attribute values.
def spam_check(spammable, user)
spam_service = SpamService.new(spammable, @request)
diff --git a/app/views/admin/dashboard/index.html.haml b/app/views/admin/dashboard/index.html.haml
index e67ad663720..ebca9beb035 100644
--- a/app/views/admin/dashboard/index.html.haml
+++ b/app/views/admin/dashboard/index.html.haml
@@ -43,28 +43,34 @@
%h4
Features
%hr
- %p
- Sign up
+ - sign_up = "Sign up"
+ %p{ "aria-label" => "#{sign_up}: status " + (signup_enabled? ? "on" : "off") }
+ = sign_up
%span.light.pull-right
= boolean_to_icon signup_enabled?
- %p
- LDAP
+ - ldap = "LDAP"
+ %p{ "aria-label" => "#{ldap}: status " + (Gitlab.config.ldap.enabled ? "on" : "off") }
+ = ldap
%span.light.pull-right
= boolean_to_icon Gitlab.config.ldap.enabled
- %p
- Gravatar
+ - gravatar = "Gravatar"
+ %p{ "aria-label" => "#{gravatar}: status " + (gravatar_enabled? ? "on" : "off") }
+ = gravatar
%span.light.pull-right
= boolean_to_icon gravatar_enabled?
- %p
- OmniAuth
+ - omniauth = "OmniAuth"
+ %p{ "aria-label" => "#{omniauth}: status " + (Gitlab.config.omniauth.enabled ? "on" : "off") }
+ = omniauth
%span.light.pull-right
= boolean_to_icon Gitlab.config.omniauth.enabled
- %p
- Reply by email
+ - reply_email = "Reply by email"
+ %p{ "aria-label" => "#{reply_email}: status " + (Gitlab::IncomingEmail.enabled? ? "on" : "off") }
+ = reply_email
%span.light.pull-right
= boolean_to_icon Gitlab::IncomingEmail.enabled?
- %p
- Container Registry
+ - container_reg = "Container Registry"
+ %p{ "aria-label" => "#{container_reg}: status " + (Gitlab.config.registry.enabled ? "on" : "off") }
+ = container_reg
%span.light.pull-right
= boolean_to_icon Gitlab.config.registry.enabled
diff --git a/app/views/award_emoji/_awards_block.html.haml b/app/views/award_emoji/_awards_block.html.haml
index a1ef34dc588..5aae410a63f 100644
--- a/app/views/award_emoji/_awards_block.html.haml
+++ b/app/views/award_emoji/_awards_block.html.haml
@@ -10,8 +10,8 @@
- if current_user
.award-menu-holder.js-award-holder
- %button.btn.award-control.js-add-award{ type: "button" }
+ %button.btn.award-control.has-tooltip.js-add-award{ type: 'button',
+ 'aria-label': 'Add emoji',
+ data: { title: 'Add emoji', placement: "bottom" } }
= icon('smile-o', class: "award-control-icon award-control-icon-normal")
= icon('spinner spin', class: "award-control-icon award-control-icon-loading")
- %span.award-control-text
- Add
diff --git a/app/views/ci/status/_graph_badge.html.haml b/app/views/ci/status/_graph_badge.html.haml
index 0530d21a7e2..128b418090f 100644
--- a/app/views/ci/status/_graph_badge.html.haml
+++ b/app/views/ci/status/_graph_badge.html.haml
@@ -6,7 +6,7 @@
- tooltip = "#{subject.name} - #{status.label}"
- if status.has_details?
- = link_to status.details_path, class: 'build-content has-tooltip', data: { toggle: 'tooltip', title: tooltip } do
+ = link_to status.details_path, class: 'build-content has-tooltip', data: { toggle: 'tooltip', title: tooltip, container: 'body' } do
%span{ class: klass }= custom_icon(status.icon)
.ci-status-text= subject.name
- else
@@ -15,6 +15,6 @@
.ci-status-text= subject.name
- if status.has_action?
- = link_to status.action_path, class: 'ci-action-icon-container has-tooltip', method: status.action_method, data: { toggle: 'tooltip', title: status.action_title } do
+ = link_to status.action_path, class: 'ci-action-icon-container has-tooltip', method: status.action_method, data: { toggle: 'tooltip', title: status.action_title, container: 'body' } do
%i.ci-action-icon-wrapper{ class: "js-#{status.action_icon.dasherize}" }
= custom_icon(status.action_icon)
diff --git a/app/views/dashboard/todos/index.html.haml b/app/views/dashboard/todos/index.html.haml
index d31ced004a0..e31fa5fbe95 100644
--- a/app/views/dashboard/todos/index.html.haml
+++ b/app/views/dashboard/todos/index.html.haml
@@ -19,12 +19,13 @@
.nav-controls
- if @todos.any?(&:pending?)
- = link_to destroy_all_dashboard_todos_path(todos_filter_params), class: 'btn btn-loading js-todos-mark-all', method: :delete, data: { href: destroy_all_dashboard_todos_path(todos_filter_params) } do
- Mark all as done
- = icon('spinner spin')
- = link_to bulk_restore_dashboard_todos_path, class: 'btn btn-loading js-todos-undo-all hidden', method: :patch , data: { href: bulk_restore_dashboard_todos_path(todos_filter_params) } do
- Undo mark all as done
- = icon('spinner spin')
+ .append-right-default
+ = link_to destroy_all_dashboard_todos_path(todos_filter_params), class: 'btn btn-loading js-todos-mark-all', method: :delete, data: { href: destroy_all_dashboard_todos_path(todos_filter_params) } do
+ Mark all as done
+ = icon('spinner spin')
+ = link_to bulk_restore_dashboard_todos_path, class: 'btn btn-loading js-todos-undo-all hidden', method: :patch , data: { href: bulk_restore_dashboard_todos_path(todos_filter_params) } do
+ Undo mark all as done
+ = icon('spinner spin')
.todos-filters
.row-content-block.second-block
diff --git a/app/views/help/_shortcuts.html.haml b/app/views/help/_shortcuts.html.haml
index 2684f16c373..8e6da3fad90 100644
--- a/app/views/help/_shortcuts.html.haml
+++ b/app/views/help/_shortcuts.html.haml
@@ -118,6 +118,12 @@
.key m
%td
Go to merge requests
+ %tr
+ %td.shortcut
+ .key g
+ .key t
+ %td
+ Go to todos
%tbody
%tr
%th
diff --git a/app/views/layouts/header/_default.html.haml b/app/views/layouts/header/_default.html.haml
index 5fde5c2613e..7ddee0e5244 100644
--- a/app/views/layouts/header/_default.html.haml
+++ b/app/views/layouts/header/_default.html.haml
@@ -32,7 +32,7 @@
= link_to admin_root_path, title: 'Admin Area', aria: { label: "Admin Area" }, data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
= icon('wrench fw')
%li
- = link_to dashboard_todos_path, title: 'Todos', aria: { label: "Todos" }, data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
+ = link_to dashboard_todos_path, title: 'Todos', aria: { label: "Todos" }, class: 'shortcuts-todos', data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
= icon('bell fw')
%span.badge.todos-pending-count{ class: ("hidden" if todos_pending_count == 0) }
= todos_count_format(todos_pending_count)
diff --git a/app/views/profiles/preferences/show.html.haml b/app/views/profiles/preferences/show.html.haml
index df0a0212f3d..99690e6b98a 100644
--- a/app/views/profiles/preferences/show.html.haml
+++ b/app/views/profiles/preferences/show.html.haml
@@ -6,7 +6,9 @@
%h4.prepend-top-0
Syntax highlighting theme
%p
- This setting allow you to customize the appearance of the syntax.
+ This setting allows you to customize the appearance of the syntax.
+ = succeed '.' do
+ = link_to 'Learn more', help_page_path('user/profile/preferences', anchor: 'syntax-highlighting-theme'), target: '_blank'
.col-lg-9.syntax-theme
- Gitlab::ColorSchemes.each do |scheme|
= label_tag do
@@ -20,6 +22,8 @@
Behavior
%p
This setting allows you to customize the behavior of the system layout and default views.
+ = succeed '.' do
+ = link_to 'Learn more', help_page_path('user/profile/preferences', anchor: 'behavior'), target: '_blank'
.col-lg-9
.form-group
= f.label :layout, class: 'label-light' do
@@ -29,13 +33,11 @@
Choose between fixed (max. 1200px) and fluid (100%) application layout.
.form-group
= f.label :dashboard, class: 'label-light' do
- Default Dashboard
- = link_to('(?)', help_page_path('profile/preferences') + '#default-dashboard', target: '_blank')
+ Default dashboard
= f.select :dashboard, dashboard_choices, {}, class: 'form-control'
.form-group
= f.label :project_view, class: 'label-light' do
Project view
- = link_to('(?)', help_page_path('profile/preferences') + '#default-project-view', target: '_blank')
= f.select :project_view, project_view_choices, {}, class: 'form-control'
.help-block
Choose what content you want to see on a project's home page.
diff --git a/app/views/projects/edit.html.haml b/app/views/projects/edit.html.haml
index 2802a4eca7b..82e0d0025ec 100644
--- a/app/views/projects/edit.html.haml
+++ b/app/views/projects/edit.html.haml
@@ -31,7 +31,7 @@
= f.select(:default_branch, @project.repository.branch_names, {}, {class: 'select2 select-wide'})
.form-group
= f.label :tag_list, "Tags", class: 'label-light'
- = f.text_field :tag_list, value: @project.tag_list.to_s, maxlength: 2000, class: "form-control"
+ = f.text_field :tag_list, value: @project.tag_list.sort.join(', '), maxlength: 2000, class: "form-control"
%p.help-block Separate tags with commas.
%hr
%fieldset
diff --git a/app/views/projects/environments/metrics.html.haml b/app/views/projects/environments/metrics.html.haml
index b8c1782f050..3b45162df52 100644
--- a/app/views/projects/environments/metrics.html.haml
+++ b/app/views/projects/environments/metrics.html.haml
@@ -18,7 +18,11 @@
= render 'projects/deployments/actions', deployment: @environment.last_deployment
.row
.col-sm-12
+ %h4
+ CPU utilization
%svg.prometheus-graph{ 'graph-type' => 'cpu_values' }
.row
.col-sm-12
+ %h4
+ Memory usage
%svg.prometheus-graph{ 'graph-type' => 'memory_values' }
diff --git a/app/views/projects/merge_requests/_new_compare.html.haml b/app/views/projects/merge_requests/_new_compare.html.haml
index ad14b4e583e..8d134aaac67 100644
--- a/app/views/projects/merge_requests/_new_compare.html.haml
+++ b/app/views/projects/merge_requests/_new_compare.html.haml
@@ -21,7 +21,7 @@
selected: f.object.source_project_id
.merge-request-select.dropdown
= f.hidden_field :source_branch
- = dropdown_toggle local_assigns.fetch(f.object.source_branch, "Select source branch"), { toggle: "dropdown", field_name: "#{f.object_name}[source_branch]" }, { toggle_class: "js-compare-dropdown js-source-branch" }
+ = dropdown_toggle f.object.source_branch || "Select source branch", { toggle: "dropdown", field_name: "#{f.object_name}[source_branch]" }, { toggle_class: "js-compare-dropdown js-source-branch" }
.dropdown-menu.dropdown-menu-selectable.dropdown-source-branch
= dropdown_title("Select source branch")
= dropdown_filter("Search branches")
diff --git a/app/views/projects/notes/_note.html.haml b/app/views/projects/notes/_note.html.haml
index 5552086bc50..6c0e6d48d6c 100644
--- a/app/views/projects/notes/_note.html.haml
+++ b/app/views/projects/notes/_note.html.haml
@@ -37,7 +37,7 @@
":can-resolve" => can_resolve,
":author-name" => "'#{j(note.author.name)}'",
"author-avatar" => note.author.avatar_url,
- ":note-truncated" => "'#{truncate(note.note, length: 17)}'",
+ ":note-truncated" => "'#{j(truncate(note.note, length: 17))}'",
":resolved-by" => "'#{j(note.resolved_by.try(:name))}'",
"v-show" => "#{can_resolve || note.resolved?}",
"inline-template" => true,
diff --git a/app/views/projects/services/_index.html.haml b/app/views/projects/services/_index.html.haml
index 964133504e6..86d5a0ec7b8 100644
--- a/app/views/projects/services/_index.html.haml
+++ b/app/views/projects/services/_index.html.haml
@@ -18,7 +18,7 @@
%th Last edit
- @services.sort_by(&:title).each do |service|
%tr
- %td
+ %td{ "aria-label" => "#{service.title}: status " + (service.activated? ? "on" : "off") }
= boolean_to_icon service.activated?
%td
= link_to edit_namespace_project_service_path(@project.namespace, @project, service.to_param) do
diff --git a/app/views/projects/stage/_in_stage_group.html.haml b/app/views/projects/stage/_in_stage_group.html.haml
index 9c5eb501174..671a3ef481c 100644
--- a/app/views/projects/stage/_in_stage_group.html.haml
+++ b/app/views/projects/stage/_in_stage_group.html.haml
@@ -1,5 +1,5 @@
- group_status = CommitStatus.where(id: subject).status
-%button.dropdown-menu-toggle.build-content.has-tooltip{ type: 'button', data: { toggle: 'dropdown', title: "#{name} - #{group_status}" } }
+%button.dropdown-menu-toggle.build-content.has-tooltip{ type: 'button', data: { toggle: 'dropdown', title: "#{name} - #{group_status}", container: 'body' } }
%span{ class: "ci-status-icon ci-status-icon-#{group_status}" }
= ci_icon_for_status(group_status)
%span.ci-status-text
diff --git a/bin/with_env b/bin/with_env
new file mode 100755
index 00000000000..e678fa2f0cc
--- /dev/null
+++ b/bin/with_env
@@ -0,0 +1,16 @@
+#!/bin/sh
+# Usage: with_env ENV_FILE COMMAND [ARGS...]
+#
+# This script lets you modify the environment of an executable before
+# launching it. It uses an 'env file' which must contain lines like
+# 'MY_VARIABLE="my value"'.
+#
+env_file=$1
+shift
+
+# Use set -a to export all variables defined in env_file.
+set -a
+. "${env_file}"
+set +a
+
+exec "$@"
diff --git a/changelogs/unreleased/1051-api-create-users-without-password.yml b/changelogs/unreleased/1051-api-create-users-without-password.yml
deleted file mode 100644
index 24b5a73b45c..00000000000
--- a/changelogs/unreleased/1051-api-create-users-without-password.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Optionally make users created via the API set their password
-merge_request: 8957
-author: Joost Rijneveld
diff --git a/changelogs/unreleased/12726-preserve-issues-after-deleting-users.yml b/changelogs/unreleased/12726-preserve-issues-after-deleting-users.yml
deleted file mode 100644
index 4a1a199673c..00000000000
--- a/changelogs/unreleased/12726-preserve-issues-after-deleting-users.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Deleting a user doesn't delete issues they've created/are assigned to
-merge_request: 7393
-author:
diff --git a/changelogs/unreleased/1363-redo-mailroom-support.yml b/changelogs/unreleased/1363-redo-mailroom-support.yml
deleted file mode 100644
index 8ed206f4fdb..00000000000
--- a/changelogs/unreleased/1363-redo-mailroom-support.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Redo internals of Incoming Mail Support
-merge_request: 9385
-author:
diff --git a/changelogs/unreleased/1381-present-commits-pagination-headers-correctly.yml b/changelogs/unreleased/1381-present-commits-pagination-headers-correctly.yml
deleted file mode 100644
index 1b7e294bd67..00000000000
--- a/changelogs/unreleased/1381-present-commits-pagination-headers-correctly.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: "GET 'projects/:id/repository/commits' endpoint improvements"
-merge_request: 9679
-author: George Andrinopoulos, Jordan Ryan Reuter
diff --git a/changelogs/unreleased/14492-change-fork-endpoint.yml b/changelogs/unreleased/14492-change-fork-endpoint.yml
deleted file mode 100644
index 39024b51b54..00000000000
--- a/changelogs/unreleased/14492-change-fork-endpoint.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Move /projects/fork/:id to /projects/:id/fork
-merge_request: 8940
-author:
diff --git a/changelogs/unreleased/14748-runner-version-in-admin-views.yml b/changelogs/unreleased/14748-runner-version-in-admin-views.yml
deleted file mode 100644
index 2478a81c824..00000000000
--- a/changelogs/unreleased/14748-runner-version-in-admin-views.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Add runner version to /admin/runners view
-merge_request: 8733
-author: Jonathon Reinhart
diff --git a/changelogs/unreleased/1648-remove-remnants-of-git-annex-from-ce.yml b/changelogs/unreleased/1648-remove-remnants-of-git-annex-from-ce.yml
deleted file mode 100644
index f247fe35439..00000000000
--- a/changelogs/unreleased/1648-remove-remnants-of-git-annex-from-ce.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Remove remnants of git annex support.
-merge_request:
-author:
diff --git a/changelogs/unreleased/18962-update-issues-button-jumps.yml b/changelogs/unreleased/18962-update-issues-button-jumps.yml
deleted file mode 100644
index 7be136ac4ff..00000000000
--- a/changelogs/unreleased/18962-update-issues-button-jumps.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Align bulk update issues button to the right
-merge_request:
-author:
diff --git a/changelogs/unreleased/19302-wiki-page-delete-does-not-trigger-the-webhook.yml b/changelogs/unreleased/19302-wiki-page-delete-does-not-trigger-the-webhook.yml
deleted file mode 100644
index d74057dca8a..00000000000
--- a/changelogs/unreleased/19302-wiki-page-delete-does-not-trigger-the-webhook.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Execute web hooks for WikiPage delete operation
-merge_request: 8198
-author:
diff --git a/changelogs/unreleased/1937-https-clone-url-username.yml b/changelogs/unreleased/1937-https-clone-url-username.yml
deleted file mode 100644
index fa89d94e0f3..00000000000
--- a/changelogs/unreleased/1937-https-clone-url-username.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Add the Username to the HTTP(S) clone URL of a Repository
-merge_request: 9347
-author: Jan Christophersen
diff --git a/changelogs/unreleased/19497-hide-relevant-info-when-project-issues-are-disabled.yml b/changelogs/unreleased/19497-hide-relevant-info-when-project-issues-are-disabled.yml
deleted file mode 100644
index eceb2b9fac6..00000000000
--- a/changelogs/unreleased/19497-hide-relevant-info-when-project-issues-are-disabled.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Hide issue info when project issues are disabled
-merge_request:
-author: George Andrinopoulos
diff --git a/changelogs/unreleased/20495-plus-icon-button.yml b/changelogs/unreleased/20495-plus-icon-button.yml
deleted file mode 100644
index 0f8650eb7b6..00000000000
--- a/changelogs/unreleased/20495-plus-icon-button.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Remove plus icon from MR button on compare view
-merge_request:
-author:
diff --git a/changelogs/unreleased/20732_member_exists_409.yml b/changelogs/unreleased/20732_member_exists_409.yml
deleted file mode 100644
index 135647c7ac3..00000000000
--- a/changelogs/unreleased/20732_member_exists_409.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: 'Add member: Always return 409 when a member exists'
-merge_request:
-author:
diff --git a/changelogs/unreleased/21240_snippets_line_ending.yml b/changelogs/unreleased/21240_snippets_line_ending.yml
deleted file mode 100644
index 880fdd2c9ed..00000000000
--- a/changelogs/unreleased/21240_snippets_line_ending.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Download snippets with LF line-endings by default
-merge_request: 8999
-author:
diff --git a/changelogs/unreleased/21605-allow-html5-details.yml b/changelogs/unreleased/21605-allow-html5-details.yml
deleted file mode 100644
index b0c654783d9..00000000000
--- a/changelogs/unreleased/21605-allow-html5-details.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: SanitizationFilter allows html5 details and summary tags
-merge_request: 6568
-author:
diff --git a/changelogs/unreleased/22018-api-milestone-merge-requests.yml b/changelogs/unreleased/22018-api-milestone-merge-requests.yml
deleted file mode 100644
index ccad2ec838c..00000000000
--- a/changelogs/unreleased/22018-api-milestone-merge-requests.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Adds API endpoint to fetch all merge request for a single milestone
-merge_request:
-author: Joren De Groof
diff --git a/changelogs/unreleased/22132-rename-branch-name-params-to-branch.yml b/changelogs/unreleased/22132-rename-branch-name-params-to-branch.yml
deleted file mode 100644
index 028923b83cf..00000000000
--- a/changelogs/unreleased/22132-rename-branch-name-params-to-branch.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Standardize branch name params as branch on V4 API
-merge_request: 8936
-author:
diff --git a/changelogs/unreleased/22466-task-list-alignment.yml b/changelogs/unreleased/22466-task-list-alignment.yml
deleted file mode 100644
index 6e6ccb873ec..00000000000
--- a/changelogs/unreleased/22466-task-list-alignment.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Align task list checkboxes
-merge_request: 6487
-author: Jared Deckard <jared.deckard@gmail.com>
diff --git a/changelogs/unreleased/22562-todos-filters.yml b/changelogs/unreleased/22562-todos-filters.yml
deleted file mode 100644
index 9cca138744a..00000000000
--- a/changelogs/unreleased/22562-todos-filters.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Fix Sort dropdown reflow issue
-merge_request: 9533
-author: Jarkko Tuunanen
diff --git a/changelogs/unreleased/22645-add-discussion-contribs-to-calendar.yml b/changelogs/unreleased/22645-add-discussion-contribs-to-calendar.yml
deleted file mode 100644
index 9b3c2bd9278..00000000000
--- a/changelogs/unreleased/22645-add-discussion-contribs-to-calendar.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Add discussion events to contributions calendar
-merge_request: 8821
-author:
diff --git a/changelogs/unreleased/22818-licence-gitignore-and-yml-endpoints-removal.yml b/changelogs/unreleased/22818-licence-gitignore-and-yml-endpoints-removal.yml
deleted file mode 100644
index 05d5993ddf3..00000000000
--- a/changelogs/unreleased/22818-licence-gitignore-and-yml-endpoints-removal.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: V3 deprecated templates endpoints removal
-merge_request: 8853
-author:
diff --git a/changelogs/unreleased/22951-fix-todos-api-endpoint-error-for-commits.yml b/changelogs/unreleased/22951-fix-todos-api-endpoint-error-for-commits.yml
deleted file mode 100644
index a53e7d77c16..00000000000
--- a/changelogs/unreleased/22951-fix-todos-api-endpoint-error-for-commits.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Add spec for todo with target_type Commit
-merge_request: 9351
-author: George Andrinopoulos
diff --git a/changelogs/unreleased/23061-consolidate-project-lists.yml b/changelogs/unreleased/23061-consolidate-project-lists.yml
deleted file mode 100644
index dbb8fed55c0..00000000000
--- a/changelogs/unreleased/23061-consolidate-project-lists.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: 'API: Consolidate /projects endpoint'
-merge_request: 8962
-author:
diff --git a/changelogs/unreleased/23062-allow-git-log-to-accept-follow-and-skip.yml b/changelogs/unreleased/23062-allow-git-log-to-accept-follow-and-skip.yml
deleted file mode 100644
index f7c856040e0..00000000000
--- a/changelogs/unreleased/23062-allow-git-log-to-accept-follow-and-skip.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Make Git history follow renames again by performing the --skip in Ruby
-merge_request:
-author:
diff --git a/changelogs/unreleased/23104-remove-public-param-for-projects.yml b/changelogs/unreleased/23104-remove-public-param-for-projects.yml
deleted file mode 100644
index 78eb785279f..00000000000
--- a/changelogs/unreleased/23104-remove-public-param-for-projects.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: 'API: remove `public` param for projects'
-merge_request: 8736
-author:
diff --git a/changelogs/unreleased/23535-folders-in-wiki-repository.yml b/changelogs/unreleased/23535-folders-in-wiki-repository.yml
deleted file mode 100644
index 05212b608d4..00000000000
--- a/changelogs/unreleased/23535-folders-in-wiki-repository.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Show directory hierarchy when listing wiki pages
-merge_request: 8133
-author: Alex Braha Stoll
diff --git a/changelogs/unreleased/23819-fix-milestone-counters-to-top-right-of-panel-headings.yml b/changelogs/unreleased/23819-fix-milestone-counters-to-top-right-of-panel-headings.yml
deleted file mode 100644
index 628db8a5419..00000000000
--- a/changelogs/unreleased/23819-fix-milestone-counters-to-top-right-of-panel-headings.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Fix position of counter in milestone panels
-merge_request: 7842
-author: Andrew Smith (EspadaV8)
diff --git a/changelogs/unreleased/23948-assign-to-me.yml b/changelogs/unreleased/23948-assign-to-me.yml
deleted file mode 100644
index d73aa92b0e9..00000000000
--- a/changelogs/unreleased/23948-assign-to-me.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Re-add Assign to me link to Merge Request and Issues
-merge_request:
-author:
diff --git a/changelogs/unreleased/23993-drop-ci_projects.yml b/changelogs/unreleased/23993-drop-ci_projects.yml
deleted file mode 100644
index ee9cf774e37..00000000000
--- a/changelogs/unreleased/23993-drop-ci_projects.yml
+++ /dev/null
@@ -1,6 +0,0 @@
----
-title: Drop unused ci_projects table and some unused project_id columns,
- then rename gl_project_id to project_id. Stop exporting job trace when
- exporting projects.
-merge_request: 9378
-author: David Wagner
diff --git a/changelogs/unreleased/24215-closed-issues-board.yml b/changelogs/unreleased/24215-closed-issues-board.yml
new file mode 100644
index 00000000000..678ec34b274
--- /dev/null
+++ b/changelogs/unreleased/24215-closed-issues-board.yml
@@ -0,0 +1,4 @@
+---
+title: Display all closed issues in “done” board list
+merge_request:
+author:
diff --git a/changelogs/unreleased/24333-close-issues-with-merge-request-title-ui.yml b/changelogs/unreleased/24333-close-issues-with-merge-request-title-ui.yml
deleted file mode 100644
index fa137a29cb4..00000000000
--- a/changelogs/unreleased/24333-close-issues-with-merge-request-title-ui.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Show Issues mentioned / being closed from a Merge Requests title below the
- 'Accept Merge Request' button
-merge_request: 9194
-author: Jan Christophersen
diff --git a/changelogs/unreleased/24683-sidebar-spinners.yml b/changelogs/unreleased/24683-sidebar-spinners.yml
deleted file mode 100644
index 3fec273152f..00000000000
--- a/changelogs/unreleased/24683-sidebar-spinners.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: hide loading spinners for server-rendered sidebar fields
-merge_request:
-author:
diff --git a/changelogs/unreleased/24976-start-of-line-mention.yml b/changelogs/unreleased/24976-start-of-line-mention.yml
deleted file mode 100644
index 99208aac87c..00000000000
--- a/changelogs/unreleased/24976-start-of-line-mention.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Added a feature to create a 'directly addressed' Todo when mentioned in the beginning of a line.
-merge_request: 7926
-author: Ershad Kunnakkadan
diff --git a/changelogs/unreleased/24998-fix-typo-gitlab-config-file.yml b/changelogs/unreleased/24998-fix-typo-gitlab-config-file.yml
deleted file mode 100644
index 3b90466e3af..00000000000
--- a/changelogs/unreleased/24998-fix-typo-gitlab-config-file.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Fix typo in Gitlab config file
-merge_request: 9702
-author: medied
diff --git a/changelogs/unreleased/25367-add-impersonation-token.yml b/changelogs/unreleased/25367-add-impersonation-token.yml
deleted file mode 100644
index 4a30f960036..00000000000
--- a/changelogs/unreleased/25367-add-impersonation-token.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Manage user personal access tokens through api and add impersonation tokens
-merge_request: 9099
-author: Simon Vocella
diff --git a/changelogs/unreleased/25437-just-emoji.yml b/changelogs/unreleased/25437-just-emoji.yml
deleted file mode 100644
index ceb81a47f2d..00000000000
--- a/changelogs/unreleased/25437-just-emoji.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Introduce /award slash command; Allow posting of just an emoji in comment
-merge_request: 9382
-author: mhasbini
diff --git a/changelogs/unreleased/25465-todo-done-clicking-is-kind-of-unsafe.yml b/changelogs/unreleased/25465-todo-done-clicking-is-kind-of-unsafe.yml
deleted file mode 100644
index e9d46f6b122..00000000000
--- a/changelogs/unreleased/25465-todo-done-clicking-is-kind-of-unsafe.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Todo done clicking is kind of unusable
-merge_request: 8691
-author: Jacopo Beschi @jacopo-beschi
diff --git a/changelogs/unreleased/25503_issues_finder_performance.yml b/changelogs/unreleased/25503_issues_finder_performance.yml
deleted file mode 100644
index 87964269c6d..00000000000
--- a/changelogs/unreleased/25503_issues_finder_performance.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Filter by projects in the end of search
-merge_request: 9030
-author:
diff --git a/changelogs/unreleased/25709-diff-file-overflow.yml b/changelogs/unreleased/25709-diff-file-overflow.yml
deleted file mode 100644
index 7d1b2b36ab8..00000000000
--- a/changelogs/unreleased/25709-diff-file-overflow.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Responsive title in diffs inline, side by side, with and without sidebar
-merge_request: 8475
-author:
diff --git a/changelogs/unreleased/25920-create-issue-from-failing-build.yml b/changelogs/unreleased/25920-create-issue-from-failing-build.yml
deleted file mode 100644
index 580d1074aa7..00000000000
--- a/changelogs/unreleased/25920-create-issue-from-failing-build.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Add button to create issue for failing build
-merge_request: 9391
-author: Alex Sanford
diff --git a/changelogs/unreleased/26087-asciidoc-cicd-badges-snippet.yml b/changelogs/unreleased/26087-asciidoc-cicd-badges-snippet.yml
deleted file mode 100644
index 799c5277207..00000000000
--- a/changelogs/unreleased/26087-asciidoc-cicd-badges-snippet.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Added AsciiDoc Snippet to CI/CD Badges
-merge_request: 9164
-author: Jan Christophersen
diff --git a/changelogs/unreleased/26136-list-repository-tree-api-doc.yml b/changelogs/unreleased/26136-list-repository-tree-api-doc.yml
deleted file mode 100644
index 85d8bc6ca8a..00000000000
--- a/changelogs/unreleased/26136-list-repository-tree-api-doc.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Make documentation of list repository tree API call more detailed
-merge_request: 9532
-author: Marius Kleiner
diff --git a/changelogs/unreleased/26206-fix-download-dropdown.yml b/changelogs/unreleased/26206-fix-download-dropdown.yml
deleted file mode 100644
index a6c101375bb..00000000000
--- a/changelogs/unreleased/26206-fix-download-dropdown.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Set dropdown height fixed to 250px and make it scrollable
-merge_request: 9063
-author:
diff --git a/changelogs/unreleased/26286-most-recent-activity-profile-header.yml b/changelogs/unreleased/26286-most-recent-activity-profile-header.yml
deleted file mode 100644
index 74d5a43a804..00000000000
--- a/changelogs/unreleased/26286-most-recent-activity-profile-header.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Added 'Most Recent Activity' header to the User Profile page
-merge_request: 9189
-author: Jan Christophersen
diff --git a/changelogs/unreleased/26287-link-branch-in-calendar-activity.yml b/changelogs/unreleased/26287-link-branch-in-calendar-activity.yml
deleted file mode 100644
index 35855578d21..00000000000
--- a/changelogs/unreleased/26287-link-branch-in-calendar-activity.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Add Links to Branches in Calendar Activity
-merge_request: 9224
-author: Jan Christophersen
diff --git a/changelogs/unreleased/2629-show-public-rss-feeds-to-anonymous-users.yml b/changelogs/unreleased/2629-show-public-rss-feeds-to-anonymous-users.yml
deleted file mode 100644
index 6ee8e5724bc..00000000000
--- a/changelogs/unreleased/2629-show-public-rss-feeds-to-anonymous-users.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Show public RSS feeds to anonymous users
-merge_request: 9596
-author: Michael Kozono
diff --git a/changelogs/unreleased/26315-unify-labels-filter-behavior.yml b/changelogs/unreleased/26315-unify-labels-filter-behavior.yml
deleted file mode 100644
index cd2f40c94fe..00000000000
--- a/changelogs/unreleased/26315-unify-labels-filter-behavior.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Unify issues search behavior by always filtering when ALL labels matches
-merge_request: 8849
-author:
diff --git a/changelogs/unreleased/26348-cleanup-navigation-order-groups.yml b/changelogs/unreleased/26348-cleanup-navigation-order-groups.yml
deleted file mode 100644
index ce888baa32f..00000000000
--- a/changelogs/unreleased/26348-cleanup-navigation-order-groups.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Clean-up Groups navigation order
-merge_request: 9309
-author:
diff --git a/changelogs/unreleased/26348-cleanup-navigation-order.yml b/changelogs/unreleased/26348-cleanup-navigation-order.yml
deleted file mode 100644
index d5324f9e025..00000000000
--- a/changelogs/unreleased/26348-cleanup-navigation-order.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Clean-up Project navigation order
-merge_request: 9272
-author:
diff --git a/changelogs/unreleased/26371-native-emojis-v3-code.yml b/changelogs/unreleased/26371-native-emojis-v3-code.yml
deleted file mode 100644
index 88346711490..00000000000
--- a/changelogs/unreleased/26371-native-emojis-v3-code.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Use native unicode emojis
-merge_request:
-author:
diff --git a/changelogs/unreleased/26379-iid-param.yml b/changelogs/unreleased/26379-iid-param.yml
deleted file mode 100644
index ac743e68d6f..00000000000
--- a/changelogs/unreleased/26379-iid-param.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: add :iids param to IssuableFinder (resolve technical dept)
-merge_request: 9222
-author: mhasbini
diff --git a/changelogs/unreleased/26500-informative-slack-notifications.yml b/changelogs/unreleased/26500-informative-slack-notifications.yml
deleted file mode 100644
index 342235424f4..00000000000
--- a/changelogs/unreleased/26500-informative-slack-notifications.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Add user & build links in Slack Notifications
-merge_request: 8641
-author: Poornima M
diff --git a/changelogs/unreleased/26651-cannot-move-project-into-group.yml b/changelogs/unreleased/26651-cannot-move-project-into-group.yml
deleted file mode 100644
index 244a19a627d..00000000000
--- a/changelogs/unreleased/26651-cannot-move-project-into-group.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Specify in the documentation that only projects owners can transfer projects
-merge_request:
-author:
diff --git a/changelogs/unreleased/26703-todos-count.yml b/changelogs/unreleased/26703-todos-count.yml
deleted file mode 100644
index 24fd0c406e2..00000000000
--- a/changelogs/unreleased/26703-todos-count.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: show 99+ for large count in todos notification bell
-merge_request: 9171
-author: mhasbini
diff --git a/changelogs/unreleased/26705-filter-todos-by-manual-add.yml b/changelogs/unreleased/26705-filter-todos-by-manual-add.yml
deleted file mode 100644
index 3521496a20e..00000000000
--- a/changelogs/unreleased/26705-filter-todos-by-manual-add.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Filter todos by manual add
-merge_request: 8691
-author: Jacopo Beschi @jacopo-beschi
diff --git a/changelogs/unreleased/26732-combine-deploy-keys-and-push-rules-and-mirror-repository-and-protect-branches-settings-pages.yml b/changelogs/unreleased/26732-combine-deploy-keys-and-push-rules-and-mirror-repository-and-protect-branches-settings-pages.yml
deleted file mode 100644
index 6fc4615dab8..00000000000
--- a/changelogs/unreleased/26732-combine-deploy-keys-and-push-rules-and-mirror-repository-and-protect-branches-settings-pages.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Combined deploy keys, push rules, protect branches and mirror repository settings options into a single one called
- Repository
-merge_request:
-author:
diff --git a/changelogs/unreleased/26744-add-omniauth-oauth2-generic-strategy.yml b/changelogs/unreleased/26744-add-omniauth-oauth2-generic-strategy.yml
deleted file mode 100644
index 15da43b8091..00000000000
--- a/changelogs/unreleased/26744-add-omniauth-oauth2-generic-strategy.yml
+++ /dev/null
@@ -1,3 +0,0 @@
-title: Add the oauth2_generic OmniAuth strategy
-merge_request: 9048
-author: Joe Marty \ No newline at end of file
diff --git a/changelogs/unreleased/26790-label-color-todos.yml b/changelogs/unreleased/26790-label-color-todos.yml
deleted file mode 100644
index 74084473d81..00000000000
--- a/changelogs/unreleased/26790-label-color-todos.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: fix background color for labels mention in todo
-merge_request: 9155
-author: mhasbini
diff --git a/changelogs/unreleased/26847-api-pipelines-use-basic.yml b/changelogs/unreleased/26847-api-pipelines-use-basic.yml
deleted file mode 100644
index 2034a4ba080..00000000000
--- a/changelogs/unreleased/26847-api-pipelines-use-basic.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Expose pipelines as PipelineBasic `api/v3/projects/:id/pipelines`
-merge_request: 8875
-author:
diff --git a/changelogs/unreleased/26875-builds-api-endpoint-skipped-scope.yml b/changelogs/unreleased/26875-builds-api-endpoint-skipped-scope.yml
deleted file mode 100644
index 3d6400cba76..00000000000
--- a/changelogs/unreleased/26875-builds-api-endpoint-skipped-scope.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Add all available statuses to scope filter for project builds endpoint
-merge_request:
-author: George Andrinopoulos
diff --git a/changelogs/unreleased/26900-pipelines-tabs.yml b/changelogs/unreleased/26900-pipelines-tabs.yml
deleted file mode 100644
index f08514c621f..00000000000
--- a/changelogs/unreleased/26900-pipelines-tabs.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Adds Pending and Finished tabs to pipelines page
-merge_request:
-author:
diff --git a/changelogs/unreleased/26957-tanuki-anim-hang.yml b/changelogs/unreleased/26957-tanuki-anim-hang.yml
deleted file mode 100644
index c7b4b9ebdfd..00000000000
--- a/changelogs/unreleased/26957-tanuki-anim-hang.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: don't animate logo when downloading files
-merge_request:
-author:
diff --git a/changelogs/unreleased/27032-add-a-house-keeping-api-call.yml b/changelogs/unreleased/27032-add-a-house-keeping-api-call.yml
deleted file mode 100644
index a9f70e339c0..00000000000
--- a/changelogs/unreleased/27032-add-a-house-keeping-api-call.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Add housekeeping endpoint for Projects API
-merge_request: 9421
-author:
diff --git a/changelogs/unreleased/27142-api-replace-destroy-with-stop-environment.yml b/changelogs/unreleased/27142-api-replace-destroy-with-stop-environment.yml
deleted file mode 100644
index dd649dcde7e..00000000000
--- a/changelogs/unreleased/27142-api-replace-destroy-with-stop-environment.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: 'API: Add environment stop action'
-merge_request: 8808
-author:
diff --git a/changelogs/unreleased/27287-label-dropdown-error-messages.yml b/changelogs/unreleased/27287-label-dropdown-error-messages.yml
deleted file mode 100644
index dfd4102c324..00000000000
--- a/changelogs/unreleased/27287-label-dropdown-error-messages.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Fix displaying error messages for create label dropdown
-merge_request: 9058
-author: Tom Koole
diff --git a/changelogs/unreleased/27336-add-environment-url-link-to-terminal-page.yml b/changelogs/unreleased/27336-add-environment-url-link-to-terminal-page.yml
deleted file mode 100644
index dd4907166c4..00000000000
--- a/changelogs/unreleased/27336-add-environment-url-link-to-terminal-page.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Added external environment link to web terminal view
-merge_request: 8303
-author:
diff --git a/changelogs/unreleased/27354-navigation-new-button.yml b/changelogs/unreleased/27354-navigation-new-button.yml
deleted file mode 100644
index 62cac9bbbd3..00000000000
--- a/changelogs/unreleased/27354-navigation-new-button.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Re-add the New Project button in nav bar
-merge_request:
-author:
diff --git a/changelogs/unreleased/27376-cache-default-branch-pipeline-on-project.yml b/changelogs/unreleased/27376-cache-default-branch-pipeline-on-project.yml
deleted file mode 100644
index a116c68ad87..00000000000
--- a/changelogs/unreleased/27376-cache-default-branch-pipeline-on-project.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Speed up project dashboard by caching pipeline status and eager loading routes
-merge_request: 9903
-author:
diff --git a/changelogs/unreleased/27452-update-issue-count.yml b/changelogs/unreleased/27452-update-issue-count.yml
deleted file mode 100644
index a7417eba63c..00000000000
--- a/changelogs/unreleased/27452-update-issue-count.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: update issue count when closing/reopening an issue
-merge_request:
-author:
diff --git a/changelogs/unreleased/27501-api-use-visibility-everywhere.yml b/changelogs/unreleased/27501-api-use-visibility-everywhere.yml
deleted file mode 100644
index f1b70687878..00000000000
--- a/changelogs/unreleased/27501-api-use-visibility-everywhere.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: "API: Use `visibility` as string parameter everywhere"
-merge_request: 9337
-author:
diff --git a/changelogs/unreleased/27503-feature-status-aria-labels.yml b/changelogs/unreleased/27503-feature-status-aria-labels.yml
new file mode 100644
index 00000000000..f514fd5b631
--- /dev/null
+++ b/changelogs/unreleased/27503-feature-status-aria-labels.yml
@@ -0,0 +1,4 @@
+---
+title: Add `aria-label` for feature status accessibility
+merge_request: 9830
+author:
diff --git a/changelogs/unreleased/27520-option-to-prevent-signing-in-from-multiple-ips.yml b/changelogs/unreleased/27520-option-to-prevent-signing-in-from-multiple-ips.yml
deleted file mode 100644
index 3050b072863..00000000000
--- a/changelogs/unreleased/27520-option-to-prevent-signing-in-from-multiple-ips.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Option to prevent signing in from multiple ips
-merge_request: 8998
-author:
diff --git a/changelogs/unreleased/27523-make-stuck-build-detection-more-performant.yml b/changelogs/unreleased/27523-make-stuck-build-detection-more-performant.yml
deleted file mode 100644
index a4ef2b23aaa..00000000000
--- a/changelogs/unreleased/27523-make-stuck-build-detection-more-performant.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Make stuck builds detection more performant
-merge_request: 9025
-author:
diff --git a/changelogs/unreleased/27530-fix-job-dropdown-pipeline-console-error.yml b/changelogs/unreleased/27530-fix-job-dropdown-pipeline-console-error.yml
deleted file mode 100644
index 4436b4bee68..00000000000
--- a/changelogs/unreleased/27530-fix-job-dropdown-pipeline-console-error.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Fixes job dropdown action throws error in js console
-merge_request: 9182
-author:
diff --git a/changelogs/unreleased/27532_api_changes.yml b/changelogs/unreleased/27532_api_changes.yml
deleted file mode 100644
index 778469d5a86..00000000000
--- a/changelogs/unreleased/27532_api_changes.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Use iids as filter parameter
-merge_request: 9096
-author:
diff --git a/changelogs/unreleased/27568-refactor-very-slow-dropdown-asignee-spec.yml b/changelogs/unreleased/27568-refactor-very-slow-dropdown-asignee-spec.yml
deleted file mode 100644
index 5c738af7704..00000000000
--- a/changelogs/unreleased/27568-refactor-very-slow-dropdown-asignee-spec.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Refactor dropdown_assignee_spec
-merge_request: 9711
-author: George Andrinopoulos
diff --git a/changelogs/unreleased/27608-fixes-markdown-in-activity-feed-is-light-gray.yml b/changelogs/unreleased/27608-fixes-markdown-in-activity-feed-is-light-gray.yml
deleted file mode 100644
index 8f297620e23..00000000000
--- a/changelogs/unreleased/27608-fixes-markdown-in-activity-feed-is-light-gray.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Fixes markdown in activity-feed is gray
-merge_request: 9179
-author:
diff --git a/changelogs/unreleased/27610-issue-number-alignment.yml b/changelogs/unreleased/27610-issue-number-alignment.yml
deleted file mode 100644
index 19ab8872c62..00000000000
--- a/changelogs/unreleased/27610-issue-number-alignment.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: fixes issue number alignment problem in MR and issue list
-merge_request: 9020
-author:
diff --git a/changelogs/unreleased/27631-fix-small-height-of-activity-header-page.yml b/changelogs/unreleased/27631-fix-small-height-of-activity-header-page.yml
deleted file mode 100644
index 59da28964f7..00000000000
--- a/changelogs/unreleased/27631-fix-small-height-of-activity-header-page.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: "Fix small height of activity header page"
-merge_request: 8952
-author: Pavel Sorokin
diff --git a/changelogs/unreleased/27726-fix-dropdown-width-in-admin-project-page.yml b/changelogs/unreleased/27726-fix-dropdown-width-in-admin-project-page.yml
deleted file mode 100644
index 6c98b46d8cb..00000000000
--- a/changelogs/unreleased/27726-fix-dropdown-width-in-admin-project-page.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Fixes dropdown width in admin project page
-merge_request: 9002
-author:
diff --git a/changelogs/unreleased/27762-add-default-artifacts-expiration.yml b/changelogs/unreleased/27762-add-default-artifacts-expiration.yml
deleted file mode 100644
index 27fa77ed04d..00000000000
--- a/changelogs/unreleased/27762-add-default-artifacts-expiration.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Add admin setting for default artifacts expiration
-merge_request: 9219
-author:
diff --git a/changelogs/unreleased/27778-a11y-sidebar.yml b/changelogs/unreleased/27778-a11y-sidebar.yml
deleted file mode 100644
index fb37d7fdb35..00000000000
--- a/changelogs/unreleased/27778-a11y-sidebar.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Improves a11y in sidebar by adding aria-hidden attributes in i tags and by
- fixing two broken aria-hidden attributes
-merge_request:
-author:
diff --git a/changelogs/unreleased/27783-fix-fe-doc-broken-link.yml b/changelogs/unreleased/27783-fix-fe-doc-broken-link.yml
deleted file mode 100644
index 429110e9178..00000000000
--- a/changelogs/unreleased/27783-fix-fe-doc-broken-link.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Fixes FE Doc broken link
-merge_request: 9120
-author:
diff --git a/changelogs/unreleased/27840-improve-search-bar-experience.yml b/changelogs/unreleased/27840-improve-search-bar-experience.yml
deleted file mode 100644
index 87b1f0c5572..00000000000
--- a/changelogs/unreleased/27840-improve-search-bar-experience.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Enhanced filter issues layout for better mobile experiance
-merge_request: 9280
-author: Pratik Borsadiya
diff --git a/changelogs/unreleased/27920-both-wip-messages-showing.yml b/changelogs/unreleased/27920-both-wip-messages-showing.yml
deleted file mode 100644
index 497fda8c8ba..00000000000
--- a/changelogs/unreleased/27920-both-wip-messages-showing.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Dispatch needed JS when creating a new MR in diff view
-merge_request:
-author:
diff --git a/changelogs/unreleased/27924-set-max-width-mini-pipeline-text.yml b/changelogs/unreleased/27924-set-max-width-mini-pipeline-text.yml
deleted file mode 100644
index 53077eedc11..00000000000
--- a/changelogs/unreleased/27924-set-max-width-mini-pipeline-text.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Set maximum width for mini pipeline graph text so it is not truncated to early
-merge_request: 9188
-author:
diff --git a/changelogs/unreleased/27934-left-align-logo.yml b/changelogs/unreleased/27934-left-align-logo.yml
deleted file mode 100644
index d4e5e169465..00000000000
--- a/changelogs/unreleased/27934-left-align-logo.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Left align logo
-merge_request:
-author:
diff --git a/changelogs/unreleased/27936-make-all-uploads-require-revalidation-on-each-browser-fetch.yml b/changelogs/unreleased/27936-make-all-uploads-require-revalidation-on-each-browser-fetch.yml
deleted file mode 100644
index adc129d8dca..00000000000
--- a/changelogs/unreleased/27936-make-all-uploads-require-revalidation-on-each-browser-fetch.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Uploaded files which content can change now require revalidation on each page load
-merge_request: 9453
-author:
diff --git a/changelogs/unreleased/27978-improve-task-list-ux.yml b/changelogs/unreleased/27978-improve-task-list-ux.yml
deleted file mode 100644
index a6bd99da82e..00000000000
--- a/changelogs/unreleased/27978-improve-task-list-ux.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Only add a newline in the Markdown Editor if the current line is not empty
-merge_request: 9455
-author: Jan Christophersen
diff --git a/changelogs/unreleased/27994-fix-mr-widget-jump.yml b/changelogs/unreleased/27994-fix-mr-widget-jump.yml
deleted file mode 100644
index 77783e54a3a..00000000000
--- a/changelogs/unreleased/27994-fix-mr-widget-jump.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Fix MR widget jump
-merge_request: 9146
-author:
diff --git a/changelogs/unreleased/28010-mr-merge-button-default-to-danger.yml b/changelogs/unreleased/28010-mr-merge-button-default-to-danger.yml
deleted file mode 100644
index 06bb669ceac..00000000000
--- a/changelogs/unreleased/28010-mr-merge-button-default-to-danger.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Default to subtle MR mege button until CI status is available
-merge_request:
-author:
diff --git a/changelogs/unreleased/28019-make-builds-show-faster.yml b/changelogs/unreleased/28019-make-builds-show-faster.yml
deleted file mode 100644
index bbfea0e4c88..00000000000
--- a/changelogs/unreleased/28019-make-builds-show-faster.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Avoid calling Build#trace_with_state for performance
-merge_request: 9149
-author: Takuya Noguchi
diff --git a/changelogs/unreleased/28058-hide-emails-in-atom-feeds.yml b/changelogs/unreleased/28058-hide-emails-in-atom-feeds.yml
deleted file mode 100644
index e0e826a67f8..00000000000
--- a/changelogs/unreleased/28058-hide-emails-in-atom-feeds.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Only show public emails in atom feeds
-merge_request:
-author:
diff --git a/changelogs/unreleased/28082-deleted-branch-event-404.yml b/changelogs/unreleased/28082-deleted-branch-event-404.yml
deleted file mode 100644
index e989ca34784..00000000000
--- a/changelogs/unreleased/28082-deleted-branch-event-404.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Stop linking to deleted Branches in Activity tabs
-merge_request: 9203
-author: Jan Christophersen
diff --git a/changelogs/unreleased/28142-overlap-bugs.yml b/changelogs/unreleased/28142-overlap-bugs.yml
deleted file mode 100644
index 9fdabdf204a..00000000000
--- a/changelogs/unreleased/28142-overlap-bugs.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Fix z index issues with sidebar
-merge_request:
-author:
diff --git a/changelogs/unreleased/28176_merge_widget_fix.yml b/changelogs/unreleased/28176_merge_widget_fix.yml
deleted file mode 100644
index 8e4e75fc237..00000000000
--- a/changelogs/unreleased/28176_merge_widget_fix.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Fix error in MR widget after /merge slash command
-merge_request: 9259
-author:
diff --git a/changelogs/unreleased/28186-long-group-names-overflow-out-of-todos-view.yml b/changelogs/unreleased/28186-long-group-names-overflow-out-of-todos-view.yml
deleted file mode 100644
index 3bcf0e06d08..00000000000
--- a/changelogs/unreleased/28186-long-group-names-overflow-out-of-todos-view.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Truncate long Todo titles for non-mobile screens
-merge_request: 9311
-author:
diff --git a/changelogs/unreleased/28204-option-to-disable-webpack-dev-server-livereload.yml b/changelogs/unreleased/28204-option-to-disable-webpack-dev-server-livereload.yml
deleted file mode 100644
index df2478a3f28..00000000000
--- a/changelogs/unreleased/28204-option-to-disable-webpack-dev-server-livereload.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Pick up option from GDK to disable webpack dev server livereload
-merge_request:
-author:
diff --git a/changelogs/unreleased/28229-pipelines-loading-icon.yml b/changelogs/unreleased/28229-pipelines-loading-icon.yml
deleted file mode 100644
index d8f82f658c2..00000000000
--- a/changelogs/unreleased/28229-pipelines-loading-icon.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Centers loading icon vertically and horizontally in pipelines table in commit
- view
-merge_request:
-author:
diff --git a/changelogs/unreleased/28236-browse-button-dropping.yml b/changelogs/unreleased/28236-browse-button-dropping.yml
deleted file mode 100644
index 3a3d755f40c..00000000000
--- a/changelogs/unreleased/28236-browse-button-dropping.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Increase right side of file header to button stays on same line
-merge_request:
-author:
diff --git a/changelogs/unreleased/28247-timeloops-bug.yml b/changelogs/unreleased/28247-timeloops-bug.yml
deleted file mode 100644
index 12ab523b7c7..00000000000
--- a/changelogs/unreleased/28247-timeloops-bug.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Only run timeago loops after rendering timeago components
-merge_request:
-author:
diff --git a/changelogs/unreleased/28253-fix-buid-scroll-button-position.yml b/changelogs/unreleased/28253-fix-buid-scroll-button-position.yml
deleted file mode 100644
index b13d115dab9..00000000000
--- a/changelogs/unreleased/28253-fix-buid-scroll-button-position.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Fix positioning of `Scroll to top` button
-merge_request:
-author:
diff --git a/changelogs/unreleased/28257-issues-iids.yml b/changelogs/unreleased/28257-issues-iids.yml
deleted file mode 100644
index 0a85504a8de..00000000000
--- a/changelogs/unreleased/28257-issues-iids.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: API issues - support filtering by iids
-merge_request:
-author:
diff --git a/changelogs/unreleased/28262-horizontal-scrolling-issue-on-long-project-names.yml b/changelogs/unreleased/28262-horizontal-scrolling-issue-on-long-project-names.yml
deleted file mode 100644
index fa1674453de..00000000000
--- a/changelogs/unreleased/28262-horizontal-scrolling-issue-on-long-project-names.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Wrap long Project and Group titles
-merge_request: 9301
-author:
diff --git a/changelogs/unreleased/28277-document-u2f-limitations-with-multiple-urls.yml b/changelogs/unreleased/28277-document-u2f-limitations-with-multiple-urls.yml
deleted file mode 100644
index 6e3cd8a60d8..00000000000
--- a/changelogs/unreleased/28277-document-u2f-limitations-with-multiple-urls.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Document U2F limitations with multiple URLs
-merge_request: 9300
-author:
diff --git a/changelogs/unreleased/28303-change-development-tanuki-favicon-colors-to-match-logo.yml b/changelogs/unreleased/28303-change-development-tanuki-favicon-colors-to-match-logo.yml
deleted file mode 100644
index b97e9a59b2a..00000000000
--- a/changelogs/unreleased/28303-change-development-tanuki-favicon-colors-to-match-logo.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Change development tanuki favicon colors to match logo color order
-merge_request:
-author:
diff --git a/changelogs/unreleased/28329-allow-slash-in-slash-command-args.yml b/changelogs/unreleased/28329-allow-slash-in-slash-command-args.yml
deleted file mode 100644
index fed02139a5c..00000000000
--- a/changelogs/unreleased/28329-allow-slash-in-slash-command-args.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Allow slashes in slash command arguments
-merge_request:
-author:
diff --git a/changelogs/unreleased/28353-little-grammar-issue.yml b/changelogs/unreleased/28353-little-grammar-issue.yml
deleted file mode 100644
index 10bdb17b266..00000000000
--- a/changelogs/unreleased/28353-little-grammar-issue.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Fix grammer issue in admin/runners
-merge_request:
-author:
diff --git a/changelogs/unreleased/28366-renamed-file-tooltip-contains-html.yml b/changelogs/unreleased/28366-renamed-file-tooltip-contains-html.yml
deleted file mode 100644
index faf1e89ed94..00000000000
--- a/changelogs/unreleased/28366-renamed-file-tooltip-contains-html.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Remove markup that was showing in tooltip for renamed files
-merge_request: 9374
-author:
diff --git a/changelogs/unreleased/28367-fix-unfold-diff-line-number-copy-paste.yml b/changelogs/unreleased/28367-fix-unfold-diff-line-number-copy-paste.yml
deleted file mode 100644
index 6fc89fd91dd..00000000000
--- a/changelogs/unreleased/28367-fix-unfold-diff-line-number-copy-paste.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Fixes includes line number during unfold copy n paste in parallel diff view
-merge_request: 9365
-author:
diff --git a/changelogs/unreleased/28389-ux-problem-with-pipeline-coverage-placeholder.yml b/changelogs/unreleased/28389-ux-problem-with-pipeline-coverage-placeholder.yml
deleted file mode 100644
index ed357d86fe3..00000000000
--- a/changelogs/unreleased/28389-ux-problem-with-pipeline-coverage-placeholder.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Changed coverage reg expression placeholder text to be more like a placeholder
-merge_request:
-author:
diff --git a/changelogs/unreleased/28410-dropdown-styling.yml b/changelogs/unreleased/28410-dropdown-styling.yml
deleted file mode 100644
index 2a7af1dd6e8..00000000000
--- a/changelogs/unreleased/28410-dropdown-styling.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Add badges to global dropdown
-merge_request:
-author:
diff --git a/changelogs/unreleased/28447-hybrid-repository-storages.yml b/changelogs/unreleased/28447-hybrid-repository-storages.yml
deleted file mode 100644
index 00dfc5781b9..00000000000
--- a/changelogs/unreleased/28447-hybrid-repository-storages.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Update storage settings to allow extra values per repository storage
-merge_request: 9597
-author:
diff --git a/changelogs/unreleased/28450-test-compiling-frontend-assets-for-production-in-ci.yml b/changelogs/unreleased/28450-test-compiling-frontend-assets-for-production-in-ci.yml
deleted file mode 100644
index 196a9b788ea..00000000000
--- a/changelogs/unreleased/28450-test-compiling-frontend-assets-for-production-in-ci.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: test compiling production assets and generate webpack bundle report in CI
-merge_request: 9396
-author:
diff --git a/changelogs/unreleased/28458-present-gitlab-version-for-v4-changes-on-docs.yml b/changelogs/unreleased/28458-present-gitlab-version-for-v4-changes-on-docs.yml
deleted file mode 100644
index dbbe8a19204..00000000000
--- a/changelogs/unreleased/28458-present-gitlab-version-for-v4-changes-on-docs.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Present GitLab version for each V3 to V4 API change on v3_to_v4.md
-merge_request:
-author:
diff --git a/changelogs/unreleased/28462-fix-delimiter-removes-issue-in-todo-counter.yml b/changelogs/unreleased/28462-fix-delimiter-removes-issue-in-todo-counter.yml
deleted file mode 100644
index 80995d75c23..00000000000
--- a/changelogs/unreleased/28462-fix-delimiter-removes-issue-in-todo-counter.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Fixes delimiter removes when todo marked as done
-merge_request: 9435
-author:
diff --git a/changelogs/unreleased/28499-fix-large-text-tooltip-in-diff-file-name.yml b/changelogs/unreleased/28499-fix-large-text-tooltip-in-diff-file-name.yml
deleted file mode 100644
index 660a881e094..00000000000
--- a/changelogs/unreleased/28499-fix-large-text-tooltip-in-diff-file-name.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Fixes large file name tooltip cutoff in diff header
-merge_request: 9529
-author:
diff --git a/changelogs/unreleased/28516-default-kubernetes-namespace.yml b/changelogs/unreleased/28516-default-kubernetes-namespace.yml
deleted file mode 100644
index 9fa5c681a53..00000000000
--- a/changelogs/unreleased/28516-default-kubernetes-namespace.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Make a default namespace of Kubernetes service to contain project ID
-merge_request:
-author:
diff --git a/changelogs/unreleased/28524-gitlab-ci-yml-coverage-key-is-unknown.yml b/changelogs/unreleased/28524-gitlab-ci-yml-coverage-key-is-unknown.yml
deleted file mode 100644
index eda5764c13e..00000000000
--- a/changelogs/unreleased/28524-gitlab-ci-yml-coverage-key-is-unknown.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Document when current coverage configuration option was introduced
-merge_request: 9443
-author:
diff --git a/changelogs/unreleased/28538-restore-nav-shortcuts.yml b/changelogs/unreleased/28538-restore-nav-shortcuts.yml
deleted file mode 100644
index 07b39cd50d1..00000000000
--- a/changelogs/unreleased/28538-restore-nav-shortcuts.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Restore keyboard shortcuts for "Activity" and "Charts"
-merge_request: 9680
-author:
diff --git a/changelogs/unreleased/28598-narrow-environment-payload-by-using-basic-project.yml b/changelogs/unreleased/28598-narrow-environment-payload-by-using-basic-project.yml
deleted file mode 100644
index ada726c9048..00000000000
--- a/changelogs/unreleased/28598-narrow-environment-payload-by-using-basic-project.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Narrow environment payload by using basic project details resource
-merge_request:
-author:
diff --git a/changelogs/unreleased/28655-current-path-text-is-not-updated-after-setting-the-new-username.yml b/changelogs/unreleased/28655-current-path-text-is-not-updated-after-setting-the-new-username.yml
deleted file mode 100644
index bff996172f3..00000000000
--- a/changelogs/unreleased/28655-current-path-text-is-not-updated-after-setting-the-new-username.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Update account view to display new username
-merge_request:
-author:
diff --git a/changelogs/unreleased/28696-improve-grammar-gitlab-flow-doc.yml b/changelogs/unreleased/28696-improve-grammar-gitlab-flow-doc.yml
deleted file mode 100644
index e38e5d0db5b..00000000000
--- a/changelogs/unreleased/28696-improve-grammar-gitlab-flow-doc.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Improve grammar in GitLab flow documentation
-merge_request: 9552
-author: infogrind
diff --git a/changelogs/unreleased/28704-fullscreen-zen-mode-is-broken.yml b/changelogs/unreleased/28704-fullscreen-zen-mode-is-broken.yml
deleted file mode 100644
index b8dba0b5993..00000000000
--- a/changelogs/unreleased/28704-fullscreen-zen-mode-is-broken.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Set max height to screen height for Zen mode
-merge_request: 9667
-author:
diff --git a/changelogs/unreleased/28713-fe-style-guide.yml b/changelogs/unreleased/28713-fe-style-guide.yml
new file mode 100644
index 00000000000..57edb43e27f
--- /dev/null
+++ b/changelogs/unreleased/28713-fe-style-guide.yml
@@ -0,0 +1,4 @@
+---
+title: Adds Frontend Styleguide to documentation
+merge_request: 9961
+author:
diff --git a/changelogs/unreleased/28723-consistent-handling-indexof.yml b/changelogs/unreleased/28723-consistent-handling-indexof.yml
deleted file mode 100644
index 95d6181d5fa..00000000000
--- a/changelogs/unreleased/28723-consistent-handling-indexof.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Keep consistent in handling indexOf results
-merge_request: 9531
-author: Takuya Noguchi
diff --git a/changelogs/unreleased/28805-download-archive-with-branch-like-feature-xxxx-add-extra-directory-level.yml b/changelogs/unreleased/28805-download-archive-with-branch-like-feature-xxxx-add-extra-directory-level.yml
deleted file mode 100644
index 38ff6b97b2b..00000000000
--- a/changelogs/unreleased/28805-download-archive-with-branch-like-feature-xxxx-add-extra-directory-level.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Ensure archive download is only one directory deep
-merge_request: 9616
-author:
diff --git a/changelogs/unreleased/28807-search-for-milestone-by-title-in-rest-api.yml b/changelogs/unreleased/28807-search-for-milestone-by-title-in-rest-api.yml
deleted file mode 100644
index 0016253e32e..00000000000
--- a/changelogs/unreleased/28807-search-for-milestone-by-title-in-rest-api.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Enable filtering milestones by search criteria in the API
-merge_request: 9606
-author:
diff --git a/changelogs/unreleased/28835-jobs-head.yml b/changelogs/unreleased/28835-jobs-head.yml
deleted file mode 100644
index 1580cfb19ba..00000000000
--- a/changelogs/unreleased/28835-jobs-head.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Fix jobs table header height
-merge_request:
-author:
diff --git a/changelogs/unreleased/28837-remove-help-duplicate.yml b/changelogs/unreleased/28837-remove-help-duplicate.yml
deleted file mode 100644
index b1001245663..00000000000
--- a/changelogs/unreleased/28837-remove-help-duplicate.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Remove help link from right dropdown
-merge_request:
-author:
diff --git a/changelogs/unreleased/28865-filter-by-authorized-projects-in-v4.yml b/changelogs/unreleased/28865-filter-by-authorized-projects-in-v4.yml
deleted file mode 100644
index 7c64783cbd0..00000000000
--- a/changelogs/unreleased/28865-filter-by-authorized-projects-in-v4.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Add filter param for project membership for current_user in API v4
-merge_request:
-author:
diff --git a/changelogs/unreleased/28890-allow-creating-mr-without-target-branch-in-url.yml b/changelogs/unreleased/28890-allow-creating-mr-without-target-branch-in-url.yml
deleted file mode 100644
index 114a14ec2df..00000000000
--- a/changelogs/unreleased/28890-allow-creating-mr-without-target-branch-in-url.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Allow creating merge request even if target branch is not specified in query
- params
-merge_request: 9968
-author:
diff --git a/changelogs/unreleased/28893-highlighted-diff-doesn-t-stay-highlighted-on-refresh.yml b/changelogs/unreleased/28893-highlighted-diff-doesn-t-stay-highlighted-on-refresh.yml
deleted file mode 100644
index 9ba33af010c..00000000000
--- a/changelogs/unreleased/28893-highlighted-diff-doesn-t-stay-highlighted-on-refresh.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Highlight line number if specified on diff pages when page loads
-merge_request: 9664
-author:
diff --git a/changelogs/unreleased/28898-fix-search-branches-in-cherry-picking.yml b/changelogs/unreleased/28898-fix-search-branches-in-cherry-picking.yml
deleted file mode 100644
index 48e62f8f70d..00000000000
--- a/changelogs/unreleased/28898-fix-search-branches-in-cherry-picking.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Fix json response in branches controller
-merge_request: 9710
-author: George Andrinopoulos
diff --git a/changelogs/unreleased/28935-make-logo-smaller.yml b/changelogs/unreleased/28935-make-logo-smaller.yml
deleted file mode 100644
index ef79fc7d212..00000000000
--- a/changelogs/unreleased/28935-make-logo-smaller.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Decrease tanuki logo size
-merge_request:
-author:
diff --git a/changelogs/unreleased/29043-upgrade-vue-and-remove-warnings.yml b/changelogs/unreleased/29043-upgrade-vue-and-remove-warnings.yml
new file mode 100644
index 00000000000..9055b23a13f
--- /dev/null
+++ b/changelogs/unreleased/29043-upgrade-vue-and-remove-warnings.yml
@@ -0,0 +1,4 @@
+---
+title: Upgrade VueJS to v2.2.4 and disable dev mode warnings
+merge_request: 9981
+author:
diff --git a/changelogs/unreleased/29263-merge-button-color.yml b/changelogs/unreleased/29263-merge-button-color.yml
deleted file mode 100644
index 2d0625483a4..00000000000
--- a/changelogs/unreleased/29263-merge-button-color.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: ensure MR widget dropdown is same color as button
-merge_request:
-author:
diff --git a/changelogs/unreleased/29428-new-directory-from-existing-branch.yml b/changelogs/unreleased/29428-new-directory-from-existing-branch.yml
new file mode 100644
index 00000000000..b3f7cd1f8f8
--- /dev/null
+++ b/changelogs/unreleased/29428-new-directory-from-existing-branch.yml
@@ -0,0 +1,4 @@
+---
+title: New directory from interface on existing branch
+merge_request: 9921
+author: Jacopo Beschi @jacopo-beschi
diff --git a/changelogs/unreleased/29483-spam-check-only-title-and-description.yml b/changelogs/unreleased/29483-spam-check-only-title-and-description.yml
new file mode 100644
index 00000000000..de8cacb250d
--- /dev/null
+++ b/changelogs/unreleased/29483-spam-check-only-title-and-description.yml
@@ -0,0 +1,4 @@
+---
+title: Spam check only when spammable attributes have changed
+merge_request:
+author:
diff --git a/changelogs/unreleased/29550-fix-quick-submit-on-preview.yml b/changelogs/unreleased/29550-fix-quick-submit-on-preview.yml
new file mode 100644
index 00000000000..71214971ffd
--- /dev/null
+++ b/changelogs/unreleased/29550-fix-quick-submit-on-preview.yml
@@ -0,0 +1,4 @@
+---
+title: Fix quick submit short-cut on preview tab for comments
+merge_request: 10002
+author:
diff --git a/changelogs/unreleased/29555-align-all-todo.yml b/changelogs/unreleased/29555-align-all-todo.yml
new file mode 100644
index 00000000000..c1555a96a92
--- /dev/null
+++ b/changelogs/unreleased/29555-align-all-todo.yml
@@ -0,0 +1,4 @@
+---
+title: align Mark all as done with other Done buttons on Todos page
+merge_request:
+author:
diff --git a/changelogs/unreleased/29565-name-of-the-uncompressed-folder-of-a-tag-archive-changed.yml b/changelogs/unreleased/29565-name-of-the-uncompressed-folder-of-a-tag-archive-changed.yml
deleted file mode 100644
index d0a04b0a130..00000000000
--- a/changelogs/unreleased/29565-name-of-the-uncompressed-folder-of-a-tag-archive-changed.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Fix archive prefix bug for refs containing dots
-merge_request:
-author:
diff --git a/changelogs/unreleased/29575-polling.yml b/changelogs/unreleased/29575-polling.yml
new file mode 100644
index 00000000000..75016afd455
--- /dev/null
+++ b/changelogs/unreleased/29575-polling.yml
@@ -0,0 +1,4 @@
+---
+title: Adds polling utility function for vue resource
+merge_request:
+author:
diff --git a/changelogs/unreleased/29604-v3-fix-branch-creation.yml b/changelogs/unreleased/29604-v3-fix-branch-creation.yml
deleted file mode 100644
index 25687e8be97..00000000000
--- a/changelogs/unreleased/29604-v3-fix-branch-creation.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Use "branch_name" instead "branch" on V3 branch creation API
-merge_request:
-author:
diff --git a/changelogs/unreleased/3440-remove-hsts-header.yml b/changelogs/unreleased/3440-remove-hsts-header.yml
deleted file mode 100644
index 0310e733f4e..00000000000
--- a/changelogs/unreleased/3440-remove-hsts-header.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Stop setting Strict-Transport-Securty header from within the app
-merge_request:
-author:
diff --git a/changelogs/unreleased/3874-correctly-return-json-on-delete-responses.yml b/changelogs/unreleased/3874-correctly-return-json-on-delete-responses.yml
deleted file mode 100644
index 4a4932288b4..00000000000
--- a/changelogs/unreleased/3874-correctly-return-json-on-delete-responses.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Return 202 with JSON body on async removals on V4 API
-merge_request:
-author:
diff --git a/changelogs/unreleased/6073_project_api.yml b/changelogs/unreleased/6073_project_api.yml
deleted file mode 100644
index fd6792a406e..00000000000
--- a/changelogs/unreleased/6073_project_api.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: 'API project create: Make name or path required'
-merge_request: 9416
-author:
diff --git a/changelogs/unreleased/9381-authentiq-backchannel-logout.yml b/changelogs/unreleased/9381-authentiq-backchannel-logout.yml
deleted file mode 100644
index 4dbf36cd096..00000000000
--- a/changelogs/unreleased/9381-authentiq-backchannel-logout.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Adds remote logout functionality to the Authentiq OAuth provider
-merge_request: 9381
-author: Alexandros Keramidas
diff --git a/changelogs/unreleased/add-auto-submited-header.yml b/changelogs/unreleased/add-auto-submited-header.yml
deleted file mode 100644
index 93481613b39..00000000000
--- a/changelogs/unreleased/add-auto-submited-header.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Set Auto-Submitted header to mails
-merge_request:
-author: Semyon Pupkov
diff --git a/changelogs/unreleased/add-changelog-filtered-search-visual-tokens.yml b/changelogs/unreleased/add-changelog-filtered-search-visual-tokens.yml
deleted file mode 100644
index d10e4cb7c87..00000000000
--- a/changelogs/unreleased/add-changelog-filtered-search-visual-tokens.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Add filtered search visual tokens
-merge_request: 8969
-author:
diff --git a/changelogs/unreleased/add-filtered-search-to-mr.yml b/changelogs/unreleased/add-filtered-search-to-mr.yml
deleted file mode 100644
index e3577e2aec7..00000000000
--- a/changelogs/unreleased/add-filtered-search-to-mr.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Add filtered search to MR page
-merge_request:
-author:
diff --git a/changelogs/unreleased/add-frequently-used-emojis-back-to-menu.yml b/changelogs/unreleased/add-frequently-used-emojis-back-to-menu.yml
deleted file mode 100644
index 66d5bb63734..00000000000
--- a/changelogs/unreleased/add-frequently-used-emojis-back-to-menu.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Add frequently used emojis back to awards menu
-merge_request:
-author:
diff --git a/changelogs/unreleased/add-git-version-to-system-info.yml b/changelogs/unreleased/add-git-version-to-system-info.yml
deleted file mode 100644
index 2827fcec28d..00000000000
--- a/changelogs/unreleased/add-git-version-to-system-info.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Add git version to gitlab:env:info
-merge_request: 9128
-author: Semyon Pupkov
diff --git a/changelogs/unreleased/add-kube-ca-pem-file-deprecate-kube-ca-pem.yml b/changelogs/unreleased/add-kube-ca-pem-file-deprecate-kube-ca-pem.yml
deleted file mode 100644
index 1ae1e3c7a7a..00000000000
--- a/changelogs/unreleased/add-kube-ca-pem-file-deprecate-kube-ca-pem.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Add KUBE_CA_PEM_FILE, deprecate KUBE_CA_PEM
-merge_request: 9398
-author:
diff --git a/changelogs/unreleased/add-pipeline-triggers.yml b/changelogs/unreleased/add-pipeline-triggers.yml
deleted file mode 100644
index 81b11da0bb2..00000000000
--- a/changelogs/unreleased/add-pipeline-triggers.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Add pipeline trigger API with user permissions
-merge_request: 9277
-author:
diff --git a/changelogs/unreleased/add-test-backoff-util.yml b/changelogs/unreleased/add-test-backoff-util.yml
new file mode 100644
index 00000000000..f3f3b99caec
--- /dev/null
+++ b/changelogs/unreleased/add-test-backoff-util.yml
@@ -0,0 +1,4 @@
+---
+title: Added tests for the w.gl.utils.backOff promise
+merge_request:
+author:
diff --git a/changelogs/unreleased/add-todos-shortcut.yml b/changelogs/unreleased/add-todos-shortcut.yml
new file mode 100644
index 00000000000..41d42775937
--- /dev/null
+++ b/changelogs/unreleased/add-todos-shortcut.yml
@@ -0,0 +1,4 @@
+---
+title: Add `g t` global shortcut to go to todos
+merge_request:
+author:
diff --git a/changelogs/unreleased/add-yarn-documentation.yml b/changelogs/unreleased/add-yarn-documentation.yml
deleted file mode 100644
index 5bcc01ac177..00000000000
--- a/changelogs/unreleased/add-yarn-documentation.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: add rake tasks to handle yarn dependencies and update documentation
-merge_request: 9316
-author:
diff --git a/changelogs/unreleased/add_mr_info_to_issues_list.yml b/changelogs/unreleased/add_mr_info_to_issues_list.yml
deleted file mode 100644
index 8087aa6296c..00000000000
--- a/changelogs/unreleased/add_mr_info_to_issues_list.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Add merge request count to each issue on issues list
-merge_request: 9252
-author: blackst0ne
diff --git a/changelogs/unreleased/alphabetically_sort_tags_on_runner_list.yml b/changelogs/unreleased/alphabetically_sort_tags_on_runner_list.yml
deleted file mode 100644
index ffcf197a596..00000000000
--- a/changelogs/unreleased/alphabetically_sort_tags_on_runner_list.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Alphabetically sort tags on runner list
-merge_request: 8922
-author: blackst0ne
diff --git a/changelogs/unreleased/api-drop-subscribed.yml b/changelogs/unreleased/api-drop-subscribed.yml
deleted file mode 100644
index 2a39026b519..00000000000
--- a/changelogs/unreleased/api-drop-subscribed.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Remove "subscribed" field from API responses returning list of issues or merge
- requests
-merge_request: 9661
-author:
diff --git a/changelogs/unreleased/api-empty-return.yml b/changelogs/unreleased/api-empty-return.yml
deleted file mode 100644
index 7810e83eb0e..00000000000
--- a/changelogs/unreleased/api-empty-return.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: 'API: Return 204 for all delete endpoints'
-merge_request: 9397
-author: Robert Schilling
diff --git a/changelogs/unreleased/api-entities.yml b/changelogs/unreleased/api-entities.yml
deleted file mode 100644
index 2003d00fd52..00000000000
--- a/changelogs/unreleased/api-entities.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: "Use an entity for RepoBranch commits and enhance RepoCommit"
-merge_request: 7138
-author: Ben Boeckel
diff --git a/changelogs/unreleased/api-notes-entity-fields.yml b/changelogs/unreleased/api-notes-entity-fields.yml
deleted file mode 100644
index f7631df31e2..00000000000
--- a/changelogs/unreleased/api-notes-entity-fields.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: 'API: Remove deprecated fields Notes#upvotes and Notes#downvotes'
-merge_request: 9384
-author: Robert Schilling
diff --git a/changelogs/unreleased/api-post-block.yml b/changelogs/unreleased/api-post-block.yml
deleted file mode 100644
index dfc61ffa9e3..00000000000
--- a/changelogs/unreleased/api-post-block.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: 'API: Use POST to (un)block a user'
-merge_request: 9371
-author: Robert Schilling
diff --git a/changelogs/unreleased/api-project-issues-404.yml b/changelogs/unreleased/api-project-issues-404.yml
deleted file mode 100644
index ce40395c99e..00000000000
--- a/changelogs/unreleased/api-project-issues-404.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Return 404 in project issues API endpoint when project cannot be found
-merge_request: 10093
-author:
diff --git a/changelogs/unreleased/api-remove-deploy-key-disable.yml b/changelogs/unreleased/api-remove-deploy-key-disable.yml
deleted file mode 100644
index f471ad2aa20..00000000000
--- a/changelogs/unreleased/api-remove-deploy-key-disable.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: 'API: Remove `DELETE projects/:id/deploy_keys/:key_id/disable`'
-merge_request: 9365
-author: Robert Schilling
diff --git a/changelogs/unreleased/api-remove-owned-groups.yml b/changelogs/unreleased/api-remove-owned-groups.yml
deleted file mode 100644
index cf0301b7fe0..00000000000
--- a/changelogs/unreleased/api-remove-owned-groups.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: 'API: Remove /groups/owned endpoint'
-merge_request: 9505
-author: Robert Schilling
diff --git a/changelogs/unreleased/api-star-restful.yml b/changelogs/unreleased/api-star-restful.yml
deleted file mode 100644
index 3e7de8cd822..00000000000
--- a/changelogs/unreleased/api-star-restful.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: 'API: Moved `DELETE /projects/:id/star` to `POST /projects/:id/unstar`'
-merge_request: 9328
-author: Robert Schilling
diff --git a/changelogs/unreleased/api-subscription-restful.yml b/changelogs/unreleased/api-subscription-restful.yml
deleted file mode 100644
index 95db470e6c9..00000000000
--- a/changelogs/unreleased/api-subscription-restful.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: 'API: - Make subscription API more RESTful. Use `post ":project_id/:subscribable_type/:subscribable_id/subscribe"` to subscribe and `post ":project_id/:subscribable_type/:subscribable_id/unsubscribe"` to unsubscribe from a resource.'
-merge_request: 9325
-author: Robert Schilling
diff --git a/changelogs/unreleased/api-todos-restful.yml b/changelogs/unreleased/api-todos-restful.yml
deleted file mode 100644
index dba1350a495..00000000000
--- a/changelogs/unreleased/api-todos-restful.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: 'API: Use POST requests to mark todos as done'
-merge_request: 9410
-author: Robert Schilling
diff --git a/changelogs/unreleased/artifactsdoc.yml b/changelogs/unreleased/artifactsdoc.yml
deleted file mode 100644
index 4ef32d5256f..00000000000
--- a/changelogs/unreleased/artifactsdoc.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Added documentation for permalinks to most recent build artifacts.
-merge_request: 8934
-author: Christian Godenschwager
diff --git a/changelogs/unreleased/backup_storage_class.yml b/changelogs/unreleased/backup_storage_class.yml
deleted file mode 100644
index fc9989fc251..00000000000
--- a/changelogs/unreleased/backup_storage_class.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Add storage class configuration option for Amazon S3 remote backups
-merge_request:
-author: Jon Keys
diff --git a/changelogs/unreleased/beautiful-karma-output.yml b/changelogs/unreleased/beautiful-karma-output.yml
deleted file mode 100644
index 6ccddebab68..00000000000
--- a/changelogs/unreleased/beautiful-karma-output.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Make Karma output look nicer for CI
-merge_request: 9165
-author: winniehell
diff --git a/changelogs/unreleased/branch_deletion.yml b/changelogs/unreleased/branch_deletion.yml
deleted file mode 100644
index dbc9265a1fb..00000000000
--- a/changelogs/unreleased/branch_deletion.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: on branch deletion show loading icon and disabled the button
-merge_request: 6761
-author: wendy0402
diff --git a/changelogs/unreleased/bypass-email-domain-validation-when-created-by-admin.yml b/changelogs/unreleased/bypass-email-domain-validation-when-created-by-admin.yml
deleted file mode 100644
index f335ae27fda..00000000000
--- a/changelogs/unreleased/bypass-email-domain-validation-when-created-by-admin.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Bypass email domain validation when a user is created by an admin.
-merge_request: 8575
-author: Reza Mohammadi @remohammadi
diff --git a/changelogs/unreleased/cleaner-additional-award-emoji-button.yml b/changelogs/unreleased/cleaner-additional-award-emoji-button.yml
new file mode 100644
index 00000000000..84685f4bd45
--- /dev/null
+++ b/changelogs/unreleased/cleaner-additional-award-emoji-button.yml
@@ -0,0 +1,4 @@
+---
+title: Removed unnecessary 'add' text in additional award emoji button
+merge_request:
+author:
diff --git a/changelogs/unreleased/clear-connections-before-starting-sidekiq.yml b/changelogs/unreleased/clear-connections-before-starting-sidekiq.yml
deleted file mode 100644
index 8778fac6e9d..00000000000
--- a/changelogs/unreleased/clear-connections-before-starting-sidekiq.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Clear ActiveRecord connections before starting Sidekiq
-merge_request:
-author:
diff --git a/changelogs/unreleased/commons-chunk-plugin.yml b/changelogs/unreleased/commons-chunk-plugin.yml
deleted file mode 100644
index 5c11ea3bbb2..00000000000
--- a/changelogs/unreleased/commons-chunk-plugin.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Use webpack CommonsChunkPlugin to place common javascript libraries in their
- own bundles
-merge_request: 9647
-author:
diff --git a/changelogs/unreleased/copy-branch-to-clipboard.yml b/changelogs/unreleased/copy-branch-to-clipboard.yml
deleted file mode 100644
index c12e324ed3c..00000000000
--- a/changelogs/unreleased/copy-branch-to-clipboard.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Added the ability to copy a branch name to the clipboard
-merge_request: 9103
-author: Glenn Sayers
diff --git a/changelogs/unreleased/cover-my-karma.yml b/changelogs/unreleased/cover-my-karma.yml
deleted file mode 100644
index 4a823dc5ca4..00000000000
--- a/changelogs/unreleased/cover-my-karma.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Reintroduce coverage report for JavaScript
-merge_request: 9133
-author: winniehell
diff --git a/changelogs/unreleased/create_branch_repo_less.yml b/changelogs/unreleased/create_branch_repo_less.yml
deleted file mode 100644
index e8b14fa3b67..00000000000
--- a/changelogs/unreleased/create_branch_repo_less.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Creating a new branch from an issue will automatically initialize a repository if one doesn't already exist.
-merge_request:
-author:
diff --git a/changelogs/unreleased/dashboard-filter-search-keep-params.yml b/changelogs/unreleased/dashboard-filter-search-keep-params.yml
deleted file mode 100644
index a140715b7a2..00000000000
--- a/changelogs/unreleased/dashboard-filter-search-keep-params.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Dashboard project search keeps selected sort & filters
-merge_request:
-author:
diff --git a/changelogs/unreleased/delete-artifacts-for-pages.yml b/changelogs/unreleased/delete-artifacts-for-pages.yml
deleted file mode 100644
index 50b3dd81d60..00000000000
--- a/changelogs/unreleased/delete-artifacts-for-pages.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Delete artifacts for pages unless expiry date is specified
-merge_request: 9716
-author:
diff --git a/changelogs/unreleased/diff-make-obvious-cant-comment.yml b/changelogs/unreleased/diff-make-obvious-cant-comment.yml
deleted file mode 100644
index 2cb95947939..00000000000
--- a/changelogs/unreleased/diff-make-obvious-cant-comment.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Visually show expanded diff lines cant have comments
-merge_request:
-author:
diff --git a/changelogs/unreleased/dm-group-reference-full-name.yml b/changelogs/unreleased/dm-group-reference-full-name.yml
deleted file mode 100644
index f445d955529..00000000000
--- a/changelogs/unreleased/dm-group-reference-full-name.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Use full group name in GFM group reference title
-merge_request:
-author:
diff --git a/changelogs/unreleased/dynamic-header-fixture.yml b/changelogs/unreleased/dynamic-header-fixture.yml
deleted file mode 100644
index 9789a1999c8..00000000000
--- a/changelogs/unreleased/dynamic-header-fixture.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Replace static fixture for header_spec.js
-merge_request: 9174
-author: winniehell
diff --git a/changelogs/unreleased/dynamic-project-title-fixture.yml b/changelogs/unreleased/dynamic-project-title-fixture.yml
deleted file mode 100644
index 2404cbb891c..00000000000
--- a/changelogs/unreleased/dynamic-project-title-fixture.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Replace static fixture for project_title_spec.js
-merge_request: 9175
-author: winniehell
diff --git a/changelogs/unreleased/dz-blacklist--names.yml b/changelogs/unreleased/dz-blacklist--names.yml
deleted file mode 100644
index 2941965002d..00000000000
--- a/changelogs/unreleased/dz-blacklist--names.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Reserve few project and nested group paths that have wildcard routes associated
-merge_request: 9898
-author:
diff --git a/changelogs/unreleased/dz-change-project-view.yml b/changelogs/unreleased/dz-change-project-view.yml
deleted file mode 100644
index 47e007a80a8..00000000000
--- a/changelogs/unreleased/dz-change-project-view.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Change default project view for user from readme to files view
-merge_request: 9584
-author:
diff --git a/changelogs/unreleased/dz-create-nested-groups-via-ui.yml b/changelogs/unreleased/dz-create-nested-groups-via-ui.yml
deleted file mode 100644
index f9529a5941a..00000000000
--- a/changelogs/unreleased/dz-create-nested-groups-via-ui.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Allow creating nested groups via UI
-merge_request: 8786
-author:
diff --git a/changelogs/unreleased/dz-dashboard-groups-search.yml b/changelogs/unreleased/dz-dashboard-groups-search.yml
deleted file mode 100644
index c473cba774d..00000000000
--- a/changelogs/unreleased/dz-dashboard-groups-search.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Add filter and sorting to dashboard groups page
-merge_request: 9619
-author:
diff --git a/changelogs/unreleased/dz-nested-groups-api.yml b/changelogs/unreleased/dz-nested-groups-api.yml
deleted file mode 100644
index d33ff42700f..00000000000
--- a/changelogs/unreleased/dz-nested-groups-api.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Add nested groups to the API
-merge_request: 9034
-author:
diff --git a/changelogs/unreleased/dz-nested-groups-members.yml b/changelogs/unreleased/dz-nested-groups-members.yml
deleted file mode 100644
index bab0c8465c2..00000000000
--- a/changelogs/unreleased/dz-nested-groups-members.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Show members of parent groups on project members page
-merge_request:
-author:
diff --git a/changelogs/unreleased/dz-nested-groups-restrictions.yml b/changelogs/unreleased/dz-nested-groups-restrictions.yml
deleted file mode 100644
index 2ffb6032525..00000000000
--- a/changelogs/unreleased/dz-nested-groups-restrictions.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Restrict nested group names to prevent ambiguous routes
-merge_request: 9738
-author:
diff --git a/changelogs/unreleased/dz-refactor-full-path.yml b/changelogs/unreleased/dz-refactor-full-path.yml
deleted file mode 100644
index da8568fd220..00000000000
--- a/changelogs/unreleased/dz-refactor-full-path.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Store group and project full name and full path in routes table
-merge_request: 8979
-author:
diff --git a/changelogs/unreleased/etag-notes-polling.yml b/changelogs/unreleased/etag-notes-polling.yml
deleted file mode 100644
index 53990821d25..00000000000
--- a/changelogs/unreleased/etag-notes-polling.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Use ETag to improve performance of issue notes polling
-merge_request: 9036
-author:
diff --git a/changelogs/unreleased/expose-pagination-headers.yml b/changelogs/unreleased/expose-pagination-headers.yml
deleted file mode 100644
index 1b4cd43fa06..00000000000
--- a/changelogs/unreleased/expose-pagination-headers.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: 'CORS: Whitelist pagination headers'
-merge_request: 9651
-author: Robert Schilling
diff --git a/changelogs/unreleased/fe-paginated-environments-api-add-subview.yml b/changelogs/unreleased/fe-paginated-environments-api-add-subview.yml
deleted file mode 100644
index 7e626982de6..00000000000
--- a/changelogs/unreleased/fe-paginated-environments-api-add-subview.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Adds paginationd and folders view to environments table
-merge_request:
-author:
diff --git a/changelogs/unreleased/feature-brand-logo-in-emails.yml b/changelogs/unreleased/feature-brand-logo-in-emails.yml
deleted file mode 100644
index a7674b9b25e..00000000000
--- a/changelogs/unreleased/feature-brand-logo-in-emails.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Brand header logo for pipeline emails
-merge_request: 9049
-author: Alexis Reigel
diff --git a/changelogs/unreleased/feature-github-find-users-by-email.yml b/changelogs/unreleased/feature-github-find-users-by-email.yml
deleted file mode 100644
index 1503cf2b9f7..00000000000
--- a/changelogs/unreleased/feature-github-find-users-by-email.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: GitHub Importer - Find users based on GitHub email address
-merge_request: 8958
-author:
diff --git a/changelogs/unreleased/feature-openid-connect.yml b/changelogs/unreleased/feature-openid-connect.yml
deleted file mode 100644
index e84eb7aff86..00000000000
--- a/changelogs/unreleased/feature-openid-connect.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Implement OpenID Connect identity provider
-merge_request: 8018
-author: Markus Koller
diff --git a/changelogs/unreleased/feature-runner-jobs-v4-api.yml b/changelogs/unreleased/feature-runner-jobs-v4-api.yml
deleted file mode 100644
index b24ea65266d..00000000000
--- a/changelogs/unreleased/feature-runner-jobs-v4-api.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Add Runner's jobs v4 API
-merge_request: 9273
-author:
diff --git a/changelogs/unreleased/feature-runners-registration-deletion-v4-api.yml b/changelogs/unreleased/feature-runners-registration-deletion-v4-api.yml
deleted file mode 100644
index e646a6a17b7..00000000000
--- a/changelogs/unreleased/feature-runners-registration-deletion-v4-api.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Add Runner's registration/deletion v4 API
-merge_request: 9246
-author:
diff --git a/changelogs/unreleased/feature-syshook_commits.yml b/changelogs/unreleased/feature-syshook_commits.yml
deleted file mode 100644
index 1305f5cd414..00000000000
--- a/changelogs/unreleased/feature-syshook_commits.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Added commit array to Syshook json
-merge_request: 9685
-author: Gabriele Pongelli
diff --git a/changelogs/unreleased/filter-bar-fix-ie.yml b/changelogs/unreleased/filter-bar-fix-ie.yml
new file mode 100644
index 00000000000..f1fa7d9b177
--- /dev/null
+++ b/changelogs/unreleased/filter-bar-fix-ie.yml
@@ -0,0 +1,4 @@
+---
+title: Fixed filtered search not working in IE
+merge_request:
+author:
diff --git a/changelogs/unreleased/fix-cycle-analytics-events-limit.yml b/changelogs/unreleased/fix-cycle-analytics-events-limit.yml
deleted file mode 100644
index 152b37ca430..00000000000
--- a/changelogs/unreleased/fix-cycle-analytics-events-limit.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Add limit to the number of events showed in cycle analytics
-merge_request:
-author:
diff --git a/changelogs/unreleased/fix-gb-deprecate-ci-config-types.yml b/changelogs/unreleased/fix-gb-deprecate-ci-config-types.yml
deleted file mode 100644
index 605b5f01d0e..00000000000
--- a/changelogs/unreleased/fix-gb-deprecate-ci-config-types.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Deprecate usage of `types` configuration entry to describe CI/CD stages
-merge_request: 9766
-author:
diff --git a/changelogs/unreleased/fix-gb-notification-settings-when-no-repository.yml b/changelogs/unreleased/fix-gb-notification-settings-when-no-repository.yml
deleted file mode 100644
index 17fd1336b8e..00000000000
--- a/changelogs/unreleased/fix-gb-notification-settings-when-no-repository.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Show notifications settings dropdown even if repository feature is disabled
-merge_request: 9180
-author:
diff --git a/changelogs/unreleased/fix-gb-passed-with-warnings-status-on-mysql.yml b/changelogs/unreleased/fix-gb-passed-with-warnings-status-on-mysql.yml
deleted file mode 100644
index 6365b1a1910..00000000000
--- a/changelogs/unreleased/fix-gb-passed-with-warnings-status-on-mysql.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Fix "passed with warnings" stage status on MySQL installations
-merge_request: 9802
-author:
diff --git a/changelogs/unreleased/fix-gb-pipeline-retry-builds-started.yml b/changelogs/unreleased/fix-gb-pipeline-retry-builds-started.yml
deleted file mode 100644
index 49e243ca6bb..00000000000
--- a/changelogs/unreleased/fix-gb-pipeline-retry-builds-started.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Fix CI/CD pipeline retry and take stages order into account
-merge_request: 9021
-author:
diff --git a/changelogs/unreleased/fix-gb-pipeline-retry-cancel-buttons-consistency.yml b/changelogs/unreleased/fix-gb-pipeline-retry-cancel-buttons-consistency.yml
deleted file mode 100644
index d747e0e63a3..00000000000
--- a/changelogs/unreleased/fix-gb-pipeline-retry-cancel-buttons-consistency.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Fix pipeline retry and cancel buttons on pipeline details page
-merge_request: 9225
-author:
diff --git a/changelogs/unreleased/fix-gb-remove-deprecated-ci-build-status-badge.yml b/changelogs/unreleased/fix-gb-remove-deprecated-ci-build-status-badge.yml
deleted file mode 100644
index 71ff768a190..00000000000
--- a/changelogs/unreleased/fix-gb-remove-deprecated-ci-build-status-badge.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Remove deprecated build status badge and related services
-merge_request: 9620
-author:
diff --git a/changelogs/unreleased/fix-gb-update-commit-status-api.yml b/changelogs/unreleased/fix-gb-update-commit-status-api.yml
deleted file mode 100644
index aa4fcba4e89..00000000000
--- a/changelogs/unreleased/fix-gb-update-commit-status-api.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Fix updaing commit status when using optional attributes
-merge_request: 9618
-author:
diff --git a/changelogs/unreleased/fix-mentioned-issues-for-external-trackers.yml b/changelogs/unreleased/fix-mentioned-issues-for-external-trackers.yml
deleted file mode 100644
index ee827b7c939..00000000000
--- a/changelogs/unreleased/fix-mentioned-issues-for-external-trackers.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Fix issues mentioned but not closed for external issue trackers
-merge_request:
-author:
diff --git a/changelogs/unreleased/fix-prometheus-including-d3-main-bundle.yml b/changelogs/unreleased/fix-prometheus-including-d3-main-bundle.yml
deleted file mode 100644
index a42b0db3cfc..00000000000
--- a/changelogs/unreleased/fix-prometheus-including-d3-main-bundle.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Removed d3 from the main application.js bundle
-merge_request: 10062
-author:
diff --git a/changelogs/unreleased/fix-slow-queries-for-branches-index.yml b/changelogs/unreleased/fix-slow-queries-for-branches-index.yml
deleted file mode 100644
index f5bd7003615..00000000000
--- a/changelogs/unreleased/fix-slow-queries-for-branches-index.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Fixes n+1 query for tags and branches index page
-merge_request: 9905
-author:
diff --git a/changelogs/unreleased/fix_issue_from_milestone.yml b/changelogs/unreleased/fix_issue_from_milestone.yml
deleted file mode 100644
index 02581e3ea09..00000000000
--- a/changelogs/unreleased/fix_issue_from_milestone.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: fix milestone does not automatically assign when create issue from milestone
-merge_request:
-author:
diff --git a/changelogs/unreleased/fixes-namespace-api-documentation.yml b/changelogs/unreleased/fixes-namespace-api-documentation.yml
deleted file mode 100644
index 6b578bb1602..00000000000
--- a/changelogs/unreleased/fixes-namespace-api-documentation.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Update API docs for new namespace format
-merge_request: 9073
-author: Markus Koller
diff --git a/changelogs/unreleased/format-timeago-date.yml b/changelogs/unreleased/format-timeago-date.yml
deleted file mode 100644
index f331c34abbc..00000000000
--- a/changelogs/unreleased/format-timeago-date.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Format timeago date to short format
-merge_request:
-author:
diff --git a/changelogs/unreleased/gfm-autocomplete-fixes.yml b/changelogs/unreleased/gfm-autocomplete-fixes.yml
deleted file mode 100644
index 737e2ad5234..00000000000
--- a/changelogs/unreleased/gfm-autocomplete-fixes.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Fix errors in slash commands matcher, add simple test coverage
-merge_request:
-author: YarNayar
diff --git a/changelogs/unreleased/gitaly-post-receive.yml b/changelogs/unreleased/gitaly-post-receive.yml
deleted file mode 100644
index cf206e39084..00000000000
--- a/changelogs/unreleased/gitaly-post-receive.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Add internal API to notify Gitaly of post receive
-merge_request: 8983
-author:
diff --git a/changelogs/unreleased/group-memebrs-owner-level.yml b/changelogs/unreleased/group-memebrs-owner-level.yml
deleted file mode 100644
index ba77f38eb6d..00000000000
--- a/changelogs/unreleased/group-memebrs-owner-level.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Added option to update to owner for group members
-merge_request:
-author:
diff --git a/changelogs/unreleased/instrument-in-karma.yml b/changelogs/unreleased/instrument-in-karma.yml
deleted file mode 100644
index cfabf2569fe..00000000000
--- a/changelogs/unreleased/instrument-in-karma.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Move babel config for instanbul to karma config
-merge_request: 9286
-author: winniehell
diff --git a/changelogs/unreleased/introduce-pipeline-triggers.yml b/changelogs/unreleased/introduce-pipeline-triggers.yml
deleted file mode 100644
index ce5a230d48f..00000000000
--- a/changelogs/unreleased/introduce-pipeline-triggers.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Introduce Pipeline Triggers that are user-aware
-merge_request:
-author:
diff --git a/changelogs/unreleased/issue-boards-cant-drag-fix.yml b/changelogs/unreleased/issue-boards-cant-drag-fix.yml
new file mode 100644
index 00000000000..ac92573abe8
--- /dev/null
+++ b/changelogs/unreleased/issue-boards-cant-drag-fix.yml
@@ -0,0 +1,4 @@
+---
+title: Fixed bug in issue boards which stopped cards being able to be dragged
+merge_request:
+author:
diff --git a/changelogs/unreleased/issue-descrpiption-spinner-off.yml b/changelogs/unreleased/issue-descrpiption-spinner-off.yml
deleted file mode 100644
index 87104d09804..00000000000
--- a/changelogs/unreleased/issue-descrpiption-spinner-off.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Fixed loading spinner position on issue template toggle
-merge_request:
-author:
diff --git a/changelogs/unreleased/issue-newproj-layout.yml b/changelogs/unreleased/issue-newproj-layout.yml
deleted file mode 100644
index d15e8b7d1e5..00000000000
--- a/changelogs/unreleased/issue-newproj-layout.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Removed duplicate "Visibility Level" label on New Project page
-merge_request:
-author: Robert Marcano
diff --git a/changelogs/unreleased/issue-tags-layout.yml b/changelogs/unreleased/issue-tags-layout.yml
deleted file mode 100644
index abf4a609932..00000000000
--- a/changelogs/unreleased/issue-tags-layout.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Fix 'New Tag' layout on Tags page
-merge_request:
-author: Robert Marcano
diff --git a/changelogs/unreleased/issue_16834.yml b/changelogs/unreleased/issue_16834.yml
deleted file mode 100644
index 06175579ac3..00000000000
--- a/changelogs/unreleased/issue_16834.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Update API endpoints for raw files
-merge_request:
-author:
diff --git a/changelogs/unreleased/issue_24815.yml b/changelogs/unreleased/issue_24815.yml
deleted file mode 100644
index 916e47d36a9..00000000000
--- a/changelogs/unreleased/issue_24815.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Fix issuable stale object error handler for js when updating tasklists
-merge_request:
-author:
diff --git a/changelogs/unreleased/issue_25900.yml b/changelogs/unreleased/issue_25900.yml
deleted file mode 100644
index b4b72b8a20c..00000000000
--- a/changelogs/unreleased/issue_25900.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Gather issuable metadata to avoid n+1 queries on index view
-merge_request:
-author:
diff --git a/changelogs/unreleased/issue_26701.yml b/changelogs/unreleased/issue_26701.yml
deleted file mode 100644
index 6834351bf43..00000000000
--- a/changelogs/unreleased/issue_26701.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Remove JIRA closed status icon
-merge_request:
-author:
diff --git a/changelogs/unreleased/list_issues_with_no_labels.yml b/changelogs/unreleased/list_issues_with_no_labels.yml
deleted file mode 100644
index ab44841631b..00000000000
--- a/changelogs/unreleased/list_issues_with_no_labels.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Document ability to list issues with no labels using API
-merge_request: 9697
-author: Vignesh Ravichandran
diff --git a/changelogs/unreleased/lnovy-gitlab-ce-empty-variables.yml b/changelogs/unreleased/lnovy-gitlab-ce-empty-variables.yml
deleted file mode 100644
index bd5db5ac7af..00000000000
--- a/changelogs/unreleased/lnovy-gitlab-ce-empty-variables.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: 'UI: Allow a project variable to be set to an empty value'
-merge_request: 6044
-author: Lukáš Nový
diff --git a/changelogs/unreleased/long-file-name-overflow.yml b/changelogs/unreleased/long-file-name-overflow.yml
deleted file mode 100644
index 7ccf05491e1..00000000000
--- a/changelogs/unreleased/long-file-name-overflow.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Fixed long file names overflowing under action buttons
-merge_request:
-author:
diff --git a/changelogs/unreleased/migrate-pipeline-events-and-email-service.yml b/changelogs/unreleased/migrate-pipeline-events-and-email-service.yml
deleted file mode 100644
index ce4d5092c17..00000000000
--- a/changelogs/unreleased/migrate-pipeline-events-and-email-service.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Migrate SlackService and MattermostService from build_events to pipeline_events, and migrate BuildsEmailService to PipelinesEmailService. Update Hipchat to use pipeline events rather than build events.
-merge_request: 8196
-author:
diff --git a/changelogs/unreleased/mock-ci-service.yml b/changelogs/unreleased/mock-ci-service.yml
deleted file mode 100644
index 24c6366177f..00000000000
--- a/changelogs/unreleased/mock-ci-service.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Add Mock CI service/integration for development
-merge_request:
-author:
diff --git a/changelogs/unreleased/move_tags_service_to_namespace.yml b/changelogs/unreleased/move_tags_service_to_namespace.yml
deleted file mode 100644
index ba76f291162..00000000000
--- a/changelogs/unreleased/move_tags_service_to_namespace.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Move tag services to Tags namespace
-merge_request:
-author: dixpac
diff --git a/changelogs/unreleased/moving-issue-with-two-list-labels.yml b/changelogs/unreleased/moving-issue-with-two-list-labels.yml
deleted file mode 100644
index d5ea81e3810..00000000000
--- a/changelogs/unreleased/moving-issue-with-two-list-labels.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Removes label when moving issue to another list that it is currently in
-merge_request:
-author:
diff --git a/changelogs/unreleased/mr-diff-comment-button.yml b/changelogs/unreleased/mr-diff-comment-button.yml
deleted file mode 100644
index 1dc6ed1c495..00000000000
--- a/changelogs/unreleased/mr-diff-comment-button.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Improved diff comment button UX
-merge_request:
-author:
diff --git a/changelogs/unreleased/new-branch-fixture.yml b/changelogs/unreleased/new-branch-fixture.yml
deleted file mode 100644
index ce5ed816102..00000000000
--- a/changelogs/unreleased/new-branch-fixture.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Replace static fixture for new_branch_spec.js
-merge_request: 9131
-author: winniehell
diff --git a/changelogs/unreleased/only-create-unmergeable-todo-once.yml b/changelogs/unreleased/only-create-unmergeable-todo-once.yml
deleted file mode 100644
index e675ed945ad..00000000000
--- a/changelogs/unreleased/only-create-unmergeable-todo-once.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Only create unmergeable todos once when MR fails to merge
-merge_request:
-author:
diff --git a/changelogs/unreleased/only-yield-valid-reference-matches.yml b/changelogs/unreleased/only-yield-valid-reference-matches.yml
deleted file mode 100644
index 95da3cc56fd..00000000000
--- a/changelogs/unreleased/only-yield-valid-reference-matches.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Only yield valid references in ReferenceFilter.references_in
-merge_request:
-author:
diff --git a/changelogs/unreleased/pages-0-4-0.yml b/changelogs/unreleased/pages-0-4-0.yml
deleted file mode 100644
index 7286b25125e..00000000000
--- a/changelogs/unreleased/pages-0-4-0.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Use GitLab Pages v0.4.0
-merge_request: 9896
-author:
diff --git a/changelogs/unreleased/paginate-all-the-things.yml b/changelogs/unreleased/paginate-all-the-things.yml
deleted file mode 100644
index 52f23ba52a9..00000000000
--- a/changelogs/unreleased/paginate-all-the-things.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: 'API: Paginate all endpoints that return an array'
-merge_request: 8606
-author: Robert Schilling
diff --git a/changelogs/unreleased/pass in current_user in MergeRequest and MergeRequestsHelper.yml b/changelogs/unreleased/pass in current_user in MergeRequest and MergeRequestsHelper.yml
deleted file mode 100644
index 0751047c3c0..00000000000
--- a/changelogs/unreleased/pass in current_user in MergeRequest and MergeRequestsHelper.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: pass in current_user in MergeRequest and MergeRequestsHelper
-merge_request: 8624
-author: Dongqing Hu
diff --git a/changelogs/unreleased/pass_coverage_value_to_commit_status_api.yml b/changelogs/unreleased/pass_coverage_value_to_commit_status_api.yml
deleted file mode 100644
index 74e0c18fa67..00000000000
--- a/changelogs/unreleased/pass_coverage_value_to_commit_status_api.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Make it possible to pass coverage value to commit status API
-merge_request: 9214
-author: wendy0402
diff --git a/changelogs/unreleased/pipeline-blocking-actions.yml b/changelogs/unreleased/pipeline-blocking-actions.yml
deleted file mode 100644
index 6bde501de18..00000000000
--- a/changelogs/unreleased/pipeline-blocking-actions.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Make it possible to configure blocking manual actions
-merge_request: 9585
-author:
diff --git a/changelogs/unreleased/pipelines-build-tooltip.yml b/changelogs/unreleased/pipelines-build-tooltip.yml
new file mode 100644
index 00000000000..000276e1de3
--- /dev/null
+++ b/changelogs/unreleased/pipelines-build-tooltip.yml
@@ -0,0 +1,4 @@
+---
+title: Fixed job tooltip being cut-off
+merge_request:
+author:
diff --git a/changelogs/unreleased/priority-to-label-priority.yml b/changelogs/unreleased/priority-to-label-priority.yml
deleted file mode 100644
index 2d9c58bfd9b..00000000000
--- a/changelogs/unreleased/priority-to-label-priority.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Rename priority sorting option to label priority
-merge_request:
-author:
diff --git a/changelogs/unreleased/protected-branch-dropdown-titles.yml b/changelogs/unreleased/protected-branch-dropdown-titles.yml
deleted file mode 100644
index df82cc00fc9..00000000000
--- a/changelogs/unreleased/protected-branch-dropdown-titles.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Added headers to protected branch access dropdowns
-merge_request:
-author:
diff --git a/changelogs/unreleased/quick-submit-fixture.yml b/changelogs/unreleased/quick-submit-fixture.yml
deleted file mode 100644
index a2cf05dabec..00000000000
--- a/changelogs/unreleased/quick-submit-fixture.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Replace static fixture for behaviors/quick_submit_spec.js
-merge_request: 9086
-author: winniehell
diff --git a/changelogs/unreleased/removal_of_unused_parameter.yml b/changelogs/unreleased/removal_of_unused_parameter.yml
deleted file mode 100644
index 26bffafd9d9..00000000000
--- a/changelogs/unreleased/removal_of_unused_parameter.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: 'removed unused parameter ''status_only: true'''
-merge_request:
-author:
diff --git a/changelogs/unreleased/remove-es6-extension.yml b/changelogs/unreleased/remove-es6-extension.yml
deleted file mode 100644
index 65f4a7a7867..00000000000
--- a/changelogs/unreleased/remove-es6-extension.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Remove es6 file extension from JavaScript files
-merge_request: 9241
-author: winniehell
diff --git a/changelogs/unreleased/remove-inactive-default-email-services.yml b/changelogs/unreleased/remove-inactive-default-email-services.yml
deleted file mode 100644
index c32c1390e4e..00000000000
--- a/changelogs/unreleased/remove-inactive-default-email-services.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Remove inactive default email services
-merge_request: 8987
-author:
diff --git a/changelogs/unreleased/remove-jquery-ui-datepicker.yml b/changelogs/unreleased/remove-jquery-ui-datepicker.yml
deleted file mode 100644
index cd00690d774..00000000000
--- a/changelogs/unreleased/remove-jquery-ui-datepicker.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Replaced jQuery UI datepicker
-merge_request:
-author:
diff --git a/changelogs/unreleased/remove-jquery-ui-plugins.yml b/changelogs/unreleased/remove-jquery-ui-plugins.yml
deleted file mode 100644
index c768f702ba2..00000000000
--- a/changelogs/unreleased/remove-jquery-ui-plugins.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Removed jQuery UI highlight & autocomplete
-merge_request:
-author:
diff --git a/changelogs/unreleased/remove-jquery-ui-sortable.yml b/changelogs/unreleased/remove-jquery-ui-sortable.yml
deleted file mode 100644
index 35f47822738..00000000000
--- a/changelogs/unreleased/remove-jquery-ui-sortable.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Replaced jQuery UI sortable
-merge_request:
-author:
diff --git a/changelogs/unreleased/remove-new-relic-gem.yml b/changelogs/unreleased/remove-new-relic-gem.yml
deleted file mode 100644
index b15ecd3e4e7..00000000000
--- a/changelogs/unreleased/remove-new-relic-gem.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Remove the newrelic gem
-merge_request: 9622
-author: Robert Schilling
diff --git a/changelogs/unreleased/remove-readme-option.yml b/changelogs/unreleased/remove-readme-option.yml
deleted file mode 100644
index 1d4c862c00e..00000000000
--- a/changelogs/unreleased/remove-readme-option.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Remove readme-only project view preference
-merge_request:
-author:
diff --git a/changelogs/unreleased/remove-subscribe-label-tooltip.yml b/changelogs/unreleased/remove-subscribe-label-tooltip.yml
deleted file mode 100644
index 90b71d3be51..00000000000
--- a/changelogs/unreleased/remove-subscribe-label-tooltip.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Remove tooltips from label subscription buttons
-merge_request:
-author:
diff --git a/changelogs/unreleased/remove-unused-ci-tables.yml b/changelogs/unreleased/remove-unused-ci-tables.yml
deleted file mode 100644
index fccfb882bd9..00000000000
--- a/changelogs/unreleased/remove-unused-ci-tables.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Remove various unused CI tables and columns
-merge_request: 9639
-author:
diff --git a/changelogs/unreleased/rename-ci_commits-to-ci_pipeline.yml b/changelogs/unreleased/rename-ci_commits-to-ci_pipeline.yml
deleted file mode 100644
index 4067b3de00c..00000000000
--- a/changelogs/unreleased/rename-ci_commits-to-ci_pipeline.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Rename table ci_commits to ci_pipelines
-merge_request: 9638
-author:
diff --git a/changelogs/unreleased/rename-retry-failed-pipeline-to-retry.yml b/changelogs/unreleased/rename-retry-failed-pipeline-to-retry.yml
deleted file mode 100644
index b813127b1e6..00000000000
--- a/changelogs/unreleased/rename-retry-failed-pipeline-to-retry.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Rename retry failed button on pipeline page to just retry
-merge_request:
-author:
diff --git a/changelogs/unreleased/rename_delete_services.yml b/changelogs/unreleased/rename_delete_services.yml
deleted file mode 100644
index 686a1ef3d55..00000000000
--- a/changelogs/unreleased/rename_delete_services.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Fix inconsistent naming for services that delete things
-merge_request: 5803
-author: dixpac
diff --git a/changelogs/unreleased/rename_files_delete_service.yml b/changelogs/unreleased/rename_files_delete_service.yml
deleted file mode 100644
index 4de1c5b0d63..00000000000
--- a/changelogs/unreleased/rename_files_delete_service.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Rename Files::DeleteService to Files::DestroyService
-merge_request: 9110
-author: dixpac
diff --git a/changelogs/unreleased/replace-npm-with-yarn.yml b/changelogs/unreleased/replace-npm-with-yarn.yml
deleted file mode 100644
index 5e795eb0c8d..00000000000
--- a/changelogs/unreleased/replace-npm-with-yarn.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: replace npm with yarn and add yarn.lock
-merge_request: 9055
-author:
diff --git a/changelogs/unreleased/replace_closing_mr_icon.yml b/changelogs/unreleased/replace_closing_mr_icon.yml
new file mode 100644
index 00000000000..4d7b5fa67a7
--- /dev/null
+++ b/changelogs/unreleased/replace_closing_mr_icon.yml
@@ -0,0 +1,4 @@
+---
+title: Replace closing MR icon
+merge_request: 10103
+author: blackst0ne
diff --git a/changelogs/unreleased/requires-input-fixture.yml b/changelogs/unreleased/requires-input-fixture.yml
deleted file mode 100644
index be674499429..00000000000
--- a/changelogs/unreleased/requires-input-fixture.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Replace static fixture for behaviors/requires_input_spec.js
-merge_request: 9162
-author: winniehell
diff --git a/changelogs/unreleased/rfr-20170307-change-default-project-number-limit.yml b/changelogs/unreleased/rfr-20170307-change-default-project-number-limit.yml
deleted file mode 100644
index e799dd3b48d..00000000000
--- a/changelogs/unreleased/rfr-20170307-change-default-project-number-limit.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Change project count limit from 10 to 100000
-merge_request:
-author:
diff --git a/changelogs/unreleased/routes-lower-case.yml b/changelogs/unreleased/routes-lower-case.yml
deleted file mode 100644
index 2110956680c..00000000000
--- a/changelogs/unreleased/routes-lower-case.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Remove repeated routes.path check for postgresql database
-merge_request:
-author: mhasbini
diff --git a/changelogs/unreleased/rss-btn-alignment-fix.yml b/changelogs/unreleased/rss-btn-alignment-fix.yml
deleted file mode 100644
index c8f57ec0b7c..00000000000
--- a/changelogs/unreleased/rss-btn-alignment-fix.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Fixed RSS button alignment on activity pages
-merge_request:
-author:
diff --git a/changelogs/unreleased/seed-abuse-reports.yml b/changelogs/unreleased/seed-abuse-reports.yml
deleted file mode 100644
index 6fbcb81ae3f..00000000000
--- a/changelogs/unreleased/seed-abuse-reports.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Seed abuse reports for development
-merge_request:
-author:
diff --git a/changelogs/unreleased/set-default-cache-key-for-jobs.yml b/changelogs/unreleased/set-default-cache-key-for-jobs.yml
deleted file mode 100644
index b69348d2ece..00000000000
--- a/changelogs/unreleased/set-default-cache-key-for-jobs.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Set default cache key to "default" for jobs
-merge_request: 9666
-author:
diff --git a/changelogs/unreleased/settings-tab.yml b/changelogs/unreleased/settings-tab.yml
deleted file mode 100644
index 69990c9a917..00000000000
--- a/changelogs/unreleased/settings-tab.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Moved project settings from the gear drop-down menu to a tab
-merge_request: 9786
-author:
diff --git a/changelogs/unreleased/sh-bump-hashie-to-3-5-5.yml b/changelogs/unreleased/sh-bump-hashie-to-3-5-5.yml
deleted file mode 100644
index 57f1474093a..00000000000
--- a/changelogs/unreleased/sh-bump-hashie-to-3-5-5.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Bump Hashie to 3.5.5 and omniauth to 1.4.2 to eliminate warning noise
-merge_request:
-author:
diff --git a/changelogs/unreleased/sh-delete-user-permission-check.yml b/changelogs/unreleased/sh-delete-user-permission-check.yml
deleted file mode 100644
index c0e79aae2a8..00000000000
--- a/changelogs/unreleased/sh-delete-user-permission-check.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Add user deletion permission check in `Users::DestroyService`
-merge_request:
-author:
diff --git a/changelogs/unreleased/snippets-search.yml b/changelogs/unreleased/snippets-search.yml
deleted file mode 100644
index 00cf34f4a48..00000000000
--- a/changelogs/unreleased/snippets-search.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Fix snippets search result spacing
-merge_request:
-author:
diff --git a/changelogs/unreleased/sort-builds-in-stage-dropdown.yml b/changelogs/unreleased/sort-builds-in-stage-dropdown.yml
deleted file mode 100644
index 646f25125b1..00000000000
--- a/changelogs/unreleased/sort-builds-in-stage-dropdown.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Sort builds in stage dropdown
-merge_request:
-author:
diff --git a/changelogs/unreleased/ssh-key-paste.yml b/changelogs/unreleased/ssh-key-paste.yml
deleted file mode 100644
index 1e34ef60f6e..00000000000
--- a/changelogs/unreleased/ssh-key-paste.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: SSH key field updates title after pasting key
-merge_request:
-author:
diff --git a/changelogs/unreleased/ssrf-protections.yml b/changelogs/unreleased/ssrf-protections.yml
deleted file mode 100644
index 8d803738009..00000000000
--- a/changelogs/unreleased/ssrf-protections.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: To protect against Server-side Request Forgery project import URLs are now prohibited against localhost or the server IP except for the assigned instance URL and port. Imports are also prohibited from ports below 1024 with the exception of ports 22, 80, and 443.
-merge_request:
-author:
diff --git a/changelogs/unreleased/static-navbar.yml b/changelogs/unreleased/static-navbar.yml
deleted file mode 100644
index eaf478a48d0..00000000000
--- a/changelogs/unreleased/static-navbar.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Remove fixed positioning from top nav
-merge_request: !7547
-author:
diff --git a/changelogs/unreleased/task_list_refactor.yml b/changelogs/unreleased/task_list_refactor.yml
deleted file mode 100644
index 68942dadaa8..00000000000
--- a/changelogs/unreleased/task_list_refactor.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Deduplicate markdown task lists
-merge_request:
-author:
diff --git a/changelogs/unreleased/tc-api-pipeline-jobs.yml b/changelogs/unreleased/tc-api-pipeline-jobs.yml
deleted file mode 100644
index 993c1b6526a..00000000000
--- a/changelogs/unreleased/tc-api-pipeline-jobs.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Add GET /projects/:id/pipelines/:pipeline_id/jobs endpoint
-merge_request: 9727
-author:
diff --git a/changelogs/unreleased/tc-fix-project-create-500.yml b/changelogs/unreleased/tc-fix-project-create-500.yml
deleted file mode 100644
index 1b746a41eab..00000000000
--- a/changelogs/unreleased/tc-fix-project-create-500.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Fix for creating a project through API when import_url is nil
-merge_request: 9841
-author:
diff --git a/changelogs/unreleased/time-tracking-color-not-consistent.yml b/changelogs/unreleased/time-tracking-color-not-consistent.yml
new file mode 100644
index 00000000000..50ec9efb1ff
--- /dev/null
+++ b/changelogs/unreleased/time-tracking-color-not-consistent.yml
@@ -0,0 +1,4 @@
+---
+title: Corrected time tracking icon color in the issuable side bar
+merge_request:
+author:
diff --git a/changelogs/unreleased/unified-member-api-response.yml b/changelogs/unreleased/unified-member-api-response.yml
deleted file mode 100644
index 0a60b4d46a3..00000000000
--- a/changelogs/unreleased/unified-member-api-response.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: 'API: Return 400 for all validation erros in the mebers API'
-merge_request: 9523
-author: Robert Schilling
diff --git a/changelogs/unreleased/update-ace.yml b/changelogs/unreleased/update-ace.yml
deleted file mode 100644
index dbe476e3ae0..00000000000
--- a/changelogs/unreleased/update-ace.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Update code editor (ACE) to 1.2.6, to fix input problems with compose key
-merge_request:
-author:
diff --git a/changelogs/unreleased/update-vue-2-1.yml b/changelogs/unreleased/update-vue-2-1.yml
deleted file mode 100644
index acc42bf00b1..00000000000
--- a/changelogs/unreleased/update-vue-2-1.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: update Vue to v2.1.10
-merge_request: 9386
-author:
diff --git a/changelogs/unreleased/use-redis-channel-to-post-runner-notifcations.yml b/changelogs/unreleased/use-redis-channel-to-post-runner-notifcations.yml
deleted file mode 100644
index ff5a58f6232..00000000000
--- a/changelogs/unreleased/use-redis-channel-to-post-runner-notifcations.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Use redis channel to post notifications
-merge_request:
-author:
diff --git a/changelogs/unreleased/user-calendar-border.yml b/changelogs/unreleased/user-calendar-border.yml
deleted file mode 100644
index 8ebcca83256..00000000000
--- a/changelogs/unreleased/user-calendar-border.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Removed top border from user contribution calendar
-merge_request:
-author:
diff --git a/changelogs/unreleased/user-callouts.yml b/changelogs/unreleased/user-callouts.yml
deleted file mode 100644
index f6ce06a3d8f..00000000000
--- a/changelogs/unreleased/user-callouts.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Added user callouts to the projects dashboard and user profile
-merge_request:
-author:
diff --git a/changelogs/unreleased/workhorse-1-4-0.yml b/changelogs/unreleased/workhorse-1-4-0.yml
deleted file mode 100644
index b55fabddb0f..00000000000
--- a/changelogs/unreleased/workhorse-1-4-0.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Use gitlab-workhorse 1.4.0
-merge_request: 9724
-author:
diff --git a/changelogs/unreleased/zj-builds-to-jobs-api.yml b/changelogs/unreleased/zj-builds-to-jobs-api.yml
deleted file mode 100644
index 473dd9bc8ed..00000000000
--- a/changelogs/unreleased/zj-builds-to-jobs-api.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Rename builds to job for the v4 API
-merge_request: 9463
-author:
diff --git a/changelogs/unreleased/zj-chat-notification-default-branch.yml b/changelogs/unreleased/zj-chat-notification-default-branch.yml
new file mode 100644
index 00000000000..fa0052d5034
--- /dev/null
+++ b/changelogs/unreleased/zj-chat-notification-default-branch.yml
@@ -0,0 +1,4 @@
+---
+title: Only send chat notifications for the default branch
+merge_request:
+author:
diff --git a/changelogs/unreleased/zj-variables-build-job.yml b/changelogs/unreleased/zj-variables-build-job.yml
deleted file mode 100644
index 1cb0919f824..00000000000
--- a/changelogs/unreleased/zj-variables-build-job.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Rename job environment variables to new terminology
-merge_request: 9756
-author:
diff --git a/config/environments/test.rb b/config/environments/test.rb
index fb25d3a8b14..a25c5016a3b 100644
--- a/config/environments/test.rb
+++ b/config/environments/test.rb
@@ -1,4 +1,7 @@
Rails.application.configure do
+ # Make sure the middleware is inserted first in middleware chain
+ config.middleware.insert_before('ActionDispatch::Static', 'Gitlab::Testing::RequestBlockerMiddleware')
+
# Settings specified here will take precedence over those in config/application.rb
# The test environment is used exclusively to run your application's
diff --git a/config/gitlab.yml.example b/config/gitlab.yml.example
index ba7f6773985..3747baf4c3b 100644
--- a/config/gitlab.yml.example
+++ b/config/gitlab.yml.example
@@ -450,7 +450,7 @@ production: &base
# This setting is obsolete because we expect it to be moved under
# repositories/storages in GitLab 9.1.
#
- # socket_path: tmp/sockets/gitaly.socket
+ # socket_path: tmp/sockets/private/gitaly.socket
#
# 4. Advanced settings
diff --git a/config/webpack.config.js b/config/webpack.config.js
index c6794d6b944..3cf94b9b435 100644
--- a/config/webpack.config.js
+++ b/config/webpack.config.js
@@ -18,7 +18,7 @@ var config = {
context: path.join(ROOT_PATH, 'app/assets/javascripts'),
entry: {
common: './commons/index.js',
- common_vue: ['vue', 'vue-resource'],
+ common_vue: ['vue', './vue_shared/common_vue.js'],
common_d3: ['d3'],
main: './main.js',
blob_edit: './blob_edit/blob_edit_bundle.js',
@@ -132,7 +132,7 @@ var config = {
'empty_states': path.join(ROOT_PATH, 'app/views/shared/empty_states'),
'icons': path.join(ROOT_PATH, 'app/views/shared/icons'),
'vendor': path.join(ROOT_PATH, 'vendor/assets/javascripts'),
- 'vue$': 'vue/dist/vue.common.js',
+ 'vue$': 'vue/dist/vue.esm.js',
}
}
}
diff --git a/db/migrate/20170317203554_index_routes_path_for_like.rb b/db/migrate/20170317203554_index_routes_path_for_like.rb
index 264ecd322c3..7ac09b2abe5 100644
--- a/db/migrate/20170317203554_index_routes_path_for_like.rb
+++ b/db/migrate/20170317203554_index_routes_path_for_like.rb
@@ -14,7 +14,7 @@ class IndexRoutesPathForLike < ActiveRecord::Migration
def up
return unless Gitlab::Database.postgresql?
- unless index_exists?(:routes, name: INDEX_NAME)
+ unless index_exists?(:routes, :path, name: INDEX_NAME)
execute("CREATE INDEX CONCURRENTLY #{INDEX_NAME} ON routes (path varchar_pattern_ops);")
end
end
@@ -22,7 +22,7 @@ class IndexRoutesPathForLike < ActiveRecord::Migration
def down
return unless Gitlab::Database.postgresql?
- if index_exists?(:routes, name: INDEX_NAME)
+ if index_exists?(:routes, :path, name: INDEX_NAME)
execute("DROP INDEX CONCURRENTLY #{INDEX_NAME};")
end
end
diff --git a/doc/administration/gitaly/index.md b/doc/administration/gitaly/index.md
new file mode 100644
index 00000000000..30a4c08508d
--- /dev/null
+++ b/doc/administration/gitaly/index.md
@@ -0,0 +1,86 @@
+# Gitaly
+
+[Gitaly](https://gitlab.com/gitlab-org/gitlay) (introduced in GitLab
+9.0) is a service that provides high-level RPC access to Git
+repositories. As of GitLab 9.0 it is still an optional component with
+limited scope.
+
+GitLab components that access Git repositories (gitlab-rails,
+gitlab-shell, gitlab-workhorse) act as clients to Gitaly. End users do
+not have direct access to Gitaly.
+
+## Configuring Gitaly
+
+The Gitaly service itself is configured via environment variables.
+These variables are documented [in the gitaly
+repository](https://gitlab.com/gitlab-org/gitaly/blob/master/doc/configuration/README.md).
+
+To change a Gitaly environment variable in Omnibus you can use
+`gitaly['env']` in `/etc/gitlab/gitlab.rb`. Changes will be applied
+when you run `gitlab-ctl reconfigure`.
+
+```ruby
+gitaly['env'] = {
+ 'GITALY_MY_VARIABLE' => 'value'
+}
+```
+
+To change a Gitaly environment variable in installations from source
+you can edit `/home/git/gitaly/env`.
+
+```shell
+GITALY_MY_VARIABLE='value'
+```
+
+Changes to `/home/git/gitaly/env` are applied when you run `service
+gitlab restart`.
+
+## Configuring GitLab to not use Gitaly
+
+Gitaly is still an optional component in GitLab 9.0. This means you
+can choose to not use it.
+
+In Omnibus you can make the following change in
+`/etc/gitlab/gitlab.rb` and reconfigure. This will both disable the
+Gitaly service and configure the rest of GitLab not to use it.
+
+```ruby
+gitaly['enable'] = false
+```
+
+In source installations, edit `/home/git/gitlab/config/gitlab.yml` and
+make sure `socket_path` in the `gitaly` section is commented out. This
+does not disable the Gitaly service; it only prevents it from being
+used.
+
+Apply the change with `service gitlab restart`.
+
+```yaml
+ gitaly:
+ # socket_path: tmp/sockets/private/gitlay.socket
+```
+
+## Disabling or enabling the Gitaly service
+
+Be careful: if you disable Gitaly without instructing the rest of your
+GitLab installation not to use Gitaly, you may end up with errors
+because GitLab tries to access a service that is not running.
+
+To disable the Gitaly service in your Omnibus installation, add the
+following line to `/etc/gitlab/gitlab.rb`:
+
+```ruby
+gitaly['enable'] = false
+```
+
+When you run `gitlab-ctl reconfigure` the Gitaly service will be
+disabled.
+
+To disable the Gitaly service in an installation from source, add the
+following to `/etc/default/gitlab`:
+
+```shell
+gitaly_enabled=false
+```
+
+When you run `service gitlab restart` Gitaly will be disabled. \ No newline at end of file
diff --git a/doc/administration/high_availability/nfs.md b/doc/administration/high_availability/nfs.md
index 3893d837006..bf1aa6b9ac5 100644
--- a/doc/administration/high_availability/nfs.md
+++ b/doc/administration/high_availability/nfs.md
@@ -26,7 +26,7 @@ options:
circumstances it could lead to data loss if a failure occurs before data has
synced.
-## Client mount options
+## NFS Client mount options
Below is an example of an NFS mount point we use on GitLab.com:
diff --git a/doc/api/pipeline_triggers.md b/doc/api/pipeline_triggers.md
index fdb41a1d615..50fc19f0e08 100644
--- a/doc/api/pipeline_triggers.md
+++ b/doc/api/pipeline_triggers.md
@@ -41,10 +41,10 @@ Get details of project's build trigger.
GET /projects/:id/triggers/:trigger_id
```
-| Attribute | Type | required | Description |
-|-----------|---------|----------|--------------------------|
-| `id` | integer | yes | The ID of a project |
-| `token` | string | yes | The `token` of a trigger |
+| Attribute | Type | required | Description |
+|--------------|---------|----------|--------------------------|
+| `id` | integer | yes | The ID of a project |
+| `trigger_id` | integer | yes | The trigger id |
```
curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" "https://gitlab.example.com/api/v4/projects/1/triggers/5"
@@ -103,6 +103,7 @@ PUT /projects/:id/triggers/:trigger_id
| Attribute | Type | required | Description |
|---------------|---------|----------|--------------------------|
+| `id` | integer | yes | The ID of a project |
| `trigger_id` | integer | yes | The trigger id |
| `description` | string | no | The trigger name |
@@ -133,6 +134,7 @@ POST /projects/:id/triggers/:trigger_id/take_ownership
| Attribute | Type | required | Description |
|---------------|---------|----------|--------------------------|
+| `id` | integer | yes | The ID of a project |
| `trigger_id` | integer | yes | The trigger id |
```
diff --git a/doc/development/README.md b/doc/development/README.md
index 265df98fb87..e27e7fc7d19 100644
--- a/doc/development/README.md
+++ b/doc/development/README.md
@@ -15,7 +15,7 @@
- [SQL Migration Style Guide](migration_style_guide.md) for creating safe SQL migrations
- [Testing standards and style guidelines](testing.md)
- [UX guide](ux_guide/index.md) for building GitLab with existing CSS styles and elements
-- [Frontend guidelines](frontend.md)
+- [Frontend guidelines](fe_guide/index.md)
- [SQL guidelines](sql.md) for working with SQL queries
- [Sidekiq guidelines](sidekiq_style_guide.md) for working with Sidekiq workers
- [`Gemfile` guidelines](gemfile.md)
diff --git a/doc/development/ci_setup.md b/doc/development/ci_setup.md
index b03216fec95..0810b32efd7 100644
--- a/doc/development/ci_setup.md
+++ b/doc/development/ci_setup.md
@@ -7,7 +7,7 @@ We currently use four CI services to test GitLab:
1. GitLab CI on [GitHost.io](https://gitlab-ce.githost.io/projects/4/) for the [GitLab.com repo](https://gitlab.com/gitlab-org/gitlab-ce)
2. GitLab CI at ci.gitlab.org to test the private GitLab B.V. repo at dev.gitlab.org
3. [Semephore](https://semaphoreapp.com/gitlabhq/gitlabhq/) for [GitHub.com repo](https://github.com/gitlabhq/gitlabhq)
-4. [Mock CI Service](user/project/integrations/mock_ci.md) for local development
+4. [Mock CI Service](../user/project/integrations/mock_ci.md) for local development
| Software @ configuration being tested | GitLab CI (ci.gitlab.org) | GitLab CI (GitHost.io) | Semaphore |
|---------------------------------------|---------------------------|---------------------------------------------------------------------------|-----------|
diff --git a/doc/development/fe_guide/accessibility.md b/doc/development/fe_guide/accessibility.md
new file mode 100644
index 00000000000..366b220cbb2
--- /dev/null
+++ b/doc/development/fe_guide/accessibility.md
@@ -0,0 +1,13 @@
+# Accessibility
+
+## Resources
+
+[Chrome Accessibility Developer Tools][chrome-accessibility-developer-tools]
+are useful for testing for potential accessibility problems in GitLab.
+
+Accessibility best-practices and more in-depth information is available on
+[the Audit Rules page][audit-rules] for the Chrome Accessibility Developer Tools.
+
+
+[chrome-accessibility-developer-tools]: https://github.com/GoogleChrome/accessibility-developer-tools
+[audit-rules]: https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules
diff --git a/doc/development/fe_guide/architecture.md b/doc/development/fe_guide/architecture.md
new file mode 100644
index 00000000000..aebb22caa15
--- /dev/null
+++ b/doc/development/fe_guide/architecture.md
@@ -0,0 +1,22 @@
+# Architecture
+
+When you are developing a new feature that requires architectural design, or if
+you are changing the fundamental design of an existing feature, make sure it is
+discussed with one of the Frontend Architecture Experts.
+
+A Frontend Architect is an expert who makes high-level Frontend design decisions
+and decides on technical standards, including coding standards and frameworks.
+
+Architectural decisions should be accessible to everyone, so please document
+them in the relevant Merge Request discussion or by updating our documentation
+when appropriate.
+
+You can find the Frontend Architecture experts on the [team page][team-page].
+
+## Examples
+
+You can find documentation about the desired architecture for a new feature
+built with Vue.js [here][vue-section].
+
+[team-page]: https://about.gitlab.com/team
+[vue-section]: vue.md#frontend.html#how-to-build-a-new-feature-with-vue-js
diff --git a/doc/development/fe_guide/design_patterns.md b/doc/development/fe_guide/design_patterns.md
new file mode 100644
index 00000000000..e05887a19af
--- /dev/null
+++ b/doc/development/fe_guide/design_patterns.md
@@ -0,0 +1,78 @@
+# Design Patterns
+
+## Singletons
+
+When exactly one object is needed for a given task, prefer to define it as a
+`class` rather than as an object literal. Prefer also to explicitly restrict
+instantiation, unless flexibility is important (e.g. for testing).
+
+```javascript
+// bad
+
+const MyThing = {
+ prop1: 'hello',
+ method1: () => {}
+};
+
+export default MyThing;
+
+// good
+
+class MyThing {
+ constructor() {
+ this.prop1 = 'hello';
+ }
+ method1() {}
+}
+
+export default new MyThing();
+
+// best
+
+export default class MyThing {
+ constructor() {
+ if (!this.prototype.singleton) {
+ this.init();
+ this.prototype.singleton = this;
+ }
+ return this.prototype.singleton;
+ }
+
+ init() {
+ this.prop1 = 'hello';
+ }
+
+ method1() {}
+}
+
+```
+
+## Manipulating the DOM in a JS Class
+
+When writing a class that needs to manipulate the DOM guarantee a container option is provided.
+This is useful when we need that class to be instantiated more than once in the same page.
+
+Bad:
+```javascript
+class Foo {
+ constructor() {
+ document.querySelector('.bar');
+ }
+}
+new Foo();
+```
+
+Good:
+```javascript
+class Foo {
+ constructor(opts) {
+ document.querySelector(`${opts.container} .bar`);
+ }
+}
+
+new Foo({ container: '.my-element' });
+```
+You can find an example of the above in this [class][container-class-example];
+
+
+[container-class-example]: https://gitlab.com/gitlab-org/gitlab-ce/blob/master/app/assets/javascripts/mini_pipeline_graph_dropdown.js
diff --git a/doc/development/fe_guide/index.md b/doc/development/fe_guide/index.md
new file mode 100644
index 00000000000..f963bffde37
--- /dev/null
+++ b/doc/development/fe_guide/index.md
@@ -0,0 +1,92 @@
+# Frontend Development Guidelines
+
+This document describes various guidelines to ensure consistency and quality
+across GitLab's frontend team.
+
+## Overview
+
+GitLab is built on top of [Ruby on Rails][rails] using [Haml][haml] with
+[Hamlit][hamlit]. Be wary of [the limitations that come with using
+Hamlit][hamlit-limits]. We also use [SCSS][scss] and plain JavaScript with
+modern ECMAScript standards supported through [Babel][babel] and ES module
+support through [webpack][webpack].
+
+We also utilize [webpack][webpack] to handle the bundling, minification, and
+compression of our assets.
+
+Working with our frontend assets requires Node (v4.3 or greater) and Yarn
+(v0.17 or greater). You can find information on how to install these on our
+[installation guide][install].
+
+[jQuery][jquery] is used throughout the application's JavaScript, with
+[Vue.js][vue] for particularly advanced, dynamic elements.
+
+### Browser Support
+
+For our currently-supported browsers, see our [requirements][requirements].
+
+---
+
+## [Architecture](architecture.md)
+How we go about making fundamental design decisions in GitLab's frontend team
+or make changes to our frontend development guidelines.
+
+---
+
+## [Testing](testing.md)
+How we write frontend tests, run the GitLab test suite, and debug test related
+issues.
+
+---
+
+## [Design Patterns](design_patterns.md)
+Common JavaScript design patterns in GitLab's codebase.
+
+---
+
+## [Vue.js Best Practices](vue.md)
+Vue specific design patterns and practices.
+
+---
+
+## Style Guides
+
+### [JavaScript Style Guide](style_guide_js.md)
+
+We use eslint to enforce our JavaScript style guides. Our guide is based on
+the excellent [Airbnb][airbnb-js-style-guide] style guide with a few small
+changes.
+
+### [SCSS Style Guide](style_guide_scss.md)
+
+Our SCSS conventions which are enforced through [scss-lint][scss-lint].
+
+---
+
+## [Performance](performance.md)
+Best practices for monitoring and maximizing frontend performance.
+
+---
+
+## [Security](security.md)
+Frontend security practices.
+
+---
+
+## [Accessibility](accessibility.md)
+Our accessibility standards and resources.
+
+
+[rails]: http://rubyonrails.org/
+[haml]: http://haml.info/
+[hamlit]: https://github.com/k0kubun/hamlit
+[hamlit-limits]: https://github.com/k0kubun/hamlit/blob/master/REFERENCE.md#limitations
+[scss]: http://sass-lang.com/
+[babel]: https://babeljs.io/
+[webpack]: https://webpack.js.org/
+[jquery]: https://jquery.com/
+[vue]: http://vuejs.org/
+[airbnb-js-style-guide]: https://github.com/airbnb/javascript
+[scss-lint]: https://github.com/brigade/scss-lint
+[install]: ../../install/installation.md#4-node
+[requirements]: ../../install/requirements.md#supported-web-browsers
diff --git a/doc/development/fe_guide/performance.md b/doc/development/fe_guide/performance.md
new file mode 100644
index 00000000000..2d76bb18cff
--- /dev/null
+++ b/doc/development/fe_guide/performance.md
@@ -0,0 +1,95 @@
+# Performance
+
+## Best Practices
+
+### Realtime Components
+
+When writing code for realtime features we have to keep a couple of things in mind:
+1. Do not overload the server with requests.
+1. It should feel realtime.
+
+Thus, we must strike a balance between sending requests and the feeling of realtime.
+Use the following rules when creating realtime solutions.
+
+1. The server will tell you how much to poll by sending `Poll-Interval` in the header.
+Use that as your polling interval. This way it is easy for system administrators to change the
+polling rate.
+A `Poll-Interval: -1` means you should disable polling, and this must be implemented.
+1. A response with HTTP status `4XX` or `5XX` should disable polling as well.
+1. Use a common library for polling.
+1. Poll on active tabs only. Use a common library to find out which tab currently has eyes on it.
+Please use [Focus](https://gitlab.com/andrewn/focus). Specifically [Eyeballs Detector](https://gitlab.com/andrewn/focus/blob/master/lib/eyeballs-detector.js).
+1. Use regular polling intervals, do not use backoff polling, or jitter, as the interval will be
+controlled by the server.
+1. The backend code will most likely be using etags. You do not and should not check for status
+`304 Not Modified`. The browser will transform it for you.
+
+## Reducing Asset Footprint
+
+### Page-specific JavaScript
+
+Certain pages may require the use of a third party library, such as [d3][d3] for
+the User Activity Calendar and [Chart.js][chartjs] for the Graphs pages. These
+libraries increase the page size significantly, and impact load times due to
+bandwidth bottlenecks and the browser needing to parse more JavaScript.
+
+In cases where libraries are only used on a few specific pages, we use
+"page-specific JavaScript" to prevent the main `main.js` file from
+becoming unnecessarily large.
+
+Steps to split page-specific JavaScript from the main `main.js`:
+
+1. Create a directory for the specific page(s), e.g. `graphs/`.
+1. In that directory, create a `namespace_bundle.js` file, e.g. `graphs_bundle.js`.
+1. Add the new "bundle" file to the list of entry files in `config/webpack.config.js`.
+ - For example: `graphs: './graphs/graphs_bundle.js',`.
+1. Move code reliant on these libraries into the `graphs` directory.
+1. In `graphs_bundle.js` add CommonJS `require('./path_to_some_component.js');` statements to load any other files in this directory. Make sure to use relative urls.
+1. In the relevant views, add the scripts to the page with the following:
+
+```haml
+- content_for :page_specific_javascripts do
+ = page_specific_javascript_bundle_tag('lib_chart')
+ = page_specific_javascript_bundle_tag('graphs')
+```
+
+The above loads `chart.js` and `graphs_bundle.js` for this page only. `chart.js`
+is separated from the bundle file so it can be cached separately from the bundle
+and reused for other pages that also rely on the library. For an example, see
+[this Haml file][page-specific-js-example].
+
+### Code Splitting
+
+> *TODO* flesh out this section once webpack is ready for code-splitting
+
+### Minimizing page size
+
+A smaller page size means the page loads faster (especially important on mobile
+and poor connections), the page is parsed more quickly by the browser, and less
+data is used for users with capped data plans.
+
+General tips:
+
+- Don't add new fonts.
+- Prefer font formats with better compression, e.g. WOFF2 is better than WOFF, which is better than TTF.
+- Compress and minify assets wherever possible (For CSS/JS, Sprockets and webpack do this for us).
+- If some functionality can reasonably be achieved without adding extra libraries, avoid them.
+- Use page-specific JavaScript as described above to dynamically load libraries that are only needed on certain pages.
+
+-------
+
+## Additional Resources
+
+- [WebPage Test][web-page-test] for testing site loading time and size.
+- [Google PageSpeed Insights][pagespeed-insights] grades web pages and provides feedback to improve the page.
+- [Profiling with Chrome DevTools][google-devtools-profiling]
+- [Browser Diet][browser-diet] is a community-built guide that catalogues practical tips for improving web page performance.
+
+
+[web-page-test]: http://www.webpagetest.org/
+[pagespeed-insights]: https://developers.google.com/speed/pagespeed/insights/
+[google-devtools-profiling]: https://developers.google.com/web/tools/chrome-devtools/profile/?hl=en
+[browser-diet]: https://browserdiet.com/
+[d3]: https://d3js.org/
+[chartjs]: http://www.chartjs.org/
+[page-specific-js-example]: https://gitlab.com/gitlab-org/gitlab-ce/blob/13bb9ed77f405c5f6ee4fdbc964ecf635c9a223f/app/views/projects/graphs/_head.html.haml#L6-8
diff --git a/doc/development/fe_guide/security.md b/doc/development/fe_guide/security.md
new file mode 100644
index 00000000000..19e72c1d368
--- /dev/null
+++ b/doc/development/fe_guide/security.md
@@ -0,0 +1,92 @@
+# Security
+### Resources
+
+[Mozilla’s HTTP Observatory CLI][observatory-cli] and the
+[Qualys SSL Labs Server Test][qualys-ssl] are good resources for finding
+potential problems and ensuring compliance with security best practices.
+
+<!-- Uncomment these sections when CSP/SRI are implemented.
+### Content Security Policy (CSP)
+
+Content Security Policy is a web standard that intends to mitigate certain
+forms of Cross-Site Scripting (XSS) as well as data injection.
+
+Content Security Policy rules should be taken into consideration when
+implementing new features, especially those that may rely on connection with
+external services.
+
+GitLab's CSP is used for the following:
+
+- Blocking plugins like Flash and Silverlight from running at all on our pages.
+- Blocking the use of scripts and stylesheets downloaded from external sources.
+- Upgrading `http` requests to `https` when possible.
+- Preventing `iframe` elements from loading in most contexts.
+
+Some exceptions include:
+
+- Scripts from Google Analytics and Piwik if either is enabled.
+- Connecting with GitHub, Bitbucket, GitLab.com, etc. to allow project importing.
+- Connecting with Google, Twitter, GitHub, etc. to allow OAuth authentication.
+
+We use [the Secure Headers gem][secure_headers] to enable Content
+Security Policy headers in the GitLab Rails app.
+
+Some resources on implementing Content Security Policy:
+
+- [MDN Article on CSP][mdn-csp]
+- [GitHub’s CSP Journey on the GitHub Engineering Blog][github-eng-csp]
+- The Dropbox Engineering Blog's series on CSP: [1][dropbox-csp-1], [2][dropbox-csp-2], [3][dropbox-csp-3], [4][dropbox-csp-4]
+
+### Subresource Integrity (SRI)
+
+Subresource Integrity prevents malicious assets from being provided by a CDN by
+guaranteeing that the asset downloaded is identical to the asset the server
+is expecting.
+
+The Rails app generates a unique hash of the asset, which is used as the
+asset's `integrity` attribute. The browser generates the hash of the asset
+on-load and will reject the asset if the hashes do not match.
+
+All CSS and JavaScript assets should use Subresource Integrity.
+
+Some resources on implementing Subresource Integrity:
+
+- [MDN Article on SRI][mdn-sri]
+- [Subresource Integrity on the GitHub Engineering Blog][github-eng-sri]
+
+-->
+
+### Including external resources
+
+External fonts, CSS, and JavaScript should never be used with the exception of
+Google Analytics and Piwik - and only when the instance has enabled it. Assets
+should always be hosted and served locally from the GitLab instance. Embedded
+resources via `iframes` should never be used except in certain circumstances
+such as with ReCaptcha, which cannot be used without an `iframe`.
+
+### Avoiding inline scripts and styles
+
+In order to protect users from [XSS vulnerabilities][xss], we will disable
+inline scripts in the future using Content Security Policy.
+
+While inline scripts can be useful, they're also a security concern. If
+user-supplied content is unintentionally left un-sanitized, malicious users can
+inject scripts into the web app.
+
+Inline styles should be avoided in almost all cases, they should only be used
+when no alternatives can be found. This allows reusability of styles as well as
+readability.
+
+
+[observatory-cli]: https://github.com/mozilla/http-observatory-cli
+[qualys-ssl]: https://www.ssllabs.com/ssltest/analyze.html
+[secure_headers]: https://github.com/twitter/secureheaders
+[mdn-csp]: https://developer.mozilla.org/en-US/docs/Web/Security/CSP
+[github-eng-csp]: http://githubengineering.com/githubs-csp-journey/
+[dropbox-csp-1]: https://blogs.dropbox.com/tech/2015/09/on-csp-reporting-and-filtering/
+[dropbox-csp-2]: https://blogs.dropbox.com/tech/2015/09/unsafe-inline-and-nonce-deployment/
+[dropbox-csp-3]: https://blogs.dropbox.com/tech/2015/09/csp-the-unexpected-eval/
+[dropbox-csp-4]: https://blogs.dropbox.com/tech/2015/09/csp-third-party-integrations-and-privilege-separation/
+[mdn-sri]: https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity
+[github-eng-sri]: http://githubengineering.com/subresource-integrity/
+[xss]: https://en.wikipedia.org/wiki/Cross-site_scripting
diff --git a/doc/development/fe_guide/style_guide_js.md b/doc/development/fe_guide/style_guide_js.md
new file mode 100644
index 00000000000..034cfe73d33
--- /dev/null
+++ b/doc/development/fe_guide/style_guide_js.md
@@ -0,0 +1,408 @@
+# Style guides and linting
+See the relevant style guides for our guidelines and for information on linting:
+
+## JavaScript
+We defer to [Airbnb][airbnb-js-style-guide] on most style-related
+conventions and enforce them with eslint.
+
+See [our current .eslintrc][eslintrc] for specific rules and patterns.
+
+### Common
+
+#### ESlint
+
+- **Never** disable eslint rules unless you have a good reason. You may see a lot of legacy files with `/* eslint-disable some-rule, some-other-rule */` at the top, but legacy files are a special case. Any time you develop a new feature or refactor an existing one, you should abide by the eslint rules.
+
+- **Never Ever EVER** disable eslint globally for a file
+
+ ```javascript
+ // bad
+ /* eslint-disable */
+
+ // better
+ /* eslint-disable some-rule, some-other-rule */
+
+ // best
+ // nothing :)
+ ```
+
+- If you do need to disable a rule for a single violation, try to do it as locally as possible
+
+ ```javascript
+ // bad
+ /* eslint-disable no-new */
+
+ import Foo from 'foo';
+
+ new Foo();
+
+ // better
+ import Foo from 'foo';
+
+ // eslint-disable-next-line no-new
+ new Foo();
+ ```
+
+- When they are needed _always_ place ESlint directive comment blocks on the first line of a script, followed by any global declarations, then a blank newline prior to any imports or code.
+
+ ```javascript
+ // bad
+ /* global Foo */
+ /* eslint-disable no-new */
+ import Bar from './bar';
+
+ // good
+ /* eslint-disable no-new */
+ /* global Foo */
+
+ import Bar from './bar';
+ ```
+
+- **Never** disable the `no-undef` rule. Declare globals with `/* global Foo */` instead.
+
+- When declaring multiple globals, always use one `/* global [name] */` line per variable.
+
+ ```javascript
+ // bad
+ /* globals Flash, Cookies, jQuery */
+
+ // good
+ /* global Flash */
+ /* global Cookies */
+ /* global jQuery */
+ ```
+
+#### Modules, Imports, and Exports
+- Use ES module syntax to import modules
+
+ ```javascript
+ // bad
+ require('foo');
+
+ // good
+ import Foo from 'foo';
+
+ // bad
+ module.exports = Foo;
+
+ // good
+ export default Foo;
+ ```
+
+- Relative paths
+
+ Unless you are writing a test, always reference other scripts using relative paths instead of `~`
+
+ In **app/assets/javascripts**:
+ ```javascript
+ // bad
+ import Foo from '~/foo'
+
+ // good
+ import Foo from '../foo';
+ ```
+
+ In **spec/javascripts**:
+ ```javascript
+ // bad
+ import Foo from '../../app/assets/javascripts/foo'
+
+ // good
+ import Foo from '~/foo';
+ ```
+
+- Avoid using IIFE. Although we have a lot of examples of files which wrap their contents in IIFEs (immediately-invoked function expressions), this is no longer necessary after the transition from Sprockets to webpack. Do not use them anymore and feel free to remove them when refactoring legacy code.
+
+- Avoid adding to the global namespace.
+
+ ```javascript
+ // bad
+ window.MyClass = class { /* ... */ };
+
+ // good
+ export default class MyClass { /* ... */ }
+ ```
+
+- Side effects are forbidden in any script which contains exports
+
+ ```javascript
+ // bad
+ export default class MyClass { /* ... */ }
+
+ document.addEventListener("DOMContentLoaded", function(event) {
+ new MyClass();
+ }
+ ```
+
+
+#### Data Mutation and Pure functions
+- Strive to write many small pure functions, and minimize where mutations occur.
+
+ ```javascript
+ // bad
+ const values = {foo: 1};
+
+ function impureFunction(items) {
+ const bar = 1;
+
+ items.foo = items.a * bar + 2;
+
+ return items.a;
+ }
+
+ const c = impureFunction(values);
+
+ // good
+ var values = {foo: 1};
+
+ function pureFunction (foo) {
+ var bar = 1;
+
+ foo = foo * bar + 2;
+
+ return foo;
+ }
+
+ var c = pureFunction(values.foo);
+ ```
+
+- Avoid constructors with side-effects
+
+
+#### Parse Strings into Numbers
+- `parseInt()` is preferable over `Number()` or `+`
+
+ ```javascript
+ // bad
+ +'10' // 10
+
+ // good
+ Number('10') // 10
+
+ // better
+ parseInt('10', 10);
+ ```
+
+
+### Vue.js
+
+
+#### Basic Rules
+- Only include one Vue.js component per file.
+- Export components as plain objects:
+
+ ```javascript
+ export default {
+ template: `<h1>I'm a component</h1>
+ }
+ ```
+
+#### Naming
+- **Extensions**: Use `.vue` extension for Vue components.
+- **Reference Naming**: Use PascalCase for Vue components and camelCase for their instances:
+
+ ```javascript
+ // bad
+ import cardBoard from 'cardBoard';
+
+ // good
+ import CardBoard from 'cardBoard'
+
+ // bad
+ components: {
+ CardBoard: CardBoard
+ };
+
+ // good
+ components: {
+ cardBoard: CardBoard
+ };
+ ```
+- **Props Naming**: Avoid using DOM component prop names.
+
+ ```javascript
+ // bad
+ <component class="btn">
+
+ // good
+ <component cssClass="btn">
+ ```
+
+#### Alignment
+- Follow these alignment styles for the template method:
+
+ ```javascript
+ // bad
+ <component v-if="bar"
+ param="baz" />
+
+ // good
+ <component
+ v-if="bar"
+ param="baz"
+ />
+
+ // if props fit in one line then keep it on the same line
+ <component bar="bar" />
+ ```
+
+#### Quotes
+- Always use double quotes `"` inside templates and single quotes `'` for all other JS.
+
+ ```javascript
+ // bad
+ template: `
+ <button :class='style'>Button</button>
+ `
+
+ // good
+ template: `
+ <button :class="style">Button</button>
+ `
+ ```
+
+#### Props
+- Props should be declared as an object
+
+ ```javascript
+ // bad
+ props: ['foo']
+
+ // good
+ props: {
+ foo: {
+ type: String,
+ required: false,
+ default: 'bar'
+ }
+ }
+ ```
+
+- Required key should always be provided when declaring a prop
+
+ ```javascript
+ // bad
+ props: {
+ foo: {
+ type: String,
+ }
+ }
+
+ // good
+ props: {
+ foo: {
+ type: String,
+ required: false,
+ default: 'bar'
+ }
+ }
+ ```
+
+- Default key should always be provided if the prop is not required:
+
+ ```javascript
+ // bad
+ props: {
+ foo: {
+ type: String,
+ required: false,
+ }
+ }
+
+ // good
+ props: {
+ foo: {
+ type: String,
+ required: false,
+ default: 'bar'
+ }
+ }
+
+ // good
+ props: {
+ foo: {
+ type: String,
+ required: true
+ }
+ }
+ ```
+
+#### Data
+- `data` method should always be a function
+
+ ```javascript
+ // bad
+ data: {
+ foo: 'foo'
+ }
+
+ // good
+ data() {
+ return {
+ foo: 'foo'
+ };
+ }
+ ```
+
+#### Directives
+
+- Shorthand `@` is preferable over `v-on`
+
+ ```javascript
+ // bad
+ <component v-on:click="eventHandler"/>
+
+
+ // good
+ <component @click="eventHandler"/>
+ ```
+
+- Shorthand `:` is preferable over `v-bind`
+
+ ```javascript
+ // bad
+ <component v-bind:class="btn"/>
+
+
+ // good
+ <component :class="btn"/>
+ ```
+
+#### Closing tags
+- Prefer self closing component tags
+
+ ```javascript
+ // bad
+ <component></component>
+
+ // good
+ <component />
+ ```
+
+#### Ordering
+- Order for a Vue Component:
+ 1. `name`
+ 2. `props`
+ 3. `data`
+ 4. `components`
+ 5. `computedProps`
+ 6. `methods`
+ 7. lifecycle methods
+ 1. `beforeCreate`
+ 2. `created`
+ 3. `beforeMount`
+ 4. `mounted`
+ 5. `beforeUpdate`
+ 6. `updated`
+ 7. `activated`
+ 8. `deactivated`
+ 9. `beforeDestroy`
+ 10. `destroyed`
+ 8. `template`
+
+
+## SCSS
+- [SCSS](style_guide_scss.md)
+
+[airbnb-js-style-guide]: https://github.com/airbnb/javascript
+[eslintrc]: https://gitlab.com/gitlab-org/gitlab-ce/blob/master/.eslintrc
diff --git a/doc/development/scss_styleguide.md b/doc/development/fe_guide/style_guide_scss.md
index a79f4073cde..77b308c4a43 100644
--- a/doc/development/scss_styleguide.md
+++ b/doc/development/fe_guide/style_guide_scss.md
@@ -35,7 +35,7 @@ between the property and its value.
```scss
// Bad
-.container-item {
+.container-item {
width: 100px; height: 100px;
margin-top: 0;
}
@@ -63,7 +63,7 @@ between the property and its value.
}
```
-Note that there is an exception for single-line rulesets, although these are
+Note that there is an exception for single-line rulesets, although these are
not typically recommended.
```scss
@@ -72,7 +72,7 @@ p { margin: 0; padding: 0; }
### Colors
-HEX (hexadecimal) colors should use shorthand where possible, and should use
+HEX (hexadecimal) colors should use shorthand where possible, and should use
lower case letters to differentiate between letters and numbers, e.g. `#E3E3E3`
vs. `#e3e3e3`.
@@ -111,7 +111,7 @@ p {
### Semicolons
-Always include semicolons after every property. When the stylesheets are
+Always include semicolons after every property. When the stylesheets are
minified, the semicolons will be removed automatically.
```scss
@@ -144,7 +144,7 @@ padding: 10px;
### Zero Units
-Omit length units on zero values, they're unnecessary and not including them
+Omit length units on zero values, they're unnecessary and not including them
is slightly more performant.
```scss
@@ -161,36 +161,56 @@ is slightly more performant.
### Selectors with a `js-` Prefix
-Do not use any selector prefixed with `js-` for styling purposes. These
-selectors are intended for use only with JavaScript to allow for removal or
+Do not use any selector prefixed with `js-` for styling purposes. These
+selectors are intended for use only with JavaScript to allow for removal or
renaming without breaking styling.
+### IDs
+Don't use ID selectors in CSS.
+
+```scss
+// Bad
+#my-element {
+ padding: 0;
+}
+
+// Good
+.my-element {
+ padding: 0;
+}
+```
+
+### Variables
+Before adding a new variable for a color or a size, guarantee:
+1. There isn't already one
+2. There isn't a similar one we can use instead.
+
## Linting
-We use [SCSS Lint][scss-lint] to check for style guide conformity. It uses the
-ruleset in `.scss-lint.yml`, which is located in the home directory of the
+We use [SCSS Lint][scss-lint] to check for style guide conformity. It uses the
+ruleset in `.scss-lint.yml`, which is located in the home directory of the
project.
-To check if any warnings will be produced by your changes, you can run `rake
-scss_lint` in the GitLab directory. SCSS Lint will also run in GitLab CI to
+To check if any warnings will be produced by your changes, you can run `rake
+scss_lint` in the GitLab directory. SCSS Lint will also run in GitLab CI to
catch any warnings.
-If the Rake task is throwing warnings you don't understand, SCSS Lint's
+If the Rake task is throwing warnings you don't understand, SCSS Lint's
documentation includes [a full list of their linters][scss-lint-documentation].
### Fixing issues
-If you want to automate changing a large portion of the codebase to conform to
+If you want to automate changing a large portion of the codebase to conform to
the SCSS style guide, you can use [CSSComb][csscomb]. First install
-[Node][node] and [NPM][npm], then run `npm install csscomb -g` to install
-CSSComb globally (system-wide). Run it in the GitLab directory with
+[Node][node] and [NPM][npm], then run `npm install csscomb -g` to install
+CSSComb globally (system-wide). Run it in the GitLab directory with
`csscomb app/assets/stylesheets` to automatically fix issues with CSS/SCSS.
Note that this won't fix every problem, but it should fix a majority.
### Ignoring issues
-If you want a line or set of lines to be ignored by the linter, you can use
+If you want a line or set of lines to be ignored by the linter, you can use
`// scss-lint:disable RuleName` ([more info][disabling-linters]):
```scss
@@ -203,8 +223,8 @@ If you want a line or set of lines to be ignored by the linter, you can use
```
Make sure a comment is added on the line above the `disable` rule, otherwise the
-linter will throw a warning. `DisableLinterReason` is enabled to make sure the
-style guide isn't being ignored, and to communicate to others why the style
+linter will throw a warning. `DisableLinterReason` is enabled to make sure the
+style guide isn't being ignored, and to communicate to others why the style
guide is ignored in this instance.
[csscomb]: https://github.com/csscomb/csscomb.js
diff --git a/doc/development/fe_guide/testing.md b/doc/development/fe_guide/testing.md
new file mode 100644
index 00000000000..bb6adeacc4c
--- /dev/null
+++ b/doc/development/fe_guide/testing.md
@@ -0,0 +1,129 @@
+# Frontend Testing
+
+There are two types of tests you'll encounter while developing frontend code
+at GitLab. We use Karma and Jasmine for JavaScript unit testing, and RSpec
+feature tests with Capybara for integration testing.
+
+Feature tests need to be written for all new features. Regression tests ought
+to be written for all bug fixes to prevent them from recurring in the future.
+
+See [the Testing Standards and Style Guidelines](/doc/development/testing.md)
+for more information on general testing practices at GitLab.
+
+## Karma test suite
+
+GitLab uses the [Karma][karma] test runner with [Jasmine][jasmine] as its test
+framework for our JavaScript unit tests. For tests that rely on DOM
+manipulation we use fixtures which are pre-compiled from HAML source files and
+served during testing by the [jasmine-jquery][jasmine-jquery] plugin.
+
+### Running frontend tests
+
+`rake karma` runs the frontend-only (JavaScript) tests.
+It consists of two subtasks:
+
+- `rake karma:fixtures` (re-)generates fixtures
+- `rake karma:tests` actually executes the tests
+
+As long as the fixtures don't change, `rake karma:tests` (or `yarn karma`)
+is sufficient (and saves you some time).
+
+### Live testing and focused testing
+
+While developing locally, it may be helpful to keep karma running so that you
+can get instant feedback on as you write tests and modify code. To do this
+you can start karma with `npm run karma-start`. It will compile the javascript
+assets and run a server at `http://localhost:9876/` where it will automatically
+run the tests on any browser which connects to it. You can enter that url on
+multiple browsers at once to have it run the tests on each in parallel.
+
+While karma is running, any changes you make will instantly trigger a recompile
+and retest of the entire test suite, so you can see instantly if you've broken
+a test with your changes. You can use [jasmine focused][jasmine-focus] or
+excluded tests (with `fdescribe` or `xdescribe`) to get karma to run only the
+tests you want while you're working on a specific feature, but make sure to
+remove these directives when you commit your code.
+
+## RSpec Feature Integration Tests
+
+Information on setting up and running RSpec integration tests with
+[Capybara][capybara] can be found in the
+[general testing guide](/doc/development/testing.md).
+
+## Gotchas
+
+### Errors due to use of unsupported JavaScript features
+
+Similar errors will be thrown if you're using JavaScript features not yet
+supported by the PhantomJS test runner which is used for both Karma and RSpec
+tests. We polyfill some JavaScript objects for older browsers, but some
+features are still unavailable:
+
+- Array.from
+- Array.first
+- Async functions
+- Generators
+- Array destructuring
+- For..Of
+- Symbol/Symbol.iterator
+- Spread
+
+Until these are polyfilled appropriately, they should not be used. Please
+update this list with additional unsupported features.
+
+### RSpec errors due to JavaScript
+
+By default RSpec unit tests will not run JavaScript in the headless browser
+and will simply rely on inspecting the HTML generated by rails.
+
+If an integration test depends on JavaScript to run correctly, you need to make
+sure the spec is configured to enable JavaScript when the tests are run. If you
+don't do this you'll see vague error messages from the spec runner.
+
+To enable a JavaScript driver in an `rspec` test, add `js: true` to the
+individual spec or the context block containing multiple specs that need
+JavaScript enabled:
+
+```ruby
+
+# For one spec
+it 'presents information about abuse report', js: true do
+ # assertions...
+end
+
+describe "Admin::AbuseReports", js: true do
+ it 'presents information about abuse report' do
+ # assertions...
+ end
+ it 'shows buttons for adding to abuse report' do
+ # assertions...
+ end
+end
+```
+
+### Spinach errors due to missing JavaScript
+
+> **Note:** Since we are discouraging the use of Spinach when writing new
+> feature tests, you shouldn't ever need to use this. This information is kept
+> available for legacy purposes only.
+
+In Spinach, the JavaScript driver is enabled differently. In the `*.feature`
+file for the failing spec, add the `@javascript` flag above the Scenario:
+
+```
+@javascript
+Scenario: Developer can approve merge request
+ Given I am a "Shop" developer
+ And I visit project "Shop" merge requests page
+ And merge request 'Bug NS-04' must be approved
+ And I click link "Bug NS-04"
+ When I click link "Approve"
+ Then I should see approved merge request "Bug NS-04"
+
+```
+
+[capybara]: http://teamcapybara.github.io/capybara/
+[jasmine]: https://jasmine.github.io/
+[jasmine-focus]: https://jasmine.github.io/2.5/focused_specs.html
+[jasmine-jquery]: https://github.com/velesin/jasmine-jquery
+[karma]: http://karma-runner.github.io/
diff --git a/doc/development/fe_guide/vue.md b/doc/development/fe_guide/vue.md
new file mode 100644
index 00000000000..3e3406e7d6a
--- /dev/null
+++ b/doc/development/fe_guide/vue.md
@@ -0,0 +1,104 @@
+# Vue
+
+For more complex frontend features, we recommend using Vue.js. It shares
+some ideas with React.js as well as Angular.
+
+To get started with Vue, read through [their documentation][vue-docs].
+
+## When to use Vue.js
+
+We recommend using Vue for more complex features. Here are some guidelines for when to use Vue.js:
+
+- If you are starting a new feature or refactoring an old one that highly interacts with the DOM;
+- For real time data updates;
+- If you are creating a component that will be reused elsewhere;
+
+## When not to use Vue.js
+
+We don't want to refactor all GitLab frontend code into Vue.js, here are some guidelines for
+when not to use Vue.js:
+
+- Adding or changing static information;
+- Features that highly depend on jQuery will be hard to work with Vue.js
+
+As always, the Frontend Architectural Experts are available to help with any Vue or JavaScript questions.
+
+## How to build a new feature with Vue.js
+
+**Components, Stores and Services**
+
+In some features implemented with Vue.js, like the [issue board][issue-boards]
+or [environments table][environments-table]
+you can find a clear separation of concerns:
+
+```
+new_feature
+├── components
+│ └── component.js.es6
+│ └── ...
+├── store
+│ └── new_feature_store.js.es6
+├── service
+│ └── new_feature_service.js.es6
+├── new_feature_bundle.js.es6
+```
+_For consistency purposes, we recommend you to follow the same structure._
+
+Let's look into each of them:
+
+**A `*_bundle.js` file**
+
+This is the index file of your new feature. This is where the root Vue instance
+of the new feature should be.
+
+The Store and the Service should be imported and initialized in this file and provided as a prop to the main component.
+
+Don't forget to follow [these steps.][page_specific_javascript]
+
+**A folder for Components**
+
+This folder holds all components that are specific of this new feature.
+If you need to use or create a component that will probably be used somewhere
+else, please refer to `vue_shared/components`.
+
+A good thumb rule to know when you should create a component is to think if
+it will be reusable elsewhere.
+
+For example, tables are used in a quite amount of places across GitLab, a table
+would be a good fit for a component. On the other hand, a table cell used only
+in one table would not be a good use of this pattern.
+
+You can read more about components in Vue.js site, [Component System][component-system]
+
+**A folder for the Store**
+
+The Store is a class that allows us to manage the state in a single
+source of truth.
+
+The concept we are trying to follow is better explained by Vue documentation
+itself, please read this guide: [State Management][state-management]
+
+**A folder for the Service**
+
+The Service is used only to communicate with the server.
+It does not store or manipulate any data.
+We use [vue-resource][vue-resource-repo] to
+communicate with the server.
+
+The [issue boards service][issue-boards-service]
+is a good example of this pattern.
+
+## Style guide
+
+Please refer to the Vue section of our [style guide](style_guide_js.md#vuejs)
+for best practices while writing your Vue components and templates.
+
+
+[vue-docs]: http://vuejs.org/guide/index.html
+[issue-boards]: https://gitlab.com/gitlab-org/gitlab-ce/tree/master/app/assets/javascripts/boards
+[environments-table]: https://gitlab.com/gitlab-org/gitlab-ce/tree/master/app/assets/javascripts/environments
+[page_specific_javascript]: https://docs.gitlab.com/ce/development/frontend.html#page-specific-javascript
+[component-system]: https://vuejs.org/v2/guide/#Composing-with-Components
+[state-management]: https://vuejs.org/v2/guide/state-management.html#Simple-State-Management-from-Scratch
+[vue-resource-repo]: https://github.com/pagekit/vue-resource
+[issue-boards-service]: https://gitlab.com/gitlab-org/gitlab-ce/blob/master/app/assets/javascripts/boards/services/board_service.js.es6
diff --git a/doc/development/frontend.md b/doc/development/frontend.md
index 50105a486d0..f46cc377f95 100644
--- a/doc/development/frontend.md
+++ b/doc/development/frontend.md
@@ -1,511 +1,4 @@
-# Frontend Development Guidelines
-
-This document describes various guidelines to ensure consistency and quality
-across GitLab's frontend team.
-
-## Overview
-
-GitLab is built on top of [Ruby on Rails][rails] using [Haml][haml] with
-[Hamlit][hamlit]. Be wary of [the limitations that come with using
-Hamlit][hamlit-limits]. We also use [SCSS][scss] and plain JavaScript with
-[ES6 by way of Babel][es6].
-
-The asset pipeline is [Sprockets][sprockets], which handles the concatenation,
-minification, and compression of our assets.
-
-[jQuery][jquery] is used throughout the application's JavaScript, with
-[Vue.js][vue] for particularly advanced, dynamic elements.
-
-### Architecture
-
-The Frontend Architect is an expert who makes high-level frontend design choices
-and decides on technical standards, including coding standards, and frameworks.
-
-When you are assigned a new feature that requires architectural design,
-make sure it is discussed with one of the Frontend Architecture Experts.
-
-This rule also applies if you plan to change the architecture of an existing feature.
-
-These decisions should be accessible to everyone, so please document it on the Merge Request.
-
-You can find the Frontend Architecture experts on the [team page][team-page].
-
-You can find documentation about the desired architecture for a new feature built with Vue.js in [here][vue-section].
-
-### Realtime
-
-When writing code for realtime features we have to keep a couple of things in mind:
-1. Do not overload the server with requests.
-1. It should feel realtime.
-
-Thus, we must strike a balance between sending requests and the feeling of realtime.
-Use the following rules when creating realtime solutions.
-
-1. The server will tell you how much to poll by sending `Poll-Interval` in the header.
-Use that as your polling interval. This way it is easy for system administrators to change the
-polling rate.
-A `Poll-Interval: -1` means you should disable polling, and this must be implemented.
-1. A response with HTTP status `4XX` or `5XX` should disable polling as well.
-1. Use a common library for polling.
-1. Poll on active tabs only. Use a common library to find out which tab currently has eyes on it.
-Please use [Focus](https://gitlab.com/andrewn/focus). Specifically [Eyeballs Detector](https://gitlab.com/andrewn/focus/blob/master/lib/eyeballs-detector.js).
-1. Use regular polling intervals, do not use backoff polling, or jitter, as the interval will be
-controlled by the server.
-1. The backend code will most likely be using etags. You do not and should not check for status
-`304 Not Modified`. The browser will transform it for you.
-
-### Vue
-
-For more complex frontend features, we recommend using Vue.js. It shares
-some ideas with React.js as well as Angular.
-
-To get started with Vue, read through [their documentation][vue-docs].
-
-#### How to build a new feature with Vue.js
-**Components, Stores and Services**
-
-In some features implemented with Vue.js, like the [issue board][issue-boards]
-or [environments table][environments-table]
-you can find a clear separation of concerns:
-
-```
-new_feature
-├── components
-│ └── component.js.es6
-│ └── ...
-├── store
-│ └── new_feature_store.js.es6
-├── service
-│ └── new_feature_service.js.es6
-├── new_feature_bundle.js.es6
-```
-_For consistency purposes, we recommend you to follow the same structure._
-
-Let's look into each of them:
-
-**A `*_bundle.js` file**
-
-This is the index file of your new feature. This is where the root Vue instance
-of the new feature should be.
-
-The Store and the Service should be imported and initialized in this file and provided as a prop to the main component.
-
-Don't forget to follow [these steps.][page_specific_javascript]
-
-**A folder for Components**
-
-This folder holds all components that are specific of this new feature.
-If you need to use or create a component that will probably be used somewhere
-else, please refer to `vue_shared/components`.
-
-A good thumb rule to know when you should create a component is to think if
-it will be reusable elsewhere.
-
-For example, tables are used in a quite amount of places across GitLab, a table
-would be a good fit for a component.
-On the other hand, a table cell used only in on table, would not be a good use
-of this pattern.
-
-You can read more about components in Vue.js site, [Component System][component-system]
-
-**A folder for the Store**
-
-The Store is a class that allows us to manage the state in a single
-source of truth.
-
-The concept we are trying to follow is better explained by Vue documentation
-itself, please read this guide: [State Management][state-management]
-
-**A folder for the Service**
-
-The Service is used only to communicate with the server.
-It does not store or manipulate any data.
-We use [vue-resource][vue-resource-repo] to
-communicate with the server.
-
-The [issue boards service][issue-boards-service]
-is a good example of this pattern.
-
-## Performance
-
-### Resources
-
-- [WebPage Test][web-page-test] for testing site loading time and size.
-- [Google PageSpeed Insights][pagespeed-insights] grades web pages and provides feedback to improve the page.
-- [Profiling with Chrome DevTools][google-devtools-profiling]
-- [Browser Diet][browser-diet] is a community-built guide that catalogues practical tips for improving web page performance.
-
-### Page-specific JavaScript
-
-Certain pages may require the use of a third party library, such as [d3][d3] for
-the User Activity Calendar and [Chart.js][chartjs] for the Graphs pages. These
-libraries increase the page size significantly, and impact load times due to
-bandwidth bottlenecks and the browser needing to parse more JavaScript.
-
-In cases where libraries are only used on a few specific pages, we use
-"page-specific JavaScript" to prevent the main `application.js` file from
-becoming unnecessarily large.
-
-Steps to split page-specific JavaScript from the main `application.js`:
-
-1. Create a directory for the specific page(s), e.g. `graphs/`.
-1. In that directory, create a `namespace_bundle.js` file, e.g. `graphs_bundle.js`.
-1. In `graphs_bundle.js` add the line `//= require_tree .`, this adds all other files in the directory to the bundle.
-1. Add any necessary libraries to `app/assets/javascripts/lib/`, all files directly descendant from this directory will be precompiled as separate assets, in this case `chart.js` would be added.
-1. Add the new "bundle" file to the list of precompiled assets in
-`config/application.rb`.
- - For example: `config.assets.precompile << "graphs/graphs_bundle.js"`.
-1. Move code reliant on these libraries into the `graphs` directory.
-1. In the relevant views, add the scripts to the page with the following:
-
-```haml
-- content_for :page_specific_javascripts do
- = page_specific_javascript_tag('lib/chart.js')
- = page_specific_javascript_tag('graphs/graphs_bundle.js')
-```
-
-The above loads `chart.js` and `graphs_bundle.js` for this page only. `chart.js`
-is separated from the bundle file so it can be cached separately from the bundle
-and reused for other pages that also rely on the library. For an example, see
-[this Haml file][page-specific-js-example].
-
-### Minimizing page size
-
-A smaller page size means the page loads faster (especially important on mobile
-and poor connections), the page is parsed more quickly by the browser, and less
-data is used for users with capped data plans.
-
-General tips:
-
-- Don't add new fonts.
-- Prefer font formats with better compression, e.g. WOFF2 is better than WOFF, which is better than TTF.
-- Compress and minify assets wherever possible (For CSS/JS, Sprockets does this for us).
-- If some functionality can reasonably be achieved without adding extra libraries, avoid them.
-- Use page-specific JavaScript as described above to dynamically load libraries that are only needed on certain pages.
-
-## Accessibility
-
-### Resources
-
-[Chrome Accessibility Developer Tools][chrome-accessibility-developer-tools]
-are useful for testing for potential accessibility problems in GitLab.
-
-Accessibility best-practices and more in-depth information is available on
-[the Audit Rules page][audit-rules] for the Chrome Accessibility Developer Tools.
-
-## Security
-
-### Resources
-
-[Mozilla’s HTTP Observatory CLI][observatory-cli] and the
-[Qualys SSL Labs Server Test][qualys-ssl] are good resources for finding
-potential problems and ensuring compliance with security best practices.
-
-<!-- Uncomment these sections when CSP/SRI are implemented.
-### Content Security Policy (CSP)
-
-Content Security Policy is a web standard that intends to mitigate certain
-forms of Cross-Site Scripting (XSS) as well as data injection.
-
-Content Security Policy rules should be taken into consideration when
-implementing new features, especially those that may rely on connection with
-external services.
-
-GitLab's CSP is used for the following:
-
-- Blocking plugins like Flash and Silverlight from running at all on our pages.
-- Blocking the use of scripts and stylesheets downloaded from external sources.
-- Upgrading `http` requests to `https` when possible.
-- Preventing `iframe` elements from loading in most contexts.
-
-Some exceptions include:
-
-- Scripts from Google Analytics and Piwik if either is enabled.
-- Connecting with GitHub, Bitbucket, GitLab.com, etc. to allow project importing.
-- Connecting with Google, Twitter, GitHub, etc. to allow OAuth authentication.
-
-We use [the Secure Headers gem][secure_headers] to enable Content
-Security Policy headers in the GitLab Rails app.
-
-Some resources on implementing Content Security Policy:
-
-- [MDN Article on CSP][mdn-csp]
-- [GitHub’s CSP Journey on the GitHub Engineering Blog][github-eng-csp]
-- The Dropbox Engineering Blog's series on CSP: [1][dropbox-csp-1], [2][dropbox-csp-2], [3][dropbox-csp-3], [4][dropbox-csp-4]
-
-### Subresource Integrity (SRI)
-
-Subresource Integrity prevents malicious assets from being provided by a CDN by
-guaranteeing that the asset downloaded is identical to the asset the server
-is expecting.
-
-The Rails app generates a unique hash of the asset, which is used as the
-asset's `integrity` attribute. The browser generates the hash of the asset
-on-load and will reject the asset if the hashes do not match.
-
-All CSS and JavaScript assets should use Subresource Integrity. For implementation details,
-see the documentation for [the Sprockets implementation of SRI][sprockets-sri].
-
-Some resources on implementing Subresource Integrity:
-
-- [MDN Article on SRI][mdn-sri]
-- [Subresource Integrity on the GitHub Engineering Blog][github-eng-sri]
-
--->
-
-### Including external resources
-
-External fonts, CSS, and JavaScript should never be used with the exception of
-Google Analytics and Piwik - and only when the instance has enabled it. Assets
-should always be hosted and served locally from the GitLab instance. Embedded
-resources via `iframes` should never be used except in certain circumstances
-such as with ReCaptcha, which cannot be used without an `iframe`.
-
-### Avoiding inline scripts and styles
-
-In order to protect users from [XSS vulnerabilities][xss], we will disable inline scripts in the future using Content Security Policy.
-
-While inline scripts can be useful, they're also a security concern. If
-user-supplied content is unintentionally left un-sanitized, malicious users can
-inject scripts into the web app.
-
-Inline styles should be avoided in almost all cases, they should only be used
-when no alternatives can be found. This allows reusability of styles as well as
-readability.
-
-## Style guides and linting
-
-See the relevant style guides for our guidelines and for information on linting:
-
-- [SCSS][scss-style-guide]
-- JavaScript - We defer to [AirBnb][airbnb-js-style-guide] on most style-related
-conventions and enforce them with eslint. See [our current .eslintrc][eslintrc]
-for specific rules and patterns.
-
-## Testing
-
-Feature tests need to be written for all new features. Regression tests
-also need to be written for all bug fixes to prevent them from occurring
-again in the future.
-
-See [the Testing Standards and Style Guidelines](testing.md) for more
-information.
-
-### Running frontend tests
-
-`rake karma` runs the frontend-only (JavaScript) tests.
-It consists of two subtasks:
-
-- `rake karma:fixtures` (re-)generates fixtures
-- `rake karma:tests` actually executes the tests
-
-As long as the fixtures don't change, `rake karma:tests` is sufficient
-(and saves you some time).
-
-Please note: Not all of the frontend fixtures are generated. Some are still static
-files. These will not be touched by `rake karma:fixtures`.
-
-## Design Patterns
-
-### Singletons
-
-When exactly one object is needed for a given task, prefer to define it as a
-`class` rather than as an object literal. Prefer also to explicitly restrict
-instantiation, unless flexibility is important (e.g. for testing).
-
-```javascript
-// bad
-
-gl.MyThing = {
- prop1: 'hello',
- method1: () => {}
-};
-
-// good
-
-class MyThing {
- constructor() {
- this.prop1 = 'hello';
- }
- method1() {}
-}
-
-gl.MyThing = new MyThing();
-
-// best
-
-let singleton;
-
-class MyThing {
- constructor() {
- if (!singleton) {
- singleton = this;
- singleton.init();
- }
- return singleton;
- }
-
- init() {
- this.prop1 = 'hello';
- }
-
- method1() {}
-}
-
-gl.MyThing = MyThing;
-
-```
-
-### Manipulating the DOM in a JS Class
-
-When writing a class that needs to manipulate the DOM guarantee a container option is provided.
-This is useful when we need that class to be instantiated more than once in the same page.
-
-Bad:
-```javascript
-class Foo {
- constructor() {
- document.querySelector('.bar');
- }
-}
-new Foo();
-```
-
-Good:
-```javascript
-class Foo {
- constructor(opts) {
- document.querySelector(`${opts.container} .bar`);
- }
-}
-
-new Foo({ container: '.my-element' });
-```
-You can find an example of the above in this [class][container-class-example];
-
-## Supported browsers
-
-For our currently-supported browsers, see our [requirements][requirements].
-
-
-## Gotchas
-
-### Spec errors due to use of ES6 features in `.js` files
-
-If you see very generic JavaScript errors (e.g. `jQuery is undefined`) being
-thrown in Karma, Spinach, or Rspec tests but can't reproduce them manually,
-you may have included `ES6`-style JavaScript in files that don't have the
-`.js.es6` file extension. Either use ES5-friendly JavaScript or rename the file
-you're working in (`git mv <file.js> <file.js.es6>`).
-
-### Spec errors due to use of unsupported JavaScript
-
-Similar errors will be thrown if you're using JavaScript features not yet
-supported by our test runner's version of webkit, whether or not you've updated
-the file extension. Examples of unsupported JavaScript features are:
-
-- Array.from
-- Array.find
-- Array.first
-- Object.assign
-- Async functions
-- Generators
-- Array destructuring
-- For Of
-- Symbol/Symbol.iterator
-- Spread
-
-Until these are polyfilled or transpiled appropriately, they should not be used.
-Please update this list with additional unsupported features or when any of
-these are made usable.
-
-### Spec errors due to JavaScript not enabled
-
-If, as a result of a change you've made, a feature now depends on JavaScript to
-run correctly, you need to make sure a JavaScript web driver is enabled when
-specs are run. If you don't you'll see vague error messages from the spec
-runner, and an explosion of vague console errors in the HTML snapshot.
-
-To enable a JavaScript driver in an `rspec` test, add `js: true` to the
-individual spec or the context block containing multiple specs that need
-JavaScript enabled:
-
-```ruby
-
-# For one spec
-it 'presents information about abuse report', js: true do
- # assertions...
-end
-
-describe "Admin::AbuseReports", js: true do
- it 'presents information about abuse report' do
- # assertions...
- end
- it 'shows buttons for adding to abuse report' do
- # assertions...
- end
-end
-```
-
-In Spinach, the JavaScript driver is enabled differently. In the `*.feature`
-file for the failing spec, add the `@javascript` flag above the Scenario:
-
-```
-@javascript
-Scenario: Developer can approve merge request
- Given I am a "Shop" developer
- And I visit project "Shop" merge requests page
- And merge request 'Bug NS-04' must be approved
- And I click link "Bug NS-04"
- When I click link "Approve"
- Then I should see approved merge request "Bug NS-04"
-
-```
+# Frontend Development Guidelines
-[rails]: http://rubyonrails.org/
-[haml]: http://haml.info/
-[hamlit]: https://github.com/k0kubun/hamlit
-[hamlit-limits]: https://github.com/k0kubun/hamlit/blob/master/REFERENCE.md#limitations
-[scss]: http://sass-lang.com/
-[es6]: https://babeljs.io/
-[sprockets]: https://github.com/rails/sprockets
-[jquery]: https://jquery.com/
-[vue]: http://vuejs.org/
-[vue-docs]: http://vuejs.org/guide/index.html
-[web-page-test]: http://www.webpagetest.org/
-[pagespeed-insights]: https://developers.google.com/speed/pagespeed/insights/
-[google-devtools-profiling]: https://developers.google.com/web/tools/chrome-devtools/profile/?hl=en
-[browser-diet]: https://browserdiet.com/
-[d3]: https://d3js.org/
-[chartjs]: http://www.chartjs.org/
-[page-specific-js-example]: https://gitlab.com/gitlab-org/gitlab-ce/blob/13bb9ed77f405c5f6ee4fdbc964ecf635c9a223f/app/views/projects/graphs/_head.html.haml#L6-8
-[chrome-accessibility-developer-tools]: https://github.com/GoogleChrome/accessibility-developer-tools
-[audit-rules]: https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules
-[observatory-cli]: https://github.com/mozilla/http-observatory-cli
-[qualys-ssl]: https://www.ssllabs.com/ssltest/analyze.html
-[secure_headers]: https://github.com/twitter/secureheaders
-[mdn-csp]: https://developer.mozilla.org/en-US/docs/Web/Security/CSP
-[github-eng-csp]: http://githubengineering.com/githubs-csp-journey/
-[dropbox-csp-1]: https://blogs.dropbox.com/tech/2015/09/on-csp-reporting-and-filtering/
-[dropbox-csp-2]: https://blogs.dropbox.com/tech/2015/09/unsafe-inline-and-nonce-deployment/
-[dropbox-csp-3]: https://blogs.dropbox.com/tech/2015/09/csp-the-unexpected-eval/
-[dropbox-csp-4]: https://blogs.dropbox.com/tech/2015/09/csp-third-party-integrations-and-privilege-separation/
-[mdn-sri]: https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity
-[github-eng-sri]: http://githubengineering.com/subresource-integrity/
-[sprockets-sri]: https://github.com/rails/sprockets-rails#sri-support
-[xss]: https://en.wikipedia.org/wiki/Cross-site_scripting
-[scss-style-guide]: scss_styleguide.md
-[requirements]: ../install/requirements.md#supported-web-browsers
-[issue-boards]: https://gitlab.com/gitlab-org/gitlab-ce/tree/master/app/assets/javascripts/boards
-[environments-table]: https://gitlab.com/gitlab-org/gitlab-ce/tree/master/app/assets/javascripts/environments
-[page_specific_javascript]: https://docs.gitlab.com/ce/development/frontend.html#page-specific-javascript
-[component-system]: https://vuejs.org/v2/guide/#Composing-with-Components
-[state-management]: https://vuejs.org/v2/guide/state-management.html#Simple-State-Management-from-Scratch
-[vue-resource-repo]: https://github.com/pagekit/vue-resource
-[issue-boards-service]: https://gitlab.com/gitlab-org/gitlab-ce/blob/master/app/assets/javascripts/boards/services/board_service.js.es6
-[airbnb-js-style-guide]: https://github.com/airbnb/javascript
-[eslintrc]: https://gitlab.com/gitlab-org/gitlab-ce/blob/master/.eslintrc
-[team-page]: https://about.gitlab.com/team
-[vue-section]: https://docs.gitlab.com/ce/development/frontend.html#how-to-build-a-new-feature-with-vue-js
-[container-class-example]: https://gitlab.com/gitlab-org/gitlab-ce/blob/master/app/assets/javascripts/mini_pipeline_graph_dropdown.js
+This page has moved [here](fe_guide/index.md).
diff --git a/doc/development/rake_tasks.md b/doc/development/rake_tasks.md
index dcd978c4cd3..ec9e4dcc59d 100644
--- a/doc/development/rake_tasks.md
+++ b/doc/development/rake_tasks.md
@@ -42,6 +42,20 @@ To run several tests inside one directory:
If you want to use [Spring](https://github.com/rails/spring) set
`ENABLE_SPRING=1` in your environment.
+## Compile Frontend Assets
+
+You shouldn't ever need to compile frontend assets manually in development, but
+if you ever need to test how the assets get compiled in a production
+environment you can do so with the following command:
+
+```
+RAILS_ENV=production NODE_ENV=production bundle exec rake gitlab:assets:compile
+```
+
+This will compile and minify all JavaScript and CSS assets and copy them along
+with all other frontend assets (images, fonts, etc) into `/public/assets` where
+they can be easily inspected.
+
## Generate API documentation for project services (e.g. Slack)
```
diff --git a/doc/development/testing.md b/doc/development/testing.md
index 5ac7b8dadeb..5bc958f5a96 100644
--- a/doc/development/testing.md
+++ b/doc/development/testing.md
@@ -34,16 +34,17 @@ GitLab uses [factory_girl] as a test fixture replacement.
GitLab uses [Karma] to run its [Jasmine] JavaScript specs. They can be run on
the command line via `bundle exec karma`.
-- JavaScript tests live in `spec/javascripts/`, matching the folder structure of
- `app/assets/javascripts/`: `app/assets/javascripts/behaviors/autosize.js` has a corresponding
- `spec/javascripts/behaviors/autosize_spec.js` file.
+- JavaScript tests live in `spec/javascripts/`, matching the folder structure
+ of `app/assets/javascripts/`: `app/assets/javascripts/behaviors/autosize.js`
+ has a corresponding `spec/javascripts/behaviors/autosize_spec.js` file.
- Haml fixtures required for JavaScript tests live in
`spec/javascripts/fixtures`. They should contain the bare minimum amount of
markup necessary for the test.
> **Warning:** Keep in mind that a Rails view may change and
invalidate your test, but everything will still pass because your fixture
- doesn't reflect the latest view.
+ doesn't reflect the latest view. Because of this we encourage you to
+ generate fixtures from actual rails views whenever possible.
- Keep in mind that in a CI environment, these tests are run in a headless
browser and you will not have access to certain APIs, such as
@@ -53,6 +54,8 @@ the command line via `bundle exec karma`.
[Karma]: https://github.com/karma-runner/karma
[Jasmine]: https://github.com/jasmine/jasmine
+For more information, see the [frontend testing guide](fe_guide/testing.md).
+
## RSpec
### General Guidelines
diff --git a/doc/install/installation.md b/doc/install/installation.md
index 177e1a9378b..a6b10176450 100644
--- a/doc/install/installation.md
+++ b/doc/install/installation.md
@@ -109,7 +109,8 @@ Then select 'Internet Site' and press enter to confirm the hostname.
## 2. Ruby
-**Note:** The current supported Ruby versions are 2.1.x and 2.3.x. 2.3.x is preferred, and support for 2.1.x will be dropped in the future.
+**Note:** The current supported Ruby version is 2.3.x. GitLab 9.0 dropped support
+for Ruby 2.1.x.
The use of Ruby version managers such as [RVM], [rbenv] or [chruby] with GitLab
in production, frequently leads to hard to diagnose problems. For example,
@@ -456,6 +457,36 @@ Make GitLab start on boot:
sudo update-rc.d gitlab defaults 21
+### Install Gitaly
+
+As of GitLab 9.0 Gitaly is an **optional** component. Its
+configuration is expected to change in GitLab 9.1. It is OK to wait
+with setting up Gitaly until you upgrade to GitLab 9.1 or later.
+
+ # Fetch Gitaly source with Git and compile with Go
+ sudo -u git -H bundle exec rake "gitlab:gitaly:install[/home/git/gitaly]" RAILS_ENV=production
+
+ # Restrict Gitaly socket access
+ sudo chmod 0700 /home/git/gitlab/tmp/sockets/private
+ sudo chown git /home/git/gitlab/tmp/sockets/private
+
+ # Configure Gitaly
+ echo 'GITALY_SOCKET_PATH=/home/git/gitlab/tmp/sockets/private/gitaly.socket' | \
+ sudo -u git tee -a /home/git/gitaly/env
+
+ # Enable Gitaly in the init script
+ echo 'gitaly_enabled=true' | sudo tee -a /etc/default/gitlab
+
+Next, edit `/home/git/gitlab/config/gitlab.yml` and make sure `socket_path` in
+the `gitaly:` section is uncommented.
+
+ # <- gitlab.yml indentation starts here
+ gitaly:
+ socket_path: tmp/sockets/private/gitaly.socket
+
+For more information about configuring Gitaly see
+[doc/administration/gitaly](../administration/gitaly).
+
### Setup Logrotate
sudo cp lib/support/logrotate/gitlab /etc/logrotate.d/gitlab
diff --git a/doc/profile/README.md b/doc/profile/README.md
index 6f8359d87fa..54e44d65959 100644
--- a/doc/profile/README.md
+++ b/doc/profile/README.md
@@ -1,4 +1,4 @@
-# Profile Settings
+# Profile settings
-- [Preferences](preferences.md)
-- [Two-factor Authentication (2FA)](two_factor_authentication.md)
+- [Preferences](../user/profile/preferences.md)
+- [Two-factor Authentication (2FA)](../user/profile/account/two_factor_authentication.md)
diff --git a/doc/profile/preferences.md b/doc/profile/preferences.md
index 4f2b00f3dd1..cc16f3afe41 100644
--- a/doc/profile/preferences.md
+++ b/doc/profile/preferences.md
@@ -1,36 +1 @@
-# Profile Preferences
-
-Settings in the **Profile > Preferences** page allow the user to customize
-various aspects of the site to their liking.
-
-## Syntax highlighting theme
-
-_GitLab uses the [rouge ruby library][rouge] for syntax highlighting. For a
-list of supported languages visit the rouge website._
-
-Changing this setting allows the user to customize the theme used when viewing
-syntax highlighted code on the site.
-
-The default is **White**.
-
-## Behavior
-
-### Default Dashboard
-
-For users who have access to a large number of projects but only keep up with a
-select few, the amount of activity on the default Dashboard page can be
-overwhelming.
-
-Changing this setting allows the user to redefine what their default dashboard
-will be. Setting it to **Starred Projects** will make that Dashboard view the
-default when signing in or clicking the application logo in the upper left.
-
-The default is **Your Projects**.
-
-### Default Project view
-
-It allows user to choose what content he or she want to see on project page.
-
-The default is **Readme**.
-
-[rouge]: http://rouge.jneen.net/ "Rouge website"
+This document was moved to [another location](../user/profile/preferences.md).
diff --git a/doc/update/8.13-to-8.14.md b/doc/update/8.13-to-8.14.md
index 327ecb7cdc2..aa1c659717e 100644
--- a/doc/update/8.13-to-8.14.md
+++ b/doc/update/8.13-to-8.14.md
@@ -72,7 +72,7 @@ sudo -u git -H git checkout 8-14-stable-ee
```bash
cd /home/git/gitlab-shell
sudo -u git -H git fetch --all --tags
-sudo -u git -H git checkout v4.0.3
+sudo -u git -H git checkout v4.1.1
```
### 6. Update gitlab-workhorse
diff --git a/doc/update/8.17-to-9.0.md b/doc/update/8.17-to-9.0.md
index b7ba970031c..6308317b1f2 100644
--- a/doc/update/8.17-to-9.0.md
+++ b/doc/update/8.17-to-9.0.md
@@ -25,9 +25,8 @@ sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production
### 3. Update Ruby
-We will continue supporting Ruby < 2.3 for the time being but we recommend you
-upgrade to Ruby 2.3 if you're running a source installation, as this is the same
-version that ships with our Omnibus package.
+NOTE: GitLab 9.0 only supports Ruby 2.3.x and dropped support for Ruby 2.1.x. Be
+sure to upgrade your interpreter if necessary.
You can check which version you are running with `ruby -v`.
@@ -98,54 +97,32 @@ cd /home/git/gitlab
sudo -u git -H git checkout 9-0-stable-ee
```
-### 6. Install libs, migrations, etc.
+### 6. Update gitlab-shell
```bash
-cd /home/git/gitlab
-
-# MySQL installations (note: the line below states '--without postgres')
-sudo -u git -H bundle install --without postgres development test --deployment
-
-# PostgreSQL installations (note: the line below states '--without mysql')
-sudo -u git -H bundle install --without mysql development test --deployment
-
-# Optional: clean up old gems
-sudo -u git -H bundle clean
-
-# Run database migrations
-sudo -u git -H bundle exec rake db:migrate RAILS_ENV=production
-
-# Update node dependencies and recompile assets
-sudo -u git -H bundle exec rake yarn:install gitlab:assets:clean gitlab:assets:compile RAILS_ENV=production NODE_ENV=production
+cd /home/git/gitlab-shell
-# Clean up cache
-sudo -u git -H bundle exec rake cache:clear RAILS_ENV=production
+sudo -u git -H git fetch --all --tags
+sudo -u git -H git checkout v$(</home/git/gitlab/GITLAB_SHELL_VERSION)
```
-**MySQL installations**: Run through the `MySQL strings limits` and `Tables and data conversion to utf8mb4` [tasks](../install/database_mysql.md).
-
### 7. Update gitlab-workhorse
Install and compile gitlab-workhorse. This requires
[Go 1.5](https://golang.org/dl) which should already be on your system from
-GitLab 8.1.
+GitLab 8.1. GitLab-Workhorse uses [GNU Make](https://www.gnu.org/software/make/).
+If you are not using Linux you may have to run `gmake` instead of
+`make` below.
```bash
-cd /home/git/gitlab
-
-sudo -u git -H bundle exec rake "gitlab:workhorse:install[/home/git/gitlab-workhorse]" RAILS_ENV=production
-```
-
-### 8. Update gitlab-shell
-
-```bash
-cd /home/git/gitlab-shell
+cd /home/git/gitlab-workhorse
sudo -u git -H git fetch --all --tags
-sudo -u git -H git checkout v5.0.0
+sudo -u git -H git checkout v$(</home/git/gitlab/GITLAB_WORKHORSE_VERSION)
+sudo -u git -H make
```
-### 9. Update configuration files
+### 8. Update configuration files
#### New configuration options for `gitlab.yml`
@@ -282,14 +259,48 @@ For Ubuntu 16.04.1 LTS:
sudo systemctl daemon-reload
```
-### 10. Start application
+### 9. Install libs, migrations, etc.
+
+```bash
+cd /home/git/gitlab
+
+# MySQL installations (note: the line below states '--without postgres')
+sudo -u git -H bundle install --without postgres development test --deployment
+
+# PostgreSQL installations (note: the line below states '--without mysql')
+sudo -u git -H bundle install --without mysql development test --deployment
+
+# Optional: clean up old gems
+sudo -u git -H bundle clean
+
+# Run database migrations
+sudo -u git -H bundle exec rake db:migrate RAILS_ENV=production
+
+# Update node dependencies and recompile assets
+sudo -u git -H bundle exec rake yarn:install gitlab:assets:clean gitlab:assets:compile RAILS_ENV=production NODE_ENV=production
+
+# Clean up cache
+sudo -u git -H bundle exec rake cache:clear RAILS_ENV=production
+```
+
+**MySQL installations**: Run through the `MySQL strings limits` and `Tables and data conversion to utf8mb4` [tasks](../install/database_mysql.md).
+
+### 10. Optional: install Gitaly
+
+Gitaly is still an optional component of GitLab. If you want to save time
+during your 9.0 upgrade **you can skip this step**.
+
+If you do want to set up Gitaly in GitLab 9.0 then follow [Gitaly section of the installation
+guide](../install/installation.md#install-gitaly).
+
+### 11. Start application
```bash
sudo service gitlab start
sudo service nginx restart
```
-### 11. Check application status
+### 12. Check application status
Check if GitLab and its environment are configured correctly:
diff --git a/doc/user/profile/preferences.md b/doc/user/profile/preferences.md
new file mode 100644
index 00000000000..e5038835027
--- /dev/null
+++ b/doc/user/profile/preferences.md
@@ -0,0 +1,64 @@
+# Profile preferences
+
+A user's profile preferences page allows the user to customize various aspects
+of GitLab to their liking.
+
+To navigate to your profile's preferences, click your avatar icon in the top
+right corner and select **Settings**. From there on, choose the **Preferences**
+tab.
+
+## Syntax highlighting theme
+
+>**Note:**
+GitLab uses the [rouge Ruby library][rouge] for syntax highlighting. For a
+list of supported languages visit the rouge website.
+
+Changing this setting allows you to customize the color theme when viewing any
+syntax highlighted code on GitLab.
+
+The default one is **White**, and you can choose among 5 different colors:
+
+- White
+- Dark
+- Solarized light
+- Solarized dark
+- Monokai
+
+## Behavior
+
+The following settings allow you to customize the behavior of GitLab's layout
+and default views of your dashboard and the projects' landing pages.
+
+### Layout width
+
+GitLab can be set up to use different widths depending on your liking. Choose
+between the fixed (max. 1200px) and the fluid (100%) application layout.
+
+### Default dashboard
+
+For users who have access to a large number of projects but only keep up with a
+select few, the amount of activity on the default Dashboard page can be
+overwhelming. Changing this setting allows you to redefine what your default
+dashboard will be.
+
+You have 6 options here that you can use for your default dashboard view:
+
+- Your projects (default)
+- Starred projects
+- Your projects' activity
+- Starred projects' activity
+- Your groups
+- Your [Todos]
+
+### Default project view
+
+The default project view settings allows you to choose what content you want to
+see on a project's landing page.
+
+You can choose between 2 options:
+
+- Show the files and the readme (default)
+- Show the project's activity
+
+[rouge]: http://rouge.jneen.net/ "Rouge website"
+[todos]: ../../workflow/todos.md
diff --git a/doc/workflow/shortcuts.md b/doc/workflow/shortcuts.md
index 7aa9b46081a..f94357abec9 100644
--- a/doc/workflow/shortcuts.md
+++ b/doc/workflow/shortcuts.md
@@ -36,6 +36,7 @@ You can see GitLab's keyboard shortcuts by using 'shift + ?'
| <kbd>g</kbd> + <kbd>p</kbd> | Go to projects |
| <kbd>g</kbd> + <kbd>i</kbd> | Go to issues |
| <kbd>g</kbd> + <kbd>m</kbd> | Go to merge requests |
+| <kbd>g</kbd> + <kbd>t</kbd> | Go to todos |
## Project
diff --git a/lib/gitlab/etag_caching/store.rb b/lib/gitlab/etag_caching/store.rb
index 9532e432f78..0039fc01c8f 100644
--- a/lib/gitlab/etag_caching/store.rb
+++ b/lib/gitlab/etag_caching/store.rb
@@ -1,7 +1,7 @@
module Gitlab
module EtagCaching
class Store
- EXPIRY_TIME = 10.minutes
+ EXPIRY_TIME = 20.minutes
REDIS_NAMESPACE = 'etag:'.freeze
def get(key)
diff --git a/lib/gitlab/gitaly_client.rb b/lib/gitlab/gitaly_client.rb
index 5534d4af439..1ce47ef2b05 100644
--- a/lib/gitlab/gitaly_client.rb
+++ b/lib/gitlab/gitaly_client.rb
@@ -2,6 +2,8 @@ require 'gitaly'
module Gitlab
module GitalyClient
+ SERVER_VERSION_FILE = 'GITALY_SERVER_VERSION'.freeze
+
def self.gitaly_address
if Gitlab.config.gitaly.socket_path
"unix://#{Gitlab.config.gitaly.socket_path}"
@@ -39,5 +41,10 @@ module Gitlab
yield is_enabled
end
end
+
+ def self.expected_server_version
+ path = Rails.root.join(SERVER_VERSION_FILE)
+ path.read.chomp
+ end
end
end
diff --git a/lib/gitlab/testing/request_blocker_middleware.rb b/lib/gitlab/testing/request_blocker_middleware.rb
new file mode 100644
index 00000000000..aa67fa08577
--- /dev/null
+++ b/lib/gitlab/testing/request_blocker_middleware.rb
@@ -0,0 +1,61 @@
+# rubocop:disable Style/ClassVars
+
+# This is inspired by http://www.salsify.com/blog/engineering/tearing-capybara-ajax-tests
+# Rack middleware that keeps track of the number of active requests and can block new requests.
+module Gitlab
+ module Testing
+ class RequestBlockerMiddleware
+ @@num_active_requests = Concurrent::AtomicFixnum.new(0)
+ @@block_requests = Concurrent::AtomicBoolean.new(false)
+
+ # Returns the number of requests the server is currently processing.
+ def self.num_active_requests
+ @@num_active_requests.value
+ end
+
+ # Prevents the server from accepting new requests. Any new requests will return an HTTP
+ # 503 status.
+ def self.block_requests!
+ @@block_requests.value = true
+ end
+
+ # Allows the server to accept requests again.
+ def self.allow_requests!
+ @@block_requests.value = false
+ end
+
+ def initialize(app)
+ @app = app
+ end
+
+ def call(env)
+ increment_active_requests
+ if block_requests?
+ block_request(env)
+ else
+ @app.call(env)
+ end
+ ensure
+ decrement_active_requests
+ end
+
+ private
+
+ def block_requests?
+ @@block_requests.true?
+ end
+
+ def block_request(env)
+ [503, {}, []]
+ end
+
+ def increment_active_requests
+ @@num_active_requests.increment
+ end
+
+ def decrement_active_requests
+ @@num_active_requests.decrement
+ end
+ end
+ end
+end
diff --git a/lib/support/init.d/gitlab b/lib/support/init.d/gitlab
index 5fd7f0f98bd..09e121e5120 100755
--- a/lib/support/init.d/gitlab
+++ b/lib/support/init.d/gitlab
@@ -48,6 +48,10 @@ gitlab_pages_pid_path="$pid_path/gitlab-pages.pid"
gitlab_pages_options="-pages-domain example.com -pages-root $app_root/shared/pages -listen-proxy 127.0.0.1:8090"
gitlab_pages_log="$app_root/log/gitlab-pages.log"
shell_path="/bin/bash"
+gitaly_enabled=false
+gitaly_dir=$(cd $app_root/../gitaly 2> /dev/null && pwd)
+gitaly_pid_path="$pid_path/gitaly.pid"
+gitaly_log="$app_root/log/gitaly.log"
# Read configuration variable file if it is present
test -f /etc/default/gitlab && . /etc/default/gitlab
@@ -101,13 +105,20 @@ check_pids(){
gppid=0
fi
fi
+ if [ "$gitaly_enabled" = true ]; then
+ if [ -f "$gitaly_pid_path" ]; then
+ gapid=$(cat "$gitaly_pid_path")
+ else
+ gapid=0
+ fi
+ fi
}
## Called when we have started the two processes and are waiting for their pid files.
wait_for_pids(){
# We are sleeping a bit here mostly because sidekiq is slow at writing its pid
i=0;
- while [ ! -f $web_server_pid_path ] || [ ! -f $sidekiq_pid_path ] || [ ! -f $gitlab_workhorse_pid_path ] || { [ "$mail_room_enabled" = true ] && [ ! -f $mail_room_pid_path ]; } || { [ "$gitlab_pages_enabled" = true ] && [ ! -f $gitlab_pages_pid_path ]; }; do
+ while [ ! -f $web_server_pid_path ] || [ ! -f $sidekiq_pid_path ] || [ ! -f $gitlab_workhorse_pid_path ] || { [ "$mail_room_enabled" = true ] && [ ! -f $mail_room_pid_path ]; } || { [ "$gitlab_pages_enabled" = true ] && [ ! -f $gitlab_pages_pid_path ]; } || { [ "$gitaly_enabled" = true ] && [ ! -f $gitaly_pid_path ]; }; do
sleep 0.1;
i=$((i+1))
if [ $((i%10)) = 0 ]; then
@@ -164,7 +175,15 @@ check_status(){
gitlab_pages_status="-1"
fi
fi
- if [ $web_status = 0 ] && [ $sidekiq_status = 0 ] && [ $gitlab_workhorse_status = 0 ] && { [ "$mail_room_enabled" != true ] || [ $mail_room_status = 0 ]; } && { [ "$gitlab_pages_enabled" != true ] || [ $gitlab_pages_status = 0 ]; }; then
+ if [ "$gitaly_enabled" = true ]; then
+ if [ $gapid -ne 0 ]; then
+ kill -0 "$gapid" 2>/dev/null
+ gitaly_status="$?"
+ else
+ gitaly_status="-1"
+ fi
+ fi
+ if [ $web_status = 0 ] && [ $sidekiq_status = 0 ] && [ $gitlab_workhorse_status = 0 ] && { [ "$mail_room_enabled" != true ] || [ $mail_room_status = 0 ]; } && { [ "$gitlab_pages_enabled" != true ] || [ $gitlab_pages_status = 0 ]; } && { [ "$gitaly_enabled" != true ] || [ $gitaly_status = 0 ]; }; then
gitlab_status=0
else
# http://refspecs.linuxbase.org/LSB_4.1.0/LSB-Core-generic/LSB-Core-generic/iniscrptact.html
@@ -213,12 +232,19 @@ check_stale_pids(){
exit 1
fi
fi
+ if [ "$gitaly_enabled" = true ] && [ "$gapid" != "0" ] && [ "$gitaly_status" != "0" ]; then
+ echo "Removing stale Gitaly pid. This is most likely caused by Gitaly crashing the last time it ran."
+ if ! rm "$gitaly_pid_path"; then
+ echo "Unable to remove stale pid, exiting"
+ exit 1
+ fi
+ fi
}
## If no parts of the service is running, bail out.
exit_if_not_running(){
check_stale_pids
- if [ "$web_status" != "0" ] && [ "$sidekiq_status" != "0" ] && [ "$gitlab_workhorse_status" != "0" ] && { [ "$mail_room_enabled" != true ] || [ "$mail_room_status" != "0" ]; } && { [ "$gitlab_pages_enabled" != true ] || [ "$gitlab_pages_status" != "0" ]; }; then
+ if [ "$web_status" != "0" ] && [ "$sidekiq_status" != "0" ] && [ "$gitlab_workhorse_status" != "0" ] && { [ "$mail_room_enabled" != true ] || [ "$mail_room_status" != "0" ]; } && { [ "$gitlab_pages_enabled" != true ] || [ "$gitlab_pages_status" != "0" ]; } && { [ "$gitaly_enabled" != true ] || [ "$gitaly_status" != "0" ]; }; then
echo "GitLab is not running."
exit
fi
@@ -243,6 +269,9 @@ start_gitlab() {
if [ "$gitlab_pages_enabled" = true ] && [ "$gitlab_pages_status" != "0" ]; then
echo "Starting GitLab Pages"
fi
+ if [ "$gitaly_enabled" = true ] && [ "$gitaly_status" != "0" ]; then
+ echo "Starting Gitaly"
+ fi
# Then check if the service is running. If it is: don't start again.
if [ "$web_status" = "0" ]; then
@@ -292,6 +321,16 @@ start_gitlab() {
fi
fi
+ if [ "$gitaly_enabled" = true ]; then
+ if [ "$gitaly_status" = "0" ]; then
+ echo "Gitaly is already running with pid $gapid, not restarting"
+ else
+ $app_root/bin/daemon_with_pidfile $gitaly_pid_path \
+ $app_root/bin/with_env $gitaly_dir/env \
+ $gitaly_dir/gitaly >> $gitaly_log 2>&1 &
+ fi
+ fi
+
# Wait for the pids to be planted
wait_for_pids
# Finally check the status to tell wether or not GitLab is running
@@ -322,13 +361,17 @@ stop_gitlab() {
echo "Shutting down gitlab-pages"
kill -- $(cat $gitlab_pages_pid_path)
fi
+ if [ "$gitaly_status" = "0" ]; then
+ echo "Shutting down Gitaly"
+ kill -- $(cat $gitaly_pid_path)
+ fi
# If something needs to be stopped, lets wait for it to stop. Never use SIGKILL in a script.
- while [ "$web_status" = "0" ] || [ "$sidekiq_status" = "0" ] || [ "$gitlab_workhorse_status" = "0" ] || { [ "$mail_room_enabled" = true ] && [ "$mail_room_status" = "0" ]; } || { [ "$gitlab_pages_enabled" = true ] && [ "$gitlab_pages_status" = "0" ]; }; do
+ while [ "$web_status" = "0" ] || [ "$sidekiq_status" = "0" ] || [ "$gitlab_workhorse_status" = "0" ] || { [ "$mail_room_enabled" = true ] && [ "$mail_room_status" = "0" ]; } || { [ "$gitlab_pages_enabled" = true ] && [ "$gitlab_pages_status" = "0" ]; } || { [ "$gitaly_enabled" = true ] && [ "$gitaly_status" = "0" ]; }; do
sleep 1
check_status
printf "."
- if [ "$web_status" != "0" ] && [ "$sidekiq_status" != "0" ] && [ "$gitlab_workhorse_status" != "0" ] && { [ "$mail_room_enabled" != true ] || [ "$mail_room_status" != "0" ]; } && { [ "$gitlab_pages_enabled" != true ] || [ "$gitlab_pages_status" != "0" ]; }; then
+ if [ "$web_status" != "0" ] && [ "$sidekiq_status" != "0" ] && [ "$gitlab_workhorse_status" != "0" ] && { [ "$mail_room_enabled" != true ] || [ "$mail_room_status" != "0" ]; } && { [ "$gitlab_pages_enabled" != true ] || [ "$gitlab_pages_status" != "0" ]; } && { [ "$gitaly_enabled" != true ] || [ "$gitaly_status" != "0" ]; }; then
printf "\n"
break
fi
@@ -343,6 +386,7 @@ stop_gitlab() {
rm "$mail_room_pid_path" 2>/dev/null
fi
rm -f "$gitlab_pages_pid_path"
+ rm -f "$gitaly_pid_path"
print_status
}
@@ -350,7 +394,7 @@ stop_gitlab() {
## Prints the status of GitLab and its components.
print_status() {
check_status
- if [ "$web_status" != "0" ] && [ "$sidekiq_status" != "0" ] && [ "$gitlab_workhorse_status" != "0" ] && { [ "$mail_room_enabled" != true ] || [ "$mail_room_status" != "0" ]; } && { [ "$gitlab_pages_enabled" != true ] || [ "$gitlab_pages_status" != "0" ]; }; then
+ if [ "$web_status" != "0" ] && [ "$sidekiq_status" != "0" ] && [ "$gitlab_workhorse_status" != "0" ] && { [ "$mail_room_enabled" != true ] || [ "$mail_room_status" != "0" ]; } && { [ "$gitlab_pages_enabled" != true ] || [ "$gitlab_pages_status" != "0" ]; } && { [ "$gitaly_enabled" != true ] || [ "$gitaly_status" != "0" ]; }; then
echo "GitLab is not running."
return
fi
@@ -383,7 +427,14 @@ print_status() {
printf "The GitLab Pages is \033[31mnot running\033[0m.\n"
fi
fi
- if [ "$web_status" = "0" ] && [ "$sidekiq_status" = "0" ] && [ "$gitlab_workhorse_status" = "0" ] && { [ "$mail_room_enabled" != true ] || [ "$mail_room_status" = "0" ]; } && { [ "$gitlab_pages_enabled" != true ] || [ "$gitlab_pages_status" = "0" ]; }; then
+ if [ "$gitaly_enabled" = true ]; then
+ if [ "$gitaly_status" = "0" ]; then
+ echo "Gitaly with pid $gapid is running."
+ else
+ printf "Gitaly is \033[31mnot running\033[0m.\n"
+ fi
+ fi
+ if [ "$web_status" = "0" ] && [ "$sidekiq_status" = "0" ] && [ "$gitlab_workhorse_status" = "0" ] && { [ "$mail_room_enabled" != true ] || [ "$mail_room_status" = "0" ]; } && { [ "$gitlab_pages_enabled" != true ] || [ "$gitlab_pages_status" = "0" ]; } && { [ "$gitaly_enabled" != true ] || [ "$gitaly_status" = "0" ]; }; then
printf "GitLab and all its components are \033[32mup and running\033[0m.\n"
fi
}
@@ -414,7 +465,7 @@ reload_gitlab(){
## Restarts Sidekiq and Unicorn.
restart_gitlab(){
check_status
- if [ "$web_status" = "0" ] || [ "$sidekiq_status" = "0" ] || [ "$gitlab_workhorse" = "0" ] || { [ "$mail_room_enabled" = true ] && [ "$mail_room_status" = "0" ]; } || { [ "$gitlab_pages_enabled" = true ] && [ "$gitlab_pages_status" = "0" ]; }; then
+ if [ "$web_status" = "0" ] || [ "$sidekiq_status" = "0" ] || [ "$gitlab_workhorse" = "0" ] || { [ "$mail_room_enabled" = true ] && [ "$mail_room_status" = "0" ]; } || { [ "$gitlab_pages_enabled" = true ] && [ "$gitlab_pages_status" = "0" ]; } || { [ "$gitaly_enabled" = true ] && [ "$gitaly_status" = "0" ]; }; then
stop_gitlab
fi
start_gitlab
diff --git a/lib/support/init.d/gitlab.default.example b/lib/support/init.d/gitlab.default.example
index f6642527639..9472c3c992f 100644
--- a/lib/support/init.d/gitlab.default.example
+++ b/lib/support/init.d/gitlab.default.example
@@ -84,3 +84,7 @@ mail_room_pid_path="$pid_path/mail_room.pid"
# shell other than "bash"
# The default is "/bin/bash"
shell_path="/bin/bash"
+
+# This variable controls whether the init script starts/stops Gitaly
+gitaly_enabled=false
+gitaly_log="$app_root/log/gitaly.log"
diff --git a/lib/tasks/gitlab/assets.rake b/lib/tasks/gitlab/assets.rake
index 098f9851b45..003d57adbbd 100644
--- a/lib/tasks/gitlab/assets.rake
+++ b/lib/tasks/gitlab/assets.rake
@@ -3,16 +3,16 @@ namespace :gitlab do
desc 'GitLab | Assets | Compile all frontend assets'
task compile: [
'yarn:check',
- 'assets:precompile',
+ 'rake:assets:precompile',
'webpack:compile',
- 'gitlab:assets:fix_urls'
+ 'fix_urls'
]
desc 'GitLab | Assets | Clean up old compiled frontend assets'
- task clean: ['assets:clean']
+ task clean: ['rake:assets:clean']
desc 'GitLab | Assets | Remove all compiled frontend assets'
- task purge: ['assets:clobber']
+ task purge: ['rake:assets:clobber']
desc 'GitLab | Assets | Uninstall frontend dependencies'
task purge_modules: ['yarn:clobber']
diff --git a/lib/tasks/gitlab/gitaly.rake b/lib/tasks/gitlab/gitaly.rake
new file mode 100644
index 00000000000..c288e17ac8d
--- /dev/null
+++ b/lib/tasks/gitlab/gitaly.rake
@@ -0,0 +1,23 @@
+namespace :gitlab do
+ namespace :gitaly do
+ desc "GitLab | Install or upgrade gitaly"
+ task :install, [:dir] => :environment do |t, args|
+ warn_user_is_not_gitlab
+ unless args.dir.present?
+ abort %(Please specify the directory where you want to install gitaly:\n rake "gitlab:gitaly:install[/home/git/gitaly]")
+ end
+
+ tag = "v#{Gitlab::GitalyClient.expected_server_version}"
+ repo = 'https://gitlab.com/gitlab-org/gitaly.git'
+
+ checkout_or_clone_tag(tag: tag, repo: repo, target_dir: args.dir)
+
+ _, status = Gitlab::Popen.popen(%w[which gmake])
+ command = status.zero? ? 'gmake' : 'make'
+
+ Dir.chdir(args.dir) do
+ run_command!([command])
+ end
+ end
+ end
+end
diff --git a/lib/tasks/gitlab/task_helpers.rb b/lib/tasks/gitlab/task_helpers.rb
index bb755ae689b..cdba2262bc2 100644
--- a/lib/tasks/gitlab/task_helpers.rb
+++ b/lib/tasks/gitlab/task_helpers.rb
@@ -81,7 +81,7 @@ module Gitlab
def run_command!(command)
output, status = Gitlab::Popen.popen(command)
- raise Gitlab::TaskFailedError unless status.zero?
+ raise Gitlab::TaskFailedError.new(output) unless status.zero?
output
end
diff --git a/package.json b/package.json
index b3d038bd3d1..91d8752bebb 100644
--- a/package.json
+++ b/package.json
@@ -35,7 +35,7 @@
"stats-webpack-plugin": "^0.4.3",
"timeago.js": "^2.0.5",
"underscore": "^1.8.3",
- "vue": "^2.1.10",
+ "vue": "^2.2.4",
"vue-resource": "^0.9.3",
"webpack": "^2.2.1",
"webpack-bundle-analyzer": "^2.3.0"
diff --git a/spec/controllers/import/bitbucket_controller_spec.rb b/spec/controllers/import/bitbucket_controller_spec.rb
index fa4cc0ebbe0..51f23e4eeb9 100644
--- a/spec/controllers/import/bitbucket_controller_spec.rb
+++ b/spec/controllers/import/bitbucket_controller_spec.rb
@@ -112,6 +112,17 @@ describe Import::BitbucketController do
post :create, format: :js
end
end
+
+ context 'when the Bitbucket user is unauthorized' do
+ render_views
+
+ it 'returns unauthorized' do
+ allow(controller).to receive(:current_user).and_return(user)
+ allow(user).to receive(:can?).and_return(false)
+
+ post :create, format: :js
+ end
+ end
end
context "when the repository owner is not the Bitbucket user" do
diff --git a/spec/controllers/projects/issues_controller_spec.rb b/spec/controllers/projects/issues_controller_spec.rb
index 57a921e3676..c467ab9fb8a 100644
--- a/spec/controllers/projects/issues_controller_spec.rb
+++ b/spec/controllers/projects/issues_controller_spec.rb
@@ -241,10 +241,27 @@ describe Projects::IssuesController do
expect(spam_logs.first.recaptcha_verified).to be_falsey
end
- it 'renders verify template' do
- update_spam_issue
+ context 'as HTML' do
+ it 'renders verify template' do
+ update_spam_issue
+
+ expect(response).to render_template(:verify)
+ end
+ end
+
+ context 'as JSON' do
+ before do
+ update_issue({ title: 'Spam Title', description: 'Spam lives here' }, format: :json)
+ end
+
+ it 'renders json errors' do
+ expect(json_response)
+ .to eql("errors" => ["Your issue has been recognized as spam. Please, change the content or solve the reCAPTCHA to proceed."])
+ end
- expect(response).to render_template(:verify)
+ it 'returns 422 status' do
+ expect(response).to have_http_status(422)
+ end
end
end
diff --git a/spec/factories/merge_requests.rb b/spec/factories/merge_requests.rb
index 21487541507..ae0bbbd6aeb 100644
--- a/spec/factories/merge_requests.rb
+++ b/spec/factories/merge_requests.rb
@@ -4,7 +4,6 @@ FactoryGirl.define do
author
association :source_project, :repository, factory: :project
target_project { source_project }
- project { target_project }
# $ git log --pretty=oneline feature..master
# 5937ac0a7beb003549fc5fd26fc247adbce4a52e Add submodule from gitlab.com
diff --git a/spec/features/admin/admin_settings_spec.rb b/spec/features/admin/admin_settings_spec.rb
index 03daab12c8f..5099441dce2 100644
--- a/spec/features/admin/admin_settings_spec.rb
+++ b/spec/features/admin/admin_settings_spec.rb
@@ -34,6 +34,7 @@ feature 'Admin updates settings', feature: true do
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')
check_all_events
click_on 'Save'
diff --git a/spec/features/dashboard/shortcuts_spec.rb b/spec/features/dashboard/shortcuts_spec.rb
index 62a2c54c94c..3642c0bfb5b 100644
--- a/spec/features/dashboard/shortcuts_spec.rb
+++ b/spec/features/dashboard/shortcuts_spec.rb
@@ -21,6 +21,11 @@ feature 'Dashboard shortcuts', feature: true, js: true do
find('body').native.send_key('m')
check_page_title('Merge Requests')
+
+ find('body').native.send_key('g')
+ find('body').native.send_key('t')
+
+ check_page_title('Todos')
end
def check_page_title(title)
diff --git a/spec/features/merge_requests/create_new_mr_spec.rb b/spec/features/merge_requests/create_new_mr_spec.rb
index 0832a3656a8..8cc0996acab 100644
--- a/spec/features/merge_requests/create_new_mr_spec.rb
+++ b/spec/features/merge_requests/create_new_mr_spec.rb
@@ -46,6 +46,12 @@ feature 'Create New Merge Request', feature: true, js: true do
end
end
+ it 'populates source branch button' do
+ visit new_namespace_project_merge_request_path(project.namespace, project, change_branches: true, merge_request: { target_branch: 'master', source_branch: 'fix' })
+
+ expect(find('.js-source-branch')).to have_content('fix')
+ end
+
it 'allows to change the diff view' do
visit new_namespace_project_merge_request_path(project.namespace, project, merge_request: { target_branch: 'master', source_branch: 'fix' })
diff --git a/spec/features/merge_requests/merge_immediately_with_pipeline_spec.rb b/spec/features/merge_requests/merge_immediately_with_pipeline_spec.rb
index 0ceaf7bc830..79105b1ee46 100644
--- a/spec/features/merge_requests/merge_immediately_with_pipeline_spec.rb
+++ b/spec/features/merge_requests/merge_immediately_with_pipeline_spec.rb
@@ -35,6 +35,8 @@ feature 'Merge immediately', :feature, :js do
click_link 'Merge Immediately'
expect(find('.js-merge-when-pipeline-succeeds-button')).to have_content('Merge in progress')
+
+ wait_for_ajax
end
end
end
diff --git a/spec/features/participants_autocomplete_spec.rb b/spec/features/participants_autocomplete_spec.rb
index c2545b0c259..decad589c23 100644
--- a/spec/features/participants_autocomplete_spec.rb
+++ b/spec/features/participants_autocomplete_spec.rb
@@ -1,101 +1,62 @@
require 'spec_helper'
-feature 'Member autocomplete', feature: true do
- include WaitForAjax
-
+feature 'Member autocomplete', :js do
let(:project) { create(:project, :public) }
let(:user) { create(:user) }
- let(:participant) { create(:user) }
let(:author) { create(:user) }
+ let(:note) { create(:note, noteable: noteable, project: noteable.project) }
before do
- allow_any_instance_of(Commit).to receive(:author).and_return(author)
- login_as user
+ note # actually create the note
+ login_as(user)
end
- shared_examples "open suggestions" do
- it 'displays suggestions' do
- expect(page).to have_selector('.atwho-view', visible: true)
- end
-
- it 'suggests author' do
- page.within('.atwho-view', visible: true) do
- expect(page).to have_content(author.username)
+ shared_examples "open suggestions when typing @" do
+ before do
+ page.within('.new-note') do
+ find('#note_note').send_keys('@')
end
end
- it 'suggests participant' do
+ it 'suggests noteable author and note author' do
page.within('.atwho-view', visible: true) do
- expect(page).to have_content(participant.username)
+ expect(page).to have_content(author.username)
+ expect(page).to have_content(note.author.username)
end
end
end
- context 'adding a new note on a Issue', js: true do
+ context 'adding a new note on a Issue' do
+ let(:noteable) { create(:issue, author: author, project: project) }
before do
- issue = create(:issue, author: author, project: project)
- create(:note, note: 'Ultralight Beam', noteable: issue,
- project: project, author: participant)
- visit_issue(project, issue)
+ visit namespace_project_issue_path(project.namespace, project, noteable)
end
- context 'when typing @' do
- include_examples "open suggestions"
- before do
- open_member_suggestions
- end
- end
+ include_examples "open suggestions when typing @"
end
- context 'adding a new note on a Merge Request ', js: true do
+ context 'adding a new note on a Merge Request' do
+ let(:noteable) do
+ create(:merge_request, source_project: project,
+ target_project: project, author: author)
+ end
before do
- merge = create(:merge_request, source_project: project, target_project: project, author: author)
- create(:note, note: 'Ultralight Beam', noteable: merge,
- project: project, author: participant)
- visit_merge_request(project, merge)
+ visit namespace_project_merge_request_path(project.namespace, project, noteable)
end
- context 'when typing @' do
- include_examples "open suggestions"
- before do
- open_member_suggestions
- end
- end
+ include_examples "open suggestions when typing @"
end
- context 'adding a new note on a Commit ', js: true do
- let(:commit) { project.commit }
+ context 'adding a new note on a Commit' do
+ let(:noteable) { project.commit }
+ let(:note) { create(:note_on_commit, project: project, commit_id: project.commit.id) }
before do
- allow(commit).to receive(:author).and_return(author)
- create(:note_on_commit, author: participant, project: project, commit_id: project.repository.commit.id, note: 'No More Parties in LA')
- visit_commit(project, commit)
- end
-
- context 'when typing @' do
- include_examples "open suggestions"
- before do
- open_member_suggestions
- end
- end
- end
+ allow_any_instance_of(Commit).to receive(:author).and_return(author)
- def open_member_suggestions
- page.within('.new-note') do
- find('#note_note').send_keys('@')
+ visit namespace_project_commit_path(project.namespace, project, noteable)
end
- wait_for_ajax
- end
-
- def visit_issue(project, issue)
- visit namespace_project_issue_path(project.namespace, project, issue)
- end
-
- def visit_merge_request(project, merge)
- visit namespace_project_merge_request_path(project.namespace, project, merge)
- end
- def visit_commit(project, commit)
- visit namespace_project_commit_path(project.namespace, project, commit)
+ include_examples "open suggestions when typing @"
end
end
diff --git a/spec/features/projects/blobs/user_create_spec.rb b/spec/features/projects/blobs/user_create_spec.rb
index 03d08c12612..5686868a0c4 100644
--- a/spec/features/projects/blobs/user_create_spec.rb
+++ b/spec/features/projects/blobs/user_create_spec.rb
@@ -2,6 +2,7 @@ require 'spec_helper'
feature 'New blob creation', feature: true, js: true do
include WaitForAjax
+ include TargetBranchHelpers
given(:user) { create(:user) }
given(:role) { :developer }
@@ -20,19 +21,6 @@ feature 'New blob creation', feature: true, js: true do
execute_script("ace.edit('editor').setValue('#{content}')")
end
- def select_branch_index(index)
- first('button.js-target-branch').click
- wait_for_ajax
- all('a[data-group="Branches"]')[index].click
- end
-
- def create_new_branch(name)
- first('button.js-target-branch').click
- click_link 'Create new branch'
- fill_in 'new_branch_name', with: name
- click_button 'Create'
- end
-
def commit_file
click_button 'Commit Changes'
end
@@ -53,12 +41,12 @@ feature 'New blob creation', feature: true, js: true do
context 'with different target branch' do
background do
edit_file
- select_branch_index(0)
+ select_branch('feature')
commit_file
end
scenario 'creates the blob in the different branch' do
- expect(page).to have_content 'test'
+ expect(page).to have_content 'feature'
expect(page).to have_content 'successfully created'
end
end
diff --git a/spec/features/projects/deploy_keys_spec.rb b/spec/features/projects/deploy_keys_spec.rb
new file mode 100644
index 00000000000..0b997f130ea
--- /dev/null
+++ b/spec/features/projects/deploy_keys_spec.rb
@@ -0,0 +1,26 @@
+require 'spec_helper'
+
+describe 'Project deploy keys', feature: true do
+ let(:user) { create(:user) }
+ let(:project) { create(:project_empty_repo) }
+
+ before do
+ project.team << [user, :master]
+ login_as(user)
+ end
+
+ describe 'removing key' do
+ before do
+ create(:deploy_keys_project, project: project)
+ end
+
+ it 'removes association between project and deploy key' do
+ visit namespace_project_settings_repository_path(project.namespace, project)
+
+ page.within '.deploy-keys' do
+ expect { click_on 'Remove' }
+ .to change { project.deploy_keys.count }.by(-1)
+ end
+ end
+ end
+end
diff --git a/spec/features/projects/group_links_spec.rb b/spec/features/projects/group_links_spec.rb
index 8b302a6aa23..4c28205da9b 100644
--- a/spec/features/projects/group_links_spec.rb
+++ b/spec/features/projects/group_links_spec.rb
@@ -8,7 +8,7 @@ feature 'Project group links', feature: true, js: true do
let!(:group) { create(:group) }
background do
- project.team << [master, :master]
+ project.add_master(master)
login_as(master)
end
@@ -29,4 +29,26 @@ feature 'Project group links', feature: true, js: true do
end
end
end
+
+ context 'nested group project' do
+ let!(:nested_group) { create(:group, parent: group) }
+ let!(:another_group) { create(:group) }
+ let!(:project) { create(:project, namespace: nested_group) }
+
+ background do
+ group.add_master(master)
+ another_group.add_master(master)
+ end
+
+ it 'does not show ancestors' do
+ visit namespace_project_settings_members_path(project.namespace, project)
+
+ click_link 'Search for a group'
+
+ page.within '.select2-drop' do
+ expect(page).to have_content(another_group.name)
+ expect(page).not_to have_content(group.name)
+ end
+ end
+ end
end
diff --git a/spec/features/projects/user_create_dir_spec.rb b/spec/features/projects/user_create_dir_spec.rb
new file mode 100644
index 00000000000..2065abfb248
--- /dev/null
+++ b/spec/features/projects/user_create_dir_spec.rb
@@ -0,0 +1,72 @@
+require 'spec_helper'
+
+feature 'New directory creation', feature: true, js: true do
+ include WaitForAjax
+ include TargetBranchHelpers
+
+ given(:user) { create(:user) }
+ given(:role) { :developer }
+ given(:project) { create(:project) }
+
+ background do
+ login_as(user)
+ project.team << [user, role]
+ visit namespace_project_tree_path(project.namespace, project, 'master')
+ open_new_directory_modal
+ fill_in 'dir_name', with: 'new_directory'
+ end
+
+ def open_new_directory_modal
+ first('.add-to-tree').click
+ click_link 'New directory'
+ end
+
+ def create_directory
+ click_button 'Create directory'
+ end
+
+ context 'with default target branch' do
+ background do
+ create_directory
+ end
+
+ scenario 'creates the directory in the default branch' do
+ expect(page).to have_content 'master'
+ expect(page).to have_content 'The directory has been successfully created'
+ expect(page).to have_content 'new_directory'
+ end
+ end
+
+ context 'with different target branch' do
+ background do
+ select_branch('feature')
+ create_directory
+ end
+
+ scenario 'creates the directory in the different branch' do
+ expect(page).to have_content 'feature'
+ expect(page).to have_content 'The directory has been successfully created'
+ end
+ end
+
+ context 'with a new target branch' do
+ given(:new_branch_name) { 'new-feature' }
+
+ background do
+ create_new_branch(new_branch_name)
+ create_directory
+ end
+
+ scenario 'creates the directory in the new branch' do
+ expect(page).to have_content new_branch_name
+ expect(page).to have_content 'The directory has been successfully created'
+ end
+
+ scenario 'redirects to the merge request' do
+ expect(page).to have_content 'New Merge Request'
+ expect(page).to have_content "From #{new_branch_name} into master"
+ expect(page).to have_content 'Add new directory'
+ expect(current_path).to eq(new_namespace_project_merge_request_path(project.namespace, project))
+ end
+ end
+end
diff --git a/spec/features/users/projects_spec.rb b/spec/features/users/projects_spec.rb
new file mode 100644
index 00000000000..1d75fe434b0
--- /dev/null
+++ b/spec/features/users/projects_spec.rb
@@ -0,0 +1,31 @@
+require 'spec_helper'
+
+describe 'Projects tab on a user profile', :feature, :js do
+ include WaitForAjax
+
+ let(:user) { create(:user) }
+ let!(:project) { create(:empty_project, namespace: user.namespace) }
+ let!(:project2) { create(:empty_project, namespace: user.namespace) }
+
+ before do
+ allow(Project).to receive(:default_per_page).and_return(1)
+
+ login_as(user)
+
+ visit user_path(user)
+
+ page.within('.user-profile-nav') do
+ click_link('Personal projects')
+ end
+
+ wait_for_ajax
+ end
+
+ it 'paginates results' do
+ expect(page).to have_content(project2.name)
+
+ click_link('Next')
+
+ expect(page).to have_content(project.name)
+ end
+end
diff --git a/spec/helpers/todos_helper_spec.rb b/spec/helpers/todos_helper_spec.rb
index 21e0e74e008..50060a0925d 100644
--- a/spec/helpers/todos_helper_spec.rb
+++ b/spec/helpers/todos_helper_spec.rb
@@ -1,40 +1,6 @@
require "spec_helper"
describe TodosHelper do
- include GitlabRoutingHelper
-
- describe '#todo_target_path' do
- let(:project) { create(:project) }
- let(:merge_request) { create(:merge_request, target_project: project, source_project: project) }
- let(:issue) { create(:issue, project: project) }
- let(:note) { create(:note_on_issue, noteable: issue, project: project) }
-
- let(:mr_todo) { build(:todo, project: project, target: merge_request) }
- let(:issue_todo) { build(:todo, project: project, target: issue) }
- let(:note_todo) { build(:todo, project: project, target: issue, note: note) }
- let(:build_failed_todo) { build(:todo, :build_failed, project: project, target: merge_request) }
-
- it 'returns correct path to the todo MR' do
- expect(todo_target_path(mr_todo)).
- to eq("/#{project.full_path}/merge_requests/#{merge_request.iid}")
- end
-
- it 'returns correct path to the todo issue' do
- expect(todo_target_path(issue_todo)).
- to eq("/#{project.full_path}/issues/#{issue.iid}")
- end
-
- it 'returns correct path to the todo note' do
- expect(todo_target_path(note_todo)).
- to eq("/#{project.full_path}/issues/#{issue.iid}#note_#{note.id}")
- end
-
- it 'returns correct path to build_todo MR when pipeline failed' do
- expect(todo_target_path(build_failed_todo)).
- to eq("/#{project.full_path}/merge_requests/#{merge_request.iid}/pipelines")
- end
- end
-
describe '#todo_projects_options' do
let(:projects) { create_list(:empty_project, 3) }
let(:user) { create(:user) }
diff --git a/spec/javascripts/boards/board_card_spec.js b/spec/javascripts/boards/board_card_spec.js
index be31f644e20..73d18458366 100644
--- a/spec/javascripts/boards/board_card_spec.js
+++ b/spec/javascripts/boards/board_card_spec.js
@@ -1,10 +1,11 @@
-/* global Vue */
/* global List */
/* global ListLabel */
/* global listObj */
/* global boardsMockInterceptor */
/* global BoardService */
+import Vue from 'vue';
+
require('~/boards/models/list');
require('~/boards/models/label');
require('~/boards/stores/boards_store');
diff --git a/spec/javascripts/boards/boards_store_spec.js b/spec/javascripts/boards/boards_store_spec.js
index 1d1069600fc..e21f4ca2bc0 100644
--- a/spec/javascripts/boards/boards_store_spec.js
+++ b/spec/javascripts/boards/boards_store_spec.js
@@ -1,12 +1,13 @@
/* eslint-disable comma-dangle, one-var, no-unused-vars */
-/* global Vue */
/* global BoardService */
/* global boardsMockInterceptor */
-/* global Cookies */
/* global listObj */
/* global listObjDuplicate */
/* global ListIssue */
+import Vue from 'vue';
+import Cookies from 'js-cookie';
+
require('~/lib/utils/url_utility');
require('~/boards/models/issue');
require('~/boards/models/label');
diff --git a/spec/javascripts/boards/issue_card_spec.js b/spec/javascripts/boards/issue_card_spec.js
index 4340a571017..1a5e9e9fd07 100644
--- a/spec/javascripts/boards/issue_card_spec.js
+++ b/spec/javascripts/boards/issue_card_spec.js
@@ -1,9 +1,10 @@
-/* global Vue */
/* global ListUser */
/* global ListLabel */
/* global listObj */
/* global ListIssue */
+import Vue from 'vue';
+
require('~/boards/models/issue');
require('~/boards/models/label');
require('~/boards/models/list');
diff --git a/spec/javascripts/boards/list_spec.js b/spec/javascripts/boards/list_spec.js
index d49d3af33d9..66fc01fa1e5 100644
--- a/spec/javascripts/boards/list_spec.js
+++ b/spec/javascripts/boards/list_spec.js
@@ -1,5 +1,4 @@
/* eslint-disable comma-dangle */
-/* global Vue */
/* global boardsMockInterceptor */
/* global BoardService */
/* global List */
@@ -7,6 +6,8 @@
/* global listObj */
/* global listObjDuplicate */
+import Vue from 'vue';
+
require('~/lib/utils/url_utility');
require('~/boards/models/issue');
require('~/boards/models/label');
diff --git a/spec/javascripts/boards/modal_store_spec.js b/spec/javascripts/boards/modal_store_spec.js
index 1815847f3fa..80db816aff8 100644
--- a/spec/javascripts/boards/modal_store_spec.js
+++ b/spec/javascripts/boards/modal_store_spec.js
@@ -1,4 +1,3 @@
-/* global Vue */
/* global ListIssue */
require('~/boards/models/issue');
diff --git a/spec/javascripts/filtered_search/filtered_search_manager_spec.js b/spec/javascripts/filtered_search/filtered_search_manager_spec.js
index 113161c21c6..848c7656a8d 100644
--- a/spec/javascripts/filtered_search/filtered_search_manager_spec.js
+++ b/spec/javascripts/filtered_search/filtered_search_manager_spec.js
@@ -58,7 +58,7 @@ const FilteredSearchSpecHelper = require('../helpers/filtered_search_spec_helper
});
describe('search', () => {
- const defaultParams = '?scope=all&utf8=✓&state=opened';
+ const defaultParams = '?scope=all&utf8=%E2%9C%93&state=opened';
it('should search with a single word', (done) => {
input.value = 'searchTerm';
diff --git a/spec/javascripts/issuable_time_tracker_spec.js b/spec/javascripts/issuable_time_tracker_spec.js
index cb068a4f879..0a830f25e29 100644
--- a/spec/javascripts/issuable_time_tracker_spec.js
+++ b/spec/javascripts/issuable_time_tracker_spec.js
@@ -1,7 +1,7 @@
-/* eslint-disable */
+/* eslint-disable no-unused-vars, space-before-function-paren, func-call-spacing, no-spaced-func, semi, max-len, quotes, space-infix-ops, padded-blocks */
+
+import Vue from 'vue';
-require('jquery');
-require('vue');
require('~/issuable/time_tracking/components/time_tracker');
function initTimeTrackingComponent(opts) {
diff --git a/spec/javascripts/lib/utils/common_utils_spec.js b/spec/javascripts/lib/utils/common_utils_spec.js
index f4d3e77e515..d2e24eb7eb2 100644
--- a/spec/javascripts/lib/utils/common_utils_spec.js
+++ b/spec/javascripts/lib/utils/common_utils_spec.js
@@ -163,5 +163,72 @@ require('~/lib/utils/common_utils');
expect(gl.utils.isMetaClick(e)).toBe(true);
});
});
+
+ describe('gl.utils.backOff', () => {
+ it('solves the promise from the callback', (done) => {
+ const expectedResponseValue = 'Success!';
+ gl.utils.backOff((next, stop) => (
+ new Promise((resolve) => {
+ resolve(expectedResponseValue);
+ }).then((resp) => {
+ stop(resp);
+ })
+ )).then((respBackoff) => {
+ expect(respBackoff).toBe(expectedResponseValue);
+ done();
+ });
+ });
+
+ it('catches the rejected promise from the callback ', (done) => {
+ const errorMessage = 'Mistakes were made!';
+ gl.utils.backOff((next, stop) => {
+ new Promise((resolve, reject) => {
+ reject(new Error(errorMessage));
+ }).then((resp) => {
+ stop(resp);
+ }).catch(err => stop(err));
+ }).catch((errBackoffResp) => {
+ expect(errBackoffResp instanceof Error).toBe(true);
+ expect(errBackoffResp.message).toBe(errorMessage);
+ done();
+ });
+ });
+
+ it('solves the promise correctly after retrying a third time', (done) => {
+ let numberOfCalls = 1;
+ const expectedResponseValue = 'Success!';
+ gl.utils.backOff((next, stop) => (
+ new Promise((resolve) => {
+ resolve(expectedResponseValue);
+ }).then((resp) => {
+ if (numberOfCalls < 3) {
+ numberOfCalls += 1;
+ next();
+ } else {
+ stop(resp);
+ }
+ })
+ )).then((respBackoff) => {
+ expect(respBackoff).toBe(expectedResponseValue);
+ expect(numberOfCalls).toBe(3);
+ done();
+ });
+ }, 10000);
+
+ it('rejects the backOff promise after timing out', (done) => {
+ const expectedResponseValue = 'Success!';
+ gl.utils.backOff(next => (
+ new Promise((resolve) => {
+ resolve(expectedResponseValue);
+ }).then(() => {
+ setTimeout(next(), 5000); // it will time out
+ })
+ ), 3000).catch((errBackoffResp) => {
+ expect(errBackoffResp instanceof Error).toBe(true);
+ expect(errBackoffResp.message).toBe('BACKOFF_TIMEOUT');
+ done();
+ });
+ }, 10000);
+ });
});
})();
diff --git a/spec/javascripts/lib/utils/poll_spec.js b/spec/javascripts/lib/utils/poll_spec.js
new file mode 100644
index 00000000000..05bc6bfd74b
--- /dev/null
+++ b/spec/javascripts/lib/utils/poll_spec.js
@@ -0,0 +1,127 @@
+import Vue from 'vue';
+import VueResource from 'vue-resource';
+import Poll from '~/lib/utils/poll';
+
+Vue.use(VueResource);
+
+class ServiceMock {
+ constructor(endpoint) {
+ this.service = Vue.resource(endpoint);
+ }
+
+ fetch() {
+ return this.service.get();
+ }
+}
+
+describe('Poll', () => {
+ let callbacks;
+
+ beforeEach(() => {
+ callbacks = {
+ success: () => {},
+ error: () => {},
+ };
+
+ spyOn(callbacks, 'success');
+ spyOn(callbacks, 'error');
+ });
+
+ it('calls the success callback when no header for interval is provided', (done) => {
+ const successInterceptor = (request, next) => {
+ next(request.respondWith(JSON.stringify([]), { status: 200 }));
+ };
+
+ Vue.http.interceptors.push(successInterceptor);
+
+ new Poll({
+ resource: new ServiceMock('endpoint'),
+ method: 'fetch',
+ successCallback: callbacks.success,
+ errorCallback: callbacks.error,
+ }).makeRequest();
+
+ setTimeout(() => {
+ expect(callbacks.success).toHaveBeenCalled();
+ expect(callbacks.error).not.toHaveBeenCalled();
+ done();
+ }, 0);
+
+ Vue.http.interceptors = _.without(Vue.http.interceptors, successInterceptor);
+ });
+
+ it('calls the error callback whe the http request returns an error', (done) => {
+ const errorInterceptor = (request, next) => {
+ next(request.respondWith(JSON.stringify([]), { status: 500 }));
+ };
+
+ Vue.http.interceptors.push(errorInterceptor);
+
+ new Poll({
+ resource: new ServiceMock('endpoint'),
+ method: 'fetch',
+ successCallback: callbacks.success,
+ errorCallback: callbacks.error,
+ }).makeRequest();
+
+ setTimeout(() => {
+ expect(callbacks.success).not.toHaveBeenCalled();
+ expect(callbacks.error).toHaveBeenCalled();
+ done();
+ }, 0);
+
+ Vue.http.interceptors = _.without(Vue.http.interceptors, errorInterceptor);
+ });
+
+ it('should call the success callback when the interval header is -1', (done) => {
+ const intervalInterceptor = (request, next) => {
+ next(request.respondWith(JSON.stringify([]), { status: 200, headers: { 'poll-interval': -1 } }));
+ };
+
+ Vue.http.interceptors.push(intervalInterceptor);
+
+ new Poll({
+ resource: new ServiceMock('endpoint'),
+ method: 'fetch',
+ successCallback: callbacks.success,
+ errorCallback: callbacks.error,
+ }).makeRequest();
+
+ setTimeout(() => {
+ expect(callbacks.success).toHaveBeenCalled();
+ expect(callbacks.error).not.toHaveBeenCalled();
+ done();
+ }, 0);
+
+ Vue.http.interceptors = _.without(Vue.http.interceptors, intervalInterceptor);
+ });
+
+ it('starts polling when http status is 200 and interval header is provided', (done) => {
+ const pollInterceptor = (request, next) => {
+ next(request.respondWith(JSON.stringify([]), { status: 200, headers: { 'poll-interval': 2 } }));
+ };
+
+ Vue.http.interceptors.push(pollInterceptor);
+
+ const service = new ServiceMock('endpoint');
+ spyOn(service, 'fetch').and.callThrough();
+
+ new Poll({
+ resource: service,
+ method: 'fetch',
+ data: { page: 1 },
+ successCallback: callbacks.success,
+ errorCallback: callbacks.error,
+ }).makeRequest();
+
+ setTimeout(() => {
+ expect(service.fetch.calls.count()).toEqual(2);
+ expect(service.fetch).toHaveBeenCalledWith({ page: 1 });
+ expect(callbacks.success).toHaveBeenCalled();
+ expect(callbacks.error).not.toHaveBeenCalled();
+ done();
+ }, 5);
+
+ Vue.http.interceptors = _.without(Vue.http.interceptors, pollInterceptor);
+ });
+});
diff --git a/spec/javascripts/test_bundle.js b/spec/javascripts/test_bundle.js
index 5cdb6473eda..15465588223 100644
--- a/spec/javascripts/test_bundle.js
+++ b/spec/javascripts/test_bundle.js
@@ -8,9 +8,6 @@ jasmine.getJSONFixtures().fixturesPath = 'base/spec/javascripts/fixtures';
require('~/commons/index.js');
window.$ = window.jQuery = require('jquery');
window._ = require('underscore');
-window.Cookies = require('js-cookie');
-window.Vue = require('vue');
-window.Vue.use(require('vue-resource'));
// stub expected globals
window.gl = window.gl || {};
diff --git a/spec/javascripts/user_callout_spec.js b/spec/javascripts/user_callout_spec.js
index 205e72af600..2398149d3ad 100644
--- a/spec/javascripts/user_callout_spec.js
+++ b/spec/javascripts/user_callout_spec.js
@@ -1,7 +1,7 @@
-const UserCallout = require('~/user_callout');
+import Cookies from 'js-cookie';
+import UserCallout from '~/user_callout';
const USER_CALLOUT_COOKIE = 'user_callout_dismissed';
-const Cookie = window.Cookies;
describe('UserCallout', function () {
const fixtureName = 'static/user_callout.html.raw';
@@ -9,7 +9,7 @@ describe('UserCallout', function () {
beforeEach(() => {
loadFixtures(fixtureName);
- Cookie.remove(USER_CALLOUT_COOKIE);
+ Cookies.remove(USER_CALLOUT_COOKIE);
this.userCallout = new UserCallout();
this.closeButton = $('.close-user-callout');
@@ -18,25 +18,25 @@ describe('UserCallout', function () {
});
it('does not show when cookie is set not defined', () => {
- expect(Cookie.get(USER_CALLOUT_COOKIE)).toBeUndefined();
+ expect(Cookies.get(USER_CALLOUT_COOKIE)).toBeUndefined();
expect(this.userCalloutContainer.is(':visible')).toBe(true);
});
it('shows when cookie is set to false', () => {
- Cookie.set(USER_CALLOUT_COOKIE, 'false');
+ Cookies.set(USER_CALLOUT_COOKIE, 'false');
- expect(Cookie.get(USER_CALLOUT_COOKIE)).toBeDefined();
+ expect(Cookies.get(USER_CALLOUT_COOKIE)).toBeDefined();
expect(this.userCalloutContainer.is(':visible')).toBe(true);
});
it('hides when user clicks on the dismiss-icon', () => {
this.closeButton.click();
- expect(Cookie.get(USER_CALLOUT_COOKIE)).toBe('true');
+ expect(Cookies.get(USER_CALLOUT_COOKIE)).toBe('true');
});
it('hides when user clicks on the "check it out" button', () => {
this.userCalloutBtn.click();
- expect(Cookie.get(USER_CALLOUT_COOKIE)).toBe('true');
+ expect(Cookies.get(USER_CALLOUT_COOKIE)).toBe('true');
});
});
@@ -46,7 +46,7 @@ describe('UserCallout when cookie is present', function () {
beforeEach(() => {
loadFixtures(fixtureName);
- Cookie.set(USER_CALLOUT_COOKIE, 'true');
+ Cookies.set(USER_CALLOUT_COOKIE, 'true');
this.userCallout = new UserCallout();
this.userCalloutContainer = $('.user-callout');
});
diff --git a/spec/mailers/emails/profile_spec.rb b/spec/mailers/emails/profile_spec.rb
index e1877d5fde0..5ca936f28f0 100644
--- a/spec/mailers/emails/profile_spec.rb
+++ b/spec/mailers/emails/profile_spec.rb
@@ -5,6 +5,16 @@ describe Notify do
include EmailSpec::Matchers
include_context 'gitlab email notification'
+ shared_examples 'a new user email' do
+ it 'is sent to the new user with the correct subject and body' do
+ aggregate_failures do
+ is_expected.to deliver_to new_user_address
+ is_expected.to have_subject(/^Account was created for you$/i)
+ is_expected.to have_body_text(new_user_address)
+ end
+ end
+ end
+
describe 'profile notifications' do
describe 'for new users, the email' do
let(:example_site_path) { root_path }
diff --git a/spec/mailers/notify_spec.rb b/spec/mailers/notify_spec.rb
index 6ee91576676..4b72eb2eaa3 100644
--- a/spec/mailers/notify_spec.rb
+++ b/spec/mailers/notify_spec.rb
@@ -24,14 +24,14 @@ describe Notify do
let(:previous_assignee) { create(:user, name: 'Previous Assignee') }
shared_examples 'an assignee email' do
- it 'is sent as the author' do
- sender = subject.header[:from].addrs[0]
- expect(sender.display_name).to eq(current_user.name)
- expect(sender.address).to eq(gitlab_sender)
- end
+ it 'is sent to the assignee as the author' do
+ sender = subject.header[:from].addrs.first
- it 'is sent to the assignee' do
- is_expected.to deliver_to assignee.email
+ aggregate_failures do
+ expect(sender.display_name).to eq(current_user.name)
+ expect(sender.address).to eq(gitlab_sender)
+ expect(subject).to deliver_to(assignee.email)
+ end
end
end
@@ -49,12 +49,11 @@ describe Notify do
it_behaves_like 'it should show Gmail Actions View Issue link'
it_behaves_like 'an unsubscribeable thread'
- it 'has the correct subject' do
- is_expected.to have_referable_subject(issue)
- end
-
- it 'contains a link to the new issue' do
- is_expected.to have_body_text namespace_project_issue_path(project.namespace, project, issue)
+ it 'has the correct subject and body' do
+ aggregate_failures do
+ is_expected.to have_referable_subject(issue)
+ is_expected.to have_body_text(namespace_project_issue_path(project.namespace, project, issue))
+ end
end
context 'when enabled email_author_in_body' do
@@ -63,7 +62,7 @@ describe Notify do
end
it 'contains a link to note author' do
- is_expected.to have_html_escaped_body_text issue.author_name
+ is_expected.to have_html_escaped_body_text(issue.author_name)
is_expected.to have_body_text 'wrote:'
end
end
@@ -95,20 +94,13 @@ describe Notify do
expect(sender.address).to eq(gitlab_sender)
end
- it 'has the correct subject' do
- is_expected.to have_referable_subject(issue, reply: true)
- end
-
- it 'contains the name of the previous assignee' do
- is_expected.to have_html_escaped_body_text previous_assignee.name
- end
-
- it 'contains the name of the new assignee' do
- is_expected.to have_html_escaped_body_text assignee.name
- end
-
- it 'contains a link to the issue' do
- is_expected.to have_body_text namespace_project_issue_path(project.namespace, project, issue)
+ it 'has the correct subject and body' do
+ aggregate_failures do
+ is_expected.to have_referable_subject(issue, reply: true)
+ is_expected.to have_html_escaped_body_text(previous_assignee.name)
+ is_expected.to have_html_escaped_body_text(assignee.name)
+ is_expected.to have_body_text(namespace_project_issue_path(project.namespace, project, issue))
+ end
end
end
@@ -129,16 +121,12 @@ describe Notify do
expect(sender.address).to eq(gitlab_sender)
end
- it 'has the correct subject' do
- is_expected.to have_referable_subject(issue, reply: true)
- end
-
- it 'contains the names of the added labels' do
- is_expected.to have_body_text 'foo, bar, and baz'
- end
-
- it 'contains a link to the issue' do
- is_expected.to have_body_text namespace_project_issue_path(project.namespace, project, issue)
+ it 'has the correct subject and body' do
+ aggregate_failures do
+ is_expected.to have_referable_subject(issue, reply: true)
+ is_expected.to have_body_text('foo, bar, and baz')
+ is_expected.to have_body_text(namespace_project_issue_path(project.namespace, project, issue))
+ end
end
end
@@ -158,20 +146,13 @@ describe Notify do
expect(sender.address).to eq(gitlab_sender)
end
- it 'has the correct subject' do
- is_expected.to have_referable_subject(issue, reply: true)
- end
-
- it 'contains the new status' do
- is_expected.to have_body_text status
- end
-
- it 'contains the user name' do
- is_expected.to have_html_escaped_body_text current_user.name
- end
-
- it 'contains a link to the issue' do
- is_expected.to have_body_text(namespace_project_issue_path project.namespace, project, issue)
+ it 'has the correct subject and body' do
+ aggregate_failures do
+ is_expected.to have_referable_subject(issue, reply: true)
+ is_expected.to have_body_text(status)
+ is_expected.to have_html_escaped_body_text(current_user.name)
+ is_expected.to have_body_text(namespace_project_issue_path project.namespace, project, issue)
+ end
end
end
@@ -189,18 +170,15 @@ describe Notify do
is_expected.to have_body_text 'Issue was moved to another project'
end
- it 'has the correct subject' do
- is_expected.to have_referable_subject(issue, reply: true)
- end
-
- it 'contains link to new issue' do
+ it 'has the correct subject and body' do
new_issue_url = namespace_project_issue_path(new_issue.project.namespace,
new_issue.project, new_issue)
- is_expected.to have_body_text new_issue_url
- end
- it 'contains a link to the original issue' do
- is_expected.to have_body_text namespace_project_issue_path(project.namespace, project, issue)
+ aggregate_failures do
+ is_expected.to have_referable_subject(issue, reply: true)
+ is_expected.to have_body_text(new_issue_url)
+ is_expected.to have_body_text(namespace_project_issue_path(project.namespace, project, issue))
+ end
end
end
end
@@ -220,20 +198,13 @@ describe Notify do
it_behaves_like 'it should show Gmail Actions View Merge request link'
it_behaves_like 'an unsubscribeable thread'
- it 'has the correct subject' do
- is_expected.to have_referable_subject(merge_request)
- end
-
- it 'contains a link to the new merge request' do
- is_expected.to have_body_text namespace_project_merge_request_path(project.namespace, project, merge_request)
- end
-
- it 'contains the source branch for the merge request' do
- is_expected.to have_body_text merge_request.source_branch
- end
-
- it 'contains the target branch for the merge request' do
- is_expected.to have_body_text merge_request.target_branch
+ it 'has the correct subject and body' do
+ aggregate_failures do
+ is_expected.to have_referable_subject(merge_request)
+ is_expected.to have_body_text(namespace_project_merge_request_path(project.namespace, project, merge_request))
+ is_expected.to have_body_text(merge_request.source_branch)
+ is_expected.to have_body_text(merge_request.target_branch)
+ end
end
context 'when enabled email_author_in_body' do
@@ -275,20 +246,13 @@ describe Notify do
expect(sender.address).to eq(gitlab_sender)
end
- it 'has the correct subject' do
- is_expected.to have_referable_subject(merge_request, reply: true)
- end
-
- it 'contains the name of the previous assignee' do
- is_expected.to have_html_escaped_body_text previous_assignee.name
- end
-
- it 'contains the name of the new assignee' do
- is_expected.to have_html_escaped_body_text assignee.name
- end
-
- it 'contains a link to the merge request' do
- is_expected.to have_body_text namespace_project_merge_request_path(project.namespace, project, merge_request)
+ it 'has the correct subject and body' do
+ aggregate_failures do
+ is_expected.to have_referable_subject(merge_request, reply: true)
+ is_expected.to have_html_escaped_body_text(previous_assignee.name)
+ is_expected.to have_body_text(namespace_project_merge_request_path(project.namespace, project, merge_request))
+ is_expected.to have_html_escaped_body_text(assignee.name)
+ end
end
end
@@ -309,16 +273,10 @@ describe Notify do
expect(sender.address).to eq(gitlab_sender)
end
- it 'has the correct subject' do
+ it 'has the correct subject and body' do
is_expected.to have_referable_subject(merge_request, reply: true)
- end
-
- it 'contains the names of the added labels' do
- is_expected.to have_body_text 'foo, bar, and baz'
- end
-
- it 'contains a link to the merge request' do
- is_expected.to have_body_text namespace_project_merge_request_path(project.namespace, project, merge_request)
+ is_expected.to have_body_text('foo, bar, and baz')
+ is_expected.to have_body_text(namespace_project_merge_request_path(project.namespace, project, merge_request))
end
end
@@ -338,20 +296,13 @@ describe Notify do
expect(sender.address).to eq(gitlab_sender)
end
- it 'has the correct subject' do
- is_expected.to have_referable_subject(merge_request, reply: true)
- end
-
- it 'contains the new status' do
- is_expected.to have_body_text status
- end
-
- it 'contains the user name' do
- is_expected.to have_html_escaped_body_text current_user.name
- end
-
- it 'contains a link to the merge request' do
- is_expected.to have_body_text namespace_project_merge_request_path(project.namespace, project, merge_request)
+ it 'has the correct subject and body' do
+ aggregate_failures do
+ is_expected.to have_referable_subject(merge_request, reply: true)
+ is_expected.to have_body_text(status)
+ is_expected.to have_html_escaped_body_text(current_user.name)
+ is_expected.to have_body_text(namespace_project_merge_request_path(project.namespace, project, merge_request))
+ end
end
end
@@ -371,16 +322,12 @@ describe Notify do
expect(sender.address).to eq(gitlab_sender)
end
- it 'has the correct subject' do
- is_expected.to have_referable_subject(merge_request, reply: true)
- end
-
- it 'contains the new status' do
- is_expected.to have_body_text 'merged'
- end
-
- it 'contains a link to the merge request' do
- is_expected.to have_body_text namespace_project_merge_request_path(project.namespace, project, merge_request)
+ it 'has the correct subject and body' do
+ aggregate_failures do
+ is_expected.to have_referable_subject(merge_request, reply: true)
+ is_expected.to have_body_text('merged')
+ is_expected.to have_body_text(namespace_project_merge_request_path(project.namespace, project, merge_request))
+ end
end
end
end
@@ -395,16 +342,10 @@ describe Notify do
it_behaves_like 'it should not have Gmail Actions links'
it_behaves_like "a user cannot unsubscribe through footer link"
- it 'has the correct subject' do
- is_expected.to have_subject "#{project.name} | Project was moved"
- end
-
- it 'contains name of project' do
+ it 'has the correct subject and body' do
+ is_expected.to have_subject("#{project.name} | Project was moved")
is_expected.to have_html_escaped_body_text project.name_with_namespace
- end
-
- it 'contains new user role' do
- is_expected.to have_body_text project.ssh_url_to_repo
+ is_expected.to have_body_text(project.ssh_url_to_repo)
end
end
@@ -597,14 +538,14 @@ describe Notify do
shared_examples 'a note email' do
it_behaves_like 'it should have Gmail Actions links'
- it 'is sent as the author' do
+ it 'is sent to the given recipient as the author' do
sender = subject.header[:from].addrs[0]
- expect(sender.display_name).to eq(note_author.name)
- expect(sender.address).to eq(gitlab_sender)
- end
- it 'is sent to the given recipient' do
- is_expected.to deliver_to recipient.notification_email
+ aggregate_failures do
+ expect(sender.display_name).to eq(note_author.name)
+ expect(sender.address).to eq(gitlab_sender)
+ expect(subject).to deliver_to(recipient.notification_email)
+ end
end
it 'contains the message from the note' do
@@ -641,12 +582,11 @@ describe Notify do
it_behaves_like 'it should show Gmail Actions View Commit link'
it_behaves_like 'a user cannot unsubscribe through footer link'
- it 'has the correct subject' do
- is_expected.to have_subject "Re: #{project.name} | #{commit.title.strip} (#{commit.short_id})"
- end
-
- it 'contains a link to the commit' do
- is_expected.to have_body_text commit.short_id
+ it 'has the correct subject and body' do
+ aggregate_failures do
+ is_expected.to have_subject("Re: #{project.name} | #{commit.title.strip} (#{commit.short_id})")
+ is_expected.to have_body_text(commit.short_id)
+ end
end
end
@@ -664,12 +604,11 @@ describe Notify do
it_behaves_like 'it should show Gmail Actions View Merge request link'
it_behaves_like 'an unsubscribeable thread'
- it 'has the correct subject' do
- is_expected.to have_referable_subject(merge_request, reply: true)
- end
-
- it 'contains a link to the merge request note' do
- is_expected.to have_body_text note_on_merge_request_path
+ it 'has the correct subject and body' do
+ aggregate_failures do
+ is_expected.to have_referable_subject(merge_request, reply: true)
+ is_expected.to have_body_text note_on_merge_request_path
+ end
end
end
@@ -687,12 +626,11 @@ describe Notify do
it_behaves_like 'it should show Gmail Actions View Issue link'
it_behaves_like 'an unsubscribeable thread'
- it 'has the correct subject' do
- is_expected.to have_referable_subject(issue, reply: true)
- end
-
- it 'contains a link to the issue note' do
- is_expected.to have_body_text note_on_issue_path
+ it 'has the correct subject and body' do
+ aggregate_failures do
+ is_expected.to have_referable_subject(issue, reply: true)
+ is_expected.to have_body_text(note_on_issue_path)
+ end
end
end
end
@@ -717,14 +655,14 @@ describe Notify do
it_behaves_like 'it should have Gmail Actions links'
- it 'is sent as the author' do
+ it 'is sent to the given recipient as the author' do
sender = subject.header[:from].addrs[0]
- expect(sender.display_name).to eq(note_author.name)
- expect(sender.address).to eq(gitlab_sender)
- end
- it 'is sent to the given recipient' do
- is_expected.to deliver_to recipient.notification_email
+ aggregate_failures do
+ expect(sender.display_name).to eq(note_author.name)
+ expect(sender.address).to eq(gitlab_sender)
+ expect(subject).to deliver_to(recipient.notification_email)
+ end
end
it 'contains the message from the note' do
@@ -934,21 +872,20 @@ describe Notify do
is_expected.to deliver_to 'new-email@mail.com'
end
- it 'has the correct subject' do
- is_expected.to have_subject 'Confirmation instructions | A Nice Suffix'
- end
-
- it 'includes a link to the site' do
- is_expected.to have_body_text example_site_path
+ it 'has the correct subject and body' do
+ aggregate_failures do
+ is_expected.to have_subject('Confirmation instructions | A Nice Suffix')
+ is_expected.to have_body_text(example_site_path)
+ end
end
end
describe 'email on push for a created branch' do
let(:example_site_path) { root_path }
let(:user) { create(:user) }
- let(:tree_path) { namespace_project_tree_path(project.namespace, project, "master") }
+ let(:tree_path) { namespace_project_tree_path(project.namespace, project, "empty-branch") }
- subject { Notify.repository_push_email(project.id, author_id: user.id, ref: 'refs/heads/master', action: :create) }
+ subject { Notify.repository_push_email(project.id, author_id: user.id, ref: 'refs/heads/empty-branch', action: :create) }
it_behaves_like 'it should not have Gmail Actions links'
it_behaves_like 'a user cannot unsubscribe through footer link'
@@ -961,12 +898,11 @@ describe Notify do
expect(sender.address).to eq(gitlab_sender)
end
- it 'has the correct subject' do
- is_expected.to have_subject "[Git][#{project.full_path}] Pushed new branch master"
- end
-
- it 'contains a link to the branch' do
- is_expected.to have_body_text tree_path
+ it 'has the correct subject and body' do
+ aggregate_failures do
+ is_expected.to have_subject("[Git][#{project.full_path}] Pushed new branch empty-branch")
+ is_expected.to have_body_text(tree_path)
+ end
end
end
@@ -988,12 +924,11 @@ describe Notify do
expect(sender.address).to eq(gitlab_sender)
end
- it 'has the correct subject' do
- is_expected.to have_subject "[Git][#{project.full_path}] Pushed new tag v1.0"
- end
-
- it 'contains a link to the tag' do
- is_expected.to have_body_text tree_path
+ it 'has the correct subject and body' do
+ aggregate_failures do
+ is_expected.to have_subject("[Git][#{project.full_path}] Pushed new tag v1.0")
+ is_expected.to have_body_text(tree_path)
+ end
end
end
@@ -1064,24 +999,14 @@ describe Notify do
expect(sender.address).to eq(gitlab_sender)
end
- it 'has the correct subject' do
- is_expected.to have_subject "[Git][#{project.full_path}][master] #{commits.length} commits: Ruby files modified"
- end
-
- it 'includes commits list' do
- is_expected.to have_body_text 'Change some files'
- end
-
- it 'includes diffs with character-level highlighting' do
- is_expected.to have_body_text 'def</span> <span class="nf">archive_formats_regex'
- end
-
- it 'contains a link to the diff' do
- is_expected.to have_body_text diff_path
- end
-
- it 'does not contain the misleading footer' do
- is_expected.not_to have_body_text 'you are a member of'
+ it 'has the correct subject and body' do
+ aggregate_failures do
+ is_expected.to have_subject("[Git][#{project.full_path}][master] #{commits.length} commits: Ruby files modified")
+ is_expected.to have_body_text('Change some files')
+ is_expected.to have_body_text('def</span> <span class="nf">archive_formats_regex')
+ is_expected.to have_body_text(diff_path)
+ is_expected.not_to have_body_text('you are a member of')
+ end
end
context "when set to send from committer email if domain matches" do
@@ -1098,13 +1023,13 @@ describe Notify do
end
it "is sent from the committer email" do
- sender = subject.header[:from].addrs[0]
- expect(sender.address).to eq(user.email)
- end
+ from = subject.header[:from].addrs.first
+ reply = subject.header[:reply_to].addrs.first
- it "is set to reply to the committer email" do
- sender = subject.header[:reply_to].addrs[0]
- expect(sender.address).to eq(user.email)
+ aggregate_failures do
+ expect(from.address).to eq(user.email)
+ expect(reply.address).to eq(user.email)
+ end
end
end
@@ -1115,13 +1040,13 @@ describe Notify do
end
it "is sent from the default email" do
- sender = subject.header[:from].addrs[0]
- expect(sender.address).to eq(gitlab_sender)
- end
+ from = subject.header[:from].addrs.first
+ reply = subject.header[:reply_to].addrs.first
- it "is set to reply to the default email" do
- sender = subject.header[:reply_to].addrs[0]
- expect(sender.address).to eq(gitlab_sender_reply_to)
+ aggregate_failures do
+ expect(from.address).to eq(gitlab_sender)
+ expect(reply.address).to eq(gitlab_sender_reply_to)
+ end
end
end
@@ -1132,13 +1057,13 @@ describe Notify do
end
it "is sent from the default email" do
- sender = subject.header[:from].addrs[0]
- expect(sender.address).to eq(gitlab_sender)
- end
+ from = subject.header[:from].addrs.first
+ reply = subject.header[:reply_to].addrs.first
- it "is set to reply to the default email" do
- sender = subject.header[:reply_to].addrs[0]
- expect(sender.address).to eq(gitlab_sender_reply_to)
+ aggregate_failures do
+ expect(from.address).to eq(gitlab_sender)
+ expect(reply.address).to eq(gitlab_sender_reply_to)
+ end
end
end
end
@@ -1166,20 +1091,13 @@ describe Notify do
expect(sender.address).to eq(gitlab_sender)
end
- it 'has the correct subject' do
- is_expected.to have_subject "[Git][#{project.full_path}][master] #{commits.first.title}"
- end
-
- it 'includes commits list' do
- is_expected.to have_body_text 'Change some files'
- end
-
- it 'includes diffs with character-level highlighting' do
- is_expected.to have_body_text 'def</span> <span class="nf">archive_formats_regex'
- end
-
- it 'contains a link to the diff' do
- is_expected.to have_body_text diff_path
+ it 'has the correct subject and body' do
+ aggregate_failures do
+ is_expected.to have_subject("[Git][#{project.full_path}][master] #{commits.first.title}")
+ is_expected.to have_body_text('Change some files')
+ is_expected.to have_body_text('def</span> <span class="nf">archive_formats_regex')
+ is_expected.to have_body_text(diff_path)
+ end
end
end
diff --git a/spec/models/concerns/issuable_spec.rb b/spec/models/concerns/issuable_spec.rb
index 9574796a945..4522206fab1 100644
--- a/spec/models/concerns/issuable_spec.rb
+++ b/spec/models/concerns/issuable_spec.rb
@@ -44,6 +44,34 @@ describe Issue, "Issuable" do
it { expect(described_class).to respond_to(:assigned) }
end
+ describe 'author_name' do
+ it 'is delegated to author' do
+ expect(issue.author_name).to eq issue.author.name
+ end
+
+ it 'returns nil when author is nil' do
+ issue.author_id = nil
+ issue.save(validate: false)
+
+ expect(issue.author_name).to eq nil
+ end
+ end
+
+ describe 'assignee_name' do
+ it 'is delegated to assignee' do
+ issue.update!(assignee: create(:user))
+
+ expect(issue.assignee_name).to eq issue.assignee.name
+ end
+
+ it 'returns nil when assignee is nil' do
+ issue.assignee_id = nil
+ issue.save(validate: false)
+
+ expect(issue.assignee_name).to eq nil
+ end
+ end
+
describe "before_save" do
describe "#update_cache_counts" do
context "when previous assignee exists" do
diff --git a/spec/models/issue_spec.rb b/spec/models/issue_spec.rb
index 73977d031f9..b8584301baa 100644
--- a/spec/models/issue_spec.rb
+++ b/spec/models/issue_spec.rb
@@ -670,4 +670,41 @@ describe Issue, models: true do
expect(attrs_hash).to include('time_estimate')
end
end
+
+ describe '#check_for_spam' do
+ let(:project) { create :project, visibility_level: visibility_level }
+ let(:issue) { create :issue, project: project }
+
+ subject do
+ issue.assign_attributes(description: description)
+ issue.check_for_spam?
+ end
+
+ context 'when project is public and spammable attributes changed' do
+ let(:visibility_level) { Gitlab::VisibilityLevel::PUBLIC }
+ let(:description) { 'woo' }
+
+ it 'returns true' do
+ is_expected.to be_truthy
+ end
+ end
+
+ context 'when project is private' do
+ let(:visibility_level) { Gitlab::VisibilityLevel::PRIVATE }
+ let(:description) { issue.description }
+
+ it 'returns false' do
+ is_expected.to be_falsey
+ end
+ end
+
+ context 'when spammable attributes have not changed' do
+ let(:visibility_level) { Gitlab::VisibilityLevel::PUBLIC }
+ let(:description) { issue.description }
+
+ it 'returns false' do
+ is_expected.to be_falsey
+ end
+ end
+ end
end
diff --git a/spec/models/namespace_spec.rb b/spec/models/namespace_spec.rb
index 757f3921450..67d48557184 100644
--- a/spec/models/namespace_spec.rb
+++ b/spec/models/namespace_spec.rb
@@ -215,10 +215,12 @@ describe Namespace, models: true do
end
describe '#descendants' do
- let!(:group) { create(:group) }
+ let!(:group) { create(:group, path: 'git_lab') }
let!(:nested_group) { create(:group, parent: group) }
let!(:deep_nested_group) { create(:group, parent: nested_group) }
let!(:very_deep_nested_group) { create(:group, parent: deep_nested_group) }
+ let!(:another_group) { create(:group, path: 'gitllab') }
+ let!(:another_group_nested) { create(:group, path: 'foo', parent: another_group) }
it 'returns the correct descendants' do
expect(very_deep_nested_group.descendants.to_a).to eq([])
diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb
index 5e5f690acd4..59a2560ca06 100644
--- a/spec/models/project_spec.rb
+++ b/spec/models/project_spec.rb
@@ -1762,11 +1762,14 @@ describe Project, models: true do
end
describe 'inside_path' do
- let!(:project1) { create(:empty_project) }
+ let!(:project1) { create(:empty_project, namespace: create(:namespace, path: 'name_pace')) }
let!(:project2) { create(:empty_project) }
+ let!(:project3) { create(:empty_project, namespace: create(:namespace, path: 'namespace')) }
let!(:path) { project1.namespace.full_path }
- it { expect(Project.inside_path(path)).to eq([project1]) }
+ it 'returns correct project' do
+ expect(Project.inside_path(path)).to eq([project1])
+ end
end
describe '#route_map_for' do
diff --git a/spec/models/route_spec.rb b/spec/models/route_spec.rb
index bc8ae4ae5a8..171a51fcc5b 100644
--- a/spec/models/route_spec.rb
+++ b/spec/models/route_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe Route, models: true do
- let!(:group) { create(:group, path: 'gitlab', name: 'gitlab') }
+ let!(:group) { create(:group, path: 'git_lab', name: 'git_lab') }
let!(:route) { group.route }
describe 'relationships' do
@@ -14,10 +14,24 @@ describe Route, models: true do
it { is_expected.to validate_uniqueness_of(:path) }
end
+ describe '.inside_path' do
+ let!(:nested_group) { create(:group, path: 'test', name: 'test', parent: group) }
+ let!(:deep_nested_group) { create(:group, path: 'foo', name: 'foo', parent: nested_group) }
+ let!(:another_group) { create(:group, path: 'other') }
+ let!(:similar_group) { create(:group, path: 'gitllab') }
+ let!(:another_group_nested) { create(:group, path: 'another', name: 'another', parent: similar_group) }
+
+ it 'returns correct routes' do
+ expect(Route.inside_path('git_lab')).to match_array([nested_group.route, deep_nested_group.route])
+ end
+ end
+
describe '#rename_descendants' do
let!(:nested_group) { create(:group, path: 'test', name: 'test', parent: group) }
let!(:deep_nested_group) { create(:group, path: 'foo', name: 'foo', parent: nested_group) }
let!(:similar_group) { create(:group, path: 'gitlab-org', name: 'gitlab-org') }
+ let!(:another_group) { create(:group, path: 'gittlab', name: 'gitllab') }
+ let!(:another_group_nested) { create(:group, path: 'git_lab', name: 'git_lab', parent: another_group) }
context 'path update' do
context 'when route name is set' do
@@ -28,6 +42,8 @@ describe Route, models: true do
expect(described_class.exists?(path: 'bar/test')).to be_truthy
expect(described_class.exists?(path: 'bar/test/foo')).to be_truthy
expect(described_class.exists?(path: 'gitlab-org')).to be_truthy
+ expect(described_class.exists?(path: 'gittlab')).to be_truthy
+ expect(described_class.exists?(path: 'gittlab/git_lab')).to be_truthy
end
end
@@ -44,7 +60,7 @@ describe Route, models: true do
context 'name update' do
it "updates children routes with new path" do
- route.update_attributes(name: 'bar')
+ route.update_attributes(name: 'bar')
expect(described_class.exists?(name: 'bar')).to be_truthy
expect(described_class.exists?(name: 'bar / test')).to be_truthy
diff --git a/spec/models/snippet_spec.rb b/spec/models/snippet_spec.rb
index 219ab1989ea..8095d01b69e 100644
--- a/spec/models/snippet_spec.rb
+++ b/spec/models/snippet_spec.rb
@@ -198,4 +198,47 @@ describe Snippet, models: true do
expect(snippet.participants).to include(note1.author, note2.author)
end
end
+
+ describe '#check_for_spam' do
+ let(:snippet) { create :snippet, visibility_level: visibility_level }
+
+ subject do
+ snippet.assign_attributes(title: title)
+ snippet.check_for_spam?
+ end
+
+ context 'when public and spammable attributes changed' do
+ let(:visibility_level) { Snippet::PUBLIC }
+ let(:title) { 'woo' }
+
+ it 'returns true' do
+ is_expected.to be_truthy
+ end
+ end
+
+ context 'when private' do
+ let(:visibility_level) { Snippet::PRIVATE }
+ let(:title) { snippet.title }
+
+ it 'returns false' do
+ is_expected.to be_falsey
+ end
+
+ it 'returns true when switching to public' do
+ snippet.save!
+ snippet.visibility_level = Snippet::PUBLIC
+
+ expect(snippet.check_for_spam?).to be_truthy
+ end
+ end
+
+ context 'when spammable attributes have not changed' do
+ let(:visibility_level) { Snippet::PUBLIC }
+ let(:title) { snippet.title }
+
+ it 'returns false' do
+ is_expected.to be_falsey
+ end
+ end
+ end
end
diff --git a/spec/services/boards/issues/list_service_spec.rb b/spec/services/boards/issues/list_service_spec.rb
index 22115c6566d..d841bdaa292 100644
--- a/spec/services/boards/issues/list_service_spec.rb
+++ b/spec/services/boards/issues/list_service_spec.rb
@@ -30,6 +30,7 @@ describe Boards::Issues::ListService, services: true do
let!(:closed_issue2) { create(:labeled_issue, :closed, project: project, labels: [p3]) }
let!(:closed_issue3) { create(:issue, :closed, project: project) }
let!(:closed_issue4) { create(:labeled_issue, :closed, project: project, labels: [p1]) }
+ let!(:closed_issue5) { create(:labeled_issue, :closed, project: project, labels: [development]) }
before do
project.team << [user, :developer]
@@ -57,7 +58,7 @@ describe Boards::Issues::ListService, services: true do
issues = described_class.new(project, user, params).execute
- expect(issues).to eq [closed_issue4, closed_issue2, closed_issue3, closed_issue1]
+ expect(issues).to eq [closed_issue4, closed_issue2, closed_issue5, closed_issue3, closed_issue1]
end
it 'returns opened issues that have label list applied when listing issues from a label list' do
diff --git a/spec/services/issuable/bulk_update_service_spec.rb b/spec/services/issuable/bulk_update_service_spec.rb
index 0475f38fe5e..7a1ac027310 100644
--- a/spec/services/issuable/bulk_update_service_spec.rb
+++ b/spec/services/issuable/bulk_update_service_spec.rb
@@ -138,7 +138,7 @@ describe Issuable::BulkUpdateService, services: true do
let(:labels) { [bug, regression] }
it 'updates the labels of all issues passed to the labels passed' do
- expect(issues.map(&:reload).map(&:label_ids)).to all(eq(labels.map(&:id)))
+ expect(issues.map(&:reload).map(&:label_ids)).to all(match_array(labels.map(&:id)))
end
it 'does not update issues not passed in' do
diff --git a/spec/services/spam_service_spec.rb b/spec/services/spam_service_spec.rb
index 4ce3b95aa87..e09c05ccf32 100644
--- a/spec/services/spam_service_spec.rb
+++ b/spec/services/spam_service_spec.rb
@@ -19,42 +19,67 @@ describe SpamService, services: true do
let(:issue) { create(:issue, project: project) }
let(:request) { double(:request, env: {}) }
- context 'when indicated as spam by akismet' do
- before { allow(AkismetService).to receive(:new).and_return(double(is_spam?: true)) }
+ context 'when spammable attributes have not changed' do
+ before do
+ issue.closed_at = Time.zone.now
- it 'doesnt check as spam when request is missing' do
- check_spam(issue, nil, false)
-
- expect(issue.spam).to be_falsey
+ allow(AkismetService).to receive(:new).and_return(double(is_spam?: true))
end
- it 'checks as spam' do
- check_spam(issue, request, false)
-
- expect(issue.spam).to be_truthy
+ it 'returns false' do
+ expect(check_spam(issue, request, false)).to be_falsey
end
- it 'creates a spam log' do
+ it 'does not create a spam log' do
expect { check_spam(issue, request, false) }
- .to change { SpamLog.count }.from(0).to(1)
+ .not_to change { SpamLog.count }
end
+ end
- it 'doesnt yield block' do
- expect(check_spam(issue, request, false))
- .to eql(SpamLog.last)
+ context 'when spammable attributes have changed' do
+ before do
+ issue.description = 'SPAM!'
end
- end
- context 'when not indicated as spam by akismet' do
- before { allow(AkismetService).to receive(:new).and_return(double(is_spam?: false)) }
+ context 'when indicated as spam by akismet' do
+ before do
+ allow(AkismetService).to receive(:new).and_return(double(is_spam?: true))
+ end
- it 'returns false' do
- expect(check_spam(issue, request, false)).to be_falsey
+ it 'doesnt check as spam when request is missing' do
+ check_spam(issue, nil, false)
+
+ expect(issue.spam).to be_falsey
+ end
+
+ it 'checks as spam' do
+ check_spam(issue, request, false)
+
+ expect(issue.spam).to be_truthy
+ end
+
+ it 'creates a spam log' do
+ expect { check_spam(issue, request, false) }
+ .to change { SpamLog.count }.from(0).to(1)
+ end
+
+ it 'doesnt yield block' do
+ expect(check_spam(issue, request, false))
+ .to eql(SpamLog.last)
+ end
end
- it 'does not create a spam log' do
- expect { check_spam(issue, request, false) }
- .not_to change { SpamLog.count }
+ context 'when not indicated as spam by akismet' do
+ before { allow(AkismetService).to receive(:new).and_return(double(is_spam?: false)) }
+
+ it 'returns false' do
+ expect(check_spam(issue, request, false)).to be_falsey
+ end
+
+ it 'does not create a spam log' do
+ expect { check_spam(issue, request, false) }
+ .not_to change { SpamLog.count }
+ end
end
end
end
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index ceb3209331f..5ab8f0d981a 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -35,7 +35,8 @@ RSpec.configure do |config|
config.include Warden::Test::Helpers, type: :request
config.include LoginHelpers, type: :feature
config.include SearchHelpers, type: :feature
- config.include WaitForAjax, type: :feature
+ config.include WaitForRequests, :js
+ config.include WaitForAjax, :js
config.include StubConfiguration
config.include EmailHelpers, type: :mailer
config.include TestEnv
diff --git a/spec/support/notify_shared_examples.rb b/spec/support/notify_shared_examples.rb
index a3724b801b3..16a425f2ca2 100644
--- a/spec/support/notify_shared_examples.rb
+++ b/spec/support/notify_shared_examples.rb
@@ -27,24 +27,14 @@ shared_examples 'a multiple recipients email' do
end
shared_examples 'an email sent from GitLab' do
- it 'is sent from GitLab' do
+ it 'has the characteristics of an email sent from GitLab' do
sender = subject.header[:from].addrs[0]
- expect(sender.display_name).to eq(gitlab_sender_display_name)
- expect(sender.address).to eq(gitlab_sender)
- end
-
- it 'has a Reply-To address' do
reply_to = subject.header[:reply_to].addresses
- expect(reply_to).to eq([gitlab_sender_reply_to])
- end
-
- context 'when custom suffix for email subject is set' do
- before do
- stub_config_setting(email_subject_suffix: 'A Nice Suffix')
- end
- it 'ends the subject with the suffix' do
- is_expected.to have_subject /\ \| A Nice Suffix$/
+ aggregate_failures do
+ expect(sender.display_name).to eq(gitlab_sender_display_name)
+ expect(sender.address).to eq(gitlab_sender)
+ expect(reply_to).to eq([gitlab_sender_reply_to])
end
end
end
@@ -56,43 +46,40 @@ shared_examples 'an email that contains a header with author username' do
end
shared_examples 'an email with X-GitLab headers containing project details' do
- it 'has X-GitLab-Project* headers' do
- is_expected.to have_header 'X-GitLab-Project', /#{project.name}/
- is_expected.to have_header 'X-GitLab-Project-Id', /#{project.id}/
- is_expected.to have_header 'X-GitLab-Project-Path', /#{project.path_with_namespace}/
+ it 'has X-GitLab-Project headers' do
+ aggregate_failures do
+ is_expected.to have_header('X-GitLab-Project', /#{project.name}/)
+ is_expected.to have_header('X-GitLab-Project-Id', /#{project.id}/)
+ is_expected.to have_header('X-GitLab-Project-Path', /#{project.path_with_namespace}/)
+ end
end
end
shared_examples 'a new thread email with reply-by-email enabled' do
- let(:regex) { /\A<reply\-(.*)@#{Gitlab.config.gitlab.host}>\Z/ }
-
- it 'has a Message-ID header' do
- is_expected.to have_header 'Message-ID', "<#{model.class.model_name.singular_route_key}_#{model.id}@#{Gitlab.config.gitlab.host}>"
- end
+ it 'has the characteristics of a threaded email' do
+ host = Gitlab.config.gitlab.host
+ route_key = "#{model.class.model_name.singular_route_key}_#{model.id}"
- it 'has a References header' do
- is_expected.to have_header 'References', regex
+ aggregate_failures do
+ is_expected.to have_header('Message-ID', "<#{route_key}@#{host}>")
+ is_expected.to have_header('References', /\A<reply\-.*@#{host}>\Z/ )
+ end
end
end
shared_examples 'a thread answer email with reply-by-email enabled' do
include_examples 'an email with X-GitLab headers containing project details'
- let(:regex) { /\A<#{model.class.model_name.singular_route_key}_#{model.id}@#{Gitlab.config.gitlab.host}> <reply\-(.*)@#{Gitlab.config.gitlab.host}>\Z/ }
-
- it 'has a Message-ID header' do
- is_expected.to have_header 'Message-ID', /\A<(.*)@#{Gitlab.config.gitlab.host}>\Z/
- end
-
- it 'has a In-Reply-To header' do
- is_expected.to have_header 'In-Reply-To', "<#{model.class.model_name.singular_route_key}_#{model.id}@#{Gitlab.config.gitlab.host}>"
- end
- it 'has a References header' do
- is_expected.to have_header 'References', regex
- end
+ it 'has the characteristics of a threaded reply' do
+ host = Gitlab.config.gitlab.host
+ route_key = "#{model.class.model_name.singular_route_key}_#{model.id}"
- it 'has a subject that begins with Re: ' do
- is_expected.to have_subject /^Re: /
+ aggregate_failures do
+ is_expected.to have_header('Message-ID', /\A<.*@#{host}>\Z/)
+ is_expected.to have_header('In-Reply-To', "<#{route_key}@#{host}>")
+ is_expected.to have_header('References', /\A<#{route_key}@#{host}> <reply\-.*@#{host}>\Z/ )
+ is_expected.to have_subject(/^Re: /)
+ end
end
end
@@ -136,80 +123,77 @@ shared_examples 'an answer to an existing thread with reply-by-email enabled' do
end
end
-shared_examples 'a new user email' do
- it 'is sent to the new user' do
- is_expected.to deliver_to new_user_address
- end
-
- it 'has the correct subject' do
- is_expected.to have_subject /^Account was created for you$/i
- end
-
- it 'contains the new user\'s login name' do
- is_expected.to have_body_text /#{new_user_address}/
- end
-end
-
shared_examples 'it should have Gmail Actions links' do
- it { is_expected.to have_body_text '<script type="application/ld+json">' }
- it { is_expected.to have_body_text /ViewAction/ }
+ it do
+ aggregate_failures do
+ is_expected.to have_body_text('<script type="application/ld+json">')
+ is_expected.to have_body_text('ViewAction')
+ end
+ end
end
shared_examples 'it should not have Gmail Actions links' do
- it { is_expected.not_to have_body_text '<script type="application/ld+json">' }
- it { is_expected.not_to have_body_text /ViewAction/ }
+ it do
+ aggregate_failures do
+ is_expected.not_to have_body_text('<script type="application/ld+json">')
+ is_expected.not_to have_body_text('ViewAction')
+ end
+ end
end
shared_examples 'it should show Gmail Actions View Issue link' do
it_behaves_like 'it should have Gmail Actions links'
- it { is_expected.to have_body_text /View Issue/ }
+ it { is_expected.to have_body_text('View Issue') }
end
shared_examples 'it should show Gmail Actions View Merge request link' do
it_behaves_like 'it should have Gmail Actions links'
- it { is_expected.to have_body_text /View Merge request/ }
+ it { is_expected.to have_body_text('View Merge request') }
end
shared_examples 'it should show Gmail Actions View Commit link' do
it_behaves_like 'it should have Gmail Actions links'
- it { is_expected.to have_body_text /View Commit/ }
+ it { is_expected.to have_body_text('View Commit') }
end
shared_examples 'an unsubscribeable thread' do
it_behaves_like 'an unsubscribeable thread with incoming address without %{key}'
- it 'has a List-Unsubscribe header in the correct format' do
- is_expected.to have_header 'List-Unsubscribe', /unsubscribe/
- is_expected.to have_header 'List-Unsubscribe', /mailto/
- is_expected.to have_header 'List-Unsubscribe', /^<.+,.+>$/
+ it 'has a List-Unsubscribe header in the correct format, and a body link' do
+ aggregate_failures do
+ is_expected.to have_header('List-Unsubscribe', /unsubscribe/)
+ is_expected.to have_header('List-Unsubscribe', /mailto/)
+ is_expected.to have_header('List-Unsubscribe', /^<.+,.+>$/)
+ is_expected.to have_body_text('unsubscribe')
+ end
end
-
- it { is_expected.to have_body_text /unsubscribe/ }
end
shared_examples 'an unsubscribeable thread with incoming address without %{key}' do
include_context 'reply-by-email is enabled with incoming address without %{key}'
- it 'has a List-Unsubscribe header in the correct format' do
- is_expected.to have_header 'List-Unsubscribe', /unsubscribe/
- is_expected.not_to have_header 'List-Unsubscribe', /mailto/
- is_expected.to have_header 'List-Unsubscribe', /^<[^,]+>$/
+ it 'has a List-Unsubscribe header in the correct format, and a body link' do
+ aggregate_failures do
+ is_expected.to have_header('List-Unsubscribe', /unsubscribe/)
+ is_expected.not_to have_header('List-Unsubscribe', /mailto/)
+ is_expected.to have_header('List-Unsubscribe', /^<[^,]+>$/)
+ is_expected.to have_body_text('unsubscribe')
+ end
end
-
- it { is_expected.to have_body_text /unsubscribe/ }
end
shared_examples 'a user cannot unsubscribe through footer link' do
- it 'does not have a List-Unsubscribe header' do
- is_expected.not_to have_header 'List-Unsubscribe', /unsubscribe/
+ it 'does not have a List-Unsubscribe header or a body link' do
+ aggregate_failures do
+ is_expected.not_to have_header('List-Unsubscribe', /unsubscribe/)
+ is_expected.not_to have_body_text('unsubscribe')
+ end
end
-
- it { is_expected.not_to have_body_text /unsubscribe/ }
end
shared_examples 'an email with a labels subscriptions link in its footer' do
- it { is_expected.to have_body_text /label subscriptions/ }
+ it { is_expected.to have_body_text('label subscriptions') }
end
diff --git a/spec/support/prometheus_helpers.rb b/spec/support/prometheus_helpers.rb
index a52d8f37d14..4afdbd68304 100644
--- a/spec/support/prometheus_helpers.rb
+++ b/spec/support/prometheus_helpers.rb
@@ -1,10 +1,10 @@
module PrometheusHelpers
def prometheus_memory_query(environment_slug)
- %{sum(container_memory_usage_bytes{container_name="app",environment="#{environment_slug}"})/1024/1024}
+ %{(sum(container_memory_usage_bytes{container_name="app",environment="#{environment_slug}"}) / count(container_memory_usage_bytes{container_name="app",environment="#{environment_slug}"})) /1024/1024}
end
def prometheus_cpu_query(environment_slug)
- %{sum(rate(container_cpu_usage_seconds_total{container_name="app",environment="#{environment_slug}"}[2m]))}
+ %{sum(rate(container_cpu_usage_seconds_total{container_name="app",environment="#{environment_slug}"}[2m])) / count(container_cpu_usage_seconds_total{container_name="app",environment="#{environment_slug}"}) * 100}
end
def prometheus_query_url(prometheus_query)
diff --git a/spec/support/slack_mattermost_notifications_shared_examples.rb b/spec/support/slack_mattermost_notifications_shared_examples.rb
index 704922b6cf4..b902fe90707 100644
--- a/spec/support/slack_mattermost_notifications_shared_examples.rb
+++ b/spec/support/slack_mattermost_notifications_shared_examples.rb
@@ -324,5 +324,24 @@ RSpec.shared_examples 'slack or mattermost notifications' do
it_behaves_like 'call Slack/Mattermost API'
end
end
+
+ context 'only notify for the default branch' do
+ context 'when enabled' do
+ let(:pipeline) do
+ create(:ci_pipeline, project: project, status: 'failed', ref: 'not-the-default-branch')
+ end
+
+ before do
+ chat_service.notify_only_default_branch = true
+ end
+
+ it 'does not call the Slack/Mattermost API for pipeline events' do
+ data = Gitlab::DataBuilder::Pipeline.build(pipeline)
+ result = chat_service.execute(data)
+
+ expect(result).to be_falsy
+ end
+ end
+ end
end
end
diff --git a/spec/support/target_branch_helpers.rb b/spec/support/target_branch_helpers.rb
new file mode 100644
index 00000000000..3ee8f0f657e
--- /dev/null
+++ b/spec/support/target_branch_helpers.rb
@@ -0,0 +1,16 @@
+module TargetBranchHelpers
+ def select_branch(name)
+ first('button.js-target-branch').click
+ wait_for_ajax
+ all('a[data-group="Branches"]').find do |el|
+ el.text == name
+ end.click
+ end
+
+ def create_new_branch(name)
+ first('button.js-target-branch').click
+ click_link 'Create new branch'
+ fill_in 'new_branch_name', with: name
+ click_button 'Create'
+ end
+end
diff --git a/spec/support/wait_for_requests.rb b/spec/support/wait_for_requests.rb
new file mode 100644
index 00000000000..0bfa7f72ff8
--- /dev/null
+++ b/spec/support/wait_for_requests.rb
@@ -0,0 +1,32 @@
+module WaitForRequests
+ extend self
+
+ # This is inspired by http://www.salsify.com/blog/engineering/tearing-capybara-ajax-tests
+ def wait_for_requests_complete
+ Gitlab::Testing::RequestBlockerMiddleware.block_requests!
+ wait_for('pending AJAX requests complete') do
+ Gitlab::Testing::RequestBlockerMiddleware.num_active_requests.zero?
+ end
+ ensure
+ Gitlab::Testing::RequestBlockerMiddleware.allow_requests!
+ end
+
+ # Waits until the passed block returns true
+ def wait_for(condition_name, max_wait_time: Capybara.default_max_wait_time, polling_interval: 0.01)
+ wait_until = Time.now + max_wait_time.seconds
+ loop do
+ break if yield
+ if Time.now > wait_until
+ raise "Condition not met: #{condition_name}"
+ else
+ sleep(polling_interval)
+ end
+ end
+ end
+end
+
+RSpec.configure do |config|
+ config.after(:each, :js) do
+ wait_for_requests_complete
+ end
+end
diff --git a/spec/support/wait_for_vue_resource.rb b/spec/support/wait_for_vue_resource.rb
index 1029f84716f..4a4e2e16ee7 100644
--- a/spec/support/wait_for_vue_resource.rb
+++ b/spec/support/wait_for_vue_resource.rb
@@ -1,7 +1,7 @@
module WaitForVueResource
def wait_for_vue_resource(spinner: true)
Timeout.timeout(Capybara.default_max_wait_time) do
- loop until page.evaluate_script('Vue.activeResources').zero?
+ loop until page.evaluate_script('window.activeVueResources').zero?
end
end
end
diff --git a/spec/tasks/gitlab/gitaly_rake_spec.rb b/spec/tasks/gitlab/gitaly_rake_spec.rb
new file mode 100644
index 00000000000..d95baddf546
--- /dev/null
+++ b/spec/tasks/gitlab/gitaly_rake_spec.rb
@@ -0,0 +1,78 @@
+require 'rake_helper'
+
+describe 'gitlab:gitaly namespace rake task' do
+ before :all do
+ Rake.application.rake_require 'tasks/gitlab/gitaly'
+ end
+
+ describe 'install' do
+ let(:repo) { 'https://gitlab.com/gitlab-org/gitaly.git' }
+ let(:clone_path) { Rails.root.join('tmp/tests/gitaly').to_s }
+ let(:tag) { "v#{File.read(Rails.root.join(Gitlab::GitalyClient::SERVER_VERSION_FILE)).chomp}" }
+
+ context 'no dir given' do
+ it 'aborts and display a help message' do
+ # avoid writing task output to spec progress
+ allow($stderr).to receive :write
+ expect { run_rake_task('gitlab:gitaly:install') }.to raise_error /Please specify the directory where you want to install gitaly/
+ end
+ end
+
+ context 'when an underlying Git command fail' do
+ it 'aborts and display a help message' do
+ expect_any_instance_of(Object).
+ to receive(:checkout_or_clone_tag).and_raise 'Git error'
+
+ expect { run_rake_task('gitlab:gitaly:install', clone_path) }.to raise_error 'Git error'
+ end
+ end
+
+ describe 'checkout or clone' do
+ before do
+ expect(Dir).to receive(:chdir).with(clone_path)
+ end
+
+ it 'calls checkout_or_clone_tag with the right arguments' do
+ expect_any_instance_of(Object).
+ to receive(:checkout_or_clone_tag).with(tag: tag, repo: repo, target_dir: clone_path)
+
+ run_rake_task('gitlab:gitaly:install', clone_path)
+ end
+ end
+
+ describe 'gmake/make' do
+ before do
+ FileUtils.mkdir_p(clone_path)
+ expect(Dir).to receive(:chdir).with(clone_path).and_call_original
+ end
+
+ context 'gmake is available' do
+ before do
+ expect_any_instance_of(Object).to receive(:checkout_or_clone_tag)
+ allow_any_instance_of(Object).to receive(:run_command!).with(['gmake']).and_return(true)
+ end
+
+ it 'calls gmake in the gitaly directory' do
+ expect(Gitlab::Popen).to receive(:popen).with(%w[which gmake]).and_return(['/usr/bin/gmake', 0])
+ expect_any_instance_of(Object).to receive(:run_command!).with(['gmake']).and_return(true)
+
+ run_rake_task('gitlab:gitaly:install', clone_path)
+ end
+ end
+
+ context 'gmake is not available' do
+ before do
+ expect_any_instance_of(Object).to receive(:checkout_or_clone_tag)
+ allow_any_instance_of(Object).to receive(:run_command!).with(['make']).and_return(true)
+ end
+
+ it 'calls make in the gitaly directory' do
+ expect(Gitlab::Popen).to receive(:popen).with(%w[which gmake]).and_return(['', 42])
+ expect_any_instance_of(Object).to receive(:run_command!).with(['make']).and_return(true)
+
+ run_rake_task('gitlab:gitaly:install', clone_path)
+ end
+ end
+ end
+ end
+end
diff --git a/spec/tasks/gitlab/workhorse_rake_spec.rb b/spec/tasks/gitlab/workhorse_rake_spec.rb
index 6de66c3cf07..8a66a4aa047 100644
--- a/spec/tasks/gitlab/workhorse_rake_spec.rb
+++ b/spec/tasks/gitlab/workhorse_rake_spec.rb
@@ -9,9 +9,6 @@ describe 'gitlab:workhorse namespace rake task' do
let(:repo) { 'https://gitlab.com/gitlab-org/gitlab-workhorse.git' }
let(:clone_path) { Rails.root.join('tmp/tests/gitlab-workhorse').to_s }
let(:tag) { "v#{File.read(Rails.root.join(Gitlab::Workhorse::VERSION_FILE)).chomp}" }
- before do
- allow(ENV).to receive(:[])
- end
context 'no dir given' do
it 'aborts and display a help message' do
diff --git a/tmp/sockets/private/.gitkeep b/tmp/sockets/private/.gitkeep
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/tmp/sockets/private/.gitkeep
diff --git a/vendor/assets/javascripts/js.cookie.js b/vendor/assets/javascripts/js.cookie.js
deleted file mode 100644
index 92dbba162c4..00000000000
--- a/vendor/assets/javascripts/js.cookie.js
+++ /dev/null
@@ -1,156 +0,0 @@
-/*!
- * JavaScript Cookie v2.1.3
- * https://github.com/js-cookie/js-cookie
- *
- * Copyright 2006, 2015 Klaus Hartl & Fagner Brack
- * Released under the MIT license
- */
-;(function (factory) {
- var registeredInModuleLoader = false;
- if (typeof define === 'function' && define.amd) {
- define(factory);
- registeredInModuleLoader = true;
- }
- if (typeof exports === 'object') {
- module.exports = factory();
- registeredInModuleLoader = true;
- }
- if (!registeredInModuleLoader) {
- var OldCookies = window.Cookies;
- var api = window.Cookies = factory();
- api.noConflict = function () {
- window.Cookies = OldCookies;
- return api;
- };
- }
-}(function () {
- function extend () {
- var i = 0;
- var result = {};
- for (; i < arguments.length; i++) {
- var attributes = arguments[ i ];
- for (var key in attributes) {
- result[key] = attributes[key];
- }
- }
- return result;
- }
-
- function init (converter) {
- function api (key, value, attributes) {
- var result;
- if (typeof document === 'undefined') {
- return;
- }
-
- // Write
-
- if (arguments.length > 1) {
- attributes = extend({
- path: '/'
- }, api.defaults, attributes);
-
- if (typeof attributes.expires === 'number') {
- var expires = new Date();
- expires.setMilliseconds(expires.getMilliseconds() + attributes.expires * 864e+5);
- attributes.expires = expires;
- }
-
- try {
- result = JSON.stringify(value);
- if (/^[\{\[]/.test(result)) {
- value = result;
- }
- } catch (e) {}
-
- if (!converter.write) {
- value = encodeURIComponent(String(value))
- .replace(/%(23|24|26|2B|3A|3C|3E|3D|2F|3F|40|5B|5D|5E|60|7B|7D|7C)/g, decodeURIComponent);
- } else {
- value = converter.write(value, key);
- }
-
- key = encodeURIComponent(String(key));
- key = key.replace(/%(23|24|26|2B|5E|60|7C)/g, decodeURIComponent);
- key = key.replace(/[\(\)]/g, escape);
-
- return (document.cookie = [
- key, '=', value,
- attributes.expires ? '; expires=' + attributes.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE
- attributes.path ? '; path=' + attributes.path : '',
- attributes.domain ? '; domain=' + attributes.domain : '',
- attributes.secure ? '; secure' : ''
- ].join(''));
- }
-
- // Read
-
- if (!key) {
- result = {};
- }
-
- // To prevent the for loop in the first place assign an empty array
- // in case there are no cookies at all. Also prevents odd result when
- // calling "get()"
- var cookies = document.cookie ? document.cookie.split('; ') : [];
- var rdecode = /(%[0-9A-Z]{2})+/g;
- var i = 0;
-
- for (; i < cookies.length; i++) {
- var parts = cookies[i].split('=');
- var cookie = parts.slice(1).join('=');
-
- if (cookie.charAt(0) === '"') {
- cookie = cookie.slice(1, -1);
- }
-
- try {
- var name = parts[0].replace(rdecode, decodeURIComponent);
- cookie = converter.read ?
- converter.read(cookie, name) : converter(cookie, name) ||
- cookie.replace(rdecode, decodeURIComponent);
-
- if (this.json) {
- try {
- cookie = JSON.parse(cookie);
- } catch (e) {}
- }
-
- if (key === name) {
- result = cookie;
- break;
- }
-
- if (!key) {
- result[name] = cookie;
- }
- } catch (e) {}
- }
-
- return result;
- }
-
- api.set = api;
- api.get = function (key) {
- return api.call(api, key);
- };
- api.getJSON = function () {
- return api.apply({
- json: true
- }, [].slice.call(arguments));
- };
- api.defaults = {};
-
- api.remove = function (key, attributes) {
- api(key, '', extend(attributes, {
- expires: -1
- }));
- };
-
- api.withConverter = init;
-
- return api;
- }
-
- return init(function () {});
-})); \ No newline at end of file
diff --git a/yarn.lock b/yarn.lock
index 2500ddc6f6b..fb3bfce4d11 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -4464,9 +4464,9 @@ vue-resource@^0.9.3:
version "0.9.3"
resolved "https://registry.yarnpkg.com/vue-resource/-/vue-resource-0.9.3.tgz#ab46e1c44ea219142dcc28ae4043b3b04c80959d"
-vue@^2.1.10:
- version "2.1.10"
- resolved "https://registry.yarnpkg.com/vue/-/vue-2.1.10.tgz#c9235ca48c7925137be5807832ac4e3ac180427b"
+vue@^2.2.4:
+ version "2.2.4"
+ resolved "https://registry.yarnpkg.com/vue/-/vue-2.2.4.tgz#d0a3a050a80a12356d7950ae5a7b3131048209cc"
watchpack@^1.2.0:
version "1.2.1"