summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.eslintrc33
-rw-r--r--.gitignore1
-rw-r--r--.gitlab-ci.yml29
-rw-r--r--CHANGELOG.md125
-rw-r--r--Gemfile2
-rw-r--r--Gemfile.lock31
-rw-r--r--VERSION2
-rw-r--r--app/assets/javascripts/activities.js.es63
-rw-r--r--app/assets/javascripts/boards/components/board_card.js.es63
-rw-r--r--app/assets/javascripts/boards/components/board_list.js.es69
-rw-r--r--app/assets/javascripts/boards/models/list.js.es68
-rw-r--r--app/assets/javascripts/boards/stores/boards_store.js.es64
-rw-r--r--app/assets/javascripts/build.js2
-rw-r--r--app/assets/javascripts/commits.js6
-rw-r--r--app/assets/javascripts/cycle_analytics/components/stage_code_component.js.es62
-rw-r--r--app/assets/javascripts/cycle_analytics/components/stage_issue_component.js.es62
-rw-r--r--app/assets/javascripts/cycle_analytics/components/stage_plan_component.js.es62
-rw-r--r--app/assets/javascripts/cycle_analytics/components/stage_production_component.js.es62
-rw-r--r--app/assets/javascripts/cycle_analytics/components/stage_review_component.js.es62
-rw-r--r--app/assets/javascripts/cycle_analytics/components/stage_staging_component.js.es62
-rw-r--r--app/assets/javascripts/cycle_analytics/components/stage_test_component.js.es62
-rw-r--r--app/assets/javascripts/cycle_analytics/components/total_time_component.js.es62
-rw-r--r--app/assets/javascripts/cycle_analytics/cycle_analytics_bundle.js.es64
-rw-r--r--app/assets/javascripts/cycle_analytics/cycle_analytics_store.js.es68
-rw-r--r--app/assets/javascripts/due_date_select.js.es622
-rw-r--r--app/assets/javascripts/environments/components/environment.js.es621
-rw-r--r--app/assets/javascripts/environments/components/environment_item.js.es67
-rw-r--r--app/assets/javascripts/extensions/element.js.es62
-rw-r--r--app/assets/javascripts/lib/utils/custom_event_polyfill.js.es612
-rw-r--r--app/assets/javascripts/lib/utils/datetime_utility.js8
-rw-r--r--app/assets/javascripts/logo.js2
-rw-r--r--app/assets/javascripts/merge_request_widget.js.es66
-rw-r--r--app/assets/javascripts/notes.js1
-rw-r--r--app/assets/javascripts/profile/profile.js.es61
-rw-r--r--app/assets/javascripts/tree.js1
-rw-r--r--app/assets/javascripts/users/calendar.js1
-rw-r--r--app/assets/stylesheets/framework/common.scss4
-rw-r--r--app/assets/stylesheets/framework/forms.scss41
-rw-r--r--app/assets/stylesheets/framework/issue_box.scss4
-rw-r--r--app/assets/stylesheets/pages/boards.scss2
-rw-r--r--app/assets/stylesheets/pages/environments.scss25
-rw-r--r--app/assets/stylesheets/pages/icons.scss53
-rw-r--r--app/assets/stylesheets/pages/merge_requests.scss39
-rw-r--r--app/assets/stylesheets/pages/notes.scss43
-rw-r--r--app/assets/stylesheets/pages/pipelines.scss17
-rw-r--r--app/assets/stylesheets/pages/settings.scss4
-rw-r--r--app/assets/stylesheets/pages/status.scss98
-rw-r--r--app/controllers/application_controller.rb10
-rw-r--r--app/controllers/groups/milestones_controller.rb2
-rw-r--r--app/controllers/projects/merge_requests_controller.rb7
-rw-r--r--app/controllers/projects/milestones_controller.rb2
-rw-r--r--app/controllers/projects/notes_controller.rb1
-rw-r--r--app/controllers/projects/pipelines_settings_controller.rb2
-rw-r--r--app/helpers/application_settings_helper.rb8
-rw-r--r--app/helpers/builds_helper.rb2
-rw-r--r--app/helpers/ci_status_helper.rb2
-rw-r--r--app/helpers/issues_helper.rb2
-rw-r--r--app/helpers/milestones_helper.rb24
-rw-r--r--app/helpers/sidekiq_helper.rb10
-rw-r--r--app/models/commit_status.rb10
-rw-r--r--app/models/concerns/milestoneish.rb24
-rw-r--r--app/models/global_milestone.rb33
-rw-r--r--app/models/group.rb4
-rw-r--r--app/models/issue.rb2
-rw-r--r--app/models/member.rb2
-rw-r--r--app/models/merge_request.rb6
-rw-r--r--app/models/milestone.rb25
-rw-r--r--app/models/namespace.rb10
-rw-r--r--app/models/note.rb3
-rw-r--r--app/models/project.rb12
-rw-r--r--app/models/project_services/jira_service.rb6
-rw-r--r--app/models/project_services/mattermost_slash_commands_service.rb7
-rw-r--r--app/models/project_team.rb133
-rw-r--r--app/models/user.rb8
-rw-r--r--app/serializers/analytics_build_entity.rb2
-rw-r--r--app/serializers/entity_date_helper.rb2
-rw-r--r--app/services/notes/create_service.rb2
-rw-r--r--app/validators/namespace_validator.rb22
-rw-r--r--app/validators/project_path_validator.rb36
-rw-r--r--app/views/admin/application_settings/_form.html.haml6
-rw-r--r--app/views/admin/services/_form.html.haml7
-rw-r--r--app/views/award_emoji/_awards_block.html.haml5
-rw-r--r--app/views/groups/milestones/new.html.haml13
-rw-r--r--app/views/notify/links/ci/builds/_build.html.haml2
-rw-r--r--app/views/notify/links/ci/builds/_build.text.erb1
-rw-r--r--app/views/notify/links/generic_commit_statuses/_generic_commit_status.html.haml1
-rw-r--r--app/views/notify/links/generic_commit_statuses/_generic_commit_status.text.erb1
-rw-r--r--app/views/notify/pipeline_failed_email.html.haml12
-rw-r--r--app/views/notify/pipeline_failed_email.text.erb4
-rw-r--r--app/views/profiles/update_username.js.haml3
-rw-r--r--app/views/projects/boards/components/_board_list.html.haml2
-rw-r--r--app/views/projects/boards/components/_card.html.haml2
-rw-r--r--app/views/projects/builds/_sidebar.html.haml3
-rw-r--r--app/views/projects/builds/show.html.haml5
-rw-r--r--app/views/projects/ci/builds/_build_pipeline.html.haml4
-rw-r--r--app/views/projects/ci/pipelines/_pipeline.html.haml5
-rw-r--r--app/views/projects/commit/_commit_box.html.haml2
-rw-r--r--app/views/projects/commit/_pipeline_stage.html.haml2
-rw-r--r--app/views/projects/commit/_pipeline_status_group.html.haml2
-rw-r--r--app/views/projects/edit.html.haml13
-rw-r--r--app/views/projects/generic_commit_statuses/_generic_commit_status_pipeline.html.haml4
-rw-r--r--app/views/projects/merge_requests/widget/_heading.html.haml5
-rw-r--r--app/views/projects/merge_requests/widget/open/_merge_when_build_succeeds.html.haml2
-rw-r--r--app/views/projects/milestones/_form.html.haml7
-rw-r--r--app/views/projects/milestones/show.html.haml6
-rw-r--r--app/views/projects/notes/_note.html.haml2
-rw-r--r--app/views/projects/pipelines/_info.html.haml6
-rw-r--r--app/views/projects/services/_form.html.haml19
-rw-r--r--app/views/projects/services/mattermost_slash_commands/_help.html.haml100
-rw-r--r--app/views/projects/tags/new.html.haml2
-rw-r--r--app/views/projects/wikis/_nav.html.haml2
-rw-r--r--app/views/shared/_milestone_expired.html.haml6
-rw-r--r--app/views/shared/_service_settings.html.haml81
-rw-r--r--app/views/shared/icons/_icon_status_canceled.svg7
-rw-r--r--app/views/shared/icons/_icon_status_created.svg2
-rw-r--r--app/views/shared/icons/_icon_status_failed.svg7
-rw-r--r--app/views/shared/icons/_icon_status_pending.svg7
-rw-r--r--app/views/shared/icons/_icon_status_running.svg7
-rw-r--r--app/views/shared/icons/_icon_status_skipped.svg2
-rw-r--r--app/views/shared/icons/_icon_status_success.svg7
-rw-r--r--app/views/shared/icons/_icon_status_warning.svg7
-rw-r--r--app/views/shared/issuable/_filter.html.haml4
-rw-r--r--app/views/shared/issuable/_label_page_default.html.haml8
-rw-r--r--app/views/shared/milestones/_form_dates.html.haml15
-rw-r--r--app/views/shared/milestones/_top.html.haml4
-rw-r--r--app/workers/new_note_worker.rb4
-rw-r--r--changelogs/unreleased/18136-ui-for-restricting-global-visibility-levels-is-unclear.yml4
-rw-r--r--changelogs/unreleased/19981-admin-links-new-group-default-visibility.yml4
-rw-r--r--changelogs/unreleased/20968-add-setting-to-check-unresolved-discussion.yml4
-rw-r--r--changelogs/unreleased/21076-deleted-merged-branches.yml4
-rw-r--r--changelogs/unreleased/21664-incorrect-workhorse-version-number-displayed.yml4
-rw-r--r--changelogs/unreleased/21992-disable-access-requests-by-default.yml4
-rw-r--r--changelogs/unreleased/22307-pipeline-link-in-builds-view.yml4
-rw-r--r--changelogs/unreleased/22539-display-folders.yml4
-rw-r--r--changelogs/unreleased/22588-todos-filter-shows-all-users.yml4
-rw-r--r--changelogs/unreleased/22699-group-permssion-background-migration.yml4
-rw-r--r--changelogs/unreleased/22790-mention-autocomplete-avatar.yml4
-rw-r--r--changelogs/unreleased/22947-fix_issues_atom_feed_url.yml4
-rw-r--r--changelogs/unreleased/23036-replace-git-blame-spinach-tests-with-rspec-feature-tests.yml4
-rw-r--r--changelogs/unreleased/23117-search-for-a-filename-in-a-project.yml4
-rw-r--r--changelogs/unreleased/23223-group-deletion-race-condition.yml4
-rw-r--r--changelogs/unreleased/23449-cycle-analytics-2-frontend.yml4
-rw-r--r--changelogs/unreleased/23532-define-common-helper-for-describe-pagination-params-in-api.yml4
-rw-r--r--changelogs/unreleased/23584-triggering-builds-from-webhooks.yml4
-rw-r--r--changelogs/unreleased/23637-title-bar-pipelines.yml4
-rw-r--r--changelogs/unreleased/23731-add-param-to-user-api.yml4
-rw-r--r--changelogs/unreleased/23961-can-t-share-project-with-groups.yml4
-rw-r--r--changelogs/unreleased/23990-project-show-error-when-empty-repo.yml4
-rw-r--r--changelogs/unreleased/24010-change-anchor-link-to-mr-diff.yml4
-rw-r--r--changelogs/unreleased/24010-double-event-trigger.yml4
-rw-r--r--changelogs/unreleased/24048-dropdown-issue-with-devider.yml4
-rw-r--r--changelogs/unreleased/24056-guest-sees-some-project-details-and-gets-404.yml4
-rw-r--r--changelogs/unreleased/24059-round-robin-repository-storage.yml4
-rw-r--r--changelogs/unreleased/24070-project-margins.yml4
-rw-r--r--changelogs/unreleased/24072-improve-importing-of-github-pull-requests.yml4
-rw-r--r--changelogs/unreleased/24102-cannot-unselect-remove-source-branch-when-editing-merge-request.yml4
-rw-r--r--changelogs/unreleased/24107-slack-comment-link.yml4
-rw-r--r--changelogs/unreleased/24161-non-intuitive-buttons-for-import-sources-in-administrator-settings-enable-disable.yml4
-rw-r--r--changelogs/unreleased/24255-search-fix.yml4
-rw-r--r--changelogs/unreleased/24266-Afraid-to-press-the-Orange-button-on-Merge-request-screen.yml4
-rw-r--r--changelogs/unreleased/24276-usernames-with-dots.yml4
-rw-r--r--changelogs/unreleased/24279-issue-merge-request-sidebar-todo-button-style-improvement.yml4
-rw-r--r--changelogs/unreleased/24369-remove-additional-padding.yml4
-rw-r--r--changelogs/unreleased/24413-show-unconfirmed-email-status.yml4
-rw-r--r--changelogs/unreleased/24492-promise-polyfill.yml4
-rw-r--r--changelogs/unreleased/24496-fix-internal-api-project-lookup.yml4
-rw-r--r--changelogs/unreleased/24499-fix-activity-autoload-on-large-viewports.yml4
-rw-r--r--changelogs/unreleased/24576_cant_stop_impersonating.yml4
-rw-r--r--changelogs/unreleased/24616-mr-shows-the-build-for-this-merge-request-failed-although-builds-still-running.yml4
-rw-r--r--changelogs/unreleased/24627-fix-bad-mr-error-message.yml4
-rw-r--r--changelogs/unreleased/24739-collapsed-build-list-sorting.yml4
-rw-r--r--changelogs/unreleased/24779-last-deployment-call-on-nil-environment-fix.yml4
-rw-r--r--changelogs/unreleased/24804-wrong-render-index-should-be-render-show-in-projects-pipelinessettingscontroller-update.yml4
-rw-r--r--changelogs/unreleased/24863-mrs-without-discussions-are-mergeable.yml4
-rw-r--r--changelogs/unreleased/Last-minute-CI-Style-tweaks-for-8-14.yml4
-rw-r--r--changelogs/unreleased/adam-build-missing-services-when-necessary.yml4
-rw-r--r--changelogs/unreleased/adam-fix-collapsed-diff-symlink-file-conversion.yml4
-rw-r--r--changelogs/unreleased/add-api-label-id.yml4
-rw-r--r--changelogs/unreleased/add-chat-names.yml4
-rw-r--r--changelogs/unreleased/add-project-import-data-index.yml4
-rw-r--r--changelogs/unreleased/always-show-download-button.yml4
-rw-r--r--changelogs/unreleased/api-delete-group-share.yml4
-rw-r--r--changelogs/unreleased/api-label-priorities.yml4
-rw-r--r--changelogs/unreleased/api-return-400-if-post-systemhook-fails.yml4
-rw-r--r--changelogs/unreleased/assignee-dropdown-autocomplete.yml4
-rw-r--r--changelogs/unreleased/boards-issue-sorting.yml4
-rw-r--r--changelogs/unreleased/broken-link-frontend-dev-guide.yml4
-rw-r--r--changelogs/unreleased/bugfix-html-only-mail.yml4
-rw-r--r--changelogs/unreleased/changelog-update.yml4
-rw-r--r--changelogs/unreleased/chatops-deploy-command.yml4
-rw-r--r--changelogs/unreleased/create-pipeline-endpoint.yml4
-rw-r--r--changelogs/unreleased/dev-issue-24554.yml4
-rw-r--r--changelogs/unreleased/disable-calendar-deselection.yml4
-rw-r--r--changelogs/unreleased/dz-allow-nested-group-routing.yml4
-rw-r--r--changelogs/unreleased/dz-fix-500-group-git.yml4
-rw-r--r--changelogs/unreleased/dz-fix-group-name-dot.yml4
-rw-r--r--changelogs/unreleased/emoji-btn-disabled.yml4
-rw-r--r--changelogs/unreleased/faster_project_search.yml4
-rw-r--r--changelogs/unreleased/feature-api_owned_resource.yml4
-rw-r--r--changelogs/unreleased/feature-cycle-analytics-events.yml4
-rw-r--r--changelogs/unreleased/feature-environment-teardown-when-branch-deleted.yml4
-rw-r--r--changelogs/unreleased/feature-precalculate-authorized-projects.yml4
-rw-r--r--changelogs/unreleased/feature-send-registry-address-with-build-payload.yml4
-rw-r--r--changelogs/unreleased/feature-subscribe-to-group-level-labels.yml4
-rw-r--r--changelogs/unreleased/fix-404-on-network-when-entering-a-nonexistent-git-revision.yml4
-rw-r--r--changelogs/unreleased/fix-Build-timeFor.yml4
-rw-r--r--changelogs/unreleased/fix-admin-ci-table.yml4
-rw-r--r--changelogs/unreleased/fix-build-without-trace-exceptions.yml4
-rw-r--r--changelogs/unreleased/fix-ci-linter-undefined-error.yml4
-rw-r--r--changelogs/unreleased/fix-cycle-analytics-permissions.yml4
-rw-r--r--changelogs/unreleased/fix-cycle-analytics-plan-issue.yml4
-rw-r--r--changelogs/unreleased/fix-do-not-add-todo-when-build-allowed-to-fail.yml4
-rw-r--r--changelogs/unreleased/fix-drop-project-authorized-for-user.yml4
-rw-r--r--changelogs/unreleased/fix-error-when-invalid-branch-for-new-pipeline-used.yml4
-rw-r--r--changelogs/unreleased/fix-help-page-links.yml4
-rw-r--r--changelogs/unreleased/fix-invalid-filename-eslint.yml4
-rw-r--r--changelogs/unreleased/fix-require-build-script-configuration-entry.yml4
-rw-r--r--changelogs/unreleased/fix-search-input-padding.yml4
-rw-r--r--changelogs/unreleased/fix-shibboleth-auth-with-no-uid.yml4
-rw-r--r--changelogs/unreleased/fix-singin-redirect-for-fork-new.yml5
-rw-r--r--changelogs/unreleased/fix-trace-patch-updated-at.yml4
-rw-r--r--changelogs/unreleased/fix_labels_api_adding_missing_parameter.yml4
-rw-r--r--changelogs/unreleased/fix_navigation_bar_issuables_counters.yml4
-rw-r--r--changelogs/unreleased/fix_sidekiq_stats_in_admin_area.yml4
-rw-r--r--changelogs/unreleased/fixed-commit-timeago.yml4
-rw-r--r--changelogs/unreleased/forking-in-progress-title.yml4
-rw-r--r--changelogs/unreleased/git-gc-improvements.yml4
-rw-r--r--changelogs/unreleased/hide-empty-merge-request-diffs.yml4
-rw-r--r--changelogs/unreleased/issue-13823.yml4
-rw-r--r--changelogs/unreleased/issue-24512.yml4
-rw-r--r--changelogs/unreleased/issue-boards-counter-border-fix.yml4
-rw-r--r--changelogs/unreleased/issue-boards-dragging-fix.yml4
-rw-r--r--changelogs/unreleased/issue-boards-scrollable-element.yml4
-rw-r--r--changelogs/unreleased/issue_13232.yml4
-rw-r--r--changelogs/unreleased/issue_23032.yml4
-rw-r--r--changelogs/unreleased/issue_24303.yml4
-rw-r--r--changelogs/unreleased/issue_5541.yml4
-rw-r--r--changelogs/unreleased/jira_service_simplify.yml4
-rw-r--r--changelogs/unreleased/ldap_check_bind.yml4
-rw-r--r--changelogs/unreleased/less-intrusive-system-note.yml4
-rw-r--r--changelogs/unreleased/mailroom_idle_timeout.yml4
-rw-r--r--changelogs/unreleased/master-recursiveTree.yml4
-rw-r--r--changelogs/unreleased/milestone-project-require.yml4
-rw-r--r--changelogs/unreleased/milestone_start_date.yml4
-rw-r--r--changelogs/unreleased/move-abuse-report-spinach-test-to-rspec.yml4
-rw-r--r--changelogs/unreleased/move-admin-abuse-report-spinach-test-to-rspec.yml4
-rw-r--r--changelogs/unreleased/move-admin-spam-spinach-test-to-rspec.yml4
-rw-r--r--changelogs/unreleased/namespace-validation.yml4
-rw-r--r--changelogs/unreleased/new-note-worker-record-not-found-fix.yml4
-rw-r--r--changelogs/unreleased/optimize-mr-index.yml4
-rw-r--r--changelogs/unreleased/pass-correct-tag-target-to-post-receive.yml4
-rw-r--r--changelogs/unreleased/pipeline-notifications.yml6
-rw-r--r--changelogs/unreleased/post_receive-any-email.yml4
-rw-r--r--changelogs/unreleased/process-commits-using-sidekiq.yml4
-rw-r--r--changelogs/unreleased/rack_attack_logging.yml4
-rw-r--r--changelogs/unreleased/related-mr-labels.yml4
-rw-r--r--changelogs/unreleased/remove-backup-strategies.yml4
-rw-r--r--changelogs/unreleased/remove-heading-space-from-diff-content.yml4
-rw-r--r--changelogs/unreleased/rs-project-team-helpers.yml4
-rw-r--r--changelogs/unreleased/setter-for-key.yml4
-rw-r--r--changelogs/unreleased/sh-bump-omniauth-gitlab.yml4
-rw-r--r--changelogs/unreleased/show-status-from-branch.yml4
-rw-r--r--changelogs/unreleased/sidekiq-job-throttling.yml4
-rw-r--r--changelogs/unreleased/sidekiq_default_retries.yml4
-rw-r--r--changelogs/unreleased/simplify-create-new-list-issue-boards.yml4
-rw-r--r--changelogs/unreleased/smarter-cache-invalidation.yml4
-rw-r--r--changelogs/unreleased/sort-api-groups.yml4
-rw-r--r--changelogs/unreleased/stanhu-gitlab-ce-fix-error-500-with-mr-images.yml4
-rw-r--r--changelogs/unreleased/upgrade-timeago.yml4
-rw-r--r--changelogs/unreleased/use-separate-token-for-incoming-email.yml4
-rw-r--r--changelogs/unreleased/user-dropdown-multiple-requests-fix.yml4
-rw-r--r--changelogs/unreleased/user_filter_auth.yml4
-rw-r--r--changelogs/unreleased/zj-slash-commands-mattermost.yml4
-rw-r--r--config/README.md22
-rw-r--r--config/routes.rb20
-rw-r--r--config/routes/git_http.rb68
-rw-r--r--config/routes/group.rb20
-rw-r--r--config/routes/project.rb58
-rw-r--r--config/routes/repository.rb122
-rw-r--r--config/routes/user.rb3
-rw-r--r--config/routes/wiki.rb27
-rw-r--r--db/fixtures/development/06_teams.rb33
-rw-r--r--db/migrate/20161115173905_add_start_date_to_milestones.rb12
-rw-r--r--db/migrate/20161117114805_remove_undeleted_groups.rb41
-rw-r--r--db/schema.rb1
-rw-r--r--doc/administration/high_availability/database.md2
-rw-r--r--doc/administration/img/custom_hooks_error_msg.pngbin159486 -> 44922 bytes
-rw-r--r--doc/administration/img/high_availability/active-active-diagram.pngbin29607 -> 14649 bytes
-rw-r--r--doc/administration/img/high_availability/active-passive-diagram.pngbin24246 -> 11699 bytes
-rw-r--r--doc/administration/img/housekeeping_settings.pngbin27420 -> 12025 bytes
-rw-r--r--doc/administration/img/raketasks/check_repos_output.pngbin35333 -> 19153 bytes
-rw-r--r--doc/administration/img/repository_storages_admin_ui.pngbin54043 -> 17760 bytes
-rw-r--r--doc/administration/monitoring/performance/img/grafana_dashboard_dropdown.pngbin14368 -> 7761 bytes
-rw-r--r--doc/administration/monitoring/performance/img/grafana_dashboard_import.pngbin18267 -> 11836 bytes
-rw-r--r--doc/administration/monitoring/performance/img/grafana_data_source_configuration.pngbin26060 -> 14700 bytes
-rw-r--r--doc/administration/monitoring/performance/img/grafana_data_source_empty.pngbin21821 -> 11963 bytes
-rw-r--r--doc/administration/monitoring/performance/img/grafana_save_icon.pngbin9107 -> 4619 bytes
-rw-r--r--doc/administration/monitoring/performance/img/metrics_gitlab_configuration_settings.pngbin61357 -> 26169 bytes
-rw-r--r--doc/administration/monitoring/performance/img/request_profile_result.pngbin9720 -> 3236 bytes
-rw-r--r--doc/administration/monitoring/performance/img/request_profiling_token.pngbin30076 -> 10229 bytes
-rw-r--r--doc/administration/operations/img/sidekiq_job_throttling.pngbin114784 -> 32229 bytes
-rw-r--r--doc/api/merge_requests.md1
-rw-r--r--doc/api/milestones.md6
-rw-r--r--doc/api/projects.md21
-rw-r--r--doc/api/services.md16
-rw-r--r--doc/ci/img/builds_tab.pngbin3047 -> 1956 bytes
-rw-r--r--doc/ci/img/deployments_view.pngbin57598 -> 19923 bytes
-rw-r--r--doc/ci/img/environments_available_staging.pngbin27398 -> 10098 bytes
-rw-r--r--doc/ci/img/environments_dynamic_groups.pngbin134164 -> 45349 bytes
-rw-r--r--doc/ci/img/environments_link_url.pngbin33561 -> 12277 bytes
-rw-r--r--doc/ci/img/environments_link_url_deployments.pngbin19652 -> 7490 bytes
-rw-r--r--doc/ci/img/environments_link_url_mr.pngbin47347 -> 17947 bytes
-rw-r--r--doc/ci/img/environments_manual_action_builds.pngbin27170 -> 11137 bytes
-rw-r--r--doc/ci/img/environments_manual_action_deployments.pngbin34504 -> 12563 bytes
-rw-r--r--doc/ci/img/environments_manual_action_environments.pngbin40297 -> 14914 bytes
-rw-r--r--doc/ci/img/environments_manual_action_pipelines.pngbin42212 -> 16243 bytes
-rw-r--r--doc/ci/img/environments_manual_action_single_pipeline.pngbin42233 -> 16576 bytes
-rw-r--r--doc/ci/img/environments_mr_review_app.pngbin39780 -> 15366 bytes
-rw-r--r--doc/ci/img/environments_view.pngbin57534 -> 21155 bytes
-rw-r--r--doc/ci/img/features_settings.pngbin15809 -> 9243 bytes
-rw-r--r--doc/ci/img/pipelines.pngbin0 -> 7516 bytes
-rw-r--r--doc/ci/pipelines.md2
-rw-r--r--doc/ci/quick_start/img/build_log.pngbin52482 -> 24461 bytes
-rw-r--r--doc/ci/quick_start/img/builds_status.pngbin41838 -> 24278 bytes
-rw-r--r--doc/ci/quick_start/img/new_commit.pngbin7587 -> 4772 bytes
-rw-r--r--doc/ci/quick_start/img/pipelines_status.pngbin89387 -> 25494 bytes
-rw-r--r--doc/ci/quick_start/img/runners_activated.pngbin22822 -> 12337 bytes
-rw-r--r--doc/ci/quick_start/img/single_commit_status_pending.pngbin29981 -> 15785 bytes
-rw-r--r--doc/ci/quick_start/img/status_pending.pngbin16205 -> 9521 bytes
-rw-r--r--doc/ci/review_apps/img/review_apps_preview_in_mr.pngbin28689 -> 11723 bytes
-rw-r--r--doc/ci/triggers/img/builds_page.pngbin76181 -> 29044 bytes
-rw-r--r--doc/ci/triggers/img/trigger_single_build.pngbin21152 -> 8233 bytes
-rw-r--r--doc/ci/triggers/img/trigger_variables.pngbin9315 -> 3652 bytes
-rw-r--r--doc/ci/triggers/img/triggers_page.pngbin12002 -> 5119 bytes
-rw-r--r--doc/customization/branded_login_page/appearance.pngbin156228 -> 85263 bytes
-rw-r--r--doc/customization/branded_login_page/custom_sign_in.pngbin166674 -> 79288 bytes
-rw-r--r--doc/customization/branded_login_page/default_login_page.pngbin150538 -> 73004 bytes
-rw-r--r--doc/development/README.md1
-rw-r--r--doc/development/gitlab_architecture_diagram.pngbin23831 -> 20339 bytes
-rw-r--r--doc/development/img/state-model-issue.pngbin0 -> 7713 bytes
-rw-r--r--doc/development/img/state-model-legend.pngbin0 -> 8496 bytes
-rw-r--r--doc/development/img/state-model-merge-request.pngbin0 -> 12459 bytes
-rw-r--r--doc/development/object_state_models.md25
-rw-r--r--doc/development/testing.md2
-rw-r--r--doc/development/ux_guide/copy.md4
-rw-r--r--doc/development/ux_guide/img/button-primary.pngbin8410 -> 1550 bytes
-rw-r--r--doc/development/ux_guide/img/button-secondary.pngbin11160 -> 2683 bytes
-rw-r--r--doc/development/ux_guide/img/color-blue.pngbin3865 -> 2725 bytes
-rw-r--r--doc/development/ux_guide/img/color-green.pngbin4127 -> 3008 bytes
-rw-r--r--doc/development/ux_guide/img/color-orange.pngbin4698 -> 3470 bytes
-rw-r--r--doc/development/ux_guide/img/color-red.pngbin3669 -> 2628 bytes
-rw-r--r--doc/development/ux_guide/img/components-alerts.pngbin46785 -> 27342 bytes
-rw-r--r--doc/development/ux_guide/img/components-anchorlinks.pngbin36456 -> 19948 bytes
-rw-r--r--doc/development/ux_guide/img/components-contentblock.pngbin19841 -> 14190 bytes
-rw-r--r--doc/development/ux_guide/img/components-coverblock.pngbin15757 -> 10141 bytes
-rw-r--r--doc/development/ux_guide/img/components-dateexact.pngbin5609 -> 4161 bytes
-rw-r--r--doc/development/ux_guide/img/components-daterelative.pngbin5843 -> 4189 bytes
-rw-r--r--doc/development/ux_guide/img/components-dropdown.pngbin60448 -> 31760 bytes
-rw-r--r--doc/development/ux_guide/img/components-fileholder.pngbin4953 -> 3938 bytes
-rw-r--r--doc/development/ux_guide/img/components-horizontalform.pngbin5708 -> 4327 bytes
-rw-r--r--doc/development/ux_guide/img/components-listinsidepanel.pngbin3962 -> 3449 bytes
-rw-r--r--doc/development/ux_guide/img/components-listwithavatar.pngbin7952 -> 5749 bytes
-rw-r--r--doc/development/ux_guide/img/components-listwithhover.pngbin3313 -> 2860 bytes
-rw-r--r--doc/development/ux_guide/img/components-panels.pngbin32886 -> 21822 bytes
-rw-r--r--doc/development/ux_guide/img/components-referencehover.pngbin11519 -> 6948 bytes
-rw-r--r--doc/development/ux_guide/img/components-referenceissues.pngbin14587 -> 10009 bytes
-rw-r--r--doc/development/ux_guide/img/components-referencelabels.pngbin4643 -> 4108 bytes
-rw-r--r--doc/development/ux_guide/img/components-referencemilestone.pngbin2468 -> 2417 bytes
-rw-r--r--doc/development/ux_guide/img/components-referencemrs.pngbin12646 -> 8859 bytes
-rw-r--r--doc/development/ux_guide/img/components-referencepeople.pngbin7214 -> 5607 bytes
-rw-r--r--doc/development/ux_guide/img/components-rowcontentblock.pngbin19730 -> 14315 bytes
-rw-r--r--doc/development/ux_guide/img/components-simplelist.pngbin3078 -> 2781 bytes
-rw-r--r--doc/development/ux_guide/img/components-table.pngbin7668 -> 6081 bytes
-rw-r--r--doc/development/ux_guide/img/components-verticalform.pngbin6541 -> 4964 bytes
-rw-r--r--doc/development/ux_guide/img/copy-form-addissuebutton.pngbin26541 -> 16085 bytes
-rw-r--r--doc/development/ux_guide/img/copy-form-addissueform.pngbin38242 -> 25978 bytes
-rw-r--r--doc/development/ux_guide/img/copy-form-editissuebutton.pngbin16466 -> 11801 bytes
-rw-r--r--doc/development/ux_guide/img/copy-form-editissueform.pngbin40660 -> 25621 bytes
-rw-r--r--doc/development/ux_guide/img/features-contextualnav.pngbin8051 -> 5912 bytes
-rw-r--r--doc/development/ux_guide/img/features-emptystates.pngbin114540 -> 61664 bytes
-rw-r--r--doc/development/ux_guide/img/features-filters.pngbin4529 -> 3924 bytes
-rw-r--r--doc/development/ux_guide/img/features-globalnav.pngbin8953 -> 5780 bytes
-rw-r--r--doc/development/ux_guide/img/surfaces-contentitemtitle.pngbin7463 -> 5142 bytes
-rw-r--r--doc/development/ux_guide/img/surfaces-header.pngbin6103 -> 4095 bytes
-rw-r--r--doc/development/ux_guide/img/surfaces-systeminformationblock.pngbin15412 -> 10423 bytes
-rw-r--r--doc/development/ux_guide/img/surfaces-ux.pngbin7673 -> 4029 bytes
-rw-r--r--doc/development/ux_guide/img/tooltip-placement.pngbin2645 -> 2071 bytes
-rw-r--r--doc/development/ux_guide/img/tooltip-usage.pngbin9160 -> 5994 bytes
-rw-r--r--doc/gitlab-basics/img/create_new_group_info.pngbin53103 -> 20321 bytes
-rw-r--r--doc/gitlab-basics/img/create_new_group_sidebar.pngbin5396 -> 2682 bytes
-rw-r--r--doc/gitlab-basics/img/create_new_project_button.pngbin10050 -> 4196 bytes
-rw-r--r--doc/gitlab-basics/img/create_new_project_from_group.pngbin6545 -> 3194 bytes
-rw-r--r--doc/gitlab-basics/img/create_new_project_info.pngbin49451 -> 20385 bytes
-rw-r--r--doc/gitlab-basics/img/fork_choose_namespace.pngbin39253 -> 13674 bytes
-rw-r--r--doc/gitlab-basics/img/fork_new.pngbin25540 -> 10722 bytes
-rw-r--r--doc/gitlab-basics/img/merge_request_new.pngbin3596 -> 2234 bytes
-rw-r--r--doc/gitlab-basics/img/merge_request_page.pngbin91432 -> 33801 bytes
-rw-r--r--doc/gitlab-basics/img/merge_request_select_branch.pngbin50707 -> 20332 bytes
-rw-r--r--doc/gitlab-basics/img/new_issue_button.pngbin3070 -> 2010 bytes
-rw-r--r--doc/gitlab-basics/img/new_issue_page.pngbin53268 -> 21386 bytes
-rw-r--r--doc/gitlab-basics/img/profile_settings.pngbin5975 -> 3045 bytes
-rw-r--r--doc/gitlab-basics/img/profile_settings_ssh_keys.pngbin42977 -> 16531 bytes
-rw-r--r--doc/gitlab-basics/img/profile_settings_ssh_keys_paste_pub.pngbin37486 -> 13447 bytes
-rw-r--r--doc/gitlab-basics/img/profile_settings_ssh_keys_single_key.pngbin18498 -> 8133 bytes
-rw-r--r--doc/gitlab-basics/img/profile_settings_ssh_keys_title.pngbin2362 -> 1872 bytes
-rw-r--r--doc/gitlab-basics/img/project_clone_url.pngbin40490 -> 14978 bytes
-rw-r--r--doc/gitlab-basics/img/project_navbar.pngbin5745 -> 3259 bytes
-rw-r--r--doc/gitlab-basics/img/select_group_dropdown.pngbin8038 -> 3489 bytes
-rw-r--r--doc/install/database_mysql.md9
-rw-r--r--doc/install/installation.md10
-rw-r--r--doc/install/requirements.md2
-rw-r--r--doc/integration/README.md2
-rw-r--r--doc/integration/github.md17
-rw-r--r--doc/integration/img/akismet_settings.pngbin26625 -> 16923 bytes
-rw-r--r--doc/integration/img/bitbucket_oauth_keys.pngbin12073 -> 5149 bytes
-rw-r--r--doc/integration/img/bitbucket_oauth_settings_page.pngbin82818 -> 30081 bytes
-rw-r--r--doc/integration/img/enabled-oauth-sign-in-sources.pngbin21767 -> 13304 bytes
-rw-r--r--doc/integration/img/facebook_api_keys.pngbin85832 -> 42308 bytes
-rw-r--r--doc/integration/img/facebook_app_settings.pngbin68086 -> 35876 bytes
-rw-r--r--doc/integration/img/facebook_website_url.pngbin19823 -> 9620 bytes
-rw-r--r--doc/integration/img/github_app.pngbin55591 -> 29330 bytes
-rw-r--r--doc/integration/img/gitlab_app.pngbin30963 -> 15402 bytes
-rw-r--r--doc/integration/img/gmail_action_buttons_for_gitlab.pngbin16020 -> 11573 bytes
-rw-r--r--doc/integration/img/google_app.pngbin29154 -> 19168 bytes
-rw-r--r--doc/integration/img/jira_add_user_to_group.pngbin41994 -> 0 bytes
-rw-r--r--doc/integration/img/jira_create_new_group.pngbin32934 -> 0 bytes
-rw-r--r--doc/integration/img/jira_create_new_group_name.pngbin9054 -> 0 bytes
-rw-r--r--doc/integration/img/jira_create_new_user.pngbin21081 -> 0 bytes
-rw-r--r--doc/integration/img/jira_group_access.pngbin32210 -> 0 bytes
-rw-r--r--doc/integration/img/jira_issue_reference.pngbin36188 -> 0 bytes
-rw-r--r--doc/integration/img/jira_merge_request_close.pngbin52556 -> 0 bytes
-rw-r--r--doc/integration/img/jira_project_name.pngbin41572 -> 0 bytes
-rw-r--r--doc/integration/img/jira_service.pngbin56834 -> 0 bytes
-rw-r--r--doc/integration/img/jira_service_close_issue.pngbin79569 -> 0 bytes
-rw-r--r--doc/integration/img/jira_service_page.pngbin45089 -> 0 bytes
-rw-r--r--doc/integration/img/jira_user_management_link.pngbin43095 -> 0 bytes
-rw-r--r--doc/integration/img/jira_workflow_screenshot.pngbin111093 -> 0 bytes
-rw-r--r--doc/integration/img/oauth_provider_admin_application.pngbin33440 -> 17082 bytes
-rw-r--r--doc/integration/img/oauth_provider_application_form.pngbin23048 -> 12566 bytes
-rw-r--r--doc/integration/img/oauth_provider_application_id_secret.pngbin27673 -> 15293 bytes
-rw-r--r--doc/integration/img/oauth_provider_authorized_application.pngbin26622 -> 14668 bytes
-rw-r--r--doc/integration/img/oauth_provider_user_wide_applications.pngbin33337 -> 17526 bytes
-rw-r--r--doc/integration/img/spam_log.pngbin187190 -> 50996 bytes
-rw-r--r--doc/integration/img/submit_issue.pngbin174556 -> 45962 bytes
-rw-r--r--doc/integration/img/twitter_app_api_keys.pngbin36921 -> 24577 bytes
-rw-r--r--doc/integration/img/twitter_app_details.pngbin64686 -> 40392 bytes
-rw-r--r--doc/integration/jira.md2
-rw-r--r--doc/monitoring/performance/img/grafana_dashboard_dropdown.pngbin14368 -> 7761 bytes
-rw-r--r--doc/monitoring/performance/img/grafana_dashboard_import.pngbin18267 -> 11836 bytes
-rw-r--r--doc/monitoring/performance/img/grafana_data_source_configuration.pngbin26060 -> 14700 bytes
-rw-r--r--doc/monitoring/performance/img/grafana_data_source_empty.pngbin21821 -> 11963 bytes
-rw-r--r--doc/monitoring/performance/img/grafana_save_icon.pngbin9107 -> 4619 bytes
-rw-r--r--doc/monitoring/performance/img/metrics_gitlab_configuration_settings.pngbin37228 -> 21387 bytes
-rw-r--r--doc/profile/2fa_u2f_authenticate.pngbin54413 -> 17585 bytes
-rw-r--r--doc/profile/2fa_u2f_register.pngbin112414 -> 35186 bytes
-rw-r--r--doc/project_services/img/builds_emails_service.pngbin33943 -> 19203 bytes
-rw-r--r--doc/project_services/img/emails_on_push_service.pngbin98160 -> 28535 bytes
-rw-r--r--doc/project_services/img/jira_add_gitlab_commit_message.pngbin46590 -> 0 bytes
-rw-r--r--doc/project_services/img/jira_add_user_to_group.pngbin41994 -> 24838 bytes
-rw-r--r--doc/project_services/img/jira_create_new_group.pngbin32934 -> 19127 bytes
-rw-r--r--doc/project_services/img/jira_create_new_group_name.pngbin9054 -> 5168 bytes
-rw-r--r--doc/project_services/img/jira_create_new_user.pngbin21081 -> 12625 bytes
-rw-r--r--doc/project_services/img/jira_group_access.pngbin32210 -> 19235 bytes
-rw-r--r--doc/project_services/img/jira_issue_closed.pngbin77028 -> 0 bytes
-rw-r--r--doc/project_services/img/jira_issue_reference.pngbin36188 -> 18399 bytes
-rw-r--r--doc/project_services/img/jira_issues_workflow.pngbin87067 -> 0 bytes
-rw-r--r--doc/project_services/img/jira_merge_request_close.pngbin102835 -> 21172 bytes
-rw-r--r--doc/project_services/img/jira_project_name.pngbin41572 -> 26685 bytes
-rw-r--r--doc/project_services/img/jira_reference_commit_message_in_jira_issue.pngbin33706 -> 0 bytes
-rw-r--r--doc/project_services/img/jira_service.pngbin56834 -> 37869 bytes
-rw-r--r--doc/project_services/img/jira_service_close_comment.pngbin0 -> 11893 bytes
-rw-r--r--doc/project_services/img/jira_service_close_issue.pngbin79569 -> 30570 bytes
-rw-r--r--doc/project_services/img/jira_service_page.pngbin36280 -> 12228 bytes
-rw-r--r--doc/project_services/img/jira_submit_gitlab_merge_request.pngbin51913 -> 0 bytes
-rw-r--r--doc/project_services/img/jira_user_management_link.pngbin43095 -> 23921 bytes
-rw-r--r--doc/project_services/img/jira_workflow_screenshot.pngbin111093 -> 66685 bytes
-rw-r--r--doc/project_services/img/mattermost_add_slash_command.pngbin0 -> 9265 bytes
-rw-r--r--doc/project_services/img/mattermost_bot_auth.pngbin0 -> 8676 bytes
-rw-r--r--doc/project_services/img/mattermost_bot_available_commands.pngbin0 -> 4647 bytes
-rw-r--r--doc/project_services/img/mattermost_config_help.pngbin0 -> 63138 bytes
-rw-r--r--doc/project_services/img/mattermost_console_integrations.pngbin0 -> 41186 bytes
-rw-r--r--doc/project_services/img/mattermost_gitlab_token.pngbin0 -> 3688 bytes
-rw-r--r--doc/project_services/img/mattermost_goto_console.pngbin0 -> 7754 bytes
-rw-r--r--doc/project_services/img/mattermost_slash_command_configuration.pngbin0 -> 24169 bytes
-rw-r--r--doc/project_services/img/mattermost_slash_command_token.pngbin0 -> 8624 bytes
-rw-r--r--doc/project_services/img/mattermost_team_integrations.pngbin0 -> 4766 bytes
-rw-r--r--doc/project_services/img/redmine_configuration.pngbin16973 -> 10266 bytes
-rw-r--r--doc/project_services/img/services_templates_redmine_example.pngbin13936 -> 8776 bytes
-rw-r--r--doc/project_services/img/slack_configuration.pngbin75762 -> 29825 bytes
-rw-r--r--doc/project_services/jira.md199
-rw-r--r--doc/project_services/mattermost_slash_commands.md157
-rw-r--r--doc/project_services/project_services.md1
-rw-r--r--doc/raketasks/backup_hrz.pngbin31784 -> 11444 bytes
-rw-r--r--doc/raketasks/backup_restore.md4
-rw-r--r--doc/security/img/two_factor_authentication_settings.pngbin16807 -> 9941 bytes
-rw-r--r--doc/university/README.md12
-rw-r--r--doc/university/high-availability/aws/img/auto-scaling-det.pngbin106157 -> 29970 bytes
-rw-r--r--doc/university/high-availability/aws/img/db-subnet-group.pngbin98632 -> 29306 bytes
-rw-r--r--doc/university/high-availability/aws/img/ec-subnet.pngbin91922 -> 28405 bytes
-rw-r--r--doc/university/high-availability/aws/img/elastic-file-system.pngbin109719 -> 34582 bytes
-rw-r--r--doc/university/high-availability/aws/img/ig-rt.pngbin42022 -> 12547 bytes
-rw-r--r--doc/university/high-availability/aws/img/ig.pngbin26220 -> 8149 bytes
-rw-r--r--doc/university/high-availability/aws/img/instance_specs.pngbin40938 -> 11525 bytes
-rw-r--r--doc/university/high-availability/aws/img/new_vpc.pngbin54072 -> 15696 bytes
-rw-r--r--doc/university/high-availability/aws/img/policies.pngbin132366 -> 39845 bytes
-rw-r--r--doc/university/high-availability/aws/img/rds-net-opt.pngbin54996 -> 16347 bytes
-rw-r--r--doc/university/high-availability/aws/img/rds-sec-group.pngbin43950 -> 11584 bytes
-rw-r--r--doc/university/high-availability/aws/img/redis-cluster-det.pngbin81524 -> 23761 bytes
-rw-r--r--doc/university/high-availability/aws/img/redis-net.pngbin100700 -> 27261 bytes
-rw-r--r--doc/university/high-availability/aws/img/route_table.pngbin39611 -> 12088 bytes
-rw-r--r--doc/university/high-availability/aws/img/subnet.pngbin56466 -> 17077 bytes
-rw-r--r--doc/university/training/gitlab_flow/feature_branches.pngbin20600 -> 6202 bytes
-rw-r--r--doc/university/training/gitlab_flow/production_branch.pngbin21716 -> 7293 bytes
-rw-r--r--doc/university/training/gitlab_flow/release_branches.pngbin44173 -> 12775 bytes
-rw-r--r--doc/university/training/logo.pngbin33117 -> 8940 bytes
-rw-r--r--doc/user/admin_area/img/admin_labels.pngbin91459 -> 23063 bytes
-rw-r--r--doc/user/admin_area/monitoring/img/health_check_token.pngbin6630 -> 4923 bytes
-rw-r--r--doc/user/admin_area/settings/img/access_restrictions.pngbin7435 -> 3794 bytes
-rw-r--r--doc/user/admin_area/settings/img/admin_area_maximum_artifacts_size.pngbin6227 -> 3447 bytes
-rw-r--r--doc/user/admin_area/settings/img/admin_area_settings_button.pngbin9184 -> 4403 bytes
-rw-r--r--doc/user/admin_area/settings/img/domain_blacklist.pngbin34684 -> 13606 bytes
-rw-r--r--doc/user/admin_area/settings/img/restricted_url.pngbin47539 -> 18202 bytes
-rw-r--r--doc/user/img/markdown_logo.pngbin9509 -> 4421 bytes
-rw-r--r--doc/user/project/builds/img/build_artifacts_browser.pngbin8365 -> 3782 bytes
-rw-r--r--doc/user/project/builds/img/build_artifacts_browser_button.pngbin11041 -> 4891 bytes
-rw-r--r--doc/user/project/builds/img/build_artifacts_builds_page.pngbin55625 -> 22022 bytes
-rw-r--r--doc/user/project/builds/img/build_artifacts_pipelines_page.pngbin73038 -> 28339 bytes
-rw-r--r--doc/user/project/builds/img/build_latest_artifacts_browser.pngbin26617 -> 10551 bytes
-rw-r--r--doc/user/project/cycle_analytics.md9
-rw-r--r--doc/user/project/img/container_registry_enable.pngbin5526 -> 3057 bytes
-rw-r--r--doc/user/project/img/container_registry_panel.pngbin96315 -> 32310 bytes
-rw-r--r--doc/user/project/img/container_registry_tab.pngbin7284 -> 3800 bytes
-rw-r--r--doc/user/project/img/cycle_analytics_landing_page.pngbin66080 -> 42117 bytes
-rw-r--r--doc/user/project/img/description_templates.pngbin20444 -> 7903 bytes
-rw-r--r--doc/user/project/img/issue_board.pngbin275093 -> 90664 bytes
-rw-r--r--doc/user/project/img/issue_board_add_list.pngbin22391 -> 23632 bytes
-rw-r--r--doc/user/project/img/issue_board_search_backlog.pngbin25948 -> 9769 bytes
-rw-r--r--doc/user/project/img/issue_board_system_notes.pngbin20637 -> 4899 bytes
-rw-r--r--doc/user/project/img/issue_board_welcome_message.pngbin78694 -> 97419 bytes
-rw-r--r--doc/user/project/img/koding_build-in-progress.pngbin70949 -> 21953 bytes
-rw-r--r--doc/user/project/img/koding_build-logs.pngbin263623 -> 91364 bytes
-rw-r--r--doc/user/project/img/koding_build-success.pngbin304666 -> 73008 bytes
-rw-r--r--doc/user/project/img/koding_commit-koding.yml.pngbin302703 -> 86043 bytes
-rw-r--r--doc/user/project/img/koding_different-stack-on-mr-try.pngbin333649 -> 93404 bytes
-rw-r--r--doc/user/project/img/koding_edit-on-ide.pngbin330880 -> 90701 bytes
-rw-r--r--doc/user/project/img/koding_enable-koding.pngbin73499 -> 20303 bytes
-rw-r--r--doc/user/project/img/koding_landing.pngbin268455 -> 81010 bytes
-rw-r--r--doc/user/project/img/koding_open-gitlab-from-koding.pngbin32559 -> 10851 bytes
-rw-r--r--doc/user/project/img/koding_run-in-ide.pngbin65465 -> 22179 bytes
-rw-r--r--doc/user/project/img/koding_run-mr-in-ide.pngbin339759 -> 93780 bytes
-rw-r--r--doc/user/project/img/koding_set-up-ide.pngbin207481 -> 54062 bytes
-rw-r--r--doc/user/project/img/koding_stack-import.pngbin500352 -> 137608 bytes
-rw-r--r--doc/user/project/img/koding_start-build.pngbin105253 -> 27926 bytes
-rw-r--r--doc/user/project/img/labels_assign_label_in_new_issue.pngbin31126 -> 11636 bytes
-rw-r--r--doc/user/project/img/labels_assign_label_sidebar.pngbin31537 -> 11767 bytes
-rw-r--r--doc/user/project/img/labels_assign_label_sidebar_saved.pngbin28396 -> 9741 bytes
-rw-r--r--doc/user/project/img/labels_default.pngbin80403 -> 32030 bytes
-rw-r--r--doc/user/project/img/labels_description_tooltip.pngbin22585 -> 8538 bytes
-rw-r--r--doc/user/project/img/labels_filter.pngbin81536 -> 31931 bytes
-rw-r--r--doc/user/project/img/labels_filter_by_priority.pngbin60849 -> 23969 bytes
-rw-r--r--doc/user/project/img/labels_generate.pngbin31608 -> 13628 bytes
-rw-r--r--doc/user/project/img/labels_new_label.pngbin43265 -> 16787 bytes
-rw-r--r--doc/user/project/img/labels_new_label_on_the_fly.pngbin10416 -> 4625 bytes
-rw-r--r--doc/user/project/img/labels_new_label_on_the_fly_create.pngbin16151 -> 6389 bytes
-rw-r--r--doc/user/project/img/labels_prioritize.pngbin108751 -> 38185 bytes
-rw-r--r--doc/user/project/img/labels_subscribe.pngbin11536 -> 5336 bytes
-rw-r--r--doc/user/project/img/mitmproxy-docker.pngbin407004 -> 142591 bytes
-rw-r--r--doc/user/project/img/project_settings_list.pngbin11404 -> 5919 bytes
-rw-r--r--doc/user/project/img/protected_branches_choose_branch.pngbin20659 -> 7009 bytes
-rw-r--r--doc/user/project/img/protected_branches_devs_can_push.pngbin19312 -> 8302 bytes
-rw-r--r--doc/user/project/img/protected_branches_error_ui.pngbin37750 -> 13125 bytes
-rw-r--r--doc/user/project/img/protected_branches_list.pngbin16223 -> 6937 bytes
-rw-r--r--doc/user/project/img/protected_branches_matches.pngbin32145 -> 12028 bytes
-rw-r--r--doc/user/project/img/protected_branches_page.pngbin17839 -> 7205 bytes
-rw-r--r--doc/user/project/issue_board.md2
-rw-r--r--doc/user/project/merge_requests/img/cherry_pick_changes_commit.pngbin304098 -> 141744 bytes
-rw-r--r--doc/user/project/merge_requests/img/cherry_pick_changes_commit_modal.pngbin264883 -> 111488 bytes
-rw-r--r--doc/user/project/merge_requests/img/cherry_pick_changes_mr.pngbin212267 -> 93870 bytes
-rw-r--r--doc/user/project/merge_requests/img/cherry_pick_changes_mr_modal.pngbin186597 -> 86650 bytes
-rw-r--r--doc/user/project/merge_requests/img/commit_compare.pngbin65010 -> 33385 bytes
-rw-r--r--doc/user/project/merge_requests/img/conflict_section.pngbin247537 -> 72815 bytes
-rw-r--r--doc/user/project/merge_requests/img/discussion_view.pngbin292754 -> 73821 bytes
-rw-r--r--doc/user/project/merge_requests/img/discussions_resolved.pngbin12840 -> 4152 bytes
-rw-r--r--doc/user/project/merge_requests/img/merge_request_diff.pngbin69394 -> 26650 bytes
-rw-r--r--doc/user/project/merge_requests/img/merge_request_widget.pngbin32292 -> 11039 bytes
-rw-r--r--doc/user/project/merge_requests/img/merge_when_build_succeeds_enable.pngbin68769 -> 39796 bytes
-rw-r--r--doc/user/project/merge_requests/img/merge_when_build_succeeds_only_if_succeeds_msg.pngbin11136 -> 5251 bytes
-rw-r--r--doc/user/project/merge_requests/img/merge_when_build_succeeds_only_if_succeeds_settings.pngbin17552 -> 12063 bytes
-rw-r--r--doc/user/project/merge_requests/img/merge_when_build_succeeds_status.pngbin82655 -> 48458 bytes
-rw-r--r--doc/user/project/merge_requests/img/only_allow_merge_if_all_discussions_are_resolved.pngbin24693 -> 17888 bytes
-rw-r--r--doc/user/project/merge_requests/img/only_allow_merge_if_all_discussions_are_resolved_msg.pngbin6940 -> 4962 bytes
-rw-r--r--doc/user/project/merge_requests/img/resolve_comment_button.pngbin14075 -> 4722 bytes
-rw-r--r--doc/user/project/merge_requests/img/resolve_discussion_button.pngbin18405 -> 4683 bytes
-rw-r--r--doc/user/project/merge_requests/img/revert_changes_commit.pngbin233750 -> 95655 bytes
-rw-r--r--doc/user/project/merge_requests/img/revert_changes_commit_modal.pngbin205046 -> 88824 bytes
-rw-r--r--doc/user/project/merge_requests/img/revert_changes_mr.pngbin241051 -> 104972 bytes
-rw-r--r--doc/user/project/merge_requests/img/revert_changes_mr_modal.pngbin211022 -> 93536 bytes
-rw-r--r--doc/user/project/merge_requests/img/versions.pngbin171413 -> 55703 bytes
-rw-r--r--doc/user/project/merge_requests/img/versions_compare.pngbin68722 -> 24886 bytes
-rw-r--r--doc/user/project/merge_requests/img/versions_dropdown.pngbin60587 -> 21547 bytes
-rw-r--r--doc/user/project/merge_requests/img/versions_system_note.pngbin18731 -> 7136 bytes
-rw-r--r--doc/user/project/merge_requests/img/wip_blocked_accept_button.pngbin32720 -> 18606 bytes
-rw-r--r--doc/user/project/merge_requests/img/wip_mark_as_wip.pngbin21640 -> 11396 bytes
-rw-r--r--doc/user/project/merge_requests/img/wip_unmark_as_wip.pngbin16606 -> 8565 bytes
-rw-r--r--doc/user/project/pipelines/img/pipelines_settings_badges.pngbin56166 -> 21137 bytes
-rw-r--r--doc/user/project/pipelines/img/pipelines_settings_test_coverage.pngbin4212 -> 2603 bytes
-rw-r--r--doc/user/project/pipelines/img/pipelines_test_coverage_build.pngbin9953 -> 4481 bytes
-rw-r--r--doc/user/project/pipelines/img/pipelines_test_coverage_mr_widget.pngbin14502 -> 6391 bytes
-rw-r--r--doc/user/project/repository/img/web_editor_new_branch_dropdown.pngbin20436 -> 10386 bytes
-rw-r--r--doc/user/project/repository/img/web_editor_new_branch_from_issue.pngbin4728 -> 2720 bytes
-rw-r--r--doc/user/project/repository/img/web_editor_new_branch_page.pngbin11245 -> 6034 bytes
-rw-r--r--doc/user/project/repository/img/web_editor_new_directory_dialog.pngbin13339 -> 7323 bytes
-rw-r--r--doc/user/project/repository/img/web_editor_new_directory_dropdown.pngbin20007 -> 9918 bytes
-rw-r--r--doc/user/project/repository/img/web_editor_new_file_dropdown.pngbin20680 -> 10233 bytes
-rw-r--r--doc/user/project/repository/img/web_editor_new_file_editor.pngbin66261 -> 38068 bytes
-rw-r--r--doc/user/project/repository/img/web_editor_new_push_widget.pngbin7076 -> 3395 bytes
-rw-r--r--doc/user/project/repository/img/web_editor_new_tag_dropdown.pngbin20080 -> 9796 bytes
-rw-r--r--doc/user/project/repository/img/web_editor_new_tag_page.pngbin36610 -> 21835 bytes
-rw-r--r--doc/user/project/repository/img/web_editor_start_new_merge_request.pngbin8596 -> 4060 bytes
-rw-r--r--doc/user/project/repository/img/web_editor_template_dropdown_buttons.pngbin14131 -> 5634 bytes
-rw-r--r--doc/user/project/repository/img/web_editor_template_dropdown_first_file.pngbin25748 -> 8846 bytes
-rw-r--r--doc/user/project/repository/img/web_editor_template_dropdown_mit_license.pngbin85413 -> 30924 bytes
-rw-r--r--doc/user/project/repository/img/web_editor_upload_file_dialog.pngbin21502 -> 12558 bytes
-rw-r--r--doc/user/project/repository/img/web_editor_upload_file_dropdown.pngbin20651 -> 10291 bytes
-rw-r--r--doc/user/project/settings/img/import_export_download_export.pngbin85600 -> 24482 bytes
-rw-r--r--doc/user/project/settings/img/import_export_export_button.pngbin84637 -> 24122 bytes
-rw-r--r--doc/user/project/settings/img/import_export_mail_link.pngbin44012 -> 13496 bytes
-rw-r--r--doc/user/project/settings/img/import_export_new_project.pngbin43574 -> 13083 bytes
-rw-r--r--doc/user/project/settings/img/import_export_select_file.pngbin46292 -> 13713 bytes
-rw-r--r--doc/user/project/settings/img/settings_edit_button.pngbin19392 -> 6901 bytes
-rw-r--r--doc/web_hooks/ssl.pngbin39120 -> 23191 bytes
-rw-r--r--doc/web_hooks/web_hooks.md58
-rw-r--r--doc/workflow/add-user/img/access_requests_management.pngbin15686 -> 11018 bytes
-rw-r--r--doc/workflow/add-user/img/add_new_user_to_project_settings.pngbin18149 -> 11046 bytes
-rw-r--r--doc/workflow/add-user/img/add_user_email_accept.pngbin22877 -> 16890 bytes
-rw-r--r--doc/workflow/add-user/img/add_user_email_ready.pngbin40207 -> 28171 bytes
-rw-r--r--doc/workflow/add-user/img/add_user_email_search.pngbin45798 -> 29628 bytes
-rw-r--r--doc/workflow/add-user/img/add_user_give_permissions.pngbin56380 -> 36619 bytes
-rw-r--r--doc/workflow/add-user/img/add_user_import_members_from_another_project.pngbin38778 -> 25343 bytes
-rw-r--r--doc/workflow/add-user/img/add_user_imported_members.pngbin37835 -> 25398 bytes
-rw-r--r--doc/workflow/add-user/img/add_user_list_members.pngbin24337 -> 16916 bytes
-rw-r--r--doc/workflow/add-user/img/add_user_members_menu.pngbin42224 -> 28994 bytes
-rw-r--r--doc/workflow/add-user/img/add_user_search_people.pngbin39844 -> 25368 bytes
-rw-r--r--doc/workflow/add-user/img/request_access_button.pngbin36588 -> 25281 bytes
-rw-r--r--doc/workflow/add-user/img/withdraw_access_request_button.pngbin37960 -> 26135 bytes
-rw-r--r--doc/workflow/award_emoji.pngbin9939 -> 5268 bytes
-rw-r--r--doc/workflow/ci_mr.pngbin29571 -> 12034 bytes
-rw-r--r--doc/workflow/close_issue_mr.pngbin82595 -> 42108 bytes
-rw-r--r--doc/workflow/environment_branches.pngbin20745 -> 12364 bytes
-rw-r--r--doc/workflow/forking/branch_select.pngbin27299 -> 15424 bytes
-rw-r--r--doc/workflow/forking/merge_request.pngbin31560 -> 16332 bytes
-rw-r--r--doc/workflow/four_stages.pngbin10003 -> 7124 bytes
-rw-r--r--doc/workflow/git_pull.pngbin94405 -> 28749 bytes
-rw-r--r--doc/workflow/gitdashflow.pngbin131491 -> 68177 bytes
-rw-r--r--doc/workflow/github_flow.pngbin10251 -> 6173 bytes
-rw-r--r--doc/workflow/gitlab_flow.pngbin70871 -> 47432 bytes
-rw-r--r--doc/workflow/good_commit.pngbin13131 -> 8742 bytes
-rw-r--r--doc/workflow/groups/access_requests_management.pngbin15829 -> 11186 bytes
-rw-r--r--doc/workflow/groups/add_member_to_group.pngbin78060 -> 35724 bytes
-rw-r--r--doc/workflow/groups/group_dashboard.pngbin59446 -> 28155 bytes
-rw-r--r--doc/workflow/groups/group_with_two_projects.pngbin73101 -> 34462 bytes
-rw-r--r--doc/workflow/groups/max_access_level.pngbin74947 -> 34718 bytes
-rw-r--r--doc/workflow/groups/new_group_button.pngbin108482 -> 49708 bytes
-rw-r--r--doc/workflow/groups/new_group_form.pngbin58860 -> 27263 bytes
-rw-r--r--doc/workflow/groups/other_group_sees_shared_project.pngbin64447 -> 30182 bytes
-rw-r--r--doc/workflow/groups/override_access_level.pngbin90122 -> 40993 bytes
-rw-r--r--doc/workflow/groups/project_members_via_group.pngbin86260 -> 39532 bytes
-rw-r--r--doc/workflow/groups/request_access_button.pngbin49067 -> 35917 bytes
-rw-r--r--doc/workflow/groups/share_project_with_groups.pngbin65633 -> 30307 bytes
-rw-r--r--doc/workflow/groups/transfer_project.pngbin92115 -> 43502 bytes
-rw-r--r--doc/workflow/groups/withdraw_access_request_button.pngbin49941 -> 36413 bytes
-rw-r--r--doc/workflow/img/award_emoji_comment_awarded.pngbin64317 -> 19159 bytes
-rw-r--r--doc/workflow/img/award_emoji_comment_picker.pngbin250861 -> 72883 bytes
-rw-r--r--doc/workflow/img/award_emoji_select.pngbin49296 -> 23779 bytes
-rw-r--r--doc/workflow/img/award_emoji_votes_least_popular.pngbin116715 -> 50191 bytes
-rw-r--r--doc/workflow/img/award_emoji_votes_most_popular.pngbin108775 -> 48342 bytes
-rw-r--r--doc/workflow/img/award_emoji_votes_sort_options.pngbin131659 -> 57145 bytes
-rw-r--r--doc/workflow/img/file_finder_find_button.pngbin25458 -> 14567 bytes
-rw-r--r--doc/workflow/img/file_finder_find_file.pngbin35114 -> 19478 bytes
-rw-r--r--doc/workflow/img/forking_workflow_choose_namespace.pngbin59114 -> 26275 bytes
-rw-r--r--doc/workflow/img/forking_workflow_fork_button.pngbin20750 -> 12973 bytes
-rw-r--r--doc/workflow/img/forking_workflow_path_taken_error.pngbin17978 -> 10103 bytes
-rw-r--r--doc/workflow/img/new_branch_from_issue.pngbin54607 -> 33584 bytes
-rw-r--r--doc/workflow/img/todo_list_item.pngbin58912 -> 18777 bytes
-rw-r--r--doc/workflow/img/todos_add_todo_sidebar.pngbin120265 -> 33350 bytes
-rw-r--r--doc/workflow/img/todos_icon.pngbin3843 -> 1341 bytes
-rw-r--r--doc/workflow/img/todos_index.pngbin152040 -> 63372 bytes
-rw-r--r--doc/workflow/img/todos_mark_done_sidebar.pngbin121303 -> 33703 bytes
-rw-r--r--doc/workflow/importing/fogbugz_importer/fogbugz_import_finished.pngbin30266 -> 17744 bytes
-rw-r--r--doc/workflow/importing/fogbugz_importer/fogbugz_import_login.pngbin20797 -> 13751 bytes
-rw-r--r--doc/workflow/importing/fogbugz_importer/fogbugz_import_select_fogbogz.pngbin20526 -> 12289 bytes
-rw-r--r--doc/workflow/importing/fogbugz_importer/fogbugz_import_select_project.pngbin34836 -> 20905 bytes
-rw-r--r--doc/workflow/importing/fogbugz_importer/fogbugz_import_user_map.pngbin77208 -> 51238 bytes
-rw-r--r--doc/workflow/importing/gitlab_importer/importer.pngbin18366 -> 12864 bytes
-rw-r--r--doc/workflow/importing/gitlab_importer/new_project_page.pngbin33589 -> 21251 bytes
-rw-r--r--doc/workflow/importing/img/import_projects_from_github_importer.pngbin65288 -> 17953 bytes
-rw-r--r--doc/workflow/importing/img/import_projects_from_github_new_project_page.pngbin24911 -> 11047 bytes
-rw-r--r--doc/workflow/importing/img/import_projects_from_github_select_auth_method.pngbin42043 -> 17613 bytes
-rw-r--r--doc/workflow/lfs/manage_large_binaries_with_git_lfs.md12
-rw-r--r--doc/workflow/merge_commits.pngbin22181 -> 7564 bytes
-rw-r--r--doc/workflow/merge_request.pngbin98070 -> 47240 bytes
-rw-r--r--doc/workflow/messy_flow.pngbin19314 -> 11665 bytes
-rw-r--r--doc/workflow/milestones/form.pngbin84872 -> 40414 bytes
-rw-r--r--doc/workflow/milestones/group_form.pngbin74429 -> 35820 bytes
-rw-r--r--doc/workflow/mr_inline_comments.pngbin117313 -> 52519 bytes
-rw-r--r--doc/workflow/notifications/settings.pngbin59256 -> 37542 bytes
-rw-r--r--doc/workflow/production_branch.pngbin10946 -> 7264 bytes
-rw-r--r--doc/workflow/rebase.pngbin68976 -> 29009 bytes
-rw-r--r--doc/workflow/release_branches.pngbin22163 -> 12746 bytes
-rw-r--r--doc/workflow/releases/new_tag.pngbin87330 -> 42456 bytes
-rw-r--r--doc/workflow/releases/tags.pngbin93016 -> 44666 bytes
-rw-r--r--doc/workflow/remove_checkbox.pngbin12339 -> 6904 bytes
-rw-r--r--features/abuse_report.feature17
-rw-r--r--features/admin/abuse_report.feature8
-rw-r--r--features/admin/spam_logs.feature8
-rw-r--r--features/steps/abuse_reports.rb32
-rw-r--r--features/steps/admin/abuse_reports.rb15
-rw-r--r--features/steps/admin/spam_logs.rb28
-rw-r--r--features/steps/project/labels.rb2
-rw-r--r--features/steps/shared/diff_note.rb5
-rw-r--r--features/steps/shared/note.rb4
-rw-r--r--lib/api/broadcast_messages.rb5
-rw-r--r--lib/api/commit_statuses.rb2
-rw-r--r--lib/api/commits.rb7
-rw-r--r--lib/api/deployments.rb5
-rw-r--r--lib/api/entities.rb1
-rw-r--r--lib/api/environments.rb5
-rw-r--r--lib/api/groups.rb2
-rw-r--r--lib/api/merge_requests.rb10
-rw-r--r--lib/api/milestones.rb5
-rw-r--r--lib/api/pagination_params.rb24
-rw-r--r--lib/api/pipelines.rb5
-rw-r--r--lib/api/projects.rb13
-rw-r--r--lib/api/sidekiq_metrics.rb36
-rw-r--r--lib/api/variables.rb7
-rw-r--r--lib/constraints/constrainer_helper.rb15
-rw-r--r--lib/constraints/group_url_constrainer.rb20
-rw-r--r--lib/constraints/project_url_constrainer.rb13
-rw-r--r--lib/constraints/user_url_constrainer.rb12
-rw-r--r--lib/gitlab/chat_commands/issue_create.rb6
-rw-r--r--lib/gitlab/cycle_analytics/base_event.rb2
-rw-r--r--lib/gitlab/cycle_analytics/plan_event.rb2
-rw-r--r--lib/gitlab/ee_compat_check.rb8
-rw-r--r--lib/gitlab/identifier.rb6
-rw-r--r--lib/gitlab/regex.rb14
-rw-r--r--package.json5
-rw-r--r--spec/controllers/admin/impersonations_controller_spec.rb28
-rw-r--r--spec/controllers/application_controller_spec.rb23
-rw-r--r--spec/controllers/autocomplete_controller_spec.rb30
-rw-r--r--spec/features/abuse_report_spec.rb24
-rw-r--r--spec/features/admin/admin_abuse_reports_spec.rb16
-rw-r--r--spec/features/admin/admin_browse_spam_logs_spec.rb22
-rw-r--r--spec/features/boards/boards_spec.rb16
-rw-r--r--spec/features/calendar_spec.rb41
-rw-r--r--spec/features/issues/award_emoji_spec.rb93
-rw-r--r--spec/features/milestone_spec.rb5
-rw-r--r--spec/features/projects/builds_spec.rb195
-rw-r--r--spec/features/projects/services/mattermost_slash_command_spec.rb48
-rw-r--r--spec/features/projects/services/slack_service_spec.rb (renamed from spec/features/projects/slack_service/slack_service_spec.rb)0
-rw-r--r--spec/helpers/members_helper_spec.rb4
-rw-r--r--spec/helpers/milestones_helper_spec.rb19
-rw-r--r--spec/helpers/sidekiq_helper_spec.rb23
-rw-r--r--spec/javascripts/.eslintrc4
-rw-r--r--spec/javascripts/build_spec.js.es65
-rw-r--r--spec/javascripts/environments/environments_store_spec.js.es64
-rw-r--r--spec/javascripts/fixtures/build.html.haml2
-rw-r--r--spec/javascripts/merge_request_widget_spec.js2
-rw-r--r--spec/lib/constraints/constrainer_helper_spec.rb20
-rw-r--r--spec/lib/constraints/group_url_constrainer_spec.rb20
-rw-r--r--spec/lib/constraints/project_url_constrainer_spec.rb32
-rw-r--r--spec/lib/constraints/user_url_constrainer_spec.rb21
-rw-r--r--spec/lib/gitlab/chat_commands/issue_create_spec.rb9
-rw-r--r--spec/lib/gitlab/cycle_analytics/plan_event_spec.rb8
-rw-r--r--spec/lib/gitlab/identifier_spec.rb5
-rw-r--r--spec/lib/gitlab/import_export/all_models.yml2
-rw-r--r--spec/lib/gitlab/import_export/safe_model_attributes.yml1
-rw-r--r--spec/models/ci/pipeline_spec.rb3
-rw-r--r--spec/models/concerns/milestoneish_spec.rb20
-rw-r--r--spec/models/issue_spec.rb2
-rw-r--r--spec/models/merge_request_spec.rb54
-rw-r--r--spec/models/milestone_spec.rb43
-rw-r--r--spec/models/project_spec.rb58
-rw-r--r--spec/models/project_team_spec.rb99
-rw-r--r--spec/models/service_spec.rb3
-rw-r--r--spec/models/user_spec.rb11
-rw-r--r--spec/requests/api/merge_requests_spec.rb10
-rw-r--r--spec/requests/api/milestones_spec.rb14
-rw-r--r--spec/requests/api/projects_spec.rb30
-rw-r--r--spec/routing/project_routing_spec.rb1034
-rw-r--r--spec/routing/routing_spec.rb16
-rw-r--r--spec/serializers/analytics_build_entity_spec.rb10
-rw-r--r--spec/services/notification_service_spec.rb60
-rw-r--r--spec/views/projects/builds/show.html.haml_spec.rb52
-rw-r--r--spec/views/projects/edit.html.haml_spec.rb24
-rw-r--r--vendor/assets/javascripts/timeago.js (renamed from app/assets/javascripts/lib/utils/timeago.js)8
795 files changed, 3307 insertions, 2448 deletions
diff --git a/.eslintrc b/.eslintrc
index 5850c107a02..788a88487d8 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -1,31 +1,20 @@
{
+ "env": {
+ "browser": true,
+ "es6": true
+ },
"extends": "airbnb",
+ "globals": {
+ "$": false,
+ "_": false,
+ "gl": false,
+ "gon": false,
+ "jQuery": false
+ },
"plugins": [
"filenames"
],
"rules": {
"filenames/match-regex": [2, "^[a-z0-9_]+(.js)?$"]
- },
- "globals": {
- "$": false,
- "_": false,
- "beforeEach": false,
- "d3": false,
- "define": false,
- "describe": false,
- "document": false,
- "expect": false,
- "fixture": false,
- "gl": false,
- "it": false,
- "jQuery": false,
- "Mousetrap": false,
- "spyOn": false,
- "spyOnEvent": false,
- "Turbolinks": false,
- "window": false,
- "Vue": false,
- "Flash": false,
- "Cookies": false
}
}
diff --git a/.gitignore b/.gitignore
index 6a1002621f4..0b602d613c7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,6 +5,7 @@
.chef
.directory
/.envrc
+eslint-report.html
/.gitlab_shell_secret
.idea
/.rbenv-version
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index ab45ea57aed..3c357c489f8 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -20,7 +20,7 @@ before_script:
- source ./scripts/prepare_build.sh
- cp config/gitlab.yml.example config/gitlab.yml
- bundle --version
- - '[ "$USE_BUNDLE_INSTALL" != "true" ] || retry bundle install --without postgres production --jobs $(nproc) "${FLAGS[@]}"'
+ - '[ "$USE_BUNDLE_INSTALL" != "true" ] || retry bundle install --without postgres production --jobs $(nproc) $FLAGS'
- retry gem install knapsack
- '[ "$SETUP_DB" != "true" ] || bundle exec rake db:drop db:create db:schema:load db:migrate add_limits_mysql'
@@ -328,7 +328,7 @@ migration paths:
- git checkout -f FETCH_HEAD
- cp config/resque.yml.example config/resque.yml
- sed -i 's/localhost/redis/g' config/resque.yml
- - bundle install --without postgres production --jobs $(nproc) ${FLAGS[@]} --retry=3
+ - bundle install --without postgres production --jobs $(nproc) $FLAGS --retry=3
- rake db:drop db:create db:schema:load db:seed_fu
- git checkout $CI_BUILD_REF
- source scripts/prepare_build.sh
@@ -349,7 +349,7 @@ coverage:
- coverage/index.html
- coverage/assets/
-lint-javascript:
+lint:javascript:
cache:
paths:
- node_modules/
@@ -358,7 +358,24 @@ lint-javascript:
before_script:
- npm install
script:
- - npm run eslint
+ - npm --silent run eslint
+
+lint:javascript:report:
+ cache:
+ paths:
+ - node_modules/
+ stage: post-test
+ image: "node:7.1"
+ before_script:
+ - npm install
+ script:
+ - find app/ spec/ -name '*.js' -or -name '*.js.es6' -exec sed --in-place 's|/\* eslint-disable .*\*/||' {} \; # run report over all files
+ - npm --silent run eslint-report || true # ignore exit code
+ artifacts:
+ name: eslint-report
+ expire_in: 31d
+ paths:
+ - eslint-report.html
# Trigger docs build
# https://gitlab.com/gitlab-com/doc-gitlab-com/blob/master/README.md#deployment-process
@@ -384,7 +401,7 @@ notify:slack:
SETUP_DB: "false"
USE_BUNDLE_INSTALL: "false"
script:
- - ./scripts/notify_slack.sh "#builds" "Build on \`$CI_BUILD_REF_NAME\` failed! Commit \`$(git log -1 --oneline)\` See <https://gitlab.com/gitlab-org/$(basename "$PWD")/commit/"$CI_BUILD_REF"/builds>"
+ - ./scripts/notify_slack.sh "#development" "Build on \`$CI_BUILD_REF_NAME\` failed! Commit \`$(git log -1 --oneline)\` See <https://gitlab.com/gitlab-org/$(basename "$PWD")/commit/"$CI_BUILD_REF"/builds>"
when: on_failure
only:
- master@gitlab-org/gitlab-ce
@@ -398,11 +415,13 @@ pages:
dependencies:
- coverage
- teaspoon
+ - lint:javascript:report
script:
- mv public/ .public/
- mkdir public/
- mv coverage public/coverage-ruby
- mv coverage-javascript/default/ public/coverage-javascript/
+ - mv eslint-report.html public/
artifacts:
paths:
- public
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5b139ac8314..549336e4dff 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,131 @@ entry.
## 8.14.0 (2016-11-22)
+- Use separate email-token for incoming email and revert back the inactive feature. !5914
+- API: allow recursive tree request. !6088 (Rebeca Mendez)
+- Replace jQuery.timeago with timeago.js. !6274 (ClemMakesApps)
+- Add CI notifications. Who triggered a pipeline would receive an email after the pipeline is succeeded or failed. Users could also update notification settings accordingly. !6342
+- Add button to delete all merged branches. !6449 (Toon Claes)
+- Finer-grained Git gargage collection. !6588
+- Introduce better credential and error checking to `rake gitlab:ldap:check`. !6601
+- Centralize LDAP config/filter logic. !6606
+- Make system notes less intrusive. !6755
+- Process commits using a dedicated Sidekiq worker. !6802
+- Show random messages when the To Do list is empty. !6818 (Josep Llaneras)
+- Precalculate user's authorized projects in database. !6839
+- Fix record not found error on NewNoteWorker processing. !6863 (Oswaldo Ferreira)
+- Show avatars in mention dropdown. !6865
+- Fix expanding a collapsed diff when converting a symlink to a regular file. !6953
+- Defer saving project services to the database if there are no user changes. !6958
+- Omniauth auto link LDAP user falls back to find by DN when user cannot be found by UID. !7002
+- Display "folders" for environments. !7015
+- Make it possible to trigger builds from webhooks. !7022 (Dmitry Poray)
+- Fix showing pipeline status for a given commit from correct branch. !7034
+- Add link to build pipeline within individual build pages. !7082
+- Add api endpoint `/groups/owned`. !7103 (Borja Aparicio)
+- Add query param to filter users by external & blocked type. !7109 (Yatish Mehta)
+- Issues atom feed url reflect filters on dashboard. !7114 (Lucas Deschamps)
+- Add setting to only allow merge requests to be merged when all discussions are resolved. !7125 (Rodolfo Arruda)
+- Remove an extra leading space from diff paste data. !7133 (Hiroyuki Sato)
+- Fix trace patching feature - update the updated_at value. !7146
+- Fix 404 on network page when entering non-existent git revision. !7172 (Hiroyuki Sato)
+- Rewrite git blame spinach feature tests to rspec feature tests. !7197 (Lisanne Fellinger)
+- Add api endpoint for creating a pipeline. !7209 (Ido Leibovich)
+- Allow users to subscribe to group labels. !7215
+- Reduce API calls needed when importing issues and pull requests from GitHub. !7241 (Andrew Smith (EspadaV8))
+- Only skip group when it's actually a group in the "Share with group" select. !7262
+- Introduce round-robin project creation to spread load over multiple shards. !7266
+- Ensure merge request's "remove branch" accessors return booleans. !7267
+- Fix no "Register" tab if ldap auth is enabled (#24038). !7274 (Luc Didry)
+- Expose label IDs in API. !7275 (Rares Sfirlogea)
+- Fix invalid filename validation on eslint. !7281
+- API: Ability to retrieve version information. !7286 (Robert Schilling)
+- Added ability to throttle Sidekiq Jobs. !7292
+- Set default Sidekiq retries to 3. !7294
+- Fix double event and ajax request call on MR page. !7298 (YarNayar)
+- Unify anchor link format for MR diff files. !7298 (YarNayar)
+- Require projects before creating milestone. !7301 (gfyoung)
+- Fix error when using invalid branch name when creating a new pipeline. !7324
+- Return 400 when creating a system hook fails. !7350 (Robert Schilling)
+- Auto-close environment when branch is deleted. !7355
+- Rework cache invalidation so only changed data is refreshed. !7360
+- Navigation bar issuables counters reflects dashboard issuables counters. !7368 (Lucas Deschamps)
+- Fix cache for commit status in commits list to respect branches. !7372
+- fixes 500 error on project show when user is not logged in and project is still empty. !7376
+- Removed gray button styling from todo buttons in sidebars. !7387
+- Fix project records with invalid visibility_level values. !7391
+- Use 'Forking in progress' title when appropriate. !7394 (Philip Karpiak)
+- Fix error links in help index page. !7396 (Fu Xu)
+- Add support for reply-by-email when the email only contains HTML. !7397
+- [Fix] Extra divider issue in dropdown. !7398
+- Project download buttons always show. !7405 (Philip Karpiak)
+- Give search-input correct padding-right value. !7407 (Philip Karpiak)
+- Remove additional padding on right-aligned items in MR widget. !7411 (Didem Acet)
+- Fix issue causing Labels not to appear in sidebar on MR page. !7416 (Alex Sanford)
+- Allow mail_room idle_timeout option to be configurable. !7423
+- Fix misaligned buttons on admin builds page. !7424 (Didem Acet)
+- Disable "Request Access" functionality by default for new projects and groups. !7425
+- fix shibboleth misconfigurations resulting in authentication bypass. !7428
+- Added Mattermost slash command. !7438
+- Allow to connect Chat account with GitLab. !7450
+- Make New Group form respect default visibility application setting. !7454 (Jacopo Beschi @jacopo-beschi)
+- Fix Error 500 when creating a merge request that contains an image that was deleted and added. !7457
+- Fix labels API by adding missing current_user parameter. !7458 (Francesco Coda Zabetta)
+- Changed restricted visibility admin buttons to checkboxes. !7463
+- Send credentials (currently for registry only) with build data to GitLab Runner. !7474
+- Fix POST /internal/allowed to cope with gitlab-shell v4.0.0 project paths. !7480
+- Adds es6-promise Polyfill. !7482
+- Added colored labels to related MR list. !7486 (Didem Acet)
+- Use setter for key instead AR callback. !7488 (Semyon Pupkov)
+- Limit labels returned for a specific project as an administrator. !7496
+- Change slack notification comment link. !7498 (Herbert Kagumba)
+- Allow registering users whose username contains dots. !7500 (Timothy Andrew)
+- Fix race condition during group deletion and remove stale records present due to this bug. !7528 (Timothy Andrew)
+- Check all namespaces on validation of new username. !7537
+- Pass correct tag target to post-receive hook when creating tag via UI. !7556
+- Add help message for configuring Mattermost slash commands. !7558
+- Fix typo in Build page JavaScript. !7563 (winniehell)
+- Make job script a required configuration entry. !7566
+- Fix errors happening when source branch of merge request is removed and then restored. !7568
+- Fix a wrong "The build for this merge request failed" message. !7579
+- Fix Margins look weird in Project page with pinned sidebar in project stats bar. !7580
+- Fix regression causing bad error message to appear on Merge Request form. !7599 (Alex Sanford)
+- Fix activity page endless scroll on large viewports. !7608
+- Fix 404 on some group pages when name contains dot. !7614
+- Do not create a new TODO when failed build is allowed to fail. !7618
+- Add deployment command to ChatOps. !7619
+- Fix 500 error when group name ends with git. !7630
+- Fix undefined error in CI linter. !7650
+- Show events per stage on Cycle Analytics page. !23449
+- Add JIRA remotelinks and prevent duplicated closing messages.
+- Fixed issue boards counter border when unauthorized.
+- Add placeholder for the example text for custom hex color on label creation popup. (Luis Alonso Chavez Armendariz)
+- Add an index for project_id in project_import_data to improve performance.
+- Fix broken commits search.
+- Assignee dropdown now searches author of issue or merge request.
+- Clicking "force remove source branch" label now toggles the checkbox again.
+- More aggressively preload on merge request and issue index pages.
+- Fix broken link to observatory cli on Frontend Dev Guide. (Sam Rose)
+- Fixing the issue of the project fork url giving 500 when not signed instead of being redirected to sign in page. (Cagdas Gerede)
+- Fix: Guest sees some repository details and gets 404.
+- Add logging for rack attack events to production.log.
+- Add environment info to builds page.
+- Allow commit note to be visible if repo is visible.
+- Bump omniauth-gitlab to 1.0.2 to fix incompatibility with omniauth-oauth2.
+- Redesign pipelines page.
+- Faster search inside Project.
+- Search for a filename in a project.
+- Allow sorting groups in the API.
+- Fix: Todos Filter Shows All Users.
+- Use the Gitlab Workhorse HTTP header in the admin dashboard. (Chris Wright)
+- Fixed multiple requests sent when opening dropdowns.
+- Added permissions per stage to cycle analytics endpoint.
+- Fix project Visibility Level selector not using default values.
+- Add events per stage to cycle analytics.
+- Allow to test JIRA service settings without having a repository.
+- Fix JIRA references for project snippets.
+- Allow enabling and disabling commit and MR events for JIRA.
+- simplify url generation. (Jarka Kadlecova)
- Show correct environment log in admin/logs (@duk3luk3 !7191)
- Fix Milestone dropdown not stay selected for `Upcoming` and `No Milestone` option !7117
- Diff collapse won't shift when collapsing.
diff --git a/Gemfile b/Gemfile
index 9e815925a1f..e7f248ee766 100644
--- a/Gemfile
+++ b/Gemfile
@@ -85,10 +85,8 @@ gem 'dropzonejs-rails', '~> 0.7.1'
# for backups
gem 'fog-aws', '~> 0.9'
-gem 'fog-azure', '~> 0.0'
gem 'fog-core', '~> 1.40'
gem 'fog-local', '~> 0.3'
-gem 'fog-google', '~> 0.3'
gem 'fog-openstack', '~> 0.1'
gem 'fog-rackspace', '~> 0.1.1'
diff --git a/Gemfile.lock b/Gemfile.lock
index bdc60552480..3684974a766 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -66,21 +66,6 @@ GEM
descendants_tracker (~> 0.0.4)
ice_nine (~> 0.11.0)
thread_safe (~> 0.3, >= 0.3.1)
- azure (0.7.5)
- addressable (~> 2.3)
- azure-core (~> 0.1)
- faraday (~> 0.9)
- faraday_middleware (~> 0.10)
- json (~> 1.8)
- mime-types (>= 1, < 3.0)
- nokogiri (~> 1.6)
- systemu (~> 2.6)
- thor (~> 0.19)
- uuid (~> 2.0)
- azure-core (0.1.2)
- faraday (~> 0.9)
- faraday_middleware (~> 0.10)
- nokogiri (~> 1.6)
babel-source (5.8.35)
babel-transpiler (0.7.0)
babel-source (>= 4.0, < 6)
@@ -217,19 +202,10 @@ GEM
fog-json (~> 1.0)
fog-xml (~> 0.1)
ipaddress (~> 0.8)
- fog-azure (0.0.2)
- azure (~> 0.6)
- fog-core (~> 1.27)
- fog-json (~> 1.0)
- fog-xml (~> 0.1)
fog-core (1.42.0)
builder
excon (~> 0.49)
formatador (~> 0.2)
- fog-google (0.3.2)
- fog-core
- fog-json
- fog-xml
fog-json (1.0.2)
fog-core (~> 1.0)
multi_json (~> 1.10)
@@ -397,8 +373,6 @@ GEM
rb-inotify (>= 0.9)
loofah (2.0.3)
nokogiri (>= 1.5.9)
- macaddr (1.7.1)
- systemu (~> 2.6.2)
mail (2.6.4)
mime-types (>= 1.16, < 4)
mail_room (0.9.0)
@@ -728,7 +702,6 @@ GEM
sys-filesystem (1.1.6)
ffi
sysexits (1.2.0)
- systemu (2.6.5)
teaspoon (1.1.5)
railties (>= 3.2.5, < 6)
teaspoon-jasmine (2.2.0)
@@ -768,8 +741,6 @@ GEM
get_process_mem (~> 0)
unicorn (>= 4, < 6)
uniform_notifier (1.10.0)
- uuid (2.3.8)
- macaddr (~> 1.0)
version_sorter (2.1.0)
virtus (1.0.5)
axiom-types (~> 0.1)
@@ -849,9 +820,7 @@ DEPENDENCIES
ffaker (~> 2.0.0)
flay (~> 2.6.1)
fog-aws (~> 0.9)
- fog-azure (~> 0.0)
fog-core (~> 1.40)
- fog-google (~> 0.3)
fog-local (~> 0.3)
fog-openstack (~> 0.1)
fog-rackspace (~> 0.1.1)
diff --git a/VERSION b/VERSION
index 919f462addc..d59bc5cbc5c 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-8.14.0-pre
+8.15.0-pre
diff --git a/app/assets/javascripts/activities.js.es6 b/app/assets/javascripts/activities.js.es6
index 19bcfef89fb..648cb4d5d85 100644
--- a/app/assets/javascripts/activities.js.es6
+++ b/app/assets/javascripts/activities.js.es6
@@ -1,5 +1,6 @@
/* eslint-disable no-param-reassign, class-methods-use-this */
-/* global Pager, Cookies */
+/* global Pager */
+/* global Cookies */
((global) => {
class Activities {
diff --git a/app/assets/javascripts/boards/components/board_card.js.es6 b/app/assets/javascripts/boards/components/board_card.js.es6
index b1afbe7d97e..2299dafd217 100644
--- a/app/assets/javascripts/boards/components/board_card.js.es6
+++ b/app/assets/javascripts/boards/components/board_card.js.es6
@@ -54,6 +54,9 @@
mouseDown () {
this.showDetail = true;
},
+ mouseMove() {
+ this.showDetail = false;
+ },
showIssue (e) {
const targetTagName = e.target.tagName.toLowerCase();
diff --git a/app/assets/javascripts/boards/components/board_list.js.es6 b/app/assets/javascripts/boards/components/board_list.js.es6
index 379f4f0d72b..43ebeef39c4 100644
--- a/app/assets/javascripts/boards/components/board_list.js.es6
+++ b/app/assets/javascripts/boards/components/board_list.js.es6
@@ -80,6 +80,7 @@
},
mounted () {
const options = gl.issueBoards.getBoardSortableDefaultOptions({
+ scroll: document.querySelectorAll('.boards-list')[0],
group: 'issues',
sort: false,
disabled: this.disabled,
@@ -88,18 +89,16 @@
const card = this.$refs.issue[e.oldIndex];
card.showDetail = false;
- Store.moving.issue = card.issue;
Store.moving.list = card.list;
+ Store.moving.issue = Store.moving.list.findIssue(+e.item.dataset.issueId);
gl.issueBoards.onStart();
},
onAdd: (e) => {
- // Add the element back to original list to allow Vue to handle DOM updates
- e.from.appendChild(e.item);
+ gl.issueBoards.BoardsStore.moveIssueToList(Store.moving.list, this.list, Store.moving.issue, e.newIndex);
this.$nextTick(() => {
- // Update the issues once we know the element has been moved
- gl.issueBoards.BoardsStore.moveIssueToList(Store.moving.list, this.list, Store.moving.issue);
+ e.item.remove();
});
},
});
diff --git a/app/assets/javascripts/boards/models/list.js.es6 b/app/assets/javascripts/boards/models/list.js.es6
index 8a7dc67409e..429bd27c3fb 100644
--- a/app/assets/javascripts/boards/models/list.js.es6
+++ b/app/assets/javascripts/boards/models/list.js.es6
@@ -106,9 +106,13 @@ class List {
});
}
- addIssue (issue, listFrom) {
+ addIssue (issue, listFrom, newIndex) {
if (!this.findIssue(issue.id)) {
- this.issues.push(issue);
+ if (newIndex !== undefined) {
+ this.issues.splice(newIndex, 0, issue);
+ } else {
+ this.issues.push(issue);
+ }
if (this.label) {
issue.addLabel(this.label);
diff --git a/app/assets/javascripts/boards/stores/boards_store.js.es6 b/app/assets/javascripts/boards/stores/boards_store.js.es6
index 6bc95aa60f2..bb2a4de8b18 100644
--- a/app/assets/javascripts/boards/stores/boards_store.js.es6
+++ b/app/assets/javascripts/boards/stores/boards_store.js.es6
@@ -89,14 +89,14 @@
});
listFrom.update();
},
- moveIssueToList (listFrom, listTo, issue) {
+ moveIssueToList (listFrom, listTo, issue, newIndex) {
const issueTo = listTo.findIssue(issue.id),
issueLists = issue.getLists(),
listLabels = issueLists.map( listIssue => listIssue.label );
// Add to new lists issues if it doesn't already exist
if (!issueTo) {
- listTo.addIssue(issue, listFrom);
+ listTo.addIssue(issue, listFrom, newIndex);
}
if (listTo.type === 'done' && listFrom.type !== 'backlog') {
diff --git a/app/assets/javascripts/build.js b/app/assets/javascripts/build.js
index e198306e67a..116a47b0907 100644
--- a/app/assets/javascripts/build.js
+++ b/app/assets/javascripts/build.js
@@ -12,7 +12,7 @@
this.pageUrl = options.pageUrl;
this.buildUrl = options.buildUrl;
this.buildStatus = options.buildStatus;
- this.state = options.state1;
+ this.state = options.logState;
this.buildStage = options.buildStage;
this.updateDropdown = bind(this.updateDropdown, this);
this.$document = $(document);
diff --git a/app/assets/javascripts/commits.js b/app/assets/javascripts/commits.js
index 951fb338f9d..3627aaf5080 100644
--- a/app/assets/javascripts/commits.js
+++ b/app/assets/javascripts/commits.js
@@ -1,4 +1,4 @@
-/* eslint-disable func-names, space-before-function-paren, wrap-iife, quotes, consistent-return, no-undef, no-return-assign, no-param-reassign, one-var, no-var, one-var-declaration-per-line, no-unused-vars, prefer-template, object-shorthand, comma-dangle, padded-blocks, max-len */
+/* eslint-disable func-names, space-before-function-paren, wrap-iife, quotes, consistent-return, no-undef, no-return-assign, no-param-reassign, one-var, no-var, one-var-declaration-per-line, no-unused-vars, prefer-template, object-shorthand, comma-dangle, padded-blocks, max-len, prefer-arrow-callback */
(function() {
this.CommitsList = (function() {
function CommitsList() {}
@@ -13,7 +13,9 @@
return false;
}
});
- Pager.init(limit, false);
+ Pager.init(limit, false, false, function() {
+ gl.utils.localTimeAgo($('.js-timeago'));
+ });
this.content = $("#commits-list");
this.searchField = $("#commits-search");
return this.initSearch();
diff --git a/app/assets/javascripts/cycle_analytics/components/stage_code_component.js.es6 b/app/assets/javascripts/cycle_analytics/components/stage_code_component.js.es6
index 520cee7738b..b83a4c63fad 100644
--- a/app/assets/javascripts/cycle_analytics/components/stage_code_component.js.es6
+++ b/app/assets/javascripts/cycle_analytics/components/stage_code_component.js.es6
@@ -1,4 +1,6 @@
/* eslint-disable no-param-reassign */
+/* global Vue */
+
((global) => {
global.cycleAnalytics = global.cycleAnalytics || {};
diff --git a/app/assets/javascripts/cycle_analytics/components/stage_issue_component.js.es6 b/app/assets/javascripts/cycle_analytics/components/stage_issue_component.js.es6
index 3bb01c67206..cb1687dcc7a 100644
--- a/app/assets/javascripts/cycle_analytics/components/stage_issue_component.js.es6
+++ b/app/assets/javascripts/cycle_analytics/components/stage_issue_component.js.es6
@@ -1,4 +1,6 @@
/* eslint-disable no-param-reassign */
+/* global Vue */
+
((global) => {
global.cycleAnalytics = global.cycleAnalytics || {};
diff --git a/app/assets/javascripts/cycle_analytics/components/stage_plan_component.js.es6 b/app/assets/javascripts/cycle_analytics/components/stage_plan_component.js.es6
index b568ab62a69..513298ba4e7 100644
--- a/app/assets/javascripts/cycle_analytics/components/stage_plan_component.js.es6
+++ b/app/assets/javascripts/cycle_analytics/components/stage_plan_component.js.es6
@@ -1,4 +1,6 @@
/* eslint-disable no-param-reassign */
+/* global Vue */
+
((global) => {
global.cycleAnalytics = global.cycleAnalytics || {};
diff --git a/app/assets/javascripts/cycle_analytics/components/stage_production_component.js.es6 b/app/assets/javascripts/cycle_analytics/components/stage_production_component.js.es6
index a6b6d817a82..73f4205b578 100644
--- a/app/assets/javascripts/cycle_analytics/components/stage_production_component.js.es6
+++ b/app/assets/javascripts/cycle_analytics/components/stage_production_component.js.es6
@@ -1,4 +1,6 @@
/* eslint-disable no-param-reassign */
+/* global Vue */
+
((global) => {
global.cycleAnalytics = global.cycleAnalytics || {};
diff --git a/app/assets/javascripts/cycle_analytics/components/stage_review_component.js.es6 b/app/assets/javascripts/cycle_analytics/components/stage_review_component.js.es6
index 9e819c1d420..501ffb1fac9 100644
--- a/app/assets/javascripts/cycle_analytics/components/stage_review_component.js.es6
+++ b/app/assets/javascripts/cycle_analytics/components/stage_review_component.js.es6
@@ -1,4 +1,6 @@
/* eslint-disable no-param-reassign */
+/* global Vue */
+
((global) => {
global.cycleAnalytics = global.cycleAnalytics || {};
diff --git a/app/assets/javascripts/cycle_analytics/components/stage_staging_component.js.es6 b/app/assets/javascripts/cycle_analytics/components/stage_staging_component.js.es6
index b30c3a31010..82622232f64 100644
--- a/app/assets/javascripts/cycle_analytics/components/stage_staging_component.js.es6
+++ b/app/assets/javascripts/cycle_analytics/components/stage_staging_component.js.es6
@@ -1,4 +1,6 @@
/* eslint-disable no-param-reassign */
+/* global Vue */
+
((global) => {
global.cycleAnalytics = global.cycleAnalytics || {};
diff --git a/app/assets/javascripts/cycle_analytics/components/stage_test_component.js.es6 b/app/assets/javascripts/cycle_analytics/components/stage_test_component.js.es6
index c54d6b6ee37..4bfd363a1f1 100644
--- a/app/assets/javascripts/cycle_analytics/components/stage_test_component.js.es6
+++ b/app/assets/javascripts/cycle_analytics/components/stage_test_component.js.es6
@@ -1,4 +1,6 @@
/* eslint-disable no-param-reassign */
+/* global Vue */
+
((global) => {
global.cycleAnalytics = global.cycleAnalytics || {};
diff --git a/app/assets/javascripts/cycle_analytics/components/total_time_component.js.es6 b/app/assets/javascripts/cycle_analytics/components/total_time_component.js.es6
index 8403fbeaab5..b9675f50e31 100644
--- a/app/assets/javascripts/cycle_analytics/components/total_time_component.js.es6
+++ b/app/assets/javascripts/cycle_analytics/components/total_time_component.js.es6
@@ -1,4 +1,6 @@
/* eslint-disable no-param-reassign */
+/* global Vue */
+
((global) => {
global.cycleAnalytics = global.cycleAnalytics || {};
diff --git a/app/assets/javascripts/cycle_analytics/cycle_analytics_bundle.js.es6 b/app/assets/javascripts/cycle_analytics/cycle_analytics_bundle.js.es6
index f1ddd139c48..2f810a69758 100644
--- a/app/assets/javascripts/cycle_analytics/cycle_analytics_bundle.js.es6
+++ b/app/assets/javascripts/cycle_analytics/cycle_analytics_bundle.js.es6
@@ -1,3 +1,7 @@
+/* global Vue */
+/* global Cookies */
+/* global Flash */
+
//= require vue
//= require_tree ./svg
//= require_tree .
diff --git a/app/assets/javascripts/cycle_analytics/cycle_analytics_store.js.es6 b/app/assets/javascripts/cycle_analytics/cycle_analytics_store.js.es6
index 9b905874167..be732971c7f 100644
--- a/app/assets/javascripts/cycle_analytics/cycle_analytics_store.js.es6
+++ b/app/assets/javascripts/cycle_analytics/cycle_analytics_store.js.es6
@@ -62,9 +62,11 @@
this.state.events = this.decorateEvents(events);
},
decorateEvents(events) {
- const newEvents = events;
+ const newEvents = [];
+
+ events.forEach((item) => {
+ if (!item) return;
- newEvents.forEach((item) => {
item.totalTime = item.total_time;
item.author.webUrl = item.author.web_url;
item.author.avatarUrl = item.author.avatar_url;
@@ -79,6 +81,8 @@
delete item.created_at;
delete item.short_sha;
delete item.commit_url;
+
+ newEvents.push(item);
});
return newEvents;
diff --git a/app/assets/javascripts/due_date_select.js.es6 b/app/assets/javascripts/due_date_select.js.es6
index fd7f961aab9..e84f5ac9183 100644
--- a/app/assets/javascripts/due_date_select.js.es6
+++ b/app/assets/javascripts/due_date_select.js.es6
@@ -145,25 +145,19 @@
class DueDateSelectors {
constructor() {
- this.initMilestoneDueDate();
+ this.initMilestoneDatePicker();
this.initIssuableSelect();
}
- initMilestoneDueDate() {
- const $datePicker = $('.datepicker');
+ initMilestoneDatePicker() {
+ $('.datepicker').datepicker({
+ dateFormat: 'yy-mm-dd'
+ });
- if ($datePicker.length) {
- const $dueDate = $('#milestone_due_date');
- $datePicker.datepicker({
- dateFormat: 'yy-mm-dd',
- onSelect: (dateText, inst) => {
- $dueDate.val(dateText);
- }
- }).datepicker('setDate', $.datepicker.parseDate('yy-mm-dd', $dueDate.val()));
- }
- $('.js-clear-due-date').on('click', (e) => {
+ $('.js-clear-due-date,.js-clear-start-date').on('click', (e) => {
e.preventDefault();
- $.datepicker._clearDate($datePicker);
+ const datepicker = $(e.target).siblings('.datepicker');
+ $.datepicker._clearDate(datepicker);
});
}
diff --git a/app/assets/javascripts/environments/components/environment.js.es6 b/app/assets/javascripts/environments/components/environment.js.es6
index 1043e516483..35e183a9086 100644
--- a/app/assets/javascripts/environments/components/environment.js.es6
+++ b/app/assets/javascripts/environments/components/environment.js.es6
@@ -1,12 +1,13 @@
+/* eslint-disable no-param-reassign */
+/* global Vue */
+/* global EnvironmentsService */
+
//= require vue
//= require vue-resource
//= require_tree ../services/
//= require ./environment_item
-/* globals Vue, EnvironmentsService */
-/* eslint-disable no-param-reassign */
-
-(() => { // eslint-disable-line
+(() => {
window.gl = window.gl || {};
/**
@@ -209,12 +210,12 @@
<table class="table ci-table environments">
<thead>
<tr>
- <th>Environment</th>
- <th>Last deployment</th>
- <th>Build</th>
- <th>Commit</th>
- <th></th>
- <th class="hidden-xs"></th>
+ <th class="environments-name">Environment</th>
+ <th class="environments-deploy">Last deployment</th>
+ <th class="environments-build">Build</th>
+ <th class="environments-commit">Commit</th>
+ <th class="environments-date"></th>
+ <th class="hidden-xs environments-actions"></th>
</tr>
</thead>
<tbody>
diff --git a/app/assets/javascripts/environments/components/environment_item.js.es6 b/app/assets/javascripts/environments/components/environment_item.js.es6
index da7db5c05bd..07f49cce3dc 100644
--- a/app/assets/javascripts/environments/components/environment_item.js.es6
+++ b/app/assets/javascripts/environments/components/environment_item.js.es6
@@ -1,4 +1,7 @@
-/*= require lib/utils/timeago */
+/* global Vue */
+/* global timeago */
+
+/*= require timeago */
/*= require lib/utils/text_utility */
/*= require vue_common_component/commit */
/*= require ./environment_actions */
@@ -6,8 +9,6 @@
/*= require ./environment_stop */
/*= require ./environment_rollback */
-/* globals Vue, timeago */
-
(() => {
/**
* Envrionment Item Component
diff --git a/app/assets/javascripts/extensions/element.js.es6 b/app/assets/javascripts/extensions/element.js.es6
index afb2f0d6956..6d9b0c4bc3e 100644
--- a/app/assets/javascripts/extensions/element.js.es6
+++ b/app/assets/javascripts/extensions/element.js.es6
@@ -3,7 +3,7 @@
Element.prototype.matches = Element.prototype.matches || Element.prototype.msMatchesSelector;
-Element.prototype.closest = function closest(selector, selectedElement = this) {
+Element.prototype.closest = Element.prototype.closest || function closest(selector, selectedElement = this) {
if (!selectedElement) return;
return selectedElement.matches(selector) ? selectedElement : Element.prototype.closest(selector, selectedElement.parentElement);
};
diff --git a/app/assets/javascripts/lib/utils/custom_event_polyfill.js.es6 b/app/assets/javascripts/lib/utils/custom_event_polyfill.js.es6
new file mode 100644
index 00000000000..5ae978010c9
--- /dev/null
+++ b/app/assets/javascripts/lib/utils/custom_event_polyfill.js.es6
@@ -0,0 +1,12 @@
+/**
+ * CustomEvent support for IE
+ */
+if (typeof window.CustomEvent !== 'function') {
+ window.CustomEvent = function CustomEvent(e, params) {
+ const options = params || { bubbles: false, cancelable: false, detail: undefined };
+ const evt = document.createEvent('CustomEvent');
+ evt.initCustomEvent(e, options.bubbles, options.cancelable, options.detail);
+ return evt;
+ };
+ window.CustomEvent.prototype = window.Event.prototype;
+}
diff --git a/app/assets/javascripts/lib/utils/datetime_utility.js b/app/assets/javascripts/lib/utils/datetime_utility.js
index d480fdc882b..963d2851e5f 100644
--- a/app/assets/javascripts/lib/utils/datetime_utility.js
+++ b/app/assets/javascripts/lib/utils/datetime_utility.js
@@ -1,4 +1,10 @@
-/* eslint-disable func-names, space-before-function-paren, wrap-iife, no-var, no-param-reassign, no-cond-assign, no-undef, comma-dangle, no-unused-expressions, prefer-template, padded-blocks, max-len */
+/* eslint-disable func-names, space-before-function-paren, wrap-iife, no-var, no-param-reassign, no-cond-assign, comma-dangle, no-unused-expressions, prefer-template, padded-blocks, max-len */
+/* global timeago */
+/* global dateFormat */
+
+/*= require timeago */
+/*= require date.format */
+
(function() {
(function(w) {
var base;
diff --git a/app/assets/javascripts/logo.js b/app/assets/javascripts/logo.js
index 9404b2c3a8c..0ae6df311bb 100644
--- a/app/assets/javascripts/logo.js
+++ b/app/assets/javascripts/logo.js
@@ -1,4 +1,6 @@
/* eslint-disable func-names, space-before-function-paren, prefer-arrow-callback, padded-blocks */
+/* global Turbolinks */
+
(function() {
Turbolinks.enableProgressBar();
diff --git a/app/assets/javascripts/merge_request_widget.js.es6 b/app/assets/javascripts/merge_request_widget.js.es6
index 54929cd8f24..a55fe9df0b3 100644
--- a/app/assets/javascripts/merge_request_widget.js.es6
+++ b/app/assets/javascripts/merge_request_widget.js.es6
@@ -67,7 +67,7 @@
MergeRequestWidget.prototype.addEventListeners = function() {
var allowedPages;
allowedPages = ['show', 'commits', 'builds', 'pipelines', 'changes'];
- return $(document).on('page:change.merge_request', (function(_this) {
+ $(document).on('page:change.merge_request', (function(_this) {
return function() {
var page;
page = $('body').data('page').split(':').last();
@@ -245,7 +245,7 @@
case "not_found":
return this.setMergeButtonClass('btn-danger');
case "running":
- return this.setMergeButtonClass('btn-warning');
+ return this.setMergeButtonClass('btn-info');
case "success":
case "success_with_warnings":
return this.setMergeButtonClass('btn-create');
@@ -263,7 +263,7 @@
};
MergeRequestWidget.prototype.setMergeButtonClass = function(css_class) {
- return $('.js-merge-button,.accept-action .dropdown-toggle').removeClass('btn-danger btn-warning btn-create').addClass(css_class);
+ return $('.js-merge-button,.accept-action .dropdown-toggle').removeClass('btn-danger btn-info btn-create').addClass(css_class);
};
return MergeRequestWidget;
diff --git a/app/assets/javascripts/notes.js b/app/assets/javascripts/notes.js
index 4149235ee21..47e7b6f831b 100644
--- a/app/assets/javascripts/notes.js
+++ b/app/assets/javascripts/notes.js
@@ -113,6 +113,7 @@
$(document).off("click", ".js-note-discard");
$(document).off("keydown", ".js-note-text");
$(document).off('click', '.js-comment-resolve-button');
+ $(document).off("click", '.system-note-commit-list-toggler');
$('.note .js-task-list-container').taskList('disable');
return $(document).off('tasklist:changed', '.note .js-task-list-container');
};
diff --git a/app/assets/javascripts/profile/profile.js.es6 b/app/assets/javascripts/profile/profile.js.es6
index 73858388261..3eb81808bd6 100644
--- a/app/assets/javascripts/profile/profile.js.es6
+++ b/app/assets/javascripts/profile/profile.js.es6
@@ -35,7 +35,6 @@
}
onSubmitForm(e) {
- e.preventDefault();
return this.saveForm();
}
diff --git a/app/assets/javascripts/tree.js b/app/assets/javascripts/tree.js
index 54c473d936d..f48a7ee0f55 100644
--- a/app/assets/javascripts/tree.js
+++ b/app/assets/javascripts/tree.js
@@ -1,4 +1,5 @@
/* eslint-disable func-names, space-before-function-paren, wrap-iife, max-len, quotes, consistent-return, no-var, one-var, one-var-declaration-per-line, no-else-return, prefer-arrow-callback, padded-blocks, max-len */
+/* global Turbolinks */
(function() {
this.TreeView = (function() {
function TreeView() {
diff --git a/app/assets/javascripts/users/calendar.js b/app/assets/javascripts/users/calendar.js
index 6d739039a5b..ba7f533c349 100644
--- a/app/assets/javascripts/users/calendar.js
+++ b/app/assets/javascripts/users/calendar.js
@@ -206,6 +206,7 @@
}
});
} else {
+ this.currentSelectedDate = '';
return $('.user-calendar-activities').html('');
}
};
diff --git a/app/assets/stylesheets/framework/common.scss b/app/assets/stylesheets/framework/common.scss
index 7f5583c917a..b24fce6f0c2 100644
--- a/app/assets/stylesheets/framework/common.scss
+++ b/app/assets/stylesheets/framework/common.scss
@@ -299,6 +299,10 @@ table {
.well {
margin-bottom: $gl-padding;
+
+ hr {
+ border-color: $gray-darker;
+ }
}
.search_box {
diff --git a/app/assets/stylesheets/framework/forms.scss b/app/assets/stylesheets/framework/forms.scss
index f0727e9688a..e83a1f7ad68 100644
--- a/app/assets/stylesheets/framework/forms.scss
+++ b/app/assets/stylesheets/framework/forms.scss
@@ -68,6 +68,46 @@ label {
}
}
+.help-form .form-group {
+ margin-left: 0;
+ margin-right: 0;
+
+ .control-label {
+ font-weight: bold;
+ padding-top: 4px;
+ }
+
+ .form-control {
+ height: 29px;
+ background: $white-light;
+ font-family: $monospace_font;
+ }
+
+ .input-group-btn .btn {
+ padding: 3px $gl-btn-padding;
+ background-color: $gray-light;
+ border: 1px solid $border-color;
+ }
+
+ .text-block {
+ line-height: 0.8;
+ padding-top: 9px;
+
+ code {
+ line-height: 1.8;
+ }
+ }
+
+ @media(max-width: $screen-sm-min) {
+ padding: 0 $gl-padding;
+
+ .control-label,
+ .text-block {
+ padding-left: 0;
+ }
+ }
+}
+
.fieldset-form fieldset {
margin-bottom: 20px;
}
@@ -167,4 +207,3 @@ label {
color: $gl-text-color;
}
}
-
diff --git a/app/assets/stylesheets/framework/issue_box.scss b/app/assets/stylesheets/framework/issue_box.scss
index ba3930e03bd..ff6f316d576 100644
--- a/app/assets/stylesheets/framework/issue_box.scss
+++ b/app/assets/stylesheets/framework/issue_box.scss
@@ -39,4 +39,8 @@
&.status-box-expired {
background: #cea61b;
}
+
+ &.status-box-upcoming {
+ background: #8f8f8f;
+ }
}
diff --git a/app/assets/stylesheets/pages/boards.scss b/app/assets/stylesheets/pages/boards.scss
index 4f5753f6fc6..4327f8bf640 100644
--- a/app/assets/stylesheets/pages/boards.scss
+++ b/app/assets/stylesheets/pages/boards.scss
@@ -243,7 +243,7 @@
}
.issue-boards-search {
- width: 335px;
+ width: 290px;
.form-control {
display: inline-block;
diff --git a/app/assets/stylesheets/pages/environments.scss b/app/assets/stylesheets/pages/environments.scss
index e9ff43a8adb..4b382e8adaf 100644
--- a/app/assets/stylesheets/pages/environments.scss
+++ b/app/assets/stylesheets/pages/environments.scss
@@ -18,6 +18,31 @@
.environments {
table-layout: fixed;
+ .environments-commit,
+ .environments-actions,
+ .environments-deploy,
+ .environments-build,
+ .environments-date {
+ position: static;
+ float: none;
+ display: table-cell;
+ }
+
+ .environments-commit,
+ .environments-actions {
+ width: 20%;
+ }
+
+ .environments-deploy,
+ .environments-build,
+ .environments-date {
+ width: 10%;
+ }
+
+ .environments-name {
+ width: 30%;
+ }
+
.deployment-column {
.avatar {
float: none;
diff --git a/app/assets/stylesheets/pages/icons.scss b/app/assets/stylesheets/pages/icons.scss
index 407c8db211d..226bd2ead31 100644
--- a/app/assets/stylesheets/pages/icons.scss
+++ b/app/assets/stylesheets/pages/icons.scss
@@ -1,12 +1,51 @@
-// CI icon colors
+.ci-status-icon-success {
+ color: $gl-success;
-.ci-status-icon {
- &-created {
- fill: $gray-darkest;
+ svg {
+ fill: $gl-success;
+ }
+}
+
+.ci-status-icon-failed {
+ color: $gl-danger;
+
+ svg {
+ fill: $gl-danger;
+ }
+}
+
+.ci-status-icon-pending,
+.ci-status-icon-success_with_warnings {
+ color: $gl-warning;
+
+ svg {
+ fill: $gl-warning;
+ }
+}
+
+.ci-status-icon-running {
+ color: $blue-normal;
+
+ svg {
+ fill: $blue-normal;
+ }
+}
+
+.ci-status-icon-canceled,
+.ci-status-icon-disabled,
+.ci-status-icon-not-found {
+ color: $gl-gray;
+
+ svg {
+ fill: $gl-gray;
}
+}
- &-skipped,
- &-canceled {
- fill: $gl-text-color;
+.ci-status-icon-created,
+.ci-status-icon-skipped {
+ color: $gray-darkest;
+
+ svg {
+ fill: $gray-darkest;
}
}
diff --git a/app/assets/stylesheets/pages/merge_requests.scss b/app/assets/stylesheets/pages/merge_requests.scss
index b6a82460f25..da1187af41c 100644
--- a/app/assets/stylesheets/pages/merge_requests.scss
+++ b/app/assets/stylesheets/pages/merge_requests.scss
@@ -24,7 +24,7 @@
.accept_merge_request {
&.ci-pending,
&.ci-running {
- @include btn-orange;
+ @include btn-blue;
}
&.ci-skipped,
@@ -62,6 +62,7 @@
.ci_widget {
border-bottom: 1px solid $well-inner-border;
+ color: $gl-gray;
svg {
margin-right: 4px;
@@ -70,48 +71,12 @@
overflow: visible;
}
- &.ci-success {
- color: $gl-success;
-
- a.environment,
- a.pipeline {
- color: inherit;
- }
- }
-
&.ci-success_with_warnings {
- color: $gl-success;
i {
color: $gl-warning;
}
}
-
- &.ci-skipped {
- background-color: #eee;
- color: #888;
- }
-
- &.ci-pending {
- color: $gl-warning;
- }
-
- &.ci-running {
- color: $blue-normal;
- }
-
- &.ci-failed,
- &.ci-error {
- color: $gl-danger;
- }
-
- &.ci-canceled {
- color: $gl-gray;
- }
-
- a.monospace {
- color: inherit;
- }
}
.mr-widget-body,
diff --git a/app/assets/stylesheets/pages/notes.scss b/app/assets/stylesheets/pages/notes.scss
index 0dfd4ab7ec9..e66c1f8d072 100644
--- a/app/assets/stylesheets/pages/notes.scss
+++ b/app/assets/stylesheets/pages/notes.scss
@@ -43,12 +43,25 @@ ul.notes {
}
.system-note-message {
- text-transform: lowercase;
+ display: inline-block;
+
+ &::first-letter {
+ text-transform: lowercase;
+ }
a {
color: $gl-link-color;
text-decoration: none;
}
+
+ p {
+ display: inline-block;
+ margin: 0;
+
+ &::first-letter {
+ text-transform: lowercase;
+ }
+ }
}
.timeline-content {
@@ -62,6 +75,13 @@ ul.notes {
display: none;
padding: 10px 0 0;
cursor: pointer;
+ position: relative;
+ z-index: 2;
+
+ &:hover {
+ color: $gl-link-color;
+ text-decoration: underline;
+ }
}
.note-text {
@@ -87,14 +107,24 @@ ul.notes {
display: none;
}
+ p:last-child {
+ a {
+ color: $gl-text-color;
+
+ &:hover {
+ color: $gl-link-color;
+ }
+ }
+ }
+
&::after {
content: '';
width: 100%;
- height: 20px;
+ height: 67px;
position: absolute;
left: 0;
- bottom: 50px;
- background: linear-gradient(rgba($gray-light, .3) 0, $white-light);
+ bottom: 0;
+ background: linear-gradient(rgba($gray-light, 0.1) -100px, $white-light 100%);
}
&.hide-shade {
@@ -188,11 +218,6 @@ ul.notes {
padding-bottom: 3px;
padding-right: 20px;
- p {
- display: inline;
- margin: 0;
- }
-
@media (min-width: $screen-sm-min) {
padding-right: 0;
}
diff --git a/app/assets/stylesheets/pages/pipelines.scss b/app/assets/stylesheets/pages/pipelines.scss
index a44a496c728..0027d2caf22 100644
--- a/app/assets/stylesheets/pages/pipelines.scss
+++ b/app/assets/stylesheets/pages/pipelines.scss
@@ -91,14 +91,6 @@
}
}
- .ci-status {
-
- svg {
- top: 1px;
- margin-right: 0;
- }
- }
-
a:hover {
text-decoration: none;
}
@@ -195,7 +187,7 @@
width: 8px;
position: absolute;
right: -7px;
- bottom: 8px;
+ bottom: 9px;
border-bottom: 2px solid $border-color;
}
}
@@ -691,10 +683,3 @@
}
}
}
-
-.ci-status-icon-created {
-
- svg {
- fill: $gray-darkest;
- }
-}
diff --git a/app/assets/stylesheets/pages/settings.scss b/app/assets/stylesheets/pages/settings.scss
index 2e8f356298d..51c926608f9 100644
--- a/app/assets/stylesheets/pages/settings.scss
+++ b/app/assets/stylesheets/pages/settings.scss
@@ -20,3 +20,7 @@
.danger-title {
color: $gl-danger;
}
+
+.service-settings .control-label {
+ padding-top: 0;
+}
diff --git a/app/assets/stylesheets/pages/status.scss b/app/assets/stylesheets/pages/status.scss
index 92997eae8b9..4c258bae1f4 100644
--- a/app/assets/stylesheets/pages/status.scss
+++ b/app/assets/stylesheets/pages/status.scss
@@ -11,80 +11,108 @@
text-decoration: none;
}
+ svg {
+ height: 13px;
+ width: 13px;
+ position: relative;
+ top: 1px;
+ margin-right: 3px;
+ overflow: visible;
+ }
+
&.ci-failed {
color: $gl-danger;
border-color: $gl-danger;
+
+ &:not(span):hover {
+ background-color: rgba( $gl-danger, .07);
+ }
+
+ svg {
+ fill: $gl-danger;
+ }
}
&.ci-success,
&.ci-success_with_warnings {
color: $gl-success;
border-color: $gl-success;
+
+ &:not(span):hover {
+ background-color: rgba( $gl-success, .07);
+ }
+
+ svg {
+ fill: $gl-success;
+ }
}
&.ci-info {
color: $gl-info;
border-color: $gl-info;
+
+ &:not(span):hover {
+ background-color: rgba( $gl-info, .07);
+ }
+
+ svg {
+ fill: $gl-info;
+ }
}
&.ci-canceled,
- &.ci-skipped,
&.ci-disabled {
color: $gl-gray;
border-color: $gl-gray;
+
+ &:not(span):hover {
+ background-color: rgba( $gl-gray, .07);
+ }
+
+ svg {
+ fill: $gl-gray;
+ }
}
&.ci-pending {
color: $gl-warning;
border-color: $gl-warning;
+
+ &:not(span):hover {
+ background-color: rgba( $gl-warning, .07);
+ }
+
+ svg {
+ fill: $gl-warning;
+ }
}
&.ci-running {
color: $blue-normal;
border-color: $blue-normal;
+
+ &:not(span):hover {
+ background-color: rgba( $blue-normal, .07);
+ }
+
+ svg {
+ fill: $blue-normal;
+ }
}
- &.ci-created {
+ &.ci-created,
+ &.ci-skipped {
color: $table-text-gray;
border-color: $table-text-gray;
+ &:not(span):hover {
+ background-color: rgba( $table-text-gray, .07);
+ }
+
svg {
fill: $table-text-gray;
}
}
-
- svg {
- height: 13px;
- width: 13px;
- position: relative;
- top: 1px;
- margin: 0 3px;
- overflow: visible;
- }
- }
-
- .ci-status-icon-success {
- color: $gl-success;
- }
-
- .ci-status-icon-failed {
- color: $gl-danger;
- }
-
- .ci-status-icon-pending,
- .ci-status-icon-success_with_warning {
- color: $gl-warning;
- }
-
- .ci-status-icon-running {
- color: $blue-normal;
- }
-
- .ci-status-icon-canceled,
- .ci-status-icon-disabled,
- .ci-status-icon-not-found,
- .ci-status-icon-skipped {
- color: $gl-gray;
}
}
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 517ad4f03f3..bcc0b17bce2 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -49,6 +49,14 @@ class ApplicationController < ActionController::Base
render_404
end
+ def route_not_found
+ if current_user
+ not_found
+ else
+ redirect_to new_user_session_path
+ end
+ end
+
protected
# This filter handles both private tokens and personal access tokens
@@ -224,7 +232,7 @@ class ApplicationController < ActionController::Base
end
def require_email
- if current_user && current_user.temp_oauth_email?
+ if current_user && current_user.temp_oauth_email? && session[:impersonator_id].nil?
redirect_to profile_path, notice: 'Please complete your profile with email address' and return
end
end
diff --git a/app/controllers/groups/milestones_controller.rb b/app/controllers/groups/milestones_controller.rb
index 506484932cc..24ec4eec3f2 100644
--- a/app/controllers/groups/milestones_controller.rb
+++ b/app/controllers/groups/milestones_controller.rb
@@ -67,7 +67,7 @@ class Groups::MilestonesController < Groups::ApplicationController
end
def milestone_params
- params.require(:milestone).permit(:title, :description, :due_date, :state_event)
+ params.require(:milestone).permit(:title, :description, :start_date, :due_date, :state_event)
end
def milestone_path(title)
diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb
index dbbd2ad849e..e24a670631f 100644
--- a/app/controllers/projects/merge_requests_controller.rb
+++ b/app/controllers/projects/merge_requests_controller.rb
@@ -563,11 +563,8 @@ class Projects::MergeRequestsController < Projects::ApplicationController
def define_pipelines_vars
@pipelines = @merge_request.all_pipelines
-
- if @pipelines.present? && @merge_request.commits.present?
- @pipeline = @pipelines.first
- @statuses = @pipeline.statuses.relevant
- end
+ @pipeline = @merge_request.pipeline
+ @statuses = @pipeline.statuses.relevant if @pipeline.present?
end
def define_new_vars
diff --git a/app/controllers/projects/milestones_controller.rb b/app/controllers/projects/milestones_controller.rb
index ff63f22cb5b..be52b0fa7cf 100644
--- a/app/controllers/projects/milestones_controller.rb
+++ b/app/controllers/projects/milestones_controller.rb
@@ -112,6 +112,6 @@ class Projects::MilestonesController < Projects::ApplicationController
end
def milestone_params
- params.require(:milestone).permit(:title, :description, :due_date, :state_event)
+ params.require(:milestone).permit(:title, :description, :start_date, :due_date, :state_event)
end
end
diff --git a/app/controllers/projects/notes_controller.rb b/app/controllers/projects/notes_controller.rb
index f029fde2a2f..15ca080c696 100644
--- a/app/controllers/projects/notes_controller.rb
+++ b/app/controllers/projects/notes_controller.rb
@@ -197,6 +197,7 @@ class Projects::NotesController < Projects::ApplicationController
)
end
+ attrs[:commands_changes] = note.commands_changes unless attrs[:award]
attrs
end
diff --git a/app/controllers/projects/pipelines_settings_controller.rb b/app/controllers/projects/pipelines_settings_controller.rb
index 9136633b87a..53ce23221ed 100644
--- a/app/controllers/projects/pipelines_settings_controller.rb
+++ b/app/controllers/projects/pipelines_settings_controller.rb
@@ -17,7 +17,7 @@ class Projects::PipelinesSettingsController < Projects::ApplicationController
flash[:notice] = "CI/CD Pipelines settings for '#{@project.name}' were successfully updated."
redirect_to namespace_project_pipelines_settings_path(@project.namespace, @project)
else
- render 'index'
+ render 'show'
end
end
diff --git a/app/helpers/application_settings_helper.rb b/app/helpers/application_settings_helper.rb
index 6d10fe3e9d7..60485160495 100644
--- a/app/helpers/application_settings_helper.rb
+++ b/app/helpers/application_settings_helper.rb
@@ -67,14 +67,14 @@ module ApplicationSettingsHelper
def import_sources_checkboxes(help_block_id)
Gitlab::ImportSources.options.map do |name, source|
checked = current_application_settings.import_sources.include?(source)
- css_class = 'btn'
- css_class += ' active' if checked
+ css_class = checked ? 'active' : ''
checkbox_name = 'application_setting[import_sources][]'
- label_tag(checkbox_name, class: css_class) do
+ label_tag(name, class: css_class) do
check_box_tag(checkbox_name, source, checked,
autocomplete: 'off',
- 'aria-describedby' => help_block_id) + name
+ 'aria-describedby' => help_block_id,
+ id: name.tr(' ', '_')) + name
end
end
end
diff --git a/app/helpers/builds_helper.rb b/app/helpers/builds_helper.rb
index fde297c588e..9fc69e12266 100644
--- a/app/helpers/builds_helper.rb
+++ b/app/helpers/builds_helper.rb
@@ -12,7 +12,7 @@ module BuildsHelper
build_url: namespace_project_build_url(@project.namespace, @project, @build, :json),
build_status: @build.status,
build_stage: @build.stage,
- state1: @build.trace_with_state[:state]
+ log_state: @build.trace_with_state[:state].to_s
}
end
end
diff --git a/app/helpers/ci_status_helper.rb b/app/helpers/ci_status_helper.rb
index 895c3d728ad..abcf84b4d15 100644
--- a/app/helpers/ci_status_helper.rb
+++ b/app/helpers/ci_status_helper.rb
@@ -5,7 +5,7 @@ module CiStatusHelper
end
def ci_status_with_icon(status, target = nil)
- content = ci_icon_for_status(status) + '&nbsp;'.html_safe + ci_label_for_status(status)
+ content = ci_icon_for_status(status) + ci_label_for_status(status)
klass = "ci-status ci-#{status}"
if target
link_to content, target, class: klass
diff --git a/app/helpers/issues_helper.rb b/app/helpers/issues_helper.rb
index 1644c346dd8..a8a49e43b05 100644
--- a/app/helpers/issues_helper.rb
+++ b/app/helpers/issues_helper.rb
@@ -64,6 +64,8 @@ module IssuesHelper
'status-box-merged'
elsif item.closed?
'status-box-closed'
+ elsif item.respond_to?(:upcoming?) && item.upcoming?
+ 'status-box-upcoming'
else
'status-box-open'
end
diff --git a/app/helpers/milestones_helper.rb b/app/helpers/milestones_helper.rb
index 83a2a4ad3ec..729928ce1dd 100644
--- a/app/helpers/milestones_helper.rb
+++ b/app/helpers/milestones_helper.rb
@@ -86,6 +86,30 @@ module MilestonesHelper
days = milestone.remaining_days
content = content_tag(:strong, days)
content << " #{'day'.pluralize(days)} remaining"
+ elsif milestone.upcoming?
+ content_tag(:strong, 'Upcoming')
+ elsif milestone.start_date && milestone.start_date.past?
+ days = milestone.elapsed_days
+ content = content_tag(:strong, days)
+ content << " #{'day'.pluralize(days)} elapsed"
+ end
+ end
+
+ def milestone_date_range(milestone)
+ if milestone.start_date && milestone.due_date
+ "#{milestone.start_date.to_s(:medium)} - #{milestone.due_date.to_s(:medium)}"
+ elsif milestone.due_date
+ if milestone.due_date.past?
+ "expired on #{milestone.due_date.to_s(:medium)}"
+ else
+ "expires on #{milestone.due_date.to_s(:medium)}"
+ end
+ elsif milestone.start_date
+ if milestone.start_date.past?
+ "started on #{milestone.start_date.to_s(:medium)}"
+ else
+ "starts on #{milestone.start_date.to_s(:medium)}"
+ end
end
end
end
diff --git a/app/helpers/sidekiq_helper.rb b/app/helpers/sidekiq_helper.rb
index 56749d80bd3..b5017080cfb 100644
--- a/app/helpers/sidekiq_helper.rb
+++ b/app/helpers/sidekiq_helper.rb
@@ -5,15 +5,11 @@ module SidekiqHelper
(?<mem>[\d\.,]+)\s+
(?<state>[DRSTWXZNLsl\+<]+)\s+
(?<start>.+)\s+
- (?<command>sidekiq.*\])\s*
+ (?<command>sidekiq.*\])
\z/x
def parse_sidekiq_ps(line)
- match = line.match(SIDEKIQ_PS_REGEXP)
- if match
- match[1..6]
- else
- %w[? ? ? ? ? ?]
- end
+ match = line.strip.match(SIDEKIQ_PS_REGEXP)
+ match ? match[1..6] : Array.new(6, '?')
end
end
diff --git a/app/models/commit_status.rb b/app/models/commit_status.rb
index d159fc6c5c7..c345bf293c9 100644
--- a/app/models/commit_status.rb
+++ b/app/models/commit_status.rb
@@ -135,15 +135,19 @@ class CommitStatus < ActiveRecord::Base
allow_failure? && (failed? || canceled?)
end
+ def duration
+ calculate_duration
+ end
+
def playable?
false
end
- def duration
- calculate_duration
+ def stuck?
+ false
end
- def stuck?
+ def has_trace?
false
end
end
diff --git a/app/models/concerns/milestoneish.rb b/app/models/concerns/milestoneish.rb
index 7bcc78247ba..e65fc9eaa09 100644
--- a/app/models/concerns/milestoneish.rb
+++ b/app/models/concerns/milestoneish.rb
@@ -23,7 +23,31 @@ module Milestoneish
(due_date - Date.today).to_i
end
+ def elapsed_days
+ return 0 if !start_date || start_date.future?
+
+ (Date.today - start_date).to_i
+ end
+
def issues_visible_to_user(user = nil)
issues.visible_to_user(user)
end
+
+ def upcoming?
+ start_date && start_date.future?
+ end
+
+ def expires_at
+ if due_date
+ if due_date.past?
+ "expired on #{due_date.to_s(:medium)}"
+ else
+ "expires on #{due_date.to_s(:medium)}"
+ end
+ end
+ end
+
+ def expired?
+ due_date && due_date.past?
+ end
end
diff --git a/app/models/global_milestone.rb b/app/models/global_milestone.rb
index cde4a568577..b01607dcda9 100644
--- a/app/models/global_milestone.rb
+++ b/app/models/global_milestone.rb
@@ -28,26 +28,16 @@ class GlobalMilestone
@title.to_slug.normalize.to_s
end
- def expired?
- if due_date
- due_date.past?
- else
- false
- end
- end
-
def projects
@projects ||= Project.for_milestones(milestones.select(:id))
end
def state
- state = milestones.map { |milestone| milestone.state }
-
- if state.count('closed') == state.size
- 'closed'
- else
- 'active'
+ milestones.each do |milestone|
+ return 'active' if milestone.state != 'closed'
end
+
+ 'closed'
end
def active?
@@ -81,18 +71,15 @@ class GlobalMilestone
@due_date =
if @milestones.all? { |x| x.due_date == @milestones.first.due_date }
@milestones.first.due_date
- else
- nil
end
end
- def expires_at
- if due_date
- if due_date.past?
- "expired on #{due_date.to_s(:medium)}"
- else
- "expires on #{due_date.to_s(:medium)}"
+ def start_date
+ return @start_date if defined?(@start_date)
+
+ @start_date =
+ if @milestones.all? { |x| x.start_date == @milestones.first.start_date }
+ @milestones.first.start_date
end
- end
end
end
diff --git a/app/models/group.rb b/app/models/group.rb
index 73b0f1c6572..4248e1162d8 100644
--- a/app/models/group.rb
+++ b/app/models/group.rb
@@ -65,7 +65,9 @@ class Group < Namespace
def select_for_project_authorization
if current_scope.joins_values.include?(:shared_projects)
- select("members.user_id, projects.id AS project_id, project_group_links.group_access")
+ joins('INNER JOIN namespaces project_namespace ON project_namespace.id = projects.namespace_id')
+ .where('project_namespace.share_with_group_lock = ?', false)
+ .select("members.user_id, projects.id AS project_id, LEAST(project_group_links.group_access, members.access_level) AS access_level")
else
super
end
diff --git a/app/models/issue.rb b/app/models/issue.rb
index 6e8f5d3c422..dd0cb75f9a8 100644
--- a/app/models/issue.rb
+++ b/app/models/issue.rb
@@ -93,7 +93,7 @@ class Issue < ActiveRecord::Base
# Check if we are scoped to a specific project's issues
if owner_project
- if owner_project.authorized_for_user?(user, Gitlab::Access::REPORTER)
+ if owner_project.team.member?(user, Gitlab::Access::REPORTER)
# If the project is authorized for the user, they can see all issues in the project
return all
else
diff --git a/app/models/member.rb b/app/models/member.rb
index 7be2665bf48..df93aaee847 100644
--- a/app/models/member.rb
+++ b/app/models/member.rb
@@ -246,7 +246,7 @@ class Member < ActiveRecord::Base
end
def post_update_hook
- # override in subclass
+ UserProjectAccessChangedService.new(user.id).execute if access_level_changed?
end
def post_destroy_hook
diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb
index 6c3c093d084..fdf54cc8a7e 100644
--- a/app/models/merge_request.rb
+++ b/app/models/merge_request.rb
@@ -494,10 +494,14 @@ class MergeRequest < ActiveRecord::Base
discussions_resolvable? && diff_discussions.none?(&:to_be_resolved?)
end
+ def discussions_to_be_resolved?
+ discussions_resolvable? && !discussions_resolved?
+ end
+
def mergeable_discussions_state?
return true unless project.only_allow_merge_if_all_discussions_are_resolved?
- discussions_resolved?
+ !discussions_to_be_resolved?
end
def hook_attrs
diff --git a/app/models/milestone.rb b/app/models/milestone.rb
index 23aecbfa3a6..c774e69080c 100644
--- a/app/models/milestone.rb
+++ b/app/models/milestone.rb
@@ -29,6 +29,7 @@ class Milestone < ActiveRecord::Base
validates :title, presence: true, uniqueness: { scope: :project_id }
validates :project, presence: true
+ validate :start_date_should_be_less_than_due_date, if: Proc.new { |m| m.start_date.present? && m.due_date.present? }
strip_attributes :title
@@ -131,24 +132,6 @@ class Milestone < ActiveRecord::Base
self.title
end
- def expired?
- if due_date
- due_date.past?
- else
- false
- end
- end
-
- def expires_at
- if due_date
- if due_date.past?
- "expired on #{due_date.to_s(:medium)}"
- else
- "expires on #{due_date.to_s(:medium)}"
- end
- end
- end
-
def can_be_closed?
active? && issues.opened.count.zero?
end
@@ -212,4 +195,10 @@ class Milestone < ActiveRecord::Base
def sanitize_title(value)
CGI.unescape_html(Sanitize.clean(value.to_s))
end
+
+ def start_date_should_be_less_than_due_date
+ if due_date <= start_date
+ errors.add(:start_date, "Can't be greater than due date")
+ end
+ end
end
diff --git a/app/models/namespace.rb b/app/models/namespace.rb
index b67049f0f55..891dffac648 100644
--- a/app/models/namespace.rb
+++ b/app/models/namespace.rb
@@ -27,6 +27,7 @@ class Namespace < ActiveRecord::Base
delegate :name, to: :owner, allow_nil: true, prefix: true
after_update :move_dir, if: :path_changed?
+ after_commit :refresh_access_of_projects_invited_groups, on: :update, if: -> { previous_changes.key?('share_with_group_lock') }
# Save the storage paths before the projects are destroyed to use them on after destroy
before_destroy(prepend: true) { @old_repository_storage_paths = repository_storage_paths }
@@ -103,6 +104,8 @@ class Namespace < ActiveRecord::Base
gitlab_shell.add_namespace(repository_storage_path, path_was)
unless gitlab_shell.mv_namespace(repository_storage_path, path_was, path)
+ Rails.logger.error "Exception moving path #{repository_storage_path} from #{path_was} to #{path}"
+
# if we cannot move namespace directory we should rollback
# db changes in order to prevent out of sync between db and fs
raise Exception.new('namespace directory cannot be moved')
@@ -175,4 +178,11 @@ class Namespace < ActiveRecord::Base
end
end
end
+
+ def refresh_access_of_projects_invited_groups
+ Group.
+ joins(project_group_links: :project).
+ where(projects: { namespace_id: id }).
+ find_each(&:refresh_members_authorized_projects)
+ end
end
diff --git a/app/models/note.rb b/app/models/note.rb
index 9ff5e308ed2..ed4224e3046 100644
--- a/app/models/note.rb
+++ b/app/models/note.rb
@@ -19,6 +19,9 @@ class Note < ActiveRecord::Base
# Banzai::ObjectRenderer
attr_accessor :user_visible_reference_count
+ # Attribute used to store the attributes that have ben changed by slash commands.
+ attr_accessor :commands_changes
+
default_value_for :system, false
attr_mentionable :note, pipeline: :note
diff --git a/app/models/project.rb b/app/models/project.rb
index f8a54324341..9256e9ddd95 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -126,6 +126,8 @@ class Project < ActiveRecord::Base
has_many :hooks, dependent: :destroy, class_name: 'ProjectHook'
has_many :protected_branches, dependent: :destroy
+ has_many :project_authorizations, dependent: :destroy
+ has_many :authorized_users, through: :project_authorizations, source: :user, class_name: 'User'
has_many :project_members, -> { where(requested_at: nil) }, dependent: :destroy, as: :source
alias_method :members, :project_members
has_many :users, through: :project_members
@@ -163,6 +165,7 @@ class Project < ActiveRecord::Base
delegate :name, to: :owner, allow_nil: true, prefix: true
delegate :members, to: :team, prefix: true
delegate :add_user, to: :team
+ delegate :add_guest, :add_reporter, :add_developer, :add_master, to: :team
# Validations
validates :creator, presence: true, on: :create
@@ -174,6 +177,7 @@ class Project < ActiveRecord::Base
message: Gitlab::Regex.project_name_regex_message }
validates :path,
presence: true,
+ project_path: true,
length: { within: 0..255 },
format: { with: Gitlab::Regex.project_path_regex,
message: Gitlab::Regex.project_path_regex_message }
@@ -1292,14 +1296,6 @@ class Project < ActiveRecord::Base
end
end
- # Checks if `user` is authorized for this project, with at least the
- # `min_access_level` (if given).
- def authorized_for_user?(user, min_access_level = nil)
- return false unless user
-
- user.authorized_project?(self, min_access_level)
- end
-
def append_or_update_attribute(name, value)
old_values = public_send(name.to_s)
diff --git a/app/models/project_services/jira_service.rb b/app/models/project_services/jira_service.rb
index aeded715893..70bbbbcda85 100644
--- a/app/models/project_services/jira_service.rb
+++ b/app/models/project_services/jira_service.rb
@@ -57,9 +57,9 @@ class JiraService < IssueTrackerService
end
def help
- 'See the ' \
- '[integration doc](http://doc.gitlab.com/ce/integration/external-issue-tracker.html) '\
- 'for details.'
+ 'You need to configure JIRA before enabling this service. For more details
+ read the
+ [JIRA service documentation](https://docs.gitlab.com/ce/project_services/jira.html).'
end
def title
diff --git a/app/models/project_services/mattermost_slash_commands_service.rb b/app/models/project_services/mattermost_slash_commands_service.rb
index 67902329593..33431f41dc2 100644
--- a/app/models/project_services/mattermost_slash_commands_service.rb
+++ b/app/models/project_services/mattermost_slash_commands_service.rb
@@ -19,13 +19,6 @@ class MattermostSlashCommandsService < ChatService
'mattermost_slash_commands'
end
- def help
- "This service allows you to use slash commands with your Mattermost installation.<br/>
- To setup this Service you need to create a new <b>Slash commands</b> in your Mattermost integration panel.<br/>
- <br/>
- Create integration with URL #{service_trigger_url(self)} and enter the token below."
- end
-
def fields
[
{ type: 'text', name: 'token', placeholder: '' }
diff --git a/app/models/project_team.rb b/app/models/project_team.rb
index a6e911df9bd..8a53e974b6f 100644
--- a/app/models/project_team.rb
+++ b/app/models/project_team.rb
@@ -21,6 +21,22 @@ class ProjectTeam
end
end
+ def add_guest(user, current_user: nil)
+ self << [user, :guest, current_user]
+ end
+
+ def add_reporter(user, current_user: nil)
+ self << [user, :reporter, current_user]
+ end
+
+ def add_developer(user, current_user: nil)
+ self << [user, :developer, current_user]
+ end
+
+ def add_master(user, current_user: nil)
+ self << [user, :master, current_user]
+ end
+
def find_member(user_id)
member = project.members.find_by(user_id: user_id)
@@ -64,19 +80,19 @@ class ProjectTeam
alias_method :users, :members
def guests
- @guests ||= fetch_members(:guests)
+ @guests ||= fetch_members(Gitlab::Access::GUEST)
end
def reporters
- @reporters ||= fetch_members(:reporters)
+ @reporters ||= fetch_members(Gitlab::Access::REPORTER)
end
def developers
- @developers ||= fetch_members(:developers)
+ @developers ||= fetch_members(Gitlab::Access::DEVELOPER)
end
def masters
- @masters ||= fetch_members(:masters)
+ @masters ||= fetch_members(Gitlab::Access::MASTER)
end
def import(source_project, current_user = nil)
@@ -125,8 +141,12 @@ class ProjectTeam
max_member_access(user.id) == Gitlab::Access::MASTER
end
- def member?(user, min_member_access = Gitlab::Access::GUEST)
- max_member_access(user.id) >= min_member_access
+ # Checks if `user` is authorized for this project, with at least the
+ # `min_access_level` (if given).
+ def member?(user, min_access_level = Gitlab::Access::GUEST)
+ return false unless user
+
+ user.authorized_project?(project, min_access_level)
end
def human_max_access(user_id)
@@ -149,112 +169,29 @@ class ProjectTeam
# Lookup only the IDs we need
user_ids = user_ids - access.keys
+ users_access = project.project_authorizations.
+ where(user: user_ids).
+ group(:user_id).
+ maximum(:access_level)
- if user_ids.present?
- user_ids.each { |id| access[id] = Gitlab::Access::NO_ACCESS }
-
- member_access = project.members.access_for_user_ids(user_ids)
- merge_max!(access, member_access)
-
- if group
- group_access = group.members.access_for_user_ids(user_ids)
- merge_max!(access, group_access)
- end
-
- # Each group produces a list of maximum access level per user. We take the
- # max of the values produced by each group.
- if project_shared_with_group?
- project.project_group_links.each do |group_link|
- invited_access = max_invited_level_for_users(group_link, user_ids)
- merge_max!(access, invited_access)
- end
- end
- end
-
+ access.merge!(users_access)
access
end
def max_member_access(user_id)
- max_member_access_for_user_ids([user_id])[user_id]
+ max_member_access_for_user_ids([user_id])[user_id] || Gitlab::Access::NO_ACCESS
end
private
- # For a given group, return the maximum access level for the user. This is the min of
- # the invited access level of the group and the access level of the user within the group.
- # For example, if the group has been given DEVELOPER access but the member has MASTER access,
- # the user should receive only DEVELOPER access.
- def max_invited_level_for_users(group_link, user_ids)
- invited_group = group_link.group
- capped_access_level = group_link.group_access
- access = invited_group.group_members.access_for_user_ids(user_ids)
-
- # If the user is not in the list, assume he/she does not have access
- missing_users = user_ids - access.keys
- missing_users.each { |id| access[id] = Gitlab::Access::NO_ACCESS }
-
- # Cap the maximum access by the invited level access
- access.each { |key, value| access[key] = [value, capped_access_level].min }
- end
-
def fetch_members(level = nil)
- project_members = project.members
- group_members = group ? group.members : []
-
- if level
- project_members = project_members.public_send(level)
- group_members = group_members.public_send(level) if group
- end
-
- user_ids = project_members.pluck(:user_id)
-
- invited_members = fetch_invited_members(level)
- user_ids.push(*invited_members.map(&:user_id)) if invited_members.any?
+ members = project.authorized_users
+ members = members.where(project_authorizations: { access_level: level }) if level
- user_ids.push(*group_members.pluck(:user_id)) if group
-
- User.where(id: user_ids)
+ members
end
def group
project.group
end
-
- def merge_max!(first_hash, second_hash)
- first_hash.merge!(second_hash) { |_key, old, new| old > new ? old : new }
- end
-
- def project_shared_with_group?
- project.invited_groups.any? && project.allowed_to_share_with_group?
- end
-
- def fetch_invited_members(level = nil)
- invited_members = []
-
- return invited_members unless project_shared_with_group?
-
- project.project_group_links.includes(group: [:group_members]).each do |link|
- invited_group_members = link.group.members
-
- if level
- numeric_level = GroupMember.access_level_roles[level.to_s.singularize.titleize]
-
- # If we're asked for a level that's higher than the group's access,
- # there's nothing left to do
- next if numeric_level > link.group_access
-
- # Make sure we include everyone _above_ the requested level as well
- invited_group_members =
- if numeric_level == link.group_access
- invited_group_members.where("access_level >= ?", link.group_access)
- else
- invited_group_members.public_send(level)
- end
- end
-
- invited_members << invited_group_members
- end
-
- invited_members.flatten.compact
- end
end
diff --git a/app/models/user.rb b/app/models/user.rb
index 29fb849940a..513a19d81d2 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -291,8 +291,12 @@ class User < ActiveRecord::Base
end
end
+ def find_by_username(username)
+ iwhere(username: username).take
+ end
+
def find_by_username!(username)
- find_by!('lower(username) = ?', username.downcase)
+ iwhere(username: username).take!
end
def find_by_personal_access_token(token_string)
@@ -926,7 +930,7 @@ class User < ActiveRecord::Base
# Returns a union query of projects that the user is authorized to access
def project_authorizations_union
relations = [
- personal_projects.select("#{id} AS user_id, projects.id AS project_id, #{Gitlab::Access::OWNER} AS access_level"),
+ personal_projects.select("#{id} AS user_id, projects.id AS project_id, #{Gitlab::Access::MASTER} AS access_level"),
groups_projects.select_for_project_authorization,
projects.select_for_project_authorization,
groups.joins(:shared_projects).select_for_project_authorization
diff --git a/app/serializers/analytics_build_entity.rb b/app/serializers/analytics_build_entity.rb
index 5fdf2bbf7c3..abefcd5cc02 100644
--- a/app/serializers/analytics_build_entity.rb
+++ b/app/serializers/analytics_build_entity.rb
@@ -13,7 +13,7 @@ class AnalyticsBuildEntity < Grape::Entity
end
expose :duration, as: :total_time do |build|
- distance_of_time_as_hash(build[:duration].to_f)
+ distance_of_time_as_hash(build.duration.to_f)
end
expose :branch do
diff --git a/app/serializers/entity_date_helper.rb b/app/serializers/entity_date_helper.rb
index b333b3344c3..918abba8d99 100644
--- a/app/serializers/entity_date_helper.rb
+++ b/app/serializers/entity_date_helper.rb
@@ -2,7 +2,7 @@ module EntityDateHelper
include ActionView::Helpers::DateHelper
def interval_in_words(diff)
- "#{distance_of_time_in_words(diff.to_f)} ago"
+ "#{distance_of_time_in_words(Time.now, diff)} ago"
end
# Converts seconds into a hash such as:
diff --git a/app/services/notes/create_service.rb b/app/services/notes/create_service.rb
index 7935fabe2da..d75592e31f3 100644
--- a/app/services/notes/create_service.rb
+++ b/app/services/notes/create_service.rb
@@ -43,6 +43,8 @@ module Notes
if only_commands
note.errors.add(:commands_only, 'Your commands have been executed!')
end
+
+ note.commands_changes = command_params.keys
end
note
diff --git a/app/validators/namespace_validator.rb b/app/validators/namespace_validator.rb
index 2821ecf0a88..eb3ed31b65b 100644
--- a/app/validators/namespace_validator.rb
+++ b/app/validators/namespace_validator.rb
@@ -35,8 +35,22 @@ class NamespaceValidator < ActiveModel::EachValidator
users
].freeze
+ def self.valid?(value)
+ !reserved?(value) && follow_format?(value)
+ end
+
+ def self.reserved?(value)
+ RESERVED.include?(value)
+ end
+
+ def self.follow_format?(value)
+ value =~ Gitlab::Regex.namespace_regex
+ end
+
+ delegate :reserved?, :follow_format?, to: :class
+
def validate_each(record, attribute, value)
- unless value =~ Gitlab::Regex.namespace_regex
+ unless follow_format?(value)
record.errors.add(attribute, Gitlab::Regex.namespace_regex_message)
end
@@ -44,10 +58,4 @@ class NamespaceValidator < ActiveModel::EachValidator
record.errors.add(attribute, "#{value} is a reserved name")
end
end
-
- private
-
- def reserved?(value)
- RESERVED.include?(value)
- end
end
diff --git a/app/validators/project_path_validator.rb b/app/validators/project_path_validator.rb
new file mode 100644
index 00000000000..927c67b65b0
--- /dev/null
+++ b/app/validators/project_path_validator.rb
@@ -0,0 +1,36 @@
+# ProjectPathValidator
+#
+# Custom validator for GitLab project path values.
+#
+# Values are checked for formatting and exclusion from a list of reserved path
+# names.
+class ProjectPathValidator < ActiveModel::EachValidator
+ # All project routes with wildcard argument must be listed here.
+ # Otherwise it can lead to routing issues when route considered as project name.
+ #
+ # Example:
+ # /group/project/tree/deploy_keys
+ #
+ # without tree as reserved name routing can match 'group/project' as group name,
+ # 'tree' as project name and 'deploy_keys' as route.
+ #
+ RESERVED = (NamespaceValidator::RESERVED +
+ %w[tree commits wikis new edit create update logs_tree
+ preview blob blame raw files create_dir find_file]).freeze
+
+ def self.valid?(value)
+ !reserved?(value)
+ end
+
+ def self.reserved?(value)
+ RESERVED.include?(value)
+ end
+
+ delegate :reserved?, to: :class
+
+ def validate_each(record, attribute, value)
+ if reserved?(value)
+ record.errors.add(attribute, "#{value} is a reserved name")
+ end
+ end
+end
diff --git a/app/views/admin/application_settings/_form.html.haml b/app/views/admin/application_settings/_form.html.haml
index 95cae5ea24b..ce803f329f9 100644
--- a/app/views/admin/application_settings/_form.html.haml
+++ b/app/views/admin/application_settings/_form.html.haml
@@ -31,10 +31,8 @@
.form-group
= f.label :import_sources, class: 'control-label col-sm-2'
.col-sm-10
- - data_attrs = { toggle: 'buttons' }
- .btn-group{ data: data_attrs }
- - import_sources_checkboxes('import-sources-help').each do |source|
- = source
+ - import_sources_checkboxes('import-sources-help').each do |source|
+ .checkbox= source
%span.help-block#import-sources-help
Enabled sources for code import during project creation. OmniAuth must be configured for GitHub
= link_to "(?)", help_page_path("integration/github")
diff --git a/app/views/admin/services/_form.html.haml b/app/views/admin/services/_form.html.haml
index cdbfc60f9a4..e5b8ebdf613 100644
--- a/app/views/admin/services/_form.html.haml
+++ b/app/views/admin/services/_form.html.haml
@@ -4,7 +4,8 @@
%p #{@service.description} template
= form_for :service, url: admin_application_settings_service_path, method: :put, html: { class: 'form-horizontal fieldset-form' } do |form|
- = render 'shared/service_settings', form: form
+ = render 'shared/service_settings', form: form, subject: @service
- .form-actions
- = form.submit 'Save', class: 'btn btn-save'
+ .footer-block.row-content-block
+ .form-actions
+ = form.submit 'Save', class: 'btn btn-save'
diff --git a/app/views/award_emoji/_awards_block.html.haml b/app/views/award_emoji/_awards_block.html.haml
index fbe3ab912b6..d8912eda314 100644
--- a/app/views/award_emoji/_awards_block.html.haml
+++ b/app/views/award_emoji/_awards_block.html.haml
@@ -1,7 +1,10 @@
- grouped_emojis = awardable.grouped_awards(with_thumbs: inline)
.awards.js-awards-block{ class: ("hidden" if !inline && grouped_emojis.empty?), data: { award_url: toggle_award_url(awardable) } }
- awards_sort(grouped_emojis).each do |emoji, awards|
- %button.btn.award-control.js-emoji-btn.has-tooltip{ type: "button", class: (award_active_class(awards, current_user)), data: { placement: "bottom", title: award_user_list(awards, current_user) } }
+ %button.btn.award-control.js-emoji-btn.has-tooltip{ type: "button",
+ disabled: !current_user,
+ class: (award_active_class(awards, current_user)),
+ data: { placement: "bottom", title: award_user_list(awards, current_user) } }
= emoji_icon(emoji, sprite: false)
%span.award-control-text.js-counter
= awards.count
diff --git a/app/views/groups/milestones/new.html.haml b/app/views/groups/milestones/new.html.haml
index 0dfaf743992..63cadfca530 100644
--- a/app/views/groups/milestones/new.html.haml
+++ b/app/views/groups/milestones/new.html.haml
@@ -36,19 +36,8 @@
= f.collection_select :project_ids, @group.projects.non_archived, :id, :name,
{ selected: @group.projects.non_archived.pluck(:id) }, required: true, multiple: true, class: 'select2'
- .col-md-6
- .form-group
- = f.label :due_date, "Due Date", class: "control-label"
- .col-sm-10
- = f.text_field :due_date, class: "datepicker form-control", placeholder: "Select due date"
+ = render "shared/milestones/form_dates", f: f
.form-actions
= f.submit 'Create Milestone', class: "btn-create btn"
= link_to "Cancel", group_milestones_path(@group), class: "btn btn-cancel"
-
-
-:javascript
- $(".datepicker").datepicker({
- dateFormat: "yy-mm-dd",
- onSelect: function(dateText, inst) { $("#milestone_due_date").val(dateText) }
- }).datepicker("setDate", $.datepicker.parseDate('yy-mm-dd', $('#milestone_due_date').val()));
diff --git a/app/views/notify/links/ci/builds/_build.html.haml b/app/views/notify/links/ci/builds/_build.html.haml
new file mode 100644
index 00000000000..38cd4e5e145
--- /dev/null
+++ b/app/views/notify/links/ci/builds/_build.html.haml
@@ -0,0 +1,2 @@
+%a{href: pipeline_build_url(pipeline, build), style: "color:#3777b0;text-decoration:none;"}
+ = build.name
diff --git a/app/views/notify/links/ci/builds/_build.text.erb b/app/views/notify/links/ci/builds/_build.text.erb
new file mode 100644
index 00000000000..f495a2e5486
--- /dev/null
+++ b/app/views/notify/links/ci/builds/_build.text.erb
@@ -0,0 +1 @@
+Build #<%= build.id %> ( <%= pipeline_build_url(pipeline, build) %> )
diff --git a/app/views/notify/links/generic_commit_statuses/_generic_commit_status.html.haml b/app/views/notify/links/generic_commit_statuses/_generic_commit_status.html.haml
new file mode 100644
index 00000000000..b6563b185b3
--- /dev/null
+++ b/app/views/notify/links/generic_commit_statuses/_generic_commit_status.html.haml
@@ -0,0 +1 @@
+= build.name
diff --git a/app/views/notify/links/generic_commit_statuses/_generic_commit_status.text.erb b/app/views/notify/links/generic_commit_statuses/_generic_commit_status.text.erb
new file mode 100644
index 00000000000..8e89c52a1f3
--- /dev/null
+++ b/app/views/notify/links/generic_commit_statuses/_generic_commit_status.text.erb
@@ -0,0 +1 @@
+Build #<%= build.id %>
diff --git a/app/views/notify/pipeline_failed_email.html.haml b/app/views/notify/pipeline_failed_email.html.haml
index 38c852f0a3a..001d9c48555 100644
--- a/app/views/notify/pipeline_failed_email.html.haml
+++ b/app/views/notify/pipeline_failed_email.html.haml
@@ -158,12 +158,14 @@
%td{style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;color:#8c8c8c;font-weight:500;font-size:15px;vertical-align:middle;"}
= build.stage
%td{align: "right", style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;padding:20px 0;color:#8c8c8c;font-weight:500;font-size:15px;"}
- %a{href: pipeline_build_url(@pipeline, build), style: "color:#3777b0;text-decoration:none;"}
- = build.name
+ = render "notify/links/#{build.to_partial_path}", pipeline: @pipeline, build: build
%tr.build-log
- %td{colspan: "2", style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;padding:0 0 15px;"}
- %pre{style: "font-family:Monaco,'Lucida Console','Courier New',Courier,monospace;background-color:#fafafa;border-radius:3px;overflow:hidden;white-space:pre-wrap;word-break:break-all;font-size:13px;line-height:1.4;padding:12px;color:#333333;margin:0;"}
- = build.trace_html(last_lines: 10).html_safe
+ - if build.has_trace?
+ %td{colspan: "2", style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;padding:0 0 15px;"}
+ %pre{style: "font-family:Monaco,'Lucida Console','Courier New',Courier,monospace;background-color:#fafafa;border-radius:3px;overflow:hidden;white-space:pre-wrap;word-break:break-all;font-size:13px;line-height:1.4;padding:12px;color:#333333;margin:0;"}
+ = build.trace_html(last_lines: 10).html_safe
+ - else
+ %td{colspan: "2"}
%tr.footer
%td{style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;padding:25px 0;font-size:13px;line-height:1.6;color:#5c5c5c;"}
%img{alt: "GitLab", height: "33", src: image_url('mailers/ci_pipeline_notif_v1/gitlab-logo-full-horizontal.gif'), style: "display:block;margin:0 auto 1em;", width: "90"}/
diff --git a/app/views/notify/pipeline_failed_email.text.erb b/app/views/notify/pipeline_failed_email.text.erb
index 8f8084b58e1..ab91c7ef350 100644
--- a/app/views/notify/pipeline_failed_email.text.erb
+++ b/app/views/notify/pipeline_failed_email.text.erb
@@ -19,10 +19,12 @@ Commit Author: <%= commit.author_name %>
Pipeline #<%= @pipeline.id %> ( <%= pipeline_url(@pipeline) %> ) had <%= failed.size %> failed <%= 'build'.pluralize(failed.size) %>.
<% failed.each do |build| -%>
-Build #<%= build.id %> ( <%= pipeline_build_url(@pipeline, build) %> )
+<%= render "notify/links/#{build.to_partial_path}", pipeline: @pipeline, build: build %>
Stage: <%= build.stage %>
Name: <%= build.name %>
+<% if build.has_trace? -%>
Trace: <%= build.trace_with_state(last_lines: 10)[:text] %>
+<% end -%>
<% end -%>
diff --git a/app/views/profiles/update_username.js.haml b/app/views/profiles/update_username.js.haml
index de1337a2a24..5307e0b48cb 100644
--- a/app/views/profiles/update_username.js.haml
+++ b/app/views/profiles/update_username.js.haml
@@ -2,5 +2,6 @@
:plain
new Flash("Username successfully changed", "notice")
- else
+ - error = @user.errors.full_messages.first
:plain
- new Flash("Username change failed - #{@user.errors.full_messages.first}", "alert")
+ new Flash("Username change failed - #{escape_javascript error.html_safe}", "alert")
diff --git a/app/views/projects/boards/components/_board_list.html.haml b/app/views/projects/boards/components/_board_list.html.haml
index d86e0ed8540..34fdb1f6a74 100644
--- a/app/views/projects/boards/components/_board_list.html.haml
+++ b/app/views/projects/boards/components/_board_list.html.haml
@@ -35,7 +35,7 @@
":issue" => "issue",
":issue-link-base" => "issueLinkBase",
":disabled" => "disabled",
- "key" => "id" }
+ ":key" => "issue.id" }
%li.board-list-count.text-center{ "v-if" => "showCount" }
= icon("spinner spin", "v-show" => "list.loadingMore" )
%span{ "v-if" => "list.issues.length === list.issuesSize" }
diff --git a/app/views/projects/boards/components/_card.html.haml b/app/views/projects/boards/components/_card.html.haml
index 72b31b8cdae..1f31496e73f 100644
--- a/app/views/projects/boards/components/_card.html.haml
+++ b/app/views/projects/boards/components/_card.html.haml
@@ -1,6 +1,8 @@
%li.card{ ":class" => '{ "user-can-drag": !disabled && issue.id, "is-disabled": disabled || !issue.id, "is-active": issueDetailVisible }',
":index" => "index",
+ ":data-issue-id" => "issue.id",
"@mousedown" => "mouseDown",
+ "@mousemove" => "mouseMove",
"@mouseup" => "showIssue($event)" }
%h4.card-title
= icon("eye-slash", class: "confidential-icon", "v-if" => "issue.confidential")
diff --git a/app/views/projects/builds/_sidebar.html.haml b/app/views/projects/builds/_sidebar.html.haml
index 28f519f11b2..f5562046953 100644
--- a/app/views/projects/builds/_sidebar.html.haml
+++ b/app/views/projects/builds/_sidebar.html.haml
@@ -128,7 +128,8 @@
.build-job{class: sidebar_build_class(build, @build), data: {stage: build.stage}}
= link_to namespace_project_build_path(@project.namespace, @project, build) do
= icon('arrow-right')
- = ci_icon_for_status(build.status)
+ %span{class: "ci-status-icon-#{build.status}"}
+ = ci_icon_for_status(build.status)
%span
- if build.name
= build.name
diff --git a/app/views/projects/builds/show.html.haml b/app/views/projects/builds/show.html.haml
index d8cbfd7173a..108674dbba6 100644
--- a/app/views/projects/builds/show.html.haml
+++ b/app/views/projects/builds/show.html.haml
@@ -40,13 +40,12 @@
This build is the most recent deployment to #{environment_link_for_build(@build.project, @build)}.
- else
This build is an out-of-date deployment to #{environment_link_for_build(@build.project, @build)}.
- - if environment.last_deployment
- View the most recent deployment #{deployment_link(environment.last_deployment)}.
+ View the most recent deployment #{deployment_link(environment.last_deployment)}.
- elsif @build.complete? && !@build.success?
The deployment of this build to #{environment_link_for_build(@build.project, @build)} did not succeed.
- else
This build is creating a deployment to #{environment_link_for_build(@build.project, @build)}
- - if environment.last_deployment
+ - if environment.try(:last_deployment)
and will overwrite the
= link_to 'latest deployment', deployment_link(environment.last_deployment)
diff --git a/app/views/projects/ci/builds/_build_pipeline.html.haml b/app/views/projects/ci/builds/_build_pipeline.html.haml
index 93dca81e6f9..423a1282eb2 100644
--- a/app/views/projects/ci/builds/_build_pipeline.html.haml
+++ b/app/views/projects/ci/builds/_build_pipeline.html.haml
@@ -5,9 +5,9 @@
.ci-status-text= subject.name
- elsif can?(current_user, :read_build, @project)
= link_to namespace_project_build_path(subject.project.namespace, subject.project, subject), data: { toggle: 'tooltip', title: "#{subject.name} - #{subject.status}", container: '.pipeline-graph', placement: 'bottom' } do
- %span.ci-status-icon
+ %span{class: "ci-status-icon ci-status-icon-#{subject.status}"}
= ci_icon_for_status(subject.status)
.ci-status-text= subject.name
- else
- %span.ci-status-icon
+ %span{class: "ci-status-icon ci-status-icon-#{subject.status}"}
= ci_icon_for_status(subject.status)
diff --git a/app/views/projects/ci/pipelines/_pipeline.html.haml b/app/views/projects/ci/pipelines/_pipeline.html.haml
index 2a2d24be736..4c7b14a04db 100644
--- a/app/views/projects/ci/pipelines/_pipeline.html.haml
+++ b/app/views/projects/ci/pipelines/_pipeline.html.haml
@@ -4,8 +4,9 @@
%tr.commit
%td.commit-link
- = link_to namespace_project_pipeline_path(pipeline.project.namespace, pipeline.project, pipeline.id) do
- = ci_status_with_icon(status)
+ = link_to namespace_project_pipeline_path(pipeline.project.namespace, pipeline.project, pipeline.id), class: "ci-status ci-#{status}" do
+ = ci_icon_for_status(status)
+ = ci_label_for_status(status)
%td
= link_to namespace_project_pipeline_path(pipeline.project.namespace, pipeline.project, pipeline.id) do
diff --git a/app/views/projects/commit/_commit_box.html.haml b/app/views/projects/commit/_commit_box.html.haml
index 503cbd13b5e..65151ac3a56 100644
--- a/app/views/projects/commit/_commit_box.html.haml
+++ b/app/views/projects/commit/_commit_box.html.haml
@@ -68,7 +68,7 @@
- if @commit.status
.well-segment.pipeline-info
- .icon-container
+ %div{class: "icon-container ci-status-icon-#{@commit.status}"}
= ci_icon_for_status(@commit.status)
Pipeline
= link_to "##{@commit.pipelines.last.id}", pipelines_namespace_project_commit_path(@project.namespace, @project, @commit.id), class: "monospace"
diff --git a/app/views/projects/commit/_pipeline_stage.html.haml b/app/views/projects/commit/_pipeline_stage.html.haml
index 289aa5178b1..f9a9c8707f5 100644
--- a/app/views/projects/commit/_pipeline_stage.html.haml
+++ b/app/views/projects/commit/_pipeline_stage.html.haml
@@ -1,4 +1,4 @@
-- status_groups = statuses.group_by(&:group_name)
+- status_groups = statuses.sort_by(&:name).group_by(&:group_name)
- status_groups.each do |group_name, grouped_statuses|
- if grouped_statuses.one?
- status = grouped_statuses.first
diff --git a/app/views/projects/commit/_pipeline_status_group.html.haml b/app/views/projects/commit/_pipeline_status_group.html.haml
index 18daa2ee693..2b26ad9d6fa 100644
--- a/app/views/projects/commit/_pipeline_status_group.html.haml
+++ b/app/views/projects/commit/_pipeline_status_group.html.haml
@@ -1,6 +1,6 @@
- group_status = CommitStatus.where(id: subject).status
%button.dropdown-menu-toggle.has-tooltip{ type: 'button', data: { toggle: 'dropdown', title: "#{name} - #{group_status}" } }
- %span.ci-status-icon
+ %span{class: "ci-status-icon ci-status-icon-#{group_status}"}
= ci_icon_for_status(group_status)
%span.ci-status-text
= name
diff --git a/app/views/projects/edit.html.haml b/app/views/projects/edit.html.haml
index 0aa8801c2d8..3a5af2723c6 100644
--- a/app/views/projects/edit.html.haml
+++ b/app/views/projects/edit.html.haml
@@ -92,14 +92,15 @@
= project_feature_access_select(:wiki_access_level)
- if Gitlab.config.lfs.enabled && current_user.admin?
- .checkbox
- = f.label :lfs_enabled do
- = f.check_box :lfs_enabled
- %strong LFS
- %br
- %span.descr
+ .row
+ .col-md-9
+ = f.label :lfs_enabled, 'LFS', class: 'label-light'
+ %span.help-block
Git Large File Storage
= link_to icon('question-circle'), help_page_path('workflow/lfs/manage_large_binaries_with_git_lfs')
+ .col-md-3
+ = f.select :lfs_enabled, [%w(Enabled true), %w(Disabled false)], {}, selected: @project.lfs_enabled?, class: 'pull-right form-control', data: { field: 'lfs_enabled' }
+
- if Gitlab.config.registry.enabled
.form-group.js-container-registry{ style: ("display: none;" if @project.project_feature.send(:repository_access_level) == 0) }
diff --git a/app/views/projects/generic_commit_statuses/_generic_commit_status_pipeline.html.haml b/app/views/projects/generic_commit_statuses/_generic_commit_status_pipeline.html.haml
index 1c457244a7a..7b82d913d29 100644
--- a/app/views/projects/generic_commit_statuses/_generic_commit_status_pipeline.html.haml
+++ b/app/views/projects/generic_commit_statuses/_generic_commit_status_pipeline.html.haml
@@ -1,10 +1,10 @@
%a{ data: { toggle: 'tooltip', title: "#{subject.name} - #{subject.status}", container: '.pipeline-graph', placement: 'bottom' } }
- if subject.target_url
= link_to subject.target_url do
- %span.ci-status-icon
+ %span{class: "ci-status-icon ci-status-icon-#{subject.status}"}
= ci_icon_for_status(subject.status)
%span.ci-status-text= subject.name
- else
- %span.ci-status-icon
+ %span{class: "ci-status-icon ci-status-icon-#{subject.status}"}
= ci_icon_for_status(subject.status)
%span.ci-status-text= subject.name
diff --git a/app/views/projects/merge_requests/widget/_heading.html.haml b/app/views/projects/merge_requests/widget/_heading.html.haml
index a82c846baa7..18c72ed875c 100644
--- a/app/views/projects/merge_requests/widget/_heading.html.haml
+++ b/app/views/projects/merge_requests/widget/_heading.html.haml
@@ -1,7 +1,7 @@
- if @pipeline
.mr-widget-heading
- %w[success success_with_warnings skipped canceled failed running pending].each do |status|
- .ci_widget{ class: "ci-#{status}", style: ("display:none" unless @pipeline.status == status) }
+ .ci_widget{ class: "ci-status-icon-#{status}", style: ("display:none" unless @pipeline.status == status) }
= ci_icon_for_status(status)
%span
Pipeline
@@ -12,7 +12,6 @@
= succeed "." do
= link_to @pipeline.short_sha, namespace_project_commit_path(@merge_request.source_project.namespace, @merge_request.source_project, @pipeline.sha), class: "monospace"
%span.ci-coverage
- = link_to "View details", pipelines_namespace_project_merge_request_path(@project.namespace, @project, @merge_request), class: "js-show-tab", data: {action: 'pipelines'}
- elsif @merge_request.has_ci?
- # Compatibility with old CI integrations (ex jenkins) when you request status from CI server via AJAX
@@ -29,8 +28,6 @@
= succeed "." do
= link_to commit.short_id, namespace_project_commit_path(@merge_request.source_project.namespace, @merge_request.source_project, commit), class: "monospace"
%span.ci-coverage
- - if details_path = ci_build_details_path(@merge_request)
- = link_to "View details", details_path, :"data-no-turbolink" => "data-no-turbolink"
.ci_widget
= icon("spinner spin")
diff --git a/app/views/projects/merge_requests/widget/open/_merge_when_build_succeeds.html.haml b/app/views/projects/merge_requests/widget/open/_merge_when_build_succeeds.html.haml
index 2b6b5e05e86..1aeb12e4661 100644
--- a/app/views/projects/merge_requests/widget/open/_merge_when_build_succeeds.html.haml
+++ b/app/views/projects/merge_requests/widget/open/_merge_when_build_succeeds.html.haml
@@ -21,5 +21,5 @@
Remove Source Branch When Merged
- if user_can_cancel_automatic_merge
- = link_to cancel_merge_when_build_succeeds_namespace_project_merge_request_path(@merge_request.target_project.namespace, @merge_request.target_project, @merge_request), remote: true, method: :post, class: "btn btn-grouped btn-warning btn-sm" do
+ = link_to cancel_merge_when_build_succeeds_namespace_project_merge_request_path(@merge_request.target_project.namespace, @merge_request.target_project, @merge_request), remote: true, method: :post, class: "btn btn-grouped btn-sm" do
Cancel Automatic Merge
diff --git a/app/views/projects/milestones/_form.html.haml b/app/views/projects/milestones/_form.html.haml
index cbf1ba04170..513710e8e66 100644
--- a/app/views/projects/milestones/_form.html.haml
+++ b/app/views/projects/milestones/_form.html.haml
@@ -14,12 +14,7 @@
= render 'projects/notes/hints'
.clearfix
.error-alert
- .col-md-6
- .form-group
- = f.label :due_date, "Due Date", class: "control-label"
- .col-sm-10
- = f.text_field :due_date, class: "datepicker form-control", placeholder: "Select due date"
- %a.inline.prepend-top-5.js-clear-due-date{ href: "#" } Clear due date
+ = render "shared/milestones/form_dates", f: f
.form-actions
- if @milestone.new_record?
diff --git a/app/views/projects/milestones/show.html.haml b/app/views/projects/milestones/show.html.haml
index e01aca3dda6..c3a6096aa54 100644
--- a/app/views/projects/milestones/show.html.haml
+++ b/app/views/projects/milestones/show.html.haml
@@ -10,15 +10,17 @@
Closed
- elsif @milestone.expired?
Past due
+ - elsif @milestone.upcoming?
+ Upcoming
- else
Open
.header-text-content
%span.identifier
Milestone ##{@milestone.iid}
- - if @milestone.expires_at
+ - if @milestone.due_date || @milestone.start_date
%span.creator
&middot;
- = @milestone.expires_at
+ = milestone_date_range(@milestone)
.milestone-buttons
- if can?(current_user, :admin_milestone, @project)
- if @milestone.active?
diff --git a/app/views/projects/notes/_note.html.haml b/app/views/projects/notes/_note.html.haml
index 89ae64554c0..ba8895438c5 100644
--- a/app/views/projects/notes/_note.html.haml
+++ b/app/views/projects/notes/_note.html.haml
@@ -16,7 +16,7 @@
commented
- if note.system
%span{class: 'system-note-message'}
- = h(note.note_html.downcase.html_safe)
+ = note.redacted_note_html
%a{ href: "##{dom_id(note)}" }
= time_ago_with_tooltip(note.created_at, placement: 'bottom', html_class: 'note-created-ago')
- unless note.system?
diff --git a/app/views/projects/pipelines/_info.html.haml b/app/views/projects/pipelines/_info.html.haml
index a0de125d765..095bd254d6b 100644
--- a/app/views/projects/pipelines/_info.html.haml
+++ b/app/views/projects/pipelines/_info.html.haml
@@ -1,8 +1,6 @@
.page-content-header
.header-main-content
- = link_to namespace_project_pipeline_path(@project.namespace, @project, @pipeline), class: "ci-status ci-#{@pipeline.status}" do
- = ci_icon_for_status(@pipeline.status)
- = ci_label_for_status(@pipeline.status)
+ = ci_status_with_icon(@pipeline.status)
%strong Pipeline ##{@commit.pipelines.last.id}
triggered #{time_ago_with_tooltip(@commit.authored_date)} by
= author_avatar(@commit, size: 24)
@@ -25,7 +23,7 @@
.info-well
- if @commit.status
.well-segment.pipeline-info
- .icon-container
+ %div{class: "icon-container ci-status-icon-#{@commit.status}"}
= ci_icon_for_status(@commit.status)
= pluralize @pipeline.statuses.count(:id), "build"
- if @pipeline.ref
diff --git a/app/views/projects/services/_form.html.haml b/app/views/projects/services/_form.html.haml
index b41edeb2c7e..db51c4f8a4e 100644
--- a/app/views/projects/services/_form.html.haml
+++ b/app/views/projects/services/_form.html.haml
@@ -7,14 +7,15 @@
%p= @service.description
.col-lg-9
= form_for(@service, as: :service, url: namespace_project_service_path(@project.namespace, @project, @service.to_param), method: :put, html: { class: 'form-horizontal' }) do |form|
- = render 'shared/service_settings', form: form
+ = render 'shared/service_settings', form: form, subject: @service
- = form.submit 'Save changes', class: 'btn btn-save'
- &nbsp;
- - if @service.valid? && @service.activated?
- - unless @service.can_test?
- - disabled_class = 'disabled'
- - disabled_title = @service.disabled_title
+ .footer-block.row-content-block
+ = form.submit 'Save changes', class: 'btn btn-save'
+ &nbsp;
+ - if @service.valid? && @service.activated?
+ - unless @service.can_test?
+ - disabled_class = 'disabled'
+ - disabled_title = @service.disabled_title
- = link_to 'Test settings', test_namespace_project_service_path(@project.namespace, @project, @service), class: "btn #{disabled_class}", title: disabled_title
- = link_to "Cancel", namespace_project_services_path(@project.namespace, @project), class: "btn btn-cancel"
+ = link_to 'Test settings', test_namespace_project_service_path(@project.namespace, @project, @service), class: "btn #{disabled_class}", title: disabled_title
+ = link_to "Cancel", namespace_project_services_path(@project.namespace, @project), class: "btn btn-cancel"
diff --git a/app/views/projects/services/mattermost_slash_commands/_help.html.haml b/app/views/projects/services/mattermost_slash_commands/_help.html.haml
new file mode 100644
index 00000000000..a676c0290a0
--- /dev/null
+++ b/app/views/projects/services/mattermost_slash_commands/_help.html.haml
@@ -0,0 +1,100 @@
+- pretty_path_with_namespace = "#{@project ? @project.namespace.name : 'namespace'} / #{@project ? @project.name : 'name'}"
+- run_actions_text = "Perform common operations on this project: #{pretty_path_with_namespace}"
+
+.well
+ This service allows GitLab users to perform common operations on this
+ project by entering slash commands in Mattermost.
+ %br
+ See list of available commands in Mattermost after setting up this service,
+ by entering
+ %code /&lt;command_trigger_word&gt; help
+ %br
+ %br
+ To setup this service:
+ %ul.list-unstyled
+ %li
+ 1.
+ = link_to 'Enable custom slash commands', 'https://docs.mattermost.com/developer/slash-commands.html#enabling-custom-commands'
+ on your Mattermost installation
+ %li
+ 2.
+ = link_to 'Add a slash command', 'https://docs.mattermost.com/developer/slash-commands.html#set-up-a-custom-command'
+ in Mattermost with these options:
+
+ %hr
+
+ .help-form
+ .form-group
+ = label_tag :display_name, 'Display name', class: 'col-sm-2 col-xs-12 control-label'
+ .col-sm-10.col-xs-12.input-group
+ = text_field_tag :display_name, "GitLab / #{pretty_path_with_namespace}", class: 'form-control input-sm', readonly: 'readonly'
+ .input-group-btn
+ = clipboard_button(clipboard_target: '#display_name')
+
+ .form-group
+ = label_tag :description, 'Description', class: 'col-sm-2 col-xs-12 control-label'
+ .col-sm-10.col-xs-12.input-group
+ = text_field_tag :description, run_actions_text, class: 'form-control input-sm', readonly: 'readonly'
+ .input-group-btn
+ = clipboard_button(clipboard_target: '#description')
+
+ .form-group
+ = label_tag nil, 'Command trigger word', class: 'col-sm-2 col-xs-12 control-label'
+ .col-sm-10.col-xs-12.text-block
+ %p Fill in the word that works best for your team.
+ %p
+ Suggestions:
+ %code= 'gitlab'
+ %code= @project.path # Path contains no spaces, but dashes
+ %code= @project.path_with_namespace
+
+ .form-group
+ = label_tag :request_url, 'Request URL', class: 'col-sm-2 col-xs-12 control-label'
+ .col-sm-10.col-xs-12.input-group
+ = text_field_tag :request_url, service_trigger_url(subject), class: 'form-control input-sm', readonly: 'readonly'
+ .input-group-btn
+ = clipboard_button(clipboard_target: '#request_url')
+
+ .form-group
+ = label_tag nil, 'Request method', class: 'col-sm-2 col-xs-12 control-label'
+ .col-sm-10.col-xs-12.text-block POST
+
+ .form-group
+ = label_tag :response_username, 'Response username', class: 'col-sm-2 col-xs-12 control-label'
+ .col-sm-10.col-xs-12.input-group
+ = text_field_tag :response_username, 'GitLab', class: 'form-control input-sm', readonly: 'readonly'
+ .input-group-btn
+ = clipboard_button(clipboard_target: '#response_username')
+
+ .form-group
+ = label_tag :response_icon, 'Response icon', class: 'col-sm-2 col-xs-12 control-label'
+ .col-sm-10.col-xs-12.input-group
+ = text_field_tag :response_icon, asset_url('gitlab_logo.png'), class: 'form-control input-sm', readonly: 'readonly'
+ .input-group-btn
+ = clipboard_button(clipboard_target: '#response_icon')
+
+ .form-group
+ = label_tag nil, 'Autocomplete', class: 'col-sm-2 col-xs-12 control-label'
+ .col-sm-10.col-xs-12.text-block Yes
+
+ .form-group
+ = label_tag :autocomplete_hint, 'Autocomplete hint', class: 'col-sm-2 col-xs-12 control-label'
+ .col-sm-10.col-xs-12.input-group
+ = text_field_tag :autocomplete_hint, '[help]', class: 'form-control input-sm', readonly: 'readonly'
+ .input-group-btn
+ = clipboard_button(clipboard_target: '#autocomplete_hint')
+
+ .form-group
+ = label_tag :autocomplete_description, 'Autocomplete description', class: 'col-sm-2 col-xs-12 control-label'
+ .col-sm-10.col-xs-12.input-group
+ = text_field_tag :autocomplete_description, run_actions_text, class: 'form-control input-sm', readonly: 'readonly'
+ .input-group-btn
+ = clipboard_button(clipboard_target: '#autocomplete_description')
+
+ %hr
+
+ %ul.list-unstyled
+ %li
+ 3. After adding the slash command, paste the
+ %strong token
+ into the field below
diff --git a/app/views/projects/tags/new.html.haml b/app/views/projects/tags/new.html.haml
index 3a097750d6e..c06a413eb2f 100644
--- a/app/views/projects/tags/new.html.haml
+++ b/app/views/projects/tags/new.html.haml
@@ -23,7 +23,7 @@
= label_tag :message, nil, class: 'control-label'
.col-sm-10
= text_area_tag :message, nil, required: false, tabindex: 3, class: 'form-control', rows: 5
- .help-block Optionally, enter a message to create an annotated tag.
+ .help-block Optionally, add a message to the tag.
%hr
.form-group
= label_tag :release_description, 'Release notes', class: 'control-label'
diff --git a/app/views/projects/wikis/_nav.html.haml b/app/views/projects/wikis/_nav.html.haml
index 09c4411d67e..afdef70e1cf 100644
--- a/app/views/projects/wikis/_nav.html.haml
+++ b/app/views/projects/wikis/_nav.html.haml
@@ -7,7 +7,7 @@
= link_to 'Home', namespace_project_wiki_path(@project.namespace, @project, :home)
= nav_link(path: 'wikis#pages') do
- = link_to 'Pages', namespace_project_wiki_pages_path(@project.namespace, @project)
+ = link_to 'Pages', namespace_project_wikis_pages_path(@project.namespace, @project)
= nav_link(path: 'wikis#git_access') do
= link_to namespace_project_wikis_git_access_path(@project.namespace, @project) do
diff --git a/app/views/shared/_milestone_expired.html.haml b/app/views/shared/_milestone_expired.html.haml
index b8eef15fbec..5e9007aaaac 100644
--- a/app/views/shared/_milestone_expired.html.haml
+++ b/app/views/shared/_milestone_expired.html.haml
@@ -1,5 +1,7 @@
- if milestone.expired? and not milestone.closed?
%span.cred (Expired)
-- if milestone.expires_at
+- if milestone.upcoming?
+ %span.clgray (Upcoming)
+- if milestone.due_date || milestone.start_date
%span
- = milestone.expires_at
+ = milestone_date_range(milestone)
diff --git a/app/views/shared/_service_settings.html.haml b/app/views/shared/_service_settings.html.haml
index 601ef51737a..9c5053dace5 100644
--- a/app/views/shared/_service_settings.html.haml
+++ b/app/views/shared/_service_settings.html.haml
@@ -1,47 +1,50 @@
= form_errors(@service)
-- if @service.help.present?
+- if lookup_context.template_exists?('help', "projects/services/#{@service.to_param}", true)
+ = render "projects/services/#{@service.to_param}/help", subject: subject
+- elsif @service.help.present?
.well
= preserve do
= markdown @service.help
-.form-group
- = form.label :active, "Active", class: "control-label"
- .col-sm-10
- = form.check_box :active
-
-- if @service.supported_events.present?
+.service-settings
.form-group
- = form.label :url, "Trigger", class: 'control-label'
-
+ = form.label :active, "Active", class: "control-label"
.col-sm-10
- - @service.supported_events.each do |event|
- %div
- = form.check_box service_event_field_name(event), class: 'pull-left'
- .prepend-left-20
- = form.label service_event_field_name(event), class: 'list-label' do
- %strong
- = event.humanize
-
- - field = @service.event_field(event)
-
- - if field
- %p
- = form.text_field field[:name], class: "form-control", placeholder: field[:placeholder]
-
- %p.light
- = service_event_description(event)
-
-- @service.global_fields.each do |field|
- - type = field[:type]
-
- - if type == 'fieldset'
- - fields = field[:fields]
- - legend = field[:legend]
-
- %fieldset
- %legend= legend
- - fields.each do |subfield|
- = render 'shared/field', form: form, field: subfield
- - else
- = render 'shared/field', form: form, field: field
+ = form.check_box :active
+
+ - if @service.supported_events.present?
+ .form-group
+ = form.label :url, "Trigger", class: 'control-label'
+
+ .col-sm-10
+ - @service.supported_events.each do |event|
+ %div
+ = form.check_box service_event_field_name(event), class: 'pull-left'
+ .prepend-left-20
+ = form.label service_event_field_name(event), class: 'list-label' do
+ %strong
+ = event.humanize
+
+ - field = @service.event_field(event)
+
+ - if field
+ %p
+ = form.text_field field[:name], class: "form-control", placeholder: field[:placeholder]
+
+ %p.light
+ = service_event_description(event)
+
+ - @service.global_fields.each do |field|
+ - type = field[:type]
+
+ - if type == 'fieldset'
+ - fields = field[:fields]
+ - legend = field[:legend]
+
+ %fieldset
+ %legend= legend
+ - fields.each do |subfield|
+ = render 'shared/field', form: form, field: subfield
+ - else
+ = render 'shared/field', form: form, field: field
diff --git a/app/views/shared/icons/_icon_status_canceled.svg b/app/views/shared/icons/_icon_status_canceled.svg
index 1b2d0891244..41a210a8ed9 100644
--- a/app/views/shared/icons/_icon_status_canceled.svg
+++ b/app/views/shared/icons/_icon_status_canceled.svg
@@ -1,6 +1 @@
-<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" class="ci-status-icon-canceled" viewBox="0 0 14 14">
- <g fill="#5C5C5C" fill-rule="evenodd">
- <path d="M12.5,7 C12.5,3.96243388 10.0375661,1.5 7,1.5 C3.96243388,1.5 1.5,3.96243388 1.5,7 C1.5,10.0375661 3.96243388,12.5 7,12.5 C10.0375661,12.5 12.5,10.0375661 12.5,7 Z M0,7 C0,3.13400675 3.13400675,0 7,0 C10.8659932,0 14,3.13400675 14,7 C14,10.8659932 10.8659932,14 7,14 C3.13400675,14 0,10.8659932 0,7 Z"/>
- <rect width="8" height="2" x="3" y="6" transform="rotate(45 7 7)" rx=".5"/>
- </g>
-</svg>
+<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 14 14"><g fill-rule="evenodd"><path d="M12.5,7 C12.5,3.96243388 10.0375661,1.5 7,1.5 C3.96243388,1.5 1.5,3.96243388 1.5,7 C1.5,10.0375661 3.96243388,12.5 7,12.5 C10.0375661,12.5 12.5,10.0375661 12.5,7 Z M0,7 C0,3.13400675 3.13400675,0 7,0 C10.8659932,0 14,3.13400675 14,7 C14,10.8659932 10.8659932,14 7,14 C3.13400675,14 0,10.8659932 0,7 Z"/><rect width="8" height="2" x="3" y="6" transform="rotate(45 7 7)" rx=".5"/></g></svg>
diff --git a/app/views/shared/icons/_icon_status_created.svg b/app/views/shared/icons/_icon_status_created.svg
index dca5d289767..1f5c3b51b03 100644
--- a/app/views/shared/icons/_icon_status_created.svg
+++ b/app/views/shared/icons/_icon_status_created.svg
@@ -1 +1 @@
-<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" class="ci-status-icon-created" viewBox="0 0 14 14" enable-background="new 0 0 14 14"><path d="M12.5,7 C12.5,4 10,1.5 7,1.5 C4,1.5 1.5,4 1.5,7 C1.5,10 4,12.5 7,12.5 C10,12.5 12.5,10 12.5,7 L12.5,7 Z M0,7 C0,3.1 3.1,0 7,0 C10.9,0 14,3.1 14,7 C14,10.9 10.9,14 7,14 C3.1,14 0,10.9 0,7 L0,7 Z" /><circle cx="7" cy="7" r="3.25"/></svg>
+<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 14 14" enable-background="new 0 0 14 14"><path d="M12.5,7 C12.5,4 10,1.5 7,1.5 C4,1.5 1.5,4 1.5,7 C1.5,10 4,12.5 7,12.5 C10,12.5 12.5,10 12.5,7 L12.5,7 Z M0,7 C0,3.1 3.1,0 7,0 C10.9,0 14,3.1 14,7 C14,10.9 10.9,14 7,14 C3.1,14 0,10.9 0,7 L0,7 Z" /><circle cx="7" cy="7" r="3.25"/></svg>
diff --git a/app/views/shared/icons/_icon_status_failed.svg b/app/views/shared/icons/_icon_status_failed.svg
index e56e0887416..af267b8938a 100644
--- a/app/views/shared/icons/_icon_status_failed.svg
+++ b/app/views/shared/icons/_icon_status_failed.svg
@@ -1,6 +1 @@
-<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 14 14">
- <g fill="#D22852" fill-rule="evenodd">
- <path d="M12.5,7 C12.5,3.96243388 10.0375661,1.5 7,1.5 C3.96243388,1.5 1.5,3.96243388 1.5,7 C1.5,10.0375661 3.96243388,12.5 7,12.5 C10.0375661,12.5 12.5,10.0375661 12.5,7 Z M0,7 C0,3.13400675 3.13400675,0 7,0 C10.8659932,0 14,3.13400675 14,7 C14,10.8659932 10.8659932,14 7,14 C3.13400675,14 0,10.8659932 0,7 Z"/>
- <path d="M7.72916667,6.27083333 L7.72916667,4.28939247 C7.72916667,4.12531853 7.59703895,4 7.43405116,4 L6.56594884,4 C6.40541585,4 6.27083333,4.12956542 6.27083333,4.28939247 L6.27083333,6.27083333 L4.28939247,6.27083333 C4.12531853,6.27083333 4,6.40296105 4,6.56594884 L4,7.43405116 C4,7.59458415 4.12956542,7.72916667 4.28939247,7.72916667 L6.27083333,7.72916667 L6.27083333,9.71060753 C6.27083333,9.87468147 6.40296105,10 6.56594884,10 L7.43405116,10 C7.59458415,10 7.72916667,9.87043458 7.72916667,9.71060753 L7.72916667,7.72916667 L9.71060753,7.72916667 C9.87468147,7.72916667 10,7.59703895 10,7.43405116 L10,6.56594884 C10,6.40541585 9.87043458,6.27083333 9.71060753,6.27083333 L7.72916667,6.27083333 Z" transform="rotate(-45 7 7)"/>
- </g>
-</svg>
+<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 14 14"><g fill-rule="evenodd"><path d="M12.5,7 C12.5,3.96243388 10.0375661,1.5 7,1.5 C3.96243388,1.5 1.5,3.96243388 1.5,7 C1.5,10.0375661 3.96243388,12.5 7,12.5 C10.0375661,12.5 12.5,10.0375661 12.5,7 Z M0,7 C0,3.13400675 3.13400675,0 7,0 C10.8659932,0 14,3.13400675 14,7 C14,10.8659932 10.8659932,14 7,14 C3.13400675,14 0,10.8659932 0,7 Z"/><path d="M7.72916667,6.27083333 L7.72916667,4.28939247 C7.72916667,4.12531853 7.59703895,4 7.43405116,4 L6.56594884,4 C6.40541585,4 6.27083333,4.12956542 6.27083333,4.28939247 L6.27083333,6.27083333 L4.28939247,6.27083333 C4.12531853,6.27083333 4,6.40296105 4,6.56594884 L4,7.43405116 C4,7.59458415 4.12956542,7.72916667 4.28939247,7.72916667 L6.27083333,7.72916667 L6.27083333,9.71060753 C6.27083333,9.87468147 6.40296105,10 6.56594884,10 L7.43405116,10 C7.59458415,10 7.72916667,9.87043458 7.72916667,9.71060753 L7.72916667,7.72916667 L9.71060753,7.72916667 C9.87468147,7.72916667 10,7.59703895 10,7.43405116 L10,6.56594884 C10,6.40541585 9.87043458,6.27083333 9.71060753,6.27083333 L7.72916667,6.27083333 Z" transform="rotate(-45 7 7)"/></g></svg>
diff --git a/app/views/shared/icons/_icon_status_pending.svg b/app/views/shared/icons/_icon_status_pending.svg
index 117f0367161..516231d1b44 100644
--- a/app/views/shared/icons/_icon_status_pending.svg
+++ b/app/views/shared/icons/_icon_status_pending.svg
@@ -1,6 +1 @@
-<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 14 14">
- <g fill="#E75E40" fill-rule="evenodd">
- <path d="M12.5,7 C12.5,3.96243388 10.0375661,1.5 7,1.5 C3.96243388,1.5 1.5,3.96243388 1.5,7 C1.5,10.0375661 3.96243388,12.5 7,12.5 C10.0375661,12.5 12.5,10.0375661 12.5,7 Z M0,7 C0,3.13400675 3.13400675,0 7,0 C10.8659932,0 14,3.13400675 14,7 C14,10.8659932 10.8659932,14 7,14 C3.13400675,14 0,10.8659932 0,7 Z"/>
- <path d="M4.69999981,5.30065012 C4.69999981,5.13460564 4.83842754,5 5.00354719,5 L5.89645243,5 C6.06409702,5 6.19999981,5.13308716 6.19999981,5.30065012 L6.19999981,8.69934988 C6.19999981,8.86539436 6.06157207,9 5.89645243,9 L5.00354719,9 C4.8359026,9 4.69999981,8.86691284 4.69999981,8.69934988 L4.69999981,5.30065012 Z M7.69999981,5.30065012 C7.69999981,5.13460564 7.83842754,5 8.00354719,5 L8.89645243,5 C9.06409702,5 9.19999981,5.13308716 9.19999981,5.30065012 L9.19999981,8.69934988 C9.19999981,8.86539436 9.06157207,9 8.89645243,9 L8.00354719,9 C7.8359026,9 7.69999981,8.86691284 7.69999981,8.69934988 L7.69999981,5.30065012 Z"/>
- </g>
-</svg>
+<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 14 14"><g fill-rule="evenodd"><path d="M12.5,7 C12.5,3.96243388 10.0375661,1.5 7,1.5 C3.96243388,1.5 1.5,3.96243388 1.5,7 C1.5,10.0375661 3.96243388,12.5 7,12.5 C10.0375661,12.5 12.5,10.0375661 12.5,7 Z M0,7 C0,3.13400675 3.13400675,0 7,0 C10.8659932,0 14,3.13400675 14,7 C14,10.8659932 10.8659932,14 7,14 C3.13400675,14 0,10.8659932 0,7 Z"/><path d="M4.69999981,5.30065012 C4.69999981,5.13460564 4.83842754,5 5.00354719,5 L5.89645243,5 C6.06409702,5 6.19999981,5.13308716 6.19999981,5.30065012 L6.19999981,8.69934988 C6.19999981,8.86539436 6.06157207,9 5.89645243,9 L5.00354719,9 C4.8359026,9 4.69999981,8.86691284 4.69999981,8.69934988 L4.69999981,5.30065012 Z M7.69999981,5.30065012 C7.69999981,5.13460564 7.83842754,5 8.00354719,5 L8.89645243,5 C9.06409702,5 9.19999981,5.13308716 9.19999981,5.30065012 L9.19999981,8.69934988 C9.19999981,8.86539436 9.06157207,9 8.89645243,9 L8.00354719,9 C7.8359026,9 7.69999981,8.86691284 7.69999981,8.69934988 L7.69999981,5.30065012 Z"/></g></svg>
diff --git a/app/views/shared/icons/_icon_status_running.svg b/app/views/shared/icons/_icon_status_running.svg
index 920d7952eb5..d2618bce200 100644
--- a/app/views/shared/icons/_icon_status_running.svg
+++ b/app/views/shared/icons/_icon_status_running.svg
@@ -1,6 +1 @@
-<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 14 14">
- <g fill="#2D9FD8" fill-rule="evenodd">
- <path d="M12.5,7 C12.5,3.96243388 10.0375661,1.5 7,1.5 C3.96243388,1.5 1.5,3.96243388 1.5,7 C1.5,10.0375661 3.96243388,12.5 7,12.5 C10.0375661,12.5 12.5,10.0375661 12.5,7 Z M0,7 C0,3.13400675 3.13400675,0 7,0 C10.8659932,0 14,3.13400675 14,7 C14,10.8659932 10.8659932,14 7,14 C3.13400675,14 0,10.8659932 0,7 Z"/>
- <path d="M7,3 C9.209139,3 11,4.790861 11,7 C11,9.209139 9.209139,11 7,11 C5.65802855,11 4.47040669,10.3391508 3.74481446,9.32513253 L7,7 L7,3 L7,3 Z"/>
- </g>
-</svg>
+<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 14 14"><g fill-rule="evenodd"><path d="M12.5,7 C12.5,3.96243388 10.0375661,1.5 7,1.5 C3.96243388,1.5 1.5,3.96243388 1.5,7 C1.5,10.0375661 3.96243388,12.5 7,12.5 C10.0375661,12.5 12.5,10.0375661 12.5,7 Z M0,7 C0,3.13400675 3.13400675,0 7,0 C10.8659932,0 14,3.13400675 14,7 C14,10.8659932 10.8659932,14 7,14 C3.13400675,14 0,10.8659932 0,7 Z"/><path d="M7,3 C9.209139,3 11,4.790861 11,7 C11,9.209139 9.209139,11 7,11 C5.65802855,11 4.47040669,10.3391508 3.74481446,9.32513253 L7,7 L7,3 L7,3 Z"/></g></svg>
diff --git a/app/views/shared/icons/_icon_status_skipped.svg b/app/views/shared/icons/_icon_status_skipped.svg
index e0a2d4282f0..701f33bcbea 100644
--- a/app/views/shared/icons/_icon_status_skipped.svg
+++ b/app/views/shared/icons/_icon_status_skipped.svg
@@ -1 +1 @@
-<svg width="14" height="14" class="ci-status-icon-skipped" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><g fill="#5C5C5C" fill-rule="evenodd"><path d="M10 17.857c4.286 0 7.857-3.571 7.857-7.857S14.286 2.143 10 2.143 2.143 5.714 2.143 10 5.714 17.857 10 17.857M10 0c5.571 0 10 4.429 10 10s-4.429 10-10 10S0 15.571 0 10 4.429 0 10 0"/><path d="M10.986 11l-1.293 1.293a1 1 0 0 0 1.414 1.414l2.644-2.644a1.505 1.505 0 0 0 0-2.126l-2.644-2.644a1 1 0 0 0-1.414 1.414L10.986 9H6.4a1 1 0 0 0 0 2h4.586z"/></g></svg>
+<svg width="14" height="14" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><g fill-rule="evenodd"><path d="M10 17.857c4.286 0 7.857-3.571 7.857-7.857S14.286 2.143 10 2.143 2.143 5.714 2.143 10 5.714 17.857 10 17.857M10 0c5.571 0 10 4.429 10 10s-4.429 10-10 10S0 15.571 0 10 4.429 0 10 0"/><path d="M10.986 11l-1.293 1.293a1 1 0 0 0 1.414 1.414l2.644-2.644a1.505 1.505 0 0 0 0-2.126l-2.644-2.644a1 1 0 0 0-1.414 1.414L10.986 9H6.4a1 1 0 0 0 0 2h4.586z"/></g></svg>
diff --git a/app/views/shared/icons/_icon_status_success.svg b/app/views/shared/icons/_icon_status_success.svg
index 67b378b3571..b7c21ba6971 100644
--- a/app/views/shared/icons/_icon_status_success.svg
+++ b/app/views/shared/icons/_icon_status_success.svg
@@ -1,6 +1 @@
-<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 14 14">
- <g fill="#31AF64" fill-rule="evenodd">
- <path d="M12.5,7 C12.5,3.96243388 10.0375661,1.5 7,1.5 C3.96243388,1.5 1.5,3.96243388 1.5,7 C1.5,10.0375661 3.96243388,12.5 7,12.5 C10.0375661,12.5 12.5,10.0375661 12.5,7 Z M0,7 C0,3.13400675 3.13400675,0 7,0 C10.8659932,0 14,3.13400675 14,7 C14,10.8659932 10.8659932,14 7,14 C3.13400675,14 0,10.8659932 0,7 Z"/>
- <path d="M7.29166667,7.875 L5.54840803,7.875 C5.38293028,7.875 5.25,8.00712771 5.25,8.17011551 L5.25,9.03821782 C5.25,9.19875081 5.38360183,9.33333333 5.54840803,9.33333333 L8.24853534,9.33333333 C8.52035522,9.33333333 8.75,9.11228506 8.75,8.83960819 L8.75,8.46475969 L8.75,4.07392947 C8.75,3.92144267 8.61787229,3.79166667 8.45488449,3.79166667 L7.58678218,3.79166667 C7.42624919,3.79166667 7.29166667,3.91804003 7.29166667,4.07392947 L7.29166667,7.875 Z" transform="rotate(45 7 6.563)"/>
- </g>
-</svg>
+<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 14 14"><g fill-rule="evenodd"><path d="M12.5,7 C12.5,3.96243388 10.0375661,1.5 7,1.5 C3.96243388,1.5 1.5,3.96243388 1.5,7 C1.5,10.0375661 3.96243388,12.5 7,12.5 C10.0375661,12.5 12.5,10.0375661 12.5,7 Z M0,7 C0,3.13400675 3.13400675,0 7,0 C10.8659932,0 14,3.13400675 14,7 C14,10.8659932 10.8659932,14 7,14 C3.13400675,14 0,10.8659932 0,7 Z"/><path d="M7.29166667,7.875 L5.54840803,7.875 C5.38293028,7.875 5.25,8.00712771 5.25,8.17011551 L5.25,9.03821782 C5.25,9.19875081 5.38360183,9.33333333 5.54840803,9.33333333 L8.24853534,9.33333333 C8.52035522,9.33333333 8.75,9.11228506 8.75,8.83960819 L8.75,8.46475969 L8.75,4.07392947 C8.75,3.92144267 8.61787229,3.79166667 8.45488449,3.79166667 L7.58678218,3.79166667 C7.42624919,3.79166667 7.29166667,3.91804003 7.29166667,4.07392947 L7.29166667,7.875 Z" transform="rotate(45 7 6.563)"/></g></svg>
diff --git a/app/views/shared/icons/_icon_status_warning.svg b/app/views/shared/icons/_icon_status_warning.svg
index d0ad4bd65b1..9191e0050a6 100644
--- a/app/views/shared/icons/_icon_status_warning.svg
+++ b/app/views/shared/icons/_icon_status_warning.svg
@@ -1,6 +1 @@
-<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 14 14">
- <g fill="#FF8A24" fill-rule="evenodd">
- <path d="M12.5,7 C12.5,3.96243388 10.0375661,1.5 7,1.5 C3.96243388,1.5 1.5,3.96243388 1.5,7 C1.5,10.0375661 3.96243388,12.5 7,12.5 C10.0375661,12.5 12.5,10.0375661 12.5,7 Z M0,7 C0,3.13400675 3.13400675,0 7,0 C10.8659932,0 14,3.13400675 14,7 C14,10.8659932 10.8659932,14 7,14 C3.13400675,14 0,10.8659932 0,7 Z"/>
- <path d="M6,3.49769878 C6,3.22282734 6.21403503,3 6.50468445,3 L7.49531555,3 C7.77404508,3 8,3.21484375 8,3.49769878 L8,7.50230122 C8,7.77717266 7.78596497,8 7.49531555,8 L6.50468445,8 C6.22595492,8 6,7.78515625 6,7.50230122 L6,3.49769878 Z M6,9.50468445 C6,9.22595492 6.21403503,9 6.50468445,9 L7.49531555,9 C7.77404508,9 8,9.21403503 8,9.50468445 L8,10.4953156 C8,10.7740451 7.78596497,11 7.49531555,11 L6.50468445,11 C6.22595492,11 6,10.785965 6,10.4953156 L6,9.50468445 Z"/>
- </g>
-</svg>
+<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 14 14"><g fill-rule="evenodd"><path d="M12.5,7 C12.5,3.96243388 10.0375661,1.5 7,1.5 C3.96243388,1.5 1.5,3.96243388 1.5,7 C1.5,10.0375661 3.96243388,12.5 7,12.5 C10.0375661,12.5 12.5,10.0375661 12.5,7 Z M0,7 C0,3.13400675 3.13400675,0 7,0 C10.8659932,0 14,3.13400675 14,7 C14,10.8659932 10.8659932,14 7,14 C3.13400675,14 0,10.8659932 0,7 Z"/><path d="M6,3.49769878 C6,3.22282734 6.21403503,3 6.50468445,3 L7.49531555,3 C7.77404508,3 8,3.21484375 8,3.49769878 L8,7.50230122 C8,7.77717266 7.78596497,8 7.49531555,8 L6.50468445,8 C6.22595492,8 6,7.78515625 6,7.50230122 L6,3.49769878 Z M6,9.50468445 C6,9.22595492 6.21403503,9 6.50468445,9 L7.49531555,9 C7.77404508,9 8,9.21403503 8,9.50468445 L8,10.4953156 C8,10.7740451 7.78596497,11 7.49531555,11 L6.50468445,11 C6.22595492,11 6,10.785965 6,10.4953156 L6,9.50468445 Z"/></g></svg>
diff --git a/app/views/shared/issuable/_filter.html.haml b/app/views/shared/issuable/_filter.html.haml
index ed93857e6d4..b7e5e928993 100644
--- a/app/views/shared/issuable/_filter.html.haml
+++ b/app/views/shared/issuable/_filter.html.haml
@@ -40,9 +40,9 @@
- if can?(current_user, :admin_list, @project)
.dropdown.pull-right
%button.btn.btn-create.js-new-board-list{ type: "button", data: { toggle: "dropdown", labels: labels_filter_path, namespace_path: @project.try(:namespace).try(:path), project_path: @project.try(:path) } }
- Create new list
+ Add list
.dropdown-menu.dropdown-menu-paging.dropdown-menu-align-right.dropdown-menu-issues-board-new.dropdown-menu-selectable
- = render partial: "shared/issuable/label_page_default", locals: { show_footer: true, show_create: true, show_boards_content: true, title: "Create a new list" }
+ = render partial: "shared/issuable/label_page_default", locals: { show_footer: true, show_create: true, show_boards_content: true, title: "Add list" }
- if can?(current_user, :admin_label, @project)
= render partial: "shared/issuable/label_page_create"
= dropdown_loading
diff --git a/app/views/shared/issuable/_label_page_default.html.haml b/app/views/shared/issuable/_label_page_default.html.haml
index c0dc63be2bf..a8f01026ca5 100644
--- a/app/views/shared/issuable/_label_page_default.html.haml
+++ b/app/views/shared/issuable/_label_page_default.html.haml
@@ -1,17 +1,15 @@
- title = local_assigns.fetch(:title, 'Assign labels')
- show_create = local_assigns.fetch(:show_create, true)
- show_footer = local_assigns.fetch(:show_footer, true)
-- filter_placeholder = local_assigns.fetch(:filter_placeholder, 'Search labels')
+- filter_placeholder = local_assigns.fetch(:filter_placeholder, 'Search')
- show_boards_content = local_assigns.fetch(:show_boards_content, false)
.dropdown-page-one
= dropdown_title(title)
- if show_boards_content
.issue-board-dropdown-content
%p
- Each label that exists in your issue tracker can have its own dedicated
- list. Select a label below to add a list to your Board and it will
- automatically be populated with issues that have that label. To create
- a list for a label that doesn't exist yet, simply create the label below.
+ Create lists from the labels you use in your project. Issues with that
+ label will automatically be added to the list.
= dropdown_filter(filter_placeholder)
= dropdown_content
- if @project && show_footer
diff --git a/app/views/shared/milestones/_form_dates.html.haml b/app/views/shared/milestones/_form_dates.html.haml
new file mode 100644
index 00000000000..748b10a1298
--- /dev/null
+++ b/app/views/shared/milestones/_form_dates.html.haml
@@ -0,0 +1,15 @@
+.col-md-6
+ .form-group
+ = f.label :start_date, "Start Date", class: "control-label"
+ .col-sm-10
+ = f.text_field :start_date, class: "datepicker form-control", placeholder: "Select start date"
+ %a.inline.prepend-top-5.js-clear-start-date{ href: "#" } Clear start date
+.col-md-6
+ .form-group
+ = f.label :due_date, "Due Date", class: "control-label"
+ .col-sm-10
+ = f.text_field :due_date, class: "datepicker form-control", placeholder: "Select due date"
+ %a.inline.prepend-top-5.js-clear-due-date{ href: "#" } Clear due date
+
+:javascript
+ new gl.DueDateSelectors();
diff --git a/app/views/shared/milestones/_top.html.haml b/app/views/shared/milestones/_top.html.haml
index 548215243db..497446c1ef3 100644
--- a/app/views/shared/milestones/_top.html.haml
+++ b/app/views/shared/milestones/_top.html.haml
@@ -12,10 +12,10 @@
Open
%span.identifier
Milestone #{milestone.title}
- - if milestone.expires_at
+ - if milestone.due_date || milestone.start_date
%span.creator
&middot;
- = milestone.expires_at
+ = milestone_date_range(milestone)
- if group
.pull-right
- if can?(current_user, :admin_milestones, group)
diff --git a/app/workers/new_note_worker.rb b/app/workers/new_note_worker.rb
index 66574d0fd01..926162b8c53 100644
--- a/app/workers/new_note_worker.rb
+++ b/app/workers/new_note_worker.rb
@@ -2,7 +2,9 @@ class NewNoteWorker
include Sidekiq::Worker
include DedicatedSidekiqQueue
- def perform(note_id)
+ # Keep extra parameter to preserve backwards compatibility with
+ # old `NewNoteWorker` jobs (can remove later)
+ def perform(note_id, _params = {})
if note = Note.find_by(id: note_id)
NotificationService.new.new_note(note)
Notes::PostProcessService.new(note).execute
diff --git a/changelogs/unreleased/18136-ui-for-restricting-global-visibility-levels-is-unclear.yml b/changelogs/unreleased/18136-ui-for-restricting-global-visibility-levels-is-unclear.yml
deleted file mode 100644
index b8b8810ecfa..00000000000
--- a/changelogs/unreleased/18136-ui-for-restricting-global-visibility-levels-is-unclear.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Changed restricted visibility admin buttons to checkboxes
-merge_request: 7463
-author:
diff --git a/changelogs/unreleased/19981-admin-links-new-group-default-visibility.yml b/changelogs/unreleased/19981-admin-links-new-group-default-visibility.yml
deleted file mode 100644
index 18fb8a6ad45..00000000000
--- a/changelogs/unreleased/19981-admin-links-new-group-default-visibility.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Make New Group form respect default visibility application setting
-merge_request: 7454
-author: Jacopo Beschi @jacopo-beschi
diff --git a/changelogs/unreleased/20968-add-setting-to-check-unresolved-discussion.yml b/changelogs/unreleased/20968-add-setting-to-check-unresolved-discussion.yml
deleted file mode 100644
index 8f03746ff80..00000000000
--- a/changelogs/unreleased/20968-add-setting-to-check-unresolved-discussion.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Add setting to only allow merge requests to be merged when all discussions are resolved
-merge_request: 7125
-author: Rodolfo Arruda
diff --git a/changelogs/unreleased/21076-deleted-merged-branches.yml b/changelogs/unreleased/21076-deleted-merged-branches.yml
deleted file mode 100644
index b7fa7f14384..00000000000
--- a/changelogs/unreleased/21076-deleted-merged-branches.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Add button to delete all merged branches
-merge_request: 6449
-author: Toon Claes
diff --git a/changelogs/unreleased/21664-incorrect-workhorse-version-number-displayed.yml b/changelogs/unreleased/21664-incorrect-workhorse-version-number-displayed.yml
deleted file mode 100644
index 95d8fef1099..00000000000
--- a/changelogs/unreleased/21664-incorrect-workhorse-version-number-displayed.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Use the Gitlab Workhorse HTTP header in the admin dashboard
-merge_request:
-author: Chris Wright
diff --git a/changelogs/unreleased/21992-disable-access-requests-by-default.yml b/changelogs/unreleased/21992-disable-access-requests-by-default.yml
deleted file mode 100644
index ddcb2169407..00000000000
--- a/changelogs/unreleased/21992-disable-access-requests-by-default.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Disable "Request Access" functionality by default for new projects and groups
-merge_request: 7425
-author:
diff --git a/changelogs/unreleased/22307-pipeline-link-in-builds-view.yml b/changelogs/unreleased/22307-pipeline-link-in-builds-view.yml
deleted file mode 100644
index 3af746cd92a..00000000000
--- a/changelogs/unreleased/22307-pipeline-link-in-builds-view.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Add link to build pipeline within individual build pages
-merge_request: 7082
-author:
diff --git a/changelogs/unreleased/22539-display-folders.yml b/changelogs/unreleased/22539-display-folders.yml
deleted file mode 100644
index d46cdedf7a7..00000000000
--- a/changelogs/unreleased/22539-display-folders.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Display "folders" for environments
-merge_request: 7015
-author:
diff --git a/changelogs/unreleased/22588-todos-filter-shows-all-users.yml b/changelogs/unreleased/22588-todos-filter-shows-all-users.yml
deleted file mode 100644
index 1da72142880..00000000000
--- a/changelogs/unreleased/22588-todos-filter-shows-all-users.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: 'Fix: Todos Filter Shows All Users'
-merge_request:
-author:
diff --git a/changelogs/unreleased/22699-group-permssion-background-migration.yml b/changelogs/unreleased/22699-group-permssion-background-migration.yml
deleted file mode 100644
index e8c221b6c42..00000000000
--- a/changelogs/unreleased/22699-group-permssion-background-migration.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Fix project records with invalid visibility_level values
-merge_request: 7391
-author:
diff --git a/changelogs/unreleased/22790-mention-autocomplete-avatar.yml b/changelogs/unreleased/22790-mention-autocomplete-avatar.yml
deleted file mode 100644
index 53068ca5607..00000000000
--- a/changelogs/unreleased/22790-mention-autocomplete-avatar.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Show avatars in mention dropdown
-merge_request: 6865
-author:
diff --git a/changelogs/unreleased/22947-fix_issues_atom_feed_url.yml b/changelogs/unreleased/22947-fix_issues_atom_feed_url.yml
deleted file mode 100644
index 2312afdb3d7..00000000000
--- a/changelogs/unreleased/22947-fix_issues_atom_feed_url.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Issues atom feed url reflect filters on dashboard
-merge_request: 7114
-author: Lucas Deschamps
diff --git a/changelogs/unreleased/23036-replace-git-blame-spinach-tests-with-rspec-feature-tests.yml b/changelogs/unreleased/23036-replace-git-blame-spinach-tests-with-rspec-feature-tests.yml
deleted file mode 100644
index 7b54d3df56d..00000000000
--- a/changelogs/unreleased/23036-replace-git-blame-spinach-tests-with-rspec-feature-tests.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Rewrite git blame spinach feature tests to rspec feature tests
-merge_request: 7197
-author: Lisanne Fellinger
diff --git a/changelogs/unreleased/23117-search-for-a-filename-in-a-project.yml b/changelogs/unreleased/23117-search-for-a-filename-in-a-project.yml
deleted file mode 100644
index 156f8d779ca..00000000000
--- a/changelogs/unreleased/23117-search-for-a-filename-in-a-project.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Search for a filename in a project
-merge_request:
-author:
diff --git a/changelogs/unreleased/23223-group-deletion-race-condition.yml b/changelogs/unreleased/23223-group-deletion-race-condition.yml
deleted file mode 100644
index 6f22e85fb4b..00000000000
--- a/changelogs/unreleased/23223-group-deletion-race-condition.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Fix race condition during group deletion and remove stale records present due to this bug
-merge_request: 7528
-author: Timothy Andrew
diff --git a/changelogs/unreleased/23449-cycle-analytics-2-frontend.yml b/changelogs/unreleased/23449-cycle-analytics-2-frontend.yml
deleted file mode 100644
index 5140c09be8a..00000000000
--- a/changelogs/unreleased/23449-cycle-analytics-2-frontend.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Show events per stage on Cycle Analytics page
-merge_request: 23449
-author:
diff --git a/changelogs/unreleased/23532-define-common-helper-for-describe-pagination-params-in-api.yml b/changelogs/unreleased/23532-define-common-helper-for-describe-pagination-params-in-api.yml
new file mode 100644
index 00000000000..bb9e96d7581
--- /dev/null
+++ b/changelogs/unreleased/23532-define-common-helper-for-describe-pagination-params-in-api.yml
@@ -0,0 +1,4 @@
+---
+title: Define common helper for describe pagination params in api
+merge_request: 7646
+author: Semyon Pupkov
diff --git a/changelogs/unreleased/23584-triggering-builds-from-webhooks.yml b/changelogs/unreleased/23584-triggering-builds-from-webhooks.yml
deleted file mode 100644
index 59e0d851366..00000000000
--- a/changelogs/unreleased/23584-triggering-builds-from-webhooks.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Make it possible to trigger builds from webhooks
-merge_request: 7022
-author: Dmitry Poray
diff --git a/changelogs/unreleased/23637-title-bar-pipelines.yml b/changelogs/unreleased/23637-title-bar-pipelines.yml
deleted file mode 100644
index 3d4cf88c54c..00000000000
--- a/changelogs/unreleased/23637-title-bar-pipelines.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Redesign pipelines page
-merge_request:
-author:
diff --git a/changelogs/unreleased/23731-add-param-to-user-api.yml b/changelogs/unreleased/23731-add-param-to-user-api.yml
deleted file mode 100644
index e31029ffb27..00000000000
--- a/changelogs/unreleased/23731-add-param-to-user-api.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Add query param to filter users by external & blocked type
-merge_request: 7109
-author: Yatish Mehta
diff --git a/changelogs/unreleased/23961-can-t-share-project-with-groups.yml b/changelogs/unreleased/23961-can-t-share-project-with-groups.yml
deleted file mode 100644
index b3bfcbda4b7..00000000000
--- a/changelogs/unreleased/23961-can-t-share-project-with-groups.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Only skip group when it's actually a group in the "Share with group" select
-merge_request: 7262
-author:
diff --git a/changelogs/unreleased/23990-project-show-error-when-empty-repo.yml b/changelogs/unreleased/23990-project-show-error-when-empty-repo.yml
deleted file mode 100644
index 8d4593d4df7..00000000000
--- a/changelogs/unreleased/23990-project-show-error-when-empty-repo.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: fixes 500 error on project show when user is not logged in and project is still empty
-merge_request: 7376
-author:
diff --git a/changelogs/unreleased/24010-change-anchor-link-to-mr-diff.yml b/changelogs/unreleased/24010-change-anchor-link-to-mr-diff.yml
deleted file mode 100644
index 33ce18b2141..00000000000
--- a/changelogs/unreleased/24010-change-anchor-link-to-mr-diff.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Unify anchor link format for MR diff files
-merge_request: 7298
-author: YarNayar
diff --git a/changelogs/unreleased/24010-double-event-trigger.yml b/changelogs/unreleased/24010-double-event-trigger.yml
deleted file mode 100644
index 3c2f20d391f..00000000000
--- a/changelogs/unreleased/24010-double-event-trigger.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Fix double event and ajax request call on MR page
-merge_request: 7298
-author: YarNayar
diff --git a/changelogs/unreleased/24048-dropdown-issue-with-devider.yml b/changelogs/unreleased/24048-dropdown-issue-with-devider.yml
deleted file mode 100644
index b889da61957..00000000000
--- a/changelogs/unreleased/24048-dropdown-issue-with-devider.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: "[Fix] Extra divider issue in dropdown"
-merge_request: 7398
-author:
diff --git a/changelogs/unreleased/24056-guest-sees-some-project-details-and-gets-404.yml b/changelogs/unreleased/24056-guest-sees-some-project-details-and-gets-404.yml
deleted file mode 100644
index 8ca0c5beab3..00000000000
--- a/changelogs/unreleased/24056-guest-sees-some-project-details-and-gets-404.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: 'Fix: Guest sees some repository details and gets 404'
-merge_request:
-author:
diff --git a/changelogs/unreleased/24059-round-robin-repository-storage.yml b/changelogs/unreleased/24059-round-robin-repository-storage.yml
deleted file mode 100644
index 109536114ff..00000000000
--- a/changelogs/unreleased/24059-round-robin-repository-storage.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Introduce round-robin project creation to spread load over multiple shards
-merge_request: 7266
-author:
diff --git a/changelogs/unreleased/24070-project-margins.yml b/changelogs/unreleased/24070-project-margins.yml
deleted file mode 100644
index cbc2b0269f0..00000000000
--- a/changelogs/unreleased/24070-project-margins.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Fix Margins look weird in Project page with pinned sidebar in project stats bar
-merge_request: 7580
-author:
diff --git a/changelogs/unreleased/24072-improve-importing-of-github-pull-requests.yml b/changelogs/unreleased/24072-improve-importing-of-github-pull-requests.yml
deleted file mode 100644
index 2c265960d67..00000000000
--- a/changelogs/unreleased/24072-improve-importing-of-github-pull-requests.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Reduce API calls needed when importing issues and pull requests from GitHub
-merge_request: 7241
-author: Andrew Smith (EspadaV8)
diff --git a/changelogs/unreleased/24102-cannot-unselect-remove-source-branch-when-editing-merge-request.yml b/changelogs/unreleased/24102-cannot-unselect-remove-source-branch-when-editing-merge-request.yml
deleted file mode 100644
index 50d018170f1..00000000000
--- a/changelogs/unreleased/24102-cannot-unselect-remove-source-branch-when-editing-merge-request.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Ensure merge request's "remove branch" accessors return booleans
-merge_request: 7267
-author:
diff --git a/changelogs/unreleased/24107-slack-comment-link.yml b/changelogs/unreleased/24107-slack-comment-link.yml
deleted file mode 100644
index 9c17d6fd825..00000000000
--- a/changelogs/unreleased/24107-slack-comment-link.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Change slack notification comment link
-merge_request: 7498
-author: Herbert Kagumba
diff --git a/changelogs/unreleased/24161-non-intuitive-buttons-for-import-sources-in-administrator-settings-enable-disable.yml b/changelogs/unreleased/24161-non-intuitive-buttons-for-import-sources-in-administrator-settings-enable-disable.yml
new file mode 100644
index 00000000000..1404748e83e
--- /dev/null
+++ b/changelogs/unreleased/24161-non-intuitive-buttons-for-import-sources-in-administrator-settings-enable-disable.yml
@@ -0,0 +1,4 @@
+---
+title: Changed import sources buttons to checkboxes
+merge_request: 7598
+author: Luke "Jared" Bennett
diff --git a/changelogs/unreleased/24255-search-fix.yml b/changelogs/unreleased/24255-search-fix.yml
deleted file mode 100644
index c0afade9bc8..00000000000
--- a/changelogs/unreleased/24255-search-fix.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Fix broken commits search
-merge_request:
-author:
diff --git a/changelogs/unreleased/24266-Afraid-to-press-the-Orange-button-on-Merge-request-screen.yml b/changelogs/unreleased/24266-Afraid-to-press-the-Orange-button-on-Merge-request-screen.yml
new file mode 100644
index 00000000000..28ca20c7dcc
--- /dev/null
+++ b/changelogs/unreleased/24266-Afraid-to-press-the-Orange-button-on-Merge-request-screen.yml
@@ -0,0 +1,4 @@
+---
+title: If Build running change accept merge request when build succeeds button from orange to blue
+merge_request: 7577
+author:
diff --git a/changelogs/unreleased/24276-usernames-with-dots.yml b/changelogs/unreleased/24276-usernames-with-dots.yml
deleted file mode 100644
index 9aeeb33e9ef..00000000000
--- a/changelogs/unreleased/24276-usernames-with-dots.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Allow registering users whose username contains dots
-merge_request: 7500
-author: Timothy Andrew
diff --git a/changelogs/unreleased/24279-issue-merge-request-sidebar-todo-button-style-improvement.yml b/changelogs/unreleased/24279-issue-merge-request-sidebar-todo-button-style-improvement.yml
deleted file mode 100644
index 72e7110d1b8..00000000000
--- a/changelogs/unreleased/24279-issue-merge-request-sidebar-todo-button-style-improvement.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Removed gray button styling from todo buttons in sidebars
-merge_request: 7387
-author:
diff --git a/changelogs/unreleased/24369-remove-additional-padding.yml b/changelogs/unreleased/24369-remove-additional-padding.yml
deleted file mode 100644
index a6a0b248412..00000000000
--- a/changelogs/unreleased/24369-remove-additional-padding.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Remove additional padding on right-aligned items in MR widget.
-merge_request: 7411
-author: Didem Acet
diff --git a/changelogs/unreleased/24413-show-unconfirmed-email-status.yml b/changelogs/unreleased/24413-show-unconfirmed-email-status.yml
new file mode 100644
index 00000000000..972eaed95e0
--- /dev/null
+++ b/changelogs/unreleased/24413-show-unconfirmed-email-status.yml
@@ -0,0 +1,4 @@
+---
+title: Shows unconfirmed email status in profile
+merge_request: 7611
+author:
diff --git a/changelogs/unreleased/24492-promise-polyfill.yml b/changelogs/unreleased/24492-promise-polyfill.yml
deleted file mode 100644
index d2fddfd83c6..00000000000
--- a/changelogs/unreleased/24492-promise-polyfill.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Adds es6-promise Polyfill
-merge_request: 7482
-author:
diff --git a/changelogs/unreleased/24496-fix-internal-api-project-lookup.yml b/changelogs/unreleased/24496-fix-internal-api-project-lookup.yml
deleted file mode 100644
index a95295c00f3..00000000000
--- a/changelogs/unreleased/24496-fix-internal-api-project-lookup.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Fix POST /internal/allowed to cope with gitlab-shell v4.0.0 project paths
-merge_request: 7480
-author:
diff --git a/changelogs/unreleased/24499-fix-activity-autoload-on-large-viewports.yml b/changelogs/unreleased/24499-fix-activity-autoload-on-large-viewports.yml
deleted file mode 100644
index 53dcc2a82f1..00000000000
--- a/changelogs/unreleased/24499-fix-activity-autoload-on-large-viewports.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Fix activity page endless scroll on large viewports
-merge_request: 7608
-author:
diff --git a/changelogs/unreleased/24576_cant_stop_impersonating.yml b/changelogs/unreleased/24576_cant_stop_impersonating.yml
new file mode 100644
index 00000000000..8fa6eeca756
--- /dev/null
+++ b/changelogs/unreleased/24576_cant_stop_impersonating.yml
@@ -0,0 +1,4 @@
+---
+title: Allow admins to stop impersonating users without e-mail addresses
+merge_request: 7550
+author: Oren Kanner
diff --git a/changelogs/unreleased/24616-mr-shows-the-build-for-this-merge-request-failed-although-builds-still-running.yml b/changelogs/unreleased/24616-mr-shows-the-build-for-this-merge-request-failed-although-builds-still-running.yml
deleted file mode 100644
index 3773459550f..00000000000
--- a/changelogs/unreleased/24616-mr-shows-the-build-for-this-merge-request-failed-although-builds-still-running.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Fix a wrong "The build for this merge request failed" message
-merge_request: 7579
-author:
diff --git a/changelogs/unreleased/24627-fix-bad-mr-error-message.yml b/changelogs/unreleased/24627-fix-bad-mr-error-message.yml
deleted file mode 100644
index d6a9818b2ce..00000000000
--- a/changelogs/unreleased/24627-fix-bad-mr-error-message.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Fix regression causing bad error message to appear on Merge Request form
-merge_request: 7599
-author: Alex Sanford
diff --git a/changelogs/unreleased/24739-collapsed-build-list-sorting.yml b/changelogs/unreleased/24739-collapsed-build-list-sorting.yml
new file mode 100644
index 00000000000..036e606318f
--- /dev/null
+++ b/changelogs/unreleased/24739-collapsed-build-list-sorting.yml
@@ -0,0 +1,4 @@
+---
+title: Sort builds by name within pipeline graph
+merge_request: 7681
+author:
diff --git a/changelogs/unreleased/24779-last-deployment-call-on-nil-environment-fix.yml b/changelogs/unreleased/24779-last-deployment-call-on-nil-environment-fix.yml
new file mode 100644
index 00000000000..5e7580fb8f2
--- /dev/null
+++ b/changelogs/unreleased/24779-last-deployment-call-on-nil-environment-fix.yml
@@ -0,0 +1,4 @@
+---
+title: fixes last_deployment call environment is nil
+merge_request: 7671
+author:
diff --git a/changelogs/unreleased/24804-wrong-render-index-should-be-render-show-in-projects-pipelinessettingscontroller-update.yml b/changelogs/unreleased/24804-wrong-render-index-should-be-render-show-in-projects-pipelinessettingscontroller-update.yml
new file mode 100644
index 00000000000..92dbbe3d164
--- /dev/null
+++ b/changelogs/unreleased/24804-wrong-render-index-should-be-render-show-in-projects-pipelinessettingscontroller-update.yml
@@ -0,0 +1,4 @@
+---
+title: Fix wrong template rendered when CI/CD settings aren't update successfully
+merge_request: 7665
+author:
diff --git a/changelogs/unreleased/24863-mrs-without-discussions-are-mergeable.yml b/changelogs/unreleased/24863-mrs-without-discussions-are-mergeable.yml
new file mode 100644
index 00000000000..9bdb9411135
--- /dev/null
+++ b/changelogs/unreleased/24863-mrs-without-discussions-are-mergeable.yml
@@ -0,0 +1,4 @@
+---
+title: Correctly determine mergeability of MR with no discussions
+merge_request:
+author:
diff --git a/changelogs/unreleased/Last-minute-CI-Style-tweaks-for-8-14.yml b/changelogs/unreleased/Last-minute-CI-Style-tweaks-for-8-14.yml
new file mode 100644
index 00000000000..7d49c639a43
--- /dev/null
+++ b/changelogs/unreleased/Last-minute-CI-Style-tweaks-for-8-14.yml
@@ -0,0 +1,4 @@
+---
+title: Last minute CI Style tweaks for 8.14
+merge_request: 7643
+author:
diff --git a/changelogs/unreleased/adam-build-missing-services-when-necessary.yml b/changelogs/unreleased/adam-build-missing-services-when-necessary.yml
deleted file mode 100644
index 8b157e31e99..00000000000
--- a/changelogs/unreleased/adam-build-missing-services-when-necessary.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Defer saving project services to the database if there are no user changes
-merge_request: 6958
-author:
diff --git a/changelogs/unreleased/adam-fix-collapsed-diff-symlink-file-conversion.yml b/changelogs/unreleased/adam-fix-collapsed-diff-symlink-file-conversion.yml
deleted file mode 100644
index c83558f33d1..00000000000
--- a/changelogs/unreleased/adam-fix-collapsed-diff-symlink-file-conversion.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Fix expanding a collapsed diff when converting a symlink to a regular file
-merge_request: 6953
-author:
diff --git a/changelogs/unreleased/add-api-label-id.yml b/changelogs/unreleased/add-api-label-id.yml
deleted file mode 100644
index 3af4f5e677d..00000000000
--- a/changelogs/unreleased/add-api-label-id.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Expose label IDs in API
-merge_request: 7275
-author: Rares Sfirlogea
diff --git a/changelogs/unreleased/add-chat-names.yml b/changelogs/unreleased/add-chat-names.yml
deleted file mode 100644
index 6a1e05783a3..00000000000
--- a/changelogs/unreleased/add-chat-names.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Allow to connect Chat account with GitLab
-merge_request: 7450
-author:
diff --git a/changelogs/unreleased/add-project-import-data-index.yml b/changelogs/unreleased/add-project-import-data-index.yml
deleted file mode 100644
index f5e4005f544..00000000000
--- a/changelogs/unreleased/add-project-import-data-index.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Add an index for project_id in project_import_data to improve performance
-merge_request:
-author:
diff --git a/changelogs/unreleased/always-show-download-button.yml b/changelogs/unreleased/always-show-download-button.yml
deleted file mode 100644
index 3a625834d01..00000000000
--- a/changelogs/unreleased/always-show-download-button.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Project download buttons always show
-merge_request: 7405
-author: Philip Karpiak
diff --git a/changelogs/unreleased/api-delete-group-share.yml b/changelogs/unreleased/api-delete-group-share.yml
new file mode 100644
index 00000000000..26cfb35bba3
--- /dev/null
+++ b/changelogs/unreleased/api-delete-group-share.yml
@@ -0,0 +1,4 @@
+---
+title: 'API: Add ability to unshare a project from a group'
+merge_request: 7662
+author: Robert Schilling
diff --git a/changelogs/unreleased/api-label-priorities.yml b/changelogs/unreleased/api-label-priorities.yml
deleted file mode 100644
index d703f8d32f3..00000000000
--- a/changelogs/unreleased/api-label-priorities.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: "API: Ability to retrieve version information"
-merge_request: 7286
-author: Robert Schilling
diff --git a/changelogs/unreleased/api-return-400-if-post-systemhook-fails.yml b/changelogs/unreleased/api-return-400-if-post-systemhook-fails.yml
deleted file mode 100644
index d132d7e79c3..00000000000
--- a/changelogs/unreleased/api-return-400-if-post-systemhook-fails.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Return 400 when creating a system hook fails
-merge_request: 7350
-author: Robert Schilling
diff --git a/changelogs/unreleased/assignee-dropdown-autocomplete.yml b/changelogs/unreleased/assignee-dropdown-autocomplete.yml
deleted file mode 100644
index 9d046b726b7..00000000000
--- a/changelogs/unreleased/assignee-dropdown-autocomplete.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Assignee dropdown now searches author of issue or merge request
-merge_request:
-author:
diff --git a/changelogs/unreleased/boards-issue-sorting.yml b/changelogs/unreleased/boards-issue-sorting.yml
new file mode 100644
index 00000000000..fb7dc2f9190
--- /dev/null
+++ b/changelogs/unreleased/boards-issue-sorting.yml
@@ -0,0 +1,4 @@
+---
+title: Fixed issue boards issue sorting when dragging issue into list
+merge_request:
+author:
diff --git a/changelogs/unreleased/broken-link-frontend-dev-guide.yml b/changelogs/unreleased/broken-link-frontend-dev-guide.yml
deleted file mode 100644
index d7b6f4a7701..00000000000
--- a/changelogs/unreleased/broken-link-frontend-dev-guide.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Fix broken link to observatory cli on Frontend Dev Guide
-merge_request:
-author: Sam Rose
diff --git a/changelogs/unreleased/bugfix-html-only-mail.yml b/changelogs/unreleased/bugfix-html-only-mail.yml
deleted file mode 100644
index ea0d4e7396f..00000000000
--- a/changelogs/unreleased/bugfix-html-only-mail.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Add support for reply-by-email when the email only contains HTML
-merge_request: 7397
-author:
diff --git a/changelogs/unreleased/changelog-update.yml b/changelogs/unreleased/changelog-update.yml
deleted file mode 100644
index 24fa34f4121..00000000000
--- a/changelogs/unreleased/changelog-update.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Add environment info to builds page
-merge_request:
-author:
diff --git a/changelogs/unreleased/chatops-deploy-command.yml b/changelogs/unreleased/chatops-deploy-command.yml
deleted file mode 100644
index 1e5a3e8df15..00000000000
--- a/changelogs/unreleased/chatops-deploy-command.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Add deployment command to ChatOps
-merge_request: 7619
-author:
diff --git a/changelogs/unreleased/create-pipeline-endpoint.yml b/changelogs/unreleased/create-pipeline-endpoint.yml
deleted file mode 100644
index c7638b7b7aa..00000000000
--- a/changelogs/unreleased/create-pipeline-endpoint.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Add api endpoint for creating a pipeline
-merge_request: 7209
-author: Ido Leibovich
diff --git a/changelogs/unreleased/dev-issue-24554.yml b/changelogs/unreleased/dev-issue-24554.yml
new file mode 100644
index 00000000000..0bb362b9325
--- /dev/null
+++ b/changelogs/unreleased/dev-issue-24554.yml
@@ -0,0 +1,4 @@
+---
+title: Edit help text to clarify annotated tag creation.
+merge_request:
+author: Liz Lam
diff --git a/changelogs/unreleased/disable-calendar-deselection.yml b/changelogs/unreleased/disable-calendar-deselection.yml
new file mode 100644
index 00000000000..060797bba34
--- /dev/null
+++ b/changelogs/unreleased/disable-calendar-deselection.yml
@@ -0,0 +1,4 @@
+---
+title: Fix deselecting calendar days on contribution graph
+merge_request: 6453
+author: ClemMakesApps
diff --git a/changelogs/unreleased/dz-allow-nested-group-routing.yml b/changelogs/unreleased/dz-allow-nested-group-routing.yml
new file mode 100644
index 00000000000..9d8e6e17914
--- /dev/null
+++ b/changelogs/unreleased/dz-allow-nested-group-routing.yml
@@ -0,0 +1,4 @@
+---
+title: Add nested groups support to the routing
+merge_request: 7459
+author:
diff --git a/changelogs/unreleased/dz-fix-500-group-git.yml b/changelogs/unreleased/dz-fix-500-group-git.yml
deleted file mode 100644
index 38e80ad8bde..00000000000
--- a/changelogs/unreleased/dz-fix-500-group-git.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Fix 500 error when group name ends with git
-merge_request: 7630
-author:
diff --git a/changelogs/unreleased/dz-fix-group-name-dot.yml b/changelogs/unreleased/dz-fix-group-name-dot.yml
deleted file mode 100644
index 439cb229e6b..00000000000
--- a/changelogs/unreleased/dz-fix-group-name-dot.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Fix 404 on some group pages when name contains dot
-merge_request: 7614
-author:
diff --git a/changelogs/unreleased/emoji-btn-disabled.yml b/changelogs/unreleased/emoji-btn-disabled.yml
new file mode 100644
index 00000000000..a18b553d513
--- /dev/null
+++ b/changelogs/unreleased/emoji-btn-disabled.yml
@@ -0,0 +1,4 @@
+---
+title: Disabled emoji buttons when user is not logged in
+merge_request:
+author:
diff --git a/changelogs/unreleased/faster_project_search.yml b/changelogs/unreleased/faster_project_search.yml
deleted file mode 100644
index e29a9f34ed4..00000000000
--- a/changelogs/unreleased/faster_project_search.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Faster search inside Project
-merge_request:
-author:
diff --git a/changelogs/unreleased/feature-api_owned_resource.yml b/changelogs/unreleased/feature-api_owned_resource.yml
deleted file mode 100644
index 9c270e4ecf4..00000000000
--- a/changelogs/unreleased/feature-api_owned_resource.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Add api endpoint `/groups/owned`
-merge_request: 7103
-author: Borja Aparicio
diff --git a/changelogs/unreleased/feature-cycle-analytics-events.yml b/changelogs/unreleased/feature-cycle-analytics-events.yml
deleted file mode 100644
index e1211a3c774..00000000000
--- a/changelogs/unreleased/feature-cycle-analytics-events.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Add events per stage to cycle analytics
-merge_request:
-author:
diff --git a/changelogs/unreleased/feature-environment-teardown-when-branch-deleted.yml b/changelogs/unreleased/feature-environment-teardown-when-branch-deleted.yml
deleted file mode 100644
index 0441b68e45f..00000000000
--- a/changelogs/unreleased/feature-environment-teardown-when-branch-deleted.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Auto-close environment when branch is deleted
-merge_request: 7355
-author:
diff --git a/changelogs/unreleased/feature-precalculate-authorized-projects.yml b/changelogs/unreleased/feature-precalculate-authorized-projects.yml
deleted file mode 100644
index 6e48b710fec..00000000000
--- a/changelogs/unreleased/feature-precalculate-authorized-projects.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Precalculate user's authorized projects in database
-merge_request: 6839
-author:
diff --git a/changelogs/unreleased/feature-send-registry-address-with-build-payload.yml b/changelogs/unreleased/feature-send-registry-address-with-build-payload.yml
deleted file mode 100644
index db9bb2bc31f..00000000000
--- a/changelogs/unreleased/feature-send-registry-address-with-build-payload.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Send credentials (currently for registry only) with build data to GitLab Runner
-merge_request: 7474
-author:
diff --git a/changelogs/unreleased/feature-subscribe-to-group-level-labels.yml b/changelogs/unreleased/feature-subscribe-to-group-level-labels.yml
deleted file mode 100644
index ea336716dce..00000000000
--- a/changelogs/unreleased/feature-subscribe-to-group-level-labels.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Allow users to subscribe to group labels
-merge_request: 7215
-author:
diff --git a/changelogs/unreleased/fix-404-on-network-when-entering-a-nonexistent-git-revision.yml b/changelogs/unreleased/fix-404-on-network-when-entering-a-nonexistent-git-revision.yml
deleted file mode 100644
index d1bc8ea2eb1..00000000000
--- a/changelogs/unreleased/fix-404-on-network-when-entering-a-nonexistent-git-revision.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Fix 404 on network page when entering non-existent git revision
-merge_request: 7172
-author: Hiroyuki Sato
diff --git a/changelogs/unreleased/fix-Build-timeFor.yml b/changelogs/unreleased/fix-Build-timeFor.yml
deleted file mode 100644
index ea115f7ee67..00000000000
--- a/changelogs/unreleased/fix-Build-timeFor.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Fix typo in Build page JavaScript
-merge_request: 7563
-author: winniehell
diff --git a/changelogs/unreleased/fix-admin-ci-table.yml b/changelogs/unreleased/fix-admin-ci-table.yml
deleted file mode 100644
index 9a9e39ee94a..00000000000
--- a/changelogs/unreleased/fix-admin-ci-table.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Fix misaligned buttons on admin builds page
-merge_request: 7424
-author: Didem Acet
diff --git a/changelogs/unreleased/fix-build-without-trace-exceptions.yml b/changelogs/unreleased/fix-build-without-trace-exceptions.yml
new file mode 100644
index 00000000000..3b95e96e212
--- /dev/null
+++ b/changelogs/unreleased/fix-build-without-trace-exceptions.yml
@@ -0,0 +1,4 @@
+---
+title: Fix exceptions when loading build trace
+merge_request: 7658
+author:
diff --git a/changelogs/unreleased/fix-ci-linter-undefined-error.yml b/changelogs/unreleased/fix-ci-linter-undefined-error.yml
deleted file mode 100644
index 229970b79c0..00000000000
--- a/changelogs/unreleased/fix-ci-linter-undefined-error.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Fix undefined error in CI linter
-merge_request: 7650
-author:
diff --git a/changelogs/unreleased/fix-cycle-analytics-permissions.yml b/changelogs/unreleased/fix-cycle-analytics-permissions.yml
deleted file mode 100644
index ddcf78d705f..00000000000
--- a/changelogs/unreleased/fix-cycle-analytics-permissions.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Added permissions per stage to cycle analytics endpoint
-merge_request:
-author:
diff --git a/changelogs/unreleased/fix-cycle-analytics-plan-issue.yml b/changelogs/unreleased/fix-cycle-analytics-plan-issue.yml
new file mode 100644
index 00000000000..6ed16c6d722
--- /dev/null
+++ b/changelogs/unreleased/fix-cycle-analytics-plan-issue.yml
@@ -0,0 +1,4 @@
+---
+title: Fix cycle analytics plan stage when commits are missing
+merge_request:
+author:
diff --git a/changelogs/unreleased/fix-do-not-add-todo-when-build-allowed-to-fail.yml b/changelogs/unreleased/fix-do-not-add-todo-when-build-allowed-to-fail.yml
deleted file mode 100644
index 6402d0c7ece..00000000000
--- a/changelogs/unreleased/fix-do-not-add-todo-when-build-allowed-to-fail.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Do not create a new TODO when failed build is allowed to fail
-merge_request: 7618
-author:
diff --git a/changelogs/unreleased/fix-drop-project-authorized-for-user.yml b/changelogs/unreleased/fix-drop-project-authorized-for-user.yml
new file mode 100644
index 00000000000..0d11969575a
--- /dev/null
+++ b/changelogs/unreleased/fix-drop-project-authorized-for-user.yml
@@ -0,0 +1,4 @@
+---
+title: Use authorized projects in ProjectTeam
+merge_request:
+author:
diff --git a/changelogs/unreleased/fix-error-when-invalid-branch-for-new-pipeline-used.yml b/changelogs/unreleased/fix-error-when-invalid-branch-for-new-pipeline-used.yml
deleted file mode 100644
index ad6aa214f0f..00000000000
--- a/changelogs/unreleased/fix-error-when-invalid-branch-for-new-pipeline-used.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Fix error when using invalid branch name when creating a new pipeline
-merge_request: 7324
-author:
diff --git a/changelogs/unreleased/fix-help-page-links.yml b/changelogs/unreleased/fix-help-page-links.yml
deleted file mode 100644
index 9e5f41c553f..00000000000
--- a/changelogs/unreleased/fix-help-page-links.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Fix error links in help index page
-merge_request: 7396
-author: Fu Xu
diff --git a/changelogs/unreleased/fix-invalid-filename-eslint.yml b/changelogs/unreleased/fix-invalid-filename-eslint.yml
deleted file mode 100644
index eea21149c90..00000000000
--- a/changelogs/unreleased/fix-invalid-filename-eslint.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Fix invalid filename validation on eslint
-merge_request: 7281
-author:
diff --git a/changelogs/unreleased/fix-require-build-script-configuration-entry.yml b/changelogs/unreleased/fix-require-build-script-configuration-entry.yml
deleted file mode 100644
index 00b3fd2681f..00000000000
--- a/changelogs/unreleased/fix-require-build-script-configuration-entry.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Make job script a required configuration entry
-merge_request: 7566
-author:
diff --git a/changelogs/unreleased/fix-search-input-padding.yml b/changelogs/unreleased/fix-search-input-padding.yml
deleted file mode 100644
index 5d559d05d73..00000000000
--- a/changelogs/unreleased/fix-search-input-padding.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Give search-input correct padding-right value
-merge_request: 7407
-author: Philip Karpiak
diff --git a/changelogs/unreleased/fix-shibboleth-auth-with-no-uid.yml b/changelogs/unreleased/fix-shibboleth-auth-with-no-uid.yml
deleted file mode 100644
index 56fa2170be3..00000000000
--- a/changelogs/unreleased/fix-shibboleth-auth-with-no-uid.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: fix shibboleth misconfigurations resulting in authentication bypass
-merge_request: 7428
-author:
diff --git a/changelogs/unreleased/fix-singin-redirect-for-fork-new.yml b/changelogs/unreleased/fix-singin-redirect-for-fork-new.yml
deleted file mode 100644
index e4cf8de8699..00000000000
--- a/changelogs/unreleased/fix-singin-redirect-for-fork-new.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fixing the issue of the project fork url giving 500 when not signed instead
- of being redirected to sign in page
-merge_request:
-author: Cagdas Gerede
diff --git a/changelogs/unreleased/fix-trace-patch-updated-at.yml b/changelogs/unreleased/fix-trace-patch-updated-at.yml
deleted file mode 100644
index 88f400f0a0e..00000000000
--- a/changelogs/unreleased/fix-trace-patch-updated-at.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Fix trace patching feature - update the updated_at value
-merge_request: 7146
-author:
diff --git a/changelogs/unreleased/fix_labels_api_adding_missing_parameter.yml b/changelogs/unreleased/fix_labels_api_adding_missing_parameter.yml
deleted file mode 100644
index 01b191a8c5a..00000000000
--- a/changelogs/unreleased/fix_labels_api_adding_missing_parameter.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Fix labels API by adding missing current_user parameter
-merge_request: 7458
-author: Francesco Coda Zabetta
diff --git a/changelogs/unreleased/fix_navigation_bar_issuables_counters.yml b/changelogs/unreleased/fix_navigation_bar_issuables_counters.yml
deleted file mode 100644
index 0f7f8155f91..00000000000
--- a/changelogs/unreleased/fix_navigation_bar_issuables_counters.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Navigation bar issuables counters reflects dashboard issuables counters
-merge_request: 7368
-author: Lucas Deschamps
diff --git a/changelogs/unreleased/fix_sidekiq_stats_in_admin_area.yml b/changelogs/unreleased/fix_sidekiq_stats_in_admin_area.yml
new file mode 100644
index 00000000000..4f007be8624
--- /dev/null
+++ b/changelogs/unreleased/fix_sidekiq_stats_in_admin_area.yml
@@ -0,0 +1,4 @@
+---
+title: Sidekiq stats in the admin area will now show correctly on different platforms
+merge_request:
+author: blackst0ne
diff --git a/changelogs/unreleased/fixed-commit-timeago.yml b/changelogs/unreleased/fixed-commit-timeago.yml
new file mode 100644
index 00000000000..295d8db63d0
--- /dev/null
+++ b/changelogs/unreleased/fixed-commit-timeago.yml
@@ -0,0 +1,4 @@
+---
+title: Fixed commit timeago not rendering after initial page
+merge_request:
+author:
diff --git a/changelogs/unreleased/forking-in-progress-title.yml b/changelogs/unreleased/forking-in-progress-title.yml
deleted file mode 100644
index 4b9684844b3..00000000000
--- a/changelogs/unreleased/forking-in-progress-title.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Use 'Forking in progress' title when appropriate
-merge_request: 7394
-author: Philip Karpiak
diff --git a/changelogs/unreleased/git-gc-improvements.yml b/changelogs/unreleased/git-gc-improvements.yml
deleted file mode 100644
index f15e667ce87..00000000000
--- a/changelogs/unreleased/git-gc-improvements.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Finer-grained Git gargage collection
-merge_request: 6588
-author:
diff --git a/changelogs/unreleased/hide-empty-merge-request-diffs.yml b/changelogs/unreleased/hide-empty-merge-request-diffs.yml
deleted file mode 100644
index e32a51b555a..00000000000
--- a/changelogs/unreleased/hide-empty-merge-request-diffs.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Fix errors happening when source branch of merge request is removed and then restored
-merge_request: 7568
-author:
diff --git a/changelogs/unreleased/issue-13823.yml b/changelogs/unreleased/issue-13823.yml
deleted file mode 100644
index c1b5760f7df..00000000000
--- a/changelogs/unreleased/issue-13823.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Show random messages when the To Do list is empty
-merge_request: 6818
-author: Josep Llaneras
diff --git a/changelogs/unreleased/issue-24512.yml b/changelogs/unreleased/issue-24512.yml
deleted file mode 100644
index a3a9bd9c3d1..00000000000
--- a/changelogs/unreleased/issue-24512.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Add placeholder for the example text for custom hex color on label creation popup
-merge_request:
-author: Luis Alonso Chavez Armendariz
diff --git a/changelogs/unreleased/issue-boards-counter-border-fix.yml b/changelogs/unreleased/issue-boards-counter-border-fix.yml
deleted file mode 100644
index c98adb6af7c..00000000000
--- a/changelogs/unreleased/issue-boards-counter-border-fix.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Fixed issue boards counter border when unauthorized
-merge_request:
-author:
diff --git a/changelogs/unreleased/issue-boards-dragging-fix.yml b/changelogs/unreleased/issue-boards-dragging-fix.yml
new file mode 100644
index 00000000000..565e09b930b
--- /dev/null
+++ b/changelogs/unreleased/issue-boards-dragging-fix.yml
@@ -0,0 +1,4 @@
+---
+title: Fixed issue boards dragging card removing random issues
+merge_request:
+author:
diff --git a/changelogs/unreleased/issue-boards-scrollable-element.yml b/changelogs/unreleased/issue-boards-scrollable-element.yml
new file mode 100644
index 00000000000..90edc30e791
--- /dev/null
+++ b/changelogs/unreleased/issue-boards-scrollable-element.yml
@@ -0,0 +1,4 @@
+---
+title: Fixed issue boards scrolling with a lot of lists & issues
+merge_request:
+author:
diff --git a/changelogs/unreleased/issue_13232.yml b/changelogs/unreleased/issue_13232.yml
deleted file mode 100644
index 6dc2de5afe4..00000000000
--- a/changelogs/unreleased/issue_13232.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Add JIRA remotelinks and prevent duplicated closing messages
-merge_request:
-author:
diff --git a/changelogs/unreleased/issue_23032.yml b/changelogs/unreleased/issue_23032.yml
deleted file mode 100644
index d376cf52112..00000000000
--- a/changelogs/unreleased/issue_23032.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Allow to test JIRA service settings without having a repository
-merge_request:
-author:
diff --git a/changelogs/unreleased/issue_24303.yml b/changelogs/unreleased/issue_24303.yml
deleted file mode 100644
index 1f007712732..00000000000
--- a/changelogs/unreleased/issue_24303.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Fix JIRA references for project snippets
-merge_request:
-author:
diff --git a/changelogs/unreleased/issue_5541.yml b/changelogs/unreleased/issue_5541.yml
deleted file mode 100644
index cf553cf8d80..00000000000
--- a/changelogs/unreleased/issue_5541.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Allow enabling and disabling commit and MR events for JIRA
-merge_request:
-author:
diff --git a/changelogs/unreleased/jira_service_simplify.yml b/changelogs/unreleased/jira_service_simplify.yml
deleted file mode 100644
index 51cedd8ce5e..00000000000
--- a/changelogs/unreleased/jira_service_simplify.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: simplify url generation
-merge_request:
-author: Jarka Kadlecova
diff --git a/changelogs/unreleased/ldap_check_bind.yml b/changelogs/unreleased/ldap_check_bind.yml
deleted file mode 100644
index daff8103a07..00000000000
--- a/changelogs/unreleased/ldap_check_bind.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Introduce better credential and error checking to `rake gitlab:ldap:check`
-merge_request: 6601
-author:
diff --git a/changelogs/unreleased/less-intrusive-system-note.yml b/changelogs/unreleased/less-intrusive-system-note.yml
deleted file mode 100644
index 87a5a3be246..00000000000
--- a/changelogs/unreleased/less-intrusive-system-note.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Make system notes less intrusive
-merge_request: 6755
-author:
diff --git a/changelogs/unreleased/mailroom_idle_timeout.yml b/changelogs/unreleased/mailroom_idle_timeout.yml
deleted file mode 100644
index 276b28a56dd..00000000000
--- a/changelogs/unreleased/mailroom_idle_timeout.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Allow mail_room idle_timeout option to be configurable
-merge_request: 7423
-author:
diff --git a/changelogs/unreleased/master-recursiveTree.yml b/changelogs/unreleased/master-recursiveTree.yml
deleted file mode 100644
index c6384d172e2..00000000000
--- a/changelogs/unreleased/master-recursiveTree.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: API: allow recursive tree request
-merge_request: 6088
-author: Rebeca Méndez
diff --git a/changelogs/unreleased/milestone-project-require.yml b/changelogs/unreleased/milestone-project-require.yml
deleted file mode 100644
index e43033541c7..00000000000
--- a/changelogs/unreleased/milestone-project-require.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Require projects before creating milestone.
-merge_request: 7301
-author: gfyoung
diff --git a/changelogs/unreleased/milestone_start_date.yml b/changelogs/unreleased/milestone_start_date.yml
new file mode 100644
index 00000000000..39ac1344329
--- /dev/null
+++ b/changelogs/unreleased/milestone_start_date.yml
@@ -0,0 +1,4 @@
+---
+title: Add a starting date to milestones
+merge_request:
+author:
diff --git a/changelogs/unreleased/move-abuse-report-spinach-test-to-rspec.yml b/changelogs/unreleased/move-abuse-report-spinach-test-to-rspec.yml
new file mode 100644
index 00000000000..9de7477c200
--- /dev/null
+++ b/changelogs/unreleased/move-abuse-report-spinach-test-to-rspec.yml
@@ -0,0 +1,4 @@
+---
+title: Move abuse report spinach test to rspec
+merge_request: 7659
+author: Semyon Pupkov
diff --git a/changelogs/unreleased/move-admin-abuse-report-spinach-test-to-rspec.yml b/changelogs/unreleased/move-admin-abuse-report-spinach-test-to-rspec.yml
new file mode 100644
index 00000000000..fb70fa2955a
--- /dev/null
+++ b/changelogs/unreleased/move-admin-abuse-report-spinach-test-to-rspec.yml
@@ -0,0 +1,4 @@
+---
+title: Move admin abuse report spinach test to rspec
+merge_request: 7691
+author: Semyon Pupkov
diff --git a/changelogs/unreleased/move-admin-spam-spinach-test-to-rspec.yml b/changelogs/unreleased/move-admin-spam-spinach-test-to-rspec.yml
new file mode 100644
index 00000000000..a7ec2c20554
--- /dev/null
+++ b/changelogs/unreleased/move-admin-spam-spinach-test-to-rspec.yml
@@ -0,0 +1,4 @@
+---
+title: Move admin spam spinach test to Rspec
+merge_request: 7708
+author: Semyon Pupkov
diff --git a/changelogs/unreleased/namespace-validation.yml b/changelogs/unreleased/namespace-validation.yml
deleted file mode 100644
index 6ac461bf82e..00000000000
--- a/changelogs/unreleased/namespace-validation.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Check all namespaces on validation of new username.
-merge_request: 7537
-author:
diff --git a/changelogs/unreleased/new-note-worker-record-not-found-fix.yml b/changelogs/unreleased/new-note-worker-record-not-found-fix.yml
deleted file mode 100644
index abfba640cc0..00000000000
--- a/changelogs/unreleased/new-note-worker-record-not-found-fix.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Fix record not found error on NewNoteWorker processing
-merge_request: 6863
-author: Oswaldo Ferreira
diff --git a/changelogs/unreleased/optimize-mr-index.yml b/changelogs/unreleased/optimize-mr-index.yml
deleted file mode 100644
index 1090b6d4528..00000000000
--- a/changelogs/unreleased/optimize-mr-index.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: More aggressively preload on merge request and issue index pages
-merge_request:
-author:
diff --git a/changelogs/unreleased/pass-correct-tag-target-to-post-receive.yml b/changelogs/unreleased/pass-correct-tag-target-to-post-receive.yml
deleted file mode 100644
index 5e868027ed6..00000000000
--- a/changelogs/unreleased/pass-correct-tag-target-to-post-receive.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Pass correct tag target to post-receive hook when creating tag via UI
-merge_request: 7556
-author:
diff --git a/changelogs/unreleased/pipeline-notifications.yml b/changelogs/unreleased/pipeline-notifications.yml
deleted file mode 100644
index b43060674b2..00000000000
--- a/changelogs/unreleased/pipeline-notifications.yml
+++ /dev/null
@@ -1,6 +0,0 @@
----
-title: Add CI notifications. Who triggered a pipeline would receive an email after
- the pipeline is succeeded or failed. Users could also update notification settings
- accordingly
-merge_request: 6342
-author:
diff --git a/changelogs/unreleased/post_receive-any-email.yml b/changelogs/unreleased/post_receive-any-email.yml
new file mode 100644
index 00000000000..3710b1b4b46
--- /dev/null
+++ b/changelogs/unreleased/post_receive-any-email.yml
@@ -0,0 +1,4 @@
+---
+title: "post_receive: accept any user email from last commit"
+merge_request: 7225
+author: Elan Ruusamäe
diff --git a/changelogs/unreleased/process-commits-using-sidekiq.yml b/changelogs/unreleased/process-commits-using-sidekiq.yml
deleted file mode 100644
index 9f596e6a584..00000000000
--- a/changelogs/unreleased/process-commits-using-sidekiq.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Process commits using a dedicated Sidekiq worker
-merge_request: 6802
-author:
diff --git a/changelogs/unreleased/rack_attack_logging.yml b/changelogs/unreleased/rack_attack_logging.yml
deleted file mode 100644
index c0d6c1fd12e..00000000000
--- a/changelogs/unreleased/rack_attack_logging.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Add logging for rack attack events to production.log
-merge_request:
-author:
diff --git a/changelogs/unreleased/related-mr-labels.yml b/changelogs/unreleased/related-mr-labels.yml
deleted file mode 100644
index 268e0eab870..00000000000
--- a/changelogs/unreleased/related-mr-labels.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Added colored labels to related MR list.
-merge_request: 7486
-author: Didem Acet
diff --git a/changelogs/unreleased/remove-backup-strategies.yml b/changelogs/unreleased/remove-backup-strategies.yml
new file mode 100644
index 00000000000..9f034613c2c
--- /dev/null
+++ b/changelogs/unreleased/remove-backup-strategies.yml
@@ -0,0 +1,4 @@
+---
+title: Stop supporting Google and Azure as backup strategies
+merge_request:
+author:
diff --git a/changelogs/unreleased/remove-heading-space-from-diff-content.yml b/changelogs/unreleased/remove-heading-space-from-diff-content.yml
deleted file mode 100644
index 1ea85784d29..00000000000
--- a/changelogs/unreleased/remove-heading-space-from-diff-content.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Remove an extra leading space from diff paste data
-merge_request: 7133
-author: Hiroyuki Sato
diff --git a/changelogs/unreleased/rs-project-team-helpers.yml b/changelogs/unreleased/rs-project-team-helpers.yml
new file mode 100644
index 00000000000..79abcbce1e3
--- /dev/null
+++ b/changelogs/unreleased/rs-project-team-helpers.yml
@@ -0,0 +1,4 @@
+---
+title: Add shortcuts for adding users to a project team with a specific role
+merge_request:
+author: Nikolay Ponomarev and Dino M
diff --git a/changelogs/unreleased/setter-for-key.yml b/changelogs/unreleased/setter-for-key.yml
deleted file mode 100644
index 15167904ed5..00000000000
--- a/changelogs/unreleased/setter-for-key.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Use setter for key instead AR callback
-merge_request: 7488
-author: Semyon Pupkov
diff --git a/changelogs/unreleased/sh-bump-omniauth-gitlab.yml b/changelogs/unreleased/sh-bump-omniauth-gitlab.yml
deleted file mode 100644
index 17cd5a993dd..00000000000
--- a/changelogs/unreleased/sh-bump-omniauth-gitlab.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Bump omniauth-gitlab to 1.0.2 to fix incompatibility with omniauth-oauth2
-merge_request:
-author:
diff --git a/changelogs/unreleased/show-status-from-branch.yml b/changelogs/unreleased/show-status-from-branch.yml
deleted file mode 100644
index 1afc230c05c..00000000000
--- a/changelogs/unreleased/show-status-from-branch.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Fix showing pipeline status for a given commit from correct branch
-merge_request: 7034
-author:
diff --git a/changelogs/unreleased/sidekiq-job-throttling.yml b/changelogs/unreleased/sidekiq-job-throttling.yml
deleted file mode 100644
index ec4e2051c7e..00000000000
--- a/changelogs/unreleased/sidekiq-job-throttling.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Added ability to throttle Sidekiq Jobs
-merge_request: 7292
-author:
diff --git a/changelogs/unreleased/sidekiq_default_retries.yml b/changelogs/unreleased/sidekiq_default_retries.yml
deleted file mode 100644
index 3df2a415dbc..00000000000
--- a/changelogs/unreleased/sidekiq_default_retries.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Set default Sidekiq retries to 3
-merge_request: 7294
-author:
diff --git a/changelogs/unreleased/simplify-create-new-list-issue-boards.yml b/changelogs/unreleased/simplify-create-new-list-issue-boards.yml
new file mode 100644
index 00000000000..ca11e3b94a7
--- /dev/null
+++ b/changelogs/unreleased/simplify-create-new-list-issue-boards.yml
@@ -0,0 +1,4 @@
+---
+title: Simplify copy on "Create a new list" dropdown in Issue Boards
+merge_request: 7605
+author: Victor Rodrigues
diff --git a/changelogs/unreleased/smarter-cache-invalidation.yml b/changelogs/unreleased/smarter-cache-invalidation.yml
deleted file mode 100644
index 14a93e26ac4..00000000000
--- a/changelogs/unreleased/smarter-cache-invalidation.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Rework cache invalidation so only changed data is refreshed
-merge_request: 7360
-author:
diff --git a/changelogs/unreleased/sort-api-groups.yml b/changelogs/unreleased/sort-api-groups.yml
deleted file mode 100644
index e3eead8c04f..00000000000
--- a/changelogs/unreleased/sort-api-groups.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Allow sorting groups in the API
-merge_request:
-author:
diff --git a/changelogs/unreleased/stanhu-gitlab-ce-fix-error-500-with-mr-images.yml b/changelogs/unreleased/stanhu-gitlab-ce-fix-error-500-with-mr-images.yml
deleted file mode 100644
index 7ca0d5fb19e..00000000000
--- a/changelogs/unreleased/stanhu-gitlab-ce-fix-error-500-with-mr-images.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Fix Error 500 when creating a merge request that contains an image that was deleted and added
-merge_request: 7457
-author:
diff --git a/changelogs/unreleased/upgrade-timeago.yml b/changelogs/unreleased/upgrade-timeago.yml
deleted file mode 100644
index ddb266ba558..00000000000
--- a/changelogs/unreleased/upgrade-timeago.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Replace jQuery.timeago with timeago.js
-merge_request: 6274
-author: ClemMakesApps
diff --git a/changelogs/unreleased/use-separate-token-for-incoming-email.yml b/changelogs/unreleased/use-separate-token-for-incoming-email.yml
deleted file mode 100644
index e498f8dd0a6..00000000000
--- a/changelogs/unreleased/use-separate-token-for-incoming-email.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Use separate email-token for incoming email and revert back the inactive feature
-merge_request: 5914
-author:
diff --git a/changelogs/unreleased/user-dropdown-multiple-requests-fix.yml b/changelogs/unreleased/user-dropdown-multiple-requests-fix.yml
deleted file mode 100644
index a83441b852a..00000000000
--- a/changelogs/unreleased/user-dropdown-multiple-requests-fix.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Fixed multiple requests sent when opening dropdowns
-merge_request:
-author:
diff --git a/changelogs/unreleased/user_filter_auth.yml b/changelogs/unreleased/user_filter_auth.yml
deleted file mode 100644
index e4071e22e5e..00000000000
--- a/changelogs/unreleased/user_filter_auth.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Centralize LDAP config/filter logic
-merge_request: 6606
-author:
diff --git a/changelogs/unreleased/zj-slash-commands-mattermost.yml b/changelogs/unreleased/zj-slash-commands-mattermost.yml
deleted file mode 100644
index 996ffe954f3..00000000000
--- a/changelogs/unreleased/zj-slash-commands-mattermost.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Added Mattermost slash command
-merge_request: 7438
-author:
diff --git a/config/README.md b/config/README.md
new file mode 100644
index 00000000000..0a5ea2424e0
--- /dev/null
+++ b/config/README.md
@@ -0,0 +1,22 @@
+# Configuration files Documentation
+
+Note that most configuration files (`config/*.*`) committed into
+[gitlab-ce](https://gitlab.com/gitlab-org/gitlab-ce) **will not be used** for
+[omnibus-gitlab](https://gitlab.com/gitlab-org/omnibus-gitlab). Configuration
+files committed into gitlab-ce are only used for development.
+
+## gitlab.yml
+
+You can find most of GitLab configuration settings here.
+
+## mail_room.yml
+
+This file is actually an YML wrapped inside an ERB file to enable templated
+values to be specified from `gitlab.yml`. mail_room loads this file first as
+an ERB file and then loads the resulting YML as its configuration.
+
+## resque.yml
+
+This file is called `resque.yml` for historical reasons. We are **NOT**
+using Resque at the moment. It is used to specify Redis configuration
+values instead.
diff --git a/config/routes.rb b/config/routes.rb
index 7bf6c03e69b..03b47261e7e 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -1,6 +1,7 @@
require 'sidekiq/web'
require 'sidekiq/cron/web'
require 'api/api'
+require 'constraints/group_url_constrainer'
Rails.application.routes.draw do
concern :access_requestable do
@@ -78,10 +79,21 @@ Rails.application.routes.draw do
draw :user
draw :project
- # Get all keys of user
- get ':username.keys' => 'profiles/keys#get_keys', constraints: { username: /.*/ }
-
root to: "root#index"
- get '*unmatched_route', to: 'application#not_found'
+ # Since group show page is wildcard routing
+ # we want all other routing to be checked before matching this one
+ constraints(GroupUrlConstrainer.new) do
+ scope(path: '*id',
+ as: :group,
+ constraints: { id: Gitlab::Regex.namespace_route_regex, format: /(html|json|atom)/ },
+ controller: :groups) do
+ get '/', action: :show
+ patch '/', action: :update
+ put '/', action: :update
+ delete '/', action: :destroy
+ end
+ end
+
+ get '*unmatched_route', to: 'application#route_not_found'
end
diff --git a/config/routes/git_http.rb b/config/routes/git_http.rb
index 03adc4815f3..42d874eeebc 100644
--- a/config/routes/git_http.rb
+++ b/config/routes/git_http.rb
@@ -1,37 +1,47 @@
-scope constraints: { id: /.+\.git/, format: nil } do
- # Git HTTP clients ('git clone' etc.)
- get '/info/refs', to: 'git_http#info_refs'
- post '/git-upload-pack', to: 'git_http#git_upload_pack'
- post '/git-receive-pack', to: 'git_http#git_receive_pack'
+scope(path: '*namespace_id/:project_id', constraints: { format: nil }) do
+ scope(constraints: { project_id: Gitlab::Regex.project_git_route_regex }, module: :projects) do
+ # Git HTTP clients ('git clone' etc.)
+ scope(controller: :git_http) do
+ get '/info/refs', action: :info_refs
+ post '/git-upload-pack', action: :git_upload_pack
+ post '/git-receive-pack', action: :git_receive_pack
+ end
- # Git LFS API (metadata)
- post '/info/lfs/objects/batch', to: 'lfs_api#batch'
- post '/info/lfs/objects', to: 'lfs_api#deprecated'
- get '/info/lfs/objects/*oid', to: 'lfs_api#deprecated'
+ # Git LFS API (metadata)
+ scope(path: 'info/lfs/objects', controller: :lfs_api) do
+ post :batch
+ post '/', action: :deprecated
+ get '/*oid', action: :deprecated
+ end
- # GitLab LFS object storage
- scope constraints: { oid: /[a-f0-9]{64}/ } do
- get '/gitlab-lfs/objects/*oid', to: 'lfs_storage#download'
+ # GitLab LFS object storage
+ scope(path: 'gitlab-lfs/objects/*oid', controller: :lfs_storage, constraints: { oid: /[a-f0-9]{64}/ }) do
+ get '/', action: :download
- scope constraints: { size: /[0-9]+/ } do
- put '/gitlab-lfs/objects/*oid/*size/authorize', to: 'lfs_storage#upload_authorize'
- put '/gitlab-lfs/objects/*oid/*size', to: 'lfs_storage#upload_finalize'
+ scope constraints: { size: /[0-9]+/ } do
+ put '/*size/authorize', action: :upload_authorize
+ put '/*size', action: :upload_finalize
+ end
end
end
-end
-# Allow /info/refs, /info/refs?service=git-upload-pack, and
-# /info/refs?service=git-receive-pack, but nothing else.
-#
-git_http_handshake = lambda do |request|
- request.query_string.blank? ||
- request.query_string.match(/\Aservice=git-(upload|receive)-pack\z/)
-end
+ # Redirect /group/project/info/refs to /group/project.git/info/refs
+ scope(constraints: { project_id: Gitlab::Regex.project_route_regex }) do
+ # Allow /info/refs, /info/refs?service=git-upload-pack, and
+ # /info/refs?service=git-receive-pack, but nothing else.
+ #
+ git_http_handshake = lambda do |request|
+ ProjectUrlConstrainer.new.matches?(request) &&
+ (request.query_string.blank? ||
+ request.query_string.match(/\Aservice=git-(upload|receive)-pack\z/))
+ end
-ref_redirect = redirect do |params, request|
- path = "#{params[:namespace_id]}/#{params[:project_id]}.git/info/refs"
- path << "?#{request.query_string}" unless request.query_string.blank?
- path
-end
+ ref_redirect = redirect do |params, request|
+ path = "#{params[:namespace_id]}/#{params[:project_id]}.git/info/refs"
+ path << "?#{request.query_string}" unless request.query_string.blank?
+ path
+ end
-get '/info/refs', constraints: git_http_handshake, to: ref_redirect
+ get '/info/refs', constraints: git_http_handshake, to: ref_redirect
+ end
+end
diff --git a/config/routes/group.rb b/config/routes/group.rb
index a3a001178b4..9fe72990994 100644
--- a/config/routes/group.rb
+++ b/config/routes/group.rb
@@ -1,20 +1,6 @@
-require 'constraints/group_url_constrainer'
-
-constraints(GroupUrlConstrainer.new) do
- scope(path: ':id',
- as: :group,
- constraints: { id: Gitlab::Regex.namespace_route_regex },
- controller: :groups) do
- get '/', action: :show
- patch '/', action: :update
- put '/', action: :update
- delete '/', action: :destroy
- end
-end
-
resources :groups, only: [:index, :new, :create]
-scope(path: 'groups/:id',
+scope(path: 'groups/*id',
controller: :groups,
constraints: { id: Gitlab::Regex.namespace_route_regex }) do
get :edit, as: :edit_group
@@ -24,7 +10,7 @@ scope(path: 'groups/:id',
get :activity, as: :activity_group
end
-scope(path: 'groups/:group_id',
+scope(path: 'groups/*group_id',
module: :groups,
as: :group,
constraints: { group_id: Gitlab::Regex.namespace_route_regex }) do
@@ -42,4 +28,4 @@ scope(path: 'groups/:group_id',
end
# Must be last route in this file
-get 'groups/:id' => 'groups#show', as: :group_canonical, constraints: { id: Gitlab::Regex.namespace_route_regex }
+get 'groups/*id' => 'groups#show', as: :group_canonical, constraints: { id: Gitlab::Regex.namespace_route_regex }
diff --git a/config/routes/project.rb b/config/routes/project.rb
index d6eae1c9fce..1336484a399 100644
--- a/config/routes/project.rb
+++ b/config/routes/project.rb
@@ -1,28 +1,15 @@
-resources :projects, constraints: { id: /[^\/]+/ }, only: [:index, :new, :create]
-
-resources :namespaces, path: '/', constraints: { id: /[a-zA-Z.0-9_\-]+/ }, only: [] do
- resources(:projects, constraints: { id: /[a-zA-Z.0-9_\-]+(?<!\.atom)/ }, except:
- [:new, :create, :index], path: "/") do
- member do
- put :transfer
- delete :remove_fork
- post :archive
- post :unarchive
- post :housekeeping
- post :toggle_star
- post :preview_markdown
- post :export
- post :remove_export
- post :generate_new_export
- get :download_export
- get :autocomplete_sources
- get :activity
- get :refs
- put :new_issue_address
- end
+require 'constraints/project_url_constrainer'
+
+resources :projects, only: [:index, :new, :create]
+
+draw :git_http
- scope module: :projects do
- draw :git_http
+constraints(ProjectUrlConstrainer.new) do
+ scope(path: '*namespace_id', as: :namespace) do
+ scope(path: ':project_id',
+ constraints: { project_id: Gitlab::Regex.project_route_regex },
+ module: :projects,
+ as: :project) do
#
# Templates
@@ -311,5 +298,28 @@ resources :namespaces, path: '/', constraints: { id: /[a-zA-Z.0-9_\-]+/ }, only:
draw :wiki
draw :repository
end
+
+ resources(:projects,
+ path: '/',
+ constraints: { id: Gitlab::Regex.project_route_regex },
+ only: [:edit, :show, :update, :destroy]) do
+ member do
+ put :transfer
+ delete :remove_fork
+ post :archive
+ post :unarchive
+ post :housekeeping
+ post :toggle_star
+ post :preview_markdown
+ post :export
+ post :remove_export
+ post :generate_new_export
+ get :download_export
+ get :autocomplete_sources
+ get :activity
+ get :refs
+ put :new_issue_address
+ end
+ end
end
end
diff --git a/config/routes/repository.rb b/config/routes/repository.rb
index 76dcf113aea..f8966c5ae75 100644
--- a/config/routes/repository.rb
+++ b/config/routes/repository.rb
@@ -29,82 +29,60 @@ get '/edit/*id', to: 'blob#edit', constraints: { id: /.+/ }, as: 'edit_blob'
put '/update/*id', to: 'blob#update', constraints: { id: /.+/ }, as: 'update_blob'
post '/preview/*id', to: 'blob#preview', constraints: { id: /.+/ }, as: 'preview_blob'
-scope do
- get(
- '/blob/*id/diff',
- to: 'blob#diff',
- constraints: { id: /.+/, format: false },
- as: :blob_diff
- )
- get(
- '/blob/*id',
- to: 'blob#show',
- constraints: { id: /.+/, format: false },
- as: :blob
- )
- delete(
- '/blob/*id',
- to: 'blob#destroy',
- constraints: { id: /.+/, format: false }
- )
- put(
- '/blob/*id',
- to: 'blob#update',
- constraints: { id: /.+/, format: false }
- )
- post(
- '/blob/*id',
- to: 'blob#create',
- constraints: { id: /.+/, format: false }
- )
+scope('/blob/*id', as: :blob, controller: :blob, constraints: { id: /.+/, format: false }) do
+ get :diff
+ get '/', action: :show
+ delete '/', action: :destroy
+ post '/', action: :create
+ put '/', action: :update
+end
- get(
- '/raw/*id',
- to: 'raw#show',
- constraints: { id: /.+/, format: /(html|js)/ },
- as: :raw
- )
+get(
+ '/raw/*id',
+ to: 'raw#show',
+ constraints: { id: /.+/, format: /(html|js)/ },
+ as: :raw
+)
- get(
- '/tree/*id',
- to: 'tree#show',
- constraints: { id: /.+/, format: /(html|js)/ },
- as: :tree
- )
+get(
+ '/tree/*id',
+ to: 'tree#show',
+ constraints: { id: /.+/, format: /(html|js)/ },
+ as: :tree
+)
- get(
- '/find_file/*id',
- to: 'find_file#show',
- constraints: { id: /.+/, format: /html/ },
- as: :find_file
- )
+get(
+ '/find_file/*id',
+ to: 'find_file#show',
+ constraints: { id: /.+/, format: /html/ },
+ as: :find_file
+)
- get(
- '/files/*id',
- to: 'find_file#list',
- constraints: { id: /(?:[^.]|\.(?!json$))+/, format: /json/ },
- as: :files
- )
+get(
+ '/files/*id',
+ to: 'find_file#list',
+ constraints: { id: /(?:[^.]|\.(?!json$))+/, format: /json/ },
+ as: :files
+)
- post(
- '/create_dir/*id',
- to: 'tree#create_dir',
- constraints: { id: /.+/ },
- as: 'create_dir'
- )
+post(
+ '/create_dir/*id',
+ to: 'tree#create_dir',
+ constraints: { id: /.+/ },
+ as: 'create_dir'
+)
- get(
- '/blame/*id',
- to: 'blame#show',
- constraints: { id: /.+/, format: /(html|js)/ },
- as: :blame
- )
+get(
+ '/blame/*id',
+ to: 'blame#show',
+ constraints: { id: /.+/, format: /(html|js)/ },
+ as: :blame
+)
- # File/dir history
- get(
- '/commits/*id',
- to: 'commits#show',
- constraints: { id: /.+/, format: false },
- as: :commits
- )
-end
+# File/dir history
+get(
+ '/commits/*id',
+ to: 'commits#show',
+ constraints: { id: /.+/, format: false },
+ as: :commits
+)
diff --git a/config/routes/user.rb b/config/routes/user.rb
index dc1068af6f6..b064a15e802 100644
--- a/config/routes/user.rb
+++ b/config/routes/user.rb
@@ -12,6 +12,9 @@ devise_scope :user do
end
constraints(UserUrlConstrainer.new) do
+ # Get all keys of user
+ get ':username.keys' => 'profiles/keys#get_keys', constraints: { username: Gitlab::Regex.namespace_route_regex }
+
scope(path: ':username',
as: :user,
constraints: { username: Gitlab::Regex.namespace_route_regex },
diff --git a/config/routes/wiki.rb b/config/routes/wiki.rb
index ecd4d395d66..dad746d59a1 100644
--- a/config/routes/wiki.rb
+++ b/config/routes/wiki.rb
@@ -1,16 +1,19 @@
WIKI_SLUG_ID = { id: /\S+/ } unless defined? WIKI_SLUG_ID
-scope do
- # Order matters to give priority to these matches
- get '/wikis/git_access', to: 'wikis#git_access'
- get '/wikis/pages', to: 'wikis#pages', as: 'wiki_pages'
- post '/wikis', to: 'wikis#create'
+scope(controller: :wikis) do
+ scope(path: 'wikis', as: :wikis) do
+ get :git_access
+ get :pages
+ get '/', to: redirect('/%{namespace_id}/%{project_id}/wikis/home')
+ post '/', to: 'wikis#create'
+ end
- get '/wikis/*id/history', to: 'wikis#history', as: 'wiki_history', constraints: WIKI_SLUG_ID
- get '/wikis/*id/edit', to: 'wikis#edit', as: 'wiki_edit', constraints: WIKI_SLUG_ID
-
- get '/wikis/*id', to: 'wikis#show', as: 'wiki', constraints: WIKI_SLUG_ID
- delete '/wikis/*id', to: 'wikis#destroy', constraints: WIKI_SLUG_ID
- put '/wikis/*id', to: 'wikis#update', constraints: WIKI_SLUG_ID
- post '/wikis/*id/preview_markdown', to: 'wikis#preview_markdown', constraints: WIKI_SLUG_ID, as: 'wiki_preview_markdown'
+ scope(path: 'wikis/*id', as: :wiki, constraints: WIKI_SLUG_ID, format: false) do
+ get :edit
+ get :history
+ post :preview_markdown
+ get '/', action: :show
+ put '/', action: :update
+ delete '/', action: :destroy
+ end
end
diff --git a/db/fixtures/development/06_teams.rb b/db/fixtures/development/06_teams.rb
index 9739a5ac8d5..04c3690e152 100644
--- a/db/fixtures/development/06_teams.rb
+++ b/db/fixtures/development/06_teams.rb
@@ -1,20 +1,25 @@
-Gitlab::Seeder.quiet do
- Group.all.each do |group|
- User.all.sample(4).each do |user|
- if group.add_user(user, Gitlab::Access.values.sample).persisted?
- print '.'
- else
- print 'F'
+require 'sidekiq/testing'
+require './db/fixtures/support/serialized_transaction'
+
+Sidekiq::Testing.inline! do
+ Gitlab::Seeder.quiet do
+ Group.all.each do |group|
+ User.all.sample(4).each do |user|
+ if group.add_user(user, Gitlab::Access.values.sample).persisted?
+ print '.'
+ else
+ print 'F'
+ end
end
end
- end
- Project.all.each do |project|
- User.all.sample(4).each do |user|
- if project.team << [user, Gitlab::Access.values.sample]
- print '.'
- else
- print 'F'
+ Project.all.each do |project|
+ User.all.sample(4).each do |user|
+ if project.team << [user, Gitlab::Access.values.sample]
+ print '.'
+ else
+ print 'F'
+ end
end
end
end
diff --git a/db/migrate/20161115173905_add_start_date_to_milestones.rb b/db/migrate/20161115173905_add_start_date_to_milestones.rb
new file mode 100644
index 00000000000..413733b8db7
--- /dev/null
+++ b/db/migrate/20161115173905_add_start_date_to_milestones.rb
@@ -0,0 +1,12 @@
+# See http://doc.gitlab.com/ce/development/migration_style_guide.html
+# for more information on how to write migrations for GitLab.
+
+class AddStartDateToMilestones < ActiveRecord::Migration
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ def change
+ add_column :milestones, :start_date, :date
+ end
+end
diff --git a/db/migrate/20161117114805_remove_undeleted_groups.rb b/db/migrate/20161117114805_remove_undeleted_groups.rb
index ebc2d974ae0..696914f8e4d 100644
--- a/db/migrate/20161117114805_remove_undeleted_groups.rb
+++ b/db/migrate/20161117114805_remove_undeleted_groups.rb
@@ -5,6 +5,47 @@ class RemoveUndeletedGroups < ActiveRecord::Migration
DOWNTIME = false
def up
+ execute <<-EOF.strip_heredoc
+ DELETE FROM projects
+ WHERE namespace_id IN (
+ SELECT id FROM (
+ SELECT id
+ FROM namespaces
+ WHERE deleted_at IS NOT NULL
+ ) namespace_ids
+ );
+ EOF
+
+ if defined?(Gitlab::License)
+ # EE adds these columns but we have to make sure this data is cleaned up
+ # here before we run the DELETE below. An alternative would be patching
+ # this migration in EE but this will only result in a mess and confusing
+ # migrations.
+ execute <<-EOF.strip_heredoc
+ DELETE FROM protected_branch_push_access_levels
+ WHERE group_id IN (
+ SELECT id FROM (
+ SELECT id
+ FROM namespaces
+ WHERE deleted_at IS NOT NULL
+ ) namespace_ids
+ );
+ EOF
+
+ execute <<-EOF.strip_heredoc
+ DELETE FROM protected_branch_merge_access_levels
+ WHERE group_id IN (
+ SELECT id FROM (
+ SELECT id
+ FROM namespaces
+ WHERE deleted_at IS NOT NULL
+ ) namespace_ids
+ );
+ EOF
+ end
+
+ # This removes namespaces that were supposed to be soft deleted but still
+ # reside in the database.
execute "DELETE FROM namespaces WHERE deleted_at IS NOT NULL;"
end
diff --git a/db/schema.rb b/db/schema.rb
index 6b28e80f01d..b3c49b52597 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -720,6 +720,7 @@ ActiveRecord::Schema.define(version: 20161118183841) do
t.integer "iid"
t.text "title_html"
t.text "description_html"
+ t.date "start_date"
end
add_index "milestones", ["description"], name: "index_milestones_on_description_trigram", using: :gin, opclasses: {"description"=>"gin_trgm_ops"}
diff --git a/doc/administration/high_availability/database.md b/doc/administration/high_availability/database.md
index 538dada1bae..76f3a0fb387 100644
--- a/doc/administration/high_availability/database.md
+++ b/doc/administration/high_availability/database.md
@@ -102,7 +102,7 @@ If you use a cloud-managed service, or provide your own PostgreSQL:
1. Exit the database prompt by typing `\q` and Enter.
1. Exit the `gitlab-psql` user by running `exit` twice.
1. Run `sudo gitlab-ctl reconfigure` a final time.
-1. Run `touch /etc/gitlab/skip-auto-migrations` to prevent database migrations
+1. Run `sudo touch /etc/gitlab/skip-auto-migrations` to prevent database migrations
from running on upgrade. Only the primary GitLab application server should
handle migrations.
diff --git a/doc/administration/img/custom_hooks_error_msg.png b/doc/administration/img/custom_hooks_error_msg.png
index 92e87e15fb3..1b3277bef16 100644
--- a/doc/administration/img/custom_hooks_error_msg.png
+++ b/doc/administration/img/custom_hooks_error_msg.png
Binary files differ
diff --git a/doc/administration/img/high_availability/active-active-diagram.png b/doc/administration/img/high_availability/active-active-diagram.png
index 81259e0ae93..4f5984b88fe 100644
--- a/doc/administration/img/high_availability/active-active-diagram.png
+++ b/doc/administration/img/high_availability/active-active-diagram.png
Binary files differ
diff --git a/doc/administration/img/high_availability/active-passive-diagram.png b/doc/administration/img/high_availability/active-passive-diagram.png
index f69ff1d0357..3b42ce5911c 100644
--- a/doc/administration/img/high_availability/active-passive-diagram.png
+++ b/doc/administration/img/high_availability/active-passive-diagram.png
Binary files differ
diff --git a/doc/administration/img/housekeeping_settings.png b/doc/administration/img/housekeeping_settings.png
index 6ebc6205635..acc4506993a 100644
--- a/doc/administration/img/housekeeping_settings.png
+++ b/doc/administration/img/housekeeping_settings.png
Binary files differ
diff --git a/doc/administration/img/raketasks/check_repos_output.png b/doc/administration/img/raketasks/check_repos_output.png
index 1f632566b00..7fda2ba0c0f 100644
--- a/doc/administration/img/raketasks/check_repos_output.png
+++ b/doc/administration/img/raketasks/check_repos_output.png
Binary files differ
diff --git a/doc/administration/img/repository_storages_admin_ui.png b/doc/administration/img/repository_storages_admin_ui.png
index 6481baca1ad..3e76c5b282c 100644
--- a/doc/administration/img/repository_storages_admin_ui.png
+++ b/doc/administration/img/repository_storages_admin_ui.png
Binary files differ
diff --git a/doc/administration/monitoring/performance/img/grafana_dashboard_dropdown.png b/doc/administration/monitoring/performance/img/grafana_dashboard_dropdown.png
index 7e34fad71ce..51eef90068d 100644
--- a/doc/administration/monitoring/performance/img/grafana_dashboard_dropdown.png
+++ b/doc/administration/monitoring/performance/img/grafana_dashboard_dropdown.png
Binary files differ
diff --git a/doc/administration/monitoring/performance/img/grafana_dashboard_import.png b/doc/administration/monitoring/performance/img/grafana_dashboard_import.png
index f97624365c7..7761ea00522 100644
--- a/doc/administration/monitoring/performance/img/grafana_dashboard_import.png
+++ b/doc/administration/monitoring/performance/img/grafana_dashboard_import.png
Binary files differ
diff --git a/doc/administration/monitoring/performance/img/grafana_data_source_configuration.png b/doc/administration/monitoring/performance/img/grafana_data_source_configuration.png
index 7d50e4c88c2..3e749eb8f9d 100644
--- a/doc/administration/monitoring/performance/img/grafana_data_source_configuration.png
+++ b/doc/administration/monitoring/performance/img/grafana_data_source_configuration.png
Binary files differ
diff --git a/doc/administration/monitoring/performance/img/grafana_data_source_empty.png b/doc/administration/monitoring/performance/img/grafana_data_source_empty.png
index aa39a53acae..33fcaaaef64 100644
--- a/doc/administration/monitoring/performance/img/grafana_data_source_empty.png
+++ b/doc/administration/monitoring/performance/img/grafana_data_source_empty.png
Binary files differ
diff --git a/doc/administration/monitoring/performance/img/grafana_save_icon.png b/doc/administration/monitoring/performance/img/grafana_save_icon.png
index c740e33cd1c..c18f2147e9d 100644
--- a/doc/administration/monitoring/performance/img/grafana_save_icon.png
+++ b/doc/administration/monitoring/performance/img/grafana_save_icon.png
Binary files differ
diff --git a/doc/administration/monitoring/performance/img/metrics_gitlab_configuration_settings.png b/doc/administration/monitoring/performance/img/metrics_gitlab_configuration_settings.png
index db396423e30..13bfd097b81 100644
--- a/doc/administration/monitoring/performance/img/metrics_gitlab_configuration_settings.png
+++ b/doc/administration/monitoring/performance/img/metrics_gitlab_configuration_settings.png
Binary files differ
diff --git a/doc/administration/monitoring/performance/img/request_profile_result.png b/doc/administration/monitoring/performance/img/request_profile_result.png
index 73e2fdcab67..8ebd74c2d3c 100644
--- a/doc/administration/monitoring/performance/img/request_profile_result.png
+++ b/doc/administration/monitoring/performance/img/request_profile_result.png
Binary files differ
diff --git a/doc/administration/monitoring/performance/img/request_profiling_token.png b/doc/administration/monitoring/performance/img/request_profiling_token.png
index 04d87567816..9160407e028 100644
--- a/doc/administration/monitoring/performance/img/request_profiling_token.png
+++ b/doc/administration/monitoring/performance/img/request_profiling_token.png
Binary files differ
diff --git a/doc/administration/operations/img/sidekiq_job_throttling.png b/doc/administration/operations/img/sidekiq_job_throttling.png
index 7f29a4d3c46..dcf40b4bf17 100644
--- a/doc/administration/operations/img/sidekiq_job_throttling.png
+++ b/doc/administration/operations/img/sidekiq_job_throttling.png
Binary files differ
diff --git a/doc/api/merge_requests.md b/doc/api/merge_requests.md
index f4167403c2c..4cc385e36fe 100644
--- a/doc/api/merge_requests.md
+++ b/doc/api/merge_requests.md
@@ -11,6 +11,7 @@ GET /projects/:id/merge_requests
GET /projects/:id/merge_requests?state=opened
GET /projects/:id/merge_requests?state=all
GET /projects/:id/merge_requests?iid=42
+GET /projects/:id/merge_requests?iid[]=42&iid[]=43
```
Parameters:
diff --git a/doc/api/milestones.md b/doc/api/milestones.md
index ae7d22a4be5..12497acff98 100644
--- a/doc/api/milestones.md
+++ b/doc/api/milestones.md
@@ -7,6 +7,7 @@ Returns a list of project milestones.
```
GET /projects/:id/milestones
GET /projects/:id/milestones?iid=42
+GET /projects/:id/milestones?iid[]=42&iid[]=43
GET /projects/:id/milestones?state=active
GET /projects/:id/milestones?state=closed
```
@@ -16,7 +17,7 @@ Parameters:
| Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `id` | integer | yes | The ID of a project |
-| `iid` | integer | optional | Return only the milestone having the given `iid` |
+| `iid` | Array[integer] | optional | Return only the milestone having the given `iid` |
| `state` | string | optional | Return only `active` or `closed` milestones` |
```bash
@@ -34,6 +35,7 @@ Example Response:
"title": "10.0",
"description": "Version",
"due_date": "2013-11-29",
+ "start_date": "2013-11-10",
"state": "active",
"updated_at": "2013-10-02T09:24:18Z",
"created_at": "2013-10-02T09:24:18Z"
@@ -69,6 +71,7 @@ Parameters:
- `title` (required) - The title of an milestone
- `description` (optional) - The description of the milestone
- `due_date` (optional) - The due date of the milestone
+- `start_date` (optional) - The start date of the milestone
## Edit milestone
@@ -85,6 +88,7 @@ Parameters:
- `title` (optional) - The title of a milestone
- `description` (optional) - The description of a milestone
- `due_date` (optional) - The due date of the milestone
+- `start_date` (optional) - The start date of the milestone
- `state_event` (optional) - The state event of the milestone (close|activate)
## Get all issues assigned to a single milestone
diff --git a/doc/api/projects.md b/doc/api/projects.md
index 467a880ac13..bd27a0a6fae 100644
--- a/doc/api/projects.md
+++ b/doc/api/projects.md
@@ -624,6 +624,7 @@ Parameters:
| `user_id` | integer | yes | The user ID of the project owner |
| `name` | string | yes | The name of the new project |
| `path` | string | no | Custom repository name for new project. By default generated based on name |
+| `default_branch` | string | no | `master` by default |
| `namespace_id` | integer | no | Namespace for the new project (defaults to the current user's namespace) |
| `description` | string | no | Short project description |
| `issues_enabled` | boolean | no | Enable issues for this project |
@@ -657,6 +658,7 @@ Parameters:
| `id` | integer/string | yes | The ID or NAMESPACE/PROJECT_NAME of the project |
| `name` | string | yes | The name of the project |
| `path` | string | no | Custom repository name for the project. By default generated based on name |
+| `default_branch` | string | no | `master` by default |
| `description` | string | no | Short project description |
| `issues_enabled` | boolean | no | Enable issues for this project |
| `merge_requests_enabled` | boolean | no | Enable merge requests for this project |
@@ -1074,6 +1076,25 @@ Parameters:
| `group_access` | integer | yes | The permissions level to grant the group |
| `expires_at` | string | no | Share expiration date in ISO 8601 format: 2016-09-26 |
+### Delete a shared project link within a group
+
+Unshare the project from the group. Returns `204` and no content on success.
+
+```
+DELETE /projects/:id/share/:group_id
+```
+
+Parameters:
+
+| Attribute | Type | Required | Description |
+| --------- | ---- | -------- | ----------- |
+| `id` | integer/string | yes | The ID of the project or NAMESPACE/PROJECT_NAME |
+| `group_id` | integer | yes | The ID of the group |
+
+```bash
+curl --request DELETE --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v3/projects/5/share/17
+```
+
## Hooks
Also called Project Hooks and Webhooks.
diff --git a/doc/api/services.md b/doc/api/services.md
index c7f537aceb6..a5d733fe6c7 100644
--- a/doc/api/services.md
+++ b/doc/api/services.md
@@ -465,10 +465,10 @@ GET /projects/:id/services/jira
Set JIRA service for a project.
->**Note:**
-Setting `project_url`, `issues_url` and `new_issue_url` will allow a user to
-easily navigate to the JIRA issue tracker. See the [integration doc][jira-doc]
-for details.
+>**Notes:**
+- Starting with GitLab 8.14, `api_url`, `issues_url`, `new_issue_url` and
+ `project_url` are replaced by `project_key`, `url`. If you are using an
+ older version, [follow this documentation][old-jira-api].
```
PUT /projects/:id/services/jira
@@ -477,11 +477,8 @@ PUT /projects/:id/services/jira
| Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `active` | boolean| no | Enable/disable the JIRA service. |
-| `project_url` | string | yes | The URL to the JIRA project which is being linked to this GitLab project. It is of the form: `https://<jira_host_url>/issues/?jql=project=<jira_project>`. |
-| `issues_url` | string | yes | The URL to the JIRA project issues overview for the project that is linked to this GitLab project. It is of the form: `https://<jira_host_url>/browse/:id`. Leave `:id` as-is, it gets replaced by GitLab at runtime.|
-| `new_issue_url` | string | yes | This is the URL to create a new issue in JIRA for the project linked to this GitLab project, and it is of the form: `https://<jira_host_url>/secure/CreateIssue.jspa` |
-| `api_url` | string | yes | The base URL of the JIRA API. It may be omitted, in which case GitLab will automatically use API version `2` based on the `project url`. It is of the form: `https://<jira_host_url>/rest/api/2`. |
-| `description` | string | no | A name for the issue tracker. |
+| `url` | string | yes | The URL to the JIRA project which is being linked to this GitLab project, e.g., `https://jira.example.com`. |
+| `project_key` | string | yes | The short identifier for your JIRA project, all uppercase, e.g., `PROJ`. |
| `username` | string | no | The username of the user created to be used with GitLab/JIRA. |
| `password` | string | no | The password of the user created to be used with GitLab/JIRA. |
| `jira_issue_transition_id` | string | no | The ID of a transition that moves issues to a closed state. You can find this number under the JIRA workflow administration (**Administration > Issues > Workflows**) by selecting **View** under **Operations** of the desired workflow of your project. The ID of each state can be found inside the parenthesis of each transition name under the **Transitions (id)** column ([see screenshot][trans]). By default, this ID is set to `2`. |
@@ -670,3 +667,4 @@ GET /projects/:id/services/teamcity
```
[jira-doc]: ../project_services/jira.md
+[old-jira-api]: https://gitlab.com/gitlab-org/gitlab-ce/blob/8-13-stable/doc/api/services.md#jira
diff --git a/doc/ci/img/builds_tab.png b/doc/ci/img/builds_tab.png
index 35780e277ae..2d7eec8a949 100644
--- a/doc/ci/img/builds_tab.png
+++ b/doc/ci/img/builds_tab.png
Binary files differ
diff --git a/doc/ci/img/deployments_view.png b/doc/ci/img/deployments_view.png
index ca6097cbea4..7ded0c97b72 100644
--- a/doc/ci/img/deployments_view.png
+++ b/doc/ci/img/deployments_view.png
Binary files differ
diff --git a/doc/ci/img/environments_available_staging.png b/doc/ci/img/environments_available_staging.png
index 784c4fd944c..5c031ad0d9d 100644
--- a/doc/ci/img/environments_available_staging.png
+++ b/doc/ci/img/environments_available_staging.png
Binary files differ
diff --git a/doc/ci/img/environments_dynamic_groups.png b/doc/ci/img/environments_dynamic_groups.png
index e89b66c502c..0f42b368c5b 100644
--- a/doc/ci/img/environments_dynamic_groups.png
+++ b/doc/ci/img/environments_dynamic_groups.png
Binary files differ
diff --git a/doc/ci/img/environments_link_url.png b/doc/ci/img/environments_link_url.png
index 224c21adfb5..44010f6aa6f 100644
--- a/doc/ci/img/environments_link_url.png
+++ b/doc/ci/img/environments_link_url.png
Binary files differ
diff --git a/doc/ci/img/environments_link_url_deployments.png b/doc/ci/img/environments_link_url_deployments.png
index 9419668a9bd..4f90143527a 100644
--- a/doc/ci/img/environments_link_url_deployments.png
+++ b/doc/ci/img/environments_link_url_deployments.png
Binary files differ
diff --git a/doc/ci/img/environments_link_url_mr.png b/doc/ci/img/environments_link_url_mr.png
index 3276dfb6096..64f134e0b0d 100644
--- a/doc/ci/img/environments_link_url_mr.png
+++ b/doc/ci/img/environments_link_url_mr.png
Binary files differ
diff --git a/doc/ci/img/environments_manual_action_builds.png b/doc/ci/img/environments_manual_action_builds.png
index d4bb7ccdbae..e7cf63a1031 100644
--- a/doc/ci/img/environments_manual_action_builds.png
+++ b/doc/ci/img/environments_manual_action_builds.png
Binary files differ
diff --git a/doc/ci/img/environments_manual_action_deployments.png b/doc/ci/img/environments_manual_action_deployments.png
index c2477381c80..2b3f6f3edad 100644
--- a/doc/ci/img/environments_manual_action_deployments.png
+++ b/doc/ci/img/environments_manual_action_deployments.png
Binary files differ
diff --git a/doc/ci/img/environments_manual_action_environments.png b/doc/ci/img/environments_manual_action_environments.png
index 56601c0db2d..e0c07604e7f 100644
--- a/doc/ci/img/environments_manual_action_environments.png
+++ b/doc/ci/img/environments_manual_action_environments.png
Binary files differ
diff --git a/doc/ci/img/environments_manual_action_pipelines.png b/doc/ci/img/environments_manual_action_pipelines.png
index eb6e87cd956..82bbae88027 100644
--- a/doc/ci/img/environments_manual_action_pipelines.png
+++ b/doc/ci/img/environments_manual_action_pipelines.png
Binary files differ
diff --git a/doc/ci/img/environments_manual_action_single_pipeline.png b/doc/ci/img/environments_manual_action_single_pipeline.png
index 9713ad212e2..36337cb1870 100644
--- a/doc/ci/img/environments_manual_action_single_pipeline.png
+++ b/doc/ci/img/environments_manual_action_single_pipeline.png
Binary files differ
diff --git a/doc/ci/img/environments_mr_review_app.png b/doc/ci/img/environments_mr_review_app.png
index a2ae25d62fa..7bff84362a3 100644
--- a/doc/ci/img/environments_mr_review_app.png
+++ b/doc/ci/img/environments_mr_review_app.png
Binary files differ
diff --git a/doc/ci/img/environments_view.png b/doc/ci/img/environments_view.png
index 131a9718cc4..821352188ef 100644
--- a/doc/ci/img/environments_view.png
+++ b/doc/ci/img/environments_view.png
Binary files differ
diff --git a/doc/ci/img/features_settings.png b/doc/ci/img/features_settings.png
index 38d7036f606..c159253d1c9 100644
--- a/doc/ci/img/features_settings.png
+++ b/doc/ci/img/features_settings.png
Binary files differ
diff --git a/doc/ci/img/pipelines.png b/doc/ci/img/pipelines.png
new file mode 100644
index 00000000000..5937e9d99c8
--- /dev/null
+++ b/doc/ci/img/pipelines.png
Binary files differ
diff --git a/doc/ci/pipelines.md b/doc/ci/pipelines.md
index 7d100a4fd93..03b9c4bb444 100644
--- a/doc/ci/pipelines.md
+++ b/doc/ci/pipelines.md
@@ -11,6 +11,8 @@ concurrent [Runners]), and if they all succeed, the pipeline moves on to the
next stage. If one of the builds fails, the next stage is not (usually)
executed.
+![Pipelines example](img/pipelines.png)
+
## Builds
Builds are individual runs of [jobs]. Not to be confused with a `build` job or
diff --git a/doc/ci/quick_start/img/build_log.png b/doc/ci/quick_start/img/build_log.png
index b53a6cd86b0..87643d62d58 100644
--- a/doc/ci/quick_start/img/build_log.png
+++ b/doc/ci/quick_start/img/build_log.png
Binary files differ
diff --git a/doc/ci/quick_start/img/builds_status.png b/doc/ci/quick_start/img/builds_status.png
index 47862761ffe..d287ae3064f 100644
--- a/doc/ci/quick_start/img/builds_status.png
+++ b/doc/ci/quick_start/img/builds_status.png
Binary files differ
diff --git a/doc/ci/quick_start/img/new_commit.png b/doc/ci/quick_start/img/new_commit.png
index a53562ce328..29c2fea5d6d 100644
--- a/doc/ci/quick_start/img/new_commit.png
+++ b/doc/ci/quick_start/img/new_commit.png
Binary files differ
diff --git a/doc/ci/quick_start/img/pipelines_status.png b/doc/ci/quick_start/img/pipelines_status.png
index 6bc97bb739c..53ccc49bd66 100644
--- a/doc/ci/quick_start/img/pipelines_status.png
+++ b/doc/ci/quick_start/img/pipelines_status.png
Binary files differ
diff --git a/doc/ci/quick_start/img/runners_activated.png b/doc/ci/quick_start/img/runners_activated.png
index 23261123b18..5ce6fe8e17c 100644
--- a/doc/ci/quick_start/img/runners_activated.png
+++ b/doc/ci/quick_start/img/runners_activated.png
Binary files differ
diff --git a/doc/ci/quick_start/img/single_commit_status_pending.png b/doc/ci/quick_start/img/single_commit_status_pending.png
index ccf3ac957bb..91fc9011847 100644
--- a/doc/ci/quick_start/img/single_commit_status_pending.png
+++ b/doc/ci/quick_start/img/single_commit_status_pending.png
Binary files differ
diff --git a/doc/ci/quick_start/img/status_pending.png b/doc/ci/quick_start/img/status_pending.png
index 9feacf0c961..cbd44a189d3 100644
--- a/doc/ci/quick_start/img/status_pending.png
+++ b/doc/ci/quick_start/img/status_pending.png
Binary files differ
diff --git a/doc/ci/review_apps/img/review_apps_preview_in_mr.png b/doc/ci/review_apps/img/review_apps_preview_in_mr.png
index 15bcb90518c..0300392f24b 100644
--- a/doc/ci/review_apps/img/review_apps_preview_in_mr.png
+++ b/doc/ci/review_apps/img/review_apps_preview_in_mr.png
Binary files differ
diff --git a/doc/ci/triggers/img/builds_page.png b/doc/ci/triggers/img/builds_page.png
index c2cf4b1852c..fded5839f76 100644
--- a/doc/ci/triggers/img/builds_page.png
+++ b/doc/ci/triggers/img/builds_page.png
Binary files differ
diff --git a/doc/ci/triggers/img/trigger_single_build.png b/doc/ci/triggers/img/trigger_single_build.png
index fa86f0fee3d..c4a5550d640 100644
--- a/doc/ci/triggers/img/trigger_single_build.png
+++ b/doc/ci/triggers/img/trigger_single_build.png
Binary files differ
diff --git a/doc/ci/triggers/img/trigger_variables.png b/doc/ci/triggers/img/trigger_variables.png
index b2fcc65d304..65fe1ea9ab6 100644
--- a/doc/ci/triggers/img/trigger_variables.png
+++ b/doc/ci/triggers/img/trigger_variables.png
Binary files differ
diff --git a/doc/ci/triggers/img/triggers_page.png b/doc/ci/triggers/img/triggers_page.png
index 438f285ae2d..56d13905ce6 100644
--- a/doc/ci/triggers/img/triggers_page.png
+++ b/doc/ci/triggers/img/triggers_page.png
Binary files differ
diff --git a/doc/customization/branded_login_page/appearance.png b/doc/customization/branded_login_page/appearance.png
index 023dc5599b4..31ea4559d37 100644
--- a/doc/customization/branded_login_page/appearance.png
+++ b/doc/customization/branded_login_page/appearance.png
Binary files differ
diff --git a/doc/customization/branded_login_page/custom_sign_in.png b/doc/customization/branded_login_page/custom_sign_in.png
index 7d99e0a2b3b..c0888fe1f18 100644
--- a/doc/customization/branded_login_page/custom_sign_in.png
+++ b/doc/customization/branded_login_page/custom_sign_in.png
Binary files differ
diff --git a/doc/customization/branded_login_page/default_login_page.png b/doc/customization/branded_login_page/default_login_page.png
index 0cfa9da202e..9b1233cef45 100644
--- a/doc/customization/branded_login_page/default_login_page.png
+++ b/doc/customization/branded_login_page/default_login_page.png
Binary files differ
diff --git a/doc/development/README.md b/doc/development/README.md
index 371bb55c127..6f2ca7b8590 100644
--- a/doc/development/README.md
+++ b/doc/development/README.md
@@ -38,6 +38,7 @@
- [Rake tasks](rake_tasks.md) for development
- [Shell commands](shell_commands.md) in the GitLab codebase
- [Sidekiq debugging](sidekiq_debugging.md)
+- [Object state models](object_state_models.md)
## Databases
diff --git a/doc/development/gitlab_architecture_diagram.png b/doc/development/gitlab_architecture_diagram.png
index 80e975718e0..cda5ce254ce 100644
--- a/doc/development/gitlab_architecture_diagram.png
+++ b/doc/development/gitlab_architecture_diagram.png
Binary files differ
diff --git a/doc/development/img/state-model-issue.png b/doc/development/img/state-model-issue.png
new file mode 100644
index 00000000000..ee33b6886c6
--- /dev/null
+++ b/doc/development/img/state-model-issue.png
Binary files differ
diff --git a/doc/development/img/state-model-legend.png b/doc/development/img/state-model-legend.png
new file mode 100644
index 00000000000..1c121f2588c
--- /dev/null
+++ b/doc/development/img/state-model-legend.png
Binary files differ
diff --git a/doc/development/img/state-model-merge-request.png b/doc/development/img/state-model-merge-request.png
new file mode 100644
index 00000000000..e00da10cac2
--- /dev/null
+++ b/doc/development/img/state-model-merge-request.png
Binary files differ
diff --git a/doc/development/object_state_models.md b/doc/development/object_state_models.md
new file mode 100644
index 00000000000..623bbf143ef
--- /dev/null
+++ b/doc/development/object_state_models.md
@@ -0,0 +1,25 @@
+# Object state models
+
+## Diagrams
+
+[GitLab object state models](https://drive.google.com/drive/u/3/folders/0B5tDlHAM4iZINmpvYlJXcDVqMGc)
+
+---
+
+## Legend
+
+![legend](img/state-model-legend.png)
+
+---
+
+## Issue
+
+[`app/models/issue.rb`](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/app/models/issue.rb)
+![issue](img/state-model-issue.png)
+
+---
+
+## Merge request
+
+[`app/models/merge_request.rb`](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/app/models/merge_request.rb)
+![merge request](img/state-model-merge-request.png) \ No newline at end of file
diff --git a/doc/development/testing.md b/doc/development/testing.md
index 6106e47daa0..dbea6b9c9aa 100644
--- a/doc/development/testing.md
+++ b/doc/development/testing.md
@@ -63,6 +63,8 @@ the command line via `bundle exec teaspoon`, or via a web browser at
- Use `.method` to describe class methods and `#method` to describe instance
methods.
- Use `context` to test branching logic.
+- Use multi-line `do...end` blocks for `before` and `after`, even when it would
+ fit on a single line.
- Don't `describe` symbols (see [Gotchas](gotchas.md#dont-describe-symbols)).
- Don't assert against the absolute value of a sequence-generated attribute (see [Gotchas](gotchas.md#dont-assert-against-the-absolute-value-of-a-sequence-generated-attribute)).
- Don't supply the `:each` argument to hooks since it's the default.
diff --git a/doc/development/ux_guide/copy.md b/doc/development/ux_guide/copy.md
index 227b4fd3451..b557fb47120 100644
--- a/doc/development/ux_guide/copy.md
+++ b/doc/development/ux_guide/copy.md
@@ -96,4 +96,6 @@ The form should be titled `Edit issue`. The submit button should be labeled `Sav
| Add | Add a merge request | Do not use `create` or `new` |
| View | View an open or merged merge request ||
| Edit | Edit an open or merged merge request| Do not use `update` |
-| Merge | Merge an open merge request || \ No newline at end of file
+| Approve | Approve an open merge request ||
+| Remove approval, unapproved | Remove approval of an open merge request | Do not use `unapprove` as that is not an English word|
+| Merge | Merge an open merge request ||
diff --git a/doc/development/ux_guide/img/button-primary.png b/doc/development/ux_guide/img/button-primary.png
index f4c673f5b88..eda5ed84aec 100644
--- a/doc/development/ux_guide/img/button-primary.png
+++ b/doc/development/ux_guide/img/button-primary.png
Binary files differ
diff --git a/doc/development/ux_guide/img/button-secondary.png b/doc/development/ux_guide/img/button-secondary.png
index 57fa65b247c..26d4e8cf43d 100644
--- a/doc/development/ux_guide/img/button-secondary.png
+++ b/doc/development/ux_guide/img/button-secondary.png
Binary files differ
diff --git a/doc/development/ux_guide/img/color-blue.png b/doc/development/ux_guide/img/color-blue.png
index 6449613eb16..2ca360173eb 100644
--- a/doc/development/ux_guide/img/color-blue.png
+++ b/doc/development/ux_guide/img/color-blue.png
Binary files differ
diff --git a/doc/development/ux_guide/img/color-green.png b/doc/development/ux_guide/img/color-green.png
index 15475b36f02..489db8f4343 100644
--- a/doc/development/ux_guide/img/color-green.png
+++ b/doc/development/ux_guide/img/color-green.png
Binary files differ
diff --git a/doc/development/ux_guide/img/color-orange.png b/doc/development/ux_guide/img/color-orange.png
index f4fc09b2d9b..4c4b772d438 100644
--- a/doc/development/ux_guide/img/color-orange.png
+++ b/doc/development/ux_guide/img/color-orange.png
Binary files differ
diff --git a/doc/development/ux_guide/img/color-red.png b/doc/development/ux_guide/img/color-red.png
index 6fbbf0a885d..3440ad48f05 100644
--- a/doc/development/ux_guide/img/color-red.png
+++ b/doc/development/ux_guide/img/color-red.png
Binary files differ
diff --git a/doc/development/ux_guide/img/components-alerts.png b/doc/development/ux_guide/img/components-alerts.png
index 0b2ecc16a5f..66a43ac69e1 100644
--- a/doc/development/ux_guide/img/components-alerts.png
+++ b/doc/development/ux_guide/img/components-alerts.png
Binary files differ
diff --git a/doc/development/ux_guide/img/components-anchorlinks.png b/doc/development/ux_guide/img/components-anchorlinks.png
index 950f348277d..7dd6a8a3876 100644
--- a/doc/development/ux_guide/img/components-anchorlinks.png
+++ b/doc/development/ux_guide/img/components-anchorlinks.png
Binary files differ
diff --git a/doc/development/ux_guide/img/components-contentblock.png b/doc/development/ux_guide/img/components-contentblock.png
index 31fc1eec9df..58d87729701 100644
--- a/doc/development/ux_guide/img/components-contentblock.png
+++ b/doc/development/ux_guide/img/components-contentblock.png
Binary files differ
diff --git a/doc/development/ux_guide/img/components-coverblock.png b/doc/development/ux_guide/img/components-coverblock.png
index c8f1f87a108..fb135f9648a 100644
--- a/doc/development/ux_guide/img/components-coverblock.png
+++ b/doc/development/ux_guide/img/components-coverblock.png
Binary files differ
diff --git a/doc/development/ux_guide/img/components-dateexact.png b/doc/development/ux_guide/img/components-dateexact.png
index 8c0c5c1be40..686ca727293 100644
--- a/doc/development/ux_guide/img/components-dateexact.png
+++ b/doc/development/ux_guide/img/components-dateexact.png
Binary files differ
diff --git a/doc/development/ux_guide/img/components-daterelative.png b/doc/development/ux_guide/img/components-daterelative.png
index 1dc6d89e4ef..4954dfb51b3 100644
--- a/doc/development/ux_guide/img/components-daterelative.png
+++ b/doc/development/ux_guide/img/components-daterelative.png
Binary files differ
diff --git a/doc/development/ux_guide/img/components-dropdown.png b/doc/development/ux_guide/img/components-dropdown.png
index 5770a393b37..7f9a701c089 100644
--- a/doc/development/ux_guide/img/components-dropdown.png
+++ b/doc/development/ux_guide/img/components-dropdown.png
Binary files differ
diff --git a/doc/development/ux_guide/img/components-fileholder.png b/doc/development/ux_guide/img/components-fileholder.png
index 4b8962905d6..ec2911a1232 100644
--- a/doc/development/ux_guide/img/components-fileholder.png
+++ b/doc/development/ux_guide/img/components-fileholder.png
Binary files differ
diff --git a/doc/development/ux_guide/img/components-horizontalform.png b/doc/development/ux_guide/img/components-horizontalform.png
index 92e28cf9afc..c57dceda43a 100644
--- a/doc/development/ux_guide/img/components-horizontalform.png
+++ b/doc/development/ux_guide/img/components-horizontalform.png
Binary files differ
diff --git a/doc/development/ux_guide/img/components-listinsidepanel.png b/doc/development/ux_guide/img/components-listinsidepanel.png
index 30ceb3eaa08..3a72d39bb5d 100644
--- a/doc/development/ux_guide/img/components-listinsidepanel.png
+++ b/doc/development/ux_guide/img/components-listinsidepanel.png
Binary files differ
diff --git a/doc/development/ux_guide/img/components-listwithavatar.png b/doc/development/ux_guide/img/components-listwithavatar.png
index d3cb0ebc02b..f6db575433c 100644
--- a/doc/development/ux_guide/img/components-listwithavatar.png
+++ b/doc/development/ux_guide/img/components-listwithavatar.png
Binary files differ
diff --git a/doc/development/ux_guide/img/components-listwithhover.png b/doc/development/ux_guide/img/components-listwithhover.png
index 1484ecba6a0..8521a8ad53e 100644
--- a/doc/development/ux_guide/img/components-listwithhover.png
+++ b/doc/development/ux_guide/img/components-listwithhover.png
Binary files differ
diff --git a/doc/development/ux_guide/img/components-panels.png b/doc/development/ux_guide/img/components-panels.png
index 6e71d0ad9c9..c1391ca07e5 100644
--- a/doc/development/ux_guide/img/components-panels.png
+++ b/doc/development/ux_guide/img/components-panels.png
Binary files differ
diff --git a/doc/development/ux_guide/img/components-referencehover.png b/doc/development/ux_guide/img/components-referencehover.png
index e9fb27e2aa9..f80564dbb16 100644
--- a/doc/development/ux_guide/img/components-referencehover.png
+++ b/doc/development/ux_guide/img/components-referencehover.png
Binary files differ
diff --git a/doc/development/ux_guide/img/components-referenceissues.png b/doc/development/ux_guide/img/components-referenceissues.png
index caf9477db38..51fb2cf3e43 100644
--- a/doc/development/ux_guide/img/components-referenceissues.png
+++ b/doc/development/ux_guide/img/components-referenceissues.png
Binary files differ
diff --git a/doc/development/ux_guide/img/components-referencelabels.png b/doc/development/ux_guide/img/components-referencelabels.png
index a122b45d1f1..aba450cc3ba 100644
--- a/doc/development/ux_guide/img/components-referencelabels.png
+++ b/doc/development/ux_guide/img/components-referencelabels.png
Binary files differ
diff --git a/doc/development/ux_guide/img/components-referencemilestone.png b/doc/development/ux_guide/img/components-referencemilestone.png
index 5aa9ecd1a78..adf2555ccf8 100644
--- a/doc/development/ux_guide/img/components-referencemilestone.png
+++ b/doc/development/ux_guide/img/components-referencemilestone.png
Binary files differ
diff --git a/doc/development/ux_guide/img/components-referencemrs.png b/doc/development/ux_guide/img/components-referencemrs.png
index 6280243859a..6c3375f1ea1 100644
--- a/doc/development/ux_guide/img/components-referencemrs.png
+++ b/doc/development/ux_guide/img/components-referencemrs.png
Binary files differ
diff --git a/doc/development/ux_guide/img/components-referencepeople.png b/doc/development/ux_guide/img/components-referencepeople.png
index 99772a539cf..b8dd431e2e6 100644
--- a/doc/development/ux_guide/img/components-referencepeople.png
+++ b/doc/development/ux_guide/img/components-referencepeople.png
Binary files differ
diff --git a/doc/development/ux_guide/img/components-rowcontentblock.png b/doc/development/ux_guide/img/components-rowcontentblock.png
index 1c2d7096955..c66a50f9564 100644
--- a/doc/development/ux_guide/img/components-rowcontentblock.png
+++ b/doc/development/ux_guide/img/components-rowcontentblock.png
Binary files differ
diff --git a/doc/development/ux_guide/img/components-simplelist.png b/doc/development/ux_guide/img/components-simplelist.png
index 892f507cfc2..858e5064c25 100644
--- a/doc/development/ux_guide/img/components-simplelist.png
+++ b/doc/development/ux_guide/img/components-simplelist.png
Binary files differ
diff --git a/doc/development/ux_guide/img/components-table.png b/doc/development/ux_guide/img/components-table.png
index 7e964c885cf..cedc55758a9 100644
--- a/doc/development/ux_guide/img/components-table.png
+++ b/doc/development/ux_guide/img/components-table.png
Binary files differ
diff --git a/doc/development/ux_guide/img/components-verticalform.png b/doc/development/ux_guide/img/components-verticalform.png
index 38863ad3c1c..489ae6f862f 100644
--- a/doc/development/ux_guide/img/components-verticalform.png
+++ b/doc/development/ux_guide/img/components-verticalform.png
Binary files differ
diff --git a/doc/development/ux_guide/img/copy-form-addissuebutton.png b/doc/development/ux_guide/img/copy-form-addissuebutton.png
index 18839d447e8..8457f0ab2ab 100644
--- a/doc/development/ux_guide/img/copy-form-addissuebutton.png
+++ b/doc/development/ux_guide/img/copy-form-addissuebutton.png
Binary files differ
diff --git a/doc/development/ux_guide/img/copy-form-addissueform.png b/doc/development/ux_guide/img/copy-form-addissueform.png
index e6838c06eca..89c6b4acdfb 100644
--- a/doc/development/ux_guide/img/copy-form-addissueform.png
+++ b/doc/development/ux_guide/img/copy-form-addissueform.png
Binary files differ
diff --git a/doc/development/ux_guide/img/copy-form-editissuebutton.png b/doc/development/ux_guide/img/copy-form-editissuebutton.png
index 2435820e14f..04bcc2bf831 100644
--- a/doc/development/ux_guide/img/copy-form-editissuebutton.png
+++ b/doc/development/ux_guide/img/copy-form-editissuebutton.png
Binary files differ
diff --git a/doc/development/ux_guide/img/copy-form-editissueform.png b/doc/development/ux_guide/img/copy-form-editissueform.png
index 5ddeda33e68..126ef34ea7e 100644
--- a/doc/development/ux_guide/img/copy-form-editissueform.png
+++ b/doc/development/ux_guide/img/copy-form-editissueform.png
Binary files differ
diff --git a/doc/development/ux_guide/img/features-contextualnav.png b/doc/development/ux_guide/img/features-contextualnav.png
index df157f54c84..f8466f28627 100644
--- a/doc/development/ux_guide/img/features-contextualnav.png
+++ b/doc/development/ux_guide/img/features-contextualnav.png
Binary files differ
diff --git a/doc/development/ux_guide/img/features-emptystates.png b/doc/development/ux_guide/img/features-emptystates.png
index 3befc14588e..51835a7080b 100644
--- a/doc/development/ux_guide/img/features-emptystates.png
+++ b/doc/development/ux_guide/img/features-emptystates.png
Binary files differ
diff --git a/doc/development/ux_guide/img/features-filters.png b/doc/development/ux_guide/img/features-filters.png
index 281e55d590c..41db76db938 100644
--- a/doc/development/ux_guide/img/features-filters.png
+++ b/doc/development/ux_guide/img/features-filters.png
Binary files differ
diff --git a/doc/development/ux_guide/img/features-globalnav.png b/doc/development/ux_guide/img/features-globalnav.png
index 3c0db2247ca..73294d1b524 100644
--- a/doc/development/ux_guide/img/features-globalnav.png
+++ b/doc/development/ux_guide/img/features-globalnav.png
Binary files differ
diff --git a/doc/development/ux_guide/img/surfaces-contentitemtitle.png b/doc/development/ux_guide/img/surfaces-contentitemtitle.png
index 2eb926c1c43..3af0b56c8fb 100644
--- a/doc/development/ux_guide/img/surfaces-contentitemtitle.png
+++ b/doc/development/ux_guide/img/surfaces-contentitemtitle.png
Binary files differ
diff --git a/doc/development/ux_guide/img/surfaces-header.png b/doc/development/ux_guide/img/surfaces-header.png
index ab44d4de696..ba616388003 100644
--- a/doc/development/ux_guide/img/surfaces-header.png
+++ b/doc/development/ux_guide/img/surfaces-header.png
Binary files differ
diff --git a/doc/development/ux_guide/img/surfaces-systeminformationblock.png b/doc/development/ux_guide/img/surfaces-systeminformationblock.png
index 5d91e993e24..9f42f1d4dd0 100644
--- a/doc/development/ux_guide/img/surfaces-systeminformationblock.png
+++ b/doc/development/ux_guide/img/surfaces-systeminformationblock.png
Binary files differ
diff --git a/doc/development/ux_guide/img/surfaces-ux.png b/doc/development/ux_guide/img/surfaces-ux.png
index e692c51e8c0..53208727c64 100644
--- a/doc/development/ux_guide/img/surfaces-ux.png
+++ b/doc/development/ux_guide/img/surfaces-ux.png
Binary files differ
diff --git a/doc/development/ux_guide/img/tooltip-placement.png b/doc/development/ux_guide/img/tooltip-placement.png
index 29a61c8400a..061f82e4df0 100644
--- a/doc/development/ux_guide/img/tooltip-placement.png
+++ b/doc/development/ux_guide/img/tooltip-placement.png
Binary files differ
diff --git a/doc/development/ux_guide/img/tooltip-usage.png b/doc/development/ux_guide/img/tooltip-usage.png
index e8e4c6ded91..40c4f051cd0 100644
--- a/doc/development/ux_guide/img/tooltip-usage.png
+++ b/doc/development/ux_guide/img/tooltip-usage.png
Binary files differ
diff --git a/doc/gitlab-basics/img/create_new_group_info.png b/doc/gitlab-basics/img/create_new_group_info.png
index c8eddfd1bbb..020b4ac00d6 100644
--- a/doc/gitlab-basics/img/create_new_group_info.png
+++ b/doc/gitlab-basics/img/create_new_group_info.png
Binary files differ
diff --git a/doc/gitlab-basics/img/create_new_group_sidebar.png b/doc/gitlab-basics/img/create_new_group_sidebar.png
index 28017ee02e0..fa88d1d51c0 100644
--- a/doc/gitlab-basics/img/create_new_group_sidebar.png
+++ b/doc/gitlab-basics/img/create_new_group_sidebar.png
Binary files differ
diff --git a/doc/gitlab-basics/img/create_new_project_button.png b/doc/gitlab-basics/img/create_new_project_button.png
index e7c794d943f..a19f0e57b56 100644
--- a/doc/gitlab-basics/img/create_new_project_button.png
+++ b/doc/gitlab-basics/img/create_new_project_button.png
Binary files differ
diff --git a/doc/gitlab-basics/img/create_new_project_from_group.png b/doc/gitlab-basics/img/create_new_project_from_group.png
index 6d41d17f9ca..c35234660db 100644
--- a/doc/gitlab-basics/img/create_new_project_from_group.png
+++ b/doc/gitlab-basics/img/create_new_project_from_group.png
Binary files differ
diff --git a/doc/gitlab-basics/img/create_new_project_info.png b/doc/gitlab-basics/img/create_new_project_info.png
index 16d56f0707f..fcfbca87b91 100644
--- a/doc/gitlab-basics/img/create_new_project_info.png
+++ b/doc/gitlab-basics/img/create_new_project_info.png
Binary files differ
diff --git a/doc/gitlab-basics/img/fork_choose_namespace.png b/doc/gitlab-basics/img/fork_choose_namespace.png
index 82c9c3bd39e..4c50276d5ad 100644
--- a/doc/gitlab-basics/img/fork_choose_namespace.png
+++ b/doc/gitlab-basics/img/fork_choose_namespace.png
Binary files differ
diff --git a/doc/gitlab-basics/img/fork_new.png b/doc/gitlab-basics/img/fork_new.png
index 41885223286..fa185fdaca1 100644
--- a/doc/gitlab-basics/img/fork_new.png
+++ b/doc/gitlab-basics/img/fork_new.png
Binary files differ
diff --git a/doc/gitlab-basics/img/merge_request_new.png b/doc/gitlab-basics/img/merge_request_new.png
index 0aba5743f01..6fcd7bebada 100644
--- a/doc/gitlab-basics/img/merge_request_new.png
+++ b/doc/gitlab-basics/img/merge_request_new.png
Binary files differ
diff --git a/doc/gitlab-basics/img/merge_request_page.png b/doc/gitlab-basics/img/merge_request_page.png
index 68c3bbf9444..f6087294e22 100644
--- a/doc/gitlab-basics/img/merge_request_page.png
+++ b/doc/gitlab-basics/img/merge_request_page.png
Binary files differ
diff --git a/doc/gitlab-basics/img/merge_request_select_branch.png b/doc/gitlab-basics/img/merge_request_select_branch.png
index 516436ff6cc..9f6b93943a9 100644
--- a/doc/gitlab-basics/img/merge_request_select_branch.png
+++ b/doc/gitlab-basics/img/merge_request_select_branch.png
Binary files differ
diff --git a/doc/gitlab-basics/img/new_issue_button.png b/doc/gitlab-basics/img/new_issue_button.png
index 46b626bed65..3b113471f0c 100644
--- a/doc/gitlab-basics/img/new_issue_button.png
+++ b/doc/gitlab-basics/img/new_issue_button.png
Binary files differ
diff --git a/doc/gitlab-basics/img/new_issue_page.png b/doc/gitlab-basics/img/new_issue_page.png
index 843504130b7..ce3e60df276 100644
--- a/doc/gitlab-basics/img/new_issue_page.png
+++ b/doc/gitlab-basics/img/new_issue_page.png
Binary files differ
diff --git a/doc/gitlab-basics/img/profile_settings.png b/doc/gitlab-basics/img/profile_settings.png
index f0abd478849..26df4c0a734 100644
--- a/doc/gitlab-basics/img/profile_settings.png
+++ b/doc/gitlab-basics/img/profile_settings.png
Binary files differ
diff --git a/doc/gitlab-basics/img/profile_settings_ssh_keys.png b/doc/gitlab-basics/img/profile_settings_ssh_keys.png
index 2c9a42fe10c..8ac603a2af9 100644
--- a/doc/gitlab-basics/img/profile_settings_ssh_keys.png
+++ b/doc/gitlab-basics/img/profile_settings_ssh_keys.png
Binary files differ
diff --git a/doc/gitlab-basics/img/profile_settings_ssh_keys_paste_pub.png b/doc/gitlab-basics/img/profile_settings_ssh_keys_paste_pub.png
index cd7add6937f..5e501ec86ef 100644
--- a/doc/gitlab-basics/img/profile_settings_ssh_keys_paste_pub.png
+++ b/doc/gitlab-basics/img/profile_settings_ssh_keys_paste_pub.png
Binary files differ
diff --git a/doc/gitlab-basics/img/profile_settings_ssh_keys_single_key.png b/doc/gitlab-basics/img/profile_settings_ssh_keys_single_key.png
index 095beb02be8..6a1430d9663 100644
--- a/doc/gitlab-basics/img/profile_settings_ssh_keys_single_key.png
+++ b/doc/gitlab-basics/img/profile_settings_ssh_keys_single_key.png
Binary files differ
diff --git a/doc/gitlab-basics/img/profile_settings_ssh_keys_title.png b/doc/gitlab-basics/img/profile_settings_ssh_keys_title.png
index 4b998a7f948..89a04c17fed 100644
--- a/doc/gitlab-basics/img/profile_settings_ssh_keys_title.png
+++ b/doc/gitlab-basics/img/profile_settings_ssh_keys_title.png
Binary files differ
diff --git a/doc/gitlab-basics/img/project_clone_url.png b/doc/gitlab-basics/img/project_clone_url.png
index eed430e1036..bdd7d011db3 100644
--- a/doc/gitlab-basics/img/project_clone_url.png
+++ b/doc/gitlab-basics/img/project_clone_url.png
Binary files differ
diff --git a/doc/gitlab-basics/img/project_navbar.png b/doc/gitlab-basics/img/project_navbar.png
index 97cf3cd9702..be6f38ede32 100644
--- a/doc/gitlab-basics/img/project_navbar.png
+++ b/doc/gitlab-basics/img/project_navbar.png
Binary files differ
diff --git a/doc/gitlab-basics/img/select_group_dropdown.png b/doc/gitlab-basics/img/select_group_dropdown.png
index 7d8b89c2df9..68fc950304c 100644
--- a/doc/gitlab-basics/img/select_group_dropdown.png
+++ b/doc/gitlab-basics/img/select_group_dropdown.png
Binary files differ
diff --git a/doc/install/database_mysql.md b/doc/install/database_mysql.md
index e8093f0b257..322680f0cf4 100644
--- a/doc/install/database_mysql.md
+++ b/doc/install/database_mysql.md
@@ -57,8 +57,15 @@ We do not recommend using MySQL due to various issues. For example, case [(in)se
After installation or upgrade, remember to run the `add_limits_mysql` Rake task:
+**Omnibus GitLab installations**
```
-bundle exec rake add_limits_mysql
+sudo gitlab-rake add_limits_mysql
+```
+
+**Installations from source**
+
+```
+bundle exec rake add_limits_mysql RAILS_ENV=production
```
The `text` type in MySQL has a different size limit than the `text` type in
diff --git a/doc/install/installation.md b/doc/install/installation.md
index b5e2640b380..dabd69d7466 100644
--- a/doc/install/installation.md
+++ b/doc/install/installation.md
@@ -175,17 +175,17 @@ We recommend using a PostgreSQL database. For MySQL check the
```bash
sudo -u postgres psql -d template1 -c "CREATE USER git CREATEDB;"
```
-
-1. Create the GitLab production database and grant all privileges on database:
+
+1. Create the `pg_trgm` extension (required for GitLab 8.6+):
```bash
- sudo -u postgres psql -d template1 -c "CREATE DATABASE gitlabhq_production OWNER git;"
+ sudo -u postgres psql -d template1 -c "CREATE EXTENSION IF NOT EXISTS pg_trgm;"
```
-1. Create the `pg_trgm` extension (required for GitLab 8.6+):
+1. Create the GitLab production database and grant all privileges on database:
```bash
- sudo -u postgres psql -d template1 -c "CREATE EXTENSION IF NOT EXISTS pg_trgm;"
+ sudo -u postgres psql -d template1 -c "CREATE DATABASE gitlabhq_production OWNER git;"
```
1. Try connecting to the new database with the new user:
diff --git a/doc/install/requirements.md b/doc/install/requirements.md
index 42b515761e0..e942346e2d7 100644
--- a/doc/install/requirements.md
+++ b/doc/install/requirements.md
@@ -143,6 +143,6 @@ On a very active server (10,000 active users) the Sidekiq process can use 1GB+ o
## Supported web browsers
-We support the current and the previous major release of Firefox, Safari and Microsoft browsers (Microsoft Edge and Internet Explorer 11).
+We support the current and the previous major release of Firefox, Chrome/Chromium, Safari and Microsoft browsers (Microsoft Edge and Internet Explorer 11).
Each time a new browser version is released, we begin supporting that version and stop supporting the third most recent version.
diff --git a/doc/integration/README.md b/doc/integration/README.md
index ae4387e2577..f8ffa6dcb7f 100644
--- a/doc/integration/README.md
+++ b/doc/integration/README.md
@@ -5,7 +5,7 @@ trackers and external authentication.
See the documentation below for details on how to configure these services.
-- [Jira](../project_services/jira.md) Integrate with the JIRA issue tracker
+- [JIRA](../project_services/jira.md) Integrate with the JIRA issue tracker
- [External issue tracker](external-issue-tracker.md) Redmine, JIRA, etc.
- [LDAP](ldap.md) Set up sign in via LDAP
- [OmniAuth](omniauth.md) Sign in via Twitter, GitHub, GitLab.com, Google, Bitbucket, Facebook, Shibboleth, SAML, Crowd and Azure
diff --git a/doc/integration/github.md b/doc/integration/github.md
index 8a01afd1177..479c697b933 100644
--- a/doc/integration/github.md
+++ b/doc/integration/github.md
@@ -48,6 +48,21 @@ GitHub will generate an application ID and secret key for you to use.
For omnibus package:
+ For GitHub.com:
+
+ ```ruby
+ gitlab_rails['omniauth_providers'] = [
+ {
+ "name" => "github",
+ "app_id" => "YOUR_APP_ID",
+ "app_secret" => "YOUR_APP_SECRET",
+ "args" => { "scope" => "user:email" }
+ }
+ ]
+ ```
+
+ For GitHub Enterprise:
+
```ruby
gitlab_rails['omniauth_providers'] = [
{
@@ -86,7 +101,7 @@ GitHub will generate an application ID and secret key for you to use.
1. Change 'YOUR_APP_SECRET' to the client secret from the GitHub application page from step 7.
-1. Save the configuration file.
+1. Save the configuration file and run `sudo gitlab-ctl reconfigure`.
1. Restart GitLab for the changes to take effect.
diff --git a/doc/integration/img/akismet_settings.png b/doc/integration/img/akismet_settings.png
index c2aa97b132e..689654bf960 100644
--- a/doc/integration/img/akismet_settings.png
+++ b/doc/integration/img/akismet_settings.png
Binary files differ
diff --git a/doc/integration/img/bitbucket_oauth_keys.png b/doc/integration/img/bitbucket_oauth_keys.png
index 3fb2f7524a3..6dd2c7d744e 100644
--- a/doc/integration/img/bitbucket_oauth_keys.png
+++ b/doc/integration/img/bitbucket_oauth_keys.png
Binary files differ
diff --git a/doc/integration/img/bitbucket_oauth_settings_page.png b/doc/integration/img/bitbucket_oauth_settings_page.png
index a3047712d8c..8dbee9762d7 100644
--- a/doc/integration/img/bitbucket_oauth_settings_page.png
+++ b/doc/integration/img/bitbucket_oauth_settings_page.png
Binary files differ
diff --git a/doc/integration/img/enabled-oauth-sign-in-sources.png b/doc/integration/img/enabled-oauth-sign-in-sources.png
index b23d6dcc595..f145aeae75c 100644
--- a/doc/integration/img/enabled-oauth-sign-in-sources.png
+++ b/doc/integration/img/enabled-oauth-sign-in-sources.png
Binary files differ
diff --git a/doc/integration/img/facebook_api_keys.png b/doc/integration/img/facebook_api_keys.png
index 995845d5a69..9463ec1e7a3 100644
--- a/doc/integration/img/facebook_api_keys.png
+++ b/doc/integration/img/facebook_api_keys.png
Binary files differ
diff --git a/doc/integration/img/facebook_app_settings.png b/doc/integration/img/facebook_app_settings.png
index 1cd586ecd7c..81f38cab16e 100644
--- a/doc/integration/img/facebook_app_settings.png
+++ b/doc/integration/img/facebook_app_settings.png
Binary files differ
diff --git a/doc/integration/img/facebook_website_url.png b/doc/integration/img/facebook_website_url.png
index 10e1bd5d5a6..67d78d13951 100644
--- a/doc/integration/img/facebook_website_url.png
+++ b/doc/integration/img/facebook_website_url.png
Binary files differ
diff --git a/doc/integration/img/github_app.png b/doc/integration/img/github_app.png
index de31242679a..d6c289a1de1 100644
--- a/doc/integration/img/github_app.png
+++ b/doc/integration/img/github_app.png
Binary files differ
diff --git a/doc/integration/img/gitlab_app.png b/doc/integration/img/gitlab_app.png
index 065316fd3c7..b4958581a9b 100644
--- a/doc/integration/img/gitlab_app.png
+++ b/doc/integration/img/gitlab_app.png
Binary files differ
diff --git a/doc/integration/img/gmail_action_buttons_for_gitlab.png b/doc/integration/img/gmail_action_buttons_for_gitlab.png
index a6704139091..0e3e24d6ffc 100644
--- a/doc/integration/img/gmail_action_buttons_for_gitlab.png
+++ b/doc/integration/img/gmail_action_buttons_for_gitlab.png
Binary files differ
diff --git a/doc/integration/img/google_app.png b/doc/integration/img/google_app.png
index 08f7f714553..9fda06dabb1 100644
--- a/doc/integration/img/google_app.png
+++ b/doc/integration/img/google_app.png
Binary files differ
diff --git a/doc/integration/img/jira_add_user_to_group.png b/doc/integration/img/jira_add_user_to_group.png
deleted file mode 100644
index 0ba737bda9a..00000000000
--- a/doc/integration/img/jira_add_user_to_group.png
+++ /dev/null
Binary files differ
diff --git a/doc/integration/img/jira_create_new_group.png b/doc/integration/img/jira_create_new_group.png
deleted file mode 100644
index 0609060cb05..00000000000
--- a/doc/integration/img/jira_create_new_group.png
+++ /dev/null
Binary files differ
diff --git a/doc/integration/img/jira_create_new_group_name.png b/doc/integration/img/jira_create_new_group_name.png
deleted file mode 100644
index 53d77b17df0..00000000000
--- a/doc/integration/img/jira_create_new_group_name.png
+++ /dev/null
Binary files differ
diff --git a/doc/integration/img/jira_create_new_user.png b/doc/integration/img/jira_create_new_user.png
deleted file mode 100644
index 9eaa444ed25..00000000000
--- a/doc/integration/img/jira_create_new_user.png
+++ /dev/null
Binary files differ
diff --git a/doc/integration/img/jira_group_access.png b/doc/integration/img/jira_group_access.png
deleted file mode 100644
index 8d4657427ae..00000000000
--- a/doc/integration/img/jira_group_access.png
+++ /dev/null
Binary files differ
diff --git a/doc/integration/img/jira_issue_reference.png b/doc/integration/img/jira_issue_reference.png
deleted file mode 100644
index 1a2d9f04a6c..00000000000
--- a/doc/integration/img/jira_issue_reference.png
+++ /dev/null
Binary files differ
diff --git a/doc/integration/img/jira_merge_request_close.png b/doc/integration/img/jira_merge_request_close.png
deleted file mode 100644
index b8f6058a514..00000000000
--- a/doc/integration/img/jira_merge_request_close.png
+++ /dev/null
Binary files differ
diff --git a/doc/integration/img/jira_project_name.png b/doc/integration/img/jira_project_name.png
deleted file mode 100644
index e785ec6140d..00000000000
--- a/doc/integration/img/jira_project_name.png
+++ /dev/null
Binary files differ
diff --git a/doc/integration/img/jira_service.png b/doc/integration/img/jira_service.png
deleted file mode 100644
index 13aefce6f84..00000000000
--- a/doc/integration/img/jira_service.png
+++ /dev/null
Binary files differ
diff --git a/doc/integration/img/jira_service_close_issue.png b/doc/integration/img/jira_service_close_issue.png
deleted file mode 100644
index eed69e80d2c..00000000000
--- a/doc/integration/img/jira_service_close_issue.png
+++ /dev/null
Binary files differ
diff --git a/doc/integration/img/jira_service_page.png b/doc/integration/img/jira_service_page.png
deleted file mode 100644
index 0cc160bebe2..00000000000
--- a/doc/integration/img/jira_service_page.png
+++ /dev/null
Binary files differ
diff --git a/doc/integration/img/jira_user_management_link.png b/doc/integration/img/jira_user_management_link.png
deleted file mode 100644
index 5f002b59bac..00000000000
--- a/doc/integration/img/jira_user_management_link.png
+++ /dev/null
Binary files differ
diff --git a/doc/integration/img/jira_workflow_screenshot.png b/doc/integration/img/jira_workflow_screenshot.png
deleted file mode 100644
index 937a50a77d9..00000000000
--- a/doc/integration/img/jira_workflow_screenshot.png
+++ /dev/null
Binary files differ
diff --git a/doc/integration/img/oauth_provider_admin_application.png b/doc/integration/img/oauth_provider_admin_application.png
index fc5f7596fcc..c8ecce129c8 100644
--- a/doc/integration/img/oauth_provider_admin_application.png
+++ b/doc/integration/img/oauth_provider_admin_application.png
Binary files differ
diff --git a/doc/integration/img/oauth_provider_application_form.png b/doc/integration/img/oauth_provider_application_form.png
index 606ab3e3467..954681e054e 100644
--- a/doc/integration/img/oauth_provider_application_form.png
+++ b/doc/integration/img/oauth_provider_application_form.png
Binary files differ
diff --git a/doc/integration/img/oauth_provider_application_id_secret.png b/doc/integration/img/oauth_provider_application_id_secret.png
index cbedcef8376..65cca5f1e1b 100644
--- a/doc/integration/img/oauth_provider_application_id_secret.png
+++ b/doc/integration/img/oauth_provider_application_id_secret.png
Binary files differ
diff --git a/doc/integration/img/oauth_provider_authorized_application.png b/doc/integration/img/oauth_provider_authorized_application.png
index 6a2ea09073c..ed99db3476d 100644
--- a/doc/integration/img/oauth_provider_authorized_application.png
+++ b/doc/integration/img/oauth_provider_authorized_application.png
Binary files differ
diff --git a/doc/integration/img/oauth_provider_user_wide_applications.png b/doc/integration/img/oauth_provider_user_wide_applications.png
index 0c7b095a2dd..9cc12555574 100644
--- a/doc/integration/img/oauth_provider_user_wide_applications.png
+++ b/doc/integration/img/oauth_provider_user_wide_applications.png
Binary files differ
diff --git a/doc/integration/img/spam_log.png b/doc/integration/img/spam_log.png
index 8d574448690..43e267daff4 100644
--- a/doc/integration/img/spam_log.png
+++ b/doc/integration/img/spam_log.png
Binary files differ
diff --git a/doc/integration/img/submit_issue.png b/doc/integration/img/submit_issue.png
index 5c7896a7eec..8accb78faf3 100644
--- a/doc/integration/img/submit_issue.png
+++ b/doc/integration/img/submit_issue.png
Binary files differ
diff --git a/doc/integration/img/twitter_app_api_keys.png b/doc/integration/img/twitter_app_api_keys.png
index 15b29ac7d16..34e3c3ba001 100644
--- a/doc/integration/img/twitter_app_api_keys.png
+++ b/doc/integration/img/twitter_app_api_keys.png
Binary files differ
diff --git a/doc/integration/img/twitter_app_details.png b/doc/integration/img/twitter_app_details.png
index 323112a88bb..b53f4eb3202 100644
--- a/doc/integration/img/twitter_app_details.png
+++ b/doc/integration/img/twitter_app_details.png
Binary files differ
diff --git a/doc/integration/jira.md b/doc/integration/jira.md
index 78aa6634116..e2f136bcc35 100644
--- a/doc/integration/jira.md
+++ b/doc/integration/jira.md
@@ -1,3 +1,3 @@
# GitLab JIRA integration
-This document was moved under [project_services/jira](../project_services/jira.md).
+This document was moved to [project_services/jira](../project_services/jira.md).
diff --git a/doc/monitoring/performance/img/grafana_dashboard_dropdown.png b/doc/monitoring/performance/img/grafana_dashboard_dropdown.png
index 7e34fad71ce..51eef90068d 100644
--- a/doc/monitoring/performance/img/grafana_dashboard_dropdown.png
+++ b/doc/monitoring/performance/img/grafana_dashboard_dropdown.png
Binary files differ
diff --git a/doc/monitoring/performance/img/grafana_dashboard_import.png b/doc/monitoring/performance/img/grafana_dashboard_import.png
index f97624365c7..7761ea00522 100644
--- a/doc/monitoring/performance/img/grafana_dashboard_import.png
+++ b/doc/monitoring/performance/img/grafana_dashboard_import.png
Binary files differ
diff --git a/doc/monitoring/performance/img/grafana_data_source_configuration.png b/doc/monitoring/performance/img/grafana_data_source_configuration.png
index 7d50e4c88c2..3e749eb8f9d 100644
--- a/doc/monitoring/performance/img/grafana_data_source_configuration.png
+++ b/doc/monitoring/performance/img/grafana_data_source_configuration.png
Binary files differ
diff --git a/doc/monitoring/performance/img/grafana_data_source_empty.png b/doc/monitoring/performance/img/grafana_data_source_empty.png
index aa39a53acae..33fcaaaef64 100644
--- a/doc/monitoring/performance/img/grafana_data_source_empty.png
+++ b/doc/monitoring/performance/img/grafana_data_source_empty.png
Binary files differ
diff --git a/doc/monitoring/performance/img/grafana_save_icon.png b/doc/monitoring/performance/img/grafana_save_icon.png
index c740e33cd1c..c18f2147e9d 100644
--- a/doc/monitoring/performance/img/grafana_save_icon.png
+++ b/doc/monitoring/performance/img/grafana_save_icon.png
Binary files differ
diff --git a/doc/monitoring/performance/img/metrics_gitlab_configuration_settings.png b/doc/monitoring/performance/img/metrics_gitlab_configuration_settings.png
index e6ed45a0386..d96a18ebc04 100644
--- a/doc/monitoring/performance/img/metrics_gitlab_configuration_settings.png
+++ b/doc/monitoring/performance/img/metrics_gitlab_configuration_settings.png
Binary files differ
diff --git a/doc/profile/2fa_u2f_authenticate.png b/doc/profile/2fa_u2f_authenticate.png
index b9138ff60db..b224ab14195 100644
--- a/doc/profile/2fa_u2f_authenticate.png
+++ b/doc/profile/2fa_u2f_authenticate.png
Binary files differ
diff --git a/doc/profile/2fa_u2f_register.png b/doc/profile/2fa_u2f_register.png
index 15b3683ef73..1cc142aa851 100644
--- a/doc/profile/2fa_u2f_register.png
+++ b/doc/profile/2fa_u2f_register.png
Binary files differ
diff --git a/doc/project_services/img/builds_emails_service.png b/doc/project_services/img/builds_emails_service.png
index 88943dc410e..9dbbed03833 100644
--- a/doc/project_services/img/builds_emails_service.png
+++ b/doc/project_services/img/builds_emails_service.png
Binary files differ
diff --git a/doc/project_services/img/emails_on_push_service.png b/doc/project_services/img/emails_on_push_service.png
index cd6f79ad1eb..df301aa1eeb 100644
--- a/doc/project_services/img/emails_on_push_service.png
+++ b/doc/project_services/img/emails_on_push_service.png
Binary files differ
diff --git a/doc/project_services/img/jira_add_gitlab_commit_message.png b/doc/project_services/img/jira_add_gitlab_commit_message.png
deleted file mode 100644
index aec472b9118..00000000000
--- a/doc/project_services/img/jira_add_gitlab_commit_message.png
+++ /dev/null
Binary files differ
diff --git a/doc/project_services/img/jira_add_user_to_group.png b/doc/project_services/img/jira_add_user_to_group.png
index 0ba737bda9a..27dac49260c 100644
--- a/doc/project_services/img/jira_add_user_to_group.png
+++ b/doc/project_services/img/jira_add_user_to_group.png
Binary files differ
diff --git a/doc/project_services/img/jira_create_new_group.png b/doc/project_services/img/jira_create_new_group.png
index 0609060cb05..06c4e84fc61 100644
--- a/doc/project_services/img/jira_create_new_group.png
+++ b/doc/project_services/img/jira_create_new_group.png
Binary files differ
diff --git a/doc/project_services/img/jira_create_new_group_name.png b/doc/project_services/img/jira_create_new_group_name.png
index 53d77b17df0..bfc0dc6b2e9 100644
--- a/doc/project_services/img/jira_create_new_group_name.png
+++ b/doc/project_services/img/jira_create_new_group_name.png
Binary files differ
diff --git a/doc/project_services/img/jira_create_new_user.png b/doc/project_services/img/jira_create_new_user.png
index 9eaa444ed25..e9c03ed770d 100644
--- a/doc/project_services/img/jira_create_new_user.png
+++ b/doc/project_services/img/jira_create_new_user.png
Binary files differ
diff --git a/doc/project_services/img/jira_group_access.png b/doc/project_services/img/jira_group_access.png
index 8d4657427ae..9d64cc57269 100644
--- a/doc/project_services/img/jira_group_access.png
+++ b/doc/project_services/img/jira_group_access.png
Binary files differ
diff --git a/doc/project_services/img/jira_issue_closed.png b/doc/project_services/img/jira_issue_closed.png
deleted file mode 100644
index acdd83702d3..00000000000
--- a/doc/project_services/img/jira_issue_closed.png
+++ /dev/null
Binary files differ
diff --git a/doc/project_services/img/jira_issue_reference.png b/doc/project_services/img/jira_issue_reference.png
index 1a2d9f04a6c..72c81460df7 100644
--- a/doc/project_services/img/jira_issue_reference.png
+++ b/doc/project_services/img/jira_issue_reference.png
Binary files differ
diff --git a/doc/project_services/img/jira_issues_workflow.png b/doc/project_services/img/jira_issues_workflow.png
deleted file mode 100644
index 0703081d77b..00000000000
--- a/doc/project_services/img/jira_issues_workflow.png
+++ /dev/null
Binary files differ
diff --git a/doc/project_services/img/jira_merge_request_close.png b/doc/project_services/img/jira_merge_request_close.png
index 47785e3ba27..0f82ceba557 100644
--- a/doc/project_services/img/jira_merge_request_close.png
+++ b/doc/project_services/img/jira_merge_request_close.png
Binary files differ
diff --git a/doc/project_services/img/jira_project_name.png b/doc/project_services/img/jira_project_name.png
index e785ec6140d..8540a427461 100644
--- a/doc/project_services/img/jira_project_name.png
+++ b/doc/project_services/img/jira_project_name.png
Binary files differ
diff --git a/doc/project_services/img/jira_reference_commit_message_in_jira_issue.png b/doc/project_services/img/jira_reference_commit_message_in_jira_issue.png
deleted file mode 100644
index fb270d85e3c..00000000000
--- a/doc/project_services/img/jira_reference_commit_message_in_jira_issue.png
+++ /dev/null
Binary files differ
diff --git a/doc/project_services/img/jira_service.png b/doc/project_services/img/jira_service.png
index 13aefce6f84..8e073b84ff9 100644
--- a/doc/project_services/img/jira_service.png
+++ b/doc/project_services/img/jira_service.png
Binary files differ
diff --git a/doc/project_services/img/jira_service_close_comment.png b/doc/project_services/img/jira_service_close_comment.png
new file mode 100644
index 00000000000..bb9cd7e3d13
--- /dev/null
+++ b/doc/project_services/img/jira_service_close_comment.png
Binary files differ
diff --git a/doc/project_services/img/jira_service_close_issue.png b/doc/project_services/img/jira_service_close_issue.png
index eed69e80d2c..c85b1d1dd97 100644
--- a/doc/project_services/img/jira_service_close_issue.png
+++ b/doc/project_services/img/jira_service_close_issue.png
Binary files differ
diff --git a/doc/project_services/img/jira_service_page.png b/doc/project_services/img/jira_service_page.png
index a5b49c501ba..c74351b57b8 100644
--- a/doc/project_services/img/jira_service_page.png
+++ b/doc/project_services/img/jira_service_page.png
Binary files differ
diff --git a/doc/project_services/img/jira_submit_gitlab_merge_request.png b/doc/project_services/img/jira_submit_gitlab_merge_request.png
deleted file mode 100644
index 77630d39d39..00000000000
--- a/doc/project_services/img/jira_submit_gitlab_merge_request.png
+++ /dev/null
Binary files differ
diff --git a/doc/project_services/img/jira_user_management_link.png b/doc/project_services/img/jira_user_management_link.png
index 5f002b59bac..f81c5b5fc87 100644
--- a/doc/project_services/img/jira_user_management_link.png
+++ b/doc/project_services/img/jira_user_management_link.png
Binary files differ
diff --git a/doc/project_services/img/jira_workflow_screenshot.png b/doc/project_services/img/jira_workflow_screenshot.png
index 937a50a77d9..e62fb202613 100644
--- a/doc/project_services/img/jira_workflow_screenshot.png
+++ b/doc/project_services/img/jira_workflow_screenshot.png
Binary files differ
diff --git a/doc/project_services/img/mattermost_add_slash_command.png b/doc/project_services/img/mattermost_add_slash_command.png
new file mode 100644
index 00000000000..7759efa183c
--- /dev/null
+++ b/doc/project_services/img/mattermost_add_slash_command.png
Binary files differ
diff --git a/doc/project_services/img/mattermost_bot_auth.png b/doc/project_services/img/mattermost_bot_auth.png
new file mode 100644
index 00000000000..830b7849f3d
--- /dev/null
+++ b/doc/project_services/img/mattermost_bot_auth.png
Binary files differ
diff --git a/doc/project_services/img/mattermost_bot_available_commands.png b/doc/project_services/img/mattermost_bot_available_commands.png
new file mode 100644
index 00000000000..b51798cf10d
--- /dev/null
+++ b/doc/project_services/img/mattermost_bot_available_commands.png
Binary files differ
diff --git a/doc/project_services/img/mattermost_config_help.png b/doc/project_services/img/mattermost_config_help.png
new file mode 100644
index 00000000000..a62e4b792f9
--- /dev/null
+++ b/doc/project_services/img/mattermost_config_help.png
Binary files differ
diff --git a/doc/project_services/img/mattermost_console_integrations.png b/doc/project_services/img/mattermost_console_integrations.png
new file mode 100644
index 00000000000..b3b8c20d7bf
--- /dev/null
+++ b/doc/project_services/img/mattermost_console_integrations.png
Binary files differ
diff --git a/doc/project_services/img/mattermost_gitlab_token.png b/doc/project_services/img/mattermost_gitlab_token.png
new file mode 100644
index 00000000000..257018914d2
--- /dev/null
+++ b/doc/project_services/img/mattermost_gitlab_token.png
Binary files differ
diff --git a/doc/project_services/img/mattermost_goto_console.png b/doc/project_services/img/mattermost_goto_console.png
new file mode 100644
index 00000000000..3354c2a24b4
--- /dev/null
+++ b/doc/project_services/img/mattermost_goto_console.png
Binary files differ
diff --git a/doc/project_services/img/mattermost_slash_command_configuration.png b/doc/project_services/img/mattermost_slash_command_configuration.png
new file mode 100644
index 00000000000..12766ab2b34
--- /dev/null
+++ b/doc/project_services/img/mattermost_slash_command_configuration.png
Binary files differ
diff --git a/doc/project_services/img/mattermost_slash_command_token.png b/doc/project_services/img/mattermost_slash_command_token.png
new file mode 100644
index 00000000000..c38f37c203c
--- /dev/null
+++ b/doc/project_services/img/mattermost_slash_command_token.png
Binary files differ
diff --git a/doc/project_services/img/mattermost_team_integrations.png b/doc/project_services/img/mattermost_team_integrations.png
new file mode 100644
index 00000000000..69d4a231e5a
--- /dev/null
+++ b/doc/project_services/img/mattermost_team_integrations.png
Binary files differ
diff --git a/doc/project_services/img/redmine_configuration.png b/doc/project_services/img/redmine_configuration.png
index e9d8c0d2da8..7b6dd271401 100644
--- a/doc/project_services/img/redmine_configuration.png
+++ b/doc/project_services/img/redmine_configuration.png
Binary files differ
diff --git a/doc/project_services/img/services_templates_redmine_example.png b/doc/project_services/img/services_templates_redmine_example.png
index 77c2b98e5d0..50d20510daf 100644
--- a/doc/project_services/img/services_templates_redmine_example.png
+++ b/doc/project_services/img/services_templates_redmine_example.png
Binary files differ
diff --git a/doc/project_services/img/slack_configuration.png b/doc/project_services/img/slack_configuration.png
index b8de8a56db7..fc8e58e686b 100644
--- a/doc/project_services/img/slack_configuration.png
+++ b/doc/project_services/img/slack_configuration.png
Binary files differ
diff --git a/doc/project_services/jira.md b/doc/project_services/jira.md
index b626c746c79..366e4b2d306 100644
--- a/doc/project_services/jira.md
+++ b/doc/project_services/jira.md
@@ -1,36 +1,31 @@
# GitLab JIRA integration
->**Note:**
-Full JIRA integration was previously exclusive to GitLab Enterprise Edition.
-With [GitLab 8.3 forward][8_3_post], this feature in now [backported][jira-ce]
-to GitLab Community Edition as well.
+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 Core] either using an
-on-premises instance or the SaaS solution that Atlassian offers. Configuration
-happens via username and password on a per-project basis. Connecting to a JIRA
-server via CAS is not possible.
+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.
-Each project can be configured to connect to a different JIRA instance or, in
-case you have a single JIRA instance, you can pre-fill the JIRA service
-settings page in GitLab with a default template. To configure the JIRA template,
-see the [Services Templates documentation][services-templates].
-
-Once the GitLab project is connected to JIRA, you can reference and close the
-issues in JIRA directly from GitLab's merge requests.
+Once the project is connected to JIRA, you can reference and close the issues
+in JIRA directly from GitLab.
## Configuration
-The configuration consists of two parts:
-
-- [JIRA configuration](#configuring-jira)
-- [GitLab configuration](#configuring-gitlab)
+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.
### Configuring JIRA
-First things first, we need to create a user in JIRA which will have access to
-all projects that need to integrate with GitLab.
+We need to create a user in JIRA which will have access to all projects that
+need to integrate with GitLab. Login to your JIRA instance as admin and under
+Administration go to User Management and create a new user.
+
+As an example, we'll create a user named `gitlab` and add it to `JIRA-developers`
+group.
+
+**It is important that the user `GitLab` has write-access to projects in JIRA**
We have split this stage in steps so it is easier to follow.
@@ -62,12 +57,12 @@ We have split this stage in steps so it is easier to follow.
Give it an optional description and hit **Create group**.
- ![JIRA create new group](img/jira_create_new_group_name.png)
+ ![jira create new group](img/jira_create_new_group_name.png)
---
1. Give the newly-created group write access by going to
- **Application access > View configuration** and adding the `gitlab-developers`
+ **Application access âž” View configuration** and adding the `gitlab-developers`
group to JIRA Core.
![JIRA group access](img/jira_group_access.png)
@@ -75,7 +70,7 @@ We have split this stage in steps so it is easier to follow.
---
1. Add the `gitlab` user to the `gitlab-developers` group by going to
- **Users > GitLab user > Add group** and selecting the `gitlab-developers`
+ **Users âž” GitLab user âž” Add group** and selecting the `gitlab-developers`
group from the dropdown menu. Notice that the group says _Access_ which is
what we aim for.
@@ -88,50 +83,30 @@ password as they will be needed when configuring GitLab in the next section.
### Configuring GitLab
->**Note:**
-The currently supported JIRA versions are v6.x and v7.x. and GitLab
-7.8 or higher is required.
-
----
-
-Assuming you [have already configured JIRA](#configuring-jira), now it's time
-to configure GitLab.
-
-JIRA configuration in GitLab is done via a project's
-[**Services**](../project_services/project_services.md).
-
-To enable JIRA integration in a project, navigate to the project's
-**Settings > Services > JIRA**.
-
-Fill in the required details on the page, as described in the table below.
-
-| Setting | Description |
-| ------- | ----------- |
-| `Description` | A name for the issue tracker (to differentiate between instances, for example). |
-| `Project url` | The URL to the JIRA project which is being linked to this GitLab project. It is of the form: `https://<jira_host_url>/issues/?jql=project=<jira_project>`. |
-| `Issues url` | The URL to the JIRA project issues overview for the project that is linked to this GitLab project. It is of the form: `https://<jira_host_url>/browse/:id`. Leave `:id` as-is, it gets replaced by GitLab at runtime. |
-| `New issue url` | This is the URL to create a new issue in JIRA for the project linked to this GitLab project, and it is of the form: `https://<jira_host_url>/secure/CreateIssue.jspa` |
-| `Api url` | The base URL of the JIRA API. It may be omitted, in which case GitLab will automatically use API version `2` based on the `project url`. It is of the form: `https://<jira_host_url>/rest/api/2`. |
-| `Username` | The username of the user created in [configuring JIRA step](#configuring-jira). |
+>**Notes:**
+- The currently supported JIRA versions are `v6.x` and `v7.x.`. GitLab 7.8 or
+ higher is required.
+- GitLab 8.14 introduced a new way to integrate with JIRA which greatly simplified
+ the configuration options you have to enter. If you are using an older version,
+ [follow this documentation][jira-repo-docs].
+
+To enable JIRA integration in a project, navigate to your project's
+**Services âž” JIRA** and fill in the required details on the page as described
+in the table below.
+
+| Field | Description |
+| ----- | ----------- |
+| `URL` | The base URL to the JIRA project which is being linked to this GitLab project. E.g., `https://jira.example.com`. |
+| `Project key` | The short identifier for your JIRA project, all uppercase, e.g., `PROJ`. |
+| `Username` | The user name created in [configuring JIRA step](#configuring-jira). |
| `Password` |The password of the user created in [configuring JIRA step](#configuring-jira). |
-| `JIRA issue transition` | This setting is very important to set up correctly. It is the ID of a transition that moves issues to a closed state. You can find this number under the JIRA workflow administration (**Administration > Issues > Workflows**) by selecting **View** under **Operations** of the desired workflow of your project. The ID of each state can be found inside the parenthesis of each transition name under the **Transitions (id)** column ([see screenshot][trans]). By default, this ID is set to `2`. |
+| `JIRA issue transition` | This is the ID of a transition that moves issues to a closed state. You can find this number under JIRA workflow administration ([see screenshot](img/jira_workflow_screenshot.png)). |
After saving the configuration, your GitLab project will be able to interact
with the linked JIRA project.
-For example, given the settings below:
-
-- the JIRA URL is `https://jira.example.com`
-- the project is named `GITLAB`
-- the user is named `gitlab`
-- the JIRA issue transition is 151 (based on the [JIRA issue transition][trans])
-
-the following screenshot shows how the JIRA service settings should look like.
-
![JIRA service page](img/jira_service_page.png)
-[trans]: img/jira_issues_workflow.png
-
---
## JIRA issues
@@ -143,36 +118,28 @@ ID in GitLab commits and merge requests.
### Referencing JIRA Issues
-If you reference a JIRA issue, e.g., `GITLAB-1`, in a commit comment, a link
-which points back to JIRA is created.
+When GitLab project has JIRA issue tracker configured and enabled, mentioning
+JIRA issue in GitLab will automatically add a comment in JIRA issue with the
+link back to GitLab. This means that in comments in merge requests and commits
+referencing an issue, e.g., `PROJECT-7`, will add a comment in JIRA issue in the
+format:
-The same works for comments in merge requests as well.
+```
+USER mentioned this issue in RESOURCE_NAME of [PROJECT_NAME|LINK_TO_COMMENT]:
+ENTITY_TITLE
+```
-![JIRA add GitLab commit message](img/jira_add_gitlab_commit_message.png)
-
----
+* `USER` A user that mentioned the issue. This is the link to the user profile in GitLab.
+* `LINK_TO_THE_COMMENT` Link to the origin of mention with a name of the entity where JIRA issue was mentioned.
+* `RESOURCE_NAME` Kind of resource which referenced the issue. Can be a commit or merge request.
+* `PROJECT_NAME` GitLab project name.
+* `ENTITY_TITLE` Merge request title or commit message first line.
-The mentioning action is two-fold, so a comment with a JIRA issue in GitLab
-will automatically add a comment in that particular JIRA issue with the link
-back to GitLab.
-
-
-![JIRA reference commit message](img/jira_reference_commit_message_in_jira_issue.png)
+![example of mentioning or closing the JIRA issue](img/jira_issue_reference.png)
---
-The comment on the JIRA issue is of the form:
-
-> USER mentioned this issue in LINK_TO_THE_MENTION
-
-Where:
-
-| Format | Description |
-| ------ | ----------- |
-| `USER` | A user that mentioned the issue. This is the link to the user profile in GitLab. |
-| `LINK_TO_THE_MENTION` | Link to the origin of mention with a name of the entity where JIRA issue was mentioned. Can be commit or merge request. |
-
-### Closing JIRA issues
+### Closing JIRA Issues
JIRA issues can be closed directly from GitLab by using trigger words in
commits and merge requests. When a commit which contains the trigger word
@@ -183,64 +150,58 @@ the transition ID was set up correctly).
There are currently three trigger words, and you can use either one to achieve
the same goal:
-- `Resolves GITLAB-1`
-- `Closes GITLAB-1`
-- `Fixes GITLAB-1`
+- `Resolves PROJECT-1`
+- `Closes PROJECT-1`
+- `Fixes PROJECT-1`
-where `GITLAB-1` the issue ID of the JIRA project.
+where `PROJECT-1` is the issue ID of the JIRA project.
### JIRA issue closing example
-Let's say for example that we submitted a bug fix and created a merge request
-in GitLab. The workflow would be something like this:
+Let's consider the following example:
-1. Create a new branch
-1. Fix the bug
-1. Commit the changes and push branch to GitLab
-1. Open a new merge request and reference the JIRA issue including one of the
- trigger words, e.g.: `Fixes GITLAB-1`, in the description
-1. Submit the merge request
-1. Ask someone to review
-1. Merge the merge request
-1. The JIRA issue is automatically closed
+1. For the project named `PROJECT` in JIRA, we implemented a new feature
+ and created a merge request in GitLab.
+1. This feature was requested in JIRA issue `PROJECT-7` and the merge request
+ in GitLab contains the improvement
+1. In the merge request description we use the issue closing trigger
+ `Closes PROJECT-7`.
+1. Once the merge request is merged, the JIRA issue will be automatically closed
+ with a comment and an associated link to the commit that resolved the issue.
---
In the following screenshot you can see what the link references to the JIRA
issue look like.
-![JIRA - submit a GitLab merge request](img/jira_submit_gitlab_merge_request.png)
+![A Git commit that causes the JIRA issue to be closed](img/jira_merge_request_close.png)
---
Once this merge request is merged, the JIRA issue will be automatically closed
with a link to the commit that resolved the issue.
-![The GitLab integration user leaves a comment on JIRA](img/jira_issue_closed.png)
+![The GitLab integration closes JIRA issue](img/jira_service_close_issue.png)
---
-You can see from the above image that there are four references to GitLab:
-
-- The first is from a comment in a specific commit
-- The second is from the JIRA issue reference in the merge request description
-- The third is from the actual commit that solved the issue
-- And the fourth is from the commit that the merge request created
-
-[services-templates]: ../project_services/services_templates.md "Services templates documentation"
-[JIRA Core]: https://www.atlassian.com/software/jira/core "The JIRA Core website"
-[jira-ce]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/2146 "MR - Backport JIRA service"
-[8_3_post]: https://about.gitlab.com/2015/12/22/gitlab-8-3-released/ "GitLab 8.3 release post"
+![The GitLab integration creates a comment and a link on JIRA issue.](img/jira_service_close_comment.png)
## Troubleshooting
+If things don't work as expected that's usually because you have configured
+incorrectly the JIRA-GitLab integration.
+
### GitLab is unable to comment on a ticket
Make sure that the user you set up for GitLab to communicate with JIRA has the
-correct access permission to post comments on a ticket and to also transition the
-ticket, if you'd like GitLab to also take care of closing them.
+correct access permission to post comments on a ticket and to also transition
+the ticket, if you'd like GitLab to also take care of closing them.
### GitLab is unable to close a ticket
-Make sure the the `Transition ID` you set within the JIRA settings matches the
-one your project needs to close a ticket.
+Make sure the `Transition ID` you set within the JIRA settings matches the one
+your project needs to close a ticket.
+
+[services-templates]: ../project_services/services_templates.md
+[jira-repo-docs]: https://gitlab.com/gitlab-org/gitlab-ce/blob/8-13-stable/doc/project_services/jira.md
diff --git a/doc/project_services/mattermost_slash_commands.md b/doc/project_services/mattermost_slash_commands.md
new file mode 100644
index 00000000000..1507dfa3abd
--- /dev/null
+++ b/doc/project_services/mattermost_slash_commands.md
@@ -0,0 +1,157 @@
+# Mattermost slash commands
+
+> Introduced in GitLab 8.14
+
+Mattermost commands give users an extra interface to perform common operations
+from the chat environment. This allows one to, for example, create an issue as
+soon as the idea was discussed in Mattermost.
+
+## Prerequisites
+
+Mattermost 3.4 and up is required.
+
+If you have the Omnibus GitLab package installed, Mattermost is already bundled
+in it. All you have to do is configure it. Read more in the
+[Omnibus GitLab Mattermost documentation][omnimmdocs].
+
+## Configuration
+
+The configuration consists of two parts. First you need to enable the slash
+commands in Mattermost and then enable the service in GitLab.
+
+
+### Step 1. Enable custom slash commands in Mattermost
+
+The first thing to do in Mattermost is to enable custom slash commands from
+the administrator console.
+
+1. Log in with an account that has admin privileges and navigate to the system
+ console.
+
+ ![Mattermost go to console](img/mattermost_goto_console.png)
+
+ ---
+
+1. Click **Custom integrations** and set **Enable Custom Slash Commands** to
+ true.
+
+ ![Mattermost console](img/mattermost_console_integrations.png)
+
+ ---
+
+1. Click **Save** at the bottom to save the changes.
+
+### Step 2. Open the Mattermost slash commands service in GitLab
+
+1. Open a new tab for GitLab and go to your project's settings
+ **Services âž” Mattermost command**. A screen will appear with all the values you
+ need to copy in Mattermost as described in the next step. Leave the window open.
+
+ >**Note:**
+ GitLab will propose some values for the Mattermost settings. The only one
+ required to copy-paste as-is is the **Request URL**, all the others are just
+ suggestions.
+
+ ![Mattermost setup instructions](img/mattermost_config_help.png)
+
+ ---
+
+1. Proceed to the next step and create a slash command in Mattermost with the
+ above values.
+
+### Step 3. Create a new custom slash command in Mattermost
+
+Now that you have enabled the custom slash commands in Mattermost and opened
+the Mattermost slash commands service in GitLab, it's time to copy these values
+in a new slash command.
+
+1. Back to Mattermost, under your team page settings, you should see the
+ **Integrations** option.
+
+ ![Mattermost team integrations](img/mattermost_team_integrations.png)
+
+ ---
+
+1. Go to the **Slash Commands** integration and add a new one by clicking the
+ **Add Slash Command** button.
+
+ ![Mattermost add command](img/mattermost_add_slash_command.png)
+
+ ---
+
+1. Fill in the options for the custom command as described in
+ [step 2](#step-2-open-the-mattermost-slash-commands-service-in-gitlab).
+
+ >**Note:**
+ If you plan on connecting multiple projects, pick a slash command trigger
+ word that relates to your projects such as `/gitlab-project-name` or even
+ just `/project-name`. Only use `/gitlab` if you will only connect a single
+ project to your Mattermost team.
+
+ ![Mattermost add command configuration](img/mattermost_slash_command_configuration.png)
+
+1. After you setup all the values, copy the token (we will use it below) and
+ click **Done**.
+
+ ![Mattermost slash command token](img/mattermost_slash_command_token.png)
+
+### Step 4. Copy the Mattermost token into the Mattermost slash command service
+
+1. In GitLab, paste the Mattermost token you copied in the previous step and
+ check the **Active** checkbox.
+
+ ![Mattermost copy token to GitLab](img/mattermost_gitlab_token.png)
+
+1. Click **Save changes** for the changes to take effect.
+
+---
+
+You are now set to start using slash commands in Mattermost that talk to the
+GitLab project you configured.
+
+## Authorizing Mattermost to interact with GitLab
+
+The first time a user will interact with the newly created slash commands,
+Mattermost will trigger an authorization process.
+
+![Mattermost bot authorize](img/mattermost_bot_auth.png)
+
+This will connect your Mattermost user with your GitLab user. You can
+see all authorized chat accounts in your profile's page under **Chat**.
+
+When the authorization process is complete, you can start interacting with
+GitLab using the Mattermost commands.
+
+## Available slash commands
+
+The available slash commands so far are:
+
+| Command | Description | Example |
+| ------- | ----------- | ------- |
+| `/<trigger> issue create <title>\n<description>` | Create a new issue in the project that `<trigger>` is tied to. `<description>` is optional. | `/trigger issue create We need to change the homepage` |
+| `/<trigger> issue show <issue-number>` | Show the issue with ID `<issue-number>` from the project that `<trigger>` is tied to. | `/trigger issue show 42` |
+| `/<trigger> deploy <environment> to <environment>` | Start the CI job that deploys from one environment to another, for example `staging` to `production`. CI/CD must be [properly configured][ciyaml]. | `/trigger deploy staging to production` |
+
+To see a list of available commands that can interact with GitLab, type the
+trigger word followed by `help`:
+
+```
+/my-project help
+```
+
+![Mattermost bot available commands](img/mattermost_bot_available_commands.png)
+
+## Permissions
+
+The permissions to run the [available commands](#available-commands) derive from
+the [permissions you have on the project](../user/permissions.md#project).
+
+## Further reading
+
+- [Mattermost slash commands documentation][mmslashdocs]
+- [Omnibus GitLab Mattermost][omnimmdocs]
+
+
+[omnimmdocs]: https://docs.gitlab.com/omnibus/gitlab-mattermost/
+[mmslashdocs]: https://docs.mattermost.com/developer/slash-commands.html
+[ciyaml]: ../ci/yaml/README.md
diff --git a/doc/project_services/project_services.md b/doc/project_services/project_services.md
index 4442b7c1742..890f7525b0e 100644
--- a/doc/project_services/project_services.md
+++ b/doc/project_services/project_services.md
@@ -42,6 +42,7 @@ further configuration instructions and details. Contributions are welcome.
| [Irker (IRC gateway)](irker.md) | Send IRC messages, on update, to a list of recipients through an Irker gateway |
| [JIRA](jira.md) | JIRA issue tracker |
| JetBrains TeamCity CI | A continuous integration and build server |
+| [Mattermost slash commands](mattermost_slash_commands.md) | Mattermost chat and ChatOps slash commands |
| PivotalTracker | Project Management Software (Source Commits Endpoint) |
| Pushover | Pushover makes it easy to get real-time notifications on your Android device, iPhone, iPad, and Desktop |
| [Redmine](redmine.md) | Redmine issue tracker |
diff --git a/doc/raketasks/backup_hrz.png b/doc/raketasks/backup_hrz.png
index 287587609a1..c9595b236ee 100644
--- a/doc/raketasks/backup_hrz.png
+++ b/doc/raketasks/backup_hrz.png
Binary files differ
diff --git a/doc/raketasks/backup_restore.md b/doc/raketasks/backup_restore.md
index 0ad84705cfd..17485b11c09 100644
--- a/doc/raketasks/backup_restore.md
+++ b/doc/raketasks/backup_restore.md
@@ -32,7 +32,7 @@ sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production
```
If you are running GitLab within a Docker container, you can run the backup from the host:
```
-docker -t exec <container name> gitlab-rake gitlab:backup:create
+docker exec -t <container name> gitlab-rake gitlab:backup:create
```
You can specify that portions of the application data be skipped using the
@@ -88,7 +88,7 @@ It uses the [Fog library](http://fog.io/) to perform the upload.
In the example below we use Amazon S3 for storage, but Fog also lets you use
[other storage providers](http://fog.io/storage/). GitLab
[imports cloud drivers](https://gitlab.com/gitlab-org/gitlab-ce/blob/30f5b9a5b711b46f1065baf755e413ceced5646b/Gemfile#L88)
-for AWS, Azure, Google, OpenStack Swift and Rackspace as well. A local driver is
+for AWS, OpenStack Swift and Rackspace as well. A local driver is
[also available](#uploading-to-locally-mounted-shares).
For omnibus packages:
diff --git a/doc/security/img/two_factor_authentication_settings.png b/doc/security/img/two_factor_authentication_settings.png
index 6af5feabb13..6d89be1eb04 100644
--- a/doc/security/img/two_factor_authentication_settings.png
+++ b/doc/security/img/two_factor_authentication_settings.png
Binary files differ
diff --git a/doc/university/README.md b/doc/university/README.md
index 4569bc72797..8917636c59b 100644
--- a/doc/university/README.md
+++ b/doc/university/README.md
@@ -19,7 +19,7 @@ The curriculum is composed of GitLab videos, screencasts, presentations, project
---
-### 1. <a name="beginner"></a> GitLab Beginner
+### 1. GitLab Beginner
#### 1.1. Version Control and Git
@@ -85,7 +85,7 @@ The curriculum is composed of GitLab videos, screencasts, presentations, project
---
-### 2. <a name="intermediate"></a> GitLab Intermediate
+### 2. GitLab Intermediate
#### 2.1 GitLab Pages
@@ -141,7 +141,7 @@ The curriculum is composed of GitLab videos, screencasts, presentations, project
---
-### 3. <a name="advanced"></a> GitLab Advanced
+### 3. GitLab Advanced
#### 3.1. Dev Ops
@@ -186,7 +186,7 @@ The curriculum is composed of GitLab videos, screencasts, presentations, project
1. [GitLab Cycle Analytics Overview](https://about.gitlab.com/2016/09/21/cycle-analytics-feature-highlight/)
1. [GitLab Cycle Analytics - Product Page](https://about.gitlab.com/solutions/cycle-analytics/)
-#### 3.9. <a name="integrations"></a> Integrations
+#### 3.9. Integrations
1. [How to Integrate JIRA and Jenkins with GitLab - Video](https://gitlabmeetings.webex.com/gitlabmeetings/ldr.php?RCID=44b548147a67ab4d8a62274047146415)
1. [How to Integrate Jira with GitLab](https://docs.gitlab.com/ee/integration/jira.html)
@@ -198,7 +198,7 @@ The curriculum is composed of GitLab videos, screencasts, presentations, project
---
-## 4. <a name="external"></a> External Articles
+## 4. External Articles
1. [2011 WSJ article by Marc Andreessen - Software is Eating the World](http://www.wsj.com/articles/SB10001424053111903480904576512250915629460)
1. [2014 Blog post by Chris Dixon - Software eats software development](http://cdixon.org/2014/04/13/software-eats-software-development/)
@@ -206,7 +206,7 @@ The curriculum is composed of GitLab videos, screencasts, presentations, project
---
-## 5. <a name="team"></a> Resources for GitLab Team Members
+## 5. Resources for GitLab Team Members
*Some content can only be accessed by GitLab team members*
diff --git a/doc/university/high-availability/aws/img/auto-scaling-det.png b/doc/university/high-availability/aws/img/auto-scaling-det.png
index e9b65529495..1e125f301bc 100644
--- a/doc/university/high-availability/aws/img/auto-scaling-det.png
+++ b/doc/university/high-availability/aws/img/auto-scaling-det.png
Binary files differ
diff --git a/doc/university/high-availability/aws/img/db-subnet-group.png b/doc/university/high-availability/aws/img/db-subnet-group.png
index 0768aa73c45..590a02b8dbe 100644
--- a/doc/university/high-availability/aws/img/db-subnet-group.png
+++ b/doc/university/high-availability/aws/img/db-subnet-group.png
Binary files differ
diff --git a/doc/university/high-availability/aws/img/ec-subnet.png b/doc/university/high-availability/aws/img/ec-subnet.png
index f41d78b271d..43ef76b62d3 100644
--- a/doc/university/high-availability/aws/img/ec-subnet.png
+++ b/doc/university/high-availability/aws/img/ec-subnet.png
Binary files differ
diff --git a/doc/university/high-availability/aws/img/elastic-file-system.png b/doc/university/high-availability/aws/img/elastic-file-system.png
index 7de866d1e89..5bcfb8d0588 100644
--- a/doc/university/high-availability/aws/img/elastic-file-system.png
+++ b/doc/university/high-availability/aws/img/elastic-file-system.png
Binary files differ
diff --git a/doc/university/high-availability/aws/img/ig-rt.png b/doc/university/high-availability/aws/img/ig-rt.png
index 93bb0c2ae02..62cca074a1e 100644
--- a/doc/university/high-availability/aws/img/ig-rt.png
+++ b/doc/university/high-availability/aws/img/ig-rt.png
Binary files differ
diff --git a/doc/university/high-availability/aws/img/ig.png b/doc/university/high-availability/aws/img/ig.png
index cc50456370f..d4fc2d12de8 100644
--- a/doc/university/high-availability/aws/img/ig.png
+++ b/doc/university/high-availability/aws/img/ig.png
Binary files differ
diff --git a/doc/university/high-availability/aws/img/instance_specs.png b/doc/university/high-availability/aws/img/instance_specs.png
index ef31dc41dae..650f375ab3c 100644
--- a/doc/university/high-availability/aws/img/instance_specs.png
+++ b/doc/university/high-availability/aws/img/instance_specs.png
Binary files differ
diff --git a/doc/university/high-availability/aws/img/new_vpc.png b/doc/university/high-availability/aws/img/new_vpc.png
index 4aac6af7c7a..e51c066cee2 100644
--- a/doc/university/high-availability/aws/img/new_vpc.png
+++ b/doc/university/high-availability/aws/img/new_vpc.png
Binary files differ
diff --git a/doc/university/high-availability/aws/img/policies.png b/doc/university/high-availability/aws/img/policies.png
index 8c58117e4fa..afcd9e4af9b 100644
--- a/doc/university/high-availability/aws/img/policies.png
+++ b/doc/university/high-availability/aws/img/policies.png
Binary files differ
diff --git a/doc/university/high-availability/aws/img/rds-net-opt.png b/doc/university/high-availability/aws/img/rds-net-opt.png
index bc204de2474..651cc23b1ab 100644
--- a/doc/university/high-availability/aws/img/rds-net-opt.png
+++ b/doc/university/high-availability/aws/img/rds-net-opt.png
Binary files differ
diff --git a/doc/university/high-availability/aws/img/rds-sec-group.png b/doc/university/high-availability/aws/img/rds-sec-group.png
index 8864dc3e463..c6d1bc350e4 100644
--- a/doc/university/high-availability/aws/img/rds-sec-group.png
+++ b/doc/university/high-availability/aws/img/rds-sec-group.png
Binary files differ
diff --git a/doc/university/high-availability/aws/img/redis-cluster-det.png b/doc/university/high-availability/aws/img/redis-cluster-det.png
index 9e9a81283c5..51d3a08eab6 100644
--- a/doc/university/high-availability/aws/img/redis-cluster-det.png
+++ b/doc/university/high-availability/aws/img/redis-cluster-det.png
Binary files differ
diff --git a/doc/university/high-availability/aws/img/redis-net.png b/doc/university/high-availability/aws/img/redis-net.png
index 037bd6d6897..9022a9ada78 100644
--- a/doc/university/high-availability/aws/img/redis-net.png
+++ b/doc/university/high-availability/aws/img/redis-net.png
Binary files differ
diff --git a/doc/university/high-availability/aws/img/route_table.png b/doc/university/high-availability/aws/img/route_table.png
index 1dea322474d..c8bef75f01a 100644
--- a/doc/university/high-availability/aws/img/route_table.png
+++ b/doc/university/high-availability/aws/img/route_table.png
Binary files differ
diff --git a/doc/university/high-availability/aws/img/subnet.png b/doc/university/high-availability/aws/img/subnet.png
index dbc71201992..de910edc948 100644
--- a/doc/university/high-availability/aws/img/subnet.png
+++ b/doc/university/high-availability/aws/img/subnet.png
Binary files differ
diff --git a/doc/university/training/gitlab_flow/feature_branches.png b/doc/university/training/gitlab_flow/feature_branches.png
index 88addb623ee..612e0248222 100644
--- a/doc/university/training/gitlab_flow/feature_branches.png
+++ b/doc/university/training/gitlab_flow/feature_branches.png
Binary files differ
diff --git a/doc/university/training/gitlab_flow/production_branch.png b/doc/university/training/gitlab_flow/production_branch.png
index 33fb26dd621..66456cc51af 100644
--- a/doc/university/training/gitlab_flow/production_branch.png
+++ b/doc/university/training/gitlab_flow/production_branch.png
Binary files differ
diff --git a/doc/university/training/gitlab_flow/release_branches.png b/doc/university/training/gitlab_flow/release_branches.png
index da7ae53413a..5661e36c4e2 100644
--- a/doc/university/training/gitlab_flow/release_branches.png
+++ b/doc/university/training/gitlab_flow/release_branches.png
Binary files differ
diff --git a/doc/university/training/logo.png b/doc/university/training/logo.png
index cc831790405..c80f65c053e 100644
--- a/doc/university/training/logo.png
+++ b/doc/university/training/logo.png
Binary files differ
diff --git a/doc/user/admin_area/img/admin_labels.png b/doc/user/admin_area/img/admin_labels.png
index 1ee33a534ab..a9ea059ccf9 100644
--- a/doc/user/admin_area/img/admin_labels.png
+++ b/doc/user/admin_area/img/admin_labels.png
Binary files differ
diff --git a/doc/user/admin_area/monitoring/img/health_check_token.png b/doc/user/admin_area/monitoring/img/health_check_token.png
index 2d7c82a65a8..182549fc484 100644
--- a/doc/user/admin_area/monitoring/img/health_check_token.png
+++ b/doc/user/admin_area/monitoring/img/health_check_token.png
Binary files differ
diff --git a/doc/user/admin_area/settings/img/access_restrictions.png b/doc/user/admin_area/settings/img/access_restrictions.png
index 8eea84320d7..8c5336c7835 100644
--- a/doc/user/admin_area/settings/img/access_restrictions.png
+++ b/doc/user/admin_area/settings/img/access_restrictions.png
Binary files differ
diff --git a/doc/user/admin_area/settings/img/admin_area_maximum_artifacts_size.png b/doc/user/admin_area/settings/img/admin_area_maximum_artifacts_size.png
index 53f7e76033e..b7d6671902a 100644
--- a/doc/user/admin_area/settings/img/admin_area_maximum_artifacts_size.png
+++ b/doc/user/admin_area/settings/img/admin_area_maximum_artifacts_size.png
Binary files differ
diff --git a/doc/user/admin_area/settings/img/admin_area_settings_button.png b/doc/user/admin_area/settings/img/admin_area_settings_button.png
index 509708b627f..1d2c0ac04bc 100644
--- a/doc/user/admin_area/settings/img/admin_area_settings_button.png
+++ b/doc/user/admin_area/settings/img/admin_area_settings_button.png
Binary files differ
diff --git a/doc/user/admin_area/settings/img/domain_blacklist.png b/doc/user/admin_area/settings/img/domain_blacklist.png
index bd87b73cf9e..dedd3be1e8f 100644
--- a/doc/user/admin_area/settings/img/domain_blacklist.png
+++ b/doc/user/admin_area/settings/img/domain_blacklist.png
Binary files differ
diff --git a/doc/user/admin_area/settings/img/restricted_url.png b/doc/user/admin_area/settings/img/restricted_url.png
index 8b00a18320b..67abd13f741 100644
--- a/doc/user/admin_area/settings/img/restricted_url.png
+++ b/doc/user/admin_area/settings/img/restricted_url.png
Binary files differ
diff --git a/doc/user/img/markdown_logo.png b/doc/user/img/markdown_logo.png
index 05c8b0d0ccf..bb3faaaec76 100644
--- a/doc/user/img/markdown_logo.png
+++ b/doc/user/img/markdown_logo.png
Binary files differ
diff --git a/doc/user/project/builds/img/build_artifacts_browser.png b/doc/user/project/builds/img/build_artifacts_browser.png
index d95e2800c0f..686273948d6 100644
--- a/doc/user/project/builds/img/build_artifacts_browser.png
+++ b/doc/user/project/builds/img/build_artifacts_browser.png
Binary files differ
diff --git a/doc/user/project/builds/img/build_artifacts_browser_button.png b/doc/user/project/builds/img/build_artifacts_browser_button.png
index 463540634e3..33ef7de0415 100644
--- a/doc/user/project/builds/img/build_artifacts_browser_button.png
+++ b/doc/user/project/builds/img/build_artifacts_browser_button.png
Binary files differ
diff --git a/doc/user/project/builds/img/build_artifacts_builds_page.png b/doc/user/project/builds/img/build_artifacts_builds_page.png
index db78386ba7b..8f75602d592 100644
--- a/doc/user/project/builds/img/build_artifacts_builds_page.png
+++ b/doc/user/project/builds/img/build_artifacts_builds_page.png
Binary files differ
diff --git a/doc/user/project/builds/img/build_artifacts_pipelines_page.png b/doc/user/project/builds/img/build_artifacts_pipelines_page.png
index 6c2d1a4bdc7..4bbd00ddaa0 100644
--- a/doc/user/project/builds/img/build_artifacts_pipelines_page.png
+++ b/doc/user/project/builds/img/build_artifacts_pipelines_page.png
Binary files differ
diff --git a/doc/user/project/builds/img/build_latest_artifacts_browser.png b/doc/user/project/builds/img/build_latest_artifacts_browser.png
index d8e9071958c..c6d8856078b 100644
--- a/doc/user/project/builds/img/build_latest_artifacts_browser.png
+++ b/doc/user/project/builds/img/build_latest_artifacts_browser.png
Binary files differ
diff --git a/doc/user/project/cycle_analytics.md b/doc/user/project/cycle_analytics.md
index 1892ccabb70..86fe52ef4ff 100644
--- a/doc/user/project/cycle_analytics.md
+++ b/doc/user/project/cycle_analytics.md
@@ -1,10 +1,7 @@
# Cycle Analytics
-> [Introduced][ce-5986] in GitLab 8.12.
->
-> **Note:**
-There are more changes coming to Cycle Analytics, you can follow the following
-issue to track the changes to this feature: [#20975][ce-20975].
+> [Introduced][ce-5986] in GitLab 8.12. Further features were added in GitLab
+ 8.14.
Cycle Analytics measures the time it takes to go from an [idea to production] for
each project you have. This is achieved by not only indicating the total time it
@@ -16,7 +13,7 @@ calculates a separate median for each stage.
## Overview
-You can find the Cycle Analytics page under your project's **Pipelines > Cycle
+You can find the Cycle Analytics page under your project's **Pipelines âž” Cycle
Analytics** tab.
![Cycle Analytics landing page](img/cycle_analytics_landing_page.png)
diff --git a/doc/user/project/img/container_registry_enable.png b/doc/user/project/img/container_registry_enable.png
index 6fffa2a91d8..d067a8be1ca 100644
--- a/doc/user/project/img/container_registry_enable.png
+++ b/doc/user/project/img/container_registry_enable.png
Binary files differ
diff --git a/doc/user/project/img/container_registry_panel.png b/doc/user/project/img/container_registry_panel.png
index 60fd76192b7..e4c9ecbb25b 100644
--- a/doc/user/project/img/container_registry_panel.png
+++ b/doc/user/project/img/container_registry_panel.png
Binary files differ
diff --git a/doc/user/project/img/container_registry_tab.png b/doc/user/project/img/container_registry_tab.png
index 36b883aaa97..a85237271d9 100644
--- a/doc/user/project/img/container_registry_tab.png
+++ b/doc/user/project/img/container_registry_tab.png
Binary files differ
diff --git a/doc/user/project/img/cycle_analytics_landing_page.png b/doc/user/project/img/cycle_analytics_landing_page.png
index b212134d5ed..316612c0da0 100644
--- a/doc/user/project/img/cycle_analytics_landing_page.png
+++ b/doc/user/project/img/cycle_analytics_landing_page.png
Binary files differ
diff --git a/doc/user/project/img/description_templates.png b/doc/user/project/img/description_templates.png
index c41cc77a94c..e9d45029532 100644
--- a/doc/user/project/img/description_templates.png
+++ b/doc/user/project/img/description_templates.png
Binary files differ
diff --git a/doc/user/project/img/issue_board.png b/doc/user/project/img/issue_board.png
index 63c269f6dbc..95e8532e908 100644
--- a/doc/user/project/img/issue_board.png
+++ b/doc/user/project/img/issue_board.png
Binary files differ
diff --git a/doc/user/project/img/issue_board_add_list.png b/doc/user/project/img/issue_board_add_list.png
index 2b8c10eaa0a..cdfc466d23f 100644
--- a/doc/user/project/img/issue_board_add_list.png
+++ b/doc/user/project/img/issue_board_add_list.png
Binary files differ
diff --git a/doc/user/project/img/issue_board_search_backlog.png b/doc/user/project/img/issue_board_search_backlog.png
index 112ea171539..fbb67b9c18f 100644
--- a/doc/user/project/img/issue_board_search_backlog.png
+++ b/doc/user/project/img/issue_board_search_backlog.png
Binary files differ
diff --git a/doc/user/project/img/issue_board_system_notes.png b/doc/user/project/img/issue_board_system_notes.png
index b69ef034954..bd0f5f54095 100644
--- a/doc/user/project/img/issue_board_system_notes.png
+++ b/doc/user/project/img/issue_board_system_notes.png
Binary files differ
diff --git a/doc/user/project/img/issue_board_welcome_message.png b/doc/user/project/img/issue_board_welcome_message.png
index b757faeb230..5bfdac88dde 100644
--- a/doc/user/project/img/issue_board_welcome_message.png
+++ b/doc/user/project/img/issue_board_welcome_message.png
Binary files differ
diff --git a/doc/user/project/img/koding_build-in-progress.png b/doc/user/project/img/koding_build-in-progress.png
index f8cc81834c4..79b7b2f10a2 100644
--- a/doc/user/project/img/koding_build-in-progress.png
+++ b/doc/user/project/img/koding_build-in-progress.png
Binary files differ
diff --git a/doc/user/project/img/koding_build-logs.png b/doc/user/project/img/koding_build-logs.png
index a04cd5aff99..b30c8375b20 100644
--- a/doc/user/project/img/koding_build-logs.png
+++ b/doc/user/project/img/koding_build-logs.png
Binary files differ
diff --git a/doc/user/project/img/koding_build-success.png b/doc/user/project/img/koding_build-success.png
index 2a0dd296480..a2342cfd324 100644
--- a/doc/user/project/img/koding_build-success.png
+++ b/doc/user/project/img/koding_build-success.png
Binary files differ
diff --git a/doc/user/project/img/koding_commit-koding.yml.png b/doc/user/project/img/koding_commit-koding.yml.png
index 3e133c50327..16842410ae2 100644
--- a/doc/user/project/img/koding_commit-koding.yml.png
+++ b/doc/user/project/img/koding_commit-koding.yml.png
Binary files differ
diff --git a/doc/user/project/img/koding_different-stack-on-mr-try.png b/doc/user/project/img/koding_different-stack-on-mr-try.png
index fd25e32f648..10c7c51d2e6 100644
--- a/doc/user/project/img/koding_different-stack-on-mr-try.png
+++ b/doc/user/project/img/koding_different-stack-on-mr-try.png
Binary files differ
diff --git a/doc/user/project/img/koding_edit-on-ide.png b/doc/user/project/img/koding_edit-on-ide.png
index fd5aaff75f5..ab861281d3e 100644
--- a/doc/user/project/img/koding_edit-on-ide.png
+++ b/doc/user/project/img/koding_edit-on-ide.png
Binary files differ
diff --git a/doc/user/project/img/koding_enable-koding.png b/doc/user/project/img/koding_enable-koding.png
index c0ae0ee9918..0b6fcfadcc5 100644
--- a/doc/user/project/img/koding_enable-koding.png
+++ b/doc/user/project/img/koding_enable-koding.png
Binary files differ
diff --git a/doc/user/project/img/koding_landing.png b/doc/user/project/img/koding_landing.png
index 7c629d9b05e..1eeddcd3813 100644
--- a/doc/user/project/img/koding_landing.png
+++ b/doc/user/project/img/koding_landing.png
Binary files differ
diff --git a/doc/user/project/img/koding_open-gitlab-from-koding.png b/doc/user/project/img/koding_open-gitlab-from-koding.png
index c958cf8f224..4235a72b36f 100644
--- a/doc/user/project/img/koding_open-gitlab-from-koding.png
+++ b/doc/user/project/img/koding_open-gitlab-from-koding.png
Binary files differ
diff --git a/doc/user/project/img/koding_run-in-ide.png b/doc/user/project/img/koding_run-in-ide.png
index f91ee0f74cc..d22e5023c59 100644
--- a/doc/user/project/img/koding_run-in-ide.png
+++ b/doc/user/project/img/koding_run-in-ide.png
Binary files differ
diff --git a/doc/user/project/img/koding_run-mr-in-ide.png b/doc/user/project/img/koding_run-mr-in-ide.png
index 502817a2a46..cb1112c4034 100644
--- a/doc/user/project/img/koding_run-mr-in-ide.png
+++ b/doc/user/project/img/koding_run-mr-in-ide.png
Binary files differ
diff --git a/doc/user/project/img/koding_set-up-ide.png b/doc/user/project/img/koding_set-up-ide.png
index 7f408c980b5..033d41729a2 100644
--- a/doc/user/project/img/koding_set-up-ide.png
+++ b/doc/user/project/img/koding_set-up-ide.png
Binary files differ
diff --git a/doc/user/project/img/koding_stack-import.png b/doc/user/project/img/koding_stack-import.png
index 2a4e3c87fc8..245ccb07ba3 100644
--- a/doc/user/project/img/koding_stack-import.png
+++ b/doc/user/project/img/koding_stack-import.png
Binary files differ
diff --git a/doc/user/project/img/koding_start-build.png b/doc/user/project/img/koding_start-build.png
index 52159440f62..3f5c16d5d2f 100644
--- a/doc/user/project/img/koding_start-build.png
+++ b/doc/user/project/img/koding_start-build.png
Binary files differ
diff --git a/doc/user/project/img/labels_assign_label_in_new_issue.png b/doc/user/project/img/labels_assign_label_in_new_issue.png
index e32a35f7cda..badfbed0bbe 100644
--- a/doc/user/project/img/labels_assign_label_in_new_issue.png
+++ b/doc/user/project/img/labels_assign_label_in_new_issue.png
Binary files differ
diff --git a/doc/user/project/img/labels_assign_label_sidebar.png b/doc/user/project/img/labels_assign_label_sidebar.png
index 799443af889..d74796fdb4d 100644
--- a/doc/user/project/img/labels_assign_label_sidebar.png
+++ b/doc/user/project/img/labels_assign_label_sidebar.png
Binary files differ
diff --git a/doc/user/project/img/labels_assign_label_sidebar_saved.png b/doc/user/project/img/labels_assign_label_sidebar_saved.png
index e7d8d69e60e..dabffe956dc 100644
--- a/doc/user/project/img/labels_assign_label_sidebar_saved.png
+++ b/doc/user/project/img/labels_assign_label_sidebar_saved.png
Binary files differ
diff --git a/doc/user/project/img/labels_default.png b/doc/user/project/img/labels_default.png
index ee0c9f889ad..474953d565b 100644
--- a/doc/user/project/img/labels_default.png
+++ b/doc/user/project/img/labels_default.png
Binary files differ
diff --git a/doc/user/project/img/labels_description_tooltip.png b/doc/user/project/img/labels_description_tooltip.png
index 0d1e3e091fb..eea4f8cf0f4 100644
--- a/doc/user/project/img/labels_description_tooltip.png
+++ b/doc/user/project/img/labels_description_tooltip.png
Binary files differ
diff --git a/doc/user/project/img/labels_filter.png b/doc/user/project/img/labels_filter.png
index ed622be2d93..3aca77f0070 100644
--- a/doc/user/project/img/labels_filter.png
+++ b/doc/user/project/img/labels_filter.png
Binary files differ
diff --git a/doc/user/project/img/labels_filter_by_priority.png b/doc/user/project/img/labels_filter_by_priority.png
index c5a9e20919b..5609a1f6d7f 100644
--- a/doc/user/project/img/labels_filter_by_priority.png
+++ b/doc/user/project/img/labels_filter_by_priority.png
Binary files differ
diff --git a/doc/user/project/img/labels_generate.png b/doc/user/project/img/labels_generate.png
index 9579be4e231..987f4b5be71 100644
--- a/doc/user/project/img/labels_generate.png
+++ b/doc/user/project/img/labels_generate.png
Binary files differ
diff --git a/doc/user/project/img/labels_new_label.png b/doc/user/project/img/labels_new_label.png
index a916d3dceb5..b44b4bd296d 100644
--- a/doc/user/project/img/labels_new_label.png
+++ b/doc/user/project/img/labels_new_label.png
Binary files differ
diff --git a/doc/user/project/img/labels_new_label_on_the_fly.png b/doc/user/project/img/labels_new_label_on_the_fly.png
index 80cc434239e..2ac9805b1ab 100644
--- a/doc/user/project/img/labels_new_label_on_the_fly.png
+++ b/doc/user/project/img/labels_new_label_on_the_fly.png
Binary files differ
diff --git a/doc/user/project/img/labels_new_label_on_the_fly_create.png b/doc/user/project/img/labels_new_label_on_the_fly_create.png
index c41090945eb..02ccf68553b 100644
--- a/doc/user/project/img/labels_new_label_on_the_fly_create.png
+++ b/doc/user/project/img/labels_new_label_on_the_fly_create.png
Binary files differ
diff --git a/doc/user/project/img/labels_prioritize.png b/doc/user/project/img/labels_prioritize.png
index 8dfe72cf826..3e888f36364 100644
--- a/doc/user/project/img/labels_prioritize.png
+++ b/doc/user/project/img/labels_prioritize.png
Binary files differ
diff --git a/doc/user/project/img/labels_subscribe.png b/doc/user/project/img/labels_subscribe.png
index ea3db2bc0cf..56f24ae7bc8 100644
--- a/doc/user/project/img/labels_subscribe.png
+++ b/doc/user/project/img/labels_subscribe.png
Binary files differ
diff --git a/doc/user/project/img/mitmproxy-docker.png b/doc/user/project/img/mitmproxy-docker.png
index 4e3e37b413d..aa3b6a0b830 100644
--- a/doc/user/project/img/mitmproxy-docker.png
+++ b/doc/user/project/img/mitmproxy-docker.png
Binary files differ
diff --git a/doc/user/project/img/project_settings_list.png b/doc/user/project/img/project_settings_list.png
index cd9f5c00eea..0bb761b45c9 100644
--- a/doc/user/project/img/project_settings_list.png
+++ b/doc/user/project/img/project_settings_list.png
Binary files differ
diff --git a/doc/user/project/img/protected_branches_choose_branch.png b/doc/user/project/img/protected_branches_choose_branch.png
index 26328143717..c2848db9c96 100644
--- a/doc/user/project/img/protected_branches_choose_branch.png
+++ b/doc/user/project/img/protected_branches_choose_branch.png
Binary files differ
diff --git a/doc/user/project/img/protected_branches_devs_can_push.png b/doc/user/project/img/protected_branches_devs_can_push.png
index 812cc8767b7..1c05cb8fd36 100644
--- a/doc/user/project/img/protected_branches_devs_can_push.png
+++ b/doc/user/project/img/protected_branches_devs_can_push.png
Binary files differ
diff --git a/doc/user/project/img/protected_branches_error_ui.png b/doc/user/project/img/protected_branches_error_ui.png
index cc61df7ca97..3f8e462d3ad 100644
--- a/doc/user/project/img/protected_branches_error_ui.png
+++ b/doc/user/project/img/protected_branches_error_ui.png
Binary files differ
diff --git a/doc/user/project/img/protected_branches_list.png b/doc/user/project/img/protected_branches_list.png
index f33f1b2bdb6..1b2936cb711 100644
--- a/doc/user/project/img/protected_branches_list.png
+++ b/doc/user/project/img/protected_branches_list.png
Binary files differ
diff --git a/doc/user/project/img/protected_branches_matches.png b/doc/user/project/img/protected_branches_matches.png
index 30ce53f704e..d7f2c8582fc 100644
--- a/doc/user/project/img/protected_branches_matches.png
+++ b/doc/user/project/img/protected_branches_matches.png
Binary files differ
diff --git a/doc/user/project/img/protected_branches_page.png b/doc/user/project/img/protected_branches_page.png
index 1585dde5b29..4e5afff3bae 100644
--- a/doc/user/project/img/protected_branches_page.png
+++ b/doc/user/project/img/protected_branches_page.png
Binary files differ
diff --git a/doc/user/project/issue_board.md b/doc/user/project/issue_board.md
index 4a6c0d88241..d1ae57c00d7 100644
--- a/doc/user/project/issue_board.md
+++ b/doc/user/project/issue_board.md
@@ -72,7 +72,7 @@ the list will be created and filled with the issues that have that label.
## Creating a new list
-Create a new list by clicking on the **Create new list** button at the upper
+Create a new list by clicking on the **Add list** button at the upper
right corner of the Issue Board.
![Issue Board welcome message](img/issue_board_add_list.png)
diff --git a/doc/user/project/merge_requests/img/cherry_pick_changes_commit.png b/doc/user/project/merge_requests/img/cherry_pick_changes_commit.png
index 7fb68cc9e9b..5ab094ab367 100644
--- a/doc/user/project/merge_requests/img/cherry_pick_changes_commit.png
+++ b/doc/user/project/merge_requests/img/cherry_pick_changes_commit.png
Binary files differ
diff --git a/doc/user/project/merge_requests/img/cherry_pick_changes_commit_modal.png b/doc/user/project/merge_requests/img/cherry_pick_changes_commit_modal.png
index 5267e04562f..42dcb9203ec 100644
--- a/doc/user/project/merge_requests/img/cherry_pick_changes_commit_modal.png
+++ b/doc/user/project/merge_requests/img/cherry_pick_changes_commit_modal.png
Binary files differ
diff --git a/doc/user/project/merge_requests/img/cherry_pick_changes_mr.png b/doc/user/project/merge_requests/img/cherry_pick_changes_mr.png
index 975fb13e463..71227747182 100644
--- a/doc/user/project/merge_requests/img/cherry_pick_changes_mr.png
+++ b/doc/user/project/merge_requests/img/cherry_pick_changes_mr.png
Binary files differ
diff --git a/doc/user/project/merge_requests/img/cherry_pick_changes_mr_modal.png b/doc/user/project/merge_requests/img/cherry_pick_changes_mr_modal.png
index 6c003bacbe3..604eb22f51c 100644
--- a/doc/user/project/merge_requests/img/cherry_pick_changes_mr_modal.png
+++ b/doc/user/project/merge_requests/img/cherry_pick_changes_mr_modal.png
Binary files differ
diff --git a/doc/user/project/merge_requests/img/commit_compare.png b/doc/user/project/merge_requests/img/commit_compare.png
index 0e4a2b23c04..e612a39716e 100644
--- a/doc/user/project/merge_requests/img/commit_compare.png
+++ b/doc/user/project/merge_requests/img/commit_compare.png
Binary files differ
diff --git a/doc/user/project/merge_requests/img/conflict_section.png b/doc/user/project/merge_requests/img/conflict_section.png
index 842e50b14b2..cfc17013218 100644
--- a/doc/user/project/merge_requests/img/conflict_section.png
+++ b/doc/user/project/merge_requests/img/conflict_section.png
Binary files differ
diff --git a/doc/user/project/merge_requests/img/discussion_view.png b/doc/user/project/merge_requests/img/discussion_view.png
index 83bb60acce2..2ee1db2eab3 100644
--- a/doc/user/project/merge_requests/img/discussion_view.png
+++ b/doc/user/project/merge_requests/img/discussion_view.png
Binary files differ
diff --git a/doc/user/project/merge_requests/img/discussions_resolved.png b/doc/user/project/merge_requests/img/discussions_resolved.png
index 85428129ac8..3fd496f6da5 100644
--- a/doc/user/project/merge_requests/img/discussions_resolved.png
+++ b/doc/user/project/merge_requests/img/discussions_resolved.png
Binary files differ
diff --git a/doc/user/project/merge_requests/img/merge_request_diff.png b/doc/user/project/merge_requests/img/merge_request_diff.png
index 06ee4908edc..9c5488cb207 100644
--- a/doc/user/project/merge_requests/img/merge_request_diff.png
+++ b/doc/user/project/merge_requests/img/merge_request_diff.png
Binary files differ
diff --git a/doc/user/project/merge_requests/img/merge_request_widget.png b/doc/user/project/merge_requests/img/merge_request_widget.png
index ffb96b17b07..43a945c74d9 100644
--- a/doc/user/project/merge_requests/img/merge_request_widget.png
+++ b/doc/user/project/merge_requests/img/merge_request_widget.png
Binary files differ
diff --git a/doc/user/project/merge_requests/img/merge_when_build_succeeds_enable.png b/doc/user/project/merge_requests/img/merge_when_build_succeeds_enable.png
index b86e6d7b3fd..f50a1be24f2 100644
--- a/doc/user/project/merge_requests/img/merge_when_build_succeeds_enable.png
+++ b/doc/user/project/merge_requests/img/merge_when_build_succeeds_enable.png
Binary files differ
diff --git a/doc/user/project/merge_requests/img/merge_when_build_succeeds_only_if_succeeds_msg.png b/doc/user/project/merge_requests/img/merge_when_build_succeeds_only_if_succeeds_msg.png
index 6b9756b7418..c43f76b058c 100644
--- a/doc/user/project/merge_requests/img/merge_when_build_succeeds_only_if_succeeds_msg.png
+++ b/doc/user/project/merge_requests/img/merge_when_build_succeeds_only_if_succeeds_msg.png
Binary files differ
diff --git a/doc/user/project/merge_requests/img/merge_when_build_succeeds_only_if_succeeds_settings.png b/doc/user/project/merge_requests/img/merge_when_build_succeeds_only_if_succeeds_settings.png
index 18bebf5fe92..ddc58ff2630 100644
--- a/doc/user/project/merge_requests/img/merge_when_build_succeeds_only_if_succeeds_settings.png
+++ b/doc/user/project/merge_requests/img/merge_when_build_succeeds_only_if_succeeds_settings.png
Binary files differ
diff --git a/doc/user/project/merge_requests/img/merge_when_build_succeeds_status.png b/doc/user/project/merge_requests/img/merge_when_build_succeeds_status.png
index f3ea61d8147..a98636ee359 100644
--- a/doc/user/project/merge_requests/img/merge_when_build_succeeds_status.png
+++ b/doc/user/project/merge_requests/img/merge_when_build_succeeds_status.png
Binary files differ
diff --git a/doc/user/project/merge_requests/img/only_allow_merge_if_all_discussions_are_resolved.png b/doc/user/project/merge_requests/img/only_allow_merge_if_all_discussions_are_resolved.png
index 52c8acf15e0..928c7d33898 100644
--- a/doc/user/project/merge_requests/img/only_allow_merge_if_all_discussions_are_resolved.png
+++ b/doc/user/project/merge_requests/img/only_allow_merge_if_all_discussions_are_resolved.png
Binary files differ
diff --git a/doc/user/project/merge_requests/img/only_allow_merge_if_all_discussions_are_resolved_msg.png b/doc/user/project/merge_requests/img/only_allow_merge_if_all_discussions_are_resolved_msg.png
index 79ba5c362c7..bcdc0250d7c 100644
--- a/doc/user/project/merge_requests/img/only_allow_merge_if_all_discussions_are_resolved_msg.png
+++ b/doc/user/project/merge_requests/img/only_allow_merge_if_all_discussions_are_resolved_msg.png
Binary files differ
diff --git a/doc/user/project/merge_requests/img/resolve_comment_button.png b/doc/user/project/merge_requests/img/resolve_comment_button.png
index 2c4ab2f5d53..70340108874 100644
--- a/doc/user/project/merge_requests/img/resolve_comment_button.png
+++ b/doc/user/project/merge_requests/img/resolve_comment_button.png
Binary files differ
diff --git a/doc/user/project/merge_requests/img/resolve_discussion_button.png b/doc/user/project/merge_requests/img/resolve_discussion_button.png
index 73f265bb101..ab454f661e0 100644
--- a/doc/user/project/merge_requests/img/resolve_discussion_button.png
+++ b/doc/user/project/merge_requests/img/resolve_discussion_button.png
Binary files differ
diff --git a/doc/user/project/merge_requests/img/revert_changes_commit.png b/doc/user/project/merge_requests/img/revert_changes_commit.png
index e7194fc3504..a0663e130e9 100644
--- a/doc/user/project/merge_requests/img/revert_changes_commit.png
+++ b/doc/user/project/merge_requests/img/revert_changes_commit.png
Binary files differ
diff --git a/doc/user/project/merge_requests/img/revert_changes_commit_modal.png b/doc/user/project/merge_requests/img/revert_changes_commit_modal.png
index c660ec7eaec..ef7b6dae553 100644
--- a/doc/user/project/merge_requests/img/revert_changes_commit_modal.png
+++ b/doc/user/project/merge_requests/img/revert_changes_commit_modal.png
Binary files differ
diff --git a/doc/user/project/merge_requests/img/revert_changes_mr.png b/doc/user/project/merge_requests/img/revert_changes_mr.png
index 3002f0ac1c5..8792018ee53 100644
--- a/doc/user/project/merge_requests/img/revert_changes_mr.png
+++ b/doc/user/project/merge_requests/img/revert_changes_mr.png
Binary files differ
diff --git a/doc/user/project/merge_requests/img/revert_changes_mr_modal.png b/doc/user/project/merge_requests/img/revert_changes_mr_modal.png
index c6aaeecc8a6..f6540c9dd33 100644
--- a/doc/user/project/merge_requests/img/revert_changes_mr_modal.png
+++ b/doc/user/project/merge_requests/img/revert_changes_mr_modal.png
Binary files differ
diff --git a/doc/user/project/merge_requests/img/versions.png b/doc/user/project/merge_requests/img/versions.png
index 6c86f2c68ac..33c58d2abff 100644
--- a/doc/user/project/merge_requests/img/versions.png
+++ b/doc/user/project/merge_requests/img/versions.png
Binary files differ
diff --git a/doc/user/project/merge_requests/img/versions_compare.png b/doc/user/project/merge_requests/img/versions_compare.png
index 890cae7768c..db978ea7b1d 100644
--- a/doc/user/project/merge_requests/img/versions_compare.png
+++ b/doc/user/project/merge_requests/img/versions_compare.png
Binary files differ
diff --git a/doc/user/project/merge_requests/img/versions_dropdown.png b/doc/user/project/merge_requests/img/versions_dropdown.png
index 9bab9304e14..889a2d93e6c 100644
--- a/doc/user/project/merge_requests/img/versions_dropdown.png
+++ b/doc/user/project/merge_requests/img/versions_dropdown.png
Binary files differ
diff --git a/doc/user/project/merge_requests/img/versions_system_note.png b/doc/user/project/merge_requests/img/versions_system_note.png
index 7c9d7715745..90be6298d15 100644
--- a/doc/user/project/merge_requests/img/versions_system_note.png
+++ b/doc/user/project/merge_requests/img/versions_system_note.png
Binary files differ
diff --git a/doc/user/project/merge_requests/img/wip_blocked_accept_button.png b/doc/user/project/merge_requests/img/wip_blocked_accept_button.png
index 89c458aa8d9..047b0b4620f 100644
--- a/doc/user/project/merge_requests/img/wip_blocked_accept_button.png
+++ b/doc/user/project/merge_requests/img/wip_blocked_accept_button.png
Binary files differ
diff --git a/doc/user/project/merge_requests/img/wip_mark_as_wip.png b/doc/user/project/merge_requests/img/wip_mark_as_wip.png
index 9c37354a653..8bd206bc24a 100644
--- a/doc/user/project/merge_requests/img/wip_mark_as_wip.png
+++ b/doc/user/project/merge_requests/img/wip_mark_as_wip.png
Binary files differ
diff --git a/doc/user/project/merge_requests/img/wip_unmark_as_wip.png b/doc/user/project/merge_requests/img/wip_unmark_as_wip.png
index 31f7326beb0..c0bfa6a35a2 100644
--- a/doc/user/project/merge_requests/img/wip_unmark_as_wip.png
+++ b/doc/user/project/merge_requests/img/wip_unmark_as_wip.png
Binary files differ
diff --git a/doc/user/project/pipelines/img/pipelines_settings_badges.png b/doc/user/project/pipelines/img/pipelines_settings_badges.png
index d0c4640791d..3bdc6374c15 100644
--- a/doc/user/project/pipelines/img/pipelines_settings_badges.png
+++ b/doc/user/project/pipelines/img/pipelines_settings_badges.png
Binary files differ
diff --git a/doc/user/project/pipelines/img/pipelines_settings_test_coverage.png b/doc/user/project/pipelines/img/pipelines_settings_test_coverage.png
index d2a5568521f..2a99201e014 100644
--- a/doc/user/project/pipelines/img/pipelines_settings_test_coverage.png
+++ b/doc/user/project/pipelines/img/pipelines_settings_test_coverage.png
Binary files differ
diff --git a/doc/user/project/pipelines/img/pipelines_test_coverage_build.png b/doc/user/project/pipelines/img/pipelines_test_coverage_build.png
index 3823100daf2..7eaba1a256f 100644
--- a/doc/user/project/pipelines/img/pipelines_test_coverage_build.png
+++ b/doc/user/project/pipelines/img/pipelines_test_coverage_build.png
Binary files differ
diff --git a/doc/user/project/pipelines/img/pipelines_test_coverage_mr_widget.png b/doc/user/project/pipelines/img/pipelines_test_coverage_mr_widget.png
index c4f78803e69..c166bb8bec8 100644
--- a/doc/user/project/pipelines/img/pipelines_test_coverage_mr_widget.png
+++ b/doc/user/project/pipelines/img/pipelines_test_coverage_mr_widget.png
Binary files differ
diff --git a/doc/user/project/repository/img/web_editor_new_branch_dropdown.png b/doc/user/project/repository/img/web_editor_new_branch_dropdown.png
index a8e635d2faf..31edb6bde3a 100644
--- a/doc/user/project/repository/img/web_editor_new_branch_dropdown.png
+++ b/doc/user/project/repository/img/web_editor_new_branch_dropdown.png
Binary files differ
diff --git a/doc/user/project/repository/img/web_editor_new_branch_from_issue.png b/doc/user/project/repository/img/web_editor_new_branch_from_issue.png
index b0a63ddf0ab..4729f5383c0 100644
--- a/doc/user/project/repository/img/web_editor_new_branch_from_issue.png
+++ b/doc/user/project/repository/img/web_editor_new_branch_from_issue.png
Binary files differ
diff --git a/doc/user/project/repository/img/web_editor_new_branch_page.png b/doc/user/project/repository/img/web_editor_new_branch_page.png
index 7f36b7faf63..8d82f981527 100644
--- a/doc/user/project/repository/img/web_editor_new_branch_page.png
+++ b/doc/user/project/repository/img/web_editor_new_branch_page.png
Binary files differ
diff --git a/doc/user/project/repository/img/web_editor_new_directory_dialog.png b/doc/user/project/repository/img/web_editor_new_directory_dialog.png
index d16e3c67116..1c9beff8849 100644
--- a/doc/user/project/repository/img/web_editor_new_directory_dialog.png
+++ b/doc/user/project/repository/img/web_editor_new_directory_dialog.png
Binary files differ
diff --git a/doc/user/project/repository/img/web_editor_new_directory_dropdown.png b/doc/user/project/repository/img/web_editor_new_directory_dropdown.png
index c8d77b16ee8..ede691f6f74 100644
--- a/doc/user/project/repository/img/web_editor_new_directory_dropdown.png
+++ b/doc/user/project/repository/img/web_editor_new_directory_dropdown.png
Binary files differ
diff --git a/doc/user/project/repository/img/web_editor_new_file_dropdown.png b/doc/user/project/repository/img/web_editor_new_file_dropdown.png
index 3fcb91c9b93..13a4d721039 100644
--- a/doc/user/project/repository/img/web_editor_new_file_dropdown.png
+++ b/doc/user/project/repository/img/web_editor_new_file_dropdown.png
Binary files differ
diff --git a/doc/user/project/repository/img/web_editor_new_file_editor.png b/doc/user/project/repository/img/web_editor_new_file_editor.png
index 21c340b9288..d0bcc69bf63 100644
--- a/doc/user/project/repository/img/web_editor_new_file_editor.png
+++ b/doc/user/project/repository/img/web_editor_new_file_editor.png
Binary files differ
diff --git a/doc/user/project/repository/img/web_editor_new_push_widget.png b/doc/user/project/repository/img/web_editor_new_push_widget.png
index c7738a4c930..77756876d4f 100644
--- a/doc/user/project/repository/img/web_editor_new_push_widget.png
+++ b/doc/user/project/repository/img/web_editor_new_push_widget.png
Binary files differ
diff --git a/doc/user/project/repository/img/web_editor_new_tag_dropdown.png b/doc/user/project/repository/img/web_editor_new_tag_dropdown.png
index ac7415009b3..b52d5cabdf2 100644
--- a/doc/user/project/repository/img/web_editor_new_tag_dropdown.png
+++ b/doc/user/project/repository/img/web_editor_new_tag_dropdown.png
Binary files differ
diff --git a/doc/user/project/repository/img/web_editor_new_tag_page.png b/doc/user/project/repository/img/web_editor_new_tag_page.png
index 231e1a13fc0..d6d9945397c 100644
--- a/doc/user/project/repository/img/web_editor_new_tag_page.png
+++ b/doc/user/project/repository/img/web_editor_new_tag_page.png
Binary files differ
diff --git a/doc/user/project/repository/img/web_editor_start_new_merge_request.png b/doc/user/project/repository/img/web_editor_start_new_merge_request.png
index 2755501dfd1..384e8320f15 100644
--- a/doc/user/project/repository/img/web_editor_start_new_merge_request.png
+++ b/doc/user/project/repository/img/web_editor_start_new_merge_request.png
Binary files differ
diff --git a/doc/user/project/repository/img/web_editor_template_dropdown_buttons.png b/doc/user/project/repository/img/web_editor_template_dropdown_buttons.png
index 4efc51cc423..f21183125f6 100644
--- a/doc/user/project/repository/img/web_editor_template_dropdown_buttons.png
+++ b/doc/user/project/repository/img/web_editor_template_dropdown_buttons.png
Binary files differ
diff --git a/doc/user/project/repository/img/web_editor_template_dropdown_first_file.png b/doc/user/project/repository/img/web_editor_template_dropdown_first_file.png
index 67190c58823..7f31c2a8887 100644
--- a/doc/user/project/repository/img/web_editor_template_dropdown_first_file.png
+++ b/doc/user/project/repository/img/web_editor_template_dropdown_first_file.png
Binary files differ
diff --git a/doc/user/project/repository/img/web_editor_template_dropdown_mit_license.png b/doc/user/project/repository/img/web_editor_template_dropdown_mit_license.png
index 47719113805..afd44d78959 100644
--- a/doc/user/project/repository/img/web_editor_template_dropdown_mit_license.png
+++ b/doc/user/project/repository/img/web_editor_template_dropdown_mit_license.png
Binary files differ
diff --git a/doc/user/project/repository/img/web_editor_upload_file_dialog.png b/doc/user/project/repository/img/web_editor_upload_file_dialog.png
index 9d6d8250bbe..04e951406ad 100644
--- a/doc/user/project/repository/img/web_editor_upload_file_dialog.png
+++ b/doc/user/project/repository/img/web_editor_upload_file_dialog.png
Binary files differ
diff --git a/doc/user/project/repository/img/web_editor_upload_file_dropdown.png b/doc/user/project/repository/img/web_editor_upload_file_dropdown.png
index 6b5205b05ec..b8c766d4b99 100644
--- a/doc/user/project/repository/img/web_editor_upload_file_dropdown.png
+++ b/doc/user/project/repository/img/web_editor_upload_file_dropdown.png
Binary files differ
diff --git a/doc/user/project/settings/img/import_export_download_export.png b/doc/user/project/settings/img/import_export_download_export.png
index a2f7f0085c1..4945590e3e8 100644
--- a/doc/user/project/settings/img/import_export_download_export.png
+++ b/doc/user/project/settings/img/import_export_download_export.png
Binary files differ
diff --git a/doc/user/project/settings/img/import_export_export_button.png b/doc/user/project/settings/img/import_export_export_button.png
index 1f7bdd21b0d..eef79821f8b 100644
--- a/doc/user/project/settings/img/import_export_export_button.png
+++ b/doc/user/project/settings/img/import_export_export_button.png
Binary files differ
diff --git a/doc/user/project/settings/img/import_export_mail_link.png b/doc/user/project/settings/img/import_export_mail_link.png
index c123f83eb8e..48ef42855bc 100644
--- a/doc/user/project/settings/img/import_export_mail_link.png
+++ b/doc/user/project/settings/img/import_export_mail_link.png
Binary files differ
diff --git a/doc/user/project/settings/img/import_export_new_project.png b/doc/user/project/settings/img/import_export_new_project.png
index b3a7f201018..9dd509dc4a0 100644
--- a/doc/user/project/settings/img/import_export_new_project.png
+++ b/doc/user/project/settings/img/import_export_new_project.png
Binary files differ
diff --git a/doc/user/project/settings/img/import_export_select_file.png b/doc/user/project/settings/img/import_export_select_file.png
index f31832af3e1..fb831dca32b 100644
--- a/doc/user/project/settings/img/import_export_select_file.png
+++ b/doc/user/project/settings/img/import_export_select_file.png
Binary files differ
diff --git a/doc/user/project/settings/img/settings_edit_button.png b/doc/user/project/settings/img/settings_edit_button.png
index 3c0cee536de..9f3a8330e3a 100644
--- a/doc/user/project/settings/img/settings_edit_button.png
+++ b/doc/user/project/settings/img/settings_edit_button.png
Binary files differ
diff --git a/doc/web_hooks/ssl.png b/doc/web_hooks/ssl.png
index 8c4f08d1825..a552888ed96 100644
--- a/doc/web_hooks/ssl.png
+++ b/doc/web_hooks/ssl.png
Binary files differ
diff --git a/doc/web_hooks/web_hooks.md b/doc/web_hooks/web_hooks.md
index 33c1a79d59c..cd37189fdd2 100644
--- a/doc/web_hooks/web_hooks.md
+++ b/doc/web_hooks/web_hooks.md
@@ -922,6 +922,64 @@ X-Gitlab-Event: Pipeline Hook
}
```
+
+## Build events
+
+Triggered on status change of a Build.
+
+**Request Header**:
+
+```
+X-Gitlab-Event: Build Hook
+```
+
+**Request Body**:
+
+```
+{
+ "object_kind": "build",
+ "ref": "gitlab-script-trigger",
+ "tag": false,
+ "before_sha": "2293ada6b400935a1378653304eaf6221e0fdb8f",
+ "sha": "2293ada6b400935a1378653304eaf6221e0fdb8f",
+ "build_id": 1977,
+ "build_name": "test",
+ "build_stage": "test",
+ "build_status": "created",
+ "build_started_at": null,
+ "build_finished_at": null,
+ "build_duration": null,
+ "build_allow_failure": false,
+ "project_id": 380,
+ "project_name": "gitlab-org/gitlab-test",
+ "user": {
+ "id": 3,
+ "name": "User",
+ "email": "user@gitlab.com"
+ },
+ "commit": {
+ "id": 2366,
+ "sha": "2293ada6b400935a1378653304eaf6221e0fdb8f",
+ "message": "test\n",
+ "author_name": "User",
+ "author_email": "user@gitlab.com",
+ "status": "created",
+ "duration": null,
+ "started_at": null,
+ "finished_at": null
+ },
+ "repository": {
+ "name": "gitlab_test",
+ "git_ssh_url": "git@192.168.64.1:gitlab-org/gitlab-test.git",
+ "description": "Atque in sunt eos similique dolores voluptatem.",
+ "homepage": "http://192.168.64.1:3005/gitlab-org/gitlab-test",
+ "git_ssh_url": "git@192.168.64.1:gitlab-org/gitlab-test.git",
+ "git_http_url": "http://192.168.64.1:3005/gitlab-org/gitlab-test.git",
+ "visibility_level": 20
+ }
+}
+```
+
#### Example webhook receiver
If you want to see GitLab's webhooks in action for testing purposes you can use
diff --git a/doc/workflow/add-user/img/access_requests_management.png b/doc/workflow/add-user/img/access_requests_management.png
index 5c9b510ba9d..3693bed869b 100644
--- a/doc/workflow/add-user/img/access_requests_management.png
+++ b/doc/workflow/add-user/img/access_requests_management.png
Binary files differ
diff --git a/doc/workflow/add-user/img/add_new_user_to_project_settings.png b/doc/workflow/add-user/img/add_new_user_to_project_settings.png
index 5da0552f9d6..40db600455f 100644
--- a/doc/workflow/add-user/img/add_new_user_to_project_settings.png
+++ b/doc/workflow/add-user/img/add_new_user_to_project_settings.png
Binary files differ
diff --git a/doc/workflow/add-user/img/add_user_email_accept.png b/doc/workflow/add-user/img/add_user_email_accept.png
index a2954ad7c37..763b3ff463d 100644
--- a/doc/workflow/add-user/img/add_user_email_accept.png
+++ b/doc/workflow/add-user/img/add_user_email_accept.png
Binary files differ
diff --git a/doc/workflow/add-user/img/add_user_email_ready.png b/doc/workflow/add-user/img/add_user_email_ready.png
index 19d91bc0999..0066eb3427b 100644
--- a/doc/workflow/add-user/img/add_user_email_ready.png
+++ b/doc/workflow/add-user/img/add_user_email_ready.png
Binary files differ
diff --git a/doc/workflow/add-user/img/add_user_email_search.png b/doc/workflow/add-user/img/add_user_email_search.png
index cb31b77d941..66bcd6aad80 100644
--- a/doc/workflow/add-user/img/add_user_email_search.png
+++ b/doc/workflow/add-user/img/add_user_email_search.png
Binary files differ
diff --git a/doc/workflow/add-user/img/add_user_give_permissions.png b/doc/workflow/add-user/img/add_user_give_permissions.png
index e6b77022f06..376a3eefccc 100644
--- a/doc/workflow/add-user/img/add_user_give_permissions.png
+++ b/doc/workflow/add-user/img/add_user_give_permissions.png
Binary files differ
diff --git a/doc/workflow/add-user/img/add_user_import_members_from_another_project.png b/doc/workflow/add-user/img/add_user_import_members_from_another_project.png
index 1068589c5ff..0c32001098e 100644
--- a/doc/workflow/add-user/img/add_user_import_members_from_another_project.png
+++ b/doc/workflow/add-user/img/add_user_import_members_from_another_project.png
Binary files differ
diff --git a/doc/workflow/add-user/img/add_user_imported_members.png b/doc/workflow/add-user/img/add_user_imported_members.png
index 5cd120a4245..51fd7688890 100644
--- a/doc/workflow/add-user/img/add_user_imported_members.png
+++ b/doc/workflow/add-user/img/add_user_imported_members.png
Binary files differ
diff --git a/doc/workflow/add-user/img/add_user_list_members.png b/doc/workflow/add-user/img/add_user_list_members.png
index 5fe3482192e..e0fa404288d 100644
--- a/doc/workflow/add-user/img/add_user_list_members.png
+++ b/doc/workflow/add-user/img/add_user_list_members.png
Binary files differ
diff --git a/doc/workflow/add-user/img/add_user_members_menu.png b/doc/workflow/add-user/img/add_user_members_menu.png
index 340d15c9830..8e61d15fe65 100644
--- a/doc/workflow/add-user/img/add_user_members_menu.png
+++ b/doc/workflow/add-user/img/add_user_members_menu.png
Binary files differ
diff --git a/doc/workflow/add-user/img/add_user_search_people.png b/doc/workflow/add-user/img/add_user_search_people.png
index 1c05d70ca31..41767a9167c 100644
--- a/doc/workflow/add-user/img/add_user_search_people.png
+++ b/doc/workflow/add-user/img/add_user_search_people.png
Binary files differ
diff --git a/doc/workflow/add-user/img/request_access_button.png b/doc/workflow/add-user/img/request_access_button.png
index 984d640b0f0..608baccb0ca 100644
--- a/doc/workflow/add-user/img/request_access_button.png
+++ b/doc/workflow/add-user/img/request_access_button.png
Binary files differ
diff --git a/doc/workflow/add-user/img/withdraw_access_request_button.png b/doc/workflow/add-user/img/withdraw_access_request_button.png
index ff54a0e4384..6edd786b151 100644
--- a/doc/workflow/add-user/img/withdraw_access_request_button.png
+++ b/doc/workflow/add-user/img/withdraw_access_request_button.png
Binary files differ
diff --git a/doc/workflow/award_emoji.png b/doc/workflow/award_emoji.png
index 481680af80c..1ad634a343e 100644
--- a/doc/workflow/award_emoji.png
+++ b/doc/workflow/award_emoji.png
Binary files differ
diff --git a/doc/workflow/ci_mr.png b/doc/workflow/ci_mr.png
index f8a7708643e..77423c68190 100644
--- a/doc/workflow/ci_mr.png
+++ b/doc/workflow/ci_mr.png
Binary files differ
diff --git a/doc/workflow/close_issue_mr.png b/doc/workflow/close_issue_mr.png
index 5e520240233..70de2fb6cee 100644
--- a/doc/workflow/close_issue_mr.png
+++ b/doc/workflow/close_issue_mr.png
Binary files differ
diff --git a/doc/workflow/environment_branches.png b/doc/workflow/environment_branches.png
index 13fb0478eaa..0941a4cad9c 100644
--- a/doc/workflow/environment_branches.png
+++ b/doc/workflow/environment_branches.png
Binary files differ
diff --git a/doc/workflow/forking/branch_select.png b/doc/workflow/forking/branch_select.png
index 7f19414f3a9..3e82afca75b 100644
--- a/doc/workflow/forking/branch_select.png
+++ b/doc/workflow/forking/branch_select.png
Binary files differ
diff --git a/doc/workflow/forking/merge_request.png b/doc/workflow/forking/merge_request.png
index e2da42a2be7..294775e1fdd 100644
--- a/doc/workflow/forking/merge_request.png
+++ b/doc/workflow/forking/merge_request.png
Binary files differ
diff --git a/doc/workflow/four_stages.png b/doc/workflow/four_stages.png
index 49413087dca..3ef6a33d2d4 100644
--- a/doc/workflow/four_stages.png
+++ b/doc/workflow/four_stages.png
Binary files differ
diff --git a/doc/workflow/git_pull.png b/doc/workflow/git_pull.png
index 9a1fdf899bf..2dd06b56c56 100644
--- a/doc/workflow/git_pull.png
+++ b/doc/workflow/git_pull.png
Binary files differ
diff --git a/doc/workflow/gitdashflow.png b/doc/workflow/gitdashflow.png
index e456cf9309d..65900853d84 100644
--- a/doc/workflow/gitdashflow.png
+++ b/doc/workflow/gitdashflow.png
Binary files differ
diff --git a/doc/workflow/github_flow.png b/doc/workflow/github_flow.png
index b3fca97cc2d..21a22becdb6 100644
--- a/doc/workflow/github_flow.png
+++ b/doc/workflow/github_flow.png
Binary files differ
diff --git a/doc/workflow/gitlab_flow.png b/doc/workflow/gitlab_flow.png
index d85d4ff374e..c3562cc69a8 100644
--- a/doc/workflow/gitlab_flow.png
+++ b/doc/workflow/gitlab_flow.png
Binary files differ
diff --git a/doc/workflow/good_commit.png b/doc/workflow/good_commit.png
index 7958feea4d9..c3664aa97f2 100644
--- a/doc/workflow/good_commit.png
+++ b/doc/workflow/good_commit.png
Binary files differ
diff --git a/doc/workflow/groups/access_requests_management.png b/doc/workflow/groups/access_requests_management.png
index 5202434f00f..36deaa89a70 100644
--- a/doc/workflow/groups/access_requests_management.png
+++ b/doc/workflow/groups/access_requests_management.png
Binary files differ
diff --git a/doc/workflow/groups/add_member_to_group.png b/doc/workflow/groups/add_member_to_group.png
index 6e3f660d2e4..a10d5032bb0 100644
--- a/doc/workflow/groups/add_member_to_group.png
+++ b/doc/workflow/groups/add_member_to_group.png
Binary files differ
diff --git a/doc/workflow/groups/group_dashboard.png b/doc/workflow/groups/group_dashboard.png
index 662c932e536..a5829f25808 100644
--- a/doc/workflow/groups/group_dashboard.png
+++ b/doc/workflow/groups/group_dashboard.png
Binary files differ
diff --git a/doc/workflow/groups/group_with_two_projects.png b/doc/workflow/groups/group_with_two_projects.png
index dc3475949f5..76d0a1b8ab2 100644
--- a/doc/workflow/groups/group_with_two_projects.png
+++ b/doc/workflow/groups/group_with_two_projects.png
Binary files differ
diff --git a/doc/workflow/groups/max_access_level.png b/doc/workflow/groups/max_access_level.png
index 2855a514013..63f33f9d91d 100644
--- a/doc/workflow/groups/max_access_level.png
+++ b/doc/workflow/groups/max_access_level.png
Binary files differ
diff --git a/doc/workflow/groups/new_group_button.png b/doc/workflow/groups/new_group_button.png
index 26136312c8f..7155d6280bd 100644
--- a/doc/workflow/groups/new_group_button.png
+++ b/doc/workflow/groups/new_group_button.png
Binary files differ
diff --git a/doc/workflow/groups/new_group_form.png b/doc/workflow/groups/new_group_form.png
index dc50a069ef2..0d798cd4b84 100644
--- a/doc/workflow/groups/new_group_form.png
+++ b/doc/workflow/groups/new_group_form.png
Binary files differ
diff --git a/doc/workflow/groups/other_group_sees_shared_project.png b/doc/workflow/groups/other_group_sees_shared_project.png
index 2230720cecd..67af27043eb 100644
--- a/doc/workflow/groups/other_group_sees_shared_project.png
+++ b/doc/workflow/groups/other_group_sees_shared_project.png
Binary files differ
diff --git a/doc/workflow/groups/override_access_level.png b/doc/workflow/groups/override_access_level.png
index 9d6aaf4c363..2b3e9a49842 100644
--- a/doc/workflow/groups/override_access_level.png
+++ b/doc/workflow/groups/override_access_level.png
Binary files differ
diff --git a/doc/workflow/groups/project_members_via_group.png b/doc/workflow/groups/project_members_via_group.png
index 58270936a0b..878c9a03ac9 100644
--- a/doc/workflow/groups/project_members_via_group.png
+++ b/doc/workflow/groups/project_members_via_group.png
Binary files differ
diff --git a/doc/workflow/groups/request_access_button.png b/doc/workflow/groups/request_access_button.png
index 0eec5cb937d..f1aae6afed7 100644
--- a/doc/workflow/groups/request_access_button.png
+++ b/doc/workflow/groups/request_access_button.png
Binary files differ
diff --git a/doc/workflow/groups/share_project_with_groups.png b/doc/workflow/groups/share_project_with_groups.png
index 5772d4deced..3cb4796f9f7 100644
--- a/doc/workflow/groups/share_project_with_groups.png
+++ b/doc/workflow/groups/share_project_with_groups.png
Binary files differ
diff --git a/doc/workflow/groups/transfer_project.png b/doc/workflow/groups/transfer_project.png
index 0aef3ab3f0f..52161817f11 100644
--- a/doc/workflow/groups/transfer_project.png
+++ b/doc/workflow/groups/transfer_project.png
Binary files differ
diff --git a/doc/workflow/groups/withdraw_access_request_button.png b/doc/workflow/groups/withdraw_access_request_button.png
index b7de830a780..c5d8ef6c04f 100644
--- a/doc/workflow/groups/withdraw_access_request_button.png
+++ b/doc/workflow/groups/withdraw_access_request_button.png
Binary files differ
diff --git a/doc/workflow/img/award_emoji_comment_awarded.png b/doc/workflow/img/award_emoji_comment_awarded.png
index 67697831869..111793ebf8a 100644
--- a/doc/workflow/img/award_emoji_comment_awarded.png
+++ b/doc/workflow/img/award_emoji_comment_awarded.png
Binary files differ
diff --git a/doc/workflow/img/award_emoji_comment_picker.png b/doc/workflow/img/award_emoji_comment_picker.png
index d9c3faecdca..3ad1bab3119 100644
--- a/doc/workflow/img/award_emoji_comment_picker.png
+++ b/doc/workflow/img/award_emoji_comment_picker.png
Binary files differ
diff --git a/doc/workflow/img/award_emoji_select.png b/doc/workflow/img/award_emoji_select.png
index ad664c0aeff..e1b37beaf62 100644
--- a/doc/workflow/img/award_emoji_select.png
+++ b/doc/workflow/img/award_emoji_select.png
Binary files differ
diff --git a/doc/workflow/img/award_emoji_votes_least_popular.png b/doc/workflow/img/award_emoji_votes_least_popular.png
index 57d595d9602..86ede4b0c10 100644
--- a/doc/workflow/img/award_emoji_votes_least_popular.png
+++ b/doc/workflow/img/award_emoji_votes_least_popular.png
Binary files differ
diff --git a/doc/workflow/img/award_emoji_votes_most_popular.png b/doc/workflow/img/award_emoji_votes_most_popular.png
index 432bd09b8a7..1d3e2e57aa0 100644
--- a/doc/workflow/img/award_emoji_votes_most_popular.png
+++ b/doc/workflow/img/award_emoji_votes_most_popular.png
Binary files differ
diff --git a/doc/workflow/img/award_emoji_votes_sort_options.png b/doc/workflow/img/award_emoji_votes_sort_options.png
index ae6e224b317..c6dc1b939c1 100644
--- a/doc/workflow/img/award_emoji_votes_sort_options.png
+++ b/doc/workflow/img/award_emoji_votes_sort_options.png
Binary files differ
diff --git a/doc/workflow/img/file_finder_find_button.png b/doc/workflow/img/file_finder_find_button.png
index 96e383f0213..23139cc00c5 100644
--- a/doc/workflow/img/file_finder_find_button.png
+++ b/doc/workflow/img/file_finder_find_button.png
Binary files differ
diff --git a/doc/workflow/img/file_finder_find_file.png b/doc/workflow/img/file_finder_find_file.png
index c6508514c76..c2212c7cd9e 100644
--- a/doc/workflow/img/file_finder_find_file.png
+++ b/doc/workflow/img/file_finder_find_file.png
Binary files differ
diff --git a/doc/workflow/img/forking_workflow_choose_namespace.png b/doc/workflow/img/forking_workflow_choose_namespace.png
index 1839d5e8be2..b34b12090a1 100644
--- a/doc/workflow/img/forking_workflow_choose_namespace.png
+++ b/doc/workflow/img/forking_workflow_choose_namespace.png
Binary files differ
diff --git a/doc/workflow/img/forking_workflow_fork_button.png b/doc/workflow/img/forking_workflow_fork_button.png
index cc79d6fd40c..29854e6c516 100644
--- a/doc/workflow/img/forking_workflow_fork_button.png
+++ b/doc/workflow/img/forking_workflow_fork_button.png
Binary files differ
diff --git a/doc/workflow/img/forking_workflow_path_taken_error.png b/doc/workflow/img/forking_workflow_path_taken_error.png
index a859155aef0..9365fd13200 100644
--- a/doc/workflow/img/forking_workflow_path_taken_error.png
+++ b/doc/workflow/img/forking_workflow_path_taken_error.png
Binary files differ
diff --git a/doc/workflow/img/new_branch_from_issue.png b/doc/workflow/img/new_branch_from_issue.png
index 61acdd30ae9..286d775bb9e 100644
--- a/doc/workflow/img/new_branch_from_issue.png
+++ b/doc/workflow/img/new_branch_from_issue.png
Binary files differ
diff --git a/doc/workflow/img/todo_list_item.png b/doc/workflow/img/todo_list_item.png
index 884ba1d22a3..076069b651e 100644
--- a/doc/workflow/img/todo_list_item.png
+++ b/doc/workflow/img/todo_list_item.png
Binary files differ
diff --git a/doc/workflow/img/todos_add_todo_sidebar.png b/doc/workflow/img/todos_add_todo_sidebar.png
index 126ecc2c82f..59175ae44c5 100644
--- a/doc/workflow/img/todos_add_todo_sidebar.png
+++ b/doc/workflow/img/todos_add_todo_sidebar.png
Binary files differ
diff --git a/doc/workflow/img/todos_icon.png b/doc/workflow/img/todos_icon.png
index bba77f88913..1ed16b09669 100644
--- a/doc/workflow/img/todos_icon.png
+++ b/doc/workflow/img/todos_icon.png
Binary files differ
diff --git a/doc/workflow/img/todos_index.png b/doc/workflow/img/todos_index.png
index f1438ef7355..902a5aa6bd3 100644
--- a/doc/workflow/img/todos_index.png
+++ b/doc/workflow/img/todos_index.png
Binary files differ
diff --git a/doc/workflow/img/todos_mark_done_sidebar.png b/doc/workflow/img/todos_mark_done_sidebar.png
index f449f977dd6..aa35bb672ea 100644
--- a/doc/workflow/img/todos_mark_done_sidebar.png
+++ b/doc/workflow/img/todos_mark_done_sidebar.png
Binary files differ
diff --git a/doc/workflow/importing/fogbugz_importer/fogbugz_import_finished.png b/doc/workflow/importing/fogbugz_importer/fogbugz_import_finished.png
index fd7a4d3fabf..62c5c86c9b3 100644
--- a/doc/workflow/importing/fogbugz_importer/fogbugz_import_finished.png
+++ b/doc/workflow/importing/fogbugz_importer/fogbugz_import_finished.png
Binary files differ
diff --git a/doc/workflow/importing/fogbugz_importer/fogbugz_import_login.png b/doc/workflow/importing/fogbugz_importer/fogbugz_import_login.png
index fd1ba6f5884..96bce70b74d 100644
--- a/doc/workflow/importing/fogbugz_importer/fogbugz_import_login.png
+++ b/doc/workflow/importing/fogbugz_importer/fogbugz_import_login.png
Binary files differ
diff --git a/doc/workflow/importing/fogbugz_importer/fogbugz_import_select_fogbogz.png b/doc/workflow/importing/fogbugz_importer/fogbugz_import_select_fogbogz.png
index 186c1563951..b26c652e382 100644
--- a/doc/workflow/importing/fogbugz_importer/fogbugz_import_select_fogbogz.png
+++ b/doc/workflow/importing/fogbugz_importer/fogbugz_import_select_fogbogz.png
Binary files differ
diff --git a/doc/workflow/importing/fogbugz_importer/fogbugz_import_select_project.png b/doc/workflow/importing/fogbugz_importer/fogbugz_import_select_project.png
index 2f84d3232f2..ccc82f9d4cd 100644
--- a/doc/workflow/importing/fogbugz_importer/fogbugz_import_select_project.png
+++ b/doc/workflow/importing/fogbugz_importer/fogbugz_import_select_project.png
Binary files differ
diff --git a/doc/workflow/importing/fogbugz_importer/fogbugz_import_user_map.png b/doc/workflow/importing/fogbugz_importer/fogbugz_import_user_map.png
index 652ca20b9ab..28ff55a8d89 100644
--- a/doc/workflow/importing/fogbugz_importer/fogbugz_import_user_map.png
+++ b/doc/workflow/importing/fogbugz_importer/fogbugz_import_user_map.png
Binary files differ
diff --git a/doc/workflow/importing/gitlab_importer/importer.png b/doc/workflow/importing/gitlab_importer/importer.png
index 35a7ddc8318..27d42eb492e 100644
--- a/doc/workflow/importing/gitlab_importer/importer.png
+++ b/doc/workflow/importing/gitlab_importer/importer.png
Binary files differ
diff --git a/doc/workflow/importing/gitlab_importer/new_project_page.png b/doc/workflow/importing/gitlab_importer/new_project_page.png
index 81074d2d016..c673724f436 100644
--- a/doc/workflow/importing/gitlab_importer/new_project_page.png
+++ b/doc/workflow/importing/gitlab_importer/new_project_page.png
Binary files differ
diff --git a/doc/workflow/importing/img/import_projects_from_github_importer.png b/doc/workflow/importing/img/import_projects_from_github_importer.png
index eadd33c695f..d8effaf6075 100644
--- a/doc/workflow/importing/img/import_projects_from_github_importer.png
+++ b/doc/workflow/importing/img/import_projects_from_github_importer.png
Binary files differ
diff --git a/doc/workflow/importing/img/import_projects_from_github_new_project_page.png b/doc/workflow/importing/img/import_projects_from_github_new_project_page.png
index 6e91c430a33..b23ade4480c 100644
--- a/doc/workflow/importing/img/import_projects_from_github_new_project_page.png
+++ b/doc/workflow/importing/img/import_projects_from_github_new_project_page.png
Binary files differ
diff --git a/doc/workflow/importing/img/import_projects_from_github_select_auth_method.png b/doc/workflow/importing/img/import_projects_from_github_select_auth_method.png
index c11863ab10c..f50d9266991 100644
--- a/doc/workflow/importing/img/import_projects_from_github_select_auth_method.png
+++ b/doc/workflow/importing/img/import_projects_from_github_select_auth_method.png
Binary files differ
diff --git a/doc/workflow/lfs/manage_large_binaries_with_git_lfs.md b/doc/workflow/lfs/manage_large_binaries_with_git_lfs.md
index 1a4f213a792..6a7098e79d0 100644
--- a/doc/workflow/lfs/manage_large_binaries_with_git_lfs.md
+++ b/doc/workflow/lfs/manage_large_binaries_with_git_lfs.md
@@ -24,6 +24,7 @@ Documentation for GitLab instance administrators is under [LFS administration do
## Requirements
* Git LFS is supported in GitLab starting with version 8.2
+* Git LFS must be enabled under project settings
* [Git LFS client](https://git-lfs.github.com) version 1.0.1 and up
## Known limitations
@@ -31,10 +32,10 @@ Documentation for GitLab instance administrators is under [LFS administration do
* Git LFS v1 original API is not supported since it was deprecated early in LFS
development
* When SSH is set as a remote, Git LFS objects still go through HTTPS
-* Any Git LFS request will ask for HTTPS credentials to be provided so good Git
+* Any Git LFS request will ask for HTTPS credentials to be provided so a good Git
credentials store is recommended
* Git LFS always assumes HTTPS so if you have GitLab server on HTTP you will have
- to add the URL to Git config manually (see #troubleshooting)
+ to add the URL to Git config manually (see [troubleshooting](#troubleshooting))
>**Note**: With 8.12 GitLab added LFS support to SSH. The Git LFS communication
still goes over HTTP, but now the SSH client passes the correct credentials
@@ -48,7 +49,7 @@ check it into your Git repository:
```bash
git clone git@gitlab.example.com:group/project.git
-git lfs install # initialize the Git LFS project project
+git lfs install # initialize the Git LFS project
git lfs track "*.iso" # select the file extensions that you want to treat as large files
```
@@ -95,7 +96,7 @@ available to the project anymore. Probably the object was removed from the serve
* Local git repository is using deprecated LFS API
-### Invalid status for <url> : 501
+### Invalid status for `<url>` : 501
Git LFS will log the failures into a log file.
To view this log file, while in project directory:
@@ -106,6 +107,9 @@ git lfs logs last
If the status `error 501` is shown, it is because:
+* Git LFS is not enabled in project settings. Check your project settings and
+ enable Git LFS.
+
* Git LFS support is not enabled on the GitLab server. Check with your GitLab
administrator why Git LFS is not enabled on the server. See
[LFS administration documentation](lfs_administration.md) for instructions
diff --git a/doc/workflow/merge_commits.png b/doc/workflow/merge_commits.png
index 8aa1587cde6..4a80811c6e3 100644
--- a/doc/workflow/merge_commits.png
+++ b/doc/workflow/merge_commits.png
Binary files differ
diff --git a/doc/workflow/merge_request.png b/doc/workflow/merge_request.png
index 6aad1d82f6e..08dfc7f2468 100644
--- a/doc/workflow/merge_request.png
+++ b/doc/workflow/merge_request.png
Binary files differ
diff --git a/doc/workflow/messy_flow.png b/doc/workflow/messy_flow.png
index 8d2c0dae8c2..7e72e2a3be6 100644
--- a/doc/workflow/messy_flow.png
+++ b/doc/workflow/messy_flow.png
Binary files differ
diff --git a/doc/workflow/milestones/form.png b/doc/workflow/milestones/form.png
index 3965ca4d083..c4731d88543 100644
--- a/doc/workflow/milestones/form.png
+++ b/doc/workflow/milestones/form.png
Binary files differ
diff --git a/doc/workflow/milestones/group_form.png b/doc/workflow/milestones/group_form.png
index ff20df8081f..dccdb019703 100644
--- a/doc/workflow/milestones/group_form.png
+++ b/doc/workflow/milestones/group_form.png
Binary files differ
diff --git a/doc/workflow/mr_inline_comments.png b/doc/workflow/mr_inline_comments.png
index af7df3100d0..6a2e66a01ba 100644
--- a/doc/workflow/mr_inline_comments.png
+++ b/doc/workflow/mr_inline_comments.png
Binary files differ
diff --git a/doc/workflow/notifications/settings.png b/doc/workflow/notifications/settings.png
index d50757beffc..8a5494d16a8 100644
--- a/doc/workflow/notifications/settings.png
+++ b/doc/workflow/notifications/settings.png
Binary files differ
diff --git a/doc/workflow/production_branch.png b/doc/workflow/production_branch.png
index d88a3687151..648d5d5c92e 100644
--- a/doc/workflow/production_branch.png
+++ b/doc/workflow/production_branch.png
Binary files differ
diff --git a/doc/workflow/rebase.png b/doc/workflow/rebase.png
index df353311fa0..8b9bb61a5cc 100644
--- a/doc/workflow/rebase.png
+++ b/doc/workflow/rebase.png
Binary files differ
diff --git a/doc/workflow/release_branches.png b/doc/workflow/release_branches.png
index c2162248d25..5194d75a667 100644
--- a/doc/workflow/release_branches.png
+++ b/doc/workflow/release_branches.png
Binary files differ
diff --git a/doc/workflow/releases/new_tag.png b/doc/workflow/releases/new_tag.png
index 2456a8500f4..97519e5808f 100644
--- a/doc/workflow/releases/new_tag.png
+++ b/doc/workflow/releases/new_tag.png
Binary files differ
diff --git a/doc/workflow/releases/tags.png b/doc/workflow/releases/tags.png
index eeda967afd6..4c032f96125 100644
--- a/doc/workflow/releases/tags.png
+++ b/doc/workflow/releases/tags.png
Binary files differ
diff --git a/doc/workflow/remove_checkbox.png b/doc/workflow/remove_checkbox.png
index 3b0393deb0f..fb0e792b37b 100644
--- a/doc/workflow/remove_checkbox.png
+++ b/doc/workflow/remove_checkbox.png
Binary files differ
diff --git a/features/abuse_report.feature b/features/abuse_report.feature
deleted file mode 100644
index 212972a762a..00000000000
--- a/features/abuse_report.feature
+++ /dev/null
@@ -1,17 +0,0 @@
-Feature: Abuse reports
- Background:
- Given I sign in as a user
- And user "Mike" exists
-
- Scenario: Report abuse
- Given I visit "Mike" user page
- And I click "Report abuse" button
- When I fill and submit abuse form
- Then I should see success message
-
- Scenario: Report abuse available only once
- Given I visit "Mike" user page
- And I click "Report abuse" button
- When I fill and submit abuse form
- And I visit "Mike" user page
- Then I should see a red "Report abuse" button
diff --git a/features/admin/abuse_report.feature b/features/admin/abuse_report.feature
deleted file mode 100644
index 7d4ec2556e5..00000000000
--- a/features/admin/abuse_report.feature
+++ /dev/null
@@ -1,8 +0,0 @@
-Feature: Admin Abuse reports
- Background:
- Given I sign in as an admin
- And abuse reports exist
-
- Scenario: Browse abuse reports
- When I visit abuse reports page
- Then I should see list of abuse reports
diff --git a/features/admin/spam_logs.feature b/features/admin/spam_logs.feature
deleted file mode 100644
index 92a5389e3a4..00000000000
--- a/features/admin/spam_logs.feature
+++ /dev/null
@@ -1,8 +0,0 @@
-Feature: Admin spam logs
- Background:
- Given I sign in as an admin
- And spam logs exist
-
- Scenario: Browse spam logs
- When I visit spam logs page
- Then I should see list of spam logs
diff --git a/features/steps/abuse_reports.rb b/features/steps/abuse_reports.rb
deleted file mode 100644
index 499accb0b08..00000000000
--- a/features/steps/abuse_reports.rb
+++ /dev/null
@@ -1,32 +0,0 @@
-class Spinach::Features::AbuseReports < Spinach::FeatureSteps
- include SharedAuthentication
-
- step 'I visit "Mike" user page' do
- visit user_path(user_mike)
- end
-
- step 'I click "Report abuse" button' do
- click_link 'Report abuse'
- end
-
- step 'I fill and submit abuse form' do
- fill_in 'abuse_report_message', with: 'This user send spam'
- click_button 'Send report'
- end
-
- step 'I should see success message' do
- page.should have_content 'Thank you for your report'
- end
-
- step 'user "Mike" exists' do
- user_mike
- end
-
- step 'I should see a red "Report abuse" button' do
- expect(page).to have_button("Already reported for abuse")
- end
-
- def user_mike
- @user_mike ||= create(:user, name: 'Mike')
- end
-end
diff --git a/features/steps/admin/abuse_reports.rb b/features/steps/admin/abuse_reports.rb
deleted file mode 100644
index 0149416c919..00000000000
--- a/features/steps/admin/abuse_reports.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-class Spinach::Features::AdminAbuseReports < Spinach::FeatureSteps
- include SharedAuthentication
- include SharedPaths
- include SharedAdmin
-
- step 'I should see list of abuse reports' do
- page.should have_content("Abuse Reports")
- page.should have_content AbuseReport.first.message
- page.should have_link("Remove user")
- end
-
- step 'abuse reports exist' do
- create(:abuse_report)
- end
-end
diff --git a/features/steps/admin/spam_logs.rb b/features/steps/admin/spam_logs.rb
deleted file mode 100644
index ad825fd414c..00000000000
--- a/features/steps/admin/spam_logs.rb
+++ /dev/null
@@ -1,28 +0,0 @@
-class Spinach::Features::AdminSpamLogs < Spinach::FeatureSteps
- include SharedAuthentication
- include SharedPaths
- include SharedAdmin
-
- step 'I should see list of spam logs' do
- expect(page).to have_content('Spam Logs')
- expect(page).to have_content spam_log.source_ip
- expect(page).to have_content spam_log.noteable_type
- expect(page).to have_content 'N'
- expect(page).to have_content spam_log.title
- expect(page).to have_content truncate(spam_log.description)
- expect(page).to have_link('Remove user')
- expect(page).to have_link('Block user')
- end
-
- step 'spam logs exist' do
- create(:spam_log)
- end
-
- def spam_log
- @spam_log ||= SpamLog.first
- end
-
- def truncate(description)
- "#{spam_log.description[0...97]}..."
- end
-end
diff --git a/features/steps/project/labels.rb b/features/steps/project/labels.rb
index 118ffef4774..dbeb07c78db 100644
--- a/features/steps/project/labels.rb
+++ b/features/steps/project/labels.rb
@@ -2,9 +2,7 @@ class Spinach::Features::Labels < Spinach::FeatureSteps
include SharedAuthentication
include SharedIssuable
include SharedProject
- include SharedNote
include SharedPaths
- include SharedMarkdown
step 'And I visit project "Shop" labels page' do
visit namespace_project_labels_path(project.namespace, project)
diff --git a/features/steps/shared/diff_note.rb b/features/steps/shared/diff_note.rb
index 35b71599708..11fa85ed2fe 100644
--- a/features/steps/shared/diff_note.rb
+++ b/features/steps/shared/diff_note.rb
@@ -1,6 +1,11 @@
module SharedDiffNote
include Spinach::DSL
include RepoHelpers
+ include WaitForAjax
+
+ after do
+ wait_for_ajax if javascript_test?
+ end
step 'I cancel the diff comment' do
page.within(diff_file_selector) do
diff --git a/features/steps/shared/note.rb b/features/steps/shared/note.rb
index 9dc1fc41b3b..1870f6bc0c3 100644
--- a/features/steps/shared/note.rb
+++ b/features/steps/shared/note.rb
@@ -2,6 +2,10 @@ module SharedNote
include Spinach::DSL
include WaitForAjax
+ after do
+ wait_for_ajax if javascript_test?
+ end
+
step 'I delete a comment' do
page.within('.main-notes-list') do
find('.note').hover
diff --git a/lib/api/broadcast_messages.rb b/lib/api/broadcast_messages.rb
index b6281a7f0ac..1217002bf8e 100644
--- a/lib/api/broadcast_messages.rb
+++ b/lib/api/broadcast_messages.rb
@@ -1,5 +1,7 @@
module API
class BroadcastMessages < Grape::API
+ include PaginationParams
+
before { authenticate! }
before { authenticated_as_admin! }
@@ -15,8 +17,7 @@ module API
success Entities::BroadcastMessage
end
params do
- optional :page, type: Integer, desc: 'Current page number'
- optional :per_page, type: Integer, desc: 'Number of messages per page'
+ use :pagination
end
get do
messages = BroadcastMessage.all
diff --git a/lib/api/commit_statuses.rb b/lib/api/commit_statuses.rb
index f54d4f06627..492884d162b 100644
--- a/lib/api/commit_statuses.rb
+++ b/lib/api/commit_statuses.rb
@@ -77,7 +77,7 @@ module API
)
begin
- case params[:state].to_s
+ case params[:state]
when 'pending'
status.enqueue!
when 'running'
diff --git a/lib/api/commits.rb b/lib/api/commits.rb
index f412e1da1bf..2670a2d413a 100644
--- a/lib/api/commits.rb
+++ b/lib/api/commits.rb
@@ -3,6 +3,8 @@ require 'mime/types'
module API
# Projects commits API
class Commits < Grape::API
+ include PaginationParams
+
before { authenticate! }
before { authorize! :download_code, user_project }
@@ -46,7 +48,7 @@ module API
requires :id, type: Integer, desc: 'The project ID'
requires :branch_name, type: String, desc: 'The name of branch'
requires :commit_message, type: String, desc: 'Commit message'
- requires :actions, type: Array, desc: 'Actions to perform in commit'
+ requires :actions, type: Array[Hash], desc: 'Actions to perform in commit'
optional :author_email, type: String, desc: 'Author email for commit'
optional :author_name, type: String, desc: 'Author name for commit'
end
@@ -107,9 +109,8 @@ module API
failure [[404, 'Not Found']]
end
params do
+ use :pagination
requires :sha, type: String, desc: 'A commit sha, or the name of a branch or tag'
- optional :per_page, type: Integer, desc: 'The amount of items per page for paginaion'
- optional :page, type: Integer, desc: 'The page number for pagination'
end
get ':id/repository/commits/:sha/comments' do
commit = user_project.commit(params[:sha])
diff --git a/lib/api/deployments.rb b/lib/api/deployments.rb
index f782bcaf7e9..c5feb49b22f 100644
--- a/lib/api/deployments.rb
+++ b/lib/api/deployments.rb
@@ -1,6 +1,8 @@
module API
# Deployments RESTfull API endpoints
class Deployments < Grape::API
+ include PaginationParams
+
before { authenticate! }
params do
@@ -12,8 +14,7 @@ module API
success Entities::Deployment
end
params do
- optional :page, type: Integer, desc: 'Page number of the current request'
- optional :per_page, type: Integer, desc: 'Number of items per page'
+ use :pagination
end
get ':id/deployments' do
authorize! :read_deployment, user_project
diff --git a/lib/api/entities.rb b/lib/api/entities.rb
index 33cb6fd3704..7a724487e02 100644
--- a/lib/api/entities.rb
+++ b/lib/api/entities.rb
@@ -210,6 +210,7 @@ module API
class Milestone < ProjectEntity
expose :due_date
+ expose :start_date
end
class Issue < ProjectEntity
diff --git a/lib/api/environments.rb b/lib/api/environments.rb
index 00c901937b1..80bbd9bb6e4 100644
--- a/lib/api/environments.rb
+++ b/lib/api/environments.rb
@@ -1,6 +1,8 @@
module API
# Environments RESTfull API endpoints
class Environments < Grape::API
+ include PaginationParams
+
before { authenticate! }
params do
@@ -12,8 +14,7 @@ module API
success Entities::Environment
end
params do
- optional :page, type: Integer, desc: 'Page number of the current request'
- optional :per_page, type: Integer, desc: 'Number of items per page'
+ use :pagination
end
get ':id/environments' do
authorize! :read_environment, user_project
diff --git a/lib/api/groups.rb b/lib/api/groups.rb
index 48ad3b80ae0..fc39fdf4b67 100644
--- a/lib/api/groups.rb
+++ b/lib/api/groups.rb
@@ -33,7 +33,7 @@ module API
groups = groups.search(params[:search]) if params[:search].present?
groups = groups.where.not(id: params[:skip_groups]) if params[:skip_groups].present?
- groups = groups.reorder(params[:order_by] => params[:sort].to_sym)
+ groups = groups.reorder(params[:order_by] => params[:sort])
present paginate(groups), with: Entities::Group
end
diff --git a/lib/api/merge_requests.rb b/lib/api/merge_requests.rb
index 4176c7eec06..e82651a1578 100644
--- a/lib/api/merge_requests.rb
+++ b/lib/api/merge_requests.rb
@@ -41,15 +41,13 @@ module API
desc: 'Return merge requests ordered by `created_at` or `updated_at` fields.'
optional :sort, type: String, values: %w[asc desc], default: 'desc',
desc: 'Return merge requests sorted in `asc` or `desc` order.'
- optional :iid, type: Integer, desc: 'The IID of the merge requests'
+ optional :iid, type: Array[Integer], desc: 'The IID of the merge requests'
end
get ":id/merge_requests" do
authorize! :read_merge_request, user_project
- merge_requests = user_project.merge_requests.inc_notes_with_associations
- unless params[:iid].nil?
- merge_requests = filter_by_iid(merge_requests, params[:iid])
- end
+ merge_requests = user_project.merge_requests.inc_notes_with_associations
+ merge_requests = filter_by_iid(merge_requests, params[:iid]) if params[:iid].present?
merge_requests =
case params[:state]
@@ -59,7 +57,7 @@ module API
else merge_requests
end
- merge_requests = merge_requests.reorder(issuable_order_by => issuable_sort)
+ merge_requests = merge_requests.reorder(params[:order_by] => params[:sort])
present paginate(merge_requests), with: Entities::MergeRequest, current_user: current_user, project: user_project
end
diff --git a/lib/api/milestones.rb b/lib/api/milestones.rb
index 937c118779d..50d6109be3d 100644
--- a/lib/api/milestones.rb
+++ b/lib/api/milestones.rb
@@ -14,7 +14,8 @@ module API
params :optional_params do
optional :description, type: String, desc: 'The description of the milestone'
- optional :due_date, type: String, desc: 'The due date of the milestone'
+ optional :due_date, type: String, desc: 'The due date of the milestone. The ISO 8601 date format (%Y-%m-%d)'
+ optional :start_date, type: String, desc: 'The start date of the milestone. The ISO 8601 date format (%Y-%m-%d)'
end
end
@@ -28,7 +29,7 @@ module API
params do
optional :state, type: String, values: %w[active closed all], default: 'all',
desc: 'Return "active", "closed", or "all" milestones'
- optional :iid, type: Integer, desc: 'The IID of the milestone'
+ optional :iid, type: Array[Integer], desc: 'The IID of the milestone'
end
get ":id/milestones" do
authorize! :read_milestone, user_project
diff --git a/lib/api/pagination_params.rb b/lib/api/pagination_params.rb
new file mode 100644
index 00000000000..8c1e4381a74
--- /dev/null
+++ b/lib/api/pagination_params.rb
@@ -0,0 +1,24 @@
+module API
+ # Concern for declare pagination params.
+ #
+ # @example
+ # class CustomApiResource < Grape::API
+ # include PaginationParams
+ #
+ # params do
+ # use :pagination
+ # end
+ # end
+ module PaginationParams
+ extend ActiveSupport::Concern
+
+ included do
+ helpers do
+ params :pagination do
+ optional :page, type: Integer, desc: 'Current page number'
+ optional :per_page, type: Integer, desc: 'Number of items per page'
+ end
+ end
+ end
+ end
+end
diff --git a/lib/api/pipelines.rb b/lib/api/pipelines.rb
index e69b0569612..b634b1d0222 100644
--- a/lib/api/pipelines.rb
+++ b/lib/api/pipelines.rb
@@ -1,5 +1,7 @@
module API
class Pipelines < Grape::API
+ include PaginationParams
+
before { authenticate! }
params do
@@ -11,8 +13,7 @@ module API
success Entities::Pipeline
end
params do
- optional :page, type: Integer, desc: 'Page number of the current request'
- optional :per_page, type: Integer, desc: 'Number of items per page'
+ use :pagination
optional :scope, type: String, values: ['running', 'branches', 'tags'],
desc: 'Either running, branches, or tags'
end
diff --git a/lib/api/projects.rb b/lib/api/projects.rb
index 6b856128c2e..ddfde178d30 100644
--- a/lib/api/projects.rb
+++ b/lib/api/projects.rb
@@ -438,6 +438,19 @@ module API
end
end
+ params do
+ requires :group_id, type: Integer, desc: 'The ID of the group'
+ end
+ delete ":id/share/:group_id" do
+ authorize! :admin_project, user_project
+
+ link = user_project.project_group_links.find_by(group_id: params[:group_id])
+ not_found!('Group Link') unless link
+
+ link.destroy
+ no_content!
+ end
+
# Upload a file
#
# Parameters:
diff --git a/lib/api/sidekiq_metrics.rb b/lib/api/sidekiq_metrics.rb
index d3d6827dc54..11f2b40269a 100644
--- a/lib/api/sidekiq_metrics.rb
+++ b/lib/api/sidekiq_metrics.rb
@@ -39,50 +39,22 @@ module API
end
end
- # Get Sidekiq Queue metrics
- #
- # Parameters:
- # None
- #
- # Example:
- # GET /sidekiq/queue_metrics
- #
+ desc 'Get the Sidekiq queue metrics'
get 'sidekiq/queue_metrics' do
{ queues: queue_metrics }
end
- # Get Sidekiq Process metrics
- #
- # Parameters:
- # None
- #
- # Example:
- # GET /sidekiq/process_metrics
- #
+ desc 'Get the Sidekiq process metrics'
get 'sidekiq/process_metrics' do
{ processes: process_metrics }
end
- # Get Sidekiq Job statistics
- #
- # Parameters:
- # None
- #
- # Example:
- # GET /sidekiq/job_stats
- #
+ desc 'Get the Sidekiq job statistics'
get 'sidekiq/job_stats' do
{ jobs: job_stats }
end
- # Get Sidekiq Compound metrics. Includes all previous metrics
- #
- # Parameters:
- # None
- #
- # Example:
- # GET /sidekiq/compound_metrics
- #
+ desc 'Get the Sidekiq Compound metrics. Includes queue, process, and job statistics'
get 'sidekiq/compound_metrics' do
{ queues: queue_metrics, processes: process_metrics, jobs: job_stats }
end
diff --git a/lib/api/variables.rb b/lib/api/variables.rb
index b9fb3c21dbb..f623b1dfe9f 100644
--- a/lib/api/variables.rb
+++ b/lib/api/variables.rb
@@ -1,6 +1,8 @@
module API
# Projects variables API
class Variables < Grape::API
+ include PaginationParams
+
before { authenticate! }
before { authorize! :admin_build, user_project }
@@ -13,8 +15,7 @@ module API
success Entities::Variable
end
params do
- optional :page, type: Integer, desc: 'The page number for pagination'
- optional :per_page, type: Integer, desc: 'The value of items per page to show'
+ use :pagination
end
get ':id/variables' do
variables = user_project.variables
@@ -29,7 +30,7 @@ module API
end
get ':id/variables/:key' do
key = params[:key]
- variable = user_project.variables.find_by(key: key.to_s)
+ variable = user_project.variables.find_by(key: key)
return not_found!('Variable') unless variable
diff --git a/lib/constraints/constrainer_helper.rb b/lib/constraints/constrainer_helper.rb
deleted file mode 100644
index ab07a6793d9..00000000000
--- a/lib/constraints/constrainer_helper.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-module ConstrainerHelper
- def extract_resource_path(path)
- id = path.dup
- id.sub!(/\A#{relative_url_root}/, '') if relative_url_root
- id.sub(/\A\/+/, '').sub(/\/+\z/, '').sub(/.atom\z/, '')
- end
-
- private
-
- def relative_url_root
- if defined?(Gitlab::Application.config.relative_url_root)
- Gitlab::Application.config.relative_url_root
- end
- end
-end
diff --git a/lib/constraints/group_url_constrainer.rb b/lib/constraints/group_url_constrainer.rb
index 2af6e1a11c8..5711d96a586 100644
--- a/lib/constraints/group_url_constrainer.rb
+++ b/lib/constraints/group_url_constrainer.rb
@@ -1,15 +1,17 @@
-require_relative 'constrainer_helper'
-
class GroupUrlConstrainer
- include ConstrainerHelper
-
def matches?(request)
- id = extract_resource_path(request.path)
+ id = request.params[:id]
+
+ return false unless valid?(id)
+
+ Group.find_by(path: id).present?
+ end
+
+ private
- if id =~ Gitlab::Regex.namespace_regex
- Group.find_by(path: id).present?
- else
- false
+ def valid?(id)
+ id.split('/').all? do |namespace|
+ NamespaceValidator.valid?(namespace)
end
end
end
diff --git a/lib/constraints/project_url_constrainer.rb b/lib/constraints/project_url_constrainer.rb
new file mode 100644
index 00000000000..730b05bed97
--- /dev/null
+++ b/lib/constraints/project_url_constrainer.rb
@@ -0,0 +1,13 @@
+class ProjectUrlConstrainer
+ def matches?(request)
+ namespace_path = request.params[:namespace_id]
+ project_path = request.params[:project_id] || request.params[:id]
+ full_path = namespace_path + '/' + project_path
+
+ unless ProjectPathValidator.valid?(project_path)
+ return false
+ end
+
+ Project.find_with_namespace(full_path).present?
+ end
+end
diff --git a/lib/constraints/user_url_constrainer.rb b/lib/constraints/user_url_constrainer.rb
index 4d722ad5af2..9ab5bcb12ff 100644
--- a/lib/constraints/user_url_constrainer.rb
+++ b/lib/constraints/user_url_constrainer.rb
@@ -1,15 +1,5 @@
-require_relative 'constrainer_helper'
-
class UserUrlConstrainer
- include ConstrainerHelper
-
def matches?(request)
- id = extract_resource_path(request.path)
-
- if id =~ Gitlab::Regex.namespace_regex
- User.find_by('lower(username) = ?', id.downcase).present?
- else
- false
- end
+ User.find_by_username(request.params[:username]).present?
end
end
diff --git a/lib/gitlab/chat_commands/issue_create.rb b/lib/gitlab/chat_commands/issue_create.rb
index 98338ebfa27..99c1382af44 100644
--- a/lib/gitlab/chat_commands/issue_create.rb
+++ b/lib/gitlab/chat_commands/issue_create.rb
@@ -2,7 +2,9 @@ module Gitlab
module ChatCommands
class IssueCreate < IssueCommand
def self.match(text)
- /\Aissue\s+create\s+(?<title>[^\n]*)\n*(?<description>.*)\z/.match(text)
+ # we can not match \n with the dot by passing the m modifier as than
+ # the title and description are not seperated
+ /\Aissue\s+create\s+(?<title>[^\n]*)\n*(?<description>(.|\n)*)/.match(text)
end
def self.help_message
@@ -15,7 +17,7 @@ module Gitlab
def execute(match)
title = match[:title]
- description = match[:description]
+ description = match[:description].to_s.rstrip
Issues::CreateService.new(project, current_user, title: title, description: description).execute
end
diff --git a/lib/gitlab/cycle_analytics/base_event.rb b/lib/gitlab/cycle_analytics/base_event.rb
index 486139b1687..53a148ad703 100644
--- a/lib/gitlab/cycle_analytics/base_event.rb
+++ b/lib/gitlab/cycle_analytics/base_event.rb
@@ -16,7 +16,7 @@ module Gitlab
event_result.map do |event|
serialize(event) if has_permission?(event['id'])
- end
+ end.compact
end
def custom_query(_base_query); end
diff --git a/lib/gitlab/cycle_analytics/plan_event.rb b/lib/gitlab/cycle_analytics/plan_event.rb
index b1ae215f348..7c3f0e9989f 100644
--- a/lib/gitlab/cycle_analytics/plan_event.rb
+++ b/lib/gitlab/cycle_analytics/plan_event.rb
@@ -27,6 +27,8 @@ module Gitlab
end
def first_time_reference_commit(commits, event)
+ return nil if commits.blank?
+
YAML.load(commits).find do |commit|
next unless commit[:committed_date] && event['first_mentioned_in_commit_at']
diff --git a/lib/gitlab/ee_compat_check.rb b/lib/gitlab/ee_compat_check.rb
index f4d1505ea91..c8e36d8ff4a 100644
--- a/lib/gitlab/ee_compat_check.rb
+++ b/lib/gitlab/ee_compat_check.rb
@@ -149,7 +149,7 @@ module Gitlab
end
def ce_patch_name
- @ce_patch_name ||= "#{ce_branch}.patch"
+ @ce_patch_name ||= patch_name_from_branch(ce_branch)
end
def ce_patch_full_path
@@ -161,13 +161,17 @@ module Gitlab
end
def ee_patch_name
- @ee_patch_name ||= "#{ee_branch}.patch"
+ @ee_patch_name ||= patch_name_from_branch(ee_branch)
end
def ee_patch_full_path
@ee_patch_full_path ||= patches_dir.join(ee_patch_name)
end
+ def patch_name_from_branch(branch_name)
+ branch_name.parameterize << '.patch'
+ end
+
def step(desc, cmd = nil)
puts "\n=> #{desc}\n"
diff --git a/lib/gitlab/identifier.rb b/lib/gitlab/identifier.rb
index f8809db21aa..94678b6ec40 100644
--- a/lib/gitlab/identifier.rb
+++ b/lib/gitlab/identifier.rb
@@ -21,10 +21,8 @@ module Gitlab
return if !commit || !commit.author_email
- email = commit.author_email
-
- identify_with_cache(:email, email) do
- User.find_by(email: email)
+ identify_with_cache(:email, commit.author_email) do
+ commit.author
end
end
diff --git a/lib/gitlab/regex.rb b/lib/gitlab/regex.rb
index c12358ceef4..a06cf6a989c 100644
--- a/lib/gitlab/regex.rb
+++ b/lib/gitlab/regex.rb
@@ -8,8 +8,10 @@ module Gitlab
# allow non-regex validatiions, etc), `NAMESPACE_REGEX_STR_SIMPLE` serves as a Javascript-compatible version of
# `NAMESPACE_REGEX_STR`, with the negative lookbehind assertion removed. This means that the client-side validation
# will pass for usernames ending in `.atom` and `.git`, but will be caught by the server-side validation.
- NAMESPACE_REGEX_STR_SIMPLE = '[a-zA-Z0-9_\.][a-zA-Z0-9_\-\.]*[a-zA-Z0-9_\-]|[a-zA-Z0-9_]'.freeze
+ PATH_REGEX_STR = '[a-zA-Z0-9_\.][a-zA-Z0-9_\-\.]*'.freeze
+ NAMESPACE_REGEX_STR_SIMPLE = PATH_REGEX_STR + '[a-zA-Z0-9_\-]|[a-zA-Z0-9_]'.freeze
NAMESPACE_REGEX_STR = '(?:' + NAMESPACE_REGEX_STR_SIMPLE + ')(?<!\.git|\.atom)'.freeze
+ PROJECT_REGEX_STR = PATH_REGEX_STR + '(?<!\.git|\.atom)'.freeze
def namespace_regex
@namespace_regex ||= /\A#{NAMESPACE_REGEX_STR}\z/.freeze
@@ -42,7 +44,15 @@ module Gitlab
end
def project_path_regex
- @project_path_regex ||= /\A[a-zA-Z0-9_.][a-zA-Z0-9_\-\.]*(?<!\.git|\.atom)\z/.freeze
+ @project_path_regex ||= /\A#{PROJECT_REGEX_STR}\z/.freeze
+ end
+
+ def project_route_regex
+ @project_route_regex ||= /#{PROJECT_REGEX_STR}/.freeze
+ end
+
+ def project_git_route_regex
+ @project_route_git_regex ||= /#{PATH_REGEX_STR}\.git/.freeze
end
def project_path_regex_message
diff --git a/package.json b/package.json
index 2a9fb808eef..350e4cd80c9 100644
--- a/package.json
+++ b/package.json
@@ -2,13 +2,14 @@
"private": true,
"scripts": {
"eslint": "eslint --ext .js,.js.es6 .",
- "eslint-fix": "eslint --fix --ext .js,.js.es6 ."
+ "eslint-fix": "npm run eslint -- --fix",
+ "eslint-report": "npm run eslint -- --format html --output-file ./eslint-report.html"
},
"devDependencies": {
"eslint": "^3.1.1",
"eslint-config-airbnb": "^12.0.0",
"eslint-plugin-filenames": "^1.1.0",
- "eslint-plugin-import": "^2.0.1",
+ "eslint-plugin-import": "^1.16.0",
"eslint-plugin-jasmine": "^1.8.1",
"eslint-plugin-jsx-a11y": "^2.2.3",
"eslint-plugin-react": "^6.4.1",
diff --git a/spec/controllers/admin/impersonations_controller_spec.rb b/spec/controllers/admin/impersonations_controller_spec.rb
index 8be662974a0..8f1f0ba89ff 100644
--- a/spec/controllers/admin/impersonations_controller_spec.rb
+++ b/spec/controllers/admin/impersonations_controller_spec.rb
@@ -76,18 +76,32 @@ describe Admin::ImpersonationsController do
end
context "when the impersonator is not blocked" do
- it "redirects to the impersonated user's page" do
- expect(Gitlab::AppLogger).to receive(:info).with("User #{impersonator.username} has stopped impersonating #{user.username}").and_call_original
+ shared_examples_for "successfully stops impersonating" do
+ it "redirects to the impersonated user's page" do
+ expect(Gitlab::AppLogger).to receive(:info).with("User #{impersonator.username} has stopped impersonating #{user.username}").and_call_original
- delete :destroy
+ delete :destroy
+
+ expect(response).to redirect_to(admin_user_path(user))
+ end
+
+ it "signs us in as the impersonator" do
+ delete :destroy
- expect(response).to redirect_to(admin_user_path(user))
+ expect(warden.user).to eq(impersonator)
+ end
end
- it "signs us in as the impersonator" do
- delete :destroy
+ # base case
+ it_behaves_like "successfully stops impersonating"
+
+ context "and the user has a temporary oauth e-mail address" do
+ before do
+ allow(user).to receive(:temp_oauth_email?).and_return(true)
+ allow(controller).to receive(:current_user).and_return(user)
+ end
- expect(warden.user).to eq(impersonator)
+ it_behaves_like "successfully stops impersonating"
end
end
end
diff --git a/spec/controllers/application_controller_spec.rb b/spec/controllers/application_controller_spec.rb
index 98e912f000c..81cbccd5436 100644
--- a/spec/controllers/application_controller_spec.rb
+++ b/spec/controllers/application_controller_spec.rb
@@ -1,8 +1,9 @@
require 'spec_helper'
describe ApplicationController do
+ let(:user) { create(:user) }
+
describe '#check_password_expiration' do
- let(:user) { create(:user) }
let(:controller) { ApplicationController.new }
it 'redirects if the user is over their password expiry' do
@@ -39,8 +40,6 @@ describe ApplicationController do
end
end
- let(:user) { create(:user) }
-
context "when the 'private_token' param is populated with the private token" do
it "logs the user in" do
get :index, private_token: user.private_token
@@ -73,7 +72,6 @@ describe ApplicationController do
end
end
- let(:user) { create(:user) }
let(:personal_access_token) { create(:personal_access_token, user: user) }
context "when the 'personal_access_token' param is populated with the personal access token" do
@@ -100,4 +98,21 @@ describe ApplicationController do
end
end
end
+
+ describe '#route_not_found' do
+ let(:controller) { ApplicationController.new }
+
+ it 'renders 404 if authenticated' do
+ allow(controller).to receive(:current_user).and_return(user)
+ expect(controller).to receive(:not_found)
+ controller.send(:route_not_found)
+ end
+
+ it 'does redirect to login page if not authenticated' do
+ allow(controller).to receive(:current_user).and_return(nil)
+ expect(controller).to receive(:redirect_to)
+ expect(controller).to receive(:new_user_session_path)
+ controller.send(:route_not_found)
+ end
+ end
end
diff --git a/spec/controllers/autocomplete_controller_spec.rb b/spec/controllers/autocomplete_controller_spec.rb
index a121cb2fc97..d9a86346c81 100644
--- a/spec/controllers/autocomplete_controller_spec.rb
+++ b/spec/controllers/autocomplete_controller_spec.rb
@@ -11,7 +11,7 @@ describe AutocompleteController do
context 'project members' do
before do
sign_in(user)
- project.team << [user, :master]
+ project.add_master(user)
end
describe 'GET #users with project ID' do
@@ -69,7 +69,7 @@ describe AutocompleteController do
before do
sign_in(non_member)
- project.team << [user, :master]
+ project.add_master(user)
end
let(:body) { JSON.parse(response.body) }
@@ -103,7 +103,7 @@ describe AutocompleteController do
describe 'GET #users with public project' do
before do
- public_project.team << [user, :guest]
+ public_project.add_guest(user)
get(:users, project_id: public_project.id)
end
@@ -129,7 +129,7 @@ describe AutocompleteController do
describe 'GET #users with inaccessible group' do
before do
- project.team << [user, :guest]
+ project.add_guest(user)
get(:users, group_id: user.namespace.id)
end
@@ -186,12 +186,12 @@ describe AutocompleteController do
before do
sign_in(user)
- project.team << [user, :master]
+ project.add_master(user)
end
context 'authorized projects' do
before do
- authorized_project.team << [user, :master]
+ authorized_project.add_master(user)
end
describe 'GET #projects with project ID' do
@@ -216,8 +216,8 @@ describe AutocompleteController do
context 'authorized projects and search' do
before do
- authorized_project.team << [user, :master]
- authorized_search_project.team << [user, :master]
+ authorized_project.add_master(user)
+ authorized_search_project.add_master(user)
end
describe 'GET #projects with project ID and search' do
@@ -242,9 +242,9 @@ describe AutocompleteController do
authorized_project2 = create(:project)
authorized_project3 = create(:project)
- authorized_project.team << [user, :master]
- authorized_project2.team << [user, :master]
- authorized_project3.team << [user, :master]
+ authorized_project.add_master(user)
+ authorized_project2.add_master(user)
+ authorized_project3.add_master(user)
stub_const 'MoveToProjectFinder::PAGE_SIZE', 2
end
@@ -268,9 +268,9 @@ describe AutocompleteController do
authorized_project2 = create(:project)
authorized_project3 = create(:project)
- authorized_project.team << [user, :master]
- authorized_project2.team << [user, :master]
- authorized_project3.team << [user, :master]
+ authorized_project.add_master(user)
+ authorized_project2.add_master(user)
+ authorized_project3.add_master(user)
end
describe 'GET #projects with project ID and offset_id' do
@@ -289,7 +289,7 @@ describe AutocompleteController do
context 'authorized projects without admin_issue ability' do
before(:each) do
- authorized_project.team << [user, :guest]
+ authorized_project.add_guest(user)
expect(user.can?(:admin_issue, authorized_project)).to eq(false)
end
diff --git a/spec/features/abuse_report_spec.rb b/spec/features/abuse_report_spec.rb
new file mode 100644
index 00000000000..1e11fb756b2
--- /dev/null
+++ b/spec/features/abuse_report_spec.rb
@@ -0,0 +1,24 @@
+require 'spec_helper'
+
+feature 'Abuse reports', feature: true do
+ let(:another_user) { create(:user) }
+
+ before do
+ login_as :user
+ end
+
+ scenario 'Report abuse' do
+ visit user_path(another_user)
+
+ click_link 'Report abuse'
+
+ fill_in 'abuse_report_message', with: 'This user send spam'
+ click_button 'Send report'
+
+ expect(page).to have_content 'Thank you for your report'
+
+ visit user_path(another_user)
+
+ expect(page).to have_button("Already reported for abuse")
+ end
+end
diff --git a/spec/features/admin/admin_abuse_reports_spec.rb b/spec/features/admin/admin_abuse_reports_spec.rb
index c1731e6414a..7fcfe5a54c7 100644
--- a/spec/features/admin/admin_abuse_reports_spec.rb
+++ b/spec/features/admin/admin_abuse_reports_spec.rb
@@ -4,17 +4,21 @@ describe "Admin::AbuseReports", feature: true, js: true do
let(:user) { create(:user) }
context 'as an admin' do
+ before do
+ login_as :admin
+ end
+
describe 'if a user has been reported for abuse' do
- before do
- create(:abuse_report, user: user)
- login_as :admin
- end
+ let!(:abuse_report) { create(:abuse_report, user: user) }
describe 'in the abuse report view' do
- it "presents a link to the user's profile" do
+ it 'presents information about abuse report' do
visit admin_abuse_reports_path
- expect(page).to have_link user.name, href: user_path(user)
+ expect(page).to have_content('Abuse Reports')
+ expect(page).to have_content(abuse_report.message)
+ expect(page).to have_link(user.name, href: user_path(user))
+ expect(page).to have_link('Remove user')
end
end
diff --git a/spec/features/admin/admin_browse_spam_logs_spec.rb b/spec/features/admin/admin_browse_spam_logs_spec.rb
new file mode 100644
index 00000000000..562ace92598
--- /dev/null
+++ b/spec/features/admin/admin_browse_spam_logs_spec.rb
@@ -0,0 +1,22 @@
+require 'spec_helper'
+
+describe 'Admin browse spam logs' do
+ let!(:spam_log) { create(:spam_log) }
+
+ before do
+ login_as :admin
+ end
+
+ scenario 'Browse spam logs' do
+ visit admin_spam_logs_path
+
+ expect(page).to have_content('Spam Logs')
+ expect(page).to have_content(spam_log.source_ip)
+ expect(page).to have_content(spam_log.noteable_type)
+ expect(page).to have_content('N')
+ expect(page).to have_content(spam_log.title)
+ expect(page).to have_content("#{spam_log.description[0...97]}...")
+ expect(page).to have_link('Remove user')
+ expect(page).to have_link('Block user')
+ end
+end
diff --git a/spec/features/boards/boards_spec.rb b/spec/features/boards/boards_spec.rb
index 4aa84fb65d9..973d5b286e9 100644
--- a/spec/features/boards/boards_spec.rb
+++ b/spec/features/boards/boards_spec.rb
@@ -158,7 +158,7 @@ describe 'Issue Boards', feature: true, js: true do
end
it 'removes checkmark in new list dropdown after deleting' do
- click_button 'Create new list'
+ click_button 'Add list'
wait_for_ajax
page.within(find('.board:nth-child(2)')) do
@@ -304,7 +304,7 @@ describe 'Issue Boards', feature: true, js: true do
context 'new list' do
it 'shows all labels in new list dropdown' do
- click_button 'Create new list'
+ click_button 'Add list'
wait_for_ajax
page.within('.dropdown-menu-issues-board-new') do
@@ -315,7 +315,7 @@ describe 'Issue Boards', feature: true, js: true do
end
it 'creates new list for label' do
- click_button 'Create new list'
+ click_button 'Add list'
wait_for_ajax
page.within('.dropdown-menu-issues-board-new') do
@@ -328,7 +328,7 @@ describe 'Issue Boards', feature: true, js: true do
end
it 'creates new list for Backlog label' do
- click_button 'Create new list'
+ click_button 'Add list'
wait_for_ajax
page.within('.dropdown-menu-issues-board-new') do
@@ -341,7 +341,7 @@ describe 'Issue Boards', feature: true, js: true do
end
it 'creates new list for Done label' do
- click_button 'Create new list'
+ click_button 'Add list'
wait_for_ajax
page.within('.dropdown-menu-issues-board-new') do
@@ -354,7 +354,7 @@ describe 'Issue Boards', feature: true, js: true do
end
it 'keeps dropdown open after adding new list' do
- click_button 'Create new list'
+ click_button 'Add list'
wait_for_ajax
page.within('.dropdown-menu-issues-board-new') do
@@ -369,7 +369,7 @@ describe 'Issue Boards', feature: true, js: true do
it 'moves issues from backlog into new list' do
wait_for_board_cards(1, 6)
- click_button 'Create new list'
+ click_button 'Add list'
wait_for_ajax
page.within('.dropdown-menu-issues-board-new') do
@@ -382,7 +382,7 @@ describe 'Issue Boards', feature: true, js: true do
end
it 'creates new list from a new label' do
- click_button 'Create new list'
+ click_button 'Add list'
wait_for_ajax
diff --git a/spec/features/calendar_spec.rb b/spec/features/calendar_spec.rb
index 7fa0c95cae2..3e0b6364e0d 100644
--- a/spec/features/calendar_spec.rb
+++ b/spec/features/calendar_spec.rb
@@ -52,6 +52,10 @@ feature 'Contributions Calendar', js: true, feature: true do
Event.create(push_params)
end
+ def get_first_cell_content
+ find('.user-calendar-activities').text
+ end
+
before do
login_as :user
visit @user.username
@@ -62,6 +66,43 @@ feature 'Contributions Calendar', js: true, feature: true do
expect(page).to have_css('.js-contrib-calendar')
end
+ describe 'select calendar day', js: true do
+ let(:cells) { page.all('.user-contrib-cell') }
+ let(:first_cell_content_before) { get_first_cell_content }
+
+ before do
+ cells[0].click
+ wait_for_ajax
+ first_cell_content_before
+ end
+
+ it 'displays calendar day activities', js: true do
+ expect(get_first_cell_content).not_to eq('')
+ end
+
+ describe 'select another calendar day', js: true do
+ before do
+ cells[1].click
+ wait_for_ajax
+ end
+
+ it 'displays different calendar day activities', js: true do
+ expect(get_first_cell_content).not_to eq(first_cell_content_before)
+ end
+ end
+
+ describe 'deselect calendar day', js: true do
+ before do
+ cells[0].click
+ wait_for_ajax
+ end
+
+ it 'hides calendar day activities', js: true do
+ expect(get_first_cell_content).to eq('')
+ end
+ end
+ end
+
describe '1 calendar activity' do
before do
Issues::CreateService.new(contributed_project, @user, issue_params).execute
diff --git a/spec/features/issues/award_emoji_spec.rb b/spec/features/issues/award_emoji_spec.rb
index ef00f209998..efb53026449 100644
--- a/spec/features/issues/award_emoji_spec.rb
+++ b/spec/features/issues/award_emoji_spec.rb
@@ -3,72 +3,83 @@ require 'rails_helper'
describe 'Awards Emoji', feature: true do
include WaitForAjax
- let!(:project) { create(:project) }
+ let!(:project) { create(:project, :public) }
let!(:user) { create(:user) }
-
- before do
- project.team << [user, :master]
- login_as(user)
+ let(:issue) do
+ create(:issue,
+ assignee: @user,
+ project: project)
end
- describe 'Click award emoji from issue#show' do
- let!(:issue) do
- create(:issue,
- assignee: @user,
- project: project)
- end
-
- let!(:note) { create(:note_on_issue, noteable: issue, project: issue.project, note: "Hello world") }
-
+ context 'authorized user' do
before do
- visit namespace_project_issue_path(project.namespace, project, issue)
+ project.team << [user, :master]
+ login_as(user)
end
- it 'increments the thumbsdown emoji', js: true do
- find('[data-emoji="thumbsdown"]').click
- wait_for_ajax
- expect(thumbsdown_emoji).to have_text("1")
- end
+ describe 'Click award emoji from issue#show' do
+ let!(:note) { create(:note_on_issue, noteable: issue, project: issue.project, note: "Hello world") }
- context 'click the thumbsup emoji' do
- it 'increments the thumbsup emoji', js: true do
- find('[data-emoji="thumbsup"]').click
- wait_for_ajax
- expect(thumbsup_emoji).to have_text("1")
+ before do
+ visit namespace_project_issue_path(project.namespace, project, issue)
end
- it 'decrements the thumbsdown emoji', js: true do
- expect(thumbsdown_emoji).to have_text("0")
- end
- end
-
- context 'click the thumbsdown emoji' do
it 'increments the thumbsdown emoji', js: true do
find('[data-emoji="thumbsdown"]').click
wait_for_ajax
expect(thumbsdown_emoji).to have_text("1")
end
- it 'decrements the thumbsup emoji', js: true do
- expect(thumbsup_emoji).to have_text("0")
+ context 'click the thumbsup emoji' do
+ it 'increments the thumbsup emoji', js: true do
+ find('[data-emoji="thumbsup"]').click
+ wait_for_ajax
+ expect(thumbsup_emoji).to have_text("1")
+ end
+
+ it 'decrements the thumbsdown emoji', js: true do
+ expect(thumbsdown_emoji).to have_text("0")
+ end
end
- end
- it 'toggles the smiley emoji on a note', js: true do
- toggle_smiley_emoji(true)
+ context 'click the thumbsdown emoji' do
+ it 'increments the thumbsdown emoji', js: true do
+ find('[data-emoji="thumbsdown"]').click
+ wait_for_ajax
+ expect(thumbsdown_emoji).to have_text("1")
+ end
- within('.note-awards') do
- expect(find(emoji_counter)).to have_text("1")
+ it 'decrements the thumbsup emoji', js: true do
+ expect(thumbsup_emoji).to have_text("0")
+ end
end
- toggle_smiley_emoji(false)
+ it 'toggles the smiley emoji on a note', js: true do
+ toggle_smiley_emoji(true)
+
+ within('.note-awards') do
+ expect(find(emoji_counter)).to have_text("1")
+ end
+
+ toggle_smiley_emoji(false)
- within('.note-awards') do
- expect(page).not_to have_selector(emoji_counter)
+ within('.note-awards') do
+ expect(page).not_to have_selector(emoji_counter)
+ end
end
end
end
+ context 'unauthorized user', js: true do
+ before do
+ visit namespace_project_issue_path(project.namespace, project, issue)
+ end
+
+ it 'has disabled emoji button' do
+ expect(first('.award-control')[:disabled]).to be(true)
+ end
+ end
+
def thumbsup_emoji
page.all(emoji_counter).first
end
diff --git a/spec/features/milestone_spec.rb b/spec/features/milestone_spec.rb
index b8c838bf7ab..a2e40546588 100644
--- a/spec/features/milestone_spec.rb
+++ b/spec/features/milestone_spec.rb
@@ -14,12 +14,17 @@ feature 'Milestone', feature: true do
feature 'Create a milestone' do
scenario 'shows an informative message for a new milestone' do
visit new_namespace_project_milestone_path(project.namespace, project)
+
page.within '.milestone-form' do
fill_in "milestone_title", with: '8.7'
+ fill_in "milestone_start_date", with: '2016-11-16'
+ fill_in "milestone_due_date", with: '2016-12-16'
end
+
find('input[name="commit"]').click
expect(find('.alert-success')).to have_content('Assign some issues to this milestone.')
+ expect(page).to have_content('Nov 16, 2016 - Dec 16, 2016')
end
end
diff --git a/spec/features/projects/builds_spec.rb b/spec/features/projects/builds_spec.rb
index a8022a5361f..a0ccc472d11 100644
--- a/spec/features/projects/builds_spec.rb
+++ b/spec/features/projects/builds_spec.rb
@@ -1,52 +1,59 @@
require 'spec_helper'
require 'tempfile'
-describe "Builds" do
- let(:artifacts_file) { fixture_file_upload(Rails.root + 'spec/fixtures/banana_sample.gif', 'image/gif') }
+feature 'Builds', :feature do
+ let(:user) { create(:user) }
+ let(:project) { create(:project) }
+ let(:pipeline) { create(:ci_pipeline, project: project) }
+
+ let(:build) { create(:ci_build, :trace, pipeline: pipeline) }
+ let(:build2) { create(:ci_build) }
+
+ let(:artifacts_file) do
+ fixture_file_upload(Rails.root + 'spec/fixtures/banana_sample.gif', 'image/gif')
+ end
before do
- login_as(:user)
- @commit = FactoryGirl.create :ci_pipeline
- @build = FactoryGirl.create :ci_build, :trace, pipeline: @commit
- @build2 = FactoryGirl.create :ci_build
- @project = @commit.project
- @project.team << [@user, :developer]
+ project.team << [user, :developer]
+ login_as(user)
end
describe "GET /:project/builds" do
+ let!(:build) { create(:ci_build, pipeline: pipeline) }
+
context "Pending scope" do
before do
- visit namespace_project_builds_path(@project.namespace, @project, scope: :pending)
+ visit namespace_project_builds_path(project.namespace, project, scope: :pending)
end
it "shows Pending tab builds" do
expect(page).to have_link 'Cancel running'
expect(page).to have_selector('.nav-links li.active', text: 'Pending')
- expect(page).to have_content @build.short_sha
- expect(page).to have_content @build.ref
- expect(page).to have_content @build.name
+ expect(page).to have_content build.short_sha
+ expect(page).to have_content build.ref
+ expect(page).to have_content build.name
end
end
context "Running scope" do
before do
- @build.run!
- visit namespace_project_builds_path(@project.namespace, @project, scope: :running)
+ build.run!
+ visit namespace_project_builds_path(project.namespace, project, scope: :running)
end
it "shows Running tab builds" do
expect(page).to have_selector('.nav-links li.active', text: 'Running')
expect(page).to have_link 'Cancel running'
- expect(page).to have_content @build.short_sha
- expect(page).to have_content @build.ref
- expect(page).to have_content @build.name
+ expect(page).to have_content build.short_sha
+ expect(page).to have_content build.ref
+ expect(page).to have_content build.name
end
end
context "Finished scope" do
before do
- @build.run!
- visit namespace_project_builds_path(@project.namespace, @project, scope: :finished)
+ build.run!
+ visit namespace_project_builds_path(project.namespace, project, scope: :finished)
end
it "shows Finished tab builds" do
@@ -58,15 +65,15 @@ describe "Builds" do
context "All builds" do
before do
- @project.builds.running_or_pending.each(&:success)
- visit namespace_project_builds_path(@project.namespace, @project)
+ project.builds.running_or_pending.each(&:success)
+ visit namespace_project_builds_path(project.namespace, project)
end
it "shows All tab builds" do
expect(page).to have_selector('.nav-links li.active', text: 'All')
- expect(page).to have_content @build.short_sha
- expect(page).to have_content @build.ref
- expect(page).to have_content @build.name
+ expect(page).to have_content build.short_sha
+ expect(page).to have_content build.ref
+ expect(page).to have_content build.name
expect(page).not_to have_link 'Cancel running'
end
end
@@ -74,17 +81,17 @@ describe "Builds" do
describe "POST /:project/builds/:id/cancel_all" do
before do
- @build.run!
- visit namespace_project_builds_path(@project.namespace, @project)
+ build.run!
+ visit namespace_project_builds_path(project.namespace, project)
click_link "Cancel running"
end
it 'shows all necessary content' do
expect(page).to have_selector('.nav-links li.active', text: 'All')
expect(page).to have_content 'canceled'
- expect(page).to have_content @build.short_sha
- expect(page).to have_content @build.ref
- expect(page).to have_content @build.name
+ expect(page).to have_content build.short_sha
+ expect(page).to have_content build.ref
+ expect(page).to have_content build.name
expect(page).not_to have_link 'Cancel running'
end
end
@@ -92,20 +99,20 @@ describe "Builds" do
describe "GET /:project/builds/:id" do
context "Build from project" do
before do
- visit namespace_project_build_path(@project.namespace, @project, @build)
+ visit namespace_project_build_path(project.namespace, project, build)
end
it 'shows commit`s data' do
expect(page.status_code).to eq(200)
- expect(page).to have_content @commit.sha[0..7]
- expect(page).to have_content @commit.git_commit_message
- expect(page).to have_content @commit.git_author_name
+ expect(page).to have_content pipeline.sha[0..7]
+ expect(page).to have_content pipeline.git_commit_message
+ expect(page).to have_content pipeline.git_author_name
end
end
context "Build from other project" do
before do
- visit namespace_project_build_path(@project.namespace, @project, @build2)
+ visit namespace_project_build_path(project.namespace, project, build2)
end
it { expect(page.status_code).to eq(404) }
@@ -113,8 +120,8 @@ describe "Builds" do
context "Download artifacts" do
before do
- @build.update_attributes(artifacts_file: artifacts_file)
- visit namespace_project_build_path(@project.namespace, @project, @build)
+ build.update_attributes(artifacts_file: artifacts_file)
+ visit namespace_project_build_path(project.namespace, project, build)
end
it 'has button to download artifacts' do
@@ -124,8 +131,8 @@ describe "Builds" do
context 'Artifacts expire date' do
before do
- @build.update_attributes(artifacts_file: artifacts_file, artifacts_expire_at: expire_at)
- visit namespace_project_build_path(@project.namespace, @project, @build)
+ build.update_attributes(artifacts_file: artifacts_file, artifacts_expire_at: expire_at)
+ visit namespace_project_build_path(project.namespace, project, build)
end
context 'no expire date defined' do
@@ -158,10 +165,10 @@ describe "Builds" do
end
end
- context 'Build raw trace' do
+ feature 'Raw trace' do
before do
- @build.run!
- visit namespace_project_build_path(@project.namespace, @project, @build)
+ build.run!
+ visit namespace_project_build_path(project.namespace, project, build)
end
it do
@@ -169,11 +176,43 @@ describe "Builds" do
end
end
- describe 'Variables' do
+ feature 'HTML trace', :js do
+ before do
+ build.run!
+
+ visit namespace_project_build_path(project.namespace, project, build)
+ end
+
+ context 'when build has an initial trace' do
+ it 'loads build trace' do
+ expect(page).to have_content 'BUILD TRACE'
+
+ build.append_trace(' and more trace', 11)
+
+ expect(page).to have_content 'BUILD TRACE and more trace'
+ end
+ end
+
+ context 'when build does not have an initial trace' do
+ let(:build) { create(:ci_build, pipeline: pipeline) }
+
+ it 'loads new trace' do
+ build.append_trace('build trace', 0)
+
+ expect(page).to have_content 'build trace'
+ end
+ end
+ end
+
+ feature 'Variables' do
+ let(:trigger_request) { create(:ci_trigger_request_with_variables) }
+
+ let(:build) do
+ create :ci_build, pipeline: pipeline, trigger_request: trigger_request
+ end
+
before do
- @trigger_request = create :ci_trigger_request_with_variables
- @build = create :ci_build, pipeline: @commit, trigger_request: @trigger_request
- visit namespace_project_build_path(@project.namespace, @project, @build)
+ visit namespace_project_build_path(project.namespace, project, build)
end
it 'shows variable key and value after click', js: true do
@@ -193,8 +232,8 @@ describe "Builds" do
describe "POST /:project/builds/:id/cancel" do
context "Build from project" do
before do
- @build.run!
- visit namespace_project_build_path(@project.namespace, @project, @build)
+ build.run!
+ visit namespace_project_build_path(project.namespace, project, build)
click_link "Cancel"
end
@@ -207,9 +246,9 @@ describe "Builds" do
context "Build from other project" do
before do
- @build.run!
- visit namespace_project_build_path(@project.namespace, @project, @build)
- page.driver.post(cancel_namespace_project_build_path(@project.namespace, @project, @build2))
+ build.run!
+ visit namespace_project_build_path(project.namespace, project, build)
+ page.driver.post(cancel_namespace_project_build_path(project.namespace, project, build2))
end
it { expect(page.status_code).to eq(404) }
@@ -219,8 +258,8 @@ describe "Builds" do
describe "POST /:project/builds/:id/retry" do
context "Build from project" do
before do
- @build.run!
- visit namespace_project_build_path(@project.namespace, @project, @build)
+ build.run!
+ visit namespace_project_build_path(project.namespace, project, build)
click_link 'Cancel'
page.within('.build-header') do
click_link 'Retry build'
@@ -238,10 +277,10 @@ describe "Builds" do
context "Build from other project" do
before do
- @build.run!
- visit namespace_project_build_path(@project.namespace, @project, @build)
+ build.run!
+ visit namespace_project_build_path(project.namespace, project, build)
click_link 'Cancel'
- page.driver.post(retry_namespace_project_build_path(@project.namespace, @project, @build2))
+ page.driver.post(retry_namespace_project_build_path(project.namespace, project, build2))
end
it { expect(page).to have_http_status(404) }
@@ -249,13 +288,13 @@ describe "Builds" do
context "Build that current user is not allowed to retry" do
before do
- @build.run!
- @build.cancel!
- @project.update(visibility_level: Gitlab::VisibilityLevel::PUBLIC)
+ build.run!
+ build.cancel!
+ project.update(visibility_level: Gitlab::VisibilityLevel::PUBLIC)
logout_direct
login_with(create(:user))
- visit namespace_project_build_path(@project.namespace, @project, @build)
+ visit namespace_project_build_path(project.namespace, project, build)
end
it 'does not show the Retry button' do
@@ -268,15 +307,15 @@ describe "Builds" do
describe "GET /:project/builds/:id/download" do
before do
- @build.update_attributes(artifacts_file: artifacts_file)
- visit namespace_project_build_path(@project.namespace, @project, @build)
+ build.update_attributes(artifacts_file: artifacts_file)
+ visit namespace_project_build_path(project.namespace, project, build)
click_link 'Download'
end
context "Build from other project" do
before do
- @build2.update_attributes(artifacts_file: artifacts_file)
- visit download_namespace_project_build_artifacts_path(@project.namespace, @project, @build2)
+ build2.update_attributes(artifacts_file: artifacts_file)
+ visit download_namespace_project_build_artifacts_path(project.namespace, project, build2)
end
it { expect(page.status_code).to eq(404) }
@@ -288,23 +327,23 @@ describe "Builds" do
context 'build from project' do
before do
Capybara.current_session.driver.header('X-Sendfile-Type', 'X-Sendfile')
- @build.run!
- visit namespace_project_build_path(@project.namespace, @project, @build)
+ build.run!
+ visit namespace_project_build_path(project.namespace, project, build)
page.within('.js-build-sidebar') { click_link 'Raw' }
end
it 'sends the right headers' do
expect(page.status_code).to eq(200)
expect(page.response_headers['Content-Type']).to eq('text/plain; charset=utf-8')
- expect(page.response_headers['X-Sendfile']).to eq(@build.path_to_trace)
+ expect(page.response_headers['X-Sendfile']).to eq(build.path_to_trace)
end
end
context 'build from other project' do
before do
Capybara.current_session.driver.header('X-Sendfile-Type', 'X-Sendfile')
- @build2.run!
- visit raw_namespace_project_build_path(@project.namespace, @project, @build2)
+ build2.run!
+ visit raw_namespace_project_build_path(project.namespace, project, build2)
end
it 'sends the right headers' do
@@ -325,8 +364,8 @@ describe "Builds" do
context 'when build has trace in file' do
before do
Capybara.current_session.driver.header('X-Sendfile-Type', 'X-Sendfile')
- @build.run!
- visit namespace_project_build_path(@project.namespace, @project, @build)
+ build.run!
+ visit namespace_project_build_path(project.namespace, project, build)
allow_any_instance_of(Project).to receive(:ci_id).and_return(nil)
allow_any_instance_of(Ci::Build).to receive(:path_to_trace).and_return(existing_file)
@@ -345,8 +384,8 @@ describe "Builds" do
context 'when build has trace in old file' do
before do
Capybara.current_session.driver.header('X-Sendfile-Type', 'X-Sendfile')
- @build.run!
- visit namespace_project_build_path(@project.namespace, @project, @build)
+ build.run!
+ visit namespace_project_build_path(project.namespace, project, build)
allow_any_instance_of(Project).to receive(:ci_id).and_return(999)
allow_any_instance_of(Ci::Build).to receive(:path_to_trace).and_return(non_existing_file)
@@ -365,8 +404,8 @@ describe "Builds" do
context 'when build has trace in DB' do
before do
Capybara.current_session.driver.header('X-Sendfile-Type', 'X-Sendfile')
- @build.run!
- visit namespace_project_build_path(@project.namespace, @project, @build)
+ build.run!
+ visit namespace_project_build_path(project.namespace, project, build)
allow_any_instance_of(Project).to receive(:ci_id).and_return(nil)
allow_any_instance_of(Ci::Build).to receive(:path_to_trace).and_return(non_existing_file)
@@ -385,7 +424,7 @@ describe "Builds" do
describe "GET /:project/builds/:id/trace.json" do
context "Build from project" do
before do
- visit trace_namespace_project_build_path(@project.namespace, @project, @build, format: :json)
+ visit trace_namespace_project_build_path(project.namespace, project, build, format: :json)
end
it { expect(page.status_code).to eq(200) }
@@ -393,7 +432,7 @@ describe "Builds" do
context "Build from other project" do
before do
- visit trace_namespace_project_build_path(@project.namespace, @project, @build2, format: :json)
+ visit trace_namespace_project_build_path(project.namespace, project, build2, format: :json)
end
it { expect(page.status_code).to eq(404) }
@@ -403,7 +442,7 @@ describe "Builds" do
describe "GET /:project/builds/:id/status" do
context "Build from project" do
before do
- visit status_namespace_project_build_path(@project.namespace, @project, @build)
+ visit status_namespace_project_build_path(project.namespace, project, build)
end
it { expect(page.status_code).to eq(200) }
@@ -411,7 +450,7 @@ describe "Builds" do
context "Build from other project" do
before do
- visit status_namespace_project_build_path(@project.namespace, @project, @build2)
+ visit status_namespace_project_build_path(project.namespace, project, build2)
end
it { expect(page.status_code).to eq(404) }
diff --git a/spec/features/projects/services/mattermost_slash_command_spec.rb b/spec/features/projects/services/mattermost_slash_command_spec.rb
new file mode 100644
index 00000000000..f474e7e891b
--- /dev/null
+++ b/spec/features/projects/services/mattermost_slash_command_spec.rb
@@ -0,0 +1,48 @@
+require 'spec_helper'
+
+feature 'Setup Mattermost slash commands', feature: true do
+ include WaitForAjax
+
+ let(:user) { create(:user) }
+ let(:project) { create(:project) }
+ let(:service) { project.create_mattermost_slash_commands_service }
+
+ before do
+ project.team << [user, :master]
+ login_as(user)
+ end
+
+ describe 'user visites the mattermost slash command config page', js: true do
+ it 'shows a help message' do
+ visit edit_namespace_project_service_path(project.namespace, project, service)
+
+ wait_for_ajax
+
+ expect(page).to have_content("This service allows GitLab users to perform common")
+ end
+ end
+
+ describe 'saving a token' do
+ let(:token) { ('a'..'z').to_a.join }
+
+ it 'shows the token after saving' do
+ visit edit_namespace_project_service_path(project.namespace, project, service)
+
+ fill_in 'service_token', with: token
+ click_on 'Save'
+
+ value = find_field('service_token').value
+
+ expect(value).to eq(token)
+ end
+ end
+
+ describe 'the trigger url' do
+ it 'shows the correct url' do
+ visit edit_namespace_project_service_path(project.namespace, project, service)
+
+ value = find_field('request_url').value
+ expect(value).to match("api/v3/projects/#{project.id}/services/mattermost_slash_commands/trigger")
+ end
+ end
+end
diff --git a/spec/features/projects/slack_service/slack_service_spec.rb b/spec/features/projects/services/slack_service_spec.rb
index 16541f51d98..16541f51d98 100644
--- a/spec/features/projects/slack_service/slack_service_spec.rb
+++ b/spec/features/projects/services/slack_service_spec.rb
diff --git a/spec/helpers/members_helper_spec.rb b/spec/helpers/members_helper_spec.rb
index ffca1c94da1..33934cdf8b1 100644
--- a/spec/helpers/members_helper_spec.rb
+++ b/spec/helpers/members_helper_spec.rb
@@ -10,7 +10,7 @@ describe MembersHelper do
end
describe '#remove_member_message' do
- let(:requester) { build(:user) }
+ let(:requester) { create(:user) }
let(:project) { create(:empty_project, :public, :access_requestable) }
let(:project_member) { build(:project_member, project: project) }
let(:project_member_invite) { build(:project_member, project: project).tap { |m| m.generate_invite_token! } }
@@ -31,7 +31,7 @@ describe MembersHelper do
end
describe '#remove_member_title' do
- let(:requester) { build(:user) }
+ let(:requester) { create(:user) }
let(:project) { create(:empty_project, :public, :access_requestable) }
let(:project_member) { build(:project_member, project: project) }
let(:project_member_request) { project.request_access(requester) }
diff --git a/spec/helpers/milestones_helper_spec.rb b/spec/helpers/milestones_helper_spec.rb
index 28c2268f8d0..ea744dbb629 100644
--- a/spec/helpers/milestones_helper_spec.rb
+++ b/spec/helpers/milestones_helper_spec.rb
@@ -1,6 +1,25 @@
require 'spec_helper'
describe MilestonesHelper do
+ describe "#milestone_date_range" do
+ def result_for(*args)
+ milestone_date_range(build(:milestone, *args))
+ end
+
+ let(:yesterday) { Date.yesterday }
+ let(:tomorrow) { yesterday + 2 }
+ let(:format) { '%b %-d, %Y' }
+ let(:yesterday_formatted) { yesterday.strftime(format) }
+ let(:tomorrow_formatted) { tomorrow.strftime(format) }
+
+ it { expect(result_for(due_date: nil, start_date: nil)).to be_nil }
+ it { expect(result_for(due_date: tomorrow)).to eq("expires on #{tomorrow_formatted}") }
+ it { expect(result_for(due_date: yesterday)).to eq("expired on #{yesterday_formatted}") }
+ it { expect(result_for(start_date: tomorrow)).to eq("starts on #{tomorrow_formatted}") }
+ it { expect(result_for(start_date: yesterday)).to eq("started on #{yesterday_formatted}") }
+ it { expect(result_for(start_date: yesterday, due_date: tomorrow)).to eq("#{yesterday_formatted} - #{tomorrow_formatted}") }
+ end
+
describe '#milestone_counts' do
let(:project) { FactoryGirl.create(:project) }
let(:counts) { helper.milestone_counts(project.milestones) }
diff --git a/spec/helpers/sidekiq_helper_spec.rb b/spec/helpers/sidekiq_helper_spec.rb
index d60839b78ec..f86e496740a 100644
--- a/spec/helpers/sidekiq_helper_spec.rb
+++ b/spec/helpers/sidekiq_helper_spec.rb
@@ -30,6 +30,29 @@ describe SidekiqHelper do
expect(parts).to eq(['55137', '10.0', '2.1', 'S+', '2:30pm', 'sidekiq 4.1.4 gitlab [0 of 25 busy]'])
end
+ it 'parses OSX output' do
+ line = ' 1641 1.5 3.8 S+ 4:04PM sidekiq 4.2.1 gitlab [0 of 25 busy]'
+ parts = helper.parse_sidekiq_ps(line)
+
+ expect(parts).to eq(['1641', '1.5', '3.8', 'S+', '4:04PM', 'sidekiq 4.2.1 gitlab [0 of 25 busy]'])
+ end
+
+ it 'parses Ubuntu output' do
+ # Ubuntu Linux 16.04 LTS / procps-3.3.10-4ubuntu2
+ line = ' 938 1.4 2.5 Sl+ 21:23:21 sidekiq 4.2.1 gitlab [0 of 25 busy] '
+ parts = helper.parse_sidekiq_ps(line)
+
+ expect(parts).to eq(['938', '1.4', '2.5', 'Sl+', '21:23:21', 'sidekiq 4.2.1 gitlab [0 of 25 busy]'])
+ end
+
+ it 'parses Debian output' do
+ # Debian Linux Wheezy/Jessie
+ line = '17725 1.0 12.1 Ssl 19:20:15 sidekiq 4.2.1 gitlab-rails [0 of 25 busy] '
+ parts = helper.parse_sidekiq_ps(line)
+
+ expect(parts).to eq(['17725', '1.0', '12.1', 'Ssl', '19:20:15', 'sidekiq 4.2.1 gitlab-rails [0 of 25 busy]'])
+ end
+
it 'does fail gracefully on line not matching the format' do
line = '55137 10.0 2.1 S+ 2:30pm something'
parts = helper.parse_sidekiq_ps(line)
diff --git a/spec/javascripts/.eslintrc b/spec/javascripts/.eslintrc
index 90388929612..7792acffac2 100644
--- a/spec/javascripts/.eslintrc
+++ b/spec/javascripts/.eslintrc
@@ -7,5 +7,9 @@
"rules": {
"prefer-arrow-callback": 0,
"func-names": 0
+ },
+ "globals": {
+ "fixture": false,
+ "spyOnEvent": false
}
}
diff --git a/spec/javascripts/build_spec.js.es6 b/spec/javascripts/build_spec.js.es6
index e21e5844a26..4208e076e96 100644
--- a/spec/javascripts/build_spec.js.es6
+++ b/spec/javascripts/build_spec.js.es6
@@ -1,6 +1,7 @@
-/* global Build */
/* eslint-disable no-new */
-//= require lib/utils/timeago
+/* global Build */
+/* global Turbolinks */
+
//= require lib/utils/datetime_utility
//= require build
//= require breakpoints
diff --git a/spec/javascripts/environments/environments_store_spec.js.es6 b/spec/javascripts/environments/environments_store_spec.js.es6
index 82d9599f372..9b0b3cb1c65 100644
--- a/spec/javascripts/environments/environments_store_spec.js.es6
+++ b/spec/javascripts/environments/environments_store_spec.js.es6
@@ -1,7 +1,9 @@
+/* global environmentsList */
+
//= require vue
//= require environments/stores/environments_store
//= require ./mock_data
-/* globals environmentsList */
+
(() => {
beforeEach(() => {
gl.environmentsList.EnvironmentsStore.create();
diff --git a/spec/javascripts/fixtures/build.html.haml b/spec/javascripts/fixtures/build.html.haml
index 27136beb14c..06b49516e5c 100644
--- a/spec/javascripts/fixtures/build.html.haml
+++ b/spec/javascripts/fixtures/build.html.haml
@@ -54,7 +54,7 @@
build_url: 'http://example.com/root/test-build/builds/2.json',
build_status: 'passed',
build_stage: 'test',
- state1: 'buildstate' }}
+ log_state: 'buildstate' }}
%p.build-detail-row
The artifacts will be removed in
diff --git a/spec/javascripts/merge_request_widget_spec.js b/spec/javascripts/merge_request_widget_spec.js
index f38e9cb8ef5..62890f1ca96 100644
--- a/spec/javascripts/merge_request_widget_spec.js
+++ b/spec/javascripts/merge_request_widget_spec.js
@@ -1,6 +1,6 @@
/* eslint-disable space-before-function-paren, quotes, comma-dangle, dot-notation, indent, quote-props, no-var, padded-blocks, max-len */
+
/*= require merge_request_widget */
-/*= require lib/utils/timeago */
/*= require lib/utils/datetime_utility */
(function() {
diff --git a/spec/lib/constraints/constrainer_helper_spec.rb b/spec/lib/constraints/constrainer_helper_spec.rb
deleted file mode 100644
index 27c8d72aefc..00000000000
--- a/spec/lib/constraints/constrainer_helper_spec.rb
+++ /dev/null
@@ -1,20 +0,0 @@
-require 'spec_helper'
-
-describe ConstrainerHelper, lib: true do
- include ConstrainerHelper
-
- describe '#extract_resource_path' do
- it { expect(extract_resource_path('/gitlab/')).to eq('gitlab') }
- it { expect(extract_resource_path('///gitlab//')).to eq('gitlab') }
- it { expect(extract_resource_path('/gitlab.atom')).to eq('gitlab') }
-
- context 'relative url' do
- before do
- allow(Gitlab::Application.config).to receive(:relative_url_root) { '/gitlab' }
- end
-
- it { expect(extract_resource_path('/gitlab/foo')).to eq('foo') }
- it { expect(extract_resource_path('/foo/bar')).to eq('foo/bar') }
- end
- end
-end
diff --git a/spec/lib/constraints/group_url_constrainer_spec.rb b/spec/lib/constraints/group_url_constrainer_spec.rb
index 42299b17c2b..892554f2870 100644
--- a/spec/lib/constraints/group_url_constrainer_spec.rb
+++ b/spec/lib/constraints/group_url_constrainer_spec.rb
@@ -4,16 +4,20 @@ describe GroupUrlConstrainer, lib: true do
let!(:group) { create(:group, path: 'gitlab') }
describe '#matches?' do
- context 'root group' do
- it { expect(subject.matches?(request '/gitlab')).to be_truthy }
- it { expect(subject.matches?(request '/gitlab.atom')).to be_truthy }
- it { expect(subject.matches?(request '/gitlab/edit')).to be_falsey }
- it { expect(subject.matches?(request '/gitlab-ce')).to be_falsey }
- it { expect(subject.matches?(request '/.gitlab')).to be_falsey }
+ context 'valid request' do
+ let(:request) { build_request(group.path) }
+
+ it { expect(subject.matches?(request)).to be_truthy }
+ end
+
+ context 'invalid request' do
+ let(:request) { build_request('foo') }
+
+ it { expect(subject.matches?(request)).to be_falsey }
end
end
- def request(path)
- double(:request, path: path)
+ def build_request(path)
+ double(:request, params: { id: path })
end
end
diff --git a/spec/lib/constraints/project_url_constrainer_spec.rb b/spec/lib/constraints/project_url_constrainer_spec.rb
new file mode 100644
index 00000000000..94266f6653b
--- /dev/null
+++ b/spec/lib/constraints/project_url_constrainer_spec.rb
@@ -0,0 +1,32 @@
+require 'spec_helper'
+
+describe ProjectUrlConstrainer, lib: true do
+ let!(:project) { create(:project) }
+ let!(:namespace) { project.namespace }
+
+ describe '#matches?' do
+ context 'valid request' do
+ let(:request) { build_request(namespace.path, project.path) }
+
+ it { expect(subject.matches?(request)).to be_truthy }
+ end
+
+ context 'invalid request' do
+ context "non-existing project" do
+ let(:request) { build_request('foo', 'bar') }
+
+ it { expect(subject.matches?(request)).to be_falsey }
+ end
+
+ context "project id ending with .git" do
+ let(:request) { build_request(namespace.path, project.path + '.git') }
+
+ it { expect(subject.matches?(request)).to be_falsey }
+ end
+ end
+ end
+
+ def build_request(namespace, project)
+ double(:request, params: { namespace_id: namespace, id: project })
+ end
+end
diff --git a/spec/lib/constraints/user_url_constrainer_spec.rb b/spec/lib/constraints/user_url_constrainer_spec.rb
index b3f8530c609..207b6fe6c9e 100644
--- a/spec/lib/constraints/user_url_constrainer_spec.rb
+++ b/spec/lib/constraints/user_url_constrainer_spec.rb
@@ -1,16 +1,23 @@
require 'spec_helper'
describe UserUrlConstrainer, lib: true do
- let!(:username) { create(:user, username: 'dz') }
+ let!(:user) { create(:user, username: 'dz') }
describe '#matches?' do
- it { expect(subject.matches?(request '/dz')).to be_truthy }
- it { expect(subject.matches?(request '/dz.atom')).to be_truthy }
- it { expect(subject.matches?(request '/dz/projects')).to be_falsey }
- it { expect(subject.matches?(request '/gitlab')).to be_falsey }
+ context 'valid request' do
+ let(:request) { build_request(user.username) }
+
+ it { expect(subject.matches?(request)).to be_truthy }
+ end
+
+ context 'invalid request' do
+ let(:request) { build_request('foo') }
+
+ it { expect(subject.matches?(request)).to be_falsey }
+ end
end
- def request(path)
- double(:request, path: path)
+ def build_request(username)
+ double(:request, params: { username: username })
end
end
diff --git a/spec/lib/gitlab/chat_commands/issue_create_spec.rb b/spec/lib/gitlab/chat_commands/issue_create_spec.rb
index df0c317ccea..dd07cff9243 100644
--- a/spec/lib/gitlab/chat_commands/issue_create_spec.rb
+++ b/spec/lib/gitlab/chat_commands/issue_create_spec.rb
@@ -32,6 +32,15 @@ describe Gitlab::ChatCommands::IssueCreate, service: true do
expect(Issue.last.description).to eq(description)
end
end
+
+ context "with more newlines between the title and the description" do
+ let(:description) { "Surfin bird" }
+ let(:regex_match) { described_class.match("issue create bird is the word\n\n#{description}\n") }
+
+ it 'creates the issue' do
+ expect { subject }.to change { project.issues.count }.by(1)
+ end
+ end
end
describe '.match' do
diff --git a/spec/lib/gitlab/cycle_analytics/plan_event_spec.rb b/spec/lib/gitlab/cycle_analytics/plan_event_spec.rb
index d76a255acf5..4a5604115ec 100644
--- a/spec/lib/gitlab/cycle_analytics/plan_event_spec.rb
+++ b/spec/lib/gitlab/cycle_analytics/plan_event_spec.rb
@@ -6,5 +6,13 @@ describe Gitlab::CycleAnalytics::PlanEvent do
it 'has the default order' do
expect(event.order).to eq(event.start_time_attrs)
end
+
+ context 'no commits' do
+ it 'does not blow up if there are no commits' do
+ allow_any_instance_of(Gitlab::CycleAnalytics::EventsQuery).to receive(:execute).and_return([{}])
+
+ expect { event.fetch }.not_to raise_error
+ end
+ end
end
end
diff --git a/spec/lib/gitlab/identifier_spec.rb b/spec/lib/gitlab/identifier_spec.rb
index 47d6f1007d1..bb758a8a202 100644
--- a/spec/lib/gitlab/identifier_spec.rb
+++ b/spec/lib/gitlab/identifier_spec.rb
@@ -40,7 +40,7 @@ describe Gitlab::Identifier do
describe '#identify_using_commit' do
it "returns the User for an existing commit author's Email address" do
- commit = double(:commit, author_email: user.email)
+ commit = double(:commit, author: user, author_email: user.email)
expect(project).to receive(:commit).with('123').and_return(commit)
@@ -62,10 +62,9 @@ describe Gitlab::Identifier do
end
it 'caches the found users per Email' do
- commit = double(:commit, author_email: user.email)
+ commit = double(:commit, author: user, author_email: user.email)
expect(project).to receive(:commit).with('123').twice.and_return(commit)
- expect(User).to receive(:find_by).once.and_call_original
2.times do
expect(identifier.identify_using_commit(project, '123')).to eq(user)
diff --git a/spec/lib/gitlab/import_export/all_models.yml b/spec/lib/gitlab/import_export/all_models.yml
index fe3c39e38db..7e00e214c6e 100644
--- a/spec/lib/gitlab/import_export/all_models.yml
+++ b/spec/lib/gitlab/import_export/all_models.yml
@@ -186,6 +186,8 @@ project:
- environments
- deployments
- project_feature
+- authorized_users
+- project_authorizations
award_emoji:
- awardable
- user
diff --git a/spec/lib/gitlab/import_export/safe_model_attributes.yml b/spec/lib/gitlab/import_export/safe_model_attributes.yml
index d6807941b31..78d6b2c5032 100644
--- a/spec/lib/gitlab/import_export/safe_model_attributes.yml
+++ b/spec/lib/gitlab/import_export/safe_model_attributes.yml
@@ -78,6 +78,7 @@ Milestone:
- project_id
- description
- due_date
+- start_date
- created_at
- updated_at
- state
diff --git a/spec/models/ci/pipeline_spec.rb b/spec/models/ci/pipeline_spec.rb
index 71b7628ef10..ea022e03608 100644
--- a/spec/models/ci/pipeline_spec.rb
+++ b/spec/models/ci/pipeline_spec.rb
@@ -571,6 +571,9 @@ describe Ci::Pipeline, models: true do
context 'with failed pipeline' do
before do
perform_enqueued_jobs do
+ create(:ci_build, :failed, pipeline: pipeline)
+ create(:generic_commit_status, :failed, pipeline: pipeline)
+
pipeline.drop
end
end
diff --git a/spec/models/concerns/milestoneish_spec.rb b/spec/models/concerns/milestoneish_spec.rb
index b7e973798a3..0e097559b59 100644
--- a/spec/models/concerns/milestoneish_spec.rb
+++ b/spec/models/concerns/milestoneish_spec.rb
@@ -115,4 +115,24 @@ describe Milestone, 'Milestoneish' do
expect(milestone.percent_complete(admin)).to eq 60
end
end
+
+ describe '#elapsed_days' do
+ it 'shows 0 if no start_date set' do
+ milestone = build(:milestone)
+
+ expect(milestone.elapsed_days).to eq(0)
+ end
+
+ it 'shows 0 if start_date is a future' do
+ milestone = build(:milestone, start_date: Time.now + 2.days)
+
+ expect(milestone.elapsed_days).to eq(0)
+ end
+
+ it 'shows correct amount of days' do
+ milestone = build(:milestone, start_date: Time.now - 2.days)
+
+ expect(milestone.elapsed_days).to eq(2)
+ end
+ end
end
diff --git a/spec/models/issue_spec.rb b/spec/models/issue_spec.rb
index 300425767ed..89e93dce8c5 100644
--- a/spec/models/issue_spec.rb
+++ b/spec/models/issue_spec.rb
@@ -331,7 +331,7 @@ describe Issue, models: true do
end
context 'with a user' do
- let(:user) { build(:user) }
+ let(:user) { create(:user) }
let(:issue) { build(:issue) }
it 'returns true when the issue is readable' do
diff --git a/spec/models/merge_request_spec.rb b/spec/models/merge_request_spec.rb
index 0b4277b1edd..58ccd056328 100644
--- a/spec/models/merge_request_spec.rb
+++ b/spec/models/merge_request_spec.rb
@@ -937,6 +937,16 @@ describe MergeRequest, models: true do
expect(merge_request.mergeable_discussions_state?).to be_falsey
end
end
+
+ context 'with no discussions' do
+ before do
+ merge_request.notes.destroy_all
+ end
+
+ it 'returns true' do
+ expect(merge_request.mergeable_discussions_state?).to be_truthy
+ end
+ end
end
context 'when project.only_allow_merge_if_all_discussions_are_resolved == false' do
@@ -1198,6 +1208,50 @@ describe MergeRequest, models: true do
end
end
end
+
+ describe "#discussions_to_be_resolved?" do
+ context "when discussions are not resolvable" do
+ before do
+ allow(subject).to receive(:discussions_resolvable?).and_return(false)
+ end
+
+ it "returns false" do
+ expect(subject.discussions_to_be_resolved?).to be false
+ end
+ end
+
+ context "when discussions are resolvable" do
+ before do
+ allow(subject).to receive(:discussions_resolvable?).and_return(true)
+
+ allow(first_discussion).to receive(:resolvable?).and_return(true)
+ allow(second_discussion).to receive(:resolvable?).and_return(false)
+ allow(third_discussion).to receive(:resolvable?).and_return(true)
+ end
+
+ context "when all resolvable discussions are resolved" do
+ before do
+ allow(first_discussion).to receive(:resolved?).and_return(true)
+ allow(third_discussion).to receive(:resolved?).and_return(true)
+ end
+
+ it "returns false" do
+ expect(subject.discussions_to_be_resolved?).to be false
+ end
+ end
+
+ context "when some resolvable discussions are not resolved" do
+ before do
+ allow(first_discussion).to receive(:resolved?).and_return(true)
+ allow(third_discussion).to receive(:resolved?).and_return(false)
+ end
+
+ it "returns true" do
+ expect(subject.discussions_to_be_resolved?).to be true
+ end
+ end
+ end
+ end
end
describe '#conflicts_can_be_resolved_in_ui?' do
diff --git a/spec/models/milestone_spec.rb b/spec/models/milestone_spec.rb
index 33fe22dd98c..a4bfe851dfb 100644
--- a/spec/models/milestone_spec.rb
+++ b/spec/models/milestone_spec.rb
@@ -1,11 +1,6 @@
require 'spec_helper'
describe Milestone, models: true do
- describe "Associations" do
- it { is_expected.to belong_to(:project) }
- it { is_expected.to have_many(:issues) }
- end
-
describe "Validation" do
before do
allow(subject).to receive(:set_iid).and_return(false)
@@ -13,6 +8,20 @@ describe Milestone, models: true do
it { is_expected.to validate_presence_of(:title) }
it { is_expected.to validate_presence_of(:project) }
+
+ describe 'start_date' do
+ it 'adds an error when start_date is greated then due_date' do
+ milestone = build(:milestone, start_date: Date.tomorrow, due_date: Date.yesterday)
+
+ expect(milestone).not_to be_valid
+ expect(milestone.errors[:start_date]).to include("Can't be greater than due date")
+ end
+ end
+ end
+
+ describe "Associations" do
+ it { is_expected.to belong_to(:project) }
+ it { is_expected.to have_many(:issues) }
end
let(:milestone) { create(:milestone) }
@@ -58,18 +67,6 @@ describe Milestone, models: true do
end
end
- describe "#expires_at" do
- it "is nil when due_date is unset" do
- milestone.update_attributes(due_date: nil)
- expect(milestone.expires_at).to be_nil
- end
-
- it "is not nil when due_date is set" do
- milestone.update_attributes(due_date: Date.tomorrow)
- expect(milestone.expires_at).to be_present
- end
- end
-
describe '#expired?' do
context "expired" do
before do
@@ -88,6 +85,18 @@ describe Milestone, models: true do
end
end
+ describe '#upcoming?' do
+ it 'returns true' do
+ milestone = build(:milestone, start_date: Time.now + 1.month)
+ expect(milestone.upcoming?).to be_truthy
+ end
+
+ it 'returns false' do
+ milestone = build(:milestone, start_date: Date.today.prev_year)
+ expect(milestone.upcoming?).to be_falsey
+ end
+ end
+
describe '#percent_complete' do
before do
allow(milestone).to receive_messages(
diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb
index e183fa88873..da38254d1bc 100644
--- a/spec/models/project_spec.rb
+++ b/spec/models/project_spec.rb
@@ -243,6 +243,13 @@ describe Project, models: true do
it { is_expected.to respond_to(:path_with_namespace) }
end
+ describe 'delegation' do
+ it { is_expected.to delegate_method(:add_guest).to(:team) }
+ it { is_expected.to delegate_method(:add_reporter).to(:team) }
+ it { is_expected.to delegate_method(:add_developer).to(:team) }
+ it { is_expected.to delegate_method(:add_master).to(:team) }
+ end
+
describe '#name_with_namespace' do
let(:project) { build_stubbed(:empty_project) }
@@ -1500,57 +1507,6 @@ describe Project, models: true do
end
end
- describe 'authorized_for_user' do
- let(:group) { create(:group) }
- let(:developer) { create(:user) }
- let(:master) { create(:user) }
- let(:personal_project) { create(:project, namespace: developer.namespace) }
- let(:group_project) { create(:project, namespace: group) }
- let(:members_project) { create(:project) }
- let(:shared_project) { create(:project) }
-
- before do
- group.add_master(master)
- group.add_developer(developer)
-
- members_project.team << [developer, :developer]
- members_project.team << [master, :master]
-
- create(:project_group_link, project: shared_project, group: group, group_access: Gitlab::Access::DEVELOPER)
- end
-
- it 'returns false for no user' do
- expect(personal_project.authorized_for_user?(nil)).to be(false)
- end
-
- it 'returns true for personal projects of the user' do
- expect(personal_project.authorized_for_user?(developer)).to be(true)
- end
-
- it 'returns true for projects of groups the user is a member of' do
- expect(group_project.authorized_for_user?(developer)).to be(true)
- end
-
- it 'returns true for projects for which the user is a member of' do
- expect(members_project.authorized_for_user?(developer)).to be(true)
- end
-
- it 'returns true for projects shared on a group the user is a member of' do
- expect(shared_project.authorized_for_user?(developer)).to be(true)
- end
-
- it 'checks for the correct minimum level access' do
- expect(group_project.authorized_for_user?(developer, Gitlab::Access::MASTER)).to be(false)
- expect(group_project.authorized_for_user?(master, Gitlab::Access::MASTER)).to be(true)
- expect(members_project.authorized_for_user?(developer, Gitlab::Access::MASTER)).to be(false)
- expect(members_project.authorized_for_user?(master, Gitlab::Access::MASTER)).to be(true)
- expect(shared_project.authorized_for_user?(developer, Gitlab::Access::MASTER)).to be(false)
- expect(shared_project.authorized_for_user?(master, Gitlab::Access::MASTER)).to be(false)
- expect(shared_project.authorized_for_user?(developer, Gitlab::Access::DEVELOPER)).to be(true)
- expect(shared_project.authorized_for_user?(master, Gitlab::Access::DEVELOPER)).to be(true)
- end
- end
-
describe 'change_head' do
let(:project) { create(:project) }
diff --git a/spec/models/project_team_spec.rb b/spec/models/project_team_spec.rb
index 12228425579..0475cecaa2d 100644
--- a/spec/models/project_team_spec.rb
+++ b/spec/models/project_team_spec.rb
@@ -10,9 +10,9 @@ describe ProjectTeam, models: true do
let(:project) { create(:empty_project) }
before do
- project.team << [master, :master]
- project.team << [reporter, :reporter]
- project.team << [guest, :guest]
+ project.add_master(master)
+ project.add_reporter(reporter)
+ project.add_guest(guest)
end
describe 'members collection' do
@@ -37,7 +37,7 @@ describe ProjectTeam, models: true do
context 'group project' do
let(:group) { create(:group) }
- let(:project) { create(:empty_project, group: group) }
+ let!(:project) { create(:empty_project, group: group) }
before do
group.add_master(master)
@@ -47,8 +47,8 @@ describe ProjectTeam, models: true do
# If user is a group and a project member - GitLab uses highest permission
# So we add group guest as master and add group master as guest
# to this project to test highest access
- project.team << [guest, :master]
- project.team << [master, :guest]
+ project.add_master(guest)
+ project.add_guest(master)
end
describe 'members collection' do
@@ -79,14 +79,14 @@ describe ProjectTeam, models: true do
it 'returns project members' do
user = create(:user)
- project.team << [user, :guest]
+ project.add_guest(user)
expect(project.team.members).to contain_exactly(user)
end
it 'returns project members of a specified level' do
user = create(:user)
- project.team << [user, :reporter]
+ project.add_reporter(user)
expect(project.team.guests).to be_empty
expect(project.team.reporters).to contain_exactly(user)
@@ -118,7 +118,7 @@ describe ProjectTeam, models: true do
context 'group project' do
let(:group) { create(:group) }
- let(:project) { create(:empty_project, group: group) }
+ let!(:project) { create(:empty_project, group: group) }
it 'returns project members' do
group_member = create(:group_member, group: group)
@@ -141,9 +141,9 @@ describe ProjectTeam, models: true do
let(:requester) { create(:user) }
before do
- project.team << [master, :master]
- project.team << [reporter, :reporter]
- project.team << [guest, :guest]
+ project.add_master(master)
+ project.add_reporter(reporter)
+ project.add_guest(guest)
project.request_access(requester)
end
@@ -178,9 +178,9 @@ describe ProjectTeam, models: true do
it 'returns Master role' do
user = create(:user)
group = create(:group)
- group.add_master(user)
+ project = create(:empty_project, namespace: group)
- project = build_stubbed(:empty_project, namespace: group)
+ group.add_master(user)
expect(project.team.human_max_access(user.id)).to eq 'Master'
end
@@ -188,9 +188,9 @@ describe ProjectTeam, models: true do
it 'returns Owner role' do
user = create(:user)
group = create(:group)
- group.add_owner(user)
+ project = create(:empty_project, namespace: group)
- project = build_stubbed(:empty_project, namespace: group)
+ group.add_owner(user)
expect(project.team.human_max_access(user.id)).to eq 'Owner'
end
@@ -204,9 +204,9 @@ describe ProjectTeam, models: true do
context 'when project is not shared with group' do
before do
- project.team << [master, :master]
- project.team << [reporter, :reporter]
- project.team << [guest, :guest]
+ project.add_master(master)
+ project.add_reporter(reporter)
+ project.add_guest(guest)
project.request_access(requester)
end
@@ -244,7 +244,7 @@ describe ProjectTeam, models: true do
context 'group project' do
let(:group) { create(:group, :access_requestable) }
- let(:project) { create(:empty_project, group: group) }
+ let!(:project) { create(:empty_project, group: group) }
before do
group.add_master(master)
@@ -261,6 +261,57 @@ describe ProjectTeam, models: true do
end
end
+ describe '#member?' do
+ let(:group) { create(:group) }
+ let(:developer) { create(:user) }
+ let(:master) { create(:user) }
+ let(:personal_project) { create(:project, namespace: developer.namespace) }
+ let(:group_project) { create(:project, namespace: group) }
+ let(:members_project) { create(:project) }
+ let(:shared_project) { create(:project) }
+
+ before do
+ group.add_master(master)
+ group.add_developer(developer)
+
+ members_project.team << [developer, :developer]
+ members_project.team << [master, :master]
+
+ create(:project_group_link, project: shared_project, group: group)
+ end
+
+ it 'returns false for no user' do
+ expect(personal_project.team.member?(nil)).to be(false)
+ end
+
+ it 'returns true for personal projects of the user' do
+ expect(personal_project.team.member?(developer)).to be(true)
+ end
+
+ it 'returns true for projects of groups the user is a member of' do
+ expect(group_project.team.member?(developer)).to be(true)
+ end
+
+ it 'returns true for projects for which the user is a member of' do
+ expect(members_project.team.member?(developer)).to be(true)
+ end
+
+ it 'returns true for projects shared on a group the user is a member of' do
+ expect(shared_project.team.member?(developer)).to be(true)
+ end
+
+ it 'checks for the correct minimum level access' do
+ expect(group_project.team.member?(developer, Gitlab::Access::MASTER)).to be(false)
+ expect(group_project.team.member?(master, Gitlab::Access::MASTER)).to be(true)
+ expect(members_project.team.member?(developer, Gitlab::Access::MASTER)).to be(false)
+ expect(members_project.team.member?(master, Gitlab::Access::MASTER)).to be(true)
+ expect(shared_project.team.member?(developer, Gitlab::Access::MASTER)).to be(false)
+ expect(shared_project.team.member?(master, Gitlab::Access::MASTER)).to be(false)
+ expect(shared_project.team.member?(developer, Gitlab::Access::DEVELOPER)).to be(true)
+ expect(shared_project.team.member?(master, Gitlab::Access::DEVELOPER)).to be(true)
+ end
+ end
+
shared_examples_for "#max_member_access_for_users" do |enable_request_store|
describe "#max_member_access_for_users" do
before do
@@ -281,10 +332,10 @@ describe ProjectTeam, models: true do
guest = create(:user)
project = create(:project)
- project.team << [master, :master]
- project.team << [reporter, :reporter]
- project.team << [promoted_guest, :guest]
- project.team << [guest, :guest]
+ project.add_master(master)
+ project.add_reporter(reporter)
+ project.add_guest(promoted_guest)
+ project.add_guest(guest)
group = create(:group)
group_developer = create(:user)
diff --git a/spec/models/service_spec.rb b/spec/models/service_spec.rb
index b1615a95004..691511cd93f 100644
--- a/spec/models/service_spec.rb
+++ b/spec/models/service_spec.rb
@@ -6,9 +6,6 @@ describe Service, models: true do
it { is_expected.to have_one :service_hook }
end
- describe "Mass assignment" do
- end
-
describe "Test Button" do
before do
@service = Service.new
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index e84042f8063..91826e5884d 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -752,6 +752,17 @@ describe User, models: true do
end
end
+ describe '.find_by_username' do
+ it 'returns nil if not found' do
+ expect(described_class.find_by_username('JohnDoe')).to be_nil
+ end
+
+ it 'is case-insensitive' do
+ user = create(:user, username: 'JohnDoe')
+ expect(described_class.find_by_username('JOHNDOE')).to eq user
+ end
+ end
+
describe '.find_by_username!' do
it 'raises RecordNotFound' do
expect { described_class.find_by_username!('JohnDoe') }.
diff --git a/spec/requests/api/merge_requests_spec.rb b/spec/requests/api/merge_requests_spec.rb
index 7b3d1460c90..37fcb2bc3a9 100644
--- a/spec/requests/api/merge_requests_spec.rb
+++ b/spec/requests/api/merge_requests_spec.rb
@@ -169,6 +169,16 @@ describe API::API, api: true do
expect(json_response.first['id']).to eq merge_request.id
end
+ it 'returns merge_request by iid array' do
+ get api("/projects/#{project.id}/merge_requests", user), iid: [merge_request.iid, merge_request_closed.iid]
+
+ expect(response).to have_http_status(200)
+ expect(json_response).to be_an Array
+ expect(json_response.length).to eq(2)
+ expect(json_response.first['title']).to eq merge_request_closed.title
+ expect(json_response.first['id']).to eq merge_request_closed.id
+ end
+
it "returns a 404 error if merge_request_id not found" do
get api("/projects/#{project.id}/merge_requests/999", user)
expect(response).to have_http_status(404)
diff --git a/spec/requests/api/milestones_spec.rb b/spec/requests/api/milestones_spec.rb
index 62327f64e50..b0946a838a1 100644
--- a/spec/requests/api/milestones_spec.rb
+++ b/spec/requests/api/milestones_spec.rb
@@ -61,6 +61,15 @@ describe API::API, api: true do
expect(json_response.first['id']).to eq closed_milestone.id
end
+ it 'returns a project milestone by iid array' do
+ get api("/projects/#{project.id}/milestones", user), iid: [milestone.iid, closed_milestone.iid]
+
+ expect(response).to have_http_status(200)
+ expect(json_response.size).to eq(2)
+ expect(json_response.first['title']).to eq milestone.title
+ expect(json_response.first['id']).to eq milestone.id
+ end
+
it 'returns 401 error if user not authenticated' do
get api("/projects/#{project.id}/milestones/#{milestone.id}")
@@ -83,13 +92,14 @@ describe API::API, api: true do
expect(json_response['description']).to be_nil
end
- it 'creates a new project milestone with description and due date' do
+ it 'creates a new project milestone with description and dates' do
post api("/projects/#{project.id}/milestones", user),
- title: 'new milestone', description: 'release', due_date: '2013-03-02'
+ title: 'new milestone', description: 'release', due_date: '2013-03-02', start_date: '2013-02-02'
expect(response).to have_http_status(201)
expect(json_response['description']).to eq('release')
expect(json_response['due_date']).to eq('2013-03-02')
+ expect(json_response['start_date']).to eq('2013-02-02')
end
it 'returns a 400 error if title is missing' do
diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb
index f020d471422..e53ee2a4e76 100644
--- a/spec/requests/api/projects_spec.rb
+++ b/spec/requests/api/projects_spec.rb
@@ -908,6 +908,36 @@ describe API::API, api: true do
end
end
+ describe 'DELETE /projects/:id/share/:group_id' do
+ it 'returns 204 when deleting a group share' do
+ group = create(:group, :public)
+ create(:project_group_link, group: group, project: project)
+
+ delete api("/projects/#{project.id}/share/#{group.id}", user)
+
+ expect(response).to have_http_status(204)
+ expect(project.project_group_links).to be_empty
+ end
+
+ it 'returns a 400 when group id is not an integer' do
+ delete api("/projects/#{project.id}/share/foo", user)
+
+ expect(response).to have_http_status(400)
+ end
+
+ it 'returns a 404 error when group link does not exist' do
+ delete api("/projects/#{project.id}/share/1234", user)
+
+ expect(response).to have_http_status(404)
+ end
+
+ it 'returns a 404 error when project does not exist' do
+ delete api("/projects/123/share/1234", user)
+
+ expect(response).to have_http_status(404)
+ end
+ end
+
describe 'GET /projects/search/:query' do
let!(:query) { 'query'}
let!(:search) { create(:empty_project, name: query, creator_id: user.id, namespace: user.namespace) }
diff --git a/spec/routing/project_routing_spec.rb b/spec/routing/project_routing_spec.rb
index 2322430d212..b6e7da841b1 100644
--- a/spec/routing/project_routing_spec.rb
+++ b/spec/routing/project_routing_spec.rb
@@ -1,511 +1,531 @@
require 'spec_helper'
-# Shared examples for a resource inside a Project
-#
-# By default it tests all the default REST actions: index, create, new, edit,
-# show, update, and destroy. You can remove actions by customizing the
-# `actions` variable.
-#
-# It also expects a `controller` variable to be available which defines both
-# the path to the resource as well as the controller name.
-#
-# Examples
-#
-# # Default behavior
-# it_behaves_like 'RESTful project resources' do
-# let(:controller) { 'issues' }
-# end
-#
-# # Customizing actions
-# it_behaves_like 'RESTful project resources' do
-# let(:actions) { [:index] }
-# let(:controller) { 'issues' }
-# end
-shared_examples 'RESTful project resources' do
- let(:actions) { [:index, :create, :new, :edit, :show, :update, :destroy] }
-
- it 'to #index' do
- expect(get("/gitlab/gitlabhq/#{controller}")).to route_to("projects/#{controller}#index", namespace_id: 'gitlab', project_id: 'gitlabhq') if actions.include?(:index)
- end
-
- it 'to #create' do
- expect(post("/gitlab/gitlabhq/#{controller}")).to route_to("projects/#{controller}#create", namespace_id: 'gitlab', project_id: 'gitlabhq') if actions.include?(:create)
- end
-
- it 'to #new' do
- expect(get("/gitlab/gitlabhq/#{controller}/new")).to route_to("projects/#{controller}#new", namespace_id: 'gitlab', project_id: 'gitlabhq') if actions.include?(:new)
- end
-
- it 'to #edit' do
- expect(get("/gitlab/gitlabhq/#{controller}/1/edit")).to route_to("projects/#{controller}#edit", namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1') if actions.include?(:edit)
- end
-
- it 'to #show' do
- expect(get("/gitlab/gitlabhq/#{controller}/1")).to route_to("projects/#{controller}#show", namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1') if actions.include?(:show)
- end
-
- it 'to #update' do
- expect(put("/gitlab/gitlabhq/#{controller}/1")).to route_to("projects/#{controller}#update", namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1') if actions.include?(:update)
- end
-
- it 'to #destroy' do
- expect(delete("/gitlab/gitlabhq/#{controller}/1")).to route_to("projects/#{controller}#destroy", namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1') if actions.include?(:destroy)
- end
-end
-
-# projects POST /projects(.:format) projects#create
-# new_project GET /projects/new(.:format) projects#new
-# files_project GET /:id/files(.:format) projects#files
-# edit_project GET /:id/edit(.:format) projects#edit
-# project GET /:id(.:format) projects#show
-# PUT /:id(.:format) projects#update
-# DELETE /:id(.:format) projects#destroy
-# preview_markdown_project POST /:id/preview_markdown(.:format) projects#preview_markdown
-describe ProjectsController, 'routing' do
- it 'to #create' do
- expect(post('/projects')).to route_to('projects#create')
- end
-
- it 'to #new' do
- expect(get('/projects/new')).to route_to('projects#new')
- end
-
- it 'to #edit' do
- expect(get('/gitlab/gitlabhq/edit')).to route_to('projects#edit', namespace_id: 'gitlab', id: 'gitlabhq')
- end
-
- it 'to #autocomplete_sources' do
- expect(get('/gitlab/gitlabhq/autocomplete_sources')).to route_to('projects#autocomplete_sources', namespace_id: 'gitlab', id: 'gitlabhq')
- end
-
- it 'to #show' do
- expect(get('/gitlab/gitlabhq')).to route_to('projects#show', namespace_id: 'gitlab', id: 'gitlabhq')
- expect(get('/gitlab/gitlabhq.keys')).to route_to('projects#show', namespace_id: 'gitlab', id: 'gitlabhq.keys')
- end
-
- it 'to #update' do
- expect(put('/gitlab/gitlabhq')).to route_to('projects#update', namespace_id: 'gitlab', id: 'gitlabhq')
- end
-
- it 'to #destroy' do
- expect(delete('/gitlab/gitlabhq')).to route_to('projects#destroy', namespace_id: 'gitlab', id: 'gitlabhq')
- end
-
- it 'to #preview_markdown' do
- expect(post('/gitlab/gitlabhq/preview_markdown')).to(
- route_to('projects#preview_markdown', namespace_id: 'gitlab', id: 'gitlabhq')
- )
- end
-end
-
-# pages_project_wikis GET /:project_id/wikis/pages(.:format) projects/wikis#pages
-# history_project_wiki GET /:project_id/wikis/:id/history(.:format) projects/wikis#history
-# project_wikis POST /:project_id/wikis(.:format) projects/wikis#create
-# edit_project_wiki GET /:project_id/wikis/:id/edit(.:format) projects/wikis#edit
-# project_wiki GET /:project_id/wikis/:id(.:format) projects/wikis#show
-# DELETE /:project_id/wikis/:id(.:format) projects/wikis#destroy
-describe Projects::WikisController, 'routing' do
- it 'to #pages' do
- expect(get('/gitlab/gitlabhq/wikis/pages')).to route_to('projects/wikis#pages', namespace_id: 'gitlab', project_id: 'gitlabhq')
- end
-
- it 'to #history' do
- expect(get('/gitlab/gitlabhq/wikis/1/history')).to route_to('projects/wikis#history', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1')
- end
-
- it_behaves_like 'RESTful project resources' do
- let(:actions) { [:create, :edit, :show, :destroy] }
- let(:controller) { 'wikis' }
- end
-end
-
-# branches_project_repository GET /:project_id/repository/branches(.:format) projects/repositories#branches
-# tags_project_repository GET /:project_id/repository/tags(.:format) projects/repositories#tags
-# archive_project_repository GET /:project_id/repository/archive(.:format) projects/repositories#archive
-# edit_project_repository GET /:project_id/repository/edit(.:format) projects/repositories#edit
-describe Projects::RepositoriesController, 'routing' do
- it 'to #archive' do
- expect(get('/gitlab/gitlabhq/repository/archive')).to route_to('projects/repositories#archive', namespace_id: 'gitlab', project_id: 'gitlabhq')
- end
-
- it 'to #archive format:zip' do
- expect(get('/gitlab/gitlabhq/repository/archive.zip')).to route_to('projects/repositories#archive', namespace_id: 'gitlab', project_id: 'gitlabhq', format: 'zip')
- end
-
- it 'to #archive format:tar.bz2' do
- expect(get('/gitlab/gitlabhq/repository/archive.tar.bz2')).to route_to('projects/repositories#archive', namespace_id: 'gitlab', project_id: 'gitlabhq', format: 'tar.bz2')
- end
-end
-
-describe Projects::BranchesController, 'routing' do
- it 'to #branches' do
- expect(get('/gitlab/gitlabhq/branches')).to route_to('projects/branches#index', namespace_id: 'gitlab', project_id: 'gitlabhq')
- expect(delete('/gitlab/gitlabhq/branches/feature%2345')).to route_to('projects/branches#destroy', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature#45')
- expect(delete('/gitlab/gitlabhq/branches/feature%2B45')).to route_to('projects/branches#destroy', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature+45')
- expect(delete('/gitlab/gitlabhq/branches/feature@45')).to route_to('projects/branches#destroy', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature@45')
- expect(delete('/gitlab/gitlabhq/branches/feature%2345/foo/bar/baz')).to route_to('projects/branches#destroy', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature#45/foo/bar/baz')
- expect(delete('/gitlab/gitlabhq/branches/feature%2B45/foo/bar/baz')).to route_to('projects/branches#destroy', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature+45/foo/bar/baz')
- expect(delete('/gitlab/gitlabhq/branches/feature@45/foo/bar/baz')).to route_to('projects/branches#destroy', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature@45/foo/bar/baz')
- end
-end
-
-describe Projects::TagsController, 'routing' do
- it 'to #tags' do
- expect(get('/gitlab/gitlabhq/tags')).to route_to('projects/tags#index', namespace_id: 'gitlab', project_id: 'gitlabhq')
- expect(delete('/gitlab/gitlabhq/tags/feature%2345')).to route_to('projects/tags#destroy', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature#45')
- expect(delete('/gitlab/gitlabhq/tags/feature%2B45')).to route_to('projects/tags#destroy', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature+45')
- expect(delete('/gitlab/gitlabhq/tags/feature@45')).to route_to('projects/tags#destroy', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature@45')
- expect(delete('/gitlab/gitlabhq/tags/feature%2345/foo/bar/baz')).to route_to('projects/tags#destroy', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature#45/foo/bar/baz')
- expect(delete('/gitlab/gitlabhq/tags/feature%2B45/foo/bar/baz')).to route_to('projects/tags#destroy', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature+45/foo/bar/baz')
- expect(delete('/gitlab/gitlabhq/tags/feature@45/foo/bar/baz')).to route_to('projects/tags#destroy', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature@45/foo/bar/baz')
- end
-end
-
-# project_deploy_keys GET /:project_id/deploy_keys(.:format) deploy_keys#index
-# POST /:project_id/deploy_keys(.:format) deploy_keys#create
-# new_project_deploy_key GET /:project_id/deploy_keys/new(.:format) deploy_keys#new
-# project_deploy_key GET /:project_id/deploy_keys/:id(.:format) deploy_keys#show
-# DELETE /:project_id/deploy_keys/:id(.:format) deploy_keys#destroy
-describe Projects::DeployKeysController, 'routing' do
- it_behaves_like 'RESTful project resources' do
- let(:actions) { [:index, :new, :create] }
- let(:controller) { 'deploy_keys' }
- end
-end
-
-# project_protected_branches GET /:project_id/protected_branches(.:format) protected_branches#index
-# POST /:project_id/protected_branches(.:format) protected_branches#create
-# project_protected_branch DELETE /:project_id/protected_branches/:id(.:format) protected_branches#destroy
-describe Projects::ProtectedBranchesController, 'routing' do
- it_behaves_like 'RESTful project resources' do
- let(:actions) { [:index, :create, :destroy] }
- let(:controller) { 'protected_branches' }
- end
-end
-
-# switch_project_refs GET /:project_id/refs/switch(.:format) refs#switch
-# logs_tree_project_ref GET /:project_id/refs/:id/logs_tree(.:format) refs#logs_tree
-# logs_file_project_ref GET /:project_id/refs/:id/logs_tree/:path(.:format) refs#logs_tree
-describe Projects::RefsController, 'routing' do
- it 'to #switch' do
- expect(get('/gitlab/gitlabhq/refs/switch')).to route_to('projects/refs#switch', namespace_id: 'gitlab', project_id: 'gitlabhq')
- end
-
- it 'to #logs_tree' do
- expect(get('/gitlab/gitlabhq/refs/stable/logs_tree')).to route_to('projects/refs#logs_tree', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'stable')
- expect(get('/gitlab/gitlabhq/refs/feature%2345/logs_tree')).to route_to('projects/refs#logs_tree', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature#45')
- expect(get('/gitlab/gitlabhq/refs/feature%2B45/logs_tree')).to route_to('projects/refs#logs_tree', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature+45')
- expect(get('/gitlab/gitlabhq/refs/feature@45/logs_tree')).to route_to('projects/refs#logs_tree', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature@45')
- expect(get('/gitlab/gitlabhq/refs/stable/logs_tree/foo/bar/baz')).to route_to('projects/refs#logs_tree', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'stable', path: 'foo/bar/baz')
- expect(get('/gitlab/gitlabhq/refs/feature%2345/logs_tree/foo/bar/baz')).to route_to('projects/refs#logs_tree', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature#45', path: 'foo/bar/baz')
- expect(get('/gitlab/gitlabhq/refs/feature%2B45/logs_tree/foo/bar/baz')).to route_to('projects/refs#logs_tree', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature+45', path: 'foo/bar/baz')
- expect(get('/gitlab/gitlabhq/refs/feature@45/logs_tree/foo/bar/baz')).to route_to('projects/refs#logs_tree', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature@45', path: 'foo/bar/baz')
- expect(get('/gitlab/gitlabhq/refs/stable/logs_tree/files.scss')).to route_to('projects/refs#logs_tree', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'stable', path: 'files.scss')
- end
-end
-
-# diffs_namespace_project_merge_request GET /:namespace_id/:project_id/merge_requests/:id/diffs(.:format) projects/merge_requests#diffs
-# commits_namespace_project_merge_request GET /:namespace_id/:project_id/merge_requests/:id/commits(.:format) projects/merge_requests#commits
-# merge_namespace_project_merge_request POST /:namespace_id/:project_id/merge_requests/:id/merge(.:format) projects/merge_requests#merge
-# merge_check_namespace_project_merge_request GET /:namespace_id/:project_id/merge_requests/:id/merge_check(.:format) projects/merge_requests#merge_check
-# ci_status_namespace_project_merge_request GET /:namespace_id/:project_id/merge_requests/:id/ci_status(.:format) projects/merge_requests#ci_status
-# toggle_subscription_namespace_project_merge_request POST /:namespace_id/:project_id/merge_requests/:id/toggle_subscription(.:format) projects/merge_requests#toggle_subscription
-# branch_from_namespace_project_merge_requests GET /:namespace_id/:project_id/merge_requests/branch_from(.:format) projects/merge_requests#branch_from
-# branch_to_namespace_project_merge_requests GET /:namespace_id/:project_id/merge_requests/branch_to(.:format) projects/merge_requests#branch_to
-# update_branches_namespace_project_merge_requests GET /:namespace_id/:project_id/merge_requests/update_branches(.:format) projects/merge_requests#update_branches
-# namespace_project_merge_requests GET /:namespace_id/:project_id/merge_requests(.:format) projects/merge_requests#index
-# POST /:namespace_id/:project_id/merge_requests(.:format) projects/merge_requests#create
-# new_namespace_project_merge_request GET /:namespace_id/:project_id/merge_requests/new(.:format) projects/merge_requests#new
-# edit_namespace_project_merge_request GET /:namespace_id/:project_id/merge_requests/:id/edit(.:format) projects/merge_requests#edit
-# namespace_project_merge_request GET /:namespace_id/:project_id/merge_requests/:id(.:format) projects/merge_requests#show
-# PATCH /:namespace_id/:project_id/merge_requests/:id(.:format) projects/merge_requests#update
-# PUT /:namespace_id/:project_id/merge_requests/:id(.:format) projects/merge_requests#update
-describe Projects::MergeRequestsController, 'routing' do
- it 'to #diffs' do
- expect(get('/gitlab/gitlabhq/merge_requests/1/diffs')).to route_to('projects/merge_requests#diffs', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1')
- end
-
- it 'to #commits' do
- expect(get('/gitlab/gitlabhq/merge_requests/1/commits')).to route_to('projects/merge_requests#commits', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1')
- end
-
- it 'to #merge' do
- expect(post('/gitlab/gitlabhq/merge_requests/1/merge')).to route_to(
- 'projects/merge_requests#merge',
- namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1'
- )
- end
-
- it 'to #merge_check' do
- expect(get('/gitlab/gitlabhq/merge_requests/1/merge_check')).to route_to('projects/merge_requests#merge_check', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1')
- end
-
- it 'to #branch_from' do
- expect(get('/gitlab/gitlabhq/merge_requests/branch_from')).to route_to('projects/merge_requests#branch_from', namespace_id: 'gitlab', project_id: 'gitlabhq')
- end
-
- it 'to #branch_to' do
- expect(get('/gitlab/gitlabhq/merge_requests/branch_to')).to route_to('projects/merge_requests#branch_to', namespace_id: 'gitlab', project_id: 'gitlabhq')
- end
-
- it 'to #show' do
- expect(get('/gitlab/gitlabhq/merge_requests/1.diff')).to route_to('projects/merge_requests#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1', format: 'diff')
- expect(get('/gitlab/gitlabhq/merge_requests/1.patch')).to route_to('projects/merge_requests#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1', format: 'patch')
- end
-
- it_behaves_like 'RESTful project resources' do
- let(:controller) { 'merge_requests' }
- let(:actions) { [:index, :create, :new, :edit, :show, :update] }
- end
-end
-
-# raw_project_snippet GET /:project_id/snippets/:id/raw(.:format) snippets#raw
-# project_snippets GET /:project_id/snippets(.:format) snippets#index
-# POST /:project_id/snippets(.:format) snippets#create
-# new_project_snippet GET /:project_id/snippets/new(.:format) snippets#new
-# edit_project_snippet GET /:project_id/snippets/:id/edit(.:format) snippets#edit
-# project_snippet GET /:project_id/snippets/:id(.:format) snippets#show
-# PUT /:project_id/snippets/:id(.:format) snippets#update
-# DELETE /:project_id/snippets/:id(.:format) snippets#destroy
-describe SnippetsController, 'routing' do
- it 'to #raw' do
- expect(get('/gitlab/gitlabhq/snippets/1/raw')).to route_to('projects/snippets#raw', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1')
- end
-
- it 'to #index' do
- expect(get('/gitlab/gitlabhq/snippets')).to route_to('projects/snippets#index', namespace_id: 'gitlab', project_id: 'gitlabhq')
- end
-
- it 'to #create' do
- expect(post('/gitlab/gitlabhq/snippets')).to route_to('projects/snippets#create', namespace_id: 'gitlab', project_id: 'gitlabhq')
- end
-
- it 'to #new' do
- expect(get('/gitlab/gitlabhq/snippets/new')).to route_to('projects/snippets#new', namespace_id: 'gitlab', project_id: 'gitlabhq')
- end
-
- it 'to #edit' do
- expect(get('/gitlab/gitlabhq/snippets/1/edit')).to route_to('projects/snippets#edit', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1')
- end
-
- it 'to #show' do
- expect(get('/gitlab/gitlabhq/snippets/1')).to route_to('projects/snippets#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1')
- end
-
- it 'to #update' do
- expect(put('/gitlab/gitlabhq/snippets/1')).to route_to('projects/snippets#update', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1')
- end
-
- it 'to #destroy' do
- expect(delete('/gitlab/gitlabhq/snippets/1')).to route_to('projects/snippets#destroy', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1')
- end
-end
-
-# test_project_hook GET /:project_id/hooks/:id/test(.:format) hooks#test
-# project_hooks GET /:project_id/hooks(.:format) hooks#index
-# POST /:project_id/hooks(.:format) hooks#create
-# project_hook DELETE /:project_id/hooks/:id(.:format) hooks#destroy
-describe Projects::HooksController, 'routing' do
- it 'to #test' do
- expect(get('/gitlab/gitlabhq/hooks/1/test')).to route_to('projects/hooks#test', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1')
- end
-
- it_behaves_like 'RESTful project resources' do
- let(:actions) { [:index, :create, :destroy] }
- let(:controller) { 'hooks' }
- end
-end
-
-# project_commit GET /:project_id/commit/:id(.:format) commit#show {id: /\h{7,40}/, project_id: /[^\/]+/}
-describe Projects::CommitController, 'routing' do
- it 'to #show' do
- expect(get('/gitlab/gitlabhq/commit/4246fbd')).to route_to('projects/commit#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '4246fbd')
- expect(get('/gitlab/gitlabhq/commit/4246fbd.diff')).to route_to('projects/commit#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '4246fbd', format: 'diff')
- expect(get('/gitlab/gitlabhq/commit/4246fbd.patch')).to route_to('projects/commit#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '4246fbd', format: 'patch')
- expect(get('/gitlab/gitlabhq/commit/4246fbd13872934f72a8fd0d6fb1317b47b59cb5')).to route_to('projects/commit#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '4246fbd13872934f72a8fd0d6fb1317b47b59cb5')
- end
-end
-
-# patch_project_commit GET /:project_id/commits/:id/patch(.:format) commits#patch
-# project_commits GET /:project_id/commits(.:format) commits#index
-# POST /:project_id/commits(.:format) commits#create
-# project_commit GET /:project_id/commits/:id(.:format) commits#show
-describe Projects::CommitsController, 'routing' do
- it_behaves_like 'RESTful project resources' do
- let(:actions) { [:show] }
- let(:controller) { 'commits' }
- end
-
- it 'to #show' do
- expect(get('/gitlab/gitlabhq/commits/master.atom')).to route_to('projects/commits#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master.atom')
- end
-end
-
-# project_project_members GET /:project_id/project_members(.:format) project_members#index
-# POST /:project_id/project_members(.:format) project_members#create
-# PUT /:project_id/project_members/:id(.:format) project_members#update
-# DELETE /:project_id/project_members/:id(.:format) project_members#destroy
-describe Projects::ProjectMembersController, 'routing' do
- it_behaves_like 'RESTful project resources' do
- let(:actions) { [:index, :create, :update, :destroy] }
- let(:controller) { 'project_members' }
- end
-end
-
-# project_milestones GET /:project_id/milestones(.:format) milestones#index
-# POST /:project_id/milestones(.:format) milestones#create
-# new_project_milestone GET /:project_id/milestones/new(.:format) milestones#new
-# edit_project_milestone GET /:project_id/milestones/:id/edit(.:format) milestones#edit
-# project_milestone GET /:project_id/milestones/:id(.:format) milestones#show
-# PUT /:project_id/milestones/:id(.:format) milestones#update
-# DELETE /:project_id/milestones/:id(.:format) milestones#destroy
-describe Projects::MilestonesController, 'routing' do
- it_behaves_like 'RESTful project resources' do
- let(:controller) { 'milestones' }
- let(:actions) { [:index, :create, :new, :edit, :show, :update] }
- end
-end
-
-# project_labels GET /:project_id/labels(.:format) labels#index
-describe Projects::LabelsController, 'routing' do
- it 'to #index' do
- expect(get('/gitlab/gitlabhq/labels')).to route_to('projects/labels#index', namespace_id: 'gitlab', project_id: 'gitlabhq')
- end
-end
-
-# sort_project_issues POST /:project_id/issues/sort(.:format) issues#sort
-# bulk_update_project_issues POST /:project_id/issues/bulk_update(.:format) issues#bulk_update
-# search_project_issues GET /:project_id/issues/search(.:format) issues#search
-# project_issues GET /:project_id/issues(.:format) issues#index
-# POST /:project_id/issues(.:format) issues#create
-# new_project_issue GET /:project_id/issues/new(.:format) issues#new
-# edit_project_issue GET /:project_id/issues/:id/edit(.:format) issues#edit
-# project_issue GET /:project_id/issues/:id(.:format) issues#show
-# PUT /:project_id/issues/:id(.:format) issues#update
-# DELETE /:project_id/issues/:id(.:format) issues#destroy
-describe Projects::IssuesController, 'routing' do
- it 'to #bulk_update' do
- expect(post('/gitlab/gitlabhq/issues/bulk_update')).to route_to('projects/issues#bulk_update', namespace_id: 'gitlab', project_id: 'gitlabhq')
- end
-
- it_behaves_like 'RESTful project resources' do
- let(:controller) { 'issues' }
- let(:actions) { [:index, :create, :new, :edit, :show, :update] }
- end
-end
-
-# project_notes GET /:project_id/notes(.:format) notes#index
-# POST /:project_id/notes(.:format) notes#create
-# project_note DELETE /:project_id/notes/:id(.:format) notes#destroy
-describe Projects::NotesController, 'routing' do
- it_behaves_like 'RESTful project resources' do
- let(:actions) { [:index, :create, :destroy] }
- let(:controller) { 'notes' }
- end
-end
-
-# project_blame GET /:project_id/blame/:id(.:format) blame#show {id: /.+/, project_id: /[^\/]+/}
-describe Projects::BlameController, 'routing' do
- it 'to #show' do
- expect(get('/gitlab/gitlabhq/blame/master/app/models/project.rb')).to route_to('projects/blame#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master/app/models/project.rb')
- expect(get('/gitlab/gitlabhq/blame/master/files.scss')).to route_to('projects/blame#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master/files.scss')
- end
-end
-
-# project_blob GET /:project_id/blob/:id(.:format) blob#show {id: /.+/, project_id: /[^\/]+/}
-describe Projects::BlobController, 'routing' do
- it 'to #show' do
- expect(get('/gitlab/gitlabhq/blob/master/app/models/project.rb')).to route_to('projects/blob#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master/app/models/project.rb')
- expect(get('/gitlab/gitlabhq/blob/master/app/models/compare.rb')).to route_to('projects/blob#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master/app/models/compare.rb')
- expect(get('/gitlab/gitlabhq/blob/master/app/models/diff.js')).to route_to('projects/blob#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master/app/models/diff.js')
- expect(get('/gitlab/gitlabhq/blob/master/files.scss')).to route_to('projects/blob#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master/files.scss')
- end
-end
-
-# project_tree GET /:project_id/tree/:id(.:format) tree#show {id: /.+/, project_id: /[^\/]+/}
-describe Projects::TreeController, 'routing' do
- it 'to #show' do
- expect(get('/gitlab/gitlabhq/tree/master/app/models/project.rb')).to route_to('projects/tree#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master/app/models/project.rb')
- expect(get('/gitlab/gitlabhq/tree/master/files.scss')).to route_to('projects/tree#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master/files.scss')
- end
-end
-
-# project_find_file GET /:namespace_id/:project_id/find_file/*id(.:format) projects/find_file#show {:id=>/.+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?<!\.atom)/, :format=>/html/}
-# project_files GET /:namespace_id/:project_id/files/*id(.:format) projects/find_file#list {:id=>/(?:[^.]|\.(?!json$))+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?<!\.atom)/, :format=>/json/}
-describe Projects::FindFileController, 'routing' do
- it 'to #show' do
- expect(get('/gitlab/gitlabhq/find_file/master')).to route_to('projects/find_file#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master')
- end
-
- it 'to #list' do
- expect(get('/gitlab/gitlabhq/files/master.json')).to route_to('projects/find_file#list', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master', format: 'json')
- end
-end
-
-describe Projects::BlobController, 'routing' do
- it 'to #edit' do
- expect(get('/gitlab/gitlabhq/edit/master/app/models/project.rb')).to(
- route_to('projects/blob#edit',
- namespace_id: 'gitlab', project_id: 'gitlabhq',
- id: 'master/app/models/project.rb'))
- end
-
- it 'to #preview' do
- expect(post('/gitlab/gitlabhq/preview/master/app/models/project.rb')).to(
- route_to('projects/blob#preview',
- namespace_id: 'gitlab', project_id: 'gitlabhq',
- id: 'master/app/models/project.rb'))
- end
-end
-
-# project_compare_index GET /:project_id/compare(.:format) compare#index {id: /[^\/]+/, project_id: /[^\/]+/}
-# POST /:project_id/compare(.:format) compare#create {id: /[^\/]+/, project_id: /[^\/]+/}
-# project_compare /:project_id/compare/:from...:to(.:format) compare#show {from: /.+/, to: /.+/, id: /[^\/]+/, project_id: /[^\/]+/}
-describe Projects::CompareController, 'routing' do
- it 'to #index' do
- expect(get('/gitlab/gitlabhq/compare')).to route_to('projects/compare#index', namespace_id: 'gitlab', project_id: 'gitlabhq')
- end
-
- it 'to #compare' do
- expect(post('/gitlab/gitlabhq/compare')).to route_to('projects/compare#create', namespace_id: 'gitlab', project_id: 'gitlabhq')
- end
-
- it 'to #show' do
- expect(get('/gitlab/gitlabhq/compare/master...stable')).to route_to('projects/compare#show', namespace_id: 'gitlab', project_id: 'gitlabhq', from: 'master', to: 'stable')
- expect(get('/gitlab/gitlabhq/compare/issue/1234...stable')).to route_to('projects/compare#show', namespace_id: 'gitlab', project_id: 'gitlabhq', from: 'issue/1234', to: 'stable')
- end
-end
-
-describe Projects::NetworkController, 'routing' do
- it 'to #show' do
- expect(get('/gitlab/gitlabhq/network/master')).to route_to('projects/network#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master')
- expect(get('/gitlab/gitlabhq/network/ends-with.json')).to route_to('projects/network#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'ends-with.json')
- expect(get('/gitlab/gitlabhq/network/master?format=json')).to route_to('projects/network#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master', format: 'json')
- end
-end
-
-describe Projects::GraphsController, 'routing' do
- it 'to #show' do
- expect(get('/gitlab/gitlabhq/graphs/master')).to route_to('projects/graphs#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master')
- expect(get('/gitlab/gitlabhq/graphs/ends-with.json')).to route_to('projects/graphs#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'ends-with.json')
- expect(get('/gitlab/gitlabhq/graphs/master?format=json')).to route_to('projects/graphs#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master', format: 'json')
- end
-end
-
-describe Projects::ForksController, 'routing' do
- it 'to #new' do
- expect(get('/gitlab/gitlabhq/forks/new')).to route_to('projects/forks#new', namespace_id: 'gitlab', project_id: 'gitlabhq')
- end
-
- it 'to #create' do
- expect(post('/gitlab/gitlabhq/forks')).to route_to('projects/forks#create', namespace_id: 'gitlab', project_id: 'gitlabhq')
- end
-end
-
-# project_avatar DELETE /project/avatar(.:format) projects/avatars#destroy
-describe Projects::AvatarsController, 'routing' do
- it 'to #destroy' do
- expect(delete('/gitlab/gitlabhq/avatar')).to route_to(
- 'projects/avatars#destroy', namespace_id: 'gitlab', project_id: 'gitlabhq')
+describe 'project routing' do
+ before do
+ allow(Project).to receive(:find_with_namespace).and_return(false)
+ allow(Project).to receive(:find_with_namespace).with('gitlab/gitlabhq').and_return(true)
+ end
+
+ # Shared examples for a resource inside a Project
+ #
+ # By default it tests all the default REST actions: index, create, new, edit,
+ # show, update, and destroy. You can remove actions by customizing the
+ # `actions` variable.
+ #
+ # It also expects a `controller` variable to be available which defines both
+ # the path to the resource as well as the controller name.
+ #
+ # Examples
+ #
+ # # Default behavior
+ # it_behaves_like 'RESTful project resources' do
+ # let(:controller) { 'issues' }
+ # end
+ #
+ # # Customizing actions
+ # it_behaves_like 'RESTful project resources' do
+ # let(:actions) { [:index] }
+ # let(:controller) { 'issues' }
+ # end
+ shared_examples 'RESTful project resources' do
+ let(:actions) { [:index, :create, :new, :edit, :show, :update, :destroy] }
+
+ it 'to #index' do
+ expect(get("/gitlab/gitlabhq/#{controller}")).to route_to("projects/#{controller}#index", namespace_id: 'gitlab', project_id: 'gitlabhq') if actions.include?(:index)
+ end
+
+ it 'to #create' do
+ expect(post("/gitlab/gitlabhq/#{controller}")).to route_to("projects/#{controller}#create", namespace_id: 'gitlab', project_id: 'gitlabhq') if actions.include?(:create)
+ end
+
+ it 'to #new' do
+ expect(get("/gitlab/gitlabhq/#{controller}/new")).to route_to("projects/#{controller}#new", namespace_id: 'gitlab', project_id: 'gitlabhq') if actions.include?(:new)
+ end
+
+ it 'to #edit' do
+ expect(get("/gitlab/gitlabhq/#{controller}/1/edit")).to route_to("projects/#{controller}#edit", namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1') if actions.include?(:edit)
+ end
+
+ it 'to #show' do
+ expect(get("/gitlab/gitlabhq/#{controller}/1")).to route_to("projects/#{controller}#show", namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1') if actions.include?(:show)
+ end
+
+ it 'to #update' do
+ expect(put("/gitlab/gitlabhq/#{controller}/1")).to route_to("projects/#{controller}#update", namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1') if actions.include?(:update)
+ end
+
+ it 'to #destroy' do
+ expect(delete("/gitlab/gitlabhq/#{controller}/1")).to route_to("projects/#{controller}#destroy", namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1') if actions.include?(:destroy)
+ end
+ end
+
+ # projects POST /projects(.:format) projects#create
+ # new_project GET /projects/new(.:format) projects#new
+ # files_project GET /:id/files(.:format) projects#files
+ # edit_project GET /:id/edit(.:format) projects#edit
+ # project GET /:id(.:format) projects#show
+ # PUT /:id(.:format) projects#update
+ # DELETE /:id(.:format) projects#destroy
+ # preview_markdown_project POST /:id/preview_markdown(.:format) projects#preview_markdown
+ describe ProjectsController, 'routing' do
+ it 'to #create' do
+ expect(post('/projects')).to route_to('projects#create')
+ end
+
+ it 'to #new' do
+ expect(get('/projects/new')).to route_to('projects#new')
+ end
+
+ it 'to #edit' do
+ expect(get('/gitlab/gitlabhq/edit')).to route_to('projects#edit', namespace_id: 'gitlab', id: 'gitlabhq')
+ end
+
+ it 'to #autocomplete_sources' do
+ expect(get('/gitlab/gitlabhq/autocomplete_sources')).to route_to('projects#autocomplete_sources', namespace_id: 'gitlab', id: 'gitlabhq')
+ end
+
+ describe 'to #show' do
+ context 'regular name' do
+ it { expect(get('/gitlab/gitlabhq')).to route_to('projects#show', namespace_id: 'gitlab', id: 'gitlabhq') }
+ end
+
+ context 'name with dot' do
+ before { allow(Project).to receive(:find_with_namespace).with('gitlab/gitlabhq.keys').and_return(true) }
+
+ it { expect(get('/gitlab/gitlabhq.keys')).to route_to('projects#show', namespace_id: 'gitlab', id: 'gitlabhq.keys') }
+ end
+
+ context 'with nested group' do
+ before { allow(Project).to receive(:find_with_namespace).with('gitlab/subgroup/gitlabhq').and_return(true) }
+
+ it { expect(get('/gitlab/subgroup/gitlabhq')).to route_to('projects#show', namespace_id: 'gitlab/subgroup', id: 'gitlabhq') }
+ end
+ end
+
+ it 'to #update' do
+ expect(put('/gitlab/gitlabhq')).to route_to('projects#update', namespace_id: 'gitlab', id: 'gitlabhq')
+ end
+
+ it 'to #destroy' do
+ expect(delete('/gitlab/gitlabhq')).to route_to('projects#destroy', namespace_id: 'gitlab', id: 'gitlabhq')
+ end
+
+ it 'to #preview_markdown' do
+ expect(post('/gitlab/gitlabhq/preview_markdown')).to(
+ route_to('projects#preview_markdown', namespace_id: 'gitlab', id: 'gitlabhq')
+ )
+ end
+ end
+
+ # pages_project_wikis GET /:project_id/wikis/pages(.:format) projects/wikis#pages
+ # history_project_wiki GET /:project_id/wikis/:id/history(.:format) projects/wikis#history
+ # project_wikis POST /:project_id/wikis(.:format) projects/wikis#create
+ # edit_project_wiki GET /:project_id/wikis/:id/edit(.:format) projects/wikis#edit
+ # project_wiki GET /:project_id/wikis/:id(.:format) projects/wikis#show
+ # DELETE /:project_id/wikis/:id(.:format) projects/wikis#destroy
+ describe Projects::WikisController, 'routing' do
+ it 'to #pages' do
+ expect(get('/gitlab/gitlabhq/wikis/pages')).to route_to('projects/wikis#pages', namespace_id: 'gitlab', project_id: 'gitlabhq')
+ end
+
+ it 'to #history' do
+ expect(get('/gitlab/gitlabhq/wikis/1/history')).to route_to('projects/wikis#history', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1')
+ end
+
+ it_behaves_like 'RESTful project resources' do
+ let(:actions) { [:create, :edit, :show, :destroy] }
+ let(:controller) { 'wikis' }
+ end
+ end
+
+ # branches_project_repository GET /:project_id/repository/branches(.:format) projects/repositories#branches
+ # tags_project_repository GET /:project_id/repository/tags(.:format) projects/repositories#tags
+ # archive_project_repository GET /:project_id/repository/archive(.:format) projects/repositories#archive
+ # edit_project_repository GET /:project_id/repository/edit(.:format) projects/repositories#edit
+ describe Projects::RepositoriesController, 'routing' do
+ it 'to #archive' do
+ expect(get('/gitlab/gitlabhq/repository/archive')).to route_to('projects/repositories#archive', namespace_id: 'gitlab', project_id: 'gitlabhq')
+ end
+
+ it 'to #archive format:zip' do
+ expect(get('/gitlab/gitlabhq/repository/archive.zip')).to route_to('projects/repositories#archive', namespace_id: 'gitlab', project_id: 'gitlabhq', format: 'zip')
+ end
+
+ it 'to #archive format:tar.bz2' do
+ expect(get('/gitlab/gitlabhq/repository/archive.tar.bz2')).to route_to('projects/repositories#archive', namespace_id: 'gitlab', project_id: 'gitlabhq', format: 'tar.bz2')
+ end
+ end
+
+ describe Projects::BranchesController, 'routing' do
+ it 'to #branches' do
+ expect(get('/gitlab/gitlabhq/branches')).to route_to('projects/branches#index', namespace_id: 'gitlab', project_id: 'gitlabhq')
+ expect(delete('/gitlab/gitlabhq/branches/feature%2345')).to route_to('projects/branches#destroy', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature#45')
+ expect(delete('/gitlab/gitlabhq/branches/feature%2B45')).to route_to('projects/branches#destroy', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature+45')
+ expect(delete('/gitlab/gitlabhq/branches/feature@45')).to route_to('projects/branches#destroy', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature@45')
+ expect(delete('/gitlab/gitlabhq/branches/feature%2345/foo/bar/baz')).to route_to('projects/branches#destroy', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature#45/foo/bar/baz')
+ expect(delete('/gitlab/gitlabhq/branches/feature%2B45/foo/bar/baz')).to route_to('projects/branches#destroy', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature+45/foo/bar/baz')
+ expect(delete('/gitlab/gitlabhq/branches/feature@45/foo/bar/baz')).to route_to('projects/branches#destroy', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature@45/foo/bar/baz')
+ end
+ end
+
+ describe Projects::TagsController, 'routing' do
+ it 'to #tags' do
+ expect(get('/gitlab/gitlabhq/tags')).to route_to('projects/tags#index', namespace_id: 'gitlab', project_id: 'gitlabhq')
+ expect(delete('/gitlab/gitlabhq/tags/feature%2345')).to route_to('projects/tags#destroy', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature#45')
+ expect(delete('/gitlab/gitlabhq/tags/feature%2B45')).to route_to('projects/tags#destroy', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature+45')
+ expect(delete('/gitlab/gitlabhq/tags/feature@45')).to route_to('projects/tags#destroy', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature@45')
+ expect(delete('/gitlab/gitlabhq/tags/feature%2345/foo/bar/baz')).to route_to('projects/tags#destroy', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature#45/foo/bar/baz')
+ expect(delete('/gitlab/gitlabhq/tags/feature%2B45/foo/bar/baz')).to route_to('projects/tags#destroy', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature+45/foo/bar/baz')
+ expect(delete('/gitlab/gitlabhq/tags/feature@45/foo/bar/baz')).to route_to('projects/tags#destroy', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature@45/foo/bar/baz')
+ end
+ end
+
+ # project_deploy_keys GET /:project_id/deploy_keys(.:format) deploy_keys#index
+ # POST /:project_id/deploy_keys(.:format) deploy_keys#create
+ # new_project_deploy_key GET /:project_id/deploy_keys/new(.:format) deploy_keys#new
+ # project_deploy_key GET /:project_id/deploy_keys/:id(.:format) deploy_keys#show
+ # DELETE /:project_id/deploy_keys/:id(.:format) deploy_keys#destroy
+ describe Projects::DeployKeysController, 'routing' do
+ it_behaves_like 'RESTful project resources' do
+ let(:actions) { [:index, :new, :create] }
+ let(:controller) { 'deploy_keys' }
+ end
+ end
+
+ # project_protected_branches GET /:project_id/protected_branches(.:format) protected_branches#index
+ # POST /:project_id/protected_branches(.:format) protected_branches#create
+ # project_protected_branch DELETE /:project_id/protected_branches/:id(.:format) protected_branches#destroy
+ describe Projects::ProtectedBranchesController, 'routing' do
+ it_behaves_like 'RESTful project resources' do
+ let(:actions) { [:index, :create, :destroy] }
+ let(:controller) { 'protected_branches' }
+ end
+ end
+
+ # switch_project_refs GET /:project_id/refs/switch(.:format) refs#switch
+ # logs_tree_project_ref GET /:project_id/refs/:id/logs_tree(.:format) refs#logs_tree
+ # logs_file_project_ref GET /:project_id/refs/:id/logs_tree/:path(.:format) refs#logs_tree
+ describe Projects::RefsController, 'routing' do
+ it 'to #switch' do
+ expect(get('/gitlab/gitlabhq/refs/switch')).to route_to('projects/refs#switch', namespace_id: 'gitlab', project_id: 'gitlabhq')
+ end
+
+ it 'to #logs_tree' do
+ expect(get('/gitlab/gitlabhq/refs/stable/logs_tree')).to route_to('projects/refs#logs_tree', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'stable')
+ expect(get('/gitlab/gitlabhq/refs/feature%2345/logs_tree')).to route_to('projects/refs#logs_tree', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature#45')
+ expect(get('/gitlab/gitlabhq/refs/feature%2B45/logs_tree')).to route_to('projects/refs#logs_tree', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature+45')
+ expect(get('/gitlab/gitlabhq/refs/feature@45/logs_tree')).to route_to('projects/refs#logs_tree', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature@45')
+ expect(get('/gitlab/gitlabhq/refs/stable/logs_tree/foo/bar/baz')).to route_to('projects/refs#logs_tree', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'stable', path: 'foo/bar/baz')
+ expect(get('/gitlab/gitlabhq/refs/feature%2345/logs_tree/foo/bar/baz')).to route_to('projects/refs#logs_tree', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature#45', path: 'foo/bar/baz')
+ expect(get('/gitlab/gitlabhq/refs/feature%2B45/logs_tree/foo/bar/baz')).to route_to('projects/refs#logs_tree', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature+45', path: 'foo/bar/baz')
+ expect(get('/gitlab/gitlabhq/refs/feature@45/logs_tree/foo/bar/baz')).to route_to('projects/refs#logs_tree', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature@45', path: 'foo/bar/baz')
+ expect(get('/gitlab/gitlabhq/refs/stable/logs_tree/files.scss')).to route_to('projects/refs#logs_tree', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'stable', path: 'files.scss')
+ end
+ end
+
+ # diffs_namespace_project_merge_request GET /:namespace_id/:project_id/merge_requests/:id/diffs(.:format) projects/merge_requests#diffs
+ # commits_namespace_project_merge_request GET /:namespace_id/:project_id/merge_requests/:id/commits(.:format) projects/merge_requests#commits
+ # merge_namespace_project_merge_request POST /:namespace_id/:project_id/merge_requests/:id/merge(.:format) projects/merge_requests#merge
+ # merge_check_namespace_project_merge_request GET /:namespace_id/:project_id/merge_requests/:id/merge_check(.:format) projects/merge_requests#merge_check
+ # ci_status_namespace_project_merge_request GET /:namespace_id/:project_id/merge_requests/:id/ci_status(.:format) projects/merge_requests#ci_status
+ # toggle_subscription_namespace_project_merge_request POST /:namespace_id/:project_id/merge_requests/:id/toggle_subscription(.:format) projects/merge_requests#toggle_subscription
+ # branch_from_namespace_project_merge_requests GET /:namespace_id/:project_id/merge_requests/branch_from(.:format) projects/merge_requests#branch_from
+ # branch_to_namespace_project_merge_requests GET /:namespace_id/:project_id/merge_requests/branch_to(.:format) projects/merge_requests#branch_to
+ # update_branches_namespace_project_merge_requests GET /:namespace_id/:project_id/merge_requests/update_branches(.:format) projects/merge_requests#update_branches
+ # namespace_project_merge_requests GET /:namespace_id/:project_id/merge_requests(.:format) projects/merge_requests#index
+ # POST /:namespace_id/:project_id/merge_requests(.:format) projects/merge_requests#create
+ # new_namespace_project_merge_request GET /:namespace_id/:project_id/merge_requests/new(.:format) projects/merge_requests#new
+ # edit_namespace_project_merge_request GET /:namespace_id/:project_id/merge_requests/:id/edit(.:format) projects/merge_requests#edit
+ # namespace_project_merge_request GET /:namespace_id/:project_id/merge_requests/:id(.:format) projects/merge_requests#show
+ # PATCH /:namespace_id/:project_id/merge_requests/:id(.:format) projects/merge_requests#update
+ # PUT /:namespace_id/:project_id/merge_requests/:id(.:format) projects/merge_requests#update
+ describe Projects::MergeRequestsController, 'routing' do
+ it 'to #diffs' do
+ expect(get('/gitlab/gitlabhq/merge_requests/1/diffs')).to route_to('projects/merge_requests#diffs', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1')
+ end
+
+ it 'to #commits' do
+ expect(get('/gitlab/gitlabhq/merge_requests/1/commits')).to route_to('projects/merge_requests#commits', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1')
+ end
+
+ it 'to #merge' do
+ expect(post('/gitlab/gitlabhq/merge_requests/1/merge')).to route_to(
+ 'projects/merge_requests#merge',
+ namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1'
+ )
+ end
+
+ it 'to #merge_check' do
+ expect(get('/gitlab/gitlabhq/merge_requests/1/merge_check')).to route_to('projects/merge_requests#merge_check', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1')
+ end
+
+ it 'to #branch_from' do
+ expect(get('/gitlab/gitlabhq/merge_requests/branch_from')).to route_to('projects/merge_requests#branch_from', namespace_id: 'gitlab', project_id: 'gitlabhq')
+ end
+
+ it 'to #branch_to' do
+ expect(get('/gitlab/gitlabhq/merge_requests/branch_to')).to route_to('projects/merge_requests#branch_to', namespace_id: 'gitlab', project_id: 'gitlabhq')
+ end
+
+ it 'to #show' do
+ expect(get('/gitlab/gitlabhq/merge_requests/1.diff')).to route_to('projects/merge_requests#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1', format: 'diff')
+ expect(get('/gitlab/gitlabhq/merge_requests/1.patch')).to route_to('projects/merge_requests#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1', format: 'patch')
+ end
+
+ it_behaves_like 'RESTful project resources' do
+ let(:controller) { 'merge_requests' }
+ let(:actions) { [:index, :create, :new, :edit, :show, :update] }
+ end
+ end
+
+ # raw_project_snippet GET /:project_id/snippets/:id/raw(.:format) snippets#raw
+ # project_snippets GET /:project_id/snippets(.:format) snippets#index
+ # POST /:project_id/snippets(.:format) snippets#create
+ # new_project_snippet GET /:project_id/snippets/new(.:format) snippets#new
+ # edit_project_snippet GET /:project_id/snippets/:id/edit(.:format) snippets#edit
+ # project_snippet GET /:project_id/snippets/:id(.:format) snippets#show
+ # PUT /:project_id/snippets/:id(.:format) snippets#update
+ # DELETE /:project_id/snippets/:id(.:format) snippets#destroy
+ describe SnippetsController, 'routing' do
+ it 'to #raw' do
+ expect(get('/gitlab/gitlabhq/snippets/1/raw')).to route_to('projects/snippets#raw', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1')
+ end
+
+ it 'to #index' do
+ expect(get('/gitlab/gitlabhq/snippets')).to route_to('projects/snippets#index', namespace_id: 'gitlab', project_id: 'gitlabhq')
+ end
+
+ it 'to #create' do
+ expect(post('/gitlab/gitlabhq/snippets')).to route_to('projects/snippets#create', namespace_id: 'gitlab', project_id: 'gitlabhq')
+ end
+
+ it 'to #new' do
+ expect(get('/gitlab/gitlabhq/snippets/new')).to route_to('projects/snippets#new', namespace_id: 'gitlab', project_id: 'gitlabhq')
+ end
+
+ it 'to #edit' do
+ expect(get('/gitlab/gitlabhq/snippets/1/edit')).to route_to('projects/snippets#edit', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1')
+ end
+
+ it 'to #show' do
+ expect(get('/gitlab/gitlabhq/snippets/1')).to route_to('projects/snippets#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1')
+ end
+
+ it 'to #update' do
+ expect(put('/gitlab/gitlabhq/snippets/1')).to route_to('projects/snippets#update', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1')
+ end
+
+ it 'to #destroy' do
+ expect(delete('/gitlab/gitlabhq/snippets/1')).to route_to('projects/snippets#destroy', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1')
+ end
+ end
+
+ # test_project_hook GET /:project_id/hooks/:id/test(.:format) hooks#test
+ # project_hooks GET /:project_id/hooks(.:format) hooks#index
+ # POST /:project_id/hooks(.:format) hooks#create
+ # project_hook DELETE /:project_id/hooks/:id(.:format) hooks#destroy
+ describe Projects::HooksController, 'routing' do
+ it 'to #test' do
+ expect(get('/gitlab/gitlabhq/hooks/1/test')).to route_to('projects/hooks#test', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1')
+ end
+
+ it_behaves_like 'RESTful project resources' do
+ let(:actions) { [:index, :create, :destroy] }
+ let(:controller) { 'hooks' }
+ end
+ end
+
+ # project_commit GET /:project_id/commit/:id(.:format) commit#show {id: /\h{7,40}/, project_id: /[^\/]+/}
+ describe Projects::CommitController, 'routing' do
+ it 'to #show' do
+ expect(get('/gitlab/gitlabhq/commit/4246fbd')).to route_to('projects/commit#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '4246fbd')
+ expect(get('/gitlab/gitlabhq/commit/4246fbd.diff')).to route_to('projects/commit#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '4246fbd', format: 'diff')
+ expect(get('/gitlab/gitlabhq/commit/4246fbd.patch')).to route_to('projects/commit#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '4246fbd', format: 'patch')
+ expect(get('/gitlab/gitlabhq/commit/4246fbd13872934f72a8fd0d6fb1317b47b59cb5')).to route_to('projects/commit#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '4246fbd13872934f72a8fd0d6fb1317b47b59cb5')
+ end
+ end
+
+ # patch_project_commit GET /:project_id/commits/:id/patch(.:format) commits#patch
+ # project_commits GET /:project_id/commits(.:format) commits#index
+ # POST /:project_id/commits(.:format) commits#create
+ # project_commit GET /:project_id/commits/:id(.:format) commits#show
+ describe Projects::CommitsController, 'routing' do
+ it_behaves_like 'RESTful project resources' do
+ let(:actions) { [:show] }
+ let(:controller) { 'commits' }
+ end
+
+ it 'to #show' do
+ expect(get('/gitlab/gitlabhq/commits/master.atom')).to route_to('projects/commits#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master.atom')
+ end
+ end
+
+ # project_project_members GET /:project_id/project_members(.:format) project_members#index
+ # POST /:project_id/project_members(.:format) project_members#create
+ # PUT /:project_id/project_members/:id(.:format) project_members#update
+ # DELETE /:project_id/project_members/:id(.:format) project_members#destroy
+ describe Projects::ProjectMembersController, 'routing' do
+ it_behaves_like 'RESTful project resources' do
+ let(:actions) { [:index, :create, :update, :destroy] }
+ let(:controller) { 'project_members' }
+ end
+ end
+
+ # project_milestones GET /:project_id/milestones(.:format) milestones#index
+ # POST /:project_id/milestones(.:format) milestones#create
+ # new_project_milestone GET /:project_id/milestones/new(.:format) milestones#new
+ # edit_project_milestone GET /:project_id/milestones/:id/edit(.:format) milestones#edit
+ # project_milestone GET /:project_id/milestones/:id(.:format) milestones#show
+ # PUT /:project_id/milestones/:id(.:format) milestones#update
+ # DELETE /:project_id/milestones/:id(.:format) milestones#destroy
+ describe Projects::MilestonesController, 'routing' do
+ it_behaves_like 'RESTful project resources' do
+ let(:controller) { 'milestones' }
+ let(:actions) { [:index, :create, :new, :edit, :show, :update] }
+ end
+ end
+
+ # project_labels GET /:project_id/labels(.:format) labels#index
+ describe Projects::LabelsController, 'routing' do
+ it 'to #index' do
+ expect(get('/gitlab/gitlabhq/labels')).to route_to('projects/labels#index', namespace_id: 'gitlab', project_id: 'gitlabhq')
+ end
+ end
+
+ # sort_project_issues POST /:project_id/issues/sort(.:format) issues#sort
+ # bulk_update_project_issues POST /:project_id/issues/bulk_update(.:format) issues#bulk_update
+ # search_project_issues GET /:project_id/issues/search(.:format) issues#search
+ # project_issues GET /:project_id/issues(.:format) issues#index
+ # POST /:project_id/issues(.:format) issues#create
+ # new_project_issue GET /:project_id/issues/new(.:format) issues#new
+ # edit_project_issue GET /:project_id/issues/:id/edit(.:format) issues#edit
+ # project_issue GET /:project_id/issues/:id(.:format) issues#show
+ # PUT /:project_id/issues/:id(.:format) issues#update
+ # DELETE /:project_id/issues/:id(.:format) issues#destroy
+ describe Projects::IssuesController, 'routing' do
+ it 'to #bulk_update' do
+ expect(post('/gitlab/gitlabhq/issues/bulk_update')).to route_to('projects/issues#bulk_update', namespace_id: 'gitlab', project_id: 'gitlabhq')
+ end
+
+ it_behaves_like 'RESTful project resources' do
+ let(:controller) { 'issues' }
+ let(:actions) { [:index, :create, :new, :edit, :show, :update] }
+ end
+ end
+
+ # project_notes GET /:project_id/notes(.:format) notes#index
+ # POST /:project_id/notes(.:format) notes#create
+ # project_note DELETE /:project_id/notes/:id(.:format) notes#destroy
+ describe Projects::NotesController, 'routing' do
+ it_behaves_like 'RESTful project resources' do
+ let(:actions) { [:index, :create, :destroy] }
+ let(:controller) { 'notes' }
+ end
+ end
+
+ # project_blame GET /:project_id/blame/:id(.:format) blame#show {id: /.+/, project_id: /[^\/]+/}
+ describe Projects::BlameController, 'routing' do
+ it 'to #show' do
+ expect(get('/gitlab/gitlabhq/blame/master/app/models/project.rb')).to route_to('projects/blame#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master/app/models/project.rb')
+ expect(get('/gitlab/gitlabhq/blame/master/files.scss')).to route_to('projects/blame#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master/files.scss')
+ end
+ end
+
+ # project_blob GET /:project_id/blob/:id(.:format) blob#show {id: /.+/, project_id: /[^\/]+/}
+ describe Projects::BlobController, 'routing' do
+ it 'to #show' do
+ expect(get('/gitlab/gitlabhq/blob/master/app/models/project.rb')).to route_to('projects/blob#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master/app/models/project.rb')
+ expect(get('/gitlab/gitlabhq/blob/master/app/models/compare.rb')).to route_to('projects/blob#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master/app/models/compare.rb')
+ expect(get('/gitlab/gitlabhq/blob/master/app/models/diff.js')).to route_to('projects/blob#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master/app/models/diff.js')
+ expect(get('/gitlab/gitlabhq/blob/master/files.scss')).to route_to('projects/blob#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master/files.scss')
+ end
+ end
+
+ # project_tree GET /:project_id/tree/:id(.:format) tree#show {id: /.+/, project_id: /[^\/]+/}
+ describe Projects::TreeController, 'routing' do
+ it 'to #show' do
+ expect(get('/gitlab/gitlabhq/tree/master/app/models/project.rb')).to route_to('projects/tree#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master/app/models/project.rb')
+ expect(get('/gitlab/gitlabhq/tree/master/files.scss')).to route_to('projects/tree#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master/files.scss')
+ end
+ end
+
+ # project_find_file GET /:namespace_id/:project_id/find_file/*id(.:format) projects/find_file#show {:id=>/.+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?<!\.atom)/, :format=>/html/}
+ # project_files GET /:namespace_id/:project_id/files/*id(.:format) projects/find_file#list {:id=>/(?:[^.]|\.(?!json$))+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?<!\.atom)/, :format=>/json/}
+ describe Projects::FindFileController, 'routing' do
+ it 'to #show' do
+ expect(get('/gitlab/gitlabhq/find_file/master')).to route_to('projects/find_file#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master')
+ end
+
+ it 'to #list' do
+ expect(get('/gitlab/gitlabhq/files/master.json')).to route_to('projects/find_file#list', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master', format: 'json')
+ end
+ end
+
+ describe Projects::BlobController, 'routing' do
+ it 'to #edit' do
+ expect(get('/gitlab/gitlabhq/edit/master/app/models/project.rb')).to(
+ route_to('projects/blob#edit',
+ namespace_id: 'gitlab', project_id: 'gitlabhq',
+ id: 'master/app/models/project.rb'))
+ end
+
+ it 'to #preview' do
+ expect(post('/gitlab/gitlabhq/preview/master/app/models/project.rb')).to(
+ route_to('projects/blob#preview',
+ namespace_id: 'gitlab', project_id: 'gitlabhq',
+ id: 'master/app/models/project.rb'))
+ end
+ end
+
+ # project_compare_index GET /:project_id/compare(.:format) compare#index {id: /[^\/]+/, project_id: /[^\/]+/}
+ # POST /:project_id/compare(.:format) compare#create {id: /[^\/]+/, project_id: /[^\/]+/}
+ # project_compare /:project_id/compare/:from...:to(.:format) compare#show {from: /.+/, to: /.+/, id: /[^\/]+/, project_id: /[^\/]+/}
+ describe Projects::CompareController, 'routing' do
+ it 'to #index' do
+ expect(get('/gitlab/gitlabhq/compare')).to route_to('projects/compare#index', namespace_id: 'gitlab', project_id: 'gitlabhq')
+ end
+
+ it 'to #compare' do
+ expect(post('/gitlab/gitlabhq/compare')).to route_to('projects/compare#create', namespace_id: 'gitlab', project_id: 'gitlabhq')
+ end
+
+ it 'to #show' do
+ expect(get('/gitlab/gitlabhq/compare/master...stable')).to route_to('projects/compare#show', namespace_id: 'gitlab', project_id: 'gitlabhq', from: 'master', to: 'stable')
+ expect(get('/gitlab/gitlabhq/compare/issue/1234...stable')).to route_to('projects/compare#show', namespace_id: 'gitlab', project_id: 'gitlabhq', from: 'issue/1234', to: 'stable')
+ end
+ end
+
+ describe Projects::NetworkController, 'routing' do
+ it 'to #show' do
+ expect(get('/gitlab/gitlabhq/network/master')).to route_to('projects/network#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master')
+ expect(get('/gitlab/gitlabhq/network/ends-with.json')).to route_to('projects/network#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'ends-with.json')
+ expect(get('/gitlab/gitlabhq/network/master?format=json')).to route_to('projects/network#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master', format: 'json')
+ end
+ end
+
+ describe Projects::GraphsController, 'routing' do
+ it 'to #show' do
+ expect(get('/gitlab/gitlabhq/graphs/master')).to route_to('projects/graphs#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master')
+ expect(get('/gitlab/gitlabhq/graphs/ends-with.json')).to route_to('projects/graphs#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'ends-with.json')
+ expect(get('/gitlab/gitlabhq/graphs/master?format=json')).to route_to('projects/graphs#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master', format: 'json')
+ end
+ end
+
+ describe Projects::ForksController, 'routing' do
+ it 'to #new' do
+ expect(get('/gitlab/gitlabhq/forks/new')).to route_to('projects/forks#new', namespace_id: 'gitlab', project_id: 'gitlabhq')
+ end
+
+ it 'to #create' do
+ expect(post('/gitlab/gitlabhq/forks')).to route_to('projects/forks#create', namespace_id: 'gitlab', project_id: 'gitlabhq')
+ end
+ end
+
+ # project_avatar DELETE /project/avatar(.:format) projects/avatars#destroy
+ describe Projects::AvatarsController, 'routing' do
+ it 'to #destroy' do
+ expect(delete('/gitlab/gitlabhq/avatar')).to route_to(
+ 'projects/avatars#destroy', namespace_id: 'gitlab', project_id: 'gitlabhq')
+ end
end
end
diff --git a/spec/routing/routing_spec.rb b/spec/routing/routing_spec.rb
index f15c45cbaac..9f6defe1450 100644
--- a/spec/routing/routing_spec.rb
+++ b/spec/routing/routing_spec.rb
@@ -9,7 +9,7 @@ require 'spec_helper'
# user_calendar_activities GET /u/:username/calendar_activities(.:format)
describe UsersController, "routing" do
it "to #show" do
- allow(User).to receive(:find_by).and_return(true)
+ allow_any_instance_of(UserUrlConstrainer).to receive(:matches?).and_return(true)
expect(get("/User")).to route_to('users#show', username: 'User')
end
@@ -195,6 +195,8 @@ describe Profiles::KeysController, "routing" do
# get all the ssh-keys of a user
it "to #get_keys" do
+ allow_any_instance_of(UserUrlConstrainer).to receive(:matches?).and_return(true)
+
expect(get("/foo.keys")).to route_to('profiles/keys#get_keys', username: 'foo')
end
end
@@ -263,13 +265,17 @@ end
describe "Groups", "routing" do
let(:name) { 'complex.group-namegit' }
+ before { allow_any_instance_of(GroupUrlConstrainer).to receive(:matches?).and_return(true) }
+
it "to #show" do
expect(get("/groups/#{name}")).to route_to('groups#show', id: name)
end
- it "also display group#show on the short path" do
- allow(Group).to receive(:find_by).and_return(true)
+ it "also supports nested groups" do
+ expect(get("/#{name}/#{name}")).to route_to('groups#show', id: "#{name}/#{name}")
+ end
+ it "also display group#show on the short path" do
expect(get("/#{name}")).to route_to('groups#show', id: name)
end
@@ -284,6 +290,10 @@ describe "Groups", "routing" do
it "to #members" do
expect(get("/groups/#{name}/group_members")).to route_to('groups/group_members#index', group_id: name)
end
+
+ it "also display group#show with slash in the path" do
+ expect(get('/group/subgroup')).to route_to('groups#show', id: 'group/subgroup')
+ end
end
describe HealthCheckController, 'routing' do
diff --git a/spec/serializers/analytics_build_entity_spec.rb b/spec/serializers/analytics_build_entity_spec.rb
index 9ac6f20fd3c..c0b7e86b17c 100644
--- a/spec/serializers/analytics_build_entity_spec.rb
+++ b/spec/serializers/analytics_build_entity_spec.rb
@@ -7,7 +7,7 @@ describe AnalyticsBuildEntity do
context 'build with an author' do
let(:user) { create(:user) }
- let(:build) { create(:ci_build, author: user) }
+ let(:build) { create(:ci_build, author: user, started_at: 2.hours.ago, finished_at: 1.hour.ago) }
subject { entity.as_json }
@@ -23,5 +23,13 @@ describe AnalyticsBuildEntity do
expect(subject).not_to include(/token/)
expect(subject).not_to include(/variables/)
end
+
+ it 'contains the right started at' do
+ expect(subject[:date]).to eq('about 2 hours ago')
+ end
+
+ it 'contains the duration' do
+ expect(subject[:total_time]).to eq(hours: 1 )
+ end
end
end
diff --git a/spec/services/notification_service_spec.rb b/spec/services/notification_service_spec.rb
index 8726c9eaa55..08ae61708a5 100644
--- a/spec/services/notification_service_spec.rb
+++ b/spec/services/notification_service_spec.rb
@@ -64,9 +64,9 @@ describe NotificationService, services: true do
before do
build_team(note.project)
- project.team << [issue.author, :master]
- project.team << [issue.assignee, :master]
- project.team << [note.author, :master]
+ project.add_master(issue.author)
+ project.add_master(issue.assignee)
+ project.add_master(note.author)
create(:note_on_issue, noteable: issue, project_id: issue.project_id, note: '@subscribed_participant cc this guy')
update_custom_notification(:new_note, @u_guest_custom, project)
update_custom_notification(:new_note, @u_custom_global)
@@ -168,8 +168,8 @@ describe NotificationService, services: true do
let(:guest_watcher) { create_user_with_notification(:watch, "guest-watcher-confidential") }
it 'filters out users that can not read the issue' do
- project.team << [member, :developer]
- project.team << [guest, :guest]
+ project.add_developer(member)
+ project.add_guest(guest)
expect(SentNotification).to receive(:record).with(confidential_issue, any_args).exactly(4).times
@@ -195,7 +195,7 @@ describe NotificationService, services: true do
before do
build_team(note.project)
- note.project.team << [note.author, :master]
+ note.project.add_master(note.author)
reset_delivered_emails!
end
@@ -237,7 +237,7 @@ describe NotificationService, services: true do
before do
build_team(note.project)
- note.project.team << [note.author, :master]
+ note.project.add_master(note.author)
reset_delivered_emails!
end
@@ -324,8 +324,8 @@ describe NotificationService, services: true do
before do
build_team(note.project)
- project.team << [merge_request.author, :master]
- project.team << [merge_request.assignee, :master]
+ project.add_master(merge_request.author)
+ project.add_master(merge_request.assignee)
end
describe '#new_note' do
@@ -409,8 +409,8 @@ describe NotificationService, services: true do
let(:confidential_issue) { create(:issue, :confidential, project: project, title: 'Confidential issue', author: author, assignee: assignee) }
it "emails subscribers of the issue's labels that can read the issue" do
- project.team << [member, :developer]
- project.team << [guest, :guest]
+ project.add_developer(member)
+ project.add_guest(guest)
label = create(:label, project: project, issues: [confidential_issue])
confidential_issue.reload
@@ -621,8 +621,8 @@ describe NotificationService, services: true do
let!(:label_2) { create(:label, project: project) }
it "emails subscribers of the issue's labels that can read the issue" do
- project.team << [member, :developer]
- project.team << [guest, :guest]
+ project.add_developer(member)
+ project.add_guest(guest)
label_2.toggle_subscription(non_member, project)
label_2.toggle_subscription(author, project)
@@ -1210,7 +1210,7 @@ describe NotificationService, services: true do
let(:member) { create(:user) }
before(:each) do
- project.team << [member, :developer, project.owner]
+ project.add_developer(member, current_user: project.owner)
end
it do
@@ -1233,9 +1233,9 @@ describe NotificationService, services: true do
let(:note) { create(:note, noteable: merge_request, project: private_project) }
before do
- private_project.team << [assignee, :developer]
- private_project.team << [developer, :developer]
- private_project.team << [guest, :guest]
+ private_project.add_developer(assignee)
+ private_project.add_developer(developer)
+ private_project.add_guest(guest)
ActionMailer::Base.deliveries.clear
end
@@ -1297,15 +1297,15 @@ describe NotificationService, services: true do
@u_guest_watcher = create_user_with_notification(:watch, 'guest_watching')
@u_guest_custom = create_user_with_notification(:custom, 'guest_custom')
- project.team << [@u_watcher, :master]
- project.team << [@u_participating, :master]
- project.team << [@u_participant_mentioned, :master]
- project.team << [@u_disabled, :master]
- project.team << [@u_mentioned, :master]
- project.team << [@u_committer, :master]
- project.team << [@u_not_mentioned, :master]
- project.team << [@u_lazy_participant, :master]
- project.team << [@u_custom_global, :master]
+ project.add_master(@u_watcher)
+ project.add_master(@u_participating)
+ project.add_master(@u_participant_mentioned)
+ project.add_master(@u_disabled)
+ project.add_master(@u_mentioned)
+ project.add_master(@u_committer)
+ project.add_master(@u_not_mentioned)
+ project.add_master(@u_lazy_participant)
+ project.add_master(@u_custom_global)
end
def create_global_setting_for(user, level)
@@ -1339,10 +1339,10 @@ describe NotificationService, services: true do
@subscribed_participant = create_global_setting_for(create(:user, username: 'subscribed_participant'), :participating)
@watcher_and_subscriber = create_global_setting_for(create(:user), :watch)
- project.team << [@subscribed_participant, :master]
- project.team << [@subscriber, :master]
- project.team << [@unsubscriber, :master]
- project.team << [@watcher_and_subscriber, :master]
+ project.add_master(@subscribed_participant)
+ project.add_master(@subscriber)
+ project.add_master(@unsubscriber)
+ project.add_master(@watcher_and_subscriber)
issuable.subscriptions.create(user: @subscriber, project: project, subscribed: true)
issuable.subscriptions.create(user: @subscribed_participant, project: project, subscribed: true)
diff --git a/spec/views/projects/builds/show.html.haml_spec.rb b/spec/views/projects/builds/show.html.haml_spec.rb
index e0c77201116..745d0c745bd 100644
--- a/spec/views/projects/builds/show.html.haml_spec.rb
+++ b/spec/views/projects/builds/show.html.haml_spec.rb
@@ -88,16 +88,46 @@ describe 'projects/builds/show', :view do
create(:ci_build, :running, environment: 'staging', pipeline: pipeline)
end
- let!(:environment) do
- create(:environment, name: 'staging', project: project)
- end
-
- it 'shows deployment message' do
- expected_text = 'This build is creating a deployment to staging'
- render
-
- expect(rendered).to have_css(
- '.environment-information', text: expected_text)
+ context 'when environment exists' do
+ let!(:environment) do
+ create(:environment, name: 'staging', project: project)
+ end
+
+ it 'shows deployment message' do
+ expected_text = 'This build is creating a deployment to staging'
+ render
+
+ expect(rendered).to have_css(
+ '.environment-information', text: expected_text)
+ end
+
+ context 'when it has deployment' do
+ let!(:deployment) do
+ create(:deployment, environment: environment)
+ end
+
+ it 'shows that deployment will be overwritten' do
+ expected_text = 'This build is creating a deployment to staging'
+ render
+
+ expect(rendered).to have_css(
+ '.environment-information', text: expected_text)
+ expect(rendered).to have_css(
+ '.environment-information', text: 'latest deployment')
+ end
+ end
+ end
+
+ context 'when environment does not exist' do
+ it 'shows deployment message' do
+ expected_text = 'This build is creating a deployment to staging'
+ render
+
+ expect(rendered).to have_css(
+ '.environment-information', text: expected_text)
+ expect(rendered).not_to have_css(
+ '.environment-information', text: 'latest deployment')
+ end
end
end
@@ -134,6 +164,8 @@ describe 'projects/builds/show', :view do
expect(rendered).to have_css(
'.environment-information', text: expected_text)
+ expect(rendered).not_to have_css(
+ '.environment-information', text: 'latest deployment')
end
end
end
diff --git a/spec/views/projects/edit.html.haml_spec.rb b/spec/views/projects/edit.html.haml_spec.rb
new file mode 100644
index 00000000000..d2575702ecc
--- /dev/null
+++ b/spec/views/projects/edit.html.haml_spec.rb
@@ -0,0 +1,24 @@
+require 'spec_helper'
+
+describe 'projects/edit' do
+ include Devise::Test::ControllerHelpers
+
+ let(:project) { create(:empty_project) }
+ let(:user) { create(:admin) }
+
+ before do
+ assign(:project, project)
+
+ allow(controller).to receive(:current_user).and_return(user)
+ allow(view).to receive_messages(current_user: user, can?: true)
+ allow(Gitlab.config.lfs).to receive(:enabled).and_return(true)
+ end
+
+ context 'LFS enabled setting' do
+ it 'displays the correct elements' do
+ render
+ expect(rendered).to have_select('project_lfs_enabled')
+ expect(rendered).to have_content('Git Large File Storage')
+ end
+ end
+end
diff --git a/app/assets/javascripts/lib/utils/timeago.js b/vendor/assets/javascripts/timeago.js
index edf0a612374..0eb6f7967a5 100644
--- a/app/assets/javascripts/lib/utils/timeago.js
+++ b/vendor/assets/javascripts/timeago.js
@@ -1,5 +1,3 @@
-/* eslint-disable no-unused-expressions, wrap-iife, func-names, curly, no-param-reassign, no-trailing-spaces, prefer-arrow-callback, no-var, one-var, quote-props, space-before-function-paren, vars-on-top, radix, prefer-template, space-infix-ops, no-use-before-define, newline-per-chained-call, no-useless-escape, no-nested-ternary, indent, no-undef, no-plusplus, one-var-declaration-per-line, operator-assignment, consistent-return, keyword-spacing, max-len, space-unary-ops, no-shadow, no-restricted-syntax, guard-for-in, eol-last, max-len */
-
/**
* Copyright (c) 2016 hustcc
* License: MIT
@@ -14,7 +12,7 @@
module.exports = factory(root);
else
root.timeago = factory(root);
-}(typeof window !== 'undefined' ? window : this,
+}(typeof window !== 'undefined' ? window : this,
function () {
var cnt = 0, // the timer counter, for timer key
indexMapEn = 'second_minute_hour_day_week_month_year'.split('_'),
@@ -32,7 +30,7 @@ function () {
SEC_ARRAY = [60, 60, 24, 7, 365/7/12, 12],
SEC_ARRAY_LEN = 6,
ATTR_DATETIME = 'datetime';
-
+
// format Date / string / timestamp to Date instance.
function toDate(input) {
if (input instanceof Date) return input;
@@ -236,4 +234,4 @@ function () {
};
return timeagoFactory;
-}); \ No newline at end of file
+});