summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md15
-rw-r--r--Gemfile.lock2
-rw-r--r--app/assets/javascripts/dispatcher.js47
-rw-r--r--app/assets/javascripts/init_issuable_sidebar.js18
-rw-r--r--app/assets/javascripts/init_legacy_filters.js15
-rw-r--r--app/assets/javascripts/init_notes.js14
-rw-r--r--app/assets/javascripts/issuable_context.js6
-rw-r--r--app/assets/javascripts/main.js11
-rw-r--r--app/assets/javascripts/merge_conflicts/merge_conflicts_bundle.js3
-rw-r--r--app/assets/javascripts/milestone_select.js2
-rw-r--r--app/assets/javascripts/notes.js4
-rw-r--r--app/assets/javascripts/pipelines/pipelines_charts.js38
-rw-r--r--app/assets/javascripts/pipelines/pipelines_times.js27
-rw-r--r--app/assets/javascripts/project.js29
-rw-r--r--app/assets/javascripts/projects/project_new.js43
-rw-r--r--app/assets/javascripts/ref_select_dropdown.js3
-rw-r--r--app/assets/javascripts/sidebar/sidebar_bundle.js3
-rw-r--r--app/assets/javascripts/snippets_list.js9
-rw-r--r--app/assets/javascripts/todos.js4
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js2
-rw-r--r--app/assets/stylesheets/framework/avatar.scss4
-rw-r--r--app/assets/stylesheets/framework/dropdowns.scss12
-rw-r--r--app/assets/stylesheets/framework/filters.scss3
-rw-r--r--app/assets/stylesheets/framework/header.scss4
-rw-r--r--app/assets/stylesheets/framework/layout.scss4
-rw-r--r--app/assets/stylesheets/framework/nav.scss20
-rw-r--r--app/assets/stylesheets/framework/sidebar.scss4
-rw-r--r--app/assets/stylesheets/framework/typography.scss6
-rw-r--r--app/assets/stylesheets/framework/variables.scss1
-rw-r--r--app/assets/stylesheets/new_sidebar.scss12
-rw-r--r--app/assets/stylesheets/pages/builds.scss15
-rw-r--r--app/assets/stylesheets/pages/issuable.scss8
-rw-r--r--app/assets/stylesheets/pages/merge_requests.scss4
-rw-r--r--app/assets/stylesheets/pages/projects.scss1
-rw-r--r--app/assets/stylesheets/performance_bar.scss14
-rw-r--r--app/controllers/concerns/notes_actions.rb22
-rw-r--r--app/controllers/projects/branches_controller.rb2
-rw-r--r--app/controllers/sessions_controller.rb7
-rw-r--r--app/finders/issuable_finder.rb1
-rw-r--r--app/helpers/application_helper.rb6
-rw-r--r--app/helpers/diff_helper.rb2
-rw-r--r--app/helpers/issuables_helper.rb10
-rw-r--r--app/helpers/nav_helper.rb33
-rw-r--r--app/helpers/notes_helper.rb16
-rw-r--r--app/helpers/webpack_helper.rb4
-rw-r--r--app/models/chat_team.rb9
-rw-r--r--app/models/ci/build.rb1
-rw-r--r--app/models/ci/pipeline.rb1
-rw-r--r--app/models/ci/pipeline_variable.rb10
-rw-r--r--app/models/concerns/issuable.rb5
-rw-r--r--app/models/issue.rb5
-rw-r--r--app/models/merge_request.rb13
-rw-r--r--app/models/project_services/drone_ci_service.rb2
-rw-r--r--app/services/ci/create_pipeline_service.rb18
-rw-r--r--app/services/ci/create_trigger_request_service.rb5
-rw-r--r--app/services/ci/pipeline_trigger_service.rb44
-rw-r--r--app/services/git_push_service.rb31
-rw-r--r--app/services/groups/destroy_service.rb2
-rw-r--r--app/services/issues/reopen_service.rb6
-rw-r--r--app/services/merge_requests/base_service.rb6
-rw-r--r--app/services/merge_requests/reopen_service.rb2
-rw-r--r--app/services/web_hook_service.rb2
-rw-r--r--app/views/layouts/_page.html.haml4
-rw-r--r--app/views/layouts/application.html.haml5
-rw-r--r--app/views/layouts/help.html.haml1
-rw-r--r--app/views/peek/views/_host.html.haml2
-rw-r--r--app/views/projects/new.html.haml45
-rw-r--r--app/views/projects/pipelines/charts/_pipeline_times.haml25
-rw-r--r--app/views/projects/pipelines/charts/_pipelines.haml36
-rw-r--r--app/views/projects/pipelines/new.html.haml5
-rw-r--r--app/views/projects/tags/new.html.haml5
-rw-r--r--app/views/projects/tree/_tree_content.html.haml8
-rw-r--r--app/views/projects/wikis/_sidebar.html.haml3
-rw-r--r--app/views/shared/_clone_panel.html.haml8
-rw-r--r--app/views/shared/_label.html.haml8
-rw-r--r--app/views/shared/_personal_access_tokens_form.html.haml15
-rw-r--r--app/views/shared/issuable/_filter.html.haml10
-rw-r--r--app/views/shared/issuable/_participants.html.haml2
-rw-r--r--app/views/shared/issuable/_search_bar.html.haml9
-rw-r--r--app/views/shared/issuable/_sidebar.html.haml15
-rw-r--r--app/views/shared/notes/_form.html.haml1
-rw-r--r--app/views/shared/notes/_notes_with_form.html.haml3
-rw-r--r--app/views/shared/projects/_project.html.haml2
-rw-r--r--app/views/snippets/_snippets.html.haml6
-rw-r--r--app/workers/git_garbage_collect_worker.rb39
-rw-r--r--changelogs/unreleased/12673-fix_v3_project_hooks_build_events4
-rw-r--r--changelogs/unreleased/2971-multiproject-grah-ce-port.yml4
-rw-r--r--changelogs/unreleased/34729-blob.yml4
-rw-r--r--changelogs/unreleased/34921-global-dropdown-ui-improvement.yml4
-rw-r--r--changelogs/unreleased/35044-projects-logo-are-not-centered-vertically-on-projects-page.yml4
-rw-r--r--changelogs/unreleased/35338-deploy-keys-should-not-show-pending-delete-projects.yml4
-rw-r--r--changelogs/unreleased/35453-pending-delete-projects-error-in-admin-dashboard-fix.yml4
-rw-r--r--changelogs/unreleased/35478-allow-admin-to-read-user-list.yml4
-rw-r--r--changelogs/unreleased/35539-can-t-create-a-merge-request-containing-a-binary-file-with-non-utf-8-characters.yml5
-rw-r--r--changelogs/unreleased/35567-fix-relative-urls-in-webpack-public-path.yml5
-rw-r--r--changelogs/unreleased/35672-edge-top-bar.yml4
-rw-r--r--changelogs/unreleased/35695-comment-appears-in-a-wrong-place-after-changing-diff-view-to-inline.yml4
-rw-r--r--changelogs/unreleased/add-instrumentation-to-link-to-gfm.yml4
-rw-r--r--changelogs/unreleased/dm-large-push-performance.yml4
-rw-r--r--changelogs/unreleased/fix-500-error-when-rendering-avatar-for-deleted-project-creator.yml4
-rw-r--r--changelogs/unreleased/fix-gb-fix-build-merge-request-link-to-fork-project.yml4
-rw-r--r--changelogs/unreleased/fix-replying-to-commit-comment-in-mr-from-fork.yml4
-rw-r--r--changelogs/unreleased/help-page-breadcrumb-title-fix.yml4
-rw-r--r--changelogs/unreleased/merge-issuable-reopened-into-opened-state.yml4
-rw-r--r--changelogs/unreleased/mk-add-ldap-ssl-certificate-verification.yml4
-rw-r--r--changelogs/unreleased/mk-add-lower-path-index-to-redirect-routes.yml4
-rw-r--r--changelogs/unreleased/new-navigation-custom-logo.yml4
-rw-r--r--changelogs/unreleased/zj-delete-mm-team.yml4
-rw-r--r--config/initializers/1_settings.rb2
-rw-r--r--config/initializers/omniauth.rb13
-rw-r--r--config/webpack.config.js5
-rw-r--r--db/migrate/20170720130522_create_ci_pipeline_variables.rb20
-rw-r--r--db/migrate/20170720130749_add_foreign_key_to_ci_pipeline_variables.rb15
-rw-r--r--db/post_migrate/20170719150301_merge_issuable_reopened_into_opened_state.rb32
-rw-r--r--db/schema.rb32
-rw-r--r--doc/README.md13
-rw-r--r--doc/administration/high_availability/nfs.md4
-rw-r--r--doc/administration/monitoring/performance/img/performance_bar.pngbin186116 -> 170256 bytes
-rw-r--r--doc/api/users.md40
-rw-r--r--doc/ci/yaml/README.md21
-rw-r--r--doc/development/ux_guide/copy.md8
-rw-r--r--doc/university/README.md1
-rw-r--r--doc/user/index.md2
-rw-r--r--doc/user/profile/index.md2
-rw-r--r--doc/user/project/index.md107
-rw-r--r--doc/user/project/integrations/jira.md21
-rw-r--r--doc/user/project/integrations/prometheus_library/haproxy.md8
-rw-r--r--doc/user/project/integrations/prometheus_library/metrics.md2
-rw-r--r--doc/user/project/koding.md2
-rw-r--r--doc/user/project/repository/index.md2
-rw-r--r--doc/workflow/gitlab_flow.md1
-rw-r--r--lib/api/helpers/related_resources_helpers.rb2
-rw-r--r--lib/api/triggers.rb23
-rw-r--r--lib/api/v3/project_hooks.rb8
-rw-r--r--lib/gitlab/data_builder/push.rb4
-rw-r--r--lib/gitlab/gitaly_client/repository_service.rb18
-rw-r--r--lib/gitlab/ldap/config.rb6
-rw-r--r--lib/gitlab/request_forgery_protection.rb8
-rw-r--r--lib/mattermost/client.rb10
-rw-r--r--lib/mattermost/team.rb7
-rw-r--r--lib/tasks/gitlab/gitaly.rake2
-rw-r--r--spec/controllers/projects/notes_controller_spec.rb62
-rw-r--r--spec/factories/ci/pipeline_variable_variables.rb8
-rw-r--r--spec/factories/issues.rb6
-rw-r--r--spec/factories/merge_requests.rb6
-rw-r--r--spec/factories/protected_branches.rb50
-rw-r--r--spec/factories/protected_tags.rb36
-rw-r--r--spec/features/admin/admin_hook_logs_spec.rb2
-rw-r--r--spec/features/admin/admin_hooks_spec.rb2
-rw-r--r--spec/features/admin/admin_projects_spec.rb19
-rw-r--r--spec/features/admin/admin_users_impersonation_tokens_spec.rb4
-rw-r--r--spec/features/admin/admin_users_spec.rb2
-rw-r--r--spec/features/atom/dashboard_issues_spec.rb4
-rw-r--r--spec/features/atom/dashboard_spec.rb2
-rw-r--r--spec/features/atom/issues_spec.rb2
-rw-r--r--spec/features/atom/users_spec.rb2
-rw-r--r--spec/features/dashboard/archived_projects_spec.rb2
-rw-r--r--spec/features/dashboard/datetime_on_tooltips_spec.rb2
-rw-r--r--spec/features/dashboard/issues_spec.rb12
-rw-r--r--spec/features/dashboard/label_filter_spec.rb4
-rw-r--r--spec/features/dashboard/milestone_filter_spec.rb2
-rw-r--r--spec/features/dashboard/todos/target_state_spec.rb2
-rw-r--r--spec/features/dashboard/todos/todos_spec.rb4
-rw-r--r--spec/features/dashboard/user_filters_projects_spec.rb4
-rw-r--r--spec/features/explore/new_menu_spec.rb2
-rw-r--r--spec/features/groups/group_settings_spec.rb6
-rw-r--r--spec/features/groups/members/request_access_spec.rb2
-rw-r--r--spec/features/groups/merge_requests_spec.rb2
-rw-r--r--spec/features/issuables/close_reopen_report_toggle_spec.rb4
-rw-r--r--spec/features/issuables/user_sees_sidebar_spec.rb2
-rw-r--r--spec/features/issues/award_emoji_spec.rb2
-rw-r--r--spec/features/issues/award_spec.rb2
-rw-r--r--spec/features/issues/bulk_assignment_labels_spec.rb2
-rw-r--r--spec/features/issues/create_branch_merge_request_spec.rb12
-rw-r--r--spec/features/issues/create_issue_for_discussions_in_merge_request_spec.rb2
-rw-r--r--spec/features/issues/create_issue_for_single_discussion_in_merge_request_spec.rb2
-rw-r--r--spec/features/issues/filtered_search/filter_issues_spec.rb2
-rw-r--r--spec/features/issues/form_spec.rb2
-rw-r--r--spec/features/issues/gfm_autocomplete_spec.rb2
-rw-r--r--spec/features/issues/issue_detail_spec.rb2
-rw-r--r--spec/features/issues/issue_sidebar_spec.rb2
-rw-r--r--spec/features/issues/markdown_toolbar_spec.rb4
-rw-r--r--spec/features/issues/move_spec.rb10
-rw-r--r--spec/features/issues/notes_on_issues_spec.rb12
-rw-r--r--spec/features/issues/spam_issues_spec.rb2
-rw-r--r--spec/features/issues/todo_spec.rb6
-rw-r--r--spec/features/issues/update_issues_spec.rb2
-rw-r--r--spec/features/issues/user_uses_slash_commands_spec.rb2
-rw-r--r--spec/features/merge_requests/assign_issues_spec.rb2
-rw-r--r--spec/features/merge_requests/award_spec.rb2
-rw-r--r--spec/features/merge_requests/check_if_mergeable_with_unresolved_discussions_spec.rb2
-rw-r--r--spec/features/merge_requests/cherry_pick_spec.rb2
-rw-r--r--spec/features/merge_requests/closes_issues_spec.rb2
-rw-r--r--spec/features/merge_requests/conflicts_spec.rb2
-rw-r--r--spec/features/merge_requests/create_new_mr_spec.rb6
-rw-r--r--spec/features/merge_requests/created_from_fork_spec.rb31
-rw-r--r--spec/features/merge_requests/diff_notes_avatars_spec.rb2
-rw-r--r--spec/features/merge_requests/diff_notes_resolve_spec.rb2
-rw-r--r--spec/features/merge_requests/diffs_spec.rb2
-rw-r--r--spec/features/merge_requests/edit_mr_spec.rb2
-rw-r--r--spec/features/merge_requests/filter_by_labels_spec.rb4
-rw-r--r--spec/features/merge_requests/filter_by_milestone_spec.rb2
-rw-r--r--spec/features/merge_requests/filter_merge_requests_spec.rb2
-rw-r--r--spec/features/merge_requests/form_spec.rb14
-rw-r--r--spec/features/merge_requests/merge_commit_message_toggle_spec.rb2
-rw-r--r--spec/features/merge_requests/merge_immediately_with_pipeline_spec.rb2
-rw-r--r--spec/features/merge_requests/merge_when_pipeline_succeeds_spec.rb2
-rw-r--r--spec/features/merge_requests/mini_pipeline_graph_spec.rb2
-rw-r--r--spec/features/merge_requests/reset_filters_spec.rb2
-rw-r--r--spec/features/merge_requests/toggler_behavior_spec.rb2
-rw-r--r--spec/features/merge_requests/update_merge_requests_spec.rb2
-rw-r--r--spec/features/merge_requests/user_lists_merge_requests_spec.rb2
-rw-r--r--spec/features/merge_requests/user_posts_notes_spec.rb2
-rw-r--r--spec/features/merge_requests/user_sees_system_notes_spec.rb4
-rw-r--r--spec/features/merge_requests/user_uses_slash_commands_spec.rb4
-rw-r--r--spec/features/merge_requests/widget_spec.rb4
-rw-r--r--spec/features/merge_requests/wip_message_spec.rb2
-rw-r--r--spec/features/profiles/account_spec.rb6
-rw-r--r--spec/features/projects/artifacts/browse_spec.rb4
-rw-r--r--spec/features/projects/artifacts/download_spec.rb4
-rw-r--r--spec/features/projects/artifacts/file_spec.rb4
-rw-r--r--spec/features/projects/artifacts/raw_spec.rb4
-rw-r--r--spec/features/projects/badges/coverage_spec.rb4
-rw-r--r--spec/features/projects/badges/list_spec.rb2
-rw-r--r--spec/features/projects/blobs/blob_show_spec.rb2
-rw-r--r--spec/features/projects/branches/download_buttons_spec.rb2
-rw-r--r--spec/features/projects/branches/new_branch_ref_dropdown_spec.rb2
-rw-r--r--spec/features/projects/branches_spec.rb8
-rw-r--r--spec/features/projects/commit/builds_spec.rb2
-rw-r--r--spec/features/projects/commit/cherry_pick_spec.rb2
-rw-r--r--spec/features/projects/commit/mini_pipeline_graph_spec.rb2
-rw-r--r--spec/features/projects/compare_spec.rb2
-rw-r--r--spec/features/projects/edit_spec.rb6
-rw-r--r--spec/features/projects/environments/environment_spec.rb2
-rw-r--r--spec/features/projects/environments/environments_spec.rb2
-rw-r--r--spec/features/projects/features_visibility_spec.rb4
-rw-r--r--spec/features/projects/files/browse_files_spec.rb2
-rw-r--r--spec/features/projects/files/creating_a_file_spec.rb2
-rw-r--r--spec/features/projects/files/dockerfile_dropdown_spec.rb2
-rw-r--r--spec/features/projects/files/download_buttons_spec.rb2
-rw-r--r--spec/features/projects/files/edit_file_soft_wrap_spec.rb2
-rw-r--r--spec/features/projects/files/editing_a_file_spec.rb2
-rw-r--r--spec/features/projects/files/find_file_keyboard_spec.rb2
-rw-r--r--spec/features/projects/files/find_files_spec.rb2
-rw-r--r--spec/features/projects/files/gitignore_dropdown_spec.rb2
-rw-r--r--spec/features/projects/files/gitlab_ci_yml_dropdown_spec.rb2
-rw-r--r--spec/features/projects/files/project_owner_creates_license_file_spec.rb2
-rw-r--r--spec/features/projects/files/template_type_dropdown_spec.rb2
-rw-r--r--spec/features/projects/files/undo_template_spec.rb2
-rw-r--r--spec/features/projects/gfm_autocomplete_load_spec.rb2
-rw-r--r--spec/features/projects/group_links_spec.rb4
-rw-r--r--spec/features/projects/import_export/import_file_spec.rb4
-rw-r--r--spec/features/projects/issuable_templates_spec.rb4
-rw-r--r--spec/features/projects/jobs_spec.rb2
-rw-r--r--spec/features/projects/labels/issues_sorted_by_priority_spec.rb2
-rw-r--r--spec/features/projects/main/download_buttons_spec.rb2
-rw-r--r--spec/features/projects/members/group_member_cannot_leave_group_project_spec.rb2
-rw-r--r--spec/features/projects/members/group_member_cannot_request_access_to_his_group_project_spec.rb2
-rw-r--r--spec/features/projects/members/group_requester_cannot_request_access_to_project_spec.rb2
-rw-r--r--spec/features/projects/members/list_spec.rb2
-rw-r--r--spec/features/projects/members/master_adds_member_with_expiration_date_spec.rb2
-rw-r--r--spec/features/projects/members/member_cannot_request_access_to_his_project_spec.rb2
-rw-r--r--spec/features/projects/members/member_leaves_project_spec.rb2
-rw-r--r--spec/features/projects/members/owner_cannot_leave_project_spec.rb2
-rw-r--r--spec/features/projects/members/owner_cannot_request_access_to_his_project_spec.rb2
-rw-r--r--spec/features/projects/members/user_requests_access_spec.rb2
-rw-r--r--spec/features/projects/merge_request_button_spec.rb4
-rw-r--r--spec/features/projects/merge_requests/list_spec.rb2
-rw-r--r--spec/features/projects/no_password_spec.rb2
-rw-r--r--spec/features/projects/pipeline_schedules_spec.rb2
-rw-r--r--spec/features/projects/pipelines/pipeline_spec.rb6
-rw-r--r--spec/features/projects/pipelines/pipelines_spec.rb12
-rw-r--r--spec/features/projects/project_settings_spec.rb6
-rw-r--r--spec/features/projects/ref_switcher_spec.rb2
-rw-r--r--spec/features/projects/services/slack_service_spec.rb2
-rw-r--r--spec/features/projects/services/slack_slash_command_spec.rb2
-rw-r--r--spec/features/projects/settings/visibility_settings_spec.rb2
-rw-r--r--spec/features/projects/shortcuts_spec.rb2
-rw-r--r--spec/features/projects/snippets/create_snippet_spec.rb2
-rw-r--r--spec/features/projects/user_browses_files_spec.rb2
-rw-r--r--spec/features/projects/user_creates_directory_spec.rb2
-rw-r--r--spec/features/projects/user_creates_files_spec.rb2
-rw-r--r--spec/features/projects/user_deletes_files_spec.rb2
-rw-r--r--spec/features/projects/user_edits_files_spec.rb2
-rw-r--r--spec/features/projects/user_replaces_files_spec.rb2
-rw-r--r--spec/features/projects/user_uploads_files_spec.rb2
-rw-r--r--spec/features/projects/wiki/markdown_preview_spec.rb2
-rw-r--r--spec/features/projects/wiki/user_creates_wiki_page_spec.rb4
-rw-r--r--spec/features/projects/wiki/user_git_access_wiki_page_spec.rb2
-rw-r--r--spec/features/projects/wiki/user_updates_wiki_page_spec.rb4
-rw-r--r--spec/features/projects/wiki/user_views_project_wiki_page_spec.rb2
-rw-r--r--spec/features/security/group/internal_access_spec.rb3
-rw-r--r--spec/features/security/group/private_access_spec.rb3
-rw-r--r--spec/features/security/group/public_access_spec.rb3
-rw-r--r--spec/features/security/project/internal_access_spec.rb2
-rw-r--r--spec/features/security/project/private_access_spec.rb2
-rw-r--r--spec/features/security/project/public_access_spec.rb2
-rw-r--r--spec/helpers/diff_helper_spec.rb17
-rw-r--r--spec/lib/banzai/filter/issuable_state_filter_spec.rb10
-rw-r--r--spec/lib/gitlab/import_export/all_models.yml3
-rw-r--r--spec/models/ci/build_spec.rb6
-rw-r--r--spec/models/ci/pipeline_spec.rb1
-rw-r--r--spec/models/ci/pipeline_variable_spec.rb8
-rw-r--r--spec/models/project_wiki_spec.rb2
-rw-r--r--spec/requests/api/issues_spec.rb2
-rw-r--r--spec/requests/api/triggers_spec.rb18
-rw-r--r--spec/requests/api/v3/issues_spec.rb2
-rw-r--r--spec/requests/api/v3/project_hooks_spec.rb6
-rw-r--r--spec/services/boards/issues/list_service_spec.rb2
-rw-r--r--spec/services/boards/issues/move_service_spec.rb2
-rw-r--r--spec/services/ci/pipeline_trigger_service_spec.rb83
-rw-r--r--spec/services/delete_merged_branches_service_spec.rb2
-rw-r--r--spec/services/git_push_service_spec.rb205
-rw-r--r--spec/services/groups/destroy_service_spec.rb10
-rw-r--r--spec/services/merge_requests/get_urls_service_spec.rb2
-rw-r--r--spec/services/merge_requests/reopen_service_spec.rb2
-rw-r--r--spec/services/web_hook_service_spec.rb2
-rw-r--r--spec/spec_helper.rb1
-rw-r--r--spec/support/capybara.rb9
-rw-r--r--spec/support/test_env.rb2
-rw-r--r--spec/views/shared/projects/_project.html.haml_spec.rb19
-rw-r--r--spec/workers/git_garbage_collect_worker_spec.rb52
322 files changed, 1739 insertions, 850 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 580d2357512..412cd86bad6 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,21 @@
documentation](doc/development/changelog.md) for instructions on adding your own
entry.
+## 9.4.2 (2017-07-28)
+
+- Fix job merge request link to a forked source project. !12965
+- Improve redirect route query performance. !13062
+- Allow admin to read_users_list even if it's restricted. !13066
+- Fixes 500 error caused by pending delete projects in admin dashboard. !13067
+- Add instrumentation to MarkupHelper#link_to_gfm. !13069
+- Pending delete projects should not show in deploy keys. !13088
+- Fix sizing of custom header logo in new navigation.
+- Fix crash on /help/ui.
+- Fix creating merge request diffs when diff contains bytes that are invalid in UTF-8.
+- fix vertical alignment of New Project button.
+- Add LDAP SSL certificate verification option.
+- Fix vertical alignment in firefox and safari for pipeline mini graph.
+
## 9.4.1 (2017-07-25)
- Fix pipeline_schedules pages throwing error 500 (when ref is empty). !12983
diff --git a/Gemfile.lock b/Gemfile.lock
index 627750e2c1d..05a70704513 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -323,7 +323,7 @@ GEM
multi_json (~> 1.10)
retriable (~> 1.4)
signet (~> 0.6)
- google-protobuf (3.2.0.2)
+ google-protobuf (3.3.0)
googleauth (0.5.1)
faraday (~> 0.9)
jwt (~> 1.4)
diff --git a/app/assets/javascripts/dispatcher.js b/app/assets/javascripts/dispatcher.js
index 54323d9a402..d5923266c60 100644
--- a/app/assets/javascripts/dispatcher.js
+++ b/app/assets/javascripts/dispatcher.js
@@ -8,6 +8,7 @@
/* global LabelsSelect */
/* global MilestoneSelect */
/* global Commit */
+/* global NewBranchForm */
/* global NotificationsForm */
/* global NotificationsDropdown */
/* global GroupAvatar */
@@ -64,6 +65,9 @@ import initSettingsPanels from './settings_panels';
import initExperimentalFlags from './experimental_flags';
import OAuthRememberMe from './oauth_remember_me';
import PerformanceBar from './performance_bar';
+import initNotes from './init_notes';
+import initLegacyFilters from './init_legacy_filters';
+import initIssuableSidebar from './init_issuable_sidebar';
import GpgBadges from './gpg_badges';
(function() {
@@ -159,6 +163,8 @@ import GpgBadges from './gpg_badges';
new Issue();
shortcut_handler = new ShortcutsIssuable();
new ZenMode();
+ initIssuableSidebar();
+ initNotes();
break;
case 'dashboard:milestones:index':
new ProjectSelect();
@@ -169,10 +175,12 @@ import GpgBadges from './gpg_badges';
new Milestone();
new Sidebar();
break;
+ case 'dashboard:issues':
+ case 'dashboard:merge_requests':
case 'groups:issues':
case 'groups:merge_requests':
- new UsersSelect();
new ProjectSelect();
+ initLegacyFilters();
break;
case 'dashboard:todos:index':
new Todos();
@@ -251,7 +259,10 @@ import GpgBadges from './gpg_badges';
case 'projects:tags:new':
new ZenMode();
new gl.GLForm($('.tag-form'), true);
- new RefSelectDropdown($('.js-branch-select'), window.gl.availableRefs);
+ new RefSelectDropdown($('.js-branch-select'));
+ break;
+ case 'projects:snippets:show':
+ initNotes();
break;
case 'projects:snippets:new':
case 'projects:snippets:edit':
@@ -273,6 +284,10 @@ import GpgBadges from './gpg_badges';
new gl.Diff();
shortcut_handler = new ShortcutsIssuable(true);
new ZenMode();
+
+ initIssuableSidebar();
+ initNotes();
+
const mrShowNode = document.querySelector('.merge-request');
window.mergeRequest = new MergeRequest({
action: mrShowNode.dataset.mrAction,
@@ -281,11 +296,6 @@ import GpgBadges from './gpg_badges';
case 'dashboard:activity':
new gl.Activities();
break;
- case 'dashboard:issues':
- case 'dashboard:merge_requests':
- new ProjectSelect();
- new UsersSelect();
- break;
case 'projects:commit:show':
new Commit();
new gl.Diff();
@@ -294,6 +304,7 @@ import GpgBadges from './gpg_badges';
new MiniPipelineGraph({
container: '.js-commit-pipeline-graph',
}).bindEvents();
+ initNotes();
break;
case 'projects:commit:pipelines':
new MiniPipelineGraph({
@@ -320,6 +331,9 @@ import GpgBadges from './gpg_badges';
case 'projects:edit':
setupProjectEdit();
break;
+ case 'projects:pipelines:new':
+ new NewBranchForm($('.js-new-pipeline-form'));
+ break;
case 'projects:pipelines:builds':
case 'projects:pipelines:failures':
case 'projects:pipelines:show':
@@ -373,6 +387,9 @@ import GpgBadges from './gpg_badges';
shortcut_handler = new ShortcutsNavigation();
new TreeView();
new BlobViewer();
+ $('#tree-slider').waitForImages(function() {
+ gl.utils.ajaxGet(document.querySelector('.js-tree-content').dataset.logsPath);
+ });
break;
case 'projects:find_file:show':
shortcut_handler = true;
@@ -390,10 +407,20 @@ import GpgBadges from './gpg_badges';
case 'projects:labels:edit':
new Labels();
break;
+ case 'groups:labels:index':
case 'projects:labels:index':
if ($('.prioritized-labels').length) {
new gl.LabelManager();
}
+ $('.label-subscription').each((i, el) => {
+ const $el = $(el);
+
+ if ($el.find('.dropdown-group-label').length) {
+ new gl.GroupLabelSubscription($el);
+ } else {
+ new gl.ProjectLabelSubscription($el);
+ }
+ });
break;
case 'projects:network:show':
// Ensure we don't create a particular shortcut handler here. This is
@@ -438,10 +465,15 @@ import GpgBadges from './gpg_badges';
case 'snippets:show':
new LineHighlighter();
new BlobViewer();
+ initNotes();
break;
case 'import:fogbugz:new_user_map':
new UsersSelect();
break;
+ case 'profiles:personal_access_tokens:index':
+ case 'admin:impersonation_tokens:index':
+ new gl.DueDateSelectors();
+ break;
}
switch (path.first()) {
case 'sessions':
@@ -515,6 +547,7 @@ import GpgBadges from './gpg_badges';
shortcut_handler = new ShortcutsWiki();
new ZenMode();
new gl.GLForm($('.wiki-form'), true);
+ new Sidebar();
break;
case 'snippets':
shortcut_handler = new ShortcutsNavigation();
diff --git a/app/assets/javascripts/init_issuable_sidebar.js b/app/assets/javascripts/init_issuable_sidebar.js
new file mode 100644
index 00000000000..29e3d2ea94e
--- /dev/null
+++ b/app/assets/javascripts/init_issuable_sidebar.js
@@ -0,0 +1,18 @@
+/* eslint-disable no-new */
+/* global MilestoneSelect */
+/* global LabelsSelect */
+/* global IssuableContext */
+/* global Sidebar */
+
+export default () => {
+ const sidebarOptions = JSON.parse(document.querySelector('.js-sidebar-options').innerHTML);
+
+ new MilestoneSelect({
+ full_path: sidebarOptions.fullPath,
+ });
+ new LabelsSelect();
+ new IssuableContext(sidebarOptions.currentUser);
+ gl.Subscription.bindAll('.subscription');
+ new gl.DueDateSelectors();
+ window.sidebar = new Sidebar();
+};
diff --git a/app/assets/javascripts/init_legacy_filters.js b/app/assets/javascripts/init_legacy_filters.js
new file mode 100644
index 00000000000..1211c2c802c
--- /dev/null
+++ b/app/assets/javascripts/init_legacy_filters.js
@@ -0,0 +1,15 @@
+/* eslint-disable no-new */
+/* global LabelsSelect */
+/* global MilestoneSelect */
+/* global IssueStatusSelect */
+/* global SubscriptionSelect */
+
+import UsersSelect from './users_select';
+
+export default () => {
+ new UsersSelect();
+ new LabelsSelect();
+ new MilestoneSelect();
+ new IssueStatusSelect();
+ new SubscriptionSelect();
+};
diff --git a/app/assets/javascripts/init_notes.js b/app/assets/javascripts/init_notes.js
new file mode 100644
index 00000000000..3a8b4360cb6
--- /dev/null
+++ b/app/assets/javascripts/init_notes.js
@@ -0,0 +1,14 @@
+/* global Notes */
+
+export default () => {
+ const dataEl = document.querySelector('.js-notes-data');
+ const {
+ notesUrl,
+ notesIds,
+ now,
+ diffView,
+ autocomplete,
+ } = JSON.parse(dataEl.innerHTML);
+
+ window.notes = new Notes(notesUrl, notesIds, now, diffView, autocomplete);
+};
diff --git a/app/assets/javascripts/issuable_context.js b/app/assets/javascripts/issuable_context.js
index a4d7bf096ef..26392db4b5b 100644
--- a/app/assets/javascripts/issuable_context.js
+++ b/app/assets/javascripts/issuable_context.js
@@ -4,6 +4,8 @@
import Cookies from 'js-cookie';
import UsersSelect from './users_select';
+const PARTICIPANTS_ROW_COUNT = 7;
+
(function() {
this.IssuableContext = (function() {
function IssuableContext(currentUser) {
@@ -50,11 +52,9 @@ import UsersSelect from './users_select';
}
IssuableContext.prototype.initParticipants = function() {
- var _this;
- _this = this;
$(document).on("click", ".js-participants-more", this.toggleHiddenParticipants);
return $(".js-participants-author").each(function(i) {
- if (i >= _this.PARTICIPANTS_ROW_COUNT) {
+ if (i >= PARTICIPANTS_ROW_COUNT) {
return $(this).addClass("js-participants-hidden").hide();
}
});
diff --git a/app/assets/javascripts/main.js b/app/assets/javascripts/main.js
index d039ca9e47c..cd45091c211 100644
--- a/app/assets/javascripts/main.js
+++ b/app/assets/javascripts/main.js
@@ -145,7 +145,6 @@ import './right_sidebar';
import './search';
import './search_autocomplete';
import './smart_interval';
-import './snippets_list';
import './star';
import './subscription';
import './subscription_select';
@@ -354,4 +353,14 @@ $(function () {
gl.utils.renderTimeago();
$(document).trigger('init.scrolling-tabs');
+
+ $('form.filter-form').on('submit', function (event) {
+ const link = document.createElement('a');
+ link.href = this.action;
+
+ const action = `${this.action}${link.search === '' ? '?' : '&'}`;
+
+ event.preventDefault();
+ gl.utils.visitUrl(`${action}${$(this).serialize()}`);
+ });
});
diff --git a/app/assets/javascripts/merge_conflicts/merge_conflicts_bundle.js b/app/assets/javascripts/merge_conflicts/merge_conflicts_bundle.js
index 17030c3e4d3..d74cf5328ad 100644
--- a/app/assets/javascripts/merge_conflicts/merge_conflicts_bundle.js
+++ b/app/assets/javascripts/merge_conflicts/merge_conflicts_bundle.js
@@ -2,6 +2,7 @@
/* global Flash */
import Vue from 'vue';
+import initIssuableSidebar from '../init_issuable_sidebar';
import './merge_conflict_store';
import './merge_conflict_service';
import './mixins/line_conflict_utils';
@@ -19,6 +20,8 @@ $(() => {
resolveConflictsPath: conflictsEl.dataset.resolveConflictsPath
});
+ initIssuableSidebar();
+
gl.MergeConflictsResolverApp = new Vue({
el: '#conflicts',
data: mergeConflictsStore.state,
diff --git a/app/assets/javascripts/milestone_select.js b/app/assets/javascripts/milestone_select.js
index 9d481d7c003..6756ab0b3aa 100644
--- a/app/assets/javascripts/milestone_select.js
+++ b/app/assets/javascripts/milestone_select.js
@@ -8,7 +8,7 @@
var _this, $els;
if (currentProject != null) {
_this = this;
- this.currentProject = JSON.parse(currentProject);
+ this.currentProject = typeof currentProject === 'string' ? JSON.parse(currentProject) : currentProject;
}
$els = $(els);
diff --git a/app/assets/javascripts/notes.js b/app/assets/javascripts/notes.js
index b2c503d1656..dfa07a2def4 100644
--- a/app/assets/javascripts/notes.js
+++ b/app/assets/javascripts/notes.js
@@ -529,6 +529,7 @@ export default class Notes {
form.find('#note_line_code').remove();
form.find('#note_position').remove();
form.find('#note_type').val('');
+ form.find('#note_project_id').remove();
form.find('#in_reply_to_discussion_id').remove();
form.find('.js-comment-resolve-button').closest('comment-and-resolve-btn').remove();
this.parentTimeline = form.parents('.timeline');
@@ -556,6 +557,7 @@ export default class Notes {
form.find('#note_noteable_id').val(),
form.find('#note_commit_id').val(),
form.find('#note_type').val(),
+ form.find('#note_project_id').val(),
form.find('#in_reply_to_discussion_id').val(),
// LegacyDiffNote
@@ -848,6 +850,8 @@ export default class Notes {
form.find('#in_reply_to_discussion_id').val(discussionID);
}
+ form.find('#note_project_id').val(dataHolder.data('discussionProjectId'));
+
form.attr('data-line-code', dataHolder.data('lineCode'));
form.find('#line_type').val(dataHolder.data('lineType'));
diff --git a/app/assets/javascripts/pipelines/pipelines_charts.js b/app/assets/javascripts/pipelines/pipelines_charts.js
new file mode 100644
index 00000000000..001faf4be33
--- /dev/null
+++ b/app/assets/javascripts/pipelines/pipelines_charts.js
@@ -0,0 +1,38 @@
+import Chart from 'vendor/Chart';
+
+document.addEventListener('DOMContentLoaded', () => {
+ const chartData = JSON.parse(document.getElementById('pipelinesChartsData').innerHTML);
+ const buildChart = (chartScope) => {
+ const data = {
+ labels: chartScope.labels,
+ datasets: [{
+ fillColor: '#7f8fa4',
+ strokeColor: '#7f8fa4',
+ pointColor: '#7f8fa4',
+ pointStrokeColor: '#EEE',
+ data: chartScope.totalValues,
+ },
+ {
+ fillColor: '#44aa22',
+ strokeColor: '#44aa22',
+ pointColor: '#44aa22',
+ pointStrokeColor: '#fff',
+ data: chartScope.successValues,
+ },
+ ],
+ };
+ const ctx = $(`#${chartScope.scope}Chart`).get(0).getContext('2d');
+ const options = {
+ scaleOverlay: true,
+ responsive: true,
+ maintainAspectRatio: false,
+ };
+ if (window.innerWidth < 768) {
+ // Scale fonts if window width lower than 768px (iPad portrait)
+ options.scaleFontSize = 8;
+ }
+ new Chart(ctx).Line(data, options);
+ };
+
+ chartData.forEach(scope => buildChart(scope));
+});
diff --git a/app/assets/javascripts/pipelines/pipelines_times.js b/app/assets/javascripts/pipelines/pipelines_times.js
new file mode 100644
index 00000000000..b5e7a0e53d9
--- /dev/null
+++ b/app/assets/javascripts/pipelines/pipelines_times.js
@@ -0,0 +1,27 @@
+import Chart from 'vendor/Chart';
+
+document.addEventListener('DOMContentLoaded', () => {
+ const chartData = JSON.parse(document.getElementById('pipelinesTimesChartsData').innerHTML);
+ const data = {
+ labels: chartData.labels,
+ datasets: [{
+ fillColor: 'rgba(220,220,220,0.5)',
+ strokeColor: 'rgba(220,220,220,1)',
+ barStrokeWidth: 1,
+ barValueSpacing: 1,
+ barDatasetSpacing: 1,
+ data: chartData.values,
+ }],
+ };
+ const ctx = $('#build_timesChart').get(0).getContext('2d');
+ const options = {
+ scaleOverlay: true,
+ responsive: true,
+ maintainAspectRatio: false,
+ };
+ if (window.innerWidth < 768) {
+ // Scale fonts if window width lower than 768px (iPad portrait)
+ options.scaleFontSize = 8;
+ }
+ new Chart(ctx).Bar(data, options);
+});
diff --git a/app/assets/javascripts/project.js b/app/assets/javascripts/project.js
index 738e710deb9..a3f7d69b98d 100644
--- a/app/assets/javascripts/project.js
+++ b/app/assets/javascripts/project.js
@@ -6,21 +6,22 @@ import Cookies from 'js-cookie';
(function() {
this.Project = (function() {
function Project() {
- $('ul.clone-options-dropdown a').click(function() {
- var url;
- if ($(this).hasClass('active')) {
- return;
- }
- $('.active').not($(this)).removeClass('active');
- $(this).toggleClass('active');
- url = $("#project_clone").val();
- $('#project_clone').val(url);
+ const $cloneOptions = $('ul.clone-options-dropdown');
+ const $projectCloneField = $('#project_clone');
+ const $cloneBtnText = $('a.clone-dropdown-btn span');
+
+ $('a', $cloneOptions).on('click', (e) => {
+ const $this = $(e.currentTarget);
+ const url = $this.attr('href');
+
+ e.preventDefault();
+
+ $('.active', $cloneOptions).not($this).removeClass('active');
+ $this.toggleClass('active');
+ $projectCloneField.val(url);
+ $cloneBtnText.text($this.text());
+
return $('.clone').text(url);
- // Git protocol switcher
- // Remove the active class for all buttons (ssh, http, kerberos if shown)
- // Add the active class for the clicked button
- // Update the input field
- // Update the command line instructions
});
// Ref switcher
this.initRefSwitcher();
diff --git a/app/assets/javascripts/projects/project_new.js b/app/assets/javascripts/projects/project_new.js
new file mode 100644
index 00000000000..2091b275c3d
--- /dev/null
+++ b/app/assets/javascripts/projects/project_new.js
@@ -0,0 +1,43 @@
+document.addEventListener('DOMContentLoaded', () => {
+ const importBtnTooltip = 'Please enter a valid project name.';
+ const $importBtnWrapper = $('.import_gitlab_project');
+
+ $('.how_to_import_link').on('click', (e) => {
+ e.preventDefault();
+ $('.how_to_import_link').next('.modal').show();
+ });
+
+ $('.modal-header .close').on('click', () => {
+ $('.modal').hide();
+ });
+
+ $('.btn_import_gitlab_project').on('click', () => {
+ const importHref = $('a.btn_import_gitlab_project').attr('href');
+ $('.btn_import_gitlab_project').attr('href', `${importHref}?namespace_id=${$('#project_namespace_id').val()}&path=${$('#project_path').val()}`);
+ });
+
+ $('.btn_import_gitlab_project').attr('disabled', !$('#project_path').val().trim().length);
+ $importBtnWrapper.attr('title', importBtnTooltip);
+
+ $('#new_project').on('submit', () => {
+ const $path = $('#project_path');
+ $path.val($path.val().trim());
+ });
+
+ $('#project_path').on('keyup', () => {
+ if ($('#project_path').val().trim().length) {
+ $('.btn_import_gitlab_project').attr('disabled', false);
+ $importBtnWrapper.attr('title', '');
+ $importBtnWrapper.removeClass('has-tooltip');
+ } else {
+ $('.btn_import_gitlab_project').attr('disabled', true);
+ $importBtnWrapper.addClass('has-tooltip');
+ }
+ });
+
+ $('#project_import_url').disable();
+ $('.import_git').on('click', () => {
+ const $projectImportUrl = $('#project_import_url');
+ $projectImportUrl.attr('disabled', !$projectImportUrl.attr('disabled'));
+ });
+});
diff --git a/app/assets/javascripts/ref_select_dropdown.js b/app/assets/javascripts/ref_select_dropdown.js
index 215cd6fbdfd..65e4101352c 100644
--- a/app/assets/javascripts/ref_select_dropdown.js
+++ b/app/assets/javascripts/ref_select_dropdown.js
@@ -1,7 +1,8 @@
class RefSelectDropdown {
constructor($dropdownButton, availableRefs) {
+ const availableRefsValue = availableRefs || JSON.parse(document.getElementById('availableRefs').innerHTML);
$dropdownButton.glDropdown({
- data: availableRefs,
+ data: availableRefsValue,
filterable: true,
filterByText: true,
remote: false,
diff --git a/app/assets/javascripts/sidebar/sidebar_bundle.js b/app/assets/javascripts/sidebar/sidebar_bundle.js
index 2b02af87d8a..a9df66748c5 100644
--- a/app/assets/javascripts/sidebar/sidebar_bundle.js
+++ b/app/assets/javascripts/sidebar/sidebar_bundle.js
@@ -5,7 +5,8 @@ import sidebarAssignees from './components/assignees/sidebar_assignees';
import Mediator from './sidebar_mediator';
function domContentLoaded() {
- const mediator = new Mediator(gl.sidebarOptions);
+ const sidebarOptions = JSON.parse(document.querySelector('.js-sidebar-options').innerHTML);
+ const mediator = new Mediator(sidebarOptions);
mediator.fetch();
const sidebarAssigneesEl = document.querySelector('#js-vue-sidebar-assignees');
diff --git a/app/assets/javascripts/snippets_list.js b/app/assets/javascripts/snippets_list.js
deleted file mode 100644
index 3b6d999b1c3..00000000000
--- a/app/assets/javascripts/snippets_list.js
+++ /dev/null
@@ -1,9 +0,0 @@
-function SnippetsList() {
- const $holder = $('.snippets-list-holder');
-
- $holder.find('.pagination').on('ajax:success', (e, data) => {
- $holder.replaceWith(data.html);
- });
-}
-
-window.gl.SnippetsList = SnippetsList;
diff --git a/app/assets/javascripts/todos.js b/app/assets/javascripts/todos.js
index cd305631c10..bba8b5abbb4 100644
--- a/app/assets/javascripts/todos.js
+++ b/app/assets/javascripts/todos.js
@@ -37,10 +37,6 @@ export default class Todos {
this.initFilterDropdown($('.js-type-search'), 'type');
this.initFilterDropdown($('.js-action-search'), 'action_id');
- $('form.filter-form').on('submit', function applyFilters(event) {
- event.preventDefault();
- gl.utils.visitUrl(`${this.action}&${$(this).serialize()}`);
- });
return new UsersSelect();
}
diff --git a/app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js b/app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js
index 72a13108404..fddafb0ddfa 100644
--- a/app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js
+++ b/app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js
@@ -65,7 +65,7 @@ export default class MergeRequestStore {
this.mergeCheckPath = data.merge_check_path;
this.mergeActionsContentPath = data.commit_change_content_path;
this.isRemovingSourceBranch = this.isRemovingSourceBranch || false;
- this.isOpen = data.state === 'opened' || data.state === 'reopened' || false;
+ this.isOpen = data.state === 'opened';
this.hasMergeableDiscussionsState = data.mergeable_discussions_state === false;
this.canRemoveSourceBranch = currentUser.can_remove_source_branch || false;
this.canMerge = !!data.merge_path;
diff --git a/app/assets/stylesheets/framework/avatar.scss b/app/assets/stylesheets/framework/avatar.scss
index 0dfa7a31d31..cb41df8a88d 100644
--- a/app/assets/stylesheets/framework/avatar.scss
+++ b/app/assets/stylesheets/framework/avatar.scss
@@ -88,6 +88,10 @@
overflow: hidden;
display: flex;
+ a {
+ display: flex;
+ }
+
.avatar {
border-radius: 0;
border: none;
diff --git a/app/assets/stylesheets/framework/dropdowns.scss b/app/assets/stylesheets/framework/dropdowns.scss
index 5e410cbf563..3f934403147 100644
--- a/app/assets/stylesheets/framework/dropdowns.scss
+++ b/app/assets/stylesheets/framework/dropdowns.scss
@@ -148,7 +148,6 @@
padding: 5px 8px;
color: $gl-text-color;
line-height: initial;
- text-overflow: ellipsis;
border-radius: 2px;
white-space: nowrap;
overflow: hidden;
@@ -203,11 +202,6 @@
border-radius: $border-radius-base;
box-shadow: 0 2px 4px $dropdown-shadow-color;
- @media (max-width: $screen-sm-min) {
- width: 100%;
- min-width: 180px;
- }
-
&.dropdown-open-left {
right: 0;
left: auto;
@@ -289,6 +283,11 @@
padding: 5px 8px;
color: $gl-text-color-secondary;
}
+
+ .badge + span:not(.badge) {
+ // Expects up to 3 digits on the badge
+ margin-right: 40px;
+ }
}
.droplab-dropdown {
@@ -373,7 +372,6 @@
.dropdown-menu,
.dropdown-menu-nav {
max-width: 280px;
- width: auto;
}
}
diff --git a/app/assets/stylesheets/framework/filters.scss b/app/assets/stylesheets/framework/filters.scss
index 41184907abb..ab2abaca33a 100644
--- a/app/assets/stylesheets/framework/filters.scss
+++ b/app/assets/stylesheets/framework/filters.scss
@@ -393,7 +393,8 @@
@media (max-width: $screen-xs) {
.filter-dropdown-container {
.dropdown-toggle,
- .dropdown {
+ .dropdown,
+ .dropdown-menu {
width: 100%;
}
diff --git a/app/assets/stylesheets/framework/header.scss b/app/assets/stylesheets/framework/header.scss
index 605f4284bb5..df847094864 100644
--- a/app/assets/stylesheets/framework/header.scss
+++ b/app/assets/stylesheets/framework/header.scss
@@ -315,6 +315,10 @@ header {
}
}
+.with-performance-bar header.navbar-gitlab {
+ top: $performance-bar-height;
+}
+
.navbar-nav {
li {
.badge {
diff --git a/app/assets/stylesheets/framework/layout.scss b/app/assets/stylesheets/framework/layout.scss
index 4a9d41b4fda..67c3287ed74 100644
--- a/app/assets/stylesheets/framework/layout.scss
+++ b/app/assets/stylesheets/framework/layout.scss
@@ -120,3 +120,7 @@ of the body element here, we negate cascading side effects but allow momentum sc
.page-with-sidebar {
-webkit-overflow-scrolling: auto;
}
+
+.with-performance-bar .page-with-sidebar {
+ margin-top: $header-height + $performance-bar-height;
+}
diff --git a/app/assets/stylesheets/framework/nav.scss b/app/assets/stylesheets/framework/nav.scss
index 35b4d77a5ab..88e7ba117d5 100644
--- a/app/assets/stylesheets/framework/nav.scss
+++ b/app/assets/stylesheets/framework/nav.scss
@@ -347,6 +347,10 @@
}
}
+.with-performance-bar .layout-nav {
+ margin-top: $header-height + $performance-bar-height;
+}
+
.scrolling-tabs-container {
position: relative;
@@ -441,6 +445,22 @@
}
}
+.with-performance-bar .page-with-layout-nav {
+ .right-sidebar {
+ top: ($header-height + 1) * 2 + $performance-bar-height;
+ }
+
+ &.page-with-sub-nav {
+ .right-sidebar {
+ top: ($header-height + 1) * 3 + $performance-bar-height;
+
+ &.affix {
+ top: $header-height + $performance-bar-height;
+ }
+ }
+ }
+}
+
.nav-block {
&.activities {
border-bottom: 1px solid $border-color;
diff --git a/app/assets/stylesheets/framework/sidebar.scss b/app/assets/stylesheets/framework/sidebar.scss
index 49b2f0e43a4..09b60ad1676 100644
--- a/app/assets/stylesheets/framework/sidebar.scss
+++ b/app/assets/stylesheets/framework/sidebar.scss
@@ -89,6 +89,10 @@
}
}
+.with-performance-bar .right-sidebar.affix {
+ top: $header-height + $performance-bar-height;
+}
+
@mixin maintain-sidebar-dimensions {
display: block;
width: $gutter-width;
diff --git a/app/assets/stylesheets/framework/typography.scss b/app/assets/stylesheets/framework/typography.scss
index befd8133be0..bf5f124d142 100644
--- a/app/assets/stylesheets/framework/typography.scss
+++ b/app/assets/stylesheets/framework/typography.scss
@@ -19,9 +19,9 @@
}
img.js-lazy-loaded {
- min-width: none;
- min-height: none;
- background-color: none;
+ min-width: inherit;
+ min-height: inherit;
+ background-color: inherit;
}
p a:not(.no-attachment-icon) img {
diff --git a/app/assets/stylesheets/framework/variables.scss b/app/assets/stylesheets/framework/variables.scss
index cf0a1ad57d0..0df6f24bfe6 100644
--- a/app/assets/stylesheets/framework/variables.scss
+++ b/app/assets/stylesheets/framework/variables.scss
@@ -204,6 +204,7 @@ $divergence-graph-separator-bg: #ccc;
$general-hover-transition-duration: 100ms;
$general-hover-transition-curve: linear;
$highlight-changes-color: rgb(235, 255, 232);
+$performance-bar-height: 35px;
/*
diff --git a/app/assets/stylesheets/new_sidebar.scss b/app/assets/stylesheets/new_sidebar.scss
index ae43197a1a6..54f3e8d882c 100644
--- a/app/assets/stylesheets/new_sidebar.scss
+++ b/app/assets/stylesheets/new_sidebar.scss
@@ -118,7 +118,7 @@ $new-sidebar-width: 220px;
z-index: 400;
width: $new-sidebar-width;
transition: left $sidebar-transition-duration;
- top: 50px;
+ top: $header-height;
bottom: 0;
left: 0;
overflow: auto;
@@ -163,6 +163,10 @@ $new-sidebar-width: 220px;
}
}
+.with-performance-bar .nav-sidebar {
+ top: $header-height + $performance-bar-height;
+}
+
.sidebar-sub-level-items {
display: none;
padding-bottom: 8px;
@@ -260,7 +264,7 @@ $new-sidebar-width: 220px;
// Make issue boards full-height now that sub-nav is gone
.boards-list {
- height: calc(100vh - 50px);
+ height: calc(100vh - #{$header-height});
@media (min-width: $screen-sm-min) {
height: 475px; // Needed for PhantomJS
@@ -270,6 +274,10 @@ $new-sidebar-width: 220px;
}
}
+.with-performance-bar .boards-list {
+ height: calc(100vh - #{$header-height} - #{$performance-bar-height});
+}
+
// Change color of all horizontal tabs to match the new indigo color
.nav-links li.active a {
diff --git a/app/assets/stylesheets/pages/builds.scss b/app/assets/stylesheets/pages/builds.scss
index b6fc628c02b..acf3719e9d2 100644
--- a/app/assets/stylesheets/pages/builds.scss
+++ b/app/assets/stylesheets/pages/builds.scss
@@ -64,10 +64,10 @@
color: $gl-text-color;
position: sticky;
position: -webkit-sticky;
- top: 50px;
+ top: $header-height;
&.affix {
- top: 50px;
+ top: $header-height;
}
// with sidebar
@@ -86,6 +86,7 @@
position: absolute;
right: 0;
left: 0;
+ top: 0;
}
.truncated-info {
@@ -171,6 +172,16 @@
}
}
+.with-performance-bar .build-page {
+ .top-bar {
+ top: $header-height + $performance-bar-height;
+
+ &.affix {
+ top: $header-height + $performance-bar-height;
+ }
+ }
+}
+
.build-header {
.ci-header-container,
.header-action-buttons {
diff --git a/app/assets/stylesheets/pages/issuable.scss b/app/assets/stylesheets/pages/issuable.scss
index eb269df46fe..6da14320914 100644
--- a/app/assets/stylesheets/pages/issuable.scss
+++ b/app/assets/stylesheets/pages/issuable.scss
@@ -445,6 +445,14 @@
}
}
+.with-performance-bar .right-sidebar {
+ top: $header-height + $performance-bar-height;
+
+ .issuable-sidebar {
+ height: calc(100% - #{$header-height} - #{$performance-bar-height});
+ }
+}
+
.detail-page-description {
padding: 16px 0;
diff --git a/app/assets/stylesheets/pages/merge_requests.scss b/app/assets/stylesheets/pages/merge_requests.scss
index 2db967547dd..4693b2434c7 100644
--- a/app/assets/stylesheets/pages/merge_requests.scss
+++ b/app/assets/stylesheets/pages/merge_requests.scss
@@ -759,6 +759,10 @@
}
}
+.with-performance-bar .merge-request-tabs-holder {
+ top: $header-height + $performance-bar-height;
+}
+
.merge-request-tabs {
display: flex;
margin-bottom: 0;
diff --git a/app/assets/stylesheets/pages/projects.scss b/app/assets/stylesheets/pages/projects.scss
index a3e07a36c33..b3a90dff89a 100644
--- a/app/assets/stylesheets/pages/projects.scss
+++ b/app/assets/stylesheets/pages/projects.scss
@@ -707,6 +707,7 @@ pre.light-well {
background-color: transparent;
border: 0;
text-align: left;
+ text-overflow: ellipsis;
}
.protected-branches-list,
diff --git a/app/assets/stylesheets/performance_bar.scss b/app/assets/stylesheets/performance_bar.scss
index 2890b6b1e49..6e539e39ca1 100644
--- a/app/assets/stylesheets/performance_bar.scss
+++ b/app/assets/stylesheets/performance_bar.scss
@@ -3,9 +3,16 @@
@import "peek/views/rblineprof";
#peek {
- height: 35px;
+ position: fixed;
+ left: 0;
+ top: 0;
+ width: 100%;
+ z-index: 2000;
+ overflow-x: hidden;
+
+ height: $performance-bar-height;
background: $black;
- line-height: 35px;
+ line-height: $performance-bar-height;
color: $perf-bar-text;
&.disabled {
@@ -25,7 +32,8 @@
}
.wrapper {
- width: 1000px;
+ width: 80%;
+ height: $performance-bar-height;
margin: 0 auto;
}
diff --git a/app/controllers/concerns/notes_actions.rb b/app/controllers/concerns/notes_actions.rb
index a57d9e6e6c0..af5f683bab5 100644
--- a/app/controllers/concerns/notes_actions.rb
+++ b/app/controllers/concerns/notes_actions.rb
@@ -4,6 +4,7 @@ module NotesActions
included do
before_action :authorize_admin_note!, only: [:update, :destroy]
+ before_action :note_project, only: [:create]
end
def index
@@ -28,7 +29,8 @@ module NotesActions
merge_request_diff_head_sha: params[:merge_request_diff_head_sha],
in_reply_to_discussion_id: params[:in_reply_to_discussion_id]
)
- @note = Notes::CreateService.new(project, current_user, create_params).execute
+
+ @note = Notes::CreateService.new(note_project, current_user, create_params).execute
if @note.is_a?(Note)
Banzai::NoteRenderer.render([@note], @project, current_user)
@@ -177,4 +179,22 @@ module NotesActions
def notes_finder
@notes_finder ||= NotesFinder.new(project, current_user, finder_params)
end
+
+ def note_project
+ return @note_project if defined?(@note_project)
+ return nil unless project
+
+ note_project_id = params[:note_project_id]
+
+ @note_project =
+ if note_project_id.present?
+ Project.find(note_project_id)
+ else
+ project
+ end
+
+ return access_denied! unless can?(current_user, :create_note, @note_project)
+
+ @note_project
+ end
end
diff --git a/app/controllers/projects/branches_controller.rb b/app/controllers/projects/branches_controller.rb
index 86058531179..747768eefb1 100644
--- a/app/controllers/projects/branches_controller.rb
+++ b/app/controllers/projects/branches_controller.rb
@@ -8,7 +8,7 @@ class Projects::BranchesController < Projects::ApplicationController
before_action :authorize_push_code!, only: [:new, :create, :destroy, :destroy_all_merged]
def index
- @sort = params[:sort].presence || sort_value_name
+ @sort = params[:sort].presence || sort_value_recently_updated
@branches = BranchesFinder.new(@repository, params).execute
@branches = Kaminari.paginate_array(@branches).page(params[:page])
diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb
index 69513f4dadc..9e743685d60 100644
--- a/app/controllers/sessions_controller.rb
+++ b/app/controllers/sessions_controller.rb
@@ -23,12 +23,7 @@ class SessionsController < Devise::SessionsController
def new
set_minimum_password_length
- @ldap_servers =
- if Gitlab.config.ldap.enabled
- Gitlab::LDAP::Config.servers
- else
- []
- end
+ @ldap_servers = Gitlab::LDAP::Config.available_servers
super
end
diff --git a/app/finders/issuable_finder.rb b/app/finders/issuable_finder.rb
index 6fe17a2b99d..08a843ada97 100644
--- a/app/finders/issuable_finder.rb
+++ b/app/finders/issuable_finder.rb
@@ -81,7 +81,6 @@ class IssuableFinder
end
counts[:all] = counts.values.sum
- counts[:opened] += counts[:reopened]
counts
end
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index 1c165700b19..14dc9bd9d62 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -264,7 +264,11 @@ module ApplicationHelper
end
def page_class
- "issue-boards-page" if current_controller?(:boards)
+ class_names = []
+ class_names << 'issue-boards-page' if current_controller?(:boards)
+ class_names << 'with-performance-bar' if performance_bar_enabled?
+
+ class_names
end
# Returns active css class when condition returns true
diff --git a/app/helpers/diff_helper.rb b/app/helpers/diff_helper.rb
index 926502bf239..91ddd73fac1 100644
--- a/app/helpers/diff_helper.rb
+++ b/app/helpers/diff_helper.rb
@@ -15,7 +15,7 @@ module DiffHelper
def diff_view
@diff_view ||= begin
diff_views = %w(inline parallel)
- diff_view = cookies[:diff_view]
+ diff_view = params[:view] || cookies[:diff_view]
diff_view = diff_views.first unless diff_views.include?(diff_view)
diff_view.to_sym
end
diff --git a/app/helpers/issuables_helper.rb b/app/helpers/issuables_helper.rb
index 425af547330..f4fad7150e8 100644
--- a/app/helpers/issuables_helper.rb
+++ b/app/helpers/issuables_helper.rb
@@ -354,4 +354,14 @@ module IssuablesHelper
params[:format] = :json if issuable.is_a?(Issue)
end
end
+
+ def issuable_sidebar_options(issuable, can_edit_issuable)
+ {
+ endpoint: "#{issuable_json_path(issuable)}?basic=true",
+ editable: can_edit_issuable,
+ currentUser: current_user.as_json(only: [:username, :id, :name], methods: :avatar_url),
+ rootPath: root_path,
+ fullPath: @project.full_path
+ }
+ end
end
diff --git a/app/helpers/nav_helper.rb b/app/helpers/nav_helper.rb
index b769462abc2..b1205b8529b 100644
--- a/app/helpers/nav_helper.rb
+++ b/app/helpers/nav_helper.rb
@@ -1,38 +1,49 @@
module NavHelper
+ def page_with_sidebar_class
+ class_name = page_gutter_class
+ class_name << 'page-with-new-sidebar' if defined?(@new_sidebar) && @new_sidebar
+
+ class_name
+ end
+
def page_gutter_class
if current_path?('merge_requests#show') ||
current_path?('projects/merge_requests/conflicts#show') ||
current_path?('issues#show') ||
current_path?('milestones#show')
if cookies[:collapsed_gutter] == 'true'
- "page-gutter right-sidebar-collapsed"
+ %w[page-gutter right-sidebar-collapsed]
else
- "page-gutter right-sidebar-expanded"
+ %w[page-gutter right-sidebar-expanded]
end
elsif current_path?('jobs#show')
- "page-gutter build-sidebar right-sidebar-expanded"
+ %w[page-gutter build-sidebar right-sidebar-expanded]
elsif current_path?('wikis#show') ||
current_path?('wikis#edit') ||
current_path?('wikis#update') ||
current_path?('wikis#history') ||
current_path?('wikis#git_access')
- "page-gutter wiki-sidebar right-sidebar-expanded"
+ %w[page-gutter wiki-sidebar right-sidebar-expanded]
+ else
+ []
end
end
def nav_header_class
- class_name = ''
- class_name << " with-horizontal-nav" if defined?(nav) && nav
+ class_names = []
+ class_names << 'with-horizontal-nav' if defined?(nav) && nav
- class_name
+ class_names
end
def layout_nav_class
- class_name = ''
- class_name << " page-with-layout-nav" if defined?(nav) && nav
- class_name << " page-with-sub-nav" if content_for?(:sub_nav)
+ return [] if show_new_nav?
- class_name
+ class_names = []
+ class_names << 'page-with-layout-nav' if defined?(nav) && nav
+ class_names << 'page-with-sub-nav' if content_for?(:sub_nav)
+
+ class_names
end
def nav_control_class
diff --git a/app/helpers/notes_helper.rb b/app/helpers/notes_helper.rb
index 0a0881d95cf..e857e837c16 100644
--- a/app/helpers/notes_helper.rb
+++ b/app/helpers/notes_helper.rb
@@ -62,7 +62,11 @@ module NotesHelper
def link_to_reply_discussion(discussion, line_type = nil)
return unless current_user
- data = { discussion_id: discussion.reply_id, line_type: line_type }
+ data = {
+ discussion_id: discussion.reply_id,
+ discussion_project_id: discussion.project&.id,
+ line_type: line_type
+ }
button_tag 'Reply...', class: 'btn btn-text-field js-discussion-reply-button',
data: data, title: 'Add a reply'
@@ -130,4 +134,14 @@ module NotesHelper
can?(current_user, :create_note, @project)
end
end
+
+ def initial_notes_data(autocomplete)
+ {
+ notesUrl: notes_url,
+ notesIds: @notes.map(&:id),
+ now: Time.now.to_i,
+ diffView: diff_view,
+ autocomplete: autocomplete
+ }
+ end
end
diff --git a/app/helpers/webpack_helper.rb b/app/helpers/webpack_helper.rb
index 0386df22374..33453dd178f 100644
--- a/app/helpers/webpack_helper.rb
+++ b/app/helpers/webpack_helper.rb
@@ -34,6 +34,8 @@ module WebpackHelper
end
def webpack_public_path
- "#{webpack_public_host}/#{Rails.application.config.webpack.public_path}/"
+ relative_path = Rails.application.config.relative_url_root
+ webpack_path = Rails.application.config.webpack.public_path
+ File.join(webpack_public_host.to_s, relative_path.to_s, webpack_path.to_s, '')
end
end
diff --git a/app/models/chat_team.rb b/app/models/chat_team.rb
index c52b6f15913..25ecf2d5937 100644
--- a/app/models/chat_team.rb
+++ b/app/models/chat_team.rb
@@ -3,4 +3,13 @@ class ChatTeam < ActiveRecord::Base
validates :namespace, uniqueness: true
belongs_to :namespace
+
+ def remove_mattermost_team(current_user)
+ Mattermost::Team.new(current_user).destroy(team_id: team_id)
+ rescue Mattermost::ClientError => e
+ # Either the group is not found, or the user doesn't have the proper
+ # access on the mattermost instance. In the first case, we're done either way
+ # in the latter case, we can't recover by retrying, so we just log what happened
+ Rails.logger.error("Mattermost team deletion failed: #{e}")
+ end
end
diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb
index 416a2a33378..8be2dee6479 100644
--- a/app/models/ci/build.rb
+++ b/app/models/ci/build.rb
@@ -219,6 +219,7 @@ module Ci
variables += project.group.secret_variables_for(ref, project).map(&:to_runner_variable) if project.group
variables += secret_variables(environment: environment)
variables += trigger_request.user_variables if trigger_request
+ variables += pipeline.variables.map(&:to_runner_variable)
variables += pipeline.pipeline_schedule.job_variables if pipeline.pipeline_schedule
variables += persisted_environment_variables if environment
diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb
index e5b615a7cc0..d2abcf30034 100644
--- a/app/models/ci/pipeline.rb
+++ b/app/models/ci/pipeline.rb
@@ -15,6 +15,7 @@ module Ci
has_many :statuses, class_name: 'CommitStatus', foreign_key: :commit_id
has_many :builds, foreign_key: :commit_id
has_many :trigger_requests, dependent: :destroy, foreign_key: :commit_id # rubocop:disable Cop/ActiveRecordDependent
+ has_many :variables, class_name: 'Ci::PipelineVariable'
# Merge requests for which the current pipeline is running against
# the merge request's latest commit.
diff --git a/app/models/ci/pipeline_variable.rb b/app/models/ci/pipeline_variable.rb
new file mode 100644
index 00000000000..00b419c3efa
--- /dev/null
+++ b/app/models/ci/pipeline_variable.rb
@@ -0,0 +1,10 @@
+module Ci
+ class PipelineVariable < ActiveRecord::Base
+ extend Ci::Model
+ include HasVariable
+
+ belongs_to :pipeline
+
+ validates :key, uniqueness: { scope: :pipeline_id }
+ end
+end
diff --git a/app/models/concerns/issuable.rb b/app/models/concerns/issuable.rb
index 13fe9d09c69..935ffe343ff 100644
--- a/app/models/concerns/issuable.rb
+++ b/app/models/concerns/issuable.rb
@@ -71,9 +71,8 @@ module Issuable
scope :of_projects, ->(ids) { where(project_id: ids) }
scope :of_milestones, ->(ids) { where(milestone_id: ids) }
scope :with_milestone, ->(title) { left_joins_milestones.where(milestones: { title: title }) }
- scope :opened, -> { with_state(:opened, :reopened) }
+ scope :opened, -> { with_state(:opened) }
scope :only_opened, -> { with_state(:opened) }
- scope :only_reopened, -> { with_state(:reopened) }
scope :closed, -> { with_state(:closed) }
scope :left_joins_milestones, -> { joins("LEFT OUTER JOIN milestones ON #{table_name}.milestone_id = milestones.id") }
@@ -234,7 +233,7 @@ module Issuable
end
def open?
- opened? || reopened?
+ opened?
end
def user_notes_count
diff --git a/app/models/issue.rb b/app/models/issue.rb
index 400bb55d2f0..1c948c8957e 100644
--- a/app/models/issue.rb
+++ b/app/models/issue.rb
@@ -62,15 +62,14 @@ class Issue < ActiveRecord::Base
state_machine :state, initial: :opened do
event :close do
- transition [:reopened, :opened] => :closed
+ transition [:opened] => :closed
end
event :reopen do
- transition closed: :reopened
+ transition closed: :opened
end
state :opened
- state :reopened
state :closed
before_transition any => :closed do |issue|
diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb
index a910099b4c1..81e0776e79c 100644
--- a/app/models/merge_request.rb
+++ b/app/models/merge_request.rb
@@ -42,23 +42,23 @@ class MergeRequest < ActiveRecord::Base
state_machine :state, initial: :opened do
event :close do
- transition [:reopened, :opened] => :closed
+ transition [:opened] => :closed
end
event :mark_as_merged do
- transition [:reopened, :opened, :locked] => :merged
+ transition [:opened, :locked] => :merged
end
event :reopen do
- transition closed: :reopened
+ transition closed: :opened
end
event :lock_mr do
- transition [:reopened, :opened] => :locked
+ transition [:opened] => :locked
end
event :unlock_mr do
- transition locked: :reopened
+ transition locked: :opened
end
after_transition any => :locked do |merge_request, transition|
@@ -72,7 +72,6 @@ class MergeRequest < ActiveRecord::Base
end
state :opened
- state :reopened
state :closed
state :merged
state :locked
@@ -368,7 +367,7 @@ class MergeRequest < ActiveRecord::Base
errors.add :branch_conflict, "You can not use same project/branch for source and target"
end
- if opened? || reopened?
+ if opened?
similar_mrs = self.target_project.merge_requests.where(source_branch: source_branch, target_branch: target_branch, source_project_id: source_project.try(:id)).opened
similar_mrs = similar_mrs.where('id not in (?)', self.id) if self.id
if similar_mrs.any?
diff --git a/app/models/project_services/drone_ci_service.rb b/app/models/project_services/drone_ci_service.rb
index f6cade9c290..c93f1632652 100644
--- a/app/models/project_services/drone_ci_service.rb
+++ b/app/models/project_services/drone_ci_service.rb
@@ -114,7 +114,7 @@ class DroneCiService < CiService
end
def merge_request_valid?(data)
- %w(opened reopened).include?(data[:object_attributes][:state]) &&
+ data[:object_attributes][:state] == 'opened' &&
data[:object_attributes][:merge_status] == 'unchecked'
end
end
diff --git a/app/services/ci/create_pipeline_service.rb b/app/services/ci/create_pipeline_service.rb
index 21e2ef153de..884b681ff81 100644
--- a/app/services/ci/create_pipeline_service.rb
+++ b/app/services/ci/create_pipeline_service.rb
@@ -21,14 +21,22 @@ module Ci
return result if result
- Ci::Pipeline.transaction do
- update_merge_requests_head_pipeline if pipeline.save
+ begin
+ Ci::Pipeline.transaction do
+ pipeline.save!
- Ci::CreatePipelineStagesService
- .new(project, current_user)
- .execute(pipeline)
+ yield(pipeline) if block_given?
+
+ Ci::CreatePipelineStagesService
+ .new(project, current_user)
+ .execute(pipeline)
+ end
+ rescue ActiveRecord::RecordInvalid => e
+ return error("Failed to persist the pipeline: #{e}")
end
+ update_merge_requests_head_pipeline
+
cancel_pending_pipelines if project.auto_cancel_pending_pipelines?
pipeline_created_counter.increment(source: source)
diff --git a/app/services/ci/create_trigger_request_service.rb b/app/services/ci/create_trigger_request_service.rb
index a43d0e4593c..b2aa457bbd5 100644
--- a/app/services/ci/create_trigger_request_service.rb
+++ b/app/services/ci/create_trigger_request_service.rb
@@ -1,3 +1,8 @@
+# This class is deprecated because we're closing Ci::TriggerRequest.
+# New class is PipelineTriggerService (app/services/ci/pipeline_trigger_service.rb)
+# which is integrated with Ci::PipelineVariable instaed of Ci::TriggerRequest.
+# We remove this class after we removed v1 and v3 API. This class is still being
+# referred by such legacy code.
module Ci
module CreateTriggerRequestService
Result = Struct.new(:trigger_request, :pipeline)
diff --git a/app/services/ci/pipeline_trigger_service.rb b/app/services/ci/pipeline_trigger_service.rb
new file mode 100644
index 00000000000..1e5ad28ba57
--- /dev/null
+++ b/app/services/ci/pipeline_trigger_service.rb
@@ -0,0 +1,44 @@
+module Ci
+ class PipelineTriggerService < BaseService
+ def execute
+ if trigger_from_token
+ create_pipeline_from_trigger(trigger_from_token)
+ end
+ end
+
+ private
+
+ def create_pipeline_from_trigger(trigger)
+ # this check is to not leak the presence of the project if user cannot read it
+ return unless trigger.project == project
+
+ pipeline = Ci::CreatePipelineService.new(project, trigger.owner, ref: params[:ref])
+ .execute(:trigger, ignore_skip_ci: true) do |pipeline|
+ trigger.trigger_requests.create!(pipeline: pipeline)
+ create_pipeline_variables!(pipeline)
+ end
+
+ if pipeline.persisted?
+ success(pipeline: pipeline)
+ else
+ error(pipeline.errors.messages, 400)
+ end
+ end
+
+ def trigger_from_token
+ return @trigger if defined?(@trigger)
+
+ @trigger = Ci::Trigger.find_by_token(params[:token].to_s)
+ end
+
+ def create_pipeline_variables!(pipeline)
+ return unless params[:variables]
+
+ variables = params[:variables].map do |key, value|
+ { key: key, value: value }
+ end
+
+ pipeline.variables.create!(variables)
+ end
+ end
+end
diff --git a/app/services/git_push_service.rb b/app/services/git_push_service.rb
index bb7680c5054..ada2b64a3a6 100644
--- a/app/services/git_push_service.rb
+++ b/app/services/git_push_service.rb
@@ -45,6 +45,7 @@ class GitPushService < BaseService
elsif push_to_existing_branch?
# Collect data for this git push
@push_commits = @project.repository.commits_between(params[:oldrev], params[:newrev])
+
process_commit_messages
# Update the bare repositories info/attributes file using the contents of the default branches
@@ -66,15 +67,21 @@ class GitPushService < BaseService
def update_caches
if is_default_branch?
- paths = Set.new
+ if push_to_new_branch?
+ # If this is the initial push into the default branch, the file type caches
+ # will already be reset as a result of `Project#change_head`.
+ types = []
+ else
+ paths = Set.new
- @push_commits.each do |commit|
- commit.raw_deltas.each do |diff|
- paths << diff.new_path
+ @push_commits.last(PROCESS_COMMIT_LIMIT).each do |commit|
+ commit.raw_deltas.each do |diff|
+ paths << diff.new_path
+ end
end
- end
- types = Gitlab::FileDetector.types_in_paths(paths.to_a)
+ types = Gitlab::FileDetector.types_in_paths(paths.to_a)
+ end
else
types = []
end
@@ -92,7 +99,7 @@ class GitPushService < BaseService
def process_commit_messages
default = is_default_branch?
- push_commits.last(PROCESS_COMMIT_LIMIT).each do |commit|
+ @push_commits.last(PROCESS_COMMIT_LIMIT).each do |commit|
if commit.matches_cross_reference_regex?
ProcessCommitWorker
.perform_async(project.id, current_user.id, commit.to_hash, default)
@@ -111,7 +118,7 @@ class GitPushService < BaseService
EventCreateService.new.push(@project, current_user, build_push_data)
Ci::CreatePipelineService.new(@project, current_user, build_push_data).execute(:push)
-
+
SystemHookPushWorker.perform_async(build_push_data.dup, :push_hooks)
@project.execute_hooks(build_push_data.dup, :push_hooks)
@project.execute_services(build_push_data.dup, :push_hooks)
@@ -131,7 +138,10 @@ class GitPushService < BaseService
end
def process_default_branch
- @push_commits = project.repository.commits(params[:newrev])
+ @push_commits_count = project.repository.commit_count_for_ref(params[:ref])
+
+ offset = [@push_commits_count - PROCESS_COMMIT_LIMIT, 0].max
+ @push_commits = project.repository.commits(params[:newrev], offset: offset, limit: PROCESS_COMMIT_LIMIT)
# Ensure HEAD points to the default branch in case it is not master
project.change_head(branch_name)
@@ -160,7 +170,8 @@ class GitPushService < BaseService
params[:oldrev],
params[:newrev],
params[:ref],
- push_commits)
+ @push_commits,
+ commits_count: @push_commits_count)
end
def push_to_existing_branch?
diff --git a/app/services/groups/destroy_service.rb b/app/services/groups/destroy_service.rb
index 80c51cb5a72..f565612a89d 100644
--- a/app/services/groups/destroy_service.rb
+++ b/app/services/groups/destroy_service.rb
@@ -21,6 +21,8 @@ module Groups
DestroyService.new(group, current_user).execute
end
+ group.chat_team&.remove_mattermost_team(current_user)
+
group.really_destroy!
end
end
diff --git a/app/services/issues/reopen_service.rb b/app/services/issues/reopen_service.rb
index 73b2e85cba3..35de4337b15 100644
--- a/app/services/issues/reopen_service.rb
+++ b/app/services/issues/reopen_service.rb
@@ -5,7 +5,7 @@ module Issues
if issue.reopen
event_service.reopen_issue(issue, current_user)
- create_note(issue)
+ create_note(issue, 'reopened')
notification_service.reopen_issue(issue, current_user)
execute_hooks(issue, 'reopen')
invalidate_cache_counts(issue, users: issue.assignees)
@@ -16,8 +16,8 @@ module Issues
private
- def create_note(issue)
- SystemNoteService.change_status(issue, issue.project, current_user, issue.state, nil)
+ def create_note(issue, state = issue.state)
+ SystemNoteService.change_status(issue, issue.project, current_user, state, nil)
end
end
end
diff --git a/app/services/merge_requests/base_service.rb b/app/services/merge_requests/base_service.rb
index 3542a41ac83..35ccff26262 100644
--- a/app/services/merge_requests/base_service.rb
+++ b/app/services/merge_requests/base_service.rb
@@ -1,7 +1,7 @@
module MergeRequests
class BaseService < ::IssuableBaseService
- def create_note(merge_request)
- SystemNoteService.change_status(merge_request, merge_request.target_project, current_user, merge_request.state, nil)
+ def create_note(merge_request, state = merge_request.state)
+ SystemNoteService.change_status(merge_request, merge_request.target_project, current_user, state, nil)
end
def create_title_change_note(issuable, old_title)
@@ -44,7 +44,7 @@ module MergeRequests
end
# Returns all origin and fork merge requests from `@project` satisfying passed arguments.
- def merge_requests_for(source_branch, mr_states: [:opened, :reopened])
+ def merge_requests_for(source_branch, mr_states: [:opened])
MergeRequest
.with_state(mr_states)
.where(source_branch: source_branch, source_project_id: @project.id)
diff --git a/app/services/merge_requests/reopen_service.rb b/app/services/merge_requests/reopen_service.rb
index 52f6d511f98..b9c65be36ec 100644
--- a/app/services/merge_requests/reopen_service.rb
+++ b/app/services/merge_requests/reopen_service.rb
@@ -5,7 +5,7 @@ module MergeRequests
if merge_request.reopen
event_service.reopen_mr(merge_request, current_user)
- create_note(merge_request)
+ create_note(merge_request, 'reopened')
notification_service.reopen_mr(merge_request, current_user)
execute_hooks(merge_request, 'reopen')
merge_request.reload_diff(current_user)
diff --git a/app/services/web_hook_service.rb b/app/services/web_hook_service.rb
index a5110a23cad..27c3ba197ac 100644
--- a/app/services/web_hook_service.rb
+++ b/app/services/web_hook_service.rb
@@ -44,7 +44,7 @@ class WebHookService
http_status: response.code,
message: response.to_s
}
- rescue SocketError, OpenSSL::SSL::SSLError, Errno::ECONNRESET, Errno::ECONNREFUSED, Net::OpenTimeout => e
+ rescue SocketError, OpenSSL::SSL::SSLError, Errno::ECONNRESET, Errno::ECONNREFUSED, Errno::EHOSTUNREACH, Net::OpenTimeout, Net::ReadTimeout => e
log_execution(
trigger: hook_name,
url: hook.url,
diff --git a/app/views/layouts/_page.html.haml b/app/views/layouts/_page.html.haml
index 873220cc73d..c4f8cd71395 100644
--- a/app/views/layouts/_page.html.haml
+++ b/app/views/layouts/_page.html.haml
@@ -1,4 +1,4 @@
-.page-with-sidebar{ class: "#{('page-with-new-sidebar' if defined?(@new_sidebar) && @new_sidebar)} #{page_gutter_class}" }
+.page-with-sidebar{ class: page_with_sidebar_class }
- if show_new_nav?
- if defined?(nav) && nav
= render "layouts/nav/#{nav}"
@@ -9,7 +9,7 @@
= render "layouts/nav/#{nav}"
- if content_for?(:sub_nav)
= yield :sub_nav
- .content-wrapper{ class: "#{(layout_nav_class unless show_new_nav?)}" }
+ .content-wrapper{ class: layout_nav_class }
- if show_new_nav?
.mobile-overlay
.alert-wrapper
diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml
index 38b95d11fd4..b53f382fa3d 100644
--- a/app/views/layouts/application.html.haml
+++ b/app/views/layouts/application.html.haml
@@ -1,8 +1,9 @@
!!! 5
-%html{ lang: I18n.locale, class: "#{page_class}" }
+%html{ lang: I18n.locale, class: page_class }
= render "layouts/head"
%body{ class: @body_class, data: { page: body_data_page, project: "#{@project.path if @project}", group: "#{@group.path if @group}", find_file: find_file_path } }
= render "layouts/init_auto_complete" if @gfm_form
+ = render 'peek/bar'
- if show_new_nav?
= render "layouts/header/new"
- else
@@ -10,5 +11,3 @@
= render 'layouts/page', sidebar: sidebar, nav: nav
= yield :scripts_body
-
- = render 'peek/bar'
diff --git a/app/views/layouts/help.html.haml b/app/views/layouts/help.html.haml
index 224b24befbe..78927bfffcd 100644
--- a/app/views/layouts/help.html.haml
+++ b/app/views/layouts/help.html.haml
@@ -1,3 +1,4 @@
+- @breadcrumb_title = "Help"
- page_title "Help"
- header_title "Help", help_path
diff --git a/app/views/peek/views/_host.html.haml b/app/views/peek/views/_host.html.haml
new file mode 100644
index 00000000000..40769b5c6f6
--- /dev/null
+++ b/app/views/peek/views/_host.html.haml
@@ -0,0 +1,2 @@
+%span.current-host
+ = truncate(view.hostname)
diff --git a/app/views/projects/new.html.haml b/app/views/projects/new.html.haml
index 87cc23fc649..25109f0f414 100644
--- a/app/views/projects/new.html.haml
+++ b/app/views/projects/new.html.haml
@@ -4,6 +4,8 @@
- page_title 'New Project'
- header_title "Projects", dashboard_projects_path
- visibility_level = params.dig(:project, :visibility_level) || default_project_visibility
+- content_for :page_specific_javascripts do
+ = webpack_bundle_tag 'project_new'
.project-edit-container
.project-edit-errors
@@ -111,46 +113,3 @@
%i.fa.fa-spinner.fa-spin
Creating project &amp; repository.
%p Please wait a moment, this page will automatically refresh when ready.
-
-:javascript
- var importBtnTooltip = "Please enter a valid project name.";
- var $importBtnWrapper = $('.import_gitlab_project');
-
- $('.how_to_import_link').bind('click', function (e) {
- e.preventDefault();
- var import_modal = $(this).next(".modal").show();
- });
-
- $('.modal-header .close').bind('click', function() {
- $(".modal").hide();
- });
-
- $('.btn_import_gitlab_project').bind('click', function() {
- var _href = $("a.btn_import_gitlab_project").attr("href");
- $(".btn_import_gitlab_project").attr("href", _href + '?namespace_id=' + $("#project_namespace_id").val() + '&path=' + $("#project_path").val());
- });
-
- $('.btn_import_gitlab_project').attr('disabled', $('#project_path').val().trim().length === 0);
- $importBtnWrapper.attr('title', importBtnTooltip);
-
- $('#new_project').submit(function(){
- var $path = $('#project_path');
- $path.val($path.val().trim());
- });
-
- $('#project_path').keyup(function(){
- if($(this).val().trim().length !== 0) {
- $('.btn_import_gitlab_project').attr('disabled', false);
- $importBtnWrapper.attr('title','');
- $importBtnWrapper.removeClass('has-tooltip');
- } else {
- $('.btn_import_gitlab_project').attr('disabled',true);
- $importBtnWrapper.addClass('has-tooltip');
- }
- });
-
- $('#project_import_url').disable();
- $('.import_git').click(function( event ) {
- $projectImportUrl = $('#project_import_url');
- $projectImportUrl.attr('disabled', !$projectImportUrl.attr('disabled'));
- });
diff --git a/app/views/projects/pipelines/charts/_pipeline_times.haml b/app/views/projects/pipelines/charts/_pipeline_times.haml
index 1292f580a81..a5dbd1b1532 100644
--- a/app/views/projects/pipelines/charts/_pipeline_times.haml
+++ b/app/views/projects/pipelines/charts/_pipeline_times.haml
@@ -1,27 +1,10 @@
+- content_for :page_specific_javascripts do
+ = webpack_bundle_tag('pipelines_times')
+
%div
%p.light
= _("Commit duration in minutes for last 30 commits")
%canvas#build_timesChart{ height: 200 }
-:javascript
- var data = {
- labels : #{@charts[:pipeline_times].labels.to_json},
- datasets : [
- {
- fillColor : "rgba(220,220,220,0.5)",
- strokeColor : "rgba(220,220,220,1)",
- barStrokeWidth: 1,
- barValueSpacing: 1,
- barDatasetSpacing: 1,
- data : #{@charts[:pipeline_times].pipeline_times.to_json}
- }
- ]
- }
- var ctx = $("#build_timesChart").get(0).getContext("2d");
- var options = { scaleOverlay: true, responsive: true, maintainAspectRatio: false };
- if (window.innerWidth < 768) {
- // Scale fonts if window width lower than 768px (iPad portrait)
- options.scaleFontSize = 8
- }
- new Chart(ctx).Bar(data, options);
+%script#pipelinesTimesChartsData{ type: "application/json" }= { :labels => @charts[:pipeline_times].labels, :values => @charts[:pipeline_times].pipeline_times }.to_json.html_safe
diff --git a/app/views/projects/pipelines/charts/_pipelines.haml b/app/views/projects/pipelines/charts/_pipelines.haml
index be884448087..02f1ef4b6da 100644
--- a/app/views/projects/pipelines/charts/_pipelines.haml
+++ b/app/views/projects/pipelines/charts/_pipelines.haml
@@ -1,3 +1,6 @@
+- content_for :page_specific_javascripts do
+ = webpack_bundle_tag('pipelines_charts')
+
%h4= _("Pipelines charts")
%p
&nbsp;
@@ -26,31 +29,8 @@
= _("Jobs for last year")
%canvas#yearChart.padded{ height: 250 }
-- [:week, :month, :year].each do |scope|
- :javascript
- var data = {
- labels : #{@charts[scope].labels.to_json},
- datasets : [
- {
- fillColor : "#7f8fa4",
- strokeColor : "#7f8fa4",
- pointColor : "#7f8fa4",
- pointStrokeColor : "#EEE",
- data : #{@charts[scope].total.to_json}
- },
- {
- fillColor : "#44aa22",
- strokeColor : "#44aa22",
- pointColor : "#44aa22",
- pointStrokeColor : "#fff",
- data : #{@charts[scope].success.to_json}
- }
- ]
- }
- var ctx = $("##{scope}Chart").get(0).getContext("2d");
- var options = { scaleOverlay: true, responsive: true, maintainAspectRatio: false };
- if (window.innerWidth < 768) {
- // Scale fonts if window width lower than 768px (iPad portrait)
- options.scaleFontSize = 8
- }
- new Chart(ctx).Line(data, options);
+%script#pipelinesChartsData{ type: "application/json" }
+ - chartData = []
+ - [:week, :month, :year].each do |scope|
+ - chartData.push({ 'scope' => scope, 'labels' => @charts[scope].labels, 'totalValues' => @charts[scope].total, 'successValues' => @charts[scope].success })
+ = chartData.to_json.html_safe
diff --git a/app/views/projects/pipelines/new.html.haml b/app/views/projects/pipelines/new.html.haml
index c966df62856..4ad37d0e882 100644
--- a/app/views/projects/pipelines/new.html.haml
+++ b/app/views/projects/pipelines/new.html.haml
@@ -20,7 +20,4 @@
= f.submit 'Create pipeline', class: 'btn btn-create', tabindex: 3
= link_to 'Cancel', project_pipelines_path(@project), class: 'btn btn-cancel'
-:javascript
- var availableRefs = #{@project.repository.ref_names.to_json};
-
- new NewBranchForm($('.js-new-pipeline-form'), availableRefs)
+%script#availableRefs{ type: "application/json" }= @project.repository.ref_names.to_json.html_safe
diff --git a/app/views/projects/tags/new.html.haml b/app/views/projects/tags/new.html.haml
index f1bbaf40387..521b4d927bc 100644
--- a/app/views/projects/tags/new.html.haml
+++ b/app/views/projects/tags/new.html.haml
@@ -40,7 +40,4 @@
.form-actions
= button_tag 'Create tag', class: 'btn btn-create', tabindex: 3
= link_to 'Cancel', project_tags_path(@project), class: 'btn btn-cancel'
-
-:javascript
- window.gl = window.gl || { };
- window.gl.availableRefs = #{@project.repository.ref_names.to_json};
+%script#availableRefs{ type: "application/json" }= @project.repository.ref_names.to_json.html_safe
diff --git a/app/views/projects/tree/_tree_content.html.haml b/app/views/projects/tree/_tree_content.html.haml
index 6560bd5ab3f..820b947804e 100644
--- a/app/views/projects/tree/_tree_content.html.haml
+++ b/app/views/projects/tree/_tree_content.html.haml
@@ -1,4 +1,4 @@
-.tree-content-holder
+.tree-content-holder.js-tree-content{ 'data-logs-path': @logs_path }
.table-holder
%table.table#tree-slider{ class: "table_#{@hex_path} tree-table" }
%thead
@@ -22,9 +22,3 @@
- if can_edit_tree?
= render 'projects/blob/upload', title: _('Upload New File'), placeholder: _('Upload New File'), button_title: _('Upload file'), form_path: project_create_blob_path(@project, @id), method: :post
= render 'projects/blob/new_dir'
-
-:javascript
- // Load last commit log for each file in tree
- $('#tree-slider').waitForImages(function() {
- gl.utils.ajaxGet("#{escape_javascript(@logs_path)}");
- });
diff --git a/app/views/projects/wikis/_sidebar.html.haml b/app/views/projects/wikis/_sidebar.html.haml
index 62873d3aa66..e71ce1f357f 100644
--- a/app/views/projects/wikis/_sidebar.html.haml
+++ b/app/views/projects/wikis/_sidebar.html.haml
@@ -19,6 +19,3 @@
More Pages
= render 'projects/wikis/new'
-
-:javascript
- new Sidebar();
diff --git a/app/views/shared/_clone_panel.html.haml b/app/views/shared/_clone_panel.html.haml
index 75704eda361..b4843eafdb7 100644
--- a/app/views/shared/_clone_panel.html.haml
+++ b/app/views/shared/_clone_panel.html.haml
@@ -20,11 +20,3 @@
= text_field_tag :project_clone, default_url_to_repo(project), class: "js-select-on-focus form-control", readonly: true, aria: { label: 'Project clone URL' }
.input-group-btn
= clipboard_button(target: '#project_clone', title: _("Copy URL to clipboard"), class: "btn-default btn-clipboard")
-
-:javascript
- $('ul.clone-options-dropdown a').on('click',function(e){
- e.preventDefault();
- var $this = $(this);
- $('a.clone-dropdown-btn span').text($this.text());
- $('#project_clone').val($this.attr('href'));
- });
diff --git a/app/views/shared/_label.html.haml b/app/views/shared/_label.html.haml
index 2f776a17f45..8ded7440de3 100644
--- a/app/views/shared/_label.html.haml
+++ b/app/views/shared/_label.html.haml
@@ -76,11 +76,3 @@
= link_to destroy_label_path(label), title: "Delete", class: 'btn btn-transparent btn-action remove-row', method: :delete, data: {confirm: label_deletion_confirm_text(label), toggle: "tooltip"} do
%span.sr-only Delete
= icon('trash-o')
-
- - if current_user
- - if can_subscribe_to_label_in_different_levels?(label)
- :javascript
- new gl.GroupLabelSubscription('##{dom_id(label)} .label-subscription');
- - else
- :javascript
- new gl.ProjectLabelSubscription('##{dom_id(label)} .label-subscription');
diff --git a/app/views/shared/_personal_access_tokens_form.html.haml b/app/views/shared/_personal_access_tokens_form.html.haml
index b20055a564e..e415ec64c38 100644
--- a/app/views/shared/_personal_access_tokens_form.html.haml
+++ b/app/views/shared/_personal_access_tokens_form.html.haml
@@ -23,18 +23,3 @@
.prepend-top-default
= f.submit "Create #{type} token", class: "btn btn-create"
-
-:javascript
- var $dateField = $('.datepicker');
- var date = $dateField.val();
-
- new Pikaday({
- field: $dateField.get(0),
- theme: 'gitlab-theme animate-picker',
- format: 'yyyy-mm-dd',
- minDate: new Date(),
- container: $dateField.parent().get(0),
- onSelect: function(dateText) {
- $dateField.val(dateFormat(new Date(dateText), 'yyyy-mm-dd'));
- }
- });
diff --git a/app/views/shared/issuable/_filter.html.haml b/app/views/shared/issuable/_filter.html.haml
index 2cabbc8c560..c4ed7f6e750 100644
--- a/app/views/shared/issuable/_filter.html.haml
+++ b/app/views/shared/issuable/_filter.html.haml
@@ -36,13 +36,3 @@
.row-content-block.second-block.filtered-labels{ class: ("hidden" unless has_labels) }
- if has_labels
= render 'shared/labels_row', labels: @labels
-
-:javascript
- new LabelsSelect();
- new MilestoneSelect();
- new IssueStatusSelect();
- new SubscriptionSelect();
- $('form.filter-form').on('submit', function (event) {
- event.preventDefault();
- gl.utils.visitUrl(this.action + '&' + $(this).serialize());
- });
diff --git a/app/views/shared/issuable/_participants.html.haml b/app/views/shared/issuable/_participants.html.haml
index db407363a09..8a71819aa8e 100644
--- a/app/views/shared/issuable/_participants.html.haml
+++ b/app/views/shared/issuable/_participants.html.haml
@@ -16,5 +16,3 @@
.hide-collapsed.participants-more
%a.js-participants-more{ href: "#", data: { original_text: "+ #{participants_size - 7} more", less_text: "- show less" } }
+ #{participants_extra} more
-:javascript
- IssuableContext.prototype.PARTICIPANTS_ROW_COUNT = #{participants_row};
diff --git a/app/views/shared/issuable/_search_bar.html.haml b/app/views/shared/issuable/_search_bar.html.haml
index 6f0b7600698..3428d6e0445 100644
--- a/app/views/shared/issuable/_search_bar.html.haml
+++ b/app/views/shared/issuable/_search_bar.html.haml
@@ -108,12 +108,3 @@
#js-add-issues-btn.prepend-left-10
- elsif type != :boards_modal
= render 'shared/sort_dropdown'
-
-- unless type === :boards_modal
- :javascript
- $(document).off('page:restore').on('page:restore', function (event) {
- if (gl.FilteredSearchManager) {
- const filteredSearchManager = new gl.FilteredSearchManager();
- filteredSearchManager.setup();
- }
- });
diff --git a/app/views/shared/issuable/_sidebar.html.haml b/app/views/shared/issuable/_sidebar.html.haml
index ecbaa901792..b08267357e5 100644
--- a/app/views/shared/issuable/_sidebar.html.haml
+++ b/app/views/shared/issuable/_sidebar.html.haml
@@ -138,17 +138,4 @@
= project_ref
= clipboard_button(text: project_ref, title: "Copy reference to clipboard", placement: "left")
- :javascript
- gl.sidebarOptions = {
- endpoint: "#{issuable_json_path(issuable)}?basic=true",
- editable: #{can_edit_issuable ? true : false},
- currentUser: #{current_user.to_json(only: [:username, :id, :name], methods: :avatar_url)},
- rootPath: "#{root_path}"
- };
-
- new MilestoneSelect('{"full_path":"#{@project.full_path}"}');
- new LabelsSelect();
- new IssuableContext('#{escape_javascript(current_user.to_json(only: [:username, :id, :name]))}');
- gl.Subscription.bindAll('.subscription');
- new gl.DueDateSelectors();
- window.sidebar = new Sidebar();
+ %script.js-sidebar-options{ type: "application/json" }= issuable_sidebar_options(issuable, can_edit_issuable).to_json.html_safe
diff --git a/app/views/shared/notes/_form.html.haml b/app/views/shared/notes/_form.html.haml
index c6b5dcc3647..725bf916592 100644
--- a/app/views/shared/notes/_form.html.haml
+++ b/app/views/shared/notes/_form.html.haml
@@ -10,6 +10,7 @@
= hidden_field_tag :line_type
= hidden_field_tag :merge_request_diff_head_sha, @note.noteable.try(:diff_head_sha)
= hidden_field_tag :in_reply_to_discussion_id
+ = hidden_field_tag :note_project_id
= note_target_fields(@note)
= f.hidden_field :noteable_type
diff --git a/app/views/shared/notes/_notes_with_form.html.haml b/app/views/shared/notes/_notes_with_form.html.haml
index f0fcc414756..eae04c9bbb8 100644
--- a/app/views/shared/notes/_notes_with_form.html.haml
+++ b/app/views/shared/notes/_notes_with_form.html.haml
@@ -22,5 +22,4 @@
= link_to "sign in", new_session_path(:user, redirect_to_referer: 'yes')
to comment
-:javascript
- var notes = new Notes("#{notes_url}", #{@notes.map(&:id).to_json}, #{Time.now.to_i}, "#{diff_view}", #{autocomplete})
+%script.js-notes-data{ type: "application/json" }= initial_notes_data(autocomplete).to_json.html_safe
diff --git a/app/views/shared/projects/_project.html.haml b/app/views/shared/projects/_project.html.haml
index 4bdbc26a4c3..f4f155c8d94 100644
--- a/app/views/shared/projects/_project.html.haml
+++ b/app/views/shared/projects/_project.html.haml
@@ -14,7 +14,7 @@
- if avatar
.avatar-container.s40
= link_to project_path(project), class: dom_class(project) do
- - if use_creator_avatar
+ - if project.creator && use_creator_avatar
= image_tag avatar_icon(project.creator.email, 40), class: "avatar s40", alt:''
- else
= project_icon(project, alt: '', class: 'avatar project-avatar s40')
diff --git a/app/views/snippets/_snippets.html.haml b/app/views/snippets/_snippets.html.haml
index ac3701233ad..dfea8b40bd8 100644
--- a/app/views/snippets/_snippets.html.haml
+++ b/app/views/snippets/_snippets.html.haml
@@ -1,4 +1,3 @@
-- remote = local_assigns.fetch(:remote, false)
- link_project = local_assigns.fetch(:link_project, false)
.snippets-list-holder
@@ -8,7 +7,4 @@
%li
.nothing-here-block Nothing here.
- = paginate @snippets, theme: 'gitlab', remote: remote
-
-:javascript
- gl.SnippetsList();
+ = paginate @snippets, theme: 'gitlab'
diff --git a/app/workers/git_garbage_collect_worker.rb b/app/workers/git_garbage_collect_worker.rb
index d369b639ae9..c95497dfaba 100644
--- a/app/workers/git_garbage_collect_worker.rb
+++ b/app/workers/git_garbage_collect_worker.rb
@@ -5,6 +5,12 @@ class GitGarbageCollectWorker
sidekiq_options retry: false
+ GITALY_MIGRATED_TASKS = {
+ gc: :garbage_collect,
+ full_repack: :repack_full,
+ incremental_repack: :repack_incremental
+ }.freeze
+
def perform(project_id, task = :gc, lease_key = nil, lease_uuid = nil)
project = Project.find(project_id)
task = task.to_sym
@@ -15,8 +21,14 @@ class GitGarbageCollectWorker
Gitlab::GitLogger.info(description)
- output, status = Gitlab::Popen.popen(cmd, repo_path)
- Gitlab::GitLogger.error("#{description} failed:\n#{output}") unless status.zero?
+ gitaly_migrate(GITALY_MIGRATED_TASKS[task]) do |is_enabled|
+ if is_enabled
+ gitaly_call(task, project.repository.raw_repository)
+ else
+ output, status = Gitlab::Popen.popen(cmd, repo_path)
+ Gitlab::GitLogger.error("#{description} failed:\n#{output}") unless status.zero?
+ end
+ end
# Refresh the branch cache in case garbage collection caused a ref lookup to fail
flush_ref_caches(project) if task == :gc
@@ -26,6 +38,19 @@ class GitGarbageCollectWorker
private
+ ## `repository` has to be a Gitlab::Git::Repository
+ def gitaly_call(task, repository)
+ client = Gitlab::GitalyClient::RepositoryService.new(repository)
+ case task
+ when :gc
+ client.garbage_collect(bitmaps_enabled?)
+ when :full_repack
+ client.repack_full(bitmaps_enabled?)
+ when :incremental_repack
+ client.repack_incremental
+ end
+ end
+
def command(task)
case task
when :gc
@@ -55,4 +80,14 @@ class GitGarbageCollectWorker
config_value = write_bitmaps ? 'true' : 'false'
%W[git -c repack.writeBitmaps=#{config_value}]
end
+
+ def gitaly_migrate(method, &block)
+ Gitlab::GitalyClient.migrate(method, &block)
+ rescue GRPC::NotFound => e
+ Gitlab::GitLogger.error("#{method} failed:\nRepository not found")
+ raise Gitlab::Git::Repository::NoRepository.new(e)
+ rescue GRPC::BadStatus => e
+ Gitlab::GitLogger.error("#{method} failed:\n#{e}")
+ raise Gitlab::Git::CommandError.new(e)
+ end
end
diff --git a/changelogs/unreleased/12673-fix_v3_project_hooks_build_events b/changelogs/unreleased/12673-fix_v3_project_hooks_build_events
new file mode 100644
index 00000000000..59bc646406f
--- /dev/null
+++ b/changelogs/unreleased/12673-fix_v3_project_hooks_build_events
@@ -0,0 +1,4 @@
+---
+title: "Fix v3 api project_hooks POST and PUT operations for build_events"
+merge_request: 12673
+author: Richard Clamp
diff --git a/changelogs/unreleased/2971-multiproject-grah-ce-port.yml b/changelogs/unreleased/2971-multiproject-grah-ce-port.yml
deleted file mode 100644
index 37584cac6ab..00000000000
--- a/changelogs/unreleased/2971-multiproject-grah-ce-port.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Fix vertical alignment in firefox and safari for pipeline mini graph
-merge_request:
-author:
diff --git a/changelogs/unreleased/34729-blob.yml b/changelogs/unreleased/34729-blob.yml
deleted file mode 100644
index 15a469d3af0..00000000000
--- a/changelogs/unreleased/34729-blob.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Fix crash on /help/ui
-merge_request:
-author:
diff --git a/changelogs/unreleased/34921-global-dropdown-ui-improvement.yml b/changelogs/unreleased/34921-global-dropdown-ui-improvement.yml
new file mode 100644
index 00000000000..6a17353ba3f
--- /dev/null
+++ b/changelogs/unreleased/34921-global-dropdown-ui-improvement.yml
@@ -0,0 +1,4 @@
+---
+title: Improve CSS for global nav dropdown UI
+merge_request: 12772
+author: Takuya Noguchi
diff --git a/changelogs/unreleased/35044-projects-logo-are-not-centered-vertically-on-projects-page.yml b/changelogs/unreleased/35044-projects-logo-are-not-centered-vertically-on-projects-page.yml
new file mode 100644
index 00000000000..9de4dbefd35
--- /dev/null
+++ b/changelogs/unreleased/35044-projects-logo-are-not-centered-vertically-on-projects-page.yml
@@ -0,0 +1,4 @@
+---
+title: Fix project logos that are not centered vertically on list pages
+merge_request: 13124
+author: Florian Lemaitre
diff --git a/changelogs/unreleased/35338-deploy-keys-should-not-show-pending-delete-projects.yml b/changelogs/unreleased/35338-deploy-keys-should-not-show-pending-delete-projects.yml
deleted file mode 100644
index 73808030f4c..00000000000
--- a/changelogs/unreleased/35338-deploy-keys-should-not-show-pending-delete-projects.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Pending delete projects should not show in deploy keys.
-merge_request: 13088
-author:
diff --git a/changelogs/unreleased/35453-pending-delete-projects-error-in-admin-dashboard-fix.yml b/changelogs/unreleased/35453-pending-delete-projects-error-in-admin-dashboard-fix.yml
deleted file mode 100644
index fa906accbb8..00000000000
--- a/changelogs/unreleased/35453-pending-delete-projects-error-in-admin-dashboard-fix.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Fixes 500 error caused by pending delete projects in admin dashboard
-merge_request: 13067
-author:
diff --git a/changelogs/unreleased/35478-allow-admin-to-read-user-list.yml b/changelogs/unreleased/35478-allow-admin-to-read-user-list.yml
deleted file mode 100644
index da4b730f0ca..00000000000
--- a/changelogs/unreleased/35478-allow-admin-to-read-user-list.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Allow admin to read_users_list even if it's restricted
-merge_request: 13066
-author:
diff --git a/changelogs/unreleased/35539-can-t-create-a-merge-request-containing-a-binary-file-with-non-utf-8-characters.yml b/changelogs/unreleased/35539-can-t-create-a-merge-request-containing-a-binary-file-with-non-utf-8-characters.yml
deleted file mode 100644
index 8d92aacc9ef..00000000000
--- a/changelogs/unreleased/35539-can-t-create-a-merge-request-containing-a-binary-file-with-non-utf-8-characters.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix creating merge request diffs when diff contains bytes that are invalid
- in UTF-8
-merge_request:
-author:
diff --git a/changelogs/unreleased/35567-fix-relative-urls-in-webpack-public-path.yml b/changelogs/unreleased/35567-fix-relative-urls-in-webpack-public-path.yml
new file mode 100644
index 00000000000..41b506681f9
--- /dev/null
+++ b/changelogs/unreleased/35567-fix-relative-urls-in-webpack-public-path.yml
@@ -0,0 +1,5 @@
+---
+title: Fix asynchronous javascript paths when GitLab is installed under a relative
+ URL
+merge_request: 13165
+author:
diff --git a/changelogs/unreleased/35672-edge-top-bar.yml b/changelogs/unreleased/35672-edge-top-bar.yml
new file mode 100644
index 00000000000..0424dee19af
--- /dev/null
+++ b/changelogs/unreleased/35672-edge-top-bar.yml
@@ -0,0 +1,4 @@
+---
+title: Properly affixes nav bar in job view in microsoft edge
+merge_request:
+author:
diff --git a/changelogs/unreleased/35695-comment-appears-in-a-wrong-place-after-changing-diff-view-to-inline.yml b/changelogs/unreleased/35695-comment-appears-in-a-wrong-place-after-changing-diff-view-to-inline.yml
new file mode 100644
index 00000000000..1c9ad20bc95
--- /dev/null
+++ b/changelogs/unreleased/35695-comment-appears-in-a-wrong-place-after-changing-diff-view-to-inline.yml
@@ -0,0 +1,4 @@
+---
+title: Fix display of new diff comments after changing b between diff views
+merge_request:
+author:
diff --git a/changelogs/unreleased/add-instrumentation-to-link-to-gfm.yml b/changelogs/unreleased/add-instrumentation-to-link-to-gfm.yml
deleted file mode 100644
index b5cf521561a..00000000000
--- a/changelogs/unreleased/add-instrumentation-to-link-to-gfm.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Add instrumentation to MarkupHelper#link_to_gfm
-merge_request: 13069
-author:
diff --git a/changelogs/unreleased/dm-large-push-performance.yml b/changelogs/unreleased/dm-large-push-performance.yml
new file mode 100644
index 00000000000..f5fe1bd3b28
--- /dev/null
+++ b/changelogs/unreleased/dm-large-push-performance.yml
@@ -0,0 +1,4 @@
+---
+title: Improve performance of large (initial) push into default branch
+merge_request:
+author:
diff --git a/changelogs/unreleased/fix-500-error-when-rendering-avatar-for-deleted-project-creator.yml b/changelogs/unreleased/fix-500-error-when-rendering-avatar-for-deleted-project-creator.yml
new file mode 100644
index 00000000000..be6f1ea00fb
--- /dev/null
+++ b/changelogs/unreleased/fix-500-error-when-rendering-avatar-for-deleted-project-creator.yml
@@ -0,0 +1,4 @@
+---
+title: Modify if condition to be more readable
+merge_request:
+author:
diff --git a/changelogs/unreleased/fix-gb-fix-build-merge-request-link-to-fork-project.yml b/changelogs/unreleased/fix-gb-fix-build-merge-request-link-to-fork-project.yml
deleted file mode 100644
index 7a68e91c6d3..00000000000
--- a/changelogs/unreleased/fix-gb-fix-build-merge-request-link-to-fork-project.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Fix job merge request link to a forked source project
-merge_request: 12965
-author:
diff --git a/changelogs/unreleased/fix-replying-to-commit-comment-in-mr-from-fork.yml b/changelogs/unreleased/fix-replying-to-commit-comment-in-mr-from-fork.yml
new file mode 100644
index 00000000000..f4136460626
--- /dev/null
+++ b/changelogs/unreleased/fix-replying-to-commit-comment-in-mr-from-fork.yml
@@ -0,0 +1,4 @@
+---
+title: Fix replying to commit comments on merge requests created from forks
+merge_request:
+author:
diff --git a/changelogs/unreleased/help-page-breadcrumb-title-fix.yml b/changelogs/unreleased/help-page-breadcrumb-title-fix.yml
new file mode 100644
index 00000000000..040fe4b9916
--- /dev/null
+++ b/changelogs/unreleased/help-page-breadcrumb-title-fix.yml
@@ -0,0 +1,4 @@
+---
+title: Fixed new navigation breadcrumb title on help pages
+merge_request:
+author:
diff --git a/changelogs/unreleased/merge-issuable-reopened-into-opened-state.yml b/changelogs/unreleased/merge-issuable-reopened-into-opened-state.yml
new file mode 100644
index 00000000000..5d7af8971e5
--- /dev/null
+++ b/changelogs/unreleased/merge-issuable-reopened-into-opened-state.yml
@@ -0,0 +1,4 @@
+---
+title: Merge issuable "reopened" state into "opened"
+merge_request:
+author:
diff --git a/changelogs/unreleased/mk-add-ldap-ssl-certificate-verification.yml b/changelogs/unreleased/mk-add-ldap-ssl-certificate-verification.yml
deleted file mode 100644
index 80e6c50d5b3..00000000000
--- a/changelogs/unreleased/mk-add-ldap-ssl-certificate-verification.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Add LDAP SSL certificate verification option
-merge_request:
-author:
diff --git a/changelogs/unreleased/mk-add-lower-path-index-to-redirect-routes.yml b/changelogs/unreleased/mk-add-lower-path-index-to-redirect-routes.yml
deleted file mode 100644
index 37a5fa66d13..00000000000
--- a/changelogs/unreleased/mk-add-lower-path-index-to-redirect-routes.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Improve redirect route query performance
-merge_request: 13062
-author:
diff --git a/changelogs/unreleased/new-navigation-custom-logo.yml b/changelogs/unreleased/new-navigation-custom-logo.yml
deleted file mode 100644
index 22e6c5dc7e5..00000000000
--- a/changelogs/unreleased/new-navigation-custom-logo.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Fix sizing of custom header logo in new navigation
-merge_request:
-author:
diff --git a/changelogs/unreleased/zj-delete-mm-team.yml b/changelogs/unreleased/zj-delete-mm-team.yml
new file mode 100644
index 00000000000..f0c782c4566
--- /dev/null
+++ b/changelogs/unreleased/zj-delete-mm-team.yml
@@ -0,0 +1,4 @@
+---
+title: Remove Mattermost team when deleting a group
+merge_request: 11362
+author:
diff --git a/config/initializers/1_settings.rb b/config/initializers/1_settings.rb
index 02d3161f769..63f4c8c9e0a 100644
--- a/config/initializers/1_settings.rb
+++ b/config/initializers/1_settings.rb
@@ -223,7 +223,7 @@ Settings.gitlab['default_can_create_group'] = true if Settings.gitlab['default_c
Settings.gitlab['host'] ||= ENV['GITLAB_HOST'] || 'localhost'
Settings.gitlab['ssh_host'] ||= Settings.gitlab.host
Settings.gitlab['https'] = false if Settings.gitlab['https'].nil?
-Settings.gitlab['port'] ||= Settings.gitlab.https ? 443 : 80
+Settings.gitlab['port'] ||= ENV['GITLAB_PORT'] || (Settings.gitlab.https ? 443 : 80)
Settings.gitlab['relative_url_root'] ||= ENV['RAILS_RELATIVE_URL_ROOT'] || ''
Settings.gitlab['protocol'] ||= Settings.gitlab.https ? "https" : "http"
Settings.gitlab['email_enabled'] ||= true if Settings.gitlab['email_enabled'].nil?
diff --git a/config/initializers/omniauth.rb b/config/initializers/omniauth.rb
index a36e59c941a..56c279ffcf4 100644
--- a/config/initializers/omniauth.rb
+++ b/config/initializers/omniauth.rb
@@ -1,13 +1,16 @@
if Gitlab::LDAP::Config.enabled?
module OmniAuth::Strategies
- server = Gitlab.config.ldap.servers.values.first
- klass = server['provider_class']
- const_set(klass, Class.new(LDAP)) unless klass == 'LDAP'
+ Gitlab::LDAP::Config.available_servers.each do |server|
+ # do not redeclare LDAP
+ next if server['provider_name'] == 'ldap'
+ const_set(server['provider_class'], Class.new(LDAP))
+ end
end
OmniauthCallbacksController.class_eval do
- server = Gitlab.config.ldap.servers.values.first
- alias_method server['provider_name'], :ldap
+ Gitlab::LDAP::Config.available_servers.each do |server|
+ alias_method server['provider_name'], :ldap
+ end
end
end
diff --git a/config/webpack.config.js b/config/webpack.config.js
index 41d3ed12b14..2f85b89d523 100644
--- a/config/webpack.config.js
+++ b/config/webpack.config.js
@@ -54,8 +54,11 @@ var config = {
notebook_viewer: './blob/notebook_viewer.js',
pdf_viewer: './blob/pdf_viewer.js',
pipelines: './pipelines/pipelines_bundle.js',
- pipelines_details: './pipelines/pipeline_details_bundle.js',
+ pipelines_charts: './pipelines/pipelines_charts.js',
+ pipelines_details: './pipelines/pipeline_details_bundle.js',
+ pipelines_times: './pipelines/pipelines_times.js',
profile: './profile/profile_bundle.js',
+ project_new: './projects/project_new.js',
prometheus_metrics: './prometheus_metrics',
protected_branches: './protected_branches',
protected_tags: './protected_tags',
diff --git a/db/migrate/20170720130522_create_ci_pipeline_variables.rb b/db/migrate/20170720130522_create_ci_pipeline_variables.rb
new file mode 100644
index 00000000000..a784f5dd142
--- /dev/null
+++ b/db/migrate/20170720130522_create_ci_pipeline_variables.rb
@@ -0,0 +1,20 @@
+class CreateCiPipelineVariables < ActiveRecord::Migration
+ DOWNTIME = false
+
+ def up
+ create_table :ci_pipeline_variables do |t|
+ t.string :key, null: false
+ t.text :value
+ t.text :encrypted_value
+ t.string :encrypted_value_salt
+ t.string :encrypted_value_iv
+ t.integer :pipeline_id, null: false
+ end
+
+ add_index :ci_pipeline_variables, [:pipeline_id, :key], unique: true
+ end
+
+ def down
+ drop_table :ci_pipeline_variables
+ end
+end
diff --git a/db/migrate/20170720130749_add_foreign_key_to_ci_pipeline_variables.rb b/db/migrate/20170720130749_add_foreign_key_to_ci_pipeline_variables.rb
new file mode 100644
index 00000000000..550b8a88f02
--- /dev/null
+++ b/db/migrate/20170720130749_add_foreign_key_to_ci_pipeline_variables.rb
@@ -0,0 +1,15 @@
+class AddForeignKeyToCiPipelineVariables < ActiveRecord::Migration
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ disable_ddl_transaction!
+
+ def up
+ add_concurrent_foreign_key(:ci_pipeline_variables, :ci_pipelines, column: :pipeline_id)
+ end
+
+ def down
+ remove_foreign_key(:ci_pipeline_variables, column: :pipeline_id)
+ end
+end
diff --git a/db/post_migrate/20170719150301_merge_issuable_reopened_into_opened_state.rb b/db/post_migrate/20170719150301_merge_issuable_reopened_into_opened_state.rb
new file mode 100644
index 00000000000..acc0fc7a0ac
--- /dev/null
+++ b/db/post_migrate/20170719150301_merge_issuable_reopened_into_opened_state.rb
@@ -0,0 +1,32 @@
+# See http://doc.gitlab.com/ce/development/migration_style_guide.html
+# for more information on how to write migrations for GitLab.
+
+class MergeIssuableReopenedIntoOpenedState < ActiveRecord::Migration
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ disable_ddl_transaction!
+
+ class Issue < ActiveRecord::Base
+ self.table_name = 'issues'
+
+ include EachBatch
+ end
+
+ class MergeRequest < ActiveRecord::Base
+ self.table_name = 'merge_requests'
+
+ include EachBatch
+ end
+
+ def up
+ [Issue, MergeRequest].each do |model|
+ say "Changing #{model.table_name}.state from 'reopened' to 'opened'"
+
+ model.where(state: 'reopened').each_batch do |batch|
+ batch.update_all(state: 'opened')
+ end
+ end
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 93ab79e14e0..5fbbdea6eaa 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -254,32 +254,32 @@ ActiveRecord::Schema.define(version: 20170725145659) do
add_index "ci_builds", ["updated_at"], name: "index_ci_builds_on_updated_at", using: :btree
add_index "ci_builds", ["user_id"], name: "index_ci_builds_on_user_id", using: :btree
- create_table "ci_pipeline_schedule_variables", force: :cascade do |t|
+ create_table "ci_group_variables", force: :cascade do |t|
t.string "key", null: false
t.text "value"
t.text "encrypted_value"
t.string "encrypted_value_salt"
t.string "encrypted_value_iv"
- t.integer "pipeline_schedule_id", null: false
+ t.integer "group_id", null: false
+ t.boolean "protected", default: false, null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
- add_index "ci_pipeline_schedule_variables", ["pipeline_schedule_id", "key"], name: "index_ci_pipeline_schedule_variables_on_schedule_id_and_key", unique: true, using: :btree
+ add_index "ci_group_variables", ["group_id", "key"], name: "index_ci_group_variables_on_group_id_and_key", unique: true, using: :btree
- create_table "ci_group_variables", force: :cascade do |t|
+ create_table "ci_pipeline_schedule_variables", force: :cascade do |t|
t.string "key", null: false
t.text "value"
t.text "encrypted_value"
t.string "encrypted_value_salt"
t.string "encrypted_value_iv"
- t.integer "group_id", null: false
- t.boolean "protected", default: false, null: false
- t.datetime "created_at", null: false
- t.datetime "updated_at", null: false
+ t.integer "pipeline_schedule_id", null: false
+ t.datetime "created_at"
+ t.datetime "updated_at"
end
- add_index "ci_group_variables", ["group_id", "key"], name: "index_ci_group_variables_on_group_id_and_key", unique: true, using: :btree
+ add_index "ci_pipeline_schedule_variables", ["pipeline_schedule_id", "key"], name: "index_ci_pipeline_schedule_variables_on_schedule_id_and_key", unique: true, using: :btree
create_table "ci_pipeline_schedules", force: :cascade do |t|
t.string "description"
@@ -298,6 +298,17 @@ ActiveRecord::Schema.define(version: 20170725145659) do
add_index "ci_pipeline_schedules", ["next_run_at", "active"], name: "index_ci_pipeline_schedules_on_next_run_at_and_active", using: :btree
add_index "ci_pipeline_schedules", ["project_id"], name: "index_ci_pipeline_schedules_on_project_id", using: :btree
+ create_table "ci_pipeline_variables", force: :cascade do |t|
+ t.string "key", null: false
+ t.text "value"
+ t.text "encrypted_value"
+ t.string "encrypted_value_salt"
+ t.string "encrypted_value_iv"
+ t.integer "pipeline_id", null: false
+ end
+
+ add_index "ci_pipeline_variables", ["pipeline_id", "key"], name: "index_ci_pipeline_variables_on_pipeline_id_and_key", unique: true, using: :btree
+
create_table "ci_pipelines", force: :cascade do |t|
t.string "ref"
t.string "sha"
@@ -1613,10 +1624,11 @@ ActiveRecord::Schema.define(version: 20170725145659) do
add_foreign_key "ci_builds", "ci_pipelines", column: "auto_canceled_by_id", name: "fk_a2141b1522", on_delete: :nullify
add_foreign_key "ci_builds", "ci_stages", column: "stage_id", name: "fk_3a9eaa254d", on_delete: :cascade
add_foreign_key "ci_builds", "projects", name: "fk_befce0568a", on_delete: :cascade
- add_foreign_key "ci_pipeline_schedule_variables", "ci_pipeline_schedules", column: "pipeline_schedule_id", name: "fk_41c35fda51", on_delete: :cascade
add_foreign_key "ci_group_variables", "namespaces", column: "group_id", name: "fk_33ae4d58d8", on_delete: :cascade
+ add_foreign_key "ci_pipeline_schedule_variables", "ci_pipeline_schedules", column: "pipeline_schedule_id", name: "fk_41c35fda51", on_delete: :cascade
add_foreign_key "ci_pipeline_schedules", "projects", name: "fk_8ead60fcc4", on_delete: :cascade
add_foreign_key "ci_pipeline_schedules", "users", column: "owner_id", name: "fk_9ea99f58d2", on_delete: :nullify
+ add_foreign_key "ci_pipeline_variables", "ci_pipelines", column: "pipeline_id", name: "fk_f29c5f4380", on_delete: :cascade
add_foreign_key "ci_pipelines", "ci_pipeline_schedules", column: "pipeline_schedule_id", name: "fk_3d34ab2e06", on_delete: :nullify
add_foreign_key "ci_pipelines", "ci_pipelines", column: "auto_canceled_by_id", name: "fk_262d4c2d19", on_delete: :nullify
add_foreign_key "ci_pipelines", "projects", name: "fk_86635dbd80", on_delete: :cascade
diff --git a/doc/README.md b/doc/README.md
index cc63ecb7eab..8bb8e147cd1 100644
--- a/doc/README.md
+++ b/doc/README.md
@@ -44,16 +44,17 @@ Shortcuts to GitLab's most visited docs:
### Projects and groups
-- [Create a project](gitlab-basics/create-project.md)
-- [Fork a project](gitlab-basics/fork-project.md)
-- [Importing and exporting projects between instances](user/project/settings/import_export.md).
-- [Project access](public_access/public_access.md): Setting up your project's visibility to public, internal, or private.
+- [Projects](user/project/index.md):
+ - [Create a project](gitlab-basics/create-project.md)
+ - [Fork a project](gitlab-basics/fork-project.md)
+ - [Importing and exporting projects between instances](user/project/settings/import_export.md).
+ - [Project access](public_access/public_access.md): Setting up your project's visibility to public, internal, or private.
+ - [GitLab Pages](user/project/pages/index.md): Build, test, and deploy your static website with GitLab Pages.
- [Groups](user/group/index.md): Organize your projects in groups.
- - [GitLab Subgroups](user/group/subgroups/index.md)
+ - [Subgroups](user/group/subgroups/index.md)
- [Search through GitLab](user/search/index.md): Search for issues, merge requests, projects, groups, todos, and issues in Issue Boards.
- [Snippets](user/snippets.md): Snippets allow you to create little bits of code.
- [Wikis](user/project/wiki/index.md): Enhance your repository documentation with built-in wikis.
-- [GitLab Pages](user/project/pages/index.md): Build, test, and deploy your static website with GitLab Pages.
### Repository
diff --git a/doc/administration/high_availability/nfs.md b/doc/administration/high_availability/nfs.md
index bd6b7327aed..90a2e9298bf 100644
--- a/doc/administration/high_availability/nfs.md
+++ b/doc/administration/high_availability/nfs.md
@@ -46,6 +46,10 @@ GitLab does not recommend using EFS with GitLab.
many small files are written in a serialized manner are not well-suited for EFS.
EBS with an NFS server on top will perform much better.
+In addition, avoid storing GitLab log files (e.g. those in `/var/log/gitlab`)
+because this will also affect performance. We recommend that the log files be
+stored on a local volume.
+
For more details on another person's experience with EFS, see
[Amazon's Elastic File System: Burst Credits](https://www.rawkode.io/2017/04/amazons-elastic-file-system-burst-credits/)
diff --git a/doc/administration/monitoring/performance/img/performance_bar.png b/doc/administration/monitoring/performance/img/performance_bar.png
index d38293d2ed6..b3c6bc474e3 100644
--- a/doc/administration/monitoring/performance/img/performance_bar.png
+++ b/doc/administration/monitoring/performance/img/performance_bar.png
Binary files differ
diff --git a/doc/api/users.md b/doc/api/users.md
index 6e5ec3231c5..57a13eb477d 100644
--- a/doc/api/users.md
+++ b/doc/api/users.md
@@ -241,26 +241,26 @@ POST /users
Parameters:
-- `email` (required) - Email
-- `password` (optional) - Password
-- `reset_password` (optional) - Send user password reset link - true or false(default)
-- `username` (required) - Username
-- `name` (required) - Name
-- `skype` (optional) - Skype ID
-- `linkedin` (optional) - LinkedIn
-- `twitter` (optional) - Twitter account
-- `website_url` (optional) - Website URL
-- `organization` (optional) - Organization name
-- `projects_limit` (optional) - Number of projects user can create
-- `extern_uid` (optional) - External UID
-- `provider` (optional) - External provider name
-- `bio` (optional) - User's biography
-- `location` (optional) - User's location
-- `admin` (optional) - User is admin - true or false (default)
-- `can_create_group` (optional) - User can create groups - true or false
-- `confirm` (optional) - Require confirmation - true (default) or false
-- `external` (optional) - Flags the user as external - true or false(default)
-- `avatar` (optional) - Image file for user's avatar
+- `email` (required) - Email
+- `password` (optional) - Password
+- `reset_password` (optional) - Send user password reset link - true or false(default)
+- `username` (required) - Username
+- `name` (required) - Name
+- `skype` (optional) - Skype ID
+- `linkedin` (optional) - LinkedIn
+- `twitter` (optional) - Twitter account
+- `website_url` (optional) - Website URL
+- `organization` (optional) - Organization name
+- `projects_limit` (optional) - Number of projects user can create
+- `extern_uid` (optional) - External UID
+- `provider` (optional) - External provider name
+- `bio` (optional) - User's biography
+- `location` (optional) - User's location
+- `admin` (optional) - User is admin - true or false (default)
+- `can_create_group` (optional) - User can create groups - true or false
+- `skip_confirmation` (optional) - Skip confirmation - true or false (default)
+- `external` (optional) - Flags the user as external - true or false(default)
+- `avatar` (optional) - Image file for user's avatar
## User modification
diff --git a/doc/ci/yaml/README.md b/doc/ci/yaml/README.md
index e12ef6e2685..1869782fe6e 100644
--- a/doc/ci/yaml/README.md
+++ b/doc/ci/yaml/README.md
@@ -441,13 +441,25 @@ There are a few rules that apply to the usage of refs policy:
* `only` and `except` are inclusive. If both `only` and `except` are defined
in a job specification, the ref is filtered by `only` and `except`.
* `only` and `except` allow the use of regular expressions.
-* `only` and `except` allow the use of special keywords:
-`api`, `branches`, `external`, `tags`, `pushes`, `schedules`, `triggers`, and `web`
* `only` and `except` allow to specify a repository path to filter jobs for
forks.
+In addition, `only` and `except` allow the use of special keywords:
+
+| **Value** | **Description** |
+| --------- | ---------------- |
+| `branches` | When a branch is pushed. |
+| `tags` | When a tag is pushed. |
+| `api` | When pipeline has been triggered by a second pipelines API (not triggers API). |
+| `external` | When using CI services other than GitLab. |
+| `pipelines` | For multi-project triggers, created using the API with `CI_JOB_TOKEN`. |
+| `pushes` | Pipeline is triggered by a `git push` by the user. |
+| `schedules` | For [scheduled pipelines][schedules]. |
+| `triggers` | For pipelines created using a trigger token. |
+| `web` | For pipelines created using **Run pipeline** button in GitLab UI (under your project's **Pipelines**). |
+
In the example below, `job` will run only for refs that start with `issue-`,
-whereas all branches will be skipped.
+whereas all branches will be skipped:
```yaml
job:
@@ -460,7 +472,7 @@ job:
```
In this example, `job` will run only for refs that are tagged, or if a build is
-explicitly requested via an API trigger or a [Pipeline Schedule](../../user/project/pipelines/schedules.md).
+explicitly requested via an API trigger or a [Pipeline Schedule][schedules]:
```yaml
job:
@@ -1532,3 +1544,4 @@ CI with various languages.
[ce-7983]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/7983
[ce-7447]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/7447
[ce-3442]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/3442
+[schedules]: ../../user/project/pipelines/schedules.md
diff --git a/doc/development/ux_guide/copy.md b/doc/development/ux_guide/copy.md
index 794c8eb6bfe..12e8d0a31bb 100644
--- a/doc/development/ux_guide/copy.md
+++ b/doc/development/ux_guide/copy.md
@@ -106,6 +106,14 @@ When using verbs or adjectives:
* If the context clearly refers to the object, use them alone. Example: `Edit` or `Closed`
* If the context isn’t clear enough, use them with the object. Example: `Edit issue` or `Closed issues`
+### Search
+
+| Term | Use |
+| ---- | --- |
+| Search | When using all metadata to add criteria that match/don't match. Search can also affect ordering, by ranking best results. |
+| Filter | When taking a single criteria that removes items within a list that match/don't match. Filters do not affect ordering. |
+| Sort | Orders a list based on a single or grouped criteria |
+
### Projects and Groups
| Term | Use | :no_entry_sign: Don't |
diff --git a/doc/university/README.md b/doc/university/README.md
index 399d54bcf23..170582bcd0c 100644
--- a/doc/university/README.md
+++ b/doc/university/README.md
@@ -122,6 +122,7 @@ The curriculum is composed of GitLab videos, screencasts, presentations, project
1. [Setting up GitLab CI for iOS projects](https://about.gitlab.com/2016/03/10/setting-up-gitlab-ci-for-ios-projects/)
1. [IBM: Continuous Delivery vs Continuous Deployment - Video](https://www.youtube.com/watch?v=igwFj8PPSnw)
1. [Amazon: Transition to Continuous Delivery - Video](https://www.youtube.com/watch?v=esEFaY0FDKc)
+2. [TechBeacon: Doing continuous delivery? Focus first on reducing release cycle times](https://techbeacon.com/doing-continuous-delivery-focus-first-reducing-release-cycle-times)
1. See **[Integrations](#integrations)** for integrations with other CI services.
#### 2.4. Workflow
diff --git a/doc/user/index.md b/doc/user/index.md
index 522cf932349..1281cc6e4f0 100644
--- a/doc/user/index.md
+++ b/doc/user/index.md
@@ -66,7 +66,7 @@ For more use cases please check our [Technical Articles](../articles/index.md).
## Projects
-In GitLab, you can create projects for numerous reasons, such as, host
+In GitLab, you can create [projects](project/index.md) for numerous reasons, such as, host
your code, use it as an issue tracker, collaborate on code, and continuously
build, test, and deploy your app with built-in GitLab CI/CD. Or, you can do
it all at once, from one single project.
diff --git a/doc/user/profile/index.md b/doc/user/profile/index.md
index 0e3747817d2..7d25970fcb1 100644
--- a/doc/user/profile/index.md
+++ b/doc/user/profile/index.md
@@ -23,7 +23,7 @@ On your profile page, you will see the following information:
- Personal information
- Activity stream: see your activity streamline and the history of your contributions
- Groups: [groups](../group/index.md) you're a member of
-- Contributed projects: projects you contributed to
+- Contributed projects: [projects](../project/index.md) you contributed to
- Personal projects: your personal projects (respecting the project's visibility level)
- Snippets: your personal code [snippets](../snippets.md#personal-snippets)
diff --git a/doc/user/project/index.md b/doc/user/project/index.md
new file mode 100644
index 00000000000..91a19600951
--- /dev/null
+++ b/doc/user/project/index.md
@@ -0,0 +1,107 @@
+# Projects
+
+In GitLab, you can create projects for hosting
+your codebase, use it as an issue tracker, collaborate on code, and continuously
+build, test, and deploy your app with built-in GitLab CI/CD.
+
+Your projects can be [available](../../public_access/public_access.md)
+publicly, internally, or privately, at your choice. GitLab does not limit
+the number of private projects you create.
+
+## Project's features
+
+When you create a project in GitLab, you'll have access to a large number of
+[features](https://about.gitlab.com/features/):
+
+**Issues and merge requests:**
+
+- [Issue tracker](issues/index.md): Discuss implementations with your team within issues
+ - [Issue Boards](issue_board.md): Organize and prioritize your workflow
+ - [Multiple Issue Boards](https://docs.gitlab.com/ee/user/project/issue_board.html#multiple-issue-boards) (**EES/EEP**): Allow your teams to create their own workflows (Issue Boards) for the same project
+- [Repositories](repository/index.md): Host your code in a fully
+integrated platform
+ - [Protected branches](protected_branches.md): Prevent collaborators
+ from messing with history or pushing code without review
+ - [Protected tags](protected_tags.md): Control over who has
+ permission to create tags, and prevent accidental update or deletion
+- [Merge Requests](merge_requests/index.md): Apply your branching
+strategy and get reviewed by your team
+ - [Merge Request Approvals](https://docs.gitlab.com/ee/user/project/merge_requests/merge_request_approvals.html) (**EES/EEP**): Ask for approval before
+ implementing a change
+ - [Fix merge conflicts from the UI](merge_requests/resolve_conflicts.md):
+ Your Git diff tool right from GitLab's UI
+ - [Review Apps](../../ci/review_apps/index.md): Live preview the results
+ of the changes proposed in a merge request in a per-branch basis
+- [Labels](labels.md): Organize issues and merge requests by labels
+- [Time Tracking](../../workflow/time_tracking.md): Track estimate time
+and time spent on
+ the conclusion of an issue or merge request
+- [Milestones](milestones/index.md): Work towards a target date
+- [Description templates](description_templates.md): Define context-specific
+templates for issue and merge request description fields for your project
+- [Slash commands (quick actions)](quick_actions.md): Textual shortcuts for
+common actions on issues or merge requests
+
+**GitLab CI/CD:**
+
+- [GitLab CI/CD](../../ci/README.md): GitLab's built-in [Continuous Integration, Delivery, and Deployment](https://about.gitlab.com/2016/08/05/continuous-integration-delivery-and-deployment-with-gitlab/) tool
+ - [Container Registry](container_registry.md): Build and push Docker
+ images out-of-the-box
+ - [Auto Deploy](../../ci/autodeploy/index.md): Configure GitLab CI/CD
+ to automatically set up your app's deployment
+ - [Enable and disable GitLab CI](../../ci/enable_or_disable_ci.md)
+ - [Pipelines](../../ci/pipelines.md#pipelines): Configure and visualize
+ your GitLab CI/CD pipelines from the UI
+ - [Scheduled Pipelines](pipelines/schedules.md): Schedule a pipeline
+ to start at a chosen time
+ - [Pipeline Graphs](../../ci/pipelines.md#pipeline-graphs): View your
+ entire pipeline from the UI
+ - [Job artifacts](pipelines/job_artifacts.md): Define,
+ browse, and download job artifacts
+ - [Pipeline settings](pipelines/settings.md): Set up Git strategy (choose the default way your repository is fetched from GitLab in a job),
+ timeout (defines the maximum amount of time in minutes that a job is able run), custom path for `.gitlab-ci.yml`, test coverage parsing, pipeline's visibility, and much more
+- [GitLab Pages](pages/index.md): Build, test, and deploy your static
+website with GitLab Pages
+
+**Other features:**
+
+- [Cycle Analytics](cycle_analytics.md): Review your development lifecycle
+- [Koding integration](koding.md) (not available on GitLab.com): Integrate
+with Koding to have access to a web terminal right from the GitLab UI
+- [Syntax highlighting](highlighting.md): An alternative to customize
+your code blocks, overriding GitLab's default choice of language
+
+### Project's integrations
+
+[Integrate your project](integrations/index.md) with Jira, Mattermost,
+Kubernetes, Slack, and a lot more.
+
+## New project
+
+Learn how to [create a new project](../../gitlab-basics/create-project.md) in GitLab.
+
+### Fork a project
+
+You can [fork a project](../../gitlab-basics/fork-project.md) in order to:
+
+- Collaborate on code by forking a project and creating a merge request
+from your fork to the upstream project
+- Fork a sample project to work on the top of that
+
+## Import or export a project
+
+- Import a project from:
+ - [GitHub to GitLab](../../workflow/importing/import_projects_from_github.md)
+ - [BitBucket to GitLab](../../workflow/importing/import_projects_from_bitbucket.md)
+ - [Gitea to GitLab](../../workflow/importing/import_projects_from_gitea.md)
+ - [FogBugz to GitLab](../../workflow/importing/import_projects_from_fogbugz.md)
+- [Export a project from GitLab](settings/import_export.md#exporting-a-project-and-its-data)
+- [Importing and exporting projects between GitLab instances](settings/import_export.md)
+
+## Leave a project
+
+**Leave project** will only display on the project's dashboard
+when a project is part of a group (under a
+[group namespace](../group/index.md#namespaces)).
+If you choose to leave a project you will no longer be a project
+member, therefore, unable to contribute.
diff --git a/doc/user/project/integrations/jira.md b/doc/user/project/integrations/jira.md
index cfa4c8a93f8..4f583879a4e 100644
--- a/doc/user/project/integrations/jira.md
+++ b/doc/user/project/integrations/jira.md
@@ -1,18 +1,22 @@
# GitLab JIRA integration
-GitLab can be configured to interact with JIRA. Configuration happens via
-user name and password. Connecting to a JIRA server via CAS is not possible.
+GitLab can be configured to interact with [JIRA], a project management platform.
-Each project can be configured to connect to a different JIRA instance, see the
-[configuration](#configuration) section. If you have one JIRA instance you can
-pre-fill the settings page with a default template. To configure the template
-see the [Services Templates][services-templates] document.
+Once your GitLab project is connected to JIRA, you can reference and close the
+issues in JIRA directly from GitLab.
-Once the project is connected to JIRA, you can reference and close the issues
-in JIRA directly from GitLab.
+For a use case, check out this article of [How and why to integrate GitLab with
+JIRA](https://www.programmableweb.com/news/how-and-why-to-integrate-gitlab-jira/how-to/2017/04/25).
## Configuration
+Each GitLab project can be configured to connect to a different JIRA instance.
+If you have one JIRA instance you can pre-fill the settings page with a default
+template, see the [Services Templates][services-templates] docs.
+
+Configuration happens via user name and password. Connecting to a JIRA server
+via CAS is not possible.
+
In order to enable the JIRA service in GitLab, you need to first configure the
project in JIRA and then enter the correct values in GitLab.
@@ -213,3 +217,4 @@ your project needs to close a ticket.
[services-templates]: services_templates.md
[jira-repo-old-docs]: https://gitlab.com/gitlab-org/gitlab-ce/blob/8-13-stable/doc/project_services/jira.md
+[jira]: https://www.atlassian.com/software/jira
diff --git a/doc/user/project/integrations/prometheus_library/haproxy.md b/doc/user/project/integrations/prometheus_library/haproxy.md
index 309da610cc0..f2939f047a3 100644
--- a/doc/user/project/integrations/prometheus_library/haproxy.md
+++ b/doc/user/project/integrations/prometheus_library/haproxy.md
@@ -1,7 +1,7 @@
-# Monitoring HA Proxy
+# Monitoring HAProxy
> [Introduced](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/12621) in GitLab 9.4
-GitLab has support for automatically detecting and monitoring HA Proxy. This is provided by leveraging the [HA Proxy Exporter](https://github.com/hnlq715/nginx-vts-exporter), which translates HA Proxy statistics into a Prometheus readable form.
+GitLab has support for automatically detecting and monitoring HAProxy. This is provided by leveraging the [HAProxy Exporter](https://github.com/prometheus/haproxy_exporter), which translates HAProxy statistics into a Prometheus readable form.
## Metrics supported
@@ -10,9 +10,9 @@ GitLab has support for automatically detecting and monitoring HA Proxy. This is
| Throughput (req/sec) | sum(rate(haproxy_frontend_http_requests_total{%{environment_filter}}[2m])) |
| HTTP Error Rate (%) | sum(rate(haproxy_frontend_http_requests_total{code="5xx",%{environment_filter}}[2m])) / sum(rate(haproxy_frontend_http_requests_total{%{environment_filter}}[2m])) |
-## Configuring Prometheus to monitor for HA Proxy metrics
+## Configuring Prometheus to monitor for HAProxy metrics
-To get started with NGINX monitoring, you should install and configure the [HA Proxy exporter](https://github.com/prometheus/haproxy_exporter) which parses these statistics and translates them into a Prometheus monitoring endpoint.
+To get started with NGINX monitoring, you should install and configure the [HAProxy exporter](https://github.com/prometheus/haproxy_exporter) which parses these statistics and translates them into a Prometheus monitoring endpoint.
## Specifying the Environment label
diff --git a/doc/user/project/integrations/prometheus_library/metrics.md b/doc/user/project/integrations/prometheus_library/metrics.md
index 546e1f51df5..6bdffce9c55 100644
--- a/doc/user/project/integrations/prometheus_library/metrics.md
+++ b/doc/user/project/integrations/prometheus_library/metrics.md
@@ -4,7 +4,7 @@
GitLab offers automatic detection of select [Prometheus exporters](https://prometheus.io/docs/instrumenting/exporters/). Currently supported exporters are:
* [Kubernetes](kubernetes.md)
* [NGINX](nginx.md)
-* [HA Proxy](haproxy.md)
+* [HAProxy](haproxy.md)
* [Amazon Cloud Watch](cloudwatch.md)
We have tried to surface the most important metrics for each exporter, and will be continuing to add support for additional exporters in future releases. If you would like to add support for other official exporters, [contributions](#adding-to-the-library) are welcome.
diff --git a/doc/user/project/koding.md b/doc/user/project/koding.md
index c56a1efe3c2..455e2ee47b4 100644
--- a/doc/user/project/koding.md
+++ b/doc/user/project/koding.md
@@ -1,4 +1,4 @@
-# Koding & GitLab
+# Koding integration
> [Introduced][ce-5909] in GitLab 8.11.
diff --git a/doc/user/project/repository/index.md b/doc/user/project/repository/index.md
index bb41eb41795..4b2c435a120 100644
--- a/doc/user/project/repository/index.md
+++ b/doc/user/project/repository/index.md
@@ -2,7 +2,7 @@
A [repository](https://git-scm.com/book/en/v2/Git-Basics-Getting-a-Git-Repository)
is what you use to store your codebase in GitLab and change it with version control.
-A repository is part of a project, which has a lot of other features.
+A repository is part of a [project](../index.md), which has a lot of other features.
## Create a repository
diff --git a/doc/workflow/gitlab_flow.md b/doc/workflow/gitlab_flow.md
index ea28968fbb2..9d466ae1971 100644
--- a/doc/workflow/gitlab_flow.md
+++ b/doc/workflow/gitlab_flow.md
@@ -91,7 +91,6 @@ This workflow where commits only flow downstream ensures that everything has bee
If you need to cherry-pick a commit with a hotfix it is common to develop it on a feature branch and merge it into master with a merge request, do not delete the feature branch.
If master is good to go (it should be if you are practicing [continuous delivery](http://martinfowler.com/bliki/ContinuousDelivery.html)) you then merge it to the other branches.
If this is not possible because more manual testing is required you can send merge requests from the feature branch to the downstream branches.
-An 'extreme' version of environment branches are setting up an environment for each feature branch as done by [Teatro](https://teatro.io/).
## Release branches with GitLab flow
diff --git a/lib/api/helpers/related_resources_helpers.rb b/lib/api/helpers/related_resources_helpers.rb
index 769cc1457fc..1f677529b07 100644
--- a/lib/api/helpers/related_resources_helpers.rb
+++ b/lib/api/helpers/related_resources_helpers.rb
@@ -12,7 +12,7 @@ module API
end
def expose_url(path)
- url_options = Rails.application.routes.default_url_options
+ url_options = Gitlab::Application.routes.default_url_options
protocol, host, port = url_options.slice(:protocol, :host, :port).values
URI::HTTP.build(scheme: protocol, host: host, port: port, path: path).to_s
diff --git a/lib/api/triggers.rb b/lib/api/triggers.rb
index 9375e7eb768..edfdb63d183 100644
--- a/lib/api/triggers.rb
+++ b/lib/api/triggers.rb
@@ -15,25 +15,22 @@ module API
optional :variables, type: Hash, desc: 'The list of variables to be injected into build'
end
post ":id/(ref/:ref/)trigger/pipeline", requirements: { ref: /.+/ } do
- project = find_project(params[:id])
- trigger = Ci::Trigger.find_by_token(params[:token].to_s)
- not_found! unless project && trigger
- unauthorized! unless trigger.project == project
-
# validate variables
- variables = params[:variables].to_h
- unless variables.all? { |key, value| key.is_a?(String) && value.is_a?(String) }
+ params[:variables] = params[:variables].to_h
+ unless params[:variables].all? { |key, value| key.is_a?(String) && value.is_a?(String) }
render_api_error!('variables needs to be a map of key-valued strings', 400)
end
- # create request and trigger builds
- result = Ci::CreateTriggerRequestService.execute(project, trigger, params[:ref].to_s, variables)
- pipeline = result.pipeline
+ project = find_project(params[:id])
+ not_found! unless project
+
+ result = Ci::PipelineTriggerService.new(project, nil, params).execute
+ not_found! unless result
- if pipeline.persisted?
- present pipeline, with: Entities::Pipeline
+ if result[:http_status]
+ render_api_error!(result[:message], result[:http_status])
else
- render_validation_error!(pipeline)
+ present result[:pipeline], with: Entities::Pipeline
end
end
diff --git a/lib/api/v3/project_hooks.rb b/lib/api/v3/project_hooks.rb
index 94614bfc8b6..51014591a93 100644
--- a/lib/api/v3/project_hooks.rb
+++ b/lib/api/v3/project_hooks.rb
@@ -56,7 +56,9 @@ module API
use :project_hook_properties
end
post ":id/hooks" do
- hook = user_project.hooks.new(declared_params(include_missing: false))
+ attrs = declared_params(include_missing: false)
+ attrs[:job_events] = attrs.delete(:build_events) if attrs.key?(:build_events)
+ hook = user_project.hooks.new(attrs)
if hook.save
present hook, with: ::API::V3::Entities::ProjectHook
@@ -77,7 +79,9 @@ module API
put ":id/hooks/:hook_id" do
hook = user_project.hooks.find(params.delete(:hook_id))
- if hook.update_attributes(declared_params(include_missing: false))
+ attrs = declared_params(include_missing: false)
+ attrs[:job_events] = attrs.delete(:build_events) if attrs.key?(:build_events)
+ if hook.update_attributes(attrs)
present hook, with: ::API::V3::Entities::ProjectHook
else
error!("Invalid url given", 422) if hook.errors[:url].present?
diff --git a/lib/gitlab/data_builder/push.rb b/lib/gitlab/data_builder/push.rb
index 8c8729b6557..5c5f507d44d 100644
--- a/lib/gitlab/data_builder/push.rb
+++ b/lib/gitlab/data_builder/push.rb
@@ -24,11 +24,11 @@ module Gitlab
# total_commits_count: Fixnum
# }
#
- def build(project, user, oldrev, newrev, ref, commits = [], message = nil)
+ def build(project, user, oldrev, newrev, ref, commits = [], message = nil, commits_count: nil)
commits = Array(commits)
# Total commits count
- commits_count = commits.size
+ commits_count ||= commits.size
# Get latest 20 commits ASC
commits_limited = commits.last(20)
diff --git a/lib/gitlab/gitaly_client/repository_service.rb b/lib/gitlab/gitaly_client/repository_service.rb
index f5d84ea8762..13e75b256a7 100644
--- a/lib/gitlab/gitaly_client/repository_service.rb
+++ b/lib/gitlab/gitaly_client/repository_service.rb
@@ -4,12 +4,28 @@ module Gitlab
def initialize(repository)
@repository = repository
@gitaly_repo = repository.gitaly_repository
+ @storage = repository.storage
end
def exists?
request = Gitaly::RepositoryExistsRequest.new(repository: @gitaly_repo)
- GitalyClient.call(@repository.storage, :repository_service, :exists, request).exists
+ GitalyClient.call(@storage, :repository_service, :exists, request).exists
+ end
+
+ def garbage_collect(create_bitmap)
+ request = Gitaly::GarbageCollectRequest.new(repository: @gitaly_repo, create_bitmap: create_bitmap)
+ GitalyClient.call(@storage, :repository_service, :garbage_collect, request)
+ end
+
+ def repack_full(create_bitmap)
+ request = Gitaly::RepackFullRequest.new(repository: @gitaly_repo, create_bitmap: create_bitmap)
+ GitalyClient.call(@storage, :repository_service, :repack_full, request)
+ end
+
+ def repack_incremental
+ request = Gitaly::RepackIncrementalRequest.new(repository: @gitaly_repo)
+ GitalyClient.call(@storage, :repository_service, :repack_incremental, request)
end
end
end
diff --git a/lib/gitlab/ldap/config.rb b/lib/gitlab/ldap/config.rb
index 8eda3ea03f9..c8f19cd52d5 100644
--- a/lib/gitlab/ldap/config.rb
+++ b/lib/gitlab/ldap/config.rb
@@ -18,6 +18,12 @@ module Gitlab
Gitlab.config.ldap.servers.values
end
+ def self.available_servers
+ return [] unless enabled?
+
+ Array.wrap(servers.first)
+ end
+
def self.providers
servers.map { |server| server['provider_name'] }
end
diff --git a/lib/gitlab/request_forgery_protection.rb b/lib/gitlab/request_forgery_protection.rb
index 48dd0487790..ccfe0d6bed3 100644
--- a/lib/gitlab/request_forgery_protection.rb
+++ b/lib/gitlab/request_forgery_protection.rb
@@ -7,6 +7,14 @@ module Gitlab
class Controller < ActionController::Base
protect_from_forgery with: :exception
+ rescue_from ActionController::InvalidAuthenticityToken do |e|
+ logger.warn "This CSRF token verification failure is handled internally by `GitLab::RequestForgeryProtection`"
+ logger.warn "Unlike the logs may suggest, this does not result in an actual 422 response to the user"
+ logger.warn "For API requests, the only effect is that `current_user` will be `nil` for the duration of the request"
+
+ raise e
+ end
+
def index
head :ok
end
diff --git a/lib/mattermost/client.rb b/lib/mattermost/client.rb
index 3d60618006c..d80cd7d2a4e 100644
--- a/lib/mattermost/client.rb
+++ b/lib/mattermost/client.rb
@@ -24,6 +24,10 @@ module Mattermost
json_response session.post(path, options)
end
+ def delete(session, path, options)
+ json_response session.delete(path, options)
+ end
+
def session_get(path, options = {})
with_session do |session|
get(session, path, options)
@@ -36,6 +40,12 @@ module Mattermost
end
end
+ def session_delete(path, options = {})
+ with_session do |session|
+ delete(session, path, options)
+ end
+ end
+
def json_response(response)
json_response = JSON.parse(response.body)
diff --git a/lib/mattermost/team.rb b/lib/mattermost/team.rb
index 2cdbbdece16..b2511f3af1d 100644
--- a/lib/mattermost/team.rb
+++ b/lib/mattermost/team.rb
@@ -14,5 +14,12 @@ module Mattermost
type: type
}.to_json)
end
+
+ # The deletion is done async, so the response is fast.
+ # On the mattermost side, this triggers an soft deletion first, after which
+ # the actuall data is removed
+ def destroy(team_id:)
+ session_delete("/api/v4/teams/#{team_id}?permanent=true")
+ end
end
end
diff --git a/lib/tasks/gitlab/gitaly.rake b/lib/tasks/gitlab/gitaly.rake
index a8db5701d0b..9df07ea8d83 100644
--- a/lib/tasks/gitlab/gitaly.rake
+++ b/lib/tasks/gitlab/gitaly.rake
@@ -19,7 +19,7 @@ namespace :gitlab do
Dir.chdir(args.dir) do
create_gitaly_configuration
- run_command!([command])
+ Bundler.with_original_env { run_command!([command]) }
end
end
diff --git a/spec/controllers/projects/notes_controller_spec.rb b/spec/controllers/projects/notes_controller_spec.rb
index 45f4cf9180d..3b88d5b0d7d 100644
--- a/spec/controllers/projects/notes_controller_spec.rb
+++ b/spec/controllers/projects/notes_controller_spec.rb
@@ -131,7 +131,7 @@ describe Projects::NotesController do
before do
sign_in(user)
- project.team << [user, :developer]
+ project.add_developer(user)
end
it "returns status 302 for html" do
@@ -165,6 +165,66 @@ describe Projects::NotesController do
expect(response).to have_http_status(302)
end
end
+
+ context 'when creating a commit comment from an MR fork' do
+ let(:project) { create(:project) }
+
+ let(:fork_project) do
+ create(:project).tap do |fork|
+ create(:forked_project_link, forked_to_project: fork, forked_from_project: project)
+ end
+ end
+
+ let(:merge_request) do
+ create(:merge_request, source_project: fork_project, target_project: project, source_branch: 'feature', target_branch: 'master')
+ end
+
+ let(:existing_comment) do
+ create(:note_on_commit, note: 'a note', project: fork_project, commit_id: merge_request.commit_shas.first)
+ end
+
+ def post_create(extra_params = {})
+ post :create, {
+ note: { note: 'some other note' },
+ namespace_id: project.namespace,
+ project_id: project,
+ target_type: 'merge_request',
+ target_id: merge_request.id,
+ note_project_id: fork_project.id,
+ in_reply_to_discussion_id: existing_comment.discussion_id
+ }.merge(extra_params)
+ end
+
+ context 'when the note_project_id is not correct' do
+ it 'returns a 404' do
+ post_create(note_project_id: Project.maximum(:id).succ)
+
+ expect(response).to have_http_status(404)
+ end
+ end
+
+ context 'when the user has no access to the fork' do
+ it 'returns a 404' do
+ post_create
+
+ expect(response).to have_http_status(404)
+ end
+ end
+
+ context 'when the user has access to the fork' do
+ let(:discussion) { fork_project.notes.find_discussion(existing_comment.discussion_id) }
+
+ before do
+ fork_project.add_developer(user)
+
+ existing_comment
+ end
+
+ it 'creates the note' do
+ expect { post_create }.to change { fork_project.notes.count }.by(1)
+ end
+ end
+ end
end
describe 'DELETE destroy' do
diff --git a/spec/factories/ci/pipeline_variable_variables.rb b/spec/factories/ci/pipeline_variable_variables.rb
new file mode 100644
index 00000000000..7c1a7faec08
--- /dev/null
+++ b/spec/factories/ci/pipeline_variable_variables.rb
@@ -0,0 +1,8 @@
+FactoryGirl.define do
+ factory :ci_pipeline_variable, class: Ci::PipelineVariable do
+ sequence(:key) { |n| "VARIABLE_#{n}" }
+ value 'VARIABLE_VALUE'
+
+ pipeline factory: :ci_empty_pipeline
+ end
+end
diff --git a/spec/factories/issues.rb b/spec/factories/issues.rb
index f1fd1fd7f73..a16695cb7c1 100644
--- a/spec/factories/issues.rb
+++ b/spec/factories/issues.rb
@@ -16,12 +16,8 @@ FactoryGirl.define do
state :closed
end
- trait :reopened do
- state :reopened
- end
-
factory :closed_issue, traits: [:closed]
- factory :reopened_issue, traits: [:reopened]
+ factory :reopened_issue, traits: [:opened]
factory :labeled_issue do
transient do
diff --git a/spec/factories/merge_requests.rb b/spec/factories/merge_requests.rb
index 253a025af48..1bc530d06db 100644
--- a/spec/factories/merge_requests.rb
+++ b/spec/factories/merge_requests.rb
@@ -44,10 +44,6 @@ FactoryGirl.define do
state :opened
end
- trait :reopened do
- state :reopened
- end
-
trait :locked do
state :locked
end
@@ -74,7 +70,7 @@ FactoryGirl.define do
factory :merged_merge_request, traits: [:merged]
factory :closed_merge_request, traits: [:closed]
- factory :reopened_merge_request, traits: [:reopened]
+ factory :reopened_merge_request, traits: [:opened]
factory :merge_request_with_diffs, traits: [:with_diffs]
factory :merge_request_with_diff_notes do
after(:create) do |mr|
diff --git a/spec/factories/protected_branches.rb b/spec/factories/protected_branches.rb
index b2695e0482a..3dbace4b38a 100644
--- a/spec/factories/protected_branches.rb
+++ b/spec/factories/protected_branches.rb
@@ -3,26 +3,58 @@ FactoryGirl.define do
name
project
- after(:build) do |protected_branch|
- protected_branch.push_access_levels.new(access_level: Gitlab::Access::MASTER)
- protected_branch.merge_access_levels.new(access_level: Gitlab::Access::MASTER)
+ transient do
+ default_push_level true
+ default_merge_level true
+ default_access_level true
end
trait :developers_can_push do
- after(:create) do |protected_branch|
- protected_branch.push_access_levels.first.update!(access_level: Gitlab::Access::DEVELOPER)
+ transient do
+ default_push_level false
+ end
+
+ after(:build) do |protected_branch|
+ protected_branch.push_access_levels.new(access_level: Gitlab::Access::DEVELOPER)
end
end
trait :developers_can_merge do
- after(:create) do |protected_branch|
- protected_branch.merge_access_levels.first.update!(access_level: Gitlab::Access::DEVELOPER)
+ transient do
+ default_merge_level false
+ end
+
+ after(:build) do |protected_branch|
+ protected_branch.merge_access_levels.new(access_level: Gitlab::Access::DEVELOPER)
end
end
trait :no_one_can_push do
- after(:create) do |protected_branch|
- protected_branch.push_access_levels.first.update!(access_level: Gitlab::Access::NO_ACCESS)
+ transient do
+ default_push_level false
+ end
+
+ after(:build) do |protected_branch|
+ protected_branch.push_access_levels.new(access_level: Gitlab::Access::NO_ACCESS)
+ end
+ end
+
+ trait :masters_can_push do
+ transient do
+ default_push_level false
+ end
+
+ after(:build) do |protected_branch|
+ protected_branch.push_access_levels.new(access_level: Gitlab::Access::MASTER)
+ end
+ end
+
+ after(:build) do |protected_branch, evaluator|
+ if evaluator.default_access_level && evaluator.default_push_level
+ protected_branch.push_access_levels.new(access_level: Gitlab::Access::MASTER)
+ end
+ if evaluator.default_access_level && evaluator.default_merge_level
+ protected_branch.merge_access_levels.new(access_level: Gitlab::Access::MASTER)
end
end
end
diff --git a/spec/factories/protected_tags.rb b/spec/factories/protected_tags.rb
index d8e90ae1ee1..225588b23cc 100644
--- a/spec/factories/protected_tags.rb
+++ b/spec/factories/protected_tags.rb
@@ -3,19 +3,43 @@ FactoryGirl.define do
name
project
- after(:build) do |protected_tag|
- protected_tag.create_access_levels.new(access_level: Gitlab::Access::MASTER)
+ transient do
+ default_access_level true
end
trait :developers_can_create do
- after(:create) do |protected_tag|
- protected_tag.create_access_levels.first.update!(access_level: Gitlab::Access::DEVELOPER)
+ transient do
+ default_access_level false
+ end
+
+ after(:build) do |protected_tag|
+ protected_tag.create_access_levels.new(access_level: Gitlab::Access::DEVELOPER)
end
end
trait :no_one_can_create do
- after(:create) do |protected_tag|
- protected_tag.create_access_levels.first.update!(access_level: Gitlab::Access::NO_ACCESS)
+ transient do
+ default_access_level false
+ end
+
+ after(:build) do |protected_tag|
+ protected_tag.create_access_levels.new(access_level: Gitlab::Access::NO_ACCESS)
+ end
+ end
+
+ trait :masters_can_create do
+ transient do
+ default_access_level false
+ end
+
+ after(:build) do |protected_tag|
+ protected_tag.create_access_levels.new(access_level: Gitlab::Access::MASTER)
+ end
+ end
+
+ after(:build) do |protected_tag, evaluator|
+ if evaluator.default_access_level
+ protected_tag.create_access_levels.new(access_level: Gitlab::Access::MASTER)
end
end
end
diff --git a/spec/features/admin/admin_hook_logs_spec.rb b/spec/features/admin/admin_hook_logs_spec.rb
index 710822ac042..7910d5fb72b 100644
--- a/spec/features/admin/admin_hook_logs_spec.rb
+++ b/spec/features/admin/admin_hook_logs_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
feature 'Admin::HookLogs' do
- let(:project) { create(:project) }
+ let(:project) { create(:empty_project) }
let(:system_hook) { create(:system_hook) }
let(:hook_log) { create(:web_hook_log, web_hook: system_hook, internal_error_message: 'some error') }
diff --git a/spec/features/admin/admin_hooks_spec.rb b/spec/features/admin/admin_hooks_spec.rb
index 30fcb334b60..141109fd464 100644
--- a/spec/features/admin/admin_hooks_spec.rb
+++ b/spec/features/admin/admin_hooks_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe 'Admin::Hooks' do
before do
- @project = create(:project)
+ @project = create(:empty_project)
sign_in(create(:admin))
@system_hook = create(:system_hook)
diff --git a/spec/features/admin/admin_projects_spec.rb b/spec/features/admin/admin_projects_spec.rb
index 9856d90bffe..4f69eafcb9d 100644
--- a/spec/features/admin/admin_projects_spec.rb
+++ b/spec/features/admin/admin_projects_spec.rb
@@ -4,17 +4,18 @@ describe "Admin::Projects" do
include Select2Helper
let(:user) { create :user }
- let!(:project) { create(:project) }
- let!(:current_user) { create(:admin) }
+ let(:project) { create(:empty_project) }
+ let(:current_user) { create(:admin) }
before do
sign_in(current_user)
end
describe "GET /admin/projects" do
- let!(:archived_project) { create :project, :public, :archived }
+ let!(:archived_project) { create :empty_project, :public, :archived }
before do
+ expect(project).to be_persisted
visit admin_projects_path
end
@@ -39,15 +40,14 @@ describe "Admin::Projects" do
describe "GET /admin/projects/:namespace_id/:id" do
before do
- visit admin_projects_path
- click_link "#{project.name}"
- end
+ expect(project).to be_persisted
- it do
- expect(current_path).to eq admin_project_path(project)
+ visit admin_projects_path
+ click_link project.name
end
it "has project info" do
+ expect(current_path).to eq admin_project_path(project)
expect(page).to have_content(project.path)
expect(page).to have_content(project.name)
expect(page).to have_content(project.name_with_namespace)
@@ -56,6 +56,9 @@ describe "Admin::Projects" do
end
describe 'transfer project' do
+ # The gitlab-shell transfer will fail for a project without a repository
+ let(:project) { create(:project, :repository) }
+
before do
create(:group, name: 'Web')
diff --git a/spec/features/admin/admin_users_impersonation_tokens_spec.rb b/spec/features/admin/admin_users_impersonation_tokens_spec.rb
index 97ffc54415c..034682dae27 100644
--- a/spec/features/admin/admin_users_impersonation_tokens_spec.rb
+++ b/spec/features/admin/admin_users_impersonation_tokens_spec.rb
@@ -32,11 +32,13 @@ describe 'Admin > Users > Impersonation Tokens', js: true do
check "api"
check "read_user"
- expect { click_on "Create impersonation token" }.to change { PersonalAccessTokensFinder.new(impersonation: true).execute.count }
+ click_on "Create impersonation token"
+
expect(active_impersonation_tokens).to have_text(name)
expect(active_impersonation_tokens).to have_text('In')
expect(active_impersonation_tokens).to have_text('api')
expect(active_impersonation_tokens).to have_text('read_user')
+ expect(PersonalAccessTokensFinder.new(impersonation: true).execute.count).to equal(1)
end
end
diff --git a/spec/features/admin/admin_users_spec.rb b/spec/features/admin/admin_users_spec.rb
index e2e2b13cf8a..0dde8bb696c 100644
--- a/spec/features/admin/admin_users_spec.rb
+++ b/spec/features/admin/admin_users_spec.rb
@@ -257,7 +257,7 @@ describe "Admin::Users" do
describe "GET /admin/users/:id/projects" do
let(:group) { create(:group) }
- let!(:project) { create(:project, group: group) }
+ let!(:project) { create(:empty_project, group: group) }
before do
group.add_developer(user)
diff --git a/spec/features/atom/dashboard_issues_spec.rb b/spec/features/atom/dashboard_issues_spec.rb
index 5aae2dbaf91..d70da7f09e9 100644
--- a/spec/features/atom/dashboard_issues_spec.rb
+++ b/spec/features/atom/dashboard_issues_spec.rb
@@ -4,8 +4,8 @@ describe "Dashboard Issues Feed" do
describe "GET /issues" do
let!(:user) { create(:user, email: 'private1@example.com', public_email: 'public1@example.com') }
let!(:assignee) { create(:user, email: 'private2@example.com', public_email: 'public2@example.com') }
- let!(:project1) { create(:project) }
- let!(:project2) { create(:project) }
+ let!(:project1) { create(:empty_project) }
+ let!(:project2) { create(:empty_project) }
before do
project1.team << [user, :master]
diff --git a/spec/features/atom/dashboard_spec.rb b/spec/features/atom/dashboard_spec.rb
index 321c8a2a670..a7c12853981 100644
--- a/spec/features/atom/dashboard_spec.rb
+++ b/spec/features/atom/dashboard_spec.rb
@@ -19,7 +19,7 @@ describe "Dashboard Feed" do
end
context 'feed content' do
- let(:project) { create(:project) }
+ let(:project) { create(:empty_project) }
let(:issue) { create(:issue, project: project, author: user, description: '') }
let(:note) { create(:note, noteable: issue, author: user, note: 'Bug confirmed', project: project) }
diff --git a/spec/features/atom/issues_spec.rb b/spec/features/atom/issues_spec.rb
index 3eeb4d35131..59e20d7e24d 100644
--- a/spec/features/atom/issues_spec.rb
+++ b/spec/features/atom/issues_spec.rb
@@ -5,7 +5,7 @@ describe 'Issues Feed' do
let!(:user) { create(:user, email: 'private1@example.com', public_email: 'public1@example.com') }
let!(:assignee) { create(:user, email: 'private2@example.com', public_email: 'public2@example.com') }
let!(:group) { create(:group) }
- let!(:project) { create(:project) }
+ let!(:project) { create(:empty_project) }
let!(:issue) { create(:issue, author: user, assignees: [assignee], project: project) }
before do
diff --git a/spec/features/atom/users_spec.rb b/spec/features/atom/users_spec.rb
index 052b07689f5..79069bbca8e 100644
--- a/spec/features/atom/users_spec.rb
+++ b/spec/features/atom/users_spec.rb
@@ -19,7 +19,7 @@ describe "User Feed" do
end
context 'feed content' do
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
let(:issue) do
create(:issue,
project: project,
diff --git a/spec/features/dashboard/archived_projects_spec.rb b/spec/features/dashboard/archived_projects_spec.rb
index 814ec0e59c7..ceac6a0a27c 100644
--- a/spec/features/dashboard/archived_projects_spec.rb
+++ b/spec/features/dashboard/archived_projects_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
RSpec.describe 'Dashboard Archived Project' do
let(:user) { create :user }
let(:project) { create :project}
- let(:archived_project) { create(:project, :archived) }
+ let(:archived_project) { create(:empty_project, :archived) }
before do
project.team << [user, :master]
diff --git a/spec/features/dashboard/datetime_on_tooltips_spec.rb b/spec/features/dashboard/datetime_on_tooltips_spec.rb
index b6dce1b8ec4..05dcdd93f37 100644
--- a/spec/features/dashboard/datetime_on_tooltips_spec.rb
+++ b/spec/features/dashboard/datetime_on_tooltips_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
feature 'Tooltips on .timeago dates', js: true do
let(:user) { create(:user) }
- let(:project) { create(:project, name: 'test', namespace: user.namespace) }
+ let(:project) { create(:empty_project, name: 'test', namespace: user.namespace) }
let(:created_date) { Date.yesterday.to_time }
let(:expected_format) { created_date.in_time_zone.strftime('%b %-d, %Y %l:%M%P') }
diff --git a/spec/features/dashboard/issues_spec.rb b/spec/features/dashboard/issues_spec.rb
index 7c0bf8de14c..82adde6258f 100644
--- a/spec/features/dashboard/issues_spec.rb
+++ b/spec/features/dashboard/issues_spec.rb
@@ -79,15 +79,7 @@ RSpec.describe 'Dashboard Issues' do
end
end
- it 'shows the new issue page', js: true do
- original_defaults = Gitlab::Application.routes.default_url_options
-
- Gitlab::Application.routes.default_url_options = {
- host: Capybara.current_session.server.host,
- port: Capybara.current_session.server.port,
- protocol: 'http'
- }
-
+ it 'shows the new issue page', :js do
find('.new-project-item-select-button').trigger('click')
wait_for_requests
find('.select2-results li').click
@@ -97,8 +89,6 @@ RSpec.describe 'Dashboard Issues' do
page.within('#content-body') do
expect(page).to have_selector('.issue-form')
end
-
- Gitlab::Application.routes.default_url_options = original_defaults
end
end
end
diff --git a/spec/features/dashboard/label_filter_spec.rb b/spec/features/dashboard/label_filter_spec.rb
index b1a207682c3..8e19fb93665 100644
--- a/spec/features/dashboard/label_filter_spec.rb
+++ b/spec/features/dashboard/label_filter_spec.rb
@@ -2,8 +2,8 @@ require 'spec_helper'
describe 'Dashboard > label filter', js: true do
let(:user) { create(:user) }
- let(:project) { create(:project, name: 'test', namespace: user.namespace) }
- let(:project2) { create(:project, name: 'test2', path: 'test2', namespace: user.namespace) }
+ let(:project) { create(:empty_project, name: 'test', namespace: user.namespace) }
+ let(:project2) { create(:empty_project, name: 'test2', path: 'test2', namespace: user.namespace) }
let(:label) { create(:label, title: 'bug', color: '#ff0000') }
let(:label2) { create(:label, title: 'bug') }
diff --git a/spec/features/dashboard/milestone_filter_spec.rb b/spec/features/dashboard/milestone_filter_spec.rb
index c965b565ca3..5ebef1eb097 100644
--- a/spec/features/dashboard/milestone_filter_spec.rb
+++ b/spec/features/dashboard/milestone_filter_spec.rb
@@ -4,7 +4,7 @@ feature 'Dashboard > milestone filter', :js do
include FilterItemSelectHelper
let(:user) { create(:user) }
- let(:project) { create(:project, name: 'test', namespace: user.namespace) }
+ let(:project) { create(:empty_project, name: 'test', namespace: user.namespace) }
let(:milestone) { create(:milestone, title: 'v1.0', project: project) }
let(:milestone2) { create(:milestone, title: 'v2.0', project: project) }
let!(:issue) { create :issue, author: user, project: project, milestone: milestone }
diff --git a/spec/features/dashboard/todos/target_state_spec.rb b/spec/features/dashboard/todos/target_state_spec.rb
index 030a86d1c01..93da36c08fc 100644
--- a/spec/features/dashboard/todos/target_state_spec.rb
+++ b/spec/features/dashboard/todos/target_state_spec.rb
@@ -3,7 +3,7 @@ require 'rails_helper'
feature 'Dashboard > Todo target states' do
let(:user) { create(:user) }
let(:author) { create(:user) }
- let(:project) { create(:project, :public) }
+ let(:project) { create(:empty_project, :public) }
before do
sign_in(user)
diff --git a/spec/features/dashboard/todos/todos_spec.rb b/spec/features/dashboard/todos/todos_spec.rb
index 30bab7eeaa7..c2a61cf5aff 100644
--- a/spec/features/dashboard/todos/todos_spec.rb
+++ b/spec/features/dashboard/todos/todos_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
feature 'Dashboard Todos' do
let(:user) { create(:user) }
let(:author) { create(:user) }
- let(:project) { create(:project, :public) }
+ let(:project) { create(:empty_project, :public) }
let(:issue) { create(:issue, due_date: Date.today) }
context 'User does not have todos' do
@@ -212,7 +212,7 @@ feature 'Dashboard Todos' do
note1 = create(:note_on_issue, note: "Hello #{label1.to_reference(format: :name)}", noteable_id: issue.id, noteable_type: 'Issue', project: issue.project)
create(:todo, :mentioned, project: project, target: issue, user: user, note_id: note1.id)
- project2 = create(:project, :public)
+ project2 = create(:empty_project, :public)
label2 = create(:label, project: project2)
issue2 = create(:issue, project: project2)
note2 = create(:note_on_issue, note: "Test #{label2.to_reference(format: :name)}", noteable_id: issue2.id, noteable_type: 'Issue', project: project2)
diff --git a/spec/features/dashboard/user_filters_projects_spec.rb b/spec/features/dashboard/user_filters_projects_spec.rb
index c352b6ded14..a88fe207e0e 100644
--- a/spec/features/dashboard/user_filters_projects_spec.rb
+++ b/spec/features/dashboard/user_filters_projects_spec.rb
@@ -2,9 +2,9 @@ require 'spec_helper'
describe 'Dashboard > User filters projects' do
let(:user) { create(:user) }
- let(:project) { create(:project, name: 'Victorialand', namespace: user.namespace) }
+ let(:project) { create(:empty_project, name: 'Victorialand', namespace: user.namespace) }
let(:user2) { create(:user) }
- let(:project2) { create(:project, name: 'Treasure', namespace: user2.namespace) }
+ let(:project2) { create(:empty_project, name: 'Treasure', namespace: user2.namespace) }
before do
project.team << [user, :master]
diff --git a/spec/features/explore/new_menu_spec.rb b/spec/features/explore/new_menu_spec.rb
index 2cd06258e22..b1ccf80c28e 100644
--- a/spec/features/explore/new_menu_spec.rb
+++ b/spec/features/explore/new_menu_spec.rb
@@ -4,7 +4,7 @@ feature 'Top Plus Menu', :js do
let(:user) { create(:user) }
let(:group) { create(:group) }
let(:project) { create(:project, :repository, creator: user, namespace: user.namespace) }
- let(:public_project) { create(:project, :public) }
+ let(:public_project) { create(:empty_project, :public) }
before do
group.add_owner(user)
diff --git a/spec/features/groups/group_settings_spec.rb b/spec/features/groups/group_settings_spec.rb
index 47553922ede..121df1ec635 100644
--- a/spec/features/groups/group_settings_spec.rb
+++ b/spec/features/groups/group_settings_spec.rb
@@ -49,7 +49,7 @@ feature 'Edit group settings' do
end
context 'with a project' do
- given!(:project) { create(:project, group: group, path: 'project') }
+ given!(:project) { create(:empty_project, group: group) }
given(:old_project_full_path) { "/#{group.path}/#{project.path}" }
given(:new_project_full_path) { "/#{new_group_path}/#{project.path}" }
@@ -65,14 +65,14 @@ feature 'Edit group settings' do
update_path(new_group_path)
visit new_project_full_path
expect(current_path).to eq(new_project_full_path)
- expect(find('h1.project-title')).to have_content(project.name)
+ expect(find('h1.title')).to have_content(project.path)
end
scenario 'the old project path redirects to the new path' do
update_path(new_group_path)
visit old_project_full_path
expect(current_path).to eq(new_project_full_path)
- expect(find('h1.project-title')).to have_content(project.name)
+ expect(find('h1.title')).to have_content(project.path)
end
end
end
diff --git a/spec/features/groups/members/request_access_spec.rb b/spec/features/groups/members/request_access_spec.rb
index 1f3c7fd3859..6141981023c 100644
--- a/spec/features/groups/members/request_access_spec.rb
+++ b/spec/features/groups/members/request_access_spec.rb
@@ -4,7 +4,7 @@ feature 'Groups > Members > Request access' do
let(:user) { create(:user) }
let(:owner) { create(:user) }
let(:group) { create(:group, :public, :access_requestable) }
- let!(:project) { create(:project, :private, namespace: group) }
+ let!(:project) { create(:empty_project, :private, namespace: group) }
background do
group.add_owner(owner)
diff --git a/spec/features/groups/merge_requests_spec.rb b/spec/features/groups/merge_requests_spec.rb
index cbf147b6a5c..c2241feb9f7 100644
--- a/spec/features/groups/merge_requests_spec.rb
+++ b/spec/features/groups/merge_requests_spec.rb
@@ -7,7 +7,7 @@ feature 'Group merge requests page' do
include_examples 'project features apply to issuables', MergeRequest
context 'archived issuable' do
- let(:project_archived) { create(:project, :archived, :merge_requests_enabled, group: group) }
+ let(:project_archived) { create(:project, :archived, :merge_requests_enabled, :repository, group: group) }
let(:issuable_archived) { create(:merge_request, source_project: project_archived, target_project: project_archived, title: 'issuable of an archived project') }
let(:access_level) { ProjectFeature::ENABLED }
let(:user) { user_in_group }
diff --git a/spec/features/issuables/close_reopen_report_toggle_spec.rb b/spec/features/issuables/close_reopen_report_toggle_spec.rb
index cf1f0624140..0e43eed8699 100644
--- a/spec/features/issuables/close_reopen_report_toggle_spec.rb
+++ b/spec/features/issuables/close_reopen_report_toggle_spec.rb
@@ -79,7 +79,7 @@ describe 'Issuables Close/Reopen/Report toggle' do
end
context 'on a merge request' do
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
let(:issuable) { create(:merge_request, source_project: project) }
before do
@@ -96,7 +96,7 @@ describe 'Issuables Close/Reopen/Report toggle' do
end
context 'when user doesnt have permission to update' do
- let(:cant_project) { create(:project) }
+ let(:cant_project) { create(:project, :repository) }
let(:cant_issuable) { create(:merge_request, source_project: cant_project) }
before do
diff --git a/spec/features/issuables/user_sees_sidebar_spec.rb b/spec/features/issuables/user_sees_sidebar_spec.rb
index 948d151a517..2bd1c8aab86 100644
--- a/spec/features/issuables/user_sees_sidebar_spec.rb
+++ b/spec/features/issuables/user_sees_sidebar_spec.rb
@@ -3,7 +3,7 @@ require 'rails_helper'
describe 'Issue Sidebar on Mobile' do
include MobileHelpers
- let(:project) { create(:project, :public) }
+ let(:project) { create(:project, :public, :repository) }
let(:merge_request) { create(:merge_request, source_project: project) }
let(:issue) { create(:issue, project: project) }
let!(:user) { create(:user)}
diff --git a/spec/features/issues/award_emoji_spec.rb b/spec/features/issues/award_emoji_spec.rb
index 134e618feac..6cb0bf6fdfd 100644
--- a/spec/features/issues/award_emoji_spec.rb
+++ b/spec/features/issues/award_emoji_spec.rb
@@ -1,7 +1,7 @@
require 'rails_helper'
describe 'Awards Emoji' do
- let!(:project) { create(:project, :public) }
+ let!(:project) { create(:empty_project, :public) }
let!(:user) { create(:user) }
let(:issue) do
create(:issue,
diff --git a/spec/features/issues/award_spec.rb b/spec/features/issues/award_spec.rb
index e95eb19f7d1..740281c1050 100644
--- a/spec/features/issues/award_spec.rb
+++ b/spec/features/issues/award_spec.rb
@@ -2,7 +2,7 @@ require 'rails_helper'
feature 'Issue awards', js: true do
let(:user) { create(:user) }
- let(:project) { create(:project, :public) }
+ let(:project) { create(:empty_project, :public) }
let(:issue) { create(:issue, project: project) }
describe 'logged in' do
diff --git a/spec/features/issues/bulk_assignment_labels_spec.rb b/spec/features/issues/bulk_assignment_labels_spec.rb
index 847e3856ba5..5acf8fdae84 100644
--- a/spec/features/issues/bulk_assignment_labels_spec.rb
+++ b/spec/features/issues/bulk_assignment_labels_spec.rb
@@ -2,7 +2,7 @@ require 'rails_helper'
feature 'Issues > Labels bulk assignment' do
let(:user) { create(:user) }
- let!(:project) { create(:project) }
+ let!(:project) { create(:empty_project) }
let!(:issue1) { create(:issue, project: project, title: "Issue 1") }
let!(:issue2) { create(:issue, project: project, title: "Issue 2") }
let!(:bug) { create(:label, project: project, title: 'bug') }
diff --git a/spec/features/issues/create_branch_merge_request_spec.rb b/spec/features/issues/create_branch_merge_request_spec.rb
index 88e81d12602..f59f687cf51 100644
--- a/spec/features/issues/create_branch_merge_request_spec.rb
+++ b/spec/features/issues/create_branch_merge_request_spec.rb
@@ -2,7 +2,7 @@ require 'rails_helper'
feature 'Create Branch/Merge Request Dropdown on issue page', js: true do
let(:user) { create(:user) }
- let!(:project) { create(:project) }
+ let!(:project) { create(:project, :repository) }
let(:issue) { create(:issue, project: project, title: 'Cherry-Coloured Funk') }
context 'for team members' do
@@ -15,16 +15,14 @@ feature 'Create Branch/Merge Request Dropdown on issue page', js: true do
visit project_issue_path(project, issue)
select_dropdown_option('create-mr')
+
+ expect(page).to have_content('WIP: Resolve "Cherry-Coloured Funk"')
+ expect(current_path).to eq(project_merge_request_path(project, MergeRequest.first))
- wait_for_requests
+ visit project_issue_path(project, issue)
expect(page).to have_content("created branch 1-cherry-coloured-funk")
expect(page).to have_content("mentioned in merge request !1")
-
- visit project_merge_request_path(project, MergeRequest.first)
-
- expect(page).to have_content('WIP: Resolve "Cherry-Coloured Funk"')
- expect(current_path).to eq(project_merge_request_path(project, MergeRequest.first))
end
it 'allows creating a branch from the issue page' do
diff --git a/spec/features/issues/create_issue_for_discussions_in_merge_request_spec.rb b/spec/features/issues/create_issue_for_discussions_in_merge_request_spec.rb
index 3c51e8053da..80cc8d22999 100644
--- a/spec/features/issues/create_issue_for_discussions_in_merge_request_spec.rb
+++ b/spec/features/issues/create_issue_for_discussions_in_merge_request_spec.rb
@@ -2,7 +2,7 @@ require 'rails_helper'
feature 'Resolving all open discussions in a merge request from an issue', js: true do
let(:user) { create(:user) }
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
let(:merge_request) { create(:merge_request, source_project: project) }
let!(:discussion) { create(:diff_note_on_merge_request, noteable: merge_request, project: project).to_discussion }
diff --git a/spec/features/issues/create_issue_for_single_discussion_in_merge_request_spec.rb b/spec/features/issues/create_issue_for_single_discussion_in_merge_request_spec.rb
index d468c7d9c75..ad5fd0fd97b 100644
--- a/spec/features/issues/create_issue_for_single_discussion_in_merge_request_spec.rb
+++ b/spec/features/issues/create_issue_for_single_discussion_in_merge_request_spec.rb
@@ -2,7 +2,7 @@ require 'rails_helper'
feature 'Resolve an open discussion in a merge request by creating an issue' do
let(:user) { create(:user) }
- let(:project) { create(:project, only_allow_merge_if_all_discussions_are_resolved: true) }
+ let(:project) { create(:project, :repository, only_allow_merge_if_all_discussions_are_resolved: true) }
let(:merge_request) { create(:merge_request, source_project: project) }
let!(:discussion) { create(:diff_note_on_merge_request, noteable: merge_request, project: project).to_discussion }
diff --git a/spec/features/issues/filtered_search/filter_issues_spec.rb b/spec/features/issues/filtered_search/filter_issues_spec.rb
index cd2cbf4bfe7..265bcb3a8e5 100644
--- a/spec/features/issues/filtered_search/filter_issues_spec.rb
+++ b/spec/features/issues/filtered_search/filter_issues_spec.rb
@@ -5,7 +5,7 @@ describe 'Filter issues', js: true do
include FilteredSearchHelpers
let!(:group) { create(:group) }
- let!(:project) { create(:project, group: group) }
+ let!(:project) { create(:empty_project, group: group) }
let!(:user) { create(:user, username: 'joe', name: 'Joe') }
let!(:user2) { create(:user, username: 'jane') }
let!(:label) { create(:label, project: project) }
diff --git a/spec/features/issues/form_spec.rb b/spec/features/issues/form_spec.rb
index b56b8744d7e..0ba02ba42ba 100644
--- a/spec/features/issues/form_spec.rb
+++ b/spec/features/issues/form_spec.rb
@@ -4,7 +4,7 @@ describe 'New/edit issue', :js do
include ActionView::Helpers::JavaScriptHelper
include FormHelper
- let!(:project) { create(:project) }
+ let!(:project) { create(:empty_project) }
let!(:user) { create(:user)}
let!(:user2) { create(:user)}
let!(:milestone) { create(:milestone, project: project) }
diff --git a/spec/features/issues/gfm_autocomplete_spec.rb b/spec/features/issues/gfm_autocomplete_spec.rb
index b84635c5134..1b36f16e8b6 100644
--- a/spec/features/issues/gfm_autocomplete_spec.rb
+++ b/spec/features/issues/gfm_autocomplete_spec.rb
@@ -2,7 +2,7 @@ require 'rails_helper'
feature 'GFM autocomplete', js: true do
let(:user) { create(:user, name: '💃speciąl someone💃', username: 'someone.special') }
- let(:project) { create(:project) }
+ let(:project) { create(:empty_project) }
let(:label) { create(:label, project: project, title: 'special+') }
let(:issue) { create(:issue, project: project) }
diff --git a/spec/features/issues/issue_detail_spec.rb b/spec/features/issues/issue_detail_spec.rb
index 28b636f9359..a7a7e02b59c 100644
--- a/spec/features/issues/issue_detail_spec.rb
+++ b/spec/features/issues/issue_detail_spec.rb
@@ -2,7 +2,7 @@ require 'rails_helper'
feature 'Issue Detail', :js do
let(:user) { create(:user) }
- let(:project) { create(:project, :public) }
+ let(:project) { create(:empty_project, :public) }
let(:issue) { create(:issue, project: project, author: user) }
context 'when user displays the issue' do
diff --git a/spec/features/issues/issue_sidebar_spec.rb b/spec/features/issues/issue_sidebar_spec.rb
index 8e22441e0e8..28f93cfd971 100644
--- a/spec/features/issues/issue_sidebar_spec.rb
+++ b/spec/features/issues/issue_sidebar_spec.rb
@@ -4,7 +4,7 @@ feature 'Issue Sidebar' do
include MobileHelpers
let(:group) { create(:group, :nested) }
- let(:project) { create(:project, :public, namespace: group) }
+ let(:project) { create(:empty_project, :public, namespace: group) }
let(:issue) { create(:issue, project: project) }
let!(:user) { create(:user)}
let!(:label) { create(:label, project: project, title: 'bug') }
diff --git a/spec/features/issues/markdown_toolbar_spec.rb b/spec/features/issues/markdown_toolbar_spec.rb
index 6aed27e8790..0f869970460 100644
--- a/spec/features/issues/markdown_toolbar_spec.rb
+++ b/spec/features/issues/markdown_toolbar_spec.rb
@@ -1,9 +1,9 @@
require 'rails_helper'
feature 'Issue markdown toolbar', js: true do
- let(:project) { create(:project, :public) }
+ let(:project) { create(:empty_project, :public) }
let(:issue) { create(:issue, project: project) }
- let(:user) { create(:user) }
+ let(:user) { create(:user) }
before do
sign_in(user)
diff --git a/spec/features/issues/move_spec.rb b/spec/features/issues/move_spec.rb
index 833eb47efb2..2ab7d1a71b7 100644
--- a/spec/features/issues/move_spec.rb
+++ b/spec/features/issues/move_spec.rb
@@ -2,7 +2,7 @@ require 'rails_helper'
feature 'issue move to another project' do
let(:user) { create(:user) }
- let(:old_project) { create(:project) }
+ let(:old_project) { create(:project, :repository) }
let(:text) { 'Some issue description' }
let(:issue) do
@@ -25,8 +25,8 @@ feature 'issue move to another project' do
context 'user has permission to move issue' do
let!(:mr) { create(:merge_request, source_project: old_project) }
- let(:new_project) { create(:project) }
- let(:new_project_search) { create(:project) }
+ let(:new_project) { create(:empty_project) }
+ let(:new_project_search) { create(:empty_project) }
let(:text) { "Text with #{mr.to_reference}" }
let(:cross_reference) { old_project.to_reference(new_project) }
@@ -63,8 +63,8 @@ feature 'issue move to another project' do
end
context 'user does not have permission to move the issue to a project', js: true do
- let!(:private_project) { create(:project, :private) }
- let(:another_project) { create(:project) }
+ let!(:private_project) { create(:empty_project, :private) }
+ let(:another_project) { create(:empty_project) }
background { another_project.team << [user, :guest] }
scenario 'browsing projects in projects select' do
diff --git a/spec/features/issues/notes_on_issues_spec.rb b/spec/features/issues/notes_on_issues_spec.rb
index be4c23645d9..29c9b99030a 100644
--- a/spec/features/issues/notes_on_issues_spec.rb
+++ b/spec/features/issues/notes_on_issues_spec.rb
@@ -35,42 +35,42 @@ describe 'Create notes on issues', :js do
context 'mentioning issue on a private project' do
it_behaves_like 'notes with reference' do
- let(:project) { create(:project, :private) }
+ let(:project) { create(:empty_project, :private) }
let(:mention) { create(:issue, project: project) }
end
end
context 'mentioning issue on an internal project' do
it_behaves_like 'notes with reference' do
- let(:project) { create(:project, :internal) }
+ let(:project) { create(:empty_project, :internal) }
let(:mention) { create(:issue, project: project) }
end
end
context 'mentioning issue on a public project' do
it_behaves_like 'notes with reference' do
- let(:project) { create(:project, :public) }
+ let(:project) { create(:empty_project, :public) }
let(:mention) { create(:issue, project: project) }
end
end
context 'mentioning merge request on a private project' do
it_behaves_like 'notes with reference' do
- let(:project) { create(:project, :private) }
+ let(:project) { create(:project, :private, :repository) }
let(:mention) { create(:merge_request, source_project: project) }
end
end
context 'mentioning merge request on an internal project' do
it_behaves_like 'notes with reference' do
- let(:project) { create(:project, :internal) }
+ let(:project) { create(:project, :internal, :repository) }
let(:mention) { create(:merge_request, source_project: project) }
end
end
context 'mentioning merge request on a public project' do
it_behaves_like 'notes with reference' do
- let(:project) { create(:project, :public) }
+ let(:project) { create(:project, :public, :repository) }
let(:mention) { create(:merge_request, source_project: project) }
end
end
diff --git a/spec/features/issues/spam_issues_spec.rb b/spec/features/issues/spam_issues_spec.rb
index 332ce78b138..7a05e8b2ccc 100644
--- a/spec/features/issues/spam_issues_spec.rb
+++ b/spec/features/issues/spam_issues_spec.rb
@@ -3,7 +3,7 @@ require 'rails_helper'
describe 'New issue', js: true do
include StubENV
- let(:project) { create(:project, :public) }
+ let(:project) { create(:empty_project, :public) }
let(:user) { create(:user)}
before do
diff --git a/spec/features/issues/todo_spec.rb b/spec/features/issues/todo_spec.rb
index 7ca5ef4649a..2460ae817f9 100644
--- a/spec/features/issues/todo_spec.rb
+++ b/spec/features/issues/todo_spec.rb
@@ -1,9 +1,9 @@
require 'rails_helper'
feature 'Manually create a todo item from issue', js: true do
- let!(:project) { create(:project) }
- let!(:issue) { create(:issue, project: project) }
- let!(:user) { create(:user)}
+ let!(:project) { create(:empty_project) }
+ let!(:issue) { create(:issue, project: project) }
+ let!(:user) { create(:user)}
before do
project.team << [user, :master]
diff --git a/spec/features/issues/update_issues_spec.rb b/spec/features/issues/update_issues_spec.rb
index 5a7c4f54cb6..389151e63f0 100644
--- a/spec/features/issues/update_issues_spec.rb
+++ b/spec/features/issues/update_issues_spec.rb
@@ -1,7 +1,7 @@
require 'rails_helper'
feature 'Multiple issue updating from issues#index', :js do
- let!(:project) { create(:project) }
+ let!(:project) { create(:empty_project) }
let!(:issue) { create(:issue, project: project) }
let!(:user) { create(:user)}
diff --git a/spec/features/issues/user_uses_slash_commands_spec.rb b/spec/features/issues/user_uses_slash_commands_spec.rb
index 4b63cc844f3..d28ad52ff56 100644
--- a/spec/features/issues/user_uses_slash_commands_spec.rb
+++ b/spec/features/issues/user_uses_slash_commands_spec.rb
@@ -9,7 +9,7 @@ feature 'Issues > User uses quick actions', js: true do
describe 'issue-only commands' do
let(:user) { create(:user) }
- let(:project) { create(:project, :public) }
+ let(:project) { create(:empty_project, :public) }
before do
project.team << [user, :master]
diff --git a/spec/features/merge_requests/assign_issues_spec.rb b/spec/features/merge_requests/assign_issues_spec.rb
index 04c2a694fff..63fa72650ac 100644
--- a/spec/features/merge_requests/assign_issues_spec.rb
+++ b/spec/features/merge_requests/assign_issues_spec.rb
@@ -2,7 +2,7 @@ require 'rails_helper'
feature 'Merge request issue assignment', js: true do
let(:user) { create(:user) }
- let(:project) { create(:project, :public) }
+ let(:project) { create(:project, :public, :repository) }
let(:issue1) { create(:issue, project: project) }
let(:issue2) { create(:issue, project: project) }
let(:merge_request) { create(:merge_request, :simple, source_project: project, author: user, description: "fixes #{issue1.to_reference} and #{issue2.to_reference}") }
diff --git a/spec/features/merge_requests/award_spec.rb b/spec/features/merge_requests/award_spec.rb
index 5a12d6f43f3..e886309133d 100644
--- a/spec/features/merge_requests/award_spec.rb
+++ b/spec/features/merge_requests/award_spec.rb
@@ -2,7 +2,7 @@ require 'rails_helper'
feature 'Merge request awards', js: true do
let(:user) { create(:user) }
- let(:project) { create(:project, :public) }
+ let(:project) { create(:project, :public, :repository) }
let(:merge_request) { create(:merge_request, source_project: project) }
describe 'logged in' do
diff --git a/spec/features/merge_requests/check_if_mergeable_with_unresolved_discussions_spec.rb b/spec/features/merge_requests/check_if_mergeable_with_unresolved_discussions_spec.rb
index c3d7d2fa23f..1f5e7b55fb0 100644
--- a/spec/features/merge_requests/check_if_mergeable_with_unresolved_discussions_spec.rb
+++ b/spec/features/merge_requests/check_if_mergeable_with_unresolved_discussions_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
feature 'Check if mergeable with unresolved discussions', js: true do
let(:user) { create(:user) }
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
let!(:merge_request) { create(:merge_request_with_diff_notes, source_project: project, author: user) }
before do
diff --git a/spec/features/merge_requests/cherry_pick_spec.rb b/spec/features/merge_requests/cherry_pick_spec.rb
index e4c33d57e8d..4b1e1b9a8d4 100644
--- a/spec/features/merge_requests/cherry_pick_spec.rb
+++ b/spec/features/merge_requests/cherry_pick_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe 'Cherry-pick Merge Requests', js: true do
let(:user) { create(:user) }
let(:group) { create(:group) }
- let(:project) { create(:project, namespace: group) }
+ let(:project) { create(:project, :repository, namespace: group) }
let(:merge_request) { create(:merge_request_with_diffs, source_project: project, author: user) }
before do
diff --git a/spec/features/merge_requests/closes_issues_spec.rb b/spec/features/merge_requests/closes_issues_spec.rb
index 24000ea75d1..0e97254eada 100644
--- a/spec/features/merge_requests/closes_issues_spec.rb
+++ b/spec/features/merge_requests/closes_issues_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
feature 'Merge Request closing issues message', js: true do
let(:user) { create(:user) }
- let(:project) { create(:project, :public) }
+ let(:project) { create(:project, :public, :repository) }
let(:issue_1) { create(:issue, project: project)}
let(:issue_2) { create(:issue, project: project)}
let(:merge_request) do
diff --git a/spec/features/merge_requests/conflicts_spec.rb b/spec/features/merge_requests/conflicts_spec.rb
index 3c5ddf8396d..2c560632a1b 100644
--- a/spec/features/merge_requests/conflicts_spec.rb
+++ b/spec/features/merge_requests/conflicts_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
feature 'Merge request conflict resolution', js: true do
let(:user) { create(:user) }
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
before do
# In order to have the diffs collapsed, we need to disable the increase feature
diff --git a/spec/features/merge_requests/create_new_mr_spec.rb b/spec/features/merge_requests/create_new_mr_spec.rb
index 67322bdc8a8..11a74276898 100644
--- a/spec/features/merge_requests/create_new_mr_spec.rb
+++ b/spec/features/merge_requests/create_new_mr_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
feature 'Create New Merge Request', js: true do
let(:user) { create(:user) }
- let(:project) { create(:project, :public) }
+ let(:project) { create(:project, :public, :repository) }
before do
project.team << [user, :master]
@@ -63,7 +63,7 @@ feature 'Create New Merge Request', js: true do
context 'when target project cannot be viewed by the current user' do
it 'does not leak the private project name & namespace' do
- private_project = create(:project, :private)
+ private_project = create(:project, :private, :repository)
visit project_new_merge_request_path(project, merge_request: { target_project_id: private_project.id })
@@ -74,7 +74,7 @@ feature 'Create New Merge Request', js: true do
context 'when source project cannot be viewed by the current user' do
it 'does not leak the private project name & namespace' do
- private_project = create(:project, :private)
+ private_project = create(:project, :private, :repository)
visit project_new_merge_request_path(project, merge_request: { source_project_id: private_project.id })
diff --git a/spec/features/merge_requests/created_from_fork_spec.rb b/spec/features/merge_requests/created_from_fork_spec.rb
index 9b7795ace62..09541873f71 100644
--- a/spec/features/merge_requests/created_from_fork_spec.rb
+++ b/spec/features/merge_requests/created_from_fork_spec.rb
@@ -2,8 +2,8 @@ require 'spec_helper'
feature 'Merge request created from fork' do
given(:user) { create(:user) }
- given(:project) { create(:project, :public) }
- given(:fork_project) { create(:project, :public) }
+ given(:project) { create(:project, :public, :repository) }
+ given(:fork_project) { create(:project, :public, :repository) }
given!(:merge_request) do
create(:forked_project_link, forked_to_project: fork_project,
@@ -25,6 +25,33 @@ feature 'Merge request created from fork' do
expect(page).to have_content 'Test merge request'
end
+ context 'when a commit comment exists on the merge request' do
+ given(:comment) { 'A commit comment' }
+ given(:reply) { 'A reply comment' }
+
+ background do
+ create(:note_on_commit, note: comment,
+ project: fork_project,
+ commit_id: merge_request.commit_shas.first)
+ end
+
+ scenario 'user can reply to the comment', js: true do
+ visit_merge_request(merge_request)
+
+ expect(page).to have_content(comment)
+
+ page.within('.discussion-notes') do
+ find('.btn-text-field').click
+ find('#note_note').send_keys(reply)
+ find('.comment-btn').click
+ end
+
+ wait_for_requests
+
+ expect(page).to have_content(reply)
+ end
+ end
+
context 'source project is deleted' do
background do
MergeRequests::MergeService.new(project, user).execute(merge_request)
diff --git a/spec/features/merge_requests/diff_notes_avatars_spec.rb b/spec/features/merge_requests/diff_notes_avatars_spec.rb
index 7f082f12d47..2d9419d6124 100644
--- a/spec/features/merge_requests/diff_notes_avatars_spec.rb
+++ b/spec/features/merge_requests/diff_notes_avatars_spec.rb
@@ -4,7 +4,7 @@ feature 'Diff note avatars', js: true do
include NoteInteractionHelpers
let(:user) { create(:user) }
- let(:project) { create(:project, :public) }
+ let(:project) { create(:project, :public, :repository) }
let(:merge_request) { create(:merge_request_with_diffs, source_project: project, author: user, title: "Bug NS-04") }
let(:path) { "files/ruby/popen.rb" }
let(:position) do
diff --git a/spec/features/merge_requests/diff_notes_resolve_spec.rb b/spec/features/merge_requests/diff_notes_resolve_spec.rb
index a2f0b24d6a8..ac7f75bd308 100644
--- a/spec/features/merge_requests/diff_notes_resolve_spec.rb
+++ b/spec/features/merge_requests/diff_notes_resolve_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
feature 'Diff notes resolve', js: true do
let(:user) { create(:user) }
- let(:project) { create(:project, :public) }
+ let(:project) { create(:project, :public, :repository) }
let(:merge_request) { create(:merge_request_with_diffs, source_project: project, author: user, title: "Bug NS-04") }
let!(:note) { create(:diff_note_on_merge_request, project: project, noteable: merge_request) }
let(:path) { "files/ruby/popen.rb" }
diff --git a/spec/features/merge_requests/diffs_spec.rb b/spec/features/merge_requests/diffs_spec.rb
index 499cd38e648..201be4b9e40 100644
--- a/spec/features/merge_requests/diffs_spec.rb
+++ b/spec/features/merge_requests/diffs_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
feature 'Diffs URL', js: true do
- let(:project) { create(:project, :public) }
+ let(:project) { create(:project, :public, :repository) }
let(:merge_request) { create(:merge_request, source_project: project) }
context 'when visit with */* as accept header' do
diff --git a/spec/features/merge_requests/edit_mr_spec.rb b/spec/features/merge_requests/edit_mr_spec.rb
index 2b0ecfc8c72..7386e78fb13 100644
--- a/spec/features/merge_requests/edit_mr_spec.rb
+++ b/spec/features/merge_requests/edit_mr_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
feature 'Edit Merge Request' do
let(:user) { create(:user) }
- let(:project) { create(:project, :public) }
+ let(:project) { create(:project, :public, :repository) }
let(:merge_request) { create(:merge_request, :simple, source_project: project) }
before do
diff --git a/spec/features/merge_requests/filter_by_labels_spec.rb b/spec/features/merge_requests/filter_by_labels_spec.rb
index 220e0c8dc68..1d52a4659ad 100644
--- a/spec/features/merge_requests/filter_by_labels_spec.rb
+++ b/spec/features/merge_requests/filter_by_labels_spec.rb
@@ -1,10 +1,10 @@
require 'rails_helper'
-feature 'Issue filtering by Labels', js: true do
+feature 'Merge Request filtering by Labels', js: true do
include FilteredSearchHelpers
include MergeRequestHelpers
- let(:project) { create(:project, :public) }
+ let(:project) { create(:project, :public, :repository) }
let!(:user) { create(:user) }
let!(:label) { create(:label, project: project) }
diff --git a/spec/features/merge_requests/filter_by_milestone_spec.rb b/spec/features/merge_requests/filter_by_milestone_spec.rb
index f6b9aa733a4..521fcabc881 100644
--- a/spec/features/merge_requests/filter_by_milestone_spec.rb
+++ b/spec/features/merge_requests/filter_by_milestone_spec.rb
@@ -4,7 +4,7 @@ feature 'Merge Request filtering by Milestone' do
include FilteredSearchHelpers
include MergeRequestHelpers
- let(:project) { create(:project, :public) }
+ let(:project) { create(:project, :public, :repository) }
let!(:user) { create(:user)}
let(:milestone) { create(:milestone, project: project) }
diff --git a/spec/features/merge_requests/filter_merge_requests_spec.rb b/spec/features/merge_requests/filter_merge_requests_spec.rb
index 38eb158d06e..f0019be86ad 100644
--- a/spec/features/merge_requests/filter_merge_requests_spec.rb
+++ b/spec/features/merge_requests/filter_merge_requests_spec.rb
@@ -4,7 +4,7 @@ describe 'Filter merge requests' do
include FilteredSearchHelpers
include MergeRequestHelpers
- let!(:project) { create(:project) }
+ let!(:project) { create(:project, :repository) }
let!(:group) { create(:group) }
let!(:user) { create(:user) }
let!(:milestone) { create(:milestone, project: project) }
diff --git a/spec/features/merge_requests/form_spec.rb b/spec/features/merge_requests/form_spec.rb
index e06cd627b20..6ffb05c5030 100644
--- a/spec/features/merge_requests/form_spec.rb
+++ b/spec/features/merge_requests/form_spec.rb
@@ -1,13 +1,13 @@
require 'rails_helper'
describe 'New/edit merge request', :js do
- let!(:project) { create(:project, visibility_level: Gitlab::VisibilityLevel::PUBLIC) }
- let(:fork_project) { create(:project, forked_from_project: project) }
- let!(:user) { create(:user)}
- let!(:user2) { create(:user)}
- let!(:milestone) { create(:milestone, project: project) }
- let!(:label) { create(:label, project: project) }
- let!(:label2) { create(:label, project: project) }
+ let!(:project) { create(:project, :public, :repository) }
+ let(:fork_project) { create(:project, :repository, forked_from_project: project) }
+ let!(:user) { create(:user) }
+ let!(:user2) { create(:user) }
+ let!(:milestone) { create(:milestone, project: project) }
+ let!(:label) { create(:label, project: project) }
+ let!(:label2) { create(:label, project: project) }
before do
project.team << [user, :master]
diff --git a/spec/features/merge_requests/merge_commit_message_toggle_spec.rb b/spec/features/merge_requests/merge_commit_message_toggle_spec.rb
index 784f362a28f..429bc277d73 100644
--- a/spec/features/merge_requests/merge_commit_message_toggle_spec.rb
+++ b/spec/features/merge_requests/merge_commit_message_toggle_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
feature 'Clicking toggle commit message link', js: true do
let(:user) { create(:user) }
- let(:project) { create(:project, :public) }
+ let(:project) { create(:project, :public, :repository) }
let(:issue_1) { create(:issue, project: project)}
let(:issue_2) { create(:issue, project: project)}
let(:merge_request) do
diff --git a/spec/features/merge_requests/merge_immediately_with_pipeline_spec.rb b/spec/features/merge_requests/merge_immediately_with_pipeline_spec.rb
index 13142d3b3c9..0b5a595acce 100644
--- a/spec/features/merge_requests/merge_immediately_with_pipeline_spec.rb
+++ b/spec/features/merge_requests/merge_immediately_with_pipeline_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
feature 'Merge immediately', :js do
let(:user) { create(:user) }
- let(:project) { create(:project, :public) }
+ let(:project) { create(:project, :public, :repository) }
let!(:merge_request) do
create(:merge_request_with_diffs, source_project: project,
diff --git a/spec/features/merge_requests/merge_when_pipeline_succeeds_spec.rb b/spec/features/merge_requests/merge_when_pipeline_succeeds_spec.rb
index 9fbdc1b2c80..574f5fe353e 100644
--- a/spec/features/merge_requests/merge_when_pipeline_succeeds_spec.rb
+++ b/spec/features/merge_requests/merge_when_pipeline_succeeds_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
feature 'Merge When Pipeline Succeeds', :js do
let(:user) { create(:user) }
- let(:project) { create(:project, :public) }
+ let(:project) { create(:project, :public, :repository) }
let(:merge_request) do
create(:merge_request_with_diffs, source_project: project,
diff --git a/spec/features/merge_requests/mini_pipeline_graph_spec.rb b/spec/features/merge_requests/mini_pipeline_graph_spec.rb
index ee6e440e70d..b1215f9ba63 100644
--- a/spec/features/merge_requests/mini_pipeline_graph_spec.rb
+++ b/spec/features/merge_requests/mini_pipeline_graph_spec.rb
@@ -2,7 +2,7 @@ require 'rails_helper'
feature 'Mini Pipeline Graph', :js do
let(:user) { create(:user) }
- let(:project) { create(:project, :public) }
+ let(:project) { create(:project, :public, :repository) }
let(:merge_request) { create(:merge_request, source_project: project, head_pipeline: pipeline) }
let(:pipeline) { create(:ci_empty_pipeline, project: project, ref: 'master', status: 'running', sha: project.commit.id) }
diff --git a/spec/features/merge_requests/reset_filters_spec.rb b/spec/features/merge_requests/reset_filters_spec.rb
index 423213709a3..c1b90e5f875 100644
--- a/spec/features/merge_requests/reset_filters_spec.rb
+++ b/spec/features/merge_requests/reset_filters_spec.rb
@@ -5,7 +5,7 @@ feature 'Merge requests filter clear button', js: true do
include MergeRequestHelpers
include IssueHelpers
- let!(:project) { create(:project, :public) }
+ let!(:project) { create(:project, :public, :repository) }
let!(:user) { create(:user) }
let!(:milestone) { create(:milestone, project: project) }
let!(:bug) { create(:label, project: project, name: 'bug')}
diff --git a/spec/features/merge_requests/toggler_behavior_spec.rb b/spec/features/merge_requests/toggler_behavior_spec.rb
index 2283164ca2f..4e5ec9fbd2d 100644
--- a/spec/features/merge_requests/toggler_behavior_spec.rb
+++ b/spec/features/merge_requests/toggler_behavior_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
feature 'toggler_behavior', js: true do
let(:user) { create(:user) }
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
let(:merge_request) { create(:merge_request, source_project: project, author: user) }
let(:note) { create(:diff_note_on_merge_request, noteable: merge_request, project: project) }
let(:fragment_id) { "#note_#{note.id}" }
diff --git a/spec/features/merge_requests/update_merge_requests_spec.rb b/spec/features/merge_requests/update_merge_requests_spec.rb
index db2f2b523d2..cf30a687df8 100644
--- a/spec/features/merge_requests/update_merge_requests_spec.rb
+++ b/spec/features/merge_requests/update_merge_requests_spec.rb
@@ -2,7 +2,7 @@ require 'rails_helper'
feature 'Multiple merge requests updating from merge_requests#index' do
let!(:user) { create(:user)}
- let!(:project) { create(:project) }
+ let!(:project) { create(:project, :repository) }
let!(:merge_request) { create(:merge_request, source_project: project, target_project: project) }
before do
diff --git a/spec/features/merge_requests/user_lists_merge_requests_spec.rb b/spec/features/merge_requests/user_lists_merge_requests_spec.rb
index d38d2d57b35..d62b035b40b 100644
--- a/spec/features/merge_requests/user_lists_merge_requests_spec.rb
+++ b/spec/features/merge_requests/user_lists_merge_requests_spec.rb
@@ -4,7 +4,7 @@ describe 'Projects > Merge requests > User lists merge requests' do
include MergeRequestHelpers
include SortingHelper
- let(:project) { create(:project, :public) }
+ let(:project) { create(:project, :public, :repository) }
let(:user) { create(:user) }
before do
diff --git a/spec/features/merge_requests/user_posts_notes_spec.rb b/spec/features/merge_requests/user_posts_notes_spec.rb
index 35ed08e0a5e..74d21822a59 100644
--- a/spec/features/merge_requests/user_posts_notes_spec.rb
+++ b/spec/features/merge_requests/user_posts_notes_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe 'Merge requests > User posts notes', :js do
include NoteInteractionHelpers
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
let(:merge_request) do
create(:merge_request, source_project: project, target_project: project)
end
diff --git a/spec/features/merge_requests/user_sees_system_notes_spec.rb b/spec/features/merge_requests/user_sees_system_notes_spec.rb
index 624a425ae52..03dc61c2efa 100644
--- a/spec/features/merge_requests/user_sees_system_notes_spec.rb
+++ b/spec/features/merge_requests/user_sees_system_notes_spec.rb
@@ -1,8 +1,8 @@
require 'spec_helper'
feature 'Merge requests > User sees system notes' do
- let(:public_project) { create(:project, :public) }
- let(:private_project) { create(:project, :private) }
+ let(:public_project) { create(:project, :public, :repository) }
+ let(:private_project) { create(:project, :private, :repository) }
let(:issue) { create(:issue, project: private_project) }
let(:merge_request) { create(:merge_request, source_project: public_project, source_branch: 'markdown') }
let!(:note) { create(:note_on_merge_request, :system, noteable: merge_request, project: public_project, note: "mentioned in #{issue.to_reference(public_project)}") }
diff --git a/spec/features/merge_requests/user_uses_slash_commands_spec.rb b/spec/features/merge_requests/user_uses_slash_commands_spec.rb
index 881527e1501..43cab65d287 100644
--- a/spec/features/merge_requests/user_uses_slash_commands_spec.rb
+++ b/spec/features/merge_requests/user_uses_slash_commands_spec.rb
@@ -4,7 +4,7 @@ feature 'Merge Requests > User uses quick actions', js: true do
include QuickActionsHelpers
let(:user) { create(:user) }
- let(:project) { create(:project, :public) }
+ let(:project) { create(:project, :public, :repository) }
let(:merge_request) { create(:merge_request, source_project: project) }
let!(:milestone) { create(:milestone, project: project, title: 'ASAP') }
@@ -129,7 +129,7 @@ feature 'Merge Requests > User uses quick actions', js: true do
end
describe '/target_branch command in merge request' do
- let(:another_project) { create(:project, :public) }
+ let(:another_project) { create(:project, :public, :repository) }
let(:new_url_opts) { { merge_request: { source_branch: 'feature' } } }
before do
diff --git a/spec/features/merge_requests/widget_spec.rb b/spec/features/merge_requests/widget_spec.rb
index 8d7bbf14d86..69e31c7481f 100644
--- a/spec/features/merge_requests/widget_spec.rb
+++ b/spec/features/merge_requests/widget_spec.rb
@@ -2,7 +2,7 @@ require 'rails_helper'
describe 'Merge request', :js do
let(:user) { create(:user) }
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
let(:merge_request) { create(:merge_request, source_project: project) }
before do
@@ -200,7 +200,7 @@ describe 'Merge request', :js do
end
context 'user can merge into source project but cannot push to fork', js: true do
- let(:fork_project) { create(:project, :public) }
+ let(:fork_project) { create(:project, :public, :repository) }
let(:user2) { create(:user) }
before do
diff --git a/spec/features/merge_requests/wip_message_spec.rb b/spec/features/merge_requests/wip_message_spec.rb
index 5a685056bf3..b422c76249d 100644
--- a/spec/features/merge_requests/wip_message_spec.rb
+++ b/spec/features/merge_requests/wip_message_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
feature 'Work In Progress help message' do
- let!(:project) { create(:project, visibility_level: Gitlab::VisibilityLevel::PUBLIC) }
+ let!(:project) { create(:project, :public, :repository) }
let!(:user) { create(:user) }
before do
diff --git a/spec/features/profiles/account_spec.rb b/spec/features/profiles/account_spec.rb
index 7791047877d..56c1f7ae9c7 100644
--- a/spec/features/profiles/account_spec.rb
+++ b/spec/features/profiles/account_spec.rb
@@ -27,7 +27,7 @@ feature 'Profile > Account' do
end
context 'with a project' do
- given!(:project) { create(:project, namespace: user.namespace, path: 'project') }
+ given!(:project) { create(:empty_project, namespace: user.namespace) }
given(:new_project_path) { "/#{new_username}/#{project.path}" }
given(:old_project_path) { "/#{user.username}/#{project.path}" }
@@ -43,14 +43,14 @@ feature 'Profile > Account' do
update_username(new_username)
visit new_project_path
expect(current_path).to eq(new_project_path)
- expect(find('h1.project-title')).to have_content(project.name)
+ expect(find('h1.title')).to have_content(project.path)
end
scenario 'the old project path redirects to the new path' do
update_username(new_username)
visit old_project_path
expect(current_path).to eq(new_project_path)
- expect(find('h1.project-title')).to have_content(project.name)
+ expect(find('h1.title')).to have_content(project.path)
end
end
end
diff --git a/spec/features/projects/artifacts/browse_spec.rb b/spec/features/projects/artifacts/browse_spec.rb
index 7dfb19f29bd..f5f7eba8e40 100644
--- a/spec/features/projects/artifacts/browse_spec.rb
+++ b/spec/features/projects/artifacts/browse_spec.rb
@@ -1,8 +1,8 @@
require 'spec_helper'
feature 'Browse artifact', :js do
- let(:project) { create(:project, :public) }
- let(:pipeline) { create(:ci_empty_pipeline, project: project, sha: project.commit.sha, ref: 'master') }
+ let(:project) { create(:empty_project, :public) }
+ let(:pipeline) { create(:ci_empty_pipeline, project: project) }
let(:job) { create(:ci_build, :artifacts, pipeline: pipeline) }
def browse_path(path)
diff --git a/spec/features/projects/artifacts/download_spec.rb b/spec/features/projects/artifacts/download_spec.rb
index f1c210281ad..c1bba8c15c4 100644
--- a/spec/features/projects/artifacts/download_spec.rb
+++ b/spec/features/projects/artifacts/download_spec.rb
@@ -1,8 +1,8 @@
require 'spec_helper'
feature 'Download artifact', :js do
- let(:project) { create(:project, :public) }
- let(:pipeline) { create(:ci_empty_pipeline, status: :success, project: project, sha: project.commit.sha, ref: 'master') }
+ let(:project) { create(:empty_project, :public) }
+ let(:pipeline) { create(:ci_empty_pipeline, status: :success, project: project) }
let(:job) { create(:ci_build, :artifacts, :success, pipeline: pipeline) }
shared_examples 'downloading' do
diff --git a/spec/features/projects/artifacts/file_spec.rb b/spec/features/projects/artifacts/file_spec.rb
index aaa98ac4851..4c268b876ea 100644
--- a/spec/features/projects/artifacts/file_spec.rb
+++ b/spec/features/projects/artifacts/file_spec.rb
@@ -1,8 +1,8 @@
require 'spec_helper'
feature 'Artifact file', :js do
- let(:project) { create(:project, :public) }
- let(:pipeline) { create(:ci_empty_pipeline, project: project, sha: project.commit.sha, ref: 'master') }
+ let(:project) { create(:empty_project, :public) }
+ let(:pipeline) { create(:ci_empty_pipeline, project: project) }
let(:build) { create(:ci_build, :artifacts, pipeline: pipeline) }
def visit_file(path)
diff --git a/spec/features/projects/artifacts/raw_spec.rb b/spec/features/projects/artifacts/raw_spec.rb
index 73292cb3873..128e39e7803 100644
--- a/spec/features/projects/artifacts/raw_spec.rb
+++ b/spec/features/projects/artifacts/raw_spec.rb
@@ -1,8 +1,8 @@
require 'spec_helper'
feature 'Raw artifact', :js do
- let(:project) { create(:project, :public) }
- let(:pipeline) { create(:ci_empty_pipeline, project: project, sha: project.commit.sha, ref: 'master') }
+ let(:project) { create(:empty_project, :public) }
+ let(:pipeline) { create(:ci_empty_pipeline, project: project) }
let(:job) { create(:ci_build, :artifacts, pipeline: pipeline) }
def raw_path(path)
diff --git a/spec/features/projects/badges/coverage_spec.rb b/spec/features/projects/badges/coverage_spec.rb
index 5c5a7c96763..8cf4bfbf978 100644
--- a/spec/features/projects/badges/coverage_spec.rb
+++ b/spec/features/projects/badges/coverage_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
feature 'test coverage badge' do
given!(:user) { create(:user) }
- given!(:project) { create(:project, :private) }
+ given!(:project) { create(:empty_project, :private) }
context 'when user has access to view badge' do
background do
@@ -55,7 +55,7 @@ feature 'test coverage badge' do
end
def create_pipeline
- opts = { project: project, ref: 'master', sha: project.commit.id }
+ opts = { project: project }
create(:ci_pipeline, opts).tap do |pipeline|
yield pipeline
diff --git a/spec/features/projects/badges/list_spec.rb b/spec/features/projects/badges/list_spec.rb
index fd8e9232b02..89ae891037e 100644
--- a/spec/features/projects/badges/list_spec.rb
+++ b/spec/features/projects/badges/list_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
feature 'list of badges' do
background do
user = create(:user)
- project = create(:project)
+ project = create(:project, :repository)
project.team << [user, :master]
sign_in(user)
visit project_pipelines_settings_path(project)
diff --git a/spec/features/projects/blobs/blob_show_spec.rb b/spec/features/projects/blobs/blob_show_spec.rb
index 8a32488b845..3d465e709b9 100644
--- a/spec/features/projects/blobs/blob_show_spec.rb
+++ b/spec/features/projects/blobs/blob_show_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
feature 'File blob', :js do
- let(:project) { create(:project, :public) }
+ let(:project) { create(:project, :public, :repository) }
def visit_blob(path, anchor: nil, ref: 'master')
visit project_blob_path(project, File.join(ref, path), anchor: anchor)
diff --git a/spec/features/projects/branches/download_buttons_spec.rb b/spec/features/projects/branches/download_buttons_spec.rb
index 47d7f27290b..ad06cee4e81 100644
--- a/spec/features/projects/branches/download_buttons_spec.rb
+++ b/spec/features/projects/branches/download_buttons_spec.rb
@@ -4,7 +4,7 @@ feature 'Download buttons in branches page' do
given(:user) { create(:user) }
given(:role) { :developer }
given(:status) { 'success' }
- given(:project) { create(:project) }
+ given(:project) { create(:project, :repository) }
given(:pipeline) do
create(:ci_pipeline,
diff --git a/spec/features/projects/branches/new_branch_ref_dropdown_spec.rb b/spec/features/projects/branches/new_branch_ref_dropdown_spec.rb
index 2123e96b816..0be434a567b 100644
--- a/spec/features/projects/branches/new_branch_ref_dropdown_spec.rb
+++ b/spec/features/projects/branches/new_branch_ref_dropdown_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe 'New Branch Ref Dropdown', :js do
let(:user) { create(:user) }
- let(:project) { create(:project, :public) }
+ let(:project) { create(:project, :public, :repository) }
let(:toggle) { find('.create-from .dropdown-menu-toggle') }
before do
diff --git a/spec/features/projects/branches_spec.rb b/spec/features/projects/branches_spec.rb
index 498dd8ee4bf..ad4527a0b74 100644
--- a/spec/features/projects/branches_spec.rb
+++ b/spec/features/projects/branches_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe 'Branches' do
let(:user) { create(:user) }
- let(:project) { create(:project, :public) }
+ let(:project) { create(:project, :public, :repository) }
let(:repository) { project.repository }
def set_protected_branch_name(branch_name)
@@ -29,7 +29,7 @@ describe 'Branches' do
it 'sorts the branches by name' do
visit project_branches_path(project)
- click_button "Name" # Open sorting dropdown
+ click_button "Last updated" # Open sorting dropdown
click_link "Name"
sorted = repository.branches_sorted_by(:name).first(20).map do |branch|
@@ -41,7 +41,7 @@ describe 'Branches' do
it 'sorts the branches by last updated' do
visit project_branches_path(project)
- click_button "Name" # Open sorting dropdown
+ click_button "Last updated" # Open sorting dropdown
click_link "Last updated"
sorted = repository.branches_sorted_by(:updated_desc).first(20).map do |branch|
@@ -53,7 +53,7 @@ describe 'Branches' do
it 'sorts the branches by oldest updated' do
visit project_branches_path(project)
- click_button "Name" # Open sorting dropdown
+ click_button "Last updated" # Open sorting dropdown
click_link "Oldest updated"
sorted = repository.branches_sorted_by(:updated_asc).first(20).map do |branch|
diff --git a/spec/features/projects/commit/builds_spec.rb b/spec/features/projects/commit/builds_spec.rb
index 257a7418f16..740331fe42a 100644
--- a/spec/features/projects/commit/builds_spec.rb
+++ b/spec/features/projects/commit/builds_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
feature 'project commit pipelines', js: true do
- given(:project) { create(:project) }
+ given(:project) { create(:project, :repository) }
background do
user = create(:user)
diff --git a/spec/features/projects/commit/cherry_pick_spec.rb b/spec/features/projects/commit/cherry_pick_spec.rb
index 2d18add82b5..7086f56bb1b 100644
--- a/spec/features/projects/commit/cherry_pick_spec.rb
+++ b/spec/features/projects/commit/cherry_pick_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe 'Cherry-pick Commits' do
let(:user) { create(:user) }
let(:group) { create(:group) }
- let(:project) { create(:project, namespace: group) }
+ let(:project) { create(:project, :repository, namespace: group) }
let(:master_pickable_commit) { project.commit('7d3b0f7cff5f37573aea97cebfd5692ea1689924') }
let(:master_pickable_merge) { project.commit('e56497bb5f03a90a51293fc6d516788730953899') }
diff --git a/spec/features/projects/commit/mini_pipeline_graph_spec.rb b/spec/features/projects/commit/mini_pipeline_graph_spec.rb
index 81a12225779..2ef74e8857c 100644
--- a/spec/features/projects/commit/mini_pipeline_graph_spec.rb
+++ b/spec/features/projects/commit/mini_pipeline_graph_spec.rb
@@ -2,7 +2,7 @@ require 'rails_helper'
feature 'Mini Pipeline Graph in Commit View', :js do
let(:user) { create(:user) }
- let(:project) { create(:project, :public) }
+ let(:project) { create(:project, :public, :repository) }
before do
sign_in(user)
diff --git a/spec/features/projects/compare_spec.rb b/spec/features/projects/compare_spec.rb
index 0f48751fa10..82d73fe8531 100644
--- a/spec/features/projects/compare_spec.rb
+++ b/spec/features/projects/compare_spec.rb
@@ -2,7 +2,7 @@ require "spec_helper"
describe "Compare", js: true do
let(:user) { create(:user) }
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
before do
project.team << [user, :master]
diff --git a/spec/features/projects/edit_spec.rb b/spec/features/projects/edit_spec.rb
index d3b1d1f7be3..4b5436027f9 100644
--- a/spec/features/projects/edit_spec.rb
+++ b/spec/features/projects/edit_spec.rb
@@ -2,7 +2,7 @@ require 'rails_helper'
feature 'Project edit', js: true do
let(:user) { create(:user) }
- let(:project) { create(:project) }
+ let(:project) { create(:empty_project) }
before do
project.team << [user, :master]
@@ -20,7 +20,7 @@ feature 'Project edit', js: true do
end
context 'given project with merge_requests_disabled access level' do
- let(:project) { create(:project, :merge_requests_disabled) }
+ let(:project) { create(:empty_project, :merge_requests_disabled) }
it 'hides merge requests section' do
expect(page).to have_selector('.merge-requests-feature', visible: false)
@@ -36,7 +36,7 @@ feature 'Project edit', js: true do
end
context 'given project with builds_disabled access level' do
- let(:project) { create(:project, :builds_disabled) }
+ let(:project) { create(:empty_project, :builds_disabled) }
it 'hides builds select section' do
expect(page).to have_selector('.builds-feature', visible: false)
diff --git a/spec/features/projects/environments/environment_spec.rb b/spec/features/projects/environments/environment_spec.rb
index db29055812c..c6b7e611a5c 100644
--- a/spec/features/projects/environments/environment_spec.rb
+++ b/spec/features/projects/environments/environment_spec.rb
@@ -205,7 +205,7 @@ feature 'Environment' do
end
feature 'auto-close environment when branch is deleted' do
- given(:project) { create(:project) }
+ given(:project) { create(:project, :repository) }
given!(:environment) do
create(:environment, :with_review_app, project: project,
diff --git a/spec/features/projects/environments/environments_spec.rb b/spec/features/projects/environments/environments_spec.rb
index e40e0b0c871..36cf307fbe2 100644
--- a/spec/features/projects/environments/environments_spec.rb
+++ b/spec/features/projects/environments/environments_spec.rb
@@ -111,7 +111,7 @@ feature 'Environments page', :js do
end
context 'with deployments' do
- given(:project) { create(:project) }
+ given(:project) { create(:project, :repository) }
given(:deployment) do
create(:deployment, environment: environment,
diff --git a/spec/features/projects/features_visibility_spec.rb b/spec/features/projects/features_visibility_spec.rb
index 16b0fa6e1ae..37fa61d038e 100644
--- a/spec/features/projects/features_visibility_spec.rb
+++ b/spec/features/projects/features_visibility_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe 'Edit Project Settings' do
let(:member) { create(:user) }
- let!(:project) { create(:project, :public, path: 'gitlab', name: 'sample') }
+ let!(:project) { create(:project, :public, :repository) }
let!(:issue) { create(:issue, project: project) }
let(:non_member) { create(:user) }
@@ -249,7 +249,7 @@ describe 'Edit Project Settings' do
# Regression spec for https://gitlab.com/gitlab-org/gitlab-ce/issues/24056
describe 'project statistic visibility' do
- let!(:project) { create(:project, :private) }
+ let!(:project) { create(:empty_project, :private) }
before do
project.team << [member, :guest]
diff --git a/spec/features/projects/files/browse_files_spec.rb b/spec/features/projects/files/browse_files_spec.rb
index 77b2fd4f80f..f62a9edd37e 100644
--- a/spec/features/projects/files/browse_files_spec.rb
+++ b/spec/features/projects/files/browse_files_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
feature 'user browses project', js: true do
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
let(:user) { create(:user) }
before do
diff --git a/spec/features/projects/files/creating_a_file_spec.rb b/spec/features/projects/files/creating_a_file_spec.rb
index d49e1541869..e13bf4b6089 100644
--- a/spec/features/projects/files/creating_a_file_spec.rb
+++ b/spec/features/projects/files/creating_a_file_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
feature 'User wants to create a file' do
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
let(:user) { create(:user) }
background do
diff --git a/spec/features/projects/files/dockerfile_dropdown_spec.rb b/spec/features/projects/files/dockerfile_dropdown_spec.rb
index 6d44c49bb6f..cebb238dda1 100644
--- a/spec/features/projects/files/dockerfile_dropdown_spec.rb
+++ b/spec/features/projects/files/dockerfile_dropdown_spec.rb
@@ -4,7 +4,7 @@ require 'fileutils'
feature 'User wants to add a Dockerfile file' do
before do
user = create(:user)
- project = create(:project)
+ project = create(:project, :repository)
project.team << [user, :master]
sign_in user
diff --git a/spec/features/projects/files/download_buttons_spec.rb b/spec/features/projects/files/download_buttons_spec.rb
index 25168203d15..d2382d55c0b 100644
--- a/spec/features/projects/files/download_buttons_spec.rb
+++ b/spec/features/projects/files/download_buttons_spec.rb
@@ -4,7 +4,7 @@ feature 'Download buttons in files tree' do
given(:user) { create(:user) }
given(:role) { :developer }
given(:status) { 'success' }
- given(:project) { create(:project) }
+ given(:project) { create(:project, :repository) }
given(:pipeline) do
create(:ci_pipeline,
diff --git a/spec/features/projects/files/edit_file_soft_wrap_spec.rb b/spec/features/projects/files/edit_file_soft_wrap_spec.rb
index 8a4511df842..c7e3f657639 100644
--- a/spec/features/projects/files/edit_file_soft_wrap_spec.rb
+++ b/spec/features/projects/files/edit_file_soft_wrap_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
feature 'User uses soft wrap whilst editing file', js: true do
before do
user = create(:user)
- project = create(:project)
+ project = create(:project, :repository)
project.team << [user, :master]
sign_in user
visit project_new_blob_path(project, 'master', file_name: 'test_file-name')
diff --git a/spec/features/projects/files/editing_a_file_spec.rb b/spec/features/projects/files/editing_a_file_spec.rb
index e084ab17441..20be968e89f 100644
--- a/spec/features/projects/files/editing_a_file_spec.rb
+++ b/spec/features/projects/files/editing_a_file_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
feature 'User wants to edit a file' do
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
let(:user) { create(:user) }
let(:commit_params) do
{
diff --git a/spec/features/projects/files/find_file_keyboard_spec.rb b/spec/features/projects/files/find_file_keyboard_spec.rb
index d7e96811e33..7f97fdb8cc9 100644
--- a/spec/features/projects/files/find_file_keyboard_spec.rb
+++ b/spec/features/projects/files/find_file_keyboard_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
feature 'Find file keyboard shortcuts', js: true do
let(:user) { create(:user) }
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
before do
project.team << [user, :master]
diff --git a/spec/features/projects/files/find_files_spec.rb b/spec/features/projects/files/find_files_spec.rb
index 05003f6a4f5..57d67b28920 100644
--- a/spec/features/projects/files/find_files_spec.rb
+++ b/spec/features/projects/files/find_files_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
feature 'Find files button in the tree header' do
given(:user) { create(:user) }
- given(:project) { create(:project) }
+ given(:project) { create(:project, :repository) }
background do
sign_in(user)
diff --git a/spec/features/projects/files/gitignore_dropdown_spec.rb b/spec/features/projects/files/gitignore_dropdown_spec.rb
index 4340c98d0d9..e2044c9d5aa 100644
--- a/spec/features/projects/files/gitignore_dropdown_spec.rb
+++ b/spec/features/projects/files/gitignore_dropdown_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
feature 'User wants to add a .gitignore file' do
before do
user = create(:user)
- project = create(:project)
+ project = create(:project, :repository)
project.team << [user, :master]
sign_in user
visit project_new_blob_path(project, 'master', file_name: '.gitignore')
diff --git a/spec/features/projects/files/gitlab_ci_yml_dropdown_spec.rb b/spec/features/projects/files/gitlab_ci_yml_dropdown_spec.rb
index f42a26b6954..ab242b0b0b5 100644
--- a/spec/features/projects/files/gitlab_ci_yml_dropdown_spec.rb
+++ b/spec/features/projects/files/gitlab_ci_yml_dropdown_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
feature 'User wants to add a .gitlab-ci.yml file' do
before do
user = create(:user)
- project = create(:project)
+ project = create(:project, :repository)
project.team << [user, :master]
sign_in user
visit project_new_blob_path(project, 'master', file_name: '.gitlab-ci.yml')
diff --git a/spec/features/projects/files/project_owner_creates_license_file_spec.rb b/spec/features/projects/files/project_owner_creates_license_file_spec.rb
index 300b631a2f4..95af263bcac 100644
--- a/spec/features/projects/files/project_owner_creates_license_file_spec.rb
+++ b/spec/features/projects/files/project_owner_creates_license_file_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
feature 'project owner creates a license file', js: true do
let(:project_master) { create(:user) }
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
background do
project.repository.delete_file(project_master, 'LICENSE',
message: 'Remove LICENSE', branch_name: 'master')
diff --git a/spec/features/projects/files/template_type_dropdown_spec.rb b/spec/features/projects/files/template_type_dropdown_spec.rb
index a0846643269..48003eeaa87 100644
--- a/spec/features/projects/files/template_type_dropdown_spec.rb
+++ b/spec/features/projects/files/template_type_dropdown_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
feature 'Template type dropdown selector', js: true do
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
let(:user) { create(:user) }
before do
diff --git a/spec/features/projects/files/undo_template_spec.rb b/spec/features/projects/files/undo_template_spec.rb
index d50ddb1f1a9..4238d25e9ee 100644
--- a/spec/features/projects/files/undo_template_spec.rb
+++ b/spec/features/projects/files/undo_template_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
feature 'Template Undo Button', js: true do
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
let(:user) { create(:user) }
before do
diff --git a/spec/features/projects/gfm_autocomplete_load_spec.rb b/spec/features/projects/gfm_autocomplete_load_spec.rb
index 7bcd3f632a8..b63e5ae46ee 100644
--- a/spec/features/projects/gfm_autocomplete_load_spec.rb
+++ b/spec/features/projects/gfm_autocomplete_load_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe 'GFM autocomplete loading', js: true do
- let(:project) { create(:project) }
+ let(:project) { create(:empty_project) }
before do
sign_in(create(:admin))
diff --git a/spec/features/projects/group_links_spec.rb b/spec/features/projects/group_links_spec.rb
index 5195d027a9f..698baad97ff 100644
--- a/spec/features/projects/group_links_spec.rb
+++ b/spec/features/projects/group_links_spec.rb
@@ -4,7 +4,7 @@ feature 'Project group links', :js do
include Select2Helper
let(:master) { create(:user) }
- let(:project) { create(:project) }
+ let(:project) { create(:empty_project) }
let!(:group) { create(:group) }
background do
@@ -35,7 +35,7 @@ feature 'Project group links', :js do
context 'nested group project' do
let!(:nested_group) { create(:group, parent: group) }
let!(:another_group) { create(:group) }
- let!(:project) { create(:project, namespace: nested_group) }
+ let!(:project) { create(:empty_project, namespace: nested_group) }
background do
group.add_master(master)
diff --git a/spec/features/projects/import_export/import_file_spec.rb b/spec/features/projects/import_export/import_file_spec.rb
index c0cfb9eafe2..f924725870b 100644
--- a/spec/features/projects/import_export/import_file_spec.rb
+++ b/spec/features/projects/import_export/import_file_spec.rb
@@ -46,7 +46,7 @@ feature 'Import/Export - project import integration test', js: true do
end
scenario 'invalid project' do
- project = create(:project, namespace: namespace)
+ project = create(:empty_project, namespace: namespace)
visit new_project_path
@@ -62,7 +62,7 @@ feature 'Import/Export - project import integration test', js: true do
end
scenario 'project with no name' do
- create(:project, namespace: namespace)
+ create(:empty_project, namespace: namespace)
visit new_project_path
diff --git a/spec/features/projects/issuable_templates_spec.rb b/spec/features/projects/issuable_templates_spec.rb
index 8c2e49377e7..d2789d0aa52 100644
--- a/spec/features/projects/issuable_templates_spec.rb
+++ b/spec/features/projects/issuable_templates_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
feature 'issuable templates', js: true do
let(:user) { create(:user) }
- let(:project) { create(:project, :public) }
+ let(:project) { create(:project, :public, :repository) }
before do
project.team << [user, :master]
@@ -120,7 +120,7 @@ feature 'issuable templates', js: true do
context 'user creates a merge request from a forked project using templates' do
let(:template_content) { 'this is a test "feature-proposal" template' }
let(:fork_user) { create(:user) }
- let(:fork_project) { create(:project, :public) }
+ let(:fork_project) { create(:project, :public, :repository) }
let(:merge_request) { create(:merge_request, :with_diffs, source_project: fork_project, target_project: project) }
background do
diff --git a/spec/features/projects/jobs_spec.rb b/spec/features/projects/jobs_spec.rb
index 395d68d3fb4..037ac00d39f 100644
--- a/spec/features/projects/jobs_spec.rb
+++ b/spec/features/projects/jobs_spec.rb
@@ -4,7 +4,7 @@ require 'tempfile'
feature 'Jobs' do
let(:user) { create(:user) }
let(:user_access_level) { :developer }
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
let(:pipeline) { create(:ci_pipeline, project: project) }
let(:job) { create(:ci_build, :trace, pipeline: pipeline) }
diff --git a/spec/features/projects/labels/issues_sorted_by_priority_spec.rb b/spec/features/projects/labels/issues_sorted_by_priority_spec.rb
index 0292a3192d8..2b0aead440c 100644
--- a/spec/features/projects/labels/issues_sorted_by_priority_spec.rb
+++ b/spec/features/projects/labels/issues_sorted_by_priority_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
feature 'Issue prioritization' do
let(:user) { create(:user) }
- let(:project) { create(:project, name: 'test', namespace: user.namespace) }
+ let(:project) { create(:empty_project, name: 'test', namespace: user.namespace) }
# Labels
let(:label_1) { create(:label, title: 'label_1', project: project, priority: 1) }
diff --git a/spec/features/projects/main/download_buttons_spec.rb b/spec/features/projects/main/download_buttons_spec.rb
index a8ae0ecbae0..3f2579bb01a 100644
--- a/spec/features/projects/main/download_buttons_spec.rb
+++ b/spec/features/projects/main/download_buttons_spec.rb
@@ -4,7 +4,7 @@ feature 'Download buttons in project main page' do
given(:user) { create(:user) }
given(:role) { :developer }
given(:status) { 'success' }
- given(:project) { create(:project) }
+ given(:project) { create(:project, :repository) }
given(:pipeline) do
create(:ci_pipeline,
diff --git a/spec/features/projects/members/group_member_cannot_leave_group_project_spec.rb b/spec/features/projects/members/group_member_cannot_leave_group_project_spec.rb
index 6b450fa4e45..1fb5e000239 100644
--- a/spec/features/projects/members/group_member_cannot_leave_group_project_spec.rb
+++ b/spec/features/projects/members/group_member_cannot_leave_group_project_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
feature 'Projects > Members > Group member cannot leave group project' do
let(:user) { create(:user) }
let(:group) { create(:group) }
- let(:project) { create(:project, namespace: group) }
+ let(:project) { create(:empty_project, namespace: group) }
background do
group.add_developer(user)
diff --git a/spec/features/projects/members/group_member_cannot_request_access_to_his_group_project_spec.rb b/spec/features/projects/members/group_member_cannot_request_access_to_his_group_project_spec.rb
index 296a80a3c60..8e3520f9f15 100644
--- a/spec/features/projects/members/group_member_cannot_request_access_to_his_group_project_spec.rb
+++ b/spec/features/projects/members/group_member_cannot_request_access_to_his_group_project_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
feature 'Projects > Members > Group member cannot request access to his group project' do
let(:user) { create(:user) }
let(:group) { create(:group) }
- let(:project) { create(:project, namespace: group) }
+ let(:project) { create(:empty_project, namespace: group) }
scenario 'owner does not see the request access button' do
group.add_owner(user)
diff --git a/spec/features/projects/members/group_requester_cannot_request_access_to_project_spec.rb b/spec/features/projects/members/group_requester_cannot_request_access_to_project_spec.rb
index c8988aa63a7..6865d721201 100644
--- a/spec/features/projects/members/group_requester_cannot_request_access_to_project_spec.rb
+++ b/spec/features/projects/members/group_requester_cannot_request_access_to_project_spec.rb
@@ -4,7 +4,7 @@ feature 'Projects > Members > Group requester cannot request access to project',
let(:user) { create(:user) }
let(:owner) { create(:user) }
let(:group) { create(:group, :public, :access_requestable) }
- let(:project) { create(:project, :public, :access_requestable, namespace: group) }
+ let(:project) { create(:empty_project, :public, :access_requestable, namespace: group) }
background do
group.add_owner(owner)
diff --git a/spec/features/projects/members/list_spec.rb b/spec/features/projects/members/list_spec.rb
index 237c059e595..f9c54d267b5 100644
--- a/spec/features/projects/members/list_spec.rb
+++ b/spec/features/projects/members/list_spec.rb
@@ -6,7 +6,7 @@ feature 'Project members list' do
let(:user1) { create(:user, name: 'John Doe') }
let(:user2) { create(:user, name: 'Mary Jane') }
let(:group) { create(:group) }
- let(:project) { create(:project, namespace: group) }
+ let(:project) { create(:empty_project, namespace: group) }
background do
sign_in(user1)
diff --git a/spec/features/projects/members/master_adds_member_with_expiration_date_spec.rb b/spec/features/projects/members/master_adds_member_with_expiration_date_spec.rb
index cd621b6b3ce..b4381ea373e 100644
--- a/spec/features/projects/members/master_adds_member_with_expiration_date_spec.rb
+++ b/spec/features/projects/members/master_adds_member_with_expiration_date_spec.rb
@@ -5,7 +5,7 @@ feature 'Projects > Members > Master adds member with expiration date', js: true
include ActiveSupport::Testing::TimeHelpers
let(:master) { create(:user) }
- let(:project) { create(:project) }
+ let(:project) { create(:empty_project) }
let!(:new_member) { create(:user) }
background do
diff --git a/spec/features/projects/members/member_cannot_request_access_to_his_project_spec.rb b/spec/features/projects/members/member_cannot_request_access_to_his_project_spec.rb
index 04806f8fd9e..7f39f5b2513 100644
--- a/spec/features/projects/members/member_cannot_request_access_to_his_project_spec.rb
+++ b/spec/features/projects/members/member_cannot_request_access_to_his_project_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
feature 'Projects > Members > Member cannot request access to his project' do
let(:member) { create(:user) }
- let(:project) { create(:project) }
+ let(:project) { create(:empty_project) }
background do
project.team << [member, :developer]
diff --git a/spec/features/projects/members/member_leaves_project_spec.rb b/spec/features/projects/members/member_leaves_project_spec.rb
index e72283d3628..1bcf827d33c 100644
--- a/spec/features/projects/members/member_leaves_project_spec.rb
+++ b/spec/features/projects/members/member_leaves_project_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
feature 'Projects > Members > Member leaves project' do
let(:user) { create(:user) }
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
background do
project.team << [user, :developer]
diff --git a/spec/features/projects/members/owner_cannot_leave_project_spec.rb b/spec/features/projects/members/owner_cannot_leave_project_spec.rb
index 15162d01c44..8b6d0aafcf8 100644
--- a/spec/features/projects/members/owner_cannot_leave_project_spec.rb
+++ b/spec/features/projects/members/owner_cannot_leave_project_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
feature 'Projects > Members > Owner cannot leave project' do
- let(:project) { create(:project) }
+ let(:project) { create(:empty_project) }
background do
sign_in(project.owner)
diff --git a/spec/features/projects/members/owner_cannot_request_access_to_his_project_spec.rb b/spec/features/projects/members/owner_cannot_request_access_to_his_project_spec.rb
index c27925c8dc4..d838af6d976 100644
--- a/spec/features/projects/members/owner_cannot_request_access_to_his_project_spec.rb
+++ b/spec/features/projects/members/owner_cannot_request_access_to_his_project_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
feature 'Projects > Members > Owner cannot request access to his project' do
- let(:project) { create(:project) }
+ let(:project) { create(:empty_project) }
background do
sign_in(project.owner)
diff --git a/spec/features/projects/members/user_requests_access_spec.rb b/spec/features/projects/members/user_requests_access_spec.rb
index 2979563f33a..24c9f708456 100644
--- a/spec/features/projects/members/user_requests_access_spec.rb
+++ b/spec/features/projects/members/user_requests_access_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
feature 'Projects > Members > User requests access' do
let(:user) { create(:user) }
- let(:project) { create(:project, :public, :access_requestable) }
+ let(:project) { create(:project, :public, :access_requestable, :repository) }
let(:master) { project.owner }
background do
diff --git a/spec/features/projects/merge_request_button_spec.rb b/spec/features/projects/merge_request_button_spec.rb
index 8cbd26551bc..85d518c0cc3 100644
--- a/spec/features/projects/merge_request_button_spec.rb
+++ b/spec/features/projects/merge_request_button_spec.rb
@@ -3,8 +3,8 @@ require 'spec_helper'
feature 'Merge Request button' do
shared_examples 'Merge request button only shown when allowed' do
let(:user) { create(:user) }
- let(:project) { create(:project, :public) }
- let(:forked_project) { create(:project, :public, forked_from_project: project) }
+ let(:project) { create(:project, :public, :repository) }
+ let(:forked_project) { create(:project, :public, :repository, forked_from_project: project) }
context 'not logged in' do
it 'does not show Create merge request button' do
diff --git a/spec/features/projects/merge_requests/list_spec.rb b/spec/features/projects/merge_requests/list_spec.rb
index 6548b4b83e6..a879efef4b5 100644
--- a/spec/features/projects/merge_requests/list_spec.rb
+++ b/spec/features/projects/merge_requests/list_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
feature 'Merge Requests List' do
let(:user) { create(:user) }
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
background do
project.team << [user, :developer]
diff --git a/spec/features/projects/no_password_spec.rb b/spec/features/projects/no_password_spec.rb
index d22a6daac08..6aff079dd39 100644
--- a/spec/features/projects/no_password_spec.rb
+++ b/spec/features/projects/no_password_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
feature 'No Password Alert' do
- let(:project) { create(:project, namespace: user.namespace) }
+ let(:project) { create(:project, :repository, namespace: user.namespace) }
context 'with internal auth enabled' do
before do
diff --git a/spec/features/projects/pipeline_schedules_spec.rb b/spec/features/projects/pipeline_schedules_spec.rb
index 47ed4c7e7c1..605415d2af4 100644
--- a/spec/features/projects/pipeline_schedules_spec.rb
+++ b/spec/features/projects/pipeline_schedules_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
feature 'Pipeline Schedules', :js do
include PipelineSchedulesHelper
- let!(:project) { create(:project) }
+ let!(:project) { create(:project, :repository) }
let!(:pipeline_schedule) { create(:ci_pipeline_schedule, :nightly, project: project ) }
let!(:pipeline) { create(:ci_pipeline, pipeline_schedule: pipeline_schedule) }
let(:scope) { nil }
diff --git a/spec/features/projects/pipelines/pipeline_spec.rb b/spec/features/projects/pipelines/pipeline_spec.rb
index d4319bca331..0b626749275 100644
--- a/spec/features/projects/pipelines/pipeline_spec.rb
+++ b/spec/features/projects/pipelines/pipeline_spec.rb
@@ -42,7 +42,7 @@ describe 'Pipeline', :js do
describe 'GET /:project/pipelines/:id' do
include_context 'pipeline builds'
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
let(:pipeline) { create(:ci_pipeline, project: project, ref: 'master', sha: project.commit.id, user: user) }
before do
@@ -188,7 +188,7 @@ describe 'Pipeline', :js do
describe 'GET /:project/pipelines/:id/builds' do
include_context 'pipeline builds'
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
let(:pipeline) { create(:ci_pipeline, project: project, ref: 'master', sha: project.commit.id) }
before do
@@ -262,7 +262,7 @@ describe 'Pipeline', :js do
end
describe 'GET /:project/pipelines/:id/failures' do
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
let(:pipeline) { create(:ci_pipeline, project: project, ref: 'master', sha: project.commit.id) }
let(:pipeline_failures_page) { failures_project_pipeline_path(project, pipeline) }
let!(:failed_build) { create(:ci_build, :failed, pipeline: pipeline) }
diff --git a/spec/features/projects/pipelines/pipelines_spec.rb b/spec/features/projects/pipelines/pipelines_spec.rb
index 6bef7317d30..59dff22eca3 100644
--- a/spec/features/projects/pipelines/pipelines_spec.rb
+++ b/spec/features/projects/pipelines/pipelines_spec.rb
@@ -12,7 +12,7 @@ describe 'Pipelines', :js do
end
describe 'GET /:project/pipelines' do
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
let!(:pipeline) do
create(
@@ -385,7 +385,7 @@ describe 'Pipelines', :js do
end
describe 'GET /:project/pipelines/show' do
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
let(:pipeline) do
create(:ci_empty_pipeline,
@@ -437,7 +437,7 @@ describe 'Pipelines', :js do
end
describe 'POST /:project/pipelines' do
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
before do
visit new_project_pipeline_path(project)
@@ -476,7 +476,7 @@ describe 'Pipelines', :js do
end
describe 'Create pipelines' do
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
before do
visit new_project_pipeline_path(project)
@@ -512,14 +512,14 @@ describe 'Pipelines', :js do
end
context 'when project is public' do
- let(:project) { create(:project, :public) }
+ let(:project) { create(:project, :public, :repository) }
it { expect(page).to have_content 'Build with confidence' }
it { expect(page).to have_http_status(:success) }
end
context 'when project is private' do
- let(:project) { create(:project, :private) }
+ let(:project) { create(:project, :private, :repository) }
it { expect(page).to have_content 'You need to sign in' }
end
diff --git a/spec/features/projects/project_settings_spec.rb b/spec/features/projects/project_settings_spec.rb
index 7e43ef92a72..6001bcfff0a 100644
--- a/spec/features/projects/project_settings_spec.rb
+++ b/spec/features/projects/project_settings_spec.rb
@@ -55,8 +55,7 @@ describe 'Edit Project Settings' do
end
context 'when changing project path' do
- # Not using empty project because we need a repo to exist
- let(:project) { create(:project, namespace: user.namespace, name: 'gitlabhq') }
+ let(:project) { create(:project, :repository, namespace: user.namespace, name: 'gitlabhq') }
before(:context) do
TestEnv.clean_test_path
@@ -97,8 +96,7 @@ describe 'Edit Project Settings' do
end
describe 'Transfer project section', js: true do
- # Not using empty project because we need a repo to exist
- let!(:project) { create(:project, namespace: user.namespace, name: 'gitlabhq') }
+ let!(:project) { create(:project, :repository, namespace: user.namespace, name: 'gitlabhq') }
let!(:group) { create(:group) }
before(:context) do
diff --git a/spec/features/projects/ref_switcher_spec.rb b/spec/features/projects/ref_switcher_spec.rb
index 2512818b297..f0a23729220 100644
--- a/spec/features/projects/ref_switcher_spec.rb
+++ b/spec/features/projects/ref_switcher_spec.rb
@@ -2,7 +2,7 @@ require 'rails_helper'
feature 'Ref switcher', js: true do
let(:user) { create(:user) }
- let(:project) { create(:project, :public) }
+ let(:project) { create(:project, :public, :repository) }
before do
project.team << [user, :master]
diff --git a/spec/features/projects/services/slack_service_spec.rb b/spec/features/projects/services/slack_service_spec.rb
index c10ec5e2987..824cae261e0 100644
--- a/spec/features/projects/services/slack_service_spec.rb
+++ b/spec/features/projects/services/slack_service_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
feature 'Projects > Slack service > Setup events' do
let(:user) { create(:user) }
let(:service) { SlackService.new }
- let(:project) { create(:project, slack_service: service) }
+ let(:project) { create(:empty_project, slack_service: service) }
background do
service.fields
diff --git a/spec/features/projects/services/slack_slash_command_spec.rb b/spec/features/projects/services/slack_slash_command_spec.rb
index a8baf126269..6002c589fba 100644
--- a/spec/features/projects/services/slack_slash_command_spec.rb
+++ b/spec/features/projects/services/slack_slash_command_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
feature 'Slack slash commands' do
given(:user) { create(:user) }
- given(:project) { create(:project) }
+ given(:project) { create(:empty_project) }
given(:service) { project.create_slack_slash_commands_service }
background do
diff --git a/spec/features/projects/settings/visibility_settings_spec.rb b/spec/features/projects/settings/visibility_settings_spec.rb
index 1756c7d00fe..1e705d211ea 100644
--- a/spec/features/projects/settings/visibility_settings_spec.rb
+++ b/spec/features/projects/settings/visibility_settings_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
feature 'Visibility settings', js: true do
let(:user) { create(:user) }
- let(:project) { create(:project, namespace: user.namespace, visibility_level: 20) }
+ let(:project) { create(:empty_project, namespace: user.namespace, visibility_level: 20) }
context 'as owner' do
before do
diff --git a/spec/features/projects/shortcuts_spec.rb b/spec/features/projects/shortcuts_spec.rb
index bf18c444c3d..2c6d0a56311 100644
--- a/spec/features/projects/shortcuts_spec.rb
+++ b/spec/features/projects/shortcuts_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
feature 'Project shortcuts' do
- let(:project) { create(:project, name: 'Victorialand') }
+ let(:project) { create(:empty_project, name: 'Victorialand') }
let(:user) { create(:user) }
describe 'On a project', js: true do
diff --git a/spec/features/projects/snippets/create_snippet_spec.rb b/spec/features/projects/snippets/create_snippet_spec.rb
index 23d4b9233b3..7f0e7e3116c 100644
--- a/spec/features/projects/snippets/create_snippet_spec.rb
+++ b/spec/features/projects/snippets/create_snippet_spec.rb
@@ -4,7 +4,7 @@ feature 'Create Snippet', :js do
include DropzoneHelper
let(:user) { create(:user) }
- let(:project) { create(:project, :repository, :public) }
+ let(:project) { create(:empty_project, :public) }
def fill_form
fill_in 'project_snippet_title', with: 'My Snippet Title'
diff --git a/spec/features/projects/user_browses_files_spec.rb b/spec/features/projects/user_browses_files_spec.rb
index 263a3a29a66..b7a0b72db50 100644
--- a/spec/features/projects/user_browses_files_spec.rb
+++ b/spec/features/projects/user_browses_files_spec.rb
@@ -7,7 +7,7 @@ describe 'User browses files' do
"You're not allowed to make changes to this project directly. "\
"A fork of this project has been created that you can make changes in, so you can submit a merge request."
end
- let(:project) { create(:project, name: 'Shop') }
+ let(:project) { create(:project, :repository, name: 'Shop') }
let(:project2) { create(:project, :repository, name: 'Another Project', path: 'another-project') }
let(:project2_tree_path_root_ref) { project_tree_path(project2, project2.repository.root_ref) }
let(:tree_path_ref_6d39438) { project_tree_path(project, '6d39438') }
diff --git a/spec/features/projects/user_creates_directory_spec.rb b/spec/features/projects/user_creates_directory_spec.rb
index 635bd4493dd..1ba5d83eadf 100644
--- a/spec/features/projects/user_creates_directory_spec.rb
+++ b/spec/features/projects/user_creates_directory_spec.rb
@@ -5,7 +5,7 @@ feature 'User creates a directory', js: true do
"You're not allowed to make changes to this project directly. "\
"A fork of this project has been created that you can make changes in, so you can submit a merge request."
end
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
let(:project2) { create(:project, :repository, name: 'Another Project', path: 'another-project') }
let(:project2_tree_path_root_ref) { project_tree_path(project2, project2.repository.root_ref) }
let(:user) { create(:user) }
diff --git a/spec/features/projects/user_creates_files_spec.rb b/spec/features/projects/user_creates_files_spec.rb
index 0c7f1a775c1..4b78cc4fc53 100644
--- a/spec/features/projects/user_creates_files_spec.rb
+++ b/spec/features/projects/user_creates_files_spec.rb
@@ -5,7 +5,7 @@ describe 'User creates files' do
"You're not allowed to make changes to this project directly. "\
"A fork of this project has been created that you can make changes in, so you can submit a merge request."
end
- let(:project) { create(:project, name: 'Shop') }
+ let(:project) { create(:project, :repository, name: 'Shop') }
let(:project2) { create(:project, :repository, name: 'Another Project', path: 'another-project') }
let(:project_tree_path_root_ref) { project_tree_path(project, project.repository.root_ref) }
let(:project2_tree_path_root_ref) { project_tree_path(project2, project2.repository.root_ref) }
diff --git a/spec/features/projects/user_deletes_files_spec.rb b/spec/features/projects/user_deletes_files_spec.rb
index 97e60862b4f..95cd316be0e 100644
--- a/spec/features/projects/user_deletes_files_spec.rb
+++ b/spec/features/projects/user_deletes_files_spec.rb
@@ -5,7 +5,7 @@ describe 'User deletes files' do
"You're not allowed to make changes to this project directly. "\
"A fork of this project has been created that you can make changes in, so you can submit a merge request."
end
- let(:project) { create(:project, name: 'Shop') }
+ let(:project) { create(:project, :repository, name: 'Shop') }
let(:project2) { create(:project, :repository, name: 'Another Project', path: 'another-project') }
let(:project_tree_path_root_ref) { project_tree_path(project, project.repository.root_ref) }
let(:project2_tree_path_root_ref) { project_tree_path(project2, project2.repository.root_ref) }
diff --git a/spec/features/projects/user_edits_files_spec.rb b/spec/features/projects/user_edits_files_spec.rb
index eb26f1bc123..8ae89c980b9 100644
--- a/spec/features/projects/user_edits_files_spec.rb
+++ b/spec/features/projects/user_edits_files_spec.rb
@@ -5,7 +5,7 @@ describe 'User edits files' do
"You're not allowed to make changes to this project directly. "\
"A fork of this project has been created that you can make changes in, so you can submit a merge request."
end
- let(:project) { create(:project, name: 'Shop') }
+ let(:project) { create(:project, :repository, name: 'Shop') }
let(:project2) { create(:project, :repository, name: 'Another Project', path: 'another-project') }
let(:project_tree_path_root_ref) { project_tree_path(project, project.repository.root_ref) }
let(:project2_tree_path_root_ref) { project_tree_path(project2, project2.repository.root_ref) }
diff --git a/spec/features/projects/user_replaces_files_spec.rb b/spec/features/projects/user_replaces_files_spec.rb
index 50f2ffc4bbf..e284fdefd4f 100644
--- a/spec/features/projects/user_replaces_files_spec.rb
+++ b/spec/features/projects/user_replaces_files_spec.rb
@@ -7,7 +7,7 @@ describe 'User replaces files' do
"You're not allowed to make changes to this project directly. "\
"A fork of this project has been created that you can make changes in, so you can submit a merge request."
end
- let(:project) { create(:project, name: 'Shop') }
+ let(:project) { create(:project, :repository, name: 'Shop') }
let(:project2) { create(:project, :repository, name: 'Another Project', path: 'another-project') }
let(:project_tree_path_root_ref) { project_tree_path(project, project.repository.root_ref) }
let(:project2_tree_path_root_ref) { project_tree_path(project2, project2.repository.root_ref) }
diff --git a/spec/features/projects/user_uploads_files_spec.rb b/spec/features/projects/user_uploads_files_spec.rb
index 64a1439badd..98871317ca3 100644
--- a/spec/features/projects/user_uploads_files_spec.rb
+++ b/spec/features/projects/user_uploads_files_spec.rb
@@ -7,7 +7,7 @@ describe 'User uploads files' do
"You're not allowed to make changes to this project directly. "\
"A fork of this project has been created that you can make changes in, so you can submit a merge request."
end
- let(:project) { create(:project, name: 'Shop') }
+ let(:project) { create(:project, :repository, name: 'Shop') }
let(:project2) { create(:project, :repository, name: 'Another Project', path: 'another-project') }
let(:project_tree_path_root_ref) { project_tree_path(project, project.repository.root_ref) }
let(:project2_tree_path_root_ref) { project_tree_path(project2, project2.repository.root_ref) }
diff --git a/spec/features/projects/wiki/markdown_preview_spec.rb b/spec/features/projects/wiki/markdown_preview_spec.rb
index 45f799ebb48..dbe98a38197 100644
--- a/spec/features/projects/wiki/markdown_preview_spec.rb
+++ b/spec/features/projects/wiki/markdown_preview_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
feature 'Projects > Wiki > User previews markdown changes', js: true do
let(:user) { create(:user) }
- let(:project) { create(:project, namespace: user.namespace) }
+ let(:project) { create(:empty_project, namespace: user.namespace) }
let(:wiki_content) do
<<-HEREDOC
[regular link](regular)
diff --git a/spec/features/projects/wiki/user_creates_wiki_page_spec.rb b/spec/features/projects/wiki/user_creates_wiki_page_spec.rb
index 9d66f482c8d..78c619f6301 100644
--- a/spec/features/projects/wiki/user_creates_wiki_page_spec.rb
+++ b/spec/features/projects/wiki/user_creates_wiki_page_spec.rb
@@ -11,7 +11,7 @@ feature 'Projects > Wiki > User creates wiki page', :js do
end
context 'in the user namespace' do
- let(:project) { create(:project, namespace: user.namespace) }
+ let(:project) { create(:empty_project, namespace: user.namespace) }
context 'when wiki is empty' do
before do
@@ -157,7 +157,7 @@ feature 'Projects > Wiki > User creates wiki page', :js do
end
context 'in a group namespace' do
- let(:project) { create(:project, namespace: create(:group, :public)) }
+ let(:project) { create(:empty_project, namespace: create(:group, :public)) }
context 'when wiki is empty' do
before do
diff --git a/spec/features/projects/wiki/user_git_access_wiki_page_spec.rb b/spec/features/projects/wiki/user_git_access_wiki_page_spec.rb
index 3450c91260b..9c58e336605 100644
--- a/spec/features/projects/wiki/user_git_access_wiki_page_spec.rb
+++ b/spec/features/projects/wiki/user_git_access_wiki_page_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe 'Projects > Wiki > User views Git access wiki page' do
let(:user) { create(:user) }
- let(:project) { create(:project, :public) }
+ let(:project) { create(:empty_project, :public) }
let(:wiki_page) do
WikiPages::CreateService.new(
project,
diff --git a/spec/features/projects/wiki/user_updates_wiki_page_spec.rb b/spec/features/projects/wiki/user_updates_wiki_page_spec.rb
index e3739a705bf..8271428582d 100644
--- a/spec/features/projects/wiki/user_updates_wiki_page_spec.rb
+++ b/spec/features/projects/wiki/user_updates_wiki_page_spec.rb
@@ -12,7 +12,7 @@ feature 'Projects > Wiki > User updates wiki page' do
end
context 'in the user namespace' do
- let(:project) { create(:project, namespace: user.namespace) }
+ let(:project) { create(:empty_project, namespace: user.namespace) }
context 'the home page' do
scenario 'success when the wiki content is not empty' do
@@ -64,7 +64,7 @@ feature 'Projects > Wiki > User updates wiki page' do
end
context 'in a group namespace' do
- let(:project) { create(:project, namespace: create(:group, :public)) }
+ let(:project) { create(:empty_project, namespace: create(:group, :public)) }
scenario 'the home page' do
click_link 'Edit'
diff --git a/spec/features/projects/wiki/user_views_project_wiki_page_spec.rb b/spec/features/projects/wiki/user_views_project_wiki_page_spec.rb
index 92e96f11219..4f94ab1a609 100644
--- a/spec/features/projects/wiki/user_views_project_wiki_page_spec.rb
+++ b/spec/features/projects/wiki/user_views_project_wiki_page_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
feature 'Projects > Wiki > User views the wiki page' do
let(:user) { create(:user) }
- let(:project) { create(:project, :public) }
+ let(:project) { create(:empty_project, :public) }
let(:old_page_version_id) { wiki_page.versions.last.id }
let(:wiki_page) do
WikiPages::CreateService.new(
diff --git a/spec/features/security/group/internal_access_spec.rb b/spec/features/security/group/internal_access_spec.rb
index 53573043ac7..bf7be33013e 100644
--- a/spec/features/security/group/internal_access_spec.rb
+++ b/spec/features/security/group/internal_access_spec.rb
@@ -4,7 +4,7 @@ describe 'Internal Group access' do
include AccessMatchers
let(:group) { create(:group, :internal) }
- let(:project) { create(:project, :internal, group: group) }
+ let(:project) { create(:empty_project, :internal, group: group) }
let(:project_guest) do
create(:user) do |user|
project.add_guest(user)
@@ -49,6 +49,7 @@ describe 'Internal Group access' do
end
describe 'GET /groups/:path/merge_requests' do
+ let(:project) { create(:project, :internal, :repository, group: group) }
subject { merge_requests_group_path(group) }
it { is_expected.to be_allowed_for(:admin) }
diff --git a/spec/features/security/group/private_access_spec.rb b/spec/features/security/group/private_access_spec.rb
index 76c4e2c7197..c399d7a0851 100644
--- a/spec/features/security/group/private_access_spec.rb
+++ b/spec/features/security/group/private_access_spec.rb
@@ -4,7 +4,7 @@ describe 'Private Group access' do
include AccessMatchers
let(:group) { create(:group, :private) }
- let(:project) { create(:project, :private, group: group) }
+ let(:project) { create(:empty_project, :private, group: group) }
let(:project_guest) do
create(:user) do |user|
project.add_guest(user)
@@ -49,6 +49,7 @@ describe 'Private Group access' do
end
describe 'GET /groups/:path/merge_requests' do
+ let(:project) { create(:project, :private, :repository, group: group) }
subject { merge_requests_group_path(group) }
it { is_expected.to be_allowed_for(:admin) }
diff --git a/spec/features/security/group/public_access_spec.rb b/spec/features/security/group/public_access_spec.rb
index 52e87d8d055..63e4d7ca65c 100644
--- a/spec/features/security/group/public_access_spec.rb
+++ b/spec/features/security/group/public_access_spec.rb
@@ -4,7 +4,7 @@ describe 'Public Group access' do
include AccessMatchers
let(:group) { create(:group, :public) }
- let(:project) { create(:project, :public, group: group) }
+ let(:project) { create(:empty_project, :public, group: group) }
let(:project_guest) do
create(:user) do |user|
project.add_guest(user)
@@ -49,6 +49,7 @@ describe 'Public Group access' do
end
describe 'GET /groups/:path/merge_requests' do
+ let(:project) { create(:project, :public, :repository, group: group) }
subject { merge_requests_group_path(group) }
it { is_expected.to be_allowed_for(:admin) }
diff --git a/spec/features/security/project/internal_access_spec.rb b/spec/features/security/project/internal_access_spec.rb
index 290cebf511a..a7928857b7d 100644
--- a/spec/features/security/project/internal_access_spec.rb
+++ b/spec/features/security/project/internal_access_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe "Internal Project Access" do
include AccessMatchers
- set(:project) { create(:project, :internal) }
+ set(:project) { create(:project, :internal, :repository) }
describe "Project should be internal" do
describe '#internal?' do
diff --git a/spec/features/security/project/private_access_spec.rb b/spec/features/security/project/private_access_spec.rb
index 276d817b59c..a4396b20afd 100644
--- a/spec/features/security/project/private_access_spec.rb
+++ b/spec/features/security/project/private_access_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe "Private Project Access" do
include AccessMatchers
- set(:project) { create(:project, :private, public_builds: false) }
+ set(:project) { create(:project, :private, :repository, public_builds: false) }
describe "Project should be private" do
describe '#private?' do
diff --git a/spec/features/security/project/public_access_spec.rb b/spec/features/security/project/public_access_spec.rb
index 417b0894a5c..fccdeb0e5b7 100644
--- a/spec/features/security/project/public_access_spec.rb
+++ b/spec/features/security/project/public_access_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe "Public Project Access" do
include AccessMatchers
- set(:project) { create(:project, :public) }
+ set(:project) { create(:project, :public, :repository) }
describe "Project should be public" do
describe '#public?' do
diff --git a/spec/helpers/diff_helper_spec.rb b/spec/helpers/diff_helper_spec.rb
index 0d909e6e140..060c112e20d 100644
--- a/spec/helpers/diff_helper_spec.rb
+++ b/spec/helpers/diff_helper_spec.rb
@@ -12,19 +12,32 @@ describe DiffHelper do
let(:diff_file) { Gitlab::Diff::File.new(diff, diff_refs: diff_refs, repository: repository) }
describe 'diff_view' do
+ it 'uses the view param over the cookie' do
+ controller.params[:view] = 'parallel'
+ helper.request.cookies[:diff_view] = 'inline'
+
+ expect(helper.diff_view).to eq :parallel
+ end
+
+ it 'returns the default value when the view param is invalid' do
+ controller.params[:view] = 'invalid'
+
+ expect(helper.diff_view).to eq :inline
+ end
+
it 'returns a valid value when cookie is set' do
helper.request.cookies[:diff_view] = 'parallel'
expect(helper.diff_view).to eq :parallel
end
- it 'returns a default value when cookie is invalid' do
+ it 'returns the default value when cookie is invalid' do
helper.request.cookies[:diff_view] = 'invalid'
expect(helper.diff_view).to eq :inline
end
- it 'returns a default value when cookie is nil' do
+ it 'returns the default value when cookie is nil' do
expect(helper.request.cookies).to be_empty
expect(helper.diff_view).to eq :inline
diff --git a/spec/lib/banzai/filter/issuable_state_filter_spec.rb b/spec/lib/banzai/filter/issuable_state_filter_spec.rb
index 7cf2f4282f8..bc7cae1df8d 100644
--- a/spec/lib/banzai/filter/issuable_state_filter_spec.rb
+++ b/spec/lib/banzai/filter/issuable_state_filter_spec.rb
@@ -107,14 +107,6 @@ describe Banzai::Filter::IssuableStateFilter do
expect(doc.css('a').last.text).to eq(issue.to_reference)
end
- it 'ignores reopened issue references' do
- issue = create_issue(:reopened)
- link = create_link(issue.to_reference, issue: issue.id, reference_type: 'issue')
- doc = filter(link, context)
-
- expect(doc.css('a').last.text).to eq(issue.to_reference)
- end
-
it 'appends state to closed issue references' do
link = create_link(closed_issue.to_reference, issue: closed_issue.id, reference_type: 'issue')
doc = filter(link, context)
@@ -139,7 +131,7 @@ describe Banzai::Filter::IssuableStateFilter do
end
it 'ignores reopened merge request references' do
- merge_request = create_merge_request(:reopened)
+ merge_request = create_merge_request(:opened)
link = create_link(
merge_request.to_reference,
diff --git a/spec/lib/gitlab/import_export/all_models.yml b/spec/lib/gitlab/import_export/all_models.yml
index 977174a5fd2..6a41afe0c25 100644
--- a/spec/lib/gitlab/import_export/all_models.yml
+++ b/spec/lib/gitlab/import_export/all_models.yml
@@ -102,6 +102,7 @@ pipelines:
- statuses
- builds
- trigger_requests
+- variables
- auto_canceled_by
- auto_canceled_pipelines
- auto_canceled_jobs
@@ -112,6 +113,8 @@ pipelines:
- artifacts
- pipeline_schedule
- merge_requests
+pipeline_variables:
+- pipeline
stages:
- project
- pipeline
diff --git a/spec/models/ci/build_spec.rb b/spec/models/ci/build_spec.rb
index a18da3768d5..86afa856ea7 100644
--- a/spec/models/ci/build_spec.rb
+++ b/spec/models/ci/build_spec.rb
@@ -1468,6 +1468,12 @@ describe Ci::Build do
it { is_expected.to include(predefined_trigger_variable) }
end
+ context 'when pipeline has a variable' do
+ let!(:pipeline_variable) { create(:ci_pipeline_variable, pipeline: pipeline) }
+
+ it { is_expected.to include(pipeline_variable.to_runner_variable) }
+ end
+
context 'when a job was triggered by a pipeline schedule' do
let(:pipeline_schedule) { create(:ci_pipeline_schedule, project: project) }
diff --git a/spec/models/ci/pipeline_spec.rb b/spec/models/ci/pipeline_spec.rb
index 9461905c787..b0efa689a07 100644
--- a/spec/models/ci/pipeline_spec.rb
+++ b/spec/models/ci/pipeline_spec.rb
@@ -17,6 +17,7 @@ describe Ci::Pipeline do
it { is_expected.to have_many(:statuses) }
it { is_expected.to have_many(:trigger_requests) }
+ it { is_expected.to have_many(:variables) }
it { is_expected.to have_many(:builds) }
it { is_expected.to have_many(:auto_canceled_pipelines) }
it { is_expected.to have_many(:auto_canceled_jobs) }
diff --git a/spec/models/ci/pipeline_variable_spec.rb b/spec/models/ci/pipeline_variable_spec.rb
new file mode 100644
index 00000000000..2ce78e34b0c
--- /dev/null
+++ b/spec/models/ci/pipeline_variable_spec.rb
@@ -0,0 +1,8 @@
+require 'spec_helper'
+
+describe Ci::PipelineVariable, models: true do
+ subject { build(:ci_pipeline_variable) }
+
+ it { is_expected.to include_module(HasVariable) }
+ it { is_expected.to validate_uniqueness_of(:key).scoped_to(:pipeline_id) }
+end
diff --git a/spec/models/project_wiki_spec.rb b/spec/models/project_wiki_spec.rb
index 7fcbeb459e0..c6ceb092810 100644
--- a/spec/models/project_wiki_spec.rb
+++ b/spec/models/project_wiki_spec.rb
@@ -21,7 +21,7 @@ describe ProjectWiki do
describe '#web_url' do
it 'returns the full web URL to the wiki' do
- expect(subject.web_url).to match("https?://[^\/]+/#{project.path_with_namespace}/wikis/home")
+ expect(subject.web_url).to eq("#{Gitlab.config.gitlab.url}/#{project.path_with_namespace}/wikis/home")
end
end
diff --git a/spec/requests/api/issues_spec.rb b/spec/requests/api/issues_spec.rb
index 33cea02153e..2c44be4e447 100644
--- a/spec/requests/api/issues_spec.rb
+++ b/spec/requests/api/issues_spec.rb
@@ -1259,7 +1259,7 @@ describe API::Issues do
put api("/projects/#{project.id}/issues/#{closed_issue.iid}", user), state_event: 'reopen'
expect(response).to have_http_status(200)
- expect(json_response['state']).to eq 'reopened'
+ expect(json_response['state']).to eq 'opened'
end
context 'when an admin or owner makes the request' do
diff --git a/spec/requests/api/triggers_spec.rb b/spec/requests/api/triggers_spec.rb
index c2636b6614e..153596c2975 100644
--- a/spec/requests/api/triggers_spec.rb
+++ b/spec/requests/api/triggers_spec.rb
@@ -22,6 +22,7 @@ describe API::Triggers do
before do
stub_ci_pipeline_to_return_yaml_file
+ trigger.update(owner: user)
end
context 'Handles errors' do
@@ -36,12 +37,6 @@ describe API::Triggers do
expect(response).to have_http_status(404)
end
-
- it 'returns unauthorized if token is for different project' do
- post api("/projects/#{project2.id}/trigger/pipeline"), options.merge(ref: 'master')
-
- expect(response).to have_http_status(401)
- end
end
context 'Have a commit' do
@@ -61,8 +56,7 @@ describe API::Triggers do
post api("/projects/#{project.id}/trigger/pipeline"), options.merge(ref: 'other-branch')
expect(response).to have_http_status(400)
- expect(json_response['message']['base'])
- .to contain_exactly('Reference not found')
+ expect(json_response['message']).to eq('base' => ["Reference not found"])
end
context 'Validates variables' do
@@ -88,12 +82,18 @@ describe API::Triggers do
post api("/projects/#{project.id}/trigger/pipeline"), options.merge(variables: variables, ref: 'master')
expect(response).to have_http_status(201)
- expect(pipeline.builds.reload.first.trigger_request.variables).to eq(variables)
+ expect(pipeline.variables.map { |v| { v.key => v.value } }.last).to eq(variables)
end
end
end
context 'when triggering a pipeline from a trigger token' do
+ it 'does not leak the presence of project when token is for different project' do
+ post api("/projects/#{project2.id}/ref/master/trigger/pipeline?token=#{trigger_token}"), { ref: 'refs/heads/other-branch' }
+
+ expect(response).to have_http_status(404)
+ end
+
it 'creates builds from the ref given in the URL, not in the body' do
expect do
post api("/projects/#{project.id}/ref/master/trigger/pipeline?token=#{trigger_token}"), { ref: 'refs/heads/other-branch' }
diff --git a/spec/requests/api/v3/issues_spec.rb b/spec/requests/api/v3/issues_spec.rb
index cc81922697a..4dff09b6df8 100644
--- a/spec/requests/api/v3/issues_spec.rb
+++ b/spec/requests/api/v3/issues_spec.rb
@@ -1114,7 +1114,7 @@ describe API::V3::Issues do
put v3_api("/projects/#{project.id}/issues/#{closed_issue.id}", user), state_event: 'reopen'
expect(response).to have_http_status(200)
- expect(json_response['state']).to eq 'reopened'
+ expect(json_response['state']).to eq 'opened'
end
context 'when an admin or owner makes the request' do
diff --git a/spec/requests/api/v3/project_hooks_spec.rb b/spec/requests/api/v3/project_hooks_spec.rb
index 1969d1c7f2b..b0eddbb5dd2 100644
--- a/spec/requests/api/v3/project_hooks_spec.rb
+++ b/spec/requests/api/v3/project_hooks_spec.rb
@@ -87,7 +87,7 @@ describe API::ProjectHooks, 'ProjectHooks' do
it "adds hook to project" do
expect do
post v3_api("/projects/#{project.id}/hooks", user),
- url: "http://example.com", issues_events: true, wiki_page_events: true
+ url: "http://example.com", issues_events: true, wiki_page_events: true, build_events: true
end.to change {project.hooks.count}.by(1)
expect(response).to have_http_status(201)
@@ -97,7 +97,7 @@ describe API::ProjectHooks, 'ProjectHooks' do
expect(json_response['merge_requests_events']).to eq(false)
expect(json_response['tag_push_events']).to eq(false)
expect(json_response['note_events']).to eq(false)
- expect(json_response['build_events']).to eq(false)
+ expect(json_response['build_events']).to eq(true)
expect(json_response['pipeline_events']).to eq(false)
expect(json_response['wiki_page_events']).to eq(true)
expect(json_response['enable_ssl_verification']).to eq(true)
@@ -135,7 +135,7 @@ describe API::ProjectHooks, 'ProjectHooks' do
describe "PUT /projects/:id/hooks/:hook_id" do
it "updates an existing project hook" do
put v3_api("/projects/#{project.id}/hooks/#{hook.id}", user),
- url: 'http://example.org', push_events: false
+ url: 'http://example.org', push_events: false, build_events: true
expect(response).to have_http_status(200)
expect(json_response['url']).to eq('http://example.org')
expect(json_response['issues_events']).to eq(hook.issues_events)
diff --git a/spec/services/boards/issues/list_service_spec.rb b/spec/services/boards/issues/list_service_spec.rb
index 2c293088097..b1b5d807a78 100644
--- a/spec/services/boards/issues/list_service_spec.rb
+++ b/spec/services/boards/issues/list_service_spec.rb
@@ -20,7 +20,7 @@ describe Boards::Issues::ListService do
let!(:opened_issue1) { create(:labeled_issue, project: project, labels: [bug]) }
let!(:opened_issue2) { create(:labeled_issue, project: project, labels: [p2]) }
- let!(:reopened_issue1) { create(:issue, :reopened, project: project) }
+ let!(:reopened_issue1) { create(:issue, :opened, project: project) }
let!(:list1_issue1) { create(:labeled_issue, project: project, labels: [p2, development]) }
let!(:list1_issue2) { create(:labeled_issue, project: project, labels: [development]) }
diff --git a/spec/services/boards/issues/move_service_spec.rb b/spec/services/boards/issues/move_service_spec.rb
index 7dd1a601700..15a32350ae2 100644
--- a/spec/services/boards/issues/move_service_spec.rb
+++ b/spec/services/boards/issues/move_service_spec.rb
@@ -73,7 +73,7 @@ describe Boards::Issues::MoveService do
issue.reload
expect(issue.labels).to contain_exactly(bug, testing)
- expect(issue).to be_reopened
+ expect(issue).to be_opened
end
end
diff --git a/spec/services/ci/pipeline_trigger_service_spec.rb b/spec/services/ci/pipeline_trigger_service_spec.rb
new file mode 100644
index 00000000000..945a2fe1a6b
--- /dev/null
+++ b/spec/services/ci/pipeline_trigger_service_spec.rb
@@ -0,0 +1,83 @@
+require 'spec_helper'
+
+describe Ci::PipelineTriggerService, services: true do
+ let(:project) { create(:project, :repository) }
+
+ before do
+ stub_ci_pipeline_to_return_yaml_file
+ end
+
+ describe '#execute' do
+ let(:user) { create(:user) }
+ let(:trigger) { create(:ci_trigger, project: project, owner: user) }
+ let(:result) { described_class.new(project, user, params).execute }
+
+ before do
+ project.add_developer(user)
+ end
+
+ context 'when trigger belongs to a different project' do
+ let(:params) { { token: trigger.token, ref: 'master', variables: nil } }
+ let(:trigger) { create(:ci_trigger, project: create(:empty_project), owner: user) }
+
+ it 'does nothing' do
+ expect { result }.not_to change { Ci::Pipeline.count }
+ end
+ end
+
+ context 'when params have an existsed trigger token' do
+ context 'when params have an existsed ref' do
+ let(:params) { { token: trigger.token, ref: 'master', variables: nil } }
+
+ it 'triggers a pipeline' do
+ expect { result }.to change { Ci::Pipeline.count }.by(1)
+ expect(result[:pipeline].ref).to eq('master')
+ expect(result[:pipeline].project).to eq(project)
+ expect(result[:pipeline].user).to eq(trigger.owner)
+ expect(result[:status]).to eq(:success)
+ end
+
+ context 'when commit message has [ci skip]' do
+ before do
+ allow_any_instance_of(Ci::Pipeline).to receive(:git_commit_message) { '[ci skip]' }
+ end
+
+ it 'ignores [ci skip] and create as general' do
+ expect { result }.to change { Ci::Pipeline.count }.by(1)
+ expect(result[:status]).to eq(:success)
+ end
+ end
+
+ context 'when params have a variable' do
+ let(:params) { { token: trigger.token, ref: 'master', variables: variables } }
+ let(:variables) { { 'AAA' => 'AAA123' } }
+
+ it 'has a variable' do
+ expect { result }.to change { Ci::PipelineVariable.count }.by(1)
+ .and change { Ci::TriggerRequest.count }.by(1)
+ expect(result[:pipeline].variables.map { |v| { v.key => v.value } }.first).to eq(variables)
+ expect(result[:pipeline].trigger_requests.last.variables).to be_nil
+ end
+ end
+ end
+
+ context 'when params have a non-existsed ref' do
+ let(:params) { { token: trigger.token, ref: 'invalid-ref', variables: nil } }
+
+ it 'does not trigger a pipeline' do
+ expect { result }.not_to change { Ci::Pipeline.count }
+ expect(result[:http_status]).to eq(400)
+ end
+ end
+ end
+
+ context 'when params have a non-existsed trigger token' do
+ let(:params) { { token: 'invalid-token', ref: nil, variables: nil } }
+
+ it 'does not trigger a pipeline' do
+ expect { result }.not_to change { Ci::Pipeline.count }
+ expect(result).to be_nil
+ end
+ end
+ end
+end
diff --git a/spec/services/delete_merged_branches_service_spec.rb b/spec/services/delete_merged_branches_service_spec.rb
index 954c5d3ab73..4b872d667cf 100644
--- a/spec/services/delete_merged_branches_service_spec.rb
+++ b/spec/services/delete_merged_branches_service_spec.rb
@@ -43,7 +43,7 @@ describe DeleteMergedBranchesService do
context 'open merge requests' do
it 'does not delete branches from open merge requests' do
fork_link = create(:forked_project_link, forked_from_project: project)
- create(:merge_request, :reopened, source_project: project, target_project: project, source_branch: 'branch-merged', target_branch: 'master')
+ create(:merge_request, :opened, source_project: project, target_project: project, source_branch: 'branch-merged', target_branch: 'master')
create(:merge_request, :opened, source_project: fork_link.forked_to_project, target_project: project, target_branch: 'improve/awesome', source_branch: 'master')
service.execute
diff --git a/spec/services/git_push_service_spec.rb b/spec/services/git_push_service_spec.rb
index 75329e9dda2..3fb677b65be 100644
--- a/spec/services/git_push_service_spec.rb
+++ b/spec/services/git_push_service_spec.rb
@@ -1,29 +1,26 @@
require 'spec_helper'
-describe GitPushService do
+describe GitPushService, services: true do
include RepoHelpers
- let(:user) { create(:user) }
- let(:project) { create(:project, :repository) }
+ let(:user) { create(:user) }
+ let(:project) { create(:project, :repository) }
+ let(:blankrev) { Gitlab::Git::BLANK_SHA }
+ let(:oldrev) { sample_commit.parent_id }
+ let(:newrev) { sample_commit.id }
+ let(:ref) { 'refs/heads/master' }
before do
project.team << [user, :master]
- @blankrev = Gitlab::Git::BLANK_SHA
- @oldrev = sample_commit.parent_id
- @newrev = sample_commit.id
- @ref = 'refs/heads/master'
end
describe 'Push branches' do
- let(:oldrev) { @oldrev }
- let(:newrev) { @newrev }
-
subject do
- execute_service(project, user, oldrev, newrev, @ref )
+ execute_service(project, user, oldrev, newrev, ref)
end
context 'new branch' do
- let(:oldrev) { @blankrev }
+ let(:oldrev) { blankrev }
it { is_expected.to be_truthy }
@@ -51,7 +48,7 @@ describe GitPushService do
end
context 'rm branch' do
- let(:newrev) { @blankrev }
+ let(:newrev) { blankrev }
it { is_expected.to be_truthy }
@@ -70,24 +67,20 @@ describe GitPushService do
end
describe "Git Push Data" do
- before do
- service = execute_service(project, user, @oldrev, @newrev, @ref )
- @push_data = service.push_data
- @commit = project.commit(@newrev)
- end
+ let(:commit) { project.commit(newrev) }
- subject { @push_data }
+ subject { push_data_from_service(project, user, oldrev, newrev, ref) }
it { is_expected.to include(object_kind: 'push') }
- it { is_expected.to include(before: @oldrev) }
- it { is_expected.to include(after: @newrev) }
- it { is_expected.to include(ref: @ref) }
+ it { is_expected.to include(before: oldrev) }
+ it { is_expected.to include(after: newrev) }
+ it { is_expected.to include(ref: ref) }
it { is_expected.to include(user_id: user.id) }
it { is_expected.to include(user_name: user.name) }
it { is_expected.to include(project_id: project.id) }
context "with repository data" do
- subject { @push_data[:repository] }
+ subject { push_data_from_service(project, user, oldrev, newrev, ref)[:repository] }
it { is_expected.to include(name: project.name) }
it { is_expected.to include(url: project.url_to_repo) }
@@ -96,7 +89,7 @@ describe GitPushService do
end
context "with commits" do
- subject { @push_data[:commits] }
+ subject { push_data_from_service(project, user, oldrev, newrev, ref)[:commits] }
it { is_expected.to be_an(Array) }
it 'has 1 element' do
@@ -104,11 +97,11 @@ describe GitPushService do
end
context "the commit" do
- subject { @push_data[:commits].first }
+ subject { push_data_from_service(project, user, oldrev, newrev, ref)[:commits].first }
- it { is_expected.to include(id: @commit.id) }
- it { is_expected.to include(message: @commit.safe_message) }
- it { expect(subject[:timestamp].in_time_zone).to eq(@commit.date.in_time_zone) }
+ it { is_expected.to include(id: commit.id) }
+ it { is_expected.to include(message: commit.safe_message) }
+ it { expect(subject[:timestamp].in_time_zone).to eq(commit.date.in_time_zone) }
it do
is_expected.to include(
url: [
@@ -116,23 +109,23 @@ describe GitPushService do
project.namespace.to_param,
project.to_param,
'commit',
- @commit.id
+ commit.id
].join('/')
)
end
context "with a author" do
- subject { @push_data[:commits].first[:author] }
+ subject { push_data_from_service(project, user, oldrev, newrev, ref)[:commits].first[:author] }
- it { is_expected.to include(name: @commit.author_name) }
- it { is_expected.to include(email: @commit.author_email) }
+ it { is_expected.to include(name: commit.author_name) }
+ it { is_expected.to include(email: commit.author_email) }
end
end
end
end
describe "Pipelines" do
- subject { execute_service(project, user, @oldrev, @newrev, @ref) }
+ subject { execute_service(project, user, oldrev, newrev, ref) }
before do
stub_ci_pipeline_to_return_yaml_file
@@ -145,29 +138,26 @@ describe GitPushService do
end
describe "Push Event" do
- before do
- service = execute_service(project, user, @oldrev, @newrev, @ref )
- @event = Event.find_by_action(Event::PUSHED)
- @push_data = service.push_data
- end
+ let!(:push_data) { push_data_from_service(project, user, oldrev, newrev, ref) }
+ let(:event) { Event.find_by_action(Event::PUSHED) }
- it { expect(@event).not_to be_nil }
- it { expect(@event.project).to eq(project) }
- it { expect(@event.action).to eq(Event::PUSHED) }
- it { expect(@event.data).to eq(@push_data) }
+ it { expect(event).not_to be_nil }
+ it { expect(event.project).to eq(project) }
+ it { expect(event.action).to eq(Event::PUSHED) }
+ it { expect(event.data).to eq(push_data) }
context "Updates merge requests" do
it "when pushing a new branch for the first time" do
expect(UpdateMergeRequestsWorker).to receive(:perform_async)
- .with(project.id, user.id, @blankrev, 'newrev', 'refs/heads/master')
- execute_service(project, user, @blankrev, 'newrev', 'refs/heads/master' )
+ .with(project.id, user.id, blankrev, 'newrev', ref)
+ execute_service(project, user, blankrev, 'newrev', ref )
end
end
context "Sends System Push data" do
it "when pushing on a branch" do
- expect(SystemHookPushWorker).to receive(:perform_async).with(@push_data, :push_hooks)
- execute_service(project, user, @oldrev, @newrev, @ref )
+ expect(SystemHookPushWorker).to receive(:perform_async).with(push_data, :push_hooks)
+ execute_service(project, user, oldrev, newrev, ref)
end
end
end
@@ -177,13 +167,13 @@ describe GitPushService do
it "calls the copy attributes method for the first push to the default branch" do
expect(project.repository).to receive(:copy_gitattributes).with('master')
- execute_service(project, user, @blankrev, 'newrev', 'refs/heads/master')
+ execute_service(project, user, blankrev, 'newrev', ref)
end
it "calls the copy attributes method for changes to the default branch" do
- expect(project.repository).to receive(:copy_gitattributes).with('refs/heads/master')
+ expect(project.repository).to receive(:copy_gitattributes).with(ref)
- execute_service(project, user, 'oldrev', 'newrev', 'refs/heads/master')
+ execute_service(project, user, 'oldrev', 'newrev', ref)
end
end
@@ -196,7 +186,7 @@ describe GitPushService do
it "does not call copy attributes method" do
expect(project.repository).not_to receive(:copy_gitattributes)
- execute_service(project, user, @oldrev, @newrev, @ref)
+ execute_service(project, user, oldrev, newrev, ref)
end
end
end
@@ -206,7 +196,7 @@ describe GitPushService do
it "when pushing a branch for the first time" do
expect(project).to receive(:execute_hooks)
expect(project.default_branch).to eq("master")
- execute_service(project, user, @blankrev, 'newrev', 'refs/heads/master' )
+ execute_service(project, user, blankrev, 'newrev', ref)
expect(project.protected_branches).not_to be_empty
expect(project.protected_branches.first.push_access_levels.map(&:access_level)).to eq([Gitlab::Access::MASTER])
expect(project.protected_branches.first.merge_access_levels.map(&:access_level)).to eq([Gitlab::Access::MASTER])
@@ -217,7 +207,7 @@ describe GitPushService do
expect(project).to receive(:execute_hooks)
expect(project.default_branch).to eq("master")
- execute_service(project, user, @blankrev, 'newrev', 'refs/heads/master' )
+ execute_service(project, user, blankrev, 'newrev', ref)
expect(project.protected_branches).to be_empty
end
@@ -227,7 +217,7 @@ describe GitPushService do
expect(project).to receive(:execute_hooks)
expect(project.default_branch).to eq("master")
- execute_service(project, user, @blankrev, 'newrev', 'refs/heads/master' )
+ execute_service(project, user, blankrev, 'newrev', ref)
expect(project.protected_branches).not_to be_empty
expect(project.protected_branches.last.push_access_levels.map(&:access_level)).to eq([Gitlab::Access::DEVELOPER])
@@ -242,7 +232,7 @@ describe GitPushService do
expect(project.default_branch).to eq("master")
expect_any_instance_of(ProtectedBranches::CreateService).not_to receive(:execute)
- execute_service(project, user, @blankrev, 'newrev', 'refs/heads/master' )
+ execute_service(project, user, blankrev, 'newrev', ref)
expect(project.protected_branches).not_to be_empty
expect(project.protected_branches.last.push_access_levels.map(&:access_level)).to eq([Gitlab::Access::NO_ACCESS])
@@ -254,7 +244,7 @@ describe GitPushService do
expect(project).to receive(:execute_hooks)
expect(project.default_branch).to eq("master")
- execute_service(project, user, @blankrev, 'newrev', 'refs/heads/master' )
+ execute_service(project, user, blankrev, 'newrev', ref)
expect(project.protected_branches).not_to be_empty
expect(project.protected_branches.first.push_access_levels.map(&:access_level)).to eq([Gitlab::Access::MASTER])
expect(project.protected_branches.first.merge_access_levels.map(&:access_level)).to eq([Gitlab::Access::DEVELOPER])
@@ -262,7 +252,7 @@ describe GitPushService do
it "when pushing new commits to existing branch" do
expect(project).to receive(:execute_hooks)
- execute_service(project, user, 'oldrev', 'newrev', 'refs/heads/master' )
+ execute_service(project, user, 'oldrev', 'newrev', ref)
end
end
end
@@ -292,7 +282,7 @@ describe GitPushService do
it "creates a note if a pushed commit mentions an issue" do
expect(SystemNoteService).to receive(:cross_reference).with(issue, commit, commit_author)
- execute_service(project, user, @oldrev, @newrev, @ref )
+ execute_service(project, user, oldrev, newrev, ref)
end
it "only creates a cross-reference note if one doesn't already exist" do
@@ -300,7 +290,7 @@ describe GitPushService do
expect(SystemNoteService).not_to receive(:cross_reference).with(issue, commit, commit_author)
- execute_service(project, user, @oldrev, @newrev, @ref )
+ execute_service(project, user, oldrev, newrev, ref)
end
it "defaults to the pushing user if the commit's author is not known" do
@@ -310,16 +300,16 @@ describe GitPushService do
)
expect(SystemNoteService).to receive(:cross_reference).with(issue, commit, user)
- execute_service(project, user, @oldrev, @newrev, @ref )
+ execute_service(project, user, oldrev, newrev, ref)
end
it "finds references in the first push to a non-default branch" do
- allow(project.repository).to receive(:commits_between).with(@blankrev, @newrev).and_return([])
- allow(project.repository).to receive(:commits_between).with("master", @newrev).and_return([commit])
+ allow(project.repository).to receive(:commits_between).with(blankrev, newrev).and_return([])
+ allow(project.repository).to receive(:commits_between).with("master", newrev).and_return([commit])
expect(SystemNoteService).to receive(:cross_reference).with(issue, commit, commit_author)
- execute_service(project, user, @blankrev, @newrev, 'refs/heads/other' )
+ execute_service(project, user, blankrev, newrev, 'refs/heads/other')
end
end
@@ -349,14 +339,14 @@ describe GitPushService do
context "while saving the 'first_mentioned_in_commit_at' metric for an issue" do
it 'sets the metric for referenced issues' do
- execute_service(project, user, @oldrev, @newrev, @ref)
+ execute_service(project, user, oldrev, newrev, ref)
expect(issue.reload.metrics.first_mentioned_in_commit_at).to be_like_time(commit_time)
end
it 'does not set the metric for non-referenced issues' do
non_referenced_issue = create(:issue, project: project)
- execute_service(project, user, @oldrev, @newrev, @ref)
+ execute_service(project, user, oldrev, newrev, ref)
expect(non_referenced_issue.reload.metrics.first_mentioned_in_commit_at).to be_nil
end
@@ -388,18 +378,18 @@ describe GitPushService do
context "to default branches" do
it "closes issues" do
- execute_service(project, commit_author, @oldrev, @newrev, @ref )
+ execute_service(project, commit_author, oldrev, newrev, ref)
expect(Issue.find(issue.id)).to be_closed
end
it "adds a note indicating that the issue is now closed" do
expect(SystemNoteService).to receive(:change_status).with(issue, project, commit_author, "closed", closing_commit)
- execute_service(project, commit_author, @oldrev, @newrev, @ref )
+ execute_service(project, commit_author, oldrev, newrev, ref)
end
it "doesn't create additional cross-reference notes" do
expect(SystemNoteService).not_to receive(:cross_reference)
- execute_service(project, commit_author, @oldrev, @newrev, @ref )
+ execute_service(project, commit_author, oldrev, newrev, ref)
end
end
@@ -411,11 +401,11 @@ describe GitPushService do
it "creates cross-reference notes" do
expect(SystemNoteService).to receive(:cross_reference).with(issue, closing_commit, commit_author)
- execute_service(project, user, @oldrev, @newrev, @ref )
+ execute_service(project, user, oldrev, newrev, ref)
end
it "doesn't close issues" do
- execute_service(project, user, @oldrev, @newrev, @ref )
+ execute_service(project, user, oldrev, newrev, ref)
expect(Issue.find(issue.id)).to be_opened
end
end
@@ -432,11 +422,12 @@ describe GitPushService do
stub_jira_urls("JIRA-1")
allow(closing_commit).to receive_messages({
- issue_closing_regex: Regexp.new(Gitlab.config.gitlab.issue_closing_pattern),
- safe_message: message,
- author_name: commit_author.name,
- author_email: commit_author.email
- })
+ issue_closing_regex: Regexp.new(Gitlab.config.gitlab.issue_closing_pattern),
+ safe_message: message,
+ author_name: commit_author.name,
+ author_email: commit_author.email
+ })
+
allow(JIRA::Resource::Remotelink).to receive(:all).and_return([])
allow(project.repository).to receive_messages(commits_between: [closing_commit])
@@ -450,7 +441,7 @@ describe GitPushService do
let(:message) { "this is some work.\n\nrelated to JIRA-1" }
it "initiates one api call to jira server to mention the issue" do
- execute_service(project, user, @oldrev, @newrev, @ref)
+ execute_service(project, user, oldrev, newrev, ref)
expect(WebMock).to have_requested(:post, jira_api_comment_url('JIRA-1')).with(
body: /mentioned this issue in/
@@ -460,7 +451,11 @@ describe GitPushService do
context "closing an issue" do
let(:message) { "this is some work.\n\ncloses JIRA-1" }
- let(:comment_body) { { body: "Issue solved with [#{closing_commit.id}|http://#{Gitlab.config.gitlab.host}/#{project.path_with_namespace}/commit/#{closing_commit.id}]." }.to_json }
+ let(:comment_body) do
+ {
+ body: "Issue solved with [#{closing_commit.id}|http://#{Gitlab.config.gitlab.host}/#{project.path_with_namespace}/commit/#{closing_commit.id}]."
+ }.to_json
+ end
before do
open_issue = JIRA::Resource::Issue.new(jira_tracker.client, attrs: { "id" => "JIRA-1" })
@@ -474,13 +469,13 @@ describe GitPushService do
context "using right markdown" do
it "initiates one api call to jira server to close the issue" do
- execute_service(project, commit_author, @oldrev, @newrev, @ref )
+ execute_service(project, commit_author, oldrev, newrev, ref)
expect(WebMock).to have_requested(:post, jira_api_transition_url('JIRA-1')).once
end
it "initiates one api call to jira server to comment on the issue" do
- execute_service(project, commit_author, @oldrev, @newrev, @ref )
+ execute_service(project, commit_author, oldrev, newrev, ref)
expect(WebMock).to have_requested(:post, jira_api_comment_url('JIRA-1')).with(
body: comment_body
@@ -497,13 +492,13 @@ describe GitPushService do
let(:message) { "this is some work.\n\ncloses #1" }
it "does not initiates one api call to jira server to close the issue" do
- execute_service(project, commit_author, @oldrev, @newrev, @ref )
+ execute_service(project, commit_author, oldrev, newrev, ref)
expect(WebMock).not_to have_requested(:post, jira_api_transition_url('JIRA-1'))
end
it "does not initiates one api call to jira server to comment on the issue" do
- execute_service(project, commit_author, @oldrev, @newrev, @ref )
+ execute_service(project, commit_author, oldrev, newrev, ref)
expect(WebMock).not_to have_requested(:post, jira_api_comment_url('JIRA-1')).with(
body: comment_body
@@ -516,13 +511,13 @@ describe GitPushService do
let(:message) { "this is some work.\n\ncloses JIRA-1 \n\n closes #{issue.to_reference}" }
it "initiates one api call to jira server to close the jira issue" do
- execute_service(project, commit_author, @oldrev, @newrev, @ref )
+ execute_service(project, commit_author, oldrev, newrev, ref)
expect(WebMock).to have_requested(:post, jira_api_transition_url('JIRA-1')).once
end
it "initiates one api call to jira server to comment on the jira issue" do
- execute_service(project, commit_author, @oldrev, @newrev, @ref )
+ execute_service(project, commit_author, oldrev, newrev, ref)
expect(WebMock).to have_requested(:post, jira_api_comment_url('JIRA-1')).with(
body: comment_body
@@ -530,14 +525,14 @@ describe GitPushService do
end
it "closes the internal issue" do
- execute_service(project, commit_author, @oldrev, @newrev, @ref )
+ execute_service(project, commit_author, oldrev, newrev, ref)
expect(issue.reload).to be_closed
end
it "adds a note indicating that the issue is now closed" do
expect(SystemNoteService).to receive(:change_status)
.with(issue, project, commit_author, "closed", closing_commit)
- execute_service(project, commit_author, @oldrev, @newrev, @ref )
+ execute_service(project, commit_author, oldrev, newrev, ref)
end
end
end
@@ -547,7 +542,7 @@ describe GitPushService do
describe "empty project" do
let(:project) { create(:project_empty_repo) }
- let(:new_ref) { 'refs/heads/feature'}
+ let(:new_ref) { 'refs/heads/feature' }
before do
allow(project).to receive(:default_branch).and_return('feature')
@@ -555,7 +550,7 @@ describe GitPushService do
end
it 'push to first branch updates HEAD' do
- execute_service(project, user, @blankrev, @newrev, new_ref )
+ execute_service(project, user, blankrev, newrev, new_ref)
end
end
@@ -580,7 +575,7 @@ describe GitPushService do
it 'does not perform housekeeping when not needed' do
expect(housekeeping).not_to receive(:execute)
- execute_service(project, user, @oldrev, @newrev, @ref)
+ execute_service(project, user, oldrev, newrev, ref)
end
context 'when housekeeping is needed' do
@@ -591,20 +586,20 @@ describe GitPushService do
it 'performs housekeeping' do
expect(housekeeping).to receive(:execute)
- execute_service(project, user, @oldrev, @newrev, @ref)
+ execute_service(project, user, oldrev, newrev, ref)
end
it 'does not raise an exception' do
allow(housekeeping).to receive(:try_obtain_lease).and_return(false)
- execute_service(project, user, @oldrev, @newrev, @ref)
+ execute_service(project, user, oldrev, newrev, ref)
end
end
it 'increments the push counter' do
expect(housekeeping).to receive(:increment!)
- execute_service(project, user, @oldrev, @newrev, @ref)
+ execute_service(project, user, oldrev, newrev, ref)
end
end
@@ -612,9 +607,9 @@ describe GitPushService do
let(:service) do
described_class.new(project,
user,
- oldrev: sample_commit.parent_id,
- newrev: sample_commit.id,
- ref: 'refs/heads/master')
+ oldrev: oldrev,
+ newrev: newrev,
+ ref: ref)
end
context 'on the default branch' do
@@ -657,14 +652,13 @@ describe GitPushService do
let(:service) do
described_class.new(project,
user,
- oldrev: sample_commit.parent_id,
- newrev: sample_commit.id,
- ref: 'refs/heads/master')
+ oldrev: oldrev,
+ newrev: newrev,
+ ref: ref)
end
it 'only schedules a limited number of commits' do
- allow(service).to receive(:push_commits)
- .and_return(Array.new(1000, double(:commit, to_hash: {}, matches_cross_reference_regex?: true)))
+ service.push_commits = Array.new(1000, double(:commit, to_hash: {}, matches_cross_reference_regex?: true))
expect(ProcessCommitWorker).to receive(:perform_async).exactly(100).times
@@ -672,8 +666,7 @@ describe GitPushService do
end
it "skips commits which don't include cross-references" do
- allow(service).to receive(:push_commits)
- .and_return([double(:commit, to_hash: {}, matches_cross_reference_regex?: false)])
+ service.push_commits = [double(:commit, to_hash: {}, matches_cross_reference_regex?: false)]
expect(ProcessCommitWorker).not_to receive(:perform_async)
@@ -686,8 +679,8 @@ describe GitPushService do
described_class.new(
project,
user,
- oldrev: sample_commit.parent_id,
- newrev: sample_commit.id,
+ oldrev: oldrev,
+ newrev: newrev,
ref: 'refs/heads/master'
)
end
@@ -695,13 +688,17 @@ describe GitPushService do
it 'calls CreateGpgSignatureWorker.perform_async for each commit' do
expect(CreateGpgSignatureWorker).to receive(:perform_async).with(sample_commit.id, project.id)
- execute_service(project, user, @oldrev, @newrev, @ref)
+ execute_service(project, user, oldrev, newrev, ref)
end
end
def execute_service(project, user, oldrev, newrev, ref)
- service = described_class.new(project, user, oldrev: oldrev, newrev: newrev, ref: ref )
+ service = described_class.new(project, user, oldrev: oldrev, newrev: newrev, ref: ref)
service.execute
service
end
+
+ def push_data_from_service(project, user, oldrev, newrev, ref)
+ execute_service(project, user, oldrev, newrev, ref).push_data
+ end
end
diff --git a/spec/services/groups/destroy_service_spec.rb b/spec/services/groups/destroy_service_spec.rb
index 3e7aa8c835c..c18870ea100 100644
--- a/spec/services/groups/destroy_service_spec.rb
+++ b/spec/services/groups/destroy_service_spec.rb
@@ -35,6 +35,16 @@ describe Groups::DestroyService do
it { expect(NotificationSetting.unscoped.all).not_to include(notification_setting) }
end
+ context 'mattermost team' do
+ let!(:chat_team) { create(:chat_team, namespace: group) }
+
+ it 'destroys the team too' do
+ expect_any_instance_of(Mattermost::Team).to receive(:destroy)
+
+ destroy_group(group, user, async)
+ end
+ end
+
context 'file system' do
context 'Sidekiq inline' do
before do
diff --git a/spec/services/merge_requests/get_urls_service_spec.rb b/spec/services/merge_requests/get_urls_service_spec.rb
index 4a7d8ab4c6c..672d86e4028 100644
--- a/spec/services/merge_requests/get_urls_service_spec.rb
+++ b/spec/services/merge_requests/get_urls_service_spec.rb
@@ -78,7 +78,7 @@ describe MergeRequests::GetUrlsService do
end
context 'pushing to existing branch and merge request is reopened' do
- let!(:merge_request) { create(:merge_request, :reopened, source_project: project, source_branch: source_branch) }
+ let!(:merge_request) { create(:merge_request, :opened, source_project: project, source_branch: source_branch) }
let(:changes) { existing_branch_changes }
it_behaves_like 'show_merge_request_url'
end
diff --git a/spec/services/merge_requests/reopen_service_spec.rb b/spec/services/merge_requests/reopen_service_spec.rb
index ce1e9f2ff45..f02af0c582e 100644
--- a/spec/services/merge_requests/reopen_service_spec.rb
+++ b/spec/services/merge_requests/reopen_service_spec.rb
@@ -28,7 +28,7 @@ describe MergeRequests::ReopenService do
end
it { expect(merge_request).to be_valid }
- it { expect(merge_request).to be_reopened }
+ it { expect(merge_request).to be_opened }
it 'executes hooks with reopen action' do
expect(service).to have_received(:execute_hooks)
diff --git a/spec/services/web_hook_service_spec.rb b/spec/services/web_hook_service_spec.rb
index a5de86a0835..e79c12daa1c 100644
--- a/spec/services/web_hook_service_spec.rb
+++ b/spec/services/web_hook_service_spec.rb
@@ -53,7 +53,7 @@ describe WebHookService do
end
it 'handles exceptions' do
- exceptions = [SocketError, OpenSSL::SSL::SSLError, Errno::ECONNRESET, Errno::ECONNREFUSED, Net::OpenTimeout]
+ exceptions = [SocketError, OpenSSL::SSL::SSLError, Errno::ECONNRESET, Errno::ECONNREFUSED, Errno::EHOSTUNREACH, Net::OpenTimeout, Net::ReadTimeout]
exceptions.each do |exception_class|
exception = exception_class.new('Exception message')
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index e7329210896..85335643921 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -59,6 +59,7 @@ RSpec.configure do |config|
config.include Gitlab::Routing, type: :routing
config.include MigrationsHelpers, :migration
config.include StubFeatureFlags
+ config.include StubENV
config.infer_spec_type_from_file_location!
diff --git a/spec/support/capybara.rb b/spec/support/capybara.rb
index 3e5d6cf1364..c45c4a4310d 100644
--- a/spec/support/capybara.rb
+++ b/spec/support/capybara.rb
@@ -36,7 +36,14 @@ RSpec.configure do |config|
$capybara_server_already_started = true
end
- config.after(:each, :js) do |example|
+ config.before(:example, :js) do
+ allow(Gitlab::Application.routes).to receive(:default_url_options).and_return(
+ host: Capybara.current_session.server.host,
+ port: Capybara.current_session.server.port,
+ protocol: 'http')
+ end
+
+ config.after(:example, :js) do |example|
# capybara/rspec already calls Capybara.reset_sessions! in an `after` hook,
# but `block_and_wait_for_requests_complete` is called before it so by
# calling it explicitely here, we prevent any new requests from being fired
diff --git a/spec/support/test_env.rb b/spec/support/test_env.rb
index 7682bdf8cd0..86f9568c12e 100644
--- a/spec/support/test_env.rb
+++ b/spec/support/test_env.rb
@@ -147,7 +147,7 @@ module TestEnv
gitaly_exec = File.join(gitaly_dir, 'gitaly')
gitaly_config = File.join(gitaly_dir, 'config.toml')
log_file = Rails.root.join('log/gitaly-test.log').to_s
- @gitaly_pid = spawn(gitaly_exec, gitaly_config, [:out, :err] => log_file)
+ @gitaly_pid = Bundler.with_original_env { spawn(gitaly_exec, gitaly_config, [:out, :err] => log_file) }
end
def stop_gitaly
diff --git a/spec/views/shared/projects/_project.html.haml_spec.rb b/spec/views/shared/projects/_project.html.haml_spec.rb
new file mode 100644
index 00000000000..43334c2c236
--- /dev/null
+++ b/spec/views/shared/projects/_project.html.haml_spec.rb
@@ -0,0 +1,19 @@
+require 'spec_helper'
+
+describe 'shared/projects/_project.html.haml' do
+ let(:project) { create(:empty_project) }
+
+ it 'should render creator avatar if project has a creator' do
+ render 'shared/projects/project', use_creator_avatar: true, project: project
+
+ expect(rendered).to have_selector('img.avatar')
+ end
+
+ it 'should render a generic avatar if project does not have a creator' do
+ project.creator = nil
+
+ render 'shared/projects/project', use_creator_avatar: true, project: project
+
+ expect(rendered).to have_selector('.project-avatar')
+ end
+end
diff --git a/spec/workers/git_garbage_collect_worker_spec.rb b/spec/workers/git_garbage_collect_worker_spec.rb
index 309b3172da1..05f971dfd13 100644
--- a/spec/workers/git_garbage_collect_worker_spec.rb
+++ b/spec/workers/git_garbage_collect_worker_spec.rb
@@ -9,17 +9,51 @@ describe GitGarbageCollectWorker do
subject { described_class.new }
describe "#perform" do
- it "flushes ref caches when the task is 'gc'" do
- expect(subject).to receive(:command).with(:gc).and_return([:the, :command])
- expect(Gitlab::Popen).to receive(:popen)
- .with([:the, :command], project.repository.path_to_repo).and_return(["", 0])
+ shared_examples 'flushing ref caches' do |gitaly|
+ it "flushes ref caches when the task if 'gc'" do
+ expect(subject).to receive(:command).with(:gc).and_return([:the, :command])
+
+ if gitaly
+ expect_any_instance_of(Gitlab::GitalyClient::RepositoryService).to receive(:garbage_collect)
+ .and_return(nil)
+ else
+ expect(Gitlab::Popen).to receive(:popen)
+ .with([:the, :command], project.repository.path_to_repo).and_return(["", 0])
+ end
+
+ expect_any_instance_of(Repository).to receive(:after_create_branch).and_call_original
+ expect_any_instance_of(Repository).to receive(:branch_names).and_call_original
+ expect_any_instance_of(Repository).to receive(:branch_count).and_call_original
+ expect_any_instance_of(Repository).to receive(:has_visible_content?).and_call_original
+
+ subject.perform(project.id)
+ end
+ end
+
+ context "with Gitaly turned on" do
+ it_should_behave_like 'flushing ref caches', true
+ end
+
+ context "with Gitaly turned off", skip_gitaly_mock: true do
+ it_should_behave_like 'flushing ref caches', false
+ end
- expect_any_instance_of(Repository).to receive(:after_create_branch).and_call_original
- expect_any_instance_of(Repository).to receive(:branch_names).and_call_original
- expect_any_instance_of(Repository).to receive(:branch_count).and_call_original
- expect_any_instance_of(Repository).to receive(:has_visible_content?).and_call_original
+ context "repack_full" do
+ it "calls Gitaly" do
+ expect_any_instance_of(Gitlab::GitalyClient::RepositoryService).to receive(:repack_full)
+ .and_return(nil)
- subject.perform(project.id)
+ subject.perform(project.id, :full_repack)
+ end
+ end
+
+ context "repack_incremental" do
+ it "calls Gitaly" do
+ expect_any_instance_of(Gitlab::GitalyClient::RepositoryService).to receive(:repack_incremental)
+ .and_return(nil)
+
+ subject.perform(project.id, :incremental_repack)
+ end
end
shared_examples 'gc tasks' do