From dd13d6ff10073d2a30bab29fff1e8b1c4998014e Mon Sep 17 00:00:00 2001 From: Pirate Praveen Date: Wed, 9 May 2018 12:01:36 +0530 Subject: [PATCH] New upstream version 10.7.3+dfsg --- .babelrc | 26 +- .codeclimate.yml | 6 - .eslintignore | 5 +- .eslintrc | 28 +- .flayignore | 1 + .gitignore | 5 + .gitlab-ci.yml | 133 +- .../Database Changes.md | 11 +- .../merge_request_templates/Documentation.md | 27 +- .prettierignore | 5 + .prettierrc | 13 + .rubocop.yml | 72 + .scss-lint.yml | 2 + CHANGELOG.md | 323 +- CONTRIBUTING.md | 18 +- GITALY_SERVER_VERSION | 2 +- GITLAB_PAGES_VERSION | 2 +- GITLAB_SHELL_VERSION | 2 +- GITLAB_WORKHORSE_VERSION | 2 +- Gemfile | 90 +- Gemfile.lock | 249 +- Gemfile.rails5 | 7 + Gemfile.rails5.lock | 1223 ++ PROCESS.md | 5 +- Procfile | 1 - VERSION | 2 +- .../canary/favicon_status_canceled.ico | Bin 0 -> 4286 bytes .../canary/favicon_status_created.ico | Bin 0 -> 4286 bytes .../canary/favicon_status_failed.ico | Bin 0 -> 4286 bytes .../canary/favicon_status_manual.ico | Bin 0 -> 4286 bytes .../canary/favicon_status_not_found.ico | Bin 0 -> 4286 bytes .../canary/favicon_status_pending.ico | Bin 0 -> 4286 bytes .../canary/favicon_status_running.ico | Bin 0 -> 4286 bytes .../canary/favicon_status_skipped.ico | Bin 0 -> 4286 bytes .../canary/favicon_status_success.ico | Bin 0 -> 4286 bytes .../canary/favicon_status_warning.ico | Bin 0 -> 4286 bytes app/assets/images/favicon-yellow.ico | Bin 0 -> 5430 bytes app/assets/images/icons.json | 1 - app/assets/images/icons.svg | 1 - .../images/illustrations/cluster_popover.svg | 1 - .../images/illustrations/clusters_empty.svg | 1 - .../illustrations/convdev/convdev_no_data.svg | 1 - .../convdev/convdev_no_index.svg | 1 - .../convdev/convdev_overview.svg | 1 - .../illustrations/convdev/i2p_step_1.svg | 1 - .../illustrations/convdev/i2p_step_10.svg | 1 - .../illustrations/convdev/i2p_step_2.svg | 1 - .../illustrations/convdev/i2p_step_3.svg | 1 - .../illustrations/convdev/i2p_step_4.svg | 1 - .../illustrations/convdev/i2p_step_5.svg | 1 - .../illustrations/convdev/i2p_step_6.svg | 1 - .../illustrations/convdev/i2p_step_7.svg | 1 - .../illustrations/convdev/i2p_step_8.svg | 1 - .../illustrations/convdev/i2p_step_9.svg | 1 - app/assets/images/illustrations/epics.svg | 1 - .../images/illustrations/gitlab_logo.svg | 1 - .../image_comment_light_cursor.svg | 1 - .../image_comment_light_cursor@2x.svg | 1 - app/assets/images/illustrations/issues.svg | 1 - .../illustrations/job_not_triggered.svg | 1 - app/assets/images/illustrations/labels.svg | 1 - .../images/illustrations/logos/go_logo.svg | 1 - .../illustrations/logos/mattermost_logo.svg | 1 - .../images/illustrations/manual_action.svg | 1 - .../merge_request_changes_empty.svg | 1 - .../images/illustrations/merge_requests.svg | 1 - .../monitoring/getting_started.svg | 1 - .../illustrations/monitoring/loading.svg | 1 - .../monitoring/unable_to_connect.svg | 1 - ...lti-editor_all_changes_committed_empty.svg | 1 - .../multi-editor_no_changes_empty.svg | 1 - .../multi-editor_no_staged_files_empty.svg | 1 - .../illustrations/multi_file_editor_empty.svg | 1 - .../images/illustrations/no_commits.svg | 1 - .../illustrations/pending_job_empty.svg | 1 - .../images/illustrations/pipelines_empty.svg | 1 - .../images/illustrations/pipelines_failed.svg | 1 - .../illustrations/pipelines_pending.svg | 1 - .../images/illustrations/priority_labels.svg | 1 - .../illustrations/service_desk_callout.svg | 1 - .../illustrations/service_desk_empty.svg | 1 - .../images/illustrations/slack_logo.svg | 1 - .../images/illustrations/todos_all_done.svg | 1 - .../images/illustrations/todos_empty.svg | 1 - .../illustrations/welcome/add_new_group.svg | 1 - .../illustrations/welcome/add_new_project.svg | 1 - .../illustrations/welcome/add_new_user.svg | 1 - .../welcome/configure_server.svg | 1 - .../images/illustrations/welcome/ee_trial.svg | 1 - .../images/illustrations/welcome/globe.svg | 1 - .../illustrations/welcome/lightbulb.svg | 1 - .../wiki-fro-logged-out-users.svg | 1 - .../images/illustrations/wiki_login_empty.svg | 1 - .../illustrations/wiki_logout_empty.svg | 1 - app/assets/javascripts/activities.js | 1 + .../javascripts/ajax_loading_spinner.js | 2 + app/assets/javascripts/api.js | 147 +- app/assets/javascripts/awards_handler.js | 17 +- .../javascripts/badges/components/badge.vue | 121 + .../badges/components/badge_form.vue | 219 + .../badges/components/badge_list.vue | 57 + .../badges/components/badge_list_row.vue | 89 + .../badges/components/badge_settings.vue | 70 + app/assets/javascripts/badges/constants.js | 2 + app/assets/javascripts/badges/empty_badge.js | 7 + .../javascripts/badges/store/actions.js | 167 + app/assets/javascripts/badges/store/index.js | 13 + .../badges/store/mutation_types.js | 21 + .../javascripts/badges/store/mutations.js | 158 + app/assets/javascripts/badges/store/state.js | 13 + .../behaviors/copy_to_clipboard.js | 1 + .../javascripts/behaviors/details_behavior.js | 1 + app/assets/javascripts/behaviors/index.js | 3 +- .../behaviors/{ => markdown}/copy_as_gfm.js | 5 +- .../{ => behaviors/markdown}/render_gfm.js | 3 +- .../{ => behaviors/markdown}/render_math.js | 7 +- .../markdown}/render_mermaid.js | 6 +- .../javascripts/behaviors/quick_submit.js | 3 +- .../javascripts/behaviors/requires_input.js | 1 + .../javascripts/behaviors/toggler_behavior.js | 4 +- .../javascripts/blob/blob_file_dropzone.js | 2 + .../javascripts/blob/blob_fork_suggestion.js | 2 + .../blob/file_template_mediator.js | 2 + .../blob/file_template_selector.js | 2 + .../javascripts/blob/template_selector.js | 4 +- app/assets/javascripts/blob/viewer/index.js | 1 + .../javascripts/blob_edit/blob_bundle.js | 2 + app/assets/javascripts/blob_edit/edit_blob.js | 1 + .../javascripts/boards/components/board.js | 2 + .../boards/components/board_delete.js | 1 + .../boards/components/board_new_issue.vue | 1 + .../boards/components/board_sidebar.js | 9 +- .../boards/components/issue_card_inner.js | 18 +- .../boards/components/new_list_dropdown.js | 5 +- .../boards/components/project_select.vue | 2 + .../boards/components/sidebar/remove_issue.js | 6 +- .../boards/filtered_search_boards.js | 1 + app/assets/javascripts/boards/index.js | 1 + .../boards/mixins/sortable_default_options.js | 1 + app/assets/javascripts/boards/models/issue.js | 6 +- app/assets/javascripts/boards/models/list.js | 2 + .../javascripts/boards/stores/boards_store.js | 2 + .../branches/branches_delete_modal.js | 2 + app/assets/javascripts/breadcrumb.js | 2 + app/assets/javascripts/build_artifacts.js | 2 + app/assets/javascripts/build_variables.js | 4 +- .../ci_variable_list/ci_variable_list.js | 4 +- .../native_form_variable_list.js | 1 + app/assets/javascripts/commit/image_file.js | 2 + .../javascripts/commit_merge_requests.js | 1 + app/assets/javascripts/commits.js | 1 + app/assets/javascripts/compare.js | 2 + .../javascripts/compare_autocomplete.js | 2 + .../javascripts/confirm_danger_modal.js | 57 +- app/assets/javascripts/contextual_sidebar.js | 1 + app/assets/javascripts/create_label.js | 2 + .../cycle_analytics/cycle_analytics_bundle.js | 1 + app/assets/javascripts/diff.js | 1 + .../components/comment_resolve_btn.js | 1 + .../components/diff_note_avatars.js | 1 + .../components/jump_to_discussion.js | 1 + .../diff_notes/components/resolve_btn.js | 1 + .../diff_notes/diff_notes_bundle.js | 1 + .../diff_notes/models/discussion.js | 1 + app/assets/javascripts/dispatcher.js | 14 +- app/assets/javascripts/dropzone_input.js | 1 + app/assets/javascripts/due_date_select.js | 1 + .../components/environment_stop.vue | 2 + app/assets/javascripts/experimental_flags.js | 1 + .../feature_highlight/feature_highlight.js | 1 + .../feature_highlight_helper.js | 1 + app/assets/javascripts/filterable_list.js | 1 + .../filtered_search_dropdown_manager.js | 18 +- .../filtered_search_manager.js | 3 +- app/assets/javascripts/gfm_auto_complete.js | 23 +- app/assets/javascripts/gl_dropdown.js | 6 +- app/assets/javascripts/gl_field_error.js | 2 + app/assets/javascripts/gl_field_errors.js | 1 + app/assets/javascripts/gl_form.js | 7 +- app/assets/javascripts/gpg_badges.js | 1 + app/assets/javascripts/group.js | 2 + app/assets/javascripts/group_avatar.js | 2 + .../javascripts/group_label_subscription.js | 1 + .../javascripts/groups/components/app.vue | 89 +- .../groups/groups_filterable_list.js | 1 + .../javascripts/groups/transfer_dropdown.js | 2 + app/assets/javascripts/groups_select.js | 1 + app/assets/javascripts/header.js | 1 + app/assets/javascripts/help/help.js | 3 + app/assets/javascripts/how_to_merge.js | 2 + .../ide/components/changed_file_icon.vue | 31 + .../ide/components/commit_sidebar/actions.vue | 65 + .../ide/components/commit_sidebar/list.vue | 66 + .../commit_sidebar/list_collapsed.vue | 35 + .../components/commit_sidebar/list_item.vue | 58 + .../components/commit_sidebar/radio_group.vue | 94 + .../ide/components/editor_mode_dropdown.vue | 130 + app/assets/javascripts/ide/components/ide.vue | 108 + .../ide/components/ide_context_bar.vue | 84 + .../ide/components/ide_external_links.vue | 43 + .../ide/components/ide_file_buttons.vue | 84 + .../components/ide_project_branches_tree.vue | 47 + .../ide/components/ide_project_tree.vue | 65 + .../ide/components/ide_repo_tree.vue | 41 + .../ide/components/ide_side_bar.vue | 51 + .../ide/components/ide_status_bar.vue | 60 + .../ide/components/mr_file_icon.vue | 23 + .../ide/components/new_dropdown/index.vue | 111 + .../ide/components/new_dropdown/modal.vue | 99 + .../ide/components/new_dropdown/upload.vue | 75 + .../ide/components/repo_commit_section.vue | 172 + .../ide/components/repo_editor.vue | 219 + .../javascripts/ide/components/repo_file.vue | 127 + .../ide/components/repo_file_status_icon.vue | 39 + .../ide/components/repo_loading_file.vue | 42 + .../javascripts/ide/components/repo_tab.vue | 104 + .../javascripts/ide/components/repo_tabs.vue | 82 + .../ide/components/resizable_panel.vue | 85 + app/assets/javascripts/ide/eventhub.js | 3 + app/assets/javascripts/ide/ide_router.js | 173 + app/assets/javascripts/ide/index.js | 33 + .../javascripts/ide/lib/common/disposable.js | 14 + .../javascripts/ide/lib/common/model.js | 94 + .../ide/lib/common/model_manager.js | 48 + .../ide/lib/decorations/controller.js | 45 + .../javascripts/ide/lib/diff/controller.js | 72 + app/assets/javascripts/ide/lib/diff/diff.js | 30 + .../javascripts/ide/lib/diff/diff_worker.js | 10 + app/assets/javascripts/ide/lib/editor.js | 192 + .../javascripts/ide/lib/editor_options.js | 16 + .../javascripts/ide/lib/themes/gl_theme.js | 14 + app/assets/javascripts/ide/monaco_loader.js | 16 + app/assets/javascripts/ide/services/index.js | 78 + app/assets/javascripts/ide/stores/actions.js | 118 + .../javascripts/ide/stores/actions/file.js | 187 + .../ide/stores/actions/merge_request.js | 84 + .../javascripts/ide/stores/actions/project.js | 49 + .../javascripts/ide/stores/actions/tree.js | 95 + app/assets/javascripts/ide/stores/getters.js | 37 + app/assets/javascripts/ide/stores/index.js | 19 + .../ide/stores/modules/commit/actions.js | 200 + .../ide/stores/modules/commit/constants.js | 3 + .../ide/stores/modules/commit/getters.js | 24 + .../ide/stores/modules/commit/index.js | 12 + .../stores/modules/commit/mutation_types.js | 4 + .../ide/stores/modules/commit/mutations.js | 24 + .../ide/stores/modules/commit/state.js | 6 + .../javascripts/ide/stores/mutation_types.js | 55 + .../javascripts/ide/stores/mutations.js | 103 + .../ide/stores/mutations/branch.js | 26 + .../javascripts/ide/stores/mutations/file.js | 147 + .../ide/stores/mutations/merge_request.js | 33 + .../ide/stores/mutations/project.js | 24 + .../javascripts/ide/stores/mutations/tree.js | 34 + app/assets/javascripts/ide/stores/state.js | 20 + app/assets/javascripts/ide/stores/utils.js | 134 + .../stores/workers/files_decorator_worker.js | 90 + .../javascripts/image_diff/image_diff.js | 1 + app/assets/javascripts/importer_status.js | 1 + .../javascripts/init_changes_dropdown.js | 1 + app/assets/javascripts/init_labels.js | 1 + .../integrations/integration_settings_form.js | 1 + .../issuable/auto_width_dropdown_select.js | 2 + .../issuable_bulk_update_actions.js | 2 + .../issuable_bulk_update_sidebar.js | 1 + app/assets/javascripts/issuable_context.js | 1 + app/assets/javascripts/issuable_form.js | 1 + app/assets/javascripts/issuable_index.js | 1 + app/assets/javascripts/issue.js | 2 + .../issue_show/components/description.vue | 1 + .../fields/description_template.vue | 1 + app/assets/javascripts/issue_status_select.js | 2 + app/assets/javascripts/job.js | 1 + .../jobs/components/sidebar_detail_row.vue | 24 + .../jobs/components/sidebar_details_block.vue | 27 + .../javascripts/jobs/job_details_bundle.js | 1 + app/assets/javascripts/label_manager.js | 2 + app/assets/javascripts/labels.js | 2 + app/assets/javascripts/labels_select.js | 2 + app/assets/javascripts/layout_nav.js | 1 + .../lib/utils/bootstrap_linked_tabs.js | 2 + .../javascripts/lib/utils/common_utils.js | 5 +- app/assets/javascripts/lib/utils/csrf.js | 2 + .../javascripts/lib/utils/datetime_utility.js | 1 + app/assets/javascripts/lib/utils/dom_utils.js | 7 +- .../javascripts/lib/utils/text_markdown.js | 135 +- .../javascripts/lib/utils/text_utility.js | 34 +- .../javascripts/lib/utils/url_utility.js | 10 +- app/assets/javascripts/line_highlighter.js | 2 + app/assets/javascripts/logo.js | 2 + app/assets/javascripts/main.js | 14 +- .../javascripts/member_expiration_date.js | 1 + app/assets/javascripts/members.js | 2 + .../merge_conflicts/merge_conflict_store.js | 1 + .../merge_conflicts/merge_conflicts_bundle.js | 1 + app/assets/javascripts/merge_request.js | 2 + app/assets/javascripts/merge_request_tabs.js | 53 +- app/assets/javascripts/milestone.js | 1 + app/assets/javascripts/milestone_select.js | 2 + .../mini_pipeline_graph_dropdown.js | 2 + .../monitoring/components/dashboard.vue | 288 +- .../monitoring/components/empty_state.vue | 159 +- .../monitoring/components/graph.vue | 442 +- .../monitoring/components/graph/axis.vue | 142 + .../components/graph/deployment.vue | 48 +- .../monitoring/components/graph/flag.vue | 246 +- .../monitoring/components/graph/legend.vue | 258 +- .../monitoring/components/graph/path.vue | 60 +- .../components/graph/track_info.vue | 29 + .../components/graph/track_line.vue | 36 + .../monitoring/components/graph_group.vue | 24 +- .../monitoring/stores/monitoring_store.js | 2 +- .../monitoring/utils/multiple_time_series.js | 82 +- app/assets/javascripts/mr_notes/index.js | 14 +- app/assets/javascripts/namespace_select.js | 2 + .../javascripts/network/branch_graph.js | 1 + app/assets/javascripts/new_branch_form.js | 2 + app/assets/javascripts/notes.js | 745 +- .../notes/components/comment_form.vue | 578 +- .../notes/components/diff_file_header.vue | 34 +- .../notes/components/diff_with_note.vue | 95 +- .../notes/components/discussion_counter.vue | 114 +- .../components/discussion_locked_widget.vue | 18 +- .../notes/components/note_actions.vue | 217 +- .../notes/components/note_attachment.vue | 16 +- .../notes/components/note_awards_list.vue | 354 +- .../notes/components/note_body.vue | 136 +- .../notes/components/note_edited_text.vue | 50 +- .../notes/components/note_form.vue | 228 +- .../notes/components/note_header.vue | 110 +- .../components/note_signed_out_widget.vue | 24 +- .../notes/components/noteable_discussion.vue | 380 +- .../notes/components/noteable_note.vue | 262 +- .../notes/components/notes_app.vue | 288 +- app/assets/javascripts/notes/constants.js | 7 + app/assets/javascripts/notes/index.js | 73 +- .../javascripts/notes/mixins/autosave.js | 7 +- .../javascripts/notes/mixins/noteable.js | 9 +- .../javascripts/notes/mixins/resolvable.js | 11 +- .../notes/services/notes_service.js | 4 +- .../javascripts/notes/stores/actions.js | 254 +- .../javascripts/notes/stores/getters.js | 34 +- .../javascripts/notes/stores/mutations.js | 28 +- app/assets/javascripts/notes/stores/utils.js | 13 +- .../javascripts/notifications_dropdown.js | 1 + app/assets/javascripts/notifications_form.js | 1 + app/assets/javascripts/pager.js | 1 + .../admin/abuse_reports/abuse_reports.js | 1 + app/assets/javascripts/pages/admin/admin.js | 1 + .../pages/admin/application_settings/index.js | 6 + .../broadcast_messages/broadcast_message.js | 1 + .../index/components/delete_project_modal.vue | 8 +- .../pages/admin/projects/index/index.js | 1 + .../users/components/delete_user_modal.vue | 8 +- .../javascripts/pages/admin/users/index.js | 1 + .../pages/dashboard/todos/index/todos.js | 2 + .../javascripts/pages/groups/edit/index.js | 2 + .../javascripts/pages/groups/issues/index.js | 1 + .../pages/groups/merge_requests/index.js | 1 + .../pages/groups/settings/badges/index.js | 10 + .../javascripts/pages/help/index/index.js | 1 + .../components/delete_milestone_modal.vue | 8 +- .../javascripts/pages/profiles/index.js | 1 + .../pages/profiles/two_factor_auths/index.js | 1 + .../pages/projects/blob/show/index.js | 22 + .../pages/projects/branches/new/index.js | 1 + .../{ => projects}/ci/lints/ci_lint_editor.js | 0 .../{ => projects}/ci/lints/new/index.js | 0 .../{ => projects}/ci/lints/show/index.js | 0 .../pages/projects/commit/pipelines/index.js | 1 + .../pages/projects/commit/show/index.js | 2 + .../javascripts/pages/projects/edit/index.js | 2 + .../pages/projects/find_file/show/index.js | 1 + .../pages/projects/graphs/charts/index.js | 1 + .../pages/projects/graphs/show/index.js | 1 + .../graphs/show/stat_graph_contributors.js | 1 + .../show/stat_graph_contributors_graph.js | 2 + .../javascripts/pages/projects/issues/form.js | 2 + .../merge_requests/init_merge_request.js | 1 + .../pages/projects/network/network.js | 1 + .../pages/projects/network/show/index.js | 1 + .../components/target_branch_dropdown.js | 2 + .../shared/components/timezone_dropdown.js | 2 + .../pipeline_schedules/shared/init_form.js | 1 + .../pages/projects/pipelines/charts/index.js | 1 + .../pages/projects/pipelines/new/index.js | 1 + .../javascripts/pages/projects/project.js | 1 + .../pages/projects/releases/edit/index.js | 1 + .../projects/settings/badges/index/index.js | 10 + .../repository/create_deploy_token/index.js | 3 + .../projects/settings/repository/form.js | 19 + .../settings/repository/show/index.js | 18 +- .../pages/projects/shared/project_avatar.js | 2 + .../pages/projects/shared/project_new.js | 1 + .../pages/projects/snippets/edit/index.js | 1 + .../pages/projects/snippets/new/index.js | 1 + .../pages/projects/tags/new/index.js | 1 + .../pages/projects/tree/show/index.js | 1 + .../javascripts/pages/projects/wikis/index.js | 1 + .../javascripts/pages/search/show/search.js | 1 + .../javascripts/pages/sessions/new/index.js | 1 + .../pages/sessions/new/oauth_remember_me.js | 2 + .../pages/sessions/new/username_validator.js | 1 + .../pages/shared/mount_badge_settings.js | 24 + app/assets/javascripts/pages/snippets/form.js | 1 + .../pages/users/activity_calendar.js | 1 + app/assets/javascripts/pages/users/index.js | 1 + .../javascripts/pages/users/user_tabs.js | 1 + app/assets/javascripts/performance_bar.js | 63 - .../components/detailed_metric.vue | 93 + .../components/performance_bar_app.vue | 191 + .../components/request_selector.vue | 52 + .../components/simple_metric.vue | 30 + .../components/upstream_performance_bar.vue | 20 + .../javascripts/performance_bar/index.js | 37 + .../services/performance_bar_service.js | 41 + .../stores/performance_bar_store.js | 39 + .../components/graph/action_component.vue | 98 +- .../graph/dropdown_job_component.vue | 1 + .../components/graph/graph_component.vue | 94 +- .../components/graph/job_component.vue | 179 +- .../graph/stage_column_component.vue | 90 +- .../pipelines/components/nav_controls.vue | 27 +- .../pipelines/components/pipelines.vue | 21 + .../pipelines/components/pipelines_table.vue | 8 +- .../pipelines/components/stage.vue | 1 + .../javascripts/pipelines/mixins/pipelines.js | 6 +- .../pipelines/pipeline_details_bundle.js | 23 + .../pipelines/pipeline_details_mediator.js | 7 +- app/assets/javascripts/preview_markdown.js | 9 +- .../components/delete_account_modal.vue | 8 +- .../account/components/update_username.vue | 121 + .../javascripts/profile/account/index.js | 15 + app/assets/javascripts/profile/gl_crop.js | 1 + app/assets/javascripts/profile/profile.js | 43 +- app/assets/javascripts/project_edit.js | 2 + app/assets/javascripts/project_find_file.js | 1 + app/assets/javascripts/project_fork.js | 2 + .../javascripts/project_label_subscription.js | 1 + app/assets/javascripts/project_select.js | 2 + .../project_select_combo_button.js | 1 + app/assets/javascripts/project_visibility.js | 2 + .../projects/project_import_gitlab_project.js | 1 + .../javascripts/projects/project_new.js | 1 + .../javascripts/projects_dropdown/index.js | 1 + .../prometheus_metrics/prometheus_metrics.js | 1 + .../protected_branch_create.js | 1 + .../protected_branch_edit_list.js | 1 + .../protected_tags/protected_tag_create.js | 1 + .../protected_tags/protected_tag_edit_list.js | 1 + app/assets/javascripts/ref_select_dropdown.js | 2 + app/assets/javascripts/right_sidebar.js | 1 + app/assets/javascripts/search_autocomplete.js | 10 +- app/assets/javascripts/settings_panels.js | 2 + .../javascripts/shared/milestones/form.js | 1 + app/assets/javascripts/shared/sessions/u2f.js | 1 + app/assets/javascripts/shortcuts.js | 1 + app/assets/javascripts/shortcuts_issuable.js | 3 +- .../components/assignees/assignee_title.js | 59 - .../components/assignees/assignee_title.vue | 64 + .../assignees/sidebar_assignees.vue | 2 +- .../confidential_issue_sidebar.vue | 101 +- .../components/confidential/edit_form.vue | 53 +- .../confidential/edit_form_buttons.vue | 21 +- .../sidebar/components/lock/edit_form.vue | 66 +- .../components/lock/edit_form_buttons.vue | 23 +- .../components/lock/lock_issue_sidebar.vue | 120 +- .../time_tracking/collapsed_state.js | 96 - .../time_tracking/collapsed_state.vue | 102 + ...comparison_pane.js => comparison_pane.vue} | 76 +- .../time_tracking/sidebar_time_tracking.js | 1 + .../components/time_tracking/time_tracker.vue | 8 +- .../sidebar/lib/sidebar_move_issue.js | 1 + .../javascripts/sidebar/mount_sidebar.js | 1 + app/assets/javascripts/single_file_diff.js | 1 + app/assets/javascripts/smart_interval.js | 2 + .../javascripts/snippet/snippet_bundle.js | 2 + app/assets/javascripts/star.js | 1 + app/assets/javascripts/subscription_select.js | 2 + app/assets/javascripts/syntax_highlight.js | 2 + app/assets/javascripts/task_list.js | 1 + .../templates/issuable_template_selector.js | 1 + .../templates/issuable_template_selectors.js | 2 + app/assets/javascripts/terminal/terminal.js | 2 + app/assets/javascripts/tree.js | 2 + app/assets/javascripts/u2f/authenticate.js | 1 + app/assets/javascripts/u2f/register.js | 1 + app/assets/javascripts/ui_development_kit.js | 1 + app/assets/javascripts/user_callout.js | 1 + app/assets/javascripts/users_select.js | 2 + .../components/deployment.vue | 144 + ...idget_memory_usage.js => memory_usage.vue} | 105 +- .../components/mr_widget_deployment.js | 113 - .../components/mr_widget_header.vue | 97 +- .../source_branch_removal_status.vue | 34 + .../states/mr_widget_nothing_to_merge.js | 44 - .../states/mr_widget_ready_to_merge.js | 4 +- .../states/mr_widget_sha_mismatch.js | 18 - .../mr_widget_unresolved_discussions.js | 27 - .../components/states/mr_widget_wip.js | 1 + .../components/states/nothing_to_merge.vue | 47 + .../components/states/sha_mismatch.vue | 25 + .../states/unresolved_discussions.vue | 33 + .../vue_merge_request_widget/dependencies.js | 12 +- .../mr_widget_options.js | 27 +- .../stores/mr_widget_store.js | 4 + .../stores/state_maps.js | 3 +- .../content_viewer/content_viewer.vue | 58 + .../content_viewer/lib/viewer_utils.js | 32 + .../viewers/download_viewer.vue | 52 + .../content_viewer/viewers/image_viewer.vue | 68 + .../viewers/markdown_viewer.vue | 90 + .../{modal.vue => deprecated_modal.vue} | 2 +- .../vue_shared/components/file_icon.vue | 3 +- .../vue_shared/components/gl_modal.vue | 79 +- .../vue_shared/components/identicon.vue | 2 +- .../vue_shared/components/markdown/field.vue | 1 + .../vue_shared/components/markdown/header.vue | 1 + .../{memory_graph.js => memory_graph.vue} | 38 +- .../vue_shared/components/navigation_tabs.vue | 2 + .../vue_shared/components/recaptcha_modal.vue | 8 +- .../components/sidebar/labels_select/base.vue | 24 + .../labels_select/dropdown_create_label.vue | 11 +- .../sidebar/labels_select/dropdown_footer.vue | 16 +- .../components/skeleton_loading_container.vue | 2 +- .../vue_shared/directives/popover.js | 2 + .../vue_shared/directives/tooltip.js | 2 + app/assets/javascripts/zen_mode.js | 1 + .../stylesheets/framework/animations.scss | 80 +- app/assets/stylesheets/framework/buttons.scss | 4 + app/assets/stylesheets/framework/common.scss | 4 + .../framework/contextual_sidebar.scss | 26 +- .../stylesheets/framework/dropdowns.scss | 33 +- .../stylesheets/framework/gitlab_theme.scss | 113 +- app/assets/stylesheets/framework/header.scss | 107 +- app/assets/stylesheets/framework/images.scss | 41 +- app/assets/stylesheets/framework/lists.scss | 13 +- .../framework/responsive_tables.scss | 2 +- app/assets/stylesheets/framework/sidebar.scss | 2 +- .../stylesheets/framework/typography.scss | 5 + .../stylesheets/framework/variables.scss | 72 +- app/assets/stylesheets/pages/boards.scss | 47 +- app/assets/stylesheets/pages/branches.scss | 21 +- app/assets/stylesheets/pages/builds.scss | 2 +- app/assets/stylesheets/pages/commits.scss | 69 +- app/assets/stylesheets/pages/diff.scss | 5 + .../stylesheets/pages/environments.scss | 46 +- app/assets/stylesheets/pages/events.scss | 9 +- app/assets/stylesheets/pages/issuable.scss | 44 +- app/assets/stylesheets/pages/labels.scss | 8 +- app/assets/stylesheets/pages/lint.scss | 21 - .../stylesheets/pages/merge_requests.scss | 52 + app/assets/stylesheets/pages/notes.scss | 8 +- app/assets/stylesheets/pages/pages.scss | 60 + app/assets/stylesheets/pages/pipelines.scss | 18 +- app/assets/stylesheets/pages/profile.scss | 7 +- app/assets/stylesheets/pages/projects.scss | 80 +- app/assets/stylesheets/pages/repo.scss | 468 +- app/assets/stylesheets/pages/repo.scss.orig | 786 + app/assets/stylesheets/pages/search.scss | 2 +- app/assets/stylesheets/pages/settings.scss | 20 + app/assets/stylesheets/performance_bar.scss | 43 +- .../admin/appearances_controller.rb | 18 +- .../admin/application_controller.rb | 14 - .../admin/application_settings_controller.rb | 23 +- app/controllers/admin/groups_controller.rb | 2 +- app/controllers/admin/users_controller.rb | 2 +- app/controllers/application_controller.rb | 4 - app/controllers/boards/issues_controller.rb | 3 +- app/controllers/ci/lints_controller.rb | 15 - .../concerns/authenticates_with_two_factor.rb | 2 +- .../concerns/checks_collaboration.rb | 21 + app/controllers/concerns/group_tree.rb | 2 +- app/controllers/concerns/issuable_actions.rb | 6 +- app/controllers/concerns/notes_actions.rb | 6 +- app/controllers/concerns/renders_notes.rb | 2 +- app/controllers/concerns/send_file_upload.rb | 17 + app/controllers/concerns/uploads_actions.rb | 32 +- app/controllers/dashboard_controller.rb | 19 + .../groups/group_members_controller.rb | 2 +- .../groups/milestones_controller.rb | 2 +- .../groups/settings/badges_controller.rb | 13 + .../groups/variables_controller.rb | 2 +- app/controllers/groups_controller.rb | 4 +- app/controllers/ide_controller.rb | 6 + app/controllers/jwt_controller.rb | 3 +- .../omniauth_callbacks_controller.rb | 12 + app/controllers/profiles_controller.rb | 24 +- .../projects/application_controller.rb | 14 +- .../projects/artifacts_controller.rb | 12 +- .../projects/branches_controller.rb | 10 +- .../projects/ci/lints_controller.rb | 27 + .../projects/deploy_tokens_controller.rb | 10 + .../projects/discussions_controller.rb | 12 +- .../projects/git_http_client_controller.rb | 1 + .../projects/git_http_controller.rb | 2 +- app/controllers/projects/issues_controller.rb | 2 +- app/controllers/projects/jobs_controller.rb | 40 +- app/controllers/projects/labels_controller.rb | 3 +- .../projects/lfs_api_controller.rb | 2 +- .../projects/lfs_storage_controller.rb | 66 +- .../merge_requests/creations_controller.rb | 2 +- .../projects/milestones_controller.rb | 6 +- app/controllers/projects/notes_controller.rb | 2 +- app/controllers/projects/pages_controller.rb | 22 + .../projects/pipeline_schedules_controller.rb | 2 +- .../projects/pipelines_settings_controller.rb | 28 - .../projects/project_members_controller.rb | 2 +- .../projects/protected_branches_controller.rb | 8 +- .../projects/protected_refs_controller.rb | 14 +- .../projects/protected_tags_controller.rb | 8 +- app/controllers/projects/raw_controller.rb | 3 +- app/controllers/projects/refs_controller.rb | 2 +- .../projects/repositories_controller.rb | 23 +- .../projects/services_controller.rb | 2 + .../projects/settings/badges_controller.rb | 13 + .../projects/settings/ci_cd_controller.rb | 72 +- .../settings/repository_controller.rb | 34 +- .../projects/variables_controller.rb | 2 +- app/controllers/projects_controller.rb | 2 +- app/controllers/root_controller.rb | 4 + app/finders/admin/projects_finder.rb | 2 +- app/finders/issuable_finder.rb | 13 +- app/finders/labels_finder.rb | 35 +- .../merge_request_target_project_finder.rb | 1 + app/finders/projects_finder.rb | 2 +- app/finders/todos_finder.rb | 2 +- app/helpers/appearances_helper.rb | 16 +- app/helpers/application_helper.rb | 93 +- app/helpers/application_settings_helper.rb | 6 +- app/helpers/avatars_helper.rb | 74 + app/helpers/blob_helper.rb | 19 +- app/helpers/boards_helper.rb | 6 +- app/helpers/commits_helper.rb | 29 +- app/helpers/compare_helper.rb | 2 +- app/helpers/deploy_tokens_helper.rb | 12 + app/helpers/emails_helper.rb | 4 +- app/helpers/groups_helper.rb | 2 +- app/helpers/import_helper.rb | 13 +- app/helpers/issuables_helper.rb | 31 +- app/helpers/issues_helper.rb | 15 +- app/helpers/javascript_helper.rb | 5 - app/helpers/labels_helper.rb | 43 +- app/helpers/markup_helper.rb | 2 +- app/helpers/merge_requests_helper.rb | 12 + app/helpers/namespaces_helper.rb | 2 +- app/helpers/notes_helper.rb | 22 +- app/helpers/page_layout_helper.rb | 5 +- app/helpers/preferences_helper.rb | 14 +- app/helpers/projects_helper.rb | 18 + app/helpers/tree_helper.rb | 2 +- app/helpers/workhorse_helper.rb | 4 +- app/mailers/emails/merge_requests.rb | 9 + app/mailers/notify.rb | 1 + app/models/ability.rb | 4 - app/models/appearance.rb | 4 +- app/models/ci/artifact_blob.rb | 7 +- app/models/ci/build.rb | 245 +- app/models/ci/build_metadata.rb | 35 + app/models/ci/group_variable.rb | 2 + app/models/ci/job_artifact.rb | 22 +- app/models/ci/pipeline.rb | 37 +- app/models/ci/pipeline_schedule_variable.rb | 2 + app/models/ci/runner.rb | 18 +- app/models/ci/variable.rb | 2 + app/models/clusters/cluster.rb | 4 + .../clusters/concerns/application_status.rb | 2 + app/models/clusters/platforms/kubernetes.rb | 24 +- app/models/commit.rb | 12 +- app/models/commit_status.rb | 2 +- app/models/concerns/atomic_internal_id.rb | 46 + app/models/concerns/avatarable.rb | 8 +- app/models/concerns/awardable.rb | 14 +- .../concerns/chronic_duration_attribute.rb | 39 + app/models/concerns/issuable.rb | 2 +- app/models/concerns/milestoneish.rb | 4 +- ...nternal_id.rb => nonatomic_internal_id.rb} | 2 +- app/models/concerns/presentable.rb | 8 + app/models/concerns/protected_ref.rb | 2 +- app/models/cycle_analytics/summary.rb | 0 app/models/deploy_key.rb | 4 + app/models/deploy_token.rb | 61 + app/models/deployment.rb | 2 +- app/models/environment.rb | 9 +- app/models/event.rb | 10 +- app/models/group.rb | 12 +- app/models/internal_id.rb | 141 + app/models/issue.rb | 24 +- app/models/lfs_object.rb | 17 + app/models/member.rb | 2 +- app/models/merge_request.rb | 36 +- app/models/merge_request_diff_commit.rb | 2 +- app/models/milestone.rb | 8 +- app/models/namespace.rb | 4 + app/models/note.rb | 11 +- app/models/notification_recipient.rb | 18 +- app/models/notification_setting.rb | 7 +- app/models/pages_domain.rb | 10 +- app/models/project.rb | 155 +- app/models/project_auto_devops.rb | 11 +- app/models/project_deploy_token.rb | 8 + .../project_services/gemnasium_service.rb | 2 +- app/models/project_services/jira_service.rb | 19 +- .../project_services/kubernetes_service.rb | 24 +- .../pipelines_email_service.rb | 4 - app/models/project_wiki.rb | 2 +- app/models/protected_branch.rb | 9 + app/models/redirect_route.rb | 28 - app/models/repository.rb | 9 +- app/models/route.rb | 26 +- app/models/service.rb | 29 +- app/models/todo.rb | 2 +- app/models/upload.rb | 19 +- app/models/user.rb | 48 +- app/policies/ci/build_policy.rb | 4 +- app/policies/ci/pipeline_schedule_policy.rb | 14 +- app/policies/deploy_token_policy.rb | 11 + app/policies/group_policy.rb | 8 +- app/policies/issuable_policy.rb | 16 - app/policies/issue_policy.rb | 2 - app/policies/merge_request_policy.rb | 1 - app/policies/note_policy.rb | 11 +- app/policies/personal_snippet_policy.rb | 2 + app/policies/project_policy.rb | 133 +- app/policies/project_policy/class_methods.rb | 19 + app/policies/protected_branch_policy.rb | 9 + app/presenters/ci/build_metadata_presenter.rb | 18 + app/presenters/ci/build_presenter.rb | 16 + app/presenters/merge_request_presenter.rb | 11 +- app/presenters/project_presenter.rb | 17 +- app/serializers/build_details_entity.rb | 2 + app/serializers/build_metadata_entity.rb | 6 + app/serializers/discussion_entity.rb | 6 +- app/serializers/issue_entity.rb | 4 + app/serializers/note_entity.rb | 36 +- app/serializers/note_serializer.rb | 3 - app/serializers/project_note_entity.rb | 25 + app/serializers/project_note_serializer.rb | 3 + app/serializers/status_entity.rb | 12 +- ...ntainer_registry_authentication_service.rb | 22 +- app/services/boards/issues/list_service.rb | 5 + app/services/boards/list_service.rb | 6 +- app/services/boards/lists/create_service.rb | 8 +- app/services/ci/create_pipeline_service.rb | 3 +- .../ci/create_pipeline_stages_service.rb | 20 - .../ci/fetch_kubernetes_token_service.rb | 2 +- app/services/ci/pipeline_trigger_service.rb | 12 +- .../check_installation_progress_service.rb | 2 +- .../clusters/applications/install_service.rb | 2 +- app/services/deploy_tokens/create_service.rb | 7 + app/services/events/render_service.rb | 12 +- app/services/files/create_service.rb | 8 +- app/services/files/multi_service.rb | 26 +- app/services/issuable/destroy_service.rb | 1 + app/services/issuable_base_service.rb | 5 +- app/services/issues/close_service.rb | 1 + app/services/issues/update_service.rb | 2 +- app/services/lfs/file_modification_handler.rb | 42 - app/services/lfs/file_transformer.rb | 66 + app/services/merge_requests/create_service.rb | 4 +- .../merge_request_diff_cache_service.rb | 11 +- .../merge_requests/refresh_service.rb | 8 +- app/services/notes/post_process_service.rb | 4 +- app/services/notes/render_service.rb | 13 +- app/services/notification_service.rb | 10 + app/services/projects/autocomplete_service.rb | 3 +- .../projects/base_move_relations_service.rb | 22 + .../projects/create_from_template_service.rb | 3 +- app/services/projects/create_service.rb | 25 +- app/services/projects/destroy_service.rb | 28 +- .../gitlab_projects_import_service.rb | 26 +- .../projects/import_export/export_service.rb | 39 +- app/services/projects/import_service.rb | 8 +- app/services/projects/move_access_service.rb | 25 + .../move_deploy_keys_projects_service.rb | 31 + app/services/projects/move_forks_service.rb | 42 + .../move_lfs_objects_projects_service.rb | 29 + .../move_notification_settings_service.rb | 38 + .../move_project_authorizations_service.rb | 40 + .../move_project_group_links_service.rb | 40 + .../projects/move_project_members_service.rb | 40 + .../move_users_star_projects_service.rb | 20 + .../projects/overwrite_project_service.rb | 69 + app/services/projects/transfer_service.rb | 2 + .../update_pages_configuration_service.rb | 6 +- app/services/projects/update_pages_service.rb | 18 +- app/services/projects/update_service.rb | 10 + .../protected_branches/create_service.rb | 17 +- .../protected_branches/destroy_service.rb | 9 + .../protected_branches/update_service.rb | 2 +- .../protected_tags/destroy_service.rb | 7 + .../quick_actions/interpret_service.rb | 5 +- .../repository_archive_clean_up_service.rb | 5 +- app/services/system_note_service.rb | 4 +- app/uploaders/attachment_uploader.rb | 6 +- app/uploaders/avatar_uploader.rb | 8 +- app/uploaders/file_mover.rb | 9 +- app/uploaders/file_uploader.rb | 56 +- app/uploaders/gitlab_uploader.rb | 14 +- app/uploaders/job_artifact_uploader.rb | 13 +- app/uploaders/legacy_artifact_uploader.rb | 5 + app/uploaders/lfs_object_uploader.rb | 6 +- app/uploaders/namespace_file_uploader.rb | 11 +- app/uploaders/object_storage.rb | 434 + app/uploaders/personal_file_uploader.rb | 17 +- app/uploaders/records_uploads.rb | 3 +- .../certificate_fingerprint_validator.rb | 9 + app/validators/certificate_validator.rb | 2 - app/validators/importable_url_validator.rb | 6 +- app/validators/top_level_group_validator.rb | 7 + .../application_settings/_abuse.html.haml | 12 + .../_account_and_limit.html.haml | 39 + .../_background_jobs.html.haml | 30 + .../application_settings/_ci_cd.html.haml | 47 + .../application_settings/_email.html.haml | 26 + .../application_settings/_form.html.haml | 873 - .../application_settings/_gitaly.html.haml | 27 + .../application_settings/_help_page.html.haml | 22 + .../application_settings/_influx.html.haml | 68 + .../application_settings/_ip_limits.html.haml | 54 + .../application_settings/_koding.html.haml | 24 + .../application_settings/_logging.html.haml | 36 + .../application_settings/_outbound.html.haml | 12 + .../application_settings/_pages.html.haml | 22 + .../_performance.html.haml | 19 + .../_performance_bar.html.haml | 16 + .../application_settings/_plantuml.html.haml | 20 + .../_prometheus.html.haml | 28 + .../application_settings/_realtime.html.haml | 19 + .../application_settings/_registry.html.haml | 10 + .../_repository_check.html.haml | 62 + .../_repository_storage.html.haml | 58 + .../application_settings/_signin.html.haml | 60 + .../application_settings/_signup.html.haml | 58 + .../application_settings/_spam.html.haml | 65 + .../application_settings/_terminal.html.haml | 13 + .../application_settings/_usage.html.haml | 37 + .../_visibility_and_access.html.haml | 67 + .../admin/application_settings/show.html.haml | 305 +- app/views/admin/projects/show.html.haml | 12 +- app/views/admin/runners/show.html.haml | 4 + app/views/award_emoji/_awards_block.html.haml | 4 +- app/views/ci/lints/show.html.haml | 36 +- app/views/ci/status/_badge.html.haml | 4 +- .../ci/status/_dropdown_graph_badge.html.haml | 7 +- .../ci/variables/_variable_row.html.haml | 4 +- app/views/dashboard/issues.html.haml | 12 +- app/views/dashboard/merge_requests.html.haml | 12 +- .../discussions/_diff_with_notes.html.haml | 34 +- app/views/discussions/_discussion.html.haml | 2 +- .../rejection.text.haml | 3 +- .../groups/settings/badges/index.html.haml | 4 + app/views/groups/show.html.haml | 2 +- app/views/ide/index.html.haml | 12 + app/views/import/github/new.html.haml | 3 - .../import/gitlab_projects/new.html.haml | 6 +- app/views/layouts/_mailer.html.haml | 10 +- app/views/layouts/_page.html.haml | 1 + app/views/layouts/devise.html.haml | 4 +- app/views/layouts/devise_empty.html.haml | 2 +- app/views/layouts/header/_new_dropdown.haml | 4 +- .../header/_read_only_banner.html.haml | 7 + .../layouts/nav/sidebar/_group.html.haml | 8 +- .../layouts/nav/sidebar/_project.html.haml | 25 +- .../push_to_merge_request_email.html.haml | 26 + .../push_to_merge_request_email.text.haml | 13 + app/views/peek/_bar.html.haml | 12 + app/views/peek/views/_gc.html.haml | 7 + app/views/peek/views/_gitaly.html.haml | 7 - app/views/peek/views/_host.html.haml | 2 - app/views/peek/views/_mysql2.html.haml | 4 - app/views/peek/views/_pg.html.haml | 4 - app/views/peek/views/_rblineprof.html.haml | 7 - app/views/peek/views/_redis.html.haml | 7 + app/views/peek/views/_sidekiq.html.haml | 7 + app/views/peek/views/_sql.html.haml | 13 - app/views/profiles/accounts/show.html.haml | 16 +- .../personal_access_tokens/index.html.haml | 7 +- app/views/projects/_export.html.haml | 4 +- app/views/projects/_home_panel.html.haml | 11 +- app/views/projects/_last_push.html.haml | 7 +- .../projects/_new_project_fields.html.haml | 4 +- app/views/projects/blob/_header.html.haml | 1 + app/views/projects/branches/_branch.html.haml | 143 +- .../projects/buttons/_download.html.haml | 9 +- .../projects/buttons/_dropdown.html.haml | 22 +- .../{ => projects}/ci/lints/_create.html.haml | 0 app/views/projects/ci/lints/show.html.haml | 27 + .../projects/clusters/_empty_state.html.haml | 5 +- app/views/projects/clusters/show.html.haml | 4 +- .../projects/clusters/user/_header.html.haml | 2 +- .../projects/commit/_commit_box.html.haml | 15 +- app/views/projects/commit/show.html.haml | 2 +- .../projects/commits/_commit.atom.builder | 2 +- app/views/projects/commits/_commit.html.haml | 15 +- .../projects/deploy_keys/_index.html.haml | 2 +- .../projects/deploy_tokens/_form.html.haml | 29 + .../projects/deploy_tokens/_index.html.haml | 18 + .../deploy_tokens/_new_deploy_token.html.haml | 14 + .../deploy_tokens/_revoke_modal.html.haml | 17 + .../projects/deploy_tokens/_table.html.haml | 31 + app/views/projects/diffs/_stats.html.haml | 4 +- app/views/projects/edit.html.haml | 19 +- app/views/projects/empty.html.haml | 16 +- .../projects/environments/metrics.html.haml | 1 + .../projects/issues/_discussion.html.haml | 1 + app/views/projects/issues/_issue.html.haml | 8 +- app/views/projects/issues/_nav_btns.html.haml | 13 +- .../projects/issues/_new_branch.html.haml | 8 +- app/views/projects/issues/show.html.haml | 13 +- .../projects/jobs/_empty_state.html.haml | 5 +- .../projects/jobs/_empty_states.html.haml | 9 + app/views/projects/jobs/_sidebar.html.haml | 10 +- app/views/projects/jobs/show.html.haml | 27 +- .../merge_requests/_merge_request.html.haml | 8 +- .../creations/_new_compare.html.haml | 2 +- .../projects/merge_requests/index.html.haml | 2 +- .../projects/merge_requests/show.html.haml | 1 + app/views/projects/new.html.haml | 8 - app/views/projects/no_repo.html.haml | 6 +- app/views/projects/notes/_actions.html.haml | 2 +- .../projects/pages/_https_only.html.haml | 10 + app/views/projects/pages/_list.html.haml | 37 +- app/views/projects/pages/show.html.haml | 6 +- .../projects/pages_domains/edit.html.haml | 2 +- .../projects/pages_domains/new.html.haml | 4 +- .../projects/pages_domains/show.html.haml | 56 +- app/views/projects/pipelines/index.html.haml | 2 +- .../shared/_branches_list.html.haml | 4 +- .../shared/_index.html.haml | 2 +- .../protected_tags/shared/_index.html.haml | 2 +- .../shared/_tags_list.html.haml | 4 +- .../registry/repositories/index.html.haml | 4 + app/views/projects/runners/_form.html.haml | 6 + app/views/projects/runners/show.html.haml | 3 + app/views/projects/services/_form.html.haml | 5 - .../projects/settings/badges/index.html.haml | 4 + .../ci_cd}/_badge.html.haml | 0 .../ci_cd/_form.html.haml} | 14 +- .../projects/settings/ci_cd/show.html.haml | 13 +- .../settings/repository/show.html.haml | 1 + app/views/projects/show.html.haml | 4 +- app/views/projects/tags/_tag.html.haml | 6 +- app/views/projects/tags/show.html.haml | 2 +- .../projects/tree/_tree_header.html.haml | 31 +- app/views/shared/_import_form.html.haml | 3 - .../shared/_issuable_meta_data.html.haml | 8 +- app/views/shared/_label.html.haml | 26 +- app/views/shared/_service_settings.html.haml | 2 +- .../shared/badges/_badge_settings.html.haml | 4 + app/views/shared/boards/_show.html.haml | 2 +- .../shared/boards/components/_board.html.haml | 2 +- .../boards/components/_sidebar.html.haml | 2 +- .../components/sidebar/_assignee.html.haml | 3 +- .../components/sidebar/_due_date.html.haml | 3 +- .../components/sidebar/_labels.html.haml | 3 +- .../components/sidebar/_milestone.html.haml | 3 +- .../dashboard/_no_filter_selected.html.haml | 8 + app/views/shared/issuable/_filter.html.haml | 9 +- .../issuable/_label_page_create.html.haml | 3 +- .../issuable/_label_page_default.html.haml | 7 +- app/views/shared/issuable/_nav.html.haml | 11 +- app/views/shared/issuable/_sidebar.html.haml | 4 +- .../shared/milestones/_milestone.html.haml | 20 +- .../shared/milestones/_sidebar.html.haml | 2 +- app/views/shared/milestones/_top.html.haml | 5 +- app/views/shared/notes/_note.html.haml | 2 +- app/workers/all_queues.yml | 4 + app/workers/concerns/object_storage_queue.rb | 8 + app/workers/git_garbage_collect_worker.rb | 9 +- app/workers/new_note_worker.rb | 2 +- .../object_storage/background_move_worker.rb | 29 + .../object_storage/migrate_uploads_worker.rb | 214 + app/workers/object_storage_upload_worker.rb | 21 + app/workers/project_export_worker.rb | 13 +- app/workers/repository_fork_worker.rb | 43 +- bin/rails | 15 +- bin/rake | 13 +- bin/rspec | 6 + bin/setup | 50 +- bin/update | 29 + .../39118-dynamic-pipeline-variables-fe.yml | 6 - ...-cluster-js-not-running-on-update-page.yml | 5 - .../bvl-external-policy-classification.yml | 5 - config.ru | 4 +- config/application.rb | 14 +- config/boot.rb | 11 +- config/environment.rb | 8 +- config/environments/production.rb | 6 +- config/environments/test.rb | 8 +- config/gitlab.yml.example | 95 +- config/initializers/1_settings.rb | 39 +- config/initializers/6_validations.rb | 6 +- .../{fast_gettext.rb => 9_fast_gettext.rb} | 0 .../active_record_array_type_casting.rb | 31 +- config/initializers/active_record_locking.rb | 108 +- .../application_controller_renderer.rb | 12 + config/initializers/ar5_batching.rb | 66 +- config/initializers/ar5_pg_10_support.rb | 5 +- .../initializers/ar_native_database_types.rb | 11 + .../artifacts_direct_upload_support.rb | 7 + config/initializers/backtrace_silencers.rb | 9 +- config/initializers/carrierwave.rb | 12 - config/initializers/devise.rb | 46 +- config/initializers/doorkeeper.rb | 2 +- .../fog_google_https_private_urls.rb | 20 + config/initializers/new_framework_defaults.rb | 29 + config/initializers/omniauth.rb | 1 + config/initializers/peek.rb | 4 +- config/initializers/sidekiq.rb | 9 +- config/karma.config.js | 10 +- config/prometheus/additional_metrics.yml | 34 +- config/routes.rb | 5 +- config/routes/ci.rb | 2 +- config/routes/git_http.rb | 2 +- config/routes/group.rb | 5 +- config/routes/project.rb | 27 +- config/routes/repository.rb | 7 +- config/routes/user.rb | 4 +- config/sidekiq_queues.yml | 2 + config/spring.rb | 6 + config/svg.config.js | 48 - config/webpack.config.js | 100 +- db/fixtures/development/10_merge_requests.rb | 8 +- .../development/22_labeled_issues_seed.rb | 103 + ...1322_migrate_process_commit_worker_jobs.rb | 2 +- ...0141214_remove_dot_git_from_group_names.rb | 2 +- ...226122833_remove_dot_git_from_usernames.rb | 4 +- ...ect_foreign_keys_with_cascading_deletes.rb | 8 +- ...1163708_add_artifacts_store_to_ci_build.rb | 10 + ...2400_add_stage_id_foreign_key_to_builds.rb | 12 +- ...04829_add_foreign_key_to_merge_requests.rb | 12 +- ...825015534_add_file_store_to_lfs_objects.rb | 31 + ...0918072949_add_file_store_job_artifacts.rb | 10 + ...71214144320_add_store_column_to_uploads.rb | 12 + ...220145_add_pages_https_only_to_projects.rb | 9 + ...ange_default_value_for_pages_https_only.rb | 13 + .../20180209165249_add_closed_by_to_issues.rb | 20 + ...53455_add_maximum_timeout_to_ci_runners.rb | 9 + ...1010859_create_ci_builds_metadata_table.rb | 20 + ...0180305095250_create_internal_ids_table.rb | 15 + ...le_commits_count_for_merge_request_diff.rb | 30 + .../20180319190020_create_deploy_tokens.rb | 19 + ..._merge_request_to_notification_settings.rb | 9 + ...27101207_remove_index_from_events_table.rb | 18 + ...0405142733_create_project_deploy_tokens.rb | 16 + ...dd_index_to_ci_job_artifacts_file_store.rb | 15 + ...12101928_schedule_build_stage_migration.rb | 25 +- ...27_build_user_interacted_projects_table.rb | 10 +- ...0_remove_permanent_from_redirect_routes.rb | 37 + ...64012_add_path_index_to_redirect_routes.rb | 38 + ...1928_reschedule_builds_stages_migration.rb | 33 + db/schema.rb | 59 +- doc/README.md | 179 +- doc/administration/auth/jwt.md | 72 + .../img/circuitbreaker_config.png | Bin 335073 -> 99523 bytes .../img/repository_storages_admin_ui.png | Bin 17760 -> 70416 bytes doc/administration/incoming_email.md | 1 + doc/administration/index.md | 9 +- doc/administration/issue_closing_pattern.md | 4 +- doc/administration/job_artifacts.md | 123 +- doc/administration/job_traces.md | 42 + doc/administration/logs.md | 30 + .../performance/img/performance_bar.png | Bin 170256 -> 344274 bytes .../img/performance_bar_gitaly_calls.png | Bin 0 -> 278693 bytes .../monitoring/performance/performance_bar.md | 12 +- .../monitoring/prometheus/index.md | 9 +- doc/administration/pages/index.md | 36 +- doc/administration/plugins.md | 77 +- doc/administration/raketasks/check.md | 8 +- doc/administration/raketasks/maintenance.md | 28 + .../raketasks/uploads/migrate.md | 74 + doc/administration/uploads.md | 210 + doc/api/commits.md | 76 +- doc/api/events.md | 4 + doc/api/features.md | 8 + doc/api/group_badges.md | 5 +- doc/api/issues.md | 48 + doc/api/jobs.md | 14 +- doc/api/notification_settings.md | 4 + doc/api/project_badges.md | 5 +- doc/api/project_import_export.md | 24 +- doc/api/projects.md | 55 + doc/api/repositories.md | 2 +- doc/api/runners.md | 7 +- doc/api/search.md | 26 +- doc/ci/caching/img/clear_runners_cache.png | Bin 0 -> 16029 bytes doc/ci/caching/index.md | 18 +- doc/ci/docker/using_docker_build.md | 91 +- doc/ci/docker/using_docker_images.md | 63 +- doc/ci/environments.md | 15 +- doc/ci/examples/README.md | 27 +- doc/ci/examples/browser_performance.md | 93 +- doc/ci/examples/code_climate.md | 13 +- doc/ci/examples/container_scanning.md | 59 + doc/ci/examples/dast.md | 25 +- doc/ci/examples/deployment/README.md | 2 +- .../img/aws_config_window.png | Bin 0 -> 22046 bytes .../img/gitlab_config.png | Bin 0 -> 27620 bytes .../img/test_pipeline_pass.png | Bin 0 -> 18789 bytes .../index.md | 526 + .../laravel_with_gitlab_and_envoy/index.md | 2 +- doc/ci/examples/sast_docker.md | 56 +- doc/ci/img/job_failure_reason.png | Bin 0 -> 5346 bytes doc/ci/pipelines.md | 24 +- doc/ci/quick_start/README.md | 9 +- doc/ci/runners/README.md | 64 +- doc/ci/variables/README.md | 105 +- doc/ci/yaml/README.md | 901 +- doc/development/changelog.md | 1 + doc/development/doc_styleguide.md | 370 +- doc/development/ee_features.md | 304 +- doc/development/emails.md | 10 +- doc/development/fe_guide/index.md | 4 +- doc/development/fe_guide/performance.md | 120 +- doc/development/fe_guide/style_guide_js.md | 51 + doc/development/fe_guide/vue.md | 12 +- doc/development/i18n/externalization.md | 2 +- doc/development/i18n/proofreader.md | 4 + doc/development/migration_style_guide.md | 21 +- .../new_fe_guide/development/performance.md | 15 +- .../new_fe_guide/development/security.md | 13 +- doc/development/new_fe_guide/index.md | 2 +- doc/development/new_fe_guide/principles.md | 34 +- doc/development/new_fe_guide/style/html.md | 52 +- doc/development/new_fe_guide/style/index.md | 8 +- .../new_fe_guide/style/javascript.md | 194 +- .../new_fe_guide/style/prettier.md | 45 + .../testing_guide/end_to_end_tests.md | 2 +- doc/development/writing_documentation.md | 275 +- doc/downgrade_ee_to_ce/README.md | 2 +- doc/img/devops_lifecycle.png | Bin 0 -> 65043 bytes doc/install/README.md | 2 +- doc/install/installation.md | 15 +- doc/install/kubernetes/index.md | 2 +- doc/install/openshift_and_gitlab/index.md | 11 +- doc/integration/google.md | 2 +- doc/integration/omniauth.md | 1 + doc/integration/saml.md | 6 +- doc/integration/slash_commands.md | 3 +- doc/policy/maintenance.md | 2 +- doc/raketasks/README.md | 1 + doc/topics/autodevops/index.md | 61 +- doc/update/10.5-to-10.6.md | 16 +- doc/update/10.6-to-10.7.md | 361 + doc/user/admin_area/settings/email.md | 5 + .../visibility_and_access_controls.md | 12 +- doc/user/discussions/index.md | 5 + doc/user/gitlab_com/index.md | 342 + doc/user/group/index.md | 11 +- doc/user/permissions.md | 3 +- doc/user/profile/preferences.md | 4 +- doc/user/project/badges.md | 73 + doc/user/project/clusters/index.md | 4 +- doc/user/project/container_registry.md | 11 +- .../deploy_tokens/img/deploy_tokens.png | Bin 0 -> 75650 bytes doc/user/project/deploy_tokens/index.md | 76 + .../project/img/project_overview_badges.png | Bin 0 -> 40188 bytes doc/user/project/index.md | 22 +- .../img/jira_workflow_screenshot.png | Bin 66685 -> 0 bytes doc/user/project/integrations/jira.md | 15 +- .../prometheus_library/kubernetes.md | 15 +- doc/user/project/issue_board.md | 5 +- .../project/issues/issues_functionalities.md | 10 +- doc/user/project/labels.md | 7 +- .../members/share_project_with_groups.md | 24 +- .../img/remove_source_branch_status.png | Bin 0 -> 32649 bytes doc/user/project/merge_requests/index.md | 28 +- doc/user/project/pipelines/schedules.md | 2 +- doc/user/project/pipelines/settings.md | 11 +- .../repository/img/jupyter_notebook.png | Bin 0 -> 63326 bytes doc/user/project/repository/index.md | 23 +- doc/user/project/settings/import_export.md | 2 +- doc/user/project/settings/index.md | 17 +- .../project/web_ide/img/commit_changes.png | Bin 0 -> 672321 bytes .../project/web_ide/img/enable_web_ide.png | Bin 0 -> 11364 bytes doc/user/project/web_ide/img/open_web_ide.png | Bin 0 -> 28574 bytes doc/user/project/web_ide/index.md | 33 + doc/workflow/lfs/lfs_administration.md | 123 +- doc/workflow/notifications.md | 3 +- doc/workflow/todos.md | 3 +- features/groups.feature | 73 - features/project/active_tab.feature | 138 - features/project/fork.feature | 49 - features/project/graph.feature | 33 - features/project/issues/issues.feature | 180 - features/project/issues/labels.feature | 48 - features/project/issues/milestones.feature | 1 + features/project/redirects.feature | 38 - features/steps/groups.rb | 147 - features/steps/project/active_tab.rb | 127 - features/steps/project/fork.rb | 85 - features/steps/project/graph.rb | 50 - features/steps/project/issues/issues.rb | 181 - features/steps/project/issues/labels.rb | 101 - features/steps/project/project.rb | 2 +- features/steps/project/redirects.rb | 67 - features/steps/shared/builds.rb | 2 +- features/steps/shared/issuable.rb | 23 - features/steps/shared/markdown.rb | 37 - features/steps/shared/note.rb | 22 - features/steps/shared/paths.rb | 31 - features/steps/shared/project.rb | 4 - features/steps/shared/user.rb | 4 - lib/api/api.rb | 9 + lib/api/badges.rb | 1 + lib/api/commits.rb | 14 + lib/api/deploy_keys.rb | 23 +- lib/api/entities.rb | 5 +- lib/api/features.rb | 7 + lib/api/helpers.rb | 59 +- lib/api/helpers/internal_helpers.rb | 14 +- lib/api/helpers/project_snapshots_helpers.rb | 25 + lib/api/helpers/projects_helpers.rb | 38 + lib/api/internal.rb | 3 +- lib/api/issues.rb | 2 +- lib/api/job_artifacts.rb | 4 +- lib/api/jobs.rb | 2 +- lib/api/merge_requests.rb | 2 +- lib/api/project_export.rb | 26 +- lib/api/project_import.rb | 16 +- lib/api/project_snapshots.rb | 19 + lib/api/projects.rb | 40 +- lib/api/protected_branches.rb | 11 +- lib/api/repositories.rb | 6 +- lib/api/runner.rb | 41 +- lib/api/runners.rb | 1 + lib/api/search.rb | 4 +- lib/api/services.rb | 2 +- lib/api/v3/builds.rb | 6 +- lib/api/v3/merge_requests.rb | 2 +- lib/api/v3/projects.rb | 6 +- lib/api/v3/repositories.rb | 2 +- lib/backup/artifacts.rb | 4 - lib/backup/builds.rb | 4 - lib/backup/files.rb | 18 +- lib/backup/helper.rb | 17 + lib/backup/lfs.rb | 4 - lib/backup/pages.rb | 4 - lib/backup/registry.rb | 4 - lib/backup/repository.rb | 30 +- lib/backup/uploads.rb | 4 - lib/banzai/commit_renderer.rb | 2 +- lib/banzai/cross_project_reference.rb | 4 +- .../filter/abstract_reference_filter.rb | 54 +- .../filter/commit_range_reference_filter.rb | 4 +- lib/banzai/filter/commit_reference_filter.rb | 2 + lib/banzai/filter/commit_trailers_filter.rb | 151 + lib/banzai/filter/emoji_filter.rb | 2 +- lib/banzai/filter/gollum_tags_filter.rb | 2 +- lib/banzai/filter/inline_diff_filter.rb | 2 +- lib/banzai/filter/issuable_state_filter.rb | 13 +- lib/banzai/filter/label_reference_filter.rb | 53 +- .../filter/merge_request_reference_filter.rb | 39 + .../filter/milestone_reference_filter.rb | 8 +- lib/banzai/filter/redactor_filter.rb | 6 +- lib/banzai/filter/relative_link_filter.rb | 2 +- lib/banzai/filter/snippet_reference_filter.rb | 2 + lib/banzai/issuable_extractor.rb | 14 +- lib/banzai/object_renderer.rb | 32 +- .../pipeline/commit_description_pipeline.rb | 11 + lib/banzai/pipeline/gfm_pipeline.rb | 4 +- lib/banzai/redactor.rb | 20 +- lib/banzai/reference_extractor.rb | 4 +- lib/banzai/reference_parser/base_parser.rb | 16 +- .../reference_parser/commit_range_parser.rb | 2 + lib/banzai/reference_parser/issue_parser.rb | 39 +- lib/banzai/reference_parser/user_parser.rb | 3 +- lib/banzai/render_context.rb | 32 + lib/constraints/group_url_constrainer.rb | 12 +- lib/constraints/project_url_constrainer.rb | 20 +- lib/constraints/user_url_constrainer.rb | 12 +- lib/container_registry/client.rb | 5 +- lib/declarative_policy.rb | 4 +- lib/declarative_policy/delegate_dsl.rb | 16 + lib/declarative_policy/dsl.rb | 103 - lib/declarative_policy/policy_dsl.rb | 44 + lib/declarative_policy/preferred_scope.rb | 2 +- lib/declarative_policy/rule_dsl.rb | 45 + lib/forever.rb | 13 + .../post_deployment_migration_generator.rb | 2 +- lib/gitlab.rb | 1 + lib/gitlab/auth.rb | 22 +- lib/gitlab/auth/ldap/access.rb | 2 + lib/gitlab/auth/ldap/adapter.rb | 43 +- lib/gitlab/auth/ldap/ldap_connection_error.rb | 7 + lib/gitlab/auth/o_auth/user.rb | 3 + lib/gitlab/auth/result.rb | 2 +- lib/gitlab/auth/saml/config.rb | 2 +- .../add_merge_request_diff_commits_count.rb | 2 +- ...rialize_merge_request_diffs_and_commits.rb | 2 +- lib/gitlab/bare_repository_import/importer.rb | 2 +- lib/gitlab/base_doorkeeper_controller.rb | 8 + lib/gitlab/bitbucket_import/importer.rb | 2 +- lib/gitlab/checks/lfs_integrity.rb | 3 +- lib/gitlab/checks/project_moved.rb | 20 +- lib/gitlab/ci/build/policy/kubernetes.rb | 2 +- lib/gitlab/ci/build/policy/refs.rb | 2 +- lib/gitlab/ci/build/policy/specification.rb | 2 +- lib/gitlab/ci/build/policy/variables.rb | 24 + lib/gitlab/ci/build/step.rb | 4 +- lib/gitlab/ci/config.rb | 3 +- lib/gitlab/ci/config/entry/policy.rb | 20 +- lib/gitlab/ci/pipeline/chain/command.rb | 2 +- lib/gitlab/ci/pipeline/chain/create.rb | 15 +- lib/gitlab/ci/pipeline/chain/populate.rb | 45 + .../ci/pipeline/chain/validate/config.rb | 6 +- .../ci/pipeline/expression/lexeme/string.rb | 2 +- .../ci/pipeline/expression/lexeme/variable.rb | 2 +- .../ci/pipeline/expression/statement.rb | 17 +- lib/gitlab/ci/pipeline/seed/base.rb | 21 + lib/gitlab/ci/pipeline/seed/build.rb | 48 + lib/gitlab/ci/pipeline/seed/stage.rb | 47 + lib/gitlab/ci/stage/seed.rb | 62 - lib/gitlab/ci/status/build/cancelable.rb | 4 + lib/gitlab/ci/status/build/canceled.rb | 21 + lib/gitlab/ci/status/build/common.rb | 8 + lib/gitlab/ci/status/build/created.rb | 22 + lib/gitlab/ci/status/build/erased.rb | 21 + lib/gitlab/ci/status/build/factory.rb | 12 +- lib/gitlab/ci/status/build/failed.rb | 40 + lib/gitlab/ci/status/build/failed_allowed.rb | 12 +- lib/gitlab/ci/status/build/manual.rb | 22 + lib/gitlab/ci/status/build/pending.rb | 22 + lib/gitlab/ci/status/build/play.rb | 4 + lib/gitlab/ci/status/build/retried.rb | 17 + lib/gitlab/ci/status/build/retryable.rb | 4 + lib/gitlab/ci/status/build/skipped.rb | 21 + lib/gitlab/ci/status/build/stop.rb | 4 + lib/gitlab/ci/status/core.rb | 18 + lib/gitlab/ci/trace/http_io.rb | 197 + lib/gitlab/ci/trace/stream.rb | 6 +- lib/gitlab/ci/variables/collection.rb | 44 + lib/gitlab/ci/variables/collection/item.rb | 47 + lib/gitlab/ci/yaml_processor.rb | 44 +- lib/gitlab/database/migration_helpers.rb | 105 +- .../v1/migration_classes.rb | 2 +- lib/gitlab/database/sha_attribute.rb | 51 +- lib/gitlab/diff/file.rb | 39 +- .../file_collection/merge_request_diff.rb | 14 +- lib/gitlab/ee_compat_check.rb | 146 +- .../handler/create_merge_request_handler.rb | 3 +- lib/gitlab/etag_caching/middleware.rb | 2 +- lib/gitlab/exclusive_lease.rb | 10 + lib/gitlab/git/commit.rb | 3 +- lib/gitlab/git/conflict/resolver.rb | 2 +- lib/gitlab/git/gitlab_projects.rb | 69 +- lib/gitlab/git/gitmodules_parser.rb | 4 +- lib/gitlab/git/hook.rb | 4 +- lib/gitlab/git/{env.rb => hook_env.rb} | 26 +- lib/gitlab/git/lfs_pointer_file.rb | 9 +- lib/gitlab/git/repository.rb | 253 +- lib/gitlab/git/storage/checker.rb | 2 +- lib/gitlab/git/storage/circuit_breaker.rb | 2 +- lib/gitlab/git/wiki.rb | 3 - lib/gitlab/git_access.rb | 47 +- lib/gitlab/gitaly_client.rb | 31 + lib/gitlab/gitaly_client/remote_service.rb | 11 + .../gitaly_client/repository_service.rb | 27 + lib/gitlab/gitaly_client/storage_settings.rb | 35 + lib/gitlab/gitaly_client/util.rb | 8 +- lib/gitlab/gitaly_client/wiki_service.rb | 2 +- lib/gitlab/github_import/client.rb | 5 +- .../importer/repository_importer.rb | 11 +- lib/gitlab/gitlab_import/client.rb | 2 +- lib/gitlab/health_checks/fs_shards_check.rb | 2 +- lib/gitlab/health_checks/metric.rb | 2 +- lib/gitlab/health_checks/result.rb | 2 +- lib/gitlab/http.rb | 2 + .../base_after_export_strategy.rb | 83 + .../download_notification_strategy.rb | 17 + .../web_upload_strategy.rb | 61 + .../after_export_strategy_builder.rb | 24 + lib/gitlab/import_export/import_export.yml | 5 +- lib/gitlab/import_export/importer.rb | 49 +- lib/gitlab/import_export/lfs_restorer.rb | 43 + lib/gitlab/import_export/lfs_saver.rb | 55 + .../import_export/project_tree_restorer.rb | 25 +- .../import_export/project_tree_saver.rb | 7 +- lib/gitlab/import_export/relation_factory.rb | 11 +- lib/gitlab/import_export/shared.rb | 14 +- .../import_export/statistics_restorer.rb | 17 + lib/gitlab/kubernetes/namespace.rb | 2 +- lib/gitlab/legacy_github_import/client.rb | 2 +- lib/gitlab/legacy_github_import/importer.rb | 2 +- lib/gitlab/metrics/methods.rb | 2 +- .../metrics/sidekiq_metrics_exporter.rb | 10 +- lib/gitlab/middleware/multipart.rb | 2 +- lib/gitlab/middleware/read_only.rb | 2 +- lib/gitlab/middleware/release_env.rb | 2 +- lib/gitlab/omniauth_initializer.rb | 75 + lib/gitlab/performance_bar.rb | 1 + lib/gitlab/profiler.rb | 12 +- lib/gitlab/project_search_results.rb | 2 +- .../queries/query_additional_metrics.rb | 2 +- lib/gitlab/proxy_http_connection_adapter.rb | 12 +- lib/gitlab/repo_path.rb | 4 +- lib/gitlab/setup_helper.rb | 2 +- lib/gitlab/shell.rb | 42 +- lib/gitlab/sidekiq_logging/json_formatter.rb | 21 + .../sidekiq_logging/structured_logger.rb | 96 + lib/gitlab/slash_commands/command.rb | 1 + lib/gitlab/slash_commands/issue_move.rb | 45 + .../slash_commands/presenters/issue_move.rb | 53 + lib/gitlab/slash_commands/result.rb | 2 +- lib/gitlab/task_helpers.rb | 4 +- lib/gitlab/url_blocker.rb | 92 +- lib/gitlab/usage_data.rb | 7 + lib/gitlab/user_access.rb | 10 +- lib/gitlab/utils.rb | 5 + lib/gitlab/verify/job_artifacts.rb | 27 + lib/gitlab/verify/lfs_objects.rb | 2 +- lib/gitlab/verify/uploads.rb | 2 +- lib/gitlab/workhorse.rb | 59 +- lib/google_api/auth.rb | 2 +- lib/haml_lint/inline_javascript.rb | 2 +- lib/mattermost/session.rb | 6 + lib/mattermost/team.rb | 5 +- lib/omni_auth/strategies/jwt.rb | 62 + lib/peek/views/gitaly.rb | 20 +- lib/peek/views/host.rb | 9 + lib/system_check/orphans/namespace_check.rb | 4 +- lib/system_check/orphans/repository_check.rb | 8 +- lib/tasks/gitlab/artifacts/check.rake | 8 + lib/tasks/gitlab/artifacts/migrate.rake | 25 + lib/tasks/gitlab/check.rake | 8 +- lib/tasks/gitlab/cleanup.rake | 4 +- lib/tasks/gitlab/exclusive_lease.rake | 9 + lib/tasks/gitlab/info.rake | 2 +- lib/tasks/gitlab/lfs/migrate.rake | 22 + lib/tasks/gitlab/shell.rake | 2 +- lib/tasks/gitlab/two_factor.rake | 2 +- lib/tasks/gitlab/uploads/migrate.rake | 34 + lib/tasks/migrate/setup_postgresql.rake | 4 +- lib/tasks/test.rake | 5 - lib/uploaded_file.rb | 40 +- locale/bg/gitlab.po | 1053 +- locale/de/gitlab.po | 1055 +- locale/eo/gitlab.po | 1053 +- locale/es/gitlab.po | 1059 +- locale/fil_PH/gitlab.po | 1047 +- locale/fr/gitlab.po | 1077 +- locale/gitlab.pot | 353 +- locale/id_ID/gitlab.po | 1042 +- locale/it/gitlab.po | 1059 +- locale/ja/gitlab.po | 1048 +- locale/ko/gitlab.po | 1048 +- locale/nl_NL/gitlab.po | 1049 +- locale/pl_PL/gitlab.po | 1057 +- locale/pt_BR/gitlab.po | 1625 +- locale/ru/gitlab.po | 1367 +- locale/tr_TR/gitlab.po | 1047 +- locale/uk/gitlab.po | 1217 +- locale/zh_CN/gitlab.po | 2154 ++- locale/zh_HK/gitlab.po | 1050 +- locale/zh_TW/gitlab.po | 1150 +- package.json | 10 +- public/robots.txt | 1 + qa/README.md | 2 +- qa/qa.rb | 9 +- qa/qa/factory/settings/hashed_storage.rb | 8 +- qa/qa/page/README.md | 2 +- qa/qa/page/admin/settings.rb | 26 - qa/qa/page/admin/settings/main.rb | 21 + .../page/admin/settings/repository_storage.rb | 23 + qa/qa/page/merge_request/show.rb | 17 +- qa/qa/page/project/settings/ci_cd.rb | 2 +- qa/qa/page/project/settings/common.rb | 20 +- qa/qa/page/settings/common.rb | 25 + qa/qa/scenario/bootable.rb | 2 +- qa/qa/scenario/test/instance.rb | 8 +- qa/qa/scenario/test/integration/mattermost.rb | 4 +- qa/qa/specs/runner.rb | 6 +- qa/spec/page/validator_spec.rb | 2 +- qa/spec/scenario/test/instance_spec.rb | 4 +- .../cop/rspec/factories_in_migration_specs.rb | 40 + rubocop/rubocop.rb | 2 + rubocop/spec_helpers.rb | 13 +- scripts/codequality | 19 - scripts/frontend/frontend_script_utils.js | 24 + scripts/frontend/prettier.js | 117 + scripts/lint-doc.sh | 34 +- scripts/trigger-build-docs | 19 +- scripts/trigger-build-omnibus | 3 +- .../application_settings_controller_spec.rb | 5 +- .../concerns/checks_collaboration_spec.rb | 55 + .../concerns/send_file_upload_spec.rb | 89 + spec/controllers/dashboard_controller_spec.rb | 2 + .../omniauth_callbacks_controller_spec.rb | 140 +- spec/controllers/profiles_controller_spec.rb | 29 + .../projects/artifacts_controller_spec.rb | 14 + .../projects/branches_controller_spec.rb | 18 +- .../projects/ci/lints_controller_spec.rb | 123 + .../projects/discussions_controller_spec.rb | 47 + .../projects/issues_controller_spec.rb | 20 +- .../projects/jobs_controller_spec.rb | 82 +- .../projects/milestones_controller_spec.rb | 13 +- .../projects/pages_controller_spec.rb | 37 + .../projects/pages_domains_controller_spec.rb | 4 +- .../pipeline_schedules_controller_spec.rb | 18 +- .../pipelines_settings_controller_spec.rb | 57 +- .../protected_branches_controller_spec.rb | 97 + .../projects/raw_controller_spec.rb | 56 +- .../projects/repositories_controller_spec.rb | 43 +- .../settings/ci_cd_controller_spec.rb | 127 +- spec/controllers/root_controller_spec.rb | 24 + spec/factories/appearances.rb | 17 +- spec/factories/award_emoji.rb | 4 + spec/factories/ci/builds.rb | 5 + spec/factories/ci/job_artifacts.rb | 10 + spec/factories/deploy_tokens.rb | 14 + spec/factories/internal_ids.rb | 7 + spec/factories/lfs_objects.rb | 4 + spec/factories/pages_domains.rb | 68 +- spec/factories/project_deploy_tokens.rb | 6 + spec/factories/projects.rb | 7 + spec/factories/redirect_routes.rb | 9 - spec/factories/uploads.rb | 5 + spec/factories/users_star_projects.rb | 6 + .../admin/admin_broadcast_messages_spec.rb | 2 +- ...admin_disables_git_access_protocol_spec.rb | 15 +- spec/features/admin/admin_settings_spec.rb | 264 +- spec/features/atom/dashboard_issues_spec.rb | 17 +- spec/features/boards/boards_spec.rb | 2 +- spec/features/boards/new_issue_spec.rb | 7 + spec/features/boards/sidebar_spec.rb | 4 +- .../features/boards/sub_group_project_spec.rb | 2 +- spec/features/dashboard/issues_filter_spec.rb | 36 +- spec/features/dashboard/issues_spec.rb | 9 - .../features/dashboard/merge_requests_spec.rb | 14 +- spec/features/groups/activity_spec.rb | 25 +- spec/features/groups/group_settings_spec.rb | 21 + spec/features/groups/issues_spec.rb | 20 +- spec/features/groups/merge_requests_spec.rb | 16 +- .../groups/settings/group_badges_spec.rb | 124 + spec/features/groups/show_spec.rb | 38 +- .../user_browse_projects_group_page_spec.rb | 29 + spec/features/ide_spec.rb | 25 + .../issuables/discussion_lock_spec.rb | 2 +- .../filtered_search/filter_issues_spec.rb | 9 - spec/features/issues/form_spec.rb | 4 +- spec/features/issues/issue_sidebar_spec.rb | 54 +- .../issues/user_uses_slash_commands_spec.rb | 26 +- spec/features/labels_hierarchy_spec.rb | 319 + spec/features/markdown/copy_as_gfm_spec.rb | 2 +- .../merge_request/user_awards_emoji_spec.rb | 8 + .../merge_request/user_cherry_picks_spec.rb | 8 + ...diff_notes_and_discussions_resolve_spec.rb | 12 +- .../user_scrolls_to_note_on_load_spec.rb | 33 +- .../user_sees_deployment_widget_spec.rb | 2 +- .../user_sees_merge_widget_spec.rb | 26 +- .../user_sees_mini_pipeline_graph_spec.rb | 9 +- .../user_uses_slash_commands_spec.rb | 22 +- spec/features/milestone_spec.rb | 11 + spec/features/profile_spec.rb | 8 +- spec/features/profiles/account_spec.rb | 16 +- spec/features/projects/actve_tabs_spec.rb | 137 + ...ser_interacts_with_awards_in_issue_spec.rb | 70 +- spec/features/projects/badges/list_spec.rb | 2 +- .../features/projects/blobs/blob_show_spec.rb | 25 + ...er_creates_new_blob_in_new_project_spec.rb | 52 + spec/features/projects/branches_spec.rb | 22 +- .../ci/lint_spec.rb} | 10 +- .../projects/commit/cherry_pick_spec.rb | 11 + .../commit/user_reverts_commit_spec.rb | 17 + spec/features/projects/fork_spec.rb | 104 + spec/features/projects/graph_spec.rb | 75 + .../projects/hook_logs/user_reads_log_spec.rb | 21 + .../import_export/import_file_spec.rb | 1 + .../import_export/test_project_export.tar.gz | Bin 343092 -> 341299 bytes .../issues/user_comments_on_issue_spec.rb | 73 + .../issues/user_creates_issue_spec.rb | 87 + .../projects/issues/user_edits_issue_spec.rb | 25 + .../projects/issues/user_sorts_issues_spec.rb | 39 + .../issues/user_toggles_subscription_spec.rb | 28 + .../projects/issues/user_views_issue_spec.rb | 32 + .../projects/issues/user_views_issues_spec.rb | 128 +- .../projects/jobs/user_browses_job_spec.rb | 35 +- .../projects/jobs/user_browses_jobs_spec.rb | 11 + spec/features/projects/jobs_spec.rb | 68 +- .../labels/user_creates_labels_spec.rb | 88 + .../projects/labels/user_edits_labels_spec.rb | 25 + .../labels/user_removes_labels_spec.rb | 52 + .../projects/labels/user_views_labels_spec.rb | 23 + .../projects/merge_request_button_spec.rb | 12 + .../user_reverts_merge_request_spec.rb | 8 + .../user_views_open_merge_requests_spec.rb | 12 + .../milestones/milestones_sorting_spec.rb | 1 - spec/features/projects/pages_spec.rb | 91 +- .../projects/pipeline_schedules_spec.rb | 4 +- .../projects/pipelines/pipeline_spec.rb | 16 + .../projects/pipelines/pipelines_spec.rb | 25 +- spec/features/projects/redirects_spec.rb | 74 + .../projects/settings/project_badges_spec.rb | 125 + .../settings/repository_settings_spec.rb | 27 + .../user_sees_collaboration_links_spec.rb | 87 + .../projects/tree/create_directory_spec.rb | 53 + .../projects/tree/create_file_spec.rb | 43 + spec/features/projects/tree/tree_show_spec.rb | 14 + .../projects/tree/upload_file_spec.rb | 51 + .../projects/user_edits_files_spec.rb | 23 + .../projects/user_views_empty_project_spec.rb | 43 + spec/features/protected_branches_spec.rb | 5 +- spec/features/protected_tags_spec.rb | 5 +- spec/features/read_only_spec.rb | 25 + .../user_uses_header_search_field_spec.rb | 127 +- .../user_can_display_performance_bar_spec.rb | 10 +- spec/features/user_sorts_things_spec.rb | 57 + spec/finders/labels_finder_spec.rb | 34 +- ...erge_request_target_project_finder_spec.rb | 6 + spec/fixtures/api/schemas/issue.json | 2 + .../public_api/v4/project/export_status.json | 11 +- spec/fixtures/big-image.png | Bin 0 -> 324444 bytes spec/fixtures/exported-project.gz | Bin 0 -> 2306 bytes spec/fixtures/trace/sample_trace | 4380 +++-- spec/helpers/application_helper_spec.rb | 139 - spec/helpers/avatars_helper_spec.rb | 139 +- spec/helpers/blob_helper_spec.rb | 25 + spec/helpers/import_helper_spec.rb | 33 +- spec/helpers/issuables_helper_spec.rb | 29 +- spec/helpers/issues_helper_spec.rb | 45 +- spec/helpers/labels_helper_spec.rb | 72 + spec/helpers/page_layout_helper_spec.rb | 5 + spec/helpers/preferences_helper_spec.rb | 4 +- spec/helpers/tree_helper_spec.rb | 10 + spec/initializers/6_validations_spec.rb | 14 +- .../artifacts_direct_upload_support_spec.rb | 71 + .../fog_google_https_private_urls_spec.rb | 24 + spec/initializers/settings_spec.rb | 2 +- spec/javascripts/activities_spec.js | 1 + spec/javascripts/ajax_loading_spinner_spec.js | 5 +- spec/javascripts/api_spec.js | 183 +- spec/javascripts/autosave_spec.js | 1 + spec/javascripts/awards_handler_spec.js | 1 + .../badges/components/badge_form_spec.js | 171 + .../badges/components/badge_list_row_spec.js | 97 + .../badges/components/badge_list_spec.js | 88 + .../badges/components/badge_settings_spec.js | 109 + .../badges/components/badge_spec.js | 147 + spec/javascripts/badges/dummy_badge.js | 23 + spec/javascripts/badges/store/actions_spec.js | 607 + .../badges/store/mutations_spec.js | 418 + spec/javascripts/behaviors/autosize_spec.js | 1 + .../javascripts/behaviors/copy_as_gfm_spec.js | 2 +- .../behaviors/quick_submit_spec.js | 1 + .../behaviors/requires_input_spec.js | 1 + .../blob/blob_file_dropzone_spec.js | 3 +- spec/javascripts/blob/viewer/index_spec.js | 2 + spec/javascripts/boards/issue_card_spec.js | 2 + spec/javascripts/boards/mock_data.js | 49 +- spec/javascripts/bootstrap_jquery_spec.js | 1 + .../ci_variable_list/ci_variable_list_spec.js | 1 + .../native_form_variable_list_spec.js | 3 +- spec/javascripts/commits_spec.js | 1 + spec/javascripts/create_item_dropdown_spec.js | 1 + spec/javascripts/droplab/constants_spec.js | 16 +- .../feature_highlight_helper_spec.js | 1 + .../feature_highlight_spec.js | 1 + .../filtered_search_dropdown_manager_spec.js | 3 +- .../fixtures/gl_dropdown.html.haml | 3 +- spec/javascripts/fixtures/one_white_pixel.png | Bin 0 -> 68 bytes spec/javascripts/fixtures/projects.rb | 2 - spec/javascripts/gfm_auto_complete_spec.js | 11 +- spec/javascripts/gl_dropdown_spec.js | 26 + spec/javascripts/gl_field_errors_spec.js | 1 + spec/javascripts/gl_form_spec.js | 1 + .../javascripts/groups/components/app_spec.js | 1 + spec/javascripts/header_spec.js | 1 + .../helpers/vue_component_helper.js | 3 + .../helpers/vue_mount_component_helper.js | 6 + .../javascripts/helpers/vuex_action_helper.js | 70 +- .../ide/components/changed_file_icon_spec.js | 46 + .../components/commit_sidebar/actions_spec.js | 35 + .../commit_sidebar/list_collapsed_spec.js | 28 + .../commit_sidebar/list_item_spec.js | 95 + .../components/commit_sidebar/list_spec.js | 53 + .../commit_sidebar/radio_group_spec.js | 130 + .../ide/components/ide_context_bar_spec.js | 37 + .../ide/components/ide_external_links_spec.js | 43 + .../ide/components/ide_file_buttons_spec.js | 61 + .../ide/components/ide_project_tree_spec.js | 39 + .../ide/components/ide_repo_tree_spec.js | 43 + .../ide/components/ide_side_bar_spec.js | 42 + spec/javascripts/ide/components/ide_spec.js | 41 + .../ide/components/new_dropdown/index_spec.js | 84 + .../ide/components/new_dropdown/modal_spec.js | 82 + .../components/new_dropdown/upload_spec.js | 87 + .../components/repo_commit_section_spec.js | 173 + .../ide/components/repo_editor_spec.js | 284 + .../ide/components/repo_file_spec.js | 80 + .../ide/components/repo_loading_file_spec.js | 63 + .../ide/components/repo_tab_spec.js | 165 + .../ide/components/repo_tabs_spec.js | 85 + spec/javascripts/ide/helpers.js | 22 + .../ide/lib/common/disposable_spec.js | 44 + .../ide/lib/common/model_manager_spec.js | 132 + spec/javascripts/ide/lib/common/model_spec.js | 123 + .../ide/lib/decorations/controller_spec.js | 120 + .../ide/lib/diff/controller_spec.js | 196 + spec/javascripts/ide/lib/diff/diff_spec.js | 80 + .../ide/lib/editor_options_spec.js | 11 + spec/javascripts/ide/lib/editor_spec.js | 271 + spec/javascripts/ide/monaco_loader_spec.js | 15 + .../ide/stores/actions/file_spec.js | 573 + .../ide/stores/actions/merge_request_spec.js | 110 + .../ide/stores/actions/tree_spec.js | 166 + spec/javascripts/ide/stores/actions_spec.js | 306 + spec/javascripts/ide/stores/getters_spec.js | 75 + .../ide/stores/modules/commit/actions_spec.js | 508 + .../ide/stores/modules/commit/getters_spec.js | 128 + .../stores/modules/commit/mutations_spec.js | 42 + .../ide/stores/mutations/branch_spec.js | 18 + .../ide/stores/mutations/file_spec.js | 272 + .../stores/mutations/merge_request_spec.js | 65 + .../ide/stores/mutations/tree_spec.js | 79 + spec/javascripts/ide/stores/mutations_spec.js | 79 + spec/javascripts/ide/stores/utils_spec.js | 66 + .../integration_settings_form_spec.js | 1 + spec/javascripts/issuable_spec.js | 1 + .../javascripts/issuable_time_tracker_spec.js | 1 + .../issue_show/components/app_spec.js | 3 +- .../issue_show/components/description_spec.js | 1 + spec/javascripts/issue_spec.js | 2 + spec/javascripts/job_spec.js | 1 + spec/javascripts/jobs/mock_data.js | 4 + .../jobs/sidebar_detail_row_spec.js | 21 + .../jobs/sidebar_details_block_spec.js | 6 + spec/javascripts/labels_issue_sidebar_spec.js | 2 + spec/javascripts/labels_select_spec.js | 1 + .../lib/utils/text_markdown_spec.js | 10 +- .../lib/utils/text_utility_spec.js | 14 +- spec/javascripts/line_highlighter_spec.js | 1 + spec/javascripts/matchers.js | 35 + spec/javascripts/merge_request_notes_spec.js | 4 +- spec/javascripts/merge_request_spec.js | 6 +- spec/javascripts/merge_request_tabs_spec.js | 2 + .../mini_pipeline_graph_dropdown_spec.js | 1 + spec/javascripts/monitoring/dashboard_spec.js | 1 + .../monitoring/dashboard_state_spec.js | 46 +- .../javascripts/monitoring/graph/axis_spec.js | 65 + .../monitoring/graph/legend_spec.js | 108 +- .../monitoring/graph/track_info_spec.js | 44 + .../monitoring/graph/track_line_spec.js | 52 + spec/javascripts/monitoring/graph_spec.js | 25 +- spec/javascripts/monitoring/mock_data.js | 14732 +++++++--------- spec/javascripts/namespace_select_spec.js | 1 + spec/javascripts/new_branch_spec.js | 1 + .../notes/components/comment_form_spec.js | 1 + .../notes/components/diff_file_header_spec.js | 2 +- .../notes/components/diff_with_note_spec.js | 2 +- .../notes/components/note_actions_spec.js | 4 +- .../notes/components/note_app_spec.js | 3 +- .../notes/components/note_awards_list_spec.js | 34 +- .../notes/components/note_body_spec.js | 1 + .../components/noteable_discussion_spec.js | 2 +- .../notes/components/noteable_note_spec.js | 1 + spec/javascripts/notes/mock_data.js | 881 +- spec/javascripts/notes/stores/actions_spec.js | 199 +- spec/javascripts/notes_spec.js | 314 +- spec/javascripts/oauth_remember_me_spec.js | 1 + .../admin/abuse_reports/abuse_reports_spec.js | 1 + .../components/promote_label_modal_spec.js | 2 +- .../promote_milestone_modal_spec.js | 2 +- .../components/detailed_metric_spec.js | 80 + .../components/performance_bar_app_spec.js | 88 + .../components/request_selector_spec.js | 47 + .../components/simple_metric_spec.js | 47 + .../pipelines/graph/action_component_spec.js | 25 +- .../pipelines/graph/job_component_spec.js | 2 + spec/javascripts/pipelines/graph/mock_data.js | 467 +- .../pipelines/nav_controls_spec.js | 37 +- spec/javascripts/pipelines/pipelines_spec.js | 14 +- .../components/update_username_spec.js | 172 + .../project_select_combo_button_spec.js | 1 + spec/javascripts/projects/project_new_spec.js | 1 + .../registry/stores/actions_spec.js | 87 +- spec/javascripts/right_sidebar_spec.js | 1 + spec/javascripts/search_autocomplete_spec.js | 217 +- spec/javascripts/search_spec.js | 1 + spec/javascripts/shortcuts_issuable_spec.js | 3 +- spec/javascripts/shortcuts_spec.js | 1 + .../sidebar/assignee_title_spec.js | 2 +- .../confidential_issue_sidebar_spec.js | 18 + .../sidebar/lock/lock_issue_sidebar_spec.js | 18 + spec/javascripts/sidebar/mock_data.js | 59 +- .../sidebar/sidebar_move_issue_spec.js | 1 + spec/javascripts/smart_interval_spec.js | 1 + spec/javascripts/syntax_highlight_spec.js | 1 + spec/javascripts/test_bundle.js | 30 +- spec/javascripts/test_constants.js | 4 + spec/javascripts/todos_spec.js | 1 + spec/javascripts/toggle_buttons_spec.js | 1 + spec/javascripts/u2f/authenticate_spec.js | 1 + spec/javascripts/u2f/register_spec.js | 1 + spec/javascripts/version_check_image_spec.js | 1 + .../components/deployment_spec.js | 172 + .../components/mr_widget_deployment_spec.js | 179 - .../components/mr_widget_header_spec.js | 244 +- .../components/mr_widget_memory_usage_spec.js | 106 +- .../states/mr_widget_conflicts_spec.js | 6 +- .../states/mr_widget_nothing_to_merge_spec.js | 6 +- .../states/mr_widget_pipeline_blocked_spec.js | 5 +- .../states/mr_widget_ready_to_merge_spec.js | 12 +- .../states/mr_widget_sha_mismatch_spec.js | 33 +- .../mr_widget_unresolved_discussions_spec.js | 8 +- spec/javascripts/vue_mr_widget/mock_data.js | 393 +- .../vue_mr_widget/mr_widget_options_spec.js | 140 +- .../content_viewer/content_viewer_spec.js | 70 + ...modal_spec.js => deprecated_modal_spec.js} | 7 +- .../vue_shared/components/gl_modal_spec.js | 1 + .../components/markdown/field_spec.js | 1 + .../components/markdown/toolbar_spec.js | 2 +- .../components/memory_graph_spec.js | 26 +- .../vue_shared/components/mock_data.js | 2 - .../sidebar/labels_select/base_spec.js | 30 +- .../labels_select/dropdown_button_spec.js | 4 +- .../dropdown_create_label_spec.js | 20 +- .../labels_select/dropdown_footer_spec.js | 36 +- .../labels_select/dropdown_header_spec.js | 2 +- .../dropdown_hidden_input_spec.js | 4 +- .../dropdown_search_input_spec.js | 2 +- .../labels_select/dropdown_title_spec.js | 2 +- .../dropdown_value_collapsed_spec.js | 4 +- .../labels_select/dropdown_value_spec.js | 4 +- .../sidebar/labels_select/mock_data.js | 1 + .../skeleton_loading_container_spec.js | 4 +- .../vue_shared/directives/tooltip_spec.js | 1 + spec/javascripts/zen_mode_spec.js | 1 + spec/lib/api/helpers_spec.rb | 42 + spec/lib/backup/files_spec.rb | 66 + spec/lib/backup/manager_spec.rb | 4 + spec/lib/backup/repository_spec.rb | 15 +- spec/lib/banzai/commit_renderer_spec.rb | 5 +- .../banzai/cross_project_reference_spec.rb | 10 + .../commit_range_reference_filter_spec.rb | 16 + .../filter/commit_reference_filter_spec.rb | 47 + .../filter/commit_trailers_filter_spec.rb | 191 + .../filter/issuable_state_filter_spec.rb | 8 + .../filter/label_reference_filter_spec.rb | 22 + .../merge_request_reference_filter_spec.rb | 35 + .../filter/milestone_reference_filter_spec.rb | 12 +- .../filter/relative_link_filter_spec.rb | 17 + .../filter/snippet_reference_filter_spec.rb | 6 + spec/lib/banzai/issuable_extractor_spec.rb | 2 +- spec/lib/banzai/object_renderer_spec.rb | 9 +- spec/lib/banzai/redactor_spec.rb | 4 +- .../reference_parser/base_parser_spec.rb | 18 +- .../reference_parser/commit_parser_spec.rb | 2 +- .../commit_range_parser_spec.rb | 16 +- .../external_issue_parser_spec.rb | 2 +- .../reference_parser/issue_parser_spec.rb | 25 +- .../reference_parser/label_parser_spec.rb | 2 +- .../merge_request_parser_spec.rb | 30 +- .../reference_parser/milestone_parser_spec.rb | 2 +- .../reference_parser/snippet_parser_spec.rb | 2 +- .../reference_parser/user_parser_spec.rb | 2 +- spec/lib/banzai/render_context_spec.rb | 37 + .../constraints/group_url_constrainer_spec.rb | 2 +- .../project_url_constrainer_spec.rb | 2 +- .../constraints/user_url_constrainer_spec.rb | 2 +- spec/lib/forever_spec.rb | 21 + spec/lib/gitlab/asciidoc_spec.rb | 2 +- spec/lib/gitlab/auth/ldap/access_spec.rb | 22 +- spec/lib/gitlab/auth/ldap/adapter_spec.rb | 30 +- spec/lib/gitlab/auth/o_auth/user_spec.rb | 66 +- spec/lib/gitlab/auth_spec.rb | 122 +- ...d_merge_request_diff_commits_count_spec.rb | 12 + .../bare_repository_import/repository_spec.rb | 4 +- .../gitlab/bitbucket_import/importer_spec.rb | 2 +- spec/lib/gitlab/checks/project_moved_spec.rb | 43 +- .../gitlab/ci/build/policy/variables_spec.rb | 72 + spec/lib/gitlab/ci/build/step_spec.rb | 12 +- .../lib/gitlab/ci/config/entry/policy_spec.rb | 33 + .../gitlab/ci/pipeline/chain/create_spec.rb | 35 +- .../gitlab/ci/pipeline/chain/populate_spec.rb | 158 + .../ci/pipeline/chain/validate/config_spec.rb | 22 - .../pipeline/expression/lexeme/string_spec.rb | 16 + .../ci/pipeline/expression/statement_spec.rb | 91 +- .../lib/gitlab/ci/pipeline/seed/build_spec.rb | 232 + .../lib/gitlab/ci/pipeline/seed/stage_spec.rb | 123 + spec/lib/gitlab/ci/stage/seed_spec.rb | 83 - .../lib/gitlab/ci/status/build/action_spec.rb | 10 + .../gitlab/ci/status/build/cancelable_spec.rb | 22 + .../gitlab/ci/status/build/canceled_spec.rb | 33 + .../lib/gitlab/ci/status/build/common_spec.rb | 6 + .../gitlab/ci/status/build/created_spec.rb | 33 + .../lib/gitlab/ci/status/build/erased_spec.rb | 33 + .../gitlab/ci/status/build/factory_spec.rb | 62 +- .../ci/status/build/failed_allowed_spec.rb | 23 + .../lib/gitlab/ci/status/build/failed_spec.rb | 83 + .../lib/gitlab/ci/status/build/manual_spec.rb | 34 + .../gitlab/ci/status/build/pending_spec.rb | 33 + spec/lib/gitlab/ci/status/build/play_spec.rb | 26 +- .../gitlab/ci/status/build/retried_spec.rb | 96 + .../gitlab/ci/status/build/retryable_spec.rb | 22 + .../gitlab/ci/status/build/skipped_spec.rb | 33 + spec/lib/gitlab/ci/status/build/stop_spec.rb | 24 + .../gitlab/ci/status/success_warning_spec.rb | 4 +- spec/lib/gitlab/ci/trace/http_io_spec.rb | 315 + .../ci/variables/collection/item_spec.rb | 83 + .../gitlab/ci/variables/collection_spec.rb | 114 + spec/lib/gitlab/ci/yaml_processor_spec.rb | 686 +- .../gitlab/database/migration_helpers_spec.rb | 137 +- .../lib/gitlab/database/sha_attribute_spec.rb | 8 +- .../merge_request_diff_spec.rb | 2 +- spec/lib/gitlab/diff/file_spec.rb | 12 + spec/lib/gitlab/exclusive_lease_spec.rb | 12 + spec/lib/gitlab/git/gitlab_projects_spec.rb | 26 +- spec/lib/gitlab/git/gitmodules_parser_spec.rb | 3 +- .../git/{env_spec.rb => hook_env_spec.rb} | 71 +- spec/lib/gitlab/git/repository_spec.rb | 200 +- spec/lib/gitlab/git/rev_list_spec.rb | 13 +- spec/lib/gitlab/git_access_spec.rb | 159 +- .../gitaly_client/remote_service_spec.rb | 10 + .../gitaly_client/repository_service_spec.rb | 32 + spec/lib/gitlab/gitaly_client/util_spec.rb | 11 +- .../importer/repository_importer_spec.rb | 8 +- .../health_checks/fs_shards_check_spec.rb | 6 +- spec/lib/gitlab/http_spec.rb | 6 +- .../base_after_export_strategy_spec.rb | 104 + .../web_upload_strategy_spec.rb | 36 + .../after_export_strategy_builder_spec.rb | 29 + spec/lib/gitlab/import_export/all_models.yml | 7 + .../lib/gitlab/import_export/importer_spec.rb | 104 + .../gitlab/import_export/lfs_restorer_spec.rb | 75 + .../gitlab/import_export/lfs_saver_spec.rb | 62 + spec/lib/gitlab/import_export/project.json | 92 +- .../project_tree_restorer_spec.rb | 34 +- .../import_export/project_tree_saver_spec.rb | 17 +- .../import_export/safe_model_attributes.yml | 4 + spec/lib/gitlab/kubernetes/namespace_spec.rb | 2 +- .../metrics/sidekiq_metrics_exporter_spec.rb | 4 +- spec/lib/gitlab/omniauth_initializer_spec.rb | 65 + spec/lib/gitlab/performance_bar_spec.rb | 6 + spec/lib/gitlab/profiler_spec.rb | 28 +- .../lib/gitlab/project_search_results_spec.rb | 22 +- spec/lib/gitlab/repo_path_spec.rb | 4 +- spec/lib/gitlab/shell_spec.rb | 34 +- .../sidekiq_logging/json_formatter_spec.rb | 31 + .../sidekiq_logging/structured_logger_spec.rb | 101 + .../lib/gitlab/slash_commands/command_spec.rb | 5 + .../gitlab/slash_commands/issue_move_spec.rb | 117 + .../presenters/issue_move_spec.rb | 26 + spec/lib/gitlab/url_blocker_spec.rb | 12 +- spec/lib/gitlab/usage_data_spec.rb | 23 + spec/lib/gitlab/user_access_spec.rb | 12 + spec/lib/gitlab/verify/job_artifacts_spec.rb | 35 + spec/lib/gitlab/verify/lfs_objects_spec.rb | 16 + spec/lib/gitlab/verify/uploads_spec.rb | 16 + spec/lib/gitlab/workhorse_spec.rb | 36 +- spec/lib/mattermost/team_spec.rb | 104 + spec/lib/omni_auth/strategies/jwt_spec.rb | 87 + spec/lib/uploaded_file_spec.rb | 116 + spec/mailers/notify_spec.rb | 42 + .../email_rejection_mailer_preview.rb | 5 + spec/mailers/previews/notify_preview.rb | 85 +- .../repository_check_mailer_preview.rb | 5 + .../add_foreign_keys_to_todos_spec.rb | 6 +- ...ad_pipeline_for_each_merge_request_spec.rb | 18 +- ...lculate_conv_dev_index_percentages_spec.rb | 2 +- ...espaceless_pending_delete_projects_spec.rb | 10 +- ..._namespace_pending_delete_projects_spec.rb | 8 +- .../issues_moved_to_id_foreign_key_spec.rb | 6 +- spec/migrations/migrate_old_artifacts_spec.rb | 20 +- ...migrate_process_commit_worker_jobs_spec.rb | 4 +- ...tivities_to_users_last_activity_on_spec.rb | 4 +- .../migrate_user_project_view_spec.rb | 2 +- .../move_personal_snippets_files_spec.rb | 16 +- .../remove_dot_git_from_usernames_spec.rb | 8 +- .../remove_duplicate_mr_events_spec.rb | 18 +- .../remove_empty_fork_networks_spec.rb | 4 + .../remove_project_labels_group_id_spec.rb | 6 +- .../remove_soft_removed_objects_spec.rb | 8 +- ...rename_more_reserved_project_names_spec.rb | 2 +- .../rename_reserved_project_names_spec.rb | 2 +- ...ename_users_with_renamed_namespace_spec.rb | 12 +- ...eschedule_builds_stages_migration_spec.rb} | 8 +- ...mmits_count_for_merge_request_diff_spec.rb | 37 + ...eate_gpg_key_subkeys_from_gpg_keys_spec.rb | 4 +- ...e_request_metrics_with_events_data_spec.rb | 2 +- ...oups_into_regular_groups_for_mysql_spec.rb | 8 +- .../update_retried_for_ci_build_spec.rb | 6 +- spec/models/ability_spec.rb | 56 - spec/models/ci/artifact_blob_spec.rb | 13 + spec/models/ci/build_metadata_spec.rb | 61 + spec/models/ci/build_spec.rb | 346 +- spec/models/ci/job_artifact_spec.rb | 83 + spec/models/ci/pipeline_spec.rb | 377 +- .../models/clusters/applications/helm_spec.rb | 12 + .../clusters/applications/ingress_spec.rb | 12 + .../clusters/applications/prometheus_spec.rb | 12 + .../clusters/applications/runner_spec.rb | 12 + spec/models/clusters/cluster_spec.rb | 36 + .../clusters/platforms/kubernetes_spec.rb | 2 +- spec/models/commit_status_spec.rb | 4 +- spec/models/concerns/avatarable_spec.rb | 16 +- spec/models/concerns/awardable_spec.rb | 25 + .../chronic_duration_attribute_spec.rb | 129 + spec/models/concerns/issuable_spec.rb | 10 +- spec/models/deploy_key_spec.rb | 21 + spec/models/deploy_token_spec.rb | 145 + spec/models/environment_spec.rb | 30 +- spec/models/group_spec.rb | 2 +- spec/models/internal_id_spec.rb | 139 + spec/models/issue_spec.rb | 8 +- spec/models/lfs_object_spec.rb | 122 + spec/models/merge_request_diff_commit_spec.rb | 6 +- spec/models/merge_request_spec.rb | 15 +- spec/models/namespace_spec.rb | 2 +- spec/models/note_spec.rb | 17 + spec/models/pages_domain_spec.rb | 156 +- spec/models/project_auto_devops_spec.rb | 8 +- spec/models/project_deploy_token_spec.rb | 14 + .../kubernetes_service_spec.rb | 2 +- spec/models/project_spec.rb | 184 +- spec/models/project_wiki_spec.rb | 14 +- spec/models/repository_spec.rb | 32 +- spec/models/route_spec.rb | 159 +- spec/models/service_spec.rb | 15 + spec/models/user_spec.rb | 83 +- spec/policies/deploy_token_policy_spec.rb | 45 + spec/policies/group_policy_spec.rb | 27 +- spec/policies/note_policy_spec.rb | 4 - spec/policies/personal_snippet_policy_spec.rb | 11 + spec/policies/project_policy_spec.rb | 103 +- spec/policies/protected_branch_policy_spec.rb | 22 + spec/presenters/ci/build_presenter_spec.rb | 95 +- spec/presenters/project_presenter_spec.rb | 11 + spec/requests/api/boards_spec.rb | 31 + spec/requests/api/commits_spec.rb | 29 + spec/requests/api/deploy_keys_spec.rb | 4 + spec/requests/api/features_spec.rb | 43 +- spec/requests/api/internal_spec.rb | 53 +- spec/requests/api/issues_spec.rb | 24 + spec/requests/api/jobs_spec.rb | 84 +- spec/requests/api/merge_requests_spec.rb | 4 +- spec/requests/api/pages_domains_spec.rb | 14 +- spec/requests/api/pipeline_schedules_spec.rb | 23 +- spec/requests/api/project_export_spec.rb | 90 +- spec/requests/api/project_import_spec.rb | 68 +- spec/requests/api/project_snapshots_spec.rb | 51 + spec/requests/api/projects_spec.rb | 56 +- spec/requests/api/protected_branches_spec.rb | 34 +- spec/requests/api/repositories_spec.rb | 15 + spec/requests/api/runner_spec.rb | 254 +- spec/requests/api/runners_spec.rb | 5 +- spec/requests/api/search_spec.rb | 48 +- spec/requests/api/templates_spec.rb | 2 +- spec/requests/api/v3/builds_spec.rb | 32 +- spec/requests/api/v3/merge_requests_spec.rb | 4 +- spec/requests/api/v3/templates_spec.rb | 2 +- spec/requests/git_http_spec.rb | 28 +- spec/requests/lfs_http_spec.rb | 213 +- spec/requests/openid_connect_spec.rb | 9 + .../projects/cycle_analytics_events_spec.rb | 10 +- spec/routing/project_routing_spec.rb | 30 +- spec/routing/routing_spec.rb | 4 +- .../factories_in_migration_specs_spec.rb | 48 + spec/serializers/build_serializer_spec.rb | 22 +- spec/serializers/discussion_entity_spec.rb | 2 +- spec/serializers/job_entity_spec.rb | 26 +- spec/serializers/note_entity_spec.rb | 50 +- spec/serializers/pipeline_entity_spec.rb | 2 +- spec/serializers/pipeline_serializer_spec.rb | 1 + spec/serializers/project_note_entity_spec.rb | 29 + spec/serializers/stage_entity_spec.rb | 2 +- spec/serializers/status_entity_spec.rb | 7 +- ...er_registry_authentication_service_spec.rb | 136 + .../boards/issues/list_service_spec.rb | 25 +- .../ci/process_pipeline_service_spec.rb | 2 + spec/services/ci/retry_build_service_spec.rb | 4 +- .../ci/retry_pipeline_service_spec.rb | 2 + .../applications/install_service_spec.rb | 2 +- .../deploy_tokens/create_service_spec.rb | 45 + spec/services/events/render_service_spec.rb | 6 +- spec/services/files/create_service_spec.rb | 4 +- spec/services/files/multi_service_spec.rb | 72 +- spec/services/groups/transfer_service_spec.rb | 42 +- .../services/issuable/destroy_service_spec.rb | 14 +- spec/services/issues/close_service_spec.rb | 4 + spec/services/issues/move_service_spec.rb | 2 +- spec/services/issues/update_service_spec.rb | 6 +- spec/services/lfs/file_transformer_spec.rb | 97 + .../conflicts/list_service_spec.rb | 16 + .../merge_requests/create_service_spec.rb | 24 +- .../merge_request_diff_cache_service_spec.rb | 36 +- .../merge_requests/refresh_service_spec.rb | 21 + spec/services/notes/render_service_spec.rb | 25 +- spec/services/notification_service_spec.rb | 51 +- .../create_from_template_service_spec.rb | 22 +- spec/services/projects/create_service_spec.rb | 31 +- .../services/projects/destroy_service_spec.rb | 28 + spec/services/projects/fork_service_spec.rb | 4 +- .../gitlab_projects_import_service_spec.rb | 40 +- .../import_export/export_service_spec.rb | 128 + spec/services/projects/import_service_spec.rb | 4 +- .../projects/move_access_service_spec.rb | 114 + .../move_deploy_keys_projects_service_spec.rb | 58 + .../projects/move_forks_service_spec.rb | 96 + .../move_lfs_objects_projects_service_spec.rb | 55 + ...move_notification_settings_service_spec.rb | 56 + ...ove_project_authorizations_service_spec.rb | 56 + .../move_project_group_links_service_spec.rb | 65 + .../move_project_members_service_spec.rb | 65 + .../move_users_star_projects_service_spec.rb | 42 + .../overwrite_project_service_spec.rb | 198 + .../projects/transfer_service_spec.rb | 10 +- .../projects/update_pages_service_spec.rb | 130 +- spec/services/projects/update_service_spec.rb | 25 +- .../protected_branches/create_service_spec.rb | 13 + .../destroy_service_spec.rb | 30 + .../protected_branches/update_service_spec.rb | 11 + .../protected_tags/destroy_service_spec.rb | 17 + ...epository_archive_clean_up_service_spec.rb | 72 +- spec/services/system_note_service_spec.rb | 2 +- spec/spec_helper.rb | 24 +- spec/support/commit_trailers_spec_helper.rb | 41 + spec/support/cookie_helper.rb | 13 + .../discussion_comments_shared_example.rb | 19 +- ...issuable_slash_commands_shared_examples.rb | 28 +- spec/support/filter_spec_helper.rb | 5 + spec/support/filtered_search_helpers.rb | 23 + spec/support/gitaly.rb | 6 +- spec/support/helpers/expect_offense.rb | 20 + .../support/helpers/features/notes_helpers.rb | 27 + .../helpers/features/sorting_helpers.rb | 26 + spec/support/http_io/http_io_helpers.rb | 65 + ...issuables_list_metadata_shared_examples.rb | 8 +- ...uables_requiring_filter_shared_examples.rb | 15 + spec/support/ldap_helpers.rb | 5 + spec/support/login_helpers.rb | 4 + spec/support/matchers/have_emoji.rb | 5 + spec/support/matchers/issuable_matchers.rb | 11 + spec/support/quick_actions_helpers.rb | 10 - spec/support/reference_parser_helpers.rb | 34 + .../controllers/variables_shared_examples.rb | 10 +- .../models/atomic_internal_id_spec.rb | 40 + .../serializers/note_entity_examples.rb | 42 + .../object_storage_shared_examples.rb | 138 + spec/support/sorting_helper.rb | 18 - spec/support/stored_repositories.rb | 2 +- spec/support/stub_configuration.rb | 12 +- spec/support/stub_object_storage.rb | 48 + spec/support/test_env.rb | 3 +- .../tasks/gitlab/artifacts/check_rake_spec.rb | 34 + .../gitlab/artifacts/migrate_rake_spec.rb | 118 + spec/tasks/gitlab/backup_rake_spec.rb | 15 +- spec/tasks/gitlab/cleanup_rake_spec.rb | 7 +- spec/tasks/gitlab/git_rake_spec.rb | 7 +- spec/tasks/gitlab/gitaly_rake_spec.rb | 10 +- spec/tasks/gitlab/lfs/migrate_rake_spec.rb | 37 + spec/tasks/gitlab/shell_rake_spec.rb | 2 +- .../tasks/gitlab/uploads/migrate_rake_spec.rb | 143 + spec/uploaders/attachment_uploader_spec.rb | 22 + spec/uploaders/avatar_uploader_spec.rb | 27 +- spec/uploaders/file_mover_spec.rb | 6 + spec/uploaders/file_uploader_spec.rb | 71 +- spec/uploaders/gitlab_uploader_spec.rb | 4 +- spec/uploaders/job_artifact_uploader_spec.rb | 35 +- .../legacy_artifact_uploader_spec.rb | 14 +- spec/uploaders/lfs_object_uploader_spec.rb | 52 + .../uploaders/namespace_file_uploader_spec.rb | 22 + spec/uploaders/object_storage_spec.rb | 660 + spec/uploaders/personal_file_uploader_spec.rb | 22 + .../background_move_worker_spec.rb | 146 + .../migrate_uploads_worker_spec.rb | 119 + .../buttons/_dropdown.html.haml_spec.rb | 3 +- .../ci/lints/show.html.haml_spec.rb | 34 +- .../commit/_commit_box.html.haml_spec.rb | 8 +- .../projects/diffs/_stats.html.haml_spec.rb | 56 + .../projects/jobs/show.html.haml_spec.rb | 20 +- .../merge_requests/_commits.html.haml_spec.rb | 2 +- .../projects/services/_form.haml_spec.rb | 46 + .../ci_cd/_form.html.haml_spec.rb} | 2 +- .../object_storage_upload_worker_spec.rb | 108 + spec/workers/project_export_worker_spec.rb | 28 + spec/workers/repository_fork_worker_spec.rb | 111 +- vendor/assets/javascripts/peek.js | 70 - vendor/gitignore/Android.gitignore | 2 + vendor/gitignore/Elixir.gitignore | 1 + vendor/gitignore/Global/JetBrains.gitignore | 15 +- vendor/gitignore/Global/Windows.gitignore | 1 + vendor/gitignore/Godot.gitignore | 8 + vendor/gitignore/Joomla.gitignore | 1 - vendor/gitignore/KiCad.gitignore | 5 + vendor/gitignore/Leiningen.gitignore | 1 + vendor/gitignore/Node.gitignore | 2 +- vendor/gitignore/Python.gitignore | 3 +- vendor/gitignore/Rails.gitignore | 1 + vendor/gitignore/Rust.gitignore | 2 +- vendor/gitignore/TeX.gitignore | 2 + vendor/gitignore/Unity.gitignore | 2 +- vendor/gitignore/VisualStudio.gitignore | 8 + .../gitlab-ci-yml/Auto-DevOps.gitlab-ci.yml | 58 +- vendor/gitlab-ci-yml/Laravel.gitlab-ci.yml | 2 +- .../gitlab-ci-yml/Pages/Gatsby.gitlab-ci.yml | 17 + vendor/gitlab-ci-yml/Pages/Hugo.gitlab-ci.yml | 2 +- vendor/gitlab-ci-yml/Python.gitlab-ci.yml | 23 +- vendor/licenses.csv | 129 +- yarn.lock | 14 +- 2200 files changed, 89163 insertions(+), 28549 deletions(-) create mode 100644 .prettierignore create mode 100644 .prettierrc create mode 100644 Gemfile.rails5 create mode 100644 Gemfile.rails5.lock create mode 100644 app/assets/images/ci_favicons/canary/favicon_status_canceled.ico create mode 100644 app/assets/images/ci_favicons/canary/favicon_status_created.ico create mode 100644 app/assets/images/ci_favicons/canary/favicon_status_failed.ico create mode 100644 app/assets/images/ci_favicons/canary/favicon_status_manual.ico create mode 100644 app/assets/images/ci_favicons/canary/favicon_status_not_found.ico create mode 100644 app/assets/images/ci_favicons/canary/favicon_status_pending.ico create mode 100644 app/assets/images/ci_favicons/canary/favicon_status_running.ico create mode 100644 app/assets/images/ci_favicons/canary/favicon_status_skipped.ico create mode 100644 app/assets/images/ci_favicons/canary/favicon_status_success.ico create mode 100644 app/assets/images/ci_favicons/canary/favicon_status_warning.ico create mode 100644 app/assets/images/favicon-yellow.ico delete mode 100644 app/assets/images/icons.json delete mode 100644 app/assets/images/icons.svg delete mode 100644 app/assets/images/illustrations/cluster_popover.svg delete mode 100644 app/assets/images/illustrations/clusters_empty.svg delete mode 100644 app/assets/images/illustrations/convdev/convdev_no_data.svg delete mode 100644 app/assets/images/illustrations/convdev/convdev_no_index.svg delete mode 100644 app/assets/images/illustrations/convdev/convdev_overview.svg delete mode 100644 app/assets/images/illustrations/convdev/i2p_step_1.svg delete mode 100644 app/assets/images/illustrations/convdev/i2p_step_10.svg delete mode 100644 app/assets/images/illustrations/convdev/i2p_step_2.svg delete mode 100644 app/assets/images/illustrations/convdev/i2p_step_3.svg delete mode 100644 app/assets/images/illustrations/convdev/i2p_step_4.svg delete mode 100644 app/assets/images/illustrations/convdev/i2p_step_5.svg delete mode 100644 app/assets/images/illustrations/convdev/i2p_step_6.svg delete mode 100644 app/assets/images/illustrations/convdev/i2p_step_7.svg delete mode 100644 app/assets/images/illustrations/convdev/i2p_step_8.svg delete mode 100644 app/assets/images/illustrations/convdev/i2p_step_9.svg delete mode 100644 app/assets/images/illustrations/epics.svg delete mode 100644 app/assets/images/illustrations/gitlab_logo.svg delete mode 100644 app/assets/images/illustrations/image_comment_light_cursor.svg delete mode 100644 app/assets/images/illustrations/image_comment_light_cursor@2x.svg delete mode 100644 app/assets/images/illustrations/issues.svg delete mode 100644 app/assets/images/illustrations/job_not_triggered.svg delete mode 100644 app/assets/images/illustrations/labels.svg delete mode 100644 app/assets/images/illustrations/logos/go_logo.svg delete mode 100644 app/assets/images/illustrations/logos/mattermost_logo.svg delete mode 100644 app/assets/images/illustrations/manual_action.svg delete mode 100644 app/assets/images/illustrations/merge_request_changes_empty.svg delete mode 100644 app/assets/images/illustrations/merge_requests.svg delete mode 100644 app/assets/images/illustrations/monitoring/getting_started.svg delete mode 100644 app/assets/images/illustrations/monitoring/loading.svg delete mode 100644 app/assets/images/illustrations/monitoring/unable_to_connect.svg delete mode 100644 app/assets/images/illustrations/multi-editor_all_changes_committed_empty.svg delete mode 100644 app/assets/images/illustrations/multi-editor_no_changes_empty.svg delete mode 100644 app/assets/images/illustrations/multi-editor_no_staged_files_empty.svg delete mode 100644 app/assets/images/illustrations/multi_file_editor_empty.svg delete mode 100644 app/assets/images/illustrations/no_commits.svg delete mode 100644 app/assets/images/illustrations/pending_job_empty.svg delete mode 100644 app/assets/images/illustrations/pipelines_empty.svg delete mode 100644 app/assets/images/illustrations/pipelines_failed.svg delete mode 100644 app/assets/images/illustrations/pipelines_pending.svg delete mode 100644 app/assets/images/illustrations/priority_labels.svg delete mode 100644 app/assets/images/illustrations/service_desk_callout.svg delete mode 100644 app/assets/images/illustrations/service_desk_empty.svg delete mode 100644 app/assets/images/illustrations/slack_logo.svg delete mode 100644 app/assets/images/illustrations/todos_all_done.svg delete mode 100644 app/assets/images/illustrations/todos_empty.svg delete mode 100644 app/assets/images/illustrations/welcome/add_new_group.svg delete mode 100644 app/assets/images/illustrations/welcome/add_new_project.svg delete mode 100644 app/assets/images/illustrations/welcome/add_new_user.svg delete mode 100644 app/assets/images/illustrations/welcome/configure_server.svg delete mode 100644 app/assets/images/illustrations/welcome/ee_trial.svg delete mode 100644 app/assets/images/illustrations/welcome/globe.svg delete mode 100644 app/assets/images/illustrations/welcome/lightbulb.svg delete mode 100644 app/assets/images/illustrations/wiki-fro-logged-out-users.svg delete mode 100644 app/assets/images/illustrations/wiki_login_empty.svg delete mode 100644 app/assets/images/illustrations/wiki_logout_empty.svg create mode 100644 app/assets/javascripts/badges/components/badge.vue create mode 100644 app/assets/javascripts/badges/components/badge_form.vue create mode 100644 app/assets/javascripts/badges/components/badge_list.vue create mode 100644 app/assets/javascripts/badges/components/badge_list_row.vue create mode 100644 app/assets/javascripts/badges/components/badge_settings.vue create mode 100644 app/assets/javascripts/badges/constants.js create mode 100644 app/assets/javascripts/badges/empty_badge.js create mode 100644 app/assets/javascripts/badges/store/actions.js create mode 100644 app/assets/javascripts/badges/store/index.js create mode 100644 app/assets/javascripts/badges/store/mutation_types.js create mode 100644 app/assets/javascripts/badges/store/mutations.js create mode 100644 app/assets/javascripts/badges/store/state.js rename app/assets/javascripts/behaviors/{ => markdown}/copy_as_gfm.js (99%) rename app/assets/javascripts/{ => behaviors/markdown}/render_gfm.js (85%) rename app/assets/javascripts/{ => behaviors/markdown}/render_math.js (85%) rename app/assets/javascripts/{ => behaviors/markdown}/render_mermaid.js (94%) create mode 100644 app/assets/javascripts/ide/components/changed_file_icon.vue create mode 100644 app/assets/javascripts/ide/components/commit_sidebar/actions.vue create mode 100644 app/assets/javascripts/ide/components/commit_sidebar/list.vue create mode 100644 app/assets/javascripts/ide/components/commit_sidebar/list_collapsed.vue create mode 100644 app/assets/javascripts/ide/components/commit_sidebar/list_item.vue create mode 100644 app/assets/javascripts/ide/components/commit_sidebar/radio_group.vue create mode 100644 app/assets/javascripts/ide/components/editor_mode_dropdown.vue create mode 100644 app/assets/javascripts/ide/components/ide.vue create mode 100644 app/assets/javascripts/ide/components/ide_context_bar.vue create mode 100644 app/assets/javascripts/ide/components/ide_external_links.vue create mode 100644 app/assets/javascripts/ide/components/ide_file_buttons.vue create mode 100644 app/assets/javascripts/ide/components/ide_project_branches_tree.vue create mode 100644 app/assets/javascripts/ide/components/ide_project_tree.vue create mode 100644 app/assets/javascripts/ide/components/ide_repo_tree.vue create mode 100644 app/assets/javascripts/ide/components/ide_side_bar.vue create mode 100644 app/assets/javascripts/ide/components/ide_status_bar.vue create mode 100644 app/assets/javascripts/ide/components/mr_file_icon.vue create mode 100644 app/assets/javascripts/ide/components/new_dropdown/index.vue create mode 100644 app/assets/javascripts/ide/components/new_dropdown/modal.vue create mode 100644 app/assets/javascripts/ide/components/new_dropdown/upload.vue create mode 100644 app/assets/javascripts/ide/components/repo_commit_section.vue create mode 100644 app/assets/javascripts/ide/components/repo_editor.vue create mode 100644 app/assets/javascripts/ide/components/repo_file.vue create mode 100644 app/assets/javascripts/ide/components/repo_file_status_icon.vue create mode 100644 app/assets/javascripts/ide/components/repo_loading_file.vue create mode 100644 app/assets/javascripts/ide/components/repo_tab.vue create mode 100644 app/assets/javascripts/ide/components/repo_tabs.vue create mode 100644 app/assets/javascripts/ide/components/resizable_panel.vue create mode 100644 app/assets/javascripts/ide/eventhub.js create mode 100644 app/assets/javascripts/ide/ide_router.js create mode 100644 app/assets/javascripts/ide/index.js create mode 100644 app/assets/javascripts/ide/lib/common/disposable.js create mode 100644 app/assets/javascripts/ide/lib/common/model.js create mode 100644 app/assets/javascripts/ide/lib/common/model_manager.js create mode 100644 app/assets/javascripts/ide/lib/decorations/controller.js create mode 100644 app/assets/javascripts/ide/lib/diff/controller.js create mode 100644 app/assets/javascripts/ide/lib/diff/diff.js create mode 100644 app/assets/javascripts/ide/lib/diff/diff_worker.js create mode 100644 app/assets/javascripts/ide/lib/editor.js create mode 100644 app/assets/javascripts/ide/lib/editor_options.js create mode 100644 app/assets/javascripts/ide/lib/themes/gl_theme.js create mode 100644 app/assets/javascripts/ide/monaco_loader.js create mode 100644 app/assets/javascripts/ide/services/index.js create mode 100644 app/assets/javascripts/ide/stores/actions.js create mode 100644 app/assets/javascripts/ide/stores/actions/file.js create mode 100644 app/assets/javascripts/ide/stores/actions/merge_request.js create mode 100644 app/assets/javascripts/ide/stores/actions/project.js create mode 100644 app/assets/javascripts/ide/stores/actions/tree.js create mode 100644 app/assets/javascripts/ide/stores/getters.js create mode 100644 app/assets/javascripts/ide/stores/index.js create mode 100644 app/assets/javascripts/ide/stores/modules/commit/actions.js create mode 100644 app/assets/javascripts/ide/stores/modules/commit/constants.js create mode 100644 app/assets/javascripts/ide/stores/modules/commit/getters.js create mode 100644 app/assets/javascripts/ide/stores/modules/commit/index.js create mode 100644 app/assets/javascripts/ide/stores/modules/commit/mutation_types.js create mode 100644 app/assets/javascripts/ide/stores/modules/commit/mutations.js create mode 100644 app/assets/javascripts/ide/stores/modules/commit/state.js create mode 100644 app/assets/javascripts/ide/stores/mutation_types.js create mode 100644 app/assets/javascripts/ide/stores/mutations.js create mode 100644 app/assets/javascripts/ide/stores/mutations/branch.js create mode 100644 app/assets/javascripts/ide/stores/mutations/file.js create mode 100644 app/assets/javascripts/ide/stores/mutations/merge_request.js create mode 100644 app/assets/javascripts/ide/stores/mutations/project.js create mode 100644 app/assets/javascripts/ide/stores/mutations/tree.js create mode 100644 app/assets/javascripts/ide/stores/state.js create mode 100644 app/assets/javascripts/ide/stores/utils.js create mode 100644 app/assets/javascripts/ide/stores/workers/files_decorator_worker.js create mode 100644 app/assets/javascripts/monitoring/components/graph/axis.vue create mode 100644 app/assets/javascripts/monitoring/components/graph/track_info.vue create mode 100644 app/assets/javascripts/monitoring/components/graph/track_line.vue create mode 100644 app/assets/javascripts/pages/admin/application_settings/index.js create mode 100644 app/assets/javascripts/pages/groups/settings/badges/index.js rename app/assets/javascripts/pages/{ => projects}/ci/lints/ci_lint_editor.js (100%) rename app/assets/javascripts/pages/{ => projects}/ci/lints/new/index.js (100%) rename app/assets/javascripts/pages/{ => projects}/ci/lints/show/index.js (100%) create mode 100644 app/assets/javascripts/pages/projects/settings/badges/index/index.js create mode 100644 app/assets/javascripts/pages/projects/settings/repository/create_deploy_token/index.js create mode 100644 app/assets/javascripts/pages/projects/settings/repository/form.js create mode 100644 app/assets/javascripts/pages/shared/mount_badge_settings.js delete mode 100644 app/assets/javascripts/performance_bar.js create mode 100644 app/assets/javascripts/performance_bar/components/detailed_metric.vue create mode 100644 app/assets/javascripts/performance_bar/components/performance_bar_app.vue create mode 100644 app/assets/javascripts/performance_bar/components/request_selector.vue create mode 100644 app/assets/javascripts/performance_bar/components/simple_metric.vue create mode 100644 app/assets/javascripts/performance_bar/components/upstream_performance_bar.vue create mode 100644 app/assets/javascripts/performance_bar/index.js create mode 100644 app/assets/javascripts/performance_bar/services/performance_bar_service.js create mode 100644 app/assets/javascripts/performance_bar/stores/performance_bar_store.js create mode 100644 app/assets/javascripts/profile/account/components/update_username.vue delete mode 100644 app/assets/javascripts/sidebar/components/assignees/assignee_title.js create mode 100644 app/assets/javascripts/sidebar/components/assignees/assignee_title.vue delete mode 100644 app/assets/javascripts/sidebar/components/time_tracking/collapsed_state.js create mode 100644 app/assets/javascripts/sidebar/components/time_tracking/collapsed_state.vue rename app/assets/javascripts/sidebar/components/time_tracking/{comparison_pane.js => comparison_pane.vue} (53%) create mode 100644 app/assets/javascripts/vue_merge_request_widget/components/deployment.vue rename app/assets/javascripts/vue_merge_request_widget/components/{mr_widget_memory_usage.js => memory_usage.vue} (61%) delete mode 100644 app/assets/javascripts/vue_merge_request_widget/components/mr_widget_deployment.js create mode 100644 app/assets/javascripts/vue_merge_request_widget/components/source_branch_removal_status.vue delete mode 100644 app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_nothing_to_merge.js delete mode 100644 app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_sha_mismatch.js delete mode 100644 app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_unresolved_discussions.js create mode 100644 app/assets/javascripts/vue_merge_request_widget/components/states/nothing_to_merge.vue create mode 100644 app/assets/javascripts/vue_merge_request_widget/components/states/sha_mismatch.vue create mode 100644 app/assets/javascripts/vue_merge_request_widget/components/states/unresolved_discussions.vue create mode 100644 app/assets/javascripts/vue_shared/components/content_viewer/content_viewer.vue create mode 100644 app/assets/javascripts/vue_shared/components/content_viewer/lib/viewer_utils.js create mode 100644 app/assets/javascripts/vue_shared/components/content_viewer/viewers/download_viewer.vue create mode 100644 app/assets/javascripts/vue_shared/components/content_viewer/viewers/image_viewer.vue create mode 100644 app/assets/javascripts/vue_shared/components/content_viewer/viewers/markdown_viewer.vue rename app/assets/javascripts/vue_shared/components/{modal.vue => deprecated_modal.vue} (98%) rename app/assets/javascripts/vue_shared/components/{memory_graph.js => memory_graph.vue} (87%) delete mode 100644 app/assets/stylesheets/pages/lint.scss create mode 100644 app/assets/stylesheets/pages/pages.scss create mode 100644 app/assets/stylesheets/pages/repo.scss.orig create mode 100644 app/controllers/concerns/checks_collaboration.rb create mode 100644 app/controllers/concerns/send_file_upload.rb create mode 100644 app/controllers/groups/settings/badges_controller.rb create mode 100644 app/controllers/ide_controller.rb create mode 100644 app/controllers/projects/ci/lints_controller.rb create mode 100644 app/controllers/projects/deploy_tokens_controller.rb create mode 100644 app/controllers/projects/settings/badges_controller.rb create mode 100644 app/helpers/deploy_tokens_helper.rb create mode 100644 app/models/ci/build_metadata.rb create mode 100644 app/models/concerns/atomic_internal_id.rb create mode 100644 app/models/concerns/chronic_duration_attribute.rb rename app/models/concerns/{internal_id.rb => nonatomic_internal_id.rb} (94%) delete mode 100644 app/models/cycle_analytics/summary.rb create mode 100644 app/models/deploy_token.rb create mode 100644 app/models/internal_id.rb create mode 100644 app/models/project_deploy_token.rb create mode 100644 app/policies/deploy_token_policy.rb create mode 100644 app/policies/project_policy/class_methods.rb create mode 100644 app/policies/protected_branch_policy.rb create mode 100644 app/presenters/ci/build_metadata_presenter.rb create mode 100644 app/serializers/build_metadata_entity.rb delete mode 100644 app/serializers/note_serializer.rb create mode 100644 app/serializers/project_note_entity.rb create mode 100644 app/serializers/project_note_serializer.rb delete mode 100644 app/services/ci/create_pipeline_stages_service.rb create mode 100644 app/services/deploy_tokens/create_service.rb delete mode 100644 app/services/lfs/file_modification_handler.rb create mode 100644 app/services/lfs/file_transformer.rb create mode 100644 app/services/projects/base_move_relations_service.rb create mode 100644 app/services/projects/move_access_service.rb create mode 100644 app/services/projects/move_deploy_keys_projects_service.rb create mode 100644 app/services/projects/move_forks_service.rb create mode 100644 app/services/projects/move_lfs_objects_projects_service.rb create mode 100644 app/services/projects/move_notification_settings_service.rb create mode 100644 app/services/projects/move_project_authorizations_service.rb create mode 100644 app/services/projects/move_project_group_links_service.rb create mode 100644 app/services/projects/move_project_members_service.rb create mode 100644 app/services/projects/move_users_star_projects_service.rb create mode 100644 app/services/projects/overwrite_project_service.rb create mode 100644 app/services/protected_branches/destroy_service.rb create mode 100644 app/services/protected_tags/destroy_service.rb create mode 100644 app/uploaders/object_storage.rb create mode 100644 app/validators/certificate_fingerprint_validator.rb create mode 100644 app/validators/top_level_group_validator.rb create mode 100644 app/views/admin/application_settings/_abuse.html.haml create mode 100644 app/views/admin/application_settings/_account_and_limit.html.haml create mode 100644 app/views/admin/application_settings/_background_jobs.html.haml create mode 100644 app/views/admin/application_settings/_ci_cd.html.haml create mode 100644 app/views/admin/application_settings/_email.html.haml delete mode 100644 app/views/admin/application_settings/_form.html.haml create mode 100644 app/views/admin/application_settings/_gitaly.html.haml create mode 100644 app/views/admin/application_settings/_help_page.html.haml create mode 100644 app/views/admin/application_settings/_influx.html.haml create mode 100644 app/views/admin/application_settings/_ip_limits.html.haml create mode 100644 app/views/admin/application_settings/_koding.html.haml create mode 100644 app/views/admin/application_settings/_logging.html.haml create mode 100644 app/views/admin/application_settings/_outbound.html.haml create mode 100644 app/views/admin/application_settings/_pages.html.haml create mode 100644 app/views/admin/application_settings/_performance.html.haml create mode 100644 app/views/admin/application_settings/_performance_bar.html.haml create mode 100644 app/views/admin/application_settings/_plantuml.html.haml create mode 100644 app/views/admin/application_settings/_prometheus.html.haml create mode 100644 app/views/admin/application_settings/_realtime.html.haml create mode 100644 app/views/admin/application_settings/_registry.html.haml create mode 100644 app/views/admin/application_settings/_repository_check.html.haml create mode 100644 app/views/admin/application_settings/_repository_storage.html.haml create mode 100644 app/views/admin/application_settings/_signin.html.haml create mode 100644 app/views/admin/application_settings/_signup.html.haml create mode 100644 app/views/admin/application_settings/_spam.html.haml create mode 100644 app/views/admin/application_settings/_terminal.html.haml create mode 100644 app/views/admin/application_settings/_usage.html.haml create mode 100644 app/views/admin/application_settings/_visibility_and_access.html.haml create mode 100644 app/views/groups/settings/badges/index.html.haml create mode 100644 app/views/ide/index.html.haml create mode 100644 app/views/layouts/header/_read_only_banner.html.haml create mode 100644 app/views/notify/push_to_merge_request_email.html.haml create mode 100644 app/views/notify/push_to_merge_request_email.text.haml create mode 100644 app/views/peek/_bar.html.haml create mode 100644 app/views/peek/views/_gc.html.haml delete mode 100644 app/views/peek/views/_gitaly.html.haml delete mode 100644 app/views/peek/views/_host.html.haml delete mode 100644 app/views/peek/views/_mysql2.html.haml delete mode 100644 app/views/peek/views/_pg.html.haml delete mode 100644 app/views/peek/views/_rblineprof.html.haml create mode 100644 app/views/peek/views/_redis.html.haml create mode 100644 app/views/peek/views/_sidekiq.html.haml delete mode 100644 app/views/peek/views/_sql.html.haml rename app/views/{ => projects}/ci/lints/_create.html.haml (100%) create mode 100644 app/views/projects/ci/lints/show.html.haml create mode 100644 app/views/projects/deploy_tokens/_form.html.haml create mode 100644 app/views/projects/deploy_tokens/_index.html.haml create mode 100644 app/views/projects/deploy_tokens/_new_deploy_token.html.haml create mode 100644 app/views/projects/deploy_tokens/_revoke_modal.html.haml create mode 100644 app/views/projects/deploy_tokens/_table.html.haml create mode 100644 app/views/projects/jobs/_empty_states.html.haml create mode 100644 app/views/projects/pages/_https_only.html.haml create mode 100644 app/views/projects/settings/badges/index.html.haml rename app/views/projects/{pipelines_settings => settings/ci_cd}/_badge.html.haml (100%) rename app/views/projects/{pipelines_settings/_show.html.haml => settings/ci_cd/_form.html.haml} (93%) create mode 100644 app/views/shared/badges/_badge_settings.html.haml create mode 100644 app/views/shared/dashboard/_no_filter_selected.html.haml create mode 100644 app/workers/concerns/object_storage_queue.rb create mode 100644 app/workers/object_storage/background_move_worker.rb create mode 100644 app/workers/object_storage/migrate_uploads_worker.rb create mode 100644 app/workers/object_storage_upload_worker.rb create mode 100755 bin/update delete mode 100644 changelogs/unreleased-ee/39118-dynamic-pipeline-variables-fe.yml delete mode 100644 changelogs/unreleased-ee/4378-fix-cluster-js-not-running-on-update-page.yml delete mode 100644 changelogs/unreleased-ee/bvl-external-policy-classification.yml rename config/initializers/{fast_gettext.rb => 9_fast_gettext.rb} (100%) create mode 100644 config/initializers/application_controller_renderer.rb create mode 100644 config/initializers/ar_native_database_types.rb create mode 100644 config/initializers/artifacts_direct_upload_support.rb create mode 100644 config/initializers/fog_google_https_private_urls.rb create mode 100644 config/initializers/new_framework_defaults.rb create mode 100644 config/spring.rb delete mode 100644 config/svg.config.js create mode 100644 db/fixtures/development/22_labeled_issues_seed.rb create mode 100644 db/migrate/20170601163708_add_artifacts_store_to_ci_build.rb create mode 100644 db/migrate/20170825015534_add_file_store_to_lfs_objects.rb create mode 100644 db/migrate/20170918072949_add_file_store_job_artifacts.rb create mode 100644 db/migrate/20171214144320_add_store_column_to_uploads.rb create mode 100644 db/migrate/20180102220145_add_pages_https_only_to_projects.rb create mode 100644 db/migrate/20180109183319_change_default_value_for_pages_https_only.rb create mode 100644 db/migrate/20180209165249_add_closed_by_to_issues.rb create mode 100644 db/migrate/20180219153455_add_maximum_timeout_to_ci_runners.rb create mode 100644 db/migrate/20180301010859_create_ci_builds_metadata_table.rb create mode 100644 db/migrate/20180305095250_create_internal_ids_table.rb create mode 100644 db/migrate/20180309121820_reschedule_commits_count_for_merge_request_diff.rb create mode 100644 db/migrate/20180319190020_create_deploy_tokens.rb create mode 100644 db/migrate/20180323150945_add_push_to_merge_request_to_notification_settings.rb create mode 100644 db/migrate/20180327101207_remove_index_from_events_table.rb create mode 100644 db/migrate/20180405142733_create_project_deploy_tokens.rb create mode 100644 db/migrate/20180418053107_add_index_to_ci_job_artifacts_file_store.rb create mode 100644 db/post_migrate/20180305100050_remove_permanent_from_redirect_routes.rb create mode 100644 db/post_migrate/20180306164012_add_path_index_to_redirect_routes.rb create mode 100644 db/post_migrate/20180405101928_reschedule_builds_stages_migration.rb create mode 100644 doc/administration/auth/jwt.md create mode 100644 doc/administration/job_traces.md create mode 100644 doc/administration/monitoring/performance/img/performance_bar_gitaly_calls.png create mode 100644 doc/administration/raketasks/uploads/migrate.md create mode 100644 doc/administration/uploads.md create mode 100644 doc/ci/caching/img/clear_runners_cache.png create mode 100644 doc/ci/examples/container_scanning.md create mode 100644 doc/ci/examples/devops_and_game_dev_with_gitlab_ci_cd/img/aws_config_window.png create mode 100644 doc/ci/examples/devops_and_game_dev_with_gitlab_ci_cd/img/gitlab_config.png create mode 100644 doc/ci/examples/devops_and_game_dev_with_gitlab_ci_cd/img/test_pipeline_pass.png create mode 100644 doc/ci/examples/devops_and_game_dev_with_gitlab_ci_cd/index.md create mode 100644 doc/ci/img/job_failure_reason.png create mode 100644 doc/development/new_fe_guide/style/prettier.md create mode 100644 doc/img/devops_lifecycle.png create mode 100644 doc/update/10.6-to-10.7.md create mode 100644 doc/user/admin_area/settings/email.md create mode 100644 doc/user/gitlab_com/index.md create mode 100644 doc/user/project/badges.md create mode 100644 doc/user/project/deploy_tokens/img/deploy_tokens.png create mode 100644 doc/user/project/deploy_tokens/index.md create mode 100644 doc/user/project/img/project_overview_badges.png delete mode 100644 doc/user/project/integrations/img/jira_workflow_screenshot.png create mode 100644 doc/user/project/merge_requests/img/remove_source_branch_status.png create mode 100644 doc/user/project/repository/img/jupyter_notebook.png create mode 100644 doc/user/project/web_ide/img/commit_changes.png create mode 100644 doc/user/project/web_ide/img/enable_web_ide.png create mode 100644 doc/user/project/web_ide/img/open_web_ide.png create mode 100644 doc/user/project/web_ide/index.md delete mode 100644 features/groups.feature delete mode 100644 features/project/active_tab.feature delete mode 100644 features/project/fork.feature delete mode 100644 features/project/graph.feature delete mode 100644 features/project/issues/issues.feature delete mode 100644 features/project/issues/labels.feature delete mode 100644 features/project/redirects.feature delete mode 100644 features/steps/groups.rb delete mode 100644 features/steps/project/active_tab.rb delete mode 100644 features/steps/project/fork.rb delete mode 100644 features/steps/project/graph.rb delete mode 100644 features/steps/project/issues/labels.rb delete mode 100644 features/steps/project/redirects.rb create mode 100644 lib/api/helpers/project_snapshots_helpers.rb create mode 100644 lib/api/helpers/projects_helpers.rb create mode 100644 lib/api/project_snapshots.rb create mode 100644 lib/backup/helper.rb create mode 100644 lib/banzai/filter/commit_trailers_filter.rb create mode 100644 lib/banzai/pipeline/commit_description_pipeline.rb create mode 100644 lib/banzai/render_context.rb create mode 100644 lib/declarative_policy/delegate_dsl.rb delete mode 100644 lib/declarative_policy/dsl.rb create mode 100644 lib/declarative_policy/policy_dsl.rb create mode 100644 lib/declarative_policy/rule_dsl.rb create mode 100644 lib/forever.rb create mode 100644 lib/gitlab/auth/ldap/ldap_connection_error.rb create mode 100644 lib/gitlab/base_doorkeeper_controller.rb create mode 100644 lib/gitlab/ci/build/policy/variables.rb create mode 100644 lib/gitlab/ci/pipeline/chain/populate.rb create mode 100644 lib/gitlab/ci/pipeline/seed/base.rb create mode 100644 lib/gitlab/ci/pipeline/seed/build.rb create mode 100644 lib/gitlab/ci/pipeline/seed/stage.rb delete mode 100644 lib/gitlab/ci/stage/seed.rb create mode 100644 lib/gitlab/ci/status/build/canceled.rb create mode 100644 lib/gitlab/ci/status/build/created.rb create mode 100644 lib/gitlab/ci/status/build/erased.rb create mode 100644 lib/gitlab/ci/status/build/failed.rb create mode 100644 lib/gitlab/ci/status/build/manual.rb create mode 100644 lib/gitlab/ci/status/build/pending.rb create mode 100644 lib/gitlab/ci/status/build/retried.rb create mode 100644 lib/gitlab/ci/status/build/skipped.rb create mode 100644 lib/gitlab/ci/trace/http_io.rb create mode 100644 lib/gitlab/ci/variables/collection.rb create mode 100644 lib/gitlab/ci/variables/collection/item.rb rename lib/gitlab/git/{env.rb => hook_env.rb} (64%) create mode 100644 lib/gitlab/gitaly_client/storage_settings.rb create mode 100644 lib/gitlab/import_export/after_export_strategies/base_after_export_strategy.rb create mode 100644 lib/gitlab/import_export/after_export_strategies/download_notification_strategy.rb create mode 100644 lib/gitlab/import_export/after_export_strategies/web_upload_strategy.rb create mode 100644 lib/gitlab/import_export/after_export_strategy_builder.rb create mode 100644 lib/gitlab/import_export/lfs_restorer.rb create mode 100644 lib/gitlab/import_export/lfs_saver.rb create mode 100644 lib/gitlab/import_export/statistics_restorer.rb create mode 100644 lib/gitlab/omniauth_initializer.rb create mode 100644 lib/gitlab/sidekiq_logging/json_formatter.rb create mode 100644 lib/gitlab/sidekiq_logging/structured_logger.rb create mode 100644 lib/gitlab/slash_commands/issue_move.rb create mode 100644 lib/gitlab/slash_commands/presenters/issue_move.rb create mode 100644 lib/gitlab/verify/job_artifacts.rb create mode 100644 lib/omni_auth/strategies/jwt.rb create mode 100644 lib/peek/views/host.rb create mode 100644 lib/tasks/gitlab/artifacts/check.rake create mode 100644 lib/tasks/gitlab/artifacts/migrate.rake create mode 100644 lib/tasks/gitlab/exclusive_lease.rake create mode 100644 lib/tasks/gitlab/lfs/migrate.rake create mode 100644 lib/tasks/gitlab/uploads/migrate.rake delete mode 100644 qa/qa/page/admin/settings.rb create mode 100644 qa/qa/page/admin/settings/main.rb create mode 100644 qa/qa/page/admin/settings/repository_storage.rb create mode 100644 qa/qa/page/settings/common.rb create mode 100644 rubocop/cop/rspec/factories_in_migration_specs.rb delete mode 100755 scripts/codequality create mode 100644 scripts/frontend/frontend_script_utils.js create mode 100644 scripts/frontend/prettier.js create mode 100644 spec/controllers/concerns/checks_collaboration_spec.rb create mode 100644 spec/controllers/concerns/send_file_upload_spec.rb create mode 100644 spec/controllers/projects/ci/lints_controller_spec.rb create mode 100644 spec/factories/deploy_tokens.rb create mode 100644 spec/factories/internal_ids.rb create mode 100644 spec/factories/project_deploy_tokens.rb create mode 100644 spec/factories/users_star_projects.rb create mode 100644 spec/features/groups/settings/group_badges_spec.rb create mode 100644 spec/features/groups/user_browse_projects_group_page_spec.rb create mode 100644 spec/features/ide_spec.rb create mode 100644 spec/features/labels_hierarchy_spec.rb create mode 100644 spec/features/projects/actve_tabs_spec.rb create mode 100644 spec/features/projects/blobs/user_creates_new_blob_in_new_project_spec.rb rename spec/features/{ci_lint_spec.rb => projects/ci/lint_spec.rb} (91%) create mode 100644 spec/features/projects/graph_spec.rb create mode 100644 spec/features/projects/hook_logs/user_reads_log_spec.rb create mode 100644 spec/features/projects/issues/user_comments_on_issue_spec.rb create mode 100644 spec/features/projects/issues/user_creates_issue_spec.rb create mode 100644 spec/features/projects/issues/user_edits_issue_spec.rb create mode 100644 spec/features/projects/issues/user_sorts_issues_spec.rb create mode 100644 spec/features/projects/issues/user_toggles_subscription_spec.rb create mode 100644 spec/features/projects/issues/user_views_issue_spec.rb create mode 100644 spec/features/projects/labels/user_creates_labels_spec.rb create mode 100644 spec/features/projects/labels/user_edits_labels_spec.rb create mode 100644 spec/features/projects/labels/user_removes_labels_spec.rb create mode 100644 spec/features/projects/labels/user_views_labels_spec.rb create mode 100644 spec/features/projects/redirects_spec.rb create mode 100644 spec/features/projects/settings/project_badges_spec.rb create mode 100644 spec/features/projects/show/user_sees_collaboration_links_spec.rb create mode 100644 spec/features/projects/tree/create_directory_spec.rb create mode 100644 spec/features/projects/tree/create_file_spec.rb create mode 100644 spec/features/projects/tree/upload_file_spec.rb create mode 100644 spec/features/projects/user_views_empty_project_spec.rb create mode 100644 spec/features/read_only_spec.rb create mode 100644 spec/features/user_sorts_things_spec.rb create mode 100644 spec/fixtures/big-image.png create mode 100644 spec/fixtures/exported-project.gz create mode 100644 spec/initializers/artifacts_direct_upload_support_spec.rb create mode 100644 spec/initializers/fog_google_https_private_urls_spec.rb create mode 100644 spec/javascripts/badges/components/badge_form_spec.js create mode 100644 spec/javascripts/badges/components/badge_list_row_spec.js create mode 100644 spec/javascripts/badges/components/badge_list_spec.js create mode 100644 spec/javascripts/badges/components/badge_settings_spec.js create mode 100644 spec/javascripts/badges/components/badge_spec.js create mode 100644 spec/javascripts/badges/dummy_badge.js create mode 100644 spec/javascripts/badges/store/actions_spec.js create mode 100644 spec/javascripts/badges/store/mutations_spec.js create mode 100644 spec/javascripts/fixtures/one_white_pixel.png create mode 100644 spec/javascripts/helpers/vue_component_helper.js create mode 100644 spec/javascripts/ide/components/changed_file_icon_spec.js create mode 100644 spec/javascripts/ide/components/commit_sidebar/actions_spec.js create mode 100644 spec/javascripts/ide/components/commit_sidebar/list_collapsed_spec.js create mode 100644 spec/javascripts/ide/components/commit_sidebar/list_item_spec.js create mode 100644 spec/javascripts/ide/components/commit_sidebar/list_spec.js create mode 100644 spec/javascripts/ide/components/commit_sidebar/radio_group_spec.js create mode 100644 spec/javascripts/ide/components/ide_context_bar_spec.js create mode 100644 spec/javascripts/ide/components/ide_external_links_spec.js create mode 100644 spec/javascripts/ide/components/ide_file_buttons_spec.js create mode 100644 spec/javascripts/ide/components/ide_project_tree_spec.js create mode 100644 spec/javascripts/ide/components/ide_repo_tree_spec.js create mode 100644 spec/javascripts/ide/components/ide_side_bar_spec.js create mode 100644 spec/javascripts/ide/components/ide_spec.js create mode 100644 spec/javascripts/ide/components/new_dropdown/index_spec.js create mode 100644 spec/javascripts/ide/components/new_dropdown/modal_spec.js create mode 100644 spec/javascripts/ide/components/new_dropdown/upload_spec.js create mode 100644 spec/javascripts/ide/components/repo_commit_section_spec.js create mode 100644 spec/javascripts/ide/components/repo_editor_spec.js create mode 100644 spec/javascripts/ide/components/repo_file_spec.js create mode 100644 spec/javascripts/ide/components/repo_loading_file_spec.js create mode 100644 spec/javascripts/ide/components/repo_tab_spec.js create mode 100644 spec/javascripts/ide/components/repo_tabs_spec.js create mode 100644 spec/javascripts/ide/helpers.js create mode 100644 spec/javascripts/ide/lib/common/disposable_spec.js create mode 100644 spec/javascripts/ide/lib/common/model_manager_spec.js create mode 100644 spec/javascripts/ide/lib/common/model_spec.js create mode 100644 spec/javascripts/ide/lib/decorations/controller_spec.js create mode 100644 spec/javascripts/ide/lib/diff/controller_spec.js create mode 100644 spec/javascripts/ide/lib/diff/diff_spec.js create mode 100644 spec/javascripts/ide/lib/editor_options_spec.js create mode 100644 spec/javascripts/ide/lib/editor_spec.js create mode 100644 spec/javascripts/ide/monaco_loader_spec.js create mode 100644 spec/javascripts/ide/stores/actions/file_spec.js create mode 100644 spec/javascripts/ide/stores/actions/merge_request_spec.js create mode 100644 spec/javascripts/ide/stores/actions/tree_spec.js create mode 100644 spec/javascripts/ide/stores/actions_spec.js create mode 100644 spec/javascripts/ide/stores/getters_spec.js create mode 100644 spec/javascripts/ide/stores/modules/commit/actions_spec.js create mode 100644 spec/javascripts/ide/stores/modules/commit/getters_spec.js create mode 100644 spec/javascripts/ide/stores/modules/commit/mutations_spec.js create mode 100644 spec/javascripts/ide/stores/mutations/branch_spec.js create mode 100644 spec/javascripts/ide/stores/mutations/file_spec.js create mode 100644 spec/javascripts/ide/stores/mutations/merge_request_spec.js create mode 100644 spec/javascripts/ide/stores/mutations/tree_spec.js create mode 100644 spec/javascripts/ide/stores/mutations_spec.js create mode 100644 spec/javascripts/ide/stores/utils_spec.js create mode 100644 spec/javascripts/matchers.js create mode 100644 spec/javascripts/monitoring/graph/axis_spec.js create mode 100644 spec/javascripts/monitoring/graph/track_info_spec.js create mode 100644 spec/javascripts/monitoring/graph/track_line_spec.js create mode 100644 spec/javascripts/performance_bar/components/detailed_metric_spec.js create mode 100644 spec/javascripts/performance_bar/components/performance_bar_app_spec.js create mode 100644 spec/javascripts/performance_bar/components/request_selector_spec.js create mode 100644 spec/javascripts/performance_bar/components/simple_metric_spec.js create mode 100644 spec/javascripts/profile/account/components/update_username_spec.js create mode 100644 spec/javascripts/test_constants.js create mode 100644 spec/javascripts/vue_mr_widget/components/deployment_spec.js delete mode 100644 spec/javascripts/vue_mr_widget/components/mr_widget_deployment_spec.js create mode 100644 spec/javascripts/vue_shared/components/content_viewer/content_viewer_spec.js rename spec/javascripts/vue_shared/components/{modal_spec.js => deprecated_modal_spec.js} (90%) create mode 100644 spec/lib/backup/files_spec.rb create mode 100644 spec/lib/banzai/filter/commit_trailers_filter_spec.rb create mode 100644 spec/lib/banzai/render_context_spec.rb create mode 100644 spec/lib/forever_spec.rb create mode 100644 spec/lib/gitlab/ci/build/policy/variables_spec.rb create mode 100644 spec/lib/gitlab/ci/pipeline/chain/populate_spec.rb create mode 100644 spec/lib/gitlab/ci/pipeline/seed/build_spec.rb create mode 100644 spec/lib/gitlab/ci/pipeline/seed/stage_spec.rb delete mode 100644 spec/lib/gitlab/ci/stage/seed_spec.rb create mode 100644 spec/lib/gitlab/ci/status/build/canceled_spec.rb create mode 100644 spec/lib/gitlab/ci/status/build/created_spec.rb create mode 100644 spec/lib/gitlab/ci/status/build/erased_spec.rb create mode 100644 spec/lib/gitlab/ci/status/build/failed_spec.rb create mode 100644 spec/lib/gitlab/ci/status/build/manual_spec.rb create mode 100644 spec/lib/gitlab/ci/status/build/pending_spec.rb create mode 100644 spec/lib/gitlab/ci/status/build/retried_spec.rb create mode 100644 spec/lib/gitlab/ci/status/build/skipped_spec.rb create mode 100644 spec/lib/gitlab/ci/trace/http_io_spec.rb create mode 100644 spec/lib/gitlab/ci/variables/collection/item_spec.rb create mode 100644 spec/lib/gitlab/ci/variables/collection_spec.rb rename spec/lib/gitlab/git/{env_spec.rb => hook_env_spec.rb} (54%) create mode 100644 spec/lib/gitlab/import_export/after_export_strategies/base_after_export_strategy_spec.rb create mode 100644 spec/lib/gitlab/import_export/after_export_strategies/web_upload_strategy_spec.rb create mode 100644 spec/lib/gitlab/import_export/after_export_strategy_builder_spec.rb create mode 100644 spec/lib/gitlab/import_export/importer_spec.rb create mode 100644 spec/lib/gitlab/import_export/lfs_restorer_spec.rb create mode 100644 spec/lib/gitlab/import_export/lfs_saver_spec.rb create mode 100644 spec/lib/gitlab/omniauth_initializer_spec.rb create mode 100644 spec/lib/gitlab/sidekiq_logging/json_formatter_spec.rb create mode 100644 spec/lib/gitlab/sidekiq_logging/structured_logger_spec.rb create mode 100644 spec/lib/gitlab/slash_commands/issue_move_spec.rb create mode 100644 spec/lib/gitlab/slash_commands/presenters/issue_move_spec.rb create mode 100644 spec/lib/gitlab/verify/job_artifacts_spec.rb create mode 100644 spec/lib/omni_auth/strategies/jwt_spec.rb create mode 100644 spec/lib/uploaded_file_spec.rb create mode 100644 spec/mailers/previews/email_rejection_mailer_preview.rb create mode 100644 spec/mailers/previews/repository_check_mailer_preview.rb rename spec/migrations/{schedule_build_stage_migration_spec.rb => reschedule_builds_stages_migration_spec.rb} (77%) create mode 100644 spec/migrations/reschedule_commits_count_for_merge_request_diff_spec.rb create mode 100644 spec/models/ci/build_metadata_spec.rb create mode 100644 spec/models/concerns/chronic_duration_attribute_spec.rb create mode 100644 spec/models/deploy_token_spec.rb create mode 100644 spec/models/internal_id_spec.rb create mode 100644 spec/models/lfs_object_spec.rb create mode 100644 spec/models/project_deploy_token_spec.rb create mode 100644 spec/policies/deploy_token_policy_spec.rb create mode 100644 spec/policies/protected_branch_policy_spec.rb create mode 100644 spec/requests/api/project_snapshots_spec.rb create mode 100644 spec/rubocop/cop/rspec/factories_in_migration_specs_spec.rb create mode 100644 spec/serializers/project_note_entity_spec.rb create mode 100644 spec/services/deploy_tokens/create_service_spec.rb create mode 100644 spec/services/lfs/file_transformer_spec.rb create mode 100644 spec/services/projects/import_export/export_service_spec.rb create mode 100644 spec/services/projects/move_access_service_spec.rb create mode 100644 spec/services/projects/move_deploy_keys_projects_service_spec.rb create mode 100644 spec/services/projects/move_forks_service_spec.rb create mode 100644 spec/services/projects/move_lfs_objects_projects_service_spec.rb create mode 100644 spec/services/projects/move_notification_settings_service_spec.rb create mode 100644 spec/services/projects/move_project_authorizations_service_spec.rb create mode 100644 spec/services/projects/move_project_group_links_service_spec.rb create mode 100644 spec/services/projects/move_project_members_service_spec.rb create mode 100644 spec/services/projects/move_users_star_projects_service_spec.rb create mode 100644 spec/services/projects/overwrite_project_service_spec.rb create mode 100644 spec/services/protected_branches/destroy_service_spec.rb create mode 100644 spec/services/protected_tags/destroy_service_spec.rb create mode 100644 spec/support/commit_trailers_spec_helper.rb create mode 100644 spec/support/helpers/expect_offense.rb create mode 100644 spec/support/helpers/features/notes_helpers.rb create mode 100644 spec/support/helpers/features/sorting_helpers.rb create mode 100644 spec/support/http_io/http_io_helpers.rb create mode 100644 spec/support/issuables_requiring_filter_shared_examples.rb create mode 100644 spec/support/matchers/have_emoji.rb create mode 100644 spec/support/matchers/issuable_matchers.rb delete mode 100644 spec/support/quick_actions_helpers.rb create mode 100644 spec/support/shared_examples/models/atomic_internal_id_spec.rb create mode 100644 spec/support/shared_examples/serializers/note_entity_examples.rb create mode 100644 spec/support/shared_examples/uploaders/object_storage_shared_examples.rb delete mode 100644 spec/support/sorting_helper.rb create mode 100644 spec/support/stub_object_storage.rb create mode 100644 spec/tasks/gitlab/artifacts/check_rake_spec.rb create mode 100644 spec/tasks/gitlab/artifacts/migrate_rake_spec.rb create mode 100644 spec/tasks/gitlab/lfs/migrate_rake_spec.rb create mode 100644 spec/tasks/gitlab/uploads/migrate_rake_spec.rb create mode 100644 spec/uploaders/object_storage_spec.rb create mode 100644 spec/uploaders/workers/object_storage/background_move_worker_spec.rb create mode 100644 spec/uploaders/workers/object_storage/migrate_uploads_worker_spec.rb rename spec/views/{ => projects}/ci/lints/show.html.haml_spec.rb (83%) create mode 100644 spec/views/projects/diffs/_stats.html.haml_spec.rb create mode 100644 spec/views/projects/services/_form.haml_spec.rb rename spec/views/projects/{pipelines_settings/_show.html.haml_spec.rb => settings/ci_cd/_form.html.haml_spec.rb} (97%) create mode 100644 spec/workers/object_storage_upload_worker_spec.rb create mode 100644 spec/workers/project_export_worker_spec.rb delete mode 100644 vendor/assets/javascripts/peek.js create mode 100644 vendor/gitignore/Godot.gitignore create mode 100644 vendor/gitlab-ci-yml/Pages/Gatsby.gitlab-ci.yml diff --git a/.babelrc b/.babelrc index b93bef72de..8cf07b7342 100644 --- a/.babelrc +++ b/.babelrc @@ -1,20 +1,20 @@ { - "presets": [ - ["latest", { "es2015": { "modules": false } }], - "stage-2" - ], + "presets": [["latest", { "es2015": { "modules": false } }], "stage-2"], "env": { "coverage": { "plugins": [ - ["istanbul", { - "exclude": [ - "spec/javascripts/**/*", - "app/assets/javascripts/locale/**/app.js" - ] - }], - ["transform-define", { - "process.env.BABEL_ENV": "coverage" - }] + [ + "istanbul", + { + "exclude": ["spec/javascripts/**/*", "app/assets/javascripts/locale/**/app.js"] + } + ], + [ + "transform-define", + { + "process.env.BABEL_ENV": "coverage" + } + ] ] } } diff --git a/.codeclimate.yml b/.codeclimate.yml index 216ecf43be..8699a903f2 100644 --- a/.codeclimate.yml +++ b/.codeclimate.yml @@ -10,12 +10,6 @@ engines: - javascript exclude_paths: - "lib/api/v3/*" - eslint: - enabled: true - channel: "eslint-4" - rubocop: - enabled: true - channel: "gitlab-rubocop-0-52-1" ratings: paths: - Gemfile.lock diff --git a/.eslintignore b/.eslintignore index 1623b99621..33a8186fad 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,11 +1,12 @@ +/app/assets/javascripts/locale/**/app.js +/config/ /builds/ /coverage/ /coverage-javascript/ /node_modules/ /public/ +/scripts/ /tmp/ /vendor/ karma.config.js webpack.config.js -svg.config.js -/app/assets/javascripts/locale/**/app.js diff --git a/.eslintrc b/.eslintrc index 8f9cdfb14a..3f187db0c0 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,6 +1,5 @@ { "env": { - "jquery": true, "browser": true, "es6": true }, @@ -36,15 +35,22 @@ "import/no-commonjs": "error", "no-multiple-empty-lines": ["error", { "max": 1 }], "promise/catch-or-return": "error", - "no-underscore-dangle": ["error", { "allow": ["__", "_links"]}], - "vue/html-self-closing": ["error", { - "html": { - "void": "always", - "normal": "never", - "component": "always" - }, - "svg": "always", - "math": "always" - }] + "no-underscore-dangle": ["error", { "allow": ["__", "_links"] }], + "no-mixed-operators": 0, + "space-before-function-paren": 0, + "curly": 0, + "arrow-parens": 0, + "vue/html-self-closing": [ + "error", + { + "html": { + "void": "always", + "normal": "never", + "component": "always" + }, + "svg": "always", + "math": "always" + } + ] } } diff --git a/.flayignore b/.flayignore index 87cb3507b0..3d69bb2c98 100644 --- a/.flayignore +++ b/.flayignore @@ -8,3 +8,4 @@ lib/gitlab/redis/*.rb lib/gitlab/gitaly_client/operation_service.rb lib/gitlab/background_migration/* app/models/project_services/kubernetes_service.rb +lib/gitlab/workhorse.rb diff --git a/.gitignore b/.gitignore index fa39ae01ff..e9ff0048c1 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,7 @@ eslint-report.html /.gitlab_shell_secret .idea +/.vscode/* /.rbenv-version .rbx/ /.ruby-gemset @@ -22,6 +23,9 @@ eslint-report.html /.yarn-cache /.byebug_history /Vagrantfile +/app/assets/images/icons.json +/app/assets/images/icons.svg +/app/assets/images/illustrations/ /app/assets/javascripts/locale/**/app.js /backups/* /config/aws.yml @@ -46,6 +50,7 @@ eslint-report.html /db/data.yml /doc/code/* /dump.rdb +/jsconfig.json /log/*.log* /node_modules/ /nohup.out diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index f3ebcb10fb..26e442ccea 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -78,6 +78,19 @@ stages: - mysql:5.7 - redis:alpine +.rails5-variables: &rails5-variables + script: + - export RAILS5=${RAILS5} + - export BUNDLE_GEMFILE=${BUNDLE_GEMFILE} + +.rails5: &rails5 + allow_failure: true + only: + - /rails5/ + variables: + BUNDLE_GEMFILE: "Gemfile.rails5" + RAILS5: "true" + # Skip all jobs except the ones that begin with 'docs/'. # Used for commits including ONLY documentation changes. # https://docs.gitlab.com/ce/development/writing_documentation.html#testing @@ -118,6 +131,7 @@ stages: <<: *dedicated-runner <<: *except-docs-and-qa <<: *pull-cache + <<: *rails5-variables stage: test script: - JOB_NAME=( $CI_JOB_NAME ) @@ -148,14 +162,23 @@ stages: <<: *rspec-metadata <<: *use-pg +.rspec-metadata-pg-rails5: &rspec-metadata-pg-rails5 + <<: *rspec-metadata-pg + <<: *rails5 + .rspec-metadata-mysql: &rspec-metadata-mysql <<: *rspec-metadata <<: *use-mysql +.rspec-metadata-mysql-rails5: &rspec-metadata-mysql-rails5 + <<: *rspec-metadata-mysql + <<: *rails5 + .spinach-metadata: &spinach-metadata <<: *dedicated-runner <<: *except-docs-and-qa <<: *pull-cache + <<: *rails5-variables stage: test script: - JOB_NAME=( $CI_JOB_NAME ) @@ -179,10 +202,18 @@ stages: <<: *spinach-metadata <<: *use-pg +.spinach-metadata-pg-rails5: &spinach-metadata-pg-rails5 + <<: *spinach-metadata-pg + <<: *rails5 + .spinach-metadata-mysql: &spinach-metadata-mysql <<: *spinach-metadata <<: *use-mysql +.spinach-metadata-mysql-rails5: &spinach-metadata-mysql-rails5 + <<: *spinach-metadata-mysql + <<: *rails5 + .only-canonical-masters: &only-canonical-masters only: - master@gitlab-org/gitlab-ce @@ -257,15 +288,25 @@ stages: ## # Trigger a package build in omnibus-gitlab repository # -package-qa: +package-and-qa: <<: *dedicated-runner image: ruby:2.4-alpine before_script: [] stage: build cache: {} when: manual + variables: + GIT_STRATEGY: none + retry: 0 + before_script: + # We need to download the script rather than clone the repo since the + # package-and-qa job will not be able to run when the branch gets + # deleted (when merging the MR). + - apk add --update openssl + - wget https://gitlab.com/$CI_PROJECT_PATH/raw/$CI_COMMIT_SHA/scripts/trigger-build-omnibus + - chmod 755 trigger-build-omnibus script: - - scripts/trigger-build-omnibus + - ./trigger-build-omnibus only: - //@gitlab-org/gitlab-ce - //@gitlab-org/gitlab-ee @@ -458,6 +499,70 @@ spinach-pg 1 2: *spinach-metadata-pg spinach-mysql 0 2: *spinach-metadata-mysql spinach-mysql 1 2: *spinach-metadata-mysql +rspec-pg-rails5 0 28: *rspec-metadata-pg-rails5 +rspec-pg-rails5 1 28: *rspec-metadata-pg-rails5 +rspec-pg-rails5 2 28: *rspec-metadata-pg-rails5 +rspec-pg-rails5 3 28: *rspec-metadata-pg-rails5 +rspec-pg-rails5 4 28: *rspec-metadata-pg-rails5 +rspec-pg-rails5 5 28: *rspec-metadata-pg-rails5 +rspec-pg-rails5 6 28: *rspec-metadata-pg-rails5 +rspec-pg-rails5 7 28: *rspec-metadata-pg-rails5 +rspec-pg-rails5 8 28: *rspec-metadata-pg-rails5 +rspec-pg-rails5 9 28: *rspec-metadata-pg-rails5 +rspec-pg-rails5 10 28: *rspec-metadata-pg-rails5 +rspec-pg-rails5 11 28: *rspec-metadata-pg-rails5 +rspec-pg-rails5 12 28: *rspec-metadata-pg-rails5 +rspec-pg-rails5 13 28: *rspec-metadata-pg-rails5 +rspec-pg-rails5 14 28: *rspec-metadata-pg-rails5 +rspec-pg-rails5 15 28: *rspec-metadata-pg-rails5 +rspec-pg-rails5 16 28: *rspec-metadata-pg-rails5 +rspec-pg-rails5 17 28: *rspec-metadata-pg-rails5 +rspec-pg-rails5 18 28: *rspec-metadata-pg-rails5 +rspec-pg-rails5 19 28: *rspec-metadata-pg-rails5 +rspec-pg-rails5 20 28: *rspec-metadata-pg-rails5 +rspec-pg-rails5 21 28: *rspec-metadata-pg-rails5 +rspec-pg-rails5 22 28: *rspec-metadata-pg-rails5 +rspec-pg-rails5 23 28: *rspec-metadata-pg-rails5 +rspec-pg-rails5 24 28: *rspec-metadata-pg-rails5 +rspec-pg-rails5 25 28: *rspec-metadata-pg-rails5 +rspec-pg-rails5 26 28: *rspec-metadata-pg-rails5 +rspec-pg-rails5 27 28: *rspec-metadata-pg-rails5 + +rspec-mysql-rails5 0 28: *rspec-metadata-mysql-rails5 +rspec-mysql-rails5 1 28: *rspec-metadata-mysql-rails5 +rspec-mysql-rails5 2 28: *rspec-metadata-mysql-rails5 +rspec-mysql-rails5 3 28: *rspec-metadata-mysql-rails5 +rspec-mysql-rails5 4 28: *rspec-metadata-mysql-rails5 +rspec-mysql-rails5 5 28: *rspec-metadata-mysql-rails5 +rspec-mysql-rails5 6 28: *rspec-metadata-mysql-rails5 +rspec-mysql-rails5 7 28: *rspec-metadata-mysql-rails5 +rspec-mysql-rails5 8 28: *rspec-metadata-mysql-rails5 +rspec-mysql-rails5 9 28: *rspec-metadata-mysql-rails5 +rspec-mysql-rails5 10 28: *rspec-metadata-mysql-rails5 +rspec-mysql-rails5 11 28: *rspec-metadata-mysql-rails5 +rspec-mysql-rails5 12 28: *rspec-metadata-mysql-rails5 +rspec-mysql-rails5 13 28: *rspec-metadata-mysql-rails5 +rspec-mysql-rails5 14 28: *rspec-metadata-mysql-rails5 +rspec-mysql-rails5 15 28: *rspec-metadata-mysql-rails5 +rspec-mysql-rails5 16 28: *rspec-metadata-mysql-rails5 +rspec-mysql-rails5 17 28: *rspec-metadata-mysql-rails5 +rspec-mysql-rails5 18 28: *rspec-metadata-mysql-rails5 +rspec-mysql-rails5 19 28: *rspec-metadata-mysql-rails5 +rspec-mysql-rails5 20 28: *rspec-metadata-mysql-rails5 +rspec-mysql-rails5 21 28: *rspec-metadata-mysql-rails5 +rspec-mysql-rails5 22 28: *rspec-metadata-mysql-rails5 +rspec-mysql-rails5 23 28: *rspec-metadata-mysql-rails5 +rspec-mysql-rails5 24 28: *rspec-metadata-mysql-rails5 +rspec-mysql-rails5 25 28: *rspec-metadata-mysql-rails5 +rspec-mysql-rails5 26 28: *rspec-metadata-mysql-rails5 +rspec-mysql-rails5 27 28: *rspec-metadata-mysql-rails5 + +spinach-pg-rails5 0 2: *spinach-metadata-pg-rails5 +spinach-pg-rails5 1 2: *spinach-metadata-pg-rails5 + +spinach-mysql-rails5 0 2: *spinach-metadata-mysql-rails5 +spinach-mysql-rails5 1 2: *spinach-metadata-mysql-rails5 + static-analysis: <<: *dedicated-no-docs-no-db-pull-cache-job dependencies: @@ -544,7 +649,7 @@ migration:path-mysql: .db-rollback: &db-rollback <<: *dedicated-no-docs-pull-cache-job script: - - bundle exec rake db:rollback STEP=119 + - bundle exec rake db:migrate VERSION=20170523121229 - bundle exec rake db:migrate db:rollback-pg: @@ -608,21 +713,23 @@ karma: codequality: <<: *dedicated-no-docs-no-db-pull-cache-job - image: docker:latest + image: docker:stable + allow_failure: true + # gitlab-org runners set `privileged: false` but we need to have it set to true + # since we're using Docker in Docker + tags: [] before_script: [] services: - docker:dind variables: SETUP_DB: "false" DOCKER_DRIVER: overlay2 - CODECLIMATE_FORMAT: json cache: {} dependencies: [] script: - - apk update && apk add jq - - ./scripts/codequality analyze -f json > raw_codeclimate.json || true - # The following line keeps only the fields used in the MR widget, reducing the JSON artifact size - - jq -c 'map({check_name,description,fingerprint,location})' raw_codeclimate.json > codeclimate.json + # Extract "MAJOR.MINOR" from CI_SERVER_VERSION and generate "MAJOR-MINOR-stable" for Security Products + - export SP_VERSION=$(echo "$CI_SERVER_VERSION" | sed 's/^\([0-9]*\)\.\([0-9]*\).*/\1-\2-stable/') + - docker run --env SOURCE_CODE="$PWD" --volume "$PWD":/code --volume /var/run/docker.sock:/var/run/docker.sock "registry.gitlab.com/gitlab-org/security-products/codequality:$SP_VERSION" /code artifacts: paths: [codeclimate.json] expire_in: 1 week @@ -655,7 +762,13 @@ qa:selectors: - bundle exec bin/qa Test::Sanity::Selectors coverage: - <<: *dedicated-no-docs-no-db-pull-cache-job + # Don't include dedicated-no-docs-no-db-pull-cache-job here since we need to + # download artifacts from all the rspec jobs instead of from setup-test-env only + <<: *dedicated-runner + <<: *except-docs-and-qa + <<: *pull-cache + variables: + SETUP_DB: "false" stage: post-test script: - bundle exec scripts/merge-simplecov diff --git a/.gitlab/merge_request_templates/Database Changes.md b/.gitlab/merge_request_templates/Database Changes.md index 8302b3b30c..68bc0fd1c7 100644 --- a/.gitlab/merge_request_templates/Database Changes.md +++ b/.gitlab/merge_request_templates/Database Changes.md @@ -33,13 +33,16 @@ When removing columns, tables, indexes or other structures: ## General Checklist -- [ ] [Changelog entry](https://docs.gitlab.com/ce/development/changelog.html) added, if necessary -- [ ] [Documentation created/updated](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/development/doc_styleguide.md) +- [ ] [Changelog entry](https://docs.gitlab.com/ee/development/changelog.html) added, if necessary +- [ ] [Documentation created/updated](https://docs.gitlab.com/ee/development/doc_styleguide.html) - [ ] API support added - [ ] Tests added for this feature/bug - Review - [ ] Has been reviewed by Backend - [ ] Has been reviewed by Database -- [ ] Conform by the [merge request performance guides](http://docs.gitlab.com/ce/development/merge_request_performance_guidelines.html) -- [ ] Conform by the [style guides](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CONTRIBUTING.md#style-guides) +- [ ] Conform by the [merge request performance guides](https://docs.gitlab.com/ee/development/merge_request_performance_guidelines.html) +- [ ] Conform by the [style guides](https://gitlab.com/gitlab-org/gitlab-ee/blob/master/CONTRIBUTING.md#style-guides) - [ ] [Squashed related commits together](https://git-scm.com/book/en/Git-Tools-Rewriting-History#Squashing-Commits) +- [ ] Internationalization required/considered +- [ ] If paid feature, have we considered GitLab.com plan and how it works for groups and is there a design for promoting it to users who aren't on the correct plan +- [ ] End-to-end tests pass (`package-qa` manual pipeline job) diff --git a/.gitlab/merge_request_templates/Documentation.md b/.gitlab/merge_request_templates/Documentation.md index 102eb7e795..da38a703c3 100644 --- a/.gitlab/merge_request_templates/Documentation.md +++ b/.gitlab/merge_request_templates/Documentation.md @@ -1,16 +1,29 @@ -See the general Documentation guidelines http://docs.gitlab.com/ce/development/doc_styleguide.html + ## What does this MR do? -(briefly describe what this MR is about) + + +## Related issues + + + +Closes ## Moving docs to a new location? -See the guidelines: http://docs.gitlab.com/ce/development/doc_styleguide.html#changing-document-location +Read the guidelines: +https://docs.gitlab.com/ce/development/writing_documentation.html#changing-document-location -- [ ] Make sure the old link is not removed and has its contents replaced with a link to the new location. +- [ ] Make sure the old link is not removed and has its contents replaced with + a link to the new location. - [ ] Make sure internal links pointing to the document in question are not broken. -- [ ] Search and replace any links referring to old docs in GitLab Rails app, specifically under the `app/views/` directory. -- [ ] Make sure to add [`redirect_from`](https://docs.gitlab.com/ee/development/doc_styleguide.html#redirections-for-pages-with-disqus-comments) to the new document if there are any Disqus comments on the old document thread. -- [ ] If working on CE, submit an MR to EE with the changes as well. +- [ ] Search and replace any links referring to old docs in GitLab Rails app, + specifically under the `app/views/` and `ee/app/views` (for GitLab EE) directories. +- [ ] Make sure to add [`redirect_from`](https://docs.gitlab.com/ce/development/writing_documentation.html#redirections-for-pages-with-disqus-comments) + to the new document if there are any Disqus comments on the old document thread. +- [ ] If working on CE and the `ee-compat-check` jobs fails, submit an MR to EE + with the changes as well (https://docs.gitlab.com/ce/development/writing_documentation.html#cherry-picking-from-ce-to-ee). - [ ] Ping one of the technical writers for review. + +/label ~Documentation diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000000..b674ccd50c --- /dev/null +++ b/.prettierignore @@ -0,0 +1,5 @@ +/app/assets/javascripts/locale/**/app.js +/node_modules/ +/public/ +/vendor/ +/tmp/ diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000000..3384551aea --- /dev/null +++ b/.prettierrc @@ -0,0 +1,13 @@ +{ + "printWidth": 100, + "singleQuote": true, + "trailingComma": "es5", + "overrides": [ + { + "files": ["**/app/**/*", "**/spec/**/*"], + "options": { + "trailingComma": "all" + } + } + ] +} diff --git a/.rubocop.yml b/.rubocop.yml index 90dac88453..0582bfe8d7 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -31,6 +31,78 @@ Style/MutableConstant: - 'ee/db/post_migrate/**/*' - 'ee/db/geo/migrate/**/*' +Naming/FileName: + ExpectMatchingDefinition: true + Exclude: + - 'spec/**/*' + - 'features/**/*' + - 'ee/spec/**/*' + - 'qa/spec/**/*' + - 'qa/qa/specs/**/*' + - 'qa/bin/*' + - 'config/**/*' + - 'lib/generators/**/*' + - 'ee/lib/generators/**/*' + IgnoreExecutableScripts: true + AllowedAcronyms: + - EE + - JSON + - LDAP + - IO + - HMAC + - QA + - ENV + - STL + - PDF + - SVG + - CTE + - DN + - RSA + - CI + - CD + - OAuth + # default ones: + - CLI + - DSL + - ACL + - API + - ASCII + - CPU + - CSS + - DNS + - EOF + - GUID + - HTML + - HTTP + - HTTPS + - ID + - IP + - JSON + - LHS + - QPS + - RAM + - RHS + - RPC + - SLA + - SMTP + - SQL + - SSH + - TCP + - TLS + - TTL + - UDP + - UI + - UID + - UUID + - URI + - URL + - UTF8 + - VM + - XML + - XMPP + - XSRF + - XSS + # Gitlab ################################################################### Gitlab/ModuleWithInstanceVariables: diff --git a/.scss-lint.yml b/.scss-lint.yml index dcd4cac780..180d377d6f 100644 --- a/.scss-lint.yml +++ b/.scss-lint.yml @@ -59,6 +59,8 @@ linters: # Reports when you define the same property twice in a single rule set. DuplicateProperty: enabled: true + ignore_consecutive: + - cursor # Separate rule, function, and mixin declarations with empty lines. EmptyLineBetweenBlocks: diff --git a/CHANGELOG.md b/CHANGELOG.md index fcc4225afd..6371b38775 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,29 +2,261 @@ documentation](doc/development/changelog.md) for instructions on adding your own entry. -## 10.6.5 (2018-04-24) +## 10.7.3 (2018-05-02) -### Security (1 change) +### Fixed (8 changes) +- Fixed wrong avatar URL when the avatar is on object storage. !18092 +- Fix errors on pushing to an empty repository. !18462 +- Update doorkeeper to 4.3.2 to fix GitLab OAuth authentication. !18543 +- Ports omniauth-jwt gem onto GitLab OmniAuth Strategies suite. !18580 +- Fix redirection error for applications using OpenID. !18599 +- Fix commit trailer rendering when Gravatar is disabled. +- Fix file_store for artifacts and lfs when saving. +- Fix users not seeing labels from private groups when being a member of a child project. + + +## 10.7.2 (2018-04-25) + +### Security (2 changes) + +- Serve archive requests with the correct file in all cases. - Sanitizes user name to avoid XSS attacks. -## 10.6.4 (2018-04-09) +## 10.7.1 (2018-04-23) -### Fixed (8 changes, 1 of them is from the community) +### Fixed (11 changes) +- [API] Fix URLs in the `Link` header for `GET /projects/:id/repository/contributors` when no value is passed for `order_by` or `sort`. !18393 +- Fix a case with secret variables being empty sometimes. !18400 +- Fix `Trace::HttpIO` can not render multi-byte chars. !18417 +- Fix specifying a non-default ref when requesting an archive using the legacy URL. !18468 +- Respect visibility options and description when importing project from template. !18473 +- Removes 'No Job log' message from build trace. !18523 +- Align action icons in pipeline graph. +- Fix direct_upload when records with null file_store are used. +- Removed alert box in IDE when redirecting to new merge request. +- Fixed IDE not loading for sub groups. +- Fixed IDE not showing loading state when tree is loading. + +### Performance (4 changes) + +- Validate project path prior to hitting the database. !18322 +- Add index to file_store on ci_job_artifacts. !18444 +- Fix N+1 queries when loading participants for a commit note. +- Support Markdown rendering using multiple projects. + +### Added (1 change) + +- Add an API endpoint to download git repository snapshots. !18173 + + +## 10.7.0 (2018-04-22) + +### Security (6 changes, 2 of them are from the community) + +- Fixed some SSRF vulnerabilities in services, hooks and integrations. !2337 +- Update ruby-saml to 1.7.2 and omniauth-saml to 1.10.0. !17734 (Takuya Noguchi) +- Update rack-protection to 2.0.1. !17835 (Takuya Noguchi) +- Adds confidential notes channel for Slack/Mattermost. +- Fix XSS on diff view stored on filenames. +- Fix GitLab Auth0 integration signing in the wrong user. + +### Fixed (65 changes, 20 of them are from the community) + +- File uploads in remote storage now support project renaming. !4597 +- Fixed bug in dropdown selector when selecting the same selection again. !14631 (bitsapien) +- Fixed group deletion linked to Mattermost. !16209 (Julien Millau) +- Create commit API and Web IDE obey LFS filters. !16718 +- Set breadcrumb for admin/runners/show. !17431 (Takuya Noguchi) +- Enable restore rake task to handle nested storage directories. !17516 (Balasankar C) +- Fix hover style of dropdown items in the right sidebar. !17519 +- Improve empty state for canceled job. !17646 +- Fix generated URL when listing repoitories for import. !17692 +- Use singular in the diff stats if only one line has been changed. !17697 (Jan Beckmann) +- Long instance urls do not overflow anymore during project creation. !17717 +- Fix importing multiple assignees from GitLab export. !17718 - Correct copy text for the promote milestone and label modals. !17726 +- Fix search results stripping last endline when parsing the results. !17777 (Jasper Maes) +- Add read-only banner to all pages. !17798 +- Fix viewing diffs on old merge requests. !17805 +- Fix forking to subgroup via API when namespace is given by name. !17815 (Jan Beckmann) +- Fix UI breakdown for Create merge request button. !17821 (Takuya Noguchi) +- Unify format for nested non-task lists. !17823 (Takuya Noguchi) +- UX re-design branch items with flexbox. !17832 (Takuya Noguchi) +- Use porcelain commit lookup method on CI::CreatePipelineService. !17911 +- Update dashboard milestones breadcrumb link. !17933 (George Tsiolis) +- Deleting a MR you are assigned to should decrements counter. !17951 (m b) +- Update no repository placeholder. !17964 (George Tsiolis) +- Drop JSON response in Project Milestone along with avoiding error. !17977 (Takuya Noguchi) +- Fix personal access token clipboard button style. !17978 (Fabian Schneider) - Avoid validation errors when running the Pages domain verification service. !17992 +- Project creation will now raise an error if a service template is invalid. !18013 +- Add better LDAP connection handling. !18039 - Fix autolinking URLs containing ampersands. !18045 - Fix exceptions raised when migrating pipeline stages in the background. !18076 +- Always display Labels section in issuable sidebar, even when the project has no labels. !18081 (Branka Martinovic) +- Fixed gitlab:uploads:migrate task ignoring some uploads. !18082 +- Fixed gitlab:uploads:migrate task failing for Groups' avatar. !18088 +- Increase dropdown width in pipeline graph & center action icon. !18089 +- Fix `JobsController#raw` endpoint can not read traces in database. !18101 +- Fix `gitlab-rake gitlab:two_factor:disable_for_all_users`. !18154 +- Adjust 404's for LegacyDiffNote discussion rendering. !18201 - Work around Prometheus Helm chart name changes to fix integration. !18206 (joshlambert) -- Don't show Jump to Discussion button on Issues. -- Fix listing commit branch/tags that contain special characters. +- Prioritize weight over title when sorting charts. !18233 +- Verify that deploy token has valid access when pulling container registry image. !18260 +- Stop redirecting the page in pipeline main actions. +- Fixed IDE button opening the wrong URL in tree list. +- Ensure hooks run when a deploy key without a user pushes. - Fix 404 in group boards when moving issue between lists. +- Display state indicator for issuable references in non-project scope (e.g. when referencing issuables from group scope). +- Add missing port to artifact links. +- Fix data race between ObjectStorage background_upload and Pages publishing. +- Fixes unresolved discussions rendering the error state instead of the diff. +- Don't show Jump to Discussion button on Issues. +- Fix bug rendering group icons when forking. +- Automatically cleanup stale worktrees and lock files upon a push. +- Use the GitLab version as part of the appearances cache key. +- Fix Firefox stealing formatting characters on issue notes. +- Include matching branches and tags in protected branches / tags count. (Jan Beckmann) +- Fix 500 error when a merge request from a fork has conflicts and has not yet been updated. +- Test if remote repository exists when importing wikis. +- Hide emoji popup after multiple spaces. (Jan Beckmann) +- Fix relative uri when "#" is in branch name. (Jan) +- Escape Markdown characters properly when using autocomplete. +- Ignore project internal references in group context. +- Fix finding wiki file when Gitaly is enabled. +- Fix listing commit branch/tags that contain special characters. +- Ensure internal users (ghost, support bot) get assigned a namespace. +- Fix links to subdirectories of a directory with a plus character in its path. -### Performance (1 change) +### Deprecated (1 change) +- Remove support for legacy tar.gz pages artifacts. !18090 + +### Changed (22 changes, 2 of them are from the community) + +- Add yellow favicon when `CANARY=true` to differientate canary environment. !12477 +- Use human readable value build_timeout in Project. !17386 +- Improved visual styles and consistency for commit hash and possible actions across commit lists. !17406 +- Don't create permanent redirect routes. !17521 +- Add empty repo check before running AutoDevOps pipeline. !17605 +- Update wording to specify create/manage project vs group labels in labels dropdown. !17640 +- Add tooltips to icons in lists of issues and merge requests. !17700 +- Change avatar error message to include allowed file formats. !17747 (Fabian Schneider) +- Polish design for verifying domains. !17767 +- Move email footer info to a single line. !17916 +- Add average and maximum summary statistics to the prometheus dashboard. !17921 +- Add additional cluster usage metrics to usage ping. !17922 +- Move 'Registry' after 'CI/CD' in project navigation sidebar. !18018 (Elias Werberich) +- Redesign application settings to match project settings. !18019 +- Allow HTTP(s) when git request is made by GitLab CI. !18021 +- Added hover background color to IDE file list rows. +- Make project avatar in IDE consistent with the rest of GitLab. +- Show issues of subgroups in group-level issue board. +- Repository checksum calculation is handled by Gitaly when feature is enabled. +- Allow viewing timings for AJAX requests in the performance bar. +- Fixes remove source branch checkbox being visible when user cannot remove the branch. +- Make /-/ delimiter optional for search endpoints. + +### Performance (24 changes, 11 of them are from the community) + +- Move AssigneeTitle vue component. !17397 (George Tsiolis) +- Move TimeTrackingCollapsedState vue component. !17399 (George Tsiolis) +- Move MemoryGraph and MemoryUsage vue components. !17533 (George Tsiolis) +- Move UnresolvedDiscussions vue component. !17538 (George Tsiolis) +- Move NothingToMerge vue component. !17544 (George Tsiolis) +- Move ShaMismatch vue component. !17546 (George Tsiolis) +- Stop caching highlighted diffs in Redis unnecessarily. !17746 +- Add i18n and update specs for ShaMismatch vue component. !17870 (George Tsiolis) +- Update spec import path for vue mount component helper. !17880 (George Tsiolis) +- Move TimeTrackingComparisonPane vue component. !17931 (George Tsiolis) +- Improves the performance of projects list page. !17934 +- Remove N+1 query for Noteable association. !17956 +- Improve performance of loading issues with lots of references to merge requests. !17986 +- Reuse root_ref_hash for performance on Branches. !17998 (Takuya Noguchi) +- Update asciidoctor-plantuml to 0.0.8. !18022 (Takuya Noguchi) +- Cache personal projects count. !18197 +- Reduce complexity of issuable finder query. !18219 +- Reduce number of queries when viewing a merge request. - Free open file descriptors and libgit2 buffers in UpdatePagesService. +- Memoize Git::Repository#has_visible_content?. +- Require at least one filter when listing issues or merge requests on dashboard page. +- lazy load diffs on merge request discussions. +- Bulk deleting refs is handled by Gitaly by default. +- ListCommitsByOid is executed by Gitaly by default. + +### Added (38 changes, 7 of them are from the community) + +- Add HTTPS-only pages. !16273 (rfwatson) +- adds closed by informations in issue api. !17042 (haseebeqx) +- Projects and groups badges settings UI. !17114 +- Add per-runner configured job timeout. !17221 +- Add alternate archive route for simplified packaging. !17225 +- Add support for pipeline variables expressions in only/except. !17316 +- Add object storage support for LFS objects, CI artifacts, and uploads. !17358 +- Added confirmation modal for changing username. !17405 +- Implement foreground verification of CI artifacts. !17578 +- Extend API for exporting a project with direct upload URL. !17686 +- Move ci/lint under project's namespace. !17729 +- Add Total CPU/Memory consumption metrics for Kubernetes. !17731 +- Adds the option to the project export API to override the project description and display GitLab export description once imported. !17744 +- Port direct upload of LFS artifacts from EE. !17752 +- Adds support for OmniAuth JWT provider. !17774 +- Display error message on job's tooltip if this one fails. !17782 +- Add 'Assigned Issues' and 'Assigned Merge Requests' as dashboard view choices for users. !17860 (Elias Werberich) +- Extend API for importing a project export with overwrite support. !17883 +- Create Deploy Tokens to allow permanent access to repository and registry. !17894 +- Detect commit message trailers and link users properly to their accounts on Gitlab. !17919 (cousine) +- Adds cancel btn to new pages domain page. !18026 (Jacopo Beschi @jacopo-beschi) +- API: Add parameter merge_method to projects. !18031 (Jan Beckmann) +- Introduce simpler env vars for auto devops REPLICAS and CANARY_REPLICAS #41436. !18036 +- Allow overriding params on project import through API. !18086 +- Support LFS objects when importing/exporting GitLab project archives. !18115 +- Store sha256 checksum of artifact metadata. !18149 +- Limit the number of failed logins when using LDAP for authentication. !43525 +- Allow assigning and filtering issuables by ancestor group labels. +- Include subgroup issues when searching for group issues using the API. +- Allow to store uploads by default on Object Storage. +- Add slash command for moving issues. (Adam Pahlevi) +- Render MR commit SHA instead "diffs" when viable. +- Send @mention notifications even if a user has explicitly unsubscribed from item. +- Add support for Sidekiq JSON logging. +- Add Gitaly call details to performance bar. +- Add support for patch link extension for commit links on GitLab Flavored Markdown. +- Allow feature gates to be removed through the API. +- Allow merge requests related to a commit to be found via API. + +### Other (27 changes, 11 of them are from the community) + +- Send notification emails when push to a merge request. !7610 (YarNayar) +- Rename modal.vue to deprecated_modal.vue. !17438 +- Atomic generation of internal ids for issues. !17580 +- Use object ID to prevent duplicate keys Vue warning on Issue Boards page during development. !17682 +- Update foreman from 0.78.0 to 0.84.0. !17690 (Takuya Noguchi) +- Add realtime pipeline status for adding/viewing files. !17705 +- Update documentation to reflect current minimum required versions of node and yarn. !17706 +- Update knapsack to 1.16.0. !17735 (Takuya Noguchi) +- Update CI services documnetation. !17749 +- Added i18n support for the prometheus memory widget. !17753 +- Use specific names for filtered CI variable controller parameters. !17796 +- Apply NestingDepth (level 5) (framework/dropdowns.scss). !17820 (Takuya Noguchi) +- Clean up selectors in framework/header.scss. !17822 (Takuya Noguchi) +- Bump `state_machines-activerecord` to 0.5.1. !17924 (blackst0ne) +- Increase the memory limits used in the unicorn killer. !17948 +- Replace the spinach test with an rspec analog. !17950 (blackst0ne) +- Remove unused index from events table. !18014 +- Make all workhorse gitaly calls opt-out, take 2. !18043 +- Update brakeman 3.6.1 to 4.2.1. !18122 (Takuya Noguchi) +- Replace the `project/issues/labels.feature` spinach test with an rspec analog. !18126 (blackst0ne) +- Bump html-pipeline to 2.7.1. !18132 (@blackst0ne) +- Remove test_ci rake task. !18139 (Takuya Noguchi) +- Add documentation for Pipelines failure reasons. !18352 +- Improve JIRA event descriptions. +- Add query counts to profiler output. +- Move Sidekiq exporter logs to log/sidekiq_exporter.log. +- Upgrade Gitaly to upgrade its charlock_holmes. ## 10.6.3 (2018-04-03) @@ -224,7 +456,6 @@ entry. - Enable privileged mode for GitLab Runner. !17528 - Expose GITLAB_FEATURES as CI/CD variable (fixes #40994). - Upgrade GitLab Workhorse to 4.0.0. -- Allow CI/CD Jobs being grouped on version strings. - Add discussions API for Issues and Snippets. - Add one group board to Libre. - Add support for filtering by source and target branch to merge requests API. @@ -251,6 +482,57 @@ entry. - Use host URL to build JIRA remote link icon. +## 10.5.7 (2018-04-03) + +### Security (2 changes) + +- Fix XSS on diff view stored on filenames. +- Adds confidential notes channel for Slack/Mattermost. + + +## 10.5.6 (2018-03-16) + +### Security (2 changes) + +- Fixed some SSRF vulnerabilities in services, hooks and integrations. !2337 +- Fix GitLab Auth0 integration signing in the wrong user. + + +## 10.5.5 (2018-03-15) + +### Fixed (3 changes) + +- Fix missing uploads after group transfer. !17658 +- Fix code and wiki search results when filename is non-ASCII. +- Remove double caching of Repository#empty?. + +### Performance (2 changes) + +- Adding missing indexes on taggings table. +- Add index on section_name_id on ci_build_trace_sections table. + + +## 10.5.4 (2018-03-08) + +### Fixed (11 changes) + +- Encode branch name as binary before creating a RPC request to copy attributes. !17291 +- Restart Unicorn and Sidekiq when GRPC throws 14:Endpoint read failed. !17293 +- Ensure group issues and merge requests pages show results from subgroups when there are no results from the current group. !17312 +- Prevent trace artifact migration to incur data loss. !17313 +- Return a 404 instead of 403 if the repository does not exist on disk. !17341 +- Allow Prometheus application to be installed from Cluster applications. !17372 +- Fixes Prometheus admin configuration page. !17377 +- Fix code and wiki search results pages when non-ASCII text is displayed. !17413 +- Fix pages flaky failure by reloading stale object. !17522 +- Fixed issue edit shortcut not opening edit form. +- Revert Project.public_or_visible_to_user changes and only apply to snippets. + +### Performance (1 change) + +- Don't use ProjectsFinder in TodosFinder. + + ## 10.5.3 (2018-03-01) ### Security (1 change) @@ -475,6 +757,22 @@ entry. - Adds empty state illustration for pending job. +## 10.4.7 (2018-04-03) + +### Security (2 changes) + +- Fix XSS on diff view stored on filenames. +- Adds confidential notes channel for Slack/Mattermost. + + +## 10.4.6 (2018-03-16) + +### Security (2 changes) + +- Fixed some SSRF vulnerabilities in services, hooks and integrations. !2337 +- Fix GitLab Auth0 integration signing in the wrong user. + + ## 10.4.5 (2018-03-01) ### Security (1 change) @@ -706,6 +1004,15 @@ entry. - Use a background migration for issues.closed_at. +## 10.3.9 (2018-03-16) + +### Security (3 changes) + +- Fixed some SSRF vulnerabilities in services, hooks and integrations. !2337 +- Update nokogiri to 1.8.2. !16807 +- Fix GitLab Auth0 integration signing in the wrong user. + + ## 10.3.8 (2018-03-01) ### Security (1 change) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 76ee6265c5..9c8fdc1275 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -26,7 +26,7 @@ _This notice should stay as the first item in the CONTRIBUTING.md file._ - [Type labels (~"feature proposal", ~bug, ~customer, etc.)](#type-labels-feature-proposal-bug-customer-etc) - [Subject labels (~wiki, ~"container registry", ~ldap, ~api, etc.)](#subject-labels-wiki-container-registry-ldap-api-etc) - [Team labels (~"CI/CD", ~Discussion, ~Edge, ~Platform, etc.)](#team-labels-cicd-discussion-edge-platform-etc) - - [Priority labels (~Deliverable and ~Stretch)](#priority-labels-deliverable-and-stretch) + - [Priority labels (~Deliverable, ~Stretch, ~"Next Patch Release")](#priority-labels-deliverable-stretch-next-patch-release) - [Label for community contributors (~"Accepting Merge Requests")](#label-for-community-contributors-accepting-merge-requests) - [Implement design & UI elements](#implement-design-ui-elements) - [Issue tracker](#issue-tracker) @@ -98,8 +98,8 @@ coach is going to finish the merge request we assign the ## Helping others -Please help other GitLab users when you can. The channels people will reach out -on can be found on the [getting help page][getting-help]. +Please help other GitLab users when you can. +The methods people will use to seek help can be found on the [getting help page][getting-help]. Sign up for the mailing list, answer GitLab questions on StackOverflow or respond in the IRC channel. You can also sign up on [CodeTriage][codetriage] to help with @@ -126,7 +126,7 @@ Most issues will have labels for at least one of the following: - Type: ~"feature proposal", ~bug, ~customer, etc. - Subject: ~wiki, ~"container registry", ~ldap, ~api, ~frontend, etc. - Team: ~"CI/CD", ~Discussion, ~Edge, ~Platform, etc. -- Priority: ~Deliverable, ~Stretch +- Priority: ~Deliverable, ~Stretch, ~"Next Patch Release" All labels, their meaning and priority are defined on the [labels page][labels-page]. @@ -185,7 +185,7 @@ indicate if an issue needs backend work, frontend work, or both. Team labels are always capitalized so that they show up as the first label for any issue. -### Priority labels (~Deliverable and ~Stretch) +### Priority labels (~Deliverable, ~Stretch, ~"Next Patch Release") Priority labels help us clearly communicate expectations of the work for the release. There are two levels of priority labels: @@ -195,6 +195,13 @@ release. There are two levels of priority labels: - ~Stretch: Issues that are a stretch goal for delivering in the current milestone. If these issues are not done in the current release, they will strongly be considered for the next release. +- ~"Next Patch Release": Issues to put in the next patch release. Work on these + first, and add the "Pick Into X" label to the merge request, along with the + appropriate milestone. + +Each issue scheduled for the current milestone should be labeled ~Deliverable +or ~"Stretch". Any open issue for a previous milestone should be labeled +~"Next Patch Release", or otherwise rescheduled to a different milestone. ### Severity labels (~S1, ~S2, etc.) @@ -686,3 +693,4 @@ available at [http://contributor-covenant.org/version/1/1/0/](http://contributor [^1]: Please note that specs other than JavaScript specs are considered backend code. + \ No newline at end of file diff --git a/GITALY_SERVER_VERSION b/GITALY_SERVER_VERSION index 8f63f4f9a1..483b771941 100644 --- a/GITALY_SERVER_VERSION +++ b/GITALY_SERVER_VERSION @@ -1 +1 @@ -0.91.0 +0.96.1 diff --git a/GITLAB_PAGES_VERSION b/GITLAB_PAGES_VERSION index 39e898a4f9..6f4eebdf6f 100644 --- a/GITLAB_PAGES_VERSION +++ b/GITLAB_PAGES_VERSION @@ -1 +1 @@ -0.7.1 +0.8.1 diff --git a/GITLAB_SHELL_VERSION b/GITLAB_SHELL_VERSION index 1aa5e414fd..a8a1887568 100644 --- a/GITLAB_SHELL_VERSION +++ b/GITLAB_SHELL_VERSION @@ -1 +1 @@ -6.0.4 +7.1.2 diff --git a/GITLAB_WORKHORSE_VERSION b/GITLAB_WORKHORSE_VERSION index fcdb2e109f..ee74734aa2 100644 --- a/GITLAB_WORKHORSE_VERSION +++ b/GITLAB_WORKHORSE_VERSION @@ -1 +1 @@ -4.0.0 +4.1.0 diff --git a/Gemfile b/Gemfile index ac06a938d0..e61dfd8e47 100644 --- a/Gemfile +++ b/Gemfile @@ -1,6 +1,18 @@ +# --- Special code for migrating to Rails 5.0 --- +def rails5? + %w[1 true].include?(ENV["RAILS5"]) +end + +gem_versions = {} +gem_versions['activerecord_sane_schema_dumper'] = rails5? ? '1.0' : '0.2' +gem_versions['default_value_for'] = rails5? ? '~> 3.0.5' : '~> 3.0.0' +gem_versions['rails'] = rails5? ? '5.0.6' : '4.2.10' +gem_versions['rails-i18n'] = rails5? ? '~> 5.1' : '~> 4.0.9' +# --- The end of special code for migrating to Rails 5.0 --- + source 'https://rubygems.org' -gem 'rails', '4.2.10' +gem 'rails', gem_versions['rails'] gem 'rails-deprecated_sanitizer', '~> 1.0.3' # Responders respond_to and respond_with @@ -9,34 +21,34 @@ gem 'responders', '~> 2.0' gem 'sprockets', '~> 3.7.0' # Default values for AR models -gem 'default_value_for', '~> 3.0.0' +gem 'default_value_for', gem_versions['default_value_for'] # Supported DBs gem 'mysql2', '~> 0.4.10', group: :mysql gem 'pg', '~> 0.18.2', group: :postgres -gem 'rugged', '~> 0.26.0' +gem 'rugged', '~> 0.27' gem 'grape-route-helpers', '~> 2.1.0' gem 'faraday', '~> 0.12' # Authentication libraries gem 'devise', '~> 4.2' -gem 'doorkeeper', '~> 4.2.0' -gem 'doorkeeper-openid_connect', '~> 1.2.0' -gem 'omniauth', '~> 1.4.2' +gem 'doorkeeper', '~> 4.3' +gem 'doorkeeper-openid_connect', '~> 1.3' +gem 'omniauth', '~> 1.8' gem 'omniauth-auth0', '~> 2.0.0' gem 'omniauth-azure-oauth2', '~> 0.0.9' gem 'omniauth-cas3', '~> 1.1.4' gem 'omniauth-facebook', '~> 4.0.0' gem 'omniauth-github', '~> 1.1.1' gem 'omniauth-gitlab', '~> 1.0.2' -gem 'omniauth-google-oauth2', '~> 0.5.2' +gem 'omniauth-google-oauth2', '~> 0.5.3' gem 'omniauth-kerberos', '~> 0.3.0', group: :kerberos gem 'omniauth-oauth2-generic', '~> 0.2.2' -gem 'omniauth-saml', '~> 1.7.0' +gem 'omniauth-saml', '~> 1.10' gem 'omniauth-shibboleth', '~> 1.2.0' -gem 'omniauth-twitter', '~> 1.2.0' +gem 'omniauth-twitter', '~> 1.4' gem 'omniauth_crowd', '~> 2.2.0' gem 'omniauth-authentiq', '~> 0.3.1' gem 'rack-oauth2', '~> 1.2.1' @@ -49,7 +61,7 @@ gem 'akismet', '~> 2.0' # Two-factor authentication gem 'devise-two-factor', '~> 3.0.0' gem 'rqrcode-rails3', '~> 0.1.7' -gem 'attr_encrypted', '~> 3.0.0' +gem 'attr_encrypted', '~> 3.1.0' gem 'u2f', '~> 0.2.1' # GitLab Pages @@ -104,16 +116,16 @@ gem 'carrierwave', '~> 1.2' gem 'dropzonejs-rails', '~> 0.7.1' # for backups -gem 'fog-aws', '~> 1.4' +gem 'fog-aws', '~> 2.0.1' gem 'fog-core', '~> 1.44' -gem 'fog-google', '~> 0.5' +gem 'fog-google', '~> 1.3.3' gem 'fog-local', '~> 0.3' gem 'fog-openstack', '~> 0.1' gem 'fog-rackspace', '~> 0.1.1' gem 'fog-aliyun', '~> 0.2.0' # for Google storage -gem 'google-api-client', '~> 0.13.6' +gem 'google-api-client', '~> 0.19.8' # for aws storage gem 'unf', '~> 0.1.4' @@ -122,7 +134,7 @@ gem 'unf', '~> 0.1.4' gem 'seed-fu', '~> 2.3.7' # Markdown and HTML processing -gem 'html-pipeline', '~> 1.11.0' +gem 'html-pipeline', '~> 2.7.1' gem 'deckar01-task_list', '2.0.0' gem 'gitlab-markup', '~> 1.6.2' gem 'redcarpet', '~> 3.4' @@ -132,8 +144,8 @@ gem 'rdoc', '~> 4.2' gem 'org-ruby', '~> 0.9.12' gem 'creole', '~> 0.5.0' gem 'wikicloth', '0.8.1' -gem 'asciidoctor', '~> 1.5.2' -gem 'asciidoctor-plantuml', '0.0.7' +gem 'asciidoctor', '~> 1.5.6' +gem 'asciidoctor-plantuml', '0.0.8' gem 'rouge', '~> 2.0' gem 'truncato', '~> 0.7.9' gem 'bootstrap_form', '~> 2.7.0' @@ -149,10 +161,10 @@ group :unicorn do end # State machine -gem 'state_machines-activerecord', '~> 0.4.0' +gem 'state_machines-activerecord', '~> 0.5.1' # Issue tags -gem 'acts-as-taggable-on', '~> 4.0' +gem 'acts-as-taggable-on', '~> 5.0' # Background jobs gem 'sidekiq', '~> 5.0' @@ -208,7 +220,7 @@ gem 'asana', '~> 0.6.0' gem 'ruby-fogbugz', '~> 0.2.1' # Kubernetes integration -gem 'kubeclient', '~> 2.2.0' +gem 'kubeclient', '~> 3.0' # d3 gem 'd3_rails', '~> 3.5.0' @@ -221,7 +233,7 @@ gem 'babosa', '~> 1.0.2' gem 'loofah', '~> 2.2' # Working with license -gem 'licensee', '~> 8.7.0' +gem 'licensee', '~> 8.9' # Protect against bruteforcing gem 'rack-attack', '~> 4.4.1' @@ -235,9 +247,6 @@ gem 'mousetrap-rails', '~> 1.4.6' # Detect and convert string character encoding gem 'charlock_holmes', '~> 0.7.5' -# Faster JSON -gem 'oj', '~> 2.17.4' - # Faster blank gem 'fast_blank' @@ -257,22 +266,21 @@ gem 'font-awesome-rails', '~> 4.7' gem 'gemojione', '~> 3.3' gem 'gon', '~> 6.1.0' gem 'jquery-atwho-rails', '~> 1.3.2' -gem 'jquery-rails', '~> 4.3.1' gem 'request_store', '~> 1.3' gem 'select2-rails', '~> 3.5.9' gem 'virtus', '~> 1.0.1' gem 'base32', '~> 0.3.0' # Sentry integration -gem 'sentry-raven', '~> 2.5.3' +gem 'sentry-raven', '~> 2.7' gem 'premailer-rails', '~> 1.9.7' # I18n gem 'ruby_parser', '~> 3.8', require: false -gem 'rails-i18n', '~> 4.0.9' +gem 'rails-i18n', gem_versions['rails-i18n'] gem 'gettext_i18n_rails', '~> 1.8.0' -gem 'gettext_i18n_rails_js', '~> 1.2.0' +gem 'gettext_i18n_rails_js', '~> 1.3' gem 'gettext', '~> 3.2.2', require: false, group: :development gem 'batch-loader', '~> 1.2.1' @@ -280,7 +288,6 @@ gem 'batch-loader', '~> 1.2.1' # Perf bar gem 'peek', '~> 1.0.1' gem 'peek-gc', '~> 0.0.2' -gem 'peek-host', '~> 1.0.0' gem 'peek-mysql2', '~> 1.1.0', group: :mysql gem 'peek-performance_bar', '~> 1.3.0' gem 'peek-pg', '~> 1.3.0', group: :postgres @@ -300,8 +307,8 @@ group :metrics do end group :development do - gem 'foreman', '~> 0.78.0' - gem 'brakeman', '~> 3.6.0', require: false + gem 'foreman', '~> 0.84.0' + gem 'brakeman', '~> 4.2', require: false gem 'letter_opener_web', '~> 1.3.0' gem 'rblineprof', '~> 0.3.6', platform: :mri, require: false @@ -360,13 +367,15 @@ group :development, :test do gem 'benchmark-ips', '~> 2.3.0', require: false gem 'license_finder', '~> 3.1', require: false - gem 'knapsack', '~> 1.11.0' + gem 'knapsack', '~> 1.16' - gem 'activerecord_sane_schema_dumper', '0.2' + gem 'activerecord_sane_schema_dumper', gem_versions['activerecord_sane_schema_dumper'] gem 'stackprof', '~> 0.2.10', require: false gem 'simple_po_parser', '~> 1.1.2', require: false + + gem 'timecop', '~> 0.8.0' end group :test do @@ -374,21 +383,20 @@ group :test do gem 'email_spec', '~> 1.6.0' gem 'json-schema', '~> 2.8.0' gem 'webmock', '~> 2.3.2' - gem 'test_after_commit', '~> 1.1' + gem 'test_after_commit', '~> 1.1' unless rails5? # Remove this gem when migrated to rails 5.0. It's been integrated to rails 5.0. gem 'sham_rack', '~> 1.3.6' - gem 'timecop', '~> 0.8.0' gem 'concurrent-ruby', '~> 1.0.5' gem 'test-prof', '~> 0.2.5' end -gem 'octokit', '~> 4.6.2' +gem 'octokit', '~> 4.8' gem 'mail_room', '~> 0.9.1' gem 'email_reply_trimmer', '~> 0.1' gem 'html2text' -gem 'ruby-prof', '~> 0.16.2' +gem 'ruby-prof', '~> 0.17.0' # OAuth gem 'oauth2', '~> 1.4' @@ -401,7 +409,7 @@ gem 'vmstat', '~> 2.3.0' gem 'sys-filesystem', '~> 1.1.6' # SSH host key support -gem 'net-ssh', '~> 4.1.0' +gem 'net-ssh', '~> 4.2.0' gem 'sshkey', '~> 1.9.0' # Required for ED25519 SSH host key support @@ -412,7 +420,7 @@ group :ed25519 do end # Gitaly GRPC client -gem 'gitaly-proto', '~> 0.88.0', require: 'gitaly' +gem 'gitaly-proto', '~> 0.96.0', require: 'gitaly' gem 'grpc', '~> 1.10.0' # Locked until https://github.com/google/protobuf/issues/4210 is closed @@ -421,9 +429,9 @@ gem 'google-protobuf', '= 3.5.1' gem 'toml-rb', '~> 1.0.0', require: false # Feature toggles -gem 'flipper', '~> 0.11.0' -gem 'flipper-active_record', '~> 0.11.0' -gem 'flipper-active_support_cache_store', '~> 0.11.0' +gem 'flipper', '~> 0.13.0' +gem 'flipper-active_record', '~> 0.13.0' +gem 'flipper-active_support_cache_store', '~> 0.13.0' # Structured logging gem 'lograge', '~> 0.5' diff --git a/Gemfile.lock b/Gemfile.lock index 41e6f2cc52..31b0dc9c0e 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -40,13 +40,14 @@ GEM minitest (~> 5.1) thread_safe (~> 0.3, >= 0.3.4) tzinfo (~> 1.1) - acts-as-taggable-on (4.0.0) - activerecord (>= 4.0) + acts-as-taggable-on (5.0.0) + activerecord (>= 4.2.8) adamantium (0.2.0) ice_nine (~> 0.11.0) memoizable (~> 0.4.0) addressable (2.5.2) public_suffix (>= 2.0.2, < 4.0) + aes_key_wrap (1.0.1) akismet (2.0.0) allocations (1.0.5) arel (6.0.4) @@ -55,17 +56,17 @@ GEM faraday_middleware (~> 0.9) faraday_middleware-multi_json (~> 0.0) oauth2 (~> 1.0) - asciidoctor (1.5.3) - asciidoctor-plantuml (0.0.7) + asciidoctor (1.5.6.2) + asciidoctor-plantuml (0.0.8) asciidoctor (~> 1.5) asset_sync (2.2.0) activemodel (>= 4.1.0) fog-core mime-types (>= 2.99) unf - ast (2.3.0) + ast (2.4.0) atomic (1.1.99) - attr_encrypted (3.0.3) + attr_encrypted (3.1.0) encryptor (~> 3.0.0) attr_required (1.0.0) autoprefixer-rails (6.2.3) @@ -86,7 +87,7 @@ GEM coderay (>= 1.0.0) erubis (>= 2.6.6) rack (>= 0.9.0) - bindata (2.4.1) + bindata (2.4.3) binding_of_caller (0.7.2) debug_inspector (>= 0.0.1) blankslate (2.1.2.4) @@ -94,7 +95,7 @@ GEM autoprefixer-rails (>= 5.2.1) sass (>= 3.3.4) bootstrap_form (2.7.0) - brakeman (3.6.1) + brakeman (4.2.1) browser (2.2.0) builder (3.2.3) bullet (5.5.1) @@ -119,7 +120,7 @@ GEM activesupport (>= 4.0.0) mime-types (>= 1.16) cause (0.1) - charlock_holmes (0.7.5) + charlock_holmes (0.7.6) childprocess (0.7.0) ffi (~> 1.0, >= 1.0.11) chronic (0.10.2) @@ -175,12 +176,12 @@ GEM diff-lcs (1.3) diffy (3.1.0) docile (1.1.5) - domain_name (0.5.20161021) + domain_name (0.5.20170404) unf (>= 0.0.5, < 1.0.0) - doorkeeper (4.2.6) + doorkeeper (4.3.2) railties (>= 4.2) - doorkeeper-openid_connect (1.2.0) - doorkeeper (~> 4.0) + doorkeeper-openid_connect (1.3.0) + doorkeeper (~> 4.3) json-jwt (~> 1.6) dropzonejs-rails (0.7.2) rails (> 3.1) @@ -195,7 +196,7 @@ GEM et-orbi (1.0.3) tzinfo eventmachine (1.0.8) - excon (0.57.1) + excon (0.60.0) execjs (2.6.0) expression_parser (0.9.0) factory_bot (4.8.2) @@ -211,7 +212,7 @@ GEM faraday_middleware multi_json fast_blank (1.0.0) - fast_gettext (1.4.0) + fast_gettext (1.6.0) ffaker (2.4.0) ffi (1.9.18) flay (2.10.0) @@ -219,13 +220,13 @@ GEM path_expander (~> 1.0) ruby_parser (~> 3.0) sexp_processor (~> 4.0) - flipper (0.11.0) - flipper-active_record (0.11.0) + flipper (0.13.0) + flipper-active_record (0.13.0) activerecord (>= 3.2, < 6) - flipper (~> 0.11.0) - flipper-active_support_cache_store (0.11.0) + flipper (~> 0.13.0) + flipper-active_support_cache_store (0.13.0) activesupport (>= 3.2, < 6) - flipper (~> 0.11.0) + flipper (~> 0.13.0) flowdock (0.7.1) httparty (~> 0.7) multi_json @@ -234,19 +235,20 @@ GEM fog-json (~> 1.0) ipaddress (~> 0.8) xml-simple (~> 1.1) - fog-aws (1.4.0) + fog-aws (2.0.1) fog-core (~> 1.38) fog-json (~> 1.0) fog-xml (~> 0.1) ipaddress (~> 0.8) - fog-core (1.44.3) + fog-core (1.45.0) builder - excon (~> 0.49) + excon (~> 0.58) formatador (~> 0.2) - fog-google (0.5.3) + fog-google (1.3.3) fog-core fog-json fog-xml + google-api-client (~> 0.19.1) fog-json (1.0.2) fog-core (~> 1.0) multi_json (~> 1.10) @@ -266,7 +268,7 @@ GEM nokogiri (>= 1.5.11, < 2.0.0) font-awesome-rails (4.7.0.1) railties (>= 3.2, < 5.1) - foreman (0.78.0) + foreman (0.84.0) thor (~> 0.19.1) formatador (0.2.5) fuubar (2.2.0) @@ -277,20 +279,20 @@ GEM gemojione (3.3.0) json get_process_mem (0.2.0) - gettext (3.2.2) + gettext (3.2.9) locale (>= 2.0.5) text (>= 1.3.0) gettext_i18n_rails (1.8.0) fast_gettext (>= 0.9.0) - gettext_i18n_rails_js (1.2.0) + gettext_i18n_rails_js (1.3.0) gettext (>= 3.0.2) gettext_i18n_rails (>= 0.7.1) po_to_json (>= 1.0.0) rails (>= 3.2.0) gherkin-ruby (0.3.2) - gitaly-proto (0.88.0) + gitaly-proto (0.96.0) google-protobuf (~> 3.1) - grpc (~> 1.0) + grpc (~> 1.10) github-linguist (5.3.3) charlock_holmes (~> 0.7.5) escape_utils (~> 1.1.0) @@ -336,9 +338,9 @@ GEM json multi_json request_store (>= 1.0) - google-api-client (0.13.6) + google-api-client (0.19.8) addressable (~> 2.5, >= 2.5.1) - googleauth (~> 0.5) + googleauth (>= 0.5, < 0.7.0) httpclient (>= 2.8.1, < 3.0) mime-types (~> 3.0) representable (~> 3.0) @@ -356,7 +358,7 @@ GEM signet (~> 0.7) gpgme (2.0.13) mini_portile2 (~> 2.1) - grape (1.0.0) + grape (1.0.2) activesupport builder mustermann-grape (~> 1.0.0) @@ -389,7 +391,7 @@ GEM thor tilt hashdiff (0.3.4) - hashie (3.5.6) + hashie (3.5.7) hashie-forbidden_attributes (0.1.1) hashie (>= 3.0) health_check (2.6.0) @@ -397,26 +399,26 @@ GEM hipchat (1.5.2) httparty mimemagic - html-pipeline (1.11.0) + html-pipeline (2.7.1) activesupport (>= 2) - nokogiri (~> 1.4) + nokogiri (>= 1.4) html2text (0.2.0) nokogiri (~> 1.6) htmlentities (4.3.4) - http (0.9.8) + http (2.2.2) addressable (~> 2.3) http-cookie (~> 1.0) http-form_data (~> 1.0.1) http_parser.rb (~> 0.6.0) http-cookie (1.0.3) domain_name (~> 0.5) - http-form_data (1.0.1) + http-form_data (1.0.3) http_parser.rb (0.6.0) httparty (0.13.7) json (~> 1.8) multi_xml (>= 0.5.2) - httpclient (2.8.2) - i18n (0.9.1) + httpclient (2.8.3) + i18n (0.9.5) concurrent-ruby (~> 1.0) ice_nine (0.11.2) influxdb (0.2.3) @@ -428,15 +430,11 @@ GEM multipart-post oauth (~> 0.5, >= 0.5.0) jquery-atwho-rails (1.3.2) - jquery-rails (4.3.1) - rails-dom-testing (>= 1, < 3) - railties (>= 4.2.0) - thor (>= 0.14, < 2.0) json (1.8.6) - json-jwt (1.7.2) + json-jwt (1.9.2) activesupport + aes_key_wrap bindata - multi_json (>= 1.3) securecompare url_safe_base64 json-schema (2.8.0) @@ -455,13 +453,13 @@ GEM kaminari-core (= 1.0.1) kaminari-core (1.0.1) kgio (2.10.0) - knapsack (1.11.0) + knapsack (1.16.0) rake timecop (>= 0.1.0) - kubeclient (2.2.0) - http (= 0.9.8) - recursive-open-struct (= 1.0.0) - rest-client + kubeclient (3.0.0) + http (~> 2.2.2) + recursive-open-struct (~> 1.0.4) + rest-client (~> 2.0) launchy (2.4.3) addressable (~> 2.3) letter_opener (1.4.1) @@ -478,7 +476,7 @@ GEM toml (= 0.1.2) with_env (> 1.0) xml-simple - licensee (8.7.0) + licensee (8.9.2) rugged (~> 0.24) little-plugger (1.1.4) locale (2.1.2) @@ -503,36 +501,35 @@ GEM mime-types-data (~> 3.2015) mime-types-data (3.2016.0521) mimemagic (0.3.0) - mini_mime (0.1.4) + mini_mime (1.0.0) mini_portile2 (2.3.0) minitest (5.7.0) mousetrap-rails (1.4.6) multi_json (1.13.1) multi_xml (0.6.0) multipart-post (2.0.0) - mustermann (1.0.0) + mustermann (1.0.2) mustermann-grape (1.0.0) mustermann (~> 1.0.0) mysql2 (0.4.10) net-ldap (0.16.0) - net-ssh (4.1.0) + net-ssh (4.2.0) netrc (0.11.0) nokogiri (1.8.2) mini_portile2 (~> 2.3.0) numerizer (0.1.1) - oauth (0.5.1) + oauth (0.5.4) oauth2 (1.4.0) faraday (>= 0.8, < 0.13) jwt (~> 1.0) multi_json (~> 1.3) multi_xml (~> 0.5) rack (>= 1.2, < 3) - octokit (4.6.2) + octokit (4.8.0) sawyer (~> 0.8.0, >= 0.5.3) - oj (2.17.5) - omniauth (1.4.2) - hashie (>= 1.2, < 4) - rack (>= 1.0, < 3) + omniauth (1.8.1) + hashie (>= 3.4.6, < 3.6.0) + rack (>= 1.6.2, < 3) omniauth-auth0 (2.0.0) omniauth-oauth2 (~> 1.4) omniauth-authentiq (0.3.1) @@ -553,11 +550,10 @@ GEM omniauth-gitlab (1.0.2) omniauth (~> 1.0) omniauth-oauth2 (~> 1.0) - omniauth-google-oauth2 (0.5.2) - jwt (~> 1.5) - multi_json (~> 1.3) + omniauth-google-oauth2 (0.5.3) + jwt (>= 1.5) omniauth (>= 1.1.1) - omniauth-oauth2 (>= 1.3.1) + omniauth-oauth2 (>= 1.5) omniauth-kerberos (0.3.0) omniauth-multipassword timfel-krb5-auth (~> 0.8) @@ -566,19 +562,19 @@ GEM omniauth-oauth (1.1.0) oauth omniauth (~> 1.0) - omniauth-oauth2 (1.4.0) - oauth2 (~> 1.0) + omniauth-oauth2 (1.5.0) + oauth2 (~> 1.1) omniauth (~> 1.2) omniauth-oauth2-generic (0.2.2) omniauth-oauth2 (~> 1.0) - omniauth-saml (1.7.0) - omniauth (~> 1.3) - ruby-saml (~> 1.4) + omniauth-saml (1.10.0) + omniauth (~> 1.3, >= 1.3.2) + ruby-saml (~> 1.7) omniauth-shibboleth (1.2.1) omniauth (>= 1.0.0) - omniauth-twitter (1.2.1) - json (~> 1.3) + omniauth-twitter (1.4.0) omniauth-oauth (~> 1.1) + rack omniauth_crowd (2.2.3) activesupport nokogiri (>= 1.4.4) @@ -588,8 +584,8 @@ GEM orm_adapter (0.5.0) os (0.9.6) parallel (1.12.1) - parser (2.4.0.2) - ast (~> 2.3) + parser (2.5.0.5) + ast (~> 2.4.0) parslet (1.5.0) blankslate (~> 2.0) path_expander (1.0.2) @@ -599,8 +595,6 @@ GEM railties (>= 4.0.0) peek-gc (0.0.2) peek - peek-host (1.0.0) - peek peek-mysql2 (1.1.0) atomic (>= 1.0.0) mysql2 @@ -652,7 +646,7 @@ GEM pry (>= 0.9.10) public_suffix (3.0.2) pyu-ruby-sasl (0.0.3.3) - rack (1.6.8) + rack (1.6.9) rack-accept (0.4.5) rack (>= 0.4) rack-attack (4.4.1) @@ -664,7 +658,7 @@ GEM httpclient (>= 2.4) multi_json (>= 1.3.6) rack (>= 1.1) - rack-protection (1.5.3) + rack-protection (2.0.1) rack rack-proxy (0.6.0) rack @@ -683,8 +677,8 @@ GEM sprockets-rails rails-deprecated_sanitizer (1.0.3) activesupport (>= 4.2.0.alpha) - rails-dom-testing (1.0.8) - activesupport (>= 4.2.0.beta, < 5.0) + rails-dom-testing (1.0.9) + activesupport (>= 4.2.0, < 5.0) nokogiri (~> 1.6) rails-deprecated_sanitizer (>= 1.0.1) rails-html-sanitizer (1.0.4) @@ -715,7 +709,7 @@ GEM re2 (1.1.1) recaptcha (3.0.0) json - recursive-open-struct (1.0.0) + recursive-open-struct (1.0.5) redcarpet (3.4.0) redis (3.3.5) redis-actionpack (5.0.2) @@ -743,7 +737,7 @@ GEM request_store (1.3.1) responders (2.3.0) railties (>= 4.2.0, < 5.1) - rest-client (2.0.0) + rest-client (2.0.2) http-cookie (>= 1.0.2, < 2.0) mime-types (>= 1.16, < 4.0) netrc (~> 0.8) @@ -805,9 +799,9 @@ GEM i18n ruby-fogbugz (0.2.1) crack (~> 0.4) - ruby-prof (0.16.2) + ruby-prof (0.17.0) ruby-progressbar (1.9.0) - ruby-saml (1.4.1) + ruby-saml (1.7.2) nokogiri (>= 1.5.10) ruby_parser (3.9.0) sexp_processor (~> 4.1) @@ -816,7 +810,7 @@ GEM rubyzip (1.2.1) rufus-scheduler (3.4.0) et-orbi (~> 1.0) - rugged (0.26.0) + rugged (0.27.0) safe_yaml (1.0.4) sanitize (2.1.0) nokogiri (>= 1.4.4) @@ -846,7 +840,7 @@ GEM selenium-webdriver (3.5.0) childprocess (~> 0.5) rubyzip (~> 1.0) - sentry-raven (2.5.3) + sentry-raven (2.7.2) faraday (>= 0.7.6, < 1.0) settingslogic (2.0.9) sexp_processor (4.9.0) @@ -903,13 +897,13 @@ GEM sqlite3 (1.3.13) sshkey (1.9.0) stackprof (0.2.10) - state_machines (0.4.0) - state_machines-activemodel (0.4.0) - activemodel (>= 4.1, < 5.1) - state_machines (>= 0.4.0) - state_machines-activerecord (0.4.0) - activerecord (>= 4.1, < 5.1) - state_machines-activemodel (>= 0.3.0) + state_machines (0.5.0) + state_machines-activemodel (0.5.1) + activemodel (>= 4.1, < 6.0) + state_machines (>= 0.5.0) + state_machines-activerecord (0.5.1) + activerecord (>= 4.1, < 6.0) + state_machines-activemodel (>= 0.5.0) stringex (2.7.1) sys-filesystem (1.1.6) ffi @@ -935,7 +929,7 @@ GEM truncato (0.7.10) htmlentities (~> 4.3.1) nokogiri (~> 1.8.0, >= 1.7.0) - tzinfo (1.2.4) + tzinfo (1.2.5) thread_safe (~> 0.1) u2f (0.2.1) uber (0.1.0) @@ -944,7 +938,7 @@ GEM json (>= 1.8.0) unf (0.1.4) unf_ext - unf_ext (0.0.7.4) + unf_ext (0.0.7.5) unicode-display_width (1.3.0) unicorn (5.1.0) kgio (~> 2.6) @@ -953,13 +947,13 @@ GEM get_process_mem (~> 0) unicorn (>= 4, < 6) uniform_notifier (1.10.0) - unparser (0.2.6) + unparser (0.2.7) abstract_type (~> 0.0.7) adamantium (~> 0.2.0) concord (~> 0.1.5) diff-lcs (~> 1.3) equalizer (~> 0.0.9) - parser (>= 2.3.1.2, < 2.5) + parser (>= 2.3.1.2, < 2.6) procto (~> 0.0.2) url_safe_base64 (0.2.2) validates_hostname (1.0.6) @@ -996,15 +990,15 @@ DEPENDENCIES RedCloth (~> 4.3.2) ace-rails-ap (~> 4.1.0) activerecord_sane_schema_dumper (= 0.2) - acts-as-taggable-on (~> 4.0) + acts-as-taggable-on (~> 5.0) addressable (~> 2.5.2) akismet (~> 2.0) allocations (~> 1.0) asana (~> 0.6.0) - asciidoctor (~> 1.5.2) - asciidoctor-plantuml (= 0.0.7) + asciidoctor (~> 1.5.6) + asciidoctor-plantuml (= 0.0.8) asset_sync (~> 2.2.0) - attr_encrypted (~> 3.0.0) + attr_encrypted (~> 3.1.0) awesome_print (~> 1.2.0) babosa (~> 1.0.2) base32 (~> 0.3.0) @@ -1015,7 +1009,7 @@ DEPENDENCIES binding_of_caller (~> 0.7.2) bootstrap-sass (~> 3.3.0) bootstrap_form (~> 2.7.0) - brakeman (~> 3.6.0) + brakeman (~> 4.2) browser (~> 2.2) bullet (~> 5.5.0) bundler-audit (~> 0.5.0) @@ -1036,8 +1030,8 @@ DEPENDENCIES devise (~> 4.2) devise-two-factor (~> 3.0.0) diffy (~> 3.1.0) - doorkeeper (~> 4.2.0) - doorkeeper-openid_connect (~> 1.2.0) + doorkeeper (~> 4.3) + doorkeeper-openid_connect (~> 1.3) dropzonejs-rails (~> 0.7.1) email_reply_trimmer (~> 0.1) email_spec (~> 1.6.0) @@ -1046,25 +1040,25 @@ DEPENDENCIES fast_blank ffaker (~> 2.4) flay (~> 2.10.0) - flipper (~> 0.11.0) - flipper-active_record (~> 0.11.0) - flipper-active_support_cache_store (~> 0.11.0) + flipper (~> 0.13.0) + flipper-active_record (~> 0.13.0) + flipper-active_support_cache_store (~> 0.13.0) fog-aliyun (~> 0.2.0) - fog-aws (~> 1.4) + fog-aws (~> 2.0.1) fog-core (~> 1.44) - fog-google (~> 0.5) + fog-google (~> 1.3.3) fog-local (~> 0.3) fog-openstack (~> 0.1) fog-rackspace (~> 0.1.1) font-awesome-rails (~> 4.7) - foreman (~> 0.78.0) + foreman (~> 0.84.0) fuubar (~> 2.2.0) gemnasium-gitlab-service (~> 0.2) gemojione (~> 3.3) gettext (~> 3.2.2) gettext_i18n_rails (~> 1.8.0) - gettext_i18n_rails_js (~> 1.2.0) - gitaly-proto (~> 0.88.0) + gettext_i18n_rails_js (~> 1.3) + gitaly-proto (~> 0.96.0) github-linguist (~> 5.3.3) gitlab-flowdock-git-hook (~> 1.0.1) gitlab-markup (~> 1.6.2) @@ -1073,7 +1067,7 @@ DEPENDENCIES gollum-lib (~> 4.2) gollum-rugged_adapter (~> 0.4.4) gon (~> 6.1.0) - google-api-client (~> 0.13.6) + google-api-client (~> 0.19.8) google-protobuf (= 3.5.1) gpgme grape (~> 1.0) @@ -1086,21 +1080,20 @@ DEPENDENCIES hashie-forbidden_attributes health_check (~> 2.6.0) hipchat (~> 1.5.0) - html-pipeline (~> 1.11.0) + html-pipeline (~> 2.7.1) html2text httparty (~> 0.13.3) influxdb (~> 0.2) jira-ruby (~> 1.4) jquery-atwho-rails (~> 1.3.2) - jquery-rails (~> 4.3.1) json-schema (~> 2.8.0) jwt (~> 1.5.6) kaminari (~> 1.0) - knapsack (~> 1.11.0) - kubeclient (~> 2.2.0) + knapsack (~> 1.16) + kubeclient (~> 3.0) letter_opener_web (~> 1.3.0) license_finder (~> 3.1) - licensee (~> 8.7.0) + licensee (~> 8.9) lograge (~> 0.5) loofah (~> 2.2) mail_room (~> 0.9.1) @@ -1109,12 +1102,11 @@ DEPENDENCIES mousetrap-rails (~> 1.4.6) mysql2 (~> 0.4.10) net-ldap - net-ssh (~> 4.1.0) + net-ssh (~> 4.2.0) nokogiri (~> 1.8.2) oauth2 (~> 1.4) - octokit (~> 4.6.2) - oj (~> 2.17.4) - omniauth (~> 1.4.2) + octokit (~> 4.8) + omniauth (~> 1.8) omniauth-auth0 (~> 2.0.0) omniauth-authentiq (~> 0.3.1) omniauth-azure-oauth2 (~> 0.0.9) @@ -1122,17 +1114,16 @@ DEPENDENCIES omniauth-facebook (~> 4.0.0) omniauth-github (~> 1.1.1) omniauth-gitlab (~> 1.0.2) - omniauth-google-oauth2 (~> 0.5.2) + omniauth-google-oauth2 (~> 0.5.3) omniauth-kerberos (~> 0.3.0) omniauth-oauth2-generic (~> 0.2.2) - omniauth-saml (~> 1.7.0) + omniauth-saml (~> 1.10) omniauth-shibboleth (~> 1.2.0) - omniauth-twitter (~> 1.2.0) + omniauth-twitter (~> 1.4) omniauth_crowd (~> 2.2.0) org-ruby (~> 0.9.12) peek (~> 1.0.1) peek-gc (~> 0.0.2) - peek-host (~> 1.0.0) peek-mysql2 (~> 1.1.0) peek-performance_bar (~> 1.3.0) peek-pg (~> 1.3.0) @@ -1175,17 +1166,17 @@ DEPENDENCIES rubocop (~> 0.52.1) rubocop-rspec (~> 1.22.1) ruby-fogbugz (~> 0.2.1) - ruby-prof (~> 0.16.2) + ruby-prof (~> 0.17.0) ruby_parser (~> 3.8) rufus-scheduler (~> 3.4) - rugged (~> 0.26.0) + rugged (~> 0.27) sanitize (~> 2.0) sass-rails (~> 5.0.6) scss_lint (~> 0.56.0) seed-fu (~> 2.3.7) select2-rails (~> 3.5.9) selenium-webdriver (~> 3.5) - sentry-raven (~> 2.5.3) + sentry-raven (~> 2.7) settingslogic (~> 2.0.9) sham_rack (~> 1.3.6) shoulda-matchers (~> 3.1.2) @@ -1203,7 +1194,7 @@ DEPENDENCIES sprockets (~> 3.7.0) sshkey (~> 1.9.0) stackprof (~> 0.2.10) - state_machines-activerecord (~> 0.4.0) + state_machines-activerecord (~> 0.5.1) sys-filesystem (~> 1.1.6) test-prof (~> 0.2.5) test_after_commit (~> 1.1) diff --git a/Gemfile.rails5 b/Gemfile.rails5 new file mode 100644 index 0000000000..2b526b19ba --- /dev/null +++ b/Gemfile.rails5 @@ -0,0 +1,7 @@ +# BUNDLE_GEMFILE=Gemfile.rails5 bundle install + +ENV["RAILS5"] = "true" + +gemfile = File.expand_path("../Gemfile", __FILE__) + +eval(File.read(gemfile), nil, gemfile) diff --git a/Gemfile.rails5.lock b/Gemfile.rails5.lock new file mode 100644 index 0000000000..18bbad88ec --- /dev/null +++ b/Gemfile.rails5.lock @@ -0,0 +1,1223 @@ +GEM + remote: https://rubygems.org/ + specs: + RedCloth (4.3.2) + abstract_type (0.0.7) + ace-rails-ap (4.1.4) + actioncable (5.0.6) + actionpack (= 5.0.6) + nio4r (>= 1.2, < 3.0) + websocket-driver (~> 0.6.1) + actionmailer (5.0.6) + actionpack (= 5.0.6) + actionview (= 5.0.6) + activejob (= 5.0.6) + mail (~> 2.5, >= 2.5.4) + rails-dom-testing (~> 2.0) + actionpack (5.0.6) + actionview (= 5.0.6) + activesupport (= 5.0.6) + rack (~> 2.0) + rack-test (~> 0.6.3) + rails-dom-testing (~> 2.0) + rails-html-sanitizer (~> 1.0, >= 1.0.2) + actionview (5.0.6) + activesupport (= 5.0.6) + builder (~> 3.1) + erubis (~> 2.7.0) + rails-dom-testing (~> 2.0) + rails-html-sanitizer (~> 1.0, >= 1.0.3) + activejob (5.0.6) + activesupport (= 5.0.6) + globalid (>= 0.3.6) + activemodel (5.0.6) + activesupport (= 5.0.6) + activerecord (5.0.6) + activemodel (= 5.0.6) + activesupport (= 5.0.6) + arel (~> 7.0) + activerecord_sane_schema_dumper (1.0) + rails (>= 5, < 6) + activesupport (5.0.6) + concurrent-ruby (~> 1.0, >= 1.0.2) + i18n (~> 0.7) + minitest (~> 5.1) + tzinfo (~> 1.1) + acts-as-taggable-on (5.0.0) + activerecord (>= 4.2.8) + adamantium (0.2.0) + ice_nine (~> 0.11.0) + memoizable (~> 0.4.0) + addressable (2.5.2) + public_suffix (>= 2.0.2, < 4.0) + aes_key_wrap (1.0.1) + akismet (2.0.0) + allocations (1.0.5) + arel (7.1.4) + asana (0.6.3) + faraday (~> 0.9) + faraday_middleware (~> 0.9) + faraday_middleware-multi_json (~> 0.0) + oauth2 (~> 1.0) + asciidoctor (1.5.6.1) + asciidoctor-plantuml (0.0.8) + asciidoctor (~> 1.5) + asset_sync (2.2.0) + activemodel (>= 4.1.0) + fog-core + mime-types (>= 2.99) + unf + ast (2.4.0) + atomic (1.1.100) + attr_encrypted (3.0.3) + encryptor (~> 3.0.0) + attr_required (1.0.1) + autoprefixer-rails (8.1.0.1) + execjs + awesome_print (1.2.0) + axiom-types (0.1.1) + descendants_tracker (~> 0.0.4) + ice_nine (~> 0.11.0) + thread_safe (~> 0.3, >= 0.3.1) + babosa (1.0.2) + base32 (0.3.2) + batch-loader (1.2.1) + bcrypt (3.1.11) + bcrypt_pbkdf (1.0.0) + benchmark-ips (2.3.0) + better_errors (2.1.1) + coderay (>= 1.0.0) + erubis (>= 2.6.6) + rack (>= 0.9.0) + bindata (2.4.3) + binding_of_caller (0.7.3) + debug_inspector (>= 0.0.1) + blankslate (2.1.2.4) + bootstrap-sass (3.3.7) + autoprefixer-rails (>= 5.2.1) + sass (>= 3.3.4) + bootstrap_form (2.7.0) + brakeman (4.2.1) + browser (2.5.3) + builder (3.2.3) + bullet (5.5.1) + activesupport (>= 3.0.0) + uniform_notifier (~> 1.10.0) + bundler-audit (0.5.0) + bundler (~> 1.2) + thor (~> 0.18) + byebug (9.0.6) + capybara (2.18.0) + addressable + mini_mime (>= 0.1.3) + nokogiri (>= 1.3.3) + rack (>= 1.0.0) + rack-test (>= 0.5.4) + xpath (>= 2.0, < 4.0) + capybara-screenshot (1.0.18) + capybara (>= 1.0, < 3) + launchy + carrierwave (1.2.2) + activemodel (>= 4.0.0) + activesupport (>= 4.0.0) + mime-types (>= 1.16) + charlock_holmes (0.7.5) + childprocess (0.9.0) + ffi (~> 1.0, >= 1.0.11) + chronic (0.10.2) + chronic_duration (0.10.6) + numerizer (~> 0.1.1) + chunky_png (1.3.10) + citrus (3.0.2) + coderay (1.1.2) + coercible (1.0.0) + descendants_tracker (~> 0.0.1) + colorize (0.8.1) + commonmarker (0.17.9) + ruby-enum (~> 0.5) + concord (0.1.5) + adamantium (~> 0.2.0) + equalizer (~> 0.0.9) + concurrent-ruby (1.0.5) + concurrent-ruby-ext (1.0.5) + concurrent-ruby (= 1.0.5) + connection_pool (2.2.1) + crack (0.4.3) + safe_yaml (~> 1.0.0) + crass (1.0.3) + creole (0.5.0) + css_parser (1.6.0) + addressable + d3_rails (3.5.17) + railties (>= 3.1.0) + daemons (1.2.6) + database_cleaner (1.5.3) + debug_inspector (0.0.3) + debugger-ruby_core_source (1.3.8) + deckar01-task_list (2.0.0) + html-pipeline + declarative (0.0.10) + declarative-option (0.1.0) + default_value_for (3.0.5) + activerecord (>= 3.2.0, < 5.2) + descendants_tracker (0.0.4) + thread_safe (~> 0.3, >= 0.3.1) + devise (4.4.1) + bcrypt (~> 3.0) + orm_adapter (~> 0.1) + railties (>= 4.1.0, < 5.2) + responders + warden (~> 1.2.3) + devise-two-factor (3.0.2) + activesupport (< 5.2) + attr_encrypted (>= 1.3, < 4, != 2) + devise (~> 4.0) + railties (< 5.2) + rotp (~> 2.0) + diff-lcs (1.3) + diffy (3.1.0) + docile (1.1.5) + domain_name (0.5.20170404) + unf (>= 0.0.5, < 1.0.0) + doorkeeper (4.3.1) + railties (>= 4.2) + doorkeeper-openid_connect (1.3.0) + doorkeeper (~> 4.3) + json-jwt (~> 1.6) + dropzonejs-rails (0.7.4) + rails (> 3.1) + email_reply_trimmer (0.1.10) + email_spec (1.6.0) + launchy (~> 2.1) + mail (~> 2.2) + encryptor (3.0.0) + equalizer (0.0.11) + erubis (2.7.0) + escape_utils (1.1.1) + et-orbi (1.0.9) + tzinfo + eventmachine (1.2.5) + excon (0.60.0) + execjs (2.7.0) + expression_parser (0.9.0) + factory_bot (4.8.2) + activesupport (>= 3.0.0) + factory_bot_rails (4.8.2) + factory_bot (~> 4.8.2) + railties (>= 3.0.0) + faraday (0.12.2) + multipart-post (>= 1.2, < 3) + faraday_middleware (0.12.2) + faraday (>= 0.7.4, < 1.0) + faraday_middleware-multi_json (0.0.6) + faraday_middleware + multi_json + fast_blank (1.0.0) + fast_gettext (1.6.0) + ffaker (2.8.1) + ffi (1.9.23) + flay (2.10.0) + erubis (~> 2.7.0) + path_expander (~> 1.0) + ruby_parser (~> 3.0) + sexp_processor (~> 4.0) + flipper (0.13.0) + flipper-active_record (0.13.0) + activerecord (>= 3.2, < 6) + flipper (~> 0.13.0) + flipper-active_support_cache_store (0.13.0) + activesupport (>= 3.2, < 6) + flipper (~> 0.13.0) + flowdock (0.7.1) + httparty (~> 0.7) + multi_json + fog-aliyun (0.2.0) + fog-core (~> 1.27) + fog-json (~> 1.0) + ipaddress (~> 0.8) + xml-simple (~> 1.1) + fog-aws (2.0.1) + fog-core (~> 1.38) + fog-json (~> 1.0) + fog-xml (~> 0.1) + ipaddress (~> 0.8) + fog-core (1.45.0) + builder + excon (~> 0.58) + formatador (~> 0.2) + fog-google (1.3.3) + fog-core + fog-json + fog-xml + google-api-client (~> 0.19.1) + fog-json (1.0.2) + fog-core (~> 1.0) + multi_json (~> 1.10) + fog-local (0.5.0) + fog-core (>= 1.27, < 3.0) + fog-openstack (0.1.24) + fog-core (~> 1.40) + fog-json (>= 1.0) + ipaddress (>= 0.8) + fog-rackspace (0.1.5) + fog-core (>= 1.35) + fog-json (>= 1.0) + fog-xml (>= 0.1) + ipaddress (>= 0.8) + fog-xml (0.1.3) + fog-core + nokogiri (>= 1.5.11, < 2.0.0) + font-awesome-rails (4.7.0.3) + railties (>= 3.2, < 5.2) + foreman (0.84.0) + thor (~> 0.19.1) + formatador (0.2.5) + fuubar (2.2.0) + rspec-core (~> 3.0) + ruby-progressbar (~> 1.4) + gemnasium-gitlab-service (0.2.6) + rugged (~> 0.21) + gemojione (3.3.0) + json + get_process_mem (0.2.1) + gettext (3.2.9) + locale (>= 2.0.5) + text (>= 1.3.0) + gettext_i18n_rails (1.8.0) + fast_gettext (>= 0.9.0) + gettext_i18n_rails_js (1.3.0) + gettext (>= 3.0.2) + gettext_i18n_rails (>= 0.7.1) + po_to_json (>= 1.0.0) + rails (>= 3.2.0) + gherkin-ruby (0.3.2) + gitaly-proto (0.94.0) + google-protobuf (~> 3.1) + grpc (~> 1.0) + github-linguist (5.3.3) + charlock_holmes (~> 0.7.5) + escape_utils (~> 1.1.0) + mime-types (>= 1.19) + rugged (>= 0.25.1) + github-markup (1.7.0) + gitlab-flowdock-git-hook (1.0.1) + flowdock (~> 0.7) + gitlab-grit (>= 2.4.1) + multi_json + gitlab-grit (2.8.2) + charlock_holmes (~> 0.6) + diff-lcs (~> 1.1) + mime-types (>= 1.16) + posix-spawn (~> 0.3) + gitlab-markup (1.6.3) + gitlab-styles (2.3.2) + rubocop (~> 0.51) + rubocop-gitlab-security (~> 0.1.0) + rubocop-rspec (~> 1.19) + gitlab_omniauth-ldap (2.0.4) + net-ldap (~> 0.16) + omniauth (~> 1.3) + pyu-ruby-sasl (>= 0.0.3.3, < 0.1) + rubyntlm (~> 0.5) + globalid (0.4.1) + activesupport (>= 4.2.0) + gollum-grit_adapter (1.0.1) + gitlab-grit (~> 2.7, >= 2.7.1) + gollum-lib (4.2.7) + gemojione (~> 3.2) + github-markup (~> 1.6) + gollum-grit_adapter (~> 1.0) + nokogiri (>= 1.6.1, < 2.0) + rouge (~> 2.1) + sanitize (~> 2.1) + stringex (~> 2.6) + gollum-rugged_adapter (0.4.4) + mime-types (>= 1.15) + rugged (~> 0.25) + gon (6.1.0) + actionpack (>= 3.0) + json + multi_json + request_store (>= 1.0) + google-api-client (0.19.8) + addressable (~> 2.5, >= 2.5.1) + googleauth (>= 0.5, < 0.7.0) + httpclient (>= 2.8.1, < 3.0) + mime-types (~> 3.0) + representable (~> 3.0) + retriable (>= 2.0, < 4.0) + google-protobuf (3.5.1) + googleapis-common-protos-types (1.0.1) + google-protobuf (~> 3.0) + googleauth (0.6.2) + faraday (~> 0.12) + jwt (>= 1.4, < 3.0) + logging (~> 2.0) + memoist (~> 0.12) + multi_json (~> 1.11) + os (~> 0.9) + signet (~> 0.7) + gpgme (2.0.16) + mini_portile2 (~> 2.3) + grape (1.0.2) + activesupport + builder + mustermann-grape (~> 1.0.0) + rack (>= 1.3.0) + rack-accept + virtus (>= 1.0.0) + grape-entity (0.6.1) + activesupport (>= 5.0.0) + multi_json (>= 1.3.2) + grape-route-helpers (2.1.0) + activesupport + grape (>= 0.16.0) + rake + grape_logging (1.7.0) + grape + grpc (1.10.0) + google-protobuf (~> 3.1) + googleapis-common-protos-types (~> 1.0.0) + googleauth (>= 0.5.1, < 0.7) + haml (4.0.7) + tilt + haml_lint (0.26.0) + haml (>= 4.0, < 5.1) + rainbow + rake (>= 10, < 13) + rubocop (>= 0.49.0) + sysexits (~> 1.1) + hamlit (2.6.2) + temple (~> 0.7.6) + thor + tilt + hashdiff (0.3.7) + hashie (3.5.7) + hashie-forbidden_attributes (0.1.1) + hashie (>= 3.0) + health_check (2.6.0) + rails (>= 4.0) + hipchat (1.5.4) + httparty + mimemagic + html-pipeline (2.7.1) + activesupport (>= 2) + nokogiri (>= 1.4) + html2text (0.2.1) + nokogiri (~> 1.6) + htmlentities (4.3.4) + http (2.2.2) + addressable (~> 2.3) + http-cookie (~> 1.0) + http-form_data (~> 1.0.1) + http_parser.rb (~> 0.6.0) + http-cookie (1.0.3) + domain_name (~> 0.5) + http-form_data (1.0.3) + http_parser.rb (0.6.0) + httparty (0.13.7) + json (~> 1.8) + multi_xml (>= 0.5.2) + httpclient (2.8.3) + i18n (0.9.5) + concurrent-ruby (~> 1.0) + ice_nine (0.11.2) + influxdb (0.5.3) + ipaddress (0.8.3) + jira-ruby (1.5.0) + activesupport + multipart-post + oauth (~> 0.5, >= 0.5.0) + jquery-atwho-rails (1.3.2) + json (1.8.6) + json-jwt (1.9.2) + activesupport + aes_key_wrap + bindata + securecompare + url_safe_base64 + json-schema (2.8.0) + addressable (>= 2.4) + jwt (1.5.6) + kaminari (1.1.1) + activesupport (>= 4.1.0) + kaminari-actionview (= 1.1.1) + kaminari-activerecord (= 1.1.1) + kaminari-core (= 1.1.1) + kaminari-actionview (1.1.1) + actionview + kaminari-core (= 1.1.1) + kaminari-activerecord (1.1.1) + activerecord + kaminari-core (= 1.1.1) + kaminari-core (1.1.1) + kgio (2.11.2) + knapsack (1.16.0) + rake + kubeclient (3.0.0) + http (~> 2.2.2) + recursive-open-struct (~> 1.0.4) + rest-client (~> 2.0) + launchy (2.4.3) + addressable (~> 2.3) + letter_opener (1.6.0) + launchy (~> 2.2) + letter_opener_web (1.3.3) + actionmailer (>= 3.2) + letter_opener (~> 1.0) + railties (>= 3.2) + license_finder (3.1.1) + bundler + httparty + rubyzip + thor + toml (= 0.1.2) + with_env (> 1.0) + xml-simple + licensee (8.9.2) + rugged (~> 0.24) + little-plugger (1.1.4) + locale (2.1.2) + logging (2.2.2) + little-plugger (~> 1.1) + multi_json (~> 1.10) + lograge (0.9.0) + actionpack (>= 4) + activesupport (>= 4) + railties (>= 4) + request_store (~> 1.0) + loofah (2.2.2) + crass (~> 1.0.2) + nokogiri (>= 1.5.9) + mail (2.7.0) + mini_mime (>= 0.1.1) + mail_room (0.9.1) + memoist (0.16.0) + memoizable (0.4.2) + thread_safe (~> 0.3, >= 0.3.1) + method_source (0.9.0) + mime-types (3.1) + mime-types-data (~> 3.2015) + mime-types-data (3.2016.0521) + mimemagic (0.3.2) + mini_mime (1.0.0) + mini_portile2 (2.3.0) + minitest (5.7.0) + mousetrap-rails (1.4.6) + multi_json (1.13.1) + multi_xml (0.6.0) + multipart-post (2.0.0) + mustermann (1.0.2) + mustermann-grape (1.0.0) + mustermann (~> 1.0.0) + mysql2 (0.4.10) + net-ldap (0.16.1) + net-ssh (4.2.0) + netrc (0.11.0) + nio4r (2.2.0) + nokogiri (1.8.2) + mini_portile2 (~> 2.3.0) + numerizer (0.1.1) + oauth (0.5.4) + oauth2 (1.4.0) + faraday (>= 0.8, < 0.13) + jwt (~> 1.0) + multi_json (~> 1.3) + multi_xml (~> 0.5) + rack (>= 1.2, < 3) + octokit (4.8.0) + sawyer (~> 0.8.0, >= 0.5.3) + omniauth (1.8.1) + hashie (>= 3.4.6, < 3.6.0) + rack (>= 1.6.2, < 3) + omniauth-auth0 (2.0.0) + omniauth-oauth2 (~> 1.4) + omniauth-authentiq (0.3.1) + omniauth-oauth2 (~> 1.3, >= 1.3.1) + omniauth-azure-oauth2 (0.0.9) + jwt (~> 1.0) + omniauth (~> 1.0) + omniauth-oauth2 (~> 1.4) + omniauth-cas3 (1.1.4) + addressable (~> 2.3) + nokogiri (~> 1.7, >= 1.7.1) + omniauth (~> 1.2) + omniauth-facebook (4.0.0) + omniauth-oauth2 (~> 1.2) + omniauth-github (1.1.2) + omniauth (~> 1.0) + omniauth-oauth2 (~> 1.1) + omniauth-gitlab (1.0.3) + omniauth (~> 1.0) + omniauth-oauth2 (~> 1.0) + omniauth-google-oauth2 (0.5.3) + jwt (>= 1.5) + omniauth (>= 1.1.1) + omniauth-oauth2 (>= 1.5) + omniauth-jwt (0.0.2) + jwt + omniauth (~> 1.1) + omniauth-kerberos (0.3.0) + omniauth-multipassword + timfel-krb5-auth (~> 0.8) + omniauth-multipassword (0.4.2) + omniauth (~> 1.0) + omniauth-oauth (1.1.0) + oauth + omniauth (~> 1.0) + omniauth-oauth2 (1.5.0) + oauth2 (~> 1.1) + omniauth (~> 1.2) + omniauth-oauth2-generic (0.2.4) + omniauth-oauth2 (~> 1.0) + omniauth-saml (1.10.0) + omniauth (~> 1.3, >= 1.3.2) + ruby-saml (~> 1.7) + omniauth-shibboleth (1.2.1) + omniauth (>= 1.0.0) + omniauth-twitter (1.4.0) + omniauth-oauth (~> 1.1) + rack + omniauth_crowd (2.2.3) + activesupport + nokogiri (>= 1.4.4) + omniauth (~> 1.0) + org-ruby (0.9.12) + rubypants (~> 0.2) + orm_adapter (0.5.0) + os (0.9.6) + parallel (1.12.1) + parser (2.5.0.5) + ast (~> 2.4.0) + parslet (1.5.0) + blankslate (~> 2.0) + path_expander (1.0.2) + peek (1.0.1) + concurrent-ruby (>= 0.9.0) + concurrent-ruby-ext (>= 0.9.0) + railties (>= 4.0.0) + peek-gc (0.0.2) + peek + peek-mysql2 (1.1.0) + atomic (>= 1.0.0) + mysql2 + peek + peek-performance_bar (1.3.1) + peek (>= 0.1.0) + peek-pg (1.3.0) + concurrent-ruby + concurrent-ruby-ext + peek + pg + peek-rblineprof (0.2.0) + peek + rblineprof + peek-redis (1.2.0) + atomic (>= 1.0.0) + peek + redis + peek-sidekiq (1.0.3) + atomic (>= 1.0.0) + peek + sidekiq + pg (0.18.4) + po_to_json (1.0.1) + json (>= 1.6.0) + posix-spawn (0.3.13) + powerpack (0.1.1) + premailer (1.11.1) + addressable + css_parser (>= 1.6.0) + htmlentities (>= 4.0.0) + premailer-rails (1.9.7) + actionmailer (>= 3, < 6) + premailer (~> 1.7, >= 1.7.9) + proc_to_ast (0.1.0) + coderay + parser + unparser + procto (0.0.3) + prometheus-client-mmap (0.9.1) + pry (0.11.3) + coderay (~> 1.1.0) + method_source (~> 0.9.0) + pry-byebug (3.4.3) + byebug (>= 9.0, < 9.1) + pry (~> 0.10) + pry-rails (0.3.6) + pry (>= 0.10.4) + public_suffix (3.0.2) + pyu-ruby-sasl (0.0.3.3) + rack (2.0.4) + rack-accept (0.4.5) + rack (>= 0.4) + rack-attack (4.4.1) + rack + rack-cors (1.0.2) + rack-oauth2 (1.2.3) + activesupport (>= 2.3) + attr_required (>= 0.0.5) + httpclient (>= 2.4) + multi_json (>= 1.3.6) + rack (>= 1.1) + rack-protection (2.0.1) + rack + rack-proxy (0.6.4) + rack + rack-test (0.6.3) + rack (>= 1.0) + rails (5.0.6) + actioncable (= 5.0.6) + actionmailer (= 5.0.6) + actionpack (= 5.0.6) + actionview (= 5.0.6) + activejob (= 5.0.6) + activemodel (= 5.0.6) + activerecord (= 5.0.6) + activesupport (= 5.0.6) + bundler (>= 1.3.0) + railties (= 5.0.6) + sprockets-rails (>= 2.0.0) + rails-deprecated_sanitizer (1.0.3) + activesupport (>= 4.2.0.alpha) + rails-dom-testing (2.0.3) + activesupport (>= 4.2.0) + nokogiri (>= 1.6) + rails-html-sanitizer (1.0.3) + loofah (~> 2.0) + rails-i18n (5.1.1) + i18n (>= 0.7, < 2) + railties (>= 5.0, < 6) + railties (5.0.6) + actionpack (= 5.0.6) + activesupport (= 5.0.6) + method_source + rake (>= 0.8.7) + thor (>= 0.18.1, < 2.0) + rainbow (2.2.2) + rake + raindrops (0.19.0) + rake (12.3.0) + rb-fsevent (0.10.3) + rb-inotify (0.9.10) + ffi (>= 0.5.0, < 2) + rblineprof (0.3.7) + debugger-ruby_core_source (~> 1.3) + rbnacl (4.0.2) + ffi + rbnacl-libsodium (1.0.16) + rbnacl (>= 3.0.1) + rdoc (4.3.0) + re2 (1.1.1) + recaptcha (3.4.0) + json + recursive-open-struct (1.0.5) + redcarpet (3.4.0) + redis (3.3.5) + redis-actionpack (5.0.2) + actionpack (>= 4.0, < 6) + redis-rack (>= 1, < 3) + redis-store (>= 1.1.0, < 2) + redis-activesupport (5.0.4) + activesupport (>= 3, < 6) + redis-store (>= 1.3, < 2) + redis-namespace (1.5.3) + redis (~> 3.0, >= 3.0.4) + redis-rack (2.0.4) + rack (>= 1.5, < 3) + redis-store (>= 1.2, < 2) + redis-rails (5.0.2) + redis-actionpack (>= 5.0, < 6) + redis-activesupport (>= 5.0, < 6) + redis-store (>= 1.2, < 2) + redis-store (1.4.1) + redis (>= 2.2, < 5) + representable (3.0.4) + declarative (< 0.1.0) + declarative-option (< 0.2.0) + uber (< 0.2.0) + request_store (1.4.0) + rack (>= 1.4) + responders (2.4.0) + actionpack (>= 4.2.0, < 5.3) + railties (>= 4.2.0, < 5.3) + rest-client (2.0.2) + http-cookie (>= 1.0.2, < 2.0) + mime-types (>= 1.16, < 4.0) + netrc (~> 0.8) + retriable (3.1.1) + rinku (2.0.4) + rotp (2.1.2) + rouge (2.2.1) + rqrcode (0.10.1) + chunky_png (~> 1.0) + rqrcode-rails3 (0.1.7) + rqrcode (>= 0.4.2) + rspec (3.6.0) + rspec-core (~> 3.6.0) + rspec-expectations (~> 3.6.0) + rspec-mocks (~> 3.6.0) + rspec-core (3.6.0) + rspec-support (~> 3.6.0) + rspec-expectations (3.6.0) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.6.0) + rspec-mocks (3.6.0) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.6.0) + rspec-parameterized (0.4.0) + binding_of_caller + parser + proc_to_ast + rspec (>= 2.13, < 4) + unparser + rspec-rails (3.6.1) + actionpack (>= 3.0) + activesupport (>= 3.0) + railties (>= 3.0) + rspec-core (~> 3.6.0) + rspec-expectations (~> 3.6.0) + rspec-mocks (~> 3.6.0) + rspec-support (~> 3.6.0) + rspec-retry (0.4.6) + rspec-core + rspec-set (0.1.3) + rspec-support (3.6.0) + rspec_profiling (0.0.5) + activerecord + pg + rails + sqlite3 + rubocop (0.52.1) + parallel (~> 1.10) + parser (>= 2.4.0.2, < 3.0) + powerpack (~> 0.1) + rainbow (>= 2.2.2, < 4.0) + ruby-progressbar (~> 1.7) + unicode-display_width (~> 1.0, >= 1.0.1) + rubocop-gitlab-security (0.1.1) + rubocop (>= 0.51) + rubocop-rspec (1.22.2) + rubocop (>= 0.52.1) + ruby-enum (0.7.2) + i18n + ruby-fogbugz (0.2.1) + crack (~> 0.4) + ruby-prof (0.17.0) + ruby-progressbar (1.9.0) + ruby-saml (1.7.2) + nokogiri (>= 1.5.10) + ruby_parser (3.11.0) + sexp_processor (~> 4.9) + rubyntlm (0.6.2) + rubypants (0.7.0) + rubyzip (1.2.1) + rufus-scheduler (3.4.2) + et-orbi (~> 1.0) + rugged (0.27.0) + safe_yaml (1.0.4) + sanitize (2.1.0) + nokogiri (>= 1.4.4) + sass (3.5.5) + sass-listen (~> 4.0.0) + sass-listen (4.0.0) + rb-fsevent (~> 0.9, >= 0.9.4) + rb-inotify (~> 0.9, >= 0.9.7) + sass-rails (5.0.7) + railties (>= 4.0.0, < 6) + sass (~> 3.1) + sprockets (>= 2.8, < 4.0) + sprockets-rails (>= 2.0, < 4.0) + tilt (>= 1.1, < 3) + sawyer (0.8.1) + addressable (>= 2.3.5, < 2.6) + faraday (~> 0.8, < 1.0) + scss_lint (0.56.0) + rake (>= 0.9, < 13) + sass (~> 3.5.3) + securecompare (1.0.0) + seed-fu (2.3.7) + activerecord (>= 3.1) + activesupport (>= 3.1) + select2-rails (3.5.10) + thor (~> 0.14) + selenium-webdriver (3.11.0) + childprocess (~> 0.5) + rubyzip (~> 1.2) + sentry-raven (2.7.2) + faraday (>= 0.7.6, < 1.0) + settingslogic (2.0.9) + sexp_processor (4.10.1) + sham_rack (1.3.6) + rack + shoulda-matchers (3.1.2) + activesupport (>= 4.0.0) + sidekiq (5.1.1) + concurrent-ruby (~> 1.0) + connection_pool (~> 2.2, >= 2.2.0) + rack-protection (>= 1.5.0) + redis (>= 3.3.5, < 5) + sidekiq-cron (0.6.3) + rufus-scheduler (>= 3.3.0) + sidekiq (>= 4.2.1) + sidekiq-limit_fetch (3.4.0) + sidekiq (>= 4) + signet (0.8.1) + addressable (~> 2.3) + faraday (~> 0.9) + jwt (>= 1.5, < 3.0) + multi_json (~> 1.10) + simple_po_parser (1.1.3) + simplecov (0.14.1) + docile (~> 1.1.0) + json (>= 1.8, < 3) + simplecov-html (~> 0.10.0) + simplecov-html (0.10.2) + slack-notifier (1.5.1) + spinach (0.10.1) + colorize + gherkin-ruby (>= 0.3.2) + json + spinach-rails (0.2.1) + capybara (>= 2.0.0) + railties (>= 3) + spinach (>= 0.4) + spinach-rerun-reporter (0.0.2) + spinach (~> 0.8) + spring (2.0.2) + activesupport (>= 4.2) + spring-commands-rspec (1.0.4) + spring (>= 0.9.1) + spring-commands-spinach (1.1.0) + spring (>= 0.9.1) + sprockets (3.7.1) + concurrent-ruby (~> 1.0) + rack (> 1, < 3) + sprockets-rails (3.2.1) + actionpack (>= 4.0) + activesupport (>= 4.0) + sprockets (>= 3.0.0) + sqlite3 (1.3.13) + sshkey (1.9.0) + stackprof (0.2.11) + state_machines (0.5.0) + state_machines-activemodel (0.5.1) + activemodel (>= 4.1, < 6.0) + state_machines (>= 0.5.0) + state_machines-activerecord (0.5.1) + activerecord (>= 4.1, < 6.0) + state_machines-activemodel (>= 0.5.0) + stringex (2.8.4) + sys-filesystem (1.1.9) + ffi + sysexits (1.2.0) + temple (0.7.7) + test-prof (0.2.5) + text (1.3.1) + thin (1.7.2) + daemons (~> 1.0, >= 1.0.9) + eventmachine (~> 1.0, >= 1.0.4) + rack (>= 1, < 3) + thor (0.19.4) + thread_safe (0.3.6) + tilt (2.0.8) + timecop (0.8.1) + timfel-krb5-auth (0.8.3) + toml (0.1.2) + parslet (~> 1.5.0) + toml-rb (1.0.0) + citrus (~> 3.0, > 3.0) + truncato (0.7.10) + htmlentities (~> 4.3.1) + nokogiri (~> 1.8.0, >= 1.7.0) + tzinfo (1.2.5) + thread_safe (~> 0.1) + u2f (0.2.1) + uber (0.1.0) + uglifier (2.7.2) + execjs (>= 0.3.0) + json (>= 1.8.0) + unf (0.1.4) + unf_ext + unf_ext (0.0.7.5) + unicode-display_width (1.3.0) + unicorn (5.1.0) + kgio (~> 2.6) + raindrops (~> 0.7) + unicorn-worker-killer (0.4.4) + get_process_mem (~> 0) + unicorn (>= 4, < 6) + uniform_notifier (1.10.0) + unparser (0.2.7) + abstract_type (~> 0.0.7) + adamantium (~> 0.2.0) + concord (~> 0.1.5) + diff-lcs (~> 1.3) + equalizer (~> 0.0.9) + parser (>= 2.3.1.2, < 2.6) + procto (~> 0.0.2) + url_safe_base64 (0.2.2) + validates_hostname (1.0.8) + activerecord (>= 3.0) + activesupport (>= 3.0) + version_sorter (2.1.0) + virtus (1.0.5) + axiom-types (~> 0.1) + coercible (~> 1.0) + descendants_tracker (~> 0.0, >= 0.0.3) + equalizer (~> 0.0, >= 0.0.9) + vmstat (2.3.0) + warden (1.2.7) + rack (>= 1.0) + webmock (2.3.2) + addressable (>= 2.3.6) + crack (>= 0.3.2) + hashdiff + webpack-rails (0.9.11) + railties (>= 3.2.0) + websocket-driver (0.6.5) + websocket-extensions (>= 0.1.0) + websocket-extensions (0.1.3) + wikicloth (0.8.1) + builder + expression_parser + rinku + with_env (1.1.0) + xml-simple (1.1.5) + xpath (3.0.0) + nokogiri (~> 1.8) + +PLATFORMS + ruby + +DEPENDENCIES + RedCloth (~> 4.3.2) + ace-rails-ap (~> 4.1.0) + activerecord_sane_schema_dumper (= 1.0) + acts-as-taggable-on (~> 5.0) + addressable (~> 2.5.2) + akismet (~> 2.0) + allocations (~> 1.0) + asana (~> 0.6.0) + asciidoctor (~> 1.5.6) + asciidoctor-plantuml (= 0.0.8) + asset_sync (~> 2.2.0) + attr_encrypted (~> 3.0.0) + awesome_print (~> 1.2.0) + babosa (~> 1.0.2) + base32 (~> 0.3.0) + batch-loader (~> 1.2.1) + bcrypt_pbkdf (~> 1.0) + benchmark-ips (~> 2.3.0) + better_errors (~> 2.1.0) + binding_of_caller (~> 0.7.2) + bootstrap-sass (~> 3.3.0) + bootstrap_form (~> 2.7.0) + brakeman (~> 4.2) + browser (~> 2.2) + bullet (~> 5.5.0) + bundler-audit (~> 0.5.0) + capybara (~> 2.15) + capybara-screenshot (~> 1.0.0) + carrierwave (~> 1.2) + charlock_holmes (~> 0.7.5) + chronic (~> 0.10.2) + chronic_duration (~> 0.10.6) + commonmarker (~> 0.17) + concurrent-ruby (~> 1.0.5) + connection_pool (~> 2.0) + creole (~> 0.5.0) + d3_rails (~> 3.5.0) + database_cleaner (~> 1.5.0) + deckar01-task_list (= 2.0.0) + default_value_for (~> 3.0.5) + devise (~> 4.2) + devise-two-factor (~> 3.0.0) + diffy (~> 3.1.0) + doorkeeper (~> 4.3) + doorkeeper-openid_connect (~> 1.3) + dropzonejs-rails (~> 0.7.1) + email_reply_trimmer (~> 0.1) + email_spec (~> 1.6.0) + factory_bot_rails (~> 4.8.2) + faraday (~> 0.12) + fast_blank + ffaker (~> 2.4) + flay (~> 2.10.0) + flipper (~> 0.13.0) + flipper-active_record (~> 0.13.0) + flipper-active_support_cache_store (~> 0.13.0) + fog-aliyun (~> 0.2.0) + fog-aws (~> 2.0.1) + fog-core (~> 1.44) + fog-google (~> 1.3.3) + fog-local (~> 0.3) + fog-openstack (~> 0.1) + fog-rackspace (~> 0.1.1) + font-awesome-rails (~> 4.7) + foreman (~> 0.84.0) + fuubar (~> 2.2.0) + gemnasium-gitlab-service (~> 0.2) + gemojione (~> 3.3) + gettext (~> 3.2.2) + gettext_i18n_rails (~> 1.8.0) + gettext_i18n_rails_js (~> 1.3) + gitaly-proto (~> 0.94.0) + github-linguist (~> 5.3.3) + gitlab-flowdock-git-hook (~> 1.0.1) + gitlab-markup (~> 1.6.2) + gitlab-styles (~> 2.3) + gitlab_omniauth-ldap (~> 2.0.4) + gollum-lib (~> 4.2) + gollum-rugged_adapter (~> 0.4.4) + gon (~> 6.1.0) + google-api-client (~> 0.19.8) + google-protobuf (= 3.5.1) + gpgme + grape (~> 1.0) + grape-entity (~> 0.6.0) + grape-route-helpers (~> 2.1.0) + grape_logging (~> 1.7) + grpc (~> 1.10.0) + haml_lint (~> 0.26.0) + hamlit (~> 2.6.1) + hashie-forbidden_attributes + health_check (~> 2.6.0) + hipchat (~> 1.5.0) + html-pipeline (~> 2.7.1) + html2text + httparty (~> 0.13.3) + influxdb (~> 0.2) + jira-ruby (~> 1.4) + jquery-atwho-rails (~> 1.3.2) + json-schema (~> 2.8.0) + jwt (~> 1.5.6) + kaminari (~> 1.0) + knapsack (~> 1.16) + kubeclient (~> 3.0) + letter_opener_web (~> 1.3.0) + license_finder (~> 3.1) + licensee (~> 8.9) + lograge (~> 0.5) + loofah (~> 2.2) + mail_room (~> 0.9.1) + method_source (~> 0.8) + minitest (~> 5.7.0) + mousetrap-rails (~> 1.4.6) + mysql2 (~> 0.4.10) + net-ldap + net-ssh (~> 4.2.0) + nokogiri (~> 1.8.2) + oauth2 (~> 1.4) + octokit (~> 4.8) + omniauth (~> 1.8) + omniauth-auth0 (~> 2.0.0) + omniauth-authentiq (~> 0.3.1) + omniauth-azure-oauth2 (~> 0.0.9) + omniauth-cas3 (~> 1.1.4) + omniauth-facebook (~> 4.0.0) + omniauth-github (~> 1.1.1) + omniauth-gitlab (~> 1.0.2) + omniauth-google-oauth2 (~> 0.5.3) + omniauth-jwt (~> 0.0.2) + omniauth-kerberos (~> 0.3.0) + omniauth-oauth2-generic (~> 0.2.2) + omniauth-saml (~> 1.10) + omniauth-shibboleth (~> 1.2.0) + omniauth-twitter (~> 1.4) + omniauth_crowd (~> 2.2.0) + org-ruby (~> 0.9.12) + peek (~> 1.0.1) + peek-gc (~> 0.0.2) + peek-mysql2 (~> 1.1.0) + peek-performance_bar (~> 1.3.0) + peek-pg (~> 1.3.0) + peek-rblineprof (~> 0.2.0) + peek-redis (~> 1.2.0) + peek-sidekiq (~> 1.0.3) + pg (~> 0.18.2) + premailer-rails (~> 1.9.7) + prometheus-client-mmap (~> 0.9.1) + pry-byebug (~> 3.4.1) + pry-rails (~> 0.3.4) + rack-attack (~> 4.4.1) + rack-cors (~> 1.0.0) + rack-oauth2 (~> 1.2.1) + rack-proxy (~> 0.6.0) + rails (= 5.0.6) + rails-deprecated_sanitizer (~> 1.0.3) + rails-i18n (~> 5.1) + rainbow (~> 2.2) + raindrops (~> 0.18) + rblineprof (~> 0.3.6) + rbnacl (~> 4.0) + rbnacl-libsodium + rdoc (~> 4.2) + re2 (~> 1.1.1) + recaptcha (~> 3.0) + redcarpet (~> 3.4) + redis (~> 3.2) + redis-namespace (~> 1.5.2) + redis-rails (~> 5.0.2) + request_store (~> 1.3) + responders (~> 2.0) + rouge (~> 2.0) + rqrcode-rails3 (~> 0.1.7) + rspec-parameterized + rspec-rails (~> 3.6.0) + rspec-retry (~> 0.4.5) + rspec-set (~> 0.1.3) + rspec_profiling (~> 0.0.5) + rubocop (~> 0.52.1) + rubocop-rspec (~> 1.22.1) + ruby-fogbugz (~> 0.2.1) + ruby-prof (~> 0.17.0) + ruby_parser (~> 3.8) + rufus-scheduler (~> 3.4) + rugged (~> 0.27) + sanitize (~> 2.0) + sass-rails (~> 5.0.6) + scss_lint (~> 0.56.0) + seed-fu (~> 2.3.7) + select2-rails (~> 3.5.9) + selenium-webdriver (~> 3.5) + sentry-raven (~> 2.7) + settingslogic (~> 2.0.9) + sham_rack (~> 1.3.6) + shoulda-matchers (~> 3.1.2) + sidekiq (~> 5.0) + sidekiq-cron (~> 0.6.0) + sidekiq-limit_fetch (~> 3.4) + simple_po_parser (~> 1.1.2) + simplecov (~> 0.14.0) + slack-notifier (~> 1.5.1) + spinach-rails (~> 0.2.1) + spinach-rerun-reporter (~> 0.0.2) + spring (~> 2.0.0) + spring-commands-rspec (~> 1.0.4) + spring-commands-spinach (~> 1.1.0) + sprockets (~> 3.7.0) + sshkey (~> 1.9.0) + stackprof (~> 0.2.10) + state_machines-activerecord (~> 0.5.1) + sys-filesystem (~> 1.1.6) + test-prof (~> 0.2.5) + thin (~> 1.7.0) + timecop (~> 0.8.0) + toml-rb (~> 1.0.0) + truncato (~> 0.7.9) + u2f (~> 0.2.1) + uglifier (~> 2.7.2) + unf (~> 0.1.4) + unicorn (~> 5.1.0) + unicorn-worker-killer (~> 0.4.4) + validates_hostname (~> 1.0.6) + version_sorter (~> 2.1.0) + virtus (~> 1.0.1) + vmstat (~> 2.3.0) + webmock (~> 2.3.2) + webpack-rails (~> 0.9.10) + wikicloth (= 0.8.1) + +BUNDLED WITH + 1.16.1 diff --git a/PROCESS.md b/PROCESS.md index 5ae191840f..f206506f7c 100644 --- a/PROCESS.md +++ b/PROCESS.md @@ -53,7 +53,7 @@ Below we describe the contributing process to GitLab for two reasons: Several people from the [GitLab team][team] are helping community members to get their contributions accepted by meeting our [Definition of done][done]. -What you can expect from them is described at https://about.gitlab.com/jobs/merge-request-coach/. +What you can expect from them is described at https://about.gitlab.com/roles/merge-request-coach/. ## Assigning issues @@ -202,6 +202,9 @@ you can ask for an exception to be made. Go to [Release tasks issue tracker](https://gitlab.com/gitlab-org/release/tasks/issues/new) and create an issue using the `Exception-request` issue template. +**Do not** set the relevant `Pick into X.Y` label (see above) before request an +exception; this should be done after the exception is approved. + You can find who is who on the [team page](https://about.gitlab.com/team/). Whether an exception is made is determined by weighing the benefit and urgency of the change diff --git a/Procfile b/Procfile index cad738d429..1776fd9794 100644 --- a/Procfile +++ b/Procfile @@ -4,4 +4,3 @@ # web: RAILS_ENV=development bin/web start_foreground worker: RAILS_ENV=development bin/background_jobs start_foreground -# mail_room: bundle exec mail_room -q -c config/mail_room.yml diff --git a/VERSION b/VERSION index cac93e55f5..992a0120b2 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -10.6.5 +10.7.3 diff --git a/app/assets/images/ci_favicons/canary/favicon_status_canceled.ico b/app/assets/images/ci_favicons/canary/favicon_status_canceled.ico new file mode 100644 index 0000000000000000000000000000000000000000..48b1095370d446df1f3107565b1c5e72c0128c7d GIT binary patch literal 4286 zcmb`Je@t6d6vrQ##y>GJ(Fmo`Qu@ju;IbISe}L%7Lgt_Rq5g%2Kb9B-GvfLK)++N4 zl`M);853LW{^<}q-Jr_ZO)dyzT^2mc1 zd(Zitd(Qn)LCE93k`e*`g|8kLgeL_-aItWgP{)FPrSRBJm!_tsUFGHFjZUYt&*gH> zar>4iiZQN3T#s}A+Z7cR)}7|U9`g<`;~F!lva&MS+}uoFua~;JyQ!_MjT#ynB#iOA z1lPS>Kd}>jV9ji+2e#|$>!s1rQHsT4WL6dz7s>5*6Z29}$G7#o2x6Jsi6ZEP$CdC!@MP{GAM-Jb4g+Dz#t>Zrk z8wPM!^BI^k@?C@SIq{+-D{NkS*>IffXQE{Pd_m#&_V()dfj~g%-`vm2nKR3`Rta}C z-V4_0Q~9OCMO3a*2iG^);15Ts?1e^pXY80f)9v8rgcLJ?*-m0-h0=ScMS2qbU)sT z590|cJ^k-}HuFn9T%`j4&m4pORQ=4JZO`GBb0!VESy(&g{s7kQx*#QV>qgE8|I@Lt z{=#>!DEz`h-;!9hmulc2<+~&DfV7k1A}eA5!$@u;K&a zfLv(zgUON!?*-m0usQBSi2DYe*MBN`ROLI*r?Rnj+eZ-{A3h)s$OUX-PvTtQY~p^v z9ff-mcQy7#`R?5$x+?JYA5yt$y|<6@aleT_aLxzsq{JQkqW7+*@YPsgPvTs_4>NJ? zd6t~7du8zzf0fEK*3O{xr(^J*DcjzEJ1txF0k!?uf^tVW-s&gE!B5E1@g2XXgozv@PtaN>r&Y4(>4d2z9>E>(u zi#^v*8g;Fn`CqhiGPSLqKYlXWV7tSa^e}GmhaCm}%eoxc+)Hm{qpQxbA6|M*&%Z1? zIztuec&56jbM|jlzp(39iSLrUOghH#!mg==YQy5YvSu9L?z`Bta8}i|dVinYZf?3U zt8acvwZZnzrJHBgZ+mCCx*)KTgObBHvi@zVwN>K2aZu$uyvxsP$Fga24x$BJQ%SxT zAI)aIaZXc^c5x0Qi|@C)#<6U^i`~};tls&_Z04q$gLA-k&ZHaH_7e%UBn$Zz6CPvP zMQcJHEh!?rgu31T9!4Fn!stFc93m5EByl0SnmSVpk)GBghqIQCoj;OLkYZTg) KC`IWG#p!=)nEBZN literal 0 HcmV?d00001 diff --git a/app/assets/images/ci_favicons/canary/favicon_status_created.ico b/app/assets/images/ci_favicons/canary/favicon_status_created.ico new file mode 100644 index 0000000000000000000000000000000000000000..623c728faf6981b0b21af20b6b351ddd277fffb7 GIT binary patch literal 4286 zcmb`JUrbwd6vr}8le;l9c^Ob%zW{Uy_o1SABl-R_@K$+%aR$5qx@M>G4ao0 z%zPNz+y*Q`na=rVL6mG{wzQ>X$e%!=g|+-!g)u1`(9+v`Jl{*NyS=^rL&lFBe!ain z`JK->=l46mdj+A0|0*j5{1?7^QV^aN1i{L}L&8B8jLVJZ_PP;KvBTjw=WxtEc5Kc{zvtJ?R0=03cNKtE;QT=bVrm2k8f=k&sh3I=~!=A=4khGa&j^+A3oqr zsvGVo9*Qa;r zblsI1b8~ZAQ#3L%l9P|xR5#q!cwaETP2pE}lG*yB7*V)#-@Prf!LRC!Qb&)A2ECcF z;9k@70p||2scov99RlBSo{rY^B*ZlKZ=ClI=7J459i_U{J9QR`M6@R5XV}Ggz?no{ zXln&Zr~|ySIQ9vCESB?q<6*vKANmqheR1OSChiB^QP_Lj)p%bxoKCv=ms8}NzprqW{>3&b!To0Gsi@~59kkExGUdL zM}C>5qrV2}t*c>r^@lrT>DVC4WpPoUv&C~v_u&q2>X7@1oFKyY`gUaK#3;s4$+p4U;{jS0{ zH!QrQo-5=x??JS**_Y&d@$o|RwK{d(RLpxI8XEt8pq(q^xuQOB-q_&x6r!6=2X(-9 zE@hinj}r;CBnc%H6P{oxrZu66Lb3?dFYJh&dtM~6;DZ&1s-MNq!VPB>?=wgVONCt! aYGpamU)xWi6N-drjlwC3Qk3pfoc;s0mi`_9 literal 0 HcmV?d00001 diff --git a/app/assets/images/ci_favicons/canary/favicon_status_failed.ico b/app/assets/images/ci_favicons/canary/favicon_status_failed.ico new file mode 100644 index 0000000000000000000000000000000000000000..3073fe5a761ba1825bfbab4337a0eacf36b848c9 GIT binary patch literal 4286 zcmb_eZ%kWN6n_MbA2Bh}2&M2|3vIH*eNYqQTK>eD7=m9^vP2UrvXH8Kp}Fo)Xa^w^|(X zh{Y){N=|u|%|6K?_el=-Cz8Ws-fCRvV|q(1PWM0J4ma6~J(0J|r>XL*S!&!rPaoF% zsd$%90ng%ahnYP;*k77@Vk_+6XLfj6pxgO|S2=Zdg;s-6G8!IVi1vOtOUxHhYk@qO z@3_AGVQpZ(J_78jujeQfHbRYG8ydYw&y`LnlGAKW|E8ory~U|qW&q~}W~sHHtVPRL2bP;z?8Q}sb!iSK2|obFrM zz)&ALjxTe4;KPRTb!@!D1|vVfjrTq50513-d$G)CV8aha z1NDLV)0Yh2-leqJ`jn`(@)p+_xE(Q4$Jfdm{V_Jc4~Yh96mmHczSvGr*-k_}w)0`K z{T?Q9?=07Sb51c-sm5FN0cLGJ=!H-x+4&cZ@a+fbP1|oukYk?3nDDvQ4~c9*twz7lQCV zJZ-$ye89a3>QV-^8vO$IS;e<>lhyvS;#YC`+#6cM27WigC>f`sU0#Y9qyTJyAG8Da zVsa+FK%-y4SLmC-w{_A-`DemP4EC?g??)Ieut7fs$n^dYmpgVkpoQ7gbBLLPo`t@N zKF0lh{=UDt4Siv<9KL%Wo8jj+&rqi8Pv(QGv~8!H@E#^J20e?Po%L><-F`+1$DA86 z?_xDtJ@@*YweJeY&#JgcQt>r<@wJIf+kl?6j@<%mjQrz@ti{hes)_kJwxun=v2lKo zsr(YR0e(O%jPgP22lNZ{EMTK|!|!Y8?EHr!O)7r=FY(y$gZQmK1|K%S4~PYHA}9BE zED-J{>H}&N>LhA4`h~TC=bB>KA@5Of)%n?0%0PXyon-(wMc(ezG~cZg@eJ&#J$KMxT~UM$gZx9}KHHOtn{*_526D=Tyr_RatY* z)!_&2O~fvGD!#R5>IE$?m1h=% zKxX}5gw@4IQ`xWIQ`SrAEC!0H_U}7-UMlZ7Rqjr6&DcOHdlT)!Jz#oz67jX`L_#4& zg$!C19%GbF%R(A?ISJG+tdWb&Oh{pb4^|{qKO+|-Hjty}XP^v5IW9pcKdAmId3k!pyqoZ@RT5X$7r<=v~ z8qf1~oGmzy;Qq(4v9YS%#wB}*mxma45Ch`k;+)0B#h};gp|Pz8X0+8rwlgy`g@J(qu-on6Z7eJ-Ky`IBpr0<(xsS0(cu^nFRwrQ_3V9`O8*=eZXd85u7j_CJ-Cl`?y4Yip34oXju@*BkZp^vHCmCU@j21C2rS z+gXQ5XJ}|hW{W;bOG`z2kd~GP1qB6kKKI_t%#4Q)-A&BHNFez9IXKMM_S*@cd>04R zzR6^Qg9i^Xtg^B)a5x-{JvKH*d1m{qt*v0ST17QBQ-7cy{udlC{!m~b!=U?-NuR90t^FzWW!@hyom!5#eaE;lTnwpZ? zp%02X#UUvv3A($xVRUp9ii(Qd*vhz&4)toRky$0auETYezah97HlBT7*Cs?>wn5}K z^UNOIE9qEYU#Fhp#**ekTvLCR4vG!E7sziD@uRvxqx)X4inwg<+uFt^{4N{pdnXs( zJ(LYjr&DSU>gwtsH8mB=%gf!lz`G4uSy>Ph69dD;!!mjDhkV2M=Mp}D0V=fD9fAz| z2aJ0s;u1E|w>D4}pJsY}eSI=}^dZ(|ettfa85|sBZ-esg(Vd|;3v2HVd&el=qfg__ zd>C;+)TMu)Vk3UU7Y`uV_zTA1FeJRSUv>|r&aAGkvfk_KU7|OO&W^dyqqFO-3l7=2 zDd!yq?Q_EBeT z44ckR6jt8Fe4sc`E|m2k#iTX87xZQkHpab^;=YZJ=fCJYCE{zZd1BMq)n8g=_~Zk{ zfpS4MsV3=O(A}i|K(#=9l6p107tvUQye^jB{^KI9I48EjUg~fBPnh$LM;>t}{IE~w zJn+R>P)*XkAV0j3Za?;*BYGGAo-tm;RLazQr_D)%H@kXvbo`wE7JJD@9%Gwe%30}!q`E! zzQb$guZX%T{qMJ*CF_f)GMFbt8))yUFF9}f>Z+xL;D+rSM4Y@A@NZM8t%&M-M@4*% zekobX3uKKsum#smI z`{GOY0l0K)ak#WW<4q+a@E|JY&27LElovudk1KdU_}liKLB(!(kCaJP&)`3#Zdr!0hnQ&`|oK znWm~LaZM27TU%R8<3oWwU@zF_>|XbQ=QXnb=*Gr|rf(=$R#s?naZz_11E^8<71_(V z;Av0roW+rmkzIX*je6Xzp(c?dmXq1$;HItbRm_>6pVxJbGa&Q7TaMrWXOq{{nGN4` zkzRZ6ubD9Th+VIt=HlxT`=DnBJ?;nQ2Qu-^P3n15ry4ui5fHvnV|p!-k8`kFthl2% z*03Jmc!8cXU5k#HZb!)UXM~Rb>KFXY%}qVL&<_s}@8kgIaBFKz(>`8<54HH_i}aT1 zrn)KEw<1(_Wu4yqWm5RX`N`B!gR&0v?g`x0od1DTzPTxO-E>Qh2{y0&V9O?zTn*9T z)(3(=F)^WupP88vXIl=Ajg1L=zAL0^r$?RQd%^rh$uDi8GV{-BP;y1zwk6o$m$Zba zx!plMZqJS%`49?)1dDyr?CdP9uC9uE5VfdvUU5F-b$S$h(J}@w_69eK|SXdD8CH})V3-NJ%9K+hp?P?@x-PrS{jU+bK zpa01{!GGxs2X%DW$<^adivb+u0^b>}hFS!h*M0_UwDKR-(M0~i)`UHe=f3oONU*Vf z$dPZlMGVM8>RxDZksExo;_PO&$=#;&`Y%TtB)|MdIvZ;@ejQBWBL?IFdjX%QNt_Fu zP23O20q!2$)u=xk*TJ2C>?-H{L&=r>%Z+pZ_nWDM_q=H(E$`qLema=Om$^Vq;#?pO zE&1E#q|fj8Vh!!%FG^-=U*4uplr^nuvP&*3>#}7G=nr3hAnvH+zm3z0-$&`48v%O# zrx`LeuaW7R`d=zD@!i-k`(>fkOIl*ApXxVS#=gra_0xS?^Pw|-7W_7mm-<{}nSVat z>WU??1C^=vTJLQ4hMbes*SlgR*6EDDzYWy`!K8Vd(}LQ&TUsnVT|sSMIL$}R z;JluFqQ1!D`#yE9!Q$;nw8`{ru#DJJeX!q_O!F{aV4W<>vpSRZz*yyfH=DWArsS0W z?PR_)R#qE$L5^qY3v2rq)C1PjUP`P%B$brgW^;7v;J+G=&QKu{`-<&Rz3Af;#fA%ya%DY zI!~1E#V50|PqnFRqg>ttwV>wT)zq4U^ literal 0 HcmV?d00001 diff --git a/app/assets/images/ci_favicons/canary/favicon_status_pending.ico b/app/assets/images/ci_favicons/canary/favicon_status_pending.ico new file mode 100644 index 0000000000000000000000000000000000000000..ccd00606aeb39546a35b0fc902765d0a085f394d GIT binary patch literal 4286 zcmb_fYe*bd6dp;Sh0^3_C?$UiDJ_lbBWtV_ z+6Efp`iPIXYA_m_zEX@}RY<9iN*)>#MMXCnYYC06&(*mzr}vxP!P(hacQxK{ym#)o z_k8Dd&)En<691QzBjB%ab)O)l3xeR{#J7YaoUpG9&fD#Atc~`V%GuH6a#n5fio+>h z_H?h81yd@RKiSJVO%>ATsnulJZCuDRRkHUv=7Z#NkzS}|(tE#1^l6twr*BDgyhEZ_ zn;8R->mzbqF23lamv=)C*v#dghipe9V^>CHT4Q85M&^k=`9p#ZGWX4NaupqZRvq?M zuts2?>Xv9jGK7uV?3*LXtY?htvHUDLn98LufnC^}Ah1Rg|6)i7_+clpNUb3=a_hqz zlB^NCttI?`SRfy^8wcb#&ueLXVOx+89sQUN(P%=e2&o8NW@+^w&R| zoJUJUKTXK=czJVAT_GnCLz7oJov07es^}fuX&sApedn~S$m4z`7G{5ZQ&RR|tI<&2 zCa({P;5%#S-OQ^j2>gdnqosBDL-^o}VYrXlL-;2?B(pD~E%PV7gWM6EW$ch%By=kIJ?!S3QU zu3?o9TwYf2do?+xdSWN|sMY8fdVH5pzV7T|vVzTRKh(5N_T~Utn-&%P(t+sw!+U(I zmC?~(B~rOR+?DB#7Dm;>>W-={DYY8?0`FPHKiEVL*N<#Y#Z~6E4Fwzc_ND+me_@ea zJP&qWeL^~*UnuX7_f6nC>*=%Hc9BJ3-#~BSxWEQg1!(^_qsqOy2hlcdTDSEI{Q^A; zeG`35@pt#8zZD%iMLO89vWd;{bH1CUOiwTO!2<28GJc0!BZs)?S&Hqvcf)p9I};=9 zM$CO{5!kRl>)bsBKcny2)jgO5G}D)US}aVVNAh z6>?r0SzpS-K zUE2!$$MolozWKQi)H@M#Nxy9O%*OrwZ7CR@i@3*qYA(9HVT2WH&s=mT7$u|d{*zee zwfk20Se^c^#XT~hJri$jagY9~m%-&W#k&W-*)#3P^z=o~Glw%vLNUlWGnw#jQ?0C={K-=)zN28~Z7na6HIG3cvv^SA zbul@S^ZGNW?K}p|TzGd`&r9Unnm<-=DH!Qb5J&+@3YfRe@*N)>@fQ^8_u0n0ASV|lHMKw*Ib%g*lcoC~v^nVn&`mLZ3^b06nB z_ndR@S&j?BzsN|A{&N=|=eQ?1j*COVF78DX>Sqs*?eqf;sljGr!mH-Ogi@0+vEO7& zzH2rnuA7RI#<9Q6Y)txcq$F9h(_GRwWK7zJ`tO(u6JV(LCHLeHhroXIILx%41ly%N z7_Cg>X$SClSf~yJd6!PMG1$9J=;~`!{G1Tg_Y56Ab+e* z^#gd^k~yv=JF|iO@PA@qIq^yu<``hx#2C*L~C#la|l<-BMKDbtVAcfW}nc5|M`f$#TfwlI-ZEc`fi1UHY zCfyH#@O2gN@~7W5uM^)nKkmb49e56AyUH=PNvd|RoZMPX_XFKg{`heu`at)ddGjFEE|1U*O8 zb4C8LrOUg9?n%00Fy0@aj-&DDiQxAhwGN!QMM7#sJ#yUqzw=Nz!Nc8u}ouGgqxz5Pmj@wuV9n(76eXMrDG2QhI!@^*pC z-VGa!P5h`j2mDmrU$a-2QbWwQ)_u&*r*|Hn6RKHMH>r*>e|OyXH?yJ51<}>_?z52} zdE5pehTqW#X<#aOP5m4q$kvh%lZ{`&!p$ZhUs27Xy;JR`y~kbQU6OrM%xl&pY}$Wl z-fhNzF0Tb{6z+qe(zmy@!Mk5kgKE~6-;KnkC$^p+7V~$X7sY(b_t9kz#-{y~q#Uhh zHjp1!EM#>~gk(*s7gVzt8*4ZDeUpy+KkLpH_^}s#*|c|UpqHiUs7cYHqd)-*%-T{4wiinhfB}G zN97k`e^oc=a8J5Mep=2He{1t+3c?L0P!etKRG(Hqa>}pd+HNVWr#|g5dx@AQZ%627 zpAI$jc*Oe=+S<(VRQY_RZ=APZSR;Ao_IRQUHow2WHJSZ($vX6DSoX~gC6-!WSoW=T zA01f(vug9j{SkUgrF^YMZ~8+#$6s5cH(!(MK)rST*3o#FVKOGf&@G99HpBWsAZvv= zQR&wAr2KAAO!oLQ!nnV8cy`~sus$^B29K9VkiRwZ@z9)Jm!Kmo>-M62e7o-m{qT8V zttNA@Z@al_W11{eub>0en8g+7pty8H335v4DS@igiV1jC~^TV=|{+5RV1Y z#uzw4a(dl(FFqQ`eEFQz1_;I&@L^eht;oj$`Hsl2RB19zJ%P+sn?vUS^_){17xx2j z@!;Wh!8-RCN-!*PL11OVK_|B<27Kcp9)*6eQc`uI7*Oz`9Hn|jvI`}`z;W?Rj&#O% Tg7t_XR#=4bEpdPYuu8#y89IH8 literal 0 HcmV?d00001 diff --git a/app/assets/images/ci_favicons/canary/favicon_status_skipped.ico b/app/assets/images/ci_favicons/canary/favicon_status_skipped.ico new file mode 100644 index 0000000000000000000000000000000000000000..7e3be35cc3a5f869c574290f58ca1bbc6f4095ef GIT binary patch literal 4286 zcmb_eT})e59KQsOkC>Qfgi2Tc}Vmdt1zm<%m zqyeP&eLkP@pmE8b)9HK-?N1;cxLmHx`1m-4LLr!*o`zsB2*bm}BJog0!1=7l<9X^J z{Ggc8<{7f>^?Jpnr6tH@GPs>PwzjsIPbe=T&7lv6AJqr6(?!_fa2O;>$_3TfSzliV z#HM^~Jcev2{Sb z4(z$i_V#v;<&BMvy*;YQ=H}+!TKz#iinfGe&IQ_d40Tqgrl!>9ARdpCJy=*+V7%Gc zS+-tTS;>*54eCj%A=1f0b8yq{f0=ZamzQ&FilPXkqoaF1q|<2_85!Bv2RfVR^FSf^ z{6%=>-9HzSgipR}jbeSE`vLKz`S2~B;(2~Rluq_XS347dibUb@C<(~bCr!W@cvCIuHot z+)ukbcwY?3;G8g;2H83?E}48gpIMEA#56T zKZs!^{-GX4&3AKOdp^OiDSo1(Uptu(l!roULGJ~l=mHUjQ?_`UB<7wk&8{S zo4$%?;gb)P2dV|xq@JX6L1&Zh2fByoo}{~)`p}MV!=1k!BIf)98CRZP?0_=5-}rv4 zdFO+iyc2%qC*wKzaxSPR>0FQ>TJ)FQ4WHc!N$q{p&&!zVxvp27HFs`lV%J<)*Tt57 zp!vw@?--yDiKP~{@wF&$+@n1Eja&2l~{G!qp1T8YP#l}q5yWi%e zwt2snKJA%4jen!WQ-4=km!GY$c_d{#^0%oe+Mt%#TBF?SvQF0A=8&YwktE{2#)VfA%a7ZbW@7rjdva4;N-R^vP#5dUH z%;h$BRt-#zk#`Ewm1Sy9Mc&HBcT47$=yNhZ-(1-;wj%3Sw0h}>MoB&$HNT?OC&)Go z&7*5-{(kE!Yq&?&H8xF-?I)|pGd2f(vJJF%T~AJH-}F)JaCzHK4XRJg6#Uy%X{)+% z<~aYIV^h#mh^(Fr zoddLURgbUS2jJ>K;>sY&J%LmTYg`FL7;!Mj?T`&;R1%Ts2P-wzAd(FU2lXhuXGCR4 dRW^>RXLNe7eh?z3Ws1NWM0Y6x33vc0_z#P^91;Kk literal 0 HcmV?d00001 diff --git a/app/assets/images/ci_favicons/canary/favicon_status_success.ico b/app/assets/images/ci_favicons/canary/favicon_status_success.ico new file mode 100644 index 0000000000000000000000000000000000000000..a1fb6e91d653f60418ab8d1c1925b7f99aa69c2f GIT binary patch literal 4286 zcmb_eYfKzf6dr=cpO~0v+!=P+Wy@^Zgqjdj@c~3*(qR3eW|u~yu~B1elQtT(WqEW_ z`BAY^Qe&XB$U=GT073d#jo2lISg2T9AT4G~d5RE%us|uWvva&>mZ3Adv&^e4}Wvym_UJsZkn!dhSj)SiDA??72k4zYm|2#sg8 z(7U&41HrCF?25l~ffxL0uwgv!Y%hG+_6$$rwX_u*2<~Ty-8fJZhM~onU7ifuK;rN) zxyWv&89ZAjI^Pqtup+Hv955Hehf@!l2R!5ZIelPyX-rjpK;U87zo@zeS%EA2WYSG6&}yS4!K-}b?Q)?ILCu788CHo-HAIkYv=pF|sjH(W2gihHh% zpAS=s*tzYmi8@i{KO(a6>>1db+FG}Qx+fQh6!>!N{Y`rKpeeGli2cWS8(?fdI-jCx1J)=!%aQPn74Q_x1%_CU zAK0J$u&1_6)H!!=TH!ywxV@FoJ#lG+AB_!IC$Uzm;akqY+w4VtRm8sR2Xoajq|`Nu z_}WiowO$dw`Q~?Fx*{>q zhNHjkg3+eZ_oXBi#D|T zA+hT2eQbiCP%;TR#}yKTGu(%_B{Feh^_);wJOya!=`i8Mp(p%h4 zc)2Y{c%?2US;7n*lU)3m*}1HWZK_y^h%MP5=H#qbtWkUFet_rePr|cxPDrlxkh8P^ zEXV&7iYb3L7Ega2?-&F%G8Rqr8SO*gYf{l{opFqtb&f7Y4ve`Y??6n>N{i!NxSKNf}=2ByrICS~Eq9d4SKMwiv73u77=ZklK`mf>$`B{3@D zM`Gl+FrX-nqzfxnNnv3vSkhV`FqJkP1PP`oGW>Puym_DJ+?m(DdGp@P!*a-(^WMGZ zp6{G*-sNg4E4P$2QI^zB|rIv`1shnR+>7m0aX5Y6p4^&?Yi#Br$}Eg21%+|`I> zl3|i_QUiu){C%3Y?>H_SY{1KeHBA`EYC`nb0C4gb;M554>P5iS1)1kaCqlYkNX^LE z5kF!v*RgF!2jrd^U{i)6%`5|N|15k^C@1q$6H1=ghkE!K`<)?RD{2UvH2B*hu)hT| z+@0pDN`^VCV zI1gk)5$9pM8$oBB>_%r-j4a2-$hN>|X-4t$5ZTtf7{=~h4fyx9AI+@B#y`0Rymbj+ zX-0e|IY*R(_pGKMs~N|5P2VjutJ@nFca!Ub1#-9JrDwm1h8chQerlZ82Z54afMqJ; z`XFjl8hlT;-0B{Zm3>{Z$k}o@mDPA&Ik&{Ah-(y|WixnZ8xFe9NAI|YBXIu|K~8H} z*qmQWWz{-9*GY4IIYM=G69+ps1pXDeKdDHZD+}>+t)}=V_4uA{ zWx#z|Rs=T1ez<1~g}ouz{i}qpz&Dx--CF!ytGQp0uPrKmQ4d_6@8u;GSIGW{0-Ny* zdqQ}+ZUaS~3S_h5L#|ngpZkT-9$!HArI{R8FQPq>WD{8b2hYyTAM+NR8N zkPe^w1@|n<{j@}VOyqm`alVBQLlG2pZ9K*%{DRLGamaU-ajinKB z&k{aT@8;M&gK{JxZr=0m2MO35f8Lp!$R+#(XRaf&K7#yqb03UwdCRzG#q(ar*i6OW z$+xxmhx;^p9?yMIYe---KJ&h_lfnni1Mfwu^T57vzu=w~-y1*YJ%pNrP2_{A5J zu{n0<=SvCrY94qm*e0Jz?zwz7xjt}>;yTH-n)^j&qXOz3GWDAeR9sa)--2weZ|+O9 z=iO^bd1w6mvr|d<>;s<%K9hVe_-@AIOOU&p6lD7qWzUy5s$%M8alibRt9#QByRdE5 z5L?{~RoYuuMUBd7+r%@i53s*|6S?QsDW(m$&&z-7F}3f`+J8RH_XS|Y&YFb@r}s{C zTCQ2VVYHsdoF6YWYVq{X4)47~dA>14jYTV+<#Q+W`bO`h_lkDiqvx72rO>yS_WRpj zKDqR0P5hkODz85@!ZI7PRo)0E*{GPhXQrb45R&>fPbJ-KVa#m(NV3(lwj2R|LjY8)R?5OwVZC`O!j2ZcS_t3Qpg( z{B5eWRZw>KT@~L|zVL!}&dM|GK`6IsJW6%(DJ%MVofA~sX%A#u#UJbXIVbSi*=DV;@OcBop%oD<7&6VjnRP jpHc2-%-O^apCpwEt{y2JL9kloAXYFJ=MX|z!xsJnN+79= literal 0 HcmV?d00001 diff --git a/app/assets/images/favicon-yellow.ico b/app/assets/images/favicon-yellow.ico new file mode 100644 index 0000000000000000000000000000000000000000..b650f277fb66d6193e27e1f2bfe59f751159270b GIT binary patch literal 5430 zcmb_geM}VT8GrRIB{5da#a7(eot^!faeIy0=I+uqHTp->f7)CvX^b_ExtJJeqvmSW zhW%g>?@J3xv3K>WD6onWRspw&7A(259-_!e!6;oR7^MwRZuvM4cLv`+&&Pc#Tw?{U6^#nzqX;)X|51 zd`+}5%eu;>=lGfL*ed7QksjfSNL}Y=sJ(iea({ZL#ap3{KI}t`vv%Z;Bk$OEkz?sw zht>Ug^ z=Y|%KbvyWw!vPqfCC+hCoDdqsTNv*QeJPI-F}A}aTCBPT+@FUPZk$JGS{Xxw*qyVj zqLBaVV=Wfr*#q~J;@Q&sN<7X3IQZ~mnzOy4c=?9HH|)noD0k$)npt*VyZMbR)d}X< z^^co+j16LP))juw?RFE!-#M&~lPT;RTd>4EU%x+CUjjbBjp}ftUuP7YX=le#&Ak`x# zseWUbwQS`=z#uO6HK^M6(GQ$ReceB|?hksl8B#Dz@JrRIF=~5Y;GE@(c%y1($--vl|oSKXO33i)0@Z8mlF?VP-;y5(MeHHFZF|N{~H-!t*knlHA za#TVdJvI)xpk2-f_9Kvgs-`G^S){@RamZ0Rl$(j~dHQW7kq?AsX&CdgE2!jQ+reQi z7ugO#4udst2EUYZIb!Xlk&@@pNQM2*-rj{=Nq1PdERJD*hx-b2lswM9_b*MKeK(%R zaUVjEg8>UMQCmrO^S6q66V7ugom4)XzjMW_A+a5JW-yP#T>^Pl(YBw!weQgMv5r2> z(N4S*F9IH8Al4m{+HFOh@|~1QCza1q@X02jQTj}15ha-i@3vDkUZU=1KfjhDHarGB&La@m@~)|6+|{B}5J%T?(#+`FS%9FD&+2Ip(?DL34=mOWib z`b=>bwO1;8Am7IjBQ!pp19HN?jJ{SkdnV_1;e_`LCco~7!g(poUyAQF>Y~AUa-M>- z2G138%68=QByIKXu^;~YDGu-sh((Ts`G5vrFEug0sauO{zbvnMqtGyW74|6+2l}qF z%30I2aqUb0lUAQA8A{N{al6jIv!KpLEm5ms_S&*7m79bRJZE@b)V_GhpNF$nrCay- z{4MX?Nvm&pr#Dd_*8rXy{+#YvP<2o~NGmDk`e#&f4U`|A3e zimp>TVD#&Sbw@S4n>8u#W_m5is`J~&~`681bk23z@P+PSM^u$7G@=_~sH z?{`@x<&7y}m01d#*cc`nj<0_h-~+--{&c|(yZl!^wqtiM;HIpe|#?XqvGMC>>nSb>>SrC0(oP2ZKRk_H{*#>!`LF|E&pkZZPHdoywsvb9009nP>8KO}w!!m~aoUo_j5- zp0Q*-cQd|!>-Dj2@!oAS@~Ca-OL|Xd3m$G(`;Dc|JFvsZpQ+9H2l9t10BZ^Sg7_&2u+d`mZ;dnHvo>$`K;h_`rq z`%_`(;xl`DBSt>6w literal 0 HcmV?d00001 diff --git a/app/assets/images/icons.json b/app/assets/images/icons.json deleted file mode 100644 index 19843d24e2..0000000000 --- a/app/assets/images/icons.json +++ /dev/null @@ -1 +0,0 @@ -{"iconCount":191,"spriteSize":86607,"icons":["abuse","account","admin","angle-double-left","angle-double-right","angle-down","angle-left","angle-right","angle-up","appearance","applications","approval","arrow-down","arrow-right","assignee","bold","book","bookmark","branch","bullhorn","calendar","cancel","chart","chevron-down","chevron-left","chevron-right","chevron-up","clock","close","code","collapse","comment-dots","comment-next","comment","comments","commit","credit-card","cut","dashboard","disk","doc_code","doc_image","doc_text","double-headed-arrow","download","duplicate","earth","ellipsis_v","emoji_slightly_smiling_face","emoji_smile","emoji_smiley","epic","external-link","eye-slash","eye","file-addition","file-deletion","file-modified","filter","folder-o","folder-open","folder","fork","geo-nodes","git-merge","group","history","home","hook","hourglass","image-comment-dark","image-comment-light","import","issue-block","issue-child","issue-close","issue-duplicate","issue-external","issue-new","issue-open-m","issue-open","issue-parent","issues","italic","key-2","key","label","labels","leave","level-up","license","link","list-bulleted","list-numbered","location-dot","location","lock-open","lock","log","mail","menu","merge-request-close","messages","mobile-issue-close","monitor","more","notifications-off","notifications","overview","pencil-square","pencil","pipeline","play","plus-square-o","plus-square","plus","podcast","preferences","profile","project","push-rules","question-o","question","quote","redo","remove","repeat","retry","scale","screen-full","screen-normal","scroll_down","scroll_up","search","settings","shield","slight-frown","slight-smile","smile","smiley","snippet","soft-unwrap","soft-wrap","spam","spinner","staged","star-o","star","status_canceled_borderless","status_canceled","status_closed","status_created_borderless","status_created","status_failed_borderless","status_failed","status_manual_borderless","status_manual","status_notfound_borderless","status_notfound","status_open","status_pending_borderless","status_pending","status_running_borderless","status_running","status_skipped_borderless","status_skipped","status_success_borderless","status_success_solid","status_success","status_warning_borderless","status_warning","stop","task-done","template","terminal","thumb-down","thumb-up","thumbtack","timer","todo-add","todo-done","token","unapproval","unassignee","unlink","unstaged","user","users","volume-up","warning","work"]} \ No newline at end of file diff --git a/app/assets/images/icons.svg b/app/assets/images/icons.svg deleted file mode 100644 index 6aec54d054..0000000000 --- a/app/assets/images/icons.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/assets/images/illustrations/cluster_popover.svg b/app/assets/images/illustrations/cluster_popover.svg deleted file mode 100644 index 202231373f..0000000000 --- a/app/assets/images/illustrations/cluster_popover.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/assets/images/illustrations/clusters_empty.svg b/app/assets/images/illustrations/clusters_empty.svg deleted file mode 100644 index 39627a1c31..0000000000 --- a/app/assets/images/illustrations/clusters_empty.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/assets/images/illustrations/convdev/convdev_no_data.svg b/app/assets/images/illustrations/convdev/convdev_no_data.svg deleted file mode 100644 index b90eddcccf..0000000000 --- a/app/assets/images/illustrations/convdev/convdev_no_data.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/assets/images/illustrations/convdev/convdev_no_index.svg b/app/assets/images/illustrations/convdev/convdev_no_index.svg deleted file mode 100644 index 4aaf505e0b..0000000000 --- a/app/assets/images/illustrations/convdev/convdev_no_index.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/assets/images/illustrations/convdev/convdev_overview.svg b/app/assets/images/illustrations/convdev/convdev_overview.svg deleted file mode 100644 index a06d70812c..0000000000 --- a/app/assets/images/illustrations/convdev/convdev_overview.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/assets/images/illustrations/convdev/i2p_step_1.svg b/app/assets/images/illustrations/convdev/i2p_step_1.svg deleted file mode 100644 index 67467b1513..0000000000 --- a/app/assets/images/illustrations/convdev/i2p_step_1.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/assets/images/illustrations/convdev/i2p_step_10.svg b/app/assets/images/illustrations/convdev/i2p_step_10.svg deleted file mode 100644 index 588ecd8141..0000000000 --- a/app/assets/images/illustrations/convdev/i2p_step_10.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/assets/images/illustrations/convdev/i2p_step_2.svg b/app/assets/images/illustrations/convdev/i2p_step_2.svg deleted file mode 100644 index 4280024c23..0000000000 --- a/app/assets/images/illustrations/convdev/i2p_step_2.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/assets/images/illustrations/convdev/i2p_step_3.svg b/app/assets/images/illustrations/convdev/i2p_step_3.svg deleted file mode 100644 index 7690f91b42..0000000000 --- a/app/assets/images/illustrations/convdev/i2p_step_3.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/assets/images/illustrations/convdev/i2p_step_4.svg b/app/assets/images/illustrations/convdev/i2p_step_4.svg deleted file mode 100644 index ba21b9e2c3..0000000000 --- a/app/assets/images/illustrations/convdev/i2p_step_4.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/assets/images/illustrations/convdev/i2p_step_5.svg b/app/assets/images/illustrations/convdev/i2p_step_5.svg deleted file mode 100644 index 3c8f8422a9..0000000000 --- a/app/assets/images/illustrations/convdev/i2p_step_5.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/assets/images/illustrations/convdev/i2p_step_6.svg b/app/assets/images/illustrations/convdev/i2p_step_6.svg deleted file mode 100644 index 933860798a..0000000000 --- a/app/assets/images/illustrations/convdev/i2p_step_6.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/assets/images/illustrations/convdev/i2p_step_7.svg b/app/assets/images/illustrations/convdev/i2p_step_7.svg deleted file mode 100644 index d97c8f7c2d..0000000000 --- a/app/assets/images/illustrations/convdev/i2p_step_7.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/assets/images/illustrations/convdev/i2p_step_8.svg b/app/assets/images/illustrations/convdev/i2p_step_8.svg deleted file mode 100644 index 919bbeff31..0000000000 --- a/app/assets/images/illustrations/convdev/i2p_step_8.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/assets/images/illustrations/convdev/i2p_step_9.svg b/app/assets/images/illustrations/convdev/i2p_step_9.svg deleted file mode 100644 index 2d1b10d430..0000000000 --- a/app/assets/images/illustrations/convdev/i2p_step_9.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/assets/images/illustrations/epics.svg b/app/assets/images/illustrations/epics.svg deleted file mode 100644 index 1a37e6bba5..0000000000 --- a/app/assets/images/illustrations/epics.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/assets/images/illustrations/gitlab_logo.svg b/app/assets/images/illustrations/gitlab_logo.svg deleted file mode 100644 index 8dbd75a340..0000000000 --- a/app/assets/images/illustrations/gitlab_logo.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/assets/images/illustrations/image_comment_light_cursor.svg b/app/assets/images/illustrations/image_comment_light_cursor.svg deleted file mode 100644 index ac712ea0c9..0000000000 --- a/app/assets/images/illustrations/image_comment_light_cursor.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/assets/images/illustrations/image_comment_light_cursor@2x.svg b/app/assets/images/illustrations/image_comment_light_cursor@2x.svg deleted file mode 100644 index 02943acd9d..0000000000 --- a/app/assets/images/illustrations/image_comment_light_cursor@2x.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/assets/images/illustrations/issues.svg b/app/assets/images/illustrations/issues.svg deleted file mode 100644 index c8e0504732..0000000000 --- a/app/assets/images/illustrations/issues.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/assets/images/illustrations/job_not_triggered.svg b/app/assets/images/illustrations/job_not_triggered.svg deleted file mode 100644 index e13c1cb0a7..0000000000 --- a/app/assets/images/illustrations/job_not_triggered.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/assets/images/illustrations/labels.svg b/app/assets/images/illustrations/labels.svg deleted file mode 100644 index 3a2d521323..0000000000 --- a/app/assets/images/illustrations/labels.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/assets/images/illustrations/logos/go_logo.svg b/app/assets/images/illustrations/logos/go_logo.svg deleted file mode 100644 index 7fd4911800..0000000000 --- a/app/assets/images/illustrations/logos/go_logo.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/assets/images/illustrations/logos/mattermost_logo.svg b/app/assets/images/illustrations/logos/mattermost_logo.svg deleted file mode 100644 index b577c0599a..0000000000 --- a/app/assets/images/illustrations/logos/mattermost_logo.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/assets/images/illustrations/manual_action.svg b/app/assets/images/illustrations/manual_action.svg deleted file mode 100644 index 85735855b4..0000000000 --- a/app/assets/images/illustrations/manual_action.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/assets/images/illustrations/merge_request_changes_empty.svg b/app/assets/images/illustrations/merge_request_changes_empty.svg deleted file mode 100644 index 40efeb2de5..0000000000 --- a/app/assets/images/illustrations/merge_request_changes_empty.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/assets/images/illustrations/merge_requests.svg b/app/assets/images/illustrations/merge_requests.svg deleted file mode 100644 index b9b8f0058e..0000000000 --- a/app/assets/images/illustrations/merge_requests.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/assets/images/illustrations/monitoring/getting_started.svg b/app/assets/images/illustrations/monitoring/getting_started.svg deleted file mode 100644 index ff783bdd38..0000000000 --- a/app/assets/images/illustrations/monitoring/getting_started.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/assets/images/illustrations/monitoring/loading.svg b/app/assets/images/illustrations/monitoring/loading.svg deleted file mode 100644 index 1e196fc8ad..0000000000 --- a/app/assets/images/illustrations/monitoring/loading.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/assets/images/illustrations/monitoring/unable_to_connect.svg b/app/assets/images/illustrations/monitoring/unable_to_connect.svg deleted file mode 100644 index 314c052f93..0000000000 --- a/app/assets/images/illustrations/monitoring/unable_to_connect.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/assets/images/illustrations/multi-editor_all_changes_committed_empty.svg b/app/assets/images/illustrations/multi-editor_all_changes_committed_empty.svg deleted file mode 100644 index 06d73941c3..0000000000 --- a/app/assets/images/illustrations/multi-editor_all_changes_committed_empty.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/assets/images/illustrations/multi-editor_no_changes_empty.svg b/app/assets/images/illustrations/multi-editor_no_changes_empty.svg deleted file mode 100644 index ebeea1f3dd..0000000000 --- a/app/assets/images/illustrations/multi-editor_no_changes_empty.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/assets/images/illustrations/multi-editor_no_staged_files_empty.svg b/app/assets/images/illustrations/multi-editor_no_staged_files_empty.svg deleted file mode 100644 index 08321ef526..0000000000 --- a/app/assets/images/illustrations/multi-editor_no_staged_files_empty.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/assets/images/illustrations/multi_file_editor_empty.svg b/app/assets/images/illustrations/multi_file_editor_empty.svg deleted file mode 100644 index bd376f0a05..0000000000 --- a/app/assets/images/illustrations/multi_file_editor_empty.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/assets/images/illustrations/no_commits.svg b/app/assets/images/illustrations/no_commits.svg deleted file mode 100644 index 76fa25156d..0000000000 --- a/app/assets/images/illustrations/no_commits.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/assets/images/illustrations/pending_job_empty.svg b/app/assets/images/illustrations/pending_job_empty.svg deleted file mode 100644 index 8de695afa1..0000000000 --- a/app/assets/images/illustrations/pending_job_empty.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/assets/images/illustrations/pipelines_empty.svg b/app/assets/images/illustrations/pipelines_empty.svg deleted file mode 100644 index f3107c8f06..0000000000 --- a/app/assets/images/illustrations/pipelines_empty.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/assets/images/illustrations/pipelines_failed.svg b/app/assets/images/illustrations/pipelines_failed.svg deleted file mode 100644 index 8daf7da86e..0000000000 --- a/app/assets/images/illustrations/pipelines_failed.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/assets/images/illustrations/pipelines_pending.svg b/app/assets/images/illustrations/pipelines_pending.svg deleted file mode 100644 index 25038366e9..0000000000 --- a/app/assets/images/illustrations/pipelines_pending.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/assets/images/illustrations/priority_labels.svg b/app/assets/images/illustrations/priority_labels.svg deleted file mode 100644 index b79c551d3d..0000000000 --- a/app/assets/images/illustrations/priority_labels.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/assets/images/illustrations/service_desk_callout.svg b/app/assets/images/illustrations/service_desk_callout.svg deleted file mode 100644 index 2886388279..0000000000 --- a/app/assets/images/illustrations/service_desk_callout.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/assets/images/illustrations/service_desk_empty.svg b/app/assets/images/illustrations/service_desk_empty.svg deleted file mode 100644 index daaaeae6a1..0000000000 --- a/app/assets/images/illustrations/service_desk_empty.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/assets/images/illustrations/slack_logo.svg b/app/assets/images/illustrations/slack_logo.svg deleted file mode 100644 index b8d7906c2e..0000000000 --- a/app/assets/images/illustrations/slack_logo.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/assets/images/illustrations/todos_all_done.svg b/app/assets/images/illustrations/todos_all_done.svg deleted file mode 100644 index 6387497a6f..0000000000 --- a/app/assets/images/illustrations/todos_all_done.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/assets/images/illustrations/todos_empty.svg b/app/assets/images/illustrations/todos_empty.svg deleted file mode 100644 index 4de6cb403b..0000000000 --- a/app/assets/images/illustrations/todos_empty.svg +++ /dev/null @@ -1 +0,0 @@ -@ \ No newline at end of file diff --git a/app/assets/images/illustrations/welcome/add_new_group.svg b/app/assets/images/illustrations/welcome/add_new_group.svg deleted file mode 100644 index b10a3ae881..0000000000 --- a/app/assets/images/illustrations/welcome/add_new_group.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/assets/images/illustrations/welcome/add_new_project.svg b/app/assets/images/illustrations/welcome/add_new_project.svg deleted file mode 100644 index 4b8dc34c08..0000000000 --- a/app/assets/images/illustrations/welcome/add_new_project.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/assets/images/illustrations/welcome/add_new_user.svg b/app/assets/images/illustrations/welcome/add_new_user.svg deleted file mode 100644 index d4c184989b..0000000000 --- a/app/assets/images/illustrations/welcome/add_new_user.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/assets/images/illustrations/welcome/configure_server.svg b/app/assets/images/illustrations/welcome/configure_server.svg deleted file mode 100644 index f9dda816f1..0000000000 --- a/app/assets/images/illustrations/welcome/configure_server.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/assets/images/illustrations/welcome/ee_trial.svg b/app/assets/images/illustrations/welcome/ee_trial.svg deleted file mode 100644 index 6d0dcf0020..0000000000 --- a/app/assets/images/illustrations/welcome/ee_trial.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/assets/images/illustrations/welcome/globe.svg b/app/assets/images/illustrations/welcome/globe.svg deleted file mode 100644 index c2daae5f31..0000000000 --- a/app/assets/images/illustrations/welcome/globe.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/assets/images/illustrations/welcome/lightbulb.svg b/app/assets/images/illustrations/welcome/lightbulb.svg deleted file mode 100644 index fce1031208..0000000000 --- a/app/assets/images/illustrations/welcome/lightbulb.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/assets/images/illustrations/wiki-fro-logged-out-users.svg b/app/assets/images/illustrations/wiki-fro-logged-out-users.svg deleted file mode 100644 index c71841f72e..0000000000 --- a/app/assets/images/illustrations/wiki-fro-logged-out-users.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/assets/images/illustrations/wiki_login_empty.svg b/app/assets/images/illustrations/wiki_login_empty.svg deleted file mode 100644 index 1cfa47220a..0000000000 --- a/app/assets/images/illustrations/wiki_login_empty.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/assets/images/illustrations/wiki_logout_empty.svg b/app/assets/images/illustrations/wiki_logout_empty.svg deleted file mode 100644 index c71841f72e..0000000000 --- a/app/assets/images/illustrations/wiki_logout_empty.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/assets/javascripts/activities.js b/app/assets/javascripts/activities.js index 6a0662ba90..c117d080bd 100644 --- a/app/assets/javascripts/activities.js +++ b/app/assets/javascripts/activities.js @@ -1,5 +1,6 @@ /* eslint-disable no-param-reassign, class-methods-use-this */ +import $ from 'jquery'; import Cookies from 'js-cookie'; import Pager from './pager'; import { localTimeAgo } from './lib/utils/datetime_utility'; diff --git a/app/assets/javascripts/ajax_loading_spinner.js b/app/assets/javascripts/ajax_loading_spinner.js index 2bc77859c2..bd08308904 100644 --- a/app/assets/javascripts/ajax_loading_spinner.js +++ b/app/assets/javascripts/ajax_loading_spinner.js @@ -1,3 +1,5 @@ +import $ from 'jquery'; + export default class AjaxLoadingSpinner { static init() { const $elements = $('.js-ajax-loading-spinner'); diff --git a/app/assets/javascripts/api.js b/app/assets/javascripts/api.js index 464611f66f..8ad3d18b30 100644 --- a/app/assets/javascripts/api.js +++ b/app/assets/javascripts/api.js @@ -1,3 +1,4 @@ +import $ from 'jquery'; import _ from 'underscore'; import axios from './lib/utils/axios_utils'; @@ -9,6 +10,9 @@ const Api = { projectsPath: '/api/:version/projects.json', projectPath: '/api/:version/projects/:id', projectLabelsPath: '/:namespace_path/:project_path/labels', + mergeRequestPath: '/api/:version/projects/:id/merge_requests/:mrid', + mergeRequestChangesPath: '/api/:version/projects/:id/merge_requests/:mrid/changes', + mergeRequestVersionsPath: '/api/:version/projects/:id/merge_requests/:mrid/versions', groupLabelsPath: '/groups/:namespace_path/-/labels', licensePath: '/api/:version/templates/licenses/:key', gitignorePath: '/api/:version/templates/gitignores/:key', @@ -21,25 +25,27 @@ const Api = { createBranchPath: '/api/:version/projects/:id/repository/branches', group(groupId, callback) { - const url = Api.buildUrl(Api.groupPath) - .replace(':id', groupId); - return axios.get(url) - .then(({ data }) => { - callback(data); + const url = Api.buildUrl(Api.groupPath).replace(':id', groupId); + return axios.get(url).then(({ data }) => { + callback(data); - return data; - }); + return data; + }); }, // Return groups list. Filtered by query groups(query, options, callback = $.noop) { const url = Api.buildUrl(Api.groupsPath); - return axios.get(url, { - params: Object.assign({ - search: query, - per_page: 20, - }, options), - }) + return axios + .get(url, { + params: Object.assign( + { + search: query, + per_page: 20, + }, + options, + ), + }) .then(({ data }) => { callback(data); @@ -50,12 +56,13 @@ const Api = { // Return namespaces list. Filtered by query namespaces(query, callback) { const url = Api.buildUrl(Api.namespacesPath); - return axios.get(url, { - params: { - search: query, - per_page: 20, - }, - }) + return axios + .get(url, { + params: { + search: query, + per_page: 20, + }, + }) .then(({ data }) => callback(data)); }, @@ -72,9 +79,10 @@ const Api = { defaults.membership = true; } - return axios.get(url, { - params: Object.assign(defaults, options), - }) + return axios + .get(url, { + params: Object.assign(defaults, options), + }) .then(({ data }) => { callback(data); @@ -84,8 +92,32 @@ const Api = { // Return single project project(projectPath) { - const url = Api.buildUrl(Api.projectPath) - .replace(':id', encodeURIComponent(projectPath)); + const url = Api.buildUrl(Api.projectPath).replace(':id', encodeURIComponent(projectPath)); + + return axios.get(url); + }, + + // Return Merge Request for project + mergeRequest(projectPath, mergeRequestId) { + const url = Api.buildUrl(Api.mergeRequestPath) + .replace(':id', encodeURIComponent(projectPath)) + .replace(':mrid', mergeRequestId); + + return axios.get(url); + }, + + mergeRequestChanges(projectPath, mergeRequestId) { + const url = Api.buildUrl(Api.mergeRequestChangesPath) + .replace(':id', encodeURIComponent(projectPath)) + .replace(':mrid', mergeRequestId); + + return axios.get(url); + }, + + mergeRequestVersions(projectPath, mergeRequestId) { + const url = Api.buildUrl(Api.mergeRequestVersionsPath) + .replace(':id', encodeURIComponent(projectPath)) + .replace(':mrid', mergeRequestId); return axios.get(url); }, @@ -101,30 +133,30 @@ const Api = { url = Api.buildUrl(Api.groupLabelsPath).replace(':namespace_path', namespacePath); } - return axios.post(url, { - label: data, - }) + return axios + .post(url, { + label: data, + }) .then(res => callback(res.data)) .catch(e => callback(e.response.data)); }, // Return group projects list. Filtered by query groupProjects(groupId, query, callback) { - const url = Api.buildUrl(Api.groupProjectsPath) - .replace(':id', groupId); - return axios.get(url, { - params: { - search: query, - per_page: 20, - }, - }) + const url = Api.buildUrl(Api.groupProjectsPath).replace(':id', groupId); + return axios + .get(url, { + params: { + search: query, + per_page: 20, + }, + }) .then(({ data }) => callback(data)); }, commitMultiple(id, data) { // see https://docs.gitlab.com/ce/api/commits.html#create-a-commit-with-multiple-files-and-actions - const url = Api.buildUrl(Api.commitPath) - .replace(':id', encodeURIComponent(id)); + const url = Api.buildUrl(Api.commitPath).replace(':id', encodeURIComponent(id)); return axios.post(url, JSON.stringify(data), { headers: { 'Content-Type': 'application/json; charset=utf-8', @@ -135,39 +167,34 @@ const Api = { branchSingle(id, branch) { const url = Api.buildUrl(Api.branchSinglePath) .replace(':id', encodeURIComponent(id)) - .replace(':branch', branch); + .replace(':branch', encodeURIComponent(branch)); return axios.get(url); }, // Return text for a specific license licenseText(key, data, callback) { - const url = Api.buildUrl(Api.licensePath) - .replace(':key', key); - return axios.get(url, { - params: data, - }) + const url = Api.buildUrl(Api.licensePath).replace(':key', key); + return axios + .get(url, { + params: data, + }) .then(res => callback(res.data)); }, gitignoreText(key, callback) { - const url = Api.buildUrl(Api.gitignorePath) - .replace(':key', key); - return axios.get(url) - .then(({ data }) => callback(data)); + const url = Api.buildUrl(Api.gitignorePath).replace(':key', key); + return axios.get(url).then(({ data }) => callback(data)); }, gitlabCiYml(key, callback) { - const url = Api.buildUrl(Api.gitlabCiYmlPath) - .replace(':key', key); - return axios.get(url) - .then(({ data }) => callback(data)); + const url = Api.buildUrl(Api.gitlabCiYmlPath).replace(':key', key); + return axios.get(url).then(({ data }) => callback(data)); }, dockerfileYml(key, callback) { const url = Api.buildUrl(Api.dockerfilePath).replace(':key', key); - return axios.get(url) - .then(({ data }) => callback(data)); + return axios.get(url).then(({ data }) => callback(data)); }, issueTemplate(namespacePath, projectPath, key, type, callback) { @@ -176,7 +203,8 @@ const Api = { .replace(':type', type) .replace(':project_path', projectPath) .replace(':namespace_path', namespacePath); - return axios.get(url) + return axios + .get(url) .then(({ data }) => callback(null, data)) .catch(callback); }, @@ -184,10 +212,13 @@ const Api = { users(query, options) { const url = Api.buildUrl(this.usersPath); return axios.get(url, { - params: Object.assign({ - search: query, - per_page: 20, - }, options), + params: Object.assign( + { + search: query, + per_page: 20, + }, + options, + ), }); }, diff --git a/app/assets/javascripts/awards_handler.js b/app/assets/javascripts/awards_handler.js index 26e62732b3..976d32abe9 100644 --- a/app/assets/javascripts/awards_handler.js +++ b/app/assets/javascripts/awards_handler.js @@ -1,8 +1,11 @@ /* eslint-disable class-methods-use-this */ + +import $ from 'jquery'; import _ from 'underscore'; import Cookies from 'js-cookie'; import { __ } from './locale'; -import { isInIssuePage, isInMRPage, hasVueMRDiscussionsCookie, updateTooltipTitle } from './lib/utils/common_utils'; +import { updateTooltipTitle } from './lib/utils/common_utils'; +import { isInVueNoteablePage } from './lib/utils/dom_utils'; import flash from './flash'; import axios from './lib/utils/axios_utils'; @@ -241,7 +244,7 @@ class AwardsHandler { addAward(votesBlock, awardUrl, emoji, checkMutuality, callback) { const isMainAwardsBlock = votesBlock.closest('.js-noteable-awards').length; - if (this.isInVueNoteablePage() && !isMainAwardsBlock) { + if (isInVueNoteablePage() && !isMainAwardsBlock) { const id = votesBlock.attr('id').replace('note_', ''); this.hideMenuElement($('.emoji-menu')); @@ -293,16 +296,8 @@ class AwardsHandler { } } - isVueMRDiscussions() { - return isInMRPage() && hasVueMRDiscussionsCookie() && !$('#diffs').is(':visible'); - } - - isInVueNoteablePage() { - return isInIssuePage() || this.isVueMRDiscussions(); - } - getVotesBlock() { - if (this.isInVueNoteablePage()) { + if (isInVueNoteablePage()) { const $el = $('.js-add-award.is-active').closest('.note.timeline-entry'); if ($el.length) { diff --git a/app/assets/javascripts/badges/components/badge.vue b/app/assets/javascripts/badges/components/badge.vue new file mode 100644 index 0000000000..6e6cb31e3a --- /dev/null +++ b/app/assets/javascripts/badges/components/badge.vue @@ -0,0 +1,121 @@ + + + diff --git a/app/assets/javascripts/badges/components/badge_form.vue b/app/assets/javascripts/badges/components/badge_form.vue new file mode 100644 index 0000000000..ae942b2c1a --- /dev/null +++ b/app/assets/javascripts/badges/components/badge_form.vue @@ -0,0 +1,219 @@ + + + diff --git a/app/assets/javascripts/badges/components/badge_list.vue b/app/assets/javascripts/badges/components/badge_list.vue new file mode 100644 index 0000000000..ca7197e1e0 --- /dev/null +++ b/app/assets/javascripts/badges/components/badge_list.vue @@ -0,0 +1,57 @@ + + + diff --git a/app/assets/javascripts/badges/components/badge_list_row.vue b/app/assets/javascripts/badges/components/badge_list_row.vue new file mode 100644 index 0000000000..af062bdf8c --- /dev/null +++ b/app/assets/javascripts/badges/components/badge_list_row.vue @@ -0,0 +1,89 @@ + + + diff --git a/app/assets/javascripts/badges/components/badge_settings.vue b/app/assets/javascripts/badges/components/badge_settings.vue new file mode 100644 index 0000000000..83f7839423 --- /dev/null +++ b/app/assets/javascripts/badges/components/badge_settings.vue @@ -0,0 +1,70 @@ + + + diff --git a/app/assets/javascripts/badges/constants.js b/app/assets/javascripts/badges/constants.js new file mode 100644 index 0000000000..8fbe3db5ef --- /dev/null +++ b/app/assets/javascripts/badges/constants.js @@ -0,0 +1,2 @@ +export const GROUP_BADGE = 'group'; +export const PROJECT_BADGE = 'project'; diff --git a/app/assets/javascripts/badges/empty_badge.js b/app/assets/javascripts/badges/empty_badge.js new file mode 100644 index 0000000000..49a9b5e1be --- /dev/null +++ b/app/assets/javascripts/badges/empty_badge.js @@ -0,0 +1,7 @@ +export default () => ({ + imageUrl: '', + isDeleting: false, + linkUrl: '', + renderedImageUrl: '', + renderedLinkUrl: '', +}); diff --git a/app/assets/javascripts/badges/store/actions.js b/app/assets/javascripts/badges/store/actions.js new file mode 100644 index 0000000000..5542278b3e --- /dev/null +++ b/app/assets/javascripts/badges/store/actions.js @@ -0,0 +1,167 @@ +import axios from '~/lib/utils/axios_utils'; +import types from './mutation_types'; + +export const transformBackendBadge = badge => ({ + id: badge.id, + imageUrl: badge.image_url, + kind: badge.kind, + linkUrl: badge.link_url, + renderedImageUrl: badge.rendered_image_url, + renderedLinkUrl: badge.rendered_link_url, + isDeleting: false, +}); + +export default { + requestNewBadge({ commit }) { + commit(types.REQUEST_NEW_BADGE); + }, + receiveNewBadge({ commit }, newBadge) { + commit(types.RECEIVE_NEW_BADGE, newBadge); + }, + receiveNewBadgeError({ commit }) { + commit(types.RECEIVE_NEW_BADGE_ERROR); + }, + addBadge({ dispatch, state }) { + const newBadge = state.badgeInAddForm; + const endpoint = state.apiEndpointUrl; + dispatch('requestNewBadge'); + return axios + .post(endpoint, { + image_url: newBadge.imageUrl, + link_url: newBadge.linkUrl, + }) + .catch(error => { + dispatch('receiveNewBadgeError'); + throw error; + }) + .then(res => { + dispatch('receiveNewBadge', transformBackendBadge(res.data)); + }); + }, + requestDeleteBadge({ commit }, badgeId) { + commit(types.REQUEST_DELETE_BADGE, badgeId); + }, + receiveDeleteBadge({ commit }, badgeId) { + commit(types.RECEIVE_DELETE_BADGE, badgeId); + }, + receiveDeleteBadgeError({ commit }, badgeId) { + commit(types.RECEIVE_DELETE_BADGE_ERROR, badgeId); + }, + deleteBadge({ dispatch, state }, badge) { + const badgeId = badge.id; + dispatch('requestDeleteBadge', badgeId); + const endpoint = `${state.apiEndpointUrl}/${badgeId}`; + return axios + .delete(endpoint) + .catch(error => { + dispatch('receiveDeleteBadgeError', badgeId); + throw error; + }) + .then(() => { + dispatch('receiveDeleteBadge', badgeId); + }); + }, + + editBadge({ commit }, badge) { + commit(types.START_EDITING, badge); + }, + + requestLoadBadges({ commit }, data) { + commit(types.REQUEST_LOAD_BADGES, data); + }, + receiveLoadBadges({ commit }, badges) { + commit(types.RECEIVE_LOAD_BADGES, badges); + }, + receiveLoadBadgesError({ commit }) { + commit(types.RECEIVE_LOAD_BADGES_ERROR); + }, + + loadBadges({ dispatch, state }, data) { + dispatch('requestLoadBadges', data); + const endpoint = state.apiEndpointUrl; + return axios + .get(endpoint) + .catch(error => { + dispatch('receiveLoadBadgesError'); + throw error; + }) + .then(res => { + dispatch('receiveLoadBadges', res.data.map(transformBackendBadge)); + }); + }, + + requestRenderedBadge({ commit }) { + commit(types.REQUEST_RENDERED_BADGE); + }, + receiveRenderedBadge({ commit }, renderedBadge) { + commit(types.RECEIVE_RENDERED_BADGE, renderedBadge); + }, + receiveRenderedBadgeError({ commit }) { + commit(types.RECEIVE_RENDERED_BADGE_ERROR); + }, + + renderBadge({ dispatch, state }) { + const badge = state.isEditing ? state.badgeInEditForm : state.badgeInAddForm; + const { linkUrl, imageUrl } = badge; + if (!linkUrl || linkUrl.trim() === '' || !imageUrl || imageUrl.trim() === '') { + return Promise.resolve(badge); + } + + dispatch('requestRenderedBadge'); + + const parameters = [ + `link_url=${encodeURIComponent(linkUrl)}`, + `image_url=${encodeURIComponent(imageUrl)}`, + ].join('&'); + const renderEndpoint = `${state.apiEndpointUrl}/render?${parameters}`; + return axios + .get(renderEndpoint) + .catch(error => { + dispatch('receiveRenderedBadgeError'); + throw error; + }) + .then(res => { + dispatch('receiveRenderedBadge', transformBackendBadge(res.data)); + }); + }, + + requestUpdatedBadge({ commit }) { + commit(types.REQUEST_UPDATED_BADGE); + }, + receiveUpdatedBadge({ commit }, updatedBadge) { + commit(types.RECEIVE_UPDATED_BADGE, updatedBadge); + }, + receiveUpdatedBadgeError({ commit }) { + commit(types.RECEIVE_UPDATED_BADGE_ERROR); + }, + + saveBadge({ dispatch, state }) { + const badge = state.badgeInEditForm; + const endpoint = `${state.apiEndpointUrl}/${badge.id}`; + dispatch('requestUpdatedBadge'); + return axios + .put(endpoint, { + image_url: badge.imageUrl, + link_url: badge.linkUrl, + }) + .catch(error => { + dispatch('receiveUpdatedBadgeError'); + throw error; + }) + .then(res => { + dispatch('receiveUpdatedBadge', transformBackendBadge(res.data)); + }); + }, + + stopEditing({ commit }) { + commit(types.STOP_EDITING); + }, + + updateBadgeInForm({ commit }, badge) { + commit(types.UPDATE_BADGE_IN_FORM, badge); + }, + + updateBadgeInModal({ commit }, badge) { + commit(types.UPDATE_BADGE_IN_MODAL, badge); + }, +}; diff --git a/app/assets/javascripts/badges/store/index.js b/app/assets/javascripts/badges/store/index.js new file mode 100644 index 0000000000..7a5df403a0 --- /dev/null +++ b/app/assets/javascripts/badges/store/index.js @@ -0,0 +1,13 @@ +import Vue from 'vue'; +import Vuex from 'vuex'; +import createState from './state'; +import actions from './actions'; +import mutations from './mutations'; + +Vue.use(Vuex); + +export default new Vuex.Store({ + state: createState(), + actions, + mutations, +}); diff --git a/app/assets/javascripts/badges/store/mutation_types.js b/app/assets/javascripts/badges/store/mutation_types.js new file mode 100644 index 0000000000..d73f91b600 --- /dev/null +++ b/app/assets/javascripts/badges/store/mutation_types.js @@ -0,0 +1,21 @@ +export default { + RECEIVE_DELETE_BADGE: 'RECEIVE_DELETE_BADGE', + RECEIVE_DELETE_BADGE_ERROR: 'RECEIVE_DELETE_BADGE_ERROR', + RECEIVE_LOAD_BADGES: 'RECEIVE_LOAD_BADGES', + RECEIVE_LOAD_BADGES_ERROR: 'RECEIVE_LOAD_BADGES_ERROR', + RECEIVE_NEW_BADGE: 'RECEIVE_NEW_BADGE', + RECEIVE_NEW_BADGE_ERROR: 'RECEIVE_NEW_BADGE_ERROR', + RECEIVE_RENDERED_BADGE: 'RECEIVE_RENDERED_BADGE', + RECEIVE_RENDERED_BADGE_ERROR: 'RECEIVE_RENDERED_BADGE_ERROR', + RECEIVE_UPDATED_BADGE: 'RECEIVE_UPDATED_BADGE', + RECEIVE_UPDATED_BADGE_ERROR: 'RECEIVE_UPDATED_BADGE_ERROR', + REQUEST_DELETE_BADGE: 'REQUEST_DELETE_BADGE', + REQUEST_LOAD_BADGES: 'REQUEST_LOAD_BADGES', + REQUEST_NEW_BADGE: 'REQUEST_NEW_BADGE', + REQUEST_RENDERED_BADGE: 'REQUEST_RENDERED_BADGE', + REQUEST_UPDATED_BADGE: 'REQUEST_UPDATED_BADGE', + START_EDITING: 'START_EDITING', + STOP_EDITING: 'STOP_EDITING', + UPDATE_BADGE_IN_FORM: 'UPDATE_BADGE_IN_FORM', + UPDATE_BADGE_IN_MODAL: 'UPDATE_BADGE_IN_MODAL', +}; diff --git a/app/assets/javascripts/badges/store/mutations.js b/app/assets/javascripts/badges/store/mutations.js new file mode 100644 index 0000000000..bd84e68c00 --- /dev/null +++ b/app/assets/javascripts/badges/store/mutations.js @@ -0,0 +1,158 @@ +import types from './mutation_types'; +import { PROJECT_BADGE } from '../constants'; + +const reorderBadges = badges => + badges.sort((a, b) => { + if (a.kind !== b.kind) { + return a.kind === PROJECT_BADGE ? 1 : -1; + } + + return a.id - b.id; + }); + +export default { + [types.RECEIVE_NEW_BADGE](state, newBadge) { + Object.assign(state, { + badgeInAddForm: null, + badges: reorderBadges(state.badges.concat(newBadge)), + isSaving: false, + renderedBadge: null, + }); + }, + [types.RECEIVE_NEW_BADGE_ERROR](state) { + Object.assign(state, { + isSaving: false, + }); + }, + [types.REQUEST_NEW_BADGE](state) { + Object.assign(state, { + isSaving: true, + }); + }, + + [types.RECEIVE_UPDATED_BADGE](state, updatedBadge) { + const badges = state.badges.map(badge => { + if (badge.id === updatedBadge.id) { + return updatedBadge; + } + return badge; + }); + Object.assign(state, { + badgeInEditForm: null, + badges, + isEditing: false, + isSaving: false, + renderedBadge: null, + }); + }, + [types.RECEIVE_UPDATED_BADGE_ERROR](state) { + Object.assign(state, { + isSaving: false, + }); + }, + [types.REQUEST_UPDATED_BADGE](state) { + Object.assign(state, { + isSaving: true, + }); + }, + + [types.RECEIVE_LOAD_BADGES](state, badges) { + Object.assign(state, { + badges: reorderBadges(badges), + isLoading: false, + }); + }, + [types.RECEIVE_LOAD_BADGES_ERROR](state) { + Object.assign(state, { + isLoading: false, + }); + }, + [types.REQUEST_LOAD_BADGES](state, data) { + Object.assign(state, { + kind: data.kind, // project or group + apiEndpointUrl: data.apiEndpointUrl, + docsUrl: data.docsUrl, + isLoading: true, + }); + }, + + [types.RECEIVE_DELETE_BADGE](state, badgeId) { + const badges = state.badges.filter(badge => badge.id !== badgeId); + Object.assign(state, { + badges, + }); + }, + [types.RECEIVE_DELETE_BADGE_ERROR](state, badgeId) { + const badges = state.badges.map(badge => { + if (badge.id === badgeId) { + return { + ...badge, + isDeleting: false, + }; + } + + return badge; + }); + Object.assign(state, { + badges, + }); + }, + [types.REQUEST_DELETE_BADGE](state, badgeId) { + const badges = state.badges.map(badge => { + if (badge.id === badgeId) { + return { + ...badge, + isDeleting: true, + }; + } + + return badge; + }); + Object.assign(state, { + badges, + }); + }, + + [types.RECEIVE_RENDERED_BADGE](state, renderedBadge) { + Object.assign(state, { isRendering: false, renderedBadge }); + }, + [types.RECEIVE_RENDERED_BADGE_ERROR](state) { + Object.assign(state, { isRendering: false }); + }, + [types.REQUEST_RENDERED_BADGE](state) { + Object.assign(state, { isRendering: true }); + }, + + [types.START_EDITING](state, badge) { + Object.assign(state, { + badgeInEditForm: { ...badge }, + isEditing: true, + renderedBadge: { ...badge }, + }); + }, + [types.STOP_EDITING](state) { + Object.assign(state, { + badgeInEditForm: null, + isEditing: false, + renderedBadge: null, + }); + }, + + [types.UPDATE_BADGE_IN_FORM](state, badge) { + if (state.isEditing) { + Object.assign(state, { + badgeInEditForm: badge, + }); + } else { + Object.assign(state, { + badgeInAddForm: badge, + }); + } + }, + + [types.UPDATE_BADGE_IN_MODAL](state, badge) { + Object.assign(state, { + badgeInModal: badge, + }); + }, +}; diff --git a/app/assets/javascripts/badges/store/state.js b/app/assets/javascripts/badges/store/state.js new file mode 100644 index 0000000000..43413aeb5b --- /dev/null +++ b/app/assets/javascripts/badges/store/state.js @@ -0,0 +1,13 @@ +export default () => ({ + apiEndpointUrl: null, + badgeInAddForm: null, + badgeInEditForm: null, + badgeInModal: null, + badges: [], + docsUrl: null, + renderedBadge: null, + isEditing: false, + isLoading: false, + isRendering: false, + isSaving: false, +}); diff --git a/app/assets/javascripts/behaviors/copy_to_clipboard.js b/app/assets/javascripts/behaviors/copy_to_clipboard.js index b669b63d23..e2a73a1797 100644 --- a/app/assets/javascripts/behaviors/copy_to_clipboard.js +++ b/app/assets/javascripts/behaviors/copy_to_clipboard.js @@ -1,3 +1,4 @@ +import $ from 'jquery'; import Clipboard from 'clipboard'; function showTooltip(target, title) { diff --git a/app/assets/javascripts/behaviors/details_behavior.js b/app/assets/javascripts/behaviors/details_behavior.js index 7c9dbcc8d6..1d63f5baee 100644 --- a/app/assets/javascripts/behaviors/details_behavior.js +++ b/app/assets/javascripts/behaviors/details_behavior.js @@ -1,3 +1,4 @@ +import $ from 'jquery'; $(() => { $('body').on('click', '.js-details-target', function target() { diff --git a/app/assets/javascripts/behaviors/index.js b/app/assets/javascripts/behaviors/index.js index 8d021de799..84fef4d8b4 100644 --- a/app/assets/javascripts/behaviors/index.js +++ b/app/assets/javascripts/behaviors/index.js @@ -1,6 +1,7 @@ import './autosize'; import './bind_in_out'; -import initCopyAsGFM from './copy_as_gfm'; +import './markdown/render_gfm'; +import initCopyAsGFM from './markdown/copy_as_gfm'; import initCopyToClipboard from './copy_to_clipboard'; import './details_behavior'; import installGlEmojiElement from './gl_emoji'; diff --git a/app/assets/javascripts/behaviors/copy_as_gfm.js b/app/assets/javascripts/behaviors/markdown/copy_as_gfm.js similarity index 99% rename from app/assets/javascripts/behaviors/copy_as_gfm.js rename to app/assets/javascripts/behaviors/markdown/copy_as_gfm.js index ffe90595b5..75cf90de0b 100644 --- a/app/assets/javascripts/behaviors/copy_as_gfm.js +++ b/app/assets/javascripts/behaviors/markdown/copy_as_gfm.js @@ -1,8 +1,9 @@ /* eslint-disable class-methods-use-this, object-shorthand, no-unused-vars, no-use-before-define, no-new, max-len, no-restricted-syntax, guard-for-in, no-continue */ +import $ from 'jquery'; import _ from 'underscore'; -import { insertText, getSelectedFragment, nodeMatchesSelector } from '../lib/utils/common_utils'; -import { placeholderImage } from '../lazy_loader'; +import { insertText, getSelectedFragment, nodeMatchesSelector } from '~/lib/utils/common_utils'; +import { placeholderImage } from '~/lazy_loader'; const gfmRules = { // The filters referenced in lib/banzai/pipeline/gfm_pipeline.rb convert diff --git a/app/assets/javascripts/render_gfm.js b/app/assets/javascripts/behaviors/markdown/render_gfm.js similarity index 85% rename from app/assets/javascripts/render_gfm.js rename to app/assets/javascripts/behaviors/markdown/render_gfm.js index 05a623ca6d..dbff2bd4b1 100644 --- a/app/assets/javascripts/render_gfm.js +++ b/app/assets/javascripts/behaviors/markdown/render_gfm.js @@ -1,6 +1,7 @@ +import $ from 'jquery'; +import syntaxHighlight from '~/syntax_highlight'; import renderMath from './render_math'; import renderMermaid from './render_mermaid'; -import syntaxHighlight from './syntax_highlight'; // Render Gitlab flavoured Markdown // diff --git a/app/assets/javascripts/render_math.js b/app/assets/javascripts/behaviors/markdown/render_math.js similarity index 85% rename from app/assets/javascripts/render_math.js rename to app/assets/javascripts/behaviors/markdown/render_math.js index eabdb01b2a..eb4e59d12b 100644 --- a/app/assets/javascripts/render_math.js +++ b/app/assets/javascripts/behaviors/markdown/render_math.js @@ -1,5 +1,6 @@ -import { __ } from './locale'; -import flash from './flash'; +import $ from 'jquery'; +import { __ } from '~/locale'; +import flash from '~/flash'; // Renders math using KaTeX in any element with the // `js-render-math` class @@ -30,7 +31,7 @@ export default function renderMath($els) { if (!$els.length) return; Promise.all([ import(/* webpackChunkName: 'katex' */ 'katex'), - import(/* webpackChunkName: 'katex' */ 'katex/dist/katex.css'), + import(/* webpackChunkName: 'katex' */ 'katex/dist/katex.min.css'), ]).then(([katex]) => { renderWithKaTeX($els, katex); }).catch(() => flash(__('An error occurred while rendering KaTeX'))); diff --git a/app/assets/javascripts/render_mermaid.js b/app/assets/javascripts/behaviors/markdown/render_mermaid.js similarity index 94% rename from app/assets/javascripts/render_mermaid.js rename to app/assets/javascripts/behaviors/markdown/render_mermaid.js index d4f18955bd..56b1896e9f 100644 --- a/app/assets/javascripts/render_mermaid.js +++ b/app/assets/javascripts/behaviors/markdown/render_mermaid.js @@ -1,3 +1,5 @@ +import flash from '~/flash'; + // Renders diagrams and flowcharts from text using Mermaid in any element with the // `js-render-mermaid` class. // @@ -12,8 +14,6 @@ // // -import Flash from './flash'; - export default function renderMermaid($els) { if (!$els.length) return; @@ -52,6 +52,6 @@ export default function renderMermaid($els) { }); }); }).catch((err) => { - Flash(`Can't load mermaid module: ${err}`); + flash(`Can't load mermaid module: ${err}`); }); } diff --git a/app/assets/javascripts/behaviors/quick_submit.js b/app/assets/javascripts/behaviors/quick_submit.js index 312edc0cd6..3ec932bdb7 100644 --- a/app/assets/javascripts/behaviors/quick_submit.js +++ b/app/assets/javascripts/behaviors/quick_submit.js @@ -1,3 +1,4 @@ +import $ from 'jquery'; import '../commons/bootstrap'; import { isInIssuePage } from '../lib/utils/common_utils'; @@ -72,5 +73,5 @@ $(document).on('keyup.quick_submit', '.js-quick-submit input[type=submit], .js-q title, trigger: 'manual', }); - $this.tooltip('show').one('blur', () => $this.tooltip('hide')); + $this.tooltip('show').one('blur click', () => $this.tooltip('hide')); }); diff --git a/app/assets/javascripts/behaviors/requires_input.js b/app/assets/javascripts/behaviors/requires_input.js index e10cb2e3dc..ffff4ddb71 100644 --- a/app/assets/javascripts/behaviors/requires_input.js +++ b/app/assets/javascripts/behaviors/requires_input.js @@ -1,3 +1,4 @@ +import $ from 'jquery'; import _ from 'underscore'; import '../commons/bootstrap'; diff --git a/app/assets/javascripts/behaviors/toggler_behavior.js b/app/assets/javascripts/behaviors/toggler_behavior.js index 81c8944142..4446be0e52 100644 --- a/app/assets/javascripts/behaviors/toggler_behavior.js +++ b/app/assets/javascripts/behaviors/toggler_behavior.js @@ -1,3 +1,6 @@ +import $ from 'jquery'; +import { getLocationHash } from '../lib/utils/url_utility'; + // Toggle button. Show/hide content inside parent container. // Button does not change visibility. If button has icon - it changes chevron style. // @@ -5,7 +8,6 @@ // %button.js-toggle-button // %div.js-toggle-content // -import { getLocationHash } from '../lib/utils/url_utility'; $(() => { function toggleContainer(container, toggleState) { diff --git a/app/assets/javascripts/blob/blob_file_dropzone.js b/app/assets/javascripts/blob/blob_file_dropzone.js index 83cac896f8..ff1739b167 100644 --- a/app/assets/javascripts/blob/blob_file_dropzone.js +++ b/app/assets/javascripts/blob/blob_file_dropzone.js @@ -1,4 +1,6 @@ /* eslint-disable func-names, object-shorthand, prefer-arrow-callback */ + +import $ from 'jquery'; import Dropzone from 'dropzone'; import { visitUrl } from '../lib/utils/url_utility'; import { HIDDEN_CLASS } from '../lib/utils/constants'; diff --git a/app/assets/javascripts/blob/blob_fork_suggestion.js b/app/assets/javascripts/blob/blob_fork_suggestion.js index 47c431fb80..476b9405a9 100644 --- a/app/assets/javascripts/blob/blob_fork_suggestion.js +++ b/app/assets/javascripts/blob/blob_fork_suggestion.js @@ -1,3 +1,5 @@ +import $ from 'jquery'; + const defaults = { // Buttons that will show the `suggestionSections` // has `data-fork-path`, and `data-action` diff --git a/app/assets/javascripts/blob/file_template_mediator.js b/app/assets/javascripts/blob/file_template_mediator.js index 37074301b5..030ca1907e 100644 --- a/app/assets/javascripts/blob/file_template_mediator.js +++ b/app/assets/javascripts/blob/file_template_mediator.js @@ -1,4 +1,6 @@ /* eslint-disable class-methods-use-this */ + +import $ from 'jquery'; import Flash from '../flash'; import FileTemplateTypeSelector from './template_selectors/type_selector'; import BlobCiYamlSelector from './template_selectors/ci_yaml_selector'; diff --git a/app/assets/javascripts/blob/file_template_selector.js b/app/assets/javascripts/blob/file_template_selector.js index 5ae30990ae..e52cf249f3 100644 --- a/app/assets/javascripts/blob/file_template_selector.js +++ b/app/assets/javascripts/blob/file_template_selector.js @@ -1,3 +1,5 @@ +import $ from 'jquery'; + export default class FileTemplateSelector { constructor(mediator) { this.mediator = mediator; diff --git a/app/assets/javascripts/blob/template_selector.js b/app/assets/javascripts/blob/template_selector.js index 888883163c..9dfdb06007 100644 --- a/app/assets/javascripts/blob/template_selector.js +++ b/app/assets/javascripts/blob/template_selector.js @@ -1,5 +1,7 @@ /* eslint-disable class-methods-use-this, no-unused-vars */ +import $ from 'jquery'; + export default class TemplateSelector { constructor({ dropdown, data, pattern, wrapper, editor, $input } = {}) { this.pattern = pattern; @@ -76,7 +78,7 @@ export default class TemplateSelector { if (!skipFocus) this.editor.focus(); - if (this.editor instanceof jQuery) { + if (this.editor instanceof $) { this.editor.get(0).dispatchEvent(this.autosizeUpdateEvent); } } diff --git a/app/assets/javascripts/blob/viewer/index.js b/app/assets/javascripts/blob/viewer/index.js index 92ea91c45a..137e1f5a09 100644 --- a/app/assets/javascripts/blob/viewer/index.js +++ b/app/assets/javascripts/blob/viewer/index.js @@ -1,3 +1,4 @@ +import $ from 'jquery'; import Flash from '../../flash'; import { handleLocationHash } from '../../lib/utils/common_utils'; import axios from '../../lib/utils/axios_utils'; diff --git a/app/assets/javascripts/blob_edit/blob_bundle.js b/app/assets/javascripts/blob_edit/blob_bundle.js index 931ed042df..4424232f64 100644 --- a/app/assets/javascripts/blob_edit/blob_bundle.js +++ b/app/assets/javascripts/blob_edit/blob_bundle.js @@ -1,5 +1,7 @@ /* eslint-disable func-names, space-before-function-paren, prefer-arrow-callback, no-var, quotes, vars-on-top, no-unused-vars, no-new, max-len */ /* global EditBlob */ + +import $ from 'jquery'; import NewCommitForm from '../new_commit_form'; import EditBlob from './edit_blob'; import BlobFileDropzone from '../blob/blob_file_dropzone'; diff --git a/app/assets/javascripts/blob_edit/edit_blob.js b/app/assets/javascripts/blob_edit/edit_blob.js index d4f6adaccb..82a3d494b6 100644 --- a/app/assets/javascripts/blob_edit/edit_blob.js +++ b/app/assets/javascripts/blob_edit/edit_blob.js @@ -1,5 +1,6 @@ /* global ace */ +import $ from 'jquery'; import axios from '~/lib/utils/axios_utils'; import createFlash from '~/flash'; import { __ } from '~/locale'; diff --git a/app/assets/javascripts/boards/components/board.js b/app/assets/javascripts/boards/components/board.js index 9c4cc2338c..3cffd91716 100644 --- a/app/assets/javascripts/boards/components/board.js +++ b/app/assets/javascripts/boards/components/board.js @@ -1,4 +1,6 @@ /* eslint-disable comma-dangle, space-before-function-paren, one-var */ + +import $ from 'jquery'; import Sortable from 'vendor/Sortable'; import Vue from 'vue'; import AccessorUtilities from '../../lib/utils/accessor'; diff --git a/app/assets/javascripts/boards/components/board_delete.js b/app/assets/javascripts/boards/components/board_delete.js index 8a1b177bba..7be98825fd 100644 --- a/app/assets/javascripts/boards/components/board_delete.js +++ b/app/assets/javascripts/boards/components/board_delete.js @@ -1,5 +1,6 @@ /* eslint-disable comma-dangle, space-before-function-paren, no-alert */ +import $ from 'jquery'; import Vue from 'vue'; window.gl = window.gl || {}; diff --git a/app/assets/javascripts/boards/components/board_new_issue.vue b/app/assets/javascripts/boards/components/board_new_issue.vue index 870d242e77..8d84c1735b 100644 --- a/app/assets/javascripts/boards/components/board_new_issue.vue +++ b/app/assets/javascripts/boards/components/board_new_issue.vue @@ -1,4 +1,5 @@ + + diff --git a/app/assets/javascripts/ide/components/commit_sidebar/actions.vue b/app/assets/javascripts/ide/components/commit_sidebar/actions.vue new file mode 100644 index 0000000000..2cbd982af1 --- /dev/null +++ b/app/assets/javascripts/ide/components/commit_sidebar/actions.vue @@ -0,0 +1,65 @@ + + + diff --git a/app/assets/javascripts/ide/components/commit_sidebar/list.vue b/app/assets/javascripts/ide/components/commit_sidebar/list.vue new file mode 100644 index 0000000000..453208f3f1 --- /dev/null +++ b/app/assets/javascripts/ide/components/commit_sidebar/list.vue @@ -0,0 +1,66 @@ + + + diff --git a/app/assets/javascripts/ide/components/commit_sidebar/list_collapsed.vue b/app/assets/javascripts/ide/components/commit_sidebar/list_collapsed.vue new file mode 100644 index 0000000000..15918ac963 --- /dev/null +++ b/app/assets/javascripts/ide/components/commit_sidebar/list_collapsed.vue @@ -0,0 +1,35 @@ + + + diff --git a/app/assets/javascripts/ide/components/commit_sidebar/list_item.vue b/app/assets/javascripts/ide/components/commit_sidebar/list_item.vue new file mode 100644 index 0000000000..560cdd941c --- /dev/null +++ b/app/assets/javascripts/ide/components/commit_sidebar/list_item.vue @@ -0,0 +1,58 @@ + + + diff --git a/app/assets/javascripts/ide/components/commit_sidebar/radio_group.vue b/app/assets/javascripts/ide/components/commit_sidebar/radio_group.vue new file mode 100644 index 0000000000..4310d762c7 --- /dev/null +++ b/app/assets/javascripts/ide/components/commit_sidebar/radio_group.vue @@ -0,0 +1,94 @@ + + + diff --git a/app/assets/javascripts/ide/components/editor_mode_dropdown.vue b/app/assets/javascripts/ide/components/editor_mode_dropdown.vue new file mode 100644 index 0000000000..0c44a755f5 --- /dev/null +++ b/app/assets/javascripts/ide/components/editor_mode_dropdown.vue @@ -0,0 +1,130 @@ + + + diff --git a/app/assets/javascripts/ide/components/ide.vue b/app/assets/javascripts/ide/components/ide.vue new file mode 100644 index 0000000000..1c237c0ec9 --- /dev/null +++ b/app/assets/javascripts/ide/components/ide.vue @@ -0,0 +1,108 @@ + + + diff --git a/app/assets/javascripts/ide/components/ide_context_bar.vue b/app/assets/javascripts/ide/components/ide_context_bar.vue new file mode 100644 index 0000000000..79a83b4799 --- /dev/null +++ b/app/assets/javascripts/ide/components/ide_context_bar.vue @@ -0,0 +1,84 @@ + + + diff --git a/app/assets/javascripts/ide/components/ide_external_links.vue b/app/assets/javascripts/ide/components/ide_external_links.vue new file mode 100644 index 0000000000..c6f6e0d234 --- /dev/null +++ b/app/assets/javascripts/ide/components/ide_external_links.vue @@ -0,0 +1,43 @@ + + + diff --git a/app/assets/javascripts/ide/components/ide_file_buttons.vue b/app/assets/javascripts/ide/components/ide_file_buttons.vue new file mode 100644 index 0000000000..a6c6f46a14 --- /dev/null +++ b/app/assets/javascripts/ide/components/ide_file_buttons.vue @@ -0,0 +1,84 @@ + + + diff --git a/app/assets/javascripts/ide/components/ide_project_branches_tree.vue b/app/assets/javascripts/ide/components/ide_project_branches_tree.vue new file mode 100644 index 0000000000..eb2749e615 --- /dev/null +++ b/app/assets/javascripts/ide/components/ide_project_branches_tree.vue @@ -0,0 +1,47 @@ + + + diff --git a/app/assets/javascripts/ide/components/ide_project_tree.vue b/app/assets/javascripts/ide/components/ide_project_tree.vue new file mode 100644 index 0000000000..a6f40286ac --- /dev/null +++ b/app/assets/javascripts/ide/components/ide_project_tree.vue @@ -0,0 +1,65 @@ + + + diff --git a/app/assets/javascripts/ide/components/ide_repo_tree.vue b/app/assets/javascripts/ide/components/ide_repo_tree.vue new file mode 100644 index 0000000000..e6af88e04b --- /dev/null +++ b/app/assets/javascripts/ide/components/ide_repo_tree.vue @@ -0,0 +1,41 @@ + + + diff --git a/app/assets/javascripts/ide/components/ide_side_bar.vue b/app/assets/javascripts/ide/components/ide_side_bar.vue new file mode 100644 index 0000000000..8cf1ccb4fc --- /dev/null +++ b/app/assets/javascripts/ide/components/ide_side_bar.vue @@ -0,0 +1,51 @@ + + + diff --git a/app/assets/javascripts/ide/components/ide_status_bar.vue b/app/assets/javascripts/ide/components/ide_status_bar.vue new file mode 100644 index 0000000000..152a5f632a --- /dev/null +++ b/app/assets/javascripts/ide/components/ide_status_bar.vue @@ -0,0 +1,60 @@ + + + diff --git a/app/assets/javascripts/ide/components/mr_file_icon.vue b/app/assets/javascripts/ide/components/mr_file_icon.vue new file mode 100644 index 0000000000..8a440902df --- /dev/null +++ b/app/assets/javascripts/ide/components/mr_file_icon.vue @@ -0,0 +1,23 @@ + + + diff --git a/app/assets/javascripts/ide/components/new_dropdown/index.vue b/app/assets/javascripts/ide/components/new_dropdown/index.vue new file mode 100644 index 0000000000..769e9b79ca --- /dev/null +++ b/app/assets/javascripts/ide/components/new_dropdown/index.vue @@ -0,0 +1,111 @@ + + + diff --git a/app/assets/javascripts/ide/components/new_dropdown/modal.vue b/app/assets/javascripts/ide/components/new_dropdown/modal.vue new file mode 100644 index 0000000000..4b5a50785b --- /dev/null +++ b/app/assets/javascripts/ide/components/new_dropdown/modal.vue @@ -0,0 +1,99 @@ + + + diff --git a/app/assets/javascripts/ide/components/new_dropdown/upload.vue b/app/assets/javascripts/ide/components/new_dropdown/upload.vue new file mode 100644 index 0000000000..c165af5ce5 --- /dev/null +++ b/app/assets/javascripts/ide/components/new_dropdown/upload.vue @@ -0,0 +1,75 @@ + + + diff --git a/app/assets/javascripts/ide/components/repo_commit_section.vue b/app/assets/javascripts/ide/components/repo_commit_section.vue new file mode 100644 index 0000000000..d885ed5e30 --- /dev/null +++ b/app/assets/javascripts/ide/components/repo_commit_section.vue @@ -0,0 +1,172 @@ + + + diff --git a/app/assets/javascripts/ide/components/repo_editor.vue b/app/assets/javascripts/ide/components/repo_editor.vue new file mode 100644 index 0000000000..711bafa17a --- /dev/null +++ b/app/assets/javascripts/ide/components/repo_editor.vue @@ -0,0 +1,219 @@ + + + diff --git a/app/assets/javascripts/ide/components/repo_file.vue b/app/assets/javascripts/ide/components/repo_file.vue new file mode 100644 index 0000000000..3b5068d491 --- /dev/null +++ b/app/assets/javascripts/ide/components/repo_file.vue @@ -0,0 +1,127 @@ + + + diff --git a/app/assets/javascripts/ide/components/repo_file_status_icon.vue b/app/assets/javascripts/ide/components/repo_file_status_icon.vue new file mode 100644 index 0000000000..97589e116c --- /dev/null +++ b/app/assets/javascripts/ide/components/repo_file_status_icon.vue @@ -0,0 +1,39 @@ + + + diff --git a/app/assets/javascripts/ide/components/repo_loading_file.vue b/app/assets/javascripts/ide/components/repo_loading_file.vue new file mode 100644 index 0000000000..79af8c0b0c --- /dev/null +++ b/app/assets/javascripts/ide/components/repo_loading_file.vue @@ -0,0 +1,42 @@ + + + diff --git a/app/assets/javascripts/ide/components/repo_tab.vue b/app/assets/javascripts/ide/components/repo_tab.vue new file mode 100644 index 0000000000..304a73ed1a --- /dev/null +++ b/app/assets/javascripts/ide/components/repo_tab.vue @@ -0,0 +1,104 @@ + + + diff --git a/app/assets/javascripts/ide/components/repo_tabs.vue b/app/assets/javascripts/ide/components/repo_tabs.vue new file mode 100644 index 0000000000..7bd646ba9b --- /dev/null +++ b/app/assets/javascripts/ide/components/repo_tabs.vue @@ -0,0 +1,82 @@ + + + diff --git a/app/assets/javascripts/ide/components/resizable_panel.vue b/app/assets/javascripts/ide/components/resizable_panel.vue new file mode 100644 index 0000000000..5ea2a2f682 --- /dev/null +++ b/app/assets/javascripts/ide/components/resizable_panel.vue @@ -0,0 +1,85 @@ + + + diff --git a/app/assets/javascripts/ide/eventhub.js b/app/assets/javascripts/ide/eventhub.js new file mode 100644 index 0000000000..0948c2e535 --- /dev/null +++ b/app/assets/javascripts/ide/eventhub.js @@ -0,0 +1,3 @@ +import Vue from 'vue'; + +export default new Vue(); diff --git a/app/assets/javascripts/ide/ide_router.js b/app/assets/javascripts/ide/ide_router.js new file mode 100644 index 0000000000..4a0a303d5a --- /dev/null +++ b/app/assets/javascripts/ide/ide_router.js @@ -0,0 +1,173 @@ +import Vue from 'vue'; +import VueRouter from 'vue-router'; +import flash from '~/flash'; +import store from './stores'; + +Vue.use(VueRouter); + +/** + * Routes below /-/ide/: + +/project/h5bp/html5-boilerplate/blob/master +/project/h5bp/html5-boilerplate/blob/master/app/js/test.js + +/project/h5bp/html5-boilerplate/mr/123 +/project/h5bp/html5-boilerplate/mr/123/app/js/test.js + +/workspace/123 +/workspace/project/h5bp/html5-boilerplate/blob/my-special-branch +/workspace/project/h5bp/html5-boilerplate/mr/123 + +/ = /workspace + +/settings +*/ + +// Unfortunately Vue Router doesn't work without at least a fake component +// If you do only data handling +const EmptyRouterComponent = { + render(createElement) { + return createElement('div'); + }, +}; + +const router = new VueRouter({ + mode: 'history', + base: `${gon.relative_url_root}/-/ide/`, + routes: [ + { + path: '/project/:namespace/:project+', + component: EmptyRouterComponent, + children: [ + { + path: ':targetmode(edit|tree|blob)/:branch/*', + component: EmptyRouterComponent, + }, + { + path: 'merge_requests/:mrid', + component: EmptyRouterComponent, + }, + ], + }, + ], +}); + +router.beforeEach((to, from, next) => { + if (to.params.namespace && to.params.project) { + store + .dispatch('getProjectData', { + namespace: to.params.namespace, + projectId: to.params.project, + }) + .then(() => { + const fullProjectId = `${to.params.namespace}/${to.params.project}`; + + if (to.params.branch) { + store.dispatch('getBranchData', { + projectId: fullProjectId, + branchId: to.params.branch, + }); + + store + .dispatch('getFiles', { + projectId: fullProjectId, + branchId: to.params.branch, + }) + .then(() => { + if (to.params[0]) { + const path = + to.params[0].slice(-1) === '/' ? to.params[0].slice(0, -1) : to.params[0]; + const treeEntryKey = Object.keys(store.state.entries).find( + key => key === path && !store.state.entries[key].pending, + ); + const treeEntry = store.state.entries[treeEntryKey]; + + if (treeEntry) { + store.dispatch('handleTreeEntryAction', treeEntry); + } + } + }) + .catch(e => { + flash( + 'Error while loading the branch files. Please try again.', + 'alert', + document, + null, + false, + true, + ); + throw e; + }); + } else if (to.params.mrid) { + store.dispatch('updateViewer', 'mrdiff'); + + store + .dispatch('getMergeRequestData', { + projectId: fullProjectId, + mergeRequestId: to.params.mrid, + }) + .then(mr => { + store.dispatch('getBranchData', { + projectId: fullProjectId, + branchId: mr.source_branch, + }); + + return store.dispatch('getFiles', { + projectId: fullProjectId, + branchId: mr.source_branch, + }); + }) + .then(() => + store.dispatch('getMergeRequestVersions', { + projectId: fullProjectId, + mergeRequestId: to.params.mrid, + }), + ) + .then(() => + store.dispatch('getMergeRequestChanges', { + projectId: fullProjectId, + mergeRequestId: to.params.mrid, + }), + ) + .then(mrChanges => { + mrChanges.changes.forEach((change, ind) => { + const changeTreeEntry = store.state.entries[change.new_path]; + + if (changeTreeEntry) { + store.dispatch('setFileMrChange', { + file: changeTreeEntry, + mrChange: change, + }); + + if (ind < 10) { + store.dispatch('getFileData', { + path: change.new_path, + makeFileActive: ind === 0, + }); + } + } + }); + }) + .catch(e => { + flash('Error while loading the merge request. Please try again.'); + throw e; + }); + } + }) + .catch(e => { + flash( + 'Error while loading the project data. Please try again.', + 'alert', + document, + null, + false, + true, + ); + throw e; + }); + } + + next(); +}); + +export default router; diff --git a/app/assets/javascripts/ide/index.js b/app/assets/javascripts/ide/index.js new file mode 100644 index 0000000000..cbfb3dc54f --- /dev/null +++ b/app/assets/javascripts/ide/index.js @@ -0,0 +1,33 @@ +import Vue from 'vue'; +import Translate from '~/vue_shared/translate'; +import ide from './components/ide.vue'; +import store from './stores'; +import router from './ide_router'; + +function initIde(el) { + if (!el) return null; + + return new Vue({ + el, + store, + router, + components: { + ide, + }, + render(createElement) { + return createElement('ide', { + props: { + emptyStateSvgPath: el.dataset.emptyStateSvgPath, + noChangesStateSvgPath: el.dataset.noChangesStateSvgPath, + committedStateSvgPath: el.dataset.committedStateSvgPath, + }, + }); + }, + }); +} + +const ideElement = document.getElementById('ide'); + +Vue.use(Translate); + +initIde(ideElement); diff --git a/app/assets/javascripts/ide/lib/common/disposable.js b/app/assets/javascripts/ide/lib/common/disposable.js new file mode 100644 index 0000000000..84b29bdb60 --- /dev/null +++ b/app/assets/javascripts/ide/lib/common/disposable.js @@ -0,0 +1,14 @@ +export default class Disposable { + constructor() { + this.disposers = new Set(); + } + + add(...disposers) { + disposers.forEach(disposer => this.disposers.add(disposer)); + } + + dispose() { + this.disposers.forEach(disposer => disposer.dispose()); + this.disposers.clear(); + } +} diff --git a/app/assets/javascripts/ide/lib/common/model.js b/app/assets/javascripts/ide/lib/common/model.js new file mode 100644 index 0000000000..e47adae99e --- /dev/null +++ b/app/assets/javascripts/ide/lib/common/model.js @@ -0,0 +1,94 @@ +/* global monaco */ +import Disposable from './disposable'; +import eventHub from '../../eventhub'; + +export default class Model { + constructor(monaco, file) { + this.monaco = monaco; + this.disposable = new Disposable(); + this.file = file; + this.content = file.content !== '' ? file.content : file.raw; + + this.disposable.add( + (this.originalModel = this.monaco.editor.createModel( + this.file.raw, + undefined, + new this.monaco.Uri(null, null, `original/${this.file.key}`), + )), + (this.model = this.monaco.editor.createModel( + this.content, + undefined, + new this.monaco.Uri(null, null, this.file.key), + )), + ); + if (this.file.mrChange) { + this.disposable.add( + (this.baseModel = this.monaco.editor.createModel( + this.file.baseRaw, + undefined, + new this.monaco.Uri(null, null, `target/${this.file.path}`), + )), + ); + } + + this.events = new Map(); + + this.updateContent = this.updateContent.bind(this); + this.dispose = this.dispose.bind(this); + + eventHub.$on(`editor.update.model.dispose.${this.file.key}`, this.dispose); + eventHub.$on(`editor.update.model.content.${this.file.path}`, this.updateContent); + } + + get url() { + return this.model.uri.toString(); + } + + get language() { + return this.model.getModeId(); + } + + get eol() { + return this.model.getEOL() === '\n' ? 'LF' : 'CRLF'; + } + + get path() { + return this.file.key; + } + + getModel() { + return this.model; + } + + getOriginalModel() { + return this.originalModel; + } + + getBaseModel() { + return this.baseModel; + } + + setValue(value) { + this.getModel().setValue(value); + } + + onChange(cb) { + this.events.set( + this.path, + this.disposable.add(this.model.onDidChangeContent(e => cb(this, e))), + ); + } + + updateContent(content) { + this.getOriginalModel().setValue(content); + this.getModel().setValue(content); + } + + dispose() { + this.disposable.dispose(); + this.events.clear(); + + eventHub.$off(`editor.update.model.dispose.${this.file.key}`, this.dispose); + eventHub.$off(`editor.update.model.content.${this.file.path}`, this.updateContent); + } +} diff --git a/app/assets/javascripts/ide/lib/common/model_manager.js b/app/assets/javascripts/ide/lib/common/model_manager.js new file mode 100644 index 0000000000..0e7b563b5d --- /dev/null +++ b/app/assets/javascripts/ide/lib/common/model_manager.js @@ -0,0 +1,48 @@ +import eventHub from '../../eventhub'; +import Disposable from './disposable'; +import Model from './model'; + +export default class ModelManager { + constructor(monaco) { + this.monaco = monaco; + this.disposable = new Disposable(); + this.models = new Map(); + } + + hasCachedModel(key) { + return this.models.has(key); + } + + getModel(key) { + return this.models.get(key); + } + + addModel(file) { + if (this.hasCachedModel(file.key)) { + return this.getModel(file.key); + } + + const model = new Model(this.monaco, file); + this.models.set(model.path, model); + this.disposable.add(model); + + eventHub.$on( + `editor.update.model.dispose.${file.key}`, + this.removeCachedModel.bind(this, file), + ); + + return model; + } + + removeCachedModel(file) { + this.models.delete(file.key); + + eventHub.$off(`editor.update.model.dispose.${file.key}`, this.removeCachedModel); + } + + dispose() { + // dispose of all the models + this.disposable.dispose(); + this.models.clear(); + } +} diff --git a/app/assets/javascripts/ide/lib/decorations/controller.js b/app/assets/javascripts/ide/lib/decorations/controller.js new file mode 100644 index 0000000000..4290477474 --- /dev/null +++ b/app/assets/javascripts/ide/lib/decorations/controller.js @@ -0,0 +1,45 @@ +export default class DecorationsController { + constructor(editor) { + this.editor = editor; + this.decorations = new Map(); + this.editorDecorations = new Map(); + } + + getAllDecorationsForModel(model) { + if (!this.decorations.has(model.url)) return []; + + const modelDecorations = this.decorations.get(model.url); + const decorations = []; + + modelDecorations.forEach(val => decorations.push(...val)); + + return decorations; + } + + addDecorations(model, decorationsKey, decorations) { + const decorationMap = this.decorations.get(model.url) || new Map(); + + decorationMap.set(decorationsKey, decorations); + + this.decorations.set(model.url, decorationMap); + + this.decorate(model); + } + + decorate(model) { + if (!this.editor.instance) return; + + const decorations = this.getAllDecorationsForModel(model); + const oldDecorations = this.editorDecorations.get(model.url) || []; + + this.editorDecorations.set( + model.url, + this.editor.instance.deltaDecorations(oldDecorations, decorations), + ); + } + + dispose() { + this.decorations.clear(); + this.editorDecorations.clear(); + } +} diff --git a/app/assets/javascripts/ide/lib/diff/controller.js b/app/assets/javascripts/ide/lib/diff/controller.js new file mode 100644 index 0000000000..b136545ad1 --- /dev/null +++ b/app/assets/javascripts/ide/lib/diff/controller.js @@ -0,0 +1,72 @@ +/* global monaco */ +import { throttle } from 'underscore'; +import DirtyDiffWorker from './diff_worker'; +import Disposable from '../common/disposable'; + +export const getDiffChangeType = (change) => { + if (change.modified) { + return 'modified'; + } else if (change.added) { + return 'added'; + } else if (change.removed) { + return 'removed'; + } + + return ''; +}; + +export const getDecorator = change => ({ + range: new monaco.Range( + change.lineNumber, + 1, + change.endLineNumber, + 1, + ), + options: { + isWholeLine: true, + linesDecorationsClassName: `dirty-diff dirty-diff-${getDiffChangeType(change)}`, + }, +}); + +export default class DirtyDiffController { + constructor(modelManager, decorationsController) { + this.disposable = new Disposable(); + this.editorSimpleWorker = null; + this.modelManager = modelManager; + this.decorationsController = decorationsController; + this.dirtyDiffWorker = new DirtyDiffWorker(); + this.throttledComputeDiff = throttle(this.computeDiff, 250); + this.decorate = this.decorate.bind(this); + + this.dirtyDiffWorker.addEventListener('message', this.decorate); + } + + attachModel(model) { + model.onChange(() => this.throttledComputeDiff(model)); + } + + computeDiff(model) { + this.dirtyDiffWorker.postMessage({ + path: model.path, + originalContent: model.getOriginalModel().getValue(), + newContent: model.getModel().getValue(), + }); + } + + reDecorate(model) { + this.decorationsController.decorate(model); + } + + decorate({ data }) { + const decorations = data.changes.map(change => getDecorator(change)); + const model = this.modelManager.getModel(data.path); + this.decorationsController.addDecorations(model, 'dirtyDiff', decorations); + } + + dispose() { + this.disposable.dispose(); + + this.dirtyDiffWorker.removeEventListener('message', this.decorate); + this.dirtyDiffWorker.terminate(); + } +} diff --git a/app/assets/javascripts/ide/lib/diff/diff.js b/app/assets/javascripts/ide/lib/diff/diff.js new file mode 100644 index 0000000000..0e37f5c470 --- /dev/null +++ b/app/assets/javascripts/ide/lib/diff/diff.js @@ -0,0 +1,30 @@ +import { diffLines } from 'diff'; + +// eslint-disable-next-line import/prefer-default-export +export const computeDiff = (originalContent, newContent) => { + const changes = diffLines(originalContent, newContent); + + let lineNumber = 1; + return changes.reduce((acc, change) => { + const findOnLine = acc.find(c => c.lineNumber === lineNumber); + + if (findOnLine) { + Object.assign(findOnLine, change, { + modified: true, + endLineNumber: (lineNumber + change.count) - 1, + }); + } else if ('added' in change || 'removed' in change) { + acc.push(Object.assign({}, change, { + lineNumber, + modified: undefined, + endLineNumber: (lineNumber + change.count) - 1, + })); + } + + if (!change.removed) { + lineNumber += change.count; + } + + return acc; + }, []); +}; diff --git a/app/assets/javascripts/ide/lib/diff/diff_worker.js b/app/assets/javascripts/ide/lib/diff/diff_worker.js new file mode 100644 index 0000000000..e74c404633 --- /dev/null +++ b/app/assets/javascripts/ide/lib/diff/diff_worker.js @@ -0,0 +1,10 @@ +import { computeDiff } from './diff'; + +self.addEventListener('message', (e) => { + const data = e.data; + + self.postMessage({ + path: data.path, + changes: computeDiff(data.originalContent, data.newContent), + }); +}); diff --git a/app/assets/javascripts/ide/lib/editor.js b/app/assets/javascripts/ide/lib/editor.js new file mode 100644 index 0000000000..001737d6ee --- /dev/null +++ b/app/assets/javascripts/ide/lib/editor.js @@ -0,0 +1,192 @@ +import _ from 'underscore'; +import DecorationsController from './decorations/controller'; +import DirtyDiffController from './diff/controller'; +import Disposable from './common/disposable'; +import ModelManager from './common/model_manager'; +import editorOptions, { defaultEditorOptions } from './editor_options'; +import gitlabTheme from './themes/gl_theme'; + +export const clearDomElement = el => { + if (!el || !el.firstChild) return; + + while (el.firstChild) { + el.removeChild(el.firstChild); + } +}; + +export default class Editor { + static create(monaco) { + if (this.editorInstance) return this.editorInstance; + + this.editorInstance = new Editor(monaco); + + return this.editorInstance; + } + + constructor(monaco) { + this.monaco = monaco; + this.currentModel = null; + this.instance = null; + this.dirtyDiffController = null; + this.disposable = new Disposable(); + this.modelManager = new ModelManager(this.monaco); + this.decorationsController = new DecorationsController(this); + + this.setupMonacoTheme(); + + this.debouncedUpdate = _.debounce(() => { + this.updateDimensions(); + }, 200); + } + + createInstance(domElement) { + if (!this.instance) { + clearDomElement(domElement); + + this.disposable.add( + (this.instance = this.monaco.editor.create(domElement, { + ...defaultEditorOptions, + })), + (this.dirtyDiffController = new DirtyDiffController( + this.modelManager, + this.decorationsController, + )), + ); + + window.addEventListener('resize', this.debouncedUpdate, false); + } + } + + createDiffInstance(domElement) { + if (!this.instance) { + clearDomElement(domElement); + + this.disposable.add( + (this.instance = this.monaco.editor.createDiffEditor(domElement, { + ...defaultEditorOptions, + readOnly: true, + quickSuggestions: false, + occurrencesHighlight: false, + renderLineHighlight: 'none', + hideCursorInOverviewRuler: true, + renderSideBySide: Editor.renderSideBySide(domElement), + })), + ); + + window.addEventListener('resize', this.debouncedUpdate, false); + } + } + + createModel(file) { + return this.modelManager.addModel(file); + } + + attachModel(model) { + if (this.isDiffEditorType) { + this.instance.setModel({ + original: model.getOriginalModel(), + modified: model.getModel(), + }); + + return; + } + + this.instance.setModel(model.getModel()); + if (this.dirtyDiffController) this.dirtyDiffController.attachModel(model); + + this.currentModel = model; + + this.instance.updateOptions( + editorOptions.reduce((acc, obj) => { + Object.keys(obj).forEach(key => { + Object.assign(acc, { + [key]: obj[key](model), + }); + }); + return acc; + }, {}), + ); + + if (this.dirtyDiffController) this.dirtyDiffController.reDecorate(model); + } + + attachMergeRequestModel(model) { + this.instance.setModel({ + original: model.getBaseModel(), + modified: model.getModel(), + }); + + this.monaco.editor.createDiffNavigator(this.instance, { + alwaysRevealFirst: true, + }); + } + + setupMonacoTheme() { + this.monaco.editor.defineTheme(gitlabTheme.themeName, gitlabTheme.monacoTheme); + + this.monaco.editor.setTheme('gitlab'); + } + + clearEditor() { + if (this.instance) { + this.instance.setModel(null); + } + } + + dispose() { + window.removeEventListener('resize', this.debouncedUpdate); + + // catch any potential errors with disposing the error + // this is mainly for tests caused by elements not existing + try { + this.disposable.dispose(); + + this.instance = null; + } catch (e) { + this.instance = null; + + if (process.env.NODE_ENV !== 'test') { + // eslint-disable-next-line no-console + console.error(e); + } + } + } + + updateDimensions() { + this.instance.layout(); + this.updateDiffView(); + } + + setPosition({ lineNumber, column }) { + this.instance.revealPositionInCenter({ + lineNumber, + column, + }); + this.instance.setPosition({ + lineNumber, + column, + }); + } + + onPositionChange(cb) { + if (!this.instance.onDidChangeCursorPosition) return; + + this.disposable.add(this.instance.onDidChangeCursorPosition(e => cb(this.instance, e))); + } + + updateDiffView() { + if (!this.isDiffEditorType) return; + + this.instance.updateOptions({ + renderSideBySide: Editor.renderSideBySide(this.instance.getDomNode()), + }); + } + + get isDiffEditorType() { + return this.instance.getEditorType() === 'vs.editor.IDiffEditor'; + } + + static renderSideBySide(domElement) { + return domElement.offsetWidth >= 700; + } +} diff --git a/app/assets/javascripts/ide/lib/editor_options.js b/app/assets/javascripts/ide/lib/editor_options.js new file mode 100644 index 0000000000..9f895d49f2 --- /dev/null +++ b/app/assets/javascripts/ide/lib/editor_options.js @@ -0,0 +1,16 @@ +export const defaultEditorOptions = { + model: null, + readOnly: false, + contextmenu: true, + scrollBeyondLastLine: false, + minimap: { + enabled: false, + }, + wordWrap: 'on', +}; + +export default [ + { + readOnly: model => !!model.file.file_lock, + }, +]; diff --git a/app/assets/javascripts/ide/lib/themes/gl_theme.js b/app/assets/javascripts/ide/lib/themes/gl_theme.js new file mode 100644 index 0000000000..2fc96250c7 --- /dev/null +++ b/app/assets/javascripts/ide/lib/themes/gl_theme.js @@ -0,0 +1,14 @@ +export default { + themeName: 'gitlab', + monacoTheme: { + base: 'vs', + inherit: true, + rules: [], + colors: { + 'editorLineNumber.foreground': '#CCCCCC', + 'diffEditor.insertedTextBackground': '#ddfbe6', + 'diffEditor.removedTextBackground': '#f9d7dc', + 'editor.selectionBackground': '#aad6f8', + }, + }, +}; diff --git a/app/assets/javascripts/ide/monaco_loader.js b/app/assets/javascripts/ide/monaco_loader.js new file mode 100644 index 0000000000..142a220097 --- /dev/null +++ b/app/assets/javascripts/ide/monaco_loader.js @@ -0,0 +1,16 @@ +import monacoContext from 'monaco-editor/dev/vs/loader'; + +monacoContext.require.config({ + paths: { + vs: `${__webpack_public_path__}monaco-editor/vs`, // eslint-disable-line camelcase + }, +}); + +// ignore CDN config and use local assets path for service worker which cannot be cross-domain +const relativeRootPath = (gon && gon.relative_url_root) || ''; +const monacoPath = `${relativeRootPath}/assets/webpack/monaco-editor/vs`; +window.MonacoEnvironment = { getWorkerUrl: () => `${monacoPath}/base/worker/workerMain.js` }; + +// eslint-disable-next-line no-underscore-dangle +window.__monaco_context__ = monacoContext; +export default monacoContext.require; diff --git a/app/assets/javascripts/ide/services/index.js b/app/assets/javascripts/ide/services/index.js new file mode 100644 index 0000000000..a12e637616 --- /dev/null +++ b/app/assets/javascripts/ide/services/index.js @@ -0,0 +1,78 @@ +import Vue from 'vue'; +import VueResource from 'vue-resource'; +import Api from '~/api'; + +Vue.use(VueResource); + +export default { + getTreeData(endpoint) { + return Vue.http.get(endpoint, { params: { format: 'json' } }); + }, + getFileData(endpoint) { + return Vue.http.get(endpoint, { params: { format: 'json' } }); + }, + getRawFileData(file) { + if (file.tempFile) { + return Promise.resolve(file.content); + } + + if (file.raw) { + return Promise.resolve(file.raw); + } + + return Vue.http.get(file.rawPath, { params: { format: 'json' } }).then(res => res.text()); + }, + getBaseRawFileData(file, sha) { + if (file.tempFile) { + return Promise.resolve(file.baseRaw); + } + + if (file.baseRaw) { + return Promise.resolve(file.baseRaw); + } + + return Vue.http + .get(file.rawPath.replace(`/raw/${file.branchId}/${file.path}`, `/raw/${sha}/${file.path}`), { + params: { format: 'json' }, + }) + .then(res => res.text()); + }, + getProjectData(namespace, project) { + return Api.project(`${namespace}/${project}`); + }, + getProjectMergeRequestData(projectId, mergeRequestId) { + return Api.mergeRequest(projectId, mergeRequestId); + }, + getProjectMergeRequestChanges(projectId, mergeRequestId) { + return Api.mergeRequestChanges(projectId, mergeRequestId); + }, + getProjectMergeRequestVersions(projectId, mergeRequestId) { + return Api.mergeRequestVersions(projectId, mergeRequestId); + }, + getBranchData(projectId, currentBranchId) { + return Api.branchSingle(projectId, currentBranchId); + }, + createBranch(projectId, payload) { + const url = Api.buildUrl(Api.createBranchPath).replace(':id', projectId); + + return Vue.http.post(url, payload); + }, + commit(projectId, payload) { + return Api.commitMultiple(projectId, payload); + }, + getTreeLastCommit(endpoint) { + return Vue.http.get(endpoint, { + params: { + format: 'json', + }, + }); + }, + getFiles(projectUrl, branchId) { + const url = `${projectUrl}/files/${branchId}`; + return Vue.http.get(url, { + params: { + format: 'json', + }, + }); + }, +}; diff --git a/app/assets/javascripts/ide/stores/actions.js b/app/assets/javascripts/ide/stores/actions.js new file mode 100644 index 0000000000..c6ba679d99 --- /dev/null +++ b/app/assets/javascripts/ide/stores/actions.js @@ -0,0 +1,118 @@ +import Vue from 'vue'; +import { visitUrl } from '~/lib/utils/url_utility'; +import flash from '~/flash'; +import * as types from './mutation_types'; +import FilesDecoratorWorker from './workers/files_decorator_worker'; + +export const redirectToUrl = (_, url) => visitUrl(url); + +export const setInitialData = ({ commit }, data) => commit(types.SET_INITIAL_DATA, data); + +export const discardAllChanges = ({ state, commit, dispatch }) => { + state.changedFiles.forEach(file => { + commit(types.DISCARD_FILE_CHANGES, file.path); + + if (file.tempFile) { + dispatch('closeFile', file.path); + } + }); + + commit(types.REMOVE_ALL_CHANGES_FILES); +}; + +export const closeAllFiles = ({ state, dispatch }) => { + state.openFiles.forEach(file => dispatch('closeFile', file)); +}; + +export const setPanelCollapsedStatus = ({ commit }, { side, collapsed }) => { + if (side === 'left') { + commit(types.SET_LEFT_PANEL_COLLAPSED, collapsed); + } else { + commit(types.SET_RIGHT_PANEL_COLLAPSED, collapsed); + } +}; + +export const setResizingStatus = ({ commit }, resizing) => { + commit(types.SET_RESIZING_STATUS, resizing); +}; + +export const createTempEntry = ( + { state, commit, dispatch }, + { branchId, name, type, content = '', base64 = false }, +) => + new Promise(resolve => { + const worker = new FilesDecoratorWorker(); + const fullName = name.slice(-1) !== '/' && type === 'tree' ? `${name}/` : name; + + if (state.entries[name]) { + flash( + `The name "${name.split('/').pop()}" is already taken in this directory.`, + 'alert', + document, + null, + false, + true, + ); + + resolve(); + + return null; + } + + worker.addEventListener('message', ({ data }) => { + const { file } = data; + + worker.terminate(); + + commit(types.CREATE_TMP_ENTRY, { + data, + projectId: state.currentProjectId, + branchId, + }); + + if (type === 'blob') { + commit(types.TOGGLE_FILE_OPEN, file.path); + commit(types.ADD_FILE_TO_CHANGED, file.path); + dispatch('setFileActive', file.path); + } + + resolve(file); + }); + + worker.postMessage({ + data: [fullName], + projectId: state.currentProjectId, + branchId, + type, + tempFile: true, + base64, + content, + }); + + return null; + }); + +export const scrollToTab = () => { + Vue.nextTick(() => { + const tabs = document.getElementById('tabs'); + + if (tabs) { + const tabEl = tabs.querySelector('.active .repo-tab'); + + tabEl.focus(); + } + }); +}; + +export const updateViewer = ({ commit }, viewer) => { + commit(types.UPDATE_VIEWER, viewer); +}; + +export const updateDelayViewerUpdated = ({ commit }, delay) => { + commit(types.UPDATE_DELAY_VIEWER_CHANGE, delay); +}; + +export * from './actions/tree'; +export * from './actions/file'; +export * from './actions/project'; +export * from './actions/merge_request'; diff --git a/app/assets/javascripts/ide/stores/actions/file.js b/app/assets/javascripts/ide/stores/actions/file.js new file mode 100644 index 0000000000..66c60ad605 --- /dev/null +++ b/app/assets/javascripts/ide/stores/actions/file.js @@ -0,0 +1,187 @@ +import { normalizeHeaders } from '~/lib/utils/common_utils'; +import flash from '~/flash'; +import eventHub from '../../eventhub'; +import service from '../../services'; +import * as types from '../mutation_types'; +import router from '../../ide_router'; +import { setPageTitle } from '../utils'; + +export const closeFile = ({ commit, state, dispatch }, file) => { + const path = file.path; + const indexOfClosedFile = state.openFiles.findIndex(f => f.key === file.key); + const fileWasActive = file.active; + + if (file.pending) { + commit(types.REMOVE_PENDING_TAB, file); + } else { + commit(types.TOGGLE_FILE_OPEN, path); + commit(types.SET_FILE_ACTIVE, { path, active: false }); + } + + if (state.openFiles.length > 0 && fileWasActive) { + const nextIndexToOpen = indexOfClosedFile === 0 ? 0 : indexOfClosedFile - 1; + const nextFileToOpen = state.openFiles[nextIndexToOpen]; + + if (nextFileToOpen.pending) { + dispatch('updateViewer', 'diff'); + dispatch('openPendingTab', nextFileToOpen); + } else { + dispatch('updateDelayViewerUpdated', true); + router.push(`/project${nextFileToOpen.url}`); + } + } else if (!state.openFiles.length) { + router.push(`/project/${file.projectId}/tree/${file.branchId}/`); + } + + eventHub.$emit(`editor.update.model.dispose.${file.key}`); +}; + +export const setFileActive = ({ commit, state, getters, dispatch }, path) => { + const file = state.entries[path]; + const currentActiveFile = getters.activeFile; + + if (file.active) return; + + if (currentActiveFile) { + commit(types.SET_FILE_ACTIVE, { + path: currentActiveFile.path, + active: false, + }); + } + + commit(types.SET_FILE_ACTIVE, { path, active: true }); + dispatch('scrollToTab'); + + commit(types.SET_CURRENT_PROJECT, file.projectId); + commit(types.SET_CURRENT_BRANCH, file.branchId); +}; + +export const getFileData = ({ state, commit, dispatch }, { path, makeFileActive = true }) => { + const file = state.entries[path]; + commit(types.TOGGLE_LOADING, { entry: file }); + return service + .getFileData(`${gon.relative_url_root ? gon.relative_url_root : ''}${file.url}`) + .then(res => { + const pageTitle = decodeURI(normalizeHeaders(res.headers)['PAGE-TITLE']); + setPageTitle(pageTitle); + + return res.json(); + }) + .then(data => { + commit(types.SET_FILE_DATA, { data, file }); + commit(types.TOGGLE_FILE_OPEN, path); + if (makeFileActive) dispatch('setFileActive', path); + commit(types.TOGGLE_LOADING, { entry: file }); + }) + .catch(() => { + commit(types.TOGGLE_LOADING, { entry: file }); + flash('Error loading file data. Please try again.', 'alert', document, null, false, true); + }); +}; + +export const setFileMrChange = ({ state, commit }, { file, mrChange }) => { + commit(types.SET_FILE_MERGE_REQUEST_CHANGE, { file, mrChange }); +}; + +export const getRawFileData = ({ state, commit, dispatch }, { path, baseSha }) => { + const file = state.entries[path]; + return new Promise((resolve, reject) => { + service + .getRawFileData(file) + .then(raw => { + commit(types.SET_FILE_RAW_DATA, { file, raw }); + if (file.mrChange && file.mrChange.new_file === false) { + service + .getBaseRawFileData(file, baseSha) + .then(baseRaw => { + commit(types.SET_FILE_BASE_RAW_DATA, { + file, + baseRaw, + }); + resolve(raw); + }) + .catch(e => { + reject(e); + }); + } else { + resolve(raw); + } + }) + .catch(() => { + flash('Error loading file content. Please try again.'); + reject(); + }); + }); +}; + +export const changeFileContent = ({ state, commit }, { path, content }) => { + const file = state.entries[path]; + commit(types.UPDATE_FILE_CONTENT, { path, content }); + + const indexOfChangedFile = state.changedFiles.findIndex(f => f.path === path); + + if (file.changed && indexOfChangedFile === -1) { + commit(types.ADD_FILE_TO_CHANGED, path); + } else if (!file.changed && indexOfChangedFile !== -1) { + commit(types.REMOVE_FILE_FROM_CHANGED, path); + } +}; + +export const setFileLanguage = ({ getters, commit }, { fileLanguage }) => { + if (getters.activeFile) { + commit(types.SET_FILE_LANGUAGE, { file: getters.activeFile, fileLanguage }); + } +}; + +export const setFileEOL = ({ getters, commit }, { eol }) => { + if (getters.activeFile) { + commit(types.SET_FILE_EOL, { file: getters.activeFile, eol }); + } +}; + +export const setEditorPosition = ({ getters, commit }, { editorRow, editorColumn }) => { + if (getters.activeFile) { + commit(types.SET_FILE_POSITION, { + file: getters.activeFile, + editorRow, + editorColumn, + }); + } +}; + +export const setFileViewMode = ({ state, commit }, { file, viewMode }) => { + commit(types.SET_FILE_VIEWMODE, { file, viewMode }); +}; + +export const discardFileChanges = ({ state, commit }, path) => { + const file = state.entries[path]; + + commit(types.DISCARD_FILE_CHANGES, path); + commit(types.REMOVE_FILE_FROM_CHANGED, path); + + if (file.tempFile && file.opened) { + commit(types.TOGGLE_FILE_OPEN, path); + } + + eventHub.$emit(`editor.update.model.content.${file.path}`, file.raw); +}; + +export const openPendingTab = ({ commit, getters, dispatch, state }, file) => { + if (getters.activeFile && getters.activeFile.path === file.path && state.viewer === 'diff') { + return false; + } + + commit(types.ADD_PENDING_TAB, { file }); + + dispatch('scrollToTab'); + + router.push(`/project/${file.projectId}/tree/${state.currentBranchId}/`); + + return true; +}; + +export const removePendingTab = ({ commit }, file) => { + commit(types.REMOVE_PENDING_TAB, file); + + eventHub.$emit(`editor.update.model.dispose.${file.key}`); +}; diff --git a/app/assets/javascripts/ide/stores/actions/merge_request.js b/app/assets/javascripts/ide/stores/actions/merge_request.js new file mode 100644 index 0000000000..da73034fd7 --- /dev/null +++ b/app/assets/javascripts/ide/stores/actions/merge_request.js @@ -0,0 +1,84 @@ +import flash from '~/flash'; +import service from '../../services'; +import * as types from '../mutation_types'; + +export const getMergeRequestData = ( + { commit, state, dispatch }, + { projectId, mergeRequestId, force = false } = {}, +) => + new Promise((resolve, reject) => { + if (!state.projects[projectId].mergeRequests[mergeRequestId] || force) { + service + .getProjectMergeRequestData(projectId, mergeRequestId) + .then(res => res.data) + .then(data => { + commit(types.SET_MERGE_REQUEST, { + projectPath: projectId, + mergeRequestId, + mergeRequest: data, + }); + if (!state.currentMergeRequestId) { + commit(types.SET_CURRENT_MERGE_REQUEST, mergeRequestId); + } + resolve(data); + }) + .catch(() => { + flash('Error loading merge request data. Please try again.'); + reject(new Error(`Merge Request not loaded ${projectId}`)); + }); + } else { + resolve(state.projects[projectId].mergeRequests[mergeRequestId]); + } + }); + +export const getMergeRequestChanges = ( + { commit, state, dispatch }, + { projectId, mergeRequestId, force = false } = {}, +) => + new Promise((resolve, reject) => { + if (!state.projects[projectId].mergeRequests[mergeRequestId].changes.length || force) { + service + .getProjectMergeRequestChanges(projectId, mergeRequestId) + .then(res => res.data) + .then(data => { + commit(types.SET_MERGE_REQUEST_CHANGES, { + projectPath: projectId, + mergeRequestId, + changes: data, + }); + resolve(data); + }) + .catch(() => { + flash('Error loading merge request changes. Please try again.'); + reject(new Error(`Merge Request Changes not loaded ${projectId}`)); + }); + } else { + resolve(state.projects[projectId].mergeRequests[mergeRequestId].changes); + } + }); + +export const getMergeRequestVersions = ( + { commit, state, dispatch }, + { projectId, mergeRequestId, force = false } = {}, +) => + new Promise((resolve, reject) => { + if (!state.projects[projectId].mergeRequests[mergeRequestId].versions.length || force) { + service + .getProjectMergeRequestVersions(projectId, mergeRequestId) + .then(res => res.data) + .then(data => { + commit(types.SET_MERGE_REQUEST_VERSIONS, { + projectPath: projectId, + mergeRequestId, + versions: data, + }); + resolve(data); + }) + .catch(() => { + flash('Error loading merge request versions. Please try again.'); + reject(new Error(`Merge Request Versions not loaded ${projectId}`)); + }); + } else { + resolve(state.projects[projectId].mergeRequests[mergeRequestId].versions); + } + }); diff --git a/app/assets/javascripts/ide/stores/actions/project.js b/app/assets/javascripts/ide/stores/actions/project.js new file mode 100644 index 0000000000..b3882cb8d2 --- /dev/null +++ b/app/assets/javascripts/ide/stores/actions/project.js @@ -0,0 +1,49 @@ +import flash from '~/flash'; +import service from '../../services'; +import * as types from '../mutation_types'; + +export const getProjectData = ( + { commit, state, dispatch }, + { namespace, projectId, force = false } = {}, +) => new Promise((resolve, reject) => { + if (!state.projects[`${namespace}/${projectId}`] || force) { + commit(types.TOGGLE_LOADING, { entry: state }); + service.getProjectData(namespace, projectId) + .then(res => res.data) + .then((data) => { + commit(types.TOGGLE_LOADING, { entry: state }); + commit(types.SET_PROJECT, { projectPath: `${namespace}/${projectId}`, project: data }); + if (!state.currentProjectId) commit(types.SET_CURRENT_PROJECT, `${namespace}/${projectId}`); + resolve(data); + }) + .catch(() => { + flash('Error loading project data. Please try again.', 'alert', document, null, false, true); + reject(new Error(`Project not loaded ${namespace}/${projectId}`)); + }); + } else { + resolve(state.projects[`${namespace}/${projectId}`]); + } +}); + +export const getBranchData = ( + { commit, state, dispatch }, + { projectId, branchId, force = false } = {}, +) => new Promise((resolve, reject) => { + if ((typeof state.projects[`${projectId}`] === 'undefined' || + !state.projects[`${projectId}`].branches[branchId]) + || force) { + service.getBranchData(`${projectId}`, branchId) + .then(({ data }) => { + const { id } = data.commit; + commit(types.SET_BRANCH, { projectPath: `${projectId}`, branchName: branchId, branch: data }); + commit(types.SET_BRANCH_WORKING_REFERENCE, { projectId, branchId, reference: id }); + resolve(data); + }) + .catch(() => { + flash('Error loading branch data. Please try again.', 'alert', document, null, false, true); + reject(new Error(`Branch not loaded - ${projectId}/${branchId}`)); + }); + } else { + resolve(state.projects[`${projectId}`].branches[branchId]); + } +}); diff --git a/app/assets/javascripts/ide/stores/actions/tree.js b/app/assets/javascripts/ide/stores/actions/tree.js new file mode 100644 index 0000000000..6536be04f0 --- /dev/null +++ b/app/assets/javascripts/ide/stores/actions/tree.js @@ -0,0 +1,95 @@ +import { normalizeHeaders } from '~/lib/utils/common_utils'; +import flash from '~/flash'; +import service from '../../services'; +import * as types from '../mutation_types'; +import { findEntry } from '../utils'; +import FilesDecoratorWorker from '../workers/files_decorator_worker'; + +export const toggleTreeOpen = ({ commit, dispatch }, path) => { + commit(types.TOGGLE_TREE_OPEN, path); +}; + +export const handleTreeEntryAction = ({ commit, dispatch }, row) => { + if (row.type === 'tree') { + dispatch('toggleTreeOpen', row.path); + } else if (row.type === 'blob' && (row.opened || row.changed)) { + if (row.changed && !row.opened) { + commit(types.TOGGLE_FILE_OPEN, row.path); + } + + dispatch('setFileActive', row.path); + } else { + dispatch('getFileData', { path: row.path }); + } +}; + +export const getLastCommitData = ({ state, commit, dispatch, getters }, tree = state) => { + if (!tree || tree.lastCommitPath === null || !tree.lastCommitPath) return; + + service + .getTreeLastCommit(tree.lastCommitPath) + .then(res => { + const lastCommitPath = normalizeHeaders(res.headers)['MORE-LOGS-URL'] || null; + + commit(types.SET_LAST_COMMIT_URL, { tree, url: lastCommitPath }); + + return res.json(); + }) + .then(data => { + data.forEach(lastCommit => { + const entry = findEntry(tree.tree, lastCommit.type, lastCommit.file_name); + + if (entry) { + commit(types.SET_LAST_COMMIT_DATA, { entry, lastCommit }); + } + }); + + dispatch('getLastCommitData', tree); + }) + .catch(() => flash('Error fetching log data.', 'alert', document, null, false, true)); +}; + +export const getFiles = ({ state, commit, dispatch }, { projectId, branchId } = {}) => + new Promise((resolve, reject) => { + if (!state.trees[`${projectId}/${branchId}`]) { + const selectedProject = state.projects[projectId]; + commit(types.CREATE_TREE, { treePath: `${projectId}/${branchId}` }); + + service + .getFiles(selectedProject.web_url, branchId) + .then(res => res.json()) + .then(data => { + const worker = new FilesDecoratorWorker(); + worker.addEventListener('message', e => { + const { entries, treeList } = e.data; + const selectedTree = state.trees[`${projectId}/${branchId}`]; + + commit(types.SET_ENTRIES, entries); + commit(types.SET_DIRECTORY_DATA, { + treePath: `${projectId}/${branchId}`, + data: treeList, + }); + commit(types.TOGGLE_LOADING, { + entry: selectedTree, + forceValue: false, + }); + + worker.terminate(); + + resolve(); + }); + + worker.postMessage({ + data, + projectId, + branchId, + }); + }) + .catch(e => { + flash('Error loading tree data. Please try again.', 'alert', document, null, false, true); + reject(e); + }); + } else { + resolve(); + } + }); diff --git a/app/assets/javascripts/ide/stores/getters.js b/app/assets/javascripts/ide/stores/getters.js new file mode 100644 index 0000000000..a77cdbc13c --- /dev/null +++ b/app/assets/javascripts/ide/stores/getters.js @@ -0,0 +1,37 @@ +export const activeFile = state => state.openFiles.find(file => file.active) || null; + +export const addedFiles = state => state.changedFiles.filter(f => f.tempFile); + +export const modifiedFiles = state => state.changedFiles.filter(f => !f.tempFile); + +export const projectsWithTrees = state => + Object.keys(state.projects).map(projectId => { + const project = state.projects[projectId]; + + return { + ...project, + branches: Object.keys(project.branches).map(branchId => { + const branch = project.branches[branchId]; + + return { + ...branch, + tree: state.trees[branch.treeId], + }; + }), + }; + }); + +export const currentMergeRequest = state => { + if (state.projects[state.currentProjectId]) { + return state.projects[state.currentProjectId].mergeRequests[state.currentMergeRequestId]; + } + return null; +}; + +// eslint-disable-next-line no-confusing-arrow +export const currentIcon = state => + state.rightPanelCollapsed ? 'angle-double-left' : 'angle-double-right'; + +export const hasChanges = state => !!state.changedFiles.length; + +export const hasMergeRequest = state => !!state.currentMergeRequestId; diff --git a/app/assets/javascripts/ide/stores/index.js b/app/assets/javascripts/ide/stores/index.js new file mode 100644 index 0000000000..7c82ce7976 --- /dev/null +++ b/app/assets/javascripts/ide/stores/index.js @@ -0,0 +1,19 @@ +import Vue from 'vue'; +import Vuex from 'vuex'; +import state from './state'; +import * as actions from './actions'; +import * as getters from './getters'; +import mutations from './mutations'; +import commitModule from './modules/commit'; + +Vue.use(Vuex); + +export default new Vuex.Store({ + state: state(), + actions, + mutations, + getters, + modules: { + commit: commitModule, + }, +}); diff --git a/app/assets/javascripts/ide/stores/modules/commit/actions.js b/app/assets/javascripts/ide/stores/modules/commit/actions.js new file mode 100644 index 0000000000..367c45f7e2 --- /dev/null +++ b/app/assets/javascripts/ide/stores/modules/commit/actions.js @@ -0,0 +1,200 @@ +import $ from 'jquery'; +import { sprintf, __ } from '~/locale'; +import flash from '~/flash'; +import { stripHtml } from '~/lib/utils/text_utility'; +import * as rootTypes from '../../mutation_types'; +import { createCommitPayload, createNewMergeRequestUrl } from '../../utils'; +import router from '../../../ide_router'; +import service from '../../../services'; +import * as types from './mutation_types'; +import * as consts from './constants'; +import eventHub from '../../../eventhub'; + +export const updateCommitMessage = ({ commit }, message) => { + commit(types.UPDATE_COMMIT_MESSAGE, message); +}; + +export const discardDraft = ({ commit }) => { + commit(types.UPDATE_COMMIT_MESSAGE, ''); +}; + +export const updateCommitAction = ({ commit }, commitAction) => { + commit(types.UPDATE_COMMIT_ACTION, commitAction); +}; + +export const updateBranchName = ({ commit }, branchName) => { + commit(types.UPDATE_NEW_BRANCH_NAME, branchName); +}; + +export const setLastCommitMessage = ({ rootState, commit }, data) => { + const currentProject = rootState.projects[rootState.currentProjectId]; + const commitStats = data.stats + ? sprintf(__('with %{additions} additions, %{deletions} deletions.'), { + additions: data.stats.additions, // eslint-disable-line indent + deletions: data.stats.deletions, // eslint-disable-line indent + }) // eslint-disable-line indent + : ''; + const commitMsg = sprintf( + __('Your changes have been committed. Commit %{commitId} %{commitStats}'), + { + commitId: `${ + data.short_id + }`, + commitStats, + }, + false, + ); + + commit(rootTypes.SET_LAST_COMMIT_MSG, commitMsg, { root: true }); +}; + +export const checkCommitStatus = ({ rootState }) => + service + .getBranchData(rootState.currentProjectId, rootState.currentBranchId) + .then(({ data }) => { + const { id } = data.commit; + const selectedBranch = + rootState.projects[rootState.currentProjectId].branches[rootState.currentBranchId]; + + if (selectedBranch.workingReference !== id) { + return true; + } + + return false; + }) + .catch(() => + flash( + __('Error checking branch data. Please try again.'), + 'alert', + document, + null, + false, + true, + ), + ); + +export const updateFilesAfterCommit = ( + { commit, dispatch, state, rootState, rootGetters }, + { data, branch }, +) => { + const selectedProject = rootState.projects[rootState.currentProjectId]; + const lastCommit = { + commit_path: `${selectedProject.web_url}/commit/${data.id}`, + commit: { + id: data.id, + message: data.message, + authored_date: data.committed_date, + author_name: data.committer_name, + }, + }; + + commit( + rootTypes.SET_BRANCH_WORKING_REFERENCE, + { + projectId: rootState.currentProjectId, + branchId: rootState.currentBranchId, + reference: data.id, + }, + { root: true }, + ); + + rootState.changedFiles.forEach(entry => { + commit( + rootTypes.SET_LAST_COMMIT_DATA, + { + entry, + lastCommit, + }, + { root: true }, + ); + + eventHub.$emit(`editor.update.model.content.${entry.path}`, entry.content); + + commit( + rootTypes.SET_FILE_RAW_DATA, + { + file: entry, + raw: entry.content, + }, + { root: true }, + ); + + commit( + rootTypes.TOGGLE_FILE_CHANGED, + { + file: entry, + changed: false, + }, + { root: true }, + ); + }); + + commit(rootTypes.REMOVE_ALL_CHANGES_FILES, null, { root: true }); + + if (state.commitAction === consts.COMMIT_TO_NEW_BRANCH) { + router.push( + `/project/${rootState.currentProjectId}/blob/${branch}/${rootGetters.activeFile.path}`, + ); + } +}; + +export const commitChanges = ({ commit, state, getters, dispatch, rootState }) => { + const newBranch = state.commitAction !== consts.COMMIT_TO_CURRENT_BRANCH; + const payload = createCommitPayload(getters.branchName, newBranch, state, rootState); + const getCommitStatus = newBranch ? Promise.resolve(false) : dispatch('checkCommitStatus'); + + commit(types.UPDATE_LOADING, true); + + return getCommitStatus + .then( + branchChanged => + new Promise(resolve => { + if (branchChanged) { + // show the modal with a Bootstrap call + $('#ide-create-branch-modal').modal('show'); + } else { + resolve(); + } + }), + ) + .then(() => service.commit(rootState.currentProjectId, payload)) + .then(({ data }) => { + commit(types.UPDATE_LOADING, false); + + if (!data.short_id) { + flash(data.message, 'alert', document, null, false, true); + return null; + } + + dispatch('setLastCommitMessage', data); + dispatch('updateCommitMessage', ''); + return dispatch('updateFilesAfterCommit', { + data, + branch: getters.branchName, + }) + .then(() => { + if (state.commitAction === consts.COMMIT_TO_NEW_BRANCH_MR) { + dispatch( + 'redirectToUrl', + createNewMergeRequestUrl( + rootState.projects[rootState.currentProjectId].web_url, + getters.branchName, + rootState.currentBranchId, + ), + { root: true }, + ); + } + }) + .then(() => dispatch('updateCommitAction', consts.COMMIT_TO_CURRENT_BRANCH)); + }) + .catch(err => { + let errMsg = __('Error committing changes. Please try again.'); + if (err.response.data && err.response.data.message) { + errMsg += ` (${stripHtml(err.response.data.message)})`; + } + flash(errMsg, 'alert', document, null, false, true); + window.dispatchEvent(new Event('resize')); + + commit(types.UPDATE_LOADING, false); + }); +}; diff --git a/app/assets/javascripts/ide/stores/modules/commit/constants.js b/app/assets/javascripts/ide/stores/modules/commit/constants.js new file mode 100644 index 0000000000..230b0a3d9b --- /dev/null +++ b/app/assets/javascripts/ide/stores/modules/commit/constants.js @@ -0,0 +1,3 @@ +export const COMMIT_TO_CURRENT_BRANCH = '1'; +export const COMMIT_TO_NEW_BRANCH = '2'; +export const COMMIT_TO_NEW_BRANCH_MR = '3'; diff --git a/app/assets/javascripts/ide/stores/modules/commit/getters.js b/app/assets/javascripts/ide/stores/modules/commit/getters.js new file mode 100644 index 0000000000..f7cdd6adb0 --- /dev/null +++ b/app/assets/javascripts/ide/stores/modules/commit/getters.js @@ -0,0 +1,24 @@ +import * as consts from './constants'; + +export const discardDraftButtonDisabled = state => state.commitMessage === '' || state.submitCommitLoading; + +export const commitButtonDisabled = (state, getters, rootState) => + getters.discardDraftButtonDisabled || !rootState.changedFiles.length; + +export const newBranchName = (state, _, rootState) => + `${gon.current_username}-${rootState.currentBranchId}-patch-${`${new Date().getTime()}`.substr(-5)}`; + +export const branchName = (state, getters, rootState) => { + if ( + state.commitAction === consts.COMMIT_TO_NEW_BRANCH || + state.commitAction === consts.COMMIT_TO_NEW_BRANCH_MR + ) { + if (state.newBranchName === '') { + return getters.newBranchName; + } + + return state.newBranchName; + } + + return rootState.currentBranchId; +}; diff --git a/app/assets/javascripts/ide/stores/modules/commit/index.js b/app/assets/javascripts/ide/stores/modules/commit/index.js new file mode 100644 index 0000000000..3bf65b0284 --- /dev/null +++ b/app/assets/javascripts/ide/stores/modules/commit/index.js @@ -0,0 +1,12 @@ +import state from './state'; +import mutations from './mutations'; +import * as actions from './actions'; +import * as getters from './getters'; + +export default { + namespaced: true, + state: state(), + mutations, + actions, + getters, +}; diff --git a/app/assets/javascripts/ide/stores/modules/commit/mutation_types.js b/app/assets/javascripts/ide/stores/modules/commit/mutation_types.js new file mode 100644 index 0000000000..9221f054e9 --- /dev/null +++ b/app/assets/javascripts/ide/stores/modules/commit/mutation_types.js @@ -0,0 +1,4 @@ +export const UPDATE_COMMIT_MESSAGE = 'UPDATE_COMMIT_MESSAGE'; +export const UPDATE_COMMIT_ACTION = 'UPDATE_COMMIT_ACTION'; +export const UPDATE_NEW_BRANCH_NAME = 'UPDATE_NEW_BRANCH_NAME'; +export const UPDATE_LOADING = 'UPDATE_LOADING'; diff --git a/app/assets/javascripts/ide/stores/modules/commit/mutations.js b/app/assets/javascripts/ide/stores/modules/commit/mutations.js new file mode 100644 index 0000000000..797357e3df --- /dev/null +++ b/app/assets/javascripts/ide/stores/modules/commit/mutations.js @@ -0,0 +1,24 @@ +import * as types from './mutation_types'; + +export default { + [types.UPDATE_COMMIT_MESSAGE](state, commitMessage) { + Object.assign(state, { + commitMessage, + }); + }, + [types.UPDATE_COMMIT_ACTION](state, commitAction) { + Object.assign(state, { + commitAction, + }); + }, + [types.UPDATE_NEW_BRANCH_NAME](state, newBranchName) { + Object.assign(state, { + newBranchName, + }); + }, + [types.UPDATE_LOADING](state, submitCommitLoading) { + Object.assign(state, { + submitCommitLoading, + }); + }, +}; diff --git a/app/assets/javascripts/ide/stores/modules/commit/state.js b/app/assets/javascripts/ide/stores/modules/commit/state.js new file mode 100644 index 0000000000..8dae50961b --- /dev/null +++ b/app/assets/javascripts/ide/stores/modules/commit/state.js @@ -0,0 +1,6 @@ +export default () => ({ + commitMessage: '', + commitAction: '1', + newBranchName: '', + submitCommitLoading: false, +}); diff --git a/app/assets/javascripts/ide/stores/mutation_types.js b/app/assets/javascripts/ide/stores/mutation_types.js new file mode 100644 index 0000000000..e3f504e5ab --- /dev/null +++ b/app/assets/javascripts/ide/stores/mutation_types.js @@ -0,0 +1,55 @@ +export const SET_INITIAL_DATA = 'SET_INITIAL_DATA'; +export const TOGGLE_LOADING = 'TOGGLE_LOADING'; +export const SET_LAST_COMMIT_DATA = 'SET_LAST_COMMIT_DATA'; +export const SET_LAST_COMMIT_MSG = 'SET_LAST_COMMIT_MSG'; +export const SET_LEFT_PANEL_COLLAPSED = 'SET_LEFT_PANEL_COLLAPSED'; +export const SET_RIGHT_PANEL_COLLAPSED = 'SET_RIGHT_PANEL_COLLAPSED'; +export const SET_RESIZING_STATUS = 'SET_RESIZING_STATUS'; + +// Project Mutation Types +export const SET_PROJECT = 'SET_PROJECT'; +export const SET_CURRENT_PROJECT = 'SET_CURRENT_PROJECT'; +export const TOGGLE_PROJECT_OPEN = 'TOGGLE_PROJECT_OPEN'; + +// Merge Request Mutation Types +export const SET_MERGE_REQUEST = 'SET_MERGE_REQUEST'; +export const SET_CURRENT_MERGE_REQUEST = 'SET_CURRENT_MERGE_REQUEST'; +export const SET_MERGE_REQUEST_CHANGES = 'SET_MERGE_REQUEST_CHANGES'; +export const SET_MERGE_REQUEST_VERSIONS = 'SET_MERGE_REQUEST_VERSIONS'; + +// Branch Mutation Types +export const SET_BRANCH = 'SET_BRANCH'; +export const SET_BRANCH_WORKING_REFERENCE = 'SET_BRANCH_WORKING_REFERENCE'; +export const TOGGLE_BRANCH_OPEN = 'TOGGLE_BRANCH_OPEN'; + +// Tree mutation types +export const SET_DIRECTORY_DATA = 'SET_DIRECTORY_DATA'; +export const TOGGLE_TREE_OPEN = 'TOGGLE_TREE_OPEN'; +export const SET_LAST_COMMIT_URL = 'SET_LAST_COMMIT_URL'; +export const CREATE_TREE = 'CREATE_TREE'; +export const REMOVE_ALL_CHANGES_FILES = 'REMOVE_ALL_CHANGES_FILES'; + +// File mutation types +export const SET_FILE_DATA = 'SET_FILE_DATA'; +export const TOGGLE_FILE_OPEN = 'TOGGLE_FILE_OPEN'; +export const SET_FILE_ACTIVE = 'SET_FILE_ACTIVE'; +export const SET_FILE_RAW_DATA = 'SET_FILE_RAW_DATA'; +export const SET_FILE_BASE_RAW_DATA = 'SET_FILE_BASE_RAW_DATA'; +export const UPDATE_FILE_CONTENT = 'UPDATE_FILE_CONTENT'; +export const SET_FILE_LANGUAGE = 'SET_FILE_LANGUAGE'; +export const SET_FILE_POSITION = 'SET_FILE_POSITION'; +export const SET_FILE_VIEWMODE = 'SET_FILE_VIEWMODE'; +export const SET_FILE_EOL = 'SET_FILE_EOL'; +export const DISCARD_FILE_CHANGES = 'DISCARD_FILE_CHANGES'; +export const ADD_FILE_TO_CHANGED = 'ADD_FILE_TO_CHANGED'; +export const REMOVE_FILE_FROM_CHANGED = 'REMOVE_FILE_FROM_CHANGED'; +export const TOGGLE_FILE_CHANGED = 'TOGGLE_FILE_CHANGED'; +export const SET_CURRENT_BRANCH = 'SET_CURRENT_BRANCH'; +export const SET_ENTRIES = 'SET_ENTRIES'; +export const CREATE_TMP_ENTRY = 'CREATE_TMP_ENTRY'; +export const SET_FILE_MERGE_REQUEST_CHANGE = 'SET_FILE_MERGE_REQUEST_CHANGE'; +export const UPDATE_VIEWER = 'UPDATE_VIEWER'; +export const UPDATE_DELAY_VIEWER_CHANGE = 'UPDATE_DELAY_VIEWER_CHANGE'; + +export const ADD_PENDING_TAB = 'ADD_PENDING_TAB'; +export const REMOVE_PENDING_TAB = 'REMOVE_PENDING_TAB'; diff --git a/app/assets/javascripts/ide/stores/mutations.js b/app/assets/javascripts/ide/stores/mutations.js new file mode 100644 index 0000000000..5e5eb83166 --- /dev/null +++ b/app/assets/javascripts/ide/stores/mutations.js @@ -0,0 +1,103 @@ +import * as types from './mutation_types'; +import projectMutations from './mutations/project'; +import mergeRequestMutation from './mutations/merge_request'; +import fileMutations from './mutations/file'; +import treeMutations from './mutations/tree'; +import branchMutations from './mutations/branch'; + +export default { + [types.SET_INITIAL_DATA](state, data) { + Object.assign(state, data); + }, + [types.TOGGLE_LOADING](state, { entry, forceValue = undefined }) { + if (entry.path) { + Object.assign(state.entries[entry.path], { + loading: forceValue !== undefined ? forceValue : !state.entries[entry.path].loading, + }); + } else { + Object.assign(entry, { + loading: forceValue !== undefined ? forceValue : !entry.loading, + }); + } + }, + [types.SET_LEFT_PANEL_COLLAPSED](state, collapsed) { + Object.assign(state, { + leftPanelCollapsed: collapsed, + }); + }, + [types.SET_RIGHT_PANEL_COLLAPSED](state, collapsed) { + Object.assign(state, { + rightPanelCollapsed: collapsed, + }); + }, + [types.SET_RESIZING_STATUS](state, resizing) { + Object.assign(state, { + panelResizing: resizing, + }); + }, + [types.SET_LAST_COMMIT_DATA](state, { entry, lastCommit }) { + Object.assign(entry.lastCommit, { + id: lastCommit.commit.id, + url: lastCommit.commit_path, + message: lastCommit.commit.message, + author: lastCommit.commit.author_name, + updatedAt: lastCommit.commit.authored_date, + }); + }, + [types.SET_LAST_COMMIT_MSG](state, lastCommitMsg) { + Object.assign(state, { + lastCommitMsg, + }); + }, + [types.SET_ENTRIES](state, entries) { + Object.assign(state, { + entries, + }); + }, + [types.CREATE_TMP_ENTRY](state, { data, projectId, branchId }) { + Object.keys(data.entries).reduce((acc, key) => { + const entry = data.entries[key]; + const foundEntry = state.entries[key]; + + if (!foundEntry) { + Object.assign(state.entries, { + [key]: entry, + }); + } else { + const tree = entry.tree.filter( + f => foundEntry.tree.find(e => e.path === f.path) === undefined, + ); + Object.assign(foundEntry, { + tree: foundEntry.tree.concat(tree), + }); + } + + return acc.concat(key); + }, []); + + const foundEntry = state.trees[`${projectId}/${branchId}`].tree.find( + e => e.path === data.treeList[0].path, + ); + + if (!foundEntry) { + Object.assign(state.trees[`${projectId}/${branchId}`], { + tree: state.trees[`${projectId}/${branchId}`].tree.concat(data.treeList), + }); + } + }, + [types.UPDATE_VIEWER](state, viewer) { + Object.assign(state, { + viewer, + }); + }, + [types.UPDATE_DELAY_VIEWER_CHANGE](state, delayViewerUpdated) { + Object.assign(state, { + delayViewerUpdated, + }); + }, + ...projectMutations, + ...mergeRequestMutation, + ...fileMutations, + ...treeMutations, + ...branchMutations, +}; diff --git a/app/assets/javascripts/ide/stores/mutations/branch.js b/app/assets/javascripts/ide/stores/mutations/branch.js new file mode 100644 index 0000000000..2972ba5e38 --- /dev/null +++ b/app/assets/javascripts/ide/stores/mutations/branch.js @@ -0,0 +1,26 @@ +import * as types from '../mutation_types'; + +export default { + [types.SET_CURRENT_BRANCH](state, currentBranchId) { + Object.assign(state, { + currentBranchId, + }); + }, + [types.SET_BRANCH](state, { projectPath, branchName, branch }) { + Object.assign(state.projects[projectPath], { + branches: { + [branchName]: { + ...branch, + treeId: `${projectPath}/${branchName}`, + active: true, + workingReference: '', + }, + }, + }); + }, + [types.SET_BRANCH_WORKING_REFERENCE](state, { projectId, branchId, reference }) { + Object.assign(state.projects[projectId].branches[branchId], { + workingReference: reference, + }); + }, +}; diff --git a/app/assets/javascripts/ide/stores/mutations/file.js b/app/assets/javascripts/ide/stores/mutations/file.js new file mode 100644 index 0000000000..eeb14b5490 --- /dev/null +++ b/app/assets/javascripts/ide/stores/mutations/file.js @@ -0,0 +1,147 @@ +import * as types from '../mutation_types'; + +export default { + [types.SET_FILE_ACTIVE](state, { path, active }) { + Object.assign(state.entries[path], { + active, + }); + + if (active && !state.entries[path].pending) { + Object.assign(state, { + openFiles: state.openFiles.map(f => + Object.assign(f, { active: f.pending ? false : f.active }), + ), + }); + } + }, + [types.TOGGLE_FILE_OPEN](state, path) { + Object.assign(state.entries[path], { + opened: !state.entries[path].opened, + }); + + if (state.entries[path].opened) { + Object.assign(state, { + openFiles: state.openFiles.filter(f => f.path !== path).concat(state.entries[path]), + }); + } else { + const file = state.entries[path]; + + Object.assign(state, { + openFiles: state.openFiles.filter(f => f.key !== file.key), + }); + } + }, + [types.SET_FILE_DATA](state, { data, file }) { + Object.assign(state.entries[file.path], { + id: data.id, + blamePath: data.blame_path, + commitsPath: data.commits_path, + permalink: data.permalink, + rawPath: data.raw_path, + binary: data.binary, + renderError: data.render_error, + raw: null, + baseRaw: null, + html: data.html, + size: data.size, + }); + }, + [types.SET_FILE_RAW_DATA](state, { file, raw }) { + Object.assign(state.entries[file.path], { + raw, + }); + }, + [types.SET_FILE_BASE_RAW_DATA](state, { file, baseRaw }) { + Object.assign(state.entries[file.path], { + baseRaw, + }); + }, + [types.UPDATE_FILE_CONTENT](state, { path, content }) { + const changed = content !== state.entries[path].raw; + + Object.assign(state.entries[path], { + content, + changed, + }); + }, + [types.SET_FILE_LANGUAGE](state, { file, fileLanguage }) { + Object.assign(state.entries[file.path], { + fileLanguage, + }); + }, + [types.SET_FILE_EOL](state, { file, eol }) { + Object.assign(state.entries[file.path], { + eol, + }); + }, + [types.SET_FILE_POSITION](state, { file, editorRow, editorColumn }) { + Object.assign(state.entries[file.path], { + editorRow, + editorColumn, + }); + }, + [types.SET_FILE_MERGE_REQUEST_CHANGE](state, { file, mrChange }) { + Object.assign(state.entries[file.path], { + mrChange, + }); + }, + [types.SET_FILE_VIEWMODE](state, { file, viewMode }) { + Object.assign(state.entries[file.path], { + viewMode, + }); + }, + [types.DISCARD_FILE_CHANGES](state, path) { + Object.assign(state.entries[path], { + content: state.entries[path].raw, + changed: false, + }); + }, + [types.ADD_FILE_TO_CHANGED](state, path) { + Object.assign(state, { + changedFiles: state.changedFiles.concat(state.entries[path]), + }); + }, + [types.REMOVE_FILE_FROM_CHANGED](state, path) { + Object.assign(state, { + changedFiles: state.changedFiles.filter(f => f.path !== path), + }); + }, + [types.TOGGLE_FILE_CHANGED](state, { file, changed }) { + Object.assign(state.entries[file.path], { + changed, + }); + }, + [types.ADD_PENDING_TAB](state, { file, keyPrefix = 'pending' }) { + const pendingTab = state.openFiles.find(f => f.path === file.path && f.pending); + let openFiles = state.openFiles.map(f => + Object.assign(f, { active: f.path === file.path, opened: false }), + ); + + if (!pendingTab) { + const openFile = openFiles.find(f => f.path === file.path); + + openFiles = openFiles.concat(openFile ? null : file).reduce((acc, f) => { + if (!f) return acc; + + if (f.path === file.path) { + return acc.concat({ + ...f, + active: true, + pending: true, + opened: true, + key: `${keyPrefix}-${f.key}`, + }); + } + + return acc.concat(f); + }, []); + } + + Object.assign(state, { openFiles }); + }, + [types.REMOVE_PENDING_TAB](state, file) { + Object.assign(state, { + openFiles: state.openFiles.filter(f => f.key !== file.key), + }); + }, +}; diff --git a/app/assets/javascripts/ide/stores/mutations/merge_request.js b/app/assets/javascripts/ide/stores/mutations/merge_request.js new file mode 100644 index 0000000000..334819fe70 --- /dev/null +++ b/app/assets/javascripts/ide/stores/mutations/merge_request.js @@ -0,0 +1,33 @@ +import * as types from '../mutation_types'; + +export default { + [types.SET_CURRENT_MERGE_REQUEST](state, currentMergeRequestId) { + Object.assign(state, { + currentMergeRequestId, + }); + }, + [types.SET_MERGE_REQUEST](state, { projectPath, mergeRequestId, mergeRequest }) { + Object.assign(state.projects[projectPath], { + mergeRequests: { + [mergeRequestId]: { + ...mergeRequest, + active: true, + changes: [], + versions: [], + baseCommitSha: null, + }, + }, + }); + }, + [types.SET_MERGE_REQUEST_CHANGES](state, { projectPath, mergeRequestId, changes }) { + Object.assign(state.projects[projectPath].mergeRequests[mergeRequestId], { + changes, + }); + }, + [types.SET_MERGE_REQUEST_VERSIONS](state, { projectPath, mergeRequestId, versions }) { + Object.assign(state.projects[projectPath].mergeRequests[mergeRequestId], { + versions, + baseCommitSha: versions.length ? versions[0].base_commit_sha : null, + }); + }, +}; diff --git a/app/assets/javascripts/ide/stores/mutations/project.js b/app/assets/javascripts/ide/stores/mutations/project.js new file mode 100644 index 0000000000..284b39a2c7 --- /dev/null +++ b/app/assets/javascripts/ide/stores/mutations/project.js @@ -0,0 +1,24 @@ +import * as types from '../mutation_types'; + +export default { + [types.SET_CURRENT_PROJECT](state, currentProjectId) { + Object.assign(state, { + currentProjectId, + }); + }, + [types.SET_PROJECT](state, { projectPath, project }) { + // Add client side properties + Object.assign(project, { + tree: [], + branches: {}, + mergeRequests: {}, + active: true, + }); + + Object.assign(state, { + projects: Object.assign({}, state.projects, { + [projectPath]: project, + }), + }); + }, +}; diff --git a/app/assets/javascripts/ide/stores/mutations/tree.js b/app/assets/javascripts/ide/stores/mutations/tree.js new file mode 100644 index 0000000000..1176c040fb --- /dev/null +++ b/app/assets/javascripts/ide/stores/mutations/tree.js @@ -0,0 +1,34 @@ +import * as types from '../mutation_types'; + +export default { + [types.TOGGLE_TREE_OPEN](state, path) { + Object.assign(state.entries[path], { + opened: !state.entries[path].opened, + }); + }, + [types.CREATE_TREE](state, { treePath }) { + Object.assign(state, { + trees: Object.assign({}, state.trees, { + [treePath]: { + tree: [], + loading: true, + }, + }), + }); + }, + [types.SET_DIRECTORY_DATA](state, { data, treePath }) { + Object.assign(state.trees[treePath], { + tree: data, + }); + }, + [types.SET_LAST_COMMIT_URL](state, { tree = state, url }) { + Object.assign(tree, { + lastCommitPath: url, + }); + }, + [types.REMOVE_ALL_CHANGES_FILES](state) { + Object.assign(state, { + changedFiles: [], + }); + }, +}; diff --git a/app/assets/javascripts/ide/stores/state.js b/app/assets/javascripts/ide/stores/state.js new file mode 100644 index 0000000000..e5cc881400 --- /dev/null +++ b/app/assets/javascripts/ide/stores/state.js @@ -0,0 +1,20 @@ +export default () => ({ + currentProjectId: '', + currentBranchId: '', + currentMergeRequestId: '', + changedFiles: [], + endpoints: {}, + lastCommitMsg: '', + lastCommitPath: '', + loading: false, + openFiles: [], + parentTreeUrl: '', + trees: {}, + projects: {}, + leftPanelCollapsed: false, + rightPanelCollapsed: false, + panelResizing: false, + entries: {}, + viewer: 'editor', + delayViewerUpdated: false, +}); diff --git a/app/assets/javascripts/ide/stores/utils.js b/app/assets/javascripts/ide/stores/utils.js new file mode 100644 index 0000000000..05a019de54 --- /dev/null +++ b/app/assets/javascripts/ide/stores/utils.js @@ -0,0 +1,134 @@ +export const dataStructure = () => ({ + id: '', + // Key will contain a mixture of ID and path + // it can also contain a prefix `pending-` for files opened in review mode + key: '', + type: '', + projectId: '', + branchId: '', + name: '', + url: '', + path: '', + tempFile: false, + tree: [], + loading: false, + opened: false, + active: false, + changed: false, + lastCommitPath: '', + lastCommit: { + id: '', + url: '', + message: '', + updatedAt: '', + author: '', + }, + blamePath: '', + commitsPath: '', + permalink: '', + rawPath: '', + binary: false, + html: '', + raw: '', + content: '', + parentTreeUrl: '', + renderError: false, + base64: false, + editorRow: 1, + editorColumn: 1, + fileLanguage: '', + eol: '', + viewMode: 'edit', + previewMode: null, + size: 0, +}); + +export const decorateData = entity => { + const { + id, + projectId, + branchId, + type, + url, + name, + path, + renderError, + content = '', + tempFile = false, + active = false, + opened = false, + changed = false, + parentTreeUrl = '', + base64 = false, + previewMode, + file_lock, + html, + } = entity; + + return { + ...dataStructure(), + id, + projectId, + branchId, + key: `${name}-${type}-${id}`, + type, + name, + url, + path, + tempFile, + opened, + active, + parentTreeUrl, + changed, + renderError, + content, + base64, + previewMode, + file_lock, + html, + }; +}; + +export const findEntry = (tree, type, name, prop = 'name') => + tree.find(f => f.type === type && f[prop] === name); + +export const findIndexOfFile = (state, file) => state.findIndex(f => f.path === file.path); + +export const setPageTitle = title => { + document.title = title; +}; + +export const createCommitPayload = (branch, newBranch, state, rootState) => ({ + branch, + commit_message: state.commitMessage, + actions: rootState.changedFiles.map(f => ({ + action: f.tempFile ? 'create' : 'update', + file_path: f.path, + content: f.content, + encoding: f.base64 ? 'base64' : 'text', + })), + start_branch: newBranch ? rootState.currentBranchId : undefined, +}); + +export const createNewMergeRequestUrl = (projectUrl, source, target) => + `${projectUrl}/merge_requests/new?merge_request[source_branch]=${source}&merge_request[target_branch]=${target}`; + +const sortTreesByTypeAndName = (a, b) => { + if (a.type === 'tree' && b.type === 'blob') { + return -1; + } else if (a.type === 'blob' && b.type === 'tree') { + return 1; + } + if (a.name.toLowerCase() < b.name.toLowerCase()) return -1; + if (a.name.toLowerCase() > b.name.toLowerCase()) return 1; + return 0; +}; + +export const sortTree = sortedTree => + sortedTree + .map(entity => + Object.assign(entity, { + tree: entity.tree.length ? sortTree(entity.tree) : [], + }), + ) + .sort(sortTreesByTypeAndName); diff --git a/app/assets/javascripts/ide/stores/workers/files_decorator_worker.js b/app/assets/javascripts/ide/stores/workers/files_decorator_worker.js new file mode 100644 index 0000000000..a167327690 --- /dev/null +++ b/app/assets/javascripts/ide/stores/workers/files_decorator_worker.js @@ -0,0 +1,90 @@ +import { viewerInformationForPath } from '~/vue_shared/components/content_viewer/lib/viewer_utils'; +import { decorateData, sortTree } from '../utils'; + +self.addEventListener('message', e => { + const { data, projectId, branchId, tempFile = false, content = '', base64 = false } = e.data; + + const treeList = []; + let file; + const entries = data.reduce((acc, path) => { + const pathSplit = path.split('/'); + const blobName = pathSplit.pop().trim(); + + if (pathSplit.length > 0) { + pathSplit.reduce((pathAcc, folderName) => { + const parentFolder = acc[pathAcc[pathAcc.length - 1]]; + const folderPath = `${parentFolder ? `${parentFolder.path}/` : ''}${folderName}`; + const foundEntry = acc[folderPath]; + + if (!foundEntry) { + const tree = decorateData({ + projectId, + branchId, + id: folderPath, + name: folderName, + path: folderPath, + url: `/${projectId}/tree/${branchId}/${folderPath}/`, + type: 'tree', + parentTreeUrl: parentFolder ? parentFolder.url : `/${projectId}/tree/${branchId}/`, + tempFile, + changed: tempFile, + opened: tempFile, + }); + + Object.assign(acc, { + [folderPath]: tree, + }); + + if (parentFolder) { + parentFolder.tree.push(tree); + } else { + treeList.push(tree); + } + + pathAcc.push(tree.path); + } else { + pathAcc.push(foundEntry.path); + } + + return pathAcc; + }, []); + } + + if (blobName !== '') { + const fileFolder = acc[pathSplit.join('/')]; + file = decorateData({ + projectId, + branchId, + id: path, + name: blobName, + path, + url: `/${projectId}/blob/${branchId}/${path}`, + type: 'blob', + parentTreeUrl: fileFolder ? fileFolder.url : `/${projectId}/blob/${branchId}`, + tempFile, + changed: tempFile, + content, + base64, + previewMode: viewerInformationForPath(blobName), + }); + + Object.assign(acc, { + [path]: file, + }); + + if (fileFolder) { + fileFolder.tree.push(file); + } else { + treeList.push(file); + } + } + + return acc; + }, {}); + + self.postMessage({ + entries, + treeList: sortTree(treeList), + file, + }); +}); diff --git a/app/assets/javascripts/image_diff/image_diff.js b/app/assets/javascripts/image_diff/image_diff.js index f3af92cf2b..fab0255c37 100644 --- a/app/assets/javascripts/image_diff/image_diff.js +++ b/app/assets/javascripts/image_diff/image_diff.js @@ -1,3 +1,4 @@ +import $ from 'jquery'; import imageDiffHelper from './helpers/index'; import ImageBadge from './image_badge'; import { isImageLoaded } from '../lib/utils/image_utility'; diff --git a/app/assets/javascripts/importer_status.js b/app/assets/javascripts/importer_status.js index 523bd2adb9..b469e1e2ad 100644 --- a/app/assets/javascripts/importer_status.js +++ b/app/assets/javascripts/importer_status.js @@ -1,3 +1,4 @@ +import $ from 'jquery'; import _ from 'underscore'; import { __, sprintf } from './locale'; import axios from './lib/utils/axios_utils'; diff --git a/app/assets/javascripts/init_changes_dropdown.js b/app/assets/javascripts/init_changes_dropdown.js index 1bab7965c1..09cca1dc7d 100644 --- a/app/assets/javascripts/init_changes_dropdown.js +++ b/app/assets/javascripts/init_changes_dropdown.js @@ -1,3 +1,4 @@ +import $ from 'jquery'; import stickyMonitor from './lib/utils/sticky'; export default (stickyTop) => { diff --git a/app/assets/javascripts/init_labels.js b/app/assets/javascripts/init_labels.js index 5f20055510..15da5d5cce 100644 --- a/app/assets/javascripts/init_labels.js +++ b/app/assets/javascripts/init_labels.js @@ -1,3 +1,4 @@ +import $ from 'jquery'; import LabelManager from './label_manager'; import GroupLabelSubscription from './group_label_subscription'; import ProjectLabelSubscription from './project_label_subscription'; diff --git a/app/assets/javascripts/integrations/integration_settings_form.js b/app/assets/javascripts/integrations/integration_settings_form.js index 2848fe003c..741894b5e6 100644 --- a/app/assets/javascripts/integrations/integration_settings_form.js +++ b/app/assets/javascripts/integrations/integration_settings_form.js @@ -1,3 +1,4 @@ +import $ from 'jquery'; import axios from '../lib/utils/axios_utils'; import flash from '../flash'; diff --git a/app/assets/javascripts/issuable/auto_width_dropdown_select.js b/app/assets/javascripts/issuable/auto_width_dropdown_select.js index 14a2bfbe4e..b2c2de9e5d 100644 --- a/app/assets/javascripts/issuable/auto_width_dropdown_select.js +++ b/app/assets/javascripts/issuable/auto_width_dropdown_select.js @@ -1,3 +1,5 @@ +import $ from 'jquery'; + let instanceCount = 0; class AutoWidthDropdownSelect { diff --git a/app/assets/javascripts/issuable_bulk_update_actions.js b/app/assets/javascripts/issuable_bulk_update_actions.js index 8c1b2e78ca..e003fb1d12 100644 --- a/app/assets/javascripts/issuable_bulk_update_actions.js +++ b/app/assets/javascripts/issuable_bulk_update_actions.js @@ -1,4 +1,6 @@ /* eslint-disable comma-dangle, quotes, consistent-return, func-names, array-callback-return, space-before-function-paren, prefer-arrow-callback, max-len, no-unused-expressions, no-sequences, no-underscore-dangle, no-unused-vars, no-param-reassign */ + +import $ from 'jquery'; import _ from 'underscore'; import axios from './lib/utils/axios_utils'; import Flash from './flash'; diff --git a/app/assets/javascripts/issuable_bulk_update_sidebar.js b/app/assets/javascripts/issuable_bulk_update_sidebar.js index 2056efe701..2307c8e0d8 100644 --- a/app/assets/javascripts/issuable_bulk_update_sidebar.js +++ b/app/assets/javascripts/issuable_bulk_update_sidebar.js @@ -1,5 +1,6 @@ /* eslint-disable class-methods-use-this, no-new */ +import $ from 'jquery'; import IssuableBulkUpdateActions from './issuable_bulk_update_actions'; import MilestoneSelect from './milestone_select'; import issueStatusSelect from './issue_status_select'; diff --git a/app/assets/javascripts/issuable_context.js b/app/assets/javascripts/issuable_context.js index da99394ff9..7470d634b9 100644 --- a/app/assets/javascripts/issuable_context.js +++ b/app/assets/javascripts/issuable_context.js @@ -1,3 +1,4 @@ +import $ from 'jquery'; import Cookies from 'js-cookie'; import bp from './breakpoints'; import UsersSelect from './users_select'; diff --git a/app/assets/javascripts/issuable_form.js b/app/assets/javascripts/issuable_form.js index fdfad0b6a4..bb8b3d91e4 100644 --- a/app/assets/javascripts/issuable_form.js +++ b/app/assets/javascripts/issuable_form.js @@ -1,6 +1,7 @@ /* eslint-disable func-names, prefer-rest-params, wrap-iife, no-use-before-define, no-useless-escape, no-new, object-shorthand, no-unused-vars, comma-dangle, no-alert, consistent-return, no-else-return, prefer-template, one-var, one-var-declaration-per-line, curly, max-len */ /* global GitLab */ +import $ from 'jquery'; import Pikaday from 'pikaday'; import Autosave from './autosave'; import UsersSelect from './users_select'; diff --git a/app/assets/javascripts/issuable_index.js b/app/assets/javascripts/issuable_index.js index 0683ca82a3..06ec454616 100644 --- a/app/assets/javascripts/issuable_index.js +++ b/app/assets/javascripts/issuable_index.js @@ -1,3 +1,4 @@ +import $ from 'jquery'; import axios from './lib/utils/axios_utils'; import flash from './flash'; import { __ } from './locale'; diff --git a/app/assets/javascripts/issue.js b/app/assets/javascripts/issue.js index 333bbd9e0b..5113ac6775 100644 --- a/app/assets/javascripts/issue.js +++ b/app/assets/javascripts/issue.js @@ -1,4 +1,6 @@ /* eslint-disable func-names, space-before-function-paren, no-var, prefer-rest-params, wrap-iife, one-var, no-underscore-dangle, one-var-declaration-per-line, object-shorthand, no-unused-vars, no-new, comma-dangle, consistent-return, quotes, dot-notation, quote-props, prefer-arrow-callback, max-len */ + +import $ from 'jquery'; import axios from './lib/utils/axios_utils'; import { addDelimiter } from './lib/utils/text_utility'; import flash from './flash'; diff --git a/app/assets/javascripts/issue_show/components/description.vue b/app/assets/javascripts/issue_show/components/description.vue index 1338be0ec4..ae577e04a5 100644 --- a/app/assets/javascripts/issue_show/components/description.vue +++ b/app/assets/javascripts/issue_show/components/description.vue @@ -1,4 +1,5 @@ @@ -28,5 +36,21 @@ {{ title }}: {{ value }} + + + + + +

diff --git a/app/assets/javascripts/jobs/components/sidebar_details_block.vue b/app/assets/javascripts/jobs/components/sidebar_details_block.vue index 56814a5252..af47056d98 100644 --- a/app/assets/javascripts/jobs/components/sidebar_details_block.vue +++ b/app/assets/javascripts/jobs/components/sidebar_details_block.vue @@ -22,6 +22,11 @@ type: Boolean, required: true, }, + runnerHelpUrl: { + type: String, + required: false, + default: '', + }, }, computed: { shouldRenderContent() { @@ -39,6 +44,21 @@ runnerId() { return `#${this.job.runner.id}`; }, + hasTimeout() { + return this.job.metadata != null && this.job.metadata.timeout_human_readable !== null; + }, + timeout() { + if (this.job.metadata == null) { + return ''; + } + + let t = this.job.metadata.timeout_human_readable; + if (this.job.metadata.timeout_source !== '') { + t += ` (from ${this.job.metadata.timeout_source})`; + } + + return t; + }, renderBlock() { return this.job.merge_request || this.job.duration || @@ -114,6 +134,13 @@ title="Queued" :value="queued" /> + { props: { isLoading: this.mediator.state.isLoading, job: this.mediator.store.state.job, + runnerHelpUrl: dataset.runnerHelpUrl, }, }); }, diff --git a/app/assets/javascripts/label_manager.js b/app/assets/javascripts/label_manager.js index 61b40f79db..e230dbbd4a 100644 --- a/app/assets/javascripts/label_manager.js +++ b/app/assets/javascripts/label_manager.js @@ -1,4 +1,6 @@ /* eslint-disable comma-dangle, class-methods-use-this, no-underscore-dangle, no-param-reassign, no-unused-vars, consistent-return, func-names, space-before-function-paren, max-len */ + +import $ from 'jquery'; import Sortable from 'vendor/Sortable'; import flash from './flash'; diff --git a/app/assets/javascripts/labels.js b/app/assets/javascripts/labels.js index 7aab13ed9c..d85ae85170 100644 --- a/app/assets/javascripts/labels.js +++ b/app/assets/javascripts/labels.js @@ -1,3 +1,5 @@ +import $ from 'jquery'; + export default class Labels { constructor() { this.setSuggestedColor = this.setSuggestedColor.bind(this); diff --git a/app/assets/javascripts/labels_select.js b/app/assets/javascripts/labels_select.js index 9b46bbf83d..824d3f7ca0 100644 --- a/app/assets/javascripts/labels_select.js +++ b/app/assets/javascripts/labels_select.js @@ -1,6 +1,8 @@ /* eslint-disable no-useless-return, func-names, space-before-function-paren, wrap-iife, no-var, no-underscore-dangle, prefer-arrow-callback, max-len, one-var, no-unused-vars, one-var-declaration-per-line, prefer-template, no-new, consistent-return, object-shorthand, comma-dangle, no-shadow, no-param-reassign, brace-style, vars-on-top, quotes, no-lonely-if, no-else-return, dot-notation, no-empty, no-return-assign, camelcase, prefer-spread */ /* global Issuable */ /* global ListLabel */ + +import $ from 'jquery'; import _ from 'underscore'; import { __ } from './locale'; import axios from './lib/utils/axios_utils'; diff --git a/app/assets/javascripts/layout_nav.js b/app/assets/javascripts/layout_nav.js index 1b4900827b..e317718877 100644 --- a/app/assets/javascripts/layout_nav.js +++ b/app/assets/javascripts/layout_nav.js @@ -1,3 +1,4 @@ +import $ from 'jquery'; import ContextualSidebar from './contextual_sidebar'; import initFlyOutNav from './fly_out_nav'; diff --git a/app/assets/javascripts/lib/utils/bootstrap_linked_tabs.js b/app/assets/javascripts/lib/utils/bootstrap_linked_tabs.js index 0bf2ba6acc..3873f4528c 100644 --- a/app/assets/javascripts/lib/utils/bootstrap_linked_tabs.js +++ b/app/assets/javascripts/lib/utils/bootstrap_linked_tabs.js @@ -1,3 +1,5 @@ +import $ from 'jquery'; + /** * Linked Tabs * diff --git a/app/assets/javascripts/lib/utils/common_utils.js b/app/assets/javascripts/lib/utils/common_utils.js index ed90db317d..9ff2042475 100644 --- a/app/assets/javascripts/lib/utils/common_utils.js +++ b/app/assets/javascripts/lib/utils/common_utils.js @@ -1,4 +1,4 @@ -import jQuery from 'jquery'; +import $ from 'jquery'; import Cookies from 'js-cookie'; import axios from './axios_utils'; import { getLocationHash } from './url_utility'; @@ -33,6 +33,7 @@ export const checkPageAndAction = (page, action) => { export const isInIssuePage = () => checkPageAndAction('issues', 'show'); export const isInMRPage = () => checkPageAndAction('merge_requests', 'show'); +export const isInEpicPage = () => checkPageAndAction('epics', 'show'); export const isInNoteablePage = () => isInIssuePage() || isInMRPage(); export const hasVueMRDiscussionsCookie = () => Cookies.get('vue_mr_discussions'); @@ -142,7 +143,7 @@ export const isMetaClick = e => e.metaKey || e.ctrlKey || e.which === 2; export const scrollToElement = (element) => { let $el = element; - if (!(element instanceof jQuery)) { + if (!(element instanceof $)) { $el = $(element); } const top = $el.offset().top; diff --git a/app/assets/javascripts/lib/utils/csrf.js b/app/assets/javascripts/lib/utils/csrf.js index 0bdb547d31..ca9828c468 100644 --- a/app/assets/javascripts/lib/utils/csrf.js +++ b/app/assets/javascripts/lib/utils/csrf.js @@ -1,3 +1,5 @@ +import $ from 'jquery'; + /* This module provides easy access to the CSRF token and caches it for re-use. It also exposes some values commonly used in relation diff --git a/app/assets/javascripts/lib/utils/datetime_utility.js b/app/assets/javascripts/lib/utils/datetime_utility.js index d6cccbef42..c3d94d63c1 100644 --- a/app/assets/javascripts/lib/utils/datetime_utility.js +++ b/app/assets/javascripts/lib/utils/datetime_utility.js @@ -1,3 +1,4 @@ +import $ from 'jquery'; import timeago from 'timeago.js'; import dateFormat from 'vendor/date.format'; import { pluralize } from './text_utility'; diff --git a/app/assets/javascripts/lib/utils/dom_utils.js b/app/assets/javascripts/lib/utils/dom_utils.js index de65ea15a6..914de9de94 100644 --- a/app/assets/javascripts/lib/utils/dom_utils.js +++ b/app/assets/javascripts/lib/utils/dom_utils.js @@ -1,7 +1,12 @@ -/* eslint-disable import/prefer-default-export */ +import $ from 'jquery'; +import { isInIssuePage, isInMRPage, isInEpicPage, hasVueMRDiscussionsCookie } from './common_utils'; + +const isVueMRDiscussions = () => isInMRPage() && hasVueMRDiscussionsCookie() && !$('#diffs').is(':visible'); export const addClassIfElementExists = (element, className) => { if (element) { element.classList.add(className); } }; + +export const isInVueNoteablePage = () => isInIssuePage() || isInEpicPage() || isVueMRDiscussions(); diff --git a/app/assets/javascripts/lib/utils/text_markdown.js b/app/assets/javascripts/lib/utils/text_markdown.js index 5dc98b4a92..5a16adea4d 100644 --- a/app/assets/javascripts/lib/utils/text_markdown.js +++ b/app/assets/javascripts/lib/utils/text_markdown.js @@ -1,26 +1,25 @@ /* eslint-disable import/prefer-default-export, func-names, space-before-function-paren, wrap-iife, no-var, no-param-reassign, no-cond-assign, quotes, one-var, one-var-declaration-per-line, operator-assignment, no-else-return, prefer-template, prefer-arrow-callback, no-empty, max-len, consistent-return, no-unused-vars, no-return-assign, max-len, vars-on-top */ +import $ from 'jquery'; +import { insertText } from '~/lib/utils/common_utils'; -const textUtils = {}; - -textUtils.selectedText = function(text, textarea) { +function selectedText(text, textarea) { return text.substring(textarea.selectionStart, textarea.selectionEnd); -}; +} -textUtils.lineBefore = function(text, textarea) { +function lineBefore(text, textarea) { var split; split = text.substring(0, textarea.selectionStart).trim().split('\n'); return split[split.length - 1]; -}; +} -textUtils.lineAfter = function(text, textarea) { +function lineAfter(text, textarea) { return text.substring(textarea.selectionEnd).trim().split('\n')[0]; -}; +} -textUtils.blockTagText = function(text, textArea, blockTag, selected) { - var lineAfter, lineBefore; - lineBefore = this.lineBefore(text, textArea); - lineAfter = this.lineAfter(text, textArea); - if (lineBefore === blockTag && lineAfter === blockTag) { +function blockTagText(text, textArea, blockTag, selected) { + const before = lineBefore(text, textArea); + const after = lineAfter(text, textArea); + if (before === blockTag && after === blockTag) { // To remove the block tag we have to select the line before & after if (blockTag != null) { textArea.selectionStart = textArea.selectionStart - (blockTag.length + 1); @@ -30,10 +29,30 @@ textUtils.blockTagText = function(text, textArea, blockTag, selected) { } else { return blockTag + "\n" + selected + "\n" + blockTag; } -}; +} -textUtils.insertText = function(textArea, text, tag, blockTag, selected, wrap) { - var insertText, inserted, selectedSplit, startChar, removedLastNewLine, removedFirstNewLine, currentLineEmpty, lastNewLine; +function moveCursor(textArea, tag, wrapped, removedLastNewLine) { + var pos; + if (!textArea.setSelectionRange) { + return; + } + if (textArea.selectionStart === textArea.selectionEnd) { + if (wrapped) { + pos = textArea.selectionStart - tag.length; + } else { + pos = textArea.selectionStart; + } + + if (removedLastNewLine) { + pos -= 1; + } + + return textArea.setSelectionRange(pos, pos); + } +} + +export function insertMarkdownText(textArea, text, tag, blockTag, selected, wrap) { + var textToInsert, inserted, selectedSplit, startChar, removedLastNewLine, removedFirstNewLine, currentLineEmpty, lastNewLine; removedLastNewLine = false; removedFirstNewLine = false; currentLineEmpty = false; @@ -65,9 +84,9 @@ textUtils.insertText = function(textArea, text, tag, blockTag, selected, wrap) { if (selectedSplit.length > 1 && (!wrap || (blockTag != null && blockTag !== ''))) { if (blockTag != null && blockTag !== '') { - insertText = this.blockTagText(text, textArea, blockTag, selected); + textToInsert = blockTagText(text, textArea, blockTag, selected); } else { - insertText = selectedSplit.map(function(val) { + textToInsert = selectedSplit.map(function(val) { if (val.indexOf(tag) === 0) { return "" + (val.replace(tag, '')); } else { @@ -76,78 +95,42 @@ textUtils.insertText = function(textArea, text, tag, blockTag, selected, wrap) { }).join('\n'); } } else { - insertText = "" + startChar + tag + selected + (wrap ? tag : ' '); + textToInsert = "" + startChar + tag + selected + (wrap ? tag : ' '); } if (removedFirstNewLine) { - insertText = '\n' + insertText; + textToInsert = '\n' + textToInsert; } if (removedLastNewLine) { - insertText += '\n'; + textToInsert += '\n'; } - if (document.queryCommandSupported('insertText')) { - inserted = document.execCommand('insertText', false, insertText); - } - if (!inserted) { - try { - document.execCommand("ms-beginUndoUnit"); - } catch (error) {} - textArea.value = this.replaceRange(text, textArea.selectionStart, textArea.selectionEnd, insertText); - try { - document.execCommand("ms-endUndoUnit"); - } catch (error) {} - } - return this.moveCursor(textArea, tag, wrap, removedLastNewLine); -}; + insertText(textArea, textToInsert); + return moveCursor(textArea, tag, wrap, removedLastNewLine); +} -textUtils.moveCursor = function(textArea, tag, wrapped, removedLastNewLine) { - var pos; - if (!textArea.setSelectionRange) { - return; - } - if (textArea.selectionStart === textArea.selectionEnd) { - if (wrapped) { - pos = textArea.selectionStart - tag.length; - } else { - pos = textArea.selectionStart; - } - - if (removedLastNewLine) { - pos -= 1; - } - - return textArea.setSelectionRange(pos, pos); - } -}; - -textUtils.updateText = function(textArea, tag, blockTag, wrap) { +function updateText(textArea, tag, blockTag, wrap) { var $textArea, selected, text; $textArea = $(textArea); textArea = $textArea.get(0); text = $textArea.val(); - selected = this.selectedText(text, textArea); + selected = selectedText(text, textArea); $textArea.focus(); - return this.insertText(textArea, text, tag, blockTag, selected, wrap); -}; + return insertMarkdownText(textArea, text, tag, blockTag, selected, wrap); +} -textUtils.init = function(form) { - var self; - self = this; - return $('.js-md', form).off('click').on('click', function() { - var $this; - $this = $(this); - return self.updateText($this.closest('.md-area').find('textarea'), $this.data('mdTag'), $this.data('mdBlock'), !$this.data('mdPrepend')); - }); -}; - -textUtils.removeListeners = function(form) { - return $('.js-md', form).off('click'); -}; - -textUtils.replaceRange = function(s, start, end, substitute) { +function replaceRange(s, start, end, substitute) { return s.substring(0, start) + substitute + s.substring(end); -}; +} -export default textUtils; +export function addMarkdownListeners(form) { + return $('.js-md', form).off('click').on('click', function() { + const $this = $(this); + return updateText($this.closest('.md-area').find('textarea'), $this.data('mdTag'), $this.data('mdBlock'), !$this.data('mdPrepend')); + }); +} + +export function removeMarkdownListeners(form) { + return $('.js-md', form).off('click'); +} diff --git a/app/assets/javascripts/lib/utils/text_utility.js b/app/assets/javascripts/lib/utils/text_utility.js index c0ce078651..b54ecd2d54 100644 --- a/app/assets/javascripts/lib/utils/text_utility.js +++ b/app/assets/javascripts/lib/utils/text_utility.js @@ -7,7 +7,8 @@ * @param {String} text * @returns {String} */ -export const addDelimiter = text => (text ? text.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',') : text); +export const addDelimiter = text => + (text ? text.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',') : text); /** * Returns '99+' for numbers bigger than 99. @@ -22,7 +23,8 @@ export const highCountTrim = count => (count > 99 ? '99+' : count); * @param {String} string * @requires {String} */ -export const humanize = string => string.charAt(0).toUpperCase() + string.replace(/_/g, ' ').slice(1); +export const humanize = string => + string.charAt(0).toUpperCase() + string.replace(/_/g, ' ').slice(1); /** * Adds an 's' to the end of the string when count is bigger than 0 @@ -53,7 +55,7 @@ export const slugify = str => str.trim().toLowerCase(); * @param {Number} maxLength * @returns {String} */ -export const truncate = (string, maxLength) => `${string.substr(0, (maxLength - 3))}...`; +export const truncate = (string, maxLength) => `${string.substr(0, maxLength - 3)}...`; /** * Capitalizes first character @@ -65,20 +67,6 @@ export function capitalizeFirstCharacter(text) { return `${text[0].toUpperCase()}${text.slice(1)}`; } -export function camelCase(str) { - return str.replace(/_+([a-z])/gi, ($1, $2) => $2.toUpperCase()); -} - -export function camelCaseKeys(obj = {}) { - return Object.keys(obj).reduce((acc, key) => { - const camelKey = camelCase(key); - return { - ...acc, - [camelKey]: obj[key], - }; - }, {}); -} - /** * Replaces all html tags from a string with the given replacement. * @@ -94,3 +82,15 @@ export const stripHtml = (string, replace = '') => string.replace(/<[^>]*>/g, re * @param {*} string */ export const convertToCamelCase = string => string.replace(/(_\w)/g, s => s[1].toUpperCase()); + +/** + * Converts a sentence to lower case from the second word onwards + * e.g. Hello World => Hello world + * + * @param {*} string + */ +export const convertToSentenceCase = string => { + const splitWord = string.split(' ').map((word, index) => (index > 0 ? word.toLowerCase() : word)); + + return splitWord.join(' '); +}; diff --git a/app/assets/javascripts/lib/utils/url_utility.js b/app/assets/javascripts/lib/utils/url_utility.js index a266bb6771..dd17544b65 100644 --- a/app/assets/javascripts/lib/utils/url_utility.js +++ b/app/assets/javascripts/lib/utils/url_utility.js @@ -51,7 +51,7 @@ export function removeParams(params) { const url = document.createElement('a'); url.href = window.location.href; - params.forEach((param) => { + params.forEach(param => { url.search = removeParamQueryString(url.search, param); }); @@ -83,3 +83,11 @@ export function refreshCurrentPage() { export function redirectTo(url) { return window.location.assign(url); } + +export function webIDEUrl(route = undefined) { + let returnUrl = `${gon.relative_url_root}/-/ide/`; + if (route) { + returnUrl += `project${route}`; + } + return returnUrl; +} diff --git a/app/assets/javascripts/line_highlighter.js b/app/assets/javascripts/line_highlighter.js index e5c1fce3db..f2323f5745 100644 --- a/app/assets/javascripts/line_highlighter.js +++ b/app/assets/javascripts/line_highlighter.js @@ -1,5 +1,7 @@ /* eslint-disable func-names, space-before-function-paren, no-var, prefer-rest-params, wrap-iife, no-use-before-define, no-underscore-dangle, no-param-reassign, prefer-template, quotes, comma-dangle, prefer-arrow-callback, consistent-return, one-var, one-var-declaration-per-line, no-else-return, max-len */ +import $ from 'jquery'; + // LineHighlighter // // Handles single- and multi-line selection and highlight for blob views. diff --git a/app/assets/javascripts/logo.js b/app/assets/javascripts/logo.js index 3688a57937..403e216e70 100644 --- a/app/assets/javascripts/logo.js +++ b/app/assets/javascripts/logo.js @@ -1,3 +1,5 @@ +import $ from 'jquery'; + export default function initLogoAnimation() { window.addEventListener('beforeunload', () => { $('.tanuki-logo').addClass('animate'); diff --git a/app/assets/javascripts/main.js b/app/assets/javascripts/main.js index 53b01cca1d..2c80baba10 100644 --- a/app/assets/javascripts/main.js +++ b/app/assets/javascripts/main.js @@ -1,5 +1,5 @@ /* eslint-disable import/first */ -/* global ConfirmDangerModal */ +/* global $ */ import jQuery from 'jquery'; import Cookies from 'js-cookie'; @@ -20,7 +20,6 @@ import './behaviors/'; // everything else import loadAwardsHandler from './awards_handler'; import bp from './breakpoints'; -import './confirm_danger_modal'; import Flash, { removeFlashClickListener } from './flash'; import './gl_dropdown'; import initTodoToggle from './header'; @@ -31,7 +30,6 @@ import LazyLoader from './lazy_loader'; import initLogoAnimation from './logo'; import './milestone_select'; import './projects_dropdown'; -import './render_gfm'; import initBreadcrumbs from './breadcrumb'; import initDispatcher from './dispatcher'; @@ -214,16 +212,6 @@ document.addEventListener('DOMContentLoaded', () => { $(document).trigger('toggle.comments'); }); - $document.on('click', '.js-confirm-danger', (e) => { - const btn = $(e.target); - const form = btn.closest('form'); - const text = btn.data('confirmDangerMessage'); - e.preventDefault(); - - // eslint-disable-next-line no-new - new ConfirmDangerModal(form, text); - }); - $document.on('breakpoint:change', (e, breakpoint) => { if (breakpoint === 'sm' || breakpoint === 'xs') { const $gutterIcon = $sidebarGutterToggle.find('i'); diff --git a/app/assets/javascripts/member_expiration_date.js b/app/assets/javascripts/member_expiration_date.js index 84e70e35ba..d27922a209 100644 --- a/app/assets/javascripts/member_expiration_date.js +++ b/app/assets/javascripts/member_expiration_date.js @@ -1,3 +1,4 @@ +import $ from 'jquery'; import Pikaday from 'pikaday'; import { parsePikadayDate, pikadayToString } from './lib/utils/datefix'; diff --git a/app/assets/javascripts/members.js b/app/assets/javascripts/members.js index 330ebed5f7..7d0c701fd7 100644 --- a/app/assets/javascripts/members.js +++ b/app/assets/javascripts/members.js @@ -1,3 +1,5 @@ +import $ from 'jquery'; + export default class Members { constructor() { this.addListeners(); diff --git a/app/assets/javascripts/merge_conflicts/merge_conflict_store.js b/app/assets/javascripts/merge_conflicts/merge_conflict_store.js index 8be7314ded..db1d09eb2f 100644 --- a/app/assets/javascripts/merge_conflicts/merge_conflict_store.js +++ b/app/assets/javascripts/merge_conflicts/merge_conflict_store.js @@ -1,5 +1,6 @@ /* eslint-disable comma-dangle, object-shorthand, no-param-reassign, camelcase, no-nested-ternary, no-continue, max-len */ +import $ from 'jquery'; import Vue from 'vue'; import Cookies from 'js-cookie'; diff --git a/app/assets/javascripts/merge_conflicts/merge_conflicts_bundle.js b/app/assets/javascripts/merge_conflicts/merge_conflicts_bundle.js index 66b258839a..4abd5433bb 100644 --- a/app/assets/javascripts/merge_conflicts/merge_conflicts_bundle.js +++ b/app/assets/javascripts/merge_conflicts/merge_conflicts_bundle.js @@ -1,5 +1,6 @@ /* eslint-disable new-cap, comma-dangle, no-new */ +import $ from 'jquery'; import Vue from 'vue'; import Flash from '../flash'; import initIssuableSidebar from '../init_issuable_sidebar'; diff --git a/app/assets/javascripts/merge_request.js b/app/assets/javascripts/merge_request.js index a64093afcf..d8222ebec6 100644 --- a/app/assets/javascripts/merge_request.js +++ b/app/assets/javascripts/merge_request.js @@ -1,4 +1,6 @@ /* eslint-disable func-names, space-before-function-paren, no-var, prefer-rest-params, wrap-iife, quotes, no-underscore-dangle, one-var, one-var-declaration-per-line, consistent-return, dot-notation, quote-props, comma-dangle, object-shorthand, max-len, prefer-arrow-callback */ + +import $ from 'jquery'; import { __ } from '~/locale'; import TaskList from './task_list'; import MergeRequestTabs from './merge_request_tabs'; diff --git a/app/assets/javascripts/merge_request_tabs.js b/app/assets/javascripts/merge_request_tabs.js index 46789e324c..3f84f4b949 100644 --- a/app/assets/javascripts/merge_request_tabs.js +++ b/app/assets/javascripts/merge_request_tabs.js @@ -1,16 +1,13 @@ /* eslint-disable no-new, class-methods-use-this */ +import $ from 'jquery'; import Cookies from 'js-cookie'; import axios from './lib/utils/axios_utils'; import flash from './flash'; import BlobForkSuggestion from './blob/blob_fork_suggestion'; import initChangesDropdown from './init_changes_dropdown'; import bp from './breakpoints'; -import { - parseUrlPathname, - handleLocationHash, - isMetaClick, -} from './lib/utils/common_utils'; +import { parseUrlPathname, handleLocationHash, isMetaClick } from './lib/utils/common_utils'; import { getLocationHash } from './lib/utils/url_utility'; import initDiscussionTab from './image_diff/init_discussion_tab'; import Diff from './diff'; @@ -68,10 +65,10 @@ import Notes from './notes'; let location = window.location; export default class MergeRequestTabs { - constructor({ action, setUrl, stubLocation } = {}) { const mergeRequestTabs = document.querySelector('.js-tabs-affix'); const navbar = document.querySelector('.navbar-gitlab'); + const peek = document.getElementById('js-peek'); const paddingTop = 16; this.diffsLoaded = false; @@ -85,6 +82,10 @@ export default class MergeRequestTabs { this.showTab = this.showTab.bind(this); this.stickyTop = navbar ? navbar.offsetHeight - paddingTop : 0; + if (peek) { + this.stickyTop += peek.offsetHeight; + } + if (mergeRequestTabs) { this.stickyTop += mergeRequestTabs.offsetHeight; } @@ -103,8 +104,7 @@ export default class MergeRequestTabs { .on('shown.bs.tab', '.merge-request-tabs a[data-toggle="tab"]', this.tabShown) .on('click', '.js-show-tab', this.showTab); - $('.merge-request-tabs a[data-toggle="tab"]') - .on('click', this.clickTab); + $('.merge-request-tabs a[data-toggle="tab"]').on('click', this.clickTab); } // Used in tests @@ -113,8 +113,7 @@ export default class MergeRequestTabs { .off('shown.bs.tab', '.merge-request-tabs a[data-toggle="tab"]', this.tabShown) .off('click', '.js-show-tab', this.showTab); - $('.merge-request-tabs a[data-toggle="tab"]') - .off('click', this.clickTab); + $('.merge-request-tabs a[data-toggle="tab"]').off('click', this.clickTab); } destroyPipelinesView() { @@ -177,10 +176,7 @@ export default class MergeRequestTabs { scrollToElement(container) { if (location.hash) { - const offset = 0 - ( - $('.navbar-gitlab').outerHeight() + - $('.js-tabs-affix').outerHeight() - ); + const offset = 0 - ($('.navbar-gitlab').outerHeight() + $('.js-tabs-affix').outerHeight()); const $el = $(`${container} ${location.hash}:not(.match)`); if ($el.length) { $.scrollTo($el[0], { offset }); @@ -234,9 +230,13 @@ export default class MergeRequestTabs { // Turbolinks' history. // // See https://github.com/rails/turbolinks/issues/363 - window.history.replaceState({ - url: newState, - }, document.title, newState); + window.history.replaceState( + { + url: newState, + }, + document.title, + newState, + ); return newState; } @@ -252,7 +252,8 @@ export default class MergeRequestTabs { this.toggleLoading(true); - axios.get(`${source}.json`) + axios + .get(`${source}.json`) .then(({ data }) => { document.querySelector('div#commits').innerHTML = data.html; localTimeAgo($('.js-timeago', 'div#commits')); @@ -297,7 +298,8 @@ export default class MergeRequestTabs { this.toggleLoading(true); - axios.get(`${urlPathname}.json${location.search}`) + axios + .get(`${urlPathname}.json${location.search}`) .then(({ data }) => { const $container = $('#diffs'); $container.html(data.html); @@ -326,8 +328,7 @@ export default class MergeRequestTabs { cancelButtons: $(el).find('.js-cancel-fork-suggestion-button'), suggestionSections: $(el).find('.js-file-fork-suggestion-section'), actionTextPieces: $(el).find('.js-file-fork-suggestion-section-action'), - }) - .init(); + }).init(); }); // Scroll any linked note into view @@ -382,8 +383,7 @@ export default class MergeRequestTabs { resetViewContainer() { if (this.fixedLayoutPref !== null) { - $('.content-wrapper .container-fluid') - .toggleClass('container-limited', this.fixedLayoutPref); + $('.content-wrapper .container-fluid').toggleClass('container-limited', this.fixedLayoutPref); } } @@ -432,12 +432,11 @@ export default class MergeRequestTabs { const $diffTabs = $('#diff-notes-app'); - $tabs.off('affix.bs.affix affix-top.bs.affix') + $tabs + .off('affix.bs.affix affix-top.bs.affix') .affix({ offset: { - top: () => ( - $diffTabs.offset().top - $tabs.height() - $fixedNav.height() - ), + top: () => $diffTabs.offset().top - $tabs.height() - $fixedNav.height(), }, }) .on('affix.bs.affix', () => $diffTabs.css({ marginTop: $tabs.height() })) diff --git a/app/assets/javascripts/milestone.js b/app/assets/javascripts/milestone.js index b1d74250df..e6e3a66aa2 100644 --- a/app/assets/javascripts/milestone.js +++ b/app/assets/javascripts/milestone.js @@ -1,3 +1,4 @@ +import $ from 'jquery'; import axios from './lib/utils/axios_utils'; import flash from './flash'; diff --git a/app/assets/javascripts/milestone_select.js b/app/assets/javascripts/milestone_select.js index 7fa3e25a0e..c749042a14 100644 --- a/app/assets/javascripts/milestone_select.js +++ b/app/assets/javascripts/milestone_select.js @@ -1,6 +1,8 @@ /* eslint-disable func-names, space-before-function-paren, wrap-iife, no-underscore-dangle, prefer-arrow-callback, max-len, one-var, one-var-declaration-per-line, no-unused-vars, object-shorthand, comma-dangle, no-else-return, no-self-compare, consistent-return, no-param-reassign, no-shadow */ /* global Issuable */ /* global ListMilestone */ + +import $ from 'jquery'; import _ from 'underscore'; import axios from './lib/utils/axios_utils'; import { timeFor } from './lib/utils/datetime_utility'; diff --git a/app/assets/javascripts/mini_pipeline_graph_dropdown.js b/app/assets/javascripts/mini_pipeline_graph_dropdown.js index c7bccd483a..01399de4c6 100644 --- a/app/assets/javascripts/mini_pipeline_graph_dropdown.js +++ b/app/assets/javascripts/mini_pipeline_graph_dropdown.js @@ -1,4 +1,6 @@ /* eslint-disable no-new */ + +import $ from 'jquery'; import flash from './flash'; import axios from './lib/utils/axios_utils'; diff --git a/app/assets/javascripts/monitoring/components/dashboard.vue b/app/assets/javascripts/monitoring/components/dashboard.vue index 8ca94ef3e2..f5572be5fb 100644 --- a/app/assets/javascripts/monitoring/components/dashboard.vue +++ b/app/assets/javascripts/monitoring/components/dashboard.vue @@ -1,158 +1,155 @@ diff --git a/app/assets/javascripts/monitoring/components/empty_state.vue b/app/assets/javascripts/monitoring/components/empty_state.vue index 9517b8ccb6..c77f451c2d 100644 --- a/app/assets/javascripts/monitoring/components/empty_state.vue +++ b/app/assets/javascripts/monitoring/components/empty_state.vue @@ -1,87 +1,90 @@