summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.eslintrc2
-rw-r--r--.gitlab-ci.yml2
-rw-r--r--Gemfile2
-rw-r--r--Gemfile.lock4
-rw-r--r--app/assets/javascripts/abuse_reports.js (renamed from app/assets/javascripts/abuse_reports.js.es6)0
-rw-r--r--app/assets/javascripts/activities.js (renamed from app/assets/javascripts/activities.js.es6)0
-rw-r--r--app/assets/javascripts/blob/blob_ci_yaml.js (renamed from app/assets/javascripts/blob/blob_ci_yaml.js.es6)0
-rw-r--r--app/assets/javascripts/blob/blob_dockerfile_selector.js (renamed from app/assets/javascripts/blob/blob_dockerfile_selector.js.es6)0
-rw-r--r--app/assets/javascripts/blob/blob_dockerfile_selectors.js (renamed from app/assets/javascripts/blob/blob_dockerfile_selectors.js.es6)0
-rw-r--r--app/assets/javascripts/blob/blob_license_selectors.js (renamed from app/assets/javascripts/blob/blob_license_selectors.js.es6)0
-rw-r--r--app/assets/javascripts/blob/template_selector.js (renamed from app/assets/javascripts/blob/template_selector.js.es6)0
-rw-r--r--app/assets/javascripts/boards/boards_bundle.js (renamed from app/assets/javascripts/boards/boards_bundle.js.es6)0
-rw-r--r--app/assets/javascripts/boards/components/board.js (renamed from app/assets/javascripts/boards/components/board.js.es6)0
-rw-r--r--app/assets/javascripts/boards/components/board_blank_state.js (renamed from app/assets/javascripts/boards/components/board_blank_state.js.es6)0
-rw-r--r--app/assets/javascripts/boards/components/board_delete.js (renamed from app/assets/javascripts/boards/components/board_delete.js.es6)0
-rw-r--r--app/assets/javascripts/boards/components/board_list.js (renamed from app/assets/javascripts/boards/components/board_list.js.es6)0
-rw-r--r--app/assets/javascripts/boards/components/board_sidebar.js (renamed from app/assets/javascripts/boards/components/board_sidebar.js.es6)0
-rw-r--r--app/assets/javascripts/boards/components/issue_card_inner.js (renamed from app/assets/javascripts/boards/components/issue_card_inner.js.es6)0
-rw-r--r--app/assets/javascripts/boards/components/modal/empty_state.js (renamed from app/assets/javascripts/boards/components/modal/empty_state.js.es6)0
-rw-r--r--app/assets/javascripts/boards/components/modal/filters.js (renamed from app/assets/javascripts/boards/components/modal/filters.js.es6)0
-rw-r--r--app/assets/javascripts/boards/components/modal/filters/label.js (renamed from app/assets/javascripts/boards/components/modal/filters/label.js.es6)0
-rw-r--r--app/assets/javascripts/boards/components/modal/filters/milestone.js (renamed from app/assets/javascripts/boards/components/modal/filters/milestone.js.es6)0
-rw-r--r--app/assets/javascripts/boards/components/modal/filters/user.js (renamed from app/assets/javascripts/boards/components/modal/filters/user.js.es6)0
-rw-r--r--app/assets/javascripts/boards/components/modal/footer.js (renamed from app/assets/javascripts/boards/components/modal/footer.js.es6)0
-rw-r--r--app/assets/javascripts/boards/components/modal/header.js (renamed from app/assets/javascripts/boards/components/modal/header.js.es6)0
-rw-r--r--app/assets/javascripts/boards/components/modal/index.js (renamed from app/assets/javascripts/boards/components/modal/index.js.es6)0
-rw-r--r--app/assets/javascripts/boards/components/modal/list.js (renamed from app/assets/javascripts/boards/components/modal/list.js.es6)0
-rw-r--r--app/assets/javascripts/boards/components/modal/lists_dropdown.js (renamed from app/assets/javascripts/boards/components/modal/lists_dropdown.js.es6)0
-rw-r--r--app/assets/javascripts/boards/components/modal/tabs.js (renamed from app/assets/javascripts/boards/components/modal/tabs.js.es6)0
-rw-r--r--app/assets/javascripts/boards/components/new_list_dropdown.js (renamed from app/assets/javascripts/boards/components/new_list_dropdown.js.es6)0
-rw-r--r--app/assets/javascripts/boards/components/sidebar/remove_issue.js (renamed from app/assets/javascripts/boards/components/sidebar/remove_issue.js.es6)0
-rw-r--r--app/assets/javascripts/boards/filters/due_date_filters.js (renamed from app/assets/javascripts/boards/filters/due_date_filters.js.es6)0
-rw-r--r--app/assets/javascripts/boards/mixins/modal_mixins.js (renamed from app/assets/javascripts/boards/mixins/modal_mixins.js.es6)0
-rw-r--r--app/assets/javascripts/boards/mixins/sortable_default_options.js (renamed from app/assets/javascripts/boards/mixins/sortable_default_options.js.es6)0
-rw-r--r--app/assets/javascripts/boards/models/issue.js (renamed from app/assets/javascripts/boards/models/issue.js.es6)0
-rw-r--r--app/assets/javascripts/boards/models/label.js (renamed from app/assets/javascripts/boards/models/label.js.es6)0
-rw-r--r--app/assets/javascripts/boards/models/list.js (renamed from app/assets/javascripts/boards/models/list.js.es6)0
-rw-r--r--app/assets/javascripts/boards/models/milestone.js (renamed from app/assets/javascripts/boards/models/milestone.js.es6)0
-rw-r--r--app/assets/javascripts/boards/models/user.js (renamed from app/assets/javascripts/boards/models/user.js.es6)0
-rw-r--r--app/assets/javascripts/boards/services/board_service.js (renamed from app/assets/javascripts/boards/services/board_service.js.es6)0
-rw-r--r--app/assets/javascripts/boards/stores/boards_store.js (renamed from app/assets/javascripts/boards/stores/boards_store.js.es6)0
-rw-r--r--app/assets/javascripts/boards/stores/modal_store.js (renamed from app/assets/javascripts/boards/stores/modal_store.js.es6)0
-rw-r--r--app/assets/javascripts/build_variables.js (renamed from app/assets/javascripts/build_variables.js.es6)0
-rw-r--r--app/assets/javascripts/ci_lint_editor.js (renamed from app/assets/javascripts/ci_lint_editor.js.es6)0
-rw-r--r--app/assets/javascripts/commit/pipelines/pipelines_bundle.js (renamed from app/assets/javascripts/commit/pipelines/pipelines_bundle.js.es6)0
-rw-r--r--app/assets/javascripts/commit/pipelines/pipelines_service.js (renamed from app/assets/javascripts/commit/pipelines/pipelines_service.js.es6)0
-rw-r--r--app/assets/javascripts/commit/pipelines/pipelines_store.js (renamed from app/assets/javascripts/commit/pipelines/pipelines_store.js.es6)0
-rw-r--r--app/assets/javascripts/commit/pipelines/pipelines_table.js (renamed from app/assets/javascripts/commit/pipelines/pipelines_table.js.es6)0
-rw-r--r--app/assets/javascripts/commons/bootstrap.js10
-rw-r--r--app/assets/javascripts/commons/index.js2
-rw-r--r--app/assets/javascripts/commons/jquery.js11
-rw-r--r--app/assets/javascripts/compare_autocomplete.js (renamed from app/assets/javascripts/compare_autocomplete.js.es6)0
-rw-r--r--app/assets/javascripts/copy_as_gfm.js (renamed from app/assets/javascripts/copy_as_gfm.js.es6)0
-rw-r--r--app/assets/javascripts/create_label.js (renamed from app/assets/javascripts/create_label.js.es6)0
-rw-r--r--app/assets/javascripts/cycle_analytics/components/stage_code_component.js (renamed from app/assets/javascripts/cycle_analytics/components/stage_code_component.js.es6)0
-rw-r--r--app/assets/javascripts/cycle_analytics/components/stage_issue_component.js (renamed from app/assets/javascripts/cycle_analytics/components/stage_issue_component.js.es6)0
-rw-r--r--app/assets/javascripts/cycle_analytics/components/stage_plan_component.js (renamed from app/assets/javascripts/cycle_analytics/components/stage_plan_component.js.es6)0
-rw-r--r--app/assets/javascripts/cycle_analytics/components/stage_production_component.js (renamed from app/assets/javascripts/cycle_analytics/components/stage_production_component.js.es6)0
-rw-r--r--app/assets/javascripts/cycle_analytics/components/stage_review_component.js (renamed from app/assets/javascripts/cycle_analytics/components/stage_review_component.js.es6)0
-rw-r--r--app/assets/javascripts/cycle_analytics/components/stage_staging_component.js (renamed from app/assets/javascripts/cycle_analytics/components/stage_staging_component.js.es6)0
-rw-r--r--app/assets/javascripts/cycle_analytics/components/stage_test_component.js (renamed from app/assets/javascripts/cycle_analytics/components/stage_test_component.js.es6)0
-rw-r--r--app/assets/javascripts/cycle_analytics/components/total_time_component.js (renamed from app/assets/javascripts/cycle_analytics/components/total_time_component.js.es6)0
-rw-r--r--app/assets/javascripts/cycle_analytics/cycle_analytics_bundle.js (renamed from app/assets/javascripts/cycle_analytics/cycle_analytics_bundle.js.es6)0
-rw-r--r--app/assets/javascripts/cycle_analytics/cycle_analytics_service.js (renamed from app/assets/javascripts/cycle_analytics/cycle_analytics_service.js.es6)0
-rw-r--r--app/assets/javascripts/cycle_analytics/cycle_analytics_store.js (renamed from app/assets/javascripts/cycle_analytics/cycle_analytics_store.js.es6)0
-rw-r--r--app/assets/javascripts/cycle_analytics/default_event_objects.js (renamed from app/assets/javascripts/cycle_analytics/default_event_objects.js.es6)0
-rw-r--r--app/assets/javascripts/diff.js (renamed from app/assets/javascripts/diff.js.es6)0
-rw-r--r--app/assets/javascripts/diff_notes/components/comment_resolve_btn.js (renamed from app/assets/javascripts/diff_notes/components/comment_resolve_btn.js.es6)0
-rw-r--r--app/assets/javascripts/diff_notes/components/jump_to_discussion.js (renamed from app/assets/javascripts/diff_notes/components/jump_to_discussion.js.es6)0
-rw-r--r--app/assets/javascripts/diff_notes/components/resolve_btn.js (renamed from app/assets/javascripts/diff_notes/components/resolve_btn.js.es6)0
-rw-r--r--app/assets/javascripts/diff_notes/components/resolve_count.js (renamed from app/assets/javascripts/diff_notes/components/resolve_count.js.es6)0
-rw-r--r--app/assets/javascripts/diff_notes/components/resolve_discussion_btn.js (renamed from app/assets/javascripts/diff_notes/components/resolve_discussion_btn.js.es6)0
-rw-r--r--app/assets/javascripts/diff_notes/diff_notes_bundle.js (renamed from app/assets/javascripts/diff_notes/diff_notes_bundle.js.es6)0
-rw-r--r--app/assets/javascripts/diff_notes/mixins/discussion.js (renamed from app/assets/javascripts/diff_notes/mixins/discussion.js.es6)0
-rw-r--r--app/assets/javascripts/diff_notes/models/discussion.js (renamed from app/assets/javascripts/diff_notes/models/discussion.js.es6)0
-rw-r--r--app/assets/javascripts/diff_notes/models/note.js (renamed from app/assets/javascripts/diff_notes/models/note.js.es6)0
-rw-r--r--app/assets/javascripts/diff_notes/services/resolve.js (renamed from app/assets/javascripts/diff_notes/services/resolve.js.es6)0
-rw-r--r--app/assets/javascripts/diff_notes/stores/comments.js (renamed from app/assets/javascripts/diff_notes/stores/comments.js.es6)0
-rw-r--r--app/assets/javascripts/dispatcher.js (renamed from app/assets/javascripts/dispatcher.js.es6)13
-rw-r--r--app/assets/javascripts/due_date_select.js (renamed from app/assets/javascripts/due_date_select.js.es6)0
-rw-r--r--app/assets/javascripts/environments/components/environment.js (renamed from app/assets/javascripts/environments/components/environment.js.es6)0
-rw-r--r--app/assets/javascripts/environments/components/environment_actions.js (renamed from app/assets/javascripts/environments/components/environment_actions.js.es6)0
-rw-r--r--app/assets/javascripts/environments/components/environment_external_url.js (renamed from app/assets/javascripts/environments/components/environment_external_url.js.es6)0
-rw-r--r--app/assets/javascripts/environments/components/environment_item.js (renamed from app/assets/javascripts/environments/components/environment_item.js.es6)0
-rw-r--r--app/assets/javascripts/environments/components/environment_rollback.js (renamed from app/assets/javascripts/environments/components/environment_rollback.js.es6)0
-rw-r--r--app/assets/javascripts/environments/components/environment_stop.js (renamed from app/assets/javascripts/environments/components/environment_stop.js.es6)0
-rw-r--r--app/assets/javascripts/environments/components/environment_terminal_button.js (renamed from app/assets/javascripts/environments/components/environment_terminal_button.js.es6)0
-rw-r--r--app/assets/javascripts/environments/components/environments_table.js (renamed from app/assets/javascripts/environments/components/environments_table.js.es6)0
-rw-r--r--app/assets/javascripts/environments/environments_bundle.js (renamed from app/assets/javascripts/environments/environments_bundle.js.es6)0
-rw-r--r--app/assets/javascripts/environments/folder/environments_folder_bundle.js (renamed from app/assets/javascripts/environments/folder/environments_folder_bundle.js.es6)0
-rw-r--r--app/assets/javascripts/environments/folder/environments_folder_view.js (renamed from app/assets/javascripts/environments/folder/environments_folder_view.js.es6)0
-rw-r--r--app/assets/javascripts/environments/services/environments_service.js (renamed from app/assets/javascripts/environments/services/environments_service.js.es6)0
-rw-r--r--app/assets/javascripts/environments/stores/environments_store.js (renamed from app/assets/javascripts/environments/stores/environments_store.js.es6)0
-rw-r--r--app/assets/javascripts/extensions/array.js (renamed from app/assets/javascripts/extensions/array.js.es6)0
-rw-r--r--app/assets/javascripts/extensions/custom_event.js (renamed from app/assets/javascripts/extensions/custom_event.js.es6)0
-rw-r--r--app/assets/javascripts/extensions/element.js (renamed from app/assets/javascripts/extensions/element.js.es6)0
-rw-r--r--app/assets/javascripts/extensions/object.js (renamed from app/assets/javascripts/extensions/object.js.es6)0
-rw-r--r--app/assets/javascripts/filterable_list.js45
-rw-r--r--app/assets/javascripts/filtered_search/dropdown_hint.js (renamed from app/assets/javascripts/filtered_search/dropdown_hint.js.es6)0
-rw-r--r--app/assets/javascripts/filtered_search/dropdown_non_user.js (renamed from app/assets/javascripts/filtered_search/dropdown_non_user.js.es6)0
-rw-r--r--app/assets/javascripts/filtered_search/dropdown_user.js (renamed from app/assets/javascripts/filtered_search/dropdown_user.js.es6)0
-rw-r--r--app/assets/javascripts/filtered_search/dropdown_utils.js (renamed from app/assets/javascripts/filtered_search/dropdown_utils.js.es6)0
-rw-r--r--app/assets/javascripts/filtered_search/filtered_search_dropdown.js (renamed from app/assets/javascripts/filtered_search/filtered_search_dropdown.js.es6)0
-rw-r--r--app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js (renamed from app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js.es6)0
-rw-r--r--app/assets/javascripts/filtered_search/filtered_search_manager.js (renamed from app/assets/javascripts/filtered_search/filtered_search_manager.js.es6)0
-rw-r--r--app/assets/javascripts/filtered_search/filtered_search_token_keys.js (renamed from app/assets/javascripts/filtered_search/filtered_search_token_keys.js.es6)0
-rw-r--r--app/assets/javascripts/filtered_search/filtered_search_tokenizer.js (renamed from app/assets/javascripts/filtered_search/filtered_search_tokenizer.js.es6)0
-rw-r--r--app/assets/javascripts/gfm_auto_complete.js (renamed from app/assets/javascripts/gfm_auto_complete.js.es6)0
-rw-r--r--app/assets/javascripts/gl_field_error.js (renamed from app/assets/javascripts/gl_field_error.js.es6)0
-rw-r--r--app/assets/javascripts/gl_field_errors.js (renamed from app/assets/javascripts/gl_field_errors.js.es6)0
-rw-r--r--app/assets/javascripts/gl_form.js (renamed from app/assets/javascripts/gl_form.js.es6)0
-rw-r--r--app/assets/javascripts/graphs/graphs_bundle.js2
-rw-r--r--app/assets/javascripts/group_label_subscription.js (renamed from app/assets/javascripts/group_label_subscription.js.es6)0
-rw-r--r--app/assets/javascripts/groups_list.js45
-rw-r--r--app/assets/javascripts/issuable.js (renamed from app/assets/javascripts/issuable.js.es6)0
-rw-r--r--app/assets/javascripts/issuable/issuable_bundle.js (renamed from app/assets/javascripts/issuable/issuable_bundle.js.es6)0
-rw-r--r--app/assets/javascripts/issuable/time_tracking/components/collapsed_state.js (renamed from app/assets/javascripts/issuable/time_tracking/components/collapsed_state.js.es6)0
-rw-r--r--app/assets/javascripts/issuable/time_tracking/components/comparison_pane.js (renamed from app/assets/javascripts/issuable/time_tracking/components/comparison_pane.js.es6)0
-rw-r--r--app/assets/javascripts/issuable/time_tracking/components/estimate_only_pane.js (renamed from app/assets/javascripts/issuable/time_tracking/components/estimate_only_pane.js.es6)0
-rw-r--r--app/assets/javascripts/issuable/time_tracking/components/help_state.js (renamed from app/assets/javascripts/issuable/time_tracking/components/help_state.js.es6)0
-rw-r--r--app/assets/javascripts/issuable/time_tracking/components/no_tracking_pane.js (renamed from app/assets/javascripts/issuable/time_tracking/components/no_tracking_pane.js.es6)0
-rw-r--r--app/assets/javascripts/issuable/time_tracking/components/spent_only_pane.js (renamed from app/assets/javascripts/issuable/time_tracking/components/spent_only_pane.js.es6)0
-rw-r--r--app/assets/javascripts/issuable/time_tracking/components/time_tracker.js (renamed from app/assets/javascripts/issuable/time_tracking/components/time_tracker.js.es6)0
-rw-r--r--app/assets/javascripts/issuable/time_tracking/time_tracking_bundle.js (renamed from app/assets/javascripts/issuable/time_tracking/time_tracking_bundle.js.es6)2
-rw-r--r--app/assets/javascripts/issues_bulk_assignment.js (renamed from app/assets/javascripts/issues_bulk_assignment.js.es6)0
-rw-r--r--app/assets/javascripts/label_manager.js (renamed from app/assets/javascripts/label_manager.js.es6)0
-rw-r--r--app/assets/javascripts/lib/chart.js3
-rw-r--r--app/assets/javascripts/lib/cropper.js7
-rw-r--r--app/assets/javascripts/lib/d3.js3
-rw-r--r--app/assets/javascripts/lib/utils/bootstrap_linked_tabs.js (renamed from app/assets/javascripts/lib/utils/bootstrap_linked_tabs.js.es6)0
-rw-r--r--app/assets/javascripts/lib/utils/common_utils.js (renamed from app/assets/javascripts/lib/utils/common_utils.js.es6)0
-rw-r--r--app/assets/javascripts/lib/utils/datetime_utility.js (renamed from app/assets/javascripts/lib/utils/datetime_utility.js.es6)0
-rw-r--r--app/assets/javascripts/lib/utils/pretty_time.js (renamed from app/assets/javascripts/lib/utils/pretty_time.js.es6)0
-rw-r--r--app/assets/javascripts/lib/utils/url_utility.js (renamed from app/assets/javascripts/lib/utils/url_utility.js.es6)0
-rw-r--r--app/assets/javascripts/lib/vue_resource.js.es62
-rw-r--r--app/assets/javascripts/main.js (renamed from app/assets/javascripts/application.js)48
-rw-r--r--app/assets/javascripts/member_expiration_date.js (renamed from app/assets/javascripts/member_expiration_date.js.es6)0
-rw-r--r--app/assets/javascripts/members.js (renamed from app/assets/javascripts/members.js.es6)0
-rw-r--r--app/assets/javascripts/merge_conflicts/components/diff_file_editor.js (renamed from app/assets/javascripts/merge_conflicts/components/diff_file_editor.js.es6)0
-rw-r--r--app/assets/javascripts/merge_conflicts/components/inline_conflict_lines.js (renamed from app/assets/javascripts/merge_conflicts/components/inline_conflict_lines.js.es6)0
-rw-r--r--app/assets/javascripts/merge_conflicts/components/parallel_conflict_lines.js (renamed from app/assets/javascripts/merge_conflicts/components/parallel_conflict_lines.js.es6)0
-rw-r--r--app/assets/javascripts/merge_conflicts/merge_conflict_service.js (renamed from app/assets/javascripts/merge_conflicts/merge_conflict_service.js.es6)0
-rw-r--r--app/assets/javascripts/merge_conflicts/merge_conflict_store.js (renamed from app/assets/javascripts/merge_conflicts/merge_conflict_store.js.es6)0
-rw-r--r--app/assets/javascripts/merge_conflicts/merge_conflicts_bundle.js (renamed from app/assets/javascripts/merge_conflicts/merge_conflicts_bundle.js.es6)0
-rw-r--r--app/assets/javascripts/merge_conflicts/mixins/line_conflict_actions.js (renamed from app/assets/javascripts/merge_conflicts/mixins/line_conflict_actions.js.es6)0
-rw-r--r--app/assets/javascripts/merge_conflicts/mixins/line_conflict_utils.js (renamed from app/assets/javascripts/merge_conflicts/mixins/line_conflict_utils.js.es6)0
-rw-r--r--app/assets/javascripts/merge_request_tabs.js (renamed from app/assets/javascripts/merge_request_tabs.js.es6)0
-rw-r--r--app/assets/javascripts/merge_request_widget.js (renamed from app/assets/javascripts/merge_request_widget.js.es6)46
-rw-r--r--app/assets/javascripts/merge_request_widget/ci_bundle.js (renamed from app/assets/javascripts/merge_request_widget/ci_bundle.js.es6)10
-rw-r--r--app/assets/javascripts/mini_pipeline_graph_dropdown.js (renamed from app/assets/javascripts/mini_pipeline_graph_dropdown.js.es6)0
-rw-r--r--app/assets/javascripts/notes.js2
-rw-r--r--app/assets/javascripts/pager.js (renamed from app/assets/javascripts/pager.js.es6)0
-rw-r--r--app/assets/javascripts/pipelines.js (renamed from app/assets/javascripts/pipelines.js.es6)0
-rw-r--r--app/assets/javascripts/profile/gl_crop.js (renamed from app/assets/javascripts/profile/gl_crop.js.es6)2
-rw-r--r--app/assets/javascripts/profile/profile.js (renamed from app/assets/javascripts/profile/profile.js.es6)0
-rw-r--r--app/assets/javascripts/project_label_subscription.js (renamed from app/assets/javascripts/project_label_subscription.js.es6)0
-rw-r--r--app/assets/javascripts/project_variables.js (renamed from app/assets/javascripts/project_variables.js.es6)0
-rw-r--r--app/assets/javascripts/projects_list.js64
-rw-r--r--app/assets/javascripts/protected_branches/protected_branch_access_dropdown.js (renamed from app/assets/javascripts/protected_branches/protected_branch_access_dropdown.js.es6)0
-rw-r--r--app/assets/javascripts/protected_branches/protected_branch_create.js (renamed from app/assets/javascripts/protected_branches/protected_branch_create.js.es6)0
-rw-r--r--app/assets/javascripts/protected_branches/protected_branch_dropdown.js (renamed from app/assets/javascripts/protected_branches/protected_branch_dropdown.js.es6)0
-rw-r--r--app/assets/javascripts/protected_branches/protected_branch_edit.js (renamed from app/assets/javascripts/protected_branches/protected_branch_edit.js.es6)0
-rw-r--r--app/assets/javascripts/protected_branches/protected_branch_edit_list.js (renamed from app/assets/javascripts/protected_branches/protected_branch_edit_list.js.es6)0
-rw-r--r--app/assets/javascripts/search_autocomplete.js (renamed from app/assets/javascripts/search_autocomplete.js.es6)0
-rw-r--r--app/assets/javascripts/shortcuts_blob.js (renamed from app/assets/javascripts/shortcuts_blob.js.es6)0
-rw-r--r--app/assets/javascripts/signin_tabs_memoizer.js (renamed from app/assets/javascripts/signin_tabs_memoizer.js.es6)0
-rw-r--r--app/assets/javascripts/smart_interval.js (renamed from app/assets/javascripts/smart_interval.js.es6)0
-rw-r--r--app/assets/javascripts/snippets_list.js (renamed from app/assets/javascripts/snippets_list.js.es6)0
-rw-r--r--app/assets/javascripts/subbable_resource.js (renamed from app/assets/javascripts/subbable_resource.js.es6)0
-rw-r--r--app/assets/javascripts/subscription.js (renamed from app/assets/javascripts/subscription.js.es6)0
-rw-r--r--app/assets/javascripts/templates/issuable_template_selector.js (renamed from app/assets/javascripts/templates/issuable_template_selector.js.es6)0
-rw-r--r--app/assets/javascripts/templates/issuable_template_selectors.js (renamed from app/assets/javascripts/templates/issuable_template_selectors.js.es6)0
-rw-r--r--app/assets/javascripts/terminal/terminal.js (renamed from app/assets/javascripts/terminal/terminal.js.es6)0
-rw-r--r--app/assets/javascripts/terminal/terminal_bundle.js (renamed from app/assets/javascripts/terminal/terminal_bundle.js.es6)0
-rw-r--r--app/assets/javascripts/todos.js (renamed from app/assets/javascripts/todos.js.es6)0
-rw-r--r--app/assets/javascripts/u2f/authenticate.js (renamed from app/assets/javascripts/u2f/authenticate.js.es6)0
-rw-r--r--app/assets/javascripts/user.js (renamed from app/assets/javascripts/user.js.es6)0
-rw-r--r--app/assets/javascripts/user_tabs.js (renamed from app/assets/javascripts/user_tabs.js.es6)0
-rw-r--r--app/assets/javascripts/username_validator.js (renamed from app/assets/javascripts/username_validator.js.es6)0
-rw-r--r--app/assets/javascripts/users/calendar.js3
-rw-r--r--app/assets/javascripts/version_check_image.js (renamed from app/assets/javascripts/version_check_image.js.es6)0
-rw-r--r--app/assets/javascripts/visibility_select.js (renamed from app/assets/javascripts/visibility_select.js.es6)0
-rw-r--r--app/assets/javascripts/vue_pipelines_index/index.js (renamed from app/assets/javascripts/vue_pipelines_index/index.js.es6)0
-rw-r--r--app/assets/javascripts/vue_pipelines_index/pipeline_actions.js (renamed from app/assets/javascripts/vue_pipelines_index/pipeline_actions.js.es6)0
-rw-r--r--app/assets/javascripts/vue_pipelines_index/pipeline_url.js (renamed from app/assets/javascripts/vue_pipelines_index/pipeline_url.js.es6)0
-rw-r--r--app/assets/javascripts/vue_pipelines_index/pipelines.js (renamed from app/assets/javascripts/vue_pipelines_index/pipelines.js.es6)0
-rw-r--r--app/assets/javascripts/vue_pipelines_index/stage.js (renamed from app/assets/javascripts/vue_pipelines_index/stage.js.es6)0
-rw-r--r--app/assets/javascripts/vue_pipelines_index/status.js (renamed from app/assets/javascripts/vue_pipelines_index/status.js.es6)0
-rw-r--r--app/assets/javascripts/vue_pipelines_index/store.js (renamed from app/assets/javascripts/vue_pipelines_index/store.js.es6)0
-rw-r--r--app/assets/javascripts/vue_pipelines_index/time_ago.js (renamed from app/assets/javascripts/vue_pipelines_index/time_ago.js.es6)0
-rw-r--r--app/assets/javascripts/vue_realtime_listener/index.js (renamed from app/assets/javascripts/vue_realtime_listener/index.js.es6)0
-rw-r--r--app/assets/javascripts/vue_shared/components/commit.js (renamed from app/assets/javascripts/vue_shared/components/commit.js.es6)0
-rw-r--r--app/assets/javascripts/vue_shared/components/pipelines_table.js (renamed from app/assets/javascripts/vue_shared/components/pipelines_table.js.es6)0
-rw-r--r--app/assets/javascripts/vue_shared/components/pipelines_table_row.js (renamed from app/assets/javascripts/vue_shared/components/pipelines_table_row.js.es6)0
-rw-r--r--app/assets/javascripts/vue_shared/components/table_pagination.js (renamed from app/assets/javascripts/vue_shared/components/table_pagination.js.es6)0
-rw-r--r--app/assets/javascripts/vue_shared/vue_resource_interceptor.js (renamed from app/assets/javascripts/vue_shared/vue_resource_interceptor.js.es6)0
-rw-r--r--app/assets/javascripts/wikis.js (renamed from app/assets/javascripts/wikis.js.es6)0
-rw-r--r--app/assets/stylesheets/framework/header.scss6
-rw-r--r--app/assets/stylesheets/framework/layout.scss13
-rw-r--r--app/assets/stylesheets/pages/merge_requests.scss8
-rw-r--r--app/assets/stylesheets/pages/search.scss6
-rw-r--r--app/controllers/admin/health_check_controller.rb2
-rw-r--r--app/controllers/admin/projects_controller.rb9
-rw-r--r--app/controllers/application_controller.rb4
-rw-r--r--app/controllers/concerns/creates_commit.rb57
-rw-r--r--app/controllers/concerns/filter_projects.rb2
-rw-r--r--app/controllers/groups_controller.rb2
-rw-r--r--app/controllers/profiles_controller.rb11
-rw-r--r--app/controllers/projects/blob_controller.rb6
-rw-r--r--app/controllers/projects/branches_controller.rb2
-rw-r--r--app/controllers/projects/commit_controller.rb32
-rw-r--r--app/controllers/projects/merge_requests_controller.rb5
-rw-r--r--app/controllers/projects/notes_controller.rb7
-rw-r--r--app/helpers/application_helper.rb2
-rw-r--r--app/helpers/explore_helper.rb9
-rw-r--r--app/helpers/mattermost_helper.rb6
-rw-r--r--app/helpers/preferences_helper.rb4
-rw-r--r--app/models/merge_request.rb5
-rw-r--r--app/models/note.rb13
-rw-r--r--app/models/project_services/kubernetes_service.rb7
-rw-r--r--app/models/repository.rb33
-rw-r--r--app/models/user.rb1
-rw-r--r--app/services/ci/retry_build_service.rb19
-rw-r--r--app/services/commits/change_service.rb52
-rw-r--r--app/services/projects/update_pages_service.rb2
-rw-r--r--app/services/system_note_service.rb1
-rw-r--r--app/views/admin/projects/_projects.html.haml32
-rw-r--r--app/views/admin/projects/index.html.haml85
-rw-r--r--app/views/dashboard/_groups_head.html.haml3
-rw-r--r--app/views/dashboard/_projects_head.html.haml3
-rw-r--r--app/views/dashboard/projects/index.html.haml5
-rw-r--r--app/views/explore/groups/_nav.html.haml8
-rw-r--r--app/views/explore/groups/index.html.haml2
-rw-r--r--app/views/explore/projects/_nav.html.haml27
-rw-r--r--app/views/explore/projects/index.html.haml7
-rw-r--r--app/views/groups/show.html.haml3
-rw-r--r--app/views/layouts/_head.html.haml4
-rw-r--r--app/views/layouts/application.html.haml2
-rw-r--r--app/views/profiles/_head.html.haml1
-rw-r--r--app/views/profiles/accounts/show.html.haml2
-rw-r--r--app/views/profiles/update_username.js.haml7
-rw-r--r--app/views/projects/boards/_show.html.haml1
-rw-r--r--app/views/projects/commit/_change.html.haml10
-rw-r--r--app/views/projects/commit/_pipelines_list.haml1
-rw-r--r--app/views/projects/cycle_analytics/show.html.haml1
-rw-r--r--app/views/projects/environments/folder.html.haml1
-rw-r--r--app/views/projects/environments/index.html.haml1
-rw-r--r--app/views/projects/graphs/charts.html.haml2
-rw-r--r--app/views/projects/graphs/show.html.haml2
-rw-r--r--app/views/projects/issues/show.html.haml2
-rw-r--r--app/views/projects/mattermosts/_team_selection.html.haml13
-rw-r--r--app/views/projects/mattermosts/new.html.haml2
-rw-r--r--app/views/projects/merge_requests/_show.html.haml1
-rw-r--r--app/views/projects/merge_requests/conflicts.html.haml2
-rw-r--r--app/views/projects/merge_requests/widget/open/_accept.html.haml10
-rw-r--r--app/views/projects/milestones/show.html.haml2
-rw-r--r--app/views/projects/notes/_notes_with_form.html.haml2
-rw-r--r--app/views/projects/pipelines/charts.html.haml2
-rw-r--r--app/views/projects/pipelines/index.html.haml1
-rw-r--r--app/views/shared/_logo.svg2
-rw-r--r--app/views/shared/groups/_search_form.html.haml2
-rw-r--r--app/views/shared/issuable/_sidebar.html.haml1
-rw-r--r--app/views/shared/milestones/_summary.html.haml27
-rw-r--r--app/views/shared/milestones/_tabs.html.haml34
-rw-r--r--app/views/shared/projects/_dropdown.html.haml20
-rw-r--r--app/views/shared/projects/_list.html.haml5
-rw-r--r--app/views/shared/projects/_search_form.html.haml23
-rw-r--r--app/views/users/show.html.haml2
-rw-r--r--changelogs/unreleased/19497-hide-relevant-info-when-project-issues-are-disabled.yml4
-rw-r--r--changelogs/unreleased/26847-api-pipelines-use-basic.yml4
-rw-r--r--changelogs/unreleased/27532_api_changes.yml4
-rw-r--r--changelogs/unreleased/28010-mr-merge-button-default-to-danger.yml4
-rw-r--r--changelogs/unreleased/28655-current-path-text-is-not-updated-after-setting-the-new-username.yml4
-rw-r--r--changelogs/unreleased/28865-filter-by-authorized-projects-in-v4.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/3440-remove-hsts-header.yml4
-rw-r--r--changelogs/unreleased/add-kube-ca-pem-file-deprecate-kube-ca-pem.yml4
-rw-r--r--changelogs/unreleased/commons-chunk-plugin.yml5
-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/dm-fix-cherry-pick.yml4
-rw-r--r--changelogs/unreleased/dz-change-project-view.yml4
-rw-r--r--changelogs/unreleased/etag-notes-polling.yml4
-rw-r--r--changelogs/unreleased/format-timeago-date.yml4
-rw-r--r--changelogs/unreleased/list_issues_with_no_labels.yml4
-rw-r--r--changelogs/unreleased/remove-es6-extension.yml4
-rw-r--r--config/application.rb1
-rw-r--r--config/initializers/8_metrics.rb (renamed from config/initializers/metrics.rb)0
-rw-r--r--config/initializers/etag_caching.rb4
-rw-r--r--config/karma.config.js13
-rw-r--r--config/routes/project.rb4
-rw-r--r--config/webpack.config.js54
-rw-r--r--db/fixtures/development/13_comments.rb4
-rw-r--r--doc/administration/reply_by_email.md56
-rw-r--r--doc/api/issues.md6
-rw-r--r--doc/api/milestones.md6
-rw-r--r--doc/api/pipelines.md40
-rw-r--r--doc/api/projects.md3
-rw-r--r--doc/api/v3_to_v4.md9
-rw-r--r--doc/development/instrumentation.md2
-rw-r--r--doc/development/limit_ee_conflicts.md5
-rw-r--r--doc/update/8.17-to-9.0.md24
-rw-r--r--doc/user/project/integrations/kubernetes.md3
-rw-r--r--doc/user/project/pages/getting_started_part_four.md3
-rw-r--r--features/steps/project/commits/revert.rb1
-rw-r--r--features/steps/project/fork.rb2
-rw-r--r--features/steps/shared/project.rb8
-rw-r--r--lib/api/api.rb2
-rw-r--r--lib/api/commits.rb2
-rw-r--r--lib/api/helpers.rb4
-rw-r--r--lib/api/milestones.rb4
-rw-r--r--lib/api/pipelines.rb4
-rw-r--r--lib/api/projects.rb3
-rw-r--r--lib/api/v3/commits.rb4
-rw-r--r--lib/api/v3/milestones.rb43
-rw-r--r--lib/api/v3/pipelines.rb36
-rw-r--r--lib/gitlab/etag_caching/middleware.rb66
-rw-r--r--lib/gitlab/etag_caching/store.rb32
-rw-r--r--lib/gitlab/seeder.rb19
-rw-r--r--lib/gitlab/sidekiq_status.rb35
-rw-r--r--lib/mattermost/team.rb2
-rw-r--r--lib/support/nginx/gitlab-ssl3
-rw-r--r--spec/controllers/health_check_controller_spec.rb4
-rw-r--r--spec/controllers/projects/branches_controller_spec.rb23
-rw-r--r--spec/controllers/projects/commit_controller_spec.rb12
-rw-r--r--spec/controllers/projects/graphs_controller_spec.rb10
-rw-r--r--spec/controllers/projects/notes_controller_spec.rb27
-rw-r--r--spec/factories/ci/builds.rb12
-rw-r--r--spec/features/commits_spec.rb2
-rw-r--r--spec/features/dashboard/archived_projects_spec.rb15
-rw-r--r--spec/features/merge_requests/merge_immediately_with_pipeline_spec.rb2
-rw-r--r--spec/features/merge_requests/widget_spec.rb67
-rw-r--r--spec/features/profile_spec.rb14
-rw-r--r--spec/features/projects/commit/cherry_pick_spec.rb1
-rw-r--r--spec/features/projects/milestones/milestone_spec.rb64
-rw-r--r--spec/features/projects/services/mattermost_slash_command_spec.rb42
-rw-r--r--spec/helpers/application_helper_spec.rb6
-rw-r--r--spec/initializers/8_metrics_spec.rb (renamed from spec/initializers/metrics_spec.rb)2
-rw-r--r--spec/javascripts/abuse_reports_spec.js (renamed from spec/javascripts/abuse_reports_spec.js.es6)0
-rw-r--r--spec/javascripts/activities_spec.js (renamed from spec/javascripts/activities_spec.js.es6)0
-rw-r--r--spec/javascripts/boards/boards_store_spec.js (renamed from spec/javascripts/boards/boards_store_spec.js.es6)0
-rw-r--r--spec/javascripts/boards/issue_card_spec.js (renamed from spec/javascripts/boards/issue_card_spec.js.es6)0
-rw-r--r--spec/javascripts/boards/issue_spec.js (renamed from spec/javascripts/boards/issue_spec.js.es6)0
-rw-r--r--spec/javascripts/boards/list_spec.js (renamed from spec/javascripts/boards/list_spec.js.es6)0
-rw-r--r--spec/javascripts/boards/mock_data.js (renamed from spec/javascripts/boards/mock_data.js.es6)0
-rw-r--r--spec/javascripts/boards/modal_store_spec.js (renamed from spec/javascripts/boards/modal_store_spec.js.es6)0
-rw-r--r--spec/javascripts/bootstrap_linked_tabs_spec.js (renamed from spec/javascripts/bootstrap_linked_tabs_spec.js.es6)0
-rw-r--r--spec/javascripts/build_spec.js (renamed from spec/javascripts/build_spec.js.es6)0
-rw-r--r--spec/javascripts/commit/pipelines/mock_data.js (renamed from spec/javascripts/commit/pipelines/mock_data.js.es6)0
-rw-r--r--spec/javascripts/commit/pipelines/pipelines_spec.js (renamed from spec/javascripts/commit/pipelines/pipelines_spec.js.es6)0
-rw-r--r--spec/javascripts/commit/pipelines/pipelines_store_spec.js (renamed from spec/javascripts/commit/pipelines/pipelines_store_spec.js.es6)0
-rw-r--r--spec/javascripts/commits_spec.js (renamed from spec/javascripts/commits_spec.js.es6)0
-rw-r--r--spec/javascripts/datetime_utility_spec.js (renamed from spec/javascripts/datetime_utility_spec.js.es6)0
-rw-r--r--spec/javascripts/diff_comments_store_spec.js (renamed from spec/javascripts/diff_comments_store_spec.js.es6)0
-rw-r--r--spec/javascripts/environments/environment_actions_spec.js (renamed from spec/javascripts/environments/environment_actions_spec.js.es6)0
-rw-r--r--spec/javascripts/environments/environment_external_url_spec.js (renamed from spec/javascripts/environments/environment_external_url_spec.js.es6)0
-rw-r--r--spec/javascripts/environments/environment_item_spec.js (renamed from spec/javascripts/environments/environment_item_spec.js.es6)0
-rw-r--r--spec/javascripts/environments/environment_rollback_spec.js (renamed from spec/javascripts/environments/environment_rollback_spec.js.es6)0
-rw-r--r--spec/javascripts/environments/environment_spec.js (renamed from spec/javascripts/environments/environment_spec.js.es6)0
-rw-r--r--spec/javascripts/environments/environment_stop_spec.js (renamed from spec/javascripts/environments/environment_stop_spec.js.es6)0
-rw-r--r--spec/javascripts/environments/environment_table_spec.js (renamed from spec/javascripts/environments/environment_table_spec.js.es6)0
-rw-r--r--spec/javascripts/environments/environments_store_spec.js (renamed from spec/javascripts/environments/environments_store_spec.js.es6)0
-rw-r--r--spec/javascripts/environments/folder/environments_folder_view_spec.js (renamed from spec/javascripts/environments/folder/environments_folder_view_spec.js.es6)0
-rw-r--r--spec/javascripts/environments/mock_data.js (renamed from spec/javascripts/environments/mock_data.js.es6)0
-rw-r--r--spec/javascripts/extensions/array_spec.js (renamed from spec/javascripts/extensions/array_spec.js.es6)0
-rw-r--r--spec/javascripts/extensions/element_spec.js (renamed from spec/javascripts/extensions/element_spec.js.es6)0
-rw-r--r--spec/javascripts/extensions/object_spec.js (renamed from spec/javascripts/extensions/object_spec.js.es6)0
-rw-r--r--spec/javascripts/filtered_search/dropdown_user_spec.js (renamed from spec/javascripts/filtered_search/dropdown_user_spec.js.es6)0
-rw-r--r--spec/javascripts/filtered_search/dropdown_utils_spec.js (renamed from spec/javascripts/filtered_search/dropdown_utils_spec.js.es6)0
-rw-r--r--spec/javascripts/filtered_search/filtered_search_dropdown_manager_spec.js (renamed from spec/javascripts/filtered_search/filtered_search_dropdown_manager_spec.js.es6)0
-rw-r--r--spec/javascripts/filtered_search/filtered_search_manager_spec.js (renamed from spec/javascripts/filtered_search/filtered_search_manager_spec.js.es6)0
-rw-r--r--spec/javascripts/filtered_search/filtered_search_token_keys_spec.js (renamed from spec/javascripts/filtered_search/filtered_search_token_keys_spec.js.es6)0
-rw-r--r--spec/javascripts/filtered_search/filtered_search_tokenizer_spec.js (renamed from spec/javascripts/filtered_search/filtered_search_tokenizer_spec.js.es6)0
-rw-r--r--spec/javascripts/gfm_auto_complete_spec.js (renamed from spec/javascripts/gfm_auto_complete_spec.js.es6)0
-rw-r--r--spec/javascripts/gl_dropdown_spec.js (renamed from spec/javascripts/gl_dropdown_spec.js.es6)0
-rw-r--r--spec/javascripts/gl_field_errors_spec.js (renamed from spec/javascripts/gl_field_errors_spec.js.es6)0
-rw-r--r--spec/javascripts/gl_form_spec.js (renamed from spec/javascripts/gl_form_spec.js.es6)0
-rw-r--r--spec/javascripts/helpers/class_spec_helper.js (renamed from spec/javascripts/helpers/class_spec_helper.js.es6)0
-rw-r--r--spec/javascripts/helpers/class_spec_helper_spec.js (renamed from spec/javascripts/helpers/class_spec_helper_spec.js.es6)0
-rw-r--r--spec/javascripts/issuable_spec.js (renamed from spec/javascripts/issuable_spec.js.es6)0
-rw-r--r--spec/javascripts/issuable_time_tracker_spec.js (renamed from spec/javascripts/issuable_time_tracker_spec.js.es6)0
-rw-r--r--spec/javascripts/labels_issue_sidebar_spec.js (renamed from spec/javascripts/labels_issue_sidebar_spec.js.es6)0
-rw-r--r--spec/javascripts/lib/utils/common_utils_spec.js (renamed from spec/javascripts/lib/utils/common_utils_spec.js.es6)0
-rw-r--r--spec/javascripts/lib/utils/text_utility_spec.js (renamed from spec/javascripts/lib/utils/text_utility_spec.js.es6)0
-rw-r--r--spec/javascripts/mini_pipeline_graph_dropdown_spec.js (renamed from spec/javascripts/mini_pipeline_graph_dropdown_spec.js.es6)0
-rw-r--r--spec/javascripts/pipelines_spec.js (renamed from spec/javascripts/pipelines_spec.js.es6)0
-rw-r--r--spec/javascripts/pretty_time_spec.js (renamed from spec/javascripts/pretty_time_spec.js.es6)0
-rw-r--r--spec/javascripts/signin_tabs_memoizer_spec.js (renamed from spec/javascripts/signin_tabs_memoizer_spec.js.es6)0
-rw-r--r--spec/javascripts/smart_interval_spec.js (renamed from spec/javascripts/smart_interval_spec.js.es6)0
-rw-r--r--spec/javascripts/subbable_resource_spec.js (renamed from spec/javascripts/subbable_resource_spec.js.es6)0
-rw-r--r--spec/javascripts/test_bundle.js13
-rw-r--r--spec/javascripts/user_callout_spec.js (renamed from spec/javascripts/user_callout_spec.js.es6)0
-rw-r--r--spec/javascripts/version_check_image_spec.js (renamed from spec/javascripts/version_check_image_spec.js.es6)0
-rw-r--r--spec/javascripts/visibility_select_spec.js (renamed from spec/javascripts/visibility_select_spec.js.es6)0
-rw-r--r--spec/javascripts/vue_shared/components/commit_spec.js (renamed from spec/javascripts/vue_shared/components/commit_spec.js.es6)0
-rw-r--r--spec/javascripts/vue_shared/components/pipelines_table_row_spec.js (renamed from spec/javascripts/vue_shared/components/pipelines_table_row_spec.js.es6)0
-rw-r--r--spec/javascripts/vue_shared/components/pipelines_table_spec.js (renamed from spec/javascripts/vue_shared/components/pipelines_table_spec.js.es6)0
-rw-r--r--spec/javascripts/vue_shared/components/table_pagination_spec.js (renamed from spec/javascripts/vue_shared/components/table_pagination_spec.js.es6)0
-rw-r--r--spec/lib/gitlab/etag_caching/middleware_spec.rb163
-rw-r--r--spec/lib/gitlab/sidekiq_status_spec.rb26
-rw-r--r--spec/lib/mattermost/team_spec.rb6
-rw-r--r--spec/models/note_spec.rb12
-rw-r--r--spec/models/project_services/kubernetes_service_spec.rb6
-rw-r--r--spec/models/project_services/mattermost_slash_commands_service_spec.rb2
-rw-r--r--spec/models/repository_spec.rb16
-rw-r--r--spec/requests/api/milestones_spec.rb43
-rw-r--r--spec/requests/api/pipelines_spec.rb1
-rw-r--r--spec/requests/api/projects_spec.rb69
-rw-r--r--spec/requests/api/v3/milestones_spec.rb232
-rw-r--r--spec/requests/api/v3/pipelines_spec.rb203
-rw-r--r--spec/routing/project_routing_spec.rb18
-rw-r--r--spec/services/ci/retry_build_service_spec.rb47
-rw-r--r--spec/services/projects/update_pages_service_spec.rb22
-rw-r--r--spec/services/system_note_service_spec.rb39
415 files changed, 2117 insertions, 707 deletions
diff --git a/.eslintrc b/.eslintrc
index 0fcd866778f..b0ae2a31919 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -23,7 +23,7 @@
}
},
"rules": {
- "filenames/match-regex": [2, "^[a-z0-9_]+(.js)?$"],
+ "filenames/match-regex": [2, "^[a-z0-9_]+$"],
"no-multiple-empty-lines": ["error", { "max": 1 }]
}
}
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 9006fef6a27..deeb01f9a3c 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -421,6 +421,7 @@ pages:
- public
only:
- master@gitlab-org/gitlab-ce
+ - master@gitlab-org/gitlab-ee
# Insurance in case a gem needed by one of our releases gets yanked from
# rubygems.org in the future.
@@ -437,3 +438,4 @@ cache gems:
- vendor/cache
only:
- master@gitlab-org/gitlab-ce
+ - master@gitlab-org/gitlab-ee
diff --git a/Gemfile b/Gemfile
index b21f563940d..a267030eb4c 100644
--- a/Gemfile
+++ b/Gemfile
@@ -344,7 +344,7 @@ gem 'oauth2', '~> 1.2.0'
gem 'paranoia', '~> 2.2'
# Health check
-gem 'health_check', '~> 2.2.0'
+gem 'health_check', '~> 2.6.0'
# System information
gem 'vmstat', '~> 2.3.0'
diff --git a/Gemfile.lock b/Gemfile.lock
index 2d7e6f6f0bf..65120df205c 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -336,7 +336,7 @@ GEM
thor
tilt
hashie (3.5.5)
- health_check (2.2.1)
+ health_check (2.6.0)
rails (>= 4.0)
hipchat (1.5.2)
httparty
@@ -895,7 +895,7 @@ DEPENDENCIES
grape-entity (~> 0.6.0)
haml_lint (~> 0.21.0)
hamlit (~> 2.6.1)
- health_check (~> 2.2.0)
+ health_check (~> 2.6.0)
hipchat (~> 1.5.0)
html-pipeline (~> 1.11.0)
html2text
diff --git a/app/assets/javascripts/abuse_reports.js.es6 b/app/assets/javascripts/abuse_reports.js
index 8a260aae1b1..8a260aae1b1 100644
--- a/app/assets/javascripts/abuse_reports.js.es6
+++ b/app/assets/javascripts/abuse_reports.js
diff --git a/app/assets/javascripts/activities.js.es6 b/app/assets/javascripts/activities.js
index 648cb4d5d85..648cb4d5d85 100644
--- a/app/assets/javascripts/activities.js.es6
+++ b/app/assets/javascripts/activities.js
diff --git a/app/assets/javascripts/blob/blob_ci_yaml.js.es6 b/app/assets/javascripts/blob/blob_ci_yaml.js
index ec1c018424d..ec1c018424d 100644
--- a/app/assets/javascripts/blob/blob_ci_yaml.js.es6
+++ b/app/assets/javascripts/blob/blob_ci_yaml.js
diff --git a/app/assets/javascripts/blob/blob_dockerfile_selector.js.es6 b/app/assets/javascripts/blob/blob_dockerfile_selector.js
index d4f60cc6ecd..d4f60cc6ecd 100644
--- a/app/assets/javascripts/blob/blob_dockerfile_selector.js.es6
+++ b/app/assets/javascripts/blob/blob_dockerfile_selector.js
diff --git a/app/assets/javascripts/blob/blob_dockerfile_selectors.js.es6 b/app/assets/javascripts/blob/blob_dockerfile_selectors.js
index 9cee79fa5d5..9cee79fa5d5 100644
--- a/app/assets/javascripts/blob/blob_dockerfile_selectors.js.es6
+++ b/app/assets/javascripts/blob/blob_dockerfile_selectors.js
diff --git a/app/assets/javascripts/blob/blob_license_selectors.js.es6 b/app/assets/javascripts/blob/blob_license_selectors.js
index c5067b0feae..c5067b0feae 100644
--- a/app/assets/javascripts/blob/blob_license_selectors.js.es6
+++ b/app/assets/javascripts/blob/blob_license_selectors.js
diff --git a/app/assets/javascripts/blob/template_selector.js.es6 b/app/assets/javascripts/blob/template_selector.js
index 7e03ec3b391..7e03ec3b391 100644
--- a/app/assets/javascripts/blob/template_selector.js.es6
+++ b/app/assets/javascripts/blob/template_selector.js
diff --git a/app/assets/javascripts/boards/boards_bundle.js.es6 b/app/assets/javascripts/boards/boards_bundle.js
index 55d13be6e5f..55d13be6e5f 100644
--- a/app/assets/javascripts/boards/boards_bundle.js.es6
+++ b/app/assets/javascripts/boards/boards_bundle.js
diff --git a/app/assets/javascripts/boards/components/board.js.es6 b/app/assets/javascripts/boards/components/board.js
index 18324de18b3..18324de18b3 100644
--- a/app/assets/javascripts/boards/components/board.js.es6
+++ b/app/assets/javascripts/boards/components/board.js
diff --git a/app/assets/javascripts/boards/components/board_blank_state.js.es6 b/app/assets/javascripts/boards/components/board_blank_state.js
index d76314c1892..d76314c1892 100644
--- a/app/assets/javascripts/boards/components/board_blank_state.js.es6
+++ b/app/assets/javascripts/boards/components/board_blank_state.js
diff --git a/app/assets/javascripts/boards/components/board_delete.js.es6 b/app/assets/javascripts/boards/components/board_delete.js
index 861600424a5..861600424a5 100644
--- a/app/assets/javascripts/boards/components/board_delete.js.es6
+++ b/app/assets/javascripts/boards/components/board_delete.js
diff --git a/app/assets/javascripts/boards/components/board_list.js.es6 b/app/assets/javascripts/boards/components/board_list.js
index 2d52e96e7fb..2d52e96e7fb 100644
--- a/app/assets/javascripts/boards/components/board_list.js.es6
+++ b/app/assets/javascripts/boards/components/board_list.js
diff --git a/app/assets/javascripts/boards/components/board_sidebar.js.es6 b/app/assets/javascripts/boards/components/board_sidebar.js
index dfc6eed785c..dfc6eed785c 100644
--- a/app/assets/javascripts/boards/components/board_sidebar.js.es6
+++ b/app/assets/javascripts/boards/components/board_sidebar.js
diff --git a/app/assets/javascripts/boards/components/issue_card_inner.js.es6 b/app/assets/javascripts/boards/components/issue_card_inner.js
index 22a8b971ff8..22a8b971ff8 100644
--- a/app/assets/javascripts/boards/components/issue_card_inner.js.es6
+++ b/app/assets/javascripts/boards/components/issue_card_inner.js
diff --git a/app/assets/javascripts/boards/components/modal/empty_state.js.es6 b/app/assets/javascripts/boards/components/modal/empty_state.js
index 9538f5b69e9..9538f5b69e9 100644
--- a/app/assets/javascripts/boards/components/modal/empty_state.js.es6
+++ b/app/assets/javascripts/boards/components/modal/empty_state.js
diff --git a/app/assets/javascripts/boards/components/modal/filters.js.es6 b/app/assets/javascripts/boards/components/modal/filters.js
index 6de06811d94..6de06811d94 100644
--- a/app/assets/javascripts/boards/components/modal/filters.js.es6
+++ b/app/assets/javascripts/boards/components/modal/filters.js
diff --git a/app/assets/javascripts/boards/components/modal/filters/label.js.es6 b/app/assets/javascripts/boards/components/modal/filters/label.js
index 4fc8f72a145..4fc8f72a145 100644
--- a/app/assets/javascripts/boards/components/modal/filters/label.js.es6
+++ b/app/assets/javascripts/boards/components/modal/filters/label.js
diff --git a/app/assets/javascripts/boards/components/modal/filters/milestone.js.es6 b/app/assets/javascripts/boards/components/modal/filters/milestone.js
index d555599d300..d555599d300 100644
--- a/app/assets/javascripts/boards/components/modal/filters/milestone.js.es6
+++ b/app/assets/javascripts/boards/components/modal/filters/milestone.js
diff --git a/app/assets/javascripts/boards/components/modal/filters/user.js.es6 b/app/assets/javascripts/boards/components/modal/filters/user.js
index 8523028c29c..8523028c29c 100644
--- a/app/assets/javascripts/boards/components/modal/filters/user.js.es6
+++ b/app/assets/javascripts/boards/components/modal/filters/user.js
diff --git a/app/assets/javascripts/boards/components/modal/footer.js.es6 b/app/assets/javascripts/boards/components/modal/footer.js
index 1cbc422c961..1cbc422c961 100644
--- a/app/assets/javascripts/boards/components/modal/footer.js.es6
+++ b/app/assets/javascripts/boards/components/modal/footer.js
diff --git a/app/assets/javascripts/boards/components/modal/header.js.es6 b/app/assets/javascripts/boards/components/modal/header.js
index 70c088f9054..70c088f9054 100644
--- a/app/assets/javascripts/boards/components/modal/header.js.es6
+++ b/app/assets/javascripts/boards/components/modal/header.js
diff --git a/app/assets/javascripts/boards/components/modal/index.js.es6 b/app/assets/javascripts/boards/components/modal/index.js
index f290cd13763..f290cd13763 100644
--- a/app/assets/javascripts/boards/components/modal/index.js.es6
+++ b/app/assets/javascripts/boards/components/modal/index.js
diff --git a/app/assets/javascripts/boards/components/modal/list.js.es6 b/app/assets/javascripts/boards/components/modal/list.js
index 3730c1ecaeb..3730c1ecaeb 100644
--- a/app/assets/javascripts/boards/components/modal/list.js.es6
+++ b/app/assets/javascripts/boards/components/modal/list.js
diff --git a/app/assets/javascripts/boards/components/modal/lists_dropdown.js.es6 b/app/assets/javascripts/boards/components/modal/lists_dropdown.js
index 3c05120a2da..3c05120a2da 100644
--- a/app/assets/javascripts/boards/components/modal/lists_dropdown.js.es6
+++ b/app/assets/javascripts/boards/components/modal/lists_dropdown.js
diff --git a/app/assets/javascripts/boards/components/modal/tabs.js.es6 b/app/assets/javascripts/boards/components/modal/tabs.js
index e8cb43f3503..e8cb43f3503 100644
--- a/app/assets/javascripts/boards/components/modal/tabs.js.es6
+++ b/app/assets/javascripts/boards/components/modal/tabs.js
diff --git a/app/assets/javascripts/boards/components/new_list_dropdown.js.es6 b/app/assets/javascripts/boards/components/new_list_dropdown.js
index 556826a9148..556826a9148 100644
--- a/app/assets/javascripts/boards/components/new_list_dropdown.js.es6
+++ b/app/assets/javascripts/boards/components/new_list_dropdown.js
diff --git a/app/assets/javascripts/boards/components/sidebar/remove_issue.js.es6 b/app/assets/javascripts/boards/components/sidebar/remove_issue.js
index e74935e1cb0..e74935e1cb0 100644
--- a/app/assets/javascripts/boards/components/sidebar/remove_issue.js.es6
+++ b/app/assets/javascripts/boards/components/sidebar/remove_issue.js
diff --git a/app/assets/javascripts/boards/filters/due_date_filters.js.es6 b/app/assets/javascripts/boards/filters/due_date_filters.js
index 03425bb145b..03425bb145b 100644
--- a/app/assets/javascripts/boards/filters/due_date_filters.js.es6
+++ b/app/assets/javascripts/boards/filters/due_date_filters.js
diff --git a/app/assets/javascripts/boards/mixins/modal_mixins.js.es6 b/app/assets/javascripts/boards/mixins/modal_mixins.js
index d378b7d4baf..d378b7d4baf 100644
--- a/app/assets/javascripts/boards/mixins/modal_mixins.js.es6
+++ b/app/assets/javascripts/boards/mixins/modal_mixins.js
diff --git a/app/assets/javascripts/boards/mixins/sortable_default_options.js.es6 b/app/assets/javascripts/boards/mixins/sortable_default_options.js
index b6c6d17274f..b6c6d17274f 100644
--- a/app/assets/javascripts/boards/mixins/sortable_default_options.js.es6
+++ b/app/assets/javascripts/boards/mixins/sortable_default_options.js
diff --git a/app/assets/javascripts/boards/models/issue.js.es6 b/app/assets/javascripts/boards/models/issue.js
index 2d0a295ae4d..2d0a295ae4d 100644
--- a/app/assets/javascripts/boards/models/issue.js.es6
+++ b/app/assets/javascripts/boards/models/issue.js
diff --git a/app/assets/javascripts/boards/models/label.js.es6 b/app/assets/javascripts/boards/models/label.js
index 9af88d167d6..9af88d167d6 100644
--- a/app/assets/javascripts/boards/models/label.js.es6
+++ b/app/assets/javascripts/boards/models/label.js
diff --git a/app/assets/javascripts/boards/models/list.js.es6 b/app/assets/javascripts/boards/models/list.js
index 8158ed4ec2c..8158ed4ec2c 100644
--- a/app/assets/javascripts/boards/models/list.js.es6
+++ b/app/assets/javascripts/boards/models/list.js
diff --git a/app/assets/javascripts/boards/models/milestone.js.es6 b/app/assets/javascripts/boards/models/milestone.js
index c867b06d320..c867b06d320 100644
--- a/app/assets/javascripts/boards/models/milestone.js.es6
+++ b/app/assets/javascripts/boards/models/milestone.js
diff --git a/app/assets/javascripts/boards/models/user.js.es6 b/app/assets/javascripts/boards/models/user.js
index 8e9de4d4cbb..8e9de4d4cbb 100644
--- a/app/assets/javascripts/boards/models/user.js.es6
+++ b/app/assets/javascripts/boards/models/user.js
diff --git a/app/assets/javascripts/boards/services/board_service.js.es6 b/app/assets/javascripts/boards/services/board_service.js
index 065e90518df..065e90518df 100644
--- a/app/assets/javascripts/boards/services/board_service.js.es6
+++ b/app/assets/javascripts/boards/services/board_service.js
diff --git a/app/assets/javascripts/boards/stores/boards_store.js.es6 b/app/assets/javascripts/boards/stores/boards_store.js
index 56436c8fdc7..56436c8fdc7 100644
--- a/app/assets/javascripts/boards/stores/boards_store.js.es6
+++ b/app/assets/javascripts/boards/stores/boards_store.js
diff --git a/app/assets/javascripts/boards/stores/modal_store.js.es6 b/app/assets/javascripts/boards/stores/modal_store.js
index 15fc6c79e8d..15fc6c79e8d 100644
--- a/app/assets/javascripts/boards/stores/modal_store.js.es6
+++ b/app/assets/javascripts/boards/stores/modal_store.js
diff --git a/app/assets/javascripts/build_variables.js.es6 b/app/assets/javascripts/build_variables.js
index 99082b412e2..99082b412e2 100644
--- a/app/assets/javascripts/build_variables.js.es6
+++ b/app/assets/javascripts/build_variables.js
diff --git a/app/assets/javascripts/ci_lint_editor.js.es6 b/app/assets/javascripts/ci_lint_editor.js
index 56ffaa765a8..56ffaa765a8 100644
--- a/app/assets/javascripts/ci_lint_editor.js.es6
+++ b/app/assets/javascripts/ci_lint_editor.js
diff --git a/app/assets/javascripts/commit/pipelines/pipelines_bundle.js.es6 b/app/assets/javascripts/commit/pipelines/pipelines_bundle.js
index b5a988df897..b5a988df897 100644
--- a/app/assets/javascripts/commit/pipelines/pipelines_bundle.js.es6
+++ b/app/assets/javascripts/commit/pipelines/pipelines_bundle.js
diff --git a/app/assets/javascripts/commit/pipelines/pipelines_service.js.es6 b/app/assets/javascripts/commit/pipelines/pipelines_service.js
index 8ae98f9bf97..8ae98f9bf97 100644
--- a/app/assets/javascripts/commit/pipelines/pipelines_service.js.es6
+++ b/app/assets/javascripts/commit/pipelines/pipelines_service.js
diff --git a/app/assets/javascripts/commit/pipelines/pipelines_store.js.es6 b/app/assets/javascripts/commit/pipelines/pipelines_store.js
index f1b80e45444..f1b80e45444 100644
--- a/app/assets/javascripts/commit/pipelines/pipelines_store.js.es6
+++ b/app/assets/javascripts/commit/pipelines/pipelines_store.js
diff --git a/app/assets/javascripts/commit/pipelines/pipelines_table.js.es6 b/app/assets/javascripts/commit/pipelines/pipelines_table.js
index 631ed34851c..631ed34851c 100644
--- a/app/assets/javascripts/commit/pipelines/pipelines_table.js.es6
+++ b/app/assets/javascripts/commit/pipelines/pipelines_table.js
diff --git a/app/assets/javascripts/commons/bootstrap.js b/app/assets/javascripts/commons/bootstrap.js
new file mode 100644
index 00000000000..db0cbfd87c3
--- /dev/null
+++ b/app/assets/javascripts/commons/bootstrap.js
@@ -0,0 +1,10 @@
+import 'jquery';
+
+// bootstrap jQuery plugins
+import 'bootstrap-sass/assets/javascripts/bootstrap/affix';
+import 'bootstrap-sass/assets/javascripts/bootstrap/alert';
+import 'bootstrap-sass/assets/javascripts/bootstrap/dropdown';
+import 'bootstrap-sass/assets/javascripts/bootstrap/modal';
+import 'bootstrap-sass/assets/javascripts/bootstrap/tab';
+import 'bootstrap-sass/assets/javascripts/bootstrap/transition';
+import 'bootstrap-sass/assets/javascripts/bootstrap/tooltip';
diff --git a/app/assets/javascripts/commons/index.js b/app/assets/javascripts/commons/index.js
new file mode 100644
index 00000000000..72ede1d621a
--- /dev/null
+++ b/app/assets/javascripts/commons/index.js
@@ -0,0 +1,2 @@
+import './jquery';
+import './bootstrap';
diff --git a/app/assets/javascripts/commons/jquery.js b/app/assets/javascripts/commons/jquery.js
new file mode 100644
index 00000000000..b53f6284afc
--- /dev/null
+++ b/app/assets/javascripts/commons/jquery.js
@@ -0,0 +1,11 @@
+import 'jquery';
+
+// common jQuery plugins
+import 'jquery-ujs';
+import 'vendor/jquery.endless-scroll';
+import 'vendor/jquery.caret';
+import 'vendor/jquery.atwho';
+import 'vendor/jquery.scrollTo';
+import 'vendor/jquery.nicescroll';
+import 'vendor/jquery.waitforimages';
+import 'select2/select2';
diff --git a/app/assets/javascripts/compare_autocomplete.js.es6 b/app/assets/javascripts/compare_autocomplete.js
index 1eca973e069..1eca973e069 100644
--- a/app/assets/javascripts/compare_autocomplete.js.es6
+++ b/app/assets/javascripts/compare_autocomplete.js
diff --git a/app/assets/javascripts/copy_as_gfm.js.es6 b/app/assets/javascripts/copy_as_gfm.js
index 2bc3d85fba4..2bc3d85fba4 100644
--- a/app/assets/javascripts/copy_as_gfm.js.es6
+++ b/app/assets/javascripts/copy_as_gfm.js
diff --git a/app/assets/javascripts/create_label.js.es6 b/app/assets/javascripts/create_label.js
index 85384d98126..85384d98126 100644
--- a/app/assets/javascripts/create_label.js.es6
+++ b/app/assets/javascripts/create_label.js
diff --git a/app/assets/javascripts/cycle_analytics/components/stage_code_component.js.es6 b/app/assets/javascripts/cycle_analytics/components/stage_code_component.js
index b83a4c63fad..b83a4c63fad 100644
--- a/app/assets/javascripts/cycle_analytics/components/stage_code_component.js.es6
+++ b/app/assets/javascripts/cycle_analytics/components/stage_code_component.js
diff --git a/app/assets/javascripts/cycle_analytics/components/stage_issue_component.js.es6 b/app/assets/javascripts/cycle_analytics/components/stage_issue_component.js
index cb1687dcc7a..cb1687dcc7a 100644
--- a/app/assets/javascripts/cycle_analytics/components/stage_issue_component.js.es6
+++ b/app/assets/javascripts/cycle_analytics/components/stage_issue_component.js
diff --git a/app/assets/javascripts/cycle_analytics/components/stage_plan_component.js.es6 b/app/assets/javascripts/cycle_analytics/components/stage_plan_component.js
index 42e1bbce744..42e1bbce744 100644
--- a/app/assets/javascripts/cycle_analytics/components/stage_plan_component.js.es6
+++ b/app/assets/javascripts/cycle_analytics/components/stage_plan_component.js
diff --git a/app/assets/javascripts/cycle_analytics/components/stage_production_component.js.es6 b/app/assets/javascripts/cycle_analytics/components/stage_production_component.js
index 73f4205b578..73f4205b578 100644
--- a/app/assets/javascripts/cycle_analytics/components/stage_production_component.js.es6
+++ b/app/assets/javascripts/cycle_analytics/components/stage_production_component.js
diff --git a/app/assets/javascripts/cycle_analytics/components/stage_review_component.js.es6 b/app/assets/javascripts/cycle_analytics/components/stage_review_component.js
index 501ffb1fac9..501ffb1fac9 100644
--- a/app/assets/javascripts/cycle_analytics/components/stage_review_component.js.es6
+++ b/app/assets/javascripts/cycle_analytics/components/stage_review_component.js
diff --git a/app/assets/javascripts/cycle_analytics/components/stage_staging_component.js.es6 b/app/assets/javascripts/cycle_analytics/components/stage_staging_component.js
index 8fa63734cf1..8fa63734cf1 100644
--- a/app/assets/javascripts/cycle_analytics/components/stage_staging_component.js.es6
+++ b/app/assets/javascripts/cycle_analytics/components/stage_staging_component.js
diff --git a/app/assets/javascripts/cycle_analytics/components/stage_test_component.js.es6 b/app/assets/javascripts/cycle_analytics/components/stage_test_component.js
index 0015249cfaa..0015249cfaa 100644
--- a/app/assets/javascripts/cycle_analytics/components/stage_test_component.js.es6
+++ b/app/assets/javascripts/cycle_analytics/components/stage_test_component.js
diff --git a/app/assets/javascripts/cycle_analytics/components/total_time_component.js.es6 b/app/assets/javascripts/cycle_analytics/components/total_time_component.js
index 0d85e1a4678..0d85e1a4678 100644
--- a/app/assets/javascripts/cycle_analytics/components/total_time_component.js.es6
+++ b/app/assets/javascripts/cycle_analytics/components/total_time_component.js
diff --git a/app/assets/javascripts/cycle_analytics/cycle_analytics_bundle.js.es6 b/app/assets/javascripts/cycle_analytics/cycle_analytics_bundle.js
index beff293b587..beff293b587 100644
--- a/app/assets/javascripts/cycle_analytics/cycle_analytics_bundle.js.es6
+++ b/app/assets/javascripts/cycle_analytics/cycle_analytics_bundle.js
diff --git a/app/assets/javascripts/cycle_analytics/cycle_analytics_service.js.es6 b/app/assets/javascripts/cycle_analytics/cycle_analytics_service.js
index 9f74b14c4b9..9f74b14c4b9 100644
--- a/app/assets/javascripts/cycle_analytics/cycle_analytics_service.js.es6
+++ b/app/assets/javascripts/cycle_analytics/cycle_analytics_service.js
diff --git a/app/assets/javascripts/cycle_analytics/cycle_analytics_store.js.es6 b/app/assets/javascripts/cycle_analytics/cycle_analytics_store.js
index 7ae9de7297c..7ae9de7297c 100644
--- a/app/assets/javascripts/cycle_analytics/cycle_analytics_store.js.es6
+++ b/app/assets/javascripts/cycle_analytics/cycle_analytics_store.js
diff --git a/app/assets/javascripts/cycle_analytics/default_event_objects.js.es6 b/app/assets/javascripts/cycle_analytics/default_event_objects.js
index cfaf9835bf8..cfaf9835bf8 100644
--- a/app/assets/javascripts/cycle_analytics/default_event_objects.js.es6
+++ b/app/assets/javascripts/cycle_analytics/default_event_objects.js
diff --git a/app/assets/javascripts/diff.js.es6 b/app/assets/javascripts/diff.js
index 6829e8aeaea..6829e8aeaea 100644
--- a/app/assets/javascripts/diff.js.es6
+++ b/app/assets/javascripts/diff.js
diff --git a/app/assets/javascripts/diff_notes/components/comment_resolve_btn.js.es6 b/app/assets/javascripts/diff_notes/components/comment_resolve_btn.js
index d948dff58ec..d948dff58ec 100644
--- a/app/assets/javascripts/diff_notes/components/comment_resolve_btn.js.es6
+++ b/app/assets/javascripts/diff_notes/components/comment_resolve_btn.js
diff --git a/app/assets/javascripts/diff_notes/components/jump_to_discussion.js.es6 b/app/assets/javascripts/diff_notes/components/jump_to_discussion.js
index 283dc330cad..283dc330cad 100644
--- a/app/assets/javascripts/diff_notes/components/jump_to_discussion.js.es6
+++ b/app/assets/javascripts/diff_notes/components/jump_to_discussion.js
diff --git a/app/assets/javascripts/diff_notes/components/resolve_btn.js.es6 b/app/assets/javascripts/diff_notes/components/resolve_btn.js
index d1873d6c7a2..d1873d6c7a2 100644
--- a/app/assets/javascripts/diff_notes/components/resolve_btn.js.es6
+++ b/app/assets/javascripts/diff_notes/components/resolve_btn.js
diff --git a/app/assets/javascripts/diff_notes/components/resolve_count.js.es6 b/app/assets/javascripts/diff_notes/components/resolve_count.js
index de9367f2136..de9367f2136 100644
--- a/app/assets/javascripts/diff_notes/components/resolve_count.js.es6
+++ b/app/assets/javascripts/diff_notes/components/resolve_count.js
diff --git a/app/assets/javascripts/diff_notes/components/resolve_discussion_btn.js.es6 b/app/assets/javascripts/diff_notes/components/resolve_discussion_btn.js
index 7c5fcd04d2d..7c5fcd04d2d 100644
--- a/app/assets/javascripts/diff_notes/components/resolve_discussion_btn.js.es6
+++ b/app/assets/javascripts/diff_notes/components/resolve_discussion_btn.js
diff --git a/app/assets/javascripts/diff_notes/diff_notes_bundle.js.es6 b/app/assets/javascripts/diff_notes/diff_notes_bundle.js
index cadf8b96b87..cadf8b96b87 100644
--- a/app/assets/javascripts/diff_notes/diff_notes_bundle.js.es6
+++ b/app/assets/javascripts/diff_notes/diff_notes_bundle.js
diff --git a/app/assets/javascripts/diff_notes/mixins/discussion.js.es6 b/app/assets/javascripts/diff_notes/mixins/discussion.js
index 3c08c222f46..3c08c222f46 100644
--- a/app/assets/javascripts/diff_notes/mixins/discussion.js.es6
+++ b/app/assets/javascripts/diff_notes/mixins/discussion.js
diff --git a/app/assets/javascripts/diff_notes/models/discussion.js.es6 b/app/assets/javascripts/diff_notes/models/discussion.js
index fa518ba4d33..fa518ba4d33 100644
--- a/app/assets/javascripts/diff_notes/models/discussion.js.es6
+++ b/app/assets/javascripts/diff_notes/models/discussion.js
diff --git a/app/assets/javascripts/diff_notes/models/note.js.es6 b/app/assets/javascripts/diff_notes/models/note.js
index f3a7cba5ef6..f3a7cba5ef6 100644
--- a/app/assets/javascripts/diff_notes/models/note.js.es6
+++ b/app/assets/javascripts/diff_notes/models/note.js
diff --git a/app/assets/javascripts/diff_notes/services/resolve.js.es6 b/app/assets/javascripts/diff_notes/services/resolve.js
index 090c454e9e4..090c454e9e4 100644
--- a/app/assets/javascripts/diff_notes/services/resolve.js.es6
+++ b/app/assets/javascripts/diff_notes/services/resolve.js
diff --git a/app/assets/javascripts/diff_notes/stores/comments.js.es6 b/app/assets/javascripts/diff_notes/stores/comments.js
index c80d979b977..c80d979b977 100644
--- a/app/assets/javascripts/diff_notes/stores/comments.js.es6
+++ b/app/assets/javascripts/diff_notes/stores/comments.js
diff --git a/app/assets/javascripts/dispatcher.js.es6 b/app/assets/javascripts/dispatcher.js
index fc25122aedc..ef5785b5532 100644
--- a/app/assets/javascripts/dispatcher.js.es6
+++ b/app/assets/javascripts/dispatcher.js
@@ -36,6 +36,7 @@
/* global Shortcuts */
import GroupsList from './groups_list';
+import ProjectsList from './projects_list';
const ShortcutsBlob = require('./shortcuts_blob');
const UserCallout = require('./user_callout');
@@ -98,6 +99,14 @@ const UserCallout = require('./user_callout');
case 'dashboard:todos:index':
new gl.Todos();
break;
+ case 'dashboard:projects:index':
+ case 'dashboard:projects:starred':
+ case 'explore:projects:index':
+ case 'explore:projects:trending':
+ case 'explore:projects:starred':
+ case 'admin:projects:index':
+ new ProjectsList();
+ break;
case 'dashboard:groups:index':
case 'explore:groups:index':
new GroupsList();
@@ -163,9 +172,6 @@ const UserCallout = require('./user_callout');
case 'dashboard:activity':
new gl.Activities();
break;
- case 'dashboard:projects:starred':
- new gl.Activities();
- break;
case 'projects:commit:show':
new Commit();
new gl.Diff();
@@ -208,6 +214,7 @@ const UserCallout = require('./user_callout');
shortcut_handler = new ShortcutsNavigation();
new NotificationsForm();
new NotificationsDropdown();
+ new ProjectsList();
break;
case 'groups:group_members:index':
new gl.MemberExpirationDate();
diff --git a/app/assets/javascripts/due_date_select.js.es6 b/app/assets/javascripts/due_date_select.js
index 9169fcd7328..9169fcd7328 100644
--- a/app/assets/javascripts/due_date_select.js.es6
+++ b/app/assets/javascripts/due_date_select.js
diff --git a/app/assets/javascripts/environments/components/environment.js.es6 b/app/assets/javascripts/environments/components/environment.js
index 2cb48dde628..2cb48dde628 100644
--- a/app/assets/javascripts/environments/components/environment.js.es6
+++ b/app/assets/javascripts/environments/components/environment.js
diff --git a/app/assets/javascripts/environments/components/environment_actions.js.es6 b/app/assets/javascripts/environments/components/environment_actions.js
index 15e3f8823d2..15e3f8823d2 100644
--- a/app/assets/javascripts/environments/components/environment_actions.js.es6
+++ b/app/assets/javascripts/environments/components/environment_actions.js
diff --git a/app/assets/javascripts/environments/components/environment_external_url.js.es6 b/app/assets/javascripts/environments/components/environment_external_url.js
index 2599bba3c59..2599bba3c59 100644
--- a/app/assets/javascripts/environments/components/environment_external_url.js.es6
+++ b/app/assets/javascripts/environments/components/environment_external_url.js
diff --git a/app/assets/javascripts/environments/components/environment_item.js.es6 b/app/assets/javascripts/environments/components/environment_item.js
index 7f4e070b229..7f4e070b229 100644
--- a/app/assets/javascripts/environments/components/environment_item.js.es6
+++ b/app/assets/javascripts/environments/components/environment_item.js
diff --git a/app/assets/javascripts/environments/components/environment_rollback.js.es6 b/app/assets/javascripts/environments/components/environment_rollback.js
index daf126eb4e8..daf126eb4e8 100644
--- a/app/assets/javascripts/environments/components/environment_rollback.js.es6
+++ b/app/assets/javascripts/environments/components/environment_rollback.js
diff --git a/app/assets/javascripts/environments/components/environment_stop.js.es6 b/app/assets/javascripts/environments/components/environment_stop.js
index 96983a19568..96983a19568 100644
--- a/app/assets/javascripts/environments/components/environment_stop.js.es6
+++ b/app/assets/javascripts/environments/components/environment_stop.js
diff --git a/app/assets/javascripts/environments/components/environment_terminal_button.js.es6 b/app/assets/javascripts/environments/components/environment_terminal_button.js
index e86607e78f4..e86607e78f4 100644
--- a/app/assets/javascripts/environments/components/environment_terminal_button.js.es6
+++ b/app/assets/javascripts/environments/components/environment_terminal_button.js
diff --git a/app/assets/javascripts/environments/components/environments_table.js.es6 b/app/assets/javascripts/environments/components/environments_table.js
index 4088d63be80..4088d63be80 100644
--- a/app/assets/javascripts/environments/components/environments_table.js.es6
+++ b/app/assets/javascripts/environments/components/environments_table.js
diff --git a/app/assets/javascripts/environments/environments_bundle.js.es6 b/app/assets/javascripts/environments/environments_bundle.js
index 7bbba91bc10..7bbba91bc10 100644
--- a/app/assets/javascripts/environments/environments_bundle.js.es6
+++ b/app/assets/javascripts/environments/environments_bundle.js
diff --git a/app/assets/javascripts/environments/folder/environments_folder_bundle.js.es6 b/app/assets/javascripts/environments/folder/environments_folder_bundle.js
index d2ca465351a..d2ca465351a 100644
--- a/app/assets/javascripts/environments/folder/environments_folder_bundle.js.es6
+++ b/app/assets/javascripts/environments/folder/environments_folder_bundle.js
diff --git a/app/assets/javascripts/environments/folder/environments_folder_view.js.es6 b/app/assets/javascripts/environments/folder/environments_folder_view.js
index 2a9d0492d7a..2a9d0492d7a 100644
--- a/app/assets/javascripts/environments/folder/environments_folder_view.js.es6
+++ b/app/assets/javascripts/environments/folder/environments_folder_view.js
diff --git a/app/assets/javascripts/environments/services/environments_service.js.es6 b/app/assets/javascripts/environments/services/environments_service.js
index effc6c4c838..effc6c4c838 100644
--- a/app/assets/javascripts/environments/services/environments_service.js.es6
+++ b/app/assets/javascripts/environments/services/environments_service.js
diff --git a/app/assets/javascripts/environments/stores/environments_store.js.es6 b/app/assets/javascripts/environments/stores/environments_store.js
index 15cd9bde08e..15cd9bde08e 100644
--- a/app/assets/javascripts/environments/stores/environments_store.js.es6
+++ b/app/assets/javascripts/environments/stores/environments_store.js
diff --git a/app/assets/javascripts/extensions/array.js.es6 b/app/assets/javascripts/extensions/array.js
index f8256a8d26d..f8256a8d26d 100644
--- a/app/assets/javascripts/extensions/array.js.es6
+++ b/app/assets/javascripts/extensions/array.js
diff --git a/app/assets/javascripts/extensions/custom_event.js.es6 b/app/assets/javascripts/extensions/custom_event.js
index abedae4c1c7..abedae4c1c7 100644
--- a/app/assets/javascripts/extensions/custom_event.js.es6
+++ b/app/assets/javascripts/extensions/custom_event.js
diff --git a/app/assets/javascripts/extensions/element.js.es6 b/app/assets/javascripts/extensions/element.js
index 90ab79305a7..90ab79305a7 100644
--- a/app/assets/javascripts/extensions/element.js.es6
+++ b/app/assets/javascripts/extensions/element.js
diff --git a/app/assets/javascripts/extensions/object.js.es6 b/app/assets/javascripts/extensions/object.js
index 70a2d765abd..70a2d765abd 100644
--- a/app/assets/javascripts/extensions/object.js.es6
+++ b/app/assets/javascripts/extensions/object.js
diff --git a/app/assets/javascripts/filterable_list.js b/app/assets/javascripts/filterable_list.js
new file mode 100644
index 00000000000..47a40e28461
--- /dev/null
+++ b/app/assets/javascripts/filterable_list.js
@@ -0,0 +1,45 @@
+/**
+ * Makes search request for content when user types a value in the search input.
+ * Updates the html content of the page with the received one.
+ */
+export default class FilterableList {
+ constructor(form, filter, holder) {
+ this.filterForm = form;
+ this.listFilterElement = filter;
+ this.listHolderElement = holder;
+ }
+
+ initSearch() {
+ this.debounceFilter = _.debounce(this.filterResults.bind(this), 500);
+
+ this.listFilterElement.removeEventListener('input', this.debounceFilter);
+ this.listFilterElement.addEventListener('input', this.debounceFilter);
+ }
+
+ filterResults() {
+ const form = this.filterForm;
+ const filterUrl = `${form.getAttribute('action')}?${$(form).serialize()}`;
+
+ $(this.listHolderElement).fadeTo(250, 0.5);
+
+ return $.ajax({
+ url: form.getAttribute('action'),
+ data: $(form).serialize(),
+ type: 'GET',
+ dataType: 'json',
+ context: this,
+ complete() {
+ $(this.listHolderElement).fadeTo(250, 1);
+ },
+ success(data) {
+ this.listHolderElement.innerHTML = data.html;
+
+ // Change url so if user reload a page - search results are saved
+ return window.history.replaceState({
+ page: filterUrl,
+
+ }, document.title, filterUrl);
+ },
+ });
+ }
+}
diff --git a/app/assets/javascripts/filtered_search/dropdown_hint.js.es6 b/app/assets/javascripts/filtered_search/dropdown_hint.js
index 9e92d544bef..9e92d544bef 100644
--- a/app/assets/javascripts/filtered_search/dropdown_hint.js.es6
+++ b/app/assets/javascripts/filtered_search/dropdown_hint.js
diff --git a/app/assets/javascripts/filtered_search/dropdown_non_user.js.es6 b/app/assets/javascripts/filtered_search/dropdown_non_user.js
index b3dc3e502c5..b3dc3e502c5 100644
--- a/app/assets/javascripts/filtered_search/dropdown_non_user.js.es6
+++ b/app/assets/javascripts/filtered_search/dropdown_non_user.js
diff --git a/app/assets/javascripts/filtered_search/dropdown_user.js.es6 b/app/assets/javascripts/filtered_search/dropdown_user.js
index 7e9c6f74aa5..7e9c6f74aa5 100644
--- a/app/assets/javascripts/filtered_search/dropdown_user.js.es6
+++ b/app/assets/javascripts/filtered_search/dropdown_user.js
diff --git a/app/assets/javascripts/filtered_search/dropdown_utils.js.es6 b/app/assets/javascripts/filtered_search/dropdown_utils.js
index de3fa116717..de3fa116717 100644
--- a/app/assets/javascripts/filtered_search/dropdown_utils.js.es6
+++ b/app/assets/javascripts/filtered_search/dropdown_utils.js
diff --git a/app/assets/javascripts/filtered_search/filtered_search_dropdown.js.es6 b/app/assets/javascripts/filtered_search/filtered_search_dropdown.js
index dd565da507e..dd565da507e 100644
--- a/app/assets/javascripts/filtered_search/filtered_search_dropdown.js.es6
+++ b/app/assets/javascripts/filtered_search/filtered_search_dropdown.js
diff --git a/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js.es6 b/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js
index cecd3518ce3..cecd3518ce3 100644
--- a/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js.es6
+++ b/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js
diff --git a/app/assets/javascripts/filtered_search/filtered_search_manager.js.es6 b/app/assets/javascripts/filtered_search/filtered_search_manager.js
index bbafead0305..bbafead0305 100644
--- a/app/assets/javascripts/filtered_search/filtered_search_manager.js.es6
+++ b/app/assets/javascripts/filtered_search/filtered_search_manager.js
diff --git a/app/assets/javascripts/filtered_search/filtered_search_token_keys.js.es6 b/app/assets/javascripts/filtered_search/filtered_search_token_keys.js
index e6b53cd4b55..e6b53cd4b55 100644
--- a/app/assets/javascripts/filtered_search/filtered_search_token_keys.js.es6
+++ b/app/assets/javascripts/filtered_search/filtered_search_token_keys.js
diff --git a/app/assets/javascripts/filtered_search/filtered_search_tokenizer.js.es6 b/app/assets/javascripts/filtered_search/filtered_search_tokenizer.js
index 9bf1b1ced88..9bf1b1ced88 100644
--- a/app/assets/javascripts/filtered_search/filtered_search_tokenizer.js.es6
+++ b/app/assets/javascripts/filtered_search/filtered_search_tokenizer.js
diff --git a/app/assets/javascripts/gfm_auto_complete.js.es6 b/app/assets/javascripts/gfm_auto_complete.js
index 60d6658dc16..60d6658dc16 100644
--- a/app/assets/javascripts/gfm_auto_complete.js.es6
+++ b/app/assets/javascripts/gfm_auto_complete.js
diff --git a/app/assets/javascripts/gl_field_error.js.es6 b/app/assets/javascripts/gl_field_error.js
index f7cbecc0385..f7cbecc0385 100644
--- a/app/assets/javascripts/gl_field_error.js.es6
+++ b/app/assets/javascripts/gl_field_error.js
diff --git a/app/assets/javascripts/gl_field_errors.js.es6 b/app/assets/javascripts/gl_field_errors.js
index e9add115429..e9add115429 100644
--- a/app/assets/javascripts/gl_field_errors.js.es6
+++ b/app/assets/javascripts/gl_field_errors.js
diff --git a/app/assets/javascripts/gl_form.js.es6 b/app/assets/javascripts/gl_form.js
index 0b446ff364a..0b446ff364a 100644
--- a/app/assets/javascripts/gl_form.js.es6
+++ b/app/assets/javascripts/gl_form.js
diff --git a/app/assets/javascripts/graphs/graphs_bundle.js b/app/assets/javascripts/graphs/graphs_bundle.js
index ea5afbd9d29..a433c7ba8f0 100644
--- a/app/assets/javascripts/graphs/graphs_bundle.js
+++ b/app/assets/javascripts/graphs/graphs_bundle.js
@@ -1,4 +1,6 @@
+import Chart from 'vendor/Chart';
import ContributorsStatGraph from './stat_graph_contributors';
// export to global scope
+window.Chart = Chart;
window.ContributorsStatGraph = ContributorsStatGraph;
diff --git a/app/assets/javascripts/group_label_subscription.js.es6 b/app/assets/javascripts/group_label_subscription.js
index 15e695e81cf..15e695e81cf 100644
--- a/app/assets/javascripts/group_label_subscription.js.es6
+++ b/app/assets/javascripts/group_label_subscription.js
diff --git a/app/assets/javascripts/groups_list.js b/app/assets/javascripts/groups_list.js
index 0ef81e49444..56a8cbf6d03 100644
--- a/app/assets/javascripts/groups_list.js
+++ b/app/assets/javascripts/groups_list.js
@@ -1,47 +1,18 @@
+import FilterableList from './filterable_list';
+
/**
- * Based on project list search.
* Makes search request for groups when user types a value in the search input.
* Updates the html content of the page with the received one.
*/
export default class GroupsList {
constructor() {
- this.groupsListFilterElement = document.querySelector('.js-groups-list-filter');
- this.groupsListHolderElement = document.querySelector('.js-groups-list-holder');
-
- this.initSearch();
- }
-
- initSearch() {
- this.debounceFilter = _.debounce(this.filterResults.bind(this), 500);
-
- this.groupsListFilterElement.removeEventListener('input', this.debounceFilter);
- this.groupsListFilterElement.addEventListener('input', this.debounceFilter);
- }
-
- filterResults() {
const form = document.querySelector('form#group-filter-form');
- const groupFilterUrl = `${form.getAttribute('action')}?${$(form).serialize()}`;
-
- $(this.groupsListHolderElement).fadeTo(250, 0.5);
-
- return $.ajax({
- url: form.getAttribute('action'),
- data: $(form).serialize(),
- type: 'GET',
- dataType: 'json',
- context: this,
- complete() {
- $(this.groupsListHolderElement).fadeTo(250, 1);
- },
- success(data) {
- this.groupsListHolderElement.innerHTML = data.html;
-
- // Change url so if user reload a page - search results are saved
- return window.history.replaceState({
- page: groupFilterUrl,
+ const filter = document.querySelector('.js-groups-list-filter');
+ const holder = document.querySelector('.js-groups-list-holder');
- }, document.title, groupFilterUrl);
- },
- });
+ if (form && filter && holder) {
+ const list = new FilterableList(form, filter, holder);
+ list.initSearch();
+ }
}
}
diff --git a/app/assets/javascripts/issuable.js.es6 b/app/assets/javascripts/issuable.js
index 3bfce32768a..3bfce32768a 100644
--- a/app/assets/javascripts/issuable.js.es6
+++ b/app/assets/javascripts/issuable.js
diff --git a/app/assets/javascripts/issuable/issuable_bundle.js.es6 b/app/assets/javascripts/issuable/issuable_bundle.js
index e927cc0077c..e927cc0077c 100644
--- a/app/assets/javascripts/issuable/issuable_bundle.js.es6
+++ b/app/assets/javascripts/issuable/issuable_bundle.js
diff --git a/app/assets/javascripts/issuable/time_tracking/components/collapsed_state.js.es6 b/app/assets/javascripts/issuable/time_tracking/components/collapsed_state.js
index 357b3487ca9..357b3487ca9 100644
--- a/app/assets/javascripts/issuable/time_tracking/components/collapsed_state.js.es6
+++ b/app/assets/javascripts/issuable/time_tracking/components/collapsed_state.js
diff --git a/app/assets/javascripts/issuable/time_tracking/components/comparison_pane.js.es6 b/app/assets/javascripts/issuable/time_tracking/components/comparison_pane.js
index 750468c679b..750468c679b 100644
--- a/app/assets/javascripts/issuable/time_tracking/components/comparison_pane.js.es6
+++ b/app/assets/javascripts/issuable/time_tracking/components/comparison_pane.js
diff --git a/app/assets/javascripts/issuable/time_tracking/components/estimate_only_pane.js.es6 b/app/assets/javascripts/issuable/time_tracking/components/estimate_only_pane.js
index 309e9f2f9ef..309e9f2f9ef 100644
--- a/app/assets/javascripts/issuable/time_tracking/components/estimate_only_pane.js.es6
+++ b/app/assets/javascripts/issuable/time_tracking/components/estimate_only_pane.js
diff --git a/app/assets/javascripts/issuable/time_tracking/components/help_state.js.es6 b/app/assets/javascripts/issuable/time_tracking/components/help_state.js
index d7ced6d7151..d7ced6d7151 100644
--- a/app/assets/javascripts/issuable/time_tracking/components/help_state.js.es6
+++ b/app/assets/javascripts/issuable/time_tracking/components/help_state.js
diff --git a/app/assets/javascripts/issuable/time_tracking/components/no_tracking_pane.js.es6 b/app/assets/javascripts/issuable/time_tracking/components/no_tracking_pane.js
index 1d2ca643b5b..1d2ca643b5b 100644
--- a/app/assets/javascripts/issuable/time_tracking/components/no_tracking_pane.js.es6
+++ b/app/assets/javascripts/issuable/time_tracking/components/no_tracking_pane.js
diff --git a/app/assets/javascripts/issuable/time_tracking/components/spent_only_pane.js.es6 b/app/assets/javascripts/issuable/time_tracking/components/spent_only_pane.js
index ed283fec3c3..ed283fec3c3 100644
--- a/app/assets/javascripts/issuable/time_tracking/components/spent_only_pane.js.es6
+++ b/app/assets/javascripts/issuable/time_tracking/components/spent_only_pane.js
diff --git a/app/assets/javascripts/issuable/time_tracking/components/time_tracker.js.es6 b/app/assets/javascripts/issuable/time_tracking/components/time_tracker.js
index 1fae2d62b14..1fae2d62b14 100644
--- a/app/assets/javascripts/issuable/time_tracking/components/time_tracker.js.es6
+++ b/app/assets/javascripts/issuable/time_tracking/components/time_tracker.js
diff --git a/app/assets/javascripts/issuable/time_tracking/time_tracking_bundle.js.es6 b/app/assets/javascripts/issuable/time_tracking/time_tracking_bundle.js
index 958a0cc6d50..0134b7cb6f3 100644
--- a/app/assets/javascripts/issuable/time_tracking/time_tracking_bundle.js.es6
+++ b/app/assets/javascripts/issuable/time_tracking/time_tracking_bundle.js
@@ -1,5 +1,7 @@
/* global Vue */
+window.Vue = require('vue');
+window.Vue.use(require('vue-resource'));
require('./components/time_tracker');
require('../../smart_interval');
require('../../subbable_resource');
diff --git a/app/assets/javascripts/issues_bulk_assignment.js.es6 b/app/assets/javascripts/issues_bulk_assignment.js
index e0ebd36a65c..e0ebd36a65c 100644
--- a/app/assets/javascripts/issues_bulk_assignment.js.es6
+++ b/app/assets/javascripts/issues_bulk_assignment.js
diff --git a/app/assets/javascripts/label_manager.js.es6 b/app/assets/javascripts/label_manager.js
index 38b2eb9ff14..38b2eb9ff14 100644
--- a/app/assets/javascripts/label_manager.js.es6
+++ b/app/assets/javascripts/label_manager.js
diff --git a/app/assets/javascripts/lib/chart.js b/app/assets/javascripts/lib/chart.js
deleted file mode 100644
index 9b011d89e93..00000000000
--- a/app/assets/javascripts/lib/chart.js
+++ /dev/null
@@ -1,3 +0,0 @@
-/* eslint-disable func-names, space-before-function-paren */
-
-window.Chart = require('vendor/Chart');
diff --git a/app/assets/javascripts/lib/cropper.js b/app/assets/javascripts/lib/cropper.js
deleted file mode 100644
index 7862c6797c3..00000000000
--- a/app/assets/javascripts/lib/cropper.js
+++ /dev/null
@@ -1,7 +0,0 @@
-/* eslint-disable func-names, space-before-function-paren */
-
-/*= require cropper */
-
-(function() {
-
-}).call(window);
diff --git a/app/assets/javascripts/lib/d3.js b/app/assets/javascripts/lib/d3.js
deleted file mode 100644
index a9dd32edbed..00000000000
--- a/app/assets/javascripts/lib/d3.js
+++ /dev/null
@@ -1,3 +0,0 @@
-/* eslint-disable func-names, space-before-function-paren */
-
-window.d3 = require('d3');
diff --git a/app/assets/javascripts/lib/utils/bootstrap_linked_tabs.js.es6 b/app/assets/javascripts/lib/utils/bootstrap_linked_tabs.js
index 2955bda1a36..2955bda1a36 100644
--- a/app/assets/javascripts/lib/utils/bootstrap_linked_tabs.js.es6
+++ b/app/assets/javascripts/lib/utils/bootstrap_linked_tabs.js
diff --git a/app/assets/javascripts/lib/utils/common_utils.js.es6 b/app/assets/javascripts/lib/utils/common_utils.js
index a1423b6fda5..a1423b6fda5 100644
--- a/app/assets/javascripts/lib/utils/common_utils.js.es6
+++ b/app/assets/javascripts/lib/utils/common_utils.js
diff --git a/app/assets/javascripts/lib/utils/datetime_utility.js.es6 b/app/assets/javascripts/lib/utils/datetime_utility.js
index 82dcbdc26c8..82dcbdc26c8 100644
--- a/app/assets/javascripts/lib/utils/datetime_utility.js.es6
+++ b/app/assets/javascripts/lib/utils/datetime_utility.js
diff --git a/app/assets/javascripts/lib/utils/pretty_time.js.es6 b/app/assets/javascripts/lib/utils/pretty_time.js
index ae397212e55..ae397212e55 100644
--- a/app/assets/javascripts/lib/utils/pretty_time.js.es6
+++ b/app/assets/javascripts/lib/utils/pretty_time.js
diff --git a/app/assets/javascripts/lib/utils/url_utility.js.es6 b/app/assets/javascripts/lib/utils/url_utility.js
index 1bc81d2e4a4..1bc81d2e4a4 100644
--- a/app/assets/javascripts/lib/utils/url_utility.js.es6
+++ b/app/assets/javascripts/lib/utils/url_utility.js
diff --git a/app/assets/javascripts/lib/vue_resource.js.es6 b/app/assets/javascripts/lib/vue_resource.js.es6
deleted file mode 100644
index 49babdea2e1..00000000000
--- a/app/assets/javascripts/lib/vue_resource.js.es6
+++ /dev/null
@@ -1,2 +0,0 @@
-window.Vue = require('vue');
-window.Vue.use(require('vue-resource'));
diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/main.js
index 4c24d35b5bb..798553c16ac 100644
--- a/app/assets/javascripts/application.js
+++ b/app/assets/javascripts/main.js
@@ -6,35 +6,34 @@
/* global AwardsHandler */
/* global Aside */
-window.$ = window.jQuery = require('jquery');
-require('jquery-ujs');
-require('vendor/jquery.endless-scroll');
-require('vendor/jquery.waitforimages');
-require('vendor/jquery.caret');
-require('vendor/jquery.atwho');
-require('vendor/jquery.scrollTo');
-window.Cookies = require('js-cookie');
-require('./autosave');
-require('bootstrap/js/affix');
-require('bootstrap/js/alert');
-require('bootstrap/js/dropdown');
-require('bootstrap/js/modal');
-require('bootstrap/js/tab');
-require('bootstrap/js/transition');
-require('bootstrap/js/tooltip');
-require('select2/select2.js');
-window.Pikaday = require('pikaday');
-window._ = require('underscore');
-window.Dropzone = require('dropzone');
-window.Sortable = require('vendor/Sortable');
+import jQuery from 'jquery';
+import _ from 'underscore';
+import Cookies from 'js-cookie';
+import Pikaday from 'pikaday';
+import Dropzone from 'dropzone';
+import Sortable from 'vendor/Sortable';
+
+// libraries with import side-effects
require('mousetrap');
require('mousetrap/plugins/pause/mousetrap-pause');
+require('vendor/fuzzaldrin-plus');
+require('es6-promise').polyfill();
+
+// expose common libraries as globals (TODO: remove these)
+window.jQuery = jQuery;
+window.$ = jQuery;
+window._ = _;
+window.Cookies = Cookies;
+window.Pikaday = Pikaday;
+window.Dropzone = Dropzone;
+window.Sortable = Sortable;
+
+// shortcuts
require('./shortcuts');
require('./shortcuts_navigation');
require('./shortcuts_dashboard_navigation');
require('./shortcuts_issuable');
require('./shortcuts_network');
-require('vendor/jquery.nicescroll');
// behaviors
require('./behaviors/autosize');
@@ -205,9 +204,6 @@ require('./visibility_select');
require('./wikis');
require('./zen_mode');
-require('vendor/fuzzaldrin-plus');
-require('es6-promise').polyfill();
-
(function () {
document.addEventListener('beforeunload', function () {
// Unbind scroll events
@@ -285,7 +281,7 @@ require('es6-promise').polyfill();
$.fn.tooltip.Constructor.DEFAULTS.trigger = 'hover';
$body.tooltip({
selector: '.has-tooltip, [data-toggle="tooltip"]',
- placement: function (_, el) {
+ placement: function (tip, el) {
return $(el).data('placement') || 'bottom';
}
});
diff --git a/app/assets/javascripts/member_expiration_date.js.es6 b/app/assets/javascripts/member_expiration_date.js
index 129d2dc5f0a..129d2dc5f0a 100644
--- a/app/assets/javascripts/member_expiration_date.js.es6
+++ b/app/assets/javascripts/member_expiration_date.js
diff --git a/app/assets/javascripts/members.js.es6 b/app/assets/javascripts/members.js
index e3f367a11eb..e3f367a11eb 100644
--- a/app/assets/javascripts/members.js.es6
+++ b/app/assets/javascripts/members.js
diff --git a/app/assets/javascripts/merge_conflicts/components/diff_file_editor.js.es6 b/app/assets/javascripts/merge_conflicts/components/diff_file_editor.js
index c7e78fed8fe..c7e78fed8fe 100644
--- a/app/assets/javascripts/merge_conflicts/components/diff_file_editor.js.es6
+++ b/app/assets/javascripts/merge_conflicts/components/diff_file_editor.js
diff --git a/app/assets/javascripts/merge_conflicts/components/inline_conflict_lines.js.es6 b/app/assets/javascripts/merge_conflicts/components/inline_conflict_lines.js
index 240c8f98932..240c8f98932 100644
--- a/app/assets/javascripts/merge_conflicts/components/inline_conflict_lines.js.es6
+++ b/app/assets/javascripts/merge_conflicts/components/inline_conflict_lines.js
diff --git a/app/assets/javascripts/merge_conflicts/components/parallel_conflict_lines.js.es6 b/app/assets/javascripts/merge_conflicts/components/parallel_conflict_lines.js
index 97753c50b60..97753c50b60 100644
--- a/app/assets/javascripts/merge_conflicts/components/parallel_conflict_lines.js.es6
+++ b/app/assets/javascripts/merge_conflicts/components/parallel_conflict_lines.js
diff --git a/app/assets/javascripts/merge_conflicts/merge_conflict_service.js.es6 b/app/assets/javascripts/merge_conflicts/merge_conflict_service.js
index c012b77e0bf..c012b77e0bf 100644
--- a/app/assets/javascripts/merge_conflicts/merge_conflict_service.js.es6
+++ b/app/assets/javascripts/merge_conflicts/merge_conflict_service.js
diff --git a/app/assets/javascripts/merge_conflicts/merge_conflict_store.js.es6 b/app/assets/javascripts/merge_conflicts/merge_conflict_store.js
index 74587df22c5..74587df22c5 100644
--- a/app/assets/javascripts/merge_conflicts/merge_conflict_store.js.es6
+++ b/app/assets/javascripts/merge_conflicts/merge_conflict_store.js
diff --git a/app/assets/javascripts/merge_conflicts/merge_conflicts_bundle.js.es6 b/app/assets/javascripts/merge_conflicts/merge_conflicts_bundle.js
index 653e52fb6bf..653e52fb6bf 100644
--- a/app/assets/javascripts/merge_conflicts/merge_conflicts_bundle.js.es6
+++ b/app/assets/javascripts/merge_conflicts/merge_conflicts_bundle.js
diff --git a/app/assets/javascripts/merge_conflicts/mixins/line_conflict_actions.js.es6 b/app/assets/javascripts/merge_conflicts/mixins/line_conflict_actions.js
index 53e000d7e9e..53e000d7e9e 100644
--- a/app/assets/javascripts/merge_conflicts/mixins/line_conflict_actions.js.es6
+++ b/app/assets/javascripts/merge_conflicts/mixins/line_conflict_actions.js
diff --git a/app/assets/javascripts/merge_conflicts/mixins/line_conflict_utils.js.es6 b/app/assets/javascripts/merge_conflicts/mixins/line_conflict_utils.js
index 0f475f62ee6..0f475f62ee6 100644
--- a/app/assets/javascripts/merge_conflicts/mixins/line_conflict_utils.js.es6
+++ b/app/assets/javascripts/merge_conflicts/mixins/line_conflict_utils.js
diff --git a/app/assets/javascripts/merge_request_tabs.js.es6 b/app/assets/javascripts/merge_request_tabs.js
index 190336dbd20..190336dbd20 100644
--- a/app/assets/javascripts/merge_request_tabs.js.es6
+++ b/app/assets/javascripts/merge_request_tabs.js
diff --git a/app/assets/javascripts/merge_request_widget.js.es6 b/app/assets/javascripts/merge_request_widget.js
index 00c6c050612..5f1bd474a0c 100644
--- a/app/assets/javascripts/merge_request_widget.js.es6
+++ b/app/assets/javascripts/merge_request_widget.js
@@ -129,8 +129,9 @@ require('./smart_interval');
};
MergeRequestWidget.prototype.getMergeStatus = function() {
- return $.get(this.opts.merge_check_url, function(data) {
+ return $.get(this.opts.merge_check_url, (data) => {
var $html = $(data);
+ this.updateMergeButton(this.status, this.hasCi, $html);
$('.mr-widget-body').replaceWith($html.find('.mr-widget-body'));
$('.mr-widget-footer').replaceWith($html.find('.mr-widget-footer'));
});
@@ -154,9 +155,9 @@ require('./smart_interval');
return $.getJSON(this.opts.ci_status_url, (function(_this) {
return function(data) {
var message, status, title;
- if (!data.status) {
- return;
- }
+ _this.status = data.status;
+ _this.hasCi = data.has_ci;
+ _this.updateMergeButton(_this.status, _this.hasCi);
if (data.environments && data.environments.length) _this.renderEnvironments(data.environments);
if (data.status !== _this.opts.ci_status ||
data.sha !== _this.opts.ci_sha ||
@@ -232,36 +233,45 @@ require('./smart_interval');
return;
}
$('.ci_widget').hide();
- allowed_states = ["failed", "canceled", "running", "pending", "success", "success_with_warnings", "skipped", "not_found"];
- if (indexOf.call(allowed_states, state) !== -1) {
- $('.ci_widget.ci-' + state).show();
+ $('.ci_widget.ci-' + state).show();
+
+ this.initMiniPipelineGraph();
+ };
+
+ MergeRequestWidget.prototype.showCICoverage = function(coverage) {
+ var text = `Coverage ${coverage}%`;
+ return $('.ci_widget:visible .ci-coverage').text(text);
+ };
+
+ MergeRequestWidget.prototype.updateMergeButton = function(state, hasCi, $html) {
+ const allowed_states = ["failed", "canceled", "running", "pending", "success", "success_with_warnings", "skipped", "not_found"];
+ let stateClass = 'btn-danger';
+ if (!hasCi) {
+ stateClass = 'btn-create';
+ } else if (indexOf.call(allowed_states, state) !== -1) {
switch (state) {
case "failed":
case "canceled":
case "not_found":
- this.setMergeButtonClass('btn-danger');
+ stateClass = 'btn-danger';
break;
case "running":
- this.setMergeButtonClass('btn-info');
+ stateClass = 'btn-info';
break;
case "success":
case "success_with_warnings":
- this.setMergeButtonClass('btn-create');
+ stateClass = 'btn-create';
}
} else {
$('.ci_widget.ci-error').show();
- this.setMergeButtonClass('btn-danger');
+ stateClass = 'btn-danger';
}
- };
- MergeRequestWidget.prototype.showCICoverage = function(coverage) {
- var text;
- text = 'Coverage ' + coverage + '%';
- return $('.ci_widget:visible .ci-coverage').text(text);
+ this.setMergeButtonClass(stateClass, $html);
};
- MergeRequestWidget.prototype.setMergeButtonClass = function(css_class) {
- return $('.js-merge-button,.accept-action .dropdown-toggle').removeClass('btn-danger btn-info btn-create').addClass(css_class);
+ MergeRequestWidget.prototype.setMergeButtonClass = function(css_class, $html = $('.mr-state-widget')) {
+ return $html.find('.js-merge-button').removeClass('btn-danger btn-info btn-create').addClass(css_class);
};
MergeRequestWidget.prototype.updatePipelineUrls = function(id) {
diff --git a/app/assets/javascripts/merge_request_widget/ci_bundle.js.es6 b/app/assets/javascripts/merge_request_widget/ci_bundle.js
index 547dfa9e677..21d7c3e168e 100644
--- a/app/assets/javascripts/merge_request_widget/ci_bundle.js.es6
+++ b/app/assets/javascripts/merge_request_widget/ci_bundle.js
@@ -15,14 +15,14 @@
});
$(document)
- .off('click', '.accept_merge_request')
- .on('click', '.accept_merge_request', () => {
- $('.js-merge-button').html('<i class="fa fa-spinner fa-spin"></i> Merge in progress');
+ .off('click', '.accept-merge-request')
+ .on('click', '.accept-merge-request', () => {
+ $('.js-merge-button, .js-merge-when-pipeline-succeeds-button').html('<i class="fa fa-spinner fa-spin"></i> Merge in progress');
});
$(document)
- .off('click', '.merge_when_pipeline_succeeds')
- .on('click', '.merge_when_pipeline_succeeds', () => {
+ .off('click', '.merge-when-pipeline-succeeds')
+ .on('click', '.merge-when-pipeline-succeeds', () => {
$('#merge_when_pipeline_succeeds').val('1');
});
diff --git a/app/assets/javascripts/mini_pipeline_graph_dropdown.js.es6 b/app/assets/javascripts/mini_pipeline_graph_dropdown.js
index 2145e531331..2145e531331 100644
--- a/app/assets/javascripts/mini_pipeline_graph_dropdown.js.es6
+++ b/app/assets/javascripts/mini_pipeline_graph_dropdown.js
diff --git a/app/assets/javascripts/notes.js b/app/assets/javascripts/notes.js
index 47fa0f2eb96..df7a7d2a459 100644
--- a/app/assets/javascripts/notes.js
+++ b/app/assets/javascripts/notes.js
@@ -198,7 +198,7 @@ require('./task_list');
this.refreshing = true;
return $.ajax({
url: this.notes_url,
- data: "last_fetched_at=" + this.last_fetched_at,
+ headers: { "X-Last-Fetched-At": this.last_fetched_at },
dataType: "json",
success: (function(_this) {
return function(data) {
diff --git a/app/assets/javascripts/pager.js.es6 b/app/assets/javascripts/pager.js
index e35cf6d295e..e35cf6d295e 100644
--- a/app/assets/javascripts/pager.js.es6
+++ b/app/assets/javascripts/pager.js
diff --git a/app/assets/javascripts/pipelines.js.es6 b/app/assets/javascripts/pipelines.js
index 9203abefbbc..9203abefbbc 100644
--- a/app/assets/javascripts/pipelines.js.es6
+++ b/app/assets/javascripts/pipelines.js
diff --git a/app/assets/javascripts/profile/gl_crop.js.es6 b/app/assets/javascripts/profile/gl_crop.js
index 192b1192d07..cf1566eeb87 100644
--- a/app/assets/javascripts/profile/gl_crop.js.es6
+++ b/app/assets/javascripts/profile/gl_crop.js
@@ -1,5 +1,7 @@
/* eslint-disable no-useless-escape, max-len, quotes, no-var, no-underscore-dangle, func-names, space-before-function-paren, no-unused-vars, no-return-assign, object-shorthand, one-var, one-var-declaration-per-line, comma-dangle, consistent-return, class-methods-use-this, new-parens */
+import 'vendor/cropper';
+
((global) => {
// Matches everything but the file name
const FILENAMEREGEX = /^.*[\\\/]/;
diff --git a/app/assets/javascripts/profile/profile.js.es6 b/app/assets/javascripts/profile/profile.js
index 4ccea0624ee..4ccea0624ee 100644
--- a/app/assets/javascripts/profile/profile.js.es6
+++ b/app/assets/javascripts/profile/profile.js
diff --git a/app/assets/javascripts/project_label_subscription.js.es6 b/app/assets/javascripts/project_label_subscription.js
index 0a811627600..0a811627600 100644
--- a/app/assets/javascripts/project_label_subscription.js.es6
+++ b/app/assets/javascripts/project_label_subscription.js
diff --git a/app/assets/javascripts/project_variables.js.es6 b/app/assets/javascripts/project_variables.js
index 4ee2e49306d..4ee2e49306d 100644
--- a/app/assets/javascripts/project_variables.js.es6
+++ b/app/assets/javascripts/project_variables.js
diff --git a/app/assets/javascripts/projects_list.js b/app/assets/javascripts/projects_list.js
index acdf9b7eb5a..c67d59d2be5 100644
--- a/app/assets/javascripts/projects_list.js
+++ b/app/assets/javascripts/projects_list.js
@@ -1,50 +1,18 @@
-/* eslint-disable func-names, space-before-function-paren, object-shorthand, quotes, no-var, one-var, one-var-declaration-per-line, prefer-arrow-callback, consistent-return, no-unused-vars, camelcase, prefer-template, comma-dangle, max-len */
+import FilterableList from './filterable_list';
-(function() {
- window.ProjectsList = {
- init: function() {
- $(".projects-list-filter").off('keyup');
- this.initSearch();
- return this.initPagination();
- },
- initSearch: function() {
- var debounceFilter, projectsListFilter;
- projectsListFilter = $('.projects-list-filter');
- debounceFilter = _.debounce(window.ProjectsList.filterResults, 500);
- return projectsListFilter.on('keyup', function(e) {
- if (projectsListFilter.val() !== '') {
- return debounceFilter();
- }
- });
- },
- filterResults: function() {
- var form, project_filter_url, search;
- $('.projects-list-holder').fadeTo(250, 0.5);
- form = null;
- form = $("form#project-filter-form");
- search = $(".projects-list-filter").val();
- project_filter_url = form.attr('action') + '?' + form.serialize();
- return $.ajax({
- type: "GET",
- url: form.attr('action'),
- data: form.serialize(),
- complete: function() {
- return $('.projects-list-holder').fadeTo(250, 1);
- },
- success: function(data) {
- $('.projects-list-holder').replaceWith(data.html);
- return history.replaceState({
- page: project_filter_url
- // Change url so if user reload a page - search results are saved
- }, document.title, project_filter_url);
- },
- dataType: "json"
- });
- },
- initPagination: function() {
- return $('.projects-list-holder .pagination').on('ajax:success', function(e, data) {
- return $('.projects-list-holder').replaceWith(data.html);
- });
+/**
+ * Makes search request for projects when user types a value in the search input.
+ * Updates the html content of the page with the received one.
+ */
+export default class ProjectsList {
+ constructor() {
+ const form = document.querySelector('form#project-filter-form');
+ const filter = document.querySelector('.js-projects-list-filter');
+ const holder = document.querySelector('.js-projects-list-holder');
+
+ if (form && filter && holder) {
+ const list = new FilterableList(form, filter, holder);
+ list.initSearch();
}
- };
-}).call(window);
+ }
+}
diff --git a/app/assets/javascripts/protected_branches/protected_branch_access_dropdown.js.es6 b/app/assets/javascripts/protected_branches/protected_branch_access_dropdown.js
index e7fff57ff45..e7fff57ff45 100644
--- a/app/assets/javascripts/protected_branches/protected_branch_access_dropdown.js.es6
+++ b/app/assets/javascripts/protected_branches/protected_branch_access_dropdown.js
diff --git a/app/assets/javascripts/protected_branches/protected_branch_create.js.es6 b/app/assets/javascripts/protected_branches/protected_branch_create.js
index 57ea2f52814..57ea2f52814 100644
--- a/app/assets/javascripts/protected_branches/protected_branch_create.js.es6
+++ b/app/assets/javascripts/protected_branches/protected_branch_create.js
diff --git a/app/assets/javascripts/protected_branches/protected_branch_dropdown.js.es6 b/app/assets/javascripts/protected_branches/protected_branch_dropdown.js
index 5cf28aa7a73..5cf28aa7a73 100644
--- a/app/assets/javascripts/protected_branches/protected_branch_dropdown.js.es6
+++ b/app/assets/javascripts/protected_branches/protected_branch_dropdown.js
diff --git a/app/assets/javascripts/protected_branches/protected_branch_edit.js.es6 b/app/assets/javascripts/protected_branches/protected_branch_edit.js
index 6ef59e94384..6ef59e94384 100644
--- a/app/assets/javascripts/protected_branches/protected_branch_edit.js.es6
+++ b/app/assets/javascripts/protected_branches/protected_branch_edit.js
diff --git a/app/assets/javascripts/protected_branches/protected_branch_edit_list.js.es6 b/app/assets/javascripts/protected_branches/protected_branch_edit_list.js
index 336fa6c57a7..336fa6c57a7 100644
--- a/app/assets/javascripts/protected_branches/protected_branch_edit_list.js.es6
+++ b/app/assets/javascripts/protected_branches/protected_branch_edit_list.js
diff --git a/app/assets/javascripts/search_autocomplete.js.es6 b/app/assets/javascripts/search_autocomplete.js
index 6fd5345a0a6..6fd5345a0a6 100644
--- a/app/assets/javascripts/search_autocomplete.js.es6
+++ b/app/assets/javascripts/search_autocomplete.js
diff --git a/app/assets/javascripts/shortcuts_blob.js.es6 b/app/assets/javascripts/shortcuts_blob.js
index bfe90aef71e..bfe90aef71e 100644
--- a/app/assets/javascripts/shortcuts_blob.js.es6
+++ b/app/assets/javascripts/shortcuts_blob.js
diff --git a/app/assets/javascripts/signin_tabs_memoizer.js.es6 b/app/assets/javascripts/signin_tabs_memoizer.js
index d811d1cd53a..d811d1cd53a 100644
--- a/app/assets/javascripts/signin_tabs_memoizer.js.es6
+++ b/app/assets/javascripts/signin_tabs_memoizer.js
diff --git a/app/assets/javascripts/smart_interval.js.es6 b/app/assets/javascripts/smart_interval.js
index d1bdc353be2..d1bdc353be2 100644
--- a/app/assets/javascripts/smart_interval.js.es6
+++ b/app/assets/javascripts/smart_interval.js
diff --git a/app/assets/javascripts/snippets_list.js.es6 b/app/assets/javascripts/snippets_list.js
index 2128007113f..2128007113f 100644
--- a/app/assets/javascripts/snippets_list.js.es6
+++ b/app/assets/javascripts/snippets_list.js
diff --git a/app/assets/javascripts/subbable_resource.js.es6 b/app/assets/javascripts/subbable_resource.js
index d8191605128..d8191605128 100644
--- a/app/assets/javascripts/subbable_resource.js.es6
+++ b/app/assets/javascripts/subbable_resource.js
diff --git a/app/assets/javascripts/subscription.js.es6 b/app/assets/javascripts/subscription.js
index 62d1604fe9e..62d1604fe9e 100644
--- a/app/assets/javascripts/subscription.js.es6
+++ b/app/assets/javascripts/subscription.js
diff --git a/app/assets/javascripts/templates/issuable_template_selector.js.es6 b/app/assets/javascripts/templates/issuable_template_selector.js
index e9e9aafd71a..e9e9aafd71a 100644
--- a/app/assets/javascripts/templates/issuable_template_selector.js.es6
+++ b/app/assets/javascripts/templates/issuable_template_selector.js
diff --git a/app/assets/javascripts/templates/issuable_template_selectors.js.es6 b/app/assets/javascripts/templates/issuable_template_selectors.js
index 97f6d37364d..97f6d37364d 100644
--- a/app/assets/javascripts/templates/issuable_template_selectors.js.es6
+++ b/app/assets/javascripts/templates/issuable_template_selectors.js
diff --git a/app/assets/javascripts/terminal/terminal.js.es6 b/app/assets/javascripts/terminal/terminal.js
index 6b9422b1816..6b9422b1816 100644
--- a/app/assets/javascripts/terminal/terminal.js.es6
+++ b/app/assets/javascripts/terminal/terminal.js
diff --git a/app/assets/javascripts/terminal/terminal_bundle.js.es6 b/app/assets/javascripts/terminal/terminal_bundle.js
index 13cf3a10a38..13cf3a10a38 100644
--- a/app/assets/javascripts/terminal/terminal_bundle.js.es6
+++ b/app/assets/javascripts/terminal/terminal_bundle.js
diff --git a/app/assets/javascripts/todos.js.es6 b/app/assets/javascripts/todos.js
index e9513725d9d..e9513725d9d 100644
--- a/app/assets/javascripts/todos.js.es6
+++ b/app/assets/javascripts/todos.js
diff --git a/app/assets/javascripts/u2f/authenticate.js.es6 b/app/assets/javascripts/u2f/authenticate.js
index 500b78fc5d8..500b78fc5d8 100644
--- a/app/assets/javascripts/u2f/authenticate.js.es6
+++ b/app/assets/javascripts/u2f/authenticate.js
diff --git a/app/assets/javascripts/user.js.es6 b/app/assets/javascripts/user.js
index 059e6c628b3..059e6c628b3 100644
--- a/app/assets/javascripts/user.js.es6
+++ b/app/assets/javascripts/user.js
diff --git a/app/assets/javascripts/user_tabs.js.es6 b/app/assets/javascripts/user_tabs.js
index 465618e3d53..465618e3d53 100644
--- a/app/assets/javascripts/user_tabs.js.es6
+++ b/app/assets/javascripts/user_tabs.js
diff --git a/app/assets/javascripts/username_validator.js.es6 b/app/assets/javascripts/username_validator.js
index 137cefa3b8e..137cefa3b8e 100644
--- a/app/assets/javascripts/username_validator.js.es6
+++ b/app/assets/javascripts/username_validator.js
diff --git a/app/assets/javascripts/users/calendar.js b/app/assets/javascripts/users/calendar.js
index 5111b260e1c..754d448564f 100644
--- a/app/assets/javascripts/users/calendar.js
+++ b/app/assets/javascripts/users/calendar.js
@@ -1,5 +1,6 @@
/* eslint-disable func-names, space-before-function-paren, no-var, prefer-rest-params, wrap-iife, camelcase, vars-on-top, object-shorthand, comma-dangle, eqeqeq, no-mixed-operators, no-return-assign, newline-per-chained-call, prefer-arrow-callback, consistent-return, one-var, one-var-declaration-per-line, prefer-template, quotes, no-unused-vars, no-else-return, max-len */
-/* global d3 */
+
+import d3 from 'd3';
(function() {
var bind = function(fn, me) { return function() { return fn.apply(me, arguments); }; };
diff --git a/app/assets/javascripts/version_check_image.js.es6 b/app/assets/javascripts/version_check_image.js
index d4f716acb72..d4f716acb72 100644
--- a/app/assets/javascripts/version_check_image.js.es6
+++ b/app/assets/javascripts/version_check_image.js
diff --git a/app/assets/javascripts/visibility_select.js.es6 b/app/assets/javascripts/visibility_select.js
index f712d7ba930..f712d7ba930 100644
--- a/app/assets/javascripts/visibility_select.js.es6
+++ b/app/assets/javascripts/visibility_select.js
diff --git a/app/assets/javascripts/vue_pipelines_index/index.js.es6 b/app/assets/javascripts/vue_pipelines_index/index.js
index a90bd1518e9..a90bd1518e9 100644
--- a/app/assets/javascripts/vue_pipelines_index/index.js.es6
+++ b/app/assets/javascripts/vue_pipelines_index/index.js
diff --git a/app/assets/javascripts/vue_pipelines_index/pipeline_actions.js.es6 b/app/assets/javascripts/vue_pipelines_index/pipeline_actions.js
index 891f1f17fb3..891f1f17fb3 100644
--- a/app/assets/javascripts/vue_pipelines_index/pipeline_actions.js.es6
+++ b/app/assets/javascripts/vue_pipelines_index/pipeline_actions.js
diff --git a/app/assets/javascripts/vue_pipelines_index/pipeline_url.js.es6 b/app/assets/javascripts/vue_pipelines_index/pipeline_url.js
index ae5649f0519..ae5649f0519 100644
--- a/app/assets/javascripts/vue_pipelines_index/pipeline_url.js.es6
+++ b/app/assets/javascripts/vue_pipelines_index/pipeline_url.js
diff --git a/app/assets/javascripts/vue_pipelines_index/pipelines.js.es6 b/app/assets/javascripts/vue_pipelines_index/pipelines.js
index 601ef41e917..601ef41e917 100644
--- a/app/assets/javascripts/vue_pipelines_index/pipelines.js.es6
+++ b/app/assets/javascripts/vue_pipelines_index/pipelines.js
diff --git a/app/assets/javascripts/vue_pipelines_index/stage.js.es6 b/app/assets/javascripts/vue_pipelines_index/stage.js
index f67ebd6a265..f67ebd6a265 100644
--- a/app/assets/javascripts/vue_pipelines_index/stage.js.es6
+++ b/app/assets/javascripts/vue_pipelines_index/stage.js
diff --git a/app/assets/javascripts/vue_pipelines_index/status.js.es6 b/app/assets/javascripts/vue_pipelines_index/status.js
index 8d9f83ac113..8d9f83ac113 100644
--- a/app/assets/javascripts/vue_pipelines_index/status.js.es6
+++ b/app/assets/javascripts/vue_pipelines_index/status.js
diff --git a/app/assets/javascripts/vue_pipelines_index/store.js.es6 b/app/assets/javascripts/vue_pipelines_index/store.js
index 909007267b9..909007267b9 100644
--- a/app/assets/javascripts/vue_pipelines_index/store.js.es6
+++ b/app/assets/javascripts/vue_pipelines_index/store.js
diff --git a/app/assets/javascripts/vue_pipelines_index/time_ago.js.es6 b/app/assets/javascripts/vue_pipelines_index/time_ago.js
index a383570857d..a383570857d 100644
--- a/app/assets/javascripts/vue_pipelines_index/time_ago.js.es6
+++ b/app/assets/javascripts/vue_pipelines_index/time_ago.js
diff --git a/app/assets/javascripts/vue_realtime_listener/index.js.es6 b/app/assets/javascripts/vue_realtime_listener/index.js
index 30f6680a673..30f6680a673 100644
--- a/app/assets/javascripts/vue_realtime_listener/index.js.es6
+++ b/app/assets/javascripts/vue_realtime_listener/index.js
diff --git a/app/assets/javascripts/vue_shared/components/commit.js.es6 b/app/assets/javascripts/vue_shared/components/commit.js
index 4381487b79e..4381487b79e 100644
--- a/app/assets/javascripts/vue_shared/components/commit.js.es6
+++ b/app/assets/javascripts/vue_shared/components/commit.js
diff --git a/app/assets/javascripts/vue_shared/components/pipelines_table.js.es6 b/app/assets/javascripts/vue_shared/components/pipelines_table.js
index 0d8f85db965..0d8f85db965 100644
--- a/app/assets/javascripts/vue_shared/components/pipelines_table.js.es6
+++ b/app/assets/javascripts/vue_shared/components/pipelines_table.js
diff --git a/app/assets/javascripts/vue_shared/components/pipelines_table_row.js.es6 b/app/assets/javascripts/vue_shared/components/pipelines_table_row.js
index e5e88186a85..e5e88186a85 100644
--- a/app/assets/javascripts/vue_shared/components/pipelines_table_row.js.es6
+++ b/app/assets/javascripts/vue_shared/components/pipelines_table_row.js
diff --git a/app/assets/javascripts/vue_shared/components/table_pagination.js.es6 b/app/assets/javascripts/vue_shared/components/table_pagination.js
index 8943b850a72..8943b850a72 100644
--- a/app/assets/javascripts/vue_shared/components/table_pagination.js.es6
+++ b/app/assets/javascripts/vue_shared/components/table_pagination.js
diff --git a/app/assets/javascripts/vue_shared/vue_resource_interceptor.js.es6 b/app/assets/javascripts/vue_shared/vue_resource_interceptor.js
index d3229f9f730..d3229f9f730 100644
--- a/app/assets/javascripts/vue_shared/vue_resource_interceptor.js.es6
+++ b/app/assets/javascripts/vue_shared/vue_resource_interceptor.js
diff --git a/app/assets/javascripts/wikis.js.es6 b/app/assets/javascripts/wikis.js
index 75fd1394a03..75fd1394a03 100644
--- a/app/assets/javascripts/wikis.js.es6
+++ b/app/assets/javascripts/wikis.js
diff --git a/app/assets/stylesheets/framework/header.scss b/app/assets/stylesheets/framework/header.scss
index 685a4847731..f4316ec7022 100644
--- a/app/assets/stylesheets/framework/header.scss
+++ b/app/assets/stylesheets/framework/header.scss
@@ -149,14 +149,14 @@ header {
.header-logo {
display: inline-block;
- margin: 0 8px 0 3px;
+ margin: 0 7px 0 2px;
position: relative;
- top: 7px;
+ top: 10px;
transition-duration: .3s;
svg,
img {
- height: 36px;
+ height: 28px;
}
&:hover {
diff --git a/app/assets/stylesheets/framework/layout.scss b/app/assets/stylesheets/framework/layout.scss
index 29d55c44699..0a42b17c1f5 100644
--- a/app/assets/stylesheets/framework/layout.scss
+++ b/app/assets/stylesheets/framework/layout.scss
@@ -8,6 +8,19 @@ body {
&.navless {
background-color: $white-light !important;
}
+
+ &.card-content {
+ background-color: $gray-darker;
+
+ .content-wrapper {
+ padding: 0;
+
+ .container-fluid,
+ .container-limited {
+ background-color: $gray-darker;
+ }
+ }
+ }
}
.container {
diff --git a/app/assets/stylesheets/pages/merge_requests.scss b/app/assets/stylesheets/pages/merge_requests.scss
index 0b0c4bc130d..a629a5333d7 100644
--- a/app/assets/stylesheets/pages/merge_requests.scss
+++ b/app/assets/stylesheets/pages/merge_requests.scss
@@ -29,7 +29,7 @@
background-color: $gl-success;
}
- .accept_merge_request {
+ .accept-merge-request {
&.ci-pending,
&.ci-running {
@include btn-blue;
@@ -42,6 +42,12 @@
@include btn-red;
}
}
+
+ .dropdown-toggle {
+ .fa {
+ color: inherit;
+ }
+ }
}
.accept-control {
diff --git a/app/assets/stylesheets/pages/search.scss b/app/assets/stylesheets/pages/search.scss
index 88ea92c5afb..543d2ece3df 100644
--- a/app/assets/stylesheets/pages/search.scss
+++ b/app/assets/stylesheets/pages/search.scss
@@ -182,7 +182,8 @@ input[type="checkbox"]:hover {
display: flex;
}
- .search-field-holder {
+ .search-field-holder,
+ .project-filter-form {
-webkit-flex: 1 0 auto;
flex: 1 0 auto;
position: relative;
@@ -201,7 +202,8 @@ input[type="checkbox"]:hover {
pointer-events: none;
}
- .search-text-input {
+ .search-text-input,
+ .project-filter-form-field {
padding-left: $gl-padding + 15px;
padding-right: $gl-padding + 15px;
}
diff --git a/app/controllers/admin/health_check_controller.rb b/app/controllers/admin/health_check_controller.rb
index 241c7be0ea1..caf4c138da8 100644
--- a/app/controllers/admin/health_check_controller.rb
+++ b/app/controllers/admin/health_check_controller.rb
@@ -1,5 +1,5 @@
class Admin::HealthCheckController < Admin::ApplicationController
def show
- @errors = HealthCheck::Utils.process_checks('standard')
+ @errors = HealthCheck::Utils.process_checks(['standard'])
end
end
diff --git a/app/controllers/admin/projects_controller.rb b/app/controllers/admin/projects_controller.rb
index 39c8c6d8a0c..daecfc832bf 100644
--- a/app/controllers/admin/projects_controller.rb
+++ b/app/controllers/admin/projects_controller.rb
@@ -14,6 +14,15 @@ class Admin::ProjectsController < Admin::ApplicationController
@projects = @projects.search(params[:name]) if params[:name].present?
@projects = @projects.sort(@sort = params[:sort])
@projects = @projects.includes(:namespace).order("namespaces.path, projects.name ASC").page(params[:page])
+
+ respond_to do |format|
+ format.html
+ format.json do
+ render json: {
+ html: view_to_html_string("admin/projects/_projects", locals: { projects: @projects })
+ }
+ end
+ end
end
def show
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 32484f810da..cc7b7f247e8 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -122,10 +122,6 @@ class ApplicationController < ActionController::Base
headers['X-XSS-Protection'] = '1; mode=block'
headers['X-UA-Compatible'] = 'IE=edge'
headers['X-Content-Type-Options'] = 'nosniff'
- # Enabling HSTS for non-standard ports would send clients to the wrong port
- if Gitlab.config.gitlab.https && Gitlab.config.gitlab.port == 443
- headers['Strict-Transport-Security'] = 'max-age=31536000'
- end
end
def validate_user_service_ticket!
diff --git a/app/controllers/concerns/creates_commit.rb b/app/controllers/concerns/creates_commit.rb
index f897f828cec..9ac8197e45a 100644
--- a/app/controllers/concerns/creates_commit.rb
+++ b/app/controllers/concerns/creates_commit.rb
@@ -4,10 +4,9 @@ module CreatesCommit
def create_commit(service, success_path:, failure_path:, failure_view: nil, success_notice: nil)
set_commit_variables
- start_branch = @mr_target_branch
commit_params = @commit_params.merge(
start_project: @mr_target_project,
- start_branch: start_branch,
+ start_branch: @mr_target_branch,
target_branch: @mr_source_branch
)
@@ -17,12 +16,16 @@ module CreatesCommit
if result[:status] == :success
update_flash_notice(success_notice)
+ success_path = final_success_path(success_path)
+
respond_to do |format|
- format.html { redirect_to final_success_path(success_path) }
- format.json { render json: { message: "success", filePath: final_success_path(success_path) } }
+ format.html { redirect_to success_path }
+ format.json { render json: { message: "success", filePath: success_path } }
end
else
flash[:alert] = result[:message]
+ failure_path = failure_path.call if failure_path.respond_to?(:call)
+
respond_to do |format|
format.html do
if failure_view
@@ -58,9 +61,13 @@ module CreatesCommit
end
def final_success_path(success_path)
- return success_path unless create_merge_request?
+ if create_merge_request?
+ merge_request_exists? ? existing_merge_request_path : new_merge_request_path
+ else
+ success_path = success_path.call if success_path.respond_to?(:call)
- merge_request_exists? ? existing_merge_request_path : new_merge_request_path
+ success_path
+ end
end
def new_merge_request_path
@@ -92,42 +99,26 @@ module CreatesCommit
end
def create_merge_request?
- # XXX: Even if the field is set, if we're checking the same branch
+ # Even if the field is set, if we're checking the same branch
# as the target branch in the same project,
# we don't want to create a merge request.
params[:create_merge_request].present? &&
- (different_project? || @ref != @target_branch)
+ (different_project? || @mr_target_branch != @mr_source_branch)
end
- # TODO: We should really clean this up
def set_commit_variables
- @mr_source_project =
- if can?(current_user, :push_code, @project)
- # Edit file in this project
- @project
- else
- # Merge request from fork to this project
- current_user.fork_of(@project)
- end
+ if can?(current_user, :push_code, @project)
+ @mr_source_project = @project
+ @target_branch ||= @ref
+ else
+ @mr_source_project = current_user.fork_of(@project)
+ @target_branch ||= @mr_source_project.repository.next_branch('patch')
+ end
# Merge request to this project
@mr_target_project = @project
- @mr_target_branch = @ref || @target_branch
-
- @mr_source_branch = guess_mr_source_branch
- end
+ @mr_target_branch ||= @ref || @target_branch
- def guess_mr_source_branch
- # XXX: Happens when viewing a commit without a branch. In this case,
- # @target_branch would be the default branch for @mr_source_project,
- # however we want a generated new branch here. Thus we can't use
- # @target_branch, but should pass nil to indicate that we want a new
- # branch instead of @target_branch.
- return if
- create_merge_request? &&
- # XXX: Don't understand why rubocop prefers this indention
- @mr_source_project.repository.branch_exists?(@target_branch)
-
- @target_branch
+ @mr_source_branch = @target_branch
end
end
diff --git a/app/controllers/concerns/filter_projects.rb b/app/controllers/concerns/filter_projects.rb
index 586f97c5eb4..6014112256a 100644
--- a/app/controllers/concerns/filter_projects.rb
+++ b/app/controllers/concerns/filter_projects.rb
@@ -8,7 +8,7 @@ module FilterProjects
extend ActiveSupport::Concern
def filter_projects(projects)
- projects = projects.search(params[:filter_projects]) if params[:filter_projects].present?
+ projects = projects.search(params[:name]) if params[:name].present?
projects = projects.non_archived if params[:archived].blank?
projects = projects.personal(current_user) if params[:personal].present? && current_user
diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb
index 7ed54479599..15db5b7762d 100644
--- a/app/controllers/groups_controller.rb
+++ b/app/controllers/groups_controller.rb
@@ -108,7 +108,7 @@ class GroupsController < Groups::ApplicationController
@projects = @projects.sorted_by_activity
@projects = filter_projects(@projects)
@projects = @projects.sort(@sort = params[:sort])
- @projects = @projects.page(params[:page]) if params[:filter_projects].blank?
+ @projects = @projects.page(params[:page]) if params[:name].blank?
end
def authorize_create_group!
diff --git a/app/controllers/profiles_controller.rb b/app/controllers/profiles_controller.rb
index f0c71725ea8..987b95e89b9 100644
--- a/app/controllers/profiles_controller.rb
+++ b/app/controllers/profiles_controller.rb
@@ -47,11 +47,14 @@ class ProfilesController < Profiles::ApplicationController
end
def update_username
- @user.update_attributes(username: user_params[:username])
-
- respond_to do |format|
- format.js
+ if @user.update_attributes(username: user_params[:username])
+ options = { notice: "Username successfully changed" }
+ else
+ message = @user.errors.full_messages.uniq.join('. ')
+ options = { alert: "Username change failed - #{message}" }
end
+
+ redirect_back_or_default(default: { action: 'show' }, options: options)
end
private
diff --git a/app/controllers/projects/blob_controller.rb b/app/controllers/projects/blob_controller.rb
index f9a5ef46786..21ed0660762 100644
--- a/app/controllers/projects/blob_controller.rb
+++ b/app/controllers/projects/blob_controller.rb
@@ -24,7 +24,7 @@ class Projects::BlobController < Projects::ApplicationController
def create
create_commit(Files::CreateService, success_notice: "The file has been successfully created.",
- success_path: namespace_project_blob_path(@project.namespace, @project, File.join(@target_branch, @file_path)),
+ success_path: -> { namespace_project_blob_path(@project.namespace, @project, File.join(@target_branch, @file_path)) },
failure_view: :new,
failure_path: namespace_project_new_blob_path(@project.namespace, @project, @ref))
end
@@ -40,7 +40,7 @@ class Projects::BlobController < Projects::ApplicationController
def update
@path = params[:file_path] if params[:file_path].present?
- create_commit(Files::UpdateService, success_path: after_edit_path,
+ create_commit(Files::UpdateService, success_path: -> { after_edit_path },
failure_view: :edit,
failure_path: namespace_project_blob_path(@project.namespace, @project, @id))
@@ -62,7 +62,7 @@ class Projects::BlobController < Projects::ApplicationController
def destroy
create_commit(Files::DestroyService, success_notice: "The file has been successfully deleted.",
- success_path: namespace_project_tree_path(@project.namespace, @project, @target_branch),
+ success_path: -> { namespace_project_tree_path(@project.namespace, @project, @target_branch) },
failure_view: :show,
failure_path: namespace_project_blob_path(@project.namespace, @project, @id))
end
diff --git a/app/controllers/projects/branches_controller.rb b/app/controllers/projects/branches_controller.rb
index a01c0caa959..c40f9b7f75f 100644
--- a/app/controllers/projects/branches_controller.rb
+++ b/app/controllers/projects/branches_controller.rb
@@ -20,7 +20,7 @@ class Projects::BranchesController < Projects::ApplicationController
respond_to do |format|
format.html
format.json do
- render json: @repository.branch_names
+ render json: @branches.map(&:name)
end
end
end
diff --git a/app/controllers/projects/commit_controller.rb b/app/controllers/projects/commit_controller.rb
index e10d7992db7..cc67f688d51 100644
--- a/app/controllers/projects/commit_controller.rb
+++ b/app/controllers/projects/commit_controller.rb
@@ -51,23 +51,35 @@ class Projects::CommitController < Projects::ApplicationController
def revert
assign_change_commit_vars
- return render_404 if @target_branch.blank?
+ return render_404 if @start_branch.blank?
+
+ @target_branch = create_new_branch? ? @commit.revert_branch_name : @start_branch
+
+ @mr_target_branch = @start_branch
create_commit(Commits::RevertService, success_notice: "The #{@commit.change_type_title(current_user)} has been successfully reverted.",
- success_path: successful_change_path, failure_path: failed_change_path)
+ success_path: -> { successful_change_path }, failure_path: failed_change_path)
end
def cherry_pick
assign_change_commit_vars
- return render_404 if @target_branch.blank?
+ return render_404 if @start_branch.blank?
+
+ @target_branch = create_new_branch? ? @commit.cherry_pick_branch_name : @start_branch
+
+ @mr_target_branch = @start_branch
create_commit(Commits::CherryPickService, success_notice: "The #{@commit.change_type_title(current_user)} has been successfully cherry-picked.",
- success_path: successful_change_path, failure_path: failed_change_path)
+ success_path: -> { successful_change_path }, failure_path: failed_change_path)
end
private
+ def create_new_branch?
+ params[:create_merge_request].present? || !can?(current_user, :push_code, @project)
+ end
+
def successful_change_path
referenced_merge_request_url || namespace_project_commits_url(@project.namespace, @project, @target_branch)
end
@@ -78,7 +90,7 @@ class Projects::CommitController < Projects::ApplicationController
def referenced_merge_request_url
if merge_request = @commit.merged_merge_request(current_user)
- namespace_project_merge_request_url(@project.namespace, @project, merge_request)
+ namespace_project_merge_request_url(merge_request.target_project.namespace, merge_request.target_project, merge_request)
end
end
@@ -94,7 +106,7 @@ class Projects::CommitController < Projects::ApplicationController
@diffs = commit.diffs(opts)
@notes_count = commit.notes.count
-
+
@environment = EnvironmentsFinder.new(@project, current_user, commit: @commit).execute.last
end
@@ -118,11 +130,7 @@ class Projects::CommitController < Projects::ApplicationController
end
def assign_change_commit_vars
- @commit = project.commit(params[:id])
- @target_branch = params[:target_branch]
- @commit_params = {
- commit: @commit,
- create_merge_request: params[:create_merge_request].present? || different_project?
- }
+ @start_branch = params[:start_branch]
+ @commit_params = { commit: @commit }
end
end
diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb
index 76519022381..82f9b6e06db 100644
--- a/app/controllers/projects/merge_requests_controller.rb
+++ b/app/controllers/projects/merge_requests_controller.rb
@@ -324,6 +324,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController
def merge_check
@merge_request.check_if_can_be_merged
+ @pipelines = @merge_request.all_pipelines
render partial: "projects/merge_requests/widget/show.html.haml", layout: false
end
@@ -446,6 +447,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController
def ci_status
pipeline = @merge_request.head_pipeline
+ @pipelines = @merge_request.all_pipelines
if pipeline
status = pipeline.status
@@ -464,7 +466,8 @@ class Projects::MergeRequestsController < Projects::ApplicationController
sha: (merge_request.diff_head_commit.short_id if merge_request.diff_head_sha),
status: status,
coverage: coverage,
- pipeline: pipeline.try(:id)
+ pipeline: pipeline.try(:id),
+ has_ci: @merge_request.has_ci?
}
render json: response
diff --git a/app/controllers/projects/notes_controller.rb b/app/controllers/projects/notes_controller.rb
index 5cf3a7f593b..d00177e7612 100644
--- a/app/controllers/projects/notes_controller.rb
+++ b/app/controllers/projects/notes_controller.rb
@@ -211,6 +211,11 @@ class Projects::NotesController < Projects::ApplicationController
end
def find_current_user_notes
- @notes = NotesFinder.new(project, current_user, params).execute.inc_author
+ @notes = NotesFinder.new(project, current_user, params.merge(last_fetched_at: last_fetched_at))
+ .execute.inc_author
+ end
+
+ def last_fetched_at
+ request.headers['X-Last-Fetched-At']
end
end
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index 70419eb4bde..a3213581498 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -167,7 +167,7 @@ module ApplicationHelper
css_classes = short_format ? 'js-short-timeago' : 'js-timeago'
css_classes << " #{html_class}" unless html_class.blank?
- element = content_tag :time, time.to_s,
+ element = content_tag :time, time.strftime("%b %d, %Y"),
class: css_classes,
title: time.to_time.in_time_zone.to_s(:medium),
datetime: time.to_time.getutc.iso8601,
diff --git a/app/helpers/explore_helper.rb b/app/helpers/explore_helper.rb
index bbcb52f7eaf..7bd212a3ef9 100644
--- a/app/helpers/explore_helper.rb
+++ b/app/helpers/explore_helper.rb
@@ -1,14 +1,19 @@
module ExploreHelper
def filter_projects_path(options = {})
exist_opts = {
- sort: params[:sort],
+ sort: params[:sort] || @sort,
scope: params[:scope],
group: params[:group],
tag: params[:tag],
visibility_level: params[:visibility_level],
+ name: params[:name],
+ personal: params[:personal],
+ archived: params[:archived],
+ shared: params[:shared],
+ namespace_id: params[:namespace_id],
}
- options = exist_opts.merge(options)
+ options = exist_opts.merge(options).delete_if { |key, value| value.blank? }
request_path_with_options(options)
end
diff --git a/app/helpers/mattermost_helper.rb b/app/helpers/mattermost_helper.rb
index 49ac12db832..27ff4051c8d 100644
--- a/app/helpers/mattermost_helper.rb
+++ b/app/helpers/mattermost_helper.rb
@@ -1,9 +1,7 @@
module MattermostHelper
def mattermost_teams_options(teams)
- teams_options = teams.map do |id, options|
- [options['display_name'] || options['name'], id]
+ teams.map do |team|
+ [team['display_name'] || team['name'], team['id']]
end
-
- teams_options.compact.unshift(['Select team...', '0'])
end
end
diff --git a/app/helpers/preferences_helper.rb b/app/helpers/preferences_helper.rb
index c3a08d76318..74cccb23956 100644
--- a/app/helpers/preferences_helper.rb
+++ b/app/helpers/preferences_helper.rb
@@ -35,9 +35,9 @@ module PreferencesHelper
def project_view_choices
[
- ['Readme (default)', :readme],
+ ['Readme', :readme],
['Activity view', :activity],
- ['Files view', :files]
+ ['Files and Readme (default)', :files]
]
end
diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb
index 81bde54d5dc..0f7b8311588 100644
--- a/app/models/merge_request.rb
+++ b/app/models/merge_request.rb
@@ -684,7 +684,10 @@ class MergeRequest < ActiveRecord::Base
end
def has_ci?
- source_project.try(:ci_service) && commits.any?
+ has_ci_integration = source_project.try(:ci_service)
+ uses_gitlab_ci = all_pipelines.any?
+
+ (has_ci_integration || uses_gitlab_ci) && commits.any?
end
def branch_missing?
diff --git a/app/models/note.rb b/app/models/note.rb
index 4c97e4a986c..e22e96aec6f 100644
--- a/app/models/note.rb
+++ b/app/models/note.rb
@@ -85,6 +85,7 @@ class Note < ActiveRecord::Base
before_validation :nullify_blank_type, :nullify_blank_line_code
before_validation :set_discussion_id
after_save :keep_around_commit, unless: :for_personal_snippet?
+ after_save :expire_etag_cache
class << self
def model_name
@@ -272,4 +273,16 @@ class Note < ActiveRecord::Base
self.class.build_discussion_id(noteable_type, noteable_id || commit_id)
end
end
+
+ def expire_etag_cache
+ return unless for_issue?
+
+ key = Gitlab::Routing.url_helpers.namespace_project_noteable_notes_path(
+ noteable.project.namespace,
+ noteable.project,
+ target_type: noteable_type.underscore,
+ target_id: noteable.id
+ )
+ Gitlab::EtagCaching::Store.new.touch(key)
+ end
end
diff --git a/app/models/project_services/kubernetes_service.rb b/app/models/project_services/kubernetes_service.rb
index 9819e723fe8..f2e1c906dac 100644
--- a/app/models/project_services/kubernetes_service.rb
+++ b/app/models/project_services/kubernetes_service.rb
@@ -94,7 +94,12 @@ class KubernetesService < DeploymentService
{ key: 'KUBE_TOKEN', value: token, public: false },
{ key: 'KUBE_NAMESPACE', value: namespace, public: true }
]
- variables << { key: 'KUBE_CA_PEM', value: ca_pem, public: true } if ca_pem.present?
+
+ if ca_pem.present?
+ variables << { key: 'KUBE_CA_PEM', value: ca_pem, public: true }
+ variables << { key: 'KUBE_CA_PEM_FILE', value: ca_pem, public: true, file: true }
+ end
+
variables
end
diff --git a/app/models/repository.rb b/app/models/repository.rb
index d410d60dbad..e7cc8d6e083 100644
--- a/app/models/repository.rb
+++ b/app/models/repository.rb
@@ -6,6 +6,7 @@ class Repository
attr_accessor :path_with_namespace, :project
CommitError = Class.new(StandardError)
+ CreateTreeError = Class.new(StandardError)
# Methods that cache data from the Git repository.
#
@@ -862,17 +863,18 @@ class Repository
end
def revert(
- user, commit, branch_name, revert_tree_id = nil,
+ user, commit, branch_name,
start_branch_name: nil, start_project: project)
- revert_tree_id ||= check_revert_content(commit, branch_name)
-
- return false unless revert_tree_id
-
GitOperationService.new(user, self).with_branch(
branch_name,
start_branch_name: start_branch_name,
start_project: start_project) do |start_commit|
+ revert_tree_id = check_revert_content(commit, start_commit.sha)
+ unless revert_tree_id
+ raise Repository::CreateTreeError.new('Failed to revert commit')
+ end
+
committer = user_to_committer(user)
Rugged::Commit.create(rugged,
@@ -885,17 +887,18 @@ class Repository
end
def cherry_pick(
- user, commit, branch_name, cherry_pick_tree_id = nil,
+ user, commit, branch_name,
start_branch_name: nil, start_project: project)
- cherry_pick_tree_id ||= check_cherry_pick_content(commit, branch_name)
-
- return false unless cherry_pick_tree_id
-
GitOperationService.new(user, self).with_branch(
branch_name,
start_branch_name: start_branch_name,
start_project: start_project) do |start_commit|
+ cherry_pick_tree_id = check_cherry_pick_content(commit, start_commit.sha)
+ unless cherry_pick_tree_id
+ raise Repository::CreateTreeError.new('Failed to cherry-pick commit')
+ end
+
committer = user_to_committer(user)
Rugged::Commit.create(rugged,
@@ -919,9 +922,8 @@ class Repository
end
end
- def check_revert_content(target_commit, branch_name)
- source_sha = commit(branch_name).sha
- args = [target_commit.sha, source_sha]
+ def check_revert_content(target_commit, source_sha)
+ args = [target_commit.sha, source_sha]
args << { mainline: 1 } if target_commit.merge_commit?
revert_index = rugged.revert_commit(*args)
@@ -933,9 +935,8 @@ class Repository
tree_id
end
- def check_cherry_pick_content(target_commit, branch_name)
- source_sha = commit(branch_name).sha
- args = [target_commit.sha, source_sha]
+ def check_cherry_pick_content(target_commit, source_sha)
+ args = [target_commit.sha, source_sha]
args << 1 if target_commit.merge_commit?
cherry_pick_index = rugged.cherrypick_commit(*args)
diff --git a/app/models/user.rb b/app/models/user.rb
index 8443594c055..d3bb04060bf 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -21,6 +21,7 @@ class User < ActiveRecord::Base
default_value_for :can_create_team, false
default_value_for :hide_no_ssh_key, false
default_value_for :hide_no_password, false
+ default_value_for :project_view, :files
attr_encrypted :otp_secret,
key: Gitlab::Application.secrets.otp_key_base,
diff --git a/app/services/ci/retry_build_service.rb b/app/services/ci/retry_build_service.rb
index 38ef323f6e5..89da05b72bb 100644
--- a/app/services/ci/retry_build_service.rb
+++ b/app/services/ci/retry_build_service.rb
@@ -1,18 +1,9 @@
module Ci
class RetryBuildService < ::BaseService
- CLONE_ATTRIBUTES = %i[pipeline project ref tag options commands name
- allow_failure stage stage_idx trigger_request
- yaml_variables when environment coverage_regex]
- .freeze
-
- REJECT_ATTRIBUTES = %i[id status user token coverage trace runner
- artifacts_expire_at artifacts_file
- artifacts_metadata artifacts_size
- created_at updated_at started_at finished_at
- queued_at erased_by erased_at].freeze
-
- IGNORE_ATTRIBUTES = %i[type lock_version gl_project_id target_url
- deploy job_id description].freeze
+ CLONE_ACCESSORS = %i[pipeline project ref tag options commands name
+ allow_failure stage stage_idx trigger_request
+ yaml_variables when environment coverage_regex
+ description tag_list].freeze
def execute(build)
reprocess(build).tap do |new_build|
@@ -31,7 +22,7 @@ module Ci
raise Gitlab::Access::AccessDeniedError
end
- attributes = CLONE_ATTRIBUTES.map do |attribute|
+ attributes = CLONE_ACCESSORS.map do |attribute|
[attribute, build.send(attribute)]
end
diff --git a/app/services/commits/change_service.rb b/app/services/commits/change_service.rb
index 8a9bcd2d053..1297a792259 100644
--- a/app/services/commits/change_service.rb
+++ b/app/services/commits/change_service.rb
@@ -8,9 +8,9 @@ module Commits
@start_branch = params[:start_branch]
@target_branch = params[:target_branch]
@commit = params[:commit]
- @create_merge_request = params[:create_merge_request].present?
- check_push_permissions unless @create_merge_request
+ check_push_permissions
+
commit
rescue Repository::CommitError, Gitlab::Git::Repository::InvalidBlobName, GitHooksService::PreReceiveError,
ValidationError, ChangeError => ex
@@ -26,34 +26,21 @@ module Commits
def commit_change(action)
raise NotImplementedError unless repository.respond_to?(action)
- if @create_merge_request
- into = @commit.public_send("#{action}_branch_name")
- tree_branch = @start_branch
- else
- into = tree_branch = @target_branch
- end
-
- tree_id = repository.public_send(
- "check_#{action}_content", @commit, tree_branch)
-
- if tree_id
- validate_target_branch(into) if @create_merge_request
+ validate_target_branch if different_branch?
- repository.public_send(
- action,
- current_user,
- @commit,
- into,
- tree_id,
- start_project: @start_project,
- start_branch_name: @start_branch)
+ repository.public_send(
+ action,
+ current_user,
+ @commit,
+ @target_branch,
+ start_project: @start_project,
+ start_branch_name: @start_branch)
- success
- else
- error_msg = "Sorry, we cannot #{action.to_s.dasherize} this #{@commit.change_type_title(current_user)} automatically.
+ success
+ rescue Repository::CreateTreeError
+ error_msg = "Sorry, we cannot #{action.to_s.dasherize} this #{@commit.change_type_title(current_user)} automatically.
A #{action.to_s.dasherize} may have already been performed with this #{@commit.change_type_title(current_user)}, or a more recent commit may have updated some of its content."
- raise ChangeError, error_msg
- end
+ raise ChangeError, error_msg
end
def check_push_permissions
@@ -66,16 +53,17 @@ module Commits
true
end
- def validate_target_branch(new_branch)
- # Temporary branch exists and contains the change commit
- return if repository.find_branch(new_branch)
-
+ def validate_target_branch
result = ValidateNewBranchService.new(@project, current_user)
- .execute(new_branch)
+ .execute(@target_branch)
if result[:status] == :error
raise ChangeError, "There was an error creating the source branch: #{result[:message]}"
end
end
+
+ def different_branch?
+ @start_branch != @target_branch || @start_project != @project
+ end
end
end
diff --git a/app/services/projects/update_pages_service.rb b/app/services/projects/update_pages_service.rb
index 2d42c4fc04a..523b9f41916 100644
--- a/app/services/projects/update_pages_service.rb
+++ b/app/services/projects/update_pages_service.rb
@@ -34,6 +34,8 @@ module Projects
end
rescue => e
error(e.message)
+ ensure
+ build.erase_artifacts! unless build.has_expiring_artifacts?
end
private
diff --git a/app/services/system_note_service.rb b/app/services/system_note_service.rb
index db6a092d8fc..8e02fe3741a 100644
--- a/app/services/system_note_service.rb
+++ b/app/services/system_note_service.rb
@@ -385,7 +385,6 @@ module SystemNoteService
# Returns Boolean
def cross_reference_disallowed?(noteable, mentioner)
return true if noteable.is_a?(ExternalIssue) && !noteable.project.jira_tracker_active?
- return true if noteable.is_a?(Issuable) && (noteable.try(:closed?) || noteable.try(:merged?))
return false unless mentioner.is_a?(MergeRequest)
return false unless noteable.is_a?(Commit)
diff --git a/app/views/admin/projects/_projects.html.haml b/app/views/admin/projects/_projects.html.haml
new file mode 100644
index 00000000000..c1a9f8d6ddd
--- /dev/null
+++ b/app/views/admin/projects/_projects.html.haml
@@ -0,0 +1,32 @@
+.js-projects-list-holder
+ - if @projects.any?
+ %ul.projects-list.content-list
+ - @projects.each_with_index do |project|
+ %li.project-row
+ .controls
+ - if project.archived
+ %span.label.label-warning archived
+ %span.badge
+ = storage_counter(project.statistics.storage_size)
+ = link_to 'Edit', edit_namespace_project_path(project.namespace, project), id: "edit_#{dom_id(project)}", class: "btn"
+ = link_to 'Delete', [project.namespace.becomes(Namespace), project], data: { confirm: remove_project_message(project) }, method: :delete, class: "btn btn-remove"
+ .title
+ = link_to [:admin, project.namespace.becomes(Namespace), project] do
+ .dash-project-avatar
+ .avatar-container.s40
+ = project_icon(project, alt: '', class: 'avatar project-avatar s40')
+ %span.project-full-name
+ %span.namespace-name
+ - if project.namespace
+ = project.namespace.human_name
+ \/
+ %span.project-name.filter-title
+ = project.name
+
+ - if project.description.present?
+ .description
+ = markdown_field(project, :description)
+
+ = paginate @projects, theme: 'gitlab'
+ - else
+ .nothing-here-block No projects found
diff --git a/app/views/admin/projects/index.html.haml b/app/views/admin/projects/index.html.haml
index c35945c5a35..3301f55b8a8 100644
--- a/app/views/admin/projects/index.html.haml
+++ b/app/views/admin/projects/index.html.haml
@@ -7,40 +7,24 @@
%div{ class: container_class }
.top-area
.prepend-top-default
- = form_tag admin_projects_path, method: :get do |f|
- .search-holder
- .search-field-holder
- = search_field_tag :name, params[:name], class: "form-control search-text-input js-search-input", id: "dashboard_search", autofocus: true, spellcheck: false, placeholder: 'Search by name'
-
- - if params[:visibility_level].present?
- = hidden_field_tag 'visibility_level', params[:visibility_level]
-
- - if params[:sort].present?
- = hidden_field_tag 'sort', params[:sort]
-
- - if params[:personal].present?
- = hidden_field_tag 'visibility_level', 'true'
-
- - if params[:archived].present?
- = hidden_field_tag 'archived', 'true'
-
- = icon("search", class: "search-icon")
-
- .dropdown
- - toggle_text = 'Namespace'
- - if params[:namespace_id].present?
- - namespace = Namespace.find(params[:namespace_id])
- - toggle_text = "#{namespace.kind}: #{namespace.full_path}"
- = dropdown_toggle(toggle_text, { toggle: 'dropdown' }, { toggle_class: 'js-namespace-select large' })
- .dropdown-menu.dropdown-select.dropdown-menu-align-right
- = dropdown_title('Namespaces')
- = dropdown_filter("Search for Namespace")
- = dropdown_content
- = dropdown_loading
- = render 'shared/projects/dropdown'
- = link_to new_project_path, class: 'btn btn-new' do
- New Project
- = button_tag "Search", class: "btn btn-primary btn-search hide"
+ .search-holder
+ = render 'shared/projects/search_form', autofocus: true, icon: true
+ .dropdown
+ - toggle_text = 'Namespace'
+ - if params[:namespace_id].present?
+ = hidden_field_tag :namespace_id, params[:namespace_id]
+ - namespace = Namespace.find(params[:namespace_id])
+ - toggle_text = "#{namespace.kind}: #{namespace.full_path}"
+ = dropdown_toggle(toggle_text, { toggle: 'dropdown' }, { toggle_class: 'js-namespace-select large' })
+ .dropdown-menu.dropdown-select.dropdown-menu-align-right
+ = dropdown_title('Namespaces')
+ = dropdown_filter("Search for Namespace")
+ = dropdown_content
+ = dropdown_loading
+ = render 'shared/projects/dropdown'
+ = link_to new_project_path, class: 'btn btn-new' do
+ New Project
+ = button_tag "Search", class: "btn btn-primary btn-search hide"
%ul.nav-links
- opts = params[:visibility_level].present? ? {} : { page: admin_projects_path }
@@ -58,35 +42,4 @@
= link_to admin_projects_path(visibility_level: Gitlab::VisibilityLevel::PUBLIC) do
Public
- .projects-list-holder
- - if @projects.any?
- %ul.projects-list.content-list
- - @projects.each_with_index do |project|
- %li.project-row
- .controls
- - if project.archived
- %span.label.label-warning archived
- %span.badge
- = storage_counter(project.statistics.storage_size)
- = link_to 'Edit', edit_namespace_project_path(project.namespace, project), id: "edit_#{dom_id(project)}", class: "btn"
- = link_to 'Delete', [project.namespace.becomes(Namespace), project], data: { confirm: remove_project_message(project) }, method: :delete, class: "btn btn-remove"
- .title
- = link_to [:admin, project.namespace.becomes(Namespace), project] do
- .dash-project-avatar
- .avatar-container.s40
- = project_icon(project, alt: '', class: 'avatar project-avatar s40')
- %span.project-full-name
- %span.namespace-name
- - if project.namespace
- = project.namespace.human_name
- \/
- %span.project-name.filter-title
- = project.name
-
- - if project.description.present?
- .description
- = markdown_field(project, :description)
-
- = paginate @projects, theme: 'gitlab'
- - else
- .nothing-here-block No projects found
+ = render 'projects'
diff --git a/app/views/dashboard/_groups_head.html.haml b/app/views/dashboard/_groups_head.html.haml
index c6d5937a3c3..13eaba41f4c 100644
--- a/app/views/dashboard/_groups_head.html.haml
+++ b/app/views/dashboard/_groups_head.html.haml
@@ -7,8 +7,7 @@
= link_to explore_groups_path, title: 'Explore groups' do
Explore Groups
.nav-controls
- = form_tag request.path, method: :get, class: 'group-filter-form', id: 'group-filter-form' do |f|
- = search_field_tag :filter_groups, params[:filter_groups], placeholder: 'Filter by name...', class: 'group-filter-form-field form-control input-short js-groups-list-filter', spellcheck: false, id: 'group-filter-form-field', tabindex: "2"
+ = render 'shared/groups/search_form'
= render 'shared/groups/dropdown'
- if current_user.can_create_group?
= link_to new_group_path, class: "btn btn-new" do
diff --git a/app/views/dashboard/_projects_head.html.haml b/app/views/dashboard/_projects_head.html.haml
index 48b0fd504f4..600ee63a5c0 100644
--- a/app/views/dashboard/_projects_head.html.haml
+++ b/app/views/dashboard/_projects_head.html.haml
@@ -13,8 +13,7 @@
Explore projects
.nav-controls
- = form_tag request.path, method: :get, class: 'project-filter-form', id: 'project-filter-form' do |f|
- = search_field_tag :filter_projects, params[:filter_projects], placeholder: 'Filter by name...', class: 'project-filter-form-field form-control input-short projects-list-filter', spellcheck: false, id: 'project-filter-form-field', tabindex: "2"
+ = render 'shared/projects/search_form'
= render 'shared/projects/dropdown'
- if current_user.can_create_project?
= link_to new_project_path, class: 'btn btn-new' do
diff --git a/app/views/dashboard/projects/index.html.haml b/app/views/dashboard/projects/index.html.haml
index f0adbad8412..eef794dbd51 100644
--- a/app/views/dashboard/projects/index.html.haml
+++ b/app/views/dashboard/projects/index.html.haml
@@ -5,14 +5,13 @@
- header_title "Projects", dashboard_projects_path
.user-callout{ 'callout-svg' => custom_icon('icon_customization') }
-
-- if @projects.any? || params[:filter_projects]
+- if @projects.any? || params[:name]
= render 'dashboard/projects_head'
- if @last_push
= render "events/event_last_push", event: @last_push
-- if @projects.any? || params[:filter_projects]
+- if @projects.any? || params[:name]
= render 'projects'
- else
= render "zero_authorized_projects"
diff --git a/app/views/explore/groups/_nav.html.haml b/app/views/explore/groups/_nav.html.haml
new file mode 100644
index 00000000000..c8d95b52156
--- /dev/null
+++ b/app/views/explore/groups/_nav.html.haml
@@ -0,0 +1,8 @@
+.top-area
+ %ul.nav-links
+ = nav_link(page: explore_groups_path) do
+ = link_to explore_groups_path do
+ Explore Groups
+ .nav-controls
+ = render 'shared/groups/search_form'
+ = render 'shared/groups/dropdown'
diff --git a/app/views/explore/groups/index.html.haml b/app/views/explore/groups/index.html.haml
index 7f1bacc91cb..8374f5a009f 100644
--- a/app/views/explore/groups/index.html.haml
+++ b/app/views/explore/groups/index.html.haml
@@ -5,7 +5,7 @@
= render 'dashboard/groups_head'
- else
= render 'explore/head'
-
+ = render 'nav'
- if @groups.present?
= render 'groups'
diff --git a/app/views/explore/projects/_nav.html.haml b/app/views/explore/projects/_nav.html.haml
index 614b5431779..e0a2a1e9c96 100644
--- a/app/views/explore/projects/_nav.html.haml
+++ b/app/views/explore/projects/_nav.html.haml
@@ -1,10 +1,17 @@
-%ul.nav-links
- = nav_link(page: [trending_explore_projects_path, explore_root_path]) do
- = link_to trending_explore_projects_path do
- Trending
- = nav_link(page: starred_explore_projects_path) do
- = link_to starred_explore_projects_path do
- Most stars
- = nav_link(page: explore_projects_path) do
- = link_to explore_projects_path do
- All
+.top-area
+ %ul.nav-links
+ = nav_link(page: [trending_explore_projects_path, explore_root_path]) do
+ = link_to trending_explore_projects_path do
+ Trending
+ = nav_link(page: starred_explore_projects_path) do
+ = link_to starred_explore_projects_path do
+ Most stars
+ = nav_link(page: explore_projects_path) do
+ = link_to explore_projects_path do
+ All
+
+ .nav-controls
+ - unless current_user
+ = render 'shared/projects/search_form'
+ = render 'shared/projects/dropdown'
+ = render 'filter'
diff --git a/app/views/explore/projects/index.html.haml b/app/views/explore/projects/index.html.haml
index 42b50481b9d..ec461755103 100644
--- a/app/views/explore/projects/index.html.haml
+++ b/app/views/explore/projects/index.html.haml
@@ -6,10 +6,5 @@
- else
= render 'explore/head'
-.top-area
- = render 'explore/projects/nav'
-
- .nav-controls
- = render 'filter'
-
+= render 'explore/projects/nav'
= render 'projects', projects: @projects
diff --git a/app/views/groups/show.html.haml b/app/views/groups/show.html.haml
index 8f0f2708194..18997baa998 100644
--- a/app/views/groups/show.html.haml
+++ b/app/views/groups/show.html.haml
@@ -11,8 +11,7 @@
.top-area
= render 'groups/show_nav'
.nav-controls
- = form_tag request.path, method: :get, class: 'project-filter-form', id: 'project-filter-form' do |f|
- = search_field_tag :filter_projects, nil, placeholder: 'Filter by name', class: 'projects-list-filter form-control', spellcheck: false
+ = render 'shared/projects/search_form'
= render 'shared/projects/dropdown'
- if can? current_user, :create_projects, @group
= link_to new_project_path(namespace_id: @group.id), class: 'btn btn-new pull-right' do
diff --git a/app/views/layouts/_head.html.haml b/app/views/layouts/_head.html.haml
index 302c1794628..f6d8bb08a64 100644
--- a/app/views/layouts/_head.html.haml
+++ b/app/views/layouts/_head.html.haml
@@ -28,7 +28,9 @@
= stylesheet_link_tag "application", media: "all"
= stylesheet_link_tag "print", media: "print"
- = javascript_include_tag(*webpack_asset_paths("application"))
+ = javascript_include_tag(*webpack_asset_paths("runtime"))
+ = javascript_include_tag(*webpack_asset_paths("common"))
+ = javascript_include_tag(*webpack_asset_paths("main"))
- if content_for?(:page_specific_javascripts)
= yield :page_specific_javascripts
diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml
index 19bd9b6d5c9..36543edc040 100644
--- a/app/views/layouts/application.html.haml
+++ b/app/views/layouts/application.html.haml
@@ -1,7 +1,7 @@
!!! 5
%html{ lang: "en", class: "#{page_class}" }
= render "layouts/head"
- %body{ data: { page: body_data_page, project: "#{@project.path if @project}", group: "#{@group.path if @group}" } }
+ %body{ class: @body_class, data: { page: body_data_page, project: "#{@project.path if @project}", group: "#{@group.path if @group}" } }
= Gon::Base.render_data
= render "layouts/header/default", title: header_title
diff --git a/app/views/profiles/_head.html.haml b/app/views/profiles/_head.html.haml
index 1df04ea614e..83ae9129807 100644
--- a/app/views/profiles/_head.html.haml
+++ b/app/views/profiles/_head.html.haml
@@ -1,3 +1,2 @@
- content_for :page_specific_javascripts do
- = page_specific_javascript_tag('lib/cropper.js')
= page_specific_javascript_bundle_tag('profile')
diff --git a/app/views/profiles/accounts/show.html.haml b/app/views/profiles/accounts/show.html.haml
index 02fb47ec981..8a994f6d600 100644
--- a/app/views/profiles/accounts/show.html.haml
+++ b/app/views/profiles/accounts/show.html.haml
@@ -93,7 +93,7 @@
%p
Changing your username will change path to all personal projects!
.col-lg-9
- = form_for @user, url: update_username_profile_path, method: :put, remote: true, html: {class: "update-username"} do |f|
+ = form_for @user, url: update_username_profile_path, method: :put, html: {class: "update-username"} do |f|
.form-group
= f.label :username, "Path", class: "label-light"
.input-group
diff --git a/app/views/profiles/update_username.js.haml b/app/views/profiles/update_username.js.haml
deleted file mode 100644
index 5307e0b48cb..00000000000
--- a/app/views/profiles/update_username.js.haml
+++ /dev/null
@@ -1,7 +0,0 @@
-- if @user.valid?
- :plain
- new Flash("Username successfully changed", "notice")
-- else
- - error = @user.errors.full_messages.first
- :plain
- new Flash("Username change failed - #{escape_javascript error.html_safe}", "alert")
diff --git a/app/views/projects/boards/_show.html.haml b/app/views/projects/boards/_show.html.haml
index b3bc6010efb..3ae78387938 100644
--- a/app/views/projects/boards/_show.html.haml
+++ b/app/views/projects/boards/_show.html.haml
@@ -3,6 +3,7 @@
- page_title "Boards"
- content_for :page_specific_javascripts do
+ = page_specific_javascript_bundle_tag('common_vue')
= page_specific_javascript_bundle_tag('boards')
= page_specific_javascript_bundle_tag('simulate_drag') if Rails.env.test?
diff --git a/app/views/projects/commit/_change.html.haml b/app/views/projects/commit/_change.html.haml
index 421b3db342d..2ebd4f9069a 100644
--- a/app/views/projects/commit/_change.html.haml
+++ b/app/views/projects/commit/_change.html.haml
@@ -1,10 +1,10 @@
- case type.to_s
- when 'revert'
- label = 'Revert'
- - target_label = 'Revert in branch'
+ - branch_label = 'Revert in branch'
- when 'cherry-pick'
- label = 'Cherry-pick'
- - target_label = 'Pick into branch'
+ - branch_label = 'Pick into branch'
.modal{ id: "modal-#{type}-commit" }
.modal-dialog
@@ -15,10 +15,10 @@
.modal-body
= form_tag [type.underscore, @project.namespace.becomes(Namespace), @project, commit], method: :post, remote: false, class: "form-horizontal js-#{type}-form js-requires-input" do
.form-group.branch
- = label_tag 'target_branch', target_label, class: 'control-label'
+ = label_tag 'start_branch', branch_label, class: 'control-label'
.col-sm-10
- = hidden_field_tag :target_branch, @project.default_branch, id: 'target_branch'
- = dropdown_tag(@project.default_branch, options: { title: "Switch branch", filter: true, placeholder: "Search branches", toggle_class: 'js-project-refs-dropdown js-target-branch dynamic', dropdown_class: 'dropdown-menu-selectable', data: { field_name: "target_branch", selected: @project.default_branch, target_branch: @project.default_branch, refs_url: namespace_project_branches_path(@project.namespace, @project), submit_form_on_click: false } })
+ = hidden_field_tag :start_branch, @project.default_branch, id: 'start_branch'
+ = dropdown_tag(@project.default_branch, options: { title: "Switch branch", filter: true, placeholder: "Search branches", toggle_class: 'js-project-refs-dropdown js-target-branch dynamic', dropdown_class: 'dropdown-menu-selectable', data: { field_name: "start_branch", selected: @project.default_branch, start_branch: @project.default_branch, refs_url: namespace_project_branches_path(@project.namespace, @project), submit_form_on_click: false } })
- if can?(current_user, :push_code, @project)
.js-create-merge-request-container
diff --git a/app/views/projects/commit/_pipelines_list.haml b/app/views/projects/commit/_pipelines_list.haml
index 6792b3f7a83..da5a676274f 100644
--- a/app/views/projects/commit/_pipelines_list.haml
+++ b/app/views/projects/commit/_pipelines_list.haml
@@ -4,4 +4,5 @@
} }
- content_for :page_specific_javascripts do
+ = page_specific_javascript_bundle_tag('common_vue')
= page_specific_javascript_bundle_tag('commit_pipelines')
diff --git a/app/views/projects/cycle_analytics/show.html.haml b/app/views/projects/cycle_analytics/show.html.haml
index be17f2c764e..dd3fa814716 100644
--- a/app/views/projects/cycle_analytics/show.html.haml
+++ b/app/views/projects/cycle_analytics/show.html.haml
@@ -1,6 +1,7 @@
- @no_container = true
- page_title "Cycle Analytics"
- content_for :page_specific_javascripts do
+ = page_specific_javascript_bundle_tag('common_vue')
= page_specific_javascript_bundle_tag('cycle_analytics')
= render "projects/head"
diff --git a/app/views/projects/environments/folder.html.haml b/app/views/projects/environments/folder.html.haml
index d9cb7bc0331..4b101447bc0 100644
--- a/app/views/projects/environments/folder.html.haml
+++ b/app/views/projects/environments/folder.html.haml
@@ -3,6 +3,7 @@
= render "projects/pipelines/head"
- content_for :page_specific_javascripts do
+ = page_specific_javascript_bundle_tag('common_vue')
= page_specific_javascript_bundle_tag("environments_folder")
#environments-folder-list-view{ data: { "can-create-deployment" => can?(current_user, :create_deployment, @project).to_s,
diff --git a/app/views/projects/environments/index.html.haml b/app/views/projects/environments/index.html.haml
index d6366b57957..80d2b6f5d95 100644
--- a/app/views/projects/environments/index.html.haml
+++ b/app/views/projects/environments/index.html.haml
@@ -3,6 +3,7 @@
= render "projects/pipelines/head"
- content_for :page_specific_javascripts do
+ = page_specific_javascript_bundle_tag('common_vue')
= page_specific_javascript_bundle_tag("environments")
#environments-list-view{ data: { environments_data: environments_list_data,
diff --git a/app/views/projects/graphs/charts.html.haml b/app/views/projects/graphs/charts.html.haml
index d3bce45e974..464ac34d961 100644
--- a/app/views/projects/graphs/charts.html.haml
+++ b/app/views/projects/graphs/charts.html.haml
@@ -1,7 +1,7 @@
- @no_container = true
- page_title "Charts"
- content_for :page_specific_javascripts do
- = page_specific_javascript_bundle_tag('lib_chart')
+ = page_specific_javascript_bundle_tag('common_d3')
= page_specific_javascript_bundle_tag('graphs')
= render "projects/commits/head"
diff --git a/app/views/projects/graphs/show.html.haml b/app/views/projects/graphs/show.html.haml
index d89dfe31e47..680f8ae6c8f 100644
--- a/app/views/projects/graphs/show.html.haml
+++ b/app/views/projects/graphs/show.html.haml
@@ -1,7 +1,7 @@
- @no_container = true
- page_title "Contributors"
- content_for :page_specific_javascripts do
- = page_specific_javascript_bundle_tag('lib_chart')
+ = page_specific_javascript_bundle_tag('common_d3')
= page_specific_javascript_bundle_tag('graphs')
= render 'projects/commits/head'
diff --git a/app/views/projects/issues/show.html.haml b/app/views/projects/issues/show.html.haml
index 069f3d97943..d39f36e94c7 100644
--- a/app/views/projects/issues/show.html.haml
+++ b/app/views/projects/issues/show.html.haml
@@ -2,8 +2,6 @@
- page_title "#{@issue.title} (#{@issue.to_reference})", "Issues"
- page_description @issue.description
- page_card_attributes @issue.card_attributes
-- content_for :page_specific_javascripts do
- = page_specific_javascript_bundle_tag('lib_vue')
.clearfix.detail-page-header
.issuable-header
diff --git a/app/views/projects/mattermosts/_team_selection.html.haml b/app/views/projects/mattermosts/_team_selection.html.haml
index a80f9aa4c4a..04bd4e8b683 100644
--- a/app/views/projects/mattermosts/_team_selection.html.haml
+++ b/app/views/projects/mattermosts/_team_selection.html.haml
@@ -2,16 +2,15 @@
This service will be installed on the Mattermost instance at
%strong= link_to Gitlab.config.mattermost.host, Gitlab.config.mattermost.host
%hr
-= form_for(:mattermost, method: :post, url: namespace_project_mattermost_path(@project.namespace, @project)) do |f|
+= form_for(:mattermost, method: :post, url: namespace_project_mattermost_path(@project.namespace, @project), html: { class: 'js-requires-input'} ) do |f|
%h4 Team
%p
= @teams.one? ? 'The team' : 'Select the team'
where the slash commands will be used in
- - selected_id = @teams.one? ? @teams.keys.first : 0
- - options = mattermost_teams_options(@teams)
- - options = options_for_select(options, selected_id)
- = f.select(:team_id, options, {}, { class: 'form-control', disabled: @teams.one?, selected: selected_id })
- = f.hidden_field(:team_id, value: selected_id) if @teams.one?
+ - selected_id = @teams.one? ? @teams.first['id'] : nil
+ - options = options_for_select(mattermost_teams_options(@teams), selected_id)
+ = f.select(:team_id, options, { include_blank: 'Select team...'}, { class: 'form-control', disabled: @teams.one?, selected: selected_id, required: true })
+ = f.hidden_field(:team_id, value: selected_id, required: true) if @teams.one?
.help-block
- if @teams.one?
This is the only available team.
@@ -25,7 +24,7 @@
%hr
%h4 Command trigger word
%p Choose the word that will trigger commands
- = f.text_field(:trigger, value: @project.path, class: 'form-control')
+ = f.text_field(:trigger, value: @project.path, class: 'form-control', required: true)
.help-block
%p
Trigger word must be unique, and can't begin with a slash or contain any spaces.
diff --git a/app/views/projects/mattermosts/new.html.haml b/app/views/projects/mattermosts/new.html.haml
index 96b1d2aee61..15829a3f143 100644
--- a/app/views/projects/mattermosts/new.html.haml
+++ b/app/views/projects/mattermosts/new.html.haml
@@ -1,3 +1,5 @@
+- @body_class = 'card-content'
+
.service-installation
.inline.pull-right
= custom_icon('mattermost_logo', size: 48)
diff --git a/app/views/projects/merge_requests/_show.html.haml b/app/views/projects/merge_requests/_show.html.haml
index 521b0694ca9..03d618327d4 100644
--- a/app/views/projects/merge_requests/_show.html.haml
+++ b/app/views/projects/merge_requests/_show.html.haml
@@ -3,6 +3,7 @@
- page_description @merge_request.description
- page_card_attributes @merge_request.card_attributes
- content_for :page_specific_javascripts do
+ = page_specific_javascript_bundle_tag('common_vue')
= page_specific_javascript_bundle_tag('diff_notes')
.merge-request{ 'data-url' => merge_request_path(@merge_request), 'data-project-path' => project_path(@merge_request.project) }
diff --git a/app/views/projects/merge_requests/conflicts.html.haml b/app/views/projects/merge_requests/conflicts.html.haml
index 1ecd9924d88..51d59280be8 100644
--- a/app/views/projects/merge_requests/conflicts.html.haml
+++ b/app/views/projects/merge_requests/conflicts.html.haml
@@ -1,6 +1,6 @@
- page_title "Merge Conflicts", "#{@merge_request.title} (#{@merge_request.to_reference}", "Merge Requests"
- content_for :page_specific_javascripts do
- = page_specific_javascript_bundle_tag('lib_vue')
+ = page_specific_javascript_bundle_tag('common_vue')
= page_specific_javascript_bundle_tag('merge_conflicts')
= page_specific_javascript_tag('lib/ace.js')
= render "projects/merge_requests/show/mr_title"
diff --git a/app/views/projects/merge_requests/widget/open/_accept.html.haml b/app/views/projects/merge_requests/widget/open/_accept.html.haml
index 1fa987bf537..c94c7944c0b 100644
--- a/app/views/projects/merge_requests/widget/open/_accept.html.haml
+++ b/app/views/projects/merge_requests/widget/open/_accept.html.haml
@@ -1,8 +1,6 @@
- content_for :page_specific_javascripts do
= page_specific_javascript_bundle_tag('merge_request_widget')
-- status_class = @pipeline ? " ci-#{@pipeline.status}" : nil
-
= form_for [:merge, @project.namespace.becomes(Namespace), @project, @merge_request], remote: true, method: :post, html: { class: 'accept-mr-form js-quick-submit js-requires-input' } do |f|
= hidden_field_tag :authenticity_token, form_authenticity_token
= hidden_field_tag :sha, @merge_request.diff_head_sha
@@ -11,10 +9,10 @@
.accept-action
- if @pipeline && @pipeline.active?
%span.btn-group
- = button_tag class: "btn btn-create js-merge-button merge_when_pipeline_succeeds" do
+ = button_tag class: "btn btn-info js-merge-when-pipeline-succeeds-button merge-when-pipeline-succeeds" do
Merge When Pipeline Succeeds
- unless @project.only_allow_merge_if_pipeline_succeeds?
- = button_tag class: "btn btn-success dropdown-toggle", 'data-toggle' => 'dropdown' do
+ = button_tag class: "btn btn-info dropdown-toggle", 'data-toggle' => 'dropdown' do
= icon('caret-down')
%span.sr-only
Select Merge Moment
@@ -24,11 +22,11 @@
= icon('check fw')
Merge When Pipeline Succeeds
%li
- = link_to "#", class: "accept_merge_request" do
+ = link_to "#", class: "accept-merge-request" do
= icon('warning fw')
Merge Immediately
- else
- = f.button class: "btn btn-create btn-grouped js-merge-button accept_merge_request #{status_class}" do
+ = f.button class: "btn btn-grouped js-merge-button accept-merge-request" do
Accept Merge Request
- if @merge_request.force_remove_source_branch?
.accept-control
diff --git a/app/views/projects/milestones/show.html.haml b/app/views/projects/milestones/show.html.haml
index a216d59bc74..b4dde2c86c9 100644
--- a/app/views/projects/milestones/show.html.haml
+++ b/app/views/projects/milestones/show.html.haml
@@ -46,7 +46,7 @@
= preserve do
= markdown_field(@milestone, :description)
- - if @milestone.total_items_count(current_user).zero?
+ - if can?(current_user, :read_issue, @project) && @milestone.total_items_count(current_user).zero?
.alert.alert-success.prepend-top-default
%span Assign some issues to this milestone.
- elsif @milestone.complete?(current_user) && @milestone.active?
diff --git a/app/views/projects/notes/_notes_with_form.html.haml b/app/views/projects/notes/_notes_with_form.html.haml
index 08c73d94a09..90a150aa74c 100644
--- a/app/views/projects/notes/_notes_with_form.html.haml
+++ b/app/views/projects/notes/_notes_with_form.html.haml
@@ -23,4 +23,4 @@
to post a comment
:javascript
- var notes = new Notes("#{namespace_project_notes_path(namespace_id: @project.namespace, project_id: @project, target_id: @noteable.id, target_type: @noteable.class.name.underscore)}", #{@notes.map(&:id).to_json}, #{Time.now.to_i}, "#{diff_view}")
+ var notes = new Notes("#{namespace_project_noteable_notes_path(namespace_id: @project.namespace, project_id: @project, target_id: @noteable.id, target_type: @noteable.class.name.underscore)}", #{@notes.map(&:id).to_json}, #{Time.now.to_i}, "#{diff_view}")
diff --git a/app/views/projects/pipelines/charts.html.haml b/app/views/projects/pipelines/charts.html.haml
index 8ffdfa1a2cf..4a5043aac3c 100644
--- a/app/views/projects/pipelines/charts.html.haml
+++ b/app/views/projects/pipelines/charts.html.haml
@@ -1,7 +1,7 @@
- @no_container = true
- page_title "Charts", "Pipelines"
- content_for :page_specific_javascripts do
- = page_specific_javascript_bundle_tag('lib_chart')
+ = page_specific_javascript_bundle_tag('common_d3')
= page_specific_javascript_bundle_tag('graphs')
= render 'head'
diff --git a/app/views/projects/pipelines/index.html.haml b/app/views/projects/pipelines/index.html.haml
index acb61aa2490..5d59ce06612 100644
--- a/app/views/projects/pipelines/index.html.haml
+++ b/app/views/projects/pipelines/index.html.haml
@@ -50,4 +50,5 @@
.content-list.pipelines{ data: { url: namespace_project_pipelines_path(@project.namespace, @project, format: :json) } }
.vue-pipelines-index
+= page_specific_javascript_bundle_tag('common_vue')
= page_specific_javascript_bundle_tag('vue_pipelines')
diff --git a/app/views/shared/_logo.svg b/app/views/shared/_logo.svg
index 9b67422da2c..10e6c49ae9f 100644
--- a/app/views/shared/_logo.svg
+++ b/app/views/shared/_logo.svg
@@ -1,4 +1,4 @@
-<svg width="36" height="36" class="tanuki-logo">
+<svg width="28" height="28" class="tanuki-logo" viewBox="0 0 36 36">
<path class="tanuki-shape tanuki-left-ear" fill="#e24329" d="M2 14l9.38 9v-9l-4-12.28c-.205-.632-1.176-.632-1.38 0z"/>
<path class="tanuki-shape tanuki-right-ear" fill="#e24329" d="M34 14l-9.38 9v-9l4-12.28c.205-.632 1.176-.632 1.38 0z"/>
<path class="tanuki-shape tanuki-nose" fill="#e24329" d="M18,34.38 3,14 33,14 Z"/>
diff --git a/app/views/shared/groups/_search_form.html.haml b/app/views/shared/groups/_search_form.html.haml
new file mode 100644
index 00000000000..ad7a7faedf1
--- /dev/null
+++ b/app/views/shared/groups/_search_form.html.haml
@@ -0,0 +1,2 @@
+= form_tag request.path, method: :get, class: 'group-filter-form', id: 'group-filter-form' do |f|
+ = search_field_tag :filter_groups, params[:filter_groups], placeholder: 'Filter by name...', class: 'group-filter-form-field form-control input-short js-groups-list-filter', spellcheck: false, id: 'group-filter-form-field', tabindex: "2"
diff --git a/app/views/shared/issuable/_sidebar.html.haml b/app/views/shared/issuable/_sidebar.html.haml
index 37a0c63e514..048fc488207 100644
--- a/app/views/shared/issuable/_sidebar.html.haml
+++ b/app/views/shared/issuable/_sidebar.html.haml
@@ -1,5 +1,6 @@
- todo = issuable_todo(issuable)
- content_for :page_specific_javascripts do
+ = page_specific_javascript_bundle_tag('common_vue')
= page_specific_javascript_bundle_tag('issuable')
%aside.right-sidebar.js-right-sidebar{ data: { "offset-top" => "101", "spy" => "affix" }, class: sidebar_gutter_collapsed_class, 'aria-live' => 'polite' }
diff --git a/app/views/shared/milestones/_summary.html.haml b/app/views/shared/milestones/_summary.html.haml
index d27fba805a3..78079f633d5 100644
--- a/app/views/shared/milestones/_summary.html.haml
+++ b/app/views/shared/milestones/_summary.html.haml
@@ -6,14 +6,15 @@
.milestone-stats-and-buttons
.milestone-stats
- %span.milestone-stat.with-drilldown
- %strong= milestone.issues_visible_to_user(current_user).size
- issues:
- %span.milestone-stat
- %strong= milestone.issues_visible_to_user(current_user).opened.size
- open and
- %strong= milestone.issues_visible_to_user(current_user).closed.size
- closed
+ - if !project || can?(current_user, :read_issue, project)
+ %span.milestone-stat.with-drilldown
+ %strong= milestone.issues_visible_to_user(current_user).size
+ issues:
+ %span.milestone-stat
+ %strong= milestone.issues_visible_to_user(current_user).opened.size
+ open and
+ %strong= milestone.issues_visible_to_user(current_user).closed.size
+ closed
%span.milestone-stat.with-drilldown
%strong= milestone.merge_requests.size
merge requests:
@@ -32,10 +33,12 @@
.milestone-progress-buttons
%span.tab-issues-buttons
- - if project && can?(current_user, :create_issue, project)
- = link_to new_namespace_project_issue_path(project.namespace, project, issue: { milestone_id: milestone.id }), class: "btn", title: "New Issue" do
- New Issue
- = link_to 'Browse Issues', milestones_browse_issuables_path(milestone, type: :issues), class: "btn"
+ - if project
+ - if can?(current_user, :create_issue, project)
+ = link_to new_namespace_project_issue_path(project.namespace, project, issue: { milestone_id: milestone.id }), class: "btn", title: "New Issue" do
+ New Issue
+ - if can?(current_user, :read_issue, project)
+ = link_to 'Browse Issues', milestones_browse_issuables_path(milestone, type: :issues), class: "btn"
%span.tab-merge-requests-buttons.hidden
= link_to 'Browse Merge Requests', milestones_browse_issuables_path(milestone, type: :merge_requests), class: "btn"
diff --git a/app/views/shared/milestones/_tabs.html.haml b/app/views/shared/milestones/_tabs.html.haml
index c8f2319d95a..a0e9ec46220 100644
--- a/app/views/shared/milestones/_tabs.html.haml
+++ b/app/views/shared/milestones/_tabs.html.haml
@@ -1,12 +1,18 @@
%ul.nav-links.no-top.no-bottom
- %li.active
- = link_to '#tab-issues', 'data-toggle' => 'tab', 'data-show' => '.tab-issues-buttons' do
- Issues
- %span.badge= milestone.issues_visible_to_user(current_user).size
- %li
- = link_to '#tab-merge-requests', 'data-toggle' => 'tab', 'data-show' => '.tab-merge-requests-buttons' do
- Merge Requests
- %span.badge= milestone.merge_requests.size
+ - if milestone.is_a?(GlobalMilestone) || can?(current_user, :read_issue, @project)
+ %li.active
+ = link_to '#tab-issues', 'data-toggle' => 'tab', 'data-show' => '.tab-issues-buttons' do
+ Issues
+ %span.badge= milestone.issues_visible_to_user(current_user).size
+ %li
+ = link_to '#tab-merge-requests', 'data-toggle' => 'tab', 'data-show' => '.tab-merge-requests-buttons' do
+ Merge Requests
+ %span.badge= milestone.merge_requests.size
+ - else
+ %li.active
+ = link_to '#tab-merge-requests', 'data-toggle' => 'tab', 'data-show' => '.tab-merge-requests-buttons' do
+ Merge Requests
+ %span.badge= milestone.merge_requests.size
%li
= link_to '#tab-participants', 'data-toggle' => 'tab' do
Participants
@@ -20,10 +26,14 @@
- show_full_project_name = local_assigns.fetch(:show_full_project_name, false)
.tab-content.milestone-content
- .tab-pane.active#tab-issues
- = render 'shared/milestones/issues_tab', issues: milestone.issues_visible_to_user(current_user).include_associations, show_project_name: show_project_name, show_full_project_name: show_full_project_name
- .tab-pane#tab-merge-requests
- = render 'shared/milestones/merge_requests_tab', merge_requests: milestone.merge_requests, show_project_name: show_project_name, show_full_project_name: show_full_project_name
+ - if milestone.is_a?(GlobalMilestone) || can?(current_user, :read_issue, @project)
+ .tab-pane.active#tab-issues
+ = render 'shared/milestones/issues_tab', issues: milestone.issues_visible_to_user(current_user).include_associations, show_project_name: show_project_name, show_full_project_name: show_full_project_name
+ .tab-pane#tab-merge-requests
+ = render 'shared/milestones/merge_requests_tab', merge_requests: milestone.merge_requests, show_project_name: show_project_name, show_full_project_name: show_full_project_name
+ - else
+ .tab-pane.active#tab-merge-requests
+ = render 'shared/milestones/merge_requests_tab', merge_requests: milestone.merge_requests, show_project_name: show_project_name, show_full_project_name: show_full_project_name
.tab-pane#tab-participants
= render 'shared/milestones/participants_tab', users: milestone.participants
.tab-pane#tab-labels
diff --git a/app/views/shared/projects/_dropdown.html.haml b/app/views/shared/projects/_dropdown.html.haml
index c19697802ce..2d25b8aad62 100644
--- a/app/views/shared/projects/_dropdown.html.haml
+++ b/app/views/shared/projects/_dropdown.html.haml
@@ -1,8 +1,4 @@
- @sort ||= sort_value_recently_updated
-- personal = params[:personal]
-- archived = params[:archived]
-- shared = params[:shared]
-- namespace_id = params[:namespace_id]
.dropdown
- toggle_text = projects_sort_options_hash[@sort]
= dropdown_toggle(toggle_text, { toggle: 'dropdown' }, { id: 'sort-projects-dropdown' })
@@ -11,32 +7,32 @@
Sort by
- projects_sort_options_hash.each do |value, title|
%li
- = link_to filter_projects_path(namespace_id: namespace_id, sort: value, archived: archived, personal: personal), class: ("is-active" if @sort == value) do
+ = link_to filter_projects_path(sort: value), class: ("is-active" if @sort == value) do
= title
%li.divider
%li
- = link_to filter_projects_path(namespace_id: namespace_id, sort: @sort, archived: nil), class: ("is-active" unless params[:archived].present?) do
+ = link_to filter_projects_path(archived: nil), class: ("is-active" unless params[:archived].present?) do
Hide archived projects
%li
- = link_to filter_projects_path(namespace_id: namespace_id, sort: @sort, archived: true), class: ("is-active" if params[:archived].present?) do
+ = link_to filter_projects_path(archived: true), class: ("is-active" if params[:archived].present?) do
Show archived projects
- if current_user
%li.divider
%li
- = link_to filter_projects_path(namespace_id: namespace_id, sort: @sort, personal: nil), class: ("is-active" unless personal.present?) do
+ = link_to filter_projects_path(personal: nil), class: ("is-active" unless params[:personal].present?) do
Owned by anyone
%li
- = link_to filter_projects_path(namespace_id: namespace_id, sort: @sort, personal: true), class: ("is-active" if personal.present?) do
+ = link_to filter_projects_path(personal: true), class: ("is-active" if params[:personal].present?) do
Owned by me
- if @group && @group.shared_projects.present?
%li.divider
%li
- = link_to filter_projects_path(namespace_id: namespace_id, sort: @sort, shared: nil), class: ("is-active" unless shared.present?) do
+ = link_to filter_projects_path(shared: nil), class: ("is-active" unless params[:shared].present?) do
All projects
%li
- = link_to filter_projects_path(namespace_id: namespace_id, sort: @sort, shared: 0), class: ("is-active" if shared == '0') do
+ = link_to filter_projects_path(shared: 0), class: ("is-active" if params[:shared] == '0') do
Hide shared projects
%li
- = link_to filter_projects_path(namespace_id: namespace_id, sort: @sort, shared: 1), class: ("is-active" if shared == '1') do
+ = link_to filter_projects_path(shared: 1), class: ("is-active" if params[:shared] == '1') do
Hide group projects
diff --git a/app/views/shared/projects/_list.html.haml b/app/views/shared/projects/_list.html.haml
index 3a9dd37dc7d..c57282c5742 100644
--- a/app/views/shared/projects/_list.html.haml
+++ b/app/views/shared/projects/_list.html.haml
@@ -8,7 +8,7 @@
- show_last_commit_as_description = false unless local_assigns[:show_last_commit_as_description] == true
- remote = false unless local_assigns[:remote] == true
-.projects-list-holder
+.js-projects-list-holder
- if projects.any?
%ul.projects-list.content-list
- projects.each_with_index do |project, i|
@@ -25,6 +25,3 @@
= paginate(projects, remote: remote, theme: "gitlab") if projects.respond_to? :total_pages
- else
.nothing-here-block No projects found
-
-:javascript
- ProjectsList.init();
diff --git a/app/views/shared/projects/_search_form.html.haml b/app/views/shared/projects/_search_form.html.haml
new file mode 100644
index 00000000000..b89194bcc67
--- /dev/null
+++ b/app/views/shared/projects/_search_form.html.haml
@@ -0,0 +1,23 @@
+= form_tag filter_projects_path, method: :get, class: 'project-filter-form', id: 'project-filter-form' do |f|
+ = search_field_tag :name, params[:name],
+ placeholder: 'Filter by name...',
+ class: 'project-filter-form-field form-control input-short js-projects-list-filter',
+ spellcheck: false,
+ id: 'project-filter-form-field',
+ tabindex: "2",
+ autofocus: local_assigns[:autofocus]
+
+ - if local_assigns[:icon]
+ = icon("search", class: "search-icon")
+
+ - if params[:sort].present?
+ = hidden_field_tag :sort, params[:sort]
+
+ - if params[:personal].present?
+ = hidden_field_tag :personal, params[:personal]
+
+ - if params[:archived].present?
+ = hidden_field_tag :archived, params[:archived]
+
+ - if params[:visibility_level].present?
+ = hidden_field_tag :visibility_level, params[:visibility_level]
diff --git a/app/views/users/show.html.haml b/app/views/users/show.html.haml
index af091f9ab88..76cd330e80a 100644
--- a/app/views/users/show.html.haml
+++ b/app/views/users/show.html.haml
@@ -1,7 +1,7 @@
- page_title @user.name
- page_description @user.bio
- content_for :page_specific_javascripts do
- = page_specific_javascript_bundle_tag('lib_d3')
+ = page_specific_javascript_bundle_tag('common_d3')
= page_specific_javascript_bundle_tag('users')
- header_title @user.name, user_path(@user)
- @no_container = true
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
new file mode 100644
index 00000000000..eceb2b9fac6
--- /dev/null
+++ b/changelogs/unreleased/19497-hide-relevant-info-when-project-issues-are-disabled.yml
@@ -0,0 +1,4 @@
+---
+title: Hide issue info when project issues are disabled
+merge_request:
+author: George Andrinopoulos
diff --git a/changelogs/unreleased/26847-api-pipelines-use-basic.yml b/changelogs/unreleased/26847-api-pipelines-use-basic.yml
new file mode 100644
index 00000000000..2034a4ba080
--- /dev/null
+++ b/changelogs/unreleased/26847-api-pipelines-use-basic.yml
@@ -0,0 +1,4 @@
+---
+title: Expose pipelines as PipelineBasic `api/v3/projects/:id/pipelines`
+merge_request: 8875
+author:
diff --git a/changelogs/unreleased/27532_api_changes.yml b/changelogs/unreleased/27532_api_changes.yml
new file mode 100644
index 00000000000..778469d5a86
--- /dev/null
+++ b/changelogs/unreleased/27532_api_changes.yml
@@ -0,0 +1,4 @@
+---
+title: Use iids as filter parameter
+merge_request: 9096
+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
new file mode 100644
index 00000000000..06bb669ceac
--- /dev/null
+++ b/changelogs/unreleased/28010-mr-merge-button-default-to-danger.yml
@@ -0,0 +1,4 @@
+---
+title: Default to subtle MR mege button until CI status is available
+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
new file mode 100644
index 00000000000..bff996172f3
--- /dev/null
+++ b/changelogs/unreleased/28655-current-path-text-is-not-updated-after-setting-the-new-username.yml
@@ -0,0 +1,4 @@
+---
+title: Update account view to display new username
+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
new file mode 100644
index 00000000000..7c64783cbd0
--- /dev/null
+++ b/changelogs/unreleased/28865-filter-by-authorized-projects-in-v4.yml
@@ -0,0 +1,4 @@
+---
+title: Add filter param for project membership for current_user in API v4
+merge_request:
+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
new file mode 100644
index 00000000000..48e62f8f70d
--- /dev/null
+++ b/changelogs/unreleased/28898-fix-search-branches-in-cherry-picking.yml
@@ -0,0 +1,4 @@
+---
+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
new file mode 100644
index 00000000000..ef79fc7d212
--- /dev/null
+++ b/changelogs/unreleased/28935-make-logo-smaller.yml
@@ -0,0 +1,4 @@
+---
+title: Decrease tanuki logo size
+merge_request:
+author:
diff --git a/changelogs/unreleased/3440-remove-hsts-header.yml b/changelogs/unreleased/3440-remove-hsts-header.yml
new file mode 100644
index 00000000000..0310e733f4e
--- /dev/null
+++ b/changelogs/unreleased/3440-remove-hsts-header.yml
@@ -0,0 +1,4 @@
+---
+title: Stop setting Strict-Transport-Securty header from within the app
+merge_request:
+author:
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
new file mode 100644
index 00000000000..1ae1e3c7a7a
--- /dev/null
+++ b/changelogs/unreleased/add-kube-ca-pem-file-deprecate-kube-ca-pem.yml
@@ -0,0 +1,4 @@
+---
+title: Add KUBE_CA_PEM_FILE, deprecate KUBE_CA_PEM
+merge_request: 9398
+author:
diff --git a/changelogs/unreleased/commons-chunk-plugin.yml b/changelogs/unreleased/commons-chunk-plugin.yml
new file mode 100644
index 00000000000..5c11ea3bbb2
--- /dev/null
+++ b/changelogs/unreleased/commons-chunk-plugin.yml
@@ -0,0 +1,5 @@
+---
+title: Use webpack CommonsChunkPlugin to place common javascript libraries in their
+ own bundles
+merge_request: 9647
+author:
diff --git a/changelogs/unreleased/dashboard-filter-search-keep-params.yml b/changelogs/unreleased/dashboard-filter-search-keep-params.yml
new file mode 100644
index 00000000000..a140715b7a2
--- /dev/null
+++ b/changelogs/unreleased/dashboard-filter-search-keep-params.yml
@@ -0,0 +1,4 @@
+---
+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
new file mode 100644
index 00000000000..50b3dd81d60
--- /dev/null
+++ b/changelogs/unreleased/delete-artifacts-for-pages.yml
@@ -0,0 +1,4 @@
+---
+title: Delete artifacts for pages unless expiry date is specified
+merge_request: 9716
+author:
diff --git a/changelogs/unreleased/dm-fix-cherry-pick.yml b/changelogs/unreleased/dm-fix-cherry-pick.yml
new file mode 100644
index 00000000000..e924b821d7e
--- /dev/null
+++ b/changelogs/unreleased/dm-fix-cherry-pick.yml
@@ -0,0 +1,4 @@
+---
+title: Fix cherry-picking or reverting through an MR
+merge_request:
+author:
diff --git a/changelogs/unreleased/dz-change-project-view.yml b/changelogs/unreleased/dz-change-project-view.yml
new file mode 100644
index 00000000000..47e007a80a8
--- /dev/null
+++ b/changelogs/unreleased/dz-change-project-view.yml
@@ -0,0 +1,4 @@
+---
+title: Change default project view for user from readme to files view
+merge_request: 9584
+author:
diff --git a/changelogs/unreleased/etag-notes-polling.yml b/changelogs/unreleased/etag-notes-polling.yml
new file mode 100644
index 00000000000..53990821d25
--- /dev/null
+++ b/changelogs/unreleased/etag-notes-polling.yml
@@ -0,0 +1,4 @@
+---
+title: Use ETag to improve performance of issue notes polling
+merge_request: 9036
+author:
diff --git a/changelogs/unreleased/format-timeago-date.yml b/changelogs/unreleased/format-timeago-date.yml
new file mode 100644
index 00000000000..f331c34abbc
--- /dev/null
+++ b/changelogs/unreleased/format-timeago-date.yml
@@ -0,0 +1,4 @@
+---
+title: Format timeago date to short format
+merge_request:
+author:
diff --git a/changelogs/unreleased/list_issues_with_no_labels.yml b/changelogs/unreleased/list_issues_with_no_labels.yml
new file mode 100644
index 00000000000..ab44841631b
--- /dev/null
+++ b/changelogs/unreleased/list_issues_with_no_labels.yml
@@ -0,0 +1,4 @@
+---
+title: Document ability to list issues with no labels using API
+merge_request: 9697
+author: Vignesh Ravichandran
diff --git a/changelogs/unreleased/remove-es6-extension.yml b/changelogs/unreleased/remove-es6-extension.yml
new file mode 100644
index 00000000000..65f4a7a7867
--- /dev/null
+++ b/changelogs/unreleased/remove-es6-extension.yml
@@ -0,0 +1,4 @@
+---
+title: Remove es6 file extension from JavaScript files
+merge_request: 9241
+author: winniehell
diff --git a/config/application.rb b/config/application.rb
index 45f3b20d214..f1a986d1731 100644
--- a/config/application.rb
+++ b/config/application.rb
@@ -100,7 +100,6 @@ module Gitlab
config.assets.precompile << "katex.js"
config.assets.precompile << "xterm/xterm.css"
config.assets.precompile << "lib/ace.js"
- config.assets.precompile << "lib/cropper.js"
config.assets.precompile << "lib/raphael.js"
config.assets.precompile << "u2f.js"
config.assets.precompile << "vendor/assets/fonts/*"
diff --git a/config/initializers/metrics.rb b/config/initializers/8_metrics.rb
index a1517e6afc8..a1517e6afc8 100644
--- a/config/initializers/metrics.rb
+++ b/config/initializers/8_metrics.rb
diff --git a/config/initializers/etag_caching.rb b/config/initializers/etag_caching.rb
new file mode 100644
index 00000000000..eba88801141
--- /dev/null
+++ b/config/initializers/etag_caching.rb
@@ -0,0 +1,4 @@
+# This middleware has to come after Gitlab::Metrics::RackMiddleware
+# in the middleware stack, because it tracks events with
+# GitLab Performance Monitoring
+Rails.application.config.middleware.use(Gitlab::EtagCaching::Middleware)
diff --git a/config/karma.config.js b/config/karma.config.js
index 2f3cc932413..a23e62f5022 100644
--- a/config/karma.config.js
+++ b/config/karma.config.js
@@ -1,9 +1,10 @@
var path = require('path');
+var webpack = require('webpack');
var webpackConfig = require('./webpack.config.js');
var ROOT_PATH = path.resolve(__dirname, '..');
// add coverage instrumentation to babel config
-if (webpackConfig && webpackConfig.module && webpackConfig.module.rules) {
+if (webpackConfig.module && webpackConfig.module.rules) {
var babelConfig = webpackConfig.module.rules.find(function (rule) {
return rule.loader === 'babel-loader';
});
@@ -13,6 +14,16 @@ if (webpackConfig && webpackConfig.module && webpackConfig.module.rules) {
babelConfig.options.plugins.push('istanbul');
}
+// remove problematic plugins
+if (webpackConfig.plugins) {
+ webpackConfig.plugins = webpackConfig.plugins.filter(function (plugin) {
+ return !(
+ plugin instanceof webpack.optimize.CommonsChunkPlugin ||
+ plugin instanceof webpack.DefinePlugin
+ );
+ });
+}
+
// Karma configuration
module.exports = function(config) {
var progressReporter = process.env.CI ? 'mocha' : 'progress';
diff --git a/config/routes/project.rb b/config/routes/project.rb
index 2703bf4ab46..7dc7963ab88 100644
--- a/config/routes/project.rb
+++ b/config/routes/project.rb
@@ -267,7 +267,7 @@ constraints(ProjectUrlConstrainer.new) do
resources :group_links, only: [:index, :create, :update, :destroy], constraints: { id: /\d+/ }
- resources :notes, only: [:index, :create, :destroy, :update], concerns: :awardable, constraints: { id: /\d+/ } do
+ resources :notes, only: [:create, :destroy, :update], concerns: :awardable, constraints: { id: /\d+/ } do
member do
delete :delete_attachment
post :resolve
@@ -275,6 +275,8 @@ constraints(ProjectUrlConstrainer.new) do
end
end
+ get 'noteable/:target_type/:target_id/notes' => 'notes#index', as: 'noteable_notes'
+
resources :boards, only: [:index, :show] do
scope module: :boards do
resources :issues, only: [:index, :update]
diff --git a/config/webpack.config.js b/config/webpack.config.js
index 13273902b0e..d9fa70c29fb 100644
--- a/config/webpack.config.js
+++ b/config/webpack.config.js
@@ -17,7 +17,10 @@ var WEBPACK_REPORT = process.env.WEBPACK_REPORT;
var config = {
context: path.join(ROOT_PATH, 'app/assets/javascripts'),
entry: {
- application: './application.js',
+ common: './commons/index.js',
+ common_vue: ['vue', 'vue-resource'],
+ common_d3: ['d3'],
+ main: './main.js',
blob_edit: './blob_edit/blob_edit_bundle.js',
boards: './boards/boards_bundle.js',
simulate_drag: './test_utils/simulate_drag.js',
@@ -38,16 +41,13 @@ var config = {
snippet: './snippet/snippet_bundle.js',
terminal: './terminal/terminal_bundle.js',
users: './users/users_bundle.js',
- lib_chart: './lib/chart.js',
- lib_d3: './lib/d3.js',
- lib_vue: './lib/vue_resource.js',
vue_pipelines: './vue_pipelines_index/index.js',
},
output: {
path: path.join(ROOT_PATH, 'public/assets/webpack'),
publicPath: '/assets/webpack/',
- filename: IS_PRODUCTION ? '[name]-[chunkhash].js' : '[name].js'
+ filename: IS_PRODUCTION ? '[name].[chunkhash].bundle.js' : '[name].bundle.js'
},
devtool: 'inline-source-map',
@@ -82,14 +82,56 @@ var config = {
modules: false,
assets: true
}),
+
+ // prevent pikaday from including moment.js
new webpack.IgnorePlugin(/moment/, /pikaday/),
+
+ // fix legacy jQuery plugins which depend on globals
+ new webpack.ProvidePlugin({
+ $: 'jquery',
+ jQuery: 'jquery',
+ }),
+
+ // use deterministic module ids in all environments
+ IS_PRODUCTION ?
+ new webpack.HashedModuleIdsPlugin() :
+ new webpack.NamedModulesPlugin(),
+
+ // create cacheable common library bundle for all vue chunks
+ new webpack.optimize.CommonsChunkPlugin({
+ name: 'common_vue',
+ chunks: [
+ 'boards',
+ 'commit_pipelines',
+ 'cycle_analytics',
+ 'diff_notes',
+ 'environments',
+ 'environments_folder',
+ 'issuable',
+ 'merge_conflicts',
+ 'vue_pipelines',
+ ],
+ minChunks: function(module, count) {
+ return module.resource && (/vue_shared/).test(module.resource);
+ },
+ }),
+
+ // create cacheable common library bundle for all d3 chunks
+ new webpack.optimize.CommonsChunkPlugin({
+ name: 'common_d3',
+ chunks: ['graphs', 'users'],
+ }),
+
+ // create cacheable common library bundles
+ new webpack.optimize.CommonsChunkPlugin({
+ names: ['main', 'common', 'runtime'],
+ }),
],
resolve: {
extensions: ['.js', '.es6', '.js.es6'],
alias: {
'~': path.join(ROOT_PATH, 'app/assets/javascripts'),
- 'bootstrap/js': 'bootstrap-sass/assets/javascripts/bootstrap',
'emoji-aliases$': path.join(ROOT_PATH, 'fixtures/emojis/aliases.json'),
'icons': path.join(ROOT_PATH, 'app/views/shared/icons'),
'vendor': path.join(ROOT_PATH, 'vendor/assets/javascripts'),
diff --git a/db/fixtures/development/13_comments.rb b/db/fixtures/development/13_comments.rb
index 29b8081055d..bc2d74c8034 100644
--- a/db/fixtures/development/13_comments.rb
+++ b/db/fixtures/development/13_comments.rb
@@ -1,7 +1,7 @@
require './spec/support/sidekiq'
Gitlab::Seeder.quiet do
- Issue.all.each do |issue|
+ Issue.find_each do |issue|
project = issue.project
project.team.users.each do |user|
@@ -16,7 +16,7 @@ Gitlab::Seeder.quiet do
end
end
- MergeRequest.all.each do |mr|
+ MergeRequest.find_each do |mr|
project = mr.project
project.team.users.each do |user|
diff --git a/doc/administration/reply_by_email.md b/doc/administration/reply_by_email.md
index 4f5c22e2d29..e99a7ee29cc 100644
--- a/doc/administration/reply_by_email.md
+++ b/doc/administration/reply_by_email.md
@@ -13,7 +13,8 @@ three strategies for this feature:
### Email sub-addressing
-**If your provider or server supports email sub-addressing, we recommend using it.**
+**If your provider or server supports email sub-addressing, we recommend using it.
+Some features (e.g. create new issue via email) only work with sub-addressing.**
[Sub-addressing](https://en.wikipedia.org/wiki/Email_address#Sub-addressing) is
a feature where any email to `user+some_arbitrary_tag@example.com` will end up
@@ -140,12 +141,32 @@ To set up a basic Postfix mail server with IMAP access on Ubuntu, follow the
# The IDLE command timeout.
gitlab_rails['incoming_email_idle_timeout'] = 60
```
+
+ ```ruby
+ # Configuration for Microsoft Exchange mail server w/ IMAP enabled, assumes mailbox incoming@exchange.example.com
+ gitlab_rails['incoming_email_enabled'] = true
+
+ # The email address replies are sent to - Exchange does not support sub-addressing so %{key} is not used here
+ gitlab_rails['incoming_email_address'] = "incoming@exchange.example.com"
+
+ # Email account username
+ # Typically this is the userPrincipalName (UPN)
+ gitlab_rails['incoming_email_email'] = "incoming@ad-domain.example.com"
+ # Email account password
+ gitlab_rails['incoming_email_password'] = "[REDACTED]"
+
+ # IMAP server host
+ gitlab_rails['incoming_email_host'] = "exchange.example.com"
+ # IMAP server port
+ gitlab_rails['incoming_email_port'] = 993
+ # Whether the IMAP server uses SSL
+ gitlab_rails['incoming_email_ssl'] = true
+ ```
-1. Reconfigure GitLab and restart mailroom for the changes to take effect:
+1. Reconfigure GitLab for the changes to take effect:
```sh
sudo gitlab-ctl reconfigure
- sudo gitlab-ctl restart mailroom
```
1. Verify that everything is configured correctly:
@@ -232,6 +253,35 @@ To set up a basic Postfix mail server with IMAP access on Ubuntu, follow the
# The IDLE command timeout.
idle_timeout: 60
```
+
+ ```yaml
+ # Configuration for Microsoft Exchange mail server w/ IMAP enabled, assumes mailbox incoming@exchange.example.com
+ incoming_email:
+ enabled: true
+
+ # The email address replies are sent to - Exchange does not support sub-addressing so %{key} is not used here
+ address: "incoming@exchange.example.com"
+
+ # Email account username
+ # Typically this is the userPrincipalName (UPN)
+ user: "incoming@ad-domain.example.com"
+ # Email account password
+ password: "[REDACTED]"
+
+ # IMAP server host
+ host: "exchange.example.com"
+ # IMAP server port
+ port: 993
+ # Whether the IMAP server uses SSL
+ ssl: true
+ # Whether the IMAP server uses StartTLS
+ start_tls: false
+
+ # The mailbox where incoming mail will end up. Usually "inbox".
+ mailbox: "inbox"
+ # The IDLE command timeout.
+ idle_timeout: 60
+ ```
1. Enable `mail_room` in the init script at `/etc/default/gitlab`:
diff --git a/doc/api/issues.md b/doc/api/issues.md
index 51ce08c873e..0f22d0b7f94 100644
--- a/doc/api/issues.md
+++ b/doc/api/issues.md
@@ -23,6 +23,7 @@ GET /issues?state=closed
GET /issues?labels=foo
GET /issues?labels=foo,bar
GET /issues?labels=foo,bar&state=opened
+GET /projects/:id/issues?labels_name=No+Label
GET /issues?milestone=1.0.0
GET /issues?milestone=1.0.0&state=opened
GET /issues?iids[]=42&iids[]=43
@@ -32,6 +33,7 @@ GET /issues?iids[]=42&iids[]=43
| --------- | ---- | -------- | ----------- |
| `state` | string | no | Return all issues or just those that are `opened` or `closed`|
| `labels` | string | no | Comma-separated list of label names, issues must have all labels to be returned |
+| `labels_name` | string | no | Return all issues with the mentioned label. `No+Label` lists all issues with no labels |
| `milestone` | string| no | The milestone title |
| `iids` | Array[integer] | no | Return only the issues having the given `iid` |
| `order_by`| string | no | Return requests ordered by `created_at` or `updated_at` fields. Default is `created_at` |
@@ -102,6 +104,7 @@ GET /groups/:id/issues?state=closed
GET /groups/:id/issues?labels=foo
GET /groups/:id/issues?labels=foo,bar
GET /groups/:id/issues?labels=foo,bar&state=opened
+GET /projects/:id/issues?labels_name=No+Label
GET /groups/:id/issues?milestone=1.0.0
GET /groups/:id/issues?milestone=1.0.0&state=opened
GET /groups/:id/issues?iids[]=42&iids[]=43
@@ -112,6 +115,7 @@ GET /groups/:id/issues?iids[]=42&iids[]=43
| `id` | integer | yes | The ID of a group |
| `state` | string | no | Return all issues or just those that are `opened` or `closed`|
| `labels` | string | no | Comma-separated list of label names, issues must have all labels to be returned |
+| `labels_name` | string | no | Return all issues with the mentioned label. `No+Label` lists all issues with no labels |
| `iids` | Array[integer] | no | Return only the issues having the given `iid` |
| `milestone` | string| no | The milestone title |
| `order_by`| string | no | Return requests ordered by `created_at` or `updated_at` fields. Default is `created_at` |
@@ -183,6 +187,7 @@ GET /projects/:id/issues?state=closed
GET /projects/:id/issues?labels=foo
GET /projects/:id/issues?labels=foo,bar
GET /projects/:id/issues?labels=foo,bar&state=opened
+GET /projects/:id/issues?labels_name=No+Label
GET /projects/:id/issues?milestone=1.0.0
GET /projects/:id/issues?milestone=1.0.0&state=opened
GET /projects/:id/issues?iids[]=42&iids[]=43
@@ -194,6 +199,7 @@ GET /projects/:id/issues?iids[]=42&iids[]=43
| `iids` | Array[integer] | no | Return only the milestone having the given `iid` |
| `state` | string | no | Return all issues or just those that are `opened` or `closed`|
| `labels` | string | no | Comma-separated list of label names, issues must have all labels to be returned |
+| `labels_name` | string | no | Return all issues with the mentioned label. `No+Label` lists all issues with no labels |
| `milestone` | string| no | The milestone title |
| `order_by`| string | no | Return requests ordered by `created_at` or `updated_at` fields. Default is `created_at` |
| `sort` | string | no | Return requests sorted in `asc` or `desc` order. Default is `desc` |
diff --git a/doc/api/milestones.md b/doc/api/milestones.md
index 9439db84e9b..3c86357a6c3 100644
--- a/doc/api/milestones.md
+++ b/doc/api/milestones.md
@@ -6,8 +6,8 @@ Returns a list of project milestones.
```
GET /projects/:id/milestones
-GET /projects/:id/milestones?iid=42
-GET /projects/:id/milestones?iid[]=42&iid[]=43
+GET /projects/:id/milestones?iids=42
+GET /projects/:id/milestones?iids[]=42&iids[]=43
GET /projects/:id/milestones?state=active
GET /projects/:id/milestones?state=closed
GET /projects/:id/milestones?search=version
@@ -18,7 +18,7 @@ Parameters:
| Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `id` | integer | yes | The ID of a project |
-| `iid` | Array[integer] | optional | Return only the milestone having the given `iid` |
+| `iids` | Array[integer] | optional | Return only the milestones having the given `iids` |
| `state` | string | optional | Return only `active` or `closed` milestones` |
| `search` | string | optional | Return only milestones with a title or description matching the provided string |
diff --git a/doc/api/pipelines.md b/doc/api/pipelines.md
index 9d6f3ea41d9..d809ec032f8 100644
--- a/doc/api/pipelines.md
+++ b/doc/api/pipelines.md
@@ -24,49 +24,13 @@ Example of response
"id": 47,
"status": "pending",
"ref": "new-pipeline",
- "sha": "a91957a858320c0e17f3a0eca7cfacbff50ea29a",
- "before_sha": "a91957a858320c0e17f3a0eca7cfacbff50ea29a",
- "tag": false,
- "yaml_errors": null,
- "user": {
- "name": "Administrator",
- "username": "root",
- "id": 1,
- "state": "active",
- "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",
- "web_url": "http://localhost:3000/root"
- },
- "created_at": "2016-08-16T10:23:19.007Z",
- "updated_at": "2016-08-16T10:23:19.216Z",
- "started_at": null,
- "finished_at": null,
- "committed_at": null,
- "duration": null,
- "coverage": "30.0"
+ "sha": "a91957a858320c0e17f3a0eca7cfacbff50ea29a"
},
{
"id": 48,
"status": "pending",
"ref": "new-pipeline",
- "sha": "eb94b618fb5865b26e80fdd8ae531b7a63ad851a",
- "before_sha": "eb94b618fb5865b26e80fdd8ae531b7a63ad851a",
- "tag": false,
- "yaml_errors": null,
- "user": {
- "name": "Administrator",
- "username": "root",
- "id": 1,
- "state": "active",
- "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",
- "web_url": "http://localhost:3000/root"
- },
- "created_at": "2016-08-16T10:23:21.184Z",
- "updated_at": "2016-08-16T10:23:21.314Z",
- "started_at": null,
- "finished_at": null,
- "committed_at": null,
- "duration": null,
- "coverage": null
+ "sha": "eb94b618fb5865b26e80fdd8ae531b7a63ad851a"
}
]
```
diff --git a/doc/api/projects.md b/doc/api/projects.md
index f6eabc1f663..6062c5ccd71 100644
--- a/doc/api/projects.md
+++ b/doc/api/projects.md
@@ -34,9 +34,10 @@ Parameters:
| `visibility` | string | no | Limit by visibility `public`, `internal`, or `private` |
| `order_by` | string | no | Return projects ordered by `id`, `name`, `path`, `created_at`, `updated_at`, or `last_activity_at` fields. Default is `created_at` |
| `sort` | string | no | Return projects sorted in `asc` or `desc` order. Default is `desc` |
-| `search` | string | no | Return list of authorized projects matching the search criteria |
+| `search` | string | no | Return list of projects matching the search criteria |
| `simple` | boolean | no | Return only the ID, URL, name, and path of each project |
| `owned` | boolean | no | Limit by projects owned by the current user |
+| `membership` | boolean | no | Limit by projects that the current user is a member of |
| `starred` | boolean | no | Limit by projects starred by the current user |
```json
diff --git a/doc/api/v3_to_v4.md b/doc/api/v3_to_v4.md
index 1b51b9200cd..39dc6d98e7b 100644
--- a/doc/api/v3_to_v4.md
+++ b/doc/api/v3_to_v4.md
@@ -28,7 +28,12 @@ changes are in V4:
- `/dockerfiles/:key`
- Moved `/projects/fork/:id` to `/projects/:id/fork` [!8940](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/8940)
- Moved `DELETE /todos` to `POST /todos/mark_as_done` and `DELETE /todos/:todo_id` to `POST /todos/:todo_id/mark_as_done` [!9410](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/9410)
-- Endpoints `/projects/owned`, `/projects/visible`, `/projects/starred` & `/projects/all` are consolidated into `/projects` using query parameters [!8962](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/8962)
+- Project filters are no longer available as `GET /projects/foo`, but as `GET /projects?foo=true` instead [!8962](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/8962)
+ - `GET /projects/visible` & `GET /projects/all` are consolidated into `GET /projects` and can be used with or without authorization
+ - `GET /projects/owned` moved to `GET /projects?owned=true`
+ - `GET /projects/starred` moved to `GET /projects?starred=true`
+- `GET /projects` returns all projects visible to current user, even if the user is not a member [!9674](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/9674)
+ - To get projects the user is a member of, use `/projects?membership=true`
- Return pagination headers for all endpoints that return an array [!8606](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/8606)
- Added `POST /environments/:environment_id/stop` to stop an environment [!8808](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/8808)
- Removed `DELETE projects/:id/deploy_keys/:key_id/disable`. Use `DELETE projects/:id/deploy_keys/:key_id` instead [!9366](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/9366)
@@ -52,3 +57,5 @@ changes are in V4:
- Return HTTP status code `400` for all validation errors when creating or updating a member instead of sometimes `422` error. [!9523](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/9523)
- Remove `GET /groups/owned`. Use `GET /groups?owned=true` instead [!9505](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/9505)
- Return 202 with JSON body on async removals on V4 API (DELETE `/projects/:id/repository/merged_branches` and DELETE `/projects/:id`) [!9449](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/9449)
+- `projects/:id/milestones?iid[]=x&iid[]=y` array filter has been renamed to `iids` [!9096](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/9096)
+- Return basic info about pipeline in `GET /projects/:id/pipelines` [!8875](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/8875)
diff --git a/doc/development/instrumentation.md b/doc/development/instrumentation.md
index b8669964c84..a14c0752366 100644
--- a/doc/development/instrumentation.md
+++ b/doc/development/instrumentation.md
@@ -35,7 +35,7 @@ Using this method is in general preferred over directly calling the various
instrumentation methods.
Method instrumentation should be added in the initializer
-`config/initializers/metrics.rb`.
+`config/initializers/8_metrics.rb`.
### Examples
diff --git a/doc/development/limit_ee_conflicts.md b/doc/development/limit_ee_conflicts.md
index e3568b65b18..51b4b398f2c 100644
--- a/doc/development/limit_ee_conflicts.md
+++ b/doc/development/limit_ee_conflicts.md
@@ -53,9 +53,12 @@ Notes:
- Code reviews for merge requests often consist of multiple iterations of
feedback and fixes. There is no need to update your EE MR after each
iteration. Instead, create an EE MR as soon as you see the
- `rake ee_compat_check` job failing and update it after the CE MR is merged.
+ `rake ee_compat_check` job failing. After you receive the final acceptance
+ from a Maintainer (but before the CE MR is merged) update the EE MR.
This helps to identify significant conflicts sooner, but also reduces the
number of times you have to resolve conflicts.
+- You can use [`git rerere`](https://git-scm.com/blog/2010/03/08/rerere.html)
+ to avoid resolving the same conflicts multiple times.
## Possible type of conflicts
diff --git a/doc/update/8.17-to-9.0.md b/doc/update/8.17-to-9.0.md
new file mode 100644
index 00000000000..7b934ecd87a
--- /dev/null
+++ b/doc/update/8.17-to-9.0.md
@@ -0,0 +1,24 @@
+#### Nginx configuration
+
+Ensure you're still up-to-date with the latest NGINX configuration changes:
+
+```sh
+cd /home/git/gitlab
+
+# For HTTPS configurations
+git diff origin/8-17-stable:lib/support/nginx/gitlab-ssl origin/9-0-stable:lib/support/nginx/gitlab-ssl
+
+# For HTTP configurations
+git diff origin/8-17-stable:lib/support/nginx/gitlab origin/9-0-stable:lib/support/nginx/gitlab
+```
+
+If you are using Strict-Transport-Security in your installation to continue using it you must enable it in your Nginx
+configuration as GitLab application no longer handles setting it.
+
+If you are using Apache instead of NGINX please see the updated [Apache templates].
+Also note that because Apache does not support upstreams behind Unix sockets you
+will need to let gitlab-workhorse listen on a TCP port. You can do this
+via [/etc/default/gitlab].
+
+[Apache templates]: https://gitlab.com/gitlab-org/gitlab-recipes/tree/master/web-server/apache
+[/etc/default/gitlab]: https://gitlab.com/gitlab-org/gitlab-ce/blob/9-0-stable/lib/support/init.d/gitlab.default.example#L38
diff --git a/doc/user/project/integrations/kubernetes.md b/doc/user/project/integrations/kubernetes.md
index cc67e667472..2a890acde4d 100644
--- a/doc/user/project/integrations/kubernetes.md
+++ b/doc/user/project/integrations/kubernetes.md
@@ -49,7 +49,8 @@ GitLab CI build environment:
- `KUBE_URL` - equal to the API URL
- `KUBE_TOKEN`
- `KUBE_NAMESPACE`
-- `KUBE_CA_PEM` - only if a custom CA bundle was specified
+- `KUBE_CA_PEM_FILE` - only present if a custom CA bundle was specified. Path to a file containing PEM data.
+- `KUBE_CA_PEM` (deprecated)- only if a custom CA bundle was specified. Raw PEM data.
## Web terminals
diff --git a/doc/user/project/pages/getting_started_part_four.md b/doc/user/project/pages/getting_started_part_four.md
index 6edf99239ea..35af48724f2 100644
--- a/doc/user/project/pages/getting_started_part_four.md
+++ b/doc/user/project/pages/getting_started_part_four.md
@@ -133,6 +133,9 @@ your Jekyll 3.4.0 site with GitLab Pages. This is the minimum
configuration for our example. On the steps below, we'll refine
the script by adding extra options to our GitLab CI.
+Artifacts will be automatically deleted once GitLab Pages got deployed.
+You can preserve artifacts for limited time by specifying the expiry time.
+
### Image
At this point, you probably ask yourself: "okay, but to install Jekyll
diff --git a/features/steps/project/commits/revert.rb b/features/steps/project/commits/revert.rb
index 94a5d4e2e4d..c9746407344 100644
--- a/features/steps/project/commits/revert.rb
+++ b/features/steps/project/commits/revert.rb
@@ -36,5 +36,6 @@ class Spinach::Features::RevertCommits < Spinach::FeatureSteps
step 'I should see the new merge request notice' do
page.should have_content('The commit has been successfully reverted. You can now submit a merge request to get this change into the original branch.')
+ page.should have_content("From revert-#{Commit.truncate_sha(sample_commit.id)} into master")
end
end
diff --git a/features/steps/project/fork.rb b/features/steps/project/fork.rb
index 9a6c04fba7a..79db9728227 100644
--- a/features/steps/project/fork.rb
+++ b/features/steps/project/fork.rb
@@ -56,7 +56,7 @@ class Spinach::Features::ProjectFork < Spinach::FeatureSteps
end
step 'I should see my fork on the list' do
- page.within('.projects-list-holder') do
+ page.within('.js-projects-list-holder') do
project = @user.fork_of(@project)
expect(page).to have_content("#{project.namespace.human_name} / #{project.name}")
end
diff --git a/features/steps/shared/project.rb b/features/steps/shared/project.rb
index dae248b8b7e..345a28f27dc 100644
--- a/features/steps/shared/project.rb
+++ b/features/steps/shared/project.rb
@@ -166,11 +166,15 @@ module SharedProject
end
step 'I should see project "Internal"' do
- expect(page).to have_content "Internal"
+ page.within '.js-projects-list-holder' do
+ expect(page).to have_content "Internal"
+ end
end
step 'I should not see project "Internal"' do
- expect(page).not_to have_content "Internal"
+ page.within '.js-projects-list-holder' do
+ expect(page).not_to have_content "Internal"
+ end
end
step 'public project "Community"' do
diff --git a/lib/api/api.rb b/lib/api/api.rb
index 02f7bc2fbbf..89449ce8813 100644
--- a/lib/api/api.rb
+++ b/lib/api/api.rb
@@ -20,7 +20,9 @@ module API
mount ::API::V3::MergeRequestDiffs
mount ::API::V3::MergeRequests
mount ::API::V3::Notes
+ mount ::API::V3::Pipelines
mount ::API::V3::ProjectHooks
+ mount ::API::V3::Milestones
mount ::API::V3::Projects
mount ::API::V3::ProjectSnippets
mount ::API::V3::Repositories
diff --git a/lib/api/commits.rb b/lib/api/commits.rb
index fd03e92264d..b0aa10f8bf2 100644
--- a/lib/api/commits.rb
+++ b/lib/api/commits.rb
@@ -127,7 +127,7 @@ module API
commit_params = {
commit: commit,
- create_merge_request: false,
+ start_branch: params[:branch],
target_branch: params[:branch]
}
diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb
index 4600abc7dc7..9c41146f1e3 100644
--- a/lib/api/helpers.rb
+++ b/lib/api/helpers.rb
@@ -252,6 +252,10 @@ module API
# project helpers
def filter_projects(projects)
+ if params[:membership]
+ projects = projects.merge(current_user.authorized_projects)
+ end
+
if params[:owned]
projects = projects.merge(current_user.owned_projects)
end
diff --git a/lib/api/milestones.rb b/lib/api/milestones.rb
index 44bdaea7fa4..bd74174c655 100644
--- a/lib/api/milestones.rb
+++ b/lib/api/milestones.rb
@@ -30,7 +30,7 @@ module API
params do
optional :state, type: String, values: %w[active closed all], default: 'all',
desc: 'Return "active", "closed", or "all" milestones'
- optional :iid, type: Array[Integer], desc: 'The IID of the milestone'
+ optional :iids, type: Array[Integer], desc: 'The IIDs of the milestones'
optional :search, type: String, desc: 'The search criteria for the title or description of the milestone'
use :pagination
end
@@ -39,7 +39,7 @@ module API
milestones = user_project.milestones
milestones = filter_milestones_state(milestones, params[:state])
- milestones = filter_by_iid(milestones, params[:iid]) if params[:iid].present?
+ milestones = filter_by_iid(milestones, params[:iids]) if params[:iids].present?
milestones = filter_by_search(milestones, params[:search]) if params[:search]
present paginate(milestones), with: Entities::Milestone
diff --git a/lib/api/pipelines.rb b/lib/api/pipelines.rb
index 3afc1e385fe..0721b975ba4 100644
--- a/lib/api/pipelines.rb
+++ b/lib/api/pipelines.rb
@@ -10,7 +10,7 @@ module API
resource :projects do
desc 'Get all Pipelines of the project' do
detail 'This feature was introduced in GitLab 8.11.'
- success Entities::Pipeline
+ success Entities::PipelineBasic
end
params do
use :pagination
@@ -21,7 +21,7 @@ module API
authorize! :read_pipeline, user_project
pipelines = PipelinesFinder.new(user_project).execute(scope: params[:scope])
- present paginate(pipelines), with: Entities::Pipeline
+ present paginate(pipelines), with: Entities::PipelineBasic
end
desc 'Create a new pipeline' do
diff --git a/lib/api/projects.rb b/lib/api/projects.rb
index f302496c12b..63a4cdd5954 100644
--- a/lib/api/projects.rb
+++ b/lib/api/projects.rb
@@ -46,9 +46,10 @@ module API
optional :archived, type: Boolean, default: false, desc: 'Limit by archived status'
optional :visibility, type: String, values: Gitlab::VisibilityLevel.string_values,
desc: 'Limit by visibility'
- optional :search, type: String, desc: 'Return list of authorized projects matching the search criteria'
+ optional :search, type: String, desc: 'Return list of projects matching the search criteria'
optional :owned, type: Boolean, default: false, desc: 'Limit by owned by authenticated user'
optional :starred, type: Boolean, default: false, desc: 'Limit by starred status'
+ optional :membership, type: Boolean, default: false, desc: 'Limit by projects that the current user is a member of'
end
params :statistics_params do
diff --git a/lib/api/v3/commits.rb b/lib/api/v3/commits.rb
index 506204b3517..d254d247042 100644
--- a/lib/api/v3/commits.rb
+++ b/lib/api/v3/commits.rb
@@ -130,9 +130,7 @@ module API
commit_params = {
commit: commit,
- create_merge_request: false,
- source_project: user_project,
- source_branch: commit.cherry_pick_branch_name,
+ start_branch: params[:branch],
target_branch: params[:branch]
}
diff --git a/lib/api/v3/milestones.rb b/lib/api/v3/milestones.rb
new file mode 100644
index 00000000000..bbc29c40ee2
--- /dev/null
+++ b/lib/api/v3/milestones.rb
@@ -0,0 +1,43 @@
+module API
+ module V3
+ class Milestones < Grape::API
+ include PaginationParams
+
+ before { authenticate! }
+
+ helpers do
+ def filter_milestones_state(milestones, state)
+ case state
+ when 'active' then milestones.active
+ when 'closed' then milestones.closed
+ else milestones
+ end
+ end
+ end
+
+ params do
+ requires :id, type: String, desc: 'The ID of a project'
+ end
+ resource :projects do
+ desc 'Get a list of project milestones' do
+ success ::API::Entities::Milestone
+ end
+ params do
+ optional :state, type: String, values: %w[active closed all], default: 'all',
+ desc: 'Return "active", "closed", or "all" milestones'
+ optional :iid, type: Array[Integer], desc: 'The IID of the milestone'
+ use :pagination
+ end
+ get ":id/milestones" do
+ authorize! :read_milestone, user_project
+
+ milestones = user_project.milestones
+ milestones = filter_milestones_state(milestones, params[:state])
+ milestones = filter_by_iid(milestones, params[:iid]) if params[:iid].present?
+
+ present paginate(milestones), with: ::API::Entities::Milestone
+ end
+ end
+ end
+ end
+end
diff --git a/lib/api/v3/pipelines.rb b/lib/api/v3/pipelines.rb
new file mode 100644
index 00000000000..2c26a5f7d35
--- /dev/null
+++ b/lib/api/v3/pipelines.rb
@@ -0,0 +1,36 @@
+module API
+ module V3
+ class Pipelines < Grape::API
+ include PaginationParams
+
+ before { authenticate! }
+
+ params do
+ requires :id, type: String, desc: 'The project ID'
+ end
+ resource :projects do
+ desc 'Get all Pipelines of the project' do
+ detail 'This feature was introduced in GitLab 8.11.'
+ success ::API::Entities::Pipeline
+ end
+ params do
+ use :pagination
+ optional :scope, type: String, values: %w(running branches tags),
+ desc: 'Either running, branches, or tags'
+ end
+ get ':id/pipelines' do
+ authorize! :read_pipeline, user_project
+
+ pipelines = PipelinesFinder.new(user_project).execute(scope: params[:scope])
+ present paginate(pipelines), with: ::API::Entities::Pipeline
+ end
+ end
+
+ helpers do
+ def pipeline
+ @pipeline ||= user_project.pipelines.find(params[:pipeline_id])
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/etag_caching/middleware.rb b/lib/gitlab/etag_caching/middleware.rb
new file mode 100644
index 00000000000..0f24f9bbfde
--- /dev/null
+++ b/lib/gitlab/etag_caching/middleware.rb
@@ -0,0 +1,66 @@
+module Gitlab
+ module EtagCaching
+ class Middleware
+ RESERVED_WORDS = ProjectPathValidator::RESERVED.map { |word| "/#{word}/" }.join('|')
+ ROUTE_REGEXP = Regexp.union(
+ %r(^(?!.*(#{RESERVED_WORDS})).*/noteable/issue/\d+/notes\z)
+ )
+
+ def initialize(app)
+ @app = app
+ end
+
+ def call(env)
+ return @app.call(env) unless enabled_for_current_route?(env)
+ Gitlab::Metrics.add_event(:etag_caching_middleware_used)
+
+ etag, cached_value_present = get_etag(env)
+ if_none_match = env['HTTP_IF_NONE_MATCH']
+
+ if if_none_match == etag
+ Gitlab::Metrics.add_event(:etag_caching_cache_hit)
+ [304, { 'ETag' => etag }, ['']]
+ else
+ track_cache_miss(if_none_match, cached_value_present)
+
+ status, headers, body = @app.call(env)
+ headers['ETag'] = etag
+ [status, headers, body]
+ end
+ end
+
+ private
+
+ def enabled_for_current_route?(env)
+ ROUTE_REGEXP.match(env['PATH_INFO'])
+ end
+
+ def get_etag(env)
+ cache_key = env['PATH_INFO']
+ store = Store.new
+ current_value = store.get(cache_key)
+ cached_value_present = current_value.present?
+
+ unless cached_value_present
+ current_value = store.touch(cache_key, only_if_missing: true)
+ end
+
+ [weak_etag_format(current_value), cached_value_present]
+ end
+
+ def weak_etag_format(value)
+ %Q{W/"#{value}"}
+ end
+
+ def track_cache_miss(if_none_match, cached_value_present)
+ if if_none_match.blank?
+ Gitlab::Metrics.add_event(:etag_caching_header_missing)
+ elsif !cached_value_present
+ Gitlab::Metrics.add_event(:etag_caching_key_not_found)
+ else
+ Gitlab::Metrics.add_event(:etag_caching_resource_changed)
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/etag_caching/store.rb b/lib/gitlab/etag_caching/store.rb
new file mode 100644
index 00000000000..9532e432f78
--- /dev/null
+++ b/lib/gitlab/etag_caching/store.rb
@@ -0,0 +1,32 @@
+module Gitlab
+ module EtagCaching
+ class Store
+ EXPIRY_TIME = 10.minutes
+ REDIS_NAMESPACE = 'etag:'.freeze
+
+ def get(key)
+ Gitlab::Redis.with { |redis| redis.get(redis_key(key)) }
+ end
+
+ def touch(key, only_if_missing: false)
+ etag = generate_etag
+
+ Gitlab::Redis.with do |redis|
+ redis.set(redis_key(key), etag, ex: EXPIRY_TIME, nx: only_if_missing)
+ end
+
+ etag
+ end
+
+ private
+
+ def generate_etag
+ SecureRandom.hex
+ end
+
+ def redis_key(key)
+ "#{REDIS_NAMESPACE}#{key}"
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/seeder.rb b/lib/gitlab/seeder.rb
index b7f825e8284..823f697f51c 100644
--- a/lib/gitlab/seeder.rb
+++ b/lib/gitlab/seeder.rb
@@ -1,24 +1,23 @@
+module DeliverNever
+ def deliver_later
+ self
+ end
+end
+
module Gitlab
class Seeder
def self.quiet
mute_mailer
SeedFu.quiet = true
+
yield
+
SeedFu.quiet = false
puts "\nOK".color(:green)
end
- def self.by_user(user)
- yield
- end
-
def self.mute_mailer
- code = <<-eos
-def Notify.deliver_later
- self
-end
- eos
- eval(code) # rubocop:disable Security/Eval
+ ActionMailer::MessageDelivery.prepend(DeliverNever)
end
end
end
diff --git a/lib/gitlab/sidekiq_status.rb b/lib/gitlab/sidekiq_status.rb
index aadc401ff8d..11e5f1b645c 100644
--- a/lib/gitlab/sidekiq_status.rb
+++ b/lib/gitlab/sidekiq_status.rb
@@ -44,19 +44,42 @@ module Gitlab
# Returns true if all the given job have been completed.
#
- # jids - The Sidekiq job IDs to check.
+ # job_ids - The Sidekiq job IDs to check.
#
# Returns true or false.
- def self.all_completed?(jids)
- keys = jids.map { |jid| key_for(jid) }
+ def self.all_completed?(job_ids)
+ self.num_running(job_ids).zero?
+ end
+
+ # Returns the number of jobs that are running.
+ #
+ # job_ids - The Sidekiq job IDs to check.
+ def self.num_running(job_ids)
+ responses = self.job_status(job_ids)
- responses = Sidekiq.redis do |redis|
+ responses.select(&:present?).count
+ end
+
+ # Returns the number of jobs that have completed.
+ #
+ # job_ids - The Sidekiq job IDs to check.
+ def self.num_completed(job_ids)
+ job_ids.size - self.num_running(job_ids)
+ end
+
+ # Returns the job status for each of the given job IDs.
+ #
+ # job_ids - The Sidekiq job IDs to check.
+ #
+ # Returns an array of true or false indicating job completion.
+ def self.job_status(job_ids)
+ keys = job_ids.map { |jid| key_for(jid) }
+
+ Sidekiq.redis do |redis|
redis.pipelined do
keys.each { |key| redis.exists(key) }
end
end
-
- responses.all? { |value| !value }
end
def self.key_for(jid)
diff --git a/lib/mattermost/team.rb b/lib/mattermost/team.rb
index 09dfd082b3a..afc152aa02e 100644
--- a/lib/mattermost/team.rb
+++ b/lib/mattermost/team.rb
@@ -1,7 +1,7 @@
module Mattermost
class Team < Client
def all
- session_get('/api/v3/teams/all')
+ session_get('/api/v3/teams/all').values
end
end
end
diff --git a/lib/support/nginx/gitlab-ssl b/lib/support/nginx/gitlab-ssl
index 5661394058d..330031aaddc 100644
--- a/lib/support/nginx/gitlab-ssl
+++ b/lib/support/nginx/gitlab-ssl
@@ -82,6 +82,9 @@ server {
##
# ssl_dhparam /etc/ssl/certs/dhparam.pem;
+ ## [Optional] Enable HTTP Strict Transport Security
+ # add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";
+
## Individual nginx logs for this GitLab vhost
access_log /var/log/nginx/gitlab_access.log;
error_log /var/log/nginx/gitlab_error.log;
diff --git a/spec/controllers/health_check_controller_spec.rb b/spec/controllers/health_check_controller_spec.rb
index cfe18dd4b6c..58c16cc57e6 100644
--- a/spec/controllers/health_check_controller_spec.rb
+++ b/spec/controllers/health_check_controller_spec.rb
@@ -64,8 +64,8 @@ describe HealthCheckController do
context 'when a service is down and an access token is provided' do
before do
- allow(HealthCheck::Utils).to receive(:process_checks).with('standard').and_return('The server is on fire')
- allow(HealthCheck::Utils).to receive(:process_checks).with('email').and_return('Email is on fire')
+ allow(HealthCheck::Utils).to receive(:process_checks).with(['standard']).and_return('The server is on fire')
+ allow(HealthCheck::Utils).to receive(:process_checks).with(['email']).and_return('Email is on fire')
end
it 'supports passing the token in the header' do
diff --git a/spec/controllers/projects/branches_controller_spec.rb b/spec/controllers/projects/branches_controller_spec.rb
index e70737376af..298a7ff179c 100644
--- a/spec/controllers/projects/branches_controller_spec.rb
+++ b/spec/controllers/projects/branches_controller_spec.rb
@@ -244,4 +244,27 @@ describe Projects::BranchesController do
end
end
end
+
+ describe "GET index" do
+ render_views
+
+ before do
+ sign_in(user)
+ end
+
+ context 'when rendering a JSON format' do
+ it 'filters branches by name' do
+ get :index,
+ namespace_id: project.namespace,
+ project_id: project,
+ format: :json,
+ search: 'master'
+
+ parsed_response = JSON.parse(response.body)
+
+ expect(parsed_response.length).to eq 1
+ expect(parsed_response.first).to eq 'master'
+ end
+ end
+ end
end
diff --git a/spec/controllers/projects/commit_controller_spec.rb b/spec/controllers/projects/commit_controller_spec.rb
index 640baa3a01c..b223a22ae60 100644
--- a/spec/controllers/projects/commit_controller_spec.rb
+++ b/spec/controllers/projects/commit_controller_spec.rb
@@ -166,7 +166,7 @@ describe Projects::CommitController do
post(:revert,
namespace_id: project.namespace,
project_id: project,
- target_branch: 'master',
+ start_branch: 'master',
id: commit.id)
expect(response).to redirect_to namespace_project_commits_path(project.namespace, project, 'master')
@@ -179,7 +179,7 @@ describe Projects::CommitController do
post(:revert,
namespace_id: project.namespace,
project_id: project,
- target_branch: 'master',
+ start_branch: 'master',
id: commit.id)
end
@@ -188,7 +188,7 @@ describe Projects::CommitController do
post(:revert,
namespace_id: project.namespace,
project_id: project,
- target_branch: 'master',
+ start_branch: 'master',
id: commit.id)
expect(response).to redirect_to namespace_project_commit_path(project.namespace, project, commit.id)
@@ -215,7 +215,7 @@ describe Projects::CommitController do
post(:cherry_pick,
namespace_id: project.namespace,
project_id: project,
- target_branch: 'master',
+ start_branch: 'master',
id: master_pickable_commit.id)
expect(response).to redirect_to namespace_project_commits_path(project.namespace, project, 'master')
@@ -228,7 +228,7 @@ describe Projects::CommitController do
post(:cherry_pick,
namespace_id: project.namespace,
project_id: project,
- target_branch: 'master',
+ start_branch: 'master',
id: master_pickable_commit.id)
end
@@ -237,7 +237,7 @@ describe Projects::CommitController do
post(:cherry_pick,
namespace_id: project.namespace,
project_id: project,
- target_branch: 'master',
+ start_branch: 'master',
id: master_pickable_commit.id)
expect(response).to redirect_to namespace_project_commit_path(project.namespace, project, master_pickable_commit.id)
diff --git a/spec/controllers/projects/graphs_controller_spec.rb b/spec/controllers/projects/graphs_controller_spec.rb
index 049bae1899d..e0de62e4454 100644
--- a/spec/controllers/projects/graphs_controller_spec.rb
+++ b/spec/controllers/projects/graphs_controller_spec.rb
@@ -30,18 +30,18 @@ describe Projects::GraphsController do
double(languages: {
'Ruby' => 1000,
'CoffeeScript' => 350,
- 'PowerShell' => 15
+ 'NSIS' => 15
})
end
let(:expected_values) do
- ps_color = "##{Digest::SHA256.hexdigest('PowerShell')[0...6]}"
+ nsis_color = "##{Digest::SHA256.hexdigest('NSIS')[0...6]}"
[
# colors from Linguist:
- { label: "Ruby", color: "#701516", highlight: "#701516" },
- { label: "CoffeeScript", color: "#244776", highlight: "#244776" },
+ { label: "Ruby", color: "#701516", highlight: "#701516" },
+ { label: "CoffeeScript", color: "#244776", highlight: "#244776" },
# colors from SHA256 fallback:
- { label: "PowerShell", color: ps_color, highlight: ps_color }
+ { label: "NSIS", color: nsis_color, highlight: nsis_color }
]
end
diff --git a/spec/controllers/projects/notes_controller_spec.rb b/spec/controllers/projects/notes_controller_spec.rb
index dc597202050..d80780b1d90 100644
--- a/spec/controllers/projects/notes_controller_spec.rb
+++ b/spec/controllers/projects/notes_controller_spec.rb
@@ -200,4 +200,31 @@ describe Projects::NotesController do
end
end
end
+
+ describe 'GET index' do
+ let(:last_fetched_at) { '1487756246' }
+ let(:request_params) do
+ {
+ namespace_id: project.namespace,
+ project_id: project,
+ target_type: 'issue',
+ target_id: issue.id
+ }
+ end
+
+ before do
+ sign_in(user)
+ project.team << [user, :developer]
+ end
+
+ it 'passes last_fetched_at from headers to NotesFinder' do
+ request.headers['X-Last-Fetched-At'] = last_fetched_at
+
+ expect(NotesFinder).to receive(:new)
+ .with(anything, anything, hash_including(last_fetched_at: last_fetched_at))
+ .and_call_original
+
+ get :index, request_params
+ end
+ end
end
diff --git a/spec/factories/ci/builds.rb b/spec/factories/ci/builds.rb
index a90534d10ba..cabe128acf7 100644
--- a/spec/factories/ci/builds.rb
+++ b/spec/factories/ci/builds.rb
@@ -76,6 +76,18 @@ FactoryGirl.define do
manual
end
+ trait :tags do
+ tag_list [:docker, :ruby]
+ end
+
+ trait :on_tag do
+ tag true
+ end
+
+ trait :triggered do
+ trigger_request factory: :ci_trigger_request_with_variables
+ end
+
after(:build) do |build, evaluator|
build.project = build.pipeline.project
end
diff --git a/spec/features/commits_spec.rb b/spec/features/commits_spec.rb
index 324ede798fe..0e305c52358 100644
--- a/spec/features/commits_spec.rb
+++ b/spec/features/commits_spec.rb
@@ -192,7 +192,7 @@ describe 'Commits' do
commits = project.repository.commits(branch_name)
commits.each do |commit|
- expect(page).to have_content("committed #{commit.committed_date}")
+ expect(page).to have_content("committed #{commit.committed_date.strftime("%b %d, %Y")}")
end
end
end
diff --git a/spec/features/dashboard/archived_projects_spec.rb b/spec/features/dashboard/archived_projects_spec.rb
index 038c1641be9..f33bcbb5318 100644
--- a/spec/features/dashboard/archived_projects_spec.rb
+++ b/spec/features/dashboard/archived_projects_spec.rb
@@ -25,4 +25,19 @@ RSpec.describe 'Dashboard Archived Project', feature: true do
expect(page).to have_link(project.name)
expect(page).to have_link(archived_project.name)
end
+
+ it 'searchs archived projects', :js do
+ click_button 'Last updated'
+ click_link 'Show archived projects'
+
+ expect(page).to have_link(project.name)
+ expect(page).to have_link(archived_project.name)
+
+ fill_in 'project-filter-form-field', with: archived_project.name
+
+ find('#project-filter-form-field').native.send_keys :return
+
+ expect(page).not_to have_link(project.name)
+ expect(page).to have_link(archived_project.name)
+ end
end
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 f2f8f11ab28..0ceaf7bc830 100644
--- a/spec/features/merge_requests/merge_immediately_with_pipeline_spec.rb
+++ b/spec/features/merge_requests/merge_immediately_with_pipeline_spec.rb
@@ -34,7 +34,7 @@ feature 'Merge immediately', :feature, :js do
click_link 'Merge Immediately'
- expect(find('.js-merge-button')).to have_content('Merge in progress')
+ expect(find('.js-merge-when-pipeline-succeeds-button')).to have_content('Merge in progress')
end
end
end
diff --git a/spec/features/merge_requests/widget_spec.rb b/spec/features/merge_requests/widget_spec.rb
index 4ad944366c8..b575aeff0d8 100644
--- a/spec/features/merge_requests/widget_spec.rb
+++ b/spec/features/merge_requests/widget_spec.rb
@@ -3,8 +3,8 @@ require 'rails_helper'
describe 'Merge request', :feature, :js do
include WaitForAjax
- let(:project) { create(:project) }
let(:user) { create(:user) }
+ let(:project) { create(:project) }
let(:merge_request) { create(:merge_request, source_project: project) }
before do
@@ -31,7 +31,7 @@ describe 'Merge request', :feature, :js do
wait_for_ajax
- expect(page).to have_selector('.accept_merge_request')
+ expect(page).to have_selector('.accept-merge-request')
end
end
@@ -51,6 +51,69 @@ describe 'Merge request', :feature, :js do
expect(find('.js-environment-link')[:href]).to include(environment.formatted_external_url)
end
end
+
+ it 'shows green accept merge request button' do
+ # Wait for the `ci_status` and `merge_check` requests
+ wait_for_ajax
+ expect(page).to have_selector('.accept-merge-request.btn-create')
+ end
+ end
+
+ context 'view merge request with external CI service' do
+ before do
+ create(:service, project: project,
+ active: true,
+ type: 'CiService',
+ category: 'ci')
+
+ visit namespace_project_merge_request_path(project.namespace, project, merge_request)
+ end
+
+ it 'has danger button while waiting for external CI status' do
+ # Wait for the `ci_status` and `merge_check` requests
+ wait_for_ajax
+ expect(page).to have_selector('.accept-merge-request.btn-danger')
+ end
+ end
+
+ context 'view merge request with failed GitLab CI pipelines' do
+ before do
+ commit_status = create(:commit_status, project: project, status: 'failed')
+ pipeline = create(:ci_pipeline, project: project,
+ sha: merge_request.diff_head_sha,
+ ref: merge_request.source_branch,
+ status: 'failed',
+ statuses: [commit_status])
+ create(:ci_build, :pending, pipeline: pipeline)
+
+ visit namespace_project_merge_request_path(project.namespace, project, merge_request)
+ end
+
+ it 'has danger button when not succeeded' do
+ # Wait for the `ci_status` and `merge_check` requests
+ wait_for_ajax
+ expect(page).to have_selector('.accept-merge-request.btn-danger')
+ end
+ end
+
+ context 'view merge request with MWBS button' do
+ before do
+ commit_status = create(:commit_status, project: project, status: 'pending')
+ pipeline = create(:ci_pipeline, project: project,
+ sha: merge_request.diff_head_sha,
+ ref: merge_request.source_branch,
+ status: 'pending',
+ statuses: [commit_status])
+ create(:ci_build, :pending, pipeline: pipeline)
+
+ visit namespace_project_merge_request_path(project.namespace, project, merge_request)
+ end
+
+ it 'has info button when MWBS button' do
+ # Wait for the `ci_status` and `merge_check` requests
+ wait_for_ajax
+ expect(page).to have_selector('.merge-when-pipeline-succeeds.btn-info')
+ end
end
context 'merge error' do
diff --git a/spec/features/profile_spec.rb b/spec/features/profile_spec.rb
index 406d7cf791c..e63feb14b7e 100644
--- a/spec/features/profile_spec.rb
+++ b/spec/features/profile_spec.rb
@@ -61,4 +61,18 @@ describe 'Profile account page', feature: true do
expect(find('#incoming-email-token').value).not_to eq(previous_token)
end
end
+
+ describe 'when I change my username' do
+ before do
+ visit profile_account_path
+ end
+
+ it 'changes my username' do
+ fill_in 'user_username', with: 'new-username'
+
+ click_button('Update username')
+
+ expect(page).to have_content('new-username')
+ end
+ end
end
diff --git a/spec/features/projects/commit/cherry_pick_spec.rb b/spec/features/projects/commit/cherry_pick_spec.rb
index 7baf7913424..0b972d2a439 100644
--- a/spec/features/projects/commit/cherry_pick_spec.rb
+++ b/spec/features/projects/commit/cherry_pick_spec.rb
@@ -60,6 +60,7 @@ describe 'Cherry-pick Commits' do
click_button 'Cherry-pick'
end
expect(page).to have_content('The commit has been successfully cherry-picked. You can now submit a merge request to get this change into the original branch.')
+ expect(page).to have_content("From cherry-pick-#{master_pickable_commit.short_id} into master")
end
end
diff --git a/spec/features/projects/milestones/milestone_spec.rb b/spec/features/projects/milestones/milestone_spec.rb
new file mode 100644
index 00000000000..df229d0aa78
--- /dev/null
+++ b/spec/features/projects/milestones/milestone_spec.rb
@@ -0,0 +1,64 @@
+require 'spec_helper'
+
+feature 'Project milestone', :feature do
+ let(:user) { create(:user) }
+ let(:project) { create(:empty_project, name: 'test', namespace: user.namespace) }
+ let(:milestone) { create(:milestone, project: project) }
+
+ before do
+ login_as(user)
+ end
+
+ context 'when project has enabled issues' do
+ before do
+ visit namespace_project_milestone_path(project.namespace, project, milestone)
+ end
+
+ it 'shows issues tab' do
+ within('#content-body') do
+ expect(page).to have_link 'Issues', href: '#tab-issues'
+ expect(page).to have_selector '.nav-links li.active', count: 1
+ expect(find('.nav-links li.active')).to have_content 'Issues'
+ end
+ end
+
+ it 'shows issues stats' do
+ expect(page).to have_content 'issues:'
+ end
+
+ it 'shows Browse Issues button' do
+ within('#content-body') do
+ expect(page).to have_link 'Browse Issues'
+ end
+ end
+ end
+
+ context 'when project has disabled issues' do
+ before do
+ project.project_feature.update_attribute(:issues_access_level, ProjectFeature::DISABLED)
+ visit namespace_project_milestone_path(project.namespace, project, milestone)
+ end
+
+ it 'hides issues tab' do
+ within('#content-body') do
+ expect(page).not_to have_link 'Issues', href: '#tab-issues'
+ expect(page).to have_selector '.nav-links li.active', count: 1
+ expect(find('.nav-links li.active')).to have_content 'Merge Requests'
+ end
+ end
+
+ it 'hides issues stats' do
+ expect(page).to have_no_content 'issues:'
+ end
+
+ it 'hides Browse Issues button' do
+ within('#content-body') do
+ expect(page).not_to have_link 'Browse Issues'
+ end
+ end
+
+ it 'does not show an informative message' do
+ expect(page).not_to have_content('Assign some issues to this milestone.')
+ end
+ end
+end
diff --git a/spec/features/projects/services/mattermost_slash_command_spec.rb b/spec/features/projects/services/mattermost_slash_command_spec.rb
index f5adb53a2dc..24d22a092d4 100644
--- a/spec/features/projects/services/mattermost_slash_command_spec.rb
+++ b/spec/features/projects/services/mattermost_slash_command_spec.rb
@@ -1,6 +1,6 @@
require 'spec_helper'
-feature 'Setup Mattermost slash commands', feature: true do
+feature 'Setup Mattermost slash commands', :feature, :js do
let(:user) { create(:user) }
let(:project) { create(:empty_project) }
let(:service) { project.create_mattermost_slash_commands_service }
@@ -62,11 +62,11 @@ feature 'Setup Mattermost slash commands', feature: true do
click_link 'Add to Mattermost'
- team_name = teams.first[1]['display_name']
- select_element = find('select#mattermost_team_id')
+ team_name = teams.first['display_name']
+ select_element = find('#mattermost_team_id')
selected_option = select_element.find('option[selected]')
- expect(select_element['disabled']).to eq('disabled')
+ expect(select_element['disabled']).to be(true)
expect(selected_option).to have_content(team_name.to_s)
end
@@ -75,7 +75,7 @@ feature 'Setup Mattermost slash commands', feature: true do
click_link 'Add to Mattermost'
- expect(find('input#mattermost_team_id', visible: false).value).to eq(teams.first[0].to_s)
+ expect(find('input#mattermost_team_id', visible: false).value).to eq(teams.first['id'])
end
it 'shows an explanation user is a member of multiple teams' do
@@ -92,12 +92,9 @@ feature 'Setup Mattermost slash commands', feature: true do
click_link 'Add to Mattermost'
- select_element = find('select#mattermost_team_id')
- selected_option = select_element.find('option[selected]')
+ select_element = find('#mattermost_team_id')
- expect(select_element['disabled']).to be(nil)
- expect(selected_option).to have_content('Select team...')
- # The 'Select team...' placeholder is item `0`.
+ expect(select_element['disabled']).to be(false)
expect(select_element.all('option').count).to eq(3)
end
@@ -110,20 +107,37 @@ feature 'Setup Mattermost slash commands', feature: true do
expect(page).to have_content('test mattermost error message')
end
+ it 'enables the submit button if the required fields are provided', :js do
+ stub_teams(count: 1)
+
+ click_link 'Add to Mattermost'
+
+ expect(find('input[type="submit"]')['disabled']).not_to be(true)
+ end
+
+ it 'disables the submit button if the required fields are not provided', :js do
+ stub_teams(count: 1)
+
+ click_link 'Add to Mattermost'
+
+ fill_in('mattermost_trigger', with: '')
+
+ expect(find('input[type="submit"]')['disabled']).to be(true)
+ end
+
def stub_teams(count: 0)
teams = create_teams(count)
- allow_any_instance_of(MattermostSlashCommandsService).to receive(:list_teams) { teams }
+ allow_any_instance_of(MattermostSlashCommandsService).to receive(:list_teams) { [teams, nil] }
teams
end
def create_teams(count = 0)
- teams = {}
+ teams = []
count.times do |i|
- i += 1
- teams[i] = { id: i, display_name: i }
+ teams.push({ "id" => "x#{i}", "display_name" => "x#{i}-name" })
end
teams
diff --git a/spec/helpers/application_helper_spec.rb b/spec/helpers/application_helper_spec.rb
index 4ffdd530171..5c07ea8a872 100644
--- a/spec/helpers/application_helper_spec.rb
+++ b/spec/helpers/application_helper_spec.rb
@@ -193,8 +193,8 @@ describe ApplicationHelper do
describe 'time_ago_with_tooltip' do
def element(*arguments)
Time.zone = 'UTC'
- time = Time.zone.parse('2015-07-02 08:23')
- element = helper.time_ago_with_tooltip(time, *arguments)
+ @time = Time.zone.parse('2015-07-02 08:23')
+ element = helper.time_ago_with_tooltip(@time, *arguments)
Nokogiri::HTML::DocumentFragment.parse(element).first_element_child
end
@@ -204,7 +204,7 @@ describe ApplicationHelper do
end
it 'includes the date string' do
- expect(element.text).to eq '2015-07-02 08:23:00 UTC'
+ expect(element.text).to eq @time.strftime("%b %d, %Y")
end
it 'has a datetime attribute' do
diff --git a/spec/initializers/metrics_spec.rb b/spec/initializers/8_metrics_spec.rb
index bb595162370..570754621f3 100644
--- a/spec/initializers/metrics_spec.rb
+++ b/spec/initializers/8_metrics_spec.rb
@@ -1,5 +1,5 @@
require 'spec_helper'
-require_relative '../../config/initializers/metrics'
+require_relative '../../config/initializers/8_metrics'
describe 'instrument_classes', lib: true do
let(:config) { double(:config) }
diff --git a/spec/javascripts/abuse_reports_spec.js.es6 b/spec/javascripts/abuse_reports_spec.js
index 76b370b345b..76b370b345b 100644
--- a/spec/javascripts/abuse_reports_spec.js.es6
+++ b/spec/javascripts/abuse_reports_spec.js
diff --git a/spec/javascripts/activities_spec.js.es6 b/spec/javascripts/activities_spec.js
index e6a6fc36ca1..e6a6fc36ca1 100644
--- a/spec/javascripts/activities_spec.js.es6
+++ b/spec/javascripts/activities_spec.js
diff --git a/spec/javascripts/boards/boards_store_spec.js.es6 b/spec/javascripts/boards/boards_store_spec.js
index 9dd741a680b..9dd741a680b 100644
--- a/spec/javascripts/boards/boards_store_spec.js.es6
+++ b/spec/javascripts/boards/boards_store_spec.js
diff --git a/spec/javascripts/boards/issue_card_spec.js.es6 b/spec/javascripts/boards/issue_card_spec.js
index 4340a571017..4340a571017 100644
--- a/spec/javascripts/boards/issue_card_spec.js.es6
+++ b/spec/javascripts/boards/issue_card_spec.js
diff --git a/spec/javascripts/boards/issue_spec.js.es6 b/spec/javascripts/boards/issue_spec.js
index aab4d9c501e..aab4d9c501e 100644
--- a/spec/javascripts/boards/issue_spec.js.es6
+++ b/spec/javascripts/boards/issue_spec.js
diff --git a/spec/javascripts/boards/list_spec.js.es6 b/spec/javascripts/boards/list_spec.js
index c8a18af7198..c8a18af7198 100644
--- a/spec/javascripts/boards/list_spec.js.es6
+++ b/spec/javascripts/boards/list_spec.js
diff --git a/spec/javascripts/boards/mock_data.js.es6 b/spec/javascripts/boards/mock_data.js
index 7a399b307ad..7a399b307ad 100644
--- a/spec/javascripts/boards/mock_data.js.es6
+++ b/spec/javascripts/boards/mock_data.js
diff --git a/spec/javascripts/boards/modal_store_spec.js.es6 b/spec/javascripts/boards/modal_store_spec.js
index 1815847f3fa..1815847f3fa 100644
--- a/spec/javascripts/boards/modal_store_spec.js.es6
+++ b/spec/javascripts/boards/modal_store_spec.js
diff --git a/spec/javascripts/bootstrap_linked_tabs_spec.js.es6 b/spec/javascripts/bootstrap_linked_tabs_spec.js
index fa9f95e16cd..fa9f95e16cd 100644
--- a/spec/javascripts/bootstrap_linked_tabs_spec.js.es6
+++ b/spec/javascripts/bootstrap_linked_tabs_spec.js
diff --git a/spec/javascripts/build_spec.js.es6 b/spec/javascripts/build_spec.js
index 0bd50588f5a..0bd50588f5a 100644
--- a/spec/javascripts/build_spec.js.es6
+++ b/spec/javascripts/build_spec.js
diff --git a/spec/javascripts/commit/pipelines/mock_data.js.es6 b/spec/javascripts/commit/pipelines/mock_data.js
index 188908d66bd..188908d66bd 100644
--- a/spec/javascripts/commit/pipelines/mock_data.js.es6
+++ b/spec/javascripts/commit/pipelines/mock_data.js
diff --git a/spec/javascripts/commit/pipelines/pipelines_spec.js.es6 b/spec/javascripts/commit/pipelines/pipelines_spec.js
index f09c57978a1..f09c57978a1 100644
--- a/spec/javascripts/commit/pipelines/pipelines_spec.js.es6
+++ b/spec/javascripts/commit/pipelines/pipelines_spec.js
diff --git a/spec/javascripts/commit/pipelines/pipelines_store_spec.js.es6 b/spec/javascripts/commit/pipelines/pipelines_store_spec.js
index 94973419979..94973419979 100644
--- a/spec/javascripts/commit/pipelines/pipelines_store_spec.js.es6
+++ b/spec/javascripts/commit/pipelines/pipelines_store_spec.js
diff --git a/spec/javascripts/commits_spec.js.es6 b/spec/javascripts/commits_spec.js
index 05260760c43..05260760c43 100644
--- a/spec/javascripts/commits_spec.js.es6
+++ b/spec/javascripts/commits_spec.js
diff --git a/spec/javascripts/datetime_utility_spec.js.es6 b/spec/javascripts/datetime_utility_spec.js
index d5eec10be42..d5eec10be42 100644
--- a/spec/javascripts/datetime_utility_spec.js.es6
+++ b/spec/javascripts/datetime_utility_spec.js
diff --git a/spec/javascripts/diff_comments_store_spec.js.es6 b/spec/javascripts/diff_comments_store_spec.js
index f956394ef53..f956394ef53 100644
--- a/spec/javascripts/diff_comments_store_spec.js.es6
+++ b/spec/javascripts/diff_comments_store_spec.js
diff --git a/spec/javascripts/environments/environment_actions_spec.js.es6 b/spec/javascripts/environments/environment_actions_spec.js
index d50d45d295e..d50d45d295e 100644
--- a/spec/javascripts/environments/environment_actions_spec.js.es6
+++ b/spec/javascripts/environments/environment_actions_spec.js
diff --git a/spec/javascripts/environments/environment_external_url_spec.js.es6 b/spec/javascripts/environments/environment_external_url_spec.js
index 393dbb5aae0..393dbb5aae0 100644
--- a/spec/javascripts/environments/environment_external_url_spec.js.es6
+++ b/spec/javascripts/environments/environment_external_url_spec.js
diff --git a/spec/javascripts/environments/environment_item_spec.js.es6 b/spec/javascripts/environments/environment_item_spec.js
index 7fea80ed799..7fea80ed799 100644
--- a/spec/javascripts/environments/environment_item_spec.js.es6
+++ b/spec/javascripts/environments/environment_item_spec.js
diff --git a/spec/javascripts/environments/environment_rollback_spec.js.es6 b/spec/javascripts/environments/environment_rollback_spec.js
index 4a596baad09..4a596baad09 100644
--- a/spec/javascripts/environments/environment_rollback_spec.js.es6
+++ b/spec/javascripts/environments/environment_rollback_spec.js
diff --git a/spec/javascripts/environments/environment_spec.js.es6 b/spec/javascripts/environments/environment_spec.js
index edd0cad32d0..edd0cad32d0 100644
--- a/spec/javascripts/environments/environment_spec.js.es6
+++ b/spec/javascripts/environments/environment_spec.js
diff --git a/spec/javascripts/environments/environment_stop_spec.js.es6 b/spec/javascripts/environments/environment_stop_spec.js
index 5ca65b1debc..5ca65b1debc 100644
--- a/spec/javascripts/environments/environment_stop_spec.js.es6
+++ b/spec/javascripts/environments/environment_stop_spec.js
diff --git a/spec/javascripts/environments/environment_table_spec.js.es6 b/spec/javascripts/environments/environment_table_spec.js
index be4330b5012..be4330b5012 100644
--- a/spec/javascripts/environments/environment_table_spec.js.es6
+++ b/spec/javascripts/environments/environment_table_spec.js
diff --git a/spec/javascripts/environments/environments_store_spec.js.es6 b/spec/javascripts/environments/environments_store_spec.js
index 77e182b3830..77e182b3830 100644
--- a/spec/javascripts/environments/environments_store_spec.js.es6
+++ b/spec/javascripts/environments/environments_store_spec.js
diff --git a/spec/javascripts/environments/folder/environments_folder_view_spec.js.es6 b/spec/javascripts/environments/folder/environments_folder_view_spec.js
index d1335b5b304..d1335b5b304 100644
--- a/spec/javascripts/environments/folder/environments_folder_view_spec.js.es6
+++ b/spec/javascripts/environments/folder/environments_folder_view_spec.js
diff --git a/spec/javascripts/environments/mock_data.js.es6 b/spec/javascripts/environments/mock_data.js
index 5c395c6b2d8..5c395c6b2d8 100644
--- a/spec/javascripts/environments/mock_data.js.es6
+++ b/spec/javascripts/environments/mock_data.js
diff --git a/spec/javascripts/extensions/array_spec.js.es6 b/spec/javascripts/extensions/array_spec.js
index 60f6b9b78e3..60f6b9b78e3 100644
--- a/spec/javascripts/extensions/array_spec.js.es6
+++ b/spec/javascripts/extensions/array_spec.js
diff --git a/spec/javascripts/extensions/element_spec.js.es6 b/spec/javascripts/extensions/element_spec.js
index 2d8a128ed33..2d8a128ed33 100644
--- a/spec/javascripts/extensions/element_spec.js.es6
+++ b/spec/javascripts/extensions/element_spec.js
diff --git a/spec/javascripts/extensions/object_spec.js.es6 b/spec/javascripts/extensions/object_spec.js
index 2467ed78459..2467ed78459 100644
--- a/spec/javascripts/extensions/object_spec.js.es6
+++ b/spec/javascripts/extensions/object_spec.js
diff --git a/spec/javascripts/filtered_search/dropdown_user_spec.js.es6 b/spec/javascripts/filtered_search/dropdown_user_spec.js
index fa9d03c8a9a..fa9d03c8a9a 100644
--- a/spec/javascripts/filtered_search/dropdown_user_spec.js.es6
+++ b/spec/javascripts/filtered_search/dropdown_user_spec.js
diff --git a/spec/javascripts/filtered_search/dropdown_utils_spec.js.es6 b/spec/javascripts/filtered_search/dropdown_utils_spec.js
index 1e2d7582d5b..1e2d7582d5b 100644
--- a/spec/javascripts/filtered_search/dropdown_utils_spec.js.es6
+++ b/spec/javascripts/filtered_search/dropdown_utils_spec.js
diff --git a/spec/javascripts/filtered_search/filtered_search_dropdown_manager_spec.js.es6 b/spec/javascripts/filtered_search/filtered_search_dropdown_manager_spec.js
index ed0b0196ec4..ed0b0196ec4 100644
--- a/spec/javascripts/filtered_search/filtered_search_dropdown_manager_spec.js.es6
+++ b/spec/javascripts/filtered_search/filtered_search_dropdown_manager_spec.js
diff --git a/spec/javascripts/filtered_search/filtered_search_manager_spec.js.es6 b/spec/javascripts/filtered_search/filtered_search_manager_spec.js
index 98959dda242..98959dda242 100644
--- a/spec/javascripts/filtered_search/filtered_search_manager_spec.js.es6
+++ b/spec/javascripts/filtered_search/filtered_search_manager_spec.js
diff --git a/spec/javascripts/filtered_search/filtered_search_token_keys_spec.js.es6 b/spec/javascripts/filtered_search/filtered_search_token_keys_spec.js
index cf409a7e509..cf409a7e509 100644
--- a/spec/javascripts/filtered_search/filtered_search_token_keys_spec.js.es6
+++ b/spec/javascripts/filtered_search/filtered_search_token_keys_spec.js
diff --git a/spec/javascripts/filtered_search/filtered_search_tokenizer_spec.js.es6 b/spec/javascripts/filtered_search/filtered_search_tokenizer_spec.js
index a91801cfc89..a91801cfc89 100644
--- a/spec/javascripts/filtered_search/filtered_search_tokenizer_spec.js.es6
+++ b/spec/javascripts/filtered_search/filtered_search_tokenizer_spec.js
diff --git a/spec/javascripts/gfm_auto_complete_spec.js.es6 b/spec/javascripts/gfm_auto_complete_spec.js
index 5dfa4008fbd..5dfa4008fbd 100644
--- a/spec/javascripts/gfm_auto_complete_spec.js.es6
+++ b/spec/javascripts/gfm_auto_complete_spec.js
diff --git a/spec/javascripts/gl_dropdown_spec.js.es6 b/spec/javascripts/gl_dropdown_spec.js
index c207fb00a47..c207fb00a47 100644
--- a/spec/javascripts/gl_dropdown_spec.js.es6
+++ b/spec/javascripts/gl_dropdown_spec.js
diff --git a/spec/javascripts/gl_field_errors_spec.js.es6 b/spec/javascripts/gl_field_errors_spec.js
index 733023481f5..733023481f5 100644
--- a/spec/javascripts/gl_field_errors_spec.js.es6
+++ b/spec/javascripts/gl_field_errors_spec.js
diff --git a/spec/javascripts/gl_form_spec.js.es6 b/spec/javascripts/gl_form_spec.js
index 71d6e2a7e22..71d6e2a7e22 100644
--- a/spec/javascripts/gl_form_spec.js.es6
+++ b/spec/javascripts/gl_form_spec.js
diff --git a/spec/javascripts/helpers/class_spec_helper.js.es6 b/spec/javascripts/helpers/class_spec_helper.js
index 61db27a8fcc..61db27a8fcc 100644
--- a/spec/javascripts/helpers/class_spec_helper.js.es6
+++ b/spec/javascripts/helpers/class_spec_helper.js
diff --git a/spec/javascripts/helpers/class_spec_helper_spec.js.es6 b/spec/javascripts/helpers/class_spec_helper_spec.js
index 0a61e561640..0a61e561640 100644
--- a/spec/javascripts/helpers/class_spec_helper_spec.js.es6
+++ b/spec/javascripts/helpers/class_spec_helper_spec.js
diff --git a/spec/javascripts/issuable_spec.js.es6 b/spec/javascripts/issuable_spec.js
index 26d87cc5931..26d87cc5931 100644
--- a/spec/javascripts/issuable_spec.js.es6
+++ b/spec/javascripts/issuable_spec.js
diff --git a/spec/javascripts/issuable_time_tracker_spec.js.es6 b/spec/javascripts/issuable_time_tracker_spec.js
index cb068a4f879..cb068a4f879 100644
--- a/spec/javascripts/issuable_time_tracker_spec.js.es6
+++ b/spec/javascripts/issuable_time_tracker_spec.js
diff --git a/spec/javascripts/labels_issue_sidebar_spec.js.es6 b/spec/javascripts/labels_issue_sidebar_spec.js
index 37e038c16da..37e038c16da 100644
--- a/spec/javascripts/labels_issue_sidebar_spec.js.es6
+++ b/spec/javascripts/labels_issue_sidebar_spec.js
diff --git a/spec/javascripts/lib/utils/common_utils_spec.js.es6 b/spec/javascripts/lib/utils/common_utils_spec.js
index f4d3e77e515..f4d3e77e515 100644
--- a/spec/javascripts/lib/utils/common_utils_spec.js.es6
+++ b/spec/javascripts/lib/utils/common_utils_spec.js
diff --git a/spec/javascripts/lib/utils/text_utility_spec.js.es6 b/spec/javascripts/lib/utils/text_utility_spec.js
index 4200e943121..4200e943121 100644
--- a/spec/javascripts/lib/utils/text_utility_spec.js.es6
+++ b/spec/javascripts/lib/utils/text_utility_spec.js
diff --git a/spec/javascripts/mini_pipeline_graph_dropdown_spec.js.es6 b/spec/javascripts/mini_pipeline_graph_dropdown_spec.js
index 7cdade01e00..7cdade01e00 100644
--- a/spec/javascripts/mini_pipeline_graph_dropdown_spec.js.es6
+++ b/spec/javascripts/mini_pipeline_graph_dropdown_spec.js
diff --git a/spec/javascripts/pipelines_spec.js.es6 b/spec/javascripts/pipelines_spec.js
index 72770a702d3..72770a702d3 100644
--- a/spec/javascripts/pipelines_spec.js.es6
+++ b/spec/javascripts/pipelines_spec.js
diff --git a/spec/javascripts/pretty_time_spec.js.es6 b/spec/javascripts/pretty_time_spec.js
index a4662cfb557..a4662cfb557 100644
--- a/spec/javascripts/pretty_time_spec.js.es6
+++ b/spec/javascripts/pretty_time_spec.js
diff --git a/spec/javascripts/signin_tabs_memoizer_spec.js.es6 b/spec/javascripts/signin_tabs_memoizer_spec.js
index d83d9a57b42..d83d9a57b42 100644
--- a/spec/javascripts/signin_tabs_memoizer_spec.js.es6
+++ b/spec/javascripts/signin_tabs_memoizer_spec.js
diff --git a/spec/javascripts/smart_interval_spec.js.es6 b/spec/javascripts/smart_interval_spec.js
index 4366ec2a5b8..4366ec2a5b8 100644
--- a/spec/javascripts/smart_interval_spec.js.es6
+++ b/spec/javascripts/smart_interval_spec.js
diff --git a/spec/javascripts/subbable_resource_spec.js.es6 b/spec/javascripts/subbable_resource_spec.js
index 454386697f5..454386697f5 100644
--- a/spec/javascripts/subbable_resource_spec.js.es6
+++ b/spec/javascripts/subbable_resource_spec.js
diff --git a/spec/javascripts/test_bundle.js b/spec/javascripts/test_bundle.js
index ca707d872a4..fae462561e9 100644
--- a/spec/javascripts/test_bundle.js
+++ b/spec/javascripts/test_bundle.js
@@ -5,23 +5,12 @@ jasmine.getFixtures().fixturesPath = 'base/spec/javascripts/fixtures';
jasmine.getJSONFixtures().fixturesPath = 'base/spec/javascripts/fixtures';
// include common libraries
+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'));
-require('jquery-ujs');
-require('bootstrap/js/affix');
-require('bootstrap/js/alert');
-require('bootstrap/js/button');
-require('bootstrap/js/collapse');
-require('bootstrap/js/dropdown');
-require('bootstrap/js/modal');
-require('bootstrap/js/scrollspy');
-require('bootstrap/js/tab');
-require('bootstrap/js/transition');
-require('bootstrap/js/tooltip');
-require('bootstrap/js/popover');
// stub expected globals
window.gl = window.gl || {};
diff --git a/spec/javascripts/user_callout_spec.js.es6 b/spec/javascripts/user_callout_spec.js
index 205e72af600..205e72af600 100644
--- a/spec/javascripts/user_callout_spec.js.es6
+++ b/spec/javascripts/user_callout_spec.js
diff --git a/spec/javascripts/version_check_image_spec.js.es6 b/spec/javascripts/version_check_image_spec.js
index 464c1fce210..464c1fce210 100644
--- a/spec/javascripts/version_check_image_spec.js.es6
+++ b/spec/javascripts/version_check_image_spec.js
diff --git a/spec/javascripts/visibility_select_spec.js.es6 b/spec/javascripts/visibility_select_spec.js
index 9727c03c91e..9727c03c91e 100644
--- a/spec/javascripts/visibility_select_spec.js.es6
+++ b/spec/javascripts/visibility_select_spec.js
diff --git a/spec/javascripts/vue_shared/components/commit_spec.js.es6 b/spec/javascripts/vue_shared/components/commit_spec.js
index 15ab10b9b69..15ab10b9b69 100644
--- a/spec/javascripts/vue_shared/components/commit_spec.js.es6
+++ b/spec/javascripts/vue_shared/components/commit_spec.js
diff --git a/spec/javascripts/vue_shared/components/pipelines_table_row_spec.js.es6 b/spec/javascripts/vue_shared/components/pipelines_table_row_spec.js
index 412abfd5e41..412abfd5e41 100644
--- a/spec/javascripts/vue_shared/components/pipelines_table_row_spec.js.es6
+++ b/spec/javascripts/vue_shared/components/pipelines_table_row_spec.js
diff --git a/spec/javascripts/vue_shared/components/pipelines_table_spec.js.es6 b/spec/javascripts/vue_shared/components/pipelines_table_spec.js
index 54d81e2ea7d..54d81e2ea7d 100644
--- a/spec/javascripts/vue_shared/components/pipelines_table_spec.js.es6
+++ b/spec/javascripts/vue_shared/components/pipelines_table_spec.js
diff --git a/spec/javascripts/vue_shared/components/table_pagination_spec.js.es6 b/spec/javascripts/vue_shared/components/table_pagination_spec.js
index 9cb067921a7..9cb067921a7 100644
--- a/spec/javascripts/vue_shared/components/table_pagination_spec.js.es6
+++ b/spec/javascripts/vue_shared/components/table_pagination_spec.js
diff --git a/spec/lib/gitlab/etag_caching/middleware_spec.rb b/spec/lib/gitlab/etag_caching/middleware_spec.rb
new file mode 100644
index 00000000000..8b5bfc4dbb0
--- /dev/null
+++ b/spec/lib/gitlab/etag_caching/middleware_spec.rb
@@ -0,0 +1,163 @@
+require 'spec_helper'
+
+describe Gitlab::EtagCaching::Middleware do
+ let(:app) { double(:app) }
+ let(:middleware) { described_class.new(app) }
+ let(:app_status_code) { 200 }
+ let(:if_none_match) { nil }
+ let(:enabled_path) { '/gitlab-org/gitlab-ce/noteable/issue/1/notes' }
+
+ context 'when ETag caching is not enabled for current route' do
+ let(:path) { '/gitlab-org/gitlab-ce/tree/master/noteable/issue/1/notes' }
+
+ before do
+ mock_app_response
+ end
+
+ it 'does not add ETag header' do
+ _, headers, _ = middleware.call(build_env(path, if_none_match))
+
+ expect(headers['ETag']).to be_nil
+ end
+
+ it 'passes status code from app' do
+ status, _, _ = middleware.call(build_env(path, if_none_match))
+
+ expect(status).to eq app_status_code
+ end
+ end
+
+ context 'when there is no ETag in store for given resource' do
+ let(:path) { enabled_path }
+
+ before do
+ mock_app_response
+ mock_value_in_store(nil)
+ end
+
+ it 'generates ETag' do
+ expect_any_instance_of(Gitlab::EtagCaching::Store)
+ .to receive(:touch).and_return('123')
+
+ middleware.call(build_env(path, if_none_match))
+ end
+
+ context 'when If-None-Match header was specified' do
+ let(:if_none_match) { 'W/"abc"' }
+
+ it 'tracks "etag_caching_key_not_found" event' do
+ expect(Gitlab::Metrics).to receive(:add_event)
+ .with(:etag_caching_middleware_used)
+ expect(Gitlab::Metrics).to receive(:add_event)
+ .with(:etag_caching_key_not_found)
+
+ middleware.call(build_env(path, if_none_match))
+ end
+ end
+ end
+
+ context 'when there is ETag in store for given resource' do
+ let(:path) { enabled_path }
+
+ before do
+ mock_app_response
+ mock_value_in_store('123')
+ end
+
+ it 'returns this value as header' do
+ _, headers, _ = middleware.call(build_env(path, if_none_match))
+
+ expect(headers['ETag']).to eq 'W/"123"'
+ end
+ end
+
+ context 'when If-None-Match header matches ETag in store' do
+ let(:path) { enabled_path }
+ let(:if_none_match) { 'W/"123"' }
+
+ before do
+ mock_value_in_store('123')
+ end
+
+ it 'does not call app' do
+ expect(app).not_to receive(:call)
+
+ middleware.call(build_env(path, if_none_match))
+ end
+
+ it 'returns status code 304' do
+ status, _, _ = middleware.call(build_env(path, if_none_match))
+
+ expect(status).to eq 304
+ end
+
+ it 'tracks "etag_caching_cache_hit" event' do
+ expect(Gitlab::Metrics).to receive(:add_event)
+ .with(:etag_caching_middleware_used)
+ expect(Gitlab::Metrics).to receive(:add_event)
+ .with(:etag_caching_cache_hit)
+
+ middleware.call(build_env(path, if_none_match))
+ end
+ end
+
+ context 'when If-None-Match header does not match ETag in store' do
+ let(:path) { enabled_path }
+ let(:if_none_match) { 'W/"abc"' }
+
+ before do
+ mock_value_in_store('123')
+ end
+
+ it 'calls app' do
+ expect(app).to receive(:call).and_return([app_status_code, {}, ['body']])
+
+ middleware.call(build_env(path, if_none_match))
+ end
+
+ it 'tracks "etag_caching_resource_changed" event' do
+ mock_app_response
+
+ expect(Gitlab::Metrics).to receive(:add_event)
+ .with(:etag_caching_middleware_used)
+ expect(Gitlab::Metrics).to receive(:add_event)
+ .with(:etag_caching_resource_changed)
+
+ middleware.call(build_env(path, if_none_match))
+ end
+ end
+
+ context 'when If-None-Match header is not specified' do
+ let(:path) { enabled_path }
+
+ before do
+ mock_value_in_store('123')
+ mock_app_response
+ end
+
+ it 'tracks "etag_caching_header_missing" event' do
+ expect(Gitlab::Metrics).to receive(:add_event)
+ .with(:etag_caching_middleware_used)
+ expect(Gitlab::Metrics).to receive(:add_event)
+ .with(:etag_caching_header_missing)
+
+ middleware.call(build_env(path, if_none_match))
+ end
+ end
+
+ def mock_app_response
+ allow(app).to receive(:call).and_return([app_status_code, {}, ['body']])
+ end
+
+ def mock_value_in_store(value)
+ allow_any_instance_of(Gitlab::EtagCaching::Store)
+ .to receive(:get).and_return(value)
+ end
+
+ def build_env(path, if_none_match)
+ {
+ 'PATH_INFO' => path,
+ 'HTTP_IF_NONE_MATCH' => if_none_match
+ }
+ end
+end
diff --git a/spec/lib/gitlab/sidekiq_status_spec.rb b/spec/lib/gitlab/sidekiq_status_spec.rb
index 0aa36a3416b..56f06b61afb 100644
--- a/spec/lib/gitlab/sidekiq_status_spec.rb
+++ b/spec/lib/gitlab/sidekiq_status_spec.rb
@@ -39,6 +39,32 @@ describe Gitlab::SidekiqStatus do
end
end
+ describe '.num_running', :redis do
+ it 'returns 0 if all jobs have been completed' do
+ expect(described_class.num_running(%w(123))).to eq(0)
+ end
+
+ it 'returns 2 if two jobs are still running' do
+ described_class.set('123')
+ described_class.set('456')
+
+ expect(described_class.num_running(%w(123 456 789))).to eq(2)
+ end
+ end
+
+ describe '.num_completed', :redis do
+ it 'returns 1 if all jobs have been completed' do
+ expect(described_class.num_completed(%w(123))).to eq(1)
+ end
+
+ it 'returns 1 if a job has not yet been completed' do
+ described_class.set('123')
+ described_class.set('456')
+
+ expect(described_class.num_completed(%w(123 456 789))).to eq(1)
+ end
+ end
+
describe '.key_for' do
it 'returns the key for a job ID' do
key = described_class.key_for('123')
diff --git a/spec/lib/mattermost/team_spec.rb b/spec/lib/mattermost/team_spec.rb
index 6a9c7cebfff..ac493fdb20f 100644
--- a/spec/lib/mattermost/team_spec.rb
+++ b/spec/lib/mattermost/team_spec.rb
@@ -13,7 +13,7 @@ describe Mattermost::Team do
context 'for valid request' do
let(:response) do
- [{
+ { "xiyro8huptfhdndadpz8r3wnbo" => {
"id" => "xiyro8huptfhdndadpz8r3wnbo",
"create_at" => 1482174222155,
"update_at" => 1482174222155,
@@ -26,7 +26,7 @@ describe Mattermost::Team do
"allowed_domains" => "",
"invite_id" => "o4utakb9jtb7imctdfzbf9r5ro",
"allow_open_invite" => false
- }]
+ } }
end
before do
@@ -39,7 +39,7 @@ describe Mattermost::Team do
end
it 'returns a token' do
- is_expected.to eq(response)
+ is_expected.to eq(response.values)
end
end
diff --git a/spec/models/note_spec.rb b/spec/models/note_spec.rb
index 1cde9e04951..33536487c41 100644
--- a/spec/models/note_spec.rb
+++ b/spec/models/note_spec.rb
@@ -387,4 +387,16 @@ describe Note, models: true do
end
end
end
+
+ describe 'expiring ETag cache' do
+ let(:note) { build(:note_on_issue) }
+
+ it "expires cache for note's issue when note is saved" do
+ expect_any_instance_of(Gitlab::EtagCaching::Store)
+ .to receive(:touch)
+ .with("/#{note.project.namespace.to_param}/#{note.project.to_param}/noteable/issue/#{note.noteable.id}/notes")
+
+ note.save!
+ end
+ end
end
diff --git a/spec/models/project_services/kubernetes_service_spec.rb b/spec/models/project_services/kubernetes_service_spec.rb
index 24356447fed..585c899cdf9 100644
--- a/spec/models/project_services/kubernetes_service_spec.rb
+++ b/spec/models/project_services/kubernetes_service_spec.rb
@@ -163,6 +163,12 @@ describe KubernetesService, models: true, caching: true do
{ key: 'KUBE_CA_PEM', value: 'CA PEM DATA', public: true }
)
end
+
+ it 'sets KUBE_CA_PEM_FILE' do
+ expect(subject.predefined_variables).to include(
+ { key: 'KUBE_CA_PEM_FILE', value: 'CA PEM DATA', public: true, file: true }
+ )
+ end
end
describe '#terminals' do
diff --git a/spec/models/project_services/mattermost_slash_commands_service_spec.rb b/spec/models/project_services/mattermost_slash_commands_service_spec.rb
index 598ff232c82..f9531be5d25 100644
--- a/spec/models/project_services/mattermost_slash_commands_service_spec.rb
+++ b/spec/models/project_services/mattermost_slash_commands_service_spec.rb
@@ -92,7 +92,7 @@ describe MattermostSlashCommandsService, :models do
to_return(
status: 200,
headers: { 'Content-Type' => 'application/json' },
- body: ['list'].to_json
+ body: { 'list' => true }.to_json
)
end
diff --git a/spec/models/repository_spec.rb b/spec/models/repository_spec.rb
index ae203fada12..eb992e1354e 100644
--- a/spec/models/repository_spec.rb
+++ b/spec/models/repository_spec.rb
@@ -1112,16 +1112,16 @@ describe Repository, models: true do
let(:update_image_commit) { repository.commit('2f63565e7aac07bcdadb654e253078b727143ec4') }
context 'when there is a conflict' do
- it 'aborts the operation' do
- expect(repository.revert(user, new_image_commit, 'master')).to eq(false)
+ it 'raises an error' do
+ expect { repository.revert(user, new_image_commit, 'master') }.to raise_error(/Failed to/)
end
end
context 'when commit was already reverted' do
- it 'aborts the operation' do
+ it 'raises an error' do
repository.revert(user, update_image_commit, 'master')
- expect(repository.revert(user, update_image_commit, 'master')).to eq(false)
+ expect { repository.revert(user, update_image_commit, 'master') }.to raise_error(/Failed to/)
end
end
@@ -1148,16 +1148,16 @@ describe Repository, models: true do
let(:pickable_merge) { repository.commit('e56497bb5f03a90a51293fc6d516788730953899') }
context 'when there is a conflict' do
- it 'aborts the operation' do
- expect(repository.cherry_pick(user, conflict_commit, 'master')).to eq(false)
+ it 'raises an error' do
+ expect { repository.cherry_pick(user, conflict_commit, 'master') }.to raise_error(/Failed to/)
end
end
context 'when commit was already cherry-picked' do
- it 'aborts the operation' do
+ it 'raises an error' do
repository.cherry_pick(user, pickable_commit, 'master')
- expect(repository.cherry_pick(user, pickable_commit, 'master')).to eq(false)
+ expect { repository.cherry_pick(user, pickable_commit, 'master') }.to raise_error(/Failed to/)
end
end
diff --git a/spec/requests/api/milestones_spec.rb b/spec/requests/api/milestones_spec.rb
index 570651165ea..78c230117b8 100644
--- a/spec/requests/api/milestones_spec.rb
+++ b/spec/requests/api/milestones_spec.rb
@@ -45,8 +45,37 @@ describe API::Milestones, api: true do
expect(json_response.first['id']).to eq(closed_milestone.id)
end
- it 'returns a project milestone by iid' do
- get api("/projects/#{project.id}/milestones?iid=#{closed_milestone.iid}", user)
+ it 'returns an array of milestones specified by iids' do
+ other_milestone = create(:milestone, project: project)
+
+ get api("/projects/#{project.id}/milestones", user), iids: [closed_milestone.iid, other_milestone.iid]
+
+ expect(response).to have_http_status(200)
+ expect(json_response).to be_an Array
+ expect(json_response.length).to eq(2)
+ expect(json_response.map{ |m| m['id'] }).to match_array([closed_milestone.id, other_milestone.id])
+ end
+
+ it 'does not return any milestone if none found' do
+ get api("/projects/#{project.id}/milestones", user), iids: [Milestone.maximum(:iid).succ]
+
+ expect(response).to have_http_status(200)
+ expect(json_response).to be_an Array
+ expect(json_response.length).to eq(0)
+ end
+ end
+
+ describe 'GET /projects/:id/milestones/:milestone_id' do
+ it 'returns a project milestone by id' do
+ get api("/projects/#{project.id}/milestones/#{milestone.id}", user)
+
+ expect(response).to have_http_status(200)
+ expect(json_response['title']).to eq(milestone.title)
+ expect(json_response['iid']).to eq(milestone.iid)
+ end
+
+ it 'returns a project milestone by iids array' do
+ get api("/projects/#{project.id}/milestones?iids=#{closed_milestone.iid}", user)
expect(response.status).to eq 200
expect(response).to include_pagination_headers
@@ -56,16 +85,6 @@ describe API::Milestones, api: true do
expect(json_response.first['id']).to eq closed_milestone.id
end
- it 'returns a project milestone by iid array' do
- get api("/projects/#{project.id}/milestones", user), iid: [milestone.iid, closed_milestone.iid]
-
- expect(response).to have_http_status(200)
- expect(response).to include_pagination_headers
- expect(json_response.size).to eq(2)
- expect(json_response.first['title']).to eq milestone.title
- expect(json_response.first['id']).to eq milestone.id
- end
-
it 'returns a project milestone by searching for title' do
get api("/projects/#{project.id}/milestones", user), search: 'version2'
diff --git a/spec/requests/api/pipelines_spec.rb b/spec/requests/api/pipelines_spec.rb
index 98d004b572e..51af999b455 100644
--- a/spec/requests/api/pipelines_spec.rb
+++ b/spec/requests/api/pipelines_spec.rb
@@ -24,6 +24,7 @@ describe API::Pipelines, api: true do
expect(json_response).to be_an Array
expect(json_response.first['sha']).to match /\A\h{40}\z/
expect(json_response.first['id']).to eq pipeline.id
+ expect(json_response.first.keys).to contain_exactly(*%w[id sha ref status])
end
end
diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb
index 2e8b557e9e2..03cae074803 100644
--- a/spec/requests/api/projects_spec.rb
+++ b/spec/requests/api/projects_spec.rb
@@ -43,9 +43,10 @@ describe API::Projects, api: true do
describe 'GET /projects' do
shared_examples_for 'projects response' do
it 'returns an array of projects' do
- get api('/projects', current_user)
+ get api('/projects', current_user), filter
expect(response).to have_http_status(200)
+ expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.map { |p| p['id'] }).to contain_exactly(*projects.map(&:id))
end
@@ -61,6 +62,7 @@ describe API::Projects, api: true do
context 'when unauthenticated' do
it_behaves_like 'projects response' do
+ let(:filter) { {} }
let(:current_user) { nil }
let(:projects) { [public_project] }
end
@@ -68,6 +70,7 @@ describe API::Projects, api: true do
context 'when authenticated as regular user' do
it_behaves_like 'projects response' do
+ let(:filter) { {} }
let(:current_user) { user }
let(:projects) { [public_project, project, project2, project3] }
end
@@ -133,13 +136,18 @@ describe API::Projects, api: true do
end
context 'and using search' do
- it 'returns searched project' do
- get api('/projects', user), { search: project.name }
+ it_behaves_like 'projects response' do
+ let(:filter) { { search: project.name } }
+ let(:current_user) { user }
+ let(:projects) { [project] }
+ end
+ end
- expect(response).to have_http_status(200)
- expect(response).to include_pagination_headers
- expect(json_response).to be_an Array
- expect(json_response.length).to eq(1)
+ context 'and membership=true' do
+ it_behaves_like 'projects response' do
+ let(:filter) { { membership: true } }
+ let(:current_user) { user }
+ let(:projects) { [project, project2, project3] }
end
end
@@ -216,36 +224,52 @@ describe API::Projects, api: true do
end
context 'and with all query parameters' do
- # | | project5 | project6 | project7 | project8 | project9 |
- # |---------+----------+----------+----------+----------+----------|
- # | search | x | | x | x | x |
- # | starred | x | x | | x | x |
- # | public | x | x | x | | x |
- # | owned | x | x | x | x | |
- let!(:project5) { create(:empty_project, :public, path: 'gitlab5', namespace: user.namespace) }
+ let!(:project5) { create(:empty_project, :public, path: 'gitlab5', namespace: create(:namespace)) }
let!(:project6) { create(:empty_project, :public, path: 'project6', namespace: user.namespace) }
let!(:project7) { create(:empty_project, :public, path: 'gitlab7', namespace: user.namespace) }
let!(:project8) { create(:empty_project, path: 'gitlab8', namespace: user.namespace) }
let!(:project9) { create(:empty_project, :public, path: 'gitlab9') }
before do
- user.update_attributes(starred_projects: [project5, project6, project8, project9])
+ user.update_attributes(starred_projects: [project5, project7, project8, project9])
end
- it 'returns only projects that satify all query parameters' do
- get api('/projects', user), { visibility: 'public', owned: true, starred: true, search: 'gitlab' }
+ context 'including owned filter' do
+ it 'returns only projects that satisfy all query parameters' do
+ get api('/projects', user), { visibility: 'public', owned: true, starred: true, search: 'gitlab' }
- expect(response).to have_http_status(200)
- expect(response).to include_pagination_headers
- expect(json_response).to be_an Array
- expect(json_response.size).to eq(1)
- expect(json_response.first['id']).to eq(project5.id)
+ expect(response).to have_http_status(200)
+ expect(response).to include_pagination_headers
+ expect(json_response).to be_an Array
+ expect(json_response.size).to eq(1)
+ expect(json_response.first['id']).to eq(project7.id)
+ end
+ end
+
+ context 'including membership filter' do
+ before do
+ create(:project_member,
+ user: user,
+ project: project5,
+ access_level: ProjectMember::MASTER)
+ end
+
+ it 'returns only projects that satisfy all query parameters' do
+ get api('/projects', user), { visibility: 'public', membership: true, starred: true, search: 'gitlab' }
+
+ expect(response).to have_http_status(200)
+ expect(response).to include_pagination_headers
+ expect(json_response).to be_an Array
+ expect(json_response.size).to eq(2)
+ expect(json_response.map { |project| project['id'] }).to contain_exactly(project5.id, project7.id)
+ end
end
end
end
context 'when authenticated as a different user' do
it_behaves_like 'projects response' do
+ let(:filter) { {} }
let(:current_user) { user2 }
let(:projects) { [public_project] }
end
@@ -253,6 +277,7 @@ describe API::Projects, api: true do
context 'when authenticated as admin' do
it_behaves_like 'projects response' do
+ let(:filter) { {} }
let(:current_user) { admin }
let(:projects) { Project.all }
end
diff --git a/spec/requests/api/v3/milestones_spec.rb b/spec/requests/api/v3/milestones_spec.rb
new file mode 100644
index 00000000000..77705d8c839
--- /dev/null
+++ b/spec/requests/api/v3/milestones_spec.rb
@@ -0,0 +1,232 @@
+require 'spec_helper'
+
+describe API::V3::Milestones, api: true do
+ include ApiHelpers
+ let(:user) { create(:user) }
+ let!(:project) { create(:empty_project, namespace: user.namespace ) }
+ let!(:closed_milestone) { create(:closed_milestone, project: project) }
+ let!(:milestone) { create(:milestone, project: project) }
+
+ before { project.team << [user, :developer] }
+
+ describe 'GET /projects/:id/milestones' do
+ it 'returns project milestones' do
+ get v3_api("/projects/#{project.id}/milestones", user)
+
+ expect(response).to have_http_status(200)
+ expect(json_response).to be_an Array
+ expect(json_response.first['title']).to eq(milestone.title)
+ end
+
+ it 'returns a 401 error if user not authenticated' do
+ get v3_api("/projects/#{project.id}/milestones")
+
+ expect(response).to have_http_status(401)
+ end
+
+ it 'returns an array of active milestones' do
+ get v3_api("/projects/#{project.id}/milestones?state=active", user)
+
+ expect(response).to have_http_status(200)
+ expect(json_response).to be_an Array
+ expect(json_response.length).to eq(1)
+ expect(json_response.first['id']).to eq(milestone.id)
+ end
+
+ it 'returns an array of closed milestones' do
+ get v3_api("/projects/#{project.id}/milestones?state=closed", user)
+
+ expect(response).to have_http_status(200)
+ expect(json_response).to be_an Array
+ expect(json_response.length).to eq(1)
+ expect(json_response.first['id']).to eq(closed_milestone.id)
+ end
+ end
+
+ describe 'GET /projects/:id/milestones/:milestone_id' do
+ it 'returns a project milestone by id' do
+ get v3_api("/projects/#{project.id}/milestones/#{milestone.id}", user)
+
+ expect(response).to have_http_status(200)
+ expect(json_response['title']).to eq(milestone.title)
+ expect(json_response['iid']).to eq(milestone.iid)
+ end
+
+ it 'returns a project milestone by iid' do
+ get v3_api("/projects/#{project.id}/milestones?iid=#{closed_milestone.iid}", user)
+
+ expect(response.status).to eq 200
+ expect(json_response.size).to eq(1)
+ expect(json_response.first['title']).to eq closed_milestone.title
+ expect(json_response.first['id']).to eq closed_milestone.id
+ end
+
+ it 'returns a project milestone by iid array' do
+ get v3_api("/projects/#{project.id}/milestones", user), iid: [milestone.iid, closed_milestone.iid]
+
+ expect(response).to have_http_status(200)
+ expect(json_response.size).to eq(2)
+ expect(json_response.first['title']).to eq milestone.title
+ expect(json_response.first['id']).to eq milestone.id
+ end
+
+ it 'returns 401 error if user not authenticated' do
+ get v3_api("/projects/#{project.id}/milestones/#{milestone.id}")
+
+ expect(response).to have_http_status(401)
+ end
+
+ it 'returns a 404 error if milestone id not found' do
+ get v3_api("/projects/#{project.id}/milestones/1234", user)
+
+ expect(response).to have_http_status(404)
+ end
+ end
+
+ describe 'POST /projects/:id/milestones' do
+ it 'creates a new project milestone' do
+ post v3_api("/projects/#{project.id}/milestones", user), title: 'new milestone'
+
+ expect(response).to have_http_status(201)
+ expect(json_response['title']).to eq('new milestone')
+ expect(json_response['description']).to be_nil
+ end
+
+ it 'creates a new project milestone with description and dates' do
+ post v3_api("/projects/#{project.id}/milestones", user),
+ title: 'new milestone', description: 'release', due_date: '2013-03-02', start_date: '2013-02-02'
+
+ expect(response).to have_http_status(201)
+ expect(json_response['description']).to eq('release')
+ expect(json_response['due_date']).to eq('2013-03-02')
+ expect(json_response['start_date']).to eq('2013-02-02')
+ end
+
+ it 'returns a 400 error if title is missing' do
+ post v3_api("/projects/#{project.id}/milestones", user)
+
+ expect(response).to have_http_status(400)
+ end
+
+ it 'returns a 400 error if params are invalid (duplicate title)' do
+ post v3_api("/projects/#{project.id}/milestones", user),
+ title: milestone.title, description: 'release', due_date: '2013-03-02'
+
+ expect(response).to have_http_status(400)
+ end
+
+ it 'creates a new project with reserved html characters' do
+ post v3_api("/projects/#{project.id}/milestones", user), title: 'foo & bar 1.1 -> 2.2'
+
+ expect(response).to have_http_status(201)
+ expect(json_response['title']).to eq('foo & bar 1.1 -> 2.2')
+ expect(json_response['description']).to be_nil
+ end
+ end
+
+ describe 'PUT /projects/:id/milestones/:milestone_id' do
+ it 'updates a project milestone' do
+ put v3_api("/projects/#{project.id}/milestones/#{milestone.id}", user),
+ title: 'updated title'
+
+ expect(response).to have_http_status(200)
+ expect(json_response['title']).to eq('updated title')
+ end
+
+ it 'removes a due date if nil is passed' do
+ milestone.update!(due_date: "2016-08-05")
+
+ put v3_api("/projects/#{project.id}/milestones/#{milestone.id}", user), due_date: nil
+
+ expect(response).to have_http_status(200)
+ expect(json_response['due_date']).to be_nil
+ end
+
+ it 'returns a 404 error if milestone id not found' do
+ put v3_api("/projects/#{project.id}/milestones/1234", user),
+ title: 'updated title'
+
+ expect(response).to have_http_status(404)
+ end
+ end
+
+ describe 'PUT /projects/:id/milestones/:milestone_id to close milestone' do
+ it 'updates a project milestone' do
+ put v3_api("/projects/#{project.id}/milestones/#{milestone.id}", user),
+ state_event: 'close'
+ expect(response).to have_http_status(200)
+
+ expect(json_response['state']).to eq('closed')
+ end
+ end
+
+ describe 'PUT /projects/:id/milestones/:milestone_id to test observer on close' do
+ it 'creates an activity event when an milestone is closed' do
+ expect(Event).to receive(:create)
+
+ put v3_api("/projects/#{project.id}/milestones/#{milestone.id}", user),
+ state_event: 'close'
+ end
+ end
+
+ describe 'GET /projects/:id/milestones/:milestone_id/issues' do
+ before do
+ milestone.issues << create(:issue, project: project)
+ end
+ it 'returns project issues for a particular milestone' do
+ get v3_api("/projects/#{project.id}/milestones/#{milestone.id}/issues", user)
+
+ expect(response).to have_http_status(200)
+ expect(json_response).to be_an Array
+ expect(json_response.first['milestone']['title']).to eq(milestone.title)
+ end
+
+ it 'returns a 401 error if user not authenticated' do
+ get v3_api("/projects/#{project.id}/milestones/#{milestone.id}/issues")
+
+ expect(response).to have_http_status(401)
+ end
+
+ describe 'confidential issues' do
+ let(:public_project) { create(:empty_project, :public) }
+ let(:milestone) { create(:milestone, project: public_project) }
+ let(:issue) { create(:issue, project: public_project) }
+ let(:confidential_issue) { create(:issue, confidential: true, project: public_project) }
+
+ before do
+ public_project.team << [user, :developer]
+ milestone.issues << issue << confidential_issue
+ end
+
+ it 'returns confidential issues to team members' do
+ get v3_api("/projects/#{public_project.id}/milestones/#{milestone.id}/issues", user)
+
+ expect(response).to have_http_status(200)
+ expect(json_response).to be_an Array
+ expect(json_response.size).to eq(2)
+ expect(json_response.map { |issue| issue['id'] }).to include(issue.id, confidential_issue.id)
+ end
+
+ it 'does not return confidential issues to team members with guest role' do
+ member = create(:user)
+ project.team << [member, :guest]
+
+ get v3_api("/projects/#{public_project.id}/milestones/#{milestone.id}/issues", member)
+
+ expect(response).to have_http_status(200)
+ expect(json_response).to be_an Array
+ expect(json_response.size).to eq(1)
+ expect(json_response.map { |issue| issue['id'] }).to include(issue.id)
+ end
+
+ it 'does not return confidential issues to regular users' do
+ get v3_api("/projects/#{public_project.id}/milestones/#{milestone.id}/issues", create(:user))
+
+ expect(response).to have_http_status(200)
+ expect(json_response).to be_an Array
+ expect(json_response.size).to eq(1)
+ expect(json_response.map { |issue| issue['id'] }).to include(issue.id)
+ end
+ end
+ end
+end
diff --git a/spec/requests/api/v3/pipelines_spec.rb b/spec/requests/api/v3/pipelines_spec.rb
new file mode 100644
index 00000000000..3786eb06932
--- /dev/null
+++ b/spec/requests/api/v3/pipelines_spec.rb
@@ -0,0 +1,203 @@
+require 'spec_helper'
+
+describe API::V3::Pipelines, api: true do
+ include ApiHelpers
+
+ let(:user) { create(:user) }
+ let(:non_member) { create(:user) }
+ let(:project) { create(:project, :repository, creator: user) }
+
+ let!(:pipeline) do
+ create(:ci_empty_pipeline, project: project, sha: project.commit.id,
+ ref: project.default_branch)
+ end
+
+ before { project.team << [user, :master] }
+
+ shared_examples 'a paginated resources' do
+ before do
+ # Fires the request
+ request
+ end
+
+ it 'has pagination headers' do
+ expect(response).to include_pagination_headers
+ end
+ end
+
+ describe 'GET /projects/:id/pipelines ' do
+ it_behaves_like 'a paginated resources' do
+ let(:request) { get v3_api("/projects/#{project.id}/pipelines", user) }
+ end
+
+ context 'authorized user' do
+ it 'returns project pipelines' do
+ get v3_api("/projects/#{project.id}/pipelines", user)
+
+ expect(response).to have_http_status(200)
+ expect(json_response).to be_an Array
+ expect(json_response.first['sha']).to match(/\A\h{40}\z/)
+ expect(json_response.first['id']).to eq pipeline.id
+ expect(json_response.first.keys).to contain_exactly(*%w[id sha ref status before_sha tag yaml_errors user created_at updated_at started_at finished_at committed_at duration coverage])
+ end
+ end
+
+ context 'unauthorized user' do
+ it 'does not return project pipelines' do
+ get v3_api("/projects/#{project.id}/pipelines", non_member)
+
+ expect(response).to have_http_status(404)
+ expect(json_response['message']).to eq '404 Project Not Found'
+ expect(json_response).not_to be_an Array
+ end
+ end
+ end
+
+ describe 'POST /projects/:id/pipeline ' do
+ context 'authorized user' do
+ context 'with gitlab-ci.yml' do
+ before { stub_ci_pipeline_to_return_yaml_file }
+
+ it 'creates and returns a new pipeline' do
+ expect do
+ post v3_api("/projects/#{project.id}/pipeline", user), ref: project.default_branch
+ end.to change { Ci::Pipeline.count }.by(1)
+
+ expect(response).to have_http_status(201)
+ expect(json_response).to be_a Hash
+ expect(json_response['sha']).to eq project.commit.id
+ end
+
+ it 'fails when using an invalid ref' do
+ post v3_api("/projects/#{project.id}/pipeline", user), ref: 'invalid_ref'
+
+ expect(response).to have_http_status(400)
+ expect(json_response['message']['base'].first).to eq 'Reference not found'
+ expect(json_response).not_to be_an Array
+ end
+ end
+
+ context 'without gitlab-ci.yml' do
+ it 'fails to create pipeline' do
+ post v3_api("/projects/#{project.id}/pipeline", user), ref: project.default_branch
+
+ expect(response).to have_http_status(400)
+ expect(json_response['message']['base'].first).to eq 'Missing .gitlab-ci.yml file'
+ expect(json_response).not_to be_an Array
+ end
+ end
+ end
+
+ context 'unauthorized user' do
+ it 'does not create pipeline' do
+ post v3_api("/projects/#{project.id}/pipeline", non_member), ref: project.default_branch
+
+ expect(response).to have_http_status(404)
+ expect(json_response['message']).to eq '404 Project Not Found'
+ expect(json_response).not_to be_an Array
+ end
+ end
+ end
+
+ describe 'GET /projects/:id/pipelines/:pipeline_id' do
+ context 'authorized user' do
+ it 'returns project pipelines' do
+ get v3_api("/projects/#{project.id}/pipelines/#{pipeline.id}", user)
+
+ expect(response).to have_http_status(200)
+ expect(json_response['sha']).to match /\A\h{40}\z/
+ end
+
+ it 'returns 404 when it does not exist' do
+ get v3_api("/projects/#{project.id}/pipelines/123456", user)
+
+ expect(response).to have_http_status(404)
+ expect(json_response['message']).to eq '404 Not found'
+ expect(json_response['id']).to be nil
+ end
+
+ context 'with coverage' do
+ before do
+ create(:ci_build, coverage: 30, pipeline: pipeline)
+ end
+
+ it 'exposes the coverage' do
+ get v3_api("/projects/#{project.id}/pipelines/#{pipeline.id}", user)
+
+ expect(json_response["coverage"].to_i).to eq(30)
+ end
+ end
+ end
+
+ context 'unauthorized user' do
+ it 'should not return a project pipeline' do
+ get v3_api("/projects/#{project.id}/pipelines/#{pipeline.id}", non_member)
+
+ expect(response).to have_http_status(404)
+ expect(json_response['message']).to eq '404 Project Not Found'
+ expect(json_response['id']).to be nil
+ end
+ end
+ end
+
+ describe 'POST /projects/:id/pipelines/:pipeline_id/retry' do
+ context 'authorized user' do
+ let!(:pipeline) do
+ create(:ci_pipeline, project: project, sha: project.commit.id,
+ ref: project.default_branch)
+ end
+
+ let!(:build) { create(:ci_build, :failed, pipeline: pipeline) }
+
+ it 'retries failed builds' do
+ expect do
+ post v3_api("/projects/#{project.id}/pipelines/#{pipeline.id}/retry", user)
+ end.to change { pipeline.builds.count }.from(1).to(2)
+
+ expect(response).to have_http_status(201)
+ expect(build.reload.retried?).to be true
+ end
+ end
+
+ context 'unauthorized user' do
+ it 'should not return a project pipeline' do
+ post v3_api("/projects/#{project.id}/pipelines/#{pipeline.id}/retry", non_member)
+
+ expect(response).to have_http_status(404)
+ expect(json_response['message']).to eq '404 Project Not Found'
+ expect(json_response['id']).to be nil
+ end
+ end
+ end
+
+ describe 'POST /projects/:id/pipelines/:pipeline_id/cancel' do
+ let!(:pipeline) do
+ create(:ci_empty_pipeline, project: project, sha: project.commit.id,
+ ref: project.default_branch)
+ end
+
+ let!(:build) { create(:ci_build, :running, pipeline: pipeline) }
+
+ context 'authorized user' do
+ it 'retries failed builds' do
+ post v3_api("/projects/#{project.id}/pipelines/#{pipeline.id}/cancel", user)
+
+ expect(response).to have_http_status(200)
+ expect(json_response['status']).to eq('canceled')
+ end
+ end
+
+ context 'user without proper access rights' do
+ let!(:reporter) { create(:user) }
+
+ before { project.team << [reporter, :reporter] }
+
+ it 'rejects the action' do
+ post v3_api("/projects/#{project.id}/pipelines/#{pipeline.id}/cancel", reporter)
+
+ expect(response).to have_http_status(403)
+ expect(pipeline.reload.status).to eq('pending')
+ end
+ end
+ end
+end
diff --git a/spec/routing/project_routing_spec.rb b/spec/routing/project_routing_spec.rb
index a5bc62ef6c2..d31f1bdfb7c 100644
--- a/spec/routing/project_routing_spec.rb
+++ b/spec/routing/project_routing_spec.rb
@@ -431,12 +431,22 @@ describe 'project routing' do
end
end
- # project_notes GET /:project_id/notes(.:format) notes#index
- # POST /:project_id/notes(.:format) notes#create
- # project_note DELETE /:project_id/notes/:id(.:format) notes#destroy
+ # project_noteable_notes GET /:project_id/noteable/:target_type/:target_id/notes notes#index
+ # POST /:project_id/notes(.:format) notes#create
+ # project_note DELETE /:project_id/notes/:id(.:format) notes#destroy
describe Projects::NotesController, 'routing' do
+ it 'to #index' do
+ expect(get('/gitlab/gitlabhq/noteable/issue/1/notes')).to route_to(
+ 'projects/notes#index',
+ namespace_id: 'gitlab',
+ project_id: 'gitlabhq',
+ target_type: 'issue',
+ target_id: '1'
+ )
+ end
+
it_behaves_like 'RESTful project resources' do
- let(:actions) { [:index, :create, :destroy] }
+ let(:actions) { [:create, :destroy] }
let(:controller) { 'notes' }
end
end
diff --git a/spec/services/ci/retry_build_service_spec.rb b/spec/services/ci/retry_build_service_spec.rb
index d03f7505eac..65af4e13118 100644
--- a/spec/services/ci/retry_build_service_spec.rb
+++ b/spec/services/ci/retry_build_service_spec.rb
@@ -10,22 +10,39 @@ describe Ci::RetryBuildService, :services do
described_class.new(project, user)
end
+ CLONE_ACCESSORS = described_class::CLONE_ACCESSORS
+
+ REJECT_ACCESSORS =
+ %i[id status user token coverage trace runner artifacts_expire_at
+ artifacts_file artifacts_metadata artifacts_size created_at
+ updated_at started_at finished_at queued_at erased_by
+ erased_at].freeze
+
+ IGNORE_ACCESSORS =
+ %i[type lock_version target_url gl_project_id deploy job_id base_tags
+ commit_id deployments erased_by_id last_deployment project_id
+ runner_id tag_taggings taggings tags trigger_request_id
+ user_id].freeze
+
shared_examples 'build duplication' do
let(:build) do
- create(:ci_build, :failed, :artifacts_expired, :erased, :trace,
- :queued, :coverage, pipeline: pipeline)
+ create(:ci_build, :failed, :artifacts_expired, :erased,
+ :queued, :coverage, :tags, :allowed_to_fail, :on_tag,
+ :teardown_environment, :triggered, :trace,
+ description: 'some build', pipeline: pipeline)
end
- describe 'clone attributes' do
- described_class::CLONE_ATTRIBUTES.each do |attribute|
+ describe 'clone accessors' do
+ CLONE_ACCESSORS.each do |attribute|
it "clones #{attribute} build attribute" do
+ expect(new_build.send(attribute)).to be_present
expect(new_build.send(attribute)).to eq build.send(attribute)
end
end
end
- describe 'reject attributes' do
- described_class::REJECT_ATTRIBUTES.each do |attribute|
+ describe 'reject acessors' do
+ REJECT_ACCESSORS.each do |attribute|
it "does not clone #{attribute} build attribute" do
expect(new_build.send(attribute)).not_to eq build.send(attribute)
end
@@ -33,12 +50,20 @@ describe Ci::RetryBuildService, :services do
end
it 'has correct number of known attributes' do
- attributes =
- described_class::CLONE_ATTRIBUTES +
- described_class::IGNORE_ATTRIBUTES +
- described_class::REJECT_ATTRIBUTES
+ known_accessors = CLONE_ACCESSORS + REJECT_ACCESSORS + IGNORE_ACCESSORS
+
+ # :tag_list is a special case, this accessor does not exist
+ # in reflected associations, comes from `act_as_taggable` and
+ # we use it to copy tags, instead of reusing tags.
+ #
+ current_accessors =
+ Ci::Build.attribute_names.map(&:to_sym) +
+ Ci::Build.reflect_on_all_associations.map(&:name) +
+ [:tag_list]
+
+ current_accessors.uniq!
- expect(build.attributes.size).to eq(attributes.size)
+ expect(known_accessors).to contain_exactly(*current_accessors)
end
end
diff --git a/spec/services/projects/update_pages_service_spec.rb b/spec/services/projects/update_pages_service_spec.rb
index 411b22a0fb8..f75fdd9e03f 100644
--- a/spec/services/projects/update_pages_service_spec.rb
+++ b/spec/services/projects/update_pages_service_spec.rb
@@ -26,6 +26,28 @@ describe Projects::UpdatePagesService do
build.update_attributes(artifacts_metadata: metadata)
end
+ describe 'pages artifacts' do
+ context 'with expiry date' do
+ before do
+ build.artifacts_expire_in = "2 days"
+ end
+
+ it "doesn't delete artifacts" do
+ expect(execute).to eq(:success)
+
+ expect(build.reload.artifacts_file?).to eq(true)
+ end
+ end
+
+ context 'without expiry date' do
+ it "does delete artifacts" do
+ expect(execute).to eq(:success)
+
+ expect(build.reload.artifacts_file?).to eq(false)
+ end
+ end
+ end
+
it 'succeeds' do
expect(project.pages_deployed?).to be_falsey
expect(execute).to eq(:success)
diff --git a/spec/services/system_note_service_spec.rb b/spec/services/system_note_service_spec.rb
index 1f2ec9eacf0..36a17a3bf2e 100644
--- a/spec/services/system_note_service_spec.rb
+++ b/spec/services/system_note_service_spec.rb
@@ -418,45 +418,6 @@ describe SystemNoteService, services: true do
to be_truthy
end
end
-
- context 'when noteable is an Issue' do
- let(:issue) { create(:issue, project: project) }
-
- it 'is truthy when issue is closed' do
- issue.close
-
- expect(described_class.cross_reference_disallowed?(issue, project.commit)).
- to be_truthy
- end
-
- it 'is falsey when issue is open' do
- expect(described_class.cross_reference_disallowed?(issue, project.commit)).
- to be_falsy
- end
- end
-
- context 'when noteable is a Merge Request' do
- let(:merge_request) { create(:merge_request, :simple, source_project: project) }
-
- it 'is truthy when merge request is closed' do
- allow(merge_request).to receive(:closed?).and_return(:true)
-
- expect(described_class.cross_reference_disallowed?(merge_request, project.commit)).
- to be_truthy
- end
-
- it 'is truthy when merge request is merged' do
- allow(merge_request).to receive(:closed?).and_return(:true)
-
- expect(described_class.cross_reference_disallowed?(merge_request, project.commit)).
- to be_truthy
- end
-
- it 'is falsey when merge request is open' do
- expect(described_class.cross_reference_disallowed?(merge_request, project.commit)).
- to be_falsy
- end
- end
end
describe '.cross_reference_exists?' do