summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.flayignore1
-rw-r--r--.gitlab-ci.yml2
-rw-r--r--.gitlab/issue_templates/Test plan.md96
-rw-r--r--.haml-lint.yml53
-rw-r--r--CHANGELOG.md295
-rw-r--r--CONTRIBUTING.md2
-rw-r--r--Gemfile4
-rw-r--r--Gemfile.lock12
-rw-r--r--Gemfile.rails5.lock30
-rw-r--r--VERSION2
-rw-r--r--app/assets/javascripts/api.js7
-rw-r--r--app/assets/javascripts/awards_handler.js33
-rw-r--r--app/assets/javascripts/ide/stores/modules/file_templates/actions.js82
-rw-r--r--app/assets/javascripts/ide/stores/modules/file_templates/getters.js23
-rw-r--r--app/assets/javascripts/ide/stores/modules/file_templates/index.js12
-rw-r--r--app/assets/javascripts/ide/stores/modules/file_templates/mutation_types.js7
-rw-r--r--app/assets/javascripts/ide/stores/modules/file_templates/mutations.js21
-rw-r--r--app/assets/javascripts/ide/stores/modules/file_templates/state.js6
-rw-r--r--app/assets/javascripts/ide/stores/mutations.js8
-rw-r--r--app/assets/javascripts/jobs/components/environments_block.vue118
-rw-r--r--app/assets/javascripts/notes/components/note_awards_list.vue24
-rw-r--r--app/assets/javascripts/pages/groups/milestones/show/index.js4
-rw-r--r--app/assets/javascripts/pages/milestones/shared/components/delete_milestone_modal.vue6
-rw-r--r--app/assets/javascripts/pages/profiles/show/index.js32
-rw-r--r--app/assets/javascripts/performance_bar/index.js4
-rw-r--r--app/assets/javascripts/performance_bar/services/performance_bar_service.js21
-rw-r--r--app/assets/javascripts/pipelines/components/graph/dropdown_job_component.vue3
-rw-r--r--app/assets/javascripts/pipelines/components/graph/job_component.vue5
-rw-r--r--app/assets/javascripts/pipelines/components/pipelines_table_row.vue2
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/deployment.vue22
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/mr_widget_header.vue61
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/mr_widget_pipeline.vue15
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue1
-rw-r--r--app/assets/javascripts/vue_shared/components/stacked_progress_bar.vue6
-rw-r--r--app/assets/javascripts/vue_shared/components/tooltip_on_truncate.vue67
-rw-r--r--app/assets/stylesheets/bootstrap_migration.scss10
-rw-r--r--app/assets/stylesheets/framework/avatar.scss12
-rw-r--r--app/assets/stylesheets/framework/badges.scss2
-rw-r--r--app/assets/stylesheets/framework/buttons.scss4
-rw-r--r--app/assets/stylesheets/framework/callout.scss24
-rw-r--r--app/assets/stylesheets/framework/common.scss12
-rw-r--r--app/assets/stylesheets/framework/dropdowns.scss8
-rw-r--r--app/assets/stylesheets/framework/feature_highlight.scss4
-rw-r--r--app/assets/stylesheets/framework/files.scss4
-rw-r--r--app/assets/stylesheets/framework/filters.scss2
-rw-r--r--app/assets/stylesheets/framework/forms.scss2
-rw-r--r--app/assets/stylesheets/framework/header.scss2
-rw-r--r--app/assets/stylesheets/framework/icons.scss2
-rw-r--r--app/assets/stylesheets/framework/issue_box.scss4
-rw-r--r--app/assets/stylesheets/framework/selects.scss6
-rw-r--r--app/assets/stylesheets/framework/variables.scss100
-rw-r--r--app/assets/stylesheets/framework/variables_overrides.scss4
-rw-r--r--app/assets/stylesheets/pages/builds.scss2
-rw-r--r--app/assets/stylesheets/pages/convdev_index.scss12
-rw-r--r--app/assets/stylesheets/pages/cycle_analytics.scss2
-rw-r--r--app/assets/stylesheets/pages/editor.scss4
-rw-r--r--app/assets/stylesheets/pages/environments.scss2
-rw-r--r--app/assets/stylesheets/pages/issuable.scss4
-rw-r--r--app/assets/stylesheets/pages/labels.scss4
-rw-r--r--app/assets/stylesheets/pages/login.scss2
-rw-r--r--app/assets/stylesheets/pages/merge_requests.scss47
-rw-r--r--app/assets/stylesheets/pages/note_form.scss6
-rw-r--r--app/assets/stylesheets/pages/notes.scss2
-rw-r--r--app/assets/stylesheets/pages/pipelines.scss10
-rw-r--r--app/assets/stylesheets/pages/projects.scss18
-rw-r--r--app/assets/stylesheets/pages/runners.scss10
-rw-r--r--app/assets/stylesheets/pages/search.scss8
-rw-r--r--app/assets/stylesheets/pages/settings.scss4
-rw-r--r--app/assets/stylesheets/pages/stat_graph.scss4
-rw-r--r--app/controllers/concerns/issuable_collections.rb22
-rw-r--r--app/controllers/concerns/renders_commits.rb20
-rw-r--r--app/controllers/concerns/toggle_award_emoji.rb2
-rw-r--r--app/controllers/groups/milestones_controller.rb17
-rw-r--r--app/controllers/projects/commit_controller.rb2
-rw-r--r--app/controllers/projects/commits_controller.rb2
-rw-r--r--app/controllers/projects/compare_controller.rb2
-rw-r--r--app/controllers/projects/issues_controller.rb2
-rw-r--r--app/controllers/projects/merge_requests/creations_controller.rb2
-rw-r--r--app/controllers/projects/merge_requests_controller.rb2
-rw-r--r--app/helpers/commits_helper.rb11
-rw-r--r--app/helpers/import_helper.rb4
-rw-r--r--app/helpers/issues_helper.rb8
-rw-r--r--app/helpers/projects_helper.rb6
-rw-r--r--app/models/ci/pipeline.rb3
-rw-r--r--app/models/commit.rb1
-rw-r--r--app/models/concerns/awardable.rb16
-rw-r--r--app/models/diff_note.rb16
-rw-r--r--app/models/issue.rb47
-rw-r--r--app/models/member.rb2
-rw-r--r--app/models/merge_request_diff.rb4
-rw-r--r--app/models/project.rb16
-rw-r--r--app/models/protected_tag.rb2
-rw-r--r--app/models/remote_mirror.rb9
-rw-r--r--app/models/repository.rb21
-rw-r--r--app/models/user.rb15
-rw-r--r--app/policies/group_policy.rb4
-rw-r--r--app/policies/project_policy.rb4
-rw-r--r--app/services/git_push_service.rb15
-rw-r--r--app/services/groups/destroy_service.rb5
-rw-r--r--app/services/issues/fetch_referenced_merge_requests_service.rb14
-rw-r--r--app/services/issues/referenced_merge_requests_service.rb66
-rw-r--r--app/services/merge_requests/build_service.rb19
-rw-r--r--app/services/milestones/destroy_service.rb20
-rw-r--r--app/services/projects/fork_service.rb8
-rw-r--r--app/services/projects/update_remote_mirror_service.rb1
-rw-r--r--app/services/quick_actions/interpret_service.rb2
-rw-r--r--app/views/admin/hook_logs/show.html.haml3
-rw-r--r--app/views/admin/users/show.html.haml4
-rw-r--r--app/views/award_emoji/_awards_block.html.haml3
-rw-r--r--app/views/ci/runner/_how_to_setup_runner.html.haml2
-rw-r--r--app/views/ci/status/_dropdown_graph_badge.html.haml4
-rw-r--r--app/views/groups/milestones/index.html.haml2
-rw-r--r--app/views/import/_githubish_status.html.haml2
-rw-r--r--app/views/import/bitbucket/status.html.haml2
-rw-r--r--app/views/import/bitbucket_server/status.html.haml2
-rw-r--r--app/views/projects/_issuable_by_email.html.haml11
-rw-r--r--app/views/projects/commits/_commit_list.html.haml5
-rw-r--r--app/views/projects/commits/_commits.html.haml3
-rw-r--r--app/views/projects/diffs/_line.html.haml4
-rw-r--r--app/views/projects/diffs/_parallel_view.html.haml4
-rw-r--r--app/views/projects/edit.html.haml2
-rw-r--r--app/views/projects/hook_logs/show.html.haml2
-rw-r--r--app/views/projects/jobs/_sidebar.html.haml2
-rw-r--r--app/views/projects/merge_requests/_how_to_merge.html.haml2
-rw-r--r--app/views/projects/merge_requests/creations/_new_submit.html.haml2
-rw-r--r--app/views/projects/milestones/show.html.haml13
-rw-r--r--app/views/projects/mirrors/_instructions.html.haml4
-rw-r--r--app/views/projects/notes/_actions.html.haml2
-rw-r--r--app/views/shared/milestones/_delete_button.html.haml14
-rw-r--r--app/views/shared/milestones/_milestone.html.haml5
-rw-r--r--app/views/shared/milestones/_top.html.haml5
-rw-r--r--app/views/snippets/notes/_actions.html.haml2
-rw-r--r--changelogs/unreleased/1756-set-iid-via-api.yml5
-rw-r--r--changelogs/unreleased/21326-avoid-nil-safe-message.yml5
-rw-r--r--changelogs/unreleased/23705-add-single-file-download-in-repo.yml5
-rw-r--r--changelogs/unreleased/25990-improve-web-terminal.yml5
-rw-r--r--changelogs/unreleased/25990-interactive-web-terminals-authorization.yml5
-rw-r--r--changelogs/unreleased/27456-improve-feedback-when-dev-cannot-push-to-empty-repo.yml5
-rw-r--r--changelogs/unreleased/29278-commits-page-tooltips.yml5
-rw-r--r--changelogs/unreleased/31576-redirect-commits-to-root-if-no-ref.yml5
-rw-r--r--changelogs/unreleased/32783-api-all-members-with-ancestors.yml6
-rw-r--r--changelogs/unreleased/32821-better-error-message-add-invalid-user-to-project.yml5
-rw-r--r--changelogs/unreleased/34572-ssh-certificates.yml5
-rw-r--r--changelogs/unreleased/35952-keep-admin-settings-open-after-submit.yml5
-rw-r--r--changelogs/unreleased/36409-frontend-for-clarifying-the-usefulness-of-the-search-bar.yml5
-rw-r--r--changelogs/unreleased/38604-add-private-profile.yml5
-rw-r--r--changelogs/unreleased/40973-disable-rack-attack-by-default.yml5
-rw-r--r--changelogs/unreleased/41416-making-instance-wide-data-tools-more-accessible.yml5
-rw-r--r--changelogs/unreleased/41441-add-target-branch-name-to-cherrypick-confirmation.yml5
-rw-r--r--changelogs/unreleased/41671-fixing-milestone-date-change-when-editing.yml5
-rw-r--r--changelogs/unreleased/41784-monitoring-graph-popovers.yml5
-rw-r--r--changelogs/unreleased/42415-omit-projects-from-get-group-endpoint.yml5
-rw-r--r--changelogs/unreleased/43011-typecast-markdownversion-prop-notesapp.yml5
-rw-r--r--changelogs/unreleased/43096-controller-projects-issuescontroller-referenced_merge_requests-json-executes-more-than-100-sql-queries.yml5
-rw-r--r--changelogs/unreleased/43312-remove_user_activity_workers.yml5
-rw-r--r--changelogs/unreleased/43625-increase-modal-checkout.yml5
-rw-r--r--changelogs/unreleased/44127-board-label-edit-drop-down-is-showing-incorrect-selected-labels-summary.yml5
-rw-r--r--changelogs/unreleased/44824-remove-ghost-notification-settings-for-group-and-project.yml5
-rw-r--r--changelogs/unreleased/45318-junit-FE.yml5
-rw-r--r--changelogs/unreleased/45318-vuex-store.yml5
-rw-r--r--changelogs/unreleased/45443-unable-to-save-user-profile-update-with-safari.yml5
-rw-r--r--changelogs/unreleased/46165-web-ide-branch-picker.yml5
-rw-r--r--changelogs/unreleased/46535-orphaned-uploads.yml5
-rw-r--r--changelogs/unreleased/46703-group-dashboard-line-height-is-too-tall-for-group-names.yml5
-rw-r--r--changelogs/unreleased/46869-deploy-tokens-failed-to-clone-lfs-repository.yml5
-rw-r--r--changelogs/unreleased/46930-fix-updated_at-if-created_at-is-set-note-api.yml5
-rw-r--r--changelogs/unreleased/46940-hashed-storage-extend-enable-hashed-storage-for-all-new-projects-to-for-all-new-and-renamed-projects.yml5
-rw-r--r--changelogs/unreleased/47156-improve-auto-devops-settings.yml5
-rw-r--r--changelogs/unreleased/47419-Fix-breadcrumbs.yml5
-rw-r--r--changelogs/unreleased/47548-monospace-commit-messages.yml5
-rw-r--r--changelogs/unreleased/47728-mr-api-documentation-changes.yml5
-rw-r--r--changelogs/unreleased/47768-web-ide-redesign-header.yml5
-rw-r--r--changelogs/unreleased/48036-fix-web-ide-blob-crash.yml5
-rw-r--r--changelogs/unreleased/48055-web-ide-resize-handles.yml5
-rw-r--r--changelogs/unreleased/48098-mutual-auth-cluster-applications.yml6
-rw-r--r--changelogs/unreleased/48246-osw-load-diffs-improvement.yml5
-rw-r--r--changelogs/unreleased/48419-charts-with-long-label-appear-oversized.yml5
-rw-r--r--changelogs/unreleased/48456-fix-system-level-labels-admin-ui.yml5
-rw-r--r--changelogs/unreleased/48537-update-avatar-only-via-api.yml5
-rw-r--r--changelogs/unreleased/48542-code-link.yml5
-rw-r--r--changelogs/unreleased/48617-promoting-milestone.yml5
-rw-r--r--changelogs/unreleased/48636-new-mr-card-styles.yml5
-rw-r--r--changelogs/unreleased/48657-persist-auto-devops-banner-dismissal-per-user-cookie.yml5
-rw-r--r--changelogs/unreleased/48773-gitlab-project-import-should-use-object-storage.yml5
-rw-r--r--changelogs/unreleased/48804-redesign-gcp-banner.yml5
-rw-r--r--changelogs/unreleased/48823-copy-gfm.yml5
-rw-r--r--changelogs/unreleased/48834-chart-versions-for-applications-installed-by-one-click-install-buttons-should-be-version-locked.yml6
-rw-r--r--changelogs/unreleased/48932-disable-saml-if-omniauth-is-disabled.yml5
-rw-r--r--changelogs/unreleased/48934.yml5
-rw-r--r--changelogs/unreleased/48976-fix-sti-background-migration.yml6
-rw-r--r--changelogs/unreleased/49025-docs-kubernetes-tiller.yml5
-rw-r--r--changelogs/unreleased/49107-prefetching-of-assets-and-cdn-domain.yml5
-rw-r--r--changelogs/unreleased/49110-update-mr-widget-styles.yml5
-rw-r--r--changelogs/unreleased/49114-add-gitaly-servers-to-admin-overview-navigation-menu.yml5
-rw-r--r--changelogs/unreleased/49161-disable-toggle-comments.yml5
-rw-r--r--changelogs/unreleased/49272-sanitize-git-url-in-import-errors.yml5
-rw-r--r--changelogs/unreleased/49291-fix-memory-graph-component-typo.yml5
-rw-r--r--changelogs/unreleased/49292-add-group-name-badge-under-milestone.yml5
-rw-r--r--changelogs/unreleased/49324-add-support-for-tar-gz-autodevops-charts.yml5
-rw-r--r--changelogs/unreleased/49364-fix-broadcast-margin.yml5
-rw-r--r--changelogs/unreleased/49375-move-help-popover.yml5
-rw-r--r--changelogs/unreleased/49499-list-of-projects-not-loading-when-trying-to-create-an-issue-from-a-board-typeerror.yml5
-rw-r--r--changelogs/unreleased/49701-sorting-by-name-on-milestones-page-error.yml5
-rw-r--r--changelogs/unreleased/49747-update-poll-2xx.yml5
-rw-r--r--changelogs/unreleased/49776-pipeline-job-log-page-uses-too-much-cpu-for-loading-animation.yml5
-rw-r--r--changelogs/unreleased/49830-use-helm-272.yml5
-rw-r--r--changelogs/unreleased/49835-increase-width.yml5
-rw-r--r--changelogs/unreleased/49851-link-to-runners.yml6
-rw-r--r--changelogs/unreleased/49854-recover-mr-regression-fixes-safe-1.yml5
-rw-r--r--changelogs/unreleased/49854-recover-mr-regression-fixes-safe-2.yml5
-rw-r--r--changelogs/unreleased/49854-recover-mr-regression-fixes-safe-3.yml5
-rw-r--r--changelogs/unreleased/49861-top-nav-search-bar-produces-console-error-when-unauthenticated.yml5
-rw-r--r--changelogs/unreleased/49899-merge-request-e-mail-link-has-full-url.yml5
-rw-r--r--changelogs/unreleased/49907-commits-and-merge-requests-does-not-list-all-files-when-one-file-exceeds-size-limits.yml5
-rw-r--r--changelogs/unreleased/49966-improve-junit-fe.yml5
-rw-r--r--changelogs/unreleased/49993-fix-remember-sorting-issue-mr.yml5
-rw-r--r--changelogs/unreleased/50101-env-block.yml5
-rw-r--r--changelogs/unreleased/50257-fix-auto-devops-glibc-pubkey-url.yml5
-rw-r--r--changelogs/unreleased/50281-js-pages-do-not-load-on-windows-8-ie-11.yml5
-rw-r--r--changelogs/unreleased/50312-instance-statistics-convdev-index-intro-banner-is-not-dismissable.yml5
-rw-r--r--changelogs/unreleased/50345-hashed-storage-feature-flag.yml5
-rw-r--r--changelogs/unreleased/50441-high-number-of-statement-timeouts-in-groupdestroyworker-due-to-sitestatistics.yml5
-rw-r--r--changelogs/unreleased/50524-artifacts-sm.yml5
-rw-r--r--changelogs/unreleased/50584-fix-ide-commit-twice.yml5
-rw-r--r--changelogs/unreleased/50801-error-getting-performance-bar-results-for-uuid.yml5
-rw-r--r--changelogs/unreleased/6028-show-generic-percent-stacked-progress-bar.yml6
-rw-r--r--changelogs/unreleased/6860-FE-instance-level-project-templates.yml5
-rw-r--r--changelogs/unreleased/accept-rf3-2822-compliant-addresses.yml5
-rw-r--r--changelogs/unreleased/add-dst-support-to-pipeline-schedule.yml5
-rw-r--r--changelogs/unreleased/add-homepage-link-to-status-pages.yml5
-rw-r--r--changelogs/unreleased/add-merge-request-header-branch-details-right-margin.yml5
-rw-r--r--changelogs/unreleased/add-total-time-flat-printer-for-profiling.yml6
-rw-r--r--changelogs/unreleased/api-empty-commit-message.yml5
-rw-r--r--changelogs/unreleased/api-empty-project-snippets.yml5
-rw-r--r--changelogs/unreleased/api-minimal-access-level.yml5
-rw-r--r--changelogs/unreleased/api-protected-tags.yml5
-rw-r--r--changelogs/unreleased/api-shared_group_expires-at.yml5
-rw-r--r--changelogs/unreleased/arguments-keyword-sast.yml5
-rw-r--r--changelogs/unreleased/artifact-format-v2-with-parser.yml5
-rw-r--r--changelogs/unreleased/artifact-format-v2.yml5
-rw-r--r--changelogs/unreleased/blackst0ne-replace-sidekiq-inline-with-perform-enqueued-jobs.yml5
-rw-r--r--changelogs/unreleased/bvl-add-galician.yml5
-rw-r--r--changelogs/unreleased/bvl-graphql-wip-mutation.yml5
-rw-r--r--changelogs/unreleased/bvl-user-status-message-35463.yml5
-rw-r--r--changelogs/unreleased/ccr-43283_allow_author_upvote.yml5
-rw-r--r--changelogs/unreleased/ccr-48800-ping_for_boards.yml6
-rw-r--r--changelogs/unreleased/ce-5666-backport.yml5
-rw-r--r--changelogs/unreleased/ce-6064-geo-sql-query-for-counting-projects-with-wikis-is-very-slow.yml5
-rw-r--r--changelogs/unreleased/close-revert-and-cherry-pick-modal-on-escape-keypress.yml5
-rw-r--r--changelogs/unreleased/cr-add-group-milestone-to-dashboard.yml5
-rw-r--r--changelogs/unreleased/cr-add-path-of-group-milestone.yml5
-rw-r--r--changelogs/unreleased/custom_wiki_sidebar.yml5
-rw-r--r--changelogs/unreleased/dz-fix-sql-error-admin-users-2fa.yml5
-rw-r--r--changelogs/unreleased/dz-labels-search.yml5
-rw-r--r--changelogs/unreleased/dz-manifest-import.yml5
-rw-r--r--changelogs/unreleased/expose-users-id-in-admin-users-show-page.yml5
-rw-r--r--changelogs/unreleased/feature-gb-email-delivery-metrics.yml5
-rw-r--r--changelogs/unreleased/feature-gb-login-activity-metrics.yml5
-rw-r--r--changelogs/unreleased/features-show-project-id-on-home-panel.yml5
-rw-r--r--changelogs/unreleased/fix-api-group-createdat.yml5
-rw-r--r--changelogs/unreleased/fix-diff-note.yml5
-rw-r--r--changelogs/unreleased/fix-email-confirmation-addtional-email.yml5
-rw-r--r--changelogs/unreleased/fix-gb-add-missing-before-sha-predefined-variable.yml5
-rw-r--r--changelogs/unreleased/fix-gb-fix-deserializing-ci-yaml-variables.yml5
-rw-r--r--changelogs/unreleased/fix-gb-fix-project-settings-build-time-validation.yml5
-rw-r--r--changelogs/unreleased/fix-mr-title-fallback-logic.yml5
-rw-r--r--changelogs/unreleased/fix-multiple-scopes.yml5
-rw-r--r--changelogs/unreleased/fix-project-api-archived.yml5
-rw-r--r--changelogs/unreleased/fix-prometheus-updated-status.yml5
-rw-r--r--changelogs/unreleased/fix-search-bar.yml5
-rw-r--r--changelogs/unreleased/fix-storage-size-for-artifacts-change.yml5
-rw-r--r--changelogs/unreleased/fj-37736-improve-performance-post-receive-create-gpg-siganture-worker.yml5
-rw-r--r--changelogs/unreleased/fj-48123-fix-gitlab-import.yml5
-rw-r--r--changelogs/unreleased/fj-49014-wiki-search-error.yml5
-rw-r--r--changelogs/unreleased/fj-49512-fix-gitlab-git-pages-encoding.yml5
-rw-r--r--changelogs/unreleased/fj-49802-bug-api-set-http-headers.yml5
-rw-r--r--changelogs/unreleased/floating-avarage-commit-numbers.yml5
-rw-r--r--changelogs/unreleased/frozen-string-danger.yml5
-rw-r--r--changelogs/unreleased/frozen-string-enable-app-models-more.yml5
-rw-r--r--changelogs/unreleased/frozen-string-enable-app-models.yml5
-rw-r--r--changelogs/unreleased/frozen-string-enable-app-presenters-policies.yml5
-rw-r--r--changelogs/unreleased/frozen-string-enable-app-serializers.yml5
-rw-r--r--changelogs/unreleased/frozen-string-enable-app-services.yml5
-rw-r--r--changelogs/unreleased/frozen-string-enable-apps-services-inner-even-more.yml5
-rw-r--r--changelogs/unreleased/frozen-string-enable-apps-services-inner-more.yml5
-rw-r--r--changelogs/unreleased/frozen-string-enable-apps-services-inner.yml5
-rw-r--r--changelogs/unreleased/frozen-string-vestigial.yml5
-rw-r--r--changelogs/unreleased/full-list-of-vulnerabilities-5239.yml5
-rw-r--r--changelogs/unreleased/git-rerere-link-doc-update.yml5
-rw-r--r--changelogs/unreleased/hangouts_chat_integration.yml5
-rw-r--r--changelogs/unreleased/ide-codesandbox-poc.yml5
-rw-r--r--changelogs/unreleased/ide-delete-entries.yml5
-rw-r--r--changelogs/unreleased/ide-pipeline-icon-open.yml5
-rw-r--r--changelogs/unreleased/ide-rename-files.yml5
-rw-r--r--changelogs/unreleased/ide-row-dropdown-design-update.yml5
-rw-r--r--changelogs/unreleased/ide-warn-staged-files.yml5
-rw-r--r--changelogs/unreleased/improve-junit-support-be.yml5
-rw-r--r--changelogs/unreleased/improve-metadata-access-performance.yml5
-rw-r--r--changelogs/unreleased/issue_36138.yml5
-rw-r--r--changelogs/unreleased/issue_43602.yml5
-rw-r--r--changelogs/unreleased/issue_44821.yml5
-rw-r--r--changelogs/unreleased/issue_47709.yml5
-rw-r--r--changelogs/unreleased/jprovazn-fix-form-uploads.yml5
-rw-r--r--changelogs/unreleased/jprovazn-resource-events.yml5
-rw-r--r--changelogs/unreleased/jr-archive-hook.yml5
-rw-r--r--changelogs/unreleased/jupyter-image.yml5
-rw-r--r--changelogs/unreleased/kp-6927-epic-dates-from-milestone.yml5
-rw-r--r--changelogs/unreleased/kp-stacked-progress-bar-decimal-places.yml5
-rw-r--r--changelogs/unreleased/leipert-fix-pipelines-view.yml5
-rw-r--r--changelogs/unreleased/mk-add-local-project-uploads-cleanup-task.yml5
-rw-r--r--changelogs/unreleased/mk-fix-callback-canceling-in-namespace-move-dir.yml5
-rw-r--r--changelogs/unreleased/osw-fix-missing-and-duplicated-milestones-on-list.yml5
-rw-r--r--changelogs/unreleased/osw-fix-n-plus-1-for-mrs-without-merge-info.yml5
-rw-r--r--changelogs/unreleased/pl-json-gon.yml5
-rw-r--r--changelogs/unreleased/process-commits-as-normal-in-forks-with-missing-upstream.yml5
-rw-r--r--changelogs/unreleased/project-visibility-tooltip.yml5
-rw-r--r--changelogs/unreleased/rails5-fix-48977.yml5
-rw-r--r--changelogs/unreleased/rails5-fix-flaky-spec-user-uses-shortcuts.yml5
-rw-r--r--changelogs/unreleased/rails5-fix-import-merge-request-creator.yml5
-rw-r--r--changelogs/unreleased/rails5-fix-revert-modal-spec.yml5
-rw-r--r--changelogs/unreleased/rails5-gpg-permit-concurrent.yml5
-rw-r--r--changelogs/unreleased/rails5-mysql-fix-pr-importer-spec.yml5
-rw-r--r--changelogs/unreleased/rails5-mysql-rename-column.yml5
-rw-r--r--changelogs/unreleased/rails5-silence-stream.yml5
-rw-r--r--changelogs/unreleased/rails5-update-gemfile-lock-2.yml5
-rw-r--r--changelogs/unreleased/rails5-update-gemfile-lock.yml6
-rw-r--r--changelogs/unreleased/rails5-update-rouge.yml5
-rw-r--r--changelogs/unreleased/ravlen-deploy-tokens-display-update.yml5
-rw-r--r--changelogs/unreleased/regen-2fa-codes.yml5
-rw-r--r--changelogs/unreleased/replace-all-snake-case-in-scss-variables.yml5
-rw-r--r--changelogs/unreleased/replace-snake-case-css-classes.yml5
-rw-r--r--changelogs/unreleased/rouge-3-2-0.yml5
-rw-r--r--changelogs/unreleased/rouge_3-2-1.yml5
-rw-r--r--changelogs/unreleased/runner-features.yml5
-rw-r--r--changelogs/unreleased/runners-max-timeout-param.yml5
-rw-r--r--changelogs/unreleased/satishperala-gitlab-ce-20720_webhooks_full_image_url.yml5
-rw-r--r--changelogs/unreleased/security-49085-persistent-xss-rendering.yml5
-rw-r--r--changelogs/unreleased/security-fj-missing-csrf-system-hooks.yml5
-rw-r--r--changelogs/unreleased/security-ide-branch-name-xss.yml5
-rw-r--r--changelogs/unreleased/sh-block-link-local-master.yml5
-rw-r--r--changelogs/unreleased/sh-bump-fog-google.yml5
-rw-r--r--changelogs/unreleased/sh-bump-gitaly-0-117.yml5
-rw-r--r--changelogs/unreleased/sh-bump-gitaly-for-11-2.yml5
-rw-r--r--changelogs/unreleased/sh-bump-haml-5-0-4.yml5
-rw-r--r--changelogs/unreleased/sh-bump-rugged-0-27-4.yml5
-rw-r--r--changelogs/unreleased/sh-bump-sanitize-4-6-6.yml5
-rw-r--r--changelogs/unreleased/sh-enable-frozen-literals-banzi-filters.yml5
-rw-r--r--changelogs/unreleased/sh-fix-admin-jobs-controller-timing-out.yml5
-rw-r--r--changelogs/unreleased/sh-fix-issue-47797-ce.yml5
-rw-r--r--changelogs/unreleased/sh-fix-issue-49133.yml5
-rw-r--r--changelogs/unreleased/sh-fix-issue-50562.yml5
-rw-r--r--changelogs/unreleased/sh-fix-stderr-pipe-consumption.yml5
-rw-r--r--changelogs/unreleased/sh-freeze-banzai-filter-strings.yml5
-rw-r--r--changelogs/unreleased/sh-handle-colons-in-url-passwords.yml5
-rw-r--r--changelogs/unreleased/sh-include-rbtrace.yml5
-rw-r--r--changelogs/unreleased/sh-insert-git-data-in-separate-transaction.yml5
-rw-r--r--changelogs/unreleased/sh-lfs-fix-content-type.yml5
-rw-r--r--changelogs/unreleased/sh-limit-commit-renderering.yml5
-rw-r--r--changelogs/unreleased/sh-limit-unauthenticated-session-times.yml5
-rw-r--r--changelogs/unreleased/sh-normalize-urls.yml5
-rw-r--r--changelogs/unreleased/sh-optimize-wiki-empty-check.yml5
-rw-r--r--changelogs/unreleased/sh-remove-banzai-instrumentation.yml5
-rw-r--r--changelogs/unreleased/sh-sanitize-project-import-names.yml5
-rw-r--r--changelogs/unreleased/sh-simplify-liveness-check.yml5
-rw-r--r--changelogs/unreleased/sh-support-users-find-by-confirmed-emails.yml5
-rw-r--r--changelogs/unreleased/sh-use-wiki-limit-parameter-gitaly.yml5
-rw-r--r--changelogs/unreleased/stop-dynamic-routable-creation.yml5
-rw-r--r--changelogs/unreleased/tc-api-fork-owners.yml5
-rw-r--r--changelogs/unreleased/tc-reorder-mail-notify-references.yml5
-rw-r--r--changelogs/unreleased/todos-visibility-change.yml5
-rw-r--r--changelogs/unreleased/todos-visibility-migration.yml5
-rw-r--r--changelogs/unreleased/toggle-password-cluster.yml5
-rw-r--r--changelogs/unreleased/tweak-sql-buckets.yml5
-rw-r--r--changelogs/unreleased/tz-mr-port-memory-fixes.yml5
-rw-r--r--changelogs/unreleased/update-card-body-style.yml5
-rw-r--r--changelogs/unreleased/update-issue-closing-pattern.yml5
-rw-r--r--changelogs/unreleased/update-specific-runners-help-url.yml5
-rw-r--r--changelogs/unreleased/upgrade-hamlit-for-ruby25.yml5
-rw-r--r--changelogs/unreleased/winh-default-status-emoji.yml5
-rw-r--r--changelogs/unreleased/winh-fix-gpg-regressions.yml5
-rw-r--r--changelogs/unreleased/winh-restyle-user-status.yml5
-rw-r--r--changelogs/unreleased/winh-stop-all-environments.yml5
-rw-r--r--changelogs/unreleased/winh-tree-view-gpg.yml5
-rw-r--r--changelogs/unreleased/winh-upgrade-grape-path-helpers.yml5
-rw-r--r--changelogs/unreleased/wrap-job-name-on-jobs-sidebar.yml5
-rw-r--r--changelogs/unreleased/zj-remove-git-rake-tasks.yml5
-rw-r--r--changelogs/unreleased/zj-repository-languages.yml5
-rw-r--r--config/initializers/fog_google_https_private_urls.rb2
-rw-r--r--config/routes.rb7
-rw-r--r--config/routes/admin.rb2
-rw-r--r--config/routes/group.rb2
-rw-r--r--config/routes/project.rb2
-rw-r--r--danger/changelog/Dangerfile6
-rw-r--r--db/migrate/20180711103851_drop_duplicate_protected_tags.rb45
-rw-r--r--db/migrate/20180711103922_add_protected_tags_index.rb18
-rw-r--r--db/migrate/20180815175440_add_index_on_list_type.rb16
-rw-r--r--db/post_migrate/20180816193530_rename_login_root_namespaces.rb16
-rw-r--r--db/post_migrate/20180826111825_recalculate_site_statistics.rb27
-rw-r--r--db/schema.rb4
-rw-r--r--doc/administration/auth/how_to_configure_ldap_gitlab_ce/img/gitlab_ou.pngbin27877 -> 11991 bytes
-rw-r--r--doc/administration/auth/img/crowd_application.pngbin55811 -> 17172 bytes
-rw-r--r--doc/administration/auth/img/crowd_application_authorisation.pngbin126994 -> 37026 bytes
-rw-r--r--doc/administration/img/circuitbreaker_config.pngbin99523 -> 29130 bytes
-rw-r--r--doc/administration/img/custom_hooks_error_msg.pngbin44922 -> 44892 bytes
-rw-r--r--doc/administration/img/failing_storage.pngbin48281 -> 16291 bytes
-rw-r--r--doc/administration/img/integration/plantuml-example.pngbin33034 -> 12559 bytes
-rw-r--r--doc/administration/img/repository_storages_admin_ui.pngbin70416 -> 20439 bytes
-rw-r--r--doc/administration/monitoring/performance/img/grafana_dashboard_import.pngbin11836 -> 11835 bytes
-rw-r--r--doc/administration/monitoring/performance/img/grafana_data_source_configuration.pngbin14700 -> 14695 bytes
-rw-r--r--doc/administration/monitoring/performance/img/grafana_data_source_empty.pngbin11963 -> 11960 bytes
-rw-r--r--doc/administration/monitoring/performance/img/grafana_save_icon.pngbin4619 -> 4598 bytes
-rw-r--r--doc/administration/monitoring/performance/img/performance_bar.pngbin344274 -> 99331 bytes
-rw-r--r--doc/administration/monitoring/performance/img/performance_bar_configuration_settings.pngbin20385 -> 16455 bytes
-rw-r--r--doc/administration/monitoring/performance/img/performance_bar_gitaly_calls.pngbin278693 -> 91275 bytes
-rw-r--r--doc/administration/monitoring/performance/img/performance_bar_line_profiling.pngbin161313 -> 93063 bytes
-rw-r--r--doc/administration/monitoring/performance/img/performance_bar_sql_queries.pngbin165124 -> 128337 bytes
-rw-r--r--doc/administration/monitoring/performance/img/request_profile_result.pngbin3236 -> 3216 bytes
-rw-r--r--doc/administration/monitoring/performance/img/request_profiling_token.pngbin10229 -> 10217 bytes
-rw-r--r--doc/administration/operations/img/sidekiq_job_throttling.pngbin32229 -> 32224 bytes
-rw-r--r--doc/administration/operations/img/write_to_authorized_keys_setting.pngbin94218 -> 29192 bytes
-rw-r--r--doc/api/README.md1
-rw-r--r--doc/api/discussions.md16
-rw-r--r--doc/api/group_milestones.md13
-rw-r--r--doc/api/groups.md6
-rw-r--r--doc/api/issues.md2
-rw-r--r--doc/api/notes.md2
-rw-r--r--doc/api/projects.md9
-rw-r--r--doc/api/protected_tags.md128
-rw-r--r--doc/ci/autodeploy/img/auto_deploy_btn.pngbin46825 -> 16779 bytes
-rw-r--r--doc/ci/autodeploy/img/auto_deploy_button.pngbin43441 -> 13321 bytes
-rw-r--r--doc/ci/autodeploy/img/auto_deploy_dropdown.pngbin75456 -> 28357 bytes
-rw-r--r--doc/ci/autodeploy/img/auto_monitoring.pngbin89206 -> 56765 bytes
-rw-r--r--doc/ci/autodeploy/img/guide_connect_cluster.pngbin38724 -> 15225 bytes
-rw-r--r--doc/ci/autodeploy/img/guide_integration.pngbin44263 -> 15042 bytes
-rw-r--r--doc/ci/autodeploy/img/guide_secret.pngbin16233 -> 4803 bytes
-rw-r--r--doc/ci/caching/img/clear_runners_cache.pngbin16029 -> 16020 bytes
-rw-r--r--doc/ci/examples/devops_and_game_dev_with_gitlab_ci_cd/img/aws_config_window.pngbin22046 -> 9300 bytes
-rw-r--r--doc/ci/examples/devops_and_game_dev_with_gitlab_ci_cd/img/gitlab_config.pngbin27620 -> 15160 bytes
-rw-r--r--doc/ci/examples/devops_and_game_dev_with_gitlab_ci_cd/img/test_pipeline_pass.pngbin18789 -> 9985 bytes
-rw-r--r--doc/ci/examples/laravel_with_gitlab_and_envoy/img/container_registry_page_empty_image.pngbin56091 -> 23936 bytes
-rw-r--r--doc/ci/examples/laravel_with_gitlab_and_envoy/img/deploy_keys_page.pngbin339666 -> 105954 bytes
-rw-r--r--doc/ci/examples/laravel_with_gitlab_and_envoy/img/environment_page.pngbin185393 -> 79265 bytes
-rw-r--r--doc/ci/examples/laravel_with_gitlab_and_envoy/img/environments_page.pngbin134742 -> 56126 bytes
-rw-r--r--doc/ci/examples/laravel_with_gitlab_and_envoy/img/pipeline_page.pngbin172664 -> 70582 bytes
-rw-r--r--doc/ci/examples/laravel_with_gitlab_and_envoy/img/pipelines_page.pngbin119955 -> 50117 bytes
-rw-r--r--doc/ci/examples/laravel_with_gitlab_and_envoy/img/pipelines_page_deploy_button.pngbin141393 -> 59140 bytes
-rw-r--r--doc/ci/examples/laravel_with_gitlab_and_envoy/img/secret_variables_page.pngbin233764 -> 96864 bytes
-rw-r--r--doc/ci/examples/test_phoenix_app_with_gitlab_ci_cd/img/job-succeeded.pngbin62101 -> 23148 bytes
-rw-r--r--doc/ci/examples/test_phoenix_app_with_gitlab_ci_cd/img/mix-phoenix-new.pngbin16112 -> 6602 bytes
-rw-r--r--doc/ci/examples/test_phoenix_app_with_gitlab_ci_cd/img/mix-phoenix-server.pngbin73726 -> 25235 bytes
-rw-r--r--doc/ci/examples/test_phoenix_app_with_gitlab_ci_cd/img/pipelines.pngbin40381 -> 15794 bytes
-rw-r--r--doc/ci/examples/test_phoenix_app_with_gitlab_ci_cd/img/select-template.pngbin29968 -> 12345 bytes
-rw-r--r--doc/ci/examples/test_phoenix_app_with_gitlab_ci_cd/img/setup-ci.pngbin46405 -> 19183 bytes
-rw-r--r--doc/ci/img/deployments_view.pngbin61088 -> 23352 bytes
-rw-r--r--doc/ci/img/environments_available.pngbin21089 -> 8464 bytes
-rw-r--r--doc/ci/img/environments_dynamic_groups.pngbin58239 -> 21902 bytes
-rw-r--r--doc/ci/img/environments_link_url_mr.pngbin34361 -> 14346 bytes
-rw-r--r--doc/ci/img/environments_manual_action_deployments.pngbin32748 -> 12635 bytes
-rw-r--r--doc/ci/img/environments_manual_action_environments.pngbin24191 -> 9485 bytes
-rw-r--r--doc/ci/img/environments_manual_action_jobs.pngbin19919 -> 8446 bytes
-rw-r--r--doc/ci/img/environments_manual_action_pipelines.pngbin38974 -> 14979 bytes
-rw-r--r--doc/ci/img/environments_manual_action_single_pipeline.pngbin23381 -> 10273 bytes
-rw-r--r--doc/ci/img/environments_monitoring.pngbin76086 -> 45153 bytes
-rw-r--r--doc/ci/img/environments_mr_review_app.pngbin30991 -> 13394 bytes
-rw-r--r--doc/ci/img/environments_terminal_button_on_index.pngbin29162 -> 11080 bytes
-rw-r--r--doc/ci/img/environments_terminal_button_on_show.pngbin17811 -> 7642 bytes
-rw-r--r--doc/ci/img/environments_terminal_page.pngbin117863 -> 28166 bytes
-rw-r--r--doc/ci/img/job_failure_reason.pngbin5346 -> 5288 bytes
-rw-r--r--doc/ci/img/pipelines_grouped.pngbin12937 -> 12888 bytes
-rw-r--r--doc/ci/img/pipelines_index.pngbin36299 -> 14896 bytes
-rw-r--r--doc/ci/img/pipelines_mini_graph.pngbin15404 -> 4671 bytes
-rw-r--r--doc/ci/img/pipelines_mini_graph_simple.pngbin1637 -> 961 bytes
-rw-r--r--doc/ci/img/view_on_env_blob.pngbin111663 -> 32924 bytes
-rw-r--r--doc/ci/img/view_on_env_mr.pngbin1005195 -> 295181 bytes
-rw-r--r--doc/ci/interactive_web_terminal/img/interactive_web_terminal_page.pngbin23431 -> 23364 bytes
-rw-r--r--doc/ci/interactive_web_terminal/img/interactive_web_terminal_running_job.pngbin55682 -> 55677 bytes
-rw-r--r--doc/ci/quick_start/img/build_log.pngbin35261 -> 35256 bytes
-rw-r--r--doc/ci/quick_start/img/builds_status.pngbin19127 -> 19107 bytes
-rw-r--r--doc/ci/quick_start/img/new_commit.pngbin5584 -> 5541 bytes
-rw-r--r--doc/ci/review_apps/img/review_apps_preview_in_mr.pngbin11723 -> 11664 bytes
-rw-r--r--doc/ci/runners/img/protected_runners_check_box.pngbin8584 -> 3963 bytes
-rw-r--r--doc/ci/runners/img/shared_runner_ip_address.pngbin69821 -> 20276 bytes
-rw-r--r--doc/ci/runners/img/specific_runner_ip_address.pngbin42055 -> 12209 bytes
-rw-r--r--doc/ci/triggers/img/builds_page.pngbin20383 -> 20366 bytes
-rw-r--r--doc/ci/triggers/img/trigger_single_build.pngbin6585 -> 6584 bytes
-rw-r--r--doc/customization/branded_login_page/custom_sign_in.pngbin79288 -> 79276 bytes
-rw-r--r--doc/customization/branded_page_and_email_header/appearance.pngbin10253 -> 5625 bytes
-rw-r--r--doc/customization/branded_page_and_email_header/custom_brand_header.pngbin10014 -> 5279 bytes
-rw-r--r--doc/customization/branded_page_and_email_header/custom_email_header.pngbin37472 -> 14671 bytes
-rw-r--r--doc/customization/favicon/appearance.pngbin52245 -> 28933 bytes
-rw-r--r--doc/customization/favicon/custom_favicon.pngbin60083 -> 31600 bytes
-rw-r--r--doc/customization/new_project_page/appearance_settings.pngbin71178 -> 30473 bytes
-rw-r--r--doc/customization/new_project_page/custom_new_project_page.pngbin164962 -> 69523 bytes
-rw-r--r--doc/customization/new_project_page/default_new_project_page.pngbin146906 -> 62717 bytes
-rw-r--r--doc/development/README.md1
-rw-r--r--doc/development/architecture.md2
-rw-r--r--doc/development/documentation/img/manual_build_docs.pngbin14867 -> 14855 bytes
-rw-r--r--doc/development/fe_guide/img/boards_diagram.pngbin30538 -> 9518 bytes
-rw-r--r--doc/development/fe_guide/img/gl-modal.pngbin25893 -> 8767 bytes
-rw-r--r--doc/development/feature_flags.md12
-rw-r--r--doc/development/gitlab_architecture_diagram.pngbin61667 -> 34253 bytes
-rw-r--r--doc/development/img/trigger_ss1.pngbin106261 -> 35756 bytes
-rw-r--r--doc/development/img/trigger_ss2.pngbin106671 -> 36082 bytes
-rw-r--r--doc/development/ux_guide/img/button-close--active.pngbin1385 -> 1120 bytes
-rw-r--r--doc/development/ux_guide/img/button-close--hover.pngbin1015 -> 765 bytes
-rw-r--r--doc/development/ux_guide/img/button-close--resting.pngbin1271 -> 915 bytes
-rw-r--r--doc/development/ux_guide/img/button-danger--active.pngbin1450 -> 1117 bytes
-rw-r--r--doc/development/ux_guide/img/button-danger--hover.pngbin1095 -> 797 bytes
-rw-r--r--doc/development/ux_guide/img/button-danger--resting.pngbin1376 -> 932 bytes
-rw-r--r--doc/development/ux_guide/img/button-info--active.pngbin1442 -> 1109 bytes
-rw-r--r--doc/development/ux_guide/img/button-info--hover.pngbin1079 -> 795 bytes
-rw-r--r--doc/development/ux_guide/img/button-info--resting.pngbin1296 -> 930 bytes
-rw-r--r--doc/development/ux_guide/img/button-spam--active.pngbin1435 -> 1107 bytes
-rw-r--r--doc/development/ux_guide/img/button-spam--hover.pngbin1108 -> 777 bytes
-rw-r--r--doc/development/ux_guide/img/button-spam--resting.pngbin1377 -> 941 bytes
-rw-r--r--doc/development/ux_guide/img/button-success--active.pngbin1510 -> 1153 bytes
-rw-r--r--doc/development/ux_guide/img/button-success--hover.pngbin1151 -> 892 bytes
-rw-r--r--doc/development/ux_guide/img/button-success--resting.pngbin1447 -> 1045 bytes
-rw-r--r--doc/development/ux_guide/img/button-success-secondary--active.pngbin1466 -> 1107 bytes
-rw-r--r--doc/development/ux_guide/img/button-success-secondary--hover.pngbin1091 -> 774 bytes
-rw-r--r--doc/development/ux_guide/img/button-success-secondary--resting.pngbin1394 -> 945 bytes
-rw-r--r--doc/development/ux_guide/img/button-warning--active.pngbin1388 -> 1124 bytes
-rw-r--r--doc/development/ux_guide/img/button-warning--hover.pngbin1040 -> 790 bytes
-rw-r--r--doc/development/ux_guide/img/button-warning--resting.pngbin1296 -> 925 bytes
-rw-r--r--doc/development/ux_guide/img/color-blue.pngbin3555 -> 1751 bytes
-rw-r--r--doc/development/ux_guide/img/color-green.pngbin3852 -> 1916 bytes
-rw-r--r--doc/development/ux_guide/img/color-grey.pngbin3523 -> 1681 bytes
-rw-r--r--doc/development/ux_guide/img/color-orange.pngbin4480 -> 2094 bytes
-rw-r--r--doc/development/ux_guide/img/color-red.pngbin3550 -> 1739 bytes
-rw-r--r--doc/development/ux_guide/img/components-anchorlinks.pngbin30089 -> 16457 bytes
-rw-r--r--doc/development/ux_guide/img/components-coverblock.pngbin10141 -> 10110 bytes
-rw-r--r--doc/development/ux_guide/img/components-dateexact.pngbin4161 -> 4157 bytes
-rw-r--r--doc/development/ux_guide/img/components-fileholder.pngbin3938 -> 3884 bytes
-rw-r--r--doc/development/ux_guide/img/components-horizontalform.pngbin4327 -> 4310 bytes
-rw-r--r--doc/development/ux_guide/img/components-listinsidepanel.pngbin3449 -> 3380 bytes
-rw-r--r--doc/development/ux_guide/img/components-listwithhover.pngbin2860 -> 2722 bytes
-rw-r--r--doc/development/ux_guide/img/components-referencehover.pngbin6948 -> 6890 bytes
-rw-r--r--doc/development/ux_guide/img/components-referenceissues.pngbin10009 -> 10002 bytes
-rw-r--r--doc/development/ux_guide/img/components-referencelabels.pngbin4108 -> 4099 bytes
-rw-r--r--doc/development/ux_guide/img/components-referencemilestone.pngbin2417 -> 2412 bytes
-rw-r--r--doc/development/ux_guide/img/components-referencemrs.pngbin8859 -> 8857 bytes
-rw-r--r--doc/development/ux_guide/img/components-referencepeople.pngbin5607 -> 5600 bytes
-rw-r--r--doc/development/ux_guide/img/components-searchbox.pngbin5292 -> 3596 bytes
-rw-r--r--doc/development/ux_guide/img/components-searchboxscoped.pngbin9668 -> 6027 bytes
-rw-r--r--doc/development/ux_guide/img/components-simplelist.pngbin2781 -> 2776 bytes
-rw-r--r--doc/development/ux_guide/img/features-contextualnav.pngbin5912 -> 5911 bytes
-rw-r--r--doc/development/ux_guide/img/features-emptystates.pngbin61664 -> 61644 bytes
-rw-r--r--doc/development/ux_guide/img/icon-add.pngbin317 -> 239 bytes
-rw-r--r--doc/development/ux_guide/img/icon-close.pngbin501 -> 301 bytes
-rw-r--r--doc/development/ux_guide/img/icon-edit.pngbin546 -> 315 bytes
-rw-r--r--doc/development/ux_guide/img/icon-notification.pngbin543 -> 379 bytes
-rw-r--r--doc/development/ux_guide/img/icon-rss.pngbin834 -> 528 bytes
-rw-r--r--doc/development/ux_guide/img/icon-spec.pngbin13889 -> 7523 bytes
-rw-r--r--doc/development/ux_guide/img/icon-subscribe.pngbin760 -> 537 bytes
-rw-r--r--doc/development/ux_guide/img/icon-trash.pngbin398 -> 281 bytes
-rw-r--r--doc/development/ux_guide/img/illustrations-caps-do.pngbin3775 -> 3671 bytes
-rw-r--r--doc/development/ux_guide/img/illustrations-caps-don't.pngbin3922 -> 3624 bytes
-rw-r--r--doc/development/ux_guide/img/james-mackey.pngbin32552 -> 11869 bytes
-rw-r--r--doc/development/ux_guide/img/karolina-plaskaty.pngbin29553 -> 10355 bytes
-rw-r--r--doc/development/ux_guide/img/matthieu-poirier.pngbin32819 -> 11483 bytes
-rw-r--r--doc/development/ux_guide/img/modals-general-confimation-dialog.pngbin51205 -> 15650 bytes
-rw-r--r--doc/development/ux_guide/img/modals-layout-for-modals.pngbin68203 -> 20060 bytes
-rw-r--r--doc/development/ux_guide/img/modals-special-confimation-dialog.pngbin89978 -> 31419 bytes
-rw-r--r--doc/development/ux_guide/img/modals-three-buttons.pngbin54927 -> 17457 bytes
-rw-r--r--doc/development/ux_guide/img/nazim-ramesh.pngbin27475 -> 10488 bytes
-rw-r--r--doc/development/ux_guide/img/popover-placement-above.pngbin68451 -> 20184 bytes
-rw-r--r--doc/development/ux_guide/img/popover-placement-below.pngbin63368 -> 19967 bytes
-rw-r--r--doc/development/ux_guide/img/surfaces-contentitemtitle.pngbin5142 -> 5139 bytes
-rw-r--r--doc/development/ux_guide/img/surfaces-systeminformationblock.pngbin10423 -> 10422 bytes
-rw-r--r--doc/development/ux_guide/img/surfaces-ux.pngbin4029 -> 4017 bytes
-rw-r--r--doc/development/ux_guide/img/tooltip-placement.pngbin2071 -> 2066 bytes
-rw-r--r--doc/development/ux_guide/img/tooltip-usage.pngbin5994 -> 5985 bytes
-rw-r--r--doc/gitlab-basics/img/create_new_project_info.pngbin77490 -> 71608 bytes
-rw-r--r--doc/gitlab-basics/img/fork_new.pngbin10722 -> 10572 bytes
-rw-r--r--doc/gitlab-basics/img/merge_request_select_branch.pngbin16668 -> 16654 bytes
-rw-r--r--doc/gitlab-basics/img/profile_settings.pngbin5842 -> 2842 bytes
-rw-r--r--doc/gitlab-basics/img/profile_settings_ssh_keys_paste_pub.pngbin13447 -> 13436 bytes
-rw-r--r--doc/gitlab-basics/img/profile_settings_ssh_keys_single_key.pngbin24639 -> 10534 bytes
-rw-r--r--doc/gitlab-basics/img/profile_settings_ssh_keys_title.pngbin1872 -> 1867 bytes
-rw-r--r--doc/img/devops_lifecycle.pngbin65043 -> 18611 bytes
-rw-r--r--doc/install/google_cloud_platform/img/boot_disk.pngbin124175 -> 37786 bytes
-rw-r--r--doc/install/google_cloud_platform/img/first_signin.pngbin69516 -> 48215 bytes
-rw-r--r--doc/install/google_cloud_platform/img/gcp_landing.pngbin15025 -> 9978 bytes
-rw-r--r--doc/install/google_cloud_platform/img/launch_vm.pngbin47201 -> 33906 bytes
-rw-r--r--doc/install/google_cloud_platform/img/ssh_terminal.pngbin94161 -> 59212 bytes
-rw-r--r--doc/install/google_cloud_platform/img/vm_created.pngbin13809 -> 9903 bytes
-rw-r--r--doc/install/google_cloud_platform/img/vm_details.pngbin76519 -> 50191 bytes
-rw-r--r--doc/install/installation.md48
-rw-r--r--doc/install/kubernetes/gitlab_chart.md109
-rw-r--r--doc/install/kubernetes/gitlab_omnibus.md141
-rw-r--r--doc/install/kubernetes/index.md49
-rw-r--r--doc/install/kubernetes/preparation/connect.md18
-rw-r--r--doc/install/kubernetes/preparation/networking.md8
-rw-r--r--doc/install/kubernetes/preparation/rbac.md20
-rw-r--r--doc/install/kubernetes/preparation/tiller.md9
-rw-r--r--doc/install/openshift_and_gitlab/img/add-gitlab-to-project.pngbin37386 -> 14619 bytes
-rw-r--r--doc/install/openshift_and_gitlab/img/add-to-project.pngbin21672 -> 8901 bytes
-rw-r--r--doc/install/openshift_and_gitlab/img/create-project-ui.pngbin22290 -> 9151 bytes
-rw-r--r--doc/install/openshift_and_gitlab/img/gitlab-logs.pngbin70858 -> 26240 bytes
-rw-r--r--doc/install/openshift_and_gitlab/img/gitlab-overview.pngbin106432 -> 42908 bytes
-rw-r--r--doc/install/openshift_and_gitlab/img/gitlab-running.pngbin107993 -> 42045 bytes
-rw-r--r--doc/install/openshift_and_gitlab/img/gitlab-scale.pngbin36628 -> 15002 bytes
-rw-r--r--doc/install/openshift_and_gitlab/img/gitlab-settings.pngbin111366 -> 42221 bytes
-rw-r--r--doc/install/openshift_and_gitlab/img/no-resources.pngbin34669 -> 12465 bytes
-rw-r--r--doc/install/openshift_and_gitlab/img/openshift-infra-project.pngbin95725 -> 37117 bytes
-rw-r--r--doc/install/openshift_and_gitlab/img/pods-overview.pngbin106861 -> 42617 bytes
-rw-r--r--doc/install/openshift_and_gitlab/img/rc-name.pngbin51390 -> 20571 bytes
-rw-r--r--doc/install/openshift_and_gitlab/img/running-pods.pngbin29818 -> 11942 bytes
-rw-r--r--doc/install/openshift_and_gitlab/img/storage-volumes.pngbin49584 -> 20007 bytes
-rw-r--r--doc/install/openshift_and_gitlab/img/web-console.pngbin34774 -> 12717 bytes
-rw-r--r--doc/integration/img/bitbucket_oauth_keys.pngbin5149 -> 5146 bytes
-rw-r--r--doc/integration/img/enable_trello_powerup.pngbin17905 -> 17791 bytes
-rw-r--r--doc/integration/img/enabled-oauth-sign-in-sources.pngbin13304 -> 13303 bytes
-rw-r--r--doc/integration/img/facebook_api_keys.pngbin42308 -> 42290 bytes
-rw-r--r--doc/integration/img/facebook_website_url.pngbin9620 -> 9615 bytes
-rw-r--r--doc/integration/img/gitlab_app.pngbin56480 -> 32020 bytes
-rw-r--r--doc/integration/img/google_app.pngbin19168 -> 18853 bytes
-rw-r--r--doc/integration/img/oauth_provider_admin_application.pngbin17082 -> 17071 bytes
-rw-r--r--doc/integration/img/oauth_provider_application_form.pngbin12566 -> 12553 bytes
-rw-r--r--doc/integration/img/oauth_provider_application_id_secret.pngbin15293 -> 15280 bytes
-rw-r--r--doc/integration/img/oauth_provider_authorized_application.pngbin14668 -> 14657 bytes
-rw-r--r--doc/integration/img/submit_issue.pngbin45962 -> 45771 bytes
-rw-r--r--doc/integration/img/twitter_app_api_keys.pngbin24577 -> 24570 bytes
-rw-r--r--doc/monitoring/performance/img/grafana_dashboard_import.pngbin11836 -> 11835 bytes
-rw-r--r--doc/monitoring/performance/img/grafana_data_source_configuration.pngbin14700 -> 14695 bytes
-rw-r--r--doc/monitoring/performance/img/grafana_data_source_empty.pngbin11963 -> 11960 bytes
-rw-r--r--doc/monitoring/performance/img/grafana_save_icon.pngbin4619 -> 4598 bytes
-rw-r--r--doc/monitoring/performance/img/metrics_gitlab_configuration_settings.pngbin21387 -> 21382 bytes
-rw-r--r--doc/public_access/img/restrict_visibility_levels.pngbin24593 -> 18825 bytes
-rw-r--r--doc/raketasks/backup_hrz.pngbin11444 -> 11441 bytes
-rw-r--r--doc/security/img/outbound_requests_section.pngbin18064 -> 7314 bytes
-rw-r--r--doc/security/img/ssh_keys_restrictions_settings.pngbin68496 -> 19571 bytes
-rw-r--r--doc/security/img/two_factor_authentication_group_settings.pngbin44874 -> 19495 bytes
-rw-r--r--doc/security/img/two_factor_authentication_settings.pngbin9941 -> 9936 bytes
-rw-r--r--doc/topics/autodevops/img/guide_environments.pngbin8570 -> 8434 bytes
-rw-r--r--doc/topics/autodevops/img/guide_ide_commit.pngbin22035 -> 22029 bytes
-rw-r--r--doc/topics/git/numerous_undo_possibilities_in_git/img/branching.pngbin26245 -> 12744 bytes
-rw-r--r--doc/topics/git/numerous_undo_possibilities_in_git/img/rebase_reset.pngbin43609 -> 21836 bytes
-rw-r--r--doc/topics/git/numerous_undo_possibilities_in_git/img/revert.pngbin28112 -> 13243 bytes
-rw-r--r--doc/university/high-availability/aws/README.md2
-rw-r--r--doc/university/high-availability/aws/img/auto-scaling-det.pngbin29970 -> 29967 bytes
-rw-r--r--doc/university/high-availability/aws/img/db-subnet-group.pngbin29306 -> 29298 bytes
-rw-r--r--doc/university/high-availability/aws/img/ig.pngbin8149 -> 8140 bytes
-rw-r--r--doc/university/high-availability/aws/img/instance_specs.pngbin11525 -> 11522 bytes
-rw-r--r--doc/university/high-availability/aws/img/new_vpc.pngbin15696 -> 15691 bytes
-rw-r--r--doc/university/high-availability/aws/img/policies.pngbin39845 -> 39723 bytes
-rw-r--r--doc/university/high-availability/aws/img/rds-net-opt.pngbin16347 -> 16340 bytes
-rw-r--r--doc/university/high-availability/aws/img/rds-sec-group.pngbin11584 -> 11579 bytes
-rw-r--r--doc/university/high-availability/aws/img/reference-arch.pngbin183997 -> 0 bytes
-rw-r--r--doc/university/high-availability/aws/img/reference-arch2.pngbin0 -> 184033 bytes
-rw-r--r--doc/university/high-availability/aws/img/subnet.pngbin17077 -> 17070 bytes
-rw-r--r--doc/university/training/gitlab_flow/production_branch.pngbin7293 -> 7291 bytes
-rw-r--r--doc/university/training/gitlab_flow/release_branches.pngbin12775 -> 12765 bytes
-rw-r--r--doc/update/10.7-to-10.8.md20
-rw-r--r--doc/user/admin_area/monitoring/img/health_check_token.pngbin4923 -> 4863 bytes
-rw-r--r--doc/user/admin_area/settings/img/admin_area_default_artifacts_expiration.pngbin14656 -> 5360 bytes
-rw-r--r--doc/user/admin_area/settings/img/admin_area_maximum_artifacts_size.pngbin12917 -> 4771 bytes
-rw-r--r--doc/user/admin_area/settings/img/domain_blacklist.pngbin13606 -> 13601 bytes
-rw-r--r--doc/user/admin_area/settings/img/restricted_url.pngbin18202 -> 18191 bytes
-rw-r--r--doc/user/admin_area/settings/img/update-available.pngbin89748 -> 26769 bytes
-rw-r--r--doc/user/discussions/img/automatically_resolve_outdated_discussions.pngbin117604 -> 38001 bytes
-rw-r--r--doc/user/discussions/img/btn_new_issue_for_all_discussions.pngbin29007 -> 9555 bytes
-rw-r--r--doc/user/discussions/img/discussion_comment.pngbin57189 -> 37351 bytes
-rw-r--r--doc/user/discussions/img/discussion_lock_system_notes.pngbin50200 -> 14288 bytes
-rw-r--r--doc/user/discussions/img/discussion_view.pngbin73821 -> 73807 bytes
-rw-r--r--doc/user/discussions/img/lock_form_member.pngbin100581 -> 23780 bytes
-rw-r--r--doc/user/discussions/img/lock_form_non_member.pngbin37432 -> 8362 bytes
-rw-r--r--doc/user/discussions/img/new_issue_for_discussion.pngbin39563 -> 11324 bytes
-rw-r--r--doc/user/discussions/img/only_allow_merge_if_all_discussions_are_resolved_msg.pngbin4962 -> 4944 bytes
-rw-r--r--doc/user/discussions/img/preview_issue_for_discussion.pngbin82412 -> 26965 bytes
-rw-r--r--doc/user/discussions/img/preview_issue_for_discussions.pngbin143871 -> 35211 bytes
-rw-r--r--doc/user/discussions/img/resolve_comment_button.pngbin4722 -> 4713 bytes
-rw-r--r--doc/user/discussions/img/resolve_discussion_issue_notice.pngbin10307 -> 4186 bytes
-rw-r--r--doc/user/discussions/img/resolve_discussion_open_issue.pngbin20967 -> 7514 bytes
-rw-r--r--doc/user/discussions/img/turn_off_lock.pngbin31580 -> 9626 bytes
-rw-r--r--doc/user/discussions/img/turn_on_lock.pngbin34839 -> 10409 bytes
-rw-r--r--doc/user/group/img/add_new_members.pngbin67235 -> 18048 bytes
-rw-r--r--doc/user/group/img/create_new_group_info.pngbin105173 -> 30175 bytes
-rw-r--r--doc/user/group/img/create_new_project_from_group.pngbin3194 -> 3185 bytes
-rw-r--r--doc/user/group/img/group_settings.pngbin28821 -> 9704 bytes
-rw-r--r--doc/user/group/img/groups.pngbin249533 -> 62070 bytes
-rw-r--r--doc/user/group/img/membership_lock.pngbin17333 -> 4820 bytes
-rw-r--r--doc/user/group/img/new_group_form.pngbin114515 -> 32510 bytes
-rw-r--r--doc/user/group/img/new_group_from_groups.pngbin109302 -> 25256 bytes
-rw-r--r--doc/user/group/img/new_group_from_other_pages.pngbin90423 -> 21593 bytes
-rw-r--r--doc/user/group/img/request_access_button.pngbin35917 -> 35908 bytes
-rw-r--r--doc/user/group/img/select_group_dropdown.pngbin3489 -> 3482 bytes
-rw-r--r--doc/user/group/img/share_with_group_lock.pngbin21541 -> 7493 bytes
-rw-r--r--doc/user/group/img/withdraw_access_request_button.pngbin36413 -> 36393 bytes
-rw-r--r--doc/user/group/subgroups/img/group_members.pngbin48240 -> 18009 bytes
-rw-r--r--doc/user/group/subgroups/img/mention_subgroups.pngbin39666 -> 14783 bytes
-rw-r--r--doc/user/img/award_emoji_comment_picker.pngbin72883 -> 72847 bytes
-rw-r--r--doc/user/img/award_emoji_select.pngbin17827 -> 17554 bytes
-rw-r--r--doc/user/img/award_emoji_votes_sort_options.pngbin99941 -> 40489 bytes
-rw-r--r--doc/user/img/markdown_logo.pngbin4421 -> 4398 bytes
-rw-r--r--doc/user/instance_statistics/img/convdev_index.pngbin316893 -> 86358 bytes
-rw-r--r--doc/user/profile/img/active_sessions_list.pngbin41649 -> 22266 bytes
-rw-r--r--doc/user/profile/img/personal_access_tokens.pngbin18555 -> 18553 bytes
-rw-r--r--doc/user/profile/img/profil-preferences-navigation-theme.pngbin16403 -> 16397 bytes
-rw-r--r--doc/user/project/clusters/eks_and_gitlab/img/add_cluster.pngbin77046 -> 59516 bytes
-rw-r--r--doc/user/project/clusters/eks_and_gitlab/img/create_dns.pngbin29185 -> 23923 bytes
-rw-r--r--doc/user/project/clusters/eks_and_gitlab/img/create_project.pngbin43429 -> 30568 bytes
-rw-r--r--doc/user/project/clusters/eks_and_gitlab/img/deploy_apps.pngbin115299 -> 82157 bytes
-rw-r--r--doc/user/project/clusters/eks_and_gitlab/img/environment.pngbin31644 -> 20339 bytes
-rw-r--r--doc/user/project/clusters/eks_and_gitlab/img/new_project.pngbin10309 -> 7813 bytes
-rw-r--r--doc/user/project/clusters/eks_and_gitlab/img/pipeline.pngbin26500 -> 15288 bytes
-rw-r--r--doc/user/project/deploy_tokens/img/deploy_tokens.pngbin75650 -> 23087 bytes
-rw-r--r--doc/user/project/img/bulk-editing.pngbin197686 -> 197667 bytes
-rw-r--r--doc/user/project/img/cycle_analytics_landing_page.pngbin42117 -> 42114 bytes
-rw-r--r--doc/user/project/img/issue_board_assignee_lists.pngbin134674 -> 134635 bytes
-rw-r--r--doc/user/project/img/issue_board_creation.pngbin108674 -> 108615 bytes
-rw-r--r--doc/user/project/img/issue_board_edit_button.pngbin108168 -> 108114 bytes
-rw-r--r--doc/user/project/img/issue_board_move_issue_card_list.pngbin13670 -> 13592 bytes
-rw-r--r--doc/user/project/img/issue_board_view_scope.pngbin63542 -> 63529 bytes
-rw-r--r--doc/user/project/img/issue_boards_add_issues_modal.pngbin12421 -> 12415 bytes
-rw-r--r--doc/user/project/img/issue_boards_multiple.pngbin6092 -> 6086 bytes
-rw-r--r--doc/user/project/img/issue_boards_remove_issue.pngbin39357 -> 39347 bytes
-rw-r--r--doc/user/project/img/koding_build-in-progress.pngbin21953 -> 21937 bytes
-rw-r--r--doc/user/project/img/koding_build-success.pngbin73008 -> 73005 bytes
-rw-r--r--doc/user/project/img/koding_commit-koding.yml.pngbin86043 -> 86023 bytes
-rw-r--r--doc/user/project/img/koding_edit-on-ide.pngbin90701 -> 90638 bytes
-rw-r--r--doc/user/project/img/koding_enable-koding.pngbin20303 -> 20291 bytes
-rw-r--r--doc/user/project/img/koding_landing.pngbin81010 -> 80985 bytes
-rw-r--r--doc/user/project/img/koding_run-in-ide.pngbin22179 -> 22178 bytes
-rw-r--r--doc/user/project/img/koding_stack-import.pngbin137608 -> 137582 bytes
-rw-r--r--doc/user/project/img/koding_start-build.pngbin27926 -> 27925 bytes
-rw-r--r--doc/user/project/img/labels_generate_default.pngbin65549 -> 25797 bytes
-rw-r--r--doc/user/project/img/labels_group_issues.pngbin264573 -> 92070 bytes
-rw-r--r--doc/user/project/img/labels_list.pngbin207736 -> 71323 bytes
-rw-r--r--doc/user/project/img/labels_prioritized.pngbin156020 -> 56353 bytes
-rw-r--r--doc/user/project/img/labels_project_list_search.pngbin175669 -> 100066 bytes
-rw-r--r--doc/user/project/img/labels_promotion.pngbin121824 -> 44021 bytes
-rw-r--r--doc/user/project/img/labels_sidebar.pngbin31123 -> 12109 bytes
-rw-r--r--doc/user/project/img/labels_sidebar_assign.pngbin28033 -> 11024 bytes
-rw-r--r--doc/user/project/img/labels_sidebar_inline.pngbin28423 -> 11083 bytes
-rw-r--r--doc/user/project/img/labels_sort_label_priority.pngbin110154 -> 42263 bytes
-rw-r--r--doc/user/project/img/labels_sort_priority.pngbin108780 -> 41486 bytes
-rw-r--r--doc/user/project/img/labels_subscriptions.pngbin87502 -> 31716 bytes
-rw-r--r--doc/user/project/img/priority_sort_order.pngbin102242 -> 69978 bytes
-rw-r--r--doc/user/project/img/project_overview_badges.pngbin40188 -> 12486 bytes
-rw-r--r--doc/user/project/img/project_repository_settings.pngbin17872 -> 7511 bytes
-rw-r--r--doc/user/project/img/protected_branches_delete.pngbin21510 -> 21507 bytes
-rw-r--r--doc/user/project/img/protected_branches_devs_can_push.pngbin34888 -> 11221 bytes
-rw-r--r--doc/user/project/img/protected_branches_error_ui.pngbin13125 -> 13117 bytes
-rw-r--r--doc/user/project/img/protected_branches_list.pngbin6937 -> 6933 bytes
-rw-r--r--doc/user/project/img/protected_branches_page.pngbin7205 -> 7199 bytes
-rw-r--r--doc/user/project/img/protected_tag_matches.pngbin85305 -> 23054 bytes
-rw-r--r--doc/user/project/img/protected_tags_list.pngbin24490 -> 7227 bytes
-rw-r--r--doc/user/project/img/protected_tags_page.pngbin56112 -> 13813 bytes
-rw-r--r--doc/user/project/img/protected_tags_permissions_dropdown.pngbin26514 -> 7770 bytes
-rw-r--r--doc/user/project/import/img/bitbucket_server_import_credentials.pngbin40566 -> 13781 bytes
-rw-r--r--doc/user/project/import/img/bitbucket_server_import_select_project.pngbin56750 -> 19427 bytes
-rw-r--r--doc/user/project/import/img/fogbugz_import_login.pngbin13751 -> 13452 bytes
-rw-r--r--doc/user/project/import/img/fogbugz_import_select_fogbogz.pngbin12289 -> 12283 bytes
-rw-r--r--doc/user/project/import/img/fogbugz_import_select_project.pngbin20905 -> 20335 bytes
-rw-r--r--doc/user/project/import/img/import_projects_from_gitea_new_import.pngbin15561 -> 15518 bytes
-rw-r--r--doc/user/project/import/img/import_projects_from_github_select_auth_method.pngbin17612 -> 17611 bytes
-rw-r--r--doc/user/project/import/img/import_projects_from_new_project_page.pngbin81639 -> 30489 bytes
-rw-r--r--doc/user/project/integrations/img/hangouts_chat_configuration.pngbin101788 -> 44655 bytes
-rw-r--r--doc/user/project/integrations/img/issue_configuration.pngbin20288 -> 11882 bytes
-rw-r--r--doc/user/project/integrations/img/jira_group_access.pngbin19235 -> 19147 bytes
-rw-r--r--doc/user/project/integrations/img/jira_project_name.pngbin26685 -> 26680 bytes
-rw-r--r--doc/user/project/integrations/img/jira_project_settings.pngbin32791 -> 14149 bytes
-rw-r--r--doc/user/project/integrations/img/jira_service.pngbin37869 -> 36976 bytes
-rw-r--r--doc/user/project/integrations/img/jira_service_close_comment.pngbin11893 -> 11890 bytes
-rw-r--r--doc/user/project/integrations/img/jira_service_page.pngbin193364 -> 47533 bytes
-rw-r--r--doc/user/project/integrations/img/jira_user_management_link.pngbin23921 -> 23906 bytes
-rw-r--r--doc/user/project/integrations/img/mattermost_bot_auth.pngbin8676 -> 8669 bytes
-rw-r--r--doc/user/project/integrations/img/mattermost_bot_available_commands.pngbin4647 -> 4642 bytes
-rw-r--r--doc/user/project/integrations/img/mattermost_configuration.pngbin249592 -> 101151 bytes
-rw-r--r--doc/user/project/integrations/img/mattermost_console_integrations.pngbin314642 -> 114618 bytes
-rw-r--r--doc/user/project/integrations/img/mattermost_gitlab_token.pngbin3688 -> 3673 bytes
-rw-r--r--doc/user/project/integrations/img/mattermost_goto_console.pngbin7754 -> 7746 bytes
-rw-r--r--doc/user/project/integrations/img/mattermost_slash_command_configuration.pngbin24169 -> 24162 bytes
-rw-r--r--doc/user/project/integrations/img/mattermost_team_integrations.pngbin4766 -> 4757 bytes
-rw-r--r--doc/user/project/integrations/img/merge_request_performance.pngbin60194 -> 40917 bytes
-rw-r--r--doc/user/project/integrations/img/microsoft_teams_configuration.pngbin350592 -> 96509 bytes
-rw-r--r--doc/user/project/integrations/img/project_services.pngbin25753 -> 11109 bytes
-rw-r--r--doc/user/project/integrations/img/prometheus_dashboard.pngbin26112 -> 12650 bytes
-rw-r--r--doc/user/project/integrations/img/prometheus_deploy.pngbin27258 -> 8413 bytes
-rw-r--r--doc/user/project/integrations/img/prometheus_yaml_deploy.pngbin23567 -> 9456 bytes
-rw-r--r--doc/user/project/integrations/img/redmine_configuration.pngbin10266 -> 10254 bytes
-rw-r--r--doc/user/project/integrations/img/services_templates_redmine_example.pngbin8608 -> 8336 bytes
-rw-r--r--doc/user/project/integrations/img/slack_configuration.pngbin229050 -> 92179 bytes
-rw-r--r--doc/user/project/integrations/img/webhook_logs.pngbin132319 -> 38687 bytes
-rw-r--r--doc/user/project/integrations/img/webhook_testing.pngbin191267 -> 55578 bytes
-rw-r--r--doc/user/project/integrations/img/webhooks_ssl.pngbin27799 -> 27790 bytes
-rw-r--r--doc/user/project/issues/img/confidential_issues_index_page.pngbin107117 -> 30634 bytes
-rw-r--r--doc/user/project/issues/img/delete_issue.pngbin49894 -> 13973 bytes
-rw-r--r--doc/user/project/issues/img/due_dates_create.pngbin6992 -> 6895 bytes
-rw-r--r--doc/user/project/issues/img/group_issues_list_view.pngbin127781 -> 46595 bytes
-rw-r--r--doc/user/project/issues/img/issue_board.pngbin56253 -> 55931 bytes
-rw-r--r--doc/user/project/issues/img/issue_template.pngbin25022 -> 25019 bytes
-rw-r--r--doc/user/project/issues/img/new_issue_from_email.pngbin13461 -> 4259 bytes
-rw-r--r--doc/user/project/issues/img/new_issue_from_issue_board.pngbin57427 -> 20063 bytes
-rw-r--r--doc/user/project/issues/img/new_issue_from_projects_dashboard.pngbin23685 -> 9674 bytes
-rw-r--r--doc/user/project/issues/img/project_issues_list_view.pngbin196071 -> 77189 bytes
-rw-r--r--doc/user/project/issues/img/sidebar_confidential_issue.pngbin10210 -> 4648 bytes
-rw-r--r--doc/user/project/issues/img/sidebar_move_issue.pngbin50132 -> 50003 bytes
-rw-r--r--doc/user/project/issues/img/sidebar_not_confidential_issue.pngbin8163 -> 4081 bytes
-rw-r--r--doc/user/project/issues/img/turn_off_confidentiality.pngbin27307 -> 10851 bytes
-rw-r--r--doc/user/project/issues/img/turn_on_confidentiality.pngbin33499 -> 13513 bytes
-rw-r--r--doc/user/project/members/img/access_requests_management.pngbin11018 -> 11005 bytes
-rw-r--r--doc/user/project/members/img/add_new_user_to_project_settings.pngbin11046 -> 11004 bytes
-rw-r--r--doc/user/project/members/img/add_user_email_accept.pngbin16890 -> 16878 bytes
-rw-r--r--doc/user/project/members/img/add_user_import_members_from_another_project.pngbin25343 -> 25333 bytes
-rw-r--r--doc/user/project/members/img/add_user_members_menu.pngbin28994 -> 28988 bytes
-rw-r--r--doc/user/project/members/img/max_access_level.pngbin34718 -> 34710 bytes
-rw-r--r--doc/user/project/members/img/request_access_button.pngbin25281 -> 25271 bytes
-rw-r--r--doc/user/project/members/img/withdraw_access_request_button.pngbin26135 -> 26123 bytes
-rw-r--r--doc/user/project/merge_requests/img/allow_collaboration.pngbin39513 -> 21522 bytes
-rw-r--r--doc/user/project/merge_requests/img/cherry_pick_changes_commit.pngbin13604 -> 13568 bytes
-rw-r--r--doc/user/project/merge_requests/img/cherry_pick_changes_mr.pngbin16494 -> 7214 bytes
-rw-r--r--doc/user/project/merge_requests/img/create_from_email.pngbin152975 -> 55777 bytes
-rw-r--r--doc/user/project/merge_requests/img/merge_conflict_editor.pngbin50422 -> 50286 bytes
-rw-r--r--doc/user/project/merge_requests/img/merge_request.pngbin748131 -> 386345 bytes
-rw-r--r--doc/user/project/merge_requests/img/merge_request_diff_file_navigation.pngbin244736 -> 112288 bytes
-rw-r--r--doc/user/project/merge_requests/img/merge_request_widget.pngbin11039 -> 11036 bytes
-rw-r--r--doc/user/project/merge_requests/img/merge_when_pipeline_succeeds_enable.pngbin22791 -> 10186 bytes
-rw-r--r--doc/user/project/merge_requests/img/merge_when_pipeline_succeeds_only_if_succeeds_msg.pngbin5251 -> 5237 bytes
-rw-r--r--doc/user/project/merge_requests/img/merge_when_pipeline_succeeds_only_if_succeeds_settings.pngbin25783 -> 6491 bytes
-rw-r--r--doc/user/project/merge_requests/img/merge_when_pipeline_succeeds_status.pngbin69953 -> 21397 bytes
-rw-r--r--doc/user/project/merge_requests/img/project_merge_requests_list_view.pngbin325819 -> 171866 bytes
-rw-r--r--doc/user/project/merge_requests/img/remove_source_branch_status.pngbin32649 -> 32586 bytes
-rw-r--r--doc/user/project/merge_requests/img/revert_changes_commit.pngbin95655 -> 95647 bytes
-rw-r--r--doc/user/project/merge_requests/img/revert_changes_mr.pngbin104972 -> 104954 bytes
-rw-r--r--doc/user/project/merge_requests/img/squash_edit_form.pngbin4232 -> 4231 bytes
-rw-r--r--doc/user/project/merge_requests/img/squash_mr_commits.pngbin85635 -> 31491 bytes
-rw-r--r--doc/user/project/merge_requests/img/squash_mr_widget.pngbin6496 -> 3573 bytes
-rw-r--r--doc/user/project/merge_requests/img/squash_squashed_commit.pngbin63371 -> 23726 bytes
-rw-r--r--doc/user/project/merge_requests/img/versions.pngbin23629 -> 22763 bytes
-rw-r--r--doc/user/project/merge_requests/img/versions_compare.pngbin17228 -> 17017 bytes
-rw-r--r--doc/user/project/merge_requests/img/versions_dropdown.pngbin13887 -> 13827 bytes
-rw-r--r--doc/user/project/merge_requests/img/versions_system_note.pngbin7136 -> 7126 bytes
-rw-r--r--doc/user/project/merge_requests/img/wip_blocked_accept_button.pngbin8071 -> 4152 bytes
-rw-r--r--doc/user/project/merge_requests/img/wip_mark_as_wip.pngbin17081 -> 7961 bytes
-rw-r--r--doc/user/project/merge_requests/img/wip_unmark_as_wip.pngbin18585 -> 8424 bytes
-rw-r--r--doc/user/project/milestones/img/milestones_new_group_milestone.pngbin276831 -> 144554 bytes
-rw-r--r--doc/user/project/milestones/img/milestones_new_project_milestone.pngbin257285 -> 133541 bytes
-rw-r--r--doc/user/project/milestones/img/milestones_project_milestone_page.pngbin489382 -> 270005 bytes
-rw-r--r--doc/user/project/milestones/img/milestones_promote_milestone.pngbin76864 -> 49288 bytes
-rw-r--r--doc/user/project/pages/img/dns_add_new_a_record_example_updated_2018.pngbin7704 -> 3701 bytes
-rw-r--r--doc/user/project/pages/img/pages_create_project.pngbin6063 -> 6062 bytes
-rw-r--r--doc/user/project/pages/img/pages_dns_details.pngbin5351 -> 5350 bytes
-rw-r--r--doc/user/project/pages/img/pages_multiple_domains.pngbin12936 -> 12930 bytes
-rw-r--r--doc/user/project/pages/img/pages_remove.pngbin3810 -> 3777 bytes
-rw-r--r--doc/user/project/pages/img/pages_upload_cert.pngbin22907 -> 22888 bytes
-rw-r--r--doc/user/project/pages/img/verify_your_domain.pngbin30163 -> 12082 bytes
-rw-r--r--doc/user/project/pipelines/img/job_artifacts_pipelines_page.pngbin16550 -> 16403 bytes
-rw-r--r--doc/user/project/pipelines/img/pipeline_schedule_play.pngbin39142 -> 11400 bytes
-rw-r--r--doc/user/project/pipelines/img/pipeline_schedule_variables.pngbin13478 -> 5360 bytes
-rw-r--r--doc/user/project/pipelines/img/pipeline_schedules_list.pngbin38034 -> 12948 bytes
-rw-r--r--doc/user/project/pipelines/img/pipeline_schedules_new_form.pngbin72501 -> 23290 bytes
-rw-r--r--doc/user/project/pipelines/img/pipeline_schedules_ownership.pngbin12043 -> 5004 bytes
-rw-r--r--doc/user/project/repository/branches/img/delete_merged_branches.pngbin42891 -> 42886 bytes
-rw-r--r--doc/user/project/repository/gpg_signed_commits/img/profile_settings_gpg_keys_paste_pub.pngbin24514 -> 13008 bytes
-rw-r--r--doc/user/project/repository/gpg_signed_commits/img/profile_settings_gpg_keys_single_key.pngbin4403 -> 4366 bytes
-rw-r--r--doc/user/project/repository/gpg_signed_commits/img/project_signed_and_unsigned_commits.pngbin113801 -> 42290 bytes
-rw-r--r--doc/user/project/repository/gpg_signed_commits/img/project_signed_commit_unverified_signature.pngbin12924 -> 7188 bytes
-rw-r--r--doc/user/project/repository/gpg_signed_commits/img/project_signed_commit_verified_signature.pngbin20652 -> 9771 bytes
-rw-r--r--doc/user/project/repository/img/compare_branches.pngbin206831 -> 131046 bytes
-rw-r--r--doc/user/project/repository/img/repository_languages.pngbin88244 -> 26516 bytes
-rw-r--r--doc/user/project/repository/img/web_editor_new_branch_dropdown.pngbin10386 -> 10324 bytes
-rw-r--r--doc/user/project/repository/img/web_editor_new_branch_from_issue.pngbin2720 -> 2715 bytes
-rw-r--r--doc/user/project/repository/img/web_editor_new_branch_page.pngbin6034 -> 5886 bytes
-rw-r--r--doc/user/project/repository/img/web_editor_new_directory_dialog.pngbin7323 -> 7157 bytes
-rw-r--r--doc/user/project/repository/img/web_editor_new_directory_dropdown.pngbin9918 -> 9916 bytes
-rw-r--r--doc/user/project/repository/img/web_editor_new_file_dropdown.pngbin10233 -> 10152 bytes
-rw-r--r--doc/user/project/repository/img/web_editor_new_push_widget.pngbin3395 -> 3388 bytes
-rw-r--r--doc/user/project/repository/img/web_editor_new_tag_dropdown.pngbin9796 -> 9706 bytes
-rw-r--r--doc/user/project/repository/img/web_editor_start_new_merge_request.pngbin4060 -> 4049 bytes
-rw-r--r--doc/user/project/repository/img/web_editor_template_dropdown_buttons.pngbin5634 -> 5629 bytes
-rw-r--r--doc/user/project/repository/img/web_editor_template_dropdown_first_file.pngbin8846 -> 8844 bytes
-rw-r--r--doc/user/project/repository/img/web_editor_upload_file_dialog.pngbin12558 -> 12553 bytes
-rw-r--r--doc/user/project/repository/img/web_editor_upload_file_dropdown.pngbin10291 -> 10200 bytes
-rw-r--r--doc/user/project/settings/img/import_export_download_export.pngbin24482 -> 24397 bytes
-rw-r--r--doc/user/project/settings/img/import_export_export_button.pngbin24122 -> 24118 bytes
-rw-r--r--doc/user/project/settings/img/import_export_new_project.pngbin13083 -> 13082 bytes
-rw-r--r--doc/user/project/settings/img/import_export_select_file.pngbin13713 -> 13514 bytes
-rw-r--r--doc/user/project/settings/img/settings_edit_button.pngbin6901 -> 6897 bytes
-rw-r--r--doc/user/project/settings/img/sharing_and_permissions_settings.pngbin143341 -> 50602 bytes
-rw-r--r--doc/user/project/web_ide/img/open_web_ide.pngbin28574 -> 28571 bytes
-rw-r--r--doc/user/project/wiki/img/wiki_create_home_page.pngbin12422 -> 12421 bytes
-rw-r--r--doc/user/project/wiki/img/wiki_create_new_page.pngbin38105 -> 14957 bytes
-rw-r--r--doc/user/project/wiki/img/wiki_create_new_page_modal.pngbin13189 -> 5831 bytes
-rw-r--r--doc/user/project/wiki/img/wiki_move_page_1.pngbin54550 -> 17270 bytes
-rw-r--r--doc/user/project/wiki/img/wiki_move_page_2.pngbin33535 -> 10571 bytes
-rw-r--r--doc/user/project/wiki/img/wiki_page_history.pngbin26478 -> 12101 bytes
-rw-r--r--doc/user/project/wiki/img/wiki_sidebar.pngbin7440 -> 3178 bytes
-rw-r--r--doc/user/search/img/issue_search_by_term.pngbin127492 -> 35648 bytes
-rw-r--r--doc/user/search/img/issue_search_filter.pngbin69559 -> 27091 bytes
-rw-r--r--doc/user/search/img/issues_mrs_shortcut.pngbin61888 -> 26706 bytes
-rw-r--r--doc/user/search/img/project_search.pngbin89002 -> 42139 bytes
-rw-r--r--doc/workflow/ci_mr.pngbin12034 -> 12024 bytes
-rw-r--r--doc/workflow/environment_branches.pngbin12364 -> 12354 bytes
-rw-r--r--doc/workflow/forking/branch_select.pngbin15424 -> 15410 bytes
-rw-r--r--doc/workflow/forking/merge_request.pngbin16332 -> 16329 bytes
-rw-r--r--doc/workflow/git_pull.pngbin28749 -> 28701 bytes
-rw-r--r--doc/workflow/gitlab_flow.pngbin47432 -> 47430 bytes
-rw-r--r--doc/workflow/good_commit.pngbin8742 -> 8740 bytes
-rw-r--r--doc/workflow/img/file_finder_find_button.pngbin14567 -> 14565 bytes
-rw-r--r--doc/workflow/img/forking_workflow_fork_button.pngbin12973 -> 12962 bytes
-rw-r--r--doc/workflow/img/forking_workflow_path_taken_error.pngbin10103 -> 10092 bytes
-rw-r--r--doc/workflow/img/notification_group_settings.pngbin171784 -> 54362 bytes
-rw-r--r--doc/workflow/img/notification_project_settings.pngbin167548 -> 58864 bytes
-rw-r--r--doc/workflow/img/todo_list_item.pngbin18777 -> 18776 bytes
-rw-r--r--doc/workflow/img/todos_add_todo_sidebar.pngbin42360 -> 17524 bytes
-rw-r--r--doc/workflow/img/todos_mark_done_sidebar.pngbin42317 -> 17619 bytes
-rw-r--r--doc/workflow/merge_request.pngbin47240 -> 47225 bytes
-rw-r--r--doc/workflow/messy_flow.pngbin11665 -> 11663 bytes
-rw-r--r--doc/workflow/mr_inline_comments.pngbin52519 -> 52503 bytes
-rw-r--r--doc/workflow/production_branch.pngbin7264 -> 7262 bytes
-rw-r--r--doc/workflow/rebase.pngbin29009 -> 28939 bytes
-rw-r--r--doc/workflow/release_branches.pngbin12746 -> 12736 bytes
-rw-r--r--doc/workflow/releases/new_tag.pngbin42456 -> 42439 bytes
-rw-r--r--doc/workflow/repository_mirroring/repository_mirroring_detect_host_keys.pngbin61463 -> 22952 bytes
-rw-r--r--doc/workflow/repository_mirroring/repository_mirroring_diverged_branch_push.pngbin9512 -> 9509 bytes
-rw-r--r--doc/workflow/repository_mirroring/repository_mirroring_hard_failed_main.pngbin47943 -> 15555 bytes
-rw-r--r--doc/workflow/repository_mirroring/repository_mirroring_hard_failed_settings.pngbin53279 -> 16414 bytes
-rw-r--r--doc/workflow/repository_mirroring/repository_mirroring_pull_advanced_host_keys.pngbin115796 -> 40414 bytes
-rw-r--r--doc/workflow/repository_mirroring/repository_mirroring_pull_settings.pngbin100470 -> 39909 bytes
-rw-r--r--doc/workflow/repository_mirroring/repository_mirroring_pull_settings_for_ssh.pngbin69467 -> 26234 bytes
-rw-r--r--doc/workflow/repository_mirroring/repository_mirroring_ssh_host_keys_verified.pngbin23724 -> 9343 bytes
-rw-r--r--doc/workflow/repository_mirroring/repository_mirroring_ssh_public_key_authentication.pngbin82456 -> 27440 bytes
-rw-r--r--doc/workflow/time-tracking/time-tracking-example.pngbin48350 -> 14564 bytes
-rw-r--r--doc/workflow/time-tracking/time-tracking-sidebar.pngbin19467 -> 9068 bytes
-rw-r--r--lib/api/api.rb9
-rw-r--r--lib/api/award_emoji.rb2
-rw-r--r--lib/api/entities.rb6
-rw-r--r--lib/api/files.rb2
-rw-r--r--lib/api/group_milestones.rb14
-rw-r--r--lib/api/helpers/notes_helpers.rb5
-rw-r--r--lib/api/issues.rb11
-rw-r--r--lib/api/project_milestones.rb3
-rw-r--r--lib/api/project_snippets.rb4
-rw-r--r--lib/api/projects.rb2
-rw-r--r--lib/api/protected_tags.rb79
-rw-r--r--lib/banzai/reference_parser/merge_request_parser.rb5
-rw-r--r--lib/feature.rb3
-rw-r--r--lib/gitlab/auth/ldap/access.rb24
-rw-r--r--lib/gitlab/auth/o_auth/provider.rb1
-rw-r--r--lib/gitlab/bitbucket_server_import/importer.rb18
-rw-r--r--lib/gitlab/ci/status/build/failed.rb2
-rw-r--r--lib/gitlab/diff/highlight.rb2
-rw-r--r--lib/gitlab/diff/line.rb9
-rw-r--r--lib/gitlab/github_import.rb18
-rw-r--r--lib/gitlab/github_import/importer/issue_importer.rb4
-rw-r--r--lib/gitlab/github_import/importer/pull_request_importer.rb92
-rw-r--r--lib/gitlab/i18n.rb1
-rw-r--r--lib/gitlab/import/database_helpers.rb25
-rw-r--r--lib/gitlab/import/merge_request_creator.rb40
-rw-r--r--lib/gitlab/import/merge_request_helpers.rb70
-rw-r--r--lib/gitlab/import_export/uploads_manager.rb19
-rw-r--r--lib/gitlab/middleware/multipart.rb10
-rw-r--r--lib/gitlab/path_regex.rb1
-rw-r--r--lib/gitlab/url_blocker.rb8
-rw-r--r--lib/gitlab/usage_data.rb3
-rw-r--r--lib/tasks/gettext.rake13
-rw-r--r--locale/gitlab.pot49
-rw-r--r--package.json2
-rw-r--r--qa/qa.rb1
-rw-r--r--qa/qa/page/project/import/github.rb2
-rw-r--r--qa/qa/scenario/template.rb8
-rw-r--r--qa/qa/scenario/test/instance.rb41
-rw-r--r--qa/qa/scenario/test/integration/github.rb2
-rw-r--r--qa/qa/scenario/test/integration/kubernetes.rb2
-rw-r--r--qa/qa/scenario/test/integration/ldap.rb2
-rw-r--r--qa/qa/scenario/test/integration/mattermost.rb2
-rw-r--r--qa/qa/specs/features/api/1_manage/.gitkeep0
-rw-r--r--qa/qa/specs/features/api/1_manage/users_spec.rb (renamed from qa/qa/specs/features/api/users_spec.rb)26
-rw-r--r--qa/qa/specs/features/api/2_plan/.gitkeep0
-rw-r--r--qa/qa/specs/features/api/3_create/repository/files_spec.rb (renamed from qa/qa/specs/features/api/basics_spec.rb)0
-rw-r--r--qa/qa/specs/features/api/4_verify/.gitkeep0
-rw-r--r--qa/qa/specs/features/api/5_package/.gitkeep0
-rw-r--r--qa/qa/specs/features/api/6_release/.gitkeep0
-rw-r--r--qa/qa/specs/features/api/7_configure/.gitkeep0
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/login/log_in_spec.rb17
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/login/log_into_gitlab_via_ldap_spec.rb23
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/login/log_into_mattermost_via_gitlab_spec.rb21
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/project/create_project_spec.rb26
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/project/import_github_repo_spec.rb110
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/project/view_project_activity_spec.rb24
-rw-r--r--qa/qa/specs/features/browser_ui/2_plan/issue/create_issue_spec.rb50
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/merge_request/create_merge_request_spec.rb57
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/merge_request/merge_merge_request_from_fork_spec.rb25
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/merge_request/rebase_merge_request_spec.rb45
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/merge_request/squash_merge_request_spec.rb54
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/repository/clone_spec.rb (renamed from qa/qa/specs/features/repository/clone_spec.rb)6
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/repository/create_edit_delete_file_via_web_spec.rb58
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/repository/push_over_http_spec.rb (renamed from qa/qa/specs/features/repository/push_spec.rb)6
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/repository/push_protected_branch_spec.rb70
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/wiki/create_edit_clone_push_wiki_spec.rb49
-rw-r--r--qa/qa/specs/features/browser_ui/4_verify/pipeline/create_and_process_pipeline_spec.rb87
-rw-r--r--qa/qa/specs/features/browser_ui/4_verify/runner/register_runner_spec.rb32
-rw-r--r--qa/qa/specs/features/browser_ui/4_verify/secret_variable/add_secret_variable_spec.rb28
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/.gitkeep0
-rw-r--r--qa/qa/specs/features/browser_ui/6_release/deploy_key/add_deploy_key_spec.rb23
-rw-r--r--qa/qa/specs/features/browser_ui/6_release/deploy_key/clone_using_deploy_key_spec.rb109
-rw-r--r--qa/qa/specs/features/browser_ui/7_configure/auto_devops/create_project_with_auto_devops_spec.rb68
-rw-r--r--qa/qa/specs/features/browser_ui/7_configure/mattermost/create_group_with_mattermost_team_spec.rb21
-rw-r--r--qa/qa/specs/features/login/basic_spec.rb15
-rw-r--r--qa/qa/specs/features/login/ldap_spec.rb19
-rw-r--r--qa/qa/specs/features/mattermost/group_create_spec.rb17
-rw-r--r--qa/qa/specs/features/mattermost/login_spec.rb17
-rw-r--r--qa/qa/specs/features/merge_request/create_spec.rb53
-rw-r--r--qa/qa/specs/features/merge_request/rebase_spec.rb39
-rw-r--r--qa/qa/specs/features/merge_request/squash_spec.rb50
-rw-r--r--qa/qa/specs/features/project/activity_spec.rb20
-rw-r--r--qa/qa/specs/features/project/add_deploy_key_spec.rb19
-rw-r--r--qa/qa/specs/features/project/add_secret_variable_spec.rb24
-rw-r--r--qa/qa/specs/features/project/auto_devops_spec.rb64
-rw-r--r--qa/qa/specs/features/project/create_issue_spec.rb46
-rw-r--r--qa/qa/specs/features/project/create_spec.rb22
-rw-r--r--qa/qa/specs/features/project/deploy_key_clone_spec.rb105
-rw-r--r--qa/qa/specs/features/project/file_spec.rb54
-rw-r--r--qa/qa/specs/features/project/fork_project_spec.rb21
-rw-r--r--qa/qa/specs/features/project/import_from_github_spec.rb106
-rw-r--r--qa/qa/specs/features/project/pipelines_spec.rb102
-rw-r--r--qa/qa/specs/features/project/wikis_spec.rb45
-rw-r--r--qa/qa/specs/features/repository/protected_branches_spec.rb66
-rw-r--r--qa/spec/runtime/env_spec.rb4
-rw-r--r--qa/spec/scenario/test/instance/all_spec.rb8
-rw-r--r--qa/spec/scenario/test/instance/smoke_spec.rb2
-rw-r--r--rubocop/cop/line_break_around_conditional_block.rb6
-rw-r--r--rubocop/cop/ruby_interpolation_in_translation.rb29
-rw-r--r--rubocop/rubocop.rb1
-rw-r--r--scripts/frontend/extract_gettext_all.js10
-rw-r--r--spec/controllers/groups/milestones_controller_spec.rb11
-rw-r--r--spec/controllers/projects/commit_controller_spec.rb2
-rw-r--r--spec/controllers/projects/merge_requests/creations_controller_spec.rb49
-rw-r--r--spec/factories/milestones.rb2
-rw-r--r--spec/factories/project_group_links.rb1
-rw-r--r--spec/features/admin/admin_users_spec.rb1
-rw-r--r--spec/features/dashboard/milestones_spec.rb3
-rw-r--r--spec/features/merge_request/user_sees_diff_spec.rb54
-rw-r--r--spec/features/milestones/user_deletes_milestone_spec.rb44
-rw-r--r--spec/features/profiles/user_edit_profile_spec.rb10
-rw-r--r--spec/features/projects/commit/cherry_pick_spec.rb8
-rw-r--r--spec/features/projects/issues/user_sorts_issues_spec.rb26
-rw-r--r--spec/features/projects/jobs/user_browses_job_spec.rb4
-rw-r--r--spec/features/projects/jobs/user_browses_jobs_spec.rb2
-rw-r--r--spec/features/projects/merge_requests/user_sorts_merge_requests_spec.rb41
-rw-r--r--spec/features/projects/pipelines/pipeline_spec.rb4
-rw-r--r--spec/features/projects/pipelines/pipelines_spec.rb2
-rw-r--r--spec/helpers/import_helper_spec.rb10
-rw-r--r--spec/javascripts/badges/dummy_badge.js3
-rw-r--r--spec/javascripts/flash_spec.js7
-rw-r--r--spec/javascripts/helpers/vue_mount_component_helper.js10
-rw-r--r--spec/javascripts/ide/stores/modules/commit/actions_spec.js28
-rw-r--r--spec/javascripts/ide/stores/modules/file_templates/actions_spec.js336
-rw-r--r--spec/javascripts/ide/stores/modules/file_templates/getters_spec.js30
-rw-r--r--spec/javascripts/ide/stores/modules/file_templates/mutations_spec.js61
-rw-r--r--spec/javascripts/jobs/components/artifacts_block_spec.js (renamed from spec/javascripts/jobs/artifacts_block_spec.js)2
-rw-r--r--spec/javascripts/jobs/components/commit_block_spec.js (renamed from spec/javascripts/jobs/commit_block_spec.js)2
-rw-r--r--spec/javascripts/jobs/components/empty_state_spec.js (renamed from spec/javascripts/jobs/empty_state_spec.js)2
-rw-r--r--spec/javascripts/jobs/components/environments_block_spec.js137
-rw-r--r--spec/javascripts/jobs/components/erased_block_spec.js (renamed from spec/javascripts/jobs/erased_block_spec.js)2
-rw-r--r--spec/javascripts/jobs/components/header_spec.js (renamed from spec/javascripts/jobs/header_spec.js)0
-rw-r--r--spec/javascripts/jobs/components/job_details_mediator_spec.js (renamed from spec/javascripts/jobs/job_details_mediator_spec.js)2
-rw-r--r--spec/javascripts/jobs/components/job_log_spec.js (renamed from spec/javascripts/jobs/job_log_spec.js)2
-rw-r--r--spec/javascripts/jobs/components/job_store_spec.js (renamed from spec/javascripts/jobs/job_store_spec.js)2
-rw-r--r--spec/javascripts/jobs/components/jobs_container_spec.js (renamed from spec/javascripts/jobs/jobs_container_spec.js)2
-rw-r--r--spec/javascripts/jobs/components/sidebar_detail_row_spec.js (renamed from spec/javascripts/jobs/sidebar_detail_row_spec.js)0
-rw-r--r--spec/javascripts/jobs/components/sidebar_details_block_spec.js (renamed from spec/javascripts/jobs/sidebar_details_block_spec.js)4
-rw-r--r--spec/javascripts/jobs/components/stages_dropdown_spec.js (renamed from spec/javascripts/jobs/stages_dropdown_spec.js)2
-rw-r--r--spec/javascripts/jobs/components/stuck_block_spec.js (renamed from spec/javascripts/jobs/stuck_block_spec.js)2
-rw-r--r--spec/javascripts/jobs/components/trigger_value_spec.js (renamed from spec/javascripts/jobs/trigger_value_spec.js)2
-rw-r--r--spec/javascripts/performance_bar/services/performance_bar_service_spec.js63
-rw-r--r--spec/javascripts/pipelines/graph/dropdown_job_component_spec.js8
-rw-r--r--spec/javascripts/pipelines/graph/job_component_spec.js20
-rw-r--r--spec/javascripts/vue_mr_widget/components/mr_widget_header_spec.js14
-rw-r--r--spec/javascripts/vue_shared/components/stacked_progress_bar_spec.js6
-rw-r--r--spec/javascripts/vue_shared/components/tooltip_on_truncate_spec.js162
-rw-r--r--spec/lib/feature_spec.rb66
-rw-r--r--spec/lib/gitlab/auth/ldap/access_spec.rb152
-rw-r--r--spec/lib/gitlab/auth/o_auth/provider_spec.rb42
-rw-r--r--spec/lib/gitlab/ci/status/build/factory_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/status/build/failed_allowed_spec.rb4
-rw-r--r--spec/lib/gitlab/ci/status/build/failed_spec.rb4
-rw-r--r--spec/lib/gitlab/ci/status/build/retried_spec.rb2
-rw-r--r--spec/lib/gitlab/conflict/file_spec.rb4
-rw-r--r--spec/lib/gitlab/diff/highlight_spec.rb10
-rw-r--r--spec/lib/gitlab/diff/line_spec.rb22
-rw-r--r--spec/lib/gitlab/github_import/importer/issue_importer_spec.rb8
-rw-r--r--spec/lib/gitlab/github_import/importer/pull_request_importer_spec.rb10
-rw-r--r--spec/lib/gitlab/github_import_spec.rb33
-rw-r--r--spec/lib/gitlab/import/database_helpers_spec.rb46
-rw-r--r--spec/lib/gitlab/import/merge_request_creator_spec.rb43
-rw-r--r--spec/lib/gitlab/import_export/uploads_manager_spec.rb32
-rw-r--r--spec/lib/gitlab/middleware/multipart_spec.rb20
-rw-r--r--spec/lib/gitlab/url_blocker_spec.rb25
-rw-r--r--spec/lib/gitlab/usage_data_spec.rb3
-rw-r--r--spec/migrations/drop_duplicate_protected_tags_spec.rb40
-rw-r--r--spec/models/commit_spec.rb6
-rw-r--r--spec/models/concerns/awardable_spec.rb11
-rw-r--r--spec/models/issue_spec.rb99
-rw-r--r--spec/models/project_spec.rb2
-rw-r--r--spec/models/remote_mirror_spec.rb12
-rw-r--r--spec/models/repository_spec.rb18
-rw-r--r--spec/models/user_spec.rb8
-rw-r--r--spec/policies/group_policy_spec.rb3
-rw-r--r--spec/policies/project_policy_spec.rb1
-rw-r--r--spec/presenters/ci/build_presenter_spec.rb12
-rw-r--r--spec/requests/api/award_emoji_spec.rb12
-rw-r--r--spec/requests/api/files_spec.rb58
-rw-r--r--spec/requests/api/issues_spec.rb61
-rw-r--r--spec/requests/api/labels_spec.rb8
-rw-r--r--spec/requests/api/project_milestones_spec.rb13
-rw-r--r--spec/requests/api/project_snippets_spec.rb16
-rw-r--r--spec/requests/api/projects_spec.rb124
-rw-r--r--spec/requests/api/protected_tags_spec.rb202
-rw-r--r--spec/routing/admin_routing_spec.rb4
-rw-r--r--spec/routing/project_routing_spec.rb6
-rw-r--r--spec/rubocop/cop/ruby_interpolation_in_translation_spec.rb68
-rw-r--r--spec/serializers/build_serializer_spec.rb2
-rw-r--r--spec/serializers/job_entity_spec.rb4
-rw-r--r--spec/services/git_push_service_spec.rb50
-rw-r--r--spec/services/groups/destroy_service_spec.rb8
-rw-r--r--spec/services/issues/fetch_referenced_merge_requests_service_spec.rb35
-rw-r--r--spec/services/issues/referenced_merge_requests_service_spec.rb133
-rw-r--r--spec/services/merge_requests/build_service_spec.rb4
-rw-r--r--spec/services/milestones/destroy_service_spec.rb28
-rw-r--r--spec/services/projects/fork_service_spec.rb8
-rw-r--r--spec/services/projects/update_remote_mirror_service_spec.rb1
-rw-r--r--spec/services/projects/update_service_spec.rb29
-rw-r--r--spec/support/api/milestones_shared_examples.rb18
-rw-r--r--spec/support/helpers/cycle_analytics_helpers.rb4
-rw-r--r--spec/support/helpers/ldap_helpers.rb17
-rw-r--r--spec/support/helpers/stub_configuration.rb4
-rw-r--r--spec/support/helpers/stub_feature_flags.rb3
-rw-r--r--spec/support/shared_examples/requests/api/notes.rb82
-rw-r--r--spec/views/projects/merge_requests/_commits.html.haml_spec.rb13
-rw-r--r--spec/views/projects/merge_requests/creations/_new_submit.html.haml_spec.rb15
-rw-r--r--yarn.lock6
1134 files changed, 6133 insertions, 3438 deletions
diff --git a/.flayignore b/.flayignore
index 4b6f7ba693a..87411516a2a 100644
--- a/.flayignore
+++ b/.flayignore
@@ -6,6 +6,7 @@ app/controllers/projects/approvers_controller.rb
app/controllers/projects/protected_branches/merge_access_levels_controller.rb
app/controllers/projects/protected_branches/push_access_levels_controller.rb
app/controllers/projects/protected_tags/create_access_levels_controller.rb
+app/helpers/system_note_helper.rb
app/policies/project_policy.rb
app/models/concerns/relative_positioning.rb
app/workers/stuck_merge_jobs_worker.rb
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 797a20ef16e..23d71675ae4 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -131,7 +131,7 @@ stages:
.single-script-job: &single-script-job
image: ruby:2.4-alpine
before_script: []
- stage: build
+ stage: test
cache: {}
dependencies: []
variables: &single-script-job-variables
diff --git a/.gitlab/issue_templates/Test plan.md b/.gitlab/issue_templates/Test plan.md
new file mode 100644
index 00000000000..580fab206b3
--- /dev/null
+++ b/.gitlab/issue_templates/Test plan.md
@@ -0,0 +1,96 @@
+# Test Plan
+
+<!-- This issue outlines testing activities related to a particular issue or epic.
+
+[Here is an example test plan](https://gitlab.com/gitlab-org/gitlab-ce/issues/50353)
+
+This and other comments should be removed as you write the plan -->
+
+## Introduction
+
+<!-- Briefly outline what is being tested
+
+Mention the issue(s) this test plan is related to -->
+
+## Scope
+
+<!-- State any limits on aspects of the feature being tested
+Outline the types of data to be included
+Outline the types of tests to be performed (functional, security, performance,
+database, automated, etc) -->
+
+## ACC Matrix
+
+<!-- Use the matrix below as a template to identify the Attributes, Components, and
+Capabilities relevant to the scope of this test plan. Add or remove Attributes
+and Components as required and list Capabilities in the next section
+
+Attributes (columns) are adverbs or adjectives that describe (at a high level)
+the qualities testing is meant to ensure Components have.
+
+Components (rows) are nouns that define major parts of the product being tested.
+
+Capabilities link Attributes and Components. They are what your product needs to
+do to make sure a Component fulfills an Attribute
+
+For more information see the [Google Testing Blog article about the 10 minute
+test plan](https://testing.googleblog.com/2011/09/10-minute-test-plan.html) and
+[this wiki page from an open-source tool that implements the ACC
+model](https://code.google.com/archive/p/test-analytics/wikis/AccExplained.wiki). -->
+
+| | Simple | Secure | Responsive | Obvious | Stable |
+|------------|:------:|:------:|:----------:|:-------:|:------:|
+| Admin | | | | | |
+| Groups | | | | | |
+| Project | | | | | |
+| Repository | | | | | |
+| Issues | | | | | |
+| MRs | | | | | |
+| CI/CD | | | | | |
+| Ops | | | | | |
+| Registry | | | | | |
+| Wiki | | | | | |
+| Snippets | | | | | |
+| Settings | | | | | |
+| Tracking | | | | | |
+| API | | | | | |
+
+## Capabilities
+
+<!-- Use the ACC matrix above to help you identify Capabilities at each relevant
+intersection of Components and Attributes.
+
+Some features might be simple enough that they only involve one Component, while
+more complex features could involve multiple or even all.
+
+Example (from https://gitlab.com/gitlab-org/gitlab-ce/issues/50353):
+* Respository is
+ * Simple
+ * It's easy to select the desired file template
+ * It doesn't require unnecessary actions to save the change
+ * It's easy to undo the change after selecting a template
+ * Responsive
+ * The list of templates can be restricted to allow a user to find a specific template among many
+ * Once a template is selected the file content updates quickly and smoothly
+-->
+
+## Test Plan
+
+<!-- If the scope is small enough you may not need to write a list of tests to
+perform. It might be enough to use the Capabilities to guide your testing.
+
+If the feature is more complex, especially if it involves multiple Components,
+briefly outline a set of tests here. When identifying tests to perform be sure
+to consider risk. Note inherent/known levels of risk so that testing can focus
+on high risk areas first.
+
+New end-to-end and integration tests (Selenium and API) should be added to the
+[Test Coverage sheet](https://docs.google.com/spreadsheets/d/1RlLfXGboJmNVIPP9jgFV5sXIACGfdcFq1tKd7xnlb74/)
+
+Please note if automated tests already exist.
+
+When adding new automated tests, please keep [testing levels](https://docs.gitlab.com/ce/development/testing_guide/testing_levels.html)
+in mind.
+-->
+
+/label ~Quality \ No newline at end of file
diff --git a/.haml-lint.yml b/.haml-lint.yml
index 32c7de0fb78..fcdc47af60f 100644
--- a/.haml-lint.yml
+++ b/.haml-lint.yml
@@ -70,14 +70,15 @@ linters:
enabled: false
RuboCop:
- enabled: false
+ enabled: true
# These cops are incredibly noisy when it comes to HAML templates, so we
# ignore them.
ignored_cops:
- - Lint/BlockAlignment
- - Lint/EndAlignment
+ - Layout/BlockAlignment
+ - Layout/EndAlignment
- Lint/Void
- Metrics/LineLength
+ - Naming/FileName
- Style/AlignParameters
- Style/BlockNesting
- Style/ElseAlignment
@@ -91,6 +92,52 @@ linters:
- Style/TrailingWhitespace
- Style/WhileUntilModifier
+ # These cops should eventually get enabled
+ - Cop/LineBreakAfterGuardClauses
+ - Cop/LineBreakAroundConditionalBlock
+ - Cop/ProjectPathHelper
+ - GitlabSecurity/PublicSend
+ - Layout/LeadingCommentSpace
+ - Layout/SpaceAfterColon
+ - Layout/SpaceAfterComma
+ - Layout/SpaceAroundOperators
+ - Layout/SpaceBeforeBlockBraces
+ - Layout/SpaceBeforeComma
+ - Layout/SpaceBeforeFirstArg
+ - Layout/SpaceInsideArrayLiteralBrackets
+ - Layout/SpaceInsideHashLiteralBraces
+ - Layout/SpaceInsideStringInterpolation
+ - Layout/TrailingBlankLines
+ - Lint/BooleanSymbol
+ - Lint/LiteralInInterpolation
+ - Lint/ParenthesesAsGroupedExpression
+ - Lint/RedundantWithIndex
+ - Lint/Syntax
+ - Lint/UselessAssignment
+ - Metrics/BlockNesting
+ - Naming/VariableName
+ - Performance/RedundantMatch
+ - Performance/StringReplacement
+ - Rails/Presence
+ - Rails/RequestReferer
+ - Style/AndOr
+ - Style/ColonMethodCall
+ - Style/ConditionalAssignment
+ - Style/HashSyntax
+ - Style/IdenticalConditionalBranches
+ - Style/NegatedIf
+ - Style/NestedTernaryOperator
+ - Style/Not
+ - Style/ParenthesesAroundCondition
+ - Style/RedundantParentheses
+ - Style/SelfAssignment
+ - Style/Semicolon
+ - Style/TernaryParentheses
+ - Style/TrailingCommaInHashLiteral
+ - Style/UnlessElse
+ - Style/WordArray
+ - Style/ZeroLengthPredicate
+
RubyComments:
enabled: true
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7be28a9ac0e..5e022b7e52b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,288 @@
documentation](doc/development/changelog.md) for instructions on adding your own
entry.
+## 11.2.3 (2018-08-28)
+
+- No changes.
+
+## 11.2.2 (2018-08-27)
+
+### Security (3 changes)
+
+- Fixed persistent XSS rendering/escaping of diff location lines.
+- Adding CSRF protection to Hooks resend action.
+- Block link-local addresses in URLBlocker.
+
+
+## 11.2.1 (2018-08-22)
+
+### Fixed (2 changes)
+
+- Fix wrong commit count in push event payload. !21338
+- Fix broken Git over HTTP clones with LDAP users. !21352
+
+### Performance (1 change)
+
+- Eliminate unnecessary and duplicate system hook fires. !21337
+
+
+## 11.2.0 (2018-08-22)
+
+### Security (5 changes)
+
+- Bump Gitaly to 0.117.1 for Rouge update. !21277
+- Fix symlink vulnerability in project import.
+- Bump rugged to 0.27.4 for security fixes.
+- Fixed XSS in branch name in Web IDE.
+- Adding CSRF protection to Hooks test action.
+
+### Removed (1 change)
+
+- Remove gitlab:user:check_repos, gitlab:check_repo, gitlab:git:prune, gitlab:git:gc, and gitlab:git:repack. !20806
+
+### Fixed (81 changes, 26 of them are from the community)
+
+- Fix namespace move callback behavior, especially to fix Geo replication of namespace moves during certain exceptions. !19297
+- Fix breadcrumbs in Admin/User interface. !19608 (Robin Naundorf)
+- Remove changes_count from MR API documentation where necessary. !19745 (Jan Beckmann)
+- Fix email confirmation bug when user adds additional email to account. !20084 (muhammadn)
+- Add support for daylight savings time to pipleline schedules. !20145
+- Fixing milestone date change when editing. !20279 (Orlando Del Aguila)
+- Add missing maximum_timeout parameter. !20355 (gfyoung)
+- [Rails5] Fix 'Invalid single-table inheritance type: Group is not a subclass of Gitlab::BackgroundMigration::FixCrossProjectLabelLinks::Namespace'. !20462 (@blackst0ne)
+- Rails5 fix mysql milliseconds problem in specs. !20464 (Jasper Maes)
+- Update Gemfile.rails5.lock with latest Gemfile.lock changes. !20466 (Jasper Maes)
+- Rails5 mysql fix milliseconds problem in pull request importer spec. !20475 (Jasper Maes)
+- Rails5 MySQL fix rename_column as part of cleanup_concurrent_column_type_change. !20514 (Jasper Maes)
+- Process commits as normal in forks when the upstream project is deleted. !20534
+- Fix project visibility tooltip. !20535 (Jamie Schembri)
+- Fix archived parameter for projects API. !20566 (Peter Marko)
+- Limit maximum project build timeout setting to 1 month. !20591
+- Fix GitLab project imports not loading due to API timeouts. !20599
+- Avoid process deadlock in popen by consuming input pipes. !20600
+- Disable SAML and Bitbucket if OmniAuth is disabled. !20608
+- Support multiple scopes when authing container registry scopes. !20617
+- Adds the ability to view group milestones on the dashboard milestone page. !20618
+- Allow issues API to receive an internal ID (iid) on create. !20626 (Jamie Schembri)
+- Fix typo in CSS transform property for Memory Graph component. !20650
+- Update design for system metrics popovers. !20655
+- Toggle Show / Hide Button for Kubernetes Password. !20659 (gfyoung)
+- Board label edit dropdown shows incorrect selected labels summary. !20673
+- Resolve "Unable to save user profile update with Safari". !20676
+- Escape username and password in UrlSanitizer#full_url. !20684
+- Remove background color from card-body style. !20689 (George Tsiolis)
+- Update total storage size when changing size of artifacts. !20697 (Peter Marko)
+- Rails5 fix user sees revert modal spec. !20706 (Jasper Maes)
+- Fix Web IDE crashing on directories named 'blob'. !20712
+- Fix accessing imported pipeline builds. !20713
+- Fixed bug with invalid repository reference using the wiki search. !20722
+- Resolve Copy diff file path as GFM is broken. !20725
+- Chart versions for applications installed by one click install buttons should be version locked. !20765
+- Fix misalignment of broadcast message on login page. !20794 (Robin Naundorf)
+- Fix Vue datatype errors for markdownVersion parsing. !20800
+- Fix authorization for interactive web terminals. !20811
+- Increase width of Web IDE sidebar resize handles. !20818
+- Fix new MR card styles. !20822
+- Fix link color in markdown code brackets. !20841
+- Rails5 update Gemfile.rails5.lock. !20858 (Jasper Maes)
+- fix height of full-width Metrics charts on large screens. !20866
+- Fix sorting by name on milestones page. !20881
+- Permit concurrent loads in gpg keychain mutex. !20894 (Jasper Maes)
+- Prevent editing and updating wiki pages with non UTF-8 encoding via web interface. !20906
+- Retrieve merge request closing issues from database cache. !20911
+- Fix LFS uploads not working with git-lfs 2.5.0. !20923
+- Fix bug setting http headers in Files API. !20938
+- Rails5: fix flaky spec. !20953 (Jasper Maes)
+- Fixed list of projects not loading in group boards. !20955
+- Fix autosave and ESC confirmation issues for MR discussions. !20968
+- Fix navigation to First and Next discussion on MR Changes tab. !20968
+- Fix rendering of the context lines in MR diffs page. !20968
+- fix error caused when using the search bar while unauthenticated. !20970
+- Fix GPG status badge loading regressions. !20987
+- Ensure links in notifications footer are not escaped. !21000
+- Rails5: update Rails5 lock for forgotten gem rouge. !21010 (Jasper Maes)
+- Fix UI error whereby prometheus application status is updated. !21029
+- Solves group dashboard line height is too tall for group names. !21033
+- Fix rendering of pipeline failure view when directly navigationg to it. !21043
+- Fix missing and duplicates on project milestone listing page. !21058
+- Fix merge requests not showing any diff files for big patches. !21125
+- Auto-DevOps.gitlab-ci.yml: Update glibc package signing key URL. !21182 (sgerrand)
+- Fix issue stopping Instance Statistics javascript to be executed. !21211
+- Fix broken JavaScript in IE11. !21214
+- Improve JUnit test reports in merge request widgets. !49966
+- Properly handle colons in URL passwords.
+- Renders test reports for resolved failures and resets error state.
+- Fix handling of annotated tags when Gitaly is not in use.
+- Fix serialization of LegacyDiffNote.
+- Escapes milestone and label's names on flash notice when promoting them.
+- Allow to toggle notifications for issues due soon.
+- Sanitize git URL in import errors. (Jamie Schembri)
+- Add missing predefined variable and fix docs.
+- Allow updating a project's avatar without other params. (Jamie Schembri)
+- Fix the UI for listing system-level labels.
+- Update hamlit to fix ruby 2.5 incompatibilities, fixes #42045. (Matthew Dawson)
+- Fix updated_at if created_at is set for Note API.
+- Fix search bar text input alignment.
+
+### Changed (32 changes, 7 of them are from the community)
+
+- Rack attack is now disabled by default. !16669
+- Include full image URL in webhooks for uploaded images. !18109 (Satish Perala)
+- Enable hashed storage for all newly created or renamed projects. !19747
+- Support manually stopping any environment from the UI. !20077
+- Close revert and cherry pick modal on escape keypress. !20341 (George Tsiolis)
+- Adds with_projects optional parameter to GET /groups/:id API endpoint. !20494
+- Improve feedback when a developer is unable to push to an empty repository. !20519
+- Display GPG status on repository and blob pages. !20524
+- Updated design of new entry dropdown in Web IDE. !20526
+- UX improvements to top nav search bar. !20537
+- Update issue closing pattern. !20554 (George Tsiolis)
+- Add merge request header branch actions left margin. !20643 (George Tsiolis)
+- Rubix, scikit-learn, tensorflow & other useful libraries pre-installed with JupyterHub. !20714 (Amit Rathi)
+- Show decimal place up to single digit in Stacked Progress Bar. !20776
+- Wrap job name on pipeline job sidebar. !20804 (George Tsiolis)
+- Redesign Web IDE back button and context header. !20850
+- Removes "show all" on reports and adds an actionButtons slot. !20855
+- Put fallback reply-key address first in the References header. !20871
+- Allow non-admins to view instance statistics (if permitted by the instance admins). !20874
+- Adds the project and group name to the return type for project and group milestones. !20890
+- Restyle status message input on profile settings. !20903
+- Ensure installed Helm Tiller For GitLab Managed Apps Is protected by mutual auth. !20928
+- Allow multiple JIRA transition ids. !20939
+- Use Helm 2.7.2 for GitLab Managed Apps. !20956
+- Create branch and MR picker for Web IDE. !20978
+- Update commit message styles with monospace font and overflow-x. !20988
+- Update to Rouge 3.2.0, including Terraform and Crystal lexer and bug fixes. !20991
+- Update design of project templates. !21012
+- Update to Rouge 3.2.1, which includes a critical fix to the Perl Lexer. !21263
+- Add a 10 ms bucket for SQL timings.
+- Show one digit after dot in commit_per_day value in charts page. (msdundar)
+- Redesign GCP offer banner.
+
+### Performance (30 changes, 10 of them are from the community)
+
+- Stop dynamically creating project and namespace routes. !20313
+- Tracking the number of repositories and wikis with a cached counter for site-wide statistics. !20413
+- Optimize ProjectWiki#empty? check. !20573
+- Delete UserActivities and related workers. !20597
+- Enable frozen string in app/services/**/*.rb. !20656 (gfyoung)
+- Enable more frozen string in app/services/**/*.rb. !20677 (gfyoung)
+- Limit the TTL for anonymous sessions to 1 hour. !20700
+- Enable even more frozen string in app/services/**/*.rb. !20702 (gfyoung)
+- Enable frozen string in app/serializers/**/*.rb. !20726 (gfyoung)
+- Enable frozen string in newly added files to previously processed directories. !20763 (gfyoung)
+- Use limit parameter to retrieve Wikis from Gitaly. !20764
+- Add Dangerfile for frozen_string_literal. !20767 (gfyoung)
+- Remove method instrumentation for Banzai filters and reference parsers. !20770
+- Enable frozen strings in lib/banzai/filter/*.rb. !20775
+- Enable frozen strings in remaining lib/banzai/filter/*.rb files. !20777
+- DNS prefetching if asset_host for CDN hosting is set. !20781
+- Bump nokogiri to 1.8.4 and sanitize to 4.6.6 for performance. !20795
+- Enable frozen string in app/presenters and app/policies. !20819 (gfyoung)
+- Bump haml gem to 5.0.4. !20847
+- Enable frozen string in app/models/*.rb. !20851 (gfyoung)
+- Performing Commit GPG signature calculation in bulk. !20870
+- Fix /admin/jobs failing to load due to statement timeout. !20909
+- refactor pipeline job log animation to reduce CPU usage. !20915
+- Improve performance when fetching collapsed diffs and commenting in merge requests. !20940
+- Enable frozen string for app/models/**/*.rb. !21001 (gfyoung)
+- Don't set gon variables in JSON requests. !21016 (Peter Leitzen)
+- Improve performance and memory footprint of Changes tab of Merge Requests. !21028
+- Avoid N+1 on MRs page when metrics merging date cannot be found. !21053
+- Bump Gitaly to 0.117.0. !21055
+- Access metadata directly from Object Storage.
+
+### Added (41 changes, 18 of them are from the community)
+
+- Show repository languages for projects. !19480
+- Adds API endpoint /api/v4/(project/group)/:id/members/all to list also inherited members. !19748 (Jacopo Beschi @jacopo-beschi)
+- Added live preview for JavaScript projects in the Web IDE. !19764
+- Add support for SSH certificate authentication. !19911 (Ævar Arnfjörð Bjarmason)
+- Add Hangouts Chat integration. !20290 (Kukovskii Vladimir)
+- Add ability to import multiple repositories by uploading a manifest file. !20304
+- Show Project ID on project home panel. !20305 (Tuğçe Nur Taş)
+- Add an option to have a private profile on GitLab. !20387 (jxterry)
+- Extend gitlab-ci.yml to request junit.xml test reports. !20390
+- Add the first mutations for merge requests to GraphQL. !20443
+- Add /-/health basic health check endpoint. !20456
+- Add filter for minimal access level in groups and projects API. !20478 (Marko, Peter)
+- Add download button for single file (including raw files) in repository. !20480 (Kia Mei Somabes)
+- Gitaly Servers link into Admin > Overview navigation menu. !20550
+- Adds foreign key to notification_settings.user_id. !20567 (Jacopo Beschi @jacopo-beschi)
+- JUnit XML Test Summary In MR widget. !20576
+- Cleans up display of Deploy Tokens to match Personal Access Tokens. !20578 (Marcel Amirault)
+- Users can set a status message and emoji. !20614 (niedermyer & davamr)
+- Add emails delivery Prometheus metrics. !20638
+- Verify runner feature set. !20664
+- Add more comprehensive metrics tracking authentication activity. !20668
+- Add support for tar.gz AUTO_DEVOPS_CHART charts (#49324). !20691 (@kondi1)
+- Adds Vuex store for reports section in MR widget. !20709
+- Redirect commits to root if no ref is provided (31576). !20738 (Kia Mei Somabes)
+- Search for labels by title or description on project labels page. !20749
+- Add object storage logic to project import. !20773
+- Enable renaming files and folders in Web IDE. !20835
+- Warn user when reload IDE with staged changes. !20857
+- Add local project uploads cleanup task. !20863
+- Improve error message when adding invalid user to a project. !20885 (Jacopo Beschi @jacopo-beschi)
+- Add link to homepage on static http status pages (404, 500, etc). !20898 (Jason Funk)
+- Clean orphaned files in object storage. !20918
+- Adds frontend support to render test reports on the MR widget. !20936
+- Trigger system hooks when project is archived/unarchived. !20995
+- Custom Wiki Sidebar Support Issue 14995. (Josh Sooter)
+- Emails on push recipients now accepts formats like John Doe <johndoe@example.com>. (George Thomas)
+- Add new model for tracking label events.
+- Improve danger confirmation modals by focusing input field. (Jamie Schembri)
+- Clicking CI icon in Web IDE now opens up pipelines panel.
+- Enabled deletion of files in the Web IDE.
+- Added button to regenerate 2FA codes. (Luke Picciau)
+
+### Other (26 changes, 7 of them are from the community)
+
+- Update specific runners help URL. !20213 (George Tsiolis)
+- Enable frozen string in apps/uploaders/*.rb. !20401 (gfyoung)
+- Update docs of Helm Tiller. !20515 (Takuya Noguchi)
+- Persist 'Auto DevOps' banner dismissal globally. !20540
+- Move xterm to a node dependency and remove it from vendor's folder. !20588
+- Upgrade grape-path-helpers to 1.0.6. !20601
+- Delete todos when user loses access to read the target. !20665
+- Remove tooltips from commit author avatar and name in commit lists. !20674
+- Allow cloning LFS repositories through DeployTokens. !20729
+- Replace 'Sidekiq::Testing.inline!' with 'perform_enqueued_jobs'. !20768 (@blackst0ne)
+- Replace author_link snake case in stylesheets, specs, and helpers. !20797 (George Tsiolis)
+- Replace snake case in SCSS variables. !20799 (George Tsiolis)
+- Add rbtrace to Gemfile. !20831
+- Add support for searching users by confirmed e-mails. !20893
+- Changes poll.js to keep polling on any 2xx http status code. !20904
+- Remove todos of users without access to targets migration. !20927
+- Improve and simplify Auto DevOps settings flow. !20946
+- Keep admin settings sections open after submitting forms. !21040
+- CE port of "List groups with developer maintainer access on project creation". !21051
+- Update git rerere link in docs. !21060 (gfyoung)
+- Add 'tabindex' attribute support on Icon component to show BS4 popover on trigger type 'focus'. !21066
+- Add a Gitlab::Profiler.print_by_total_time convenience method for profiling from a Rails console.
+- Automatically expand runner's settings block when linking to the runner's settings page.
+- Increases title column on modal for reports.
+- Disables toggle comments button if diff has no discussions.
+- Moves help_popover component to a common location.
+
+
+## 11.1.6 (2018-08-28)
+
+- No changes.
+
+## 11.1.5 (2018-08-27)
+
+### Security (3 changes)
+
+- Fixed persistent XSS rendering/escaping of diff location lines.
+- Adding CSRF protection to Hooks resend action.
+- Block link-local addresses in URLBlocker.
+
+### Fixed (1 change, 1 of them is from the community)
+
+- Sanitize git URL in import errors. (Jamie Schembri)
+
+
## 11.1.4 (2018-07-30)
### Fixed (4 changes, 1 of them is from the community)
@@ -284,6 +566,19 @@ entry.
- Use monospaced font for MR diff commit link ref on GFM.
+## 11.0.6 (2018-08-27)
+
+### Security (3 changes)
+
+- Fixed persistent XSS rendering/escaping of diff location lines.
+- Adding CSRF protection to Hooks resend action.
+- Block link-local addresses in URLBlocker.
+
+### Fixed (1 change, 1 of them is from the community)
+
+- Sanitize git URL in import errors. (Jamie Schembri)
+
+
## 11.0.5 (2018-07-26)
### Security (4 changes)
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index fb7c0c88629..1b9e9d4a5a3 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -314,7 +314,7 @@ This [documentation](doc/development/contributing/merge_request_workflow.md) has
## Definition of done
-This [documentation](doc/development/contributing/merge_request_workflow.md)) has been moved.
+This [documentation](doc/development/contributing/merge_request_workflow.md) has been moved.
## Style guides
diff --git a/Gemfile b/Gemfile
index bcede83df12..208289cb7fb 100644
--- a/Gemfile
+++ b/Gemfile
@@ -116,14 +116,14 @@ gem 'dropzonejs-rails', '~> 0.7.1'
# for backups
gem 'fog-aws', '~> 2.0.1'
gem 'fog-core', '~> 1.44'
-gem 'fog-google', '~> 1.3.3'
+gem 'fog-google', '~> 1.7.1'
gem 'fog-local', '~> 0.3'
gem 'fog-openstack', '~> 0.1'
gem 'fog-rackspace', '~> 0.1.1'
gem 'fog-aliyun', '~> 0.2.0'
# for Google storage
-gem 'google-api-client', '~> 0.19.8'
+gem 'google-api-client', '~> 0.23'
# for aws storage
gem 'unf', '~> 0.1.4'
diff --git a/Gemfile.lock b/Gemfile.lock
index 15a105579fb..77effb63d2e 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -239,11 +239,11 @@ GEM
builder
excon (~> 0.58)
formatador (~> 0.2)
- fog-google (1.3.3)
+ fog-google (1.7.1)
fog-core
fog-json
fog-xml
- google-api-client (~> 0.19.1)
+ google-api-client (~> 0.23.0)
fog-json (1.0.2)
fog-core (~> 1.0)
multi_json (~> 1.10)
@@ -329,7 +329,7 @@ GEM
actionpack (>= 3.0)
multi_json
request_store (>= 1.0)
- google-api-client (0.19.8)
+ google-api-client (0.23.4)
addressable (~> 2.5, >= 2.5.1)
googleauth (>= 0.5, < 0.7.0)
httpclient (>= 2.8.1, < 3.0)
@@ -738,7 +738,7 @@ GEM
http-cookie (>= 1.0.2, < 2.0)
mime-types (>= 1.16, < 4.0)
netrc (~> 0.8)
- retriable (3.1.1)
+ retriable (3.1.2)
rinku (2.0.0)
rotp (2.1.2)
rouge (3.2.1)
@@ -1031,7 +1031,7 @@ DEPENDENCIES
fog-aliyun (~> 0.2.0)
fog-aws (~> 2.0.1)
fog-core (~> 1.44)
- fog-google (~> 1.3.3)
+ fog-google (~> 1.7.1)
fog-local (~> 0.3)
fog-openstack (~> 0.1)
fog-rackspace (~> 0.1.1)
@@ -1051,7 +1051,7 @@ DEPENDENCIES
gitlab-styles (~> 2.4)
gitlab_omniauth-ldap (~> 2.0.4)
gon (~> 6.2)
- google-api-client (~> 0.19.8)
+ google-api-client (~> 0.23)
google-protobuf (= 3.5.1)
gpgme
grape (~> 1.0)
diff --git a/Gemfile.rails5.lock b/Gemfile.rails5.lock
index 7803d12c6b4..63b450d3f62 100644
--- a/Gemfile.rails5.lock
+++ b/Gemfile.rails5.lock
@@ -126,7 +126,7 @@ GEM
numerizer (~> 0.1.1)
chunky_png (1.3.5)
citrus (3.0.2)
- coderay (1.1.1)
+ coderay (1.1.2)
coercible (1.0.0)
descendants_tracker (~> 0.0.1)
commonmarker (0.17.8)
@@ -242,11 +242,11 @@ GEM
builder
excon (~> 0.58)
formatador (~> 0.2)
- fog-google (1.3.3)
+ fog-google (1.7.1)
fog-core
fog-json
fog-xml
- google-api-client (~> 0.19.1)
+ google-api-client (~> 0.23.0)
fog-json (1.0.2)
fog-core (~> 1.0)
multi_json (~> 1.10)
@@ -332,7 +332,7 @@ GEM
actionpack (>= 3.0)
multi_json
request_store (>= 1.0)
- google-api-client (0.19.8)
+ google-api-client (0.23.4)
addressable (~> 2.5, >= 2.5.1)
googleauth (>= 0.5, < 0.7.0)
httpclient (>= 2.8.1, < 3.0)
@@ -495,7 +495,7 @@ GEM
memoist (0.16.0)
memoizable (0.4.2)
thread_safe (~> 0.3, >= 0.3.1)
- method_source (0.8.2)
+ method_source (0.9.0)
mime-types (3.1)
mime-types-data (~> 3.2015)
mime-types-data (3.2016.0521)
@@ -638,12 +638,11 @@ GEM
unparser
procto (0.0.3)
prometheus-client-mmap (0.9.4)
- pry (0.10.4)
+ pry (0.11.3)
coderay (~> 1.1.0)
- method_source (~> 0.8.1)
- slop (~> 3.4)
- pry-byebug (3.4.2)
- byebug (~> 9.0)
+ method_source (~> 0.9.0)
+ pry-byebug (3.4.3)
+ byebug (>= 9.0, < 9.1)
pry (~> 0.10)
pry-rails (0.3.5)
pry (>= 0.9.10)
@@ -748,10 +747,10 @@ GEM
http-cookie (>= 1.0.2, < 2.0)
mime-types (>= 1.16, < 4.0)
netrc (~> 0.8)
- retriable (3.1.1)
+ retriable (3.1.2)
rinku (2.0.0)
rotp (2.1.2)
- rouge (3.2.0)
+ rouge (3.2.1)
rqrcode (0.7.0)
chunky_png
rqrcode-rails3 (0.1.7)
@@ -817,7 +816,7 @@ GEM
rubyzip (1.2.1)
rufus-scheduler (3.4.0)
et-orbi (~> 1.0)
- rugged (0.27.2)
+ rugged (0.27.4)
safe_yaml (1.0.4)
sanitize (4.6.6)
crass (~> 1.0.2)
@@ -878,7 +877,6 @@ GEM
simplecov-html (~> 0.10.0)
simplecov-html (0.10.0)
slack-notifier (1.5.1)
- slop (3.6.0)
spring (2.0.1)
activesupport (>= 4.2)
spring-commands-rspec (1.0.4)
@@ -1043,7 +1041,7 @@ DEPENDENCIES
fog-aliyun (~> 0.2.0)
fog-aws (~> 2.0.1)
fog-core (~> 1.44)
- fog-google (~> 1.3.3)
+ fog-google (~> 1.7.1)
fog-local (~> 0.3)
fog-openstack (~> 0.1)
fog-rackspace (~> 0.1.1)
@@ -1063,7 +1061,7 @@ DEPENDENCIES
gitlab-styles (~> 2.4)
gitlab_omniauth-ldap (~> 2.0.4)
gon (~> 6.2)
- google-api-client (~> 0.19.8)
+ google-api-client (~> 0.23)
google-protobuf (= 3.5.1)
gpgme
grape (~> 1.0)
diff --git a/VERSION b/VERSION
index 53906da50f8..e1ceae704b9 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-11.2.0-pre
+11.3.0-pre
diff --git a/app/assets/javascripts/api.js b/app/assets/javascripts/api.js
index 25fe2ae553e..cd800d75f7a 100644
--- a/app/assets/javascripts/api.js
+++ b/app/assets/javascripts/api.js
@@ -15,6 +15,7 @@ const Api = {
mergeRequestChangesPath: '/api/:version/projects/:id/merge_requests/:mrid/changes',
mergeRequestVersionsPath: '/api/:version/projects/:id/merge_requests/:mrid/versions',
groupLabelsPath: '/groups/:namespace_path/-/labels',
+ templatesPath: '/api/:version/templates/:key',
licensePath: '/api/:version/templates/licenses/:key',
gitignorePath: '/api/:version/templates/gitignores/:key',
gitlabCiYmlPath: '/api/:version/templates/gitlab_ci_ymls/:key',
@@ -265,6 +266,12 @@ const Api = {
});
},
+ templates(key, params = {}) {
+ const url = Api.buildUrl(this.templatesPath).replace(':key', key);
+
+ return axios.get(url, { params });
+ },
+
buildUrl(url) {
let urlRoot = '';
if (gon.relative_url_root != null) {
diff --git a/app/assets/javascripts/awards_handler.js b/app/assets/javascripts/awards_handler.js
index e34db893989..5b0c4285339 100644
--- a/app/assets/javascripts/awards_handler.js
+++ b/app/assets/javascripts/awards_handler.js
@@ -109,8 +109,6 @@ export class AwardsHandler {
}
const $menu = $(`.${this.menuClass}`);
- const $thumbsBtn = $menu.find('[data-name="thumbsup"], [data-name="thumbsdown"]').parent();
- const $userAuthored = this.isUserAuthored($addBtn);
if ($menu.length) {
if ($menu.is('.is-visible')) {
$addBtn.removeClass('is-active');
@@ -134,9 +132,6 @@ export class AwardsHandler {
}, 200);
});
}
-
- $thumbsBtn.toggleClass('disabled', $userAuthored);
- $thumbsBtn.prop('disabled', $userAuthored);
}
// Create the emoji menu with the first category of emojis.
@@ -364,10 +359,6 @@ export class AwardsHandler {
return $emojiButton.hasClass('active');
}
- isUserAuthored($button) {
- return $button.hasClass('js-user-authored');
- }
-
decrementCounter($emojiButton, emoji) {
const counter = $('.js-counter', $emojiButton);
const counterNumber = parseInt(counter.text(), 10);
@@ -474,20 +465,16 @@ export class AwardsHandler {
}
postEmoji($emojiButton, awardUrl, emoji, callback) {
- if (this.isUserAuthored($emojiButton)) {
- this.userAuthored($emojiButton);
- } else {
- axios
- .post(awardUrl, {
- name: emoji,
- })
- .then(({ data }) => {
- if (data.ok) {
- callback();
- }
- })
- .catch(() => flash(__('Something went wrong on our end.')));
- }
+ axios
+ .post(awardUrl, {
+ name: emoji,
+ })
+ .then(({ data }) => {
+ if (data.ok) {
+ callback();
+ }
+ })
+ .catch(() => flash(__('Something went wrong on our end.')));
}
findEmojiIcon(votesBlock, emoji) {
diff --git a/app/assets/javascripts/ide/stores/modules/file_templates/actions.js b/app/assets/javascripts/ide/stores/modules/file_templates/actions.js
new file mode 100644
index 00000000000..43237a29466
--- /dev/null
+++ b/app/assets/javascripts/ide/stores/modules/file_templates/actions.js
@@ -0,0 +1,82 @@
+import Api from '~/api';
+import { __ } from '~/locale';
+import * as types from './mutation_types';
+
+export const requestTemplateTypes = ({ commit }) => commit(types.REQUEST_TEMPLATE_TYPES);
+export const receiveTemplateTypesError = ({ commit, dispatch }) => {
+ commit(types.RECEIVE_TEMPLATE_TYPES_ERROR);
+ dispatch(
+ 'setErrorMessage',
+ {
+ text: __('Error loading template types.'),
+ action: () =>
+ dispatch('fetchTemplateTypes').then(() =>
+ dispatch('setErrorMessage', null, { root: true }),
+ ),
+ actionText: __('Please try again'),
+ },
+ { root: true },
+ );
+};
+export const receiveTemplateTypesSuccess = ({ commit }, templates) =>
+ commit(types.RECEIVE_TEMPLATE_TYPES_SUCCESS, templates);
+
+export const fetchTemplateTypes = ({ dispatch, state }) => {
+ if (!Object.keys(state.selectedTemplateType).length) return Promise.reject();
+
+ dispatch('requestTemplateTypes');
+
+ return Api.templates(state.selectedTemplateType.key)
+ .then(({ data }) => dispatch('receiveTemplateTypesSuccess', data))
+ .catch(() => dispatch('receiveTemplateTypesError'));
+};
+
+export const setSelectedTemplateType = ({ commit }, type) =>
+ commit(types.SET_SELECTED_TEMPLATE_TYPE, type);
+
+export const receiveTemplateError = ({ dispatch }, template) => {
+ dispatch(
+ 'setErrorMessage',
+ {
+ text: __('Error loading template.'),
+ action: payload =>
+ dispatch('fetchTemplateTypes', payload).then(() =>
+ dispatch('setErrorMessage', null, { root: true }),
+ ),
+ actionText: __('Please try again'),
+ actionPayload: template,
+ },
+ { root: true },
+ );
+};
+
+export const fetchTemplate = ({ dispatch, state }, template) => {
+ if (template.content) {
+ return dispatch('setFileTemplate', template);
+ }
+
+ return Api.templates(`${state.selectedTemplateType.key}/${template.key || template.name}`)
+ .then(({ data }) => {
+ dispatch('setFileTemplate', data);
+ })
+ .catch(() => dispatch('receiveTemplateError', template));
+};
+
+export const setFileTemplate = ({ dispatch, commit, rootGetters }, template) => {
+ dispatch(
+ 'changeFileContent',
+ { path: rootGetters.activeFile.path, content: template.content },
+ { root: true },
+ );
+ commit(types.SET_UPDATE_SUCCESS, true);
+};
+
+export const undoFileTemplate = ({ dispatch, commit, rootGetters }) => {
+ const file = rootGetters.activeFile;
+
+ dispatch('changeFileContent', { path: file.path, content: file.raw }, { root: true });
+ commit(types.SET_UPDATE_SUCCESS, false);
+};
+
+// prevent babel-plugin-rewire from generating an invalid default during karma tests
+export default () => {};
diff --git a/app/assets/javascripts/ide/stores/modules/file_templates/getters.js b/app/assets/javascripts/ide/stores/modules/file_templates/getters.js
new file mode 100644
index 00000000000..38318fd49bf
--- /dev/null
+++ b/app/assets/javascripts/ide/stores/modules/file_templates/getters.js
@@ -0,0 +1,23 @@
+export const templateTypes = () => [
+ {
+ name: '.gitlab-ci.yml',
+ key: 'gitlab_ci_ymls',
+ },
+ {
+ name: '.gitignore',
+ key: 'gitignores',
+ },
+ {
+ name: 'LICENSE',
+ key: 'licenses',
+ },
+ {
+ name: 'Dockerfile',
+ key: 'dockerfiles',
+ },
+];
+
+export const showFileTemplatesBar = (_, getters) => name =>
+ getters.templateTypes.find(t => t.name === name);
+
+export default () => {};
diff --git a/app/assets/javascripts/ide/stores/modules/file_templates/index.js b/app/assets/javascripts/ide/stores/modules/file_templates/index.js
new file mode 100644
index 00000000000..dfa5ef54413
--- /dev/null
+++ b/app/assets/javascripts/ide/stores/modules/file_templates/index.js
@@ -0,0 +1,12 @@
+import createState from './state';
+import * as actions from './actions';
+import * as getters from './getters';
+import mutations from './mutations';
+
+export default {
+ namespaced: true,
+ actions,
+ state: createState(),
+ getters,
+ mutations,
+};
diff --git a/app/assets/javascripts/ide/stores/modules/file_templates/mutation_types.js b/app/assets/javascripts/ide/stores/modules/file_templates/mutation_types.js
new file mode 100644
index 00000000000..cf4499c0264
--- /dev/null
+++ b/app/assets/javascripts/ide/stores/modules/file_templates/mutation_types.js
@@ -0,0 +1,7 @@
+export const REQUEST_TEMPLATE_TYPES = 'REQUEST_TEMPLATE_TYPES';
+export const RECEIVE_TEMPLATE_TYPES_ERROR = 'RECEIVE_TEMPLATE_TYPES_ERROR';
+export const RECEIVE_TEMPLATE_TYPES_SUCCESS = 'RECEIVE_TEMPLATE_TYPES_SUCCESS';
+
+export const SET_SELECTED_TEMPLATE_TYPE = 'SET_SELECTED_TEMPLATE_TYPE';
+
+export const SET_UPDATE_SUCCESS = 'SET_UPDATE_SUCCESS';
diff --git a/app/assets/javascripts/ide/stores/modules/file_templates/mutations.js b/app/assets/javascripts/ide/stores/modules/file_templates/mutations.js
new file mode 100644
index 00000000000..e413e61eaaa
--- /dev/null
+++ b/app/assets/javascripts/ide/stores/modules/file_templates/mutations.js
@@ -0,0 +1,21 @@
+/* eslint-disable no-param-reassign */
+import * as types from './mutation_types';
+
+export default {
+ [types.REQUEST_TEMPLATE_TYPES](state) {
+ state.isLoading = true;
+ },
+ [types.RECEIVE_TEMPLATE_TYPES_ERROR](state) {
+ state.isLoading = false;
+ },
+ [types.RECEIVE_TEMPLATE_TYPES_SUCCESS](state, templates) {
+ state.isLoading = false;
+ state.templates = templates;
+ },
+ [types.SET_SELECTED_TEMPLATE_TYPE](state, type) {
+ state.selectedTemplateType = type;
+ },
+ [types.SET_UPDATE_SUCCESS](state, success) {
+ state.updateSuccess = success;
+ },
+};
diff --git a/app/assets/javascripts/ide/stores/modules/file_templates/state.js b/app/assets/javascripts/ide/stores/modules/file_templates/state.js
new file mode 100644
index 00000000000..bd4b7d7bc52
--- /dev/null
+++ b/app/assets/javascripts/ide/stores/modules/file_templates/state.js
@@ -0,0 +1,6 @@
+export default () => ({
+ isLoading: false,
+ templates: [],
+ selectedTemplateType: {},
+ updateSuccess: false,
+});
diff --git a/app/assets/javascripts/ide/stores/mutations.js b/app/assets/javascripts/ide/stores/mutations.js
index 56a8d9430c7..0347f803757 100644
--- a/app/assets/javascripts/ide/stores/mutations.js
+++ b/app/assets/javascripts/ide/stores/mutations.js
@@ -146,13 +146,7 @@ export default {
staged: false,
prevPath: '',
moved: false,
- lastCommit: Object.assign(state.entries[file.path].lastCommit, {
- id: lastCommit.commit.id,
- url: lastCommit.commit_path,
- message: lastCommit.commit.message,
- author: lastCommit.commit.author_name,
- updatedAt: lastCommit.commit.authored_date,
- }),
+ lastCommitSha: lastCommit.commit.id,
});
if (prevPath) {
diff --git a/app/assets/javascripts/jobs/components/environments_block.vue b/app/assets/javascripts/jobs/components/environments_block.vue
new file mode 100644
index 00000000000..ca6386595c7
--- /dev/null
+++ b/app/assets/javascripts/jobs/components/environments_block.vue
@@ -0,0 +1,118 @@
+<script>
+ import _ from 'underscore';
+ import CiIcon from '~/vue_shared/components/ci_icon.vue';
+ import { sprintf, __ } from '../../locale';
+
+ export default {
+ components: {
+ CiIcon,
+ },
+ props: {
+ deploymentStatus: {
+ type: Object,
+ required: true,
+ },
+ },
+ computed: {
+ environment() {
+ let environmentText;
+ switch (this.deploymentStatus.status) {
+ case 'latest':
+ environmentText = sprintf(
+ __('This job is the most recent deployment to %{link}.'),
+ { link: this.environmentLink },
+ false,
+ );
+ break;
+ case 'out_of_date':
+ if (this.hasLastDeployment) {
+ environmentText = sprintf(
+ __(
+ 'This job is an out-of-date deployment to %{environmentLink}. View the most recent deployment %{deploymentLink}.',
+ ),
+ {
+ environmentLink: this.environmentLink,
+ deploymentLink: this.deploymentLink,
+ },
+ false,
+ );
+ } else {
+ environmentText = sprintf(
+ __('This job is an out-of-date deployment to %{environmentLink}.'),
+ { environmentLink: this.environmentLink },
+ false,
+ );
+ }
+
+ break;
+ case 'failed':
+ environmentText = sprintf(
+ __('The deployment of this job to %{environmentLink} did not succeed.'),
+ { environmentLink: this.environmentLink },
+ false,
+ );
+ break;
+ case 'creating':
+ if (this.hasLastDeployment) {
+ environmentText = sprintf(
+ __(
+ 'This job is creating a deployment to %{environmentLink} and will overwrite the last %{deploymentLink}.',
+ ),
+ {
+ environmentLink: this.environmentLink,
+ deploymentLink: this.deploymentLink,
+ },
+ false,
+ );
+ } else {
+ environmentText = sprintf(
+ __('This job is creating a deployment to %{environmentLink}.'),
+ { environmentLink: this.environmentLink },
+ false,
+ );
+ }
+ break;
+ default:
+ break;
+ }
+ return environmentText;
+ },
+ environmentLink() {
+ return sprintf(
+ '%{startLink}%{name}%{endLink}',
+ {
+ startLink: `<a href="${this.deploymentStatus.environment.path}">`,
+ name: _.escape(this.deploymentStatus.environment.name),
+ endLink: '</a>',
+ },
+ false,
+ );
+ },
+ deploymentLink() {
+ return sprintf(
+ '%{startLink}%{name}%{endLink}',
+ {
+ startLink: `<a href="${this.lastDeployment.path}">`,
+ name: _.escape(this.lastDeployment.name),
+ endLink: '</a>',
+ },
+ false,
+ );
+ },
+ hasLastDeployment() {
+ return this.deploymentStatus.environment.last_deployment;
+ },
+ lastDeployment() {
+ return this.deploymentStatus.environment.last_deployment;
+ },
+ },
+ };
+</script>
+<template>
+ <div class="prepend-top-default js-environment-container">
+ <div class="environment-information">
+ <ci-icon :status="deploymentStatus.icon" />
+ <p v-html="environment"></p>
+ </div>
+ </div>
+</template>
diff --git a/app/assets/javascripts/notes/components/note_awards_list.vue b/app/assets/javascripts/notes/components/note_awards_list.vue
index 225d9f18612..e111d3b9ac2 100644
--- a/app/assets/javascripts/notes/components/note_awards_list.vue
+++ b/app/assets/javascripts/notes/components/note_awards_list.vue
@@ -82,29 +82,17 @@ export default {
getAwardHTML(name) {
return glEmojiTag(name);
},
- getAwardClassBindings(awardList, awardName) {
+ getAwardClassBindings(awardList) {
return {
active: this.hasReactionByCurrentUser(awardList),
- disabled: !this.canInteractWithEmoji(awardList, awardName),
+ disabled: !this.canInteractWithEmoji(),
};
},
- canInteractWithEmoji(awardList, awardName) {
- let isAllowed = true;
- const restrictedEmojis = ['thumbsup', 'thumbsdown'];
-
- // Users can not add :+1: and :-1: to their own notes
- if (
- this.getUserData.id === this.noteAuthorId &&
- restrictedEmojis.indexOf(awardName) > -1
- ) {
- isAllowed = false;
- }
-
- return this.getUserData.id && isAllowed;
+ canInteractWithEmoji() {
+ return this.getUserData.id;
},
hasReactionByCurrentUser(awardList) {
- return awardList.filter(award => award.user.id === this.getUserData.id)
- .length;
+ return awardList.filter(award => award.user.id === this.getUserData.id).length;
},
awardTitle(awardsList) {
const hasReactionByCurrentUser = this.hasReactionByCurrentUser(
@@ -197,7 +185,7 @@ export default {
v-tooltip
v-for="(awardList, awardName, index) in groupedAwards"
:key="index"
- :class="getAwardClassBindings(awardList, awardName)"
+ :class="getAwardClassBindings(awardList)"
:title="awardTitle(awardList)"
class="btn award-control"
data-boundary="viewport"
diff --git a/app/assets/javascripts/pages/groups/milestones/show/index.js b/app/assets/javascripts/pages/groups/milestones/show/index.js
index 74cc4ba42c1..ebaea5ef3dc 100644
--- a/app/assets/javascripts/pages/groups/milestones/show/index.js
+++ b/app/assets/javascripts/pages/groups/milestones/show/index.js
@@ -1,8 +1,10 @@
import initMilestonesShow from '~/pages/milestones/shared/init_milestones_show';
+import initDeleteMilestoneModal from '~/pages/milestones/shared/delete_milestone_modal_init';
+
import Milestone from '~/milestone';
document.addEventListener('DOMContentLoaded', () => {
initMilestonesShow();
-
+ initDeleteMilestoneModal();
Milestone.initDeprecationMessage();
});
diff --git a/app/assets/javascripts/pages/milestones/shared/components/delete_milestone_modal.vue b/app/assets/javascripts/pages/milestones/shared/components/delete_milestone_modal.vue
index 4061c11ba8f..48668562f09 100644
--- a/app/assets/javascripts/pages/milestones/shared/components/delete_milestone_modal.vue
+++ b/app/assets/javascripts/pages/milestones/shared/components/delete_milestone_modal.vue
@@ -40,8 +40,8 @@
if (this.issueCount === 0 && this.mergeRequestCount === 0) {
return sprintf(
s__(`Milestones|
-You’re about to permanently delete the milestone %{milestoneTitle} from this project.
-%{milestoneTitle} is not currently used in any issues or merge requests.`),
+You’re about to permanently delete the milestone %{milestoneTitle}.
+This milestone is not currently used in any issues or merge requests.`),
{
milestoneTitle,
},
@@ -51,7 +51,7 @@ You’re about to permanently delete the milestone %{milestoneTitle} from this p
return sprintf(
s__(`Milestones|
-You’re about to permanently delete the milestone %{milestoneTitle} from this project and remove it from %{issuesWithCount} and %{mergeRequestsWithCount}.
+You’re about to permanently delete the milestone %{milestoneTitle} and remove it from %{issuesWithCount} and %{mergeRequestsWithCount}.
Once deleted, it cannot be undone or recovered.`),
{
milestoneTitle,
diff --git a/app/assets/javascripts/pages/profiles/show/index.js b/app/assets/javascripts/pages/profiles/show/index.js
index 949219a0837..aea7b649c20 100644
--- a/app/assets/javascripts/pages/profiles/show/index.js
+++ b/app/assets/javascripts/pages/profiles/show/index.js
@@ -3,15 +3,22 @@ import createFlash from '~/flash';
import GfmAutoComplete from '~/gfm_auto_complete';
import EmojiMenu from './emoji_menu';
+const defaultStatusEmoji = 'speech_balloon';
+
document.addEventListener('DOMContentLoaded', () => {
const toggleEmojiMenuButtonSelector = '.js-toggle-emoji-menu';
const toggleEmojiMenuButton = document.querySelector(toggleEmojiMenuButtonSelector);
const statusEmojiField = document.getElementById('js-status-emoji-field');
const statusMessageField = document.getElementById('js-status-message-field');
- const findNoEmojiPlaceholder = () => document.getElementById('js-no-emoji-placeholder');
+ const toggleNoEmojiPlaceholder = (isVisible) => {
+ const placeholderElement = document.getElementById('js-no-emoji-placeholder');
+ placeholderElement.classList.toggle('hidden', !isVisible);
+ };
+
+ const findStatusEmoji = () => toggleEmojiMenuButton.querySelector('gl-emoji');
const removeStatusEmoji = () => {
- const statusEmoji = toggleEmojiMenuButton.querySelector('gl-emoji');
+ const statusEmoji = findStatusEmoji();
if (statusEmoji) {
statusEmoji.remove();
}
@@ -19,7 +26,7 @@ document.addEventListener('DOMContentLoaded', () => {
const selectEmojiCallback = (emoji, emojiTag) => {
statusEmojiField.value = emoji;
- findNoEmojiPlaceholder().classList.add('hidden');
+ toggleNoEmojiPlaceholder(false);
removeStatusEmoji();
toggleEmojiMenuButton.innerHTML += emojiTag;
};
@@ -29,7 +36,7 @@ document.addEventListener('DOMContentLoaded', () => {
statusEmojiField.value = '';
statusMessageField.value = '';
removeStatusEmoji();
- findNoEmojiPlaceholder().classList.remove('hidden');
+ toggleNoEmojiPlaceholder(true);
});
const emojiAutocomplete = new GfmAutoComplete();
@@ -44,6 +51,23 @@ document.addEventListener('DOMContentLoaded', () => {
selectEmojiCallback,
);
emojiMenu.bindEvents();
+
+ const defaultEmojiTag = Emoji.glEmojiTag(defaultStatusEmoji);
+ statusMessageField.addEventListener('input', () => {
+ const hasStatusMessage = statusMessageField.value.trim() !== '';
+ const statusEmoji = findStatusEmoji();
+ if (hasStatusMessage && statusEmoji) {
+ return;
+ }
+
+ if (hasStatusMessage) {
+ toggleNoEmojiPlaceholder(false);
+ toggleEmojiMenuButton.innerHTML += defaultEmojiTag;
+ } else if (statusEmoji.dataset.name === defaultStatusEmoji) {
+ toggleNoEmojiPlaceholder(true);
+ removeStatusEmoji();
+ }
+ });
})
.catch(() => createFlash('Failed to load emoji list!'));
});
diff --git a/app/assets/javascripts/performance_bar/index.js b/app/assets/javascripts/performance_bar/index.js
index 41880d27516..6e5ef0ac0b2 100644
--- a/app/assets/javascripts/performance_bar/index.js
+++ b/app/assets/javascripts/performance_bar/index.js
@@ -1,5 +1,4 @@
import Vue from 'vue';
-import Flash from '../flash';
import PerformanceBarService from './services/performance_bar_service';
import PerformanceBarStore from './stores/performance_bar_store';
@@ -46,7 +45,8 @@ export default ({ container }) =>
this.store.addRequestDetails(requestId, res.data.data);
})
.catch(() =>
- Flash(`Error getting performance bar results for ${requestId}`),
+ // eslint-disable-next-line no-console
+ console.warn(`Error getting performance bar results for ${requestId}`),
);
},
},
diff --git a/app/assets/javascripts/performance_bar/services/performance_bar_service.js b/app/assets/javascripts/performance_bar/services/performance_bar_service.js
index bc71911ae35..60d9ba62570 100644
--- a/app/assets/javascripts/performance_bar/services/performance_bar_service.js
+++ b/app/assets/javascripts/performance_bar/services/performance_bar_service.js
@@ -11,13 +11,10 @@ export default class PerformanceBarService {
static registerInterceptor(peekUrl, callback) {
const interceptor = response => {
- const requestId = response.headers['x-request-id'];
- // Get the request URL from response.config for Axios, and response for
- // Vue Resource.
- const requestUrl = (response.config || response).url;
- const cachedResponse = response.headers['x-gitlab-from-cache'] === 'true';
+ const [fireCallback, requestId, requestUrl] =
+ PerformanceBarService.callbackParams(response, peekUrl);
- if (requestUrl !== peekUrl && requestId && !cachedResponse) {
+ if (fireCallback) {
callback(requestId, requestUrl);
}
@@ -38,4 +35,16 @@ export default class PerformanceBarService {
vueResourceInterceptor,
);
}
+
+ static callbackParams(response, peekUrl) {
+ const requestId = response.headers && response.headers['x-request-id'];
+ // Get the request URL from response.config for Axios, and response for
+ // Vue Resource.
+ const requestUrl = (response.config || response).url;
+ const apiRequest = requestUrl && requestUrl.match(/^\/api\//);
+ const cachedResponse = response.headers && response.headers['x-gitlab-from-cache'] === 'true';
+ const fireCallback = requestUrl !== peekUrl && requestId && !apiRequest && !cachedResponse;
+
+ return [fireCallback, requestId, requestUrl];
+ }
}
diff --git a/app/assets/javascripts/pipelines/components/graph/dropdown_job_component.vue b/app/assets/javascripts/pipelines/components/graph/dropdown_job_component.vue
index 8487c8036ee..2ad66f4fe86 100644
--- a/app/assets/javascripts/pipelines/components/graph/dropdown_job_component.vue
+++ b/app/assets/javascripts/pipelines/components/graph/dropdown_job_component.vue
@@ -1,6 +1,5 @@
<script>
import $ from 'jquery';
-import _ from 'underscore';
import JobNameComponent from './job_name_component.vue';
import JobComponent from './job_component.vue';
import tooltip from '../../../vue_shared/directives/tooltip';
@@ -47,7 +46,7 @@ export default {
computed: {
tooltipText() {
- return _.escape(`${this.job.name} - ${this.job.status.label}`);
+ return `${this.job.name} - ${this.job.status.label}`;
},
},
diff --git a/app/assets/javascripts/pipelines/components/graph/job_component.vue b/app/assets/javascripts/pipelines/components/graph/job_component.vue
index 66f95147193..9ac16b7e541 100644
--- a/app/assets/javascripts/pipelines/components/graph/job_component.vue
+++ b/app/assets/javascripts/pipelines/components/graph/job_component.vue
@@ -1,5 +1,4 @@
<script>
-import _ from 'underscore';
import ActionComponent from './action_component.vue';
import JobNameComponent from './job_name_component.vue';
import tooltip from '../../../vue_shared/directives/tooltip';
@@ -62,7 +61,7 @@ export default {
const textBuilder = [];
if (this.job.name) {
- textBuilder.push(_.escape(this.job.name));
+ textBuilder.push(this.job.name);
}
if (this.job.name && this.status.tooltip) {
@@ -106,7 +105,6 @@ export default {
:class="cssClassJobName"
:data-boundary="tooltipBoundary"
data-container="body"
- data-html="true"
class="js-pipeline-graph-job-link"
>
@@ -122,7 +120,6 @@ export default {
:title="tooltipText"
:class="cssClassJobName"
class="js-job-component-tooltip non-details-job-component"
- data-html="true"
data-container="body"
>
diff --git a/app/assets/javascripts/pipelines/components/pipelines_table_row.vue b/app/assets/javascripts/pipelines/components/pipelines_table_row.vue
index 804822a3ea8..29b347824de 100644
--- a/app/assets/javascripts/pipelines/components/pipelines_table_row.vue
+++ b/app/assets/javascripts/pipelines/components/pipelines_table_row.vue
@@ -330,7 +330,7 @@ export default {
<pipelines-artifacts-component
v-if="pipeline.details.artifacts.length"
:artifacts="pipeline.details.artifacts"
- class="d-none d-sm-none d-md-block"
+ class="d-md-block"
/>
<loading-button
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/deployment.vue b/app/assets/javascripts/vue_merge_request_widget/components/deployment.vue
index 21f21232596..d530ab2767b 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/deployment.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/deployment.vue
@@ -1,5 +1,6 @@
<script>
import Icon from '~/vue_shared/components/icon.vue';
+import TooltipOnTruncate from '~/vue_shared/components/tooltip_on_truncate.vue';
import timeagoMixin from '../../vue_shared/mixins/timeago';
import tooltip from '../../vue_shared/directives/tooltip';
import LoadingButton from '../../vue_shared/components/loading_button.vue';
@@ -16,6 +17,7 @@ export default {
MemoryUsage,
StatusIcon,
Icon,
+ TooltipOnTruncate,
},
directives: {
tooltip,
@@ -88,14 +90,20 @@ export default {
<span>
Deployed to
</span>
- <a
- :href="deployment.url"
- target="_blank"
- rel="noopener noreferrer nofollow"
- class="deploy-link js-deploy-meta"
+ <tooltip-on-truncate
+ :title="deployment.name"
+ truncate-target="child"
+ class="deploy-link label-truncate"
>
- {{ deployment.name }}
- </a>
+ <a
+ :href="deployment.url"
+ target="_blank"
+ rel="noopener noreferrer nofollow"
+ class="js-deploy-meta"
+ >
+ {{ deployment.name }}
+ </a>
+ </tooltip-on-truncate>
</template>
<span
v-tooltip
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_header.vue b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_header.vue
index a4c2289c590..72bd28ae03f 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_header.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_header.vue
@@ -1,18 +1,17 @@
<script>
-import tooltip from '~/vue_shared/directives/tooltip';
-import { n__ } from '~/locale';
+import _ from 'underscore';
+import { n__, s__, sprintf } from '~/locale';
import { mergeUrlParams, webIDEUrl } from '~/lib/utils/url_utility';
import Icon from '~/vue_shared/components/icon.vue';
import clipboardButton from '~/vue_shared/components/clipboard_button.vue';
+import TooltipOnTruncate from '~/vue_shared/components/tooltip_on_truncate.vue';
export default {
name: 'MRWidgetHeader',
- directives: {
- tooltip,
- },
components: {
Icon,
clipboardButton,
+ TooltipOnTruncate,
},
props: {
mr: {
@@ -24,8 +23,12 @@ export default {
shouldShowCommitsBehindText() {
return this.mr.divergedCommitsCount > 0;
},
- commitsText() {
- return n__('%d commit behind', '%d commits behind', this.mr.divergedCommitsCount);
+ commitsBehindText() {
+ return sprintf(s__('mrWidget|The source branch is %{commitsBehindLinkStart}%{commitsBehind}%{commitsBehindLinkEnd} the target branch'), {
+ commitsBehindLinkStart: `<a href="${_.escape(this.mr.targetBranchPath)}">`,
+ commitsBehind: n__('%d commit behind', '%d commits behind', this.mr.divergedCommitsCount),
+ commitsBehindLinkEnd: '</a>',
+ }, false);
},
branchNameClipboardData() {
// This supports code in app/assets/javascripts/copy_to_clipboard.js that
@@ -36,12 +39,6 @@ export default {
gfm: `\`${this.mr.sourceBranch}\``,
});
},
- isSourceBranchLong() {
- return this.isBranchTitleLong(this.mr.sourceBranch);
- },
- isTargetBranchLong() {
- return this.isBranchTitleLong(this.mr.targetBranch);
- },
webIdePath() {
return mergeUrlParams({
target_project: this.mr.sourceProjectFullPath !== this.mr.targetProjectFullPath ?
@@ -49,11 +46,6 @@ export default {
}, webIDEUrl(`/${this.mr.sourceProjectFullPath}/merge_requests/${this.mr.iid}`));
},
},
- methods: {
- isBranchTitleLong(branchTitle) {
- return branchTitle.length > 32;
- },
- },
};
</script>
<template>
@@ -65,30 +57,21 @@ export default {
<div class="normal">
<strong>
{{ s__("mrWidget|Request to merge") }}
- <span
- :class="{ 'label-truncated': isSourceBranchLong }"
- :title="isSourceBranchLong ? mr.sourceBranch : ''"
- :v-tooltip="isSourceBranchLong"
- class="label-branch js-source-branch"
- data-placement="bottom"
+ <tooltip-on-truncate
+ :title="mr.sourceBranch"
+ truncate-target="child"
+ class="label-branch label-truncate js-source-branch"
v-html="mr.sourceBranchLink"
- >
- </span>
-
- <clipboard-button
+ /><clipboard-button
:text="branchNameClipboardData"
:title="__('Copy branch name to clipboard')"
css-class="btn-default btn-transparent btn-clipboard"
/>
-
{{ s__("mrWidget|into") }}
-
- <span
- :v-tooltip="isTargetBranchLong"
- :class="{ 'label-truncatedtooltip': isTargetBranchLong }"
- :title="isTargetBranchLong ? mr.targetBranch : ''"
- class="label-branch"
- data-placement="bottom"
+ <tooltip-on-truncate
+ :title="mr.targetBranch"
+ truncate-target="child"
+ class="label-branch label-truncate"
>
<a
:href="mr.targetBranchTreePath"
@@ -96,15 +79,13 @@ export default {
>
{{ mr.targetBranch }}
</a>
- </span>
+ </tooltip-on-truncate>
</strong>
<div
v-if="shouldShowCommitsBehindText"
class="diverged-commits-count"
+ v-html="commitsBehindText"
>
- <span class="monospace">{{ mr.sourceBranch }}</span>
- is {{ commitsText }}
- <span class="monospace">{{ mr.targetBranch }}</span>
</div>
</div>
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_pipeline.vue b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_pipeline.vue
index 4a3fd01fa39..fee41b239e8 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_pipeline.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_pipeline.vue
@@ -3,6 +3,7 @@
import PipelineStage from '~/pipelines/components/stage.vue';
import CiIcon from '~/vue_shared/components/ci_icon.vue';
import Icon from '~/vue_shared/components/icon.vue';
+import TooltipOnTruncate from '~/vue_shared/components/tooltip_on_truncate.vue';
export default {
name: 'MRWidgetPipeline',
@@ -10,6 +11,7 @@ export default {
PipelineStage,
CiIcon,
Icon,
+ TooltipOnTruncate,
},
props: {
pipeline: {
@@ -30,6 +32,10 @@ export default {
type: String,
required: false,
},
+ sourceBranch: {
+ type: String,
+ required: false,
+ },
},
computed: {
hasPipeline() {
@@ -107,11 +113,12 @@ export default {
>
{{ pipeline.commit.short_id }}</a>
on
- <span
- class="label-branch"
+ <tooltip-on-truncate
+ :title="sourceBranch"
+ truncate-target="child"
+ class="label-branch label-truncate"
v-html="sourceBranchLink"
- >
- </span>
+ />
</template>
</div>
<div
diff --git a/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue b/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue
index 80593d1f34a..dc6be025f11 100644
--- a/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue
@@ -254,6 +254,7 @@ export default {
:pipeline="mr.pipeline"
:ci-status="mr.ciStatus"
:has-ci="mr.hasCI"
+ :source-branch="mr.sourceBranch"
:source-branch-link="mr.sourceBranchLink"
/>
<deployment
diff --git a/app/assets/javascripts/vue_shared/components/stacked_progress_bar.vue b/app/assets/javascripts/vue_shared/components/stacked_progress_bar.vue
index f44d361c47e..78fde463507 100644
--- a/app/assets/javascripts/vue_shared/components/stacked_progress_bar.vue
+++ b/app/assets/javascripts/vue_shared/components/stacked_progress_bar.vue
@@ -71,7 +71,11 @@ export default {
},
methods: {
getPercent(count) {
- return roundOffFloat((count / this.totalCount) * 100, 1);
+ const percent = roundOffFloat((count / this.totalCount) * 100, 1);
+ if (percent > 0 && percent < 1) {
+ return '< 1';
+ }
+ return percent;
},
barStyle(percent) {
return `width: ${percent}%;`;
diff --git a/app/assets/javascripts/vue_shared/components/tooltip_on_truncate.vue b/app/assets/javascripts/vue_shared/components/tooltip_on_truncate.vue
new file mode 100644
index 00000000000..125826da6c3
--- /dev/null
+++ b/app/assets/javascripts/vue_shared/components/tooltip_on_truncate.vue
@@ -0,0 +1,67 @@
+<script>
+import _ from 'underscore';
+import tooltip from '../directives/tooltip';
+
+export default {
+ directives: {
+ tooltip,
+ },
+ props: {
+ title: {
+ type: String,
+ required: false,
+ default: '',
+ },
+ placement: {
+ type: String,
+ required: false,
+ default: 'top',
+ },
+ truncateTarget: {
+ type: [String, Function],
+ required: false,
+ default: '',
+ },
+ },
+ data() {
+ return {
+ showTooltip: false,
+ };
+ },
+ mounted() {
+ const target = this.selectTarget();
+
+ if (target && target.scrollWidth > target.offsetWidth) {
+ this.showTooltip = true;
+ }
+ },
+ methods: {
+ selectTarget() {
+ if (_.isFunction(this.truncateTarget)) {
+ return this.truncateTarget(this.$el);
+ } else if (this.truncateTarget === 'child') {
+ return this.$el.childNodes[0];
+ }
+
+ return this.$el;
+ },
+ },
+};
+</script>
+
+<template>
+ <span
+ v-tooltip
+ v-if="showTooltip"
+ :title="title"
+ :data-placement="placement"
+ class="js-show-tooltip"
+ >
+ <slot></slot>
+ </span>
+ <span
+ v-else
+ >
+ <slot></slot>
+ </span>
+</template>
diff --git a/app/assets/stylesheets/bootstrap_migration.scss b/app/assets/stylesheets/bootstrap_migration.scss
index e8e707cf90c..c91f5e279ea 100644
--- a/app/assets/stylesheets/bootstrap_migration.scss
+++ b/app/assets/stylesheets/bootstrap_migration.scss
@@ -4,11 +4,11 @@
$text-color: $gl-text-color;
-$brand-primary: $gl-primary;
-$brand-success: $gl-success;
-$brand-info: $gl-info;
-$brand-warning: $gl-warning;
-$brand-danger: $gl-danger;
+$brand-primary: $blue-500;
+$brand-success: $green-500;
+$brand-info: $blue-500;
+$brand-warning: $orange-500;
+$brand-danger: $red-500;
$border-radius-base: 3px !default;
diff --git a/app/assets/stylesheets/framework/avatar.scss b/app/assets/stylesheets/framework/avatar.scss
index 4c7c399a3ca..9dd0384a228 100644
--- a/app/assets/stylesheets/framework/avatar.scss
+++ b/app/assets/stylesheets/framework/avatar.scss
@@ -8,7 +8,7 @@
float: left;
margin-right: 15px;
border-radius: $avatar-radius;
- border: 1px solid $avatar-border;
+ border: 1px solid $gray-normal;
&.s16 { @include avatar-size(16px, 6px); }
&.s18 { @include avatar-size(18px, 6px); }
&.s19 { @include avatar-size(19px, 6px); }
@@ -36,7 +36,7 @@
width: 40px;
height: 40px;
padding: 0;
- background: $avatar-background;
+ background: $gray-lightest;
overflow: hidden;
&.avatar-inline {
@@ -62,7 +62,7 @@
}
&:not([href]):hover {
- border-color: darken($avatar-border, 10%);
+ border-color: darken($gray-normal, 10%);
}
}
@@ -70,7 +70,7 @@
text-align: center;
vertical-align: top;
color: $identicon-fg-color;
- background-color: $identicon-gray;
+ background-color: $gray-darker;
// Sizes
&.s16 { font-size: 12px; line-height: 1.33; }
@@ -94,7 +94,7 @@
&.bg4 { background-color: $identicon-blue; }
&.bg5 { background-color: $identicon-teal; }
&.bg6 { background-color: $identicon-orange; }
- &.bg7 { background-color: $identicon-gray; }
+ &.bg7 { background-color: $gray-darker; }
}
.avatar-container {
@@ -122,7 +122,7 @@
.avatar-counter {
background-color: $gray-darkest;
color: $white-light;
- border: 1px solid $avatar-border;
+ border: 1px solid $gray-normal;
border-radius: 1em;
font-family: $regular-font;
font-size: 9px;
diff --git a/app/assets/stylesheets/framework/badges.scss b/app/assets/stylesheets/framework/badges.scss
index 57df9b969c3..c6060161dec 100644
--- a/app/assets/stylesheets/framework/badges.scss
+++ b/app/assets/stylesheets/framework/badges.scss
@@ -1,6 +1,6 @@
.badge.badge-pill {
font-weight: $gl-font-weight-normal;
background-color: $badge-bg;
- color: $badge-color;
+ color: $gl-text-color-secondary;
vertical-align: baseline;
}
diff --git a/app/assets/stylesheets/framework/buttons.scss b/app/assets/stylesheets/framework/buttons.scss
index 0dc7aa4ef68..72b4ed0ac33 100644
--- a/app/assets/stylesheets/framework/buttons.scss
+++ b/app/assets/stylesheets/framework/buttons.scss
@@ -452,14 +452,14 @@
}
.btn-missing {
- color: $notes-light-color;
+ color: $gl-text-color-secondary;
border: 1px dashed $border-gray-normal-dashed;
border-radius: $border-radius-default;
&:hover,
&:active,
&:focus {
- color: $notes-light-color;
+ color: $gl-text-color-secondary;
background-color: $white-normal;
}
}
diff --git a/app/assets/stylesheets/framework/callout.scss b/app/assets/stylesheets/framework/callout.scss
index 1bd94c0acba..bdd7f09d926 100644
--- a/app/assets/stylesheets/framework/callout.scss
+++ b/app/assets/stylesheets/framework/callout.scss
@@ -25,25 +25,25 @@
/* Variations */
.bs-callout-danger {
- background-color: $callout-danger-bg;
- border-color: $callout-danger-border;
- color: $callout-danger-color;
+ background-color: $red-100;
+ border-color: $red-200;
+ color: $red-700;
}
.bs-callout-warning {
- background-color: $callout-warning-bg;
- border-color: $callout-warning-border;
- color: $callout-warning-color;
+ background-color: $orange-100;
+ border-color: $orange-200;
+ color: $orange-700;
}
.bs-callout-info {
- background-color: $callout-info-bg;
- border-color: $callout-info-border;
- color: $callout-info-color;
+ background-color: $blue-100;
+ border-color: $blue-200;
+ color: $blue-700;
}
.bs-callout-success {
- background-color: $callout-success-bg;
- border-color: $callout-success-border;
- color: $callout-success-color;
+ background-color: $green-100;
+ border-color: $green-200;
+ color: $green-700;
}
diff --git a/app/assets/stylesheets/framework/common.scss b/app/assets/stylesheets/framework/common.scss
index 79ca6e61e9a..72e27f9ad16 100644
--- a/app/assets/stylesheets/framework/common.scss
+++ b/app/assets/stylesheets/framework/common.scss
@@ -1,8 +1,8 @@
/** COLORS **/
-.cgray { color: $common-gray; }
+.cgray { color: $gl-text-color; }
.clgray { color: $common-gray-light; }
-.cred { color: $common-red; }
-.cgreen { color: $common-green; }
+.cred { color: $red-500; }
+.cgreen { color: $green-600; }
.cdark { color: $common-gray-dark; }
.text-plain,
@@ -44,10 +44,10 @@
}
.hint { font-style: italic; color: $hint-color; }
-.light { color: $common-gray; }
+.light { color: $gl-text-color; }
.slead {
- color: $common-gray;
+ color: $gl-text-color;
font-size: 14px;
margin-bottom: 12px;
font-weight: $gl-font-weight-normal;
@@ -352,7 +352,7 @@ img.emoji {
border-color: $border-color !important;
.dz-upload {
- background: $gl-success !important;
+ background: $green-500 !important;
}
}
diff --git a/app/assets/stylesheets/framework/dropdowns.scss b/app/assets/stylesheets/framework/dropdowns.scss
index 83bc3776178..8a224dc517e 100644
--- a/app/assets/stylesheets/framework/dropdowns.scss
+++ b/app/assets/stylesheets/framework/dropdowns.scss
@@ -147,7 +147,7 @@
}
@mixin dropdown-item-hover {
- background-color: $dropdown-item-hover-bg;
+ background-color: $gray-darker;
color: $gl-text-color;
outline: 0;
@@ -195,7 +195,7 @@
text-decoration: none;
.badge.badge-pill {
- background-color: darken($dropdown-link-hover-bg, 5%);
+ background-color: darken($blue-50, 5%);
}
}
@@ -233,7 +233,7 @@
font-weight: $gl-font-weight-normal;
padding: 8px 0;
background-color: $white-light;
- border: 1px solid $dropdown-border-color;
+ border: 1px solid $border-color;
border-radius: $border-radius-base;
box-shadow: 0 2px 4px $dropdown-shadow-color;
@@ -874,7 +874,7 @@ header.header-content .dropdown-menu.frequent-items-dropdown-menu {
overflow-y: auto;
li.section-empty.section-failure {
- color: $callout-danger-color;
+ color: $red-700;
}
.frequent-items-list-item-container a {
diff --git a/app/assets/stylesheets/framework/feature_highlight.scss b/app/assets/stylesheets/framework/feature_highlight.scss
index cad915bc86f..85cabf43e9e 100644
--- a/app/assets/stylesheets/framework/feature_highlight.scss
+++ b/app/assets/stylesheets/framework/feature_highlight.scss
@@ -72,11 +72,11 @@
.feature-highlight-popover {
width: 240px;
padding: 0;
- border: 1px solid $dropdown-border-color;
+ border: 1px solid $border-color;
box-shadow: 0 2px 4px $dropdown-shadow-color;
&.right > .arrow {
- border-right-color: $dropdown-border-color;
+ border-right-color: $border-color;
}
.popover-body {
diff --git a/app/assets/stylesheets/framework/files.scss b/app/assets/stylesheets/framework/files.scss
index 3bdf5bfc93a..1d3512bbb4c 100644
--- a/app/assets/stylesheets/framework/files.scss
+++ b/app/assets/stylesheets/framework/files.scss
@@ -312,11 +312,11 @@ span.idiff {
text-decoration: none;
.new-file {
- color: $notify-new-file;
+ color: $green-600;
}
.deleted-file {
- color: $notify-deleted-file;
+ color: $red-700;
}
}
}
diff --git a/app/assets/stylesheets/framework/filters.scss b/app/assets/stylesheets/framework/filters.scss
index 9b09ed0ed0a..abfe350677e 100644
--- a/app/assets/stylesheets/framework/filters.scss
+++ b/app/assets/stylesheets/framework/filters.scss
@@ -206,7 +206,7 @@
&.focus,
&.focus:hover {
border-color: $blue-300;
- box-shadow: 0 0 4px $search-input-focus-shadow-color;
+ box-shadow: 0 0 4px $dropdown-input-focus-shadow;
}
gl-emoji {
diff --git a/app/assets/stylesheets/framework/forms.scss b/app/assets/stylesheets/framework/forms.scss
index a70eece8f68..afd888af672 100644
--- a/app/assets/stylesheets/framework/forms.scss
+++ b/app/assets/stylesheets/framework/forms.scss
@@ -8,7 +8,7 @@ input {
input[type='text'].danger {
background: $input-danger-bg !important;
- border-color: $input-danger-border;
+ border-color: $red-400;
text-shadow: 0 1px 1px $white-light;
}
diff --git a/app/assets/stylesheets/framework/header.scss b/app/assets/stylesheets/framework/header.scss
index e7e13d35d8e..11a30d83f03 100644
--- a/app/assets/stylesheets/framework/header.scss
+++ b/app/assets/stylesheets/framework/header.scss
@@ -554,7 +554,7 @@
float: left;
margin-right: 5px;
border-radius: 50%;
- border: 1px solid $avatar-border;
+ border: 1px solid $gray-normal;
}
.with-performance-bar .navbar-gitlab {
diff --git a/app/assets/stylesheets/framework/icons.scss b/app/assets/stylesheets/framework/icons.scss
index d1f7ff4438b..f002edced8a 100644
--- a/app/assets/stylesheets/framework/icons.scss
+++ b/app/assets/stylesheets/framework/icons.scss
@@ -11,7 +11,7 @@
.ci-status-icon-failed {
svg {
- fill: $gl-danger;
+ fill: $red-500;
}
&.add-border {
diff --git a/app/assets/stylesheets/framework/issue_box.scss b/app/assets/stylesheets/framework/issue_box.scss
index da5f80d9d37..2d672e62e08 100644
--- a/app/assets/stylesheets/framework/issue_box.scss
+++ b/app/assets/stylesheets/framework/issue_box.scss
@@ -26,12 +26,12 @@
&.status-box-closed,
&.status-box-mr-closed {
- background-color: $gl-danger;
+ background-color: $red-500;
}
&.status-box-issue-closed,
&.status-box-mr-merged {
- background-color: $gl-primary;
+ background-color: $blue-500;
}
&.status-box-open {
diff --git a/app/assets/stylesheets/framework/selects.scss b/app/assets/stylesheets/framework/selects.scss
index 88d2f0aaf85..3ae2c7078d6 100644
--- a/app/assets/stylesheets/framework/selects.scss
+++ b/app/assets/stylesheets/framework/selects.scss
@@ -58,7 +58,7 @@
.select2-drop.select2-drop-above {
box-shadow: 0 2px 4px $dropdown-shadow-color;
border-radius: $border-radius-base;
- border: 1px solid $dropdown-border-color;
+ border: 1px solid $border-color;
min-width: 175px;
color: $gl-text-color;
z-index: 999;
@@ -69,7 +69,7 @@
}
.select2-drop.select2-drop-above.select2-drop-active {
- border-top: 1px solid $dropdown-border-color;
+ border-top: 1px solid $border-color;
margin-top: -6px;
}
@@ -193,7 +193,7 @@
color: $gl-text-color;
.select2-result-label {
- background: $dropdown-item-hover-bg;
+ background: $gray-darker;
}
}
diff --git a/app/assets/stylesheets/framework/variables.scss b/app/assets/stylesheets/framework/variables.scss
index 96508a71bd8..2781d910b8d 100644
--- a/app/assets/stylesheets/framework/variables.scss
+++ b/app/assets/stylesheets/framework/variables.scss
@@ -297,19 +297,9 @@ $tanuki-yellow: #fca326;
/*
* State colors:
*/
-$gl-primary: $blue-500;
-$gl-success: $green-500;
-$gl-success-focus: rgba($gl-success, 0.4);
-$gl-info: $blue-500;
-$gl-warning: $orange-500;
-$gl-danger: $red-500;
+$green-500-focus: rgba($green-500, 0.4);
$gl-btn-active-background: rgba(0, 0, 0, 0.16);
$gl-btn-active-gradient: inset 0 2px 3px $gl-btn-active-background;
-// Bootstrap override states
-$success: $gl-success;
-$info: $gl-info;
-$warning: $gl-warning;
-$danger: $gl-danger;
/*
* Commit Diff Colors
@@ -329,10 +319,9 @@ $line-select-yellow-dark: #f0e2bd;
$dark-diff-match-bg: rgba(255, 255, 255, 0.3);
$dark-diff-match-color: rgba(255, 255, 255, 0.1);
$file-mode-changed: #777;
-$file-mode-changed: #777;
-$diff-image-info-color: grey;
+$diff-image-info-color: gray;
$diff-swipe-border: #999;
-$diff-view-modes-color: grey;
+$diff-view-modes-color: gray;
$diff-view-modes-border: #c1c1c1;
$diff-jagged-border-gradient-color: darken($white-normal, 8%);
@@ -352,9 +341,7 @@ $dropdown-min-height: 40px;
$dropdown-max-height: 312px;
$dropdown-vertical-offset: 4px;
$dropdown-link-color: #555;
-$dropdown-link-hover-bg: $blue-50;
$dropdown-empty-row-bg: rgba(#000, 0.04);
-$dropdown-border-color: $border-color;
$dropdown-shadow-color: rgba(#000, 0.1);
$dropdown-divider-color: rgba(#000, 0.1);
$dropdown-title-btn-color: #bfbfbf;
@@ -364,7 +351,6 @@ $dropdown-input-focus-shadow: rgba($blue-300, 0.4);
$dropdown-loading-bg: rgba(#fff, 0.6);
$dropdown-chevron-size: 10px;
$dropdown-toggle-active-border-color: darken($border-color, 14%);
-$dropdown-item-hover-bg: $gray-darker;
$dropdown-fade-mask-height: 32px;
$dropdown-member-form-control-width: 163px;
@@ -372,7 +358,6 @@ $dropdown-member-form-control-width: 163px;
* Filtered Search
*/
$filtered-search-term-shadow-color: rgba(0, 0, 0, 0.09);
-$dropdown-hover-color: $blue-400;
/*
* Contextual Sidebar
@@ -387,7 +372,7 @@ $sidebar-milestone-toggle-bottom-margin: 10px;
* Buttons
*/
$btn-active-gray: #ececec;
-$btn-active-gray-light: e4e7ed;
+$btn-active-gray-light: #e4e7ed;
$btn-white-active: #848484;
$gl-btn-padding: 10px;
$gl-btn-line-height: 16px;
@@ -398,7 +383,6 @@ $gl-btn-horz-padding: 12px;
* Badges
*/
$badge-bg: rgba(0, 0, 0, 0.07);
-$badge-color: $gl-text-color-secondary;
/*
* Pagination
@@ -406,21 +390,12 @@ $badge-color: $gl-text-color-secondary;
$pagination-padding-y: 6px;
$pagination-padding-x: 16px;
$pagination-line-height: 20px;
-$pagination-border-color: $border-color;
-$pagination-active-bg: $blue-600;
-$pagination-active-border-color: $blue-600;
-$pagination-hover-bg: $blue-50;
-$pagination-hover-border-color: $border-color;
-$pagination-hover-color: $gl-text-color;
$pagination-disabled-color: #cdcdcd;
-$pagination-disabled-bg: $gray-light;
-$pagination-disabled-border-color: $border-color;
/*
* Status icons
*/
$status-icon-size: 22px;
-$status-icon-margin: $gl-btn-padding;
/*
* Award emoji
@@ -433,16 +408,13 @@ $award-emoji-positive-add-lines: #bb9c13;
* Search Box
*/
$search-input-border-color: rgba($blue-400, 0.8);
-$search-input-focus-shadow-color: $dropdown-input-focus-shadow;
$search-input-width: 240px;
$search-input-active-width: 320px;
-$location-badge-active-bg: $blue-500;
$location-icon-color: #e7e9ed;
/*
* Notes
*/
-$notes-light-color: $gl-text-color-secondary;
$note-disabled-comment-color: #b2b2b2;
$note-targe3-outside: #fffff0;
$note-targe3-inside: #ffffd3;
@@ -463,7 +435,6 @@ $identicon-indigo: #e8eaf6;
$identicon-blue: #e3f2fd;
$identicon-teal: #e0f2f1;
$identicon-orange: #fbe9e7;
-$identicon-gray: $gray-darker;
$identicon-fg-color: #555555;
/*
@@ -479,7 +450,6 @@ $calendar-user-contrib-text: #959494;
$cycle-analytics-box-padding: 30px;
$cycle-analytics-box-text-color: #8c8c8c;
$cycle-analytics-big-font: 19px;
-$cycle-analytics-dark-text: $gl-text-color;
$cycle-analytics-light-gray: #bfbfbf;
$cycle-analytics-dismiss-icon-color: #b2b2b2;
@@ -507,9 +477,6 @@ $issue-board-list-difference-md: $issue-board-list-difference-sm + $issue-boards
* Avatar
*/
$avatar-radius: 50%;
-$avatar-border: $gray-normal;
-$avatar-border-hover: $gray-darker;
-$avatar-background: $gray-lightest;
$gl-avatar-size: 40px;
/*
@@ -525,22 +492,6 @@ $blame-blue: #254e77;
$builds-trace-bg: #111;
/*
-* Callout
-*/
-$callout-danger-bg: $red-100;
-$callout-danger-border: $red-200;
-$callout-danger-color: $red-700;
-$callout-warning-bg: $orange-100;
-$callout-warning-border: $orange-200;
-$callout-warning-color: $orange-700;
-$callout-info-bg: $blue-100;
-$callout-info-border: $blue-200;
-$callout-info-color: $blue-700;
-$callout-success-bg: $green-100;
-$callout-success-border: $green-200;
-$callout-success-color: $green-700;
-
-/*
* Commit Page
*/
$commit-max-width-marker-color: rgba(0, 0, 0, 0);
@@ -549,16 +500,8 @@ $commit-message-text-area-bg: rgba(0, 0, 0, 0);
/*
* Common
*/
-$common-gray: $gl-text-color;
$common-gray-light: #bbb;
$common-gray-dark: #444;
-$common-red: $red-500;
-$common-green: $green-600;
-
-/*
-* Editor
-*/
-$editor-cancel-color: $red-600;
/*
* Events
@@ -579,7 +522,6 @@ $logs-p-color: #333;
*/
$input-height: 34px;
$input-danger-bg: #f2dede;
-$input-danger-border: $red-400;
$input-group-addon-bg: #f7f8fa;
$gl-field-focus-shadow: rgba(0, 0, 0, 0.075);
$gl-field-focus-shadow-error: rgba($red-500, 0.6);
@@ -626,16 +568,9 @@ $fade-mask-transition-duration: 0.1s;
$fade-mask-transition-curve: ease-in-out;
/*
-* Lint
-*/
-$lint-incorrect-color: $red-500;
-$lint-correct-color: $green-500;
-
-/*
* Login
*/
$login-brand-holder-color: #888;
-$login-devise-error-color: $red-700;
/*
* Nav
@@ -648,15 +583,12 @@ $nav-toggle-gray: #666;
*/
$notify-details: #777;
$notify-footer: #777;
-$notify-new-file: $green-600;
-$notify-deleted-file: $red-700;
/*
* Projects
*/
$project-option-descr-color: #54565b;
$project-breadcrumb-color: #999;
-$project-private-forks-notice-odd: $green-600;
$project-network-controls-color: #888;
$feature-toggle-color: #fff;
@@ -665,21 +597,10 @@ $feature-toggle-color-disabled: #999;
$feature-toggle-color-enabled: #4a8bee;
/*
-* Runners
-*/
-$runner-state-shared-bg: $green-400;
-$runner-state-specific-bg: $blue-400;
-$runner-status-online-color: $green-600;
-$runner-status-offline-color: $gray-darkest;
-$runner-status-paused-color: $red-500;
-
-/*
Stat Graph
*/
$stat-graph-common-bg: #f3f3f3;
-$stat-graph-area-fill: $green-500;
$stat-graph-axis-fill: #aaa;
-$stat-graph-orange-fill: $orange-500;
$stat-graph-selection-fill: #333;
$stat-graph-selection-stroke: #333;
@@ -692,7 +613,6 @@ $select2-drop-shadow2: rgba(31, 37, 50, 0.317647);
/*
* Todo
*/
-$todo-alert-blue: $blue-500;
$todo-body-pre-color: #777;
$todo-body-border: #ddd;
@@ -715,7 +635,6 @@ $ui-dev-kit-example-border: #ddd;
/*
Pipeline Graph
*/
-$stage-hover-bg: $gray-darker;
$ci-action-icon-size: 22px;
$ci-action-icon-size-lg: 24px;
$pipeline-dropdown-line-height: 20px;
@@ -743,13 +662,6 @@ Animation Functions
$dropdown-animation-timing: cubic-bezier(0.23, 1, 0.32, 1);
/*
-Convdev Index
-*/
-$color-high-score: $green-400;
-$color-average-score: $orange-400;
-$color-low-score: $red-400;
-
-/*
Performance Bar
*/
$perf-bar-text: #999;
@@ -790,9 +702,5 @@ Modals
*/
$modal-body-height: 134px;
-/*
-Prometheus
-*/
-$prometheus-table-row-highlight-color: $theme-gray-100;
$priority-label-empty-state-width: 114px;
diff --git a/app/assets/stylesheets/framework/variables_overrides.scss b/app/assets/stylesheets/framework/variables_overrides.scss
index b9c343fa2e9..7d90452e1f4 100644
--- a/app/assets/stylesheets/framework/variables_overrides.scss
+++ b/app/assets/stylesheets/framework/variables_overrides.scss
@@ -14,3 +14,7 @@ $btn-line-height: 20px;
$table-accent-bg: $gray-light;
$card-border-color: $border-color;
$card-cap-bg: $gray-light;
+$success: $green-500;
+$info: $blue-500;
+$warning: $orange-500;
+$danger: $red-500;
diff --git a/app/assets/stylesheets/pages/builds.scss b/app/assets/stylesheets/pages/builds.scss
index 1696d18584d..14ba8b1df83 100644
--- a/app/assets/stylesheets/pages/builds.scss
+++ b/app/assets/stylesheets/pages/builds.scss
@@ -397,7 +397,7 @@
}
&:hover {
- background-color: $dropdown-item-hover-bg;
+ background-color: $gray-darker;
}
.icon-retry {
diff --git a/app/assets/stylesheets/pages/convdev_index.scss b/app/assets/stylesheets/pages/convdev_index.scss
index bd338326154..52fcdf4a405 100644
--- a/app/assets/stylesheets/pages/convdev_index.scss
+++ b/app/assets/stylesheets/pages/convdev_index.scss
@@ -80,7 +80,7 @@ $space-between-cards: 8px;
}
.convdev-card-low {
- border-top-color: $color-low-score;
+ border-top-color: $red-400;
.board-card-score-big {
background-color: $red-50;
@@ -88,7 +88,7 @@ $space-between-cards: 8px;
}
.convdev-card-average {
- border-top-color: $color-average-score;
+ border-top-color: $orange-400;
.board-card-score-big {
background-color: $orange-50;
@@ -96,7 +96,7 @@ $space-between-cards: 8px;
}
.convdev-card-high {
- border-top-color: $color-high-score;
+ border-top-color: $green-400;
.board-card-score-big {
background-color: $green-50;
@@ -243,13 +243,13 @@ $space-between-cards: 8px;
}
.convdev-high-score {
- color: $color-high-score;
+ color: $green-400;
}
.convdev-average-score {
- color: $color-average-score;
+ color: $orange-400;
}
.convdev-low-score {
- color: $color-low-score;
+ color: $red-400;
}
diff --git a/app/assets/stylesheets/pages/cycle_analytics.scss b/app/assets/stylesheets/pages/cycle_analytics.scss
index bc4c90711d7..f0228768b5a 100644
--- a/app/assets/stylesheets/pages/cycle_analytics.scss
+++ b/app/assets/stylesheets/pages/cycle_analytics.scss
@@ -285,7 +285,7 @@
.total-time {
font-size: $cycle-analytics-big-font;
- color: $cycle-analytics-dark-text;
+ color: $gl-text-color;
span {
color: $gl-text-color;
diff --git a/app/assets/stylesheets/pages/editor.scss b/app/assets/stylesheets/pages/editor.scss
index 892da152b5f..04570c057d1 100644
--- a/app/assets/stylesheets/pages/editor.scss
+++ b/app/assets/stylesheets/pages/editor.scss
@@ -23,10 +23,10 @@
}
.cancel-btn {
- color: $editor-cancel-color;
+ color: $red-600;
&:hover {
- color: $editor-cancel-color;
+ color: $red-600;
}
}
diff --git a/app/assets/stylesheets/pages/environments.scss b/app/assets/stylesheets/pages/environments.scss
index 179c0964567..196f6ae6d8c 100644
--- a/app/assets/stylesheets/pages/environments.scss
+++ b/app/assets/stylesheets/pages/environments.scss
@@ -501,5 +501,5 @@
}
.prometheus-table-row-highlight {
- background-color: $prometheus-table-row-highlight-color;
+ background-color: $theme-gray-100;
}
diff --git a/app/assets/stylesheets/pages/issuable.scss b/app/assets/stylesheets/pages/issuable.scss
index 6f0f82964c8..9ac47a771a5 100644
--- a/app/assets/stylesheets/pages/issuable.scss
+++ b/app/assets/stylesheets/pages/issuable.scss
@@ -144,7 +144,7 @@
color: $blue-800;
.avatar {
- border-color: rgba($avatar-border, .2);
+ border-color: rgba($gray-normal, .2);
}
}
@@ -231,7 +231,7 @@
}
a.edit-link:not([href]):hover {
- color: rgba($avatar-border, .2);
+ color: rgba($gray-normal, .2);
}
.lock-edit, // uses same style, different js behaviour
diff --git a/app/assets/stylesheets/pages/labels.scss b/app/assets/stylesheets/pages/labels.scss
index d32943fceec..d2b9470be69 100644
--- a/app/assets/stylesheets/pages/labels.scss
+++ b/app/assets/stylesheets/pages/labels.scss
@@ -67,7 +67,7 @@
.dropdown-labels-error {
padding: 5px 10px;
margin-bottom: 10px;
- background-color: $gl-danger;
+ background-color: $red-500;
color: $white-light;
}
@@ -117,7 +117,7 @@
color: $blue-600;
&.remove-row {
- color: $gl-danger;
+ color: $red-500;
}
}
}
diff --git a/app/assets/stylesheets/pages/login.scss b/app/assets/stylesheets/pages/login.scss
index 8a4a2caa6c9..c9e5fb9c579 100644
--- a/app/assets/stylesheets/pages/login.scss
+++ b/app/assets/stylesheets/pages/login.scss
@@ -186,7 +186,7 @@
h2 {
margin-top: 0;
font-size: 14px;
- color: $login-devise-error-color;
+ color: $red-700;
}
}
}
diff --git a/app/assets/stylesheets/pages/merge_requests.scss b/app/assets/stylesheets/pages/merge_requests.scss
index 621321101cd..7b8cad254c7 100644
--- a/app/assets/stylesheets/pages/merge_requests.scss
+++ b/app/assets/stylesheets/pages/merge_requests.scss
@@ -195,12 +195,13 @@
.ci-widget-content {
display: flex;
align-items: center;
+ flex: 1;
}
}
.mr-widget-icon {
font-size: 22px;
- margin-right: $status-icon-margin;
+ margin-right: $gl-btn-padding;
}
.ci-status-icon svg {
@@ -222,6 +223,7 @@
.normal {
flex: 1;
+ flex-basis: auto;
}
.capitalize {
@@ -235,22 +237,23 @@
font-weight: normal;
overflow: hidden;
word-break: break-all;
+ }
- &.label-truncated {
- position: relative;
- display: inline-block;
- width: 250px;
- margin-bottom: -3px;
- white-space: nowrap;
- text-overflow: clip;
- line-height: 14px;
-
- &::after {
- position: absolute;
- content: '...';
- right: 0;
- font-family: $regular-font;
- background-color: $gray-light;
+ .deploy-link,
+ .label-branch {
+ &.label-truncate {
+ // NOTE: This selector targets its children because some of the HTML comes from
+ // 'source_branch_link'. Once this external HTML is no longer used, we could
+ // simplify this.
+ > a,
+ > span {
+ display: inline-block;
+ max-width: 12.5em;
+ margin-bottom: -3px;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+ line-height: 14px;
+ overflow: hidden;
}
}
}
@@ -281,7 +284,7 @@
margin-bottom: 0;
&.has-conflicts .fa-exclamation-triangle {
- color: $gl-warning;
+ color: $orange-500;
}
time {
@@ -313,7 +316,7 @@
}
.danger {
- color: $gl-danger;
+ color: $red-500;
}
.spacing,
@@ -514,7 +517,7 @@
}
.mr-links {
- padding-left: $status-icon-size + $status-icon-margin;
+ padding-left: $status-icon-size + $gl-btn-padding;
}
.mr-info-list {
@@ -582,7 +585,7 @@
@include media-breakpoint-down(md) {
flex-direction: column;
- align-items: flex-start;
+ align-items: stretch;
.branch-actions {
margin-top: 16px;
@@ -593,13 +596,13 @@
.branch-actions {
align-self: center;
margin-left: $gl-padding;
+ white-space: nowrap;
}
}
}
.diverged-commits-count {
color: $gl-text-color-secondary;
- font-size: 12px;
}
}
@@ -918,7 +921,7 @@
flex: 1;
flex-direction: row;
- @include media-breakpoint-down(md) {
+ @include media-breakpoint-down(sm) {
flex-direction: column;
.stage-cell .stage-container {
diff --git a/app/assets/stylesheets/pages/note_form.scss b/app/assets/stylesheets/pages/note_form.scss
index 4f861d43f55..ac7b701c2e2 100644
--- a/app/assets/stylesheets/pages/note_form.scss
+++ b/app/assets/stylesheets/pages/note_form.scss
@@ -74,13 +74,13 @@
}
&.is-dropzone-hover {
- border-color: $gl-success;
+ border-color: $green-500;
box-shadow: 0 0 2px $black-transparent,
- 0 0 4px $gl-success-focus;
+ 0 0 4px $green-500-focus;
.comment-toolbar,
.nav-links {
- border-color: $gl-success;
+ border-color: $green-500;
}
}
}
diff --git a/app/assets/stylesheets/pages/notes.scss b/app/assets/stylesheets/pages/notes.scss
index 2e1b2126887..fce04c58c24 100644
--- a/app/assets/stylesheets/pages/notes.scss
+++ b/app/assets/stylesheets/pages/notes.scss
@@ -443,7 +443,7 @@ ul.notes {
.note-headline-light,
.discussion-headline-light {
- color: $notes-light-color;
+ color: $gl-text-color-secondary;
}
.discussion-headline-light {
diff --git a/app/assets/stylesheets/pages/pipelines.scss b/app/assets/stylesheets/pages/pipelines.scss
index ad057ed3c83..8bb8b83dc5e 100644
--- a/app/assets/stylesheets/pages/pipelines.scss
+++ b/app/assets/stylesheets/pages/pipelines.scss
@@ -19,7 +19,7 @@
background-color: $white-light;
&:hover {
- background-color: $stage-hover-bg;
+ background-color: $gray-darker;
border: 1px solid $dropdown-toggle-active-border-color;
color: $gl-text-color;
}
@@ -595,7 +595,7 @@
a.build-content:hover,
button.build-content:hover {
- background-color: $stage-hover-bg;
+ background-color: $gray-darker;
border: 1px solid $dropdown-toggle-active-border-color;
}
@@ -668,7 +668,7 @@
display: block;
&:hover {
- background-color: $stage-hover-bg;
+ background-color: $gray-darker;
border: 1px solid $dropdown-toggle-active-border-color;
svg {
@@ -835,7 +835,7 @@ button.mini-pipeline-graph-dropdown-toggle {
display: block;
&:hover {
- background-color: $stage-hover-bg;
+ background-color: $gray-darker;
border: 1px solid $dropdown-toggle-active-border-color;
svg {
@@ -934,7 +934,7 @@ button.mini-pipeline-graph-dropdown-toggle {
&:focus {
outline: none;
text-decoration: none;
- background-color: $stage-hover-bg;
+ background-color: $gray-darker;
}
}
}
diff --git a/app/assets/stylesheets/pages/projects.scss b/app/assets/stylesheets/pages/projects.scss
index c11916454c8..a95e78931b1 100644
--- a/app/assets/stylesheets/pages/projects.scss
+++ b/app/assets/stylesheets/pages/projects.scss
@@ -394,23 +394,23 @@
}
.vs-public {
- color: $gl-primary;
+ color: $blue-500;
}
.vs-internal {
- color: $gl-warning;
+ color: $orange-500;
}
.vs-private {
- color: $gl-success;
+ color: $green-500;
}
.lfs-enabled {
- color: $gl-success;
+ color: $green-500;
}
.lfs-disabled {
- color: $gl-warning;
+ color: $orange-500;
}
.breadcrumb.repo-breadcrumb {
@@ -731,7 +731,7 @@
background-color: transparent;
font-size: $gl-font-size;
line-height: $gl-btn-line-height;
- color: $notes-light-color;
+ color: $gl-text-color-secondary;
}
.stat-link {
@@ -900,7 +900,7 @@ pre.light-well {
.private-forks-notice .private-fork-icon {
i:nth-child(1) {
- color: $project-private-forks-notice-odd;
+ color: $green-600;
}
i:nth-child(2) {
@@ -1128,12 +1128,12 @@ pre.light-well {
.project-ci-body {
.incorrect-syntax {
font-size: 18px;
- color: $lint-incorrect-color;
+ color: $red-500;
}
.correct-syntax {
font-size: 18px;
- color: $lint-correct-color;
+ color: $green-500;
}
}
diff --git a/app/assets/stylesheets/pages/runners.scss b/app/assets/stylesheets/pages/runners.scss
index 2734faec558..59f01f3e958 100644
--- a/app/assets/stylesheets/pages/runners.scss
+++ b/app/assets/stylesheets/pages/runners.scss
@@ -4,24 +4,24 @@
color: $white-light;
&.runner-state-shared {
- background: $runner-state-shared-bg;
+ background: $green-400;
}
&.runner-state-specific {
- background: $runner-state-specific-bg;
+ background: $blue-400;
}
}
.runner-status-online {
- color: $runner-status-online-color;
+ color: $green-600;
}
.runner-status-offline {
- color: $runner-status-offline-color;
+ color: $gray-darkest;
}
.runner-status-paused {
- color: $runner-status-paused-color;
+ color: $red-500;
}
.runner {
diff --git a/app/assets/stylesheets/pages/search.scss b/app/assets/stylesheets/pages/search.scss
index 5b3a468cd1c..77119aea9e2 100644
--- a/app/assets/stylesheets/pages/search.scss
+++ b/app/assets/stylesheets/pages/search.scss
@@ -24,12 +24,12 @@ $search-avatar-size: 16px;
.form-control:hover,
:not[readonly] {
border-color: lighten($blue-300, 20%);
- box-shadow: 0 0 4px lighten($search-input-focus-shadow-color, 20%);
+ box-shadow: 0 0 4px lighten($dropdown-input-focus-shadow, 20%);
}
input[type='checkbox']:hover {
- box-shadow: 0 0 2px 2px lighten($search-input-focus-shadow-color, 20%),
- 0 0 0 1px lighten($search-input-focus-shadow-color, 20%);
+ box-shadow: 0 0 2px 2px lighten($dropdown-input-focus-shadow, 20%),
+ 0 0 0 1px lighten($dropdown-input-focus-shadow, 20%);
}
.search {
@@ -181,7 +181,7 @@ input[type='checkbox']:hover {
width: $search-avatar-size;
height: $search-avatar-size;
border-radius: 50%;
- border: 1px solid $avatar-border;
+ border: 1px solid $gray-normal;
}
}
diff --git a/app/assets/stylesheets/pages/settings.scss b/app/assets/stylesheets/pages/settings.scss
index 5aa4cdec9c3..e351dd7c0bb 100644
--- a/app/assets/stylesheets/pages/settings.scss
+++ b/app/assets/stylesheets/pages/settings.scss
@@ -120,11 +120,11 @@
}
.warning-title {
- color: $gl-warning;
+ color: $orange-500;
}
.danger-title {
- color: $gl-danger;
+ color: $red-500;
}
.integration-settings-form {
diff --git a/app/assets/stylesheets/pages/stat_graph.scss b/app/assets/stylesheets/pages/stat_graph.scss
index 3f6f5f06075..d331edaa302 100644
--- a/app/assets/stylesheets/pages/stat_graph.scss
+++ b/app/assets/stylesheets/pages/stat_graph.scss
@@ -5,7 +5,7 @@
}
.area {
- fill: $stat-graph-area-fill;
+ fill: $green-500;
fill-opacity: 0.5;
}
@@ -54,7 +54,7 @@
}
.area-contributor {
- fill: $stat-graph-orange-fill;
+ fill: $orange-500;
}
}
}
diff --git a/app/controllers/concerns/issuable_collections.rb b/app/controllers/concerns/issuable_collections.rb
index 2ef2ee76855..22b39f47bf0 100644
--- a/app/controllers/concerns/issuable_collections.rb
+++ b/app/controllers/concerns/issuable_collections.rb
@@ -107,11 +107,15 @@ module IssuableCollections
end
def set_sort_order_from_cookie
- key = 'issuable_sort'
+ cookies[remember_sorting_key] = params[:sort] if params[:sort].present?
+ # fallback to legacy cookie value for backward compatibility
+ cookies[remember_sorting_key] ||= cookies['issuable_sort']
+ cookies[remember_sorting_key] = update_cookie_value(cookies[remember_sorting_key])
+ params[:sort] = cookies[remember_sorting_key]
+ end
- cookies[key] = params[:sort] if params[:sort].present?
- cookies[key] = update_cookie_value(cookies[key])
- params[:sort] = cookies[key]
+ def remember_sorting_key
+ @remember_sorting_key ||= "#{collection_type.downcase}_sort"
end
def default_sort_order
@@ -140,16 +144,14 @@ module IssuableCollections
end
def finder
- strong_memoize(:finder) do
- issuable_finder_for(finder_type)
- end
+ @finder ||= issuable_finder_for(finder_type)
end
def collection_type
- @collection_type ||= case finder
- when IssuesFinder
+ @collection_type ||= case finder_type.name
+ when 'IssuesFinder'
'Issue'
- when MergeRequestsFinder
+ when 'MergeRequestsFinder'
'MergeRequest'
end
end
diff --git a/app/controllers/concerns/renders_commits.rb b/app/controllers/concerns/renders_commits.rb
index fb41dc1e8a8..b1c9b1e532f 100644
--- a/app/controllers/concerns/renders_commits.rb
+++ b/app/controllers/concerns/renders_commits.rb
@@ -1,4 +1,24 @@
module RendersCommits
+ def limited_commits(commits)
+ if commits.size > MergeRequestDiff::COMMITS_SAFE_SIZE
+ [
+ commits.first(MergeRequestDiff::COMMITS_SAFE_SIZE),
+ commits.size - MergeRequestDiff::COMMITS_SAFE_SIZE
+ ]
+ else
+ [commits, 0]
+ end
+ end
+
+ # This is used as a helper method in a controller.
+ # rubocop: disable Gitlab/ModuleWithInstanceVariables
+ def set_commits_for_rendering(commits)
+ @total_commit_count = commits.size
+ limited, @hidden_commit_count = limited_commits(commits)
+ prepare_commits_for_rendering(limited)
+ end
+ # rubocop: enable Gitlab/ModuleWithInstanceVariables
+
def prepare_commits_for_rendering(commits)
Banzai::CommitRenderer.render(commits, @project, current_user) # rubocop:disable Gitlab/ModuleWithInstanceVariables
diff --git a/app/controllers/concerns/toggle_award_emoji.rb b/app/controllers/concerns/toggle_award_emoji.rb
index ba5b7d33f87..ae0b815f85e 100644
--- a/app/controllers/concerns/toggle_award_emoji.rb
+++ b/app/controllers/concerns/toggle_award_emoji.rb
@@ -5,7 +5,7 @@ module ToggleAwardEmoji
authenticate_user!
name = params.require(:name)
- if awardable.user_can_award?(current_user, name)
+ if awardable.user_can_award?(current_user)
awardable.toggle_award_emoji(name, current_user)
todoable = to_todoable(awardable)
diff --git a/app/controllers/groups/milestones_controller.rb b/app/controllers/groups/milestones_controller.rb
index 9bd51de7e97..6bdc0f79ef2 100644
--- a/app/controllers/groups/milestones_controller.rb
+++ b/app/controllers/groups/milestones_controller.rb
@@ -2,8 +2,8 @@ class Groups::MilestonesController < Groups::ApplicationController
include MilestoneActions
before_action :group_projects
- before_action :milestone, only: [:edit, :show, :update, :merge_requests, :participants, :labels]
- before_action :authorize_admin_milestones!, only: [:edit, :new, :create, :update]
+ before_action :milestone, only: [:edit, :show, :update, :merge_requests, :participants, :labels, :destroy]
+ before_action :authorize_admin_milestones!, only: [:edit, :new, :create, :update, :destroy]
def index
respond_to do |format|
@@ -56,10 +56,21 @@ class Groups::MilestonesController < Groups::ApplicationController
redirect_to milestone_path
end
+ def destroy
+ return render_404 if @milestone.legacy_group_milestone?
+
+ Milestones::DestroyService.new(group, current_user).execute(@milestone)
+
+ respond_to do |format|
+ format.html { redirect_to group_milestones_path(group), status: :see_other }
+ format.js { head :ok }
+ end
+ end
+
private
def authorize_admin_milestones!
- return render_404 unless can?(current_user, :admin_milestones, group)
+ return render_404 unless can?(current_user, :admin_milestone, group)
end
def milestone_params
diff --git a/app/controllers/projects/commit_controller.rb b/app/controllers/projects/commit_controller.rb
index 44b176d304e..53637780a07 100644
--- a/app/controllers/projects/commit_controller.rb
+++ b/app/controllers/projects/commit_controller.rb
@@ -101,7 +101,7 @@ class Projects::CommitController < Projects::ApplicationController
@branch_name = create_new_branch? ? @commit.cherry_pick_branch_name : @start_branch
- create_commit(Commits::CherryPickService, success_notice: "The #{@commit.change_type_title(current_user)} has been successfully cherry-picked.",
+ create_commit(Commits::CherryPickService, success_notice: "The #{@commit.change_type_title(current_user)} has been successfully cherry-picked into #{@branch_name}.",
success_path: -> { successful_change_path }, failure_path: failed_change_path)
end
diff --git a/app/controllers/projects/commits_controller.rb b/app/controllers/projects/commits_controller.rb
index 36faea8056e..5546bef850b 100644
--- a/app/controllers/projects/commits_controller.rb
+++ b/app/controllers/projects/commits_controller.rb
@@ -63,7 +63,7 @@ class Projects::CommitsController < Projects::ApplicationController
end
@commits = @commits.with_pipeline_status
- @commits = prepare_commits_for_rendering(@commits)
+ @commits = set_commits_for_rendering(@commits)
end
# Rails 5 sets request.format from the extension.
diff --git a/app/controllers/projects/compare_controller.rb b/app/controllers/projects/compare_controller.rb
index f93e500a07a..a1e12821caf 100644
--- a/app/controllers/projects/compare_controller.rb
+++ b/app/controllers/projects/compare_controller.rb
@@ -78,7 +78,7 @@ class Projects::CompareController < Projects::ApplicationController
end
def define_commits
- @commits = compare.present? ? prepare_commits_for_rendering(compare.commits) : []
+ @commits = compare.present? ? set_commits_for_rendering(@compare.commits) : []
end
def define_diffs
diff --git a/app/controllers/projects/issues_controller.rb b/app/controllers/projects/issues_controller.rb
index ef8159aa553..c3ac8e107fb 100644
--- a/app/controllers/projects/issues_controller.rb
+++ b/app/controllers/projects/issues_controller.rb
@@ -113,7 +113,7 @@ class Projects::IssuesController < Projects::ApplicationController
end
def referenced_merge_requests
- @merge_requests, @closed_by_merge_requests = ::Issues::FetchReferencedMergeRequestsService.new(project, current_user).execute(issue)
+ @merge_requests, @closed_by_merge_requests = ::Issues::ReferencedMergeRequestsService.new(project, current_user).execute(issue)
respond_to do |format|
format.json do
diff --git a/app/controllers/projects/merge_requests/creations_controller.rb b/app/controllers/projects/merge_requests/creations_controller.rb
index 81129456ad8..03d0290ac1d 100644
--- a/app/controllers/projects/merge_requests/creations_controller.rb
+++ b/app/controllers/projects/merge_requests/creations_controller.rb
@@ -101,7 +101,7 @@ class Projects::MergeRequests::CreationsController < Projects::MergeRequests::Ap
@target_project = @merge_request.target_project
@source_project = @merge_request.source_project
- @commits = prepare_commits_for_rendering(@merge_request.commits)
+ @commits = set_commits_for_rendering(@merge_request.commits)
@commit = @merge_request.diff_head_commit
@labels = LabelsFinder.new(current_user, project_id: @project.id).execute
diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb
index 1b069fe507b..d31b58972ca 100644
--- a/app/controllers/projects/merge_requests_controller.rb
+++ b/app/controllers/projects/merge_requests_controller.rb
@@ -79,7 +79,7 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
# Get commits from repository
# or from cache if already merged
@commits =
- prepare_commits_for_rendering(@merge_request.commits.with_pipeline_status)
+ set_commits_for_rendering(@merge_request.commits.with_pipeline_status)
render json: { html: view_to_html_string('projects/merge_requests/_commits') }
end
diff --git a/app/helpers/commits_helper.rb b/app/helpers/commits_helper.rb
index 89fe90fd801..7a942c44ac4 100644
--- a/app/helpers/commits_helper.rb
+++ b/app/helpers/commits_helper.rb
@@ -210,17 +210,6 @@ module CommitsHelper
Sanitize.clean(string, remove_contents: true)
end
- def limited_commits(commits)
- if commits.size > MergeRequestDiff::COMMITS_SAFE_SIZE
- [
- commits.first(MergeRequestDiff::COMMITS_SAFE_SIZE),
- commits.size - MergeRequestDiff::COMMITS_SAFE_SIZE
- ]
- else
- [commits, 0]
- end
- end
-
def commit_path(project, commit, merge_request: nil)
if merge_request&.persisted?
diffs_project_merge_request_path(project, merge_request, commit_id: commit.id)
diff --git a/app/helpers/import_helper.rb b/app/helpers/import_helper.rb
index 4664b1728c4..c65f1565425 100644
--- a/app/helpers/import_helper.rb
+++ b/app/helpers/import_helper.rb
@@ -5,6 +5,10 @@ module ImportHelper
false
end
+ def sanitize_project_name(name)
+ name.gsub(/[^\w\-]/, '-')
+ end
+
def import_project_target(owner, name)
namespace = current_user.can_create_group? ? owner : current_user.namespace_path
"#{namespace}/#{name}"
diff --git a/app/helpers/issues_helper.rb b/app/helpers/issues_helper.rb
index 96dc7ae1185..5b27d1d9404 100644
--- a/app/helpers/issues_helper.rb
+++ b/app/helpers/issues_helper.rb
@@ -92,14 +92,6 @@ module IssuesHelper
end
end
- def award_user_authored_class(award)
- if award == 'thumbsdown' || award == 'thumbsup'
- 'user-authored js-user-authored'
- else
- ''
- end
- end
-
def awards_sort(awards)
awards.sort_by do |award, award_emojis|
if award == "thumbsup"
diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb
index 6b4079b4113..18b3badda8d 100644
--- a/app/helpers/projects_helper.rb
+++ b/app/helpers/projects_helper.rb
@@ -447,7 +447,7 @@ module ProjectsHelper
end
def project_permissions_panel_data(project)
- data = {
+ {
currentSettings: project_permissions_settings(project),
canChangeVisibilityLevel: can_change_visibility_level?(project, current_user),
allowedVisibilityOptions: project_allowed_visibility_levels(project),
@@ -457,8 +457,10 @@ module ProjectsHelper
lfsAvailable: Gitlab.config.lfs.enabled,
lfsHelpPath: help_page_path('workflow/lfs/manage_large_binaries_with_git_lfs')
}
+ end
- data.to_json.html_safe
+ def project_permissions_panel_data_json(project)
+ project_permissions_panel_data(project).to_json.html_safe
end
def project_allowed_visibility_levels(project)
diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb
index e4aed76f611..526bf7af99b 100644
--- a/app/models/ci/pipeline.rb
+++ b/app/models/ci/pipeline.rb
@@ -649,8 +649,7 @@ module Ci
def keep_around_commits
return unless project
- project.repository.keep_around(self.sha)
- project.repository.keep_around(self.before_sha)
+ project.repository.keep_around(self.sha, self.before_sha)
end
def valid_source
diff --git a/app/models/commit.rb b/app/models/commit.rb
index 27fbdc3e386..594972ad344 100644
--- a/app/models/commit.rb
+++ b/app/models/commit.rb
@@ -193,6 +193,7 @@ class Commit
# otherwise returns commit message without first line
def description
return safe_message if full_title.length >= 100
+ return no_commit_message if safe_message.blank?
safe_message.split("\n", 2)[1].try(:chomp)
end
diff --git a/app/models/concerns/awardable.rb b/app/models/concerns/awardable.rb
index 49981db0d80..4200253053a 100644
--- a/app/models/concerns/awardable.rb
+++ b/app/models/concerns/awardable.rb
@@ -76,12 +76,8 @@ module Awardable
true
end
- def awardable_votes?(name)
- AwardEmoji::UPVOTE_NAME == name || AwardEmoji::DOWNVOTE_NAME == name
- end
-
- def user_can_award?(current_user, name)
- awardable_by_user?(current_user, name) && Ability.allowed?(current_user, :award_emoji, self)
+ def user_can_award?(current_user)
+ Ability.allowed?(current_user, :award_emoji, self)
end
def user_authored?(current_user)
@@ -117,12 +113,4 @@ module Awardable
def normalize_name(name)
Gitlab::Emoji.normalize_emoji_name(name)
end
-
- def awardable_by_user?(current_user, name)
- if user_authored?(current_user)
- !awardable_votes?(normalize_name(name))
- else
- true
- end
- end
end
diff --git a/app/models/diff_note.rb b/app/models/diff_note.rb
index 58d949315e0..716cf6574d3 100644
--- a/app/models/diff_note.rb
+++ b/app/models/diff_note.rb
@@ -191,14 +191,18 @@ class DiffNote < Note
end
def keep_around_commits
- project.repository.keep_around(self.original_position.base_sha)
- project.repository.keep_around(self.original_position.start_sha)
- project.repository.keep_around(self.original_position.head_sha)
+ shas = [
+ self.original_position.base_sha,
+ self.original_position.start_sha,
+ self.original_position.head_sha
+ ]
if self.position != self.original_position
- project.repository.keep_around(self.position.base_sha)
- project.repository.keep_around(self.position.start_sha)
- project.repository.keep_around(self.position.head_sha)
+ shas << self.position.base_sha
+ shas << self.position.start_sha
+ shas << self.position.head_sha
end
+
+ project.repository.keep_around(*shas)
end
end
diff --git a/app/models/issue.rb b/app/models/issue.rb
index 94cf12f3c2b..d0cd7461daa 100644
--- a/app/models/issue.rb
+++ b/app/models/issue.rb
@@ -170,27 +170,6 @@ class Issue < ActiveRecord::Base
"#{project.to_reference(from, full: full)}#{reference}"
end
- def referenced_merge_requests(current_user = nil)
- ext = all_references(current_user)
-
- notes_with_associations.each do |object|
- object.all_references(current_user, extractor: ext)
- end
-
- merge_requests = ext.merge_requests.sort_by(&:iid)
-
- cross_project_filter = -> (merge_requests) do
- merge_requests.select { |mr| mr.target_project == project }
- end
-
- Ability.merge_requests_readable_by_user(
- merge_requests, current_user,
- filters: {
- read_cross_project: cross_project_filter
- }
- )
- end
-
# All branches containing the current issue's ID, except for
# those with a merge request open referencing the current issue.
def related_branches(current_user)
@@ -198,7 +177,11 @@ class Issue < ActiveRecord::Base
branch =~ /\A#{iid}-(?!\d+-stable)/i
end
- branches_with_merge_request = self.referenced_merge_requests(current_user).map(&:source_branch)
+ branches_with_merge_request =
+ Issues::ReferencedMergeRequestsService
+ .new(project, current_user)
+ .referenced_merge_requests(self)
+ .map(&:source_branch)
branches_with_iid - branches_with_merge_request
end
@@ -225,26 +208,6 @@ class Issue < ActiveRecord::Base
project
end
- # From all notes on this issue, we'll select the system notes about linked
- # merge requests. Of those, the MRs closing `self` are returned.
- def closed_by_merge_requests(current_user = nil)
- return [] unless open?
-
- ext = all_references(current_user)
-
- notes.system.each do |note|
- note.all_references(current_user, extractor: ext)
- end
-
- merge_requests = ext.merge_requests.select(&:open?)
- if merge_requests.any?
- ids = MergeRequestsClosingIssues.where(merge_request_id: merge_requests.map(&:id), issue_id: id).pluck(:merge_request_id)
- merge_requests.select { |mr| mr.id.in?(ids) }
- else
- []
- end
- end
-
def moved?
!moved_to.nil?
end
diff --git a/app/models/member.rb b/app/models/member.rb
index 05c0bc8cb97..d9b4e8d2ac6 100644
--- a/app/models/member.rb
+++ b/app/models/member.rb
@@ -103,7 +103,7 @@ class Member < ActiveRecord::Base
def filter_by_2fa(value)
case value
when 'enabled'
- left_join_users.merge(User.with_two_factor_indistinct)
+ left_join_users.merge(User.with_two_factor)
when 'disabled'
left_join_users.merge(User.without_two_factor)
else
diff --git a/app/models/merge_request_diff.rb b/app/models/merge_request_diff.rb
index d9393b4e545..bbe4f6f7969 100644
--- a/app/models/merge_request_diff.rb
+++ b/app/models/merge_request_diff.rb
@@ -314,9 +314,7 @@ class MergeRequestDiff < ActiveRecord::Base
def keep_around_commits
[repository, merge_request.source_project.repository].uniq.each do |repo|
- repo.keep_around(start_commit_sha)
- repo.keep_around(head_commit_sha)
- repo.keep_around(base_commit_sha)
+ repo.keep_around(start_commit_sha, head_commit_sha, base_commit_sha)
end
end
end
diff --git a/app/models/project.rb b/app/models/project.rb
index 8f631d7f0ed..67593c9b2fe 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -85,8 +85,7 @@ class Project < ActiveRecord::Base
after_create :create_project_feature, unless: :project_feature
after_create -> { SiteStatistic.track(STATISTICS_ATTRIBUTE) }
- before_destroy ->(project) { project.project_feature.untrack_statistics_for_deletion! }
- after_destroy -> { SiteStatistic.untrack(STATISTICS_ATTRIBUTE) }
+ before_destroy :untrack_site_statistics
after_create :create_ci_cd_settings,
unless: :ci_cd_settings,
@@ -2072,13 +2071,19 @@ class Project < ActiveRecord::Base
private
def rename_or_migrate_repository!
- if Gitlab::CurrentSettings.hashed_storage_enabled? && storage_version != LATEST_STORAGE_VERSION
+ if Gitlab::CurrentSettings.hashed_storage_enabled? &&
+ storage_upgradable? &&
+ Feature.disabled?(:skip_hashed_storage_upgrade) # kill switch in case we need to disable upgrade behavior
::Projects::HashedStorageMigrationService.new(self, full_path_was).execute
else
storage.rename_repo
end
end
+ def storage_upgradable?
+ storage_version != LATEST_STORAGE_VERSION
+ end
+
def after_rename_repository(full_path_before, path_before)
execute_rename_repository_hooks!(full_path_before)
@@ -2093,6 +2098,11 @@ class Project < ActiveRecord::Base
Gitlab::PagesTransfer.new.rename_project(path_before, self.path, namespace.full_path)
end
+ def untrack_site_statistics
+ SiteStatistic.untrack(STATISTICS_ATTRIBUTE)
+ self.project_feature.untrack_statistics_for_deletion!
+ end
+
def execute_rename_repository_hooks!(full_path_before)
# When we import a project overwriting the original project, there
# is a move operation. In that case we don't want to send the instructions.
diff --git a/app/models/protected_tag.rb b/app/models/protected_tag.rb
index a36f0d36262..94746141945 100644
--- a/app/models/protected_tag.rb
+++ b/app/models/protected_tag.rb
@@ -4,6 +4,8 @@ class ProtectedTag < ActiveRecord::Base
include Gitlab::ShellAdapter
include ProtectedRef
+ validates :name, uniqueness: { scope: :project_id }
+
protected_ref_access_levels :create
def self.protected?(project, ref_name)
diff --git a/app/models/remote_mirror.rb b/app/models/remote_mirror.rb
index 833faf3bc82..c1f53b5da4f 100644
--- a/app/models/remote_mirror.rb
+++ b/app/models/remote_mirror.rb
@@ -150,6 +150,15 @@ class RemoteMirror < ActiveRecord::Base
result.to_s
end
+ def ensure_remote!
+ return unless project
+ return unless remote_name && url
+
+ # If this fails or the remote already exists, we won't know due to
+ # https://gitlab.com/gitlab-org/gitaly/issues/1317
+ project.repository.add_remote(remote_name, url)
+ end
+
private
def raw
diff --git a/app/models/repository.rb b/app/models/repository.rb
index 69f375dc6f3..cf255c8951f 100644
--- a/app/models/repository.rb
+++ b/app/models/repository.rb
@@ -247,15 +247,22 @@ class Repository
# Git GC will delete commits from the repository that are no longer in any
# branches or tags, but we want to keep some of these commits around, for
# example if they have comments or CI builds.
- def keep_around(sha)
- return unless sha.present? && commit_by(oid: sha)
+ #
+ # For Geo's sake, pass in multiple shas rather than calling it multiple times,
+ # to avoid unnecessary syncing.
+ def keep_around(*shas)
+ shas.each do |sha|
+ begin
+ next unless sha.present? && commit_by(oid: sha)
- return if kept_around?(sha)
+ next if kept_around?(sha)
- # This will still fail if the file is corrupted (e.g. 0 bytes)
- raw_repository.write_ref(keep_around_ref_name(sha), sha, shell: false)
- rescue Gitlab::Git::CommandError => ex
- Rails.logger.error "Unable to create keep-around reference for repository #{disk_path}: #{ex}"
+ # This will still fail if the file is corrupted (e.g. 0 bytes)
+ raw_repository.write_ref(keep_around_ref_name(sha), sha, shell: false)
+ rescue Gitlab::Git::CommandError => ex
+ Rails.logger.error "Unable to create keep-around reference for repository #{disk_path}: #{ex}"
+ end
+ end
end
def kept_around?(sha)
diff --git a/app/models/user.rb b/app/models/user.rb
index a6ba90794d6..f21ca1c569f 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -289,13 +289,16 @@ class User < ActiveRecord::Base
end
end
- def self.with_two_factor_indistinct
- joins("LEFT OUTER JOIN u2f_registrations AS u2f ON u2f.user_id = users.id")
- .where("u2f.id IS NOT NULL OR users.otp_required_for_login = ?", true)
- end
-
def self.with_two_factor
- with_two_factor_indistinct.distinct(arel_table[:id])
+ with_u2f_registrations = <<-SQL
+ EXISTS (
+ SELECT *
+ FROM u2f_registrations AS u2f
+ WHERE u2f.user_id = users.id
+ ) OR users.otp_required_for_login = ?
+ SQL
+
+ where(with_u2f_registrations, true)
end
def self.without_two_factor
diff --git a/app/policies/group_policy.rb b/app/policies/group_policy.rb
index a8d7a05f509..73c93b22c95 100644
--- a/app/policies/group_policy.rb
+++ b/app/policies/group_policy.rb
@@ -53,7 +53,7 @@ class GroupPolicy < BasePolicy
rule { has_access }.enable :read_namespace
- rule { developer }.enable :admin_milestones
+ rule { developer }.enable :admin_milestone
rule { reporter }.policy do
enable :admin_label
@@ -72,6 +72,8 @@ class GroupPolicy < BasePolicy
enable :admin_namespace
enable :admin_group_member
enable :change_visibility_level
+
+ enable :set_note_created_at
end
rule { can?(:read_nested_project_resources) }.policy do
diff --git a/app/policies/project_policy.rb b/app/policies/project_policy.rb
index 00c58f15013..fd6cc504a3b 100644
--- a/app/policies/project_policy.rb
+++ b/app/policies/project_policy.rb
@@ -143,6 +143,10 @@ class ProjectPolicy < BasePolicy
enable :destroy_merge_request
enable :destroy_issue
enable :remove_pages
+
+ enable :set_issue_iid
+ enable :set_issue_created_at
+ enable :set_note_created_at
end
rule { can?(:guest_access) }.policy do
diff --git a/app/services/git_push_service.rb b/app/services/git_push_service.rb
index 637c1df4ad9..26e90e8cf8c 100644
--- a/app/services/git_push_service.rb
+++ b/app/services/git_push_service.rb
@@ -140,7 +140,6 @@ class GitPushService < BaseService
EventCreateService.new.push(project, current_user, build_push_data)
Ci::CreatePipelineService.new(project, current_user, build_push_data).execute(:push)
- SystemHookPushWorker.perform_async(build_push_data.dup, :push_hooks)
project.execute_hooks(build_push_data.dup, :push_hooks)
project.execute_services(build_push_data.dup, :push_hooks)
@@ -159,7 +158,7 @@ class GitPushService < BaseService
end
def process_default_branch
- offset = [push_commits_count - PROCESS_COMMIT_LIMIT, 0].max
+ offset = [push_commits_count_for_ref - PROCESS_COMMIT_LIMIT, 0].max
@push_commits = project.repository.commits(params[:newrev], offset: offset, limit: PROCESS_COMMIT_LIMIT)
project.after_create_default_branch
@@ -173,7 +172,7 @@ class GitPushService < BaseService
params[:newrev],
params[:ref],
@push_commits,
- commits_count: push_commits_count)
+ commits_count: commits_count)
end
def push_to_existing_branch?
@@ -214,8 +213,14 @@ class GitPushService < BaseService
end
end
- def push_commits_count
- strong_memoize(:push_commits_count) do
+ def commits_count
+ return push_commits_count_for_ref if default_branch? && push_to_new_branch?
+
+ Array(@push_commits).size
+ end
+
+ def push_commits_count_for_ref
+ strong_memoize(:push_commits_count_for_ref) do
project.repository.commit_count_for_ref(params[:ref])
end
end
diff --git a/app/services/groups/destroy_service.rb b/app/services/groups/destroy_service.rb
index 12aeba4af71..93d84bd8a9c 100644
--- a/app/services/groups/destroy_service.rb
+++ b/app/services/groups/destroy_service.rb
@@ -12,12 +12,15 @@ module Groups
def execute
group.prepare_for_destroy
- group.projects.each do |project|
+ group.projects.includes(:project_feature).each do |project|
# Execute the destruction of the models immediately to ensure atomic cleanup.
success = ::Projects::DestroyService.new(project, current_user).execute
raise DestroyError, "Project #{project.id} can't be deleted" unless success
end
+ # reload the relation to prevent triggering destroy hooks on the projects again
+ group.projects.reload
+
group.children.each do |group|
# This needs to be synchronous since the namespace gets destroyed below
DestroyService.new(group, current_user).execute
diff --git a/app/services/issues/fetch_referenced_merge_requests_service.rb b/app/services/issues/fetch_referenced_merge_requests_service.rb
deleted file mode 100644
index 5e84f3c81c9..00000000000
--- a/app/services/issues/fetch_referenced_merge_requests_service.rb
+++ /dev/null
@@ -1,14 +0,0 @@
-# frozen_string_literal: true
-
-module Issues
- class FetchReferencedMergeRequestsService < Issues::BaseService
- def execute(issue)
- referenced_merge_requests = issue.referenced_merge_requests(current_user)
- referenced_merge_requests = Gitlab::IssuableSorter.sort(project, referenced_merge_requests) { |i| i.iid.to_s }
- closed_by_merge_requests = issue.closed_by_merge_requests(current_user)
- closed_by_merge_requests = Gitlab::IssuableSorter.sort(project, closed_by_merge_requests) { |i| i.iid.to_s }
-
- [referenced_merge_requests, closed_by_merge_requests]
- end
- end
-end
diff --git a/app/services/issues/referenced_merge_requests_service.rb b/app/services/issues/referenced_merge_requests_service.rb
new file mode 100644
index 00000000000..40d78502697
--- /dev/null
+++ b/app/services/issues/referenced_merge_requests_service.rb
@@ -0,0 +1,66 @@
+# frozen_string_literal: true
+
+module Issues
+ class ReferencedMergeRequestsService < Issues::BaseService
+ def execute(issue)
+ referenced = referenced_merge_requests(issue)
+ closed_by = closed_by_merge_requests(issue)
+ preloader = ActiveRecord::Associations::Preloader.new
+
+ preloader.preload(referenced + closed_by,
+ head_pipeline: { project: [:route, { namespace: :route }] })
+
+ [sort_by_iid(referenced), sort_by_iid(closed_by)]
+ end
+
+ def referenced_merge_requests(issue)
+ merge_requests = extract_merge_requests(issue)
+
+ cross_project_filter = -> (merge_requests) do
+ merge_requests.select { |mr| mr.target_project == project }
+ end
+
+ Ability.merge_requests_readable_by_user(
+ merge_requests,
+ current_user,
+ filters: {
+ read_cross_project: cross_project_filter
+ }
+ )
+ end
+
+ def closed_by_merge_requests(issue)
+ return [] unless issue.open?
+
+ merge_requests = extract_merge_requests(issue, filter: :system).select(&:open?)
+
+ return [] if merge_requests.empty?
+
+ ids = MergeRequestsClosingIssues.where(merge_request_id: merge_requests.map(&:id), issue_id: issue.id).pluck(:merge_request_id)
+ merge_requests.select { |mr| mr.id.in?(ids) }
+ end
+
+ private
+
+ def extract_merge_requests(issue, filter: nil)
+ ext = issue.all_references(current_user)
+ notes = issue_notes(issue)
+ notes = notes.select(&filter) if filter
+
+ notes.each do |note|
+ note.all_references(current_user, extractor: ext)
+ end
+
+ ext.merge_requests
+ end
+
+ def issue_notes(issue)
+ @issue_notes ||= {}
+ @issue_notes[issue] ||= issue.notes.includes(:author)
+ end
+
+ def sort_by_iid(merge_requests)
+ Gitlab::IssuableSorter.sort(project, merge_requests) { |mr| mr.iid.to_s }
+ end
+ end
+end
diff --git a/app/services/merge_requests/build_service.rb b/app/services/merge_requests/build_service.rb
index bc988eb2a26..55750269bb4 100644
--- a/app/services/merge_requests/build_service.rb
+++ b/app/services/merge_requests/build_service.rb
@@ -128,8 +128,7 @@ module MergeRequests
#
def assign_title_and_description
assign_title_and_description_from_single_commit
- assign_title_from_issue if target_project.issues_enabled? || target_project.external_issue_tracker
-
+ merge_request.title ||= title_from_issue if target_project.issues_enabled? || target_project.external_issue_tracker
merge_request.title ||= source_branch.titleize.humanize
merge_request.title = wip_title if compare_commits.empty?
@@ -159,20 +158,18 @@ module MergeRequests
merge_request.description ||= commit.description.try(:strip)
end
- def assign_title_from_issue
+ def title_from_issue
return unless issue
- merge_request.title = "Resolve \"#{issue.title}\"" if issue.is_a?(Issue)
+ return "Resolve \"#{issue.title}\"" if issue.is_a?(Issue)
- return if merge_request.title.present?
+ return if issue_iid.blank?
- if issue_iid.present?
- title_parts = ["Resolve #{issue.to_reference}"]
- branch_title = source_branch.downcase.remove(issue_iid.downcase).titleize.humanize
+ title_parts = ["Resolve #{issue.to_reference}"]
+ branch_title = source_branch.downcase.remove(issue_iid.downcase).titleize.humanize
- title_parts << "\"#{branch_title}\"" if branch_title.present?
- merge_request.title = title_parts.join(' ')
- end
+ title_parts << "\"#{branch_title}\"" if branch_title.present?
+ title_parts.join(' ')
end
def issue_iid
diff --git a/app/services/milestones/destroy_service.rb b/app/services/milestones/destroy_service.rb
index 15c04525075..7cda802c120 100644
--- a/app/services/milestones/destroy_service.rb
+++ b/app/services/milestones/destroy_service.rb
@@ -3,8 +3,6 @@
module Milestones
class DestroyService < Milestones::BaseService
def execute(milestone)
- return unless milestone.project_milestone?
-
Milestone.transaction do
update_params = { milestone: nil }
@@ -16,15 +14,21 @@ module Milestones
MergeRequests::UpdateService.new(parent, current_user, update_params).execute(merge_request)
end
- event_service.destroy_milestone(milestone, current_user)
-
- Event.for_milestone_id(milestone.id).each do |event|
- event.target_id = nil
- event.save
- end
+ log_destroy_event_for(milestone)
milestone.destroy
end
end
+
+ def log_destroy_event_for(milestone)
+ return if milestone.group_milestone?
+
+ event_service.destroy_milestone(milestone, current_user)
+
+ Event.for_milestone_id(milestone.id).each do |event|
+ event.target_id = nil
+ event.save
+ end
+ end
end
end
diff --git a/app/services/projects/fork_service.rb b/app/services/projects/fork_service.rb
index 33ad2120a75..cbbb88a9410 100644
--- a/app/services/projects/fork_service.rb
+++ b/app/services/projects/fork_service.rb
@@ -17,6 +17,14 @@ module Projects
link_fork_network(fork_to_project)
+ # A forked project stores its LFS objects in the `forked_from_project`.
+ # So the LFS objects become inaccessible, and therefore delete them from
+ # the database so they'll get cleaned up.
+ #
+ # TODO: refactor this to get the correct lfs objects when implementing
+ # https://gitlab.com/gitlab-org/gitlab-ce/issues/39769
+ fork_to_project.lfs_objects_projects.delete_all
+
fork_to_project
end
diff --git a/app/services/projects/update_remote_mirror_service.rb b/app/services/projects/update_remote_mirror_service.rb
index 4651f7c4f8f..591b38b8151 100644
--- a/app/services/projects/update_remote_mirror_service.rb
+++ b/app/services/projects/update_remote_mirror_service.rb
@@ -10,6 +10,7 @@ module Projects
return success unless remote_mirror.enabled?
begin
+ remote_mirror.ensure_remote!
repository.fetch_remote(remote_mirror.remote_name, no_tags: true)
opts = {}
diff --git a/app/services/quick_actions/interpret_service.rb b/app/services/quick_actions/interpret_service.rb
index 8838ed06324..a4c4c9e4812 100644
--- a/app/services/quick_actions/interpret_service.rb
+++ b/app/services/quick_actions/interpret_service.rb
@@ -402,7 +402,7 @@ module QuickActions
match[1] if match
end
command :award do |name|
- if name && issuable.user_can_award?(current_user, name)
+ if name && issuable.user_can_award?(current_user)
@updates[:emoji_award] = name
end
end
diff --git a/app/views/admin/hook_logs/show.html.haml b/app/views/admin/hook_logs/show.html.haml
index 2eb3ac85722..86729dbe7bc 100644
--- a/app/views/admin/hook_logs/show.html.haml
+++ b/app/views/admin/hook_logs/show.html.haml
@@ -4,7 +4,6 @@
%hr
-= link_to 'Resend Request', retry_admin_hook_hook_log_path(@hook, @hook_log), class: "btn btn-default float-right prepend-left-10"
+= link_to 'Resend Request', retry_admin_hook_hook_log_path(@hook, @hook_log), method: :post, class: "btn btn-default float-right prepend-left-10"
= render partial: 'shared/hook_logs/content', locals: { hook_log: @hook_log }
-
diff --git a/app/views/admin/users/show.html.haml b/app/views/admin/users/show.html.haml
index 029efadd75d..a74e052707f 100644
--- a/app/views/admin/users/show.html.haml
+++ b/app/views/admin/users/show.html.haml
@@ -39,6 +39,10 @@
%strong= email.email
= link_to remove_email_admin_user_path(@user, email), data: { confirm: "Are you sure you want to remove #{email.email}?" }, method: :delete, class: "btn-sm btn btn-remove float-right", title: 'Remove secondary email', id: "remove_email_#{email.id}" do
%i.fa.fa-times
+ %li
+ %span.light ID:
+ %strong
+ = @user.id
%li.two-factor-status
%span.light Two-factor Authentication:
diff --git a/app/views/award_emoji/_awards_block.html.haml b/app/views/award_emoji/_awards_block.html.haml
index 8ca9fb4512e..30d7b21b1b8 100644
--- a/app/views/award_emoji/_awards_block.html.haml
+++ b/app/views/award_emoji/_awards_block.html.haml
@@ -3,7 +3,7 @@
.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_state_class(awardable, awards, current_user)), (award_user_authored_class(emoji) if user_authored)],
+ class: [(award_state_class(awardable, awards, current_user))],
data: { placement: "bottom", title: award_user_list(awards, current_user) } }
= emoji_icon(emoji)
%span.award-control-text.js-counter
@@ -13,7 +13,6 @@
.award-menu-holder.js-award-holder
%button.btn.award-control.has-tooltip.js-add-award{ type: 'button',
'aria-label': _('Add reaction'),
- class: ("js-user-authored" if user_authored),
data: { title: _('Add reaction'), placement: "bottom" } }
%span{ class: "award-control-icon award-control-icon-neutral" }= custom_icon('emoji_slightly_smiling_face')
%span{ class: "award-control-icon award-control-icon-positive" }= custom_icon('emoji_smiley')
diff --git a/app/views/ci/runner/_how_to_setup_runner.html.haml b/app/views/ci/runner/_how_to_setup_runner.html.haml
index 13f96b9747c..c26eb873718 100644
--- a/app/views/ci/runner/_how_to_setup_runner.html.haml
+++ b/app/views/ci/runner/_how_to_setup_runner.html.haml
@@ -1,6 +1,6 @@
- link = link_to _("Install GitLab Runner"), 'https://docs.gitlab.com/runner/install/', target: '_blank'
.append-bottom-10
- %h4= _("Setup a #{type} Runner manually")
+ %h4= _("Setup a %{type} Runner manually") % { type: type }
%ol
%li
diff --git a/app/views/ci/status/_dropdown_graph_badge.html.haml b/app/views/ci/status/_dropdown_graph_badge.html.haml
index 8b0463db000..9de9143e8b1 100644
--- a/app/views/ci/status/_dropdown_graph_badge.html.haml
+++ b/app/views/ci/status/_dropdown_graph_badge.html.haml
@@ -6,12 +6,12 @@
- tooltip = "#{subject.name} - #{status.status_tooltip}"
- if status.has_details?
- = link_to status.details_path, class: 'mini-pipeline-graph-dropdown-item', data: { toggle: 'tooltip', title: tooltip, html: 'true', container: 'body' } do
+ = link_to status.details_path, class: 'mini-pipeline-graph-dropdown-item', data: { toggle: 'tooltip', title: tooltip, container: 'body' } do
%span{ class: klass }= sprite_icon(status.icon)
%span.ci-build-text= subject.name
- else
- .menu-item.mini-pipeline-graph-dropdown-item{ data: { toggle: 'tooltip', html: 'true', title: tooltip, container: 'body' } }
+ .menu-item.mini-pipeline-graph-dropdown-item{ data: { toggle: 'tooltip', title: tooltip, container: 'body' } }
%span{ class: klass }= sprite_icon(status.icon)
%span.ci-build-text= subject.name
diff --git a/app/views/groups/milestones/index.html.haml b/app/views/groups/milestones/index.html.haml
index f5f621507b8..b6424df55cd 100644
--- a/app/views/groups/milestones/index.html.haml
+++ b/app/views/groups/milestones/index.html.haml
@@ -5,7 +5,7 @@
.nav-controls
= render 'shared/milestones_sort_dropdown'
- - if can?(current_user, :admin_milestones, @group)
+ - if can?(current_user, :admin_milestone, @group)
= link_to "New milestone", new_group_milestone_path(@group), class: "btn btn-new"
.milestones
diff --git a/app/views/import/_githubish_status.html.haml b/app/views/import/_githubish_status.html.haml
index f0d1e837317..f4a29ed18dc 100644
--- a/app/views/import/_githubish_status.html.haml
+++ b/app/views/import/_githubish_status.html.haml
@@ -45,7 +45,7 @@
= text_field_tag :path, current_user.namespace_path, class: "input-group-text input-large form-control", tabindex: 1, disabled: true
%span.input-group-prepend
.input-group-text /
- = text_field_tag :path, repo.name, class: "input-mini form-control", tabindex: 2, autofocus: true, required: true
+ = text_field_tag :path, sanitize_project_name(repo.name), class: "input-mini form-control", tabindex: 2, autofocus: true, required: true
%td.import-actions.job-status
= button_tag class: "btn btn-import js-add-to-import" do
= has_ci_cd_only_params? ? _('Connect') : _('Import')
diff --git a/app/views/import/bitbucket/status.html.haml b/app/views/import/bitbucket/status.html.haml
index a75b7aa9dd2..3b1b5e55302 100644
--- a/app/views/import/bitbucket/status.html.haml
+++ b/app/views/import/bitbucket/status.html.haml
@@ -63,7 +63,7 @@
= text_field_tag :path, current_user.namespace_path, class: "input-group-text input-large form-control", tabindex: 1, disabled: true
%span.input-group-prepend
.input-group-text /
- = text_field_tag :path, repo.name, class: "input-mini form-control", tabindex: 2, autofocus: true, required: true
+ = text_field_tag :path, sanitize_project_name(repo.slug), class: "input-mini form-control", tabindex: 2, autofocus: true, required: true
%td.import-actions.job-status
= button_tag class: 'btn btn-import js-add-to-import' do
= _('Import')
diff --git a/app/views/import/bitbucket_server/status.html.haml b/app/views/import/bitbucket_server/status.html.haml
index 3d05a5e696f..ae09e0dfa18 100644
--- a/app/views/import/bitbucket_server/status.html.haml
+++ b/app/views/import/bitbucket_server/status.html.haml
@@ -61,7 +61,7 @@
= text_field_tag :path, current_user.namespace_path, class: "input-group-text input-large form-control", tabindex: 1, disabled: true
%span.input-group-prepend
.input-group-text /
- = text_field_tag :path, repo.name, class: "input-mini form-control", tabindex: 2, autofocus: true, required: true
+ = text_field_tag :path, sanitize_project_name(repo.slug), class: "input-mini form-control", tabindex: 2, autofocus: true, required: true
%td.import-actions.job-status
= button_tag class: 'btn btn-import js-add-to-import' do
Import
diff --git a/app/views/projects/_issuable_by_email.html.haml b/app/views/projects/_issuable_by_email.html.haml
index 22adf5b4008..d59191a6f87 100644
--- a/app/views/projects/_issuable_by_email.html.haml
+++ b/app/views/projects/_issuable_by_email.html.haml
@@ -19,9 +19,16 @@
= text_field_tag :issuable_email, email, class: "monospace js-select-on-focus form-control", readonly: true
.input-group-append
= clipboard_button(target: '#issuable_email', class: 'btn btn-clipboard input-group-text btn-transparent d-none d-sm-block')
+
+ - if issuable_type == 'issue'
+ - enter_title_text = _('Enter the issue title')
+ - enter_description_text = _('Enter the issue description')
+ - else
+ - enter_title_text = _('Enter the merge request title')
+ - enter_description_text = _('Enter the merge request description')
= mail_to email, class: 'btn btn-clipboard btn-transparent',
- subject: _("Enter the #{name} title"),
- body: _("Enter the #{name} description"),
+ subject: enter_title_text,
+ body: enter_description_text,
title: _('Send email'),
data: { toggle: 'tooltip', placement: 'bottom' } do
= sprite_icon('mail')
diff --git a/app/views/projects/commits/_commit_list.html.haml b/app/views/projects/commits/_commit_list.html.haml
index 8f8eb2c3d5a..6ed65d07202 100644
--- a/app/views/projects/commits/_commit_list.html.haml
+++ b/app/views/projects/commits/_commit_list.html.haml
@@ -1,9 +1,10 @@
-- commits, hidden = limited_commits(@commits)
+- commits = @commits
+- hidden = @hidden_commit_count
- commits = Commit.decorate(commits, @project)
.card
.card-header
- Commits (#{@commits.count})
+ Commits (#{@total_commit_count})
- if hidden > 0
%ul.content-list
- commits.each do |commit|
diff --git a/app/views/projects/commits/_commits.html.haml b/app/views/projects/commits/_commits.html.haml
index ac6852751be..ec05ff50f25 100644
--- a/app/views/projects/commits/_commits.html.haml
+++ b/app/views/projects/commits/_commits.html.haml
@@ -2,7 +2,8 @@
- project = local_assigns.fetch(:project) { merge_request&.project }
- ref = local_assigns.fetch(:ref) { merge_request&.source_branch }
-- commits, hidden = limited_commits(@commits)
+- commits = @commits
+- hidden = @hidden_commit_count
- commits.chunk { |c| c.committed_date.in_time_zone.to_date }.each do |day, commits|
%li.commit-header.js-commit-header{ data: { day: day } }
diff --git a/app/views/projects/diffs/_line.html.haml b/app/views/projects/diffs/_line.html.haml
index cd0fb21f8a7..ffdca500abe 100644
--- a/app/views/projects/diffs/_line.html.haml
+++ b/app/views/projects/diffs/_line.html.haml
@@ -32,9 +32,9 @@
%a{ href: "##{line_code}", data: { linenumber: link_text } }
%td.line_content.noteable_line{ class: type }<
- if email
- %pre= line.text
+ %pre= line.rich_text
- else
- = diff_line_content(line.text)
+ = diff_line_content(line.rich_text)
- if line_discussions&.any?
- discussion_expanded = local_assigns.fetch(:discussion_expanded, line_discussions.any?(&:expanded?))
diff --git a/app/views/projects/diffs/_parallel_view.html.haml b/app/views/projects/diffs/_parallel_view.html.haml
index 1f0ca211074..e47361354f3 100644
--- a/app/views/projects/diffs/_parallel_view.html.haml
+++ b/app/views/projects/diffs/_parallel_view.html.haml
@@ -24,7 +24,7 @@
- discussion_left = discussions_left.try(:first)
- if discussion_left && discussion_left.resolvable?
%diff-note-avatars{ "discussion-id" => discussion_left.id }
- %td.line_content.parallel.noteable_line.left-side{ id: left_line_code, class: left.type }= diff_line_content(left.text)
+ %td.line_content.parallel.noteable_line.left-side{ id: left_line_code, class: left.type }= diff_line_content(left.rich_text)
- else
%td.old_line.diff-line-num.empty-cell
%td.line_content.parallel.left-side
@@ -45,7 +45,7 @@
- discussion_right = discussions_right.try(:first)
- if discussion_right && discussion_right.resolvable?
%diff-note-avatars{ "discussion-id" => discussion_right.id }
- %td.line_content.parallel.noteable_line.right-side{ id: right_line_code, class: right.type }= diff_line_content(right.text)
+ %td.line_content.parallel.noteable_line.right-side{ id: right_line_code, class: right.type }= diff_line_content(right.rich_text)
- else
%td.old_line.diff-line-num.empty-cell
%td.line_content.parallel.right-side
diff --git a/app/views/projects/edit.html.haml b/app/views/projects/edit.html.haml
index 30544dde451..e37a444c1c9 100644
--- a/app/views/projects/edit.html.haml
+++ b/app/views/projects/edit.html.haml
@@ -78,7 +78,7 @@
= form_for [@project.namespace.becomes(Namespace), @project], remote: true, html: { multipart: true, class: "sharing-permissions-form" }, authenticity_token: true do |f|
%input{ name: 'update_section', type: 'hidden', value: 'js-shared-permissions' }
-# haml-lint:disable InlineJavaScript
- %script.js-project-permissions-form-data{ type: "application/json" }= project_permissions_panel_data(@project)
+ %script.js-project-permissions-form-data{ type: "application/json" }= project_permissions_panel_data_json(@project)
.js-project-permissions-form
= f.submit 'Save changes', class: "btn btn-save"
diff --git a/app/views/projects/hook_logs/show.html.haml b/app/views/projects/hook_logs/show.html.haml
index e51efa85df0..bd8ca5e7d70 100644
--- a/app/views/projects/hook_logs/show.html.haml
+++ b/app/views/projects/hook_logs/show.html.haml
@@ -4,6 +4,6 @@
Request details
.col-lg-9
- = link_to 'Resend Request', retry_project_hook_hook_log_path(@project, @hook, @hook_log), class: "btn btn-default float-right prepend-left-10"
+ = link_to 'Resend Request', retry_project_hook_hook_log_path(@project, @hook, @hook_log), method: :post, class: "btn btn-default float-right prepend-left-10"
= render partial: 'shared/hook_logs/content', locals: { hook_log: @hook_log }
diff --git a/app/views/projects/jobs/_sidebar.html.haml b/app/views/projects/jobs/_sidebar.html.haml
index 86b2b8bf2f7..acc1e17b811 100644
--- a/app/views/projects/jobs/_sidebar.html.haml
+++ b/app/views/projects/jobs/_sidebar.html.haml
@@ -82,7 +82,7 @@
- builds.select{|build| build.status == build_status}.each do |build|
.build-job{ class: sidebar_build_class(build, @build), data: { stage: build.stage } }
- tooltip = sanitize(build.tooltip_message.dup)
- = link_to(project_job_path(@project, build), data: { toggle: 'tooltip', html: 'true', title: tooltip, container: 'body' }) do
+ = link_to(project_job_path(@project, build), data: { toggle: 'tooltip', title: tooltip, container: 'body' }) do
= sprite_icon('arrow-right', size:16, css_class: 'icon-arrow-right')
%span{ class: "ci-status-icon-#{build.status}" }
= ci_icon_for_status(build.status)
diff --git a/app/views/projects/merge_requests/_how_to_merge.html.haml b/app/views/projects/merge_requests/_how_to_merge.html.haml
index 62dd21ef6e0..d3871453b9f 100644
--- a/app/views/projects/merge_requests/_how_to_merge.html.haml
+++ b/app/views/projects/merge_requests/_how_to_merge.html.haml
@@ -1,5 +1,5 @@
#modal_merge_info.modal{ tabindex: '-1' }
- .modal-dialog
+ .modal-dialog.modal-lg
.modal-content
.modal-header
%h3.modal-title Check out, review, and merge locally
diff --git a/app/views/projects/merge_requests/creations/_new_submit.html.haml b/app/views/projects/merge_requests/creations/_new_submit.html.haml
index f7a5d85500f..d5c4134dee2 100644
--- a/app/views/projects/merge_requests/creations/_new_submit.html.haml
+++ b/app/views/projects/merge_requests/creations/_new_submit.html.haml
@@ -33,7 +33,7 @@
%li.commits-tab.new-tab
= link_to url_for(safe_params), data: {target: 'div#commits', action: 'new', toggle: 'tabvue'} do
Commits
- %span.badge.badge-pill= @commits.size
+ %span.badge.badge-pill= @total_commit_count
- if @pipelines.any?
%li.builds-tab
= link_to url_for(safe_params.merge(action: 'pipelines')), data: {target: 'div#pipelines', action: 'pipelines', toggle: 'tabvue'} do
diff --git a/app/views/projects/milestones/show.html.haml b/app/views/projects/milestones/show.html.haml
index 2a9e20c2caa..0a684f9016a 100644
--- a/app/views/projects/milestones/show.html.haml
+++ b/app/views/projects/milestones/show.html.haml
@@ -43,18 +43,7 @@
- else
= link_to 'Reopen milestone', project_milestone_path(@project, @milestone, milestone: {state_event: :activate }), method: :put, class: "btn btn-reopen btn-nr btn-grouped"
- %button.js-delete-milestone-button.btn.btn-grouped.btn-danger{ data: { toggle: 'modal',
- target: '#delete-milestone-modal',
- milestone_id: @milestone.id,
- milestone_title: markdown_field(@milestone, :title),
- milestone_url: project_milestone_path(@project, @milestone),
- milestone_issue_count: @milestone.issues.count,
- milestone_merge_request_count: @milestone.merge_requests.count },
- disabled: true }
- = _('Delete')
- = icon('spin spinner', class: 'js-loading-icon hidden' )
-
- #delete-milestone-modal
+ = render 'shared/milestones/delete_button'
%a.btn.btn-default.btn-grouped.float-right.d-block.d-sm-none.js-sidebar-toggle{ href: "#" }
= icon('angle-double-left')
diff --git a/app/views/projects/mirrors/_instructions.html.haml b/app/views/projects/mirrors/_instructions.html.haml
index e051f9e6331..35a6885318a 100644
--- a/app/views/projects/mirrors/_instructions.html.haml
+++ b/app/views/projects/mirrors/_instructions.html.haml
@@ -4,7 +4,9 @@
= _('The repository must be accessible over <code>http://</code>,
<code>https://</code>, <code>ssh://</code> and <code>git://</code>.').html_safe
%li= _('Include the username in the URL if required: <code>https://username@gitlab.company.com/group/project.git</code>.').html_safe
- %li= _("The update action will time out after #{import_will_timeout_message(Gitlab.config.gitlab_shell.git_timeout)} minutes. For big repositories, use a clone/push combination.")
+ %li
+ - minutes = Gitlab.config.gitlab_shell.git_timeout / 60
+ = _("The update action will time out after %{number_of_minutes} minutes. For big repositories, use a clone/push combination.") % { number_of_minutes: minutes }
%li= _('The Git LFS objects will <strong>not</strong> be synced.').html_safe
%li
= _('This user will be the author of all events in the activity feed that are the result of an update,
diff --git a/app/views/projects/notes/_actions.html.haml b/app/views/projects/notes/_actions.html.haml
index b4fe1cabdfd..e9008d60098 100644
--- a/app/views/projects/notes/_actions.html.haml
+++ b/app/views/projects/notes/_actions.html.haml
@@ -40,7 +40,7 @@
- if note.emoji_awardable?
- user_authored = note.user_authored?(current_user)
.note-actions-item
- = button_tag title: 'Add reaction', class: "note-action-button note-emoji-button js-add-award js-note-emoji #{'js-user-authored' if user_authored} has-tooltip btn btn-transparent", data: { position: 'right', container: 'body' } do
+ = button_tag title: 'Add reaction', class: "note-action-button note-emoji-button js-add-award js-note-emoji} has-tooltip btn btn-transparent", data: { position: 'right', container: 'body' } do
= icon('spinner spin')
%span{ class: 'link-highlight award-control-icon-neutral' }= custom_icon('emoji_slightly_smiling_face')
%span{ class: 'link-highlight award-control-icon-positive' }= custom_icon('emoji_smiley')
diff --git a/app/views/shared/milestones/_delete_button.html.haml b/app/views/shared/milestones/_delete_button.html.haml
new file mode 100644
index 00000000000..e236c24b088
--- /dev/null
+++ b/app/views/shared/milestones/_delete_button.html.haml
@@ -0,0 +1,14 @@
+- milestone_url = @milestone.project_milestone? ? project_milestone_path(@project, @milestone) : group_milestone_path(@group, @milestone)
+
+%button.js-delete-milestone-button.btn.btn-grouped.btn-danger{ data: { toggle: 'modal',
+ target: '#delete-milestone-modal',
+ milestone_id: @milestone.id,
+ milestone_title: markdown_field(@milestone, :title),
+ milestone_url: milestone_url,
+ milestone_issue_count: @milestone.issues.count,
+ milestone_merge_request_count: @milestone.merge_requests.count },
+ disabled: true }
+ = _('Delete')
+ = icon('spin spinner', class: 'js-loading-icon hidden' )
+
+#delete-milestone-modal
diff --git a/app/views/shared/milestones/_milestone.html.haml b/app/views/shared/milestones/_milestone.html.haml
index c559945a9c9..3dd2842be4f 100644
--- a/app/views/shared/milestones/_milestone.html.haml
+++ b/app/views/shared/milestones/_milestone.html.haml
@@ -16,6 +16,9 @@
= milestone_date_range(milestone)
%div
= render('shared/milestone_expired', milestone: milestone)
+ - if milestone.group_milestone?
+ .label-badge.label-badge-blue.d-inline-block
+ = milestone.group.full_name
- if milestone.legacy_group_milestone?
.projects
- milestone.milestones.each do |milestone|
@@ -49,7 +52,7 @@
- unless milestone.active?
= link_to 'Reopen Milestone', project_milestone_path(@project, milestone, {state_event: :activate }), method: :put, class: "btn btn-grouped btn-reopen"
- if @group
- - if can?(current_user, :admin_milestones, @group)
+ - if can?(current_user, :admin_milestone, @group)
- if milestone.closed?
= link_to 'Reopen Milestone', group_milestone_route(milestone, {state_event: :activate }), method: :put, class: "btn btn-sm btn-grouped btn-reopen"
- else
diff --git a/app/views/shared/milestones/_top.html.haml b/app/views/shared/milestones/_top.html.haml
index 320e3788a0f..0499b04a482 100644
--- a/app/views/shared/milestones/_top.html.haml
+++ b/app/views/shared/milestones/_top.html.haml
@@ -23,7 +23,7 @@
= milestone_date_range(milestone)
- if group
.float-right
- - if can?(current_user, :admin_milestones, group)
+ - if can?(current_user, :admin_milestone, group)
- if milestone.group_milestone?
= link_to edit_group_milestone_path(group, milestone), class: "btn btn btn-grouped" do
Edit
@@ -32,6 +32,9 @@
- else
= link_to 'Reopen Milestone', group_milestone_route(milestone, {state_event: :activate }), method: :put, class: "btn btn-grouped btn-reopen"
+ - unless is_dynamic_milestone
+ = render 'shared/milestones/delete_button'
+
= render 'shared/milestones/deprecation_message' if is_dynamic_milestone
.detail-page-description.milestone-detail
diff --git a/app/views/snippets/notes/_actions.html.haml b/app/views/snippets/notes/_actions.html.haml
index 3a50324770d..e1f7ee80ebb 100644
--- a/app/views/snippets/notes/_actions.html.haml
+++ b/app/views/snippets/notes/_actions.html.haml
@@ -2,7 +2,7 @@
- if note.emoji_awardable?
- user_authored = note.user_authored?(current_user)
.note-actions-item
- = link_to '#', title: 'Add reaction', class: "note-action-button note-emoji-button js-add-award js-note-emoji #{'js-user-authored' if user_authored} has-tooltip", data: { position: 'right' } do
+ = link_to '#', title: 'Add reaction', class: "note-action-button note-emoji-button js-add-award js-note-emoji has-tooltip", data: { position: 'right' } do
= icon('spinner spin')
%span{ class: 'link-highlight award-control-icon-neutral' }= custom_icon('emoji_slightly_smiling_face')
%span{ class: 'link-highlight award-control-icon-positive' }= custom_icon('emoji_smiley')
diff --git a/changelogs/unreleased/1756-set-iid-via-api.yml b/changelogs/unreleased/1756-set-iid-via-api.yml
deleted file mode 100644
index 680a9464ab4..00000000000
--- a/changelogs/unreleased/1756-set-iid-via-api.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Allow issues API to receive an internal ID (iid) on create
-merge_request: 20626
-author: Jamie Schembri
-type: fixed
diff --git a/changelogs/unreleased/21326-avoid-nil-safe-message.yml b/changelogs/unreleased/21326-avoid-nil-safe-message.yml
new file mode 100644
index 00000000000..ca1a89191a8
--- /dev/null
+++ b/changelogs/unreleased/21326-avoid-nil-safe-message.yml
@@ -0,0 +1,5 @@
+---
+title: "Avoid nil safe message"
+merge_request: 21326
+author: Yi Siliang
+type: fixed
diff --git a/changelogs/unreleased/23705-add-single-file-download-in-repo.yml b/changelogs/unreleased/23705-add-single-file-download-in-repo.yml
deleted file mode 100644
index f156bfb1101..00000000000
--- a/changelogs/unreleased/23705-add-single-file-download-in-repo.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Add download button for single file (including raw files) in repository
-merge_request: 20480
-author: Kia Mei Somabes
-type: added
diff --git a/changelogs/unreleased/25990-improve-web-terminal.yml b/changelogs/unreleased/25990-improve-web-terminal.yml
deleted file mode 100644
index 3f8a8c6211c..00000000000
--- a/changelogs/unreleased/25990-improve-web-terminal.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Move xterm to a node dependency and remove it from vendor's folder
-merge_request: 20588
-author:
-type: other
diff --git a/changelogs/unreleased/25990-interactive-web-terminals-authorization.yml b/changelogs/unreleased/25990-interactive-web-terminals-authorization.yml
deleted file mode 100644
index 0a2853c20c6..00000000000
--- a/changelogs/unreleased/25990-interactive-web-terminals-authorization.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix authorization for interactive web terminals
-merge_request: 20811
-author:
-type: fixed
diff --git a/changelogs/unreleased/27456-improve-feedback-when-dev-cannot-push-to-empty-repo.yml b/changelogs/unreleased/27456-improve-feedback-when-dev-cannot-push-to-empty-repo.yml
deleted file mode 100644
index 55d82c4ee5d..00000000000
--- a/changelogs/unreleased/27456-improve-feedback-when-dev-cannot-push-to-empty-repo.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Improve feedback when a developer is unable to push to an empty repository
-merge_request: 20519
-author:
-type: changed
diff --git a/changelogs/unreleased/29278-commits-page-tooltips.yml b/changelogs/unreleased/29278-commits-page-tooltips.yml
deleted file mode 100644
index d54301a1cf0..00000000000
--- a/changelogs/unreleased/29278-commits-page-tooltips.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Remove tooltips from commit author avatar and name in commit lists
-merge_request: 20674
-author:
-type: other
diff --git a/changelogs/unreleased/31576-redirect-commits-to-root-if-no-ref.yml b/changelogs/unreleased/31576-redirect-commits-to-root-if-no-ref.yml
deleted file mode 100644
index 21d9d25d342..00000000000
--- a/changelogs/unreleased/31576-redirect-commits-to-root-if-no-ref.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Redirect commits to root if no ref is provided (31576)
-merge_request: 20738
-author: Kia Mei Somabes
-type: added
diff --git a/changelogs/unreleased/32783-api-all-members-with-ancestors.yml b/changelogs/unreleased/32783-api-all-members-with-ancestors.yml
deleted file mode 100644
index ca53d02845d..00000000000
--- a/changelogs/unreleased/32783-api-all-members-with-ancestors.yml
+++ /dev/null
@@ -1,6 +0,0 @@
----
-title: Adds API endpoint /api/v4/(project/group)/:id/members/all to list also inherited
- members
-merge_request: 19748
-author: Jacopo Beschi @jacopo-beschi
-type: added
diff --git a/changelogs/unreleased/32821-better-error-message-add-invalid-user-to-project.yml b/changelogs/unreleased/32821-better-error-message-add-invalid-user-to-project.yml
deleted file mode 100644
index 587d7209c2f..00000000000
--- a/changelogs/unreleased/32821-better-error-message-add-invalid-user-to-project.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Improve error message when adding invalid user to a project
-merge_request: 20885
-author: Jacopo Beschi @jacopo-beschi
-type: added
diff --git a/changelogs/unreleased/34572-ssh-certificates.yml b/changelogs/unreleased/34572-ssh-certificates.yml
deleted file mode 100644
index 76a08a188de..00000000000
--- a/changelogs/unreleased/34572-ssh-certificates.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Add support for SSH certificate authentication
-merge_request: 19911
-author: Ævar Arnfjörð Bjarmason
-type: added
diff --git a/changelogs/unreleased/35952-keep-admin-settings-open-after-submit.yml b/changelogs/unreleased/35952-keep-admin-settings-open-after-submit.yml
deleted file mode 100644
index e1e5c8db046..00000000000
--- a/changelogs/unreleased/35952-keep-admin-settings-open-after-submit.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Keep admin settings sections open after submitting forms
-merge_request: 21040
-author:
-type: other
diff --git a/changelogs/unreleased/36409-frontend-for-clarifying-the-usefulness-of-the-search-bar.yml b/changelogs/unreleased/36409-frontend-for-clarifying-the-usefulness-of-the-search-bar.yml
deleted file mode 100644
index efa13c9ab3c..00000000000
--- a/changelogs/unreleased/36409-frontend-for-clarifying-the-usefulness-of-the-search-bar.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: UX improvements to top nav search bar
-merge_request: 20537
-author:
-type: changed
diff --git a/changelogs/unreleased/38604-add-private-profile.yml b/changelogs/unreleased/38604-add-private-profile.yml
deleted file mode 100644
index e40e7d9321e..00000000000
--- a/changelogs/unreleased/38604-add-private-profile.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Add an option to have a private profile on GitLab.
-merge_request: 20387
-author: jxterry
-type: added
diff --git a/changelogs/unreleased/40973-disable-rack-attack-by-default.yml b/changelogs/unreleased/40973-disable-rack-attack-by-default.yml
deleted file mode 100644
index 681aa761e2a..00000000000
--- a/changelogs/unreleased/40973-disable-rack-attack-by-default.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Rack attack is now disabled by default
-merge_request: 16669
-author:
-type: changed
diff --git a/changelogs/unreleased/41416-making-instance-wide-data-tools-more-accessible.yml b/changelogs/unreleased/41416-making-instance-wide-data-tools-more-accessible.yml
deleted file mode 100644
index b980b719d68..00000000000
--- a/changelogs/unreleased/41416-making-instance-wide-data-tools-more-accessible.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Allow non-admins to view instance statistics (if permitted by the instance admins)
-merge_request: 20874
-author:
-type: changed
diff --git a/changelogs/unreleased/41441-add-target-branch-name-to-cherrypick-confirmation.yml b/changelogs/unreleased/41441-add-target-branch-name-to-cherrypick-confirmation.yml
new file mode 100644
index 00000000000..c23676a3104
--- /dev/null
+++ b/changelogs/unreleased/41441-add-target-branch-name-to-cherrypick-confirmation.yml
@@ -0,0 +1,5 @@
+---
+title: Add target branch name to cherrypick confirmation message
+merge_request: 20846
+author: George Andrinopoulos
+type: other
diff --git a/changelogs/unreleased/41671-fixing-milestone-date-change-when-editing.yml b/changelogs/unreleased/41671-fixing-milestone-date-change-when-editing.yml
deleted file mode 100644
index c6a0dc4f129..00000000000
--- a/changelogs/unreleased/41671-fixing-milestone-date-change-when-editing.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: "Fixing milestone date change when editing"
-merge_request: 20279
-author: Orlando Del Aguila
-type: fixed \ No newline at end of file
diff --git a/changelogs/unreleased/41784-monitoring-graph-popovers.yml b/changelogs/unreleased/41784-monitoring-graph-popovers.yml
deleted file mode 100644
index 757445d7e0c..00000000000
--- a/changelogs/unreleased/41784-monitoring-graph-popovers.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Update design for system metrics popovers
-merge_request: 20655
-author:
-type: fixed
diff --git a/changelogs/unreleased/42415-omit-projects-from-get-group-endpoint.yml b/changelogs/unreleased/42415-omit-projects-from-get-group-endpoint.yml
deleted file mode 100644
index cabe5216045..00000000000
--- a/changelogs/unreleased/42415-omit-projects-from-get-group-endpoint.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Adds with_projects optional parameter to GET /groups/:id API endpoint
-merge_request: 20494
-author:
-type: changed
diff --git a/changelogs/unreleased/43011-typecast-markdownversion-prop-notesapp.yml b/changelogs/unreleased/43011-typecast-markdownversion-prop-notesapp.yml
deleted file mode 100644
index b60aeba860a..00000000000
--- a/changelogs/unreleased/43011-typecast-markdownversion-prop-notesapp.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix Vue datatype errors for markdownVersion parsing
-merge_request: 20800
-author:
-type: fixed
diff --git a/changelogs/unreleased/43096-controller-projects-issuescontroller-referenced_merge_requests-json-executes-more-than-100-sql-queries.yml b/changelogs/unreleased/43096-controller-projects-issuescontroller-referenced_merge_requests-json-executes-more-than-100-sql-queries.yml
new file mode 100644
index 00000000000..f4744c868ef
--- /dev/null
+++ b/changelogs/unreleased/43096-controller-projects-issuescontroller-referenced_merge_requests-json-executes-more-than-100-sql-queries.yml
@@ -0,0 +1,5 @@
+---
+title: Improve performance when fetching related merge requests for an issue
+merge_request: 21237
+author:
+type: performance
diff --git a/changelogs/unreleased/43312-remove_user_activity_workers.yml b/changelogs/unreleased/43312-remove_user_activity_workers.yml
deleted file mode 100644
index 6dfd018e350..00000000000
--- a/changelogs/unreleased/43312-remove_user_activity_workers.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Delete UserActivities and related workers
-merge_request: 20597
-author:
-type: performance
diff --git a/changelogs/unreleased/43625-increase-modal-checkout.yml b/changelogs/unreleased/43625-increase-modal-checkout.yml
new file mode 100644
index 00000000000..877550924c1
--- /dev/null
+++ b/changelogs/unreleased/43625-increase-modal-checkout.yml
@@ -0,0 +1,5 @@
+---
+title: Increase width of checkout branch modal box
+merge_request:
+author:
+type: fixed
diff --git a/changelogs/unreleased/44127-board-label-edit-drop-down-is-showing-incorrect-selected-labels-summary.yml b/changelogs/unreleased/44127-board-label-edit-drop-down-is-showing-incorrect-selected-labels-summary.yml
deleted file mode 100644
index de991ef475a..00000000000
--- a/changelogs/unreleased/44127-board-label-edit-drop-down-is-showing-incorrect-selected-labels-summary.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Board label edit dropdown shows incorrect selected labels summary
-merge_request: 20673
-author:
-type: fixed
diff --git a/changelogs/unreleased/44824-remove-ghost-notification-settings-for-group-and-project.yml b/changelogs/unreleased/44824-remove-ghost-notification-settings-for-group-and-project.yml
deleted file mode 100644
index ddc878ee710..00000000000
--- a/changelogs/unreleased/44824-remove-ghost-notification-settings-for-group-and-project.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Adds foreign key to notification_settings.user_id
-merge_request: 20567
-author: Jacopo Beschi @jacopo-beschi
-type: added
diff --git a/changelogs/unreleased/45318-junit-FE.yml b/changelogs/unreleased/45318-junit-FE.yml
deleted file mode 100644
index bbc08f54484..00000000000
--- a/changelogs/unreleased/45318-junit-FE.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Adds frontend support to render test reports on the MR widget
-merge_request: 20936
-author:
-type: added
diff --git a/changelogs/unreleased/45318-vuex-store.yml b/changelogs/unreleased/45318-vuex-store.yml
deleted file mode 100644
index 5ea89034bce..00000000000
--- a/changelogs/unreleased/45318-vuex-store.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Adds Vuex store for reports section in MR widget
-merge_request: 20709
-author:
-type: added
diff --git a/changelogs/unreleased/45443-unable-to-save-user-profile-update-with-safari.yml b/changelogs/unreleased/45443-unable-to-save-user-profile-update-with-safari.yml
deleted file mode 100644
index b18f7aec546..00000000000
--- a/changelogs/unreleased/45443-unable-to-save-user-profile-update-with-safari.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Resolve "Unable to save user profile update with Safari"
-merge_request: 20676
-author:
-type: fixed
diff --git a/changelogs/unreleased/46165-web-ide-branch-picker.yml b/changelogs/unreleased/46165-web-ide-branch-picker.yml
deleted file mode 100644
index ff879cb3d37..00000000000
--- a/changelogs/unreleased/46165-web-ide-branch-picker.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Create branch and MR picker for Web IDE
-merge_request: 20978
-author:
-type: changed
diff --git a/changelogs/unreleased/46535-orphaned-uploads.yml b/changelogs/unreleased/46535-orphaned-uploads.yml
deleted file mode 100644
index 1cd087a6aad..00000000000
--- a/changelogs/unreleased/46535-orphaned-uploads.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Clean orphaned files in object storage
-merge_request: 20918
-author:
-type: added
diff --git a/changelogs/unreleased/46703-group-dashboard-line-height-is-too-tall-for-group-names.yml b/changelogs/unreleased/46703-group-dashboard-line-height-is-too-tall-for-group-names.yml
deleted file mode 100644
index 5b91c6d5a9f..00000000000
--- a/changelogs/unreleased/46703-group-dashboard-line-height-is-too-tall-for-group-names.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Solves group dashboard line height is too tall for group names.
-merge_request: 21033
-author:
-type: fixed
diff --git a/changelogs/unreleased/46869-deploy-tokens-failed-to-clone-lfs-repository.yml b/changelogs/unreleased/46869-deploy-tokens-failed-to-clone-lfs-repository.yml
deleted file mode 100644
index d490df58144..00000000000
--- a/changelogs/unreleased/46869-deploy-tokens-failed-to-clone-lfs-repository.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Allow cloning LFS repositories through DeployTokens
-merge_request: 20729
-author:
-type: other
diff --git a/changelogs/unreleased/46930-fix-updated_at-if-created_at-is-set-note-api.yml b/changelogs/unreleased/46930-fix-updated_at-if-created_at-is-set-note-api.yml
deleted file mode 100644
index d95714a5267..00000000000
--- a/changelogs/unreleased/46930-fix-updated_at-if-created_at-is-set-note-api.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix updated_at if created_at is set for Note API
-merge_request:
-author:
-type: fixed
diff --git a/changelogs/unreleased/46940-hashed-storage-extend-enable-hashed-storage-for-all-new-projects-to-for-all-new-and-renamed-projects.yml b/changelogs/unreleased/46940-hashed-storage-extend-enable-hashed-storage-for-all-new-projects-to-for-all-new-and-renamed-projects.yml
deleted file mode 100644
index 71e523e6de8..00000000000
--- a/changelogs/unreleased/46940-hashed-storage-extend-enable-hashed-storage-for-all-new-projects-to-for-all-new-and-renamed-projects.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Enable hashed storage for all newly created or renamed projects
-merge_request: 19747
-author:
-type: changed
diff --git a/changelogs/unreleased/47156-improve-auto-devops-settings.yml b/changelogs/unreleased/47156-improve-auto-devops-settings.yml
deleted file mode 100644
index d8993565047..00000000000
--- a/changelogs/unreleased/47156-improve-auto-devops-settings.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Improve and simplify Auto DevOps settings flow
-merge_request: 20946
-author:
-type: other
diff --git a/changelogs/unreleased/47419-Fix-breadcrumbs.yml b/changelogs/unreleased/47419-Fix-breadcrumbs.yml
deleted file mode 100644
index 1a7f8196683..00000000000
--- a/changelogs/unreleased/47419-Fix-breadcrumbs.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix breadcrumbs in Admin/User interface.
-merge_request: 19608
-author: Robin Naundorf
-type: fixed
diff --git a/changelogs/unreleased/47548-monospace-commit-messages.yml b/changelogs/unreleased/47548-monospace-commit-messages.yml
deleted file mode 100644
index 7344f72207b..00000000000
--- a/changelogs/unreleased/47548-monospace-commit-messages.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Update commit message styles with monospace font and overflow-x
-merge_request: 20988
-author:
-type: changed
diff --git a/changelogs/unreleased/47728-mr-api-documentation-changes.yml b/changelogs/unreleased/47728-mr-api-documentation-changes.yml
deleted file mode 100644
index 12720f280a1..00000000000
--- a/changelogs/unreleased/47728-mr-api-documentation-changes.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Remove changes_count from MR API documentation where necessary
-merge_request: 19745
-author: Jan Beckmann
-type: fixed
diff --git a/changelogs/unreleased/47768-web-ide-redesign-header.yml b/changelogs/unreleased/47768-web-ide-redesign-header.yml
deleted file mode 100644
index 49133158164..00000000000
--- a/changelogs/unreleased/47768-web-ide-redesign-header.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Redesign Web IDE back button and context header
-merge_request: 20850
-author:
-type: changed
diff --git a/changelogs/unreleased/48036-fix-web-ide-blob-crash.yml b/changelogs/unreleased/48036-fix-web-ide-blob-crash.yml
deleted file mode 100644
index 6ff209b5181..00000000000
--- a/changelogs/unreleased/48036-fix-web-ide-blob-crash.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix Web IDE crashing on directories named 'blob'
-merge_request: 20712
-author:
-type: fixed
diff --git a/changelogs/unreleased/48055-web-ide-resize-handles.yml b/changelogs/unreleased/48055-web-ide-resize-handles.yml
deleted file mode 100644
index 0f650cdda6f..00000000000
--- a/changelogs/unreleased/48055-web-ide-resize-handles.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Increase width of Web IDE sidebar resize handles
-merge_request: 20818
-author:
-type: fixed
diff --git a/changelogs/unreleased/48098-mutual-auth-cluster-applications.yml b/changelogs/unreleased/48098-mutual-auth-cluster-applications.yml
deleted file mode 100644
index 43125ef25c4..00000000000
--- a/changelogs/unreleased/48098-mutual-auth-cluster-applications.yml
+++ /dev/null
@@ -1,6 +0,0 @@
----
-title: Ensure installed Helm Tiller For GitLab Managed Apps Is protected by mutual
- auth
-merge_request: 20928
-author:
-type: changed
diff --git a/changelogs/unreleased/48246-osw-load-diffs-improvement.yml b/changelogs/unreleased/48246-osw-load-diffs-improvement.yml
deleted file mode 100644
index c4292ab0d29..00000000000
--- a/changelogs/unreleased/48246-osw-load-diffs-improvement.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Improve performance when fetching collapsed diffs and commenting in merge requests
-merge_request: 20940
-author:
-type: performance
diff --git a/changelogs/unreleased/48419-charts-with-long-label-appear-oversized.yml b/changelogs/unreleased/48419-charts-with-long-label-appear-oversized.yml
deleted file mode 100644
index b3ccbb121f0..00000000000
--- a/changelogs/unreleased/48419-charts-with-long-label-appear-oversized.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: fix height of full-width Metrics charts on large screens
-merge_request: 20866
-author:
-type: fixed
diff --git a/changelogs/unreleased/48456-fix-system-level-labels-admin-ui.yml b/changelogs/unreleased/48456-fix-system-level-labels-admin-ui.yml
deleted file mode 100644
index c34750a3b88..00000000000
--- a/changelogs/unreleased/48456-fix-system-level-labels-admin-ui.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix the UI for listing system-level labels
-merge_request:
-author:
-type: fixed
diff --git a/changelogs/unreleased/48537-update-avatar-only-via-api.yml b/changelogs/unreleased/48537-update-avatar-only-via-api.yml
deleted file mode 100644
index 9b3ab946cc1..00000000000
--- a/changelogs/unreleased/48537-update-avatar-only-via-api.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Allow updating a project's avatar without other params
-merge_request:
-author: Jamie Schembri
-type: fixed
diff --git a/changelogs/unreleased/48542-code-link.yml b/changelogs/unreleased/48542-code-link.yml
deleted file mode 100644
index 8d8d9bf8d74..00000000000
--- a/changelogs/unreleased/48542-code-link.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix link color in markdown code brackets
-merge_request: 20841
-author:
-type: fixed
diff --git a/changelogs/unreleased/48617-promoting-milestone.yml b/changelogs/unreleased/48617-promoting-milestone.yml
deleted file mode 100644
index 7fbc15051cf..00000000000
--- a/changelogs/unreleased/48617-promoting-milestone.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Escapes milestone and label's names on flash notice when promoting them
-merge_request:
-author:
-type: fixed
diff --git a/changelogs/unreleased/48636-new-mr-card-styles.yml b/changelogs/unreleased/48636-new-mr-card-styles.yml
deleted file mode 100644
index 94f62e677fb..00000000000
--- a/changelogs/unreleased/48636-new-mr-card-styles.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix new MR card styles
-merge_request: 20822
-author:
-type: fixed
diff --git a/changelogs/unreleased/48657-persist-auto-devops-banner-dismissal-per-user-cookie.yml b/changelogs/unreleased/48657-persist-auto-devops-banner-dismissal-per-user-cookie.yml
deleted file mode 100644
index 7ee018ef679..00000000000
--- a/changelogs/unreleased/48657-persist-auto-devops-banner-dismissal-per-user-cookie.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Persist 'Auto DevOps' banner dismissal globally
-merge_request: 20540
-author:
-type: other
diff --git a/changelogs/unreleased/48773-gitlab-project-import-should-use-object-storage.yml b/changelogs/unreleased/48773-gitlab-project-import-should-use-object-storage.yml
deleted file mode 100644
index f298380b920..00000000000
--- a/changelogs/unreleased/48773-gitlab-project-import-should-use-object-storage.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Add object storage logic to project import
-merge_request: 20773
-author:
-type: added
diff --git a/changelogs/unreleased/48804-redesign-gcp-banner.yml b/changelogs/unreleased/48804-redesign-gcp-banner.yml
deleted file mode 100644
index 729f959badc..00000000000
--- a/changelogs/unreleased/48804-redesign-gcp-banner.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Redesign GCP offer banner
-merge_request:
-author:
-type: changed
diff --git a/changelogs/unreleased/48823-copy-gfm.yml b/changelogs/unreleased/48823-copy-gfm.yml
deleted file mode 100644
index b6137e2e3f9..00000000000
--- a/changelogs/unreleased/48823-copy-gfm.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Resolve Copy diff file path as GFM is broken
-merge_request: 20725
-author:
-type: fixed
diff --git a/changelogs/unreleased/48834-chart-versions-for-applications-installed-by-one-click-install-buttons-should-be-version-locked.yml b/changelogs/unreleased/48834-chart-versions-for-applications-installed-by-one-click-install-buttons-should-be-version-locked.yml
deleted file mode 100644
index d79b95411aa..00000000000
--- a/changelogs/unreleased/48834-chart-versions-for-applications-installed-by-one-click-install-buttons-should-be-version-locked.yml
+++ /dev/null
@@ -1,6 +0,0 @@
----
-title: Chart versions for applications installed by one click install buttons should
- be version locked
-merge_request: 20765
-author:
-type: fixed
diff --git a/changelogs/unreleased/48932-disable-saml-if-omniauth-is-disabled.yml b/changelogs/unreleased/48932-disable-saml-if-omniauth-is-disabled.yml
deleted file mode 100644
index 0466debea65..00000000000
--- a/changelogs/unreleased/48932-disable-saml-if-omniauth-is-disabled.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Disable SAML and Bitbucket if OmniAuth is disabled
-merge_request: 20608
-author:
-type: fixed
diff --git a/changelogs/unreleased/48934.yml b/changelogs/unreleased/48934.yml
deleted file mode 100644
index 8e2e53ed198..00000000000
--- a/changelogs/unreleased/48934.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Improve danger confirmation modals by focusing input field
-merge_request:
-author: Jamie Schembri
-type: added
diff --git a/changelogs/unreleased/48976-fix-sti-background-migration.yml b/changelogs/unreleased/48976-fix-sti-background-migration.yml
deleted file mode 100644
index e95536b213c..00000000000
--- a/changelogs/unreleased/48976-fix-sti-background-migration.yml
+++ /dev/null
@@ -1,6 +0,0 @@
----
-title: "[Rails5] Fix 'Invalid single-table inheritance type: Group is not a subclass
- of Gitlab::BackgroundMigration::FixCrossProjectLabelLinks::Namespace'"
-merge_request: 20462
-author: "@blackst0ne"
-type: fixed
diff --git a/changelogs/unreleased/49025-docs-kubernetes-tiller.yml b/changelogs/unreleased/49025-docs-kubernetes-tiller.yml
deleted file mode 100644
index c4f01490cfa..00000000000
--- a/changelogs/unreleased/49025-docs-kubernetes-tiller.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Update docs of Helm Tiller
-merge_request: 20515
-author: Takuya Noguchi
-type: other
diff --git a/changelogs/unreleased/49107-prefetching-of-assets-and-cdn-domain.yml b/changelogs/unreleased/49107-prefetching-of-assets-and-cdn-domain.yml
deleted file mode 100644
index 541b562adac..00000000000
--- a/changelogs/unreleased/49107-prefetching-of-assets-and-cdn-domain.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: DNS prefetching if asset_host for CDN hosting is set
-merge_request: 20781
-author:
-type: performance
diff --git a/changelogs/unreleased/49110-update-mr-widget-styles.yml b/changelogs/unreleased/49110-update-mr-widget-styles.yml
new file mode 100644
index 00000000000..e54866a0908
--- /dev/null
+++ b/changelogs/unreleased/49110-update-mr-widget-styles.yml
@@ -0,0 +1,5 @@
+---
+title: Truncate branch names and update "commits behind" text in MR page
+merge_request: 21206
+author:
+type: changed
diff --git a/changelogs/unreleased/49114-add-gitaly-servers-to-admin-overview-navigation-menu.yml b/changelogs/unreleased/49114-add-gitaly-servers-to-admin-overview-navigation-menu.yml
deleted file mode 100644
index ab320450a1a..00000000000
--- a/changelogs/unreleased/49114-add-gitaly-servers-to-admin-overview-navigation-menu.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Gitaly Servers link into Admin > Overview navigation menu
-merge_request: 20550
-author:
-type: added
diff --git a/changelogs/unreleased/49161-disable-toggle-comments.yml b/changelogs/unreleased/49161-disable-toggle-comments.yml
deleted file mode 100644
index 5ec16191f07..00000000000
--- a/changelogs/unreleased/49161-disable-toggle-comments.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Disables toggle comments button if diff has no discussions
-merge_request:
-author:
-type: other
diff --git a/changelogs/unreleased/49272-sanitize-git-url-in-import-errors.yml b/changelogs/unreleased/49272-sanitize-git-url-in-import-errors.yml
deleted file mode 100644
index c757e55f1cd..00000000000
--- a/changelogs/unreleased/49272-sanitize-git-url-in-import-errors.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Sanitize git URL in import errors
-merge_request:
-author: Jamie Schembri
-type: fixed
diff --git a/changelogs/unreleased/49291-fix-memory-graph-component-typo.yml b/changelogs/unreleased/49291-fix-memory-graph-component-typo.yml
deleted file mode 100644
index f21bd454e84..00000000000
--- a/changelogs/unreleased/49291-fix-memory-graph-component-typo.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix typo in CSS transform property for Memory Graph component
-merge_request: 20650
-author:
-type: fixed
diff --git a/changelogs/unreleased/49292-add-group-name-badge-under-milestone.yml b/changelogs/unreleased/49292-add-group-name-badge-under-milestone.yml
new file mode 100644
index 00000000000..69089cfe357
--- /dev/null
+++ b/changelogs/unreleased/49292-add-group-name-badge-under-milestone.yml
@@ -0,0 +1,5 @@
+---
+title: Add group name badge under group milestone
+merge_request: 21384
+author:
+type: added
diff --git a/changelogs/unreleased/49324-add-support-for-tar-gz-autodevops-charts.yml b/changelogs/unreleased/49324-add-support-for-tar-gz-autodevops-charts.yml
deleted file mode 100644
index a87eef3f7f3..00000000000
--- a/changelogs/unreleased/49324-add-support-for-tar-gz-autodevops-charts.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Add support for tar.gz AUTO_DEVOPS_CHART charts (#49324)
-merge_request: 20691
-author: '@kondi1'
-type: added
diff --git a/changelogs/unreleased/49364-fix-broadcast-margin.yml b/changelogs/unreleased/49364-fix-broadcast-margin.yml
deleted file mode 100644
index 821fb9df1af..00000000000
--- a/changelogs/unreleased/49364-fix-broadcast-margin.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix misalignment of broadcast message on login page
-merge_request: 20794
-author: Robin Naundorf
-type: fixed
diff --git a/changelogs/unreleased/49375-move-help-popover.yml b/changelogs/unreleased/49375-move-help-popover.yml
deleted file mode 100644
index 2547d5768bf..00000000000
--- a/changelogs/unreleased/49375-move-help-popover.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Moves help_popover component to a common location
-merge_request:
-author:
-type: other
diff --git a/changelogs/unreleased/49499-list-of-projects-not-loading-when-trying-to-create-an-issue-from-a-board-typeerror.yml b/changelogs/unreleased/49499-list-of-projects-not-loading-when-trying-to-create-an-issue-from-a-board-typeerror.yml
deleted file mode 100644
index 043698269e2..00000000000
--- a/changelogs/unreleased/49499-list-of-projects-not-loading-when-trying-to-create-an-issue-from-a-board-typeerror.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fixed list of projects not loading in group boards
-merge_request: 20955
-author:
-type: fixed
diff --git a/changelogs/unreleased/49701-sorting-by-name-on-milestones-page-error.yml b/changelogs/unreleased/49701-sorting-by-name-on-milestones-page-error.yml
deleted file mode 100644
index 7eb73110d60..00000000000
--- a/changelogs/unreleased/49701-sorting-by-name-on-milestones-page-error.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix sorting by name on milestones page
-merge_request: 20881
-author:
-type: fixed
diff --git a/changelogs/unreleased/49747-update-poll-2xx.yml b/changelogs/unreleased/49747-update-poll-2xx.yml
deleted file mode 100644
index 359d1b80447..00000000000
--- a/changelogs/unreleased/49747-update-poll-2xx.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Changes poll.js to keep polling on any 2xx http status code
-merge_request: 20904
-author:
-type: other
diff --git a/changelogs/unreleased/49776-pipeline-job-log-page-uses-too-much-cpu-for-loading-animation.yml b/changelogs/unreleased/49776-pipeline-job-log-page-uses-too-much-cpu-for-loading-animation.yml
deleted file mode 100644
index 96da2436a9f..00000000000
--- a/changelogs/unreleased/49776-pipeline-job-log-page-uses-too-much-cpu-for-loading-animation.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: refactor pipeline job log animation to reduce CPU usage
-merge_request: 20915
-author:
-type: performance
diff --git a/changelogs/unreleased/49830-use-helm-272.yml b/changelogs/unreleased/49830-use-helm-272.yml
deleted file mode 100644
index f6ecc12dbfa..00000000000
--- a/changelogs/unreleased/49830-use-helm-272.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Use Helm 2.7.2 for GitLab Managed Apps
-merge_request: 20956
-author:
-type: changed
diff --git a/changelogs/unreleased/49835-increase-width.yml b/changelogs/unreleased/49835-increase-width.yml
deleted file mode 100644
index f963c0c5e47..00000000000
--- a/changelogs/unreleased/49835-increase-width.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Increases title column on modal for reports
-merge_request:
-author:
-type: other
diff --git a/changelogs/unreleased/49851-link-to-runners.yml b/changelogs/unreleased/49851-link-to-runners.yml
deleted file mode 100644
index 89fd6853bc8..00000000000
--- a/changelogs/unreleased/49851-link-to-runners.yml
+++ /dev/null
@@ -1,6 +0,0 @@
----
-title: Automatically expand runner's settings block when linking to the runner's settings
- page
-merge_request:
-author:
-type: other
diff --git a/changelogs/unreleased/49854-recover-mr-regression-fixes-safe-1.yml b/changelogs/unreleased/49854-recover-mr-regression-fixes-safe-1.yml
deleted file mode 100644
index ffa4a3bc710..00000000000
--- a/changelogs/unreleased/49854-recover-mr-regression-fixes-safe-1.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix rendering of the context lines in MR diffs page.
-merge_request: 20968
-author:
-type: fixed
diff --git a/changelogs/unreleased/49854-recover-mr-regression-fixes-safe-2.yml b/changelogs/unreleased/49854-recover-mr-regression-fixes-safe-2.yml
deleted file mode 100644
index 42b0e4194f1..00000000000
--- a/changelogs/unreleased/49854-recover-mr-regression-fixes-safe-2.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix autosave and ESC confirmation issues for MR discussions.
-merge_request: 20968
-author:
-type: fixed
diff --git a/changelogs/unreleased/49854-recover-mr-regression-fixes-safe-3.yml b/changelogs/unreleased/49854-recover-mr-regression-fixes-safe-3.yml
deleted file mode 100644
index 29419091d02..00000000000
--- a/changelogs/unreleased/49854-recover-mr-regression-fixes-safe-3.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix navigation to First and Next discussion on MR Changes tab.
-merge_request: 20968
-author:
-type: fixed
diff --git a/changelogs/unreleased/49861-top-nav-search-bar-produces-console-error-when-unauthenticated.yml b/changelogs/unreleased/49861-top-nav-search-bar-produces-console-error-when-unauthenticated.yml
deleted file mode 100644
index 30f5002c5b5..00000000000
--- a/changelogs/unreleased/49861-top-nav-search-bar-produces-console-error-when-unauthenticated.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: fix error caused when using the search bar while unauthenticated
-merge_request: 20970
-author:
-type: fixed
diff --git a/changelogs/unreleased/49899-merge-request-e-mail-link-has-full-url.yml b/changelogs/unreleased/49899-merge-request-e-mail-link-has-full-url.yml
deleted file mode 100644
index 856a7c579f3..00000000000
--- a/changelogs/unreleased/49899-merge-request-e-mail-link-has-full-url.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Ensure links in notifications footer are not escaped
-merge_request: 21000
-author:
-type: fixed
diff --git a/changelogs/unreleased/49907-commits-and-merge-requests-does-not-list-all-files-when-one-file-exceeds-size-limits.yml b/changelogs/unreleased/49907-commits-and-merge-requests-does-not-list-all-files-when-one-file-exceeds-size-limits.yml
deleted file mode 100644
index 2fce00a662f..00000000000
--- a/changelogs/unreleased/49907-commits-and-merge-requests-does-not-list-all-files-when-one-file-exceeds-size-limits.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix merge requests not showing any diff files for big patches
-merge_request: 21125
-author:
-type: fixed
diff --git a/changelogs/unreleased/49966-improve-junit-fe.yml b/changelogs/unreleased/49966-improve-junit-fe.yml
deleted file mode 100644
index 48971d3bfd6..00000000000
--- a/changelogs/unreleased/49966-improve-junit-fe.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Renders test reports for resolved failures and resets error state
-merge_request:
-author:
-type: fixed
diff --git a/changelogs/unreleased/49993-fix-remember-sorting-issue-mr.yml b/changelogs/unreleased/49993-fix-remember-sorting-issue-mr.yml
new file mode 100644
index 00000000000..df05bf3f3e2
--- /dev/null
+++ b/changelogs/unreleased/49993-fix-remember-sorting-issue-mr.yml
@@ -0,0 +1,5 @@
+---
+title: Split remembering sorting for issues and merge requests
+merge_request: 21153
+author: Jacopo Beschi @jacopo-beschi
+type: fixed
diff --git a/changelogs/unreleased/50101-env-block.yml b/changelogs/unreleased/50101-env-block.yml
new file mode 100644
index 00000000000..11e603e7a79
--- /dev/null
+++ b/changelogs/unreleased/50101-env-block.yml
@@ -0,0 +1,5 @@
+---
+title: Creates vue component for environments information in job log view
+merge_request:
+author:
+type: other
diff --git a/changelogs/unreleased/50257-fix-auto-devops-glibc-pubkey-url.yml b/changelogs/unreleased/50257-fix-auto-devops-glibc-pubkey-url.yml
deleted file mode 100644
index e081dfe6093..00000000000
--- a/changelogs/unreleased/50257-fix-auto-devops-glibc-pubkey-url.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: 'Auto-DevOps.gitlab-ci.yml: Update glibc package signing key URL'
-merge_request: 21182
-author: sgerrand
-type: fixed
diff --git a/changelogs/unreleased/50281-js-pages-do-not-load-on-windows-8-ie-11.yml b/changelogs/unreleased/50281-js-pages-do-not-load-on-windows-8-ie-11.yml
deleted file mode 100644
index eb20e34c466..00000000000
--- a/changelogs/unreleased/50281-js-pages-do-not-load-on-windows-8-ie-11.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix broken JavaScript in IE11
-merge_request: 21214
-author:
-type: fixed
diff --git a/changelogs/unreleased/50312-instance-statistics-convdev-index-intro-banner-is-not-dismissable.yml b/changelogs/unreleased/50312-instance-statistics-convdev-index-intro-banner-is-not-dismissable.yml
deleted file mode 100644
index 50a3b9c9aff..00000000000
--- a/changelogs/unreleased/50312-instance-statistics-convdev-index-intro-banner-is-not-dismissable.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix issue stopping Instance Statistics javascript to be executed
-merge_request: 21211
-author:
-type: fixed
diff --git a/changelogs/unreleased/50345-hashed-storage-feature-flag.yml b/changelogs/unreleased/50345-hashed-storage-feature-flag.yml
new file mode 100644
index 00000000000..4c5182b843b
--- /dev/null
+++ b/changelogs/unreleased/50345-hashed-storage-feature-flag.yml
@@ -0,0 +1,5 @@
+---
+title: Feature flag to disable Hashed Storage migration when renaming a repository
+merge_request: 21291
+author:
+type: added
diff --git a/changelogs/unreleased/50441-high-number-of-statement-timeouts-in-groupdestroyworker-due-to-sitestatistics.yml b/changelogs/unreleased/50441-high-number-of-statement-timeouts-in-groupdestroyworker-due-to-sitestatistics.yml
new file mode 100644
index 00000000000..3e360f8d6bb
--- /dev/null
+++ b/changelogs/unreleased/50441-high-number-of-statement-timeouts-in-groupdestroyworker-due-to-sitestatistics.yml
@@ -0,0 +1,5 @@
+---
+title: Removing a group no longer triggers hooks for project deletion twice
+merge_request: 21366
+author:
+type: fixed
diff --git a/changelogs/unreleased/50524-artifacts-sm.yml b/changelogs/unreleased/50524-artifacts-sm.yml
new file mode 100644
index 00000000000..22bd097f911
--- /dev/null
+++ b/changelogs/unreleased/50524-artifacts-sm.yml
@@ -0,0 +1,5 @@
+---
+title: Shows download artifacts button for pipelines on small screens
+merge_request:
+author:
+type: changed
diff --git a/changelogs/unreleased/50584-fix-ide-commit-twice.yml b/changelogs/unreleased/50584-fix-ide-commit-twice.yml
new file mode 100644
index 00000000000..92b292cf4ab
--- /dev/null
+++ b/changelogs/unreleased/50584-fix-ide-commit-twice.yml
@@ -0,0 +1,5 @@
+---
+title: Fix Web IDE unable to commit to same file twice
+merge_request: 21372
+author:
+type: fixed
diff --git a/changelogs/unreleased/50801-error-getting-performance-bar-results-for-uuid.yml b/changelogs/unreleased/50801-error-getting-performance-bar-results-for-uuid.yml
new file mode 100644
index 00000000000..6e57a215367
--- /dev/null
+++ b/changelogs/unreleased/50801-error-getting-performance-bar-results-for-uuid.yml
@@ -0,0 +1,5 @@
+---
+title: Don't show flash messages for performance bar errors
+merge_request: 21411
+author:
+type: other
diff --git a/changelogs/unreleased/6028-show-generic-percent-stacked-progress-bar.yml b/changelogs/unreleased/6028-show-generic-percent-stacked-progress-bar.yml
new file mode 100644
index 00000000000..94098dd0144
--- /dev/null
+++ b/changelogs/unreleased/6028-show-generic-percent-stacked-progress-bar.yml
@@ -0,0 +1,6 @@
+---
+title: Show '< 1%' when percent value evaluated is less than 1 on Stacked Progress
+ Bar
+merge_request: 21306
+author:
+type: fixed
diff --git a/changelogs/unreleased/6860-FE-instance-level-project-templates.yml b/changelogs/unreleased/6860-FE-instance-level-project-templates.yml
deleted file mode 100644
index 74e0daee71b..00000000000
--- a/changelogs/unreleased/6860-FE-instance-level-project-templates.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Update design of project templates
-merge_request: 21012
-author:
-type: changed
diff --git a/changelogs/unreleased/accept-rf3-2822-compliant-addresses.yml b/changelogs/unreleased/accept-rf3-2822-compliant-addresses.yml
deleted file mode 100644
index 97d017613ba..00000000000
--- a/changelogs/unreleased/accept-rf3-2822-compliant-addresses.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Emails on push recipients now accepts formats like John Doe <johndoe@example.com>
-merge_request:
-author: George Thomas
-type: added
diff --git a/changelogs/unreleased/add-dst-support-to-pipeline-schedule.yml b/changelogs/unreleased/add-dst-support-to-pipeline-schedule.yml
deleted file mode 100644
index 08376014ad7..00000000000
--- a/changelogs/unreleased/add-dst-support-to-pipeline-schedule.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Add support for daylight savings time to pipleline schedules
-merge_request: 20145
-author:
-type: fixed
diff --git a/changelogs/unreleased/add-homepage-link-to-status-pages.yml b/changelogs/unreleased/add-homepage-link-to-status-pages.yml
deleted file mode 100644
index 0e7375f2061..00000000000
--- a/changelogs/unreleased/add-homepage-link-to-status-pages.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Add link to homepage on static http status pages (404, 500, etc)
-merge_request: 20898
-author: Jason Funk
-type: added
diff --git a/changelogs/unreleased/add-merge-request-header-branch-details-right-margin.yml b/changelogs/unreleased/add-merge-request-header-branch-details-right-margin.yml
deleted file mode 100644
index 4f9a551d13e..00000000000
--- a/changelogs/unreleased/add-merge-request-header-branch-details-right-margin.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Add merge request header branch actions left margin
-merge_request: 20643
-author: George Tsiolis
-type: changed
diff --git a/changelogs/unreleased/add-total-time-flat-printer-for-profiling.yml b/changelogs/unreleased/add-total-time-flat-printer-for-profiling.yml
deleted file mode 100644
index 37a4e31896e..00000000000
--- a/changelogs/unreleased/add-total-time-flat-printer-for-profiling.yml
+++ /dev/null
@@ -1,6 +0,0 @@
----
-title: Add a Gitlab::Profiler.print_by_total_time convenience method for profiling
- from a Rails console
-merge_request:
-author:
-type: other
diff --git a/changelogs/unreleased/api-empty-commit-message.yml b/changelogs/unreleased/api-empty-commit-message.yml
new file mode 100644
index 00000000000..34ddc020644
--- /dev/null
+++ b/changelogs/unreleased/api-empty-commit-message.yml
@@ -0,0 +1,5 @@
+---
+title: 'API: Catch empty commit messages'
+merge_request: 21322
+author: Robert Schilling
+type: fixed
diff --git a/changelogs/unreleased/api-empty-project-snippets.yml b/changelogs/unreleased/api-empty-project-snippets.yml
new file mode 100644
index 00000000000..7b8c7c9e48d
--- /dev/null
+++ b/changelogs/unreleased/api-empty-project-snippets.yml
@@ -0,0 +1,5 @@
+---
+title: 'API: Catch empty code content for project snippets'
+merge_request: 21325
+author: Robert Schilling
+type: fixed
diff --git a/changelogs/unreleased/api-minimal-access-level.yml b/changelogs/unreleased/api-minimal-access-level.yml
deleted file mode 100644
index 43cab246d69..00000000000
--- a/changelogs/unreleased/api-minimal-access-level.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Add filter for minimal access level in groups and projects API
-merge_request: 20478
-author: Marko, Peter
-type: added
diff --git a/changelogs/unreleased/api-protected-tags.yml b/changelogs/unreleased/api-protected-tags.yml
new file mode 100644
index 00000000000..6e7ecf24b6e
--- /dev/null
+++ b/changelogs/unreleased/api-protected-tags.yml
@@ -0,0 +1,5 @@
+---
+title: 'API: Protected tags'
+merge_request: 14986
+author: Robert Schilling
+type: added
diff --git a/changelogs/unreleased/api-shared_group_expires-at.yml b/changelogs/unreleased/api-shared_group_expires-at.yml
new file mode 100644
index 00000000000..3d569de65fa
--- /dev/null
+++ b/changelogs/unreleased/api-shared_group_expires-at.yml
@@ -0,0 +1,5 @@
+---
+title: 'API: Add expiration date for shared projects to the project entity'
+merge_request: 21104
+author: Robert Schilling
+type: added
diff --git a/changelogs/unreleased/arguments-keyword-sast.yml b/changelogs/unreleased/arguments-keyword-sast.yml
new file mode 100644
index 00000000000..2ecbc5e8174
--- /dev/null
+++ b/changelogs/unreleased/arguments-keyword-sast.yml
@@ -0,0 +1,5 @@
+---
+title: Don't use arguments keyword in gettext script
+merge_request: 21296
+author: gfyoung
+type: fixed
diff --git a/changelogs/unreleased/artifact-format-v2-with-parser.yml b/changelogs/unreleased/artifact-format-v2-with-parser.yml
deleted file mode 100644
index e1a779cf6dd..00000000000
--- a/changelogs/unreleased/artifact-format-v2-with-parser.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: JUnit XML Test Summary In MR widget
-merge_request: 20576
-author:
-type: added
diff --git a/changelogs/unreleased/artifact-format-v2.yml b/changelogs/unreleased/artifact-format-v2.yml
deleted file mode 100644
index e264e0a9fa1..00000000000
--- a/changelogs/unreleased/artifact-format-v2.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Extend gitlab-ci.yml to request junit.xml test reports
-merge_request: 20390
-author:
-type: added
diff --git a/changelogs/unreleased/blackst0ne-replace-sidekiq-inline-with-perform-enqueued-jobs.yml b/changelogs/unreleased/blackst0ne-replace-sidekiq-inline-with-perform-enqueued-jobs.yml
deleted file mode 100644
index 69e6b7d815a..00000000000
--- a/changelogs/unreleased/blackst0ne-replace-sidekiq-inline-with-perform-enqueued-jobs.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Replace 'Sidekiq::Testing.inline!' with 'perform_enqueued_jobs'
-merge_request: 20768
-author: "@blackst0ne"
-type: other
diff --git a/changelogs/unreleased/bvl-add-galician.yml b/changelogs/unreleased/bvl-add-galician.yml
new file mode 100644
index 00000000000..e7035901ace
--- /dev/null
+++ b/changelogs/unreleased/bvl-add-galician.yml
@@ -0,0 +1,5 @@
+---
+title: Add Galician as an available language.
+merge_request: 21202
+author:
+type: added
diff --git a/changelogs/unreleased/bvl-graphql-wip-mutation.yml b/changelogs/unreleased/bvl-graphql-wip-mutation.yml
deleted file mode 100644
index 00aa1c48677..00000000000
--- a/changelogs/unreleased/bvl-graphql-wip-mutation.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Add the first mutations for merge requests to GraphQL
-merge_request: 20443
-author:
-type: added
diff --git a/changelogs/unreleased/bvl-user-status-message-35463.yml b/changelogs/unreleased/bvl-user-status-message-35463.yml
deleted file mode 100644
index c844e7ea0e4..00000000000
--- a/changelogs/unreleased/bvl-user-status-message-35463.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Users can set a status message and emoji
-merge_request: 20614
-author: niedermyer & davamr
-type: added
diff --git a/changelogs/unreleased/ccr-43283_allow_author_upvote.yml b/changelogs/unreleased/ccr-43283_allow_author_upvote.yml
new file mode 100644
index 00000000000..12ef6e3f790
--- /dev/null
+++ b/changelogs/unreleased/ccr-43283_allow_author_upvote.yml
@@ -0,0 +1,5 @@
+---
+title: Allow author to vote on their own issue and MRs
+merge_request: 21203
+author:
+type: changed
diff --git a/changelogs/unreleased/ccr-48800-ping_for_boards.yml b/changelogs/unreleased/ccr-48800-ping_for_boards.yml
new file mode 100644
index 00000000000..c08578cddba
--- /dev/null
+++ b/changelogs/unreleased/ccr-48800-ping_for_boards.yml
@@ -0,0 +1,6 @@
+---
+title: Adds count for different board list types (label lists, assignee lists, and
+ milestone lists) to usage statistics.
+merge_request: 21208
+author:
+type: changed
diff --git a/changelogs/unreleased/ce-5666-backport.yml b/changelogs/unreleased/ce-5666-backport.yml
deleted file mode 100644
index 344f1a1983f..00000000000
--- a/changelogs/unreleased/ce-5666-backport.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: CE port of "List groups with developer maintainer access on project creation"
-merge_request: 21051
-author:
-type: other
diff --git a/changelogs/unreleased/ce-6064-geo-sql-query-for-counting-projects-with-wikis-is-very-slow.yml b/changelogs/unreleased/ce-6064-geo-sql-query-for-counting-projects-with-wikis-is-very-slow.yml
deleted file mode 100644
index b76437a8773..00000000000
--- a/changelogs/unreleased/ce-6064-geo-sql-query-for-counting-projects-with-wikis-is-very-slow.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Tracking the number of repositories and wikis with a cached counter for site-wide statistics
-merge_request: 20413
-author:
-type: performance
diff --git a/changelogs/unreleased/close-revert-and-cherry-pick-modal-on-escape-keypress.yml b/changelogs/unreleased/close-revert-and-cherry-pick-modal-on-escape-keypress.yml
deleted file mode 100644
index 49648cdfcfc..00000000000
--- a/changelogs/unreleased/close-revert-and-cherry-pick-modal-on-escape-keypress.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Close revert and cherry pick modal on escape keypress
-merge_request: 20341
-author: George Tsiolis
-type: changed
diff --git a/changelogs/unreleased/cr-add-group-milestone-to-dashboard.yml b/changelogs/unreleased/cr-add-group-milestone-to-dashboard.yml
deleted file mode 100644
index b87a1e5faf7..00000000000
--- a/changelogs/unreleased/cr-add-group-milestone-to-dashboard.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Adds the ability to view group milestones on the dashboard milestone page.
-merge_request: 20618
-author:
-type: fixed
diff --git a/changelogs/unreleased/cr-add-path-of-group-milestone.yml b/changelogs/unreleased/cr-add-path-of-group-milestone.yml
deleted file mode 100644
index 5ce240110ef..00000000000
--- a/changelogs/unreleased/cr-add-path-of-group-milestone.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Adds the project and group name to the return type for project and group milestones.
-merge_request: 20890
-author:
-type: changed
diff --git a/changelogs/unreleased/custom_wiki_sidebar.yml b/changelogs/unreleased/custom_wiki_sidebar.yml
deleted file mode 100644
index 988fccc929c..00000000000
--- a/changelogs/unreleased/custom_wiki_sidebar.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: "Custom Wiki Sidebar Support Issue 14995"
-merge_request:
-author: Josh Sooter
-type: added
diff --git a/changelogs/unreleased/dz-fix-sql-error-admin-users-2fa.yml b/changelogs/unreleased/dz-fix-sql-error-admin-users-2fa.yml
new file mode 100644
index 00000000000..67926f3738a
--- /dev/null
+++ b/changelogs/unreleased/dz-fix-sql-error-admin-users-2fa.yml
@@ -0,0 +1,5 @@
+---
+title: Fix SQL error when sorting 2FA-enabled users by name in admin area
+merge_request: 21324
+author:
+type: fixed
diff --git a/changelogs/unreleased/dz-labels-search.yml b/changelogs/unreleased/dz-labels-search.yml
deleted file mode 100644
index 49c1b6c1a86..00000000000
--- a/changelogs/unreleased/dz-labels-search.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Search for labels by title or description on project labels page
-merge_request: 20749
-author:
-type: added
diff --git a/changelogs/unreleased/dz-manifest-import.yml b/changelogs/unreleased/dz-manifest-import.yml
deleted file mode 100644
index b0d29b0869f..00000000000
--- a/changelogs/unreleased/dz-manifest-import.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Add ability to import multiple repositories by uploading a manifest file
-merge_request: 20304
-author:
-type: added
diff --git a/changelogs/unreleased/expose-users-id-in-admin-users-show-page.yml b/changelogs/unreleased/expose-users-id-in-admin-users-show-page.yml
new file mode 100644
index 00000000000..0b8ae527214
--- /dev/null
+++ b/changelogs/unreleased/expose-users-id-in-admin-users-show-page.yml
@@ -0,0 +1,5 @@
+---
+title: Expose user's id in /admin/users/ show page
+merge_request:
+author: Eva Kadlecova
+type: changed
diff --git a/changelogs/unreleased/feature-gb-email-delivery-metrics.yml b/changelogs/unreleased/feature-gb-email-delivery-metrics.yml
deleted file mode 100644
index 9d0d08a471d..00000000000
--- a/changelogs/unreleased/feature-gb-email-delivery-metrics.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Add emails delivery Prometheus metrics
-merge_request: 20638
-author:
-type: added
diff --git a/changelogs/unreleased/feature-gb-login-activity-metrics.yml b/changelogs/unreleased/feature-gb-login-activity-metrics.yml
deleted file mode 100644
index 5d687b984eb..00000000000
--- a/changelogs/unreleased/feature-gb-login-activity-metrics.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Add more comprehensive metrics tracking authentication activity
-merge_request: 20668
-author:
-type: added
diff --git a/changelogs/unreleased/features-show-project-id-on-home-panel.yml b/changelogs/unreleased/features-show-project-id-on-home-panel.yml
deleted file mode 100644
index f592be07a52..00000000000
--- a/changelogs/unreleased/features-show-project-id-on-home-panel.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Show Project ID on project home panel
-merge_request: 20305
-author: Tuğçe Nur Taş
-type: added
diff --git a/changelogs/unreleased/fix-api-group-createdat.yml b/changelogs/unreleased/fix-api-group-createdat.yml
new file mode 100644
index 00000000000..e628facf1bf
--- /dev/null
+++ b/changelogs/unreleased/fix-api-group-createdat.yml
@@ -0,0 +1,5 @@
+---
+title: Allow date parameters on Issues, Notes, and Discussions API for group owners
+merge_request: 21342
+author: Florent Dubois
+type: fixed
diff --git a/changelogs/unreleased/fix-diff-note.yml b/changelogs/unreleased/fix-diff-note.yml
deleted file mode 100644
index 6f10f86b9bc..00000000000
--- a/changelogs/unreleased/fix-diff-note.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix serialization of LegacyDiffNote
-merge_request:
-author:
-type: fixed
diff --git a/changelogs/unreleased/fix-email-confirmation-addtional-email.yml b/changelogs/unreleased/fix-email-confirmation-addtional-email.yml
deleted file mode 100644
index 56a2efa4d60..00000000000
--- a/changelogs/unreleased/fix-email-confirmation-addtional-email.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix email confirmation bug when user adds additional email to account
-merge_request: 20084
-author: muhammadn
-type: fixed
diff --git a/changelogs/unreleased/fix-gb-add-missing-before-sha-predefined-variable.yml b/changelogs/unreleased/fix-gb-add-missing-before-sha-predefined-variable.yml
deleted file mode 100644
index 7e9e8c33a71..00000000000
--- a/changelogs/unreleased/fix-gb-add-missing-before-sha-predefined-variable.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Add missing predefined variable and fix docs
-merge_request:
-author:
-type: fixed
diff --git a/changelogs/unreleased/fix-gb-fix-deserializing-ci-yaml-variables.yml b/changelogs/unreleased/fix-gb-fix-deserializing-ci-yaml-variables.yml
deleted file mode 100644
index 80b069c9251..00000000000
--- a/changelogs/unreleased/fix-gb-fix-deserializing-ci-yaml-variables.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix accessing imported pipeline builds
-merge_request: 20713
-author:
-type: fixed
diff --git a/changelogs/unreleased/fix-gb-fix-project-settings-build-time-validation.yml b/changelogs/unreleased/fix-gb-fix-project-settings-build-time-validation.yml
deleted file mode 100644
index adf582e34a2..00000000000
--- a/changelogs/unreleased/fix-gb-fix-project-settings-build-time-validation.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Limit maximum project build timeout setting to 1 month
-merge_request: 20591
-author:
-type: fixed
diff --git a/changelogs/unreleased/fix-mr-title-fallback-logic.yml b/changelogs/unreleased/fix-mr-title-fallback-logic.yml
new file mode 100644
index 00000000000..5056c38573b
--- /dev/null
+++ b/changelogs/unreleased/fix-mr-title-fallback-logic.yml
@@ -0,0 +1,5 @@
+---
+title: Fix fallback logic for automatic MR title assignment
+merge_request: 20930
+author: Franz Liedke
+type: fixed
diff --git a/changelogs/unreleased/fix-multiple-scopes.yml b/changelogs/unreleased/fix-multiple-scopes.yml
deleted file mode 100644
index 24e5172d9a1..00000000000
--- a/changelogs/unreleased/fix-multiple-scopes.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Support multiple scopes when authing container registry scopes
-merge_request: 20617
-author:
-type: fixed
diff --git a/changelogs/unreleased/fix-project-api-archived.yml b/changelogs/unreleased/fix-project-api-archived.yml
deleted file mode 100644
index 9d119fd3429..00000000000
--- a/changelogs/unreleased/fix-project-api-archived.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix archived parameter for projects API
-merge_request: 20566
-author: Peter Marko
-type: fixed
diff --git a/changelogs/unreleased/fix-prometheus-updated-status.yml b/changelogs/unreleased/fix-prometheus-updated-status.yml
deleted file mode 100644
index 7261c3429c8..00000000000
--- a/changelogs/unreleased/fix-prometheus-updated-status.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix UI error whereby prometheus application status is updated
-merge_request: 21029
-author:
-type: fixed
diff --git a/changelogs/unreleased/fix-search-bar.yml b/changelogs/unreleased/fix-search-bar.yml
deleted file mode 100644
index d4c0c1efddf..00000000000
--- a/changelogs/unreleased/fix-search-bar.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix search bar text input alignment
-merge_request:
-author:
-type: fixed
diff --git a/changelogs/unreleased/fix-storage-size-for-artifacts-change.yml b/changelogs/unreleased/fix-storage-size-for-artifacts-change.yml
deleted file mode 100644
index 6a3e1420726..00000000000
--- a/changelogs/unreleased/fix-storage-size-for-artifacts-change.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Update total storage size when changing size of artifacts
-merge_request: 20697
-author: Peter Marko
-type: fixed
diff --git a/changelogs/unreleased/fj-37736-improve-performance-post-receive-create-gpg-siganture-worker.yml b/changelogs/unreleased/fj-37736-improve-performance-post-receive-create-gpg-siganture-worker.yml
deleted file mode 100644
index 0b35c5c6786..00000000000
--- a/changelogs/unreleased/fj-37736-improve-performance-post-receive-create-gpg-siganture-worker.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Performing Commit GPG signature calculation in bulk
-merge_request: 20870
-author:
-type: performance
diff --git a/changelogs/unreleased/fj-48123-fix-gitlab-import.yml b/changelogs/unreleased/fj-48123-fix-gitlab-import.yml
deleted file mode 100644
index 896db2cdcb8..00000000000
--- a/changelogs/unreleased/fj-48123-fix-gitlab-import.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix GitLab project imports not loading due to API timeouts
-merge_request: 20599
-author:
-type: fixed
diff --git a/changelogs/unreleased/fj-49014-wiki-search-error.yml b/changelogs/unreleased/fj-49014-wiki-search-error.yml
deleted file mode 100644
index a76805cb7f9..00000000000
--- a/changelogs/unreleased/fj-49014-wiki-search-error.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fixed bug with invalid repository reference using the wiki search
-merge_request: 20722
-author:
-type: fixed
diff --git a/changelogs/unreleased/fj-49512-fix-gitlab-git-pages-encoding.yml b/changelogs/unreleased/fj-49512-fix-gitlab-git-pages-encoding.yml
deleted file mode 100644
index 3af90fff3f6..00000000000
--- a/changelogs/unreleased/fj-49512-fix-gitlab-git-pages-encoding.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Prevent editing and updating wiki pages with non UTF-8 encoding via web interface
-merge_request: 20906
-author:
-type: fixed
diff --git a/changelogs/unreleased/fj-49802-bug-api-set-http-headers.yml b/changelogs/unreleased/fj-49802-bug-api-set-http-headers.yml
deleted file mode 100644
index ba61d378cda..00000000000
--- a/changelogs/unreleased/fj-49802-bug-api-set-http-headers.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix bug setting http headers in Files API
-merge_request: 20938
-author:
-type: fixed
diff --git a/changelogs/unreleased/floating-avarage-commit-numbers.yml b/changelogs/unreleased/floating-avarage-commit-numbers.yml
deleted file mode 100644
index 7f91ab16af4..00000000000
--- a/changelogs/unreleased/floating-avarage-commit-numbers.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Show one digit after dot in commit_per_day value in charts page.
-merge_request:
-author: msdundar
-type: changed
diff --git a/changelogs/unreleased/frozen-string-danger.yml b/changelogs/unreleased/frozen-string-danger.yml
deleted file mode 100644
index 9910139b8a9..00000000000
--- a/changelogs/unreleased/frozen-string-danger.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Add Dangerfile for frozen_string_literal
-merge_request: 20767
-author: gfyoung
-type: performance
diff --git a/changelogs/unreleased/frozen-string-enable-app-models-more.yml b/changelogs/unreleased/frozen-string-enable-app-models-more.yml
deleted file mode 100644
index c0466984134..00000000000
--- a/changelogs/unreleased/frozen-string-enable-app-models-more.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Enable frozen string for app/models/**/*.rb
-merge_request: 21001
-author: gfyoung
-type: performance
diff --git a/changelogs/unreleased/frozen-string-enable-app-models.yml b/changelogs/unreleased/frozen-string-enable-app-models.yml
deleted file mode 100644
index 4c149ea55ef..00000000000
--- a/changelogs/unreleased/frozen-string-enable-app-models.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Enable frozen string in app/models/*.rb
-merge_request: 20851
-author: gfyoung
-type: performance
diff --git a/changelogs/unreleased/frozen-string-enable-app-presenters-policies.yml b/changelogs/unreleased/frozen-string-enable-app-presenters-policies.yml
deleted file mode 100644
index 5c6b1b1a904..00000000000
--- a/changelogs/unreleased/frozen-string-enable-app-presenters-policies.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Enable frozen string in app/presenters and app/policies
-merge_request: 20819
-author: gfyoung
-type: performance
diff --git a/changelogs/unreleased/frozen-string-enable-app-serializers.yml b/changelogs/unreleased/frozen-string-enable-app-serializers.yml
deleted file mode 100644
index 40c7b695d39..00000000000
--- a/changelogs/unreleased/frozen-string-enable-app-serializers.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Enable frozen string in app/serializers/**/*.rb
-merge_request: 20726
-author: gfyoung
-type: performance
diff --git a/changelogs/unreleased/frozen-string-enable-app-services.yml b/changelogs/unreleased/frozen-string-enable-app-services.yml
deleted file mode 100644
index cfc1f356e3a..00000000000
--- a/changelogs/unreleased/frozen-string-enable-app-services.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Enable frozen string in apps/uploaders/*.rb
-merge_request: 20401
-author: gfyoung
-type: other
diff --git a/changelogs/unreleased/frozen-string-enable-apps-services-inner-even-more.yml b/changelogs/unreleased/frozen-string-enable-apps-services-inner-even-more.yml
deleted file mode 100644
index cee790a07ff..00000000000
--- a/changelogs/unreleased/frozen-string-enable-apps-services-inner-even-more.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Enable even more frozen string in app/services/**/*.rb
-merge_request: 20702
-author: gfyoung
-type: performance
diff --git a/changelogs/unreleased/frozen-string-enable-apps-services-inner-more.yml b/changelogs/unreleased/frozen-string-enable-apps-services-inner-more.yml
deleted file mode 100644
index ea962cf8edc..00000000000
--- a/changelogs/unreleased/frozen-string-enable-apps-services-inner-more.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Enable more frozen string in app/services/**/*.rb
-merge_request: 20677
-author: gfyoung
-type: performance
diff --git a/changelogs/unreleased/frozen-string-enable-apps-services-inner.yml b/changelogs/unreleased/frozen-string-enable-apps-services-inner.yml
deleted file mode 100644
index 16b8ec3908f..00000000000
--- a/changelogs/unreleased/frozen-string-enable-apps-services-inner.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Enable frozen string in app/services/**/*.rb
-merge_request: 20656
-author: gfyoung
-type: performance
diff --git a/changelogs/unreleased/frozen-string-vestigial.yml b/changelogs/unreleased/frozen-string-vestigial.yml
deleted file mode 100644
index 79e92a19a7a..00000000000
--- a/changelogs/unreleased/frozen-string-vestigial.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Enable frozen string in newly added files to previously processed directories
-merge_request: 20763
-author: gfyoung
-type: performance
diff --git a/changelogs/unreleased/full-list-of-vulnerabilities-5239.yml b/changelogs/unreleased/full-list-of-vulnerabilities-5239.yml
deleted file mode 100644
index b26eb82b6c9..00000000000
--- a/changelogs/unreleased/full-list-of-vulnerabilities-5239.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Removes "show all" on reports and adds an actionButtons slot
-merge_request: 20855
-author:
-type: changed
diff --git a/changelogs/unreleased/git-rerere-link-doc-update.yml b/changelogs/unreleased/git-rerere-link-doc-update.yml
deleted file mode 100644
index 06093e8ec13..00000000000
--- a/changelogs/unreleased/git-rerere-link-doc-update.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Update git rerere link in docs
-merge_request: 21060
-author: gfyoung
-type: other
diff --git a/changelogs/unreleased/hangouts_chat_integration.yml b/changelogs/unreleased/hangouts_chat_integration.yml
deleted file mode 100644
index bf3484a6d02..00000000000
--- a/changelogs/unreleased/hangouts_chat_integration.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Add Hangouts Chat integration
-merge_request: 20290
-author: Kukovskii Vladimir
-type: added
diff --git a/changelogs/unreleased/ide-codesandbox-poc.yml b/changelogs/unreleased/ide-codesandbox-poc.yml
deleted file mode 100644
index 7da1f4e6472..00000000000
--- a/changelogs/unreleased/ide-codesandbox-poc.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Added live preview for JavaScript projects in the Web IDE
-merge_request: 19764
-author:
-type: added
diff --git a/changelogs/unreleased/ide-delete-entries.yml b/changelogs/unreleased/ide-delete-entries.yml
deleted file mode 100644
index 8cbc0739406..00000000000
--- a/changelogs/unreleased/ide-delete-entries.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Enabled deletion of files in the Web IDE
-merge_request:
-author:
-type: added
diff --git a/changelogs/unreleased/ide-pipeline-icon-open.yml b/changelogs/unreleased/ide-pipeline-icon-open.yml
deleted file mode 100644
index 3a73ff2170f..00000000000
--- a/changelogs/unreleased/ide-pipeline-icon-open.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Clicking CI icon in Web IDE now opens up pipelines panel
-merge_request:
-author:
-type: added
diff --git a/changelogs/unreleased/ide-rename-files.yml b/changelogs/unreleased/ide-rename-files.yml
deleted file mode 100644
index c2db284e07c..00000000000
--- a/changelogs/unreleased/ide-rename-files.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Enable renaming files and folders in Web IDE
-merge_request: 20835
-author:
-type: added
diff --git a/changelogs/unreleased/ide-row-dropdown-design-update.yml b/changelogs/unreleased/ide-row-dropdown-design-update.yml
deleted file mode 100644
index e0fe64c944e..00000000000
--- a/changelogs/unreleased/ide-row-dropdown-design-update.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Updated design of new entry dropdown in Web IDE
-merge_request: 20526
-author:
-type: changed
diff --git a/changelogs/unreleased/ide-warn-staged-files.yml b/changelogs/unreleased/ide-warn-staged-files.yml
deleted file mode 100644
index ae3c4f392c0..00000000000
--- a/changelogs/unreleased/ide-warn-staged-files.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Warn user when reload IDE with staged changes
-merge_request: 20857
-author:
-type: added
diff --git a/changelogs/unreleased/improve-junit-support-be.yml b/changelogs/unreleased/improve-junit-support-be.yml
deleted file mode 100644
index db4d47caa7c..00000000000
--- a/changelogs/unreleased/improve-junit-support-be.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Improve JUnit test reports in merge request widgets
-merge_request: 49966
-author:
-type: fixed
diff --git a/changelogs/unreleased/improve-metadata-access-performance.yml b/changelogs/unreleased/improve-metadata-access-performance.yml
deleted file mode 100644
index b16fa99dd3b..00000000000
--- a/changelogs/unreleased/improve-metadata-access-performance.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Access metadata directly from Object Storage
-merge_request:
-author:
-type: performance
diff --git a/changelogs/unreleased/issue_36138.yml b/changelogs/unreleased/issue_36138.yml
new file mode 100644
index 00000000000..2fb2eea65f5
--- /dev/null
+++ b/changelogs/unreleased/issue_36138.yml
@@ -0,0 +1,5 @@
+---
+title: Allow to delete group milestones
+merge_request:
+author:
+type: added
diff --git a/changelogs/unreleased/issue_43602.yml b/changelogs/unreleased/issue_43602.yml
deleted file mode 100644
index 0482606db0a..00000000000
--- a/changelogs/unreleased/issue_43602.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Allow multiple JIRA transition ids
-merge_request: 20939
-author:
-type: changed
diff --git a/changelogs/unreleased/issue_44821.yml b/changelogs/unreleased/issue_44821.yml
deleted file mode 100644
index b1807e069af..00000000000
--- a/changelogs/unreleased/issue_44821.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Retrieve merge request closing issues from database cache
-merge_request: 20911
-author:
-type: fixed
diff --git a/changelogs/unreleased/issue_47709.yml b/changelogs/unreleased/issue_47709.yml
deleted file mode 100644
index c3ef55fd692..00000000000
--- a/changelogs/unreleased/issue_47709.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: 'Allow to toggle notifications for issues due soon'
-merge_request:
-author:
-type: fixed
diff --git a/changelogs/unreleased/jprovazn-fix-form-uploads.yml b/changelogs/unreleased/jprovazn-fix-form-uploads.yml
new file mode 100644
index 00000000000..8bcee335e93
--- /dev/null
+++ b/changelogs/unreleased/jprovazn-fix-form-uploads.yml
@@ -0,0 +1,5 @@
+---
+title: Accept upload files in public/uplaods/tmp when using accelerated uploads.
+merge_request:
+author:
+type: fixed
diff --git a/changelogs/unreleased/jprovazn-resource-events.yml b/changelogs/unreleased/jprovazn-resource-events.yml
deleted file mode 100644
index 05643150f16..00000000000
--- a/changelogs/unreleased/jprovazn-resource-events.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Add new model for tracking label events.
-merge_request:
-author:
-type: added
diff --git a/changelogs/unreleased/jr-archive-hook.yml b/changelogs/unreleased/jr-archive-hook.yml
deleted file mode 100644
index 56c13f1370e..00000000000
--- a/changelogs/unreleased/jr-archive-hook.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Trigger system hooks when project is archived/unarchived
-merge_request: 20995
-author:
-type: added
diff --git a/changelogs/unreleased/jupyter-image.yml b/changelogs/unreleased/jupyter-image.yml
deleted file mode 100644
index 8aeefd603d8..00000000000
--- a/changelogs/unreleased/jupyter-image.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Rubix, scikit-learn, tensorflow & other useful libraries pre-installed with JupyterHub
-merge_request: 20714
-author: Amit Rathi
-type: changed
diff --git a/changelogs/unreleased/kp-6927-epic-dates-from-milestone.yml b/changelogs/unreleased/kp-6927-epic-dates-from-milestone.yml
deleted file mode 100644
index c15d73a0c12..00000000000
--- a/changelogs/unreleased/kp-6927-epic-dates-from-milestone.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Add 'tabindex' attribute support on Icon component to show BS4 popover on trigger type 'focus'
-merge_request: 21066
-author:
-type: other
diff --git a/changelogs/unreleased/kp-stacked-progress-bar-decimal-places.yml b/changelogs/unreleased/kp-stacked-progress-bar-decimal-places.yml
deleted file mode 100644
index a2fca4c5b91..00000000000
--- a/changelogs/unreleased/kp-stacked-progress-bar-decimal-places.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Show decimal place up to single digit in Stacked Progress Bar
-merge_request: 20776
-author:
-type: changed
diff --git a/changelogs/unreleased/leipert-fix-pipelines-view.yml b/changelogs/unreleased/leipert-fix-pipelines-view.yml
deleted file mode 100644
index 7bcc2e84cd2..00000000000
--- a/changelogs/unreleased/leipert-fix-pipelines-view.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix rendering of pipeline failure view when directly navigationg to it
-merge_request: 21043
-author:
-type: fixed
diff --git a/changelogs/unreleased/mk-add-local-project-uploads-cleanup-task.yml b/changelogs/unreleased/mk-add-local-project-uploads-cleanup-task.yml
deleted file mode 100644
index 9d38b353a41..00000000000
--- a/changelogs/unreleased/mk-add-local-project-uploads-cleanup-task.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Add local project uploads cleanup task
-merge_request: 20863
-author:
-type: added
diff --git a/changelogs/unreleased/mk-fix-callback-canceling-in-namespace-move-dir.yml b/changelogs/unreleased/mk-fix-callback-canceling-in-namespace-move-dir.yml
deleted file mode 100644
index 8e71377d93f..00000000000
--- a/changelogs/unreleased/mk-fix-callback-canceling-in-namespace-move-dir.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix namespace move callback behavior, especially to fix Geo replication of namespace moves during certain exceptions.
-merge_request: 19297
-author:
-type: fixed
diff --git a/changelogs/unreleased/osw-fix-missing-and-duplicated-milestones-on-list.yml b/changelogs/unreleased/osw-fix-missing-and-duplicated-milestones-on-list.yml
deleted file mode 100644
index 62416b7f87e..00000000000
--- a/changelogs/unreleased/osw-fix-missing-and-duplicated-milestones-on-list.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix missing and duplicates on project milestone listing page
-merge_request: 21058
-author:
-type: fixed
diff --git a/changelogs/unreleased/osw-fix-n-plus-1-for-mrs-without-merge-info.yml b/changelogs/unreleased/osw-fix-n-plus-1-for-mrs-without-merge-info.yml
deleted file mode 100644
index dc8148fa1a5..00000000000
--- a/changelogs/unreleased/osw-fix-n-plus-1-for-mrs-without-merge-info.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Avoid N+1 on MRs page when metrics merging date cannot be found
-merge_request: 21053
-author:
-type: performance
diff --git a/changelogs/unreleased/pl-json-gon.yml b/changelogs/unreleased/pl-json-gon.yml
deleted file mode 100644
index c0f93006c07..00000000000
--- a/changelogs/unreleased/pl-json-gon.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Don't set gon variables in JSON requests
-merge_request: 21016
-author: Peter Leitzen
-type: performance
diff --git a/changelogs/unreleased/process-commits-as-normal-in-forks-with-missing-upstream.yml b/changelogs/unreleased/process-commits-as-normal-in-forks-with-missing-upstream.yml
deleted file mode 100644
index 6994a238074..00000000000
--- a/changelogs/unreleased/process-commits-as-normal-in-forks-with-missing-upstream.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Process commits as normal in forks when the upstream project is deleted
-merge_request: 20534
-author:
-type: fixed
diff --git a/changelogs/unreleased/project-visibility-tooltip.yml b/changelogs/unreleased/project-visibility-tooltip.yml
deleted file mode 100644
index 806c93e493a..00000000000
--- a/changelogs/unreleased/project-visibility-tooltip.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix project visibility tooltip
-merge_request: 20535
-author: Jamie Schembri
-type: fixed
diff --git a/changelogs/unreleased/rails5-fix-48977.yml b/changelogs/unreleased/rails5-fix-48977.yml
deleted file mode 100644
index bfd86f20e24..00000000000
--- a/changelogs/unreleased/rails5-fix-48977.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Rails5 fix mysql milliseconds problem in specs
-merge_request: 20464
-author: Jasper Maes
-type: fixed
diff --git a/changelogs/unreleased/rails5-fix-flaky-spec-user-uses-shortcuts.yml b/changelogs/unreleased/rails5-fix-flaky-spec-user-uses-shortcuts.yml
deleted file mode 100644
index 5f2504c604d..00000000000
--- a/changelogs/unreleased/rails5-fix-flaky-spec-user-uses-shortcuts.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: 'Rails5: fix flaky spec'
-merge_request: 20953
-author: Jasper Maes
-type: fixed
diff --git a/changelogs/unreleased/rails5-fix-import-merge-request-creator.yml b/changelogs/unreleased/rails5-fix-import-merge-request-creator.yml
new file mode 100644
index 00000000000..661bd748333
--- /dev/null
+++ b/changelogs/unreleased/rails5-fix-import-merge-request-creator.yml
@@ -0,0 +1,5 @@
+---
+title: 'Rails5: fix can''t quote ActiveSupport::HashWithIndifferentAccess'
+merge_request: 21397
+author: Jasper Maes
+type: other
diff --git a/changelogs/unreleased/rails5-fix-revert-modal-spec.yml b/changelogs/unreleased/rails5-fix-revert-modal-spec.yml
deleted file mode 100644
index 0637e503ca9..00000000000
--- a/changelogs/unreleased/rails5-fix-revert-modal-spec.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Rails5 fix user sees revert modal spec
-merge_request: 20706
-author: Jasper Maes
-type: fixed
diff --git a/changelogs/unreleased/rails5-gpg-permit-concurrent.yml b/changelogs/unreleased/rails5-gpg-permit-concurrent.yml
deleted file mode 100644
index cf1b0023f86..00000000000
--- a/changelogs/unreleased/rails5-gpg-permit-concurrent.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Permit concurrent loads in gpg keychain mutex
-merge_request: 20894
-author: Jasper Maes
-type: fixed
diff --git a/changelogs/unreleased/rails5-mysql-fix-pr-importer-spec.yml b/changelogs/unreleased/rails5-mysql-fix-pr-importer-spec.yml
deleted file mode 100644
index afd9865ee45..00000000000
--- a/changelogs/unreleased/rails5-mysql-fix-pr-importer-spec.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Rails5 mysql fix milliseconds problem in pull request importer spec
-merge_request: 20475
-author: Jasper Maes
-type: fixed
diff --git a/changelogs/unreleased/rails5-mysql-rename-column.yml b/changelogs/unreleased/rails5-mysql-rename-column.yml
deleted file mode 100644
index cbae9250744..00000000000
--- a/changelogs/unreleased/rails5-mysql-rename-column.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Rails5 MySQL fix rename_column as part of cleanup_concurrent_column_type_change
-merge_request: 20514
-author: Jasper Maes
-type: fixed
diff --git a/changelogs/unreleased/rails5-silence-stream.yml b/changelogs/unreleased/rails5-silence-stream.yml
new file mode 100644
index 00000000000..df4fd14a077
--- /dev/null
+++ b/changelogs/unreleased/rails5-silence-stream.yml
@@ -0,0 +1,5 @@
+---
+title: 'Rails 5: replace removed silence_stream'
+merge_request: 21387
+author: Jasper Maes
+type: other
diff --git a/changelogs/unreleased/rails5-update-gemfile-lock-2.yml b/changelogs/unreleased/rails5-update-gemfile-lock-2.yml
deleted file mode 100644
index 1f3e9bd2238..00000000000
--- a/changelogs/unreleased/rails5-update-gemfile-lock-2.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Rails5 update Gemfile.rails5.lock
-merge_request: 20858
-author: Jasper Maes
-type: fixed
diff --git a/changelogs/unreleased/rails5-update-gemfile-lock.yml b/changelogs/unreleased/rails5-update-gemfile-lock.yml
index 58931587fff..3891b16e2b8 100644
--- a/changelogs/unreleased/rails5-update-gemfile-lock.yml
+++ b/changelogs/unreleased/rails5-update-gemfile-lock.yml
@@ -1,5 +1,5 @@
---
-title: Update Gemfile.rails5.lock with latest Gemfile.lock changes
-merge_request: 20466
+title: Rails5 update Gemfile.rails5.lock
+merge_request: 21388
author: Jasper Maes
-type: fixed
+type: other
diff --git a/changelogs/unreleased/rails5-update-rouge.yml b/changelogs/unreleased/rails5-update-rouge.yml
deleted file mode 100644
index 1173b3b7e9a..00000000000
--- a/changelogs/unreleased/rails5-update-rouge.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: 'Rails5: update Rails5 lock for forgotten gem rouge'
-merge_request: 21010
-author: Jasper Maes
-type: fixed
diff --git a/changelogs/unreleased/ravlen-deploy-tokens-display-update.yml b/changelogs/unreleased/ravlen-deploy-tokens-display-update.yml
deleted file mode 100644
index fd5a6521882..00000000000
--- a/changelogs/unreleased/ravlen-deploy-tokens-display-update.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: "Cleans up display of Deploy Tokens to match Personal Access Tokens"
-merge_request: 20578
-author: Marcel Amirault
-type: added \ No newline at end of file
diff --git a/changelogs/unreleased/regen-2fa-codes.yml b/changelogs/unreleased/regen-2fa-codes.yml
deleted file mode 100644
index 596f759df0f..00000000000
--- a/changelogs/unreleased/regen-2fa-codes.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Added button to regenerate 2FA codes
-merge_request:
-author: Luke Picciau
-type: added
diff --git a/changelogs/unreleased/replace-all-snake-case-in-scss-variables.yml b/changelogs/unreleased/replace-all-snake-case-in-scss-variables.yml
deleted file mode 100644
index 8d5ecdfa57e..00000000000
--- a/changelogs/unreleased/replace-all-snake-case-in-scss-variables.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Replace snake case in SCSS variables
-merge_request: 20799
-author: George Tsiolis
-type: other
diff --git a/changelogs/unreleased/replace-snake-case-css-classes.yml b/changelogs/unreleased/replace-snake-case-css-classes.yml
deleted file mode 100644
index 28ec5ee097f..00000000000
--- a/changelogs/unreleased/replace-snake-case-css-classes.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Replace author_link snake case in stylesheets, specs, and helpers
-merge_request: 20797
-author: George Tsiolis
-type: other
diff --git a/changelogs/unreleased/rouge-3-2-0.yml b/changelogs/unreleased/rouge-3-2-0.yml
deleted file mode 100644
index 15ac4cc1e76..00000000000
--- a/changelogs/unreleased/rouge-3-2-0.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Update to Rouge 3.2.0, including Terraform and Crystal lexer and bug fixes
-merge_request: 20991
-author:
-type: changed
diff --git a/changelogs/unreleased/rouge_3-2-1.yml b/changelogs/unreleased/rouge_3-2-1.yml
deleted file mode 100644
index b281a4f0e95..00000000000
--- a/changelogs/unreleased/rouge_3-2-1.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Update to Rouge 3.2.1, which includes a critical fix to the Perl Lexer
-merge_request: 21263
-author:
-type: changed
diff --git a/changelogs/unreleased/runner-features.yml b/changelogs/unreleased/runner-features.yml
deleted file mode 100644
index c5e0fff5a18..00000000000
--- a/changelogs/unreleased/runner-features.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Verify runner feature set
-merge_request: 20664
-author:
-type: added
diff --git a/changelogs/unreleased/runners-max-timeout-param.yml b/changelogs/unreleased/runners-max-timeout-param.yml
deleted file mode 100644
index 875f805d849..00000000000
--- a/changelogs/unreleased/runners-max-timeout-param.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Add missing maximum_timeout parameter
-merge_request: 20355
-author: gfyoung
-type: fixed
diff --git a/changelogs/unreleased/satishperala-gitlab-ce-20720_webhooks_full_image_url.yml b/changelogs/unreleased/satishperala-gitlab-ce-20720_webhooks_full_image_url.yml
deleted file mode 100644
index 7bfe1b5778f..00000000000
--- a/changelogs/unreleased/satishperala-gitlab-ce-20720_webhooks_full_image_url.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Include full image URL in webhooks for uploaded images
-merge_request: 18109
-author: Satish Perala
-type: changed
diff --git a/changelogs/unreleased/security-49085-persistent-xss-rendering.yml b/changelogs/unreleased/security-49085-persistent-xss-rendering.yml
new file mode 100644
index 00000000000..dc15d356c1c
--- /dev/null
+++ b/changelogs/unreleased/security-49085-persistent-xss-rendering.yml
@@ -0,0 +1,5 @@
+---
+title: Fixed persistent XSS rendering/escaping of diff location lines
+merge_request:
+author:
+type: security
diff --git a/changelogs/unreleased/security-fj-missing-csrf-system-hooks.yml b/changelogs/unreleased/security-fj-missing-csrf-system-hooks.yml
deleted file mode 100644
index fabf48acbbc..00000000000
--- a/changelogs/unreleased/security-fj-missing-csrf-system-hooks.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Adding CSRF protection to Hooks test action
-merge_request:
-author:
-type: security
diff --git a/changelogs/unreleased/security-ide-branch-name-xss.yml b/changelogs/unreleased/security-ide-branch-name-xss.yml
deleted file mode 100644
index 51742ffa4e9..00000000000
--- a/changelogs/unreleased/security-ide-branch-name-xss.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fixed XSS in branch name in Web IDE
-merge_request:
-author:
-type: security
diff --git a/changelogs/unreleased/sh-block-link-local-master.yml b/changelogs/unreleased/sh-block-link-local-master.yml
new file mode 100644
index 00000000000..0a6017479af
--- /dev/null
+++ b/changelogs/unreleased/sh-block-link-local-master.yml
@@ -0,0 +1,5 @@
+---
+title: Block link-local addresses in URLBlocker
+merge_request:
+author:
+type: security
diff --git a/changelogs/unreleased/sh-bump-fog-google.yml b/changelogs/unreleased/sh-bump-fog-google.yml
new file mode 100644
index 00000000000..b5fa55e53a5
--- /dev/null
+++ b/changelogs/unreleased/sh-bump-fog-google.yml
@@ -0,0 +1,5 @@
+---
+title: Bump fog-google to 1.7.0 and google-api-client to 0.23.0
+merge_request: 21295
+author:
+type: fixed
diff --git a/changelogs/unreleased/sh-bump-gitaly-0-117.yml b/changelogs/unreleased/sh-bump-gitaly-0-117.yml
deleted file mode 100644
index 90ca86d076b..00000000000
--- a/changelogs/unreleased/sh-bump-gitaly-0-117.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Bump Gitaly to 0.117.0
-merge_request: 21055
-author:
-type: performance
diff --git a/changelogs/unreleased/sh-bump-gitaly-for-11-2.yml b/changelogs/unreleased/sh-bump-gitaly-for-11-2.yml
deleted file mode 100644
index 0e748c3a346..00000000000
--- a/changelogs/unreleased/sh-bump-gitaly-for-11-2.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Bump Gitaly to 0.117.1 for Rouge update
-merge_request: 21277
-author:
-type: security
diff --git a/changelogs/unreleased/sh-bump-haml-5-0-4.yml b/changelogs/unreleased/sh-bump-haml-5-0-4.yml
deleted file mode 100644
index 269b1e55417..00000000000
--- a/changelogs/unreleased/sh-bump-haml-5-0-4.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Bump haml gem to 5.0.4
-merge_request: 20847
-author:
-type: performance
diff --git a/changelogs/unreleased/sh-bump-rugged-0-27-4.yml b/changelogs/unreleased/sh-bump-rugged-0-27-4.yml
deleted file mode 100644
index 50373cb81ad..00000000000
--- a/changelogs/unreleased/sh-bump-rugged-0-27-4.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Bump rugged to 0.27.4 for security fixes
-merge_request:
-author:
-type: security
diff --git a/changelogs/unreleased/sh-bump-sanitize-4-6-6.yml b/changelogs/unreleased/sh-bump-sanitize-4-6-6.yml
deleted file mode 100644
index b9444440cb9..00000000000
--- a/changelogs/unreleased/sh-bump-sanitize-4-6-6.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Bump nokogiri to 1.8.4 and sanitize to 4.6.6 for performance
-merge_request: 20795
-author:
-type: performance
diff --git a/changelogs/unreleased/sh-enable-frozen-literals-banzi-filters.yml b/changelogs/unreleased/sh-enable-frozen-literals-banzi-filters.yml
deleted file mode 100644
index 897d673e97d..00000000000
--- a/changelogs/unreleased/sh-enable-frozen-literals-banzi-filters.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Enable frozen strings in remaining lib/banzai/filter/*.rb files
-merge_request: 20777
-author:
-type: performance
diff --git a/changelogs/unreleased/sh-fix-admin-jobs-controller-timing-out.yml b/changelogs/unreleased/sh-fix-admin-jobs-controller-timing-out.yml
deleted file mode 100644
index e1adebbf076..00000000000
--- a/changelogs/unreleased/sh-fix-admin-jobs-controller-timing-out.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix /admin/jobs failing to load due to statement timeout
-merge_request: 20909
-author:
-type: performance
diff --git a/changelogs/unreleased/sh-fix-issue-47797-ce.yml b/changelogs/unreleased/sh-fix-issue-47797-ce.yml
deleted file mode 100644
index 456d96acacb..00000000000
--- a/changelogs/unreleased/sh-fix-issue-47797-ce.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix handling of annotated tags when Gitaly is not in use
-merge_request:
-author:
-type: fixed
diff --git a/changelogs/unreleased/sh-fix-issue-49133.yml b/changelogs/unreleased/sh-fix-issue-49133.yml
deleted file mode 100644
index 847220d88b2..00000000000
--- a/changelogs/unreleased/sh-fix-issue-49133.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix symlink vulnerability in project import
-merge_request:
-author:
-type: security
diff --git a/changelogs/unreleased/sh-fix-issue-50562.yml b/changelogs/unreleased/sh-fix-issue-50562.yml
new file mode 100644
index 00000000000..a207dd28622
--- /dev/null
+++ b/changelogs/unreleased/sh-fix-issue-50562.yml
@@ -0,0 +1,5 @@
+---
+title: Fix remote mirrors failing if Git remotes have not been added
+merge_request: 21351
+author:
+type: fixed
diff --git a/changelogs/unreleased/sh-fix-stderr-pipe-consumption.yml b/changelogs/unreleased/sh-fix-stderr-pipe-consumption.yml
deleted file mode 100644
index b7366cf2569..00000000000
--- a/changelogs/unreleased/sh-fix-stderr-pipe-consumption.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Avoid process deadlock in popen by consuming input pipes
-merge_request: 20600
-author:
-type: fixed
diff --git a/changelogs/unreleased/sh-freeze-banzai-filter-strings.yml b/changelogs/unreleased/sh-freeze-banzai-filter-strings.yml
deleted file mode 100644
index 37b397ea49f..00000000000
--- a/changelogs/unreleased/sh-freeze-banzai-filter-strings.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Enable frozen strings in lib/banzai/filter/*.rb
-merge_request: 20775
-author:
-type: performance
diff --git a/changelogs/unreleased/sh-handle-colons-in-url-passwords.yml b/changelogs/unreleased/sh-handle-colons-in-url-passwords.yml
deleted file mode 100644
index 7717d0aab37..00000000000
--- a/changelogs/unreleased/sh-handle-colons-in-url-passwords.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Properly handle colons in URL passwords
-merge_request:
-author:
-type: fixed
diff --git a/changelogs/unreleased/sh-include-rbtrace.yml b/changelogs/unreleased/sh-include-rbtrace.yml
deleted file mode 100644
index 41f0655e3f8..00000000000
--- a/changelogs/unreleased/sh-include-rbtrace.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Add rbtrace to Gemfile
-merge_request: 20831
-author:
-type: other
diff --git a/changelogs/unreleased/sh-insert-git-data-in-separate-transaction.yml b/changelogs/unreleased/sh-insert-git-data-in-separate-transaction.yml
new file mode 100644
index 00000000000..116929b2f53
--- /dev/null
+++ b/changelogs/unreleased/sh-insert-git-data-in-separate-transaction.yml
@@ -0,0 +1,5 @@
+---
+title: 'Bitbucket Server importer: Eliminate most idle-in-transaction issues'
+merge_request:
+author:
+type: performance
diff --git a/changelogs/unreleased/sh-lfs-fix-content-type.yml b/changelogs/unreleased/sh-lfs-fix-content-type.yml
deleted file mode 100644
index a839be9b3ae..00000000000
--- a/changelogs/unreleased/sh-lfs-fix-content-type.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix LFS uploads not working with git-lfs 2.5.0
-merge_request: 20923
-author:
-type: fixed
diff --git a/changelogs/unreleased/sh-limit-commit-renderering.yml b/changelogs/unreleased/sh-limit-commit-renderering.yml
new file mode 100644
index 00000000000..c44c67bcc90
--- /dev/null
+++ b/changelogs/unreleased/sh-limit-commit-renderering.yml
@@ -0,0 +1,5 @@
+---
+title: Speed up diff comparisons by limiting number of commit messages rendered
+merge_request: 21335
+author:
+type: performance
diff --git a/changelogs/unreleased/sh-limit-unauthenticated-session-times.yml b/changelogs/unreleased/sh-limit-unauthenticated-session-times.yml
deleted file mode 100644
index 44a46b4115e..00000000000
--- a/changelogs/unreleased/sh-limit-unauthenticated-session-times.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Limit the TTL for anonymous sessions to 1 hour
-merge_request: 20700
-author:
-type: performance
diff --git a/changelogs/unreleased/sh-normalize-urls.yml b/changelogs/unreleased/sh-normalize-urls.yml
deleted file mode 100644
index b0d1120e10b..00000000000
--- a/changelogs/unreleased/sh-normalize-urls.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Escape username and password in UrlSanitizer#full_url
-merge_request: 20684
-author:
-type: fixed
diff --git a/changelogs/unreleased/sh-optimize-wiki-empty-check.yml b/changelogs/unreleased/sh-optimize-wiki-empty-check.yml
deleted file mode 100644
index 31ca7497b5a..00000000000
--- a/changelogs/unreleased/sh-optimize-wiki-empty-check.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Optimize ProjectWiki#empty? check
-merge_request: 20573
-author:
-type: performance
diff --git a/changelogs/unreleased/sh-remove-banzai-instrumentation.yml b/changelogs/unreleased/sh-remove-banzai-instrumentation.yml
deleted file mode 100644
index 8bb3cd5942b..00000000000
--- a/changelogs/unreleased/sh-remove-banzai-instrumentation.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Remove method instrumentation for Banzai filters and reference parsers
-merge_request: 20770
-author:
-type: performance
diff --git a/changelogs/unreleased/sh-sanitize-project-import-names.yml b/changelogs/unreleased/sh-sanitize-project-import-names.yml
new file mode 100644
index 00000000000..6e0284bda08
--- /dev/null
+++ b/changelogs/unreleased/sh-sanitize-project-import-names.yml
@@ -0,0 +1,5 @@
+---
+title: Use slugs for default project path and sanitize names before import
+merge_request: 21367
+author:
+type: fixed
diff --git a/changelogs/unreleased/sh-simplify-liveness-check.yml b/changelogs/unreleased/sh-simplify-liveness-check.yml
deleted file mode 100644
index 225e3dc1378..00000000000
--- a/changelogs/unreleased/sh-simplify-liveness-check.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Add /-/health basic health check endpoint
-merge_request: 20456
-author:
-type: added
diff --git a/changelogs/unreleased/sh-support-users-find-by-confirmed-emails.yml b/changelogs/unreleased/sh-support-users-find-by-confirmed-emails.yml
deleted file mode 100644
index 4b0c8117b3e..00000000000
--- a/changelogs/unreleased/sh-support-users-find-by-confirmed-emails.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Add support for searching users by confirmed e-mails
-merge_request: 20893
-author:
-type: other
diff --git a/changelogs/unreleased/sh-use-wiki-limit-parameter-gitaly.yml b/changelogs/unreleased/sh-use-wiki-limit-parameter-gitaly.yml
deleted file mode 100644
index e8c2e11ad31..00000000000
--- a/changelogs/unreleased/sh-use-wiki-limit-parameter-gitaly.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Use limit parameter to retrieve Wikis from Gitaly
-merge_request: 20764
-author:
-type: performance
diff --git a/changelogs/unreleased/stop-dynamic-routable-creation.yml b/changelogs/unreleased/stop-dynamic-routable-creation.yml
deleted file mode 100644
index 8bfcb5b2d11..00000000000
--- a/changelogs/unreleased/stop-dynamic-routable-creation.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Stop dynamically creating project and namespace routes
-merge_request: 20313
-author:
-type: performance
diff --git a/changelogs/unreleased/tc-api-fork-owners.yml b/changelogs/unreleased/tc-api-fork-owners.yml
new file mode 100644
index 00000000000..feaa3c1705e
--- /dev/null
+++ b/changelogs/unreleased/tc-api-fork-owners.yml
@@ -0,0 +1,5 @@
+---
+title: Allow project owners to set up forking relation through API
+merge_request: 18104
+author:
+type: changed
diff --git a/changelogs/unreleased/tc-reorder-mail-notify-references.yml b/changelogs/unreleased/tc-reorder-mail-notify-references.yml
deleted file mode 100644
index 689afda0259..00000000000
--- a/changelogs/unreleased/tc-reorder-mail-notify-references.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Put fallback reply-key address first in the References header
-merge_request: 20871
-author:
-type: changed
diff --git a/changelogs/unreleased/todos-visibility-change.yml b/changelogs/unreleased/todos-visibility-change.yml
deleted file mode 100644
index b7632b94771..00000000000
--- a/changelogs/unreleased/todos-visibility-change.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Delete todos when user loses access to read the target
-merge_request: 20665
-author:
-type: other
diff --git a/changelogs/unreleased/todos-visibility-migration.yml b/changelogs/unreleased/todos-visibility-migration.yml
deleted file mode 100644
index 651facc4ec8..00000000000
--- a/changelogs/unreleased/todos-visibility-migration.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Remove todos of users without access to targets migration
-merge_request: 20927
-author:
-type: other
diff --git a/changelogs/unreleased/toggle-password-cluster.yml b/changelogs/unreleased/toggle-password-cluster.yml
deleted file mode 100644
index 1a43c4baa25..00000000000
--- a/changelogs/unreleased/toggle-password-cluster.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Toggle Show / Hide Button for Kubernetes Password
-merge_request: 20659
-author: gfyoung
-type: fixed
diff --git a/changelogs/unreleased/tweak-sql-buckets.yml b/changelogs/unreleased/tweak-sql-buckets.yml
deleted file mode 100644
index 00a0f733ee1..00000000000
--- a/changelogs/unreleased/tweak-sql-buckets.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Add a 10 ms bucket for SQL timings
-merge_request:
-author:
-type: changed
diff --git a/changelogs/unreleased/tz-mr-port-memory-fixes.yml b/changelogs/unreleased/tz-mr-port-memory-fixes.yml
deleted file mode 100644
index 61d3c9abf71..00000000000
--- a/changelogs/unreleased/tz-mr-port-memory-fixes.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Improve performance and memory footprint of Changes tab of Merge Requests
-merge_request: 21028
-author:
-type: performance
diff --git a/changelogs/unreleased/update-card-body-style.yml b/changelogs/unreleased/update-card-body-style.yml
deleted file mode 100644
index d9197c18502..00000000000
--- a/changelogs/unreleased/update-card-body-style.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Remove background color from card-body style
-merge_request: 20689
-author: George Tsiolis
-type: fixed
diff --git a/changelogs/unreleased/update-issue-closing-pattern.yml b/changelogs/unreleased/update-issue-closing-pattern.yml
deleted file mode 100644
index 95488adf449..00000000000
--- a/changelogs/unreleased/update-issue-closing-pattern.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Update issue closing pattern
-merge_request: 20554
-author: George Tsiolis
-type: changed
diff --git a/changelogs/unreleased/update-specific-runners-help-url.yml b/changelogs/unreleased/update-specific-runners-help-url.yml
deleted file mode 100644
index 0ccbc3b2d65..00000000000
--- a/changelogs/unreleased/update-specific-runners-help-url.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Update specific runners help URL
-merge_request: 20213
-author: George Tsiolis
-type: other
diff --git a/changelogs/unreleased/upgrade-hamlit-for-ruby25.yml b/changelogs/unreleased/upgrade-hamlit-for-ruby25.yml
deleted file mode 100644
index 39e10121507..00000000000
--- a/changelogs/unreleased/upgrade-hamlit-for-ruby25.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: 'Update hamlit to fix ruby 2.5 incompatibilities, fixes #42045'
-merge_request:
-author: Matthew Dawson
-type: fixed
diff --git a/changelogs/unreleased/winh-default-status-emoji.yml b/changelogs/unreleased/winh-default-status-emoji.yml
new file mode 100644
index 00000000000..00cca4db0a6
--- /dev/null
+++ b/changelogs/unreleased/winh-default-status-emoji.yml
@@ -0,0 +1,5 @@
+---
+title: Display default status emoji if only message is entered
+merge_request: 21330
+author:
+type: changed
diff --git a/changelogs/unreleased/winh-fix-gpg-regressions.yml b/changelogs/unreleased/winh-fix-gpg-regressions.yml
deleted file mode 100644
index 75d28321259..00000000000
--- a/changelogs/unreleased/winh-fix-gpg-regressions.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix GPG status badge loading regressions
-merge_request: 20987
-author:
-type: fixed
diff --git a/changelogs/unreleased/winh-restyle-user-status.yml b/changelogs/unreleased/winh-restyle-user-status.yml
deleted file mode 100644
index 90370e87825..00000000000
--- a/changelogs/unreleased/winh-restyle-user-status.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Restyle status message input on profile settings
-merge_request: 20903
-author:
-type: changed
diff --git a/changelogs/unreleased/winh-stop-all-environments.yml b/changelogs/unreleased/winh-stop-all-environments.yml
deleted file mode 100644
index 6e5f2f506d9..00000000000
--- a/changelogs/unreleased/winh-stop-all-environments.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Support manually stopping any environment from the UI
-merge_request: 20077
-author:
-type: changed
diff --git a/changelogs/unreleased/winh-tree-view-gpg.yml b/changelogs/unreleased/winh-tree-view-gpg.yml
deleted file mode 100644
index 84d63814a47..00000000000
--- a/changelogs/unreleased/winh-tree-view-gpg.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Display GPG status on repository and blob pages
-merge_request: 20524
-author:
-type: changed
diff --git a/changelogs/unreleased/winh-upgrade-grape-path-helpers.yml b/changelogs/unreleased/winh-upgrade-grape-path-helpers.yml
deleted file mode 100644
index 62addff1d0f..00000000000
--- a/changelogs/unreleased/winh-upgrade-grape-path-helpers.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Upgrade grape-path-helpers to 1.0.6
-merge_request: 20601
-author:
-type: other
diff --git a/changelogs/unreleased/wrap-job-name-on-jobs-sidebar.yml b/changelogs/unreleased/wrap-job-name-on-jobs-sidebar.yml
deleted file mode 100644
index 97fa1592753..00000000000
--- a/changelogs/unreleased/wrap-job-name-on-jobs-sidebar.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Wrap job name on pipeline job sidebar
-merge_request: 20804
-author: George Tsiolis
-type: changed
diff --git a/changelogs/unreleased/zj-remove-git-rake-tasks.yml b/changelogs/unreleased/zj-remove-git-rake-tasks.yml
deleted file mode 100644
index 8c90fc7d0fe..00000000000
--- a/changelogs/unreleased/zj-remove-git-rake-tasks.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Remove gitlab:user:check_repos, gitlab:check_repo, gitlab:git:prune, gitlab:git:gc, and gitlab:git:repack
-merge_request: 20806
-author:
-type: removed
diff --git a/changelogs/unreleased/zj-repository-languages.yml b/changelogs/unreleased/zj-repository-languages.yml
deleted file mode 100644
index c42ba60be29..00000000000
--- a/changelogs/unreleased/zj-repository-languages.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Show repository languages for projects
-merge_request: 19480
-author:
-type: added
diff --git a/config/initializers/fog_google_https_private_urls.rb b/config/initializers/fog_google_https_private_urls.rb
index f92e623a5d2..c65a534b536 100644
--- a/config/initializers/fog_google_https_private_urls.rb
+++ b/config/initializers/fog_google_https_private_urls.rb
@@ -7,7 +7,7 @@ module Fog
class GoogleXML
class File < Fog::Model
module MonkeyPatch
- def url(expires)
+ def url(expires, options = {})
requires :key
collection.get_https_url(key, expires)
end
diff --git a/config/routes.rb b/config/routes.rb
index d16a587c5ee..e2e97b46d23 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -27,6 +27,13 @@ Rails.application.routes.draw do
authorizations: 'oauth/authorizations'
end
+ # This is here so we can "reserve" the path for the Jira integration in GitLab EE
+ # Having a non-existent controller here does not affect the scope in any way since all possible routes
+ # get a 404 proc returned. It is written in this way to minimize merge conflicts with EE
+ scope path: '/login/oauth', controller: 'oauth/jira/authorizations', as: :oauth_jira do
+ match ':action', via: [:get, :post], to: proc { [404, {}, ['']] }
+ end
+
use_doorkeeper_openid_connect
# Autocomplete
diff --git a/config/routes/admin.rb b/config/routes/admin.rb
index 7ee960970f8..fa1f79a90be 100644
--- a/config/routes/admin.rb
+++ b/config/routes/admin.rb
@@ -59,7 +59,7 @@ namespace :admin do
resources :hook_logs, only: [:show] do
member do
- get :retry
+ post :retry
end
end
end
diff --git a/config/routes/group.rb b/config/routes/group.rb
index 25fbb38ba87..d7313e43786 100644
--- a/config/routes/group.rb
+++ b/config/routes/group.rb
@@ -37,7 +37,7 @@ constraints(::Constraints::GroupUrlConstrainer.new) do
post :toggle_subscription, on: :member
end
- resources :milestones, constraints: { id: %r{[^/]+} }, only: [:index, :show, :edit, :update, :new, :create] do
+ resources :milestones, constraints: { id: %r{[^/]+} } do
member do
get :merge_requests
get :participants
diff --git a/config/routes/project.rb b/config/routes/project.rb
index 0220e88c819..34f49546983 100644
--- a/config/routes/project.rb
+++ b/config/routes/project.rb
@@ -307,7 +307,7 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do
resources :hook_logs, only: [:show] do
member do
- get :retry
+ post :retry
end
end
end
diff --git a/danger/changelog/Dangerfile b/danger/changelog/Dangerfile
index a1f94dc6004..713ed95a04c 100644
--- a/danger/changelog/Dangerfile
+++ b/danger/changelog/Dangerfile
@@ -53,9 +53,11 @@ end
changelog_needed = (gitlab.mr_labels & NO_CHANGELOG_LABELS).empty?
changelog_found = git.added_files.find { |path| path =~ %r{\A(ee/)?(changelogs/unreleased)(-ee)?/} }
+mr_title = gitlab.mr_json["title"].gsub(/^WIP: */, '')
+
if git.modified_files.include?("CHANGELOG.md")
fail "**CHANGELOG.md was edited.** Please remove the additions and create a CHANGELOG entry.\n\n" +
- format(CREATE_CHANGELOG_MESSAGE, mr_iid: gitlab.mr_json["iid"], mr_title: gitlab.mr_json["title"], labels: presented_no_changelog_labels)
+ format(CREATE_CHANGELOG_MESSAGE, mr_iid: gitlab.mr_json["iid"], mr_title: mr_title, labels: presented_no_changelog_labels)
end
if changelog_needed
@@ -63,6 +65,6 @@ if changelog_needed
check_changelog(changelog_found)
else
warn "**[CHANGELOG missing](https://docs.gitlab.com/ce/development/changelog.html).**\n\n" +
- format(CREATE_CHANGELOG_MESSAGE, mr_iid: gitlab.mr_json["iid"], mr_title: gitlab.mr_json["title"], labels: presented_no_changelog_labels)
+ format(CREATE_CHANGELOG_MESSAGE, mr_iid: gitlab.mr_json["iid"], mr_title: mr_title, labels: presented_no_changelog_labels)
end
end
diff --git a/db/migrate/20180711103851_drop_duplicate_protected_tags.rb b/db/migrate/20180711103851_drop_duplicate_protected_tags.rb
new file mode 100644
index 00000000000..8fa2137551e
--- /dev/null
+++ b/db/migrate/20180711103851_drop_duplicate_protected_tags.rb
@@ -0,0 +1,45 @@
+# See http://doc.gitlab.com/ce/development/migration_style_guide.html
+# for more information on how to write migrations for GitLab.
+
+class DropDuplicateProtectedTags < ActiveRecord::Migration
+ DOWNTIME = false
+
+ disable_ddl_transaction!
+
+ BATCH_SIZE = 1000
+
+ class Project < ActiveRecord::Base
+ self.table_name = 'projects'
+
+ include ::EachBatch
+ end
+
+ class ProtectedTag < ActiveRecord::Base
+ self.table_name = 'protected_tags'
+ end
+
+ def up
+ Project.each_batch(of: BATCH_SIZE) do |projects|
+ ids = ProtectedTag
+ .where(project_id: projects)
+ .group(:name, :project_id)
+ .select('max(id)')
+
+ tags = ProtectedTag
+ .where(project_id: projects)
+ .where.not(id: ids)
+
+ if Gitlab::Database.postgresql?
+ tags.delete_all
+ else
+ # Workaround needed for MySQL
+ sql = "SELECT id FROM (#{tags.to_sql}) protected_tags"
+
+ ProtectedTag.where("id IN (#{sql})").delete_all # rubocop:disable GitlabSecurity/SqlInjection
+ end
+ end
+ end
+
+ def down
+ end
+end
diff --git a/db/migrate/20180711103922_add_protected_tags_index.rb b/db/migrate/20180711103922_add_protected_tags_index.rb
new file mode 100644
index 00000000000..7ed2258ebaf
--- /dev/null
+++ b/db/migrate/20180711103922_add_protected_tags_index.rb
@@ -0,0 +1,18 @@
+# See http://doc.gitlab.com/ce/development/migration_style_guide.html
+# for more information on how to write migrations for GitLab.
+
+class AddProtectedTagsIndex < ActiveRecord::Migration
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ disable_ddl_transaction!
+
+ def up
+ add_concurrent_index :protected_tags, [:project_id, :name], unique: true
+ end
+
+ def down
+ remove_concurrent_index :protected_tags, [:project_id, :name]
+ end
+end
diff --git a/db/migrate/20180815175440_add_index_on_list_type.rb b/db/migrate/20180815175440_add_index_on_list_type.rb
new file mode 100644
index 00000000000..aad805e436e
--- /dev/null
+++ b/db/migrate/20180815175440_add_index_on_list_type.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+class AddIndexOnListType < ActiveRecord::Migration
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ disable_ddl_transaction!
+
+ def up
+ add_concurrent_index :lists, :list_type
+ end
+
+ def down
+ remove_concurrent_index :lists, :list_type
+ end
+end
diff --git a/db/post_migrate/20180816193530_rename_login_root_namespaces.rb b/db/post_migrate/20180816193530_rename_login_root_namespaces.rb
new file mode 100644
index 00000000000..60cec24eed6
--- /dev/null
+++ b/db/post_migrate/20180816193530_rename_login_root_namespaces.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+class RenameLoginRootNamespaces < ActiveRecord::Migration
+ include Gitlab::Database::MigrationHelpers
+ include Gitlab::Database::RenameReservedPathsMigration::V1
+
+ DOWNTIME = false
+
+ # We're taking over the /login namespace as part of a fix for the Jira integration
+ def up
+ rename_root_paths 'login'
+ end
+
+ def down
+ revert_renames
+ end
+end
diff --git a/db/post_migrate/20180826111825_recalculate_site_statistics.rb b/db/post_migrate/20180826111825_recalculate_site_statistics.rb
new file mode 100644
index 00000000000..741035a444f
--- /dev/null
+++ b/db/post_migrate/20180826111825_recalculate_site_statistics.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+class RecalculateSiteStatistics < ActiveRecord::Migration
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ disable_ddl_transaction!
+
+ def up
+ transaction do
+ execute('SET LOCAL statement_timeout TO 0') if Gitlab::Database.postgresql? # see https://gitlab.com/gitlab-org/gitlab-ce/issues/48967
+
+ execute("UPDATE site_statistics SET repositories_count = (SELECT COUNT(*) FROM projects)")
+ end
+
+ transaction do
+ execute('SET LOCAL statement_timeout TO 0') if Gitlab::Database.postgresql? # see https://gitlab.com/gitlab-org/gitlab-ce/issues/48967
+
+ execute("UPDATE site_statistics SET wikis_count = (SELECT COUNT(*) FROM project_features WHERE wiki_access_level != 0)")
+ end
+ end
+
+ def down
+ # No downside in keeping the counter up-to-date
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 9dc122b54b3..cb8f90efded 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema.define(version: 20180809195358) do
+ActiveRecord::Schema.define(version: 20180826111825) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@@ -1135,6 +1135,7 @@ ActiveRecord::Schema.define(version: 20180809195358) do
add_index "lists", ["board_id", "label_id"], name: "index_lists_on_board_id_and_label_id", unique: true, using: :btree
add_index "lists", ["label_id"], name: "index_lists_on_label_id", using: :btree
+ add_index "lists", ["list_type"], name: "index_lists_on_list_type", using: :btree
create_table "members", force: :cascade do |t|
t.integer "access_level", null: false
@@ -1740,6 +1741,7 @@ ActiveRecord::Schema.define(version: 20180809195358) do
t.datetime "updated_at", null: false
end
+ add_index "protected_tags", ["project_id", "name"], name: "index_protected_tags_on_project_id_and_name", unique: true, using: :btree
add_index "protected_tags", ["project_id"], name: "index_protected_tags_on_project_id", using: :btree
create_table "push_event_payloads", id: false, force: :cascade do |t|
diff --git a/doc/administration/auth/how_to_configure_ldap_gitlab_ce/img/gitlab_ou.png b/doc/administration/auth/how_to_configure_ldap_gitlab_ce/img/gitlab_ou.png
index 11ce324f938..223fd0ac401 100644
--- a/doc/administration/auth/how_to_configure_ldap_gitlab_ce/img/gitlab_ou.png
+++ b/doc/administration/auth/how_to_configure_ldap_gitlab_ce/img/gitlab_ou.png
Binary files differ
diff --git a/doc/administration/auth/img/crowd_application.png b/doc/administration/auth/img/crowd_application.png
index 7deea9dac8e..5029a005667 100644
--- a/doc/administration/auth/img/crowd_application.png
+++ b/doc/administration/auth/img/crowd_application.png
Binary files differ
diff --git a/doc/administration/auth/img/crowd_application_authorisation.png b/doc/administration/auth/img/crowd_application_authorisation.png
index 70339891b34..0e0bde1344b 100644
--- a/doc/administration/auth/img/crowd_application_authorisation.png
+++ b/doc/administration/auth/img/crowd_application_authorisation.png
Binary files differ
diff --git a/doc/administration/img/circuitbreaker_config.png b/doc/administration/img/circuitbreaker_config.png
index 693b2ee9c69..20233276055 100644
--- a/doc/administration/img/circuitbreaker_config.png
+++ b/doc/administration/img/circuitbreaker_config.png
Binary files differ
diff --git a/doc/administration/img/custom_hooks_error_msg.png b/doc/administration/img/custom_hooks_error_msg.png
index 1b3277bef16..845f0de19ce 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/failing_storage.png b/doc/administration/img/failing_storage.png
index 82b393a58b2..652d7dcb5d7 100644
--- a/doc/administration/img/failing_storage.png
+++ b/doc/administration/img/failing_storage.png
Binary files differ
diff --git a/doc/administration/img/integration/plantuml-example.png b/doc/administration/img/integration/plantuml-example.png
index cb64eca1a8a..3e0d6389cbd 100644
--- a/doc/administration/img/integration/plantuml-example.png
+++ b/doc/administration/img/integration/plantuml-example.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 036e708cdac..5f1b4936704 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_import.png b/doc/administration/monitoring/performance/img/grafana_dashboard_import.png
index 7761ea00522..fd639ee0eb8 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 3e749eb8f9d..a98e0ed1e7d 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 33fcaaaef64..549ada8343e 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 c18f2147e9d..68a071f5ae2 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/performance_bar.png b/doc/administration/monitoring/performance/img/performance_bar.png
index 48212f6276a..2bf686f9017 100644
--- a/doc/administration/monitoring/performance/img/performance_bar.png
+++ b/doc/administration/monitoring/performance/img/performance_bar.png
Binary files differ
diff --git a/doc/administration/monitoring/performance/img/performance_bar_configuration_settings.png b/doc/administration/monitoring/performance/img/performance_bar_configuration_settings.png
index 2d64ef8c5fc..fafc50cd000 100644
--- a/doc/administration/monitoring/performance/img/performance_bar_configuration_settings.png
+++ b/doc/administration/monitoring/performance/img/performance_bar_configuration_settings.png
Binary files differ
diff --git a/doc/administration/monitoring/performance/img/performance_bar_gitaly_calls.png b/doc/administration/monitoring/performance/img/performance_bar_gitaly_calls.png
index 52176df9ecd..7af6d401d1d 100644
--- a/doc/administration/monitoring/performance/img/performance_bar_gitaly_calls.png
+++ b/doc/administration/monitoring/performance/img/performance_bar_gitaly_calls.png
Binary files differ
diff --git a/doc/administration/monitoring/performance/img/performance_bar_line_profiling.png b/doc/administration/monitoring/performance/img/performance_bar_line_profiling.png
index 7868e2c46d1..a55ce753101 100644
--- a/doc/administration/monitoring/performance/img/performance_bar_line_profiling.png
+++ b/doc/administration/monitoring/performance/img/performance_bar_line_profiling.png
Binary files differ
diff --git a/doc/administration/monitoring/performance/img/performance_bar_sql_queries.png b/doc/administration/monitoring/performance/img/performance_bar_sql_queries.png
index 372ae021f6b..b3219b4fa94 100644
--- a/doc/administration/monitoring/performance/img/performance_bar_sql_queries.png
+++ b/doc/administration/monitoring/performance/img/performance_bar_sql_queries.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 8ebd74c2d3c..1b06e240fa0 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 9160407e028..8c4109c17f0 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 dcf40b4bf17..abd09f3b115 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/administration/operations/img/write_to_authorized_keys_setting.png b/doc/administration/operations/img/write_to_authorized_keys_setting.png
index 232765f1917..f6227a6057b 100644
--- a/doc/administration/operations/img/write_to_authorized_keys_setting.png
+++ b/doc/administration/operations/img/write_to_authorized_keys_setting.png
Binary files differ
diff --git a/doc/api/README.md b/doc/api/README.md
index 45e926d3b6b..e2a6e87a2c3 100644
--- a/doc/api/README.md
+++ b/doc/api/README.md
@@ -53,6 +53,7 @@ following locations:
- [Project Members](members.md)
- [Project Snippets](project_snippets.md)
- [Protected Branches](protected_branches.md)
+- [Protected Tags](protected_tags.md)
- [Repositories](repositories.md)
- [Repository Files](repository_files.md)
- [Runners](runners.md)
diff --git a/doc/api/discussions.md b/doc/api/discussions.md
index 65e2f9d6cd9..a1e1ff1419d 100644
--- a/doc/api/discussions.md
+++ b/doc/api/discussions.md
@@ -136,7 +136,7 @@ Parameters:
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) |
| `issue_iid` | integer | yes | The IID of an issue |
| `body` | string | yes | The content of a discussion |
-| `created_at` | string | no | Date time string, ISO 8601 formatted, e.g. 2016-03-11T03:45:40Z |
+| `created_at` | string | no | Date time string, ISO 8601 formatted, e.g. 2016-03-11T03:45:40Z (requires admin or project/group owner rights) |
```bash
curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/projects/5/issues/11/discussions?body=comment
@@ -159,7 +159,7 @@ Parameters:
| `discussion_id` | integer | yes | The ID of a discussion |
| `note_id` | integer | yes | The ID of a discussion note |
| `body` | string | yes | The content of a discussion |
-| `created_at` | string | no | Date time string, ISO 8601 formatted, e.g. 2016-03-11T03:45:40Z |
+| `created_at` | string | no | Date time string, ISO 8601 formatted, e.g. 2016-03-11T03:45:40Z (requires admin or project/group owner rights) |
```bash
curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/projects/5/issues/11/discussions/6a9c1750b37d513a43987b574953fceb50b03ce7/notes?body=comment
@@ -342,7 +342,7 @@ Parameters:
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) |
| `snippet_id` | integer | yes | The ID of an snippet |
| `body` | string | yes | The content of a discussion |
-| `created_at` | string | no | Date time string, ISO 8601 formatted, e.g. 2016-03-11T03:45:40Z |
+| `created_at` | string | no | Date time string, ISO 8601 formatted, e.g. 2016-03-11T03:45:40Z (requires admin or project/group owner rights) |
```bash
curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/projects/5/snippets/11/discussions?body=comment
@@ -365,7 +365,7 @@ Parameters:
| `discussion_id` | integer | yes | The ID of a discussion |
| `note_id` | integer | yes | The ID of a discussion note |
| `body` | string | yes | The content of a discussion |
-| `created_at` | string | no | Date time string, ISO 8601 formatted, e.g. 2016-03-11T03:45:40Z |
+| `created_at` | string | no | Date time string, ISO 8601 formatted, e.g. 2016-03-11T03:45:40Z (requires admin or project/group owner rights) |
```bash
curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/projects/5/snippets/11/discussions/6a9c1750b37d513a43987b574953fceb50b03ce7/notes?body=comment
@@ -601,7 +601,7 @@ Parameters:
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) |
| `merge_request_iid` | integer | yes | The IID of a merge request |
| `body` | string | yes | The content of a discussion |
-| `created_at` | string | no | Date time string, ISO 8601 formatted, e.g. 2016-03-11T03:45:40Z |
+| `created_at` | string | no | Date time string, ISO 8601 formatted, e.g. 2016-03-11T03:45:40Z (requires admin or project/group owner rights) |
| `position` | hash | no | Position when creating a diff note |
| `position[base_sha]` | string | yes | Base commit SHA in the source branch |
| `position[start_sha]` | string | yes | SHA referencing commit in target branch |
@@ -659,7 +659,7 @@ Parameters:
| `discussion_id` | integer | yes | The ID of a discussion |
| `note_id` | integer | yes | The ID of a discussion note |
| `body` | string | yes | The content of a discussion |
-| `created_at` | string | no | Date time string, ISO 8601 formatted, e.g. 2016-03-11T03:45:40Z |
+| `created_at` | string | no | Date time string, ISO 8601 formatted, e.g. 2016-03-11T03:45:40Z (requires admin or project/group owner rights) |
```bash
curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/projects/5/merge_requests/11/discussions/6a9c1750b37d513a43987b574953fceb50b03ce7/notes?body=comment
@@ -894,7 +894,7 @@ Parameters:
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) |
| `commit_id` | integer | yes | The ID of a commit |
| `body` | string | yes | The content of a discussion |
-| `created_at` | string | no | Date time string, ISO 8601 formatted, e.g. 2016-03-11T03:45:40Z |
+| `created_at` | string | no | Date time string, ISO 8601 formatted, e.g. 2016-03-11T03:45:40Z (requires admin or project/group owner rights) |
| `position` | hash | no | Position when creating a diff note |
| `position[base_sha]` | string | yes | Base commit SHA in the source branch |
| `position[start_sha]` | string | yes | SHA referencing commit in target branch |
@@ -930,7 +930,7 @@ Parameters:
| `discussion_id` | integer | yes | The ID of a discussion |
| `note_id` | integer | yes | The ID of a discussion note |
| `body` | string | yes | The content of a discussion |
-| `created_at` | string | no | Date time string, ISO 8601 formatted, e.g. 2016-03-11T03:45:40Z |
+| `created_at` | string | no | Date time string, ISO 8601 formatted, e.g. 2016-03-11T03:45:40Z (requires admin or project/group owner rights) |
```bash
curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/projects/5/commits/11/discussions/6a9c1750b37d513a43987b574953fceb50b03ce7/notes?body=comment
diff --git a/doc/api/group_milestones.md b/doc/api/group_milestones.md
index 152929b7614..e396f4411e6 100644
--- a/doc/api/group_milestones.md
+++ b/doc/api/group_milestones.md
@@ -96,6 +96,19 @@ Parameters:
- `start_date` (optional) - The start date of the milestone
- `state_event` (optional) - The state event of the milestone (close|activate)
+## Delete group milestone
+
+Only for user with developer access to the group.
+
+```
+DELETE /groups/:id/milestones/:milestone_id
+```
+
+Parameters:
+
+- `id` (required) - The ID or [URL-encoded path of the group](README.md#namespaced-path-encoding) owned by the authenticated user
+- `milestone_id` (required) - The ID of the group's milestone
+
## Get all issues assigned to a single milestone
Gets all issues assigned to a single group milestone.
diff --git a/doc/api/groups.md b/doc/api/groups.md
index 87be36cc815..64e0d78788d 100644
--- a/doc/api/groups.md
+++ b/doc/api/groups.md
@@ -351,12 +351,14 @@ Example response:
{
"group_id": 4,
"group_name": "Twitter",
- "group_access_level": 30
+ "group_access_level": 30,
+ "expires_at": null
},
{
"group_id": 3,
"group_name": "Gitlab Org",
- "group_access_level": 10
+ "group_access_level": 10,
+ "expires_at": "2018-08-14"
}
]
}
diff --git a/doc/api/issues.md b/doc/api/issues.md
index 103eaa5655f..f4c0f4ea65b 100644
--- a/doc/api/issues.md
+++ b/doc/api/issues.md
@@ -470,7 +470,7 @@ POST /projects/:id/issues
| `assignee_ids` | Array[integer] | no | The ID of the users to assign issue |
| `milestone_id` | integer | no | The global ID of a milestone to assign issue |
| `labels` | string | no | Comma-separated label names for an issue |
-| `created_at` | string | no | Date time string, ISO 8601 formatted, e.g. `2016-03-11T03:45:40Z` (requires admin or project owner rights) |
+| `created_at` | string | no | Date time string, ISO 8601 formatted, e.g. `2016-03-11T03:45:40Z` (requires admin or project/group owner rights) |
| `due_date` | string | no | Date time string in the format YEAR-MONTH-DAY, e.g. `2016-03-11` |
| `merge_request_to_resolve_discussions_of` | integer | no | The IID of a merge request in which to resolve all issues. This will fill the issue with a default description and mark all discussions as resolved. When passing a description or title, these values will take precedence over the default values.|
| `discussion_to_resolve` | string | no | The ID of a discussion to resolve. This will fill in the issue with a default description and mark the discussion as resolved. Use in combination with `merge_request_to_resolve_discussions_of`. |
diff --git a/doc/api/notes.md b/doc/api/notes.md
index c271d46688f..44940bdd9e5 100644
--- a/doc/api/notes.md
+++ b/doc/api/notes.md
@@ -100,7 +100,7 @@ Parameters:
- `id` (required) - The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding)
- `issue_id` (required) - The IID of an issue
- `body` (required) - The content of a note
-- `created_at` (optional) - Date time string, ISO 8601 formatted, e.g. 2016-03-11T03:45:40Z
+- `created_at` (optional) - Date time string, ISO 8601 formatted, e.g. 2016-03-11T03:45:40Z (requires admin or project/group owner rights)
```bash
curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/projects/5/issues/11/notes?body=note
diff --git a/doc/api/projects.md b/doc/api/projects.md
index bda4164ee92..0936ff52dae 100644
--- a/doc/api/projects.md
+++ b/doc/api/projects.md
@@ -1413,12 +1413,17 @@ DELETE /projects/:id/hooks/:hook_id
Note the JSON response differs if the hook is available or not. If the project hook
is available before it is returned in the JSON response or an empty response is returned.
-## Admin fork relation
+## Fork relationship
-Allows modification of the forked relationship between existing projects. Available only for admins.
+Allows modification of the forked relationship between existing projects. Available only for project owners and admins.
### Create a forked from/to relation between existing projects
+CAUTION: **Warning:**
+This will destroy the LFS objects stored in the fork.
+So to retain the LFS objects, make sure you've pulled them **before** creating the fork relation,
+and push them again **after** creating the fork relation.
+
```
POST /projects/:id/fork/:forked_from_id
```
diff --git a/doc/api/protected_tags.md b/doc/api/protected_tags.md
new file mode 100644
index 00000000000..aa750e467f8
--- /dev/null
+++ b/doc/api/protected_tags.md
@@ -0,0 +1,128 @@
+# Protected tags API
+
+>**Note:** This feature was introduced in GitLab 11.3
+
+**Valid access levels**
+
+Currently, these levels are recognized:
+```
+0 => No access
+30 => Developer access
+40 => Maintainer access
+```
+
+## List protected tags
+
+Gets a list of protected tags from a project.
+This function takes pagination parameters `page` and `per_page` to restrict the list of protected tags.
+
+```
+GET /projects/:id/protected_tags
+```
+
+| Attribute | Type | Required | Description |
+| --------- | ---- | -------- | ----------- |
+| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
+
+```bash
+curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" 'https://gitlab.example.com/api/v4/projects/5/protected_tags'
+```
+
+Example response:
+
+```json
+[
+ {
+ "name": "release-1-0",
+ "create_access_levels": [
+ {
+ "access_level": 40,
+ "access_level_description": "Maintainers"
+ }
+ ]
+ },
+ ...
+]
+```
+
+## Get a single protected tag or wildcard protected tag
+
+Gets a single protected tag or wildcard protected tag.
+The pagination parameters `page` and `per_page` can be used to restrict the list of protected tags.
+
+```
+GET /projects/:id/protected_tags/:name
+```
+
+| Attribute | Type | Required | Description |
+| --------- | ---- | -------- | ----------- |
+| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
+| `name` | string | yes | The name of the tag or wildcard |
+
+```bash
+curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" 'https://gitlab.example.com/api/v4/projects/5/protected_tags/release-1-0'
+```
+
+Example response:
+
+```json
+{
+ "name": "release-1-0",
+ "create_access_levels": [
+ {
+ "access_level": 40,
+ "access_level_description": "Maintainers"
+ }
+ ]
+}
+```
+
+## Protect repository tags
+
+Protects a single repository tag or several project repository
+tags using a wildcard protected tag.
+
+```
+POST /projects/:id/protected_tags
+```
+
+```bash
+curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" 'https://gitlab.example.com/api/v4/projects/5/protected_tags?name=*-stable&create_access_level=30'
+```
+
+| Attribute | Type | Required | Description |
+| --------- | ---- | -------- | ----------- |
+| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
+| `name` | string | yes | The name of the tag or wildcard |
+| `create_access_level` | string | no | Access levels allowed to create (defaults: `40`, maintainer access level) |
+
+Example response:
+
+```json
+{
+ "name": "*-stable",
+ "create_access_levels": [
+ {
+ "access_level": 30,
+ "access_level_description": "Developers + Maintainers"
+ }
+ ]
+}
+```
+
+## Unprotect repository tags
+
+Unprotects the given protected tag or wildcard protected tag.
+
+```
+DELETE /projects/:id/protected_tags/:name
+```
+
+```bash
+curl --request DELETE --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" 'https://gitlab.example.com/api/v4/projects/5/protected_tags/*-stable'
+```
+
+| Attribute | Type | Required | Description |
+| --------- | ---- | -------- | ----------- |
+| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
+| `name` | string | yes | The name of the tag |
diff --git a/doc/ci/autodeploy/img/auto_deploy_btn.png b/doc/ci/autodeploy/img/auto_deploy_btn.png
index 25915ed1c9d..ee88e5ce8c0 100644
--- a/doc/ci/autodeploy/img/auto_deploy_btn.png
+++ b/doc/ci/autodeploy/img/auto_deploy_btn.png
Binary files differ
diff --git a/doc/ci/autodeploy/img/auto_deploy_button.png b/doc/ci/autodeploy/img/auto_deploy_button.png
index 423e76a6cda..0e84d9c57a1 100644
--- a/doc/ci/autodeploy/img/auto_deploy_button.png
+++ b/doc/ci/autodeploy/img/auto_deploy_button.png
Binary files differ
diff --git a/doc/ci/autodeploy/img/auto_deploy_dropdown.png b/doc/ci/autodeploy/img/auto_deploy_dropdown.png
index 5815937a4af..4094f8ebb4e 100644
--- a/doc/ci/autodeploy/img/auto_deploy_dropdown.png
+++ b/doc/ci/autodeploy/img/auto_deploy_dropdown.png
Binary files differ
diff --git a/doc/ci/autodeploy/img/auto_monitoring.png b/doc/ci/autodeploy/img/auto_monitoring.png
index 5661b50841b..5a11923d199 100644
--- a/doc/ci/autodeploy/img/auto_monitoring.png
+++ b/doc/ci/autodeploy/img/auto_monitoring.png
Binary files differ
diff --git a/doc/ci/autodeploy/img/guide_connect_cluster.png b/doc/ci/autodeploy/img/guide_connect_cluster.png
index b856b81a1d0..703d536f37a 100644
--- a/doc/ci/autodeploy/img/guide_connect_cluster.png
+++ b/doc/ci/autodeploy/img/guide_connect_cluster.png
Binary files differ
diff --git a/doc/ci/autodeploy/img/guide_integration.png b/doc/ci/autodeploy/img/guide_integration.png
index 723b2619ea2..ab72de2bba3 100644
--- a/doc/ci/autodeploy/img/guide_integration.png
+++ b/doc/ci/autodeploy/img/guide_integration.png
Binary files differ
diff --git a/doc/ci/autodeploy/img/guide_secret.png b/doc/ci/autodeploy/img/guide_secret.png
index 01f5aa49908..8469bee48b7 100644
--- a/doc/ci/autodeploy/img/guide_secret.png
+++ b/doc/ci/autodeploy/img/guide_secret.png
Binary files differ
diff --git a/doc/ci/caching/img/clear_runners_cache.png b/doc/ci/caching/img/clear_runners_cache.png
index e5db4a47b3e..4f1171513ad 100644
--- a/doc/ci/caching/img/clear_runners_cache.png
+++ b/doc/ci/caching/img/clear_runners_cache.png
Binary files differ
diff --git a/doc/ci/examples/devops_and_game_dev_with_gitlab_ci_cd/img/aws_config_window.png b/doc/ci/examples/devops_and_game_dev_with_gitlab_ci_cd/img/aws_config_window.png
index 76e0295722b..09eef98202f 100644
--- a/doc/ci/examples/devops_and_game_dev_with_gitlab_ci_cd/img/aws_config_window.png
+++ b/doc/ci/examples/devops_and_game_dev_with_gitlab_ci_cd/img/aws_config_window.png
Binary files differ
diff --git a/doc/ci/examples/devops_and_game_dev_with_gitlab_ci_cd/img/gitlab_config.png b/doc/ci/examples/devops_and_game_dev_with_gitlab_ci_cd/img/gitlab_config.png
index 050a97d2726..71ffcdea289 100644
--- a/doc/ci/examples/devops_and_game_dev_with_gitlab_ci_cd/img/gitlab_config.png
+++ b/doc/ci/examples/devops_and_game_dev_with_gitlab_ci_cd/img/gitlab_config.png
Binary files differ
diff --git a/doc/ci/examples/devops_and_game_dev_with_gitlab_ci_cd/img/test_pipeline_pass.png b/doc/ci/examples/devops_and_game_dev_with_gitlab_ci_cd/img/test_pipeline_pass.png
index 4ab5d5f401a..a9452577a42 100644
--- a/doc/ci/examples/devops_and_game_dev_with_gitlab_ci_cd/img/test_pipeline_pass.png
+++ b/doc/ci/examples/devops_and_game_dev_with_gitlab_ci_cd/img/test_pipeline_pass.png
Binary files differ
diff --git a/doc/ci/examples/laravel_with_gitlab_and_envoy/img/container_registry_page_empty_image.png b/doc/ci/examples/laravel_with_gitlab_and_envoy/img/container_registry_page_empty_image.png
index b1406fed6b8..704d43ea52e 100644
--- a/doc/ci/examples/laravel_with_gitlab_and_envoy/img/container_registry_page_empty_image.png
+++ b/doc/ci/examples/laravel_with_gitlab_and_envoy/img/container_registry_page_empty_image.png
Binary files differ
diff --git a/doc/ci/examples/laravel_with_gitlab_and_envoy/img/deploy_keys_page.png b/doc/ci/examples/laravel_with_gitlab_and_envoy/img/deploy_keys_page.png
index 9aae11b8679..763ce48fa5a 100644
--- a/doc/ci/examples/laravel_with_gitlab_and_envoy/img/deploy_keys_page.png
+++ b/doc/ci/examples/laravel_with_gitlab_and_envoy/img/deploy_keys_page.png
Binary files differ
diff --git a/doc/ci/examples/laravel_with_gitlab_and_envoy/img/environment_page.png b/doc/ci/examples/laravel_with_gitlab_and_envoy/img/environment_page.png
index a06b6d417cd..f299d6355cb 100644
--- a/doc/ci/examples/laravel_with_gitlab_and_envoy/img/environment_page.png
+++ b/doc/ci/examples/laravel_with_gitlab_and_envoy/img/environment_page.png
Binary files differ
diff --git a/doc/ci/examples/laravel_with_gitlab_and_envoy/img/environments_page.png b/doc/ci/examples/laravel_with_gitlab_and_envoy/img/environments_page.png
index d357ecda7d2..9c301e1fc8c 100644
--- a/doc/ci/examples/laravel_with_gitlab_and_envoy/img/environments_page.png
+++ b/doc/ci/examples/laravel_with_gitlab_and_envoy/img/environments_page.png
Binary files differ
diff --git a/doc/ci/examples/laravel_with_gitlab_and_envoy/img/pipeline_page.png b/doc/ci/examples/laravel_with_gitlab_and_envoy/img/pipeline_page.png
index baf8dec499c..2f451615a3a 100644
--- a/doc/ci/examples/laravel_with_gitlab_and_envoy/img/pipeline_page.png
+++ b/doc/ci/examples/laravel_with_gitlab_and_envoy/img/pipeline_page.png
Binary files differ
diff --git a/doc/ci/examples/laravel_with_gitlab_and_envoy/img/pipelines_page.png b/doc/ci/examples/laravel_with_gitlab_and_envoy/img/pipelines_page.png
index d96c43bcf16..a5fd6b020d1 100644
--- a/doc/ci/examples/laravel_with_gitlab_and_envoy/img/pipelines_page.png
+++ b/doc/ci/examples/laravel_with_gitlab_and_envoy/img/pipelines_page.png
Binary files differ
diff --git a/doc/ci/examples/laravel_with_gitlab_and_envoy/img/pipelines_page_deploy_button.png b/doc/ci/examples/laravel_with_gitlab_and_envoy/img/pipelines_page_deploy_button.png
index 997db10189f..1f605504171 100644
--- a/doc/ci/examples/laravel_with_gitlab_and_envoy/img/pipelines_page_deploy_button.png
+++ b/doc/ci/examples/laravel_with_gitlab_and_envoy/img/pipelines_page_deploy_button.png
Binary files differ
diff --git a/doc/ci/examples/laravel_with_gitlab_and_envoy/img/secret_variables_page.png b/doc/ci/examples/laravel_with_gitlab_and_envoy/img/secret_variables_page.png
index 658c0b5bcac..b7906d49dcb 100644
--- a/doc/ci/examples/laravel_with_gitlab_and_envoy/img/secret_variables_page.png
+++ b/doc/ci/examples/laravel_with_gitlab_and_envoy/img/secret_variables_page.png
Binary files differ
diff --git a/doc/ci/examples/test_phoenix_app_with_gitlab_ci_cd/img/job-succeeded.png b/doc/ci/examples/test_phoenix_app_with_gitlab_ci_cd/img/job-succeeded.png
index 0f94ac60fee..77b05f55f88 100644
--- a/doc/ci/examples/test_phoenix_app_with_gitlab_ci_cd/img/job-succeeded.png
+++ b/doc/ci/examples/test_phoenix_app_with_gitlab_ci_cd/img/job-succeeded.png
Binary files differ
diff --git a/doc/ci/examples/test_phoenix_app_with_gitlab_ci_cd/img/mix-phoenix-new.png b/doc/ci/examples/test_phoenix_app_with_gitlab_ci_cd/img/mix-phoenix-new.png
index 94828a20f51..04d3dc40fa5 100644
--- a/doc/ci/examples/test_phoenix_app_with_gitlab_ci_cd/img/mix-phoenix-new.png
+++ b/doc/ci/examples/test_phoenix_app_with_gitlab_ci_cd/img/mix-phoenix-new.png
Binary files differ
diff --git a/doc/ci/examples/test_phoenix_app_with_gitlab_ci_cd/img/mix-phoenix-server.png b/doc/ci/examples/test_phoenix_app_with_gitlab_ci_cd/img/mix-phoenix-server.png
index 68503b392ed..63812b41c2c 100644
--- a/doc/ci/examples/test_phoenix_app_with_gitlab_ci_cd/img/mix-phoenix-server.png
+++ b/doc/ci/examples/test_phoenix_app_with_gitlab_ci_cd/img/mix-phoenix-server.png
Binary files differ
diff --git a/doc/ci/examples/test_phoenix_app_with_gitlab_ci_cd/img/pipelines.png b/doc/ci/examples/test_phoenix_app_with_gitlab_ci_cd/img/pipelines.png
index d73140ccdd9..c0daa1a6a91 100644
--- a/doc/ci/examples/test_phoenix_app_with_gitlab_ci_cd/img/pipelines.png
+++ b/doc/ci/examples/test_phoenix_app_with_gitlab_ci_cd/img/pipelines.png
Binary files differ
diff --git a/doc/ci/examples/test_phoenix_app_with_gitlab_ci_cd/img/select-template.png b/doc/ci/examples/test_phoenix_app_with_gitlab_ci_cd/img/select-template.png
index 38bfde0a3dd..727995f463c 100644
--- a/doc/ci/examples/test_phoenix_app_with_gitlab_ci_cd/img/select-template.png
+++ b/doc/ci/examples/test_phoenix_app_with_gitlab_ci_cd/img/select-template.png
Binary files differ
diff --git a/doc/ci/examples/test_phoenix_app_with_gitlab_ci_cd/img/setup-ci.png b/doc/ci/examples/test_phoenix_app_with_gitlab_ci_cd/img/setup-ci.png
index bfe85c6a10b..50c6ca593c1 100644
--- a/doc/ci/examples/test_phoenix_app_with_gitlab_ci_cd/img/setup-ci.png
+++ b/doc/ci/examples/test_phoenix_app_with_gitlab_ci_cd/img/setup-ci.png
Binary files differ
diff --git a/doc/ci/img/deployments_view.png b/doc/ci/img/deployments_view.png
index 436fed5f465..45d882b536c 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.png b/doc/ci/img/environments_available.png
index 2991a309655..7ab92838ece 100644
--- a/doc/ci/img/environments_available.png
+++ b/doc/ci/img/environments_available.png
Binary files differ
diff --git a/doc/ci/img/environments_dynamic_groups.png b/doc/ci/img/environments_dynamic_groups.png
index 45124b3d8d8..37828ccd0c1 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_mr.png b/doc/ci/img/environments_link_url_mr.png
index 7ce46063062..75d7311b862 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_deployments.png b/doc/ci/img/environments_manual_action_deployments.png
index 93beaa0de54..c5959c0003e 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 9490be63f14..b2ec27cc721 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_jobs.png b/doc/ci/img/environments_manual_action_jobs.png
index 9ae223cf77f..d948ee5da9e 100644
--- a/doc/ci/img/environments_manual_action_jobs.png
+++ b/doc/ci/img/environments_manual_action_jobs.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 129e44f6fb0..332850afb7f 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 1eeb4379eb7..8c1c0c1d993 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_monitoring.png b/doc/ci/img/environments_monitoring.png
index dcffdd1fdb8..63d272ae42a 100644
--- a/doc/ci/img/environments_monitoring.png
+++ b/doc/ci/img/environments_monitoring.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 4bb643d708f..61b7e9fe77c 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_terminal_button_on_index.png b/doc/ci/img/environments_terminal_button_on_index.png
index 061bb7c3c87..40110ff325f 100644
--- a/doc/ci/img/environments_terminal_button_on_index.png
+++ b/doc/ci/img/environments_terminal_button_on_index.png
Binary files differ
diff --git a/doc/ci/img/environments_terminal_button_on_show.png b/doc/ci/img/environments_terminal_button_on_show.png
index 4d24304bc93..e96ca9c9c7e 100644
--- a/doc/ci/img/environments_terminal_button_on_show.png
+++ b/doc/ci/img/environments_terminal_button_on_show.png
Binary files differ
diff --git a/doc/ci/img/environments_terminal_page.png b/doc/ci/img/environments_terminal_page.png
index fde1bf325a6..736b2d01a99 100644
--- a/doc/ci/img/environments_terminal_page.png
+++ b/doc/ci/img/environments_terminal_page.png
Binary files differ
diff --git a/doc/ci/img/job_failure_reason.png b/doc/ci/img/job_failure_reason.png
index a60ce1fb21c..d44b8e6d1be 100644
--- a/doc/ci/img/job_failure_reason.png
+++ b/doc/ci/img/job_failure_reason.png
Binary files differ
diff --git a/doc/ci/img/pipelines_grouped.png b/doc/ci/img/pipelines_grouped.png
index 06f52e03320..82814754747 100644
--- a/doc/ci/img/pipelines_grouped.png
+++ b/doc/ci/img/pipelines_grouped.png
Binary files differ
diff --git a/doc/ci/img/pipelines_index.png b/doc/ci/img/pipelines_index.png
index 3b522a9c5e4..e168e7e23df 100644
--- a/doc/ci/img/pipelines_index.png
+++ b/doc/ci/img/pipelines_index.png
Binary files differ
diff --git a/doc/ci/img/pipelines_mini_graph.png b/doc/ci/img/pipelines_mini_graph.png
index 042c8ffeef5..8656b02f60d 100644
--- a/doc/ci/img/pipelines_mini_graph.png
+++ b/doc/ci/img/pipelines_mini_graph.png
Binary files differ
diff --git a/doc/ci/img/pipelines_mini_graph_simple.png b/doc/ci/img/pipelines_mini_graph_simple.png
index eb36c09b2d4..d00a8313088 100644
--- a/doc/ci/img/pipelines_mini_graph_simple.png
+++ b/doc/ci/img/pipelines_mini_graph_simple.png
Binary files differ
diff --git a/doc/ci/img/view_on_env_blob.png b/doc/ci/img/view_on_env_blob.png
index f4fe99046f0..dd9ca40280a 100644
--- a/doc/ci/img/view_on_env_blob.png
+++ b/doc/ci/img/view_on_env_blob.png
Binary files differ
diff --git a/doc/ci/img/view_on_env_mr.png b/doc/ci/img/view_on_env_mr.png
index 47ddb40bdc1..2c0bd25a4f2 100644
--- a/doc/ci/img/view_on_env_mr.png
+++ b/doc/ci/img/view_on_env_mr.png
Binary files differ
diff --git a/doc/ci/interactive_web_terminal/img/interactive_web_terminal_page.png b/doc/ci/interactive_web_terminal/img/interactive_web_terminal_page.png
index b59c1b6bc43..0523e62db70 100644
--- a/doc/ci/interactive_web_terminal/img/interactive_web_terminal_page.png
+++ b/doc/ci/interactive_web_terminal/img/interactive_web_terminal_page.png
Binary files differ
diff --git a/doc/ci/interactive_web_terminal/img/interactive_web_terminal_running_job.png b/doc/ci/interactive_web_terminal/img/interactive_web_terminal_running_job.png
index f92c6df07a1..3ee5e39afc0 100644
--- a/doc/ci/interactive_web_terminal/img/interactive_web_terminal_running_job.png
+++ b/doc/ci/interactive_web_terminal/img/interactive_web_terminal_running_job.png
Binary files differ
diff --git a/doc/ci/quick_start/img/build_log.png b/doc/ci/quick_start/img/build_log.png
index 3a7248ca772..2bf0992c50e 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 f829240f3b3..58978e23978 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 b3dd848b294..507eb93ac0c 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/review_apps/img/review_apps_preview_in_mr.png b/doc/ci/review_apps/img/review_apps_preview_in_mr.png
index 0300392f24b..7d0923f198f 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/runners/img/protected_runners_check_box.png b/doc/ci/runners/img/protected_runners_check_box.png
index fb58498c7ce..3c47ebdec29 100644
--- a/doc/ci/runners/img/protected_runners_check_box.png
+++ b/doc/ci/runners/img/protected_runners_check_box.png
Binary files differ
diff --git a/doc/ci/runners/img/shared_runner_ip_address.png b/doc/ci/runners/img/shared_runner_ip_address.png
index 3b1542d59d3..527b4f4043d 100644
--- a/doc/ci/runners/img/shared_runner_ip_address.png
+++ b/doc/ci/runners/img/shared_runner_ip_address.png
Binary files differ
diff --git a/doc/ci/runners/img/specific_runner_ip_address.png b/doc/ci/runners/img/specific_runner_ip_address.png
index 3b4c3e9f2eb..e08663109ba 100644
--- a/doc/ci/runners/img/specific_runner_ip_address.png
+++ b/doc/ci/runners/img/specific_runner_ip_address.png
Binary files differ
diff --git a/doc/ci/triggers/img/builds_page.png b/doc/ci/triggers/img/builds_page.png
index c9cc8f308f4..14d73b140f4 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 837bbeffe9f..b760782afdc 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/customization/branded_login_page/custom_sign_in.png b/doc/customization/branded_login_page/custom_sign_in.png
index c0888fe1f18..03ea5281ebe 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_page_and_email_header/appearance.png b/doc/customization/branded_page_and_email_header/appearance.png
index abbba6f9ac9..6b79bc47005 100644
--- a/doc/customization/branded_page_and_email_header/appearance.png
+++ b/doc/customization/branded_page_and_email_header/appearance.png
Binary files differ
diff --git a/doc/customization/branded_page_and_email_header/custom_brand_header.png b/doc/customization/branded_page_and_email_header/custom_brand_header.png
index 7390f8a5e4e..d779236bbe7 100644
--- a/doc/customization/branded_page_and_email_header/custom_brand_header.png
+++ b/doc/customization/branded_page_and_email_header/custom_brand_header.png
Binary files differ
diff --git a/doc/customization/branded_page_and_email_header/custom_email_header.png b/doc/customization/branded_page_and_email_header/custom_email_header.png
index 705698ef4a8..729b166364b 100644
--- a/doc/customization/branded_page_and_email_header/custom_email_header.png
+++ b/doc/customization/branded_page_and_email_header/custom_email_header.png
Binary files differ
diff --git a/doc/customization/favicon/appearance.png b/doc/customization/favicon/appearance.png
index 6c41a05fc1f..da1002826dd 100644
--- a/doc/customization/favicon/appearance.png
+++ b/doc/customization/favicon/appearance.png
Binary files differ
diff --git a/doc/customization/favicon/custom_favicon.png b/doc/customization/favicon/custom_favicon.png
index fa1b8827a36..20dddfbea33 100644
--- a/doc/customization/favicon/custom_favicon.png
+++ b/doc/customization/favicon/custom_favicon.png
Binary files differ
diff --git a/doc/customization/new_project_page/appearance_settings.png b/doc/customization/new_project_page/appearance_settings.png
index 08eea684e14..4fcdd1caa21 100644
--- a/doc/customization/new_project_page/appearance_settings.png
+++ b/doc/customization/new_project_page/appearance_settings.png
Binary files differ
diff --git a/doc/customization/new_project_page/custom_new_project_page.png b/doc/customization/new_project_page/custom_new_project_page.png
index 662c715f193..c6f7839e9c3 100644
--- a/doc/customization/new_project_page/custom_new_project_page.png
+++ b/doc/customization/new_project_page/custom_new_project_page.png
Binary files differ
diff --git a/doc/customization/new_project_page/default_new_project_page.png b/doc/customization/new_project_page/default_new_project_page.png
index 4a0bcf09903..f5b209ac5ea 100644
--- a/doc/customization/new_project_page/default_new_project_page.png
+++ b/doc/customization/new_project_page/default_new_project_page.png
Binary files differ
diff --git a/doc/development/README.md b/doc/development/README.md
index ee9a9852205..20f8fa1d368 100644
--- a/doc/development/README.md
+++ b/doc/development/README.md
@@ -54,6 +54,7 @@ description: 'Learn how to contribute to GitLab.'
- [Performance guidelines](performance.md)
- [Merge request performance guidelines](merge_request_performance_guidelines.md)
for ensuring merge requests do not negatively impact GitLab performance
+- [Profiling](profiling.md) for profiling a URL
## Database guides
diff --git a/doc/development/architecture.md b/doc/development/architecture.md
index 3e417a44ec1..66d8a4f2f6e 100644
--- a/doc/development/architecture.md
+++ b/doc/development/architecture.md
@@ -70,7 +70,7 @@ The add-on component gitlab-shell serves repositories over SSH. It manages the S
Gitaly executes git operations from gitlab-shell and the GitLab web app, and provides an API to the GitLab web app to get attributes from git (e.g. title, branches, tags, other meta data), and to get blobs (e.g. diffs, commits, files).
-You may also be interested in the [production architecture of GitLab.com](https://about.gitlab.com/handbook/infrastructure/production-architecture/).
+You may also be interested in the [production architecture of GitLab.com](https://about.gitlab.com/handbook/engineering/infrastructure/production-architecture/).
### Installation Folder Summary
diff --git a/doc/development/documentation/img/manual_build_docs.png b/doc/development/documentation/img/manual_build_docs.png
index 615facabb5f..e366a2f7ec4 100644
--- a/doc/development/documentation/img/manual_build_docs.png
+++ b/doc/development/documentation/img/manual_build_docs.png
Binary files differ
diff --git a/doc/development/fe_guide/img/boards_diagram.png b/doc/development/fe_guide/img/boards_diagram.png
index 7a2cf972fd0..856c9b05bbf 100644
--- a/doc/development/fe_guide/img/boards_diagram.png
+++ b/doc/development/fe_guide/img/boards_diagram.png
Binary files differ
diff --git a/doc/development/fe_guide/img/gl-modal.png b/doc/development/fe_guide/img/gl-modal.png
index 47302e857bc..b2d2d637e57 100644
--- a/doc/development/fe_guide/img/gl-modal.png
+++ b/doc/development/fe_guide/img/gl-modal.png
Binary files differ
diff --git a/doc/development/feature_flags.md b/doc/development/feature_flags.md
index 09ea8c05be6..702caacc74f 100644
--- a/doc/development/feature_flags.md
+++ b/doc/development/feature_flags.md
@@ -57,3 +57,15 @@ end
Features that are developed and are intended to be merged behind a feature flag
should not include a changelog entry. The entry should be added in the merge
request removing the feature flags.
+
+### Specs
+
+In the test environment `Feature.enabled?` is stubbed to always respond to `true`,
+so we make sure behavior under feature flag doesn't go untested in some non-specific
+contexts.
+
+If you need to test the feature flag in a different state, you need to stub it with:
+
+```ruby
+stub_feature_flags(my_feature_flag: false)
+```
diff --git a/doc/development/gitlab_architecture_diagram.png b/doc/development/gitlab_architecture_diagram.png
index 378f7384574..90e27d5462a 100644
--- a/doc/development/gitlab_architecture_diagram.png
+++ b/doc/development/gitlab_architecture_diagram.png
Binary files differ
diff --git a/doc/development/img/trigger_ss1.png b/doc/development/img/trigger_ss1.png
index ccff1009a25..addbc551f73 100644
--- a/doc/development/img/trigger_ss1.png
+++ b/doc/development/img/trigger_ss1.png
Binary files differ
diff --git a/doc/development/img/trigger_ss2.png b/doc/development/img/trigger_ss2.png
index 94dfd048793..02ef3810a59 100644
--- a/doc/development/img/trigger_ss2.png
+++ b/doc/development/img/trigger_ss2.png
Binary files differ
diff --git a/doc/development/ux_guide/img/button-close--active.png b/doc/development/ux_guide/img/button-close--active.png
index 824bfc8f31b..97a5301fb91 100644
--- a/doc/development/ux_guide/img/button-close--active.png
+++ b/doc/development/ux_guide/img/button-close--active.png
Binary files differ
diff --git a/doc/development/ux_guide/img/button-close--hover.png b/doc/development/ux_guide/img/button-close--hover.png
index 0291e121894..6b8fdf5695b 100644
--- a/doc/development/ux_guide/img/button-close--hover.png
+++ b/doc/development/ux_guide/img/button-close--hover.png
Binary files differ
diff --git a/doc/development/ux_guide/img/button-close--resting.png b/doc/development/ux_guide/img/button-close--resting.png
index 986d7174ce7..5679b51687c 100644
--- a/doc/development/ux_guide/img/button-close--resting.png
+++ b/doc/development/ux_guide/img/button-close--resting.png
Binary files differ
diff --git a/doc/development/ux_guide/img/button-danger--active.png b/doc/development/ux_guide/img/button-danger--active.png
index d3c64424b26..6a9aab0fcc2 100644
--- a/doc/development/ux_guide/img/button-danger--active.png
+++ b/doc/development/ux_guide/img/button-danger--active.png
Binary files differ
diff --git a/doc/development/ux_guide/img/button-danger--hover.png b/doc/development/ux_guide/img/button-danger--hover.png
index 8506e093306..13e21c28779 100644
--- a/doc/development/ux_guide/img/button-danger--hover.png
+++ b/doc/development/ux_guide/img/button-danger--hover.png
Binary files differ
diff --git a/doc/development/ux_guide/img/button-danger--resting.png b/doc/development/ux_guide/img/button-danger--resting.png
index 69ad6bb796b..0ff192bc463 100644
--- a/doc/development/ux_guide/img/button-danger--resting.png
+++ b/doc/development/ux_guide/img/button-danger--resting.png
Binary files differ
diff --git a/doc/development/ux_guide/img/button-info--active.png b/doc/development/ux_guide/img/button-info--active.png
index 23be20b225c..12ecdc72a31 100644
--- a/doc/development/ux_guide/img/button-info--active.png
+++ b/doc/development/ux_guide/img/button-info--active.png
Binary files differ
diff --git a/doc/development/ux_guide/img/button-info--hover.png b/doc/development/ux_guide/img/button-info--hover.png
index 4cb4e38558c..3bf93bf2b32 100644
--- a/doc/development/ux_guide/img/button-info--hover.png
+++ b/doc/development/ux_guide/img/button-info--hover.png
Binary files differ
diff --git a/doc/development/ux_guide/img/button-info--resting.png b/doc/development/ux_guide/img/button-info--resting.png
index 5883340aa83..a37a37033bf 100644
--- a/doc/development/ux_guide/img/button-info--resting.png
+++ b/doc/development/ux_guide/img/button-info--resting.png
Binary files differ
diff --git a/doc/development/ux_guide/img/button-spam--active.png b/doc/development/ux_guide/img/button-spam--active.png
index 55b44898684..a9e115f49c1 100644
--- a/doc/development/ux_guide/img/button-spam--active.png
+++ b/doc/development/ux_guide/img/button-spam--active.png
Binary files differ
diff --git a/doc/development/ux_guide/img/button-spam--hover.png b/doc/development/ux_guide/img/button-spam--hover.png
index 3dc8ed34c54..3b2c16430a6 100644
--- a/doc/development/ux_guide/img/button-spam--hover.png
+++ b/doc/development/ux_guide/img/button-spam--hover.png
Binary files differ
diff --git a/doc/development/ux_guide/img/button-spam--resting.png b/doc/development/ux_guide/img/button-spam--resting.png
index b6bf10a5b64..4f9f18ca68a 100644
--- a/doc/development/ux_guide/img/button-spam--resting.png
+++ b/doc/development/ux_guide/img/button-spam--resting.png
Binary files differ
diff --git a/doc/development/ux_guide/img/button-success--active.png b/doc/development/ux_guide/img/button-success--active.png
index 895a52831cb..b99f6f5e70e 100644
--- a/doc/development/ux_guide/img/button-success--active.png
+++ b/doc/development/ux_guide/img/button-success--active.png
Binary files differ
diff --git a/doc/development/ux_guide/img/button-success--hover.png b/doc/development/ux_guide/img/button-success--hover.png
index e4c74bd9778..0d0a61c679a 100644
--- a/doc/development/ux_guide/img/button-success--hover.png
+++ b/doc/development/ux_guide/img/button-success--hover.png
Binary files differ
diff --git a/doc/development/ux_guide/img/button-success--resting.png b/doc/development/ux_guide/img/button-success--resting.png
index 2fa971b5347..53b955c650a 100644
--- a/doc/development/ux_guide/img/button-success--resting.png
+++ b/doc/development/ux_guide/img/button-success--resting.png
Binary files differ
diff --git a/doc/development/ux_guide/img/button-success-secondary--active.png b/doc/development/ux_guide/img/button-success-secondary--active.png
index e7383b36946..333a91f2217 100644
--- a/doc/development/ux_guide/img/button-success-secondary--active.png
+++ b/doc/development/ux_guide/img/button-success-secondary--active.png
Binary files differ
diff --git a/doc/development/ux_guide/img/button-success-secondary--hover.png b/doc/development/ux_guide/img/button-success-secondary--hover.png
index 4af2a68cf1b..0cce59212e3 100644
--- a/doc/development/ux_guide/img/button-success-secondary--hover.png
+++ b/doc/development/ux_guide/img/button-success-secondary--hover.png
Binary files differ
diff --git a/doc/development/ux_guide/img/button-success-secondary--resting.png b/doc/development/ux_guide/img/button-success-secondary--resting.png
index a5a4ec512c8..2779a4949f8 100644
--- a/doc/development/ux_guide/img/button-success-secondary--resting.png
+++ b/doc/development/ux_guide/img/button-success-secondary--resting.png
Binary files differ
diff --git a/doc/development/ux_guide/img/button-warning--active.png b/doc/development/ux_guide/img/button-warning--active.png
index 5877d46c94d..f5760cd7c12 100644
--- a/doc/development/ux_guide/img/button-warning--active.png
+++ b/doc/development/ux_guide/img/button-warning--active.png
Binary files differ
diff --git a/doc/development/ux_guide/img/button-warning--hover.png b/doc/development/ux_guide/img/button-warning--hover.png
index 308e1adc8a3..a1f4c5cbcc6 100644
--- a/doc/development/ux_guide/img/button-warning--hover.png
+++ b/doc/development/ux_guide/img/button-warning--hover.png
Binary files differ
diff --git a/doc/development/ux_guide/img/button-warning--resting.png b/doc/development/ux_guide/img/button-warning--resting.png
index 28e5e601520..3d62fed5930 100644
--- a/doc/development/ux_guide/img/button-warning--resting.png
+++ b/doc/development/ux_guide/img/button-warning--resting.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 844e926f1f5..77c1a2cab31 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 5c4c23c7067..51600584c96 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-grey.png b/doc/development/ux_guide/img/color-grey.png
index 5247649a0ce..f0f0b9d80bb 100644
--- a/doc/development/ux_guide/img/color-grey.png
+++ b/doc/development/ux_guide/img/color-grey.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 1103c715225..f16435c0a64 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 77ecbbc0a20..5008e75da78 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-anchorlinks.png b/doc/development/ux_guide/img/components-anchorlinks.png
index 4a9c730566c..bd8d30f5905 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-coverblock.png b/doc/development/ux_guide/img/components-coverblock.png
index fb135f9648a..61160de5613 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 686ca727293..cc1fb8216bf 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-fileholder.png b/doc/development/ux_guide/img/components-fileholder.png
index ec2911a1232..5bf8565346a 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 c57dceda43a..e6cbc69d20a 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 3a72d39bb5d..6b773a19954 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-listwithhover.png b/doc/development/ux_guide/img/components-listwithhover.png
index 8521a8ad53e..0826848ff34 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-referencehover.png b/doc/development/ux_guide/img/components-referencehover.png
index f80564dbb16..af5405d3e0b 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 51fb2cf3e43..4e175dc169d 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 aba450cc3ba..29a985bbaa0 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 adf2555ccf8..47c76a9d60f 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 6c3375f1ea1..9a5032a1516 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 b8dd431e2e6..f9ef11be853 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-searchbox.png b/doc/development/ux_guide/img/components-searchbox.png
index a25189296ba..5c19024bfb0 100644
--- a/doc/development/ux_guide/img/components-searchbox.png
+++ b/doc/development/ux_guide/img/components-searchbox.png
Binary files differ
diff --git a/doc/development/ux_guide/img/components-searchboxscoped.png b/doc/development/ux_guide/img/components-searchboxscoped.png
index b116d714848..d4a35977658 100644
--- a/doc/development/ux_guide/img/components-searchboxscoped.png
+++ b/doc/development/ux_guide/img/components-searchboxscoped.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 858e5064c25..8d11c674e84 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/features-contextualnav.png b/doc/development/ux_guide/img/features-contextualnav.png
index f8466f28627..aa816776fad 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 51835a7080b..50f31f5e523 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/icon-add.png b/doc/development/ux_guide/img/icon-add.png
index bcad5e84591..f66525cc1b4 100644
--- a/doc/development/ux_guide/img/icon-add.png
+++ b/doc/development/ux_guide/img/icon-add.png
Binary files differ
diff --git a/doc/development/ux_guide/img/icon-close.png b/doc/development/ux_guide/img/icon-close.png
index dfe1495f5fa..af6c30ebe6a 100644
--- a/doc/development/ux_guide/img/icon-close.png
+++ b/doc/development/ux_guide/img/icon-close.png
Binary files differ
diff --git a/doc/development/ux_guide/img/icon-edit.png b/doc/development/ux_guide/img/icon-edit.png
index 50f6f841868..b9649f4aeec 100644
--- a/doc/development/ux_guide/img/icon-edit.png
+++ b/doc/development/ux_guide/img/icon-edit.png
Binary files differ
diff --git a/doc/development/ux_guide/img/icon-notification.png b/doc/development/ux_guide/img/icon-notification.png
index 6ddfaa44f66..5cf8f8ab59a 100644
--- a/doc/development/ux_guide/img/icon-notification.png
+++ b/doc/development/ux_guide/img/icon-notification.png
Binary files differ
diff --git a/doc/development/ux_guide/img/icon-rss.png b/doc/development/ux_guide/img/icon-rss.png
index b766488b32d..7e2987a2656 100644
--- a/doc/development/ux_guide/img/icon-rss.png
+++ b/doc/development/ux_guide/img/icon-rss.png
Binary files differ
diff --git a/doc/development/ux_guide/img/icon-spec.png b/doc/development/ux_guide/img/icon-spec.png
index 56b19610dc1..5bb85c5be98 100644
--- a/doc/development/ux_guide/img/icon-spec.png
+++ b/doc/development/ux_guide/img/icon-spec.png
Binary files differ
diff --git a/doc/development/ux_guide/img/icon-subscribe.png b/doc/development/ux_guide/img/icon-subscribe.png
index 650168296c6..7e2f5e6a1c6 100644
--- a/doc/development/ux_guide/img/icon-subscribe.png
+++ b/doc/development/ux_guide/img/icon-subscribe.png
Binary files differ
diff --git a/doc/development/ux_guide/img/icon-trash.png b/doc/development/ux_guide/img/icon-trash.png
index b02178ca992..bc46638fb2e 100644
--- a/doc/development/ux_guide/img/icon-trash.png
+++ b/doc/development/ux_guide/img/icon-trash.png
Binary files differ
diff --git a/doc/development/ux_guide/img/illustrations-caps-do.png b/doc/development/ux_guide/img/illustrations-caps-do.png
index 7a2c74382f6..f1030769b94 100644
--- a/doc/development/ux_guide/img/illustrations-caps-do.png
+++ b/doc/development/ux_guide/img/illustrations-caps-do.png
Binary files differ
diff --git a/doc/development/ux_guide/img/illustrations-caps-don't.png b/doc/development/ux_guide/img/illustrations-caps-don't.png
index 848f72dbe30..ab7abcaaf6f 100644
--- a/doc/development/ux_guide/img/illustrations-caps-don't.png
+++ b/doc/development/ux_guide/img/illustrations-caps-don't.png
Binary files differ
diff --git a/doc/development/ux_guide/img/james-mackey.png b/doc/development/ux_guide/img/james-mackey.png
index c8f9097f69f..f51a45c437b 100644
--- a/doc/development/ux_guide/img/james-mackey.png
+++ b/doc/development/ux_guide/img/james-mackey.png
Binary files differ
diff --git a/doc/development/ux_guide/img/karolina-plaskaty.png b/doc/development/ux_guide/img/karolina-plaskaty.png
index ae2e98b7bad..d1c9528dd5a 100644
--- a/doc/development/ux_guide/img/karolina-plaskaty.png
+++ b/doc/development/ux_guide/img/karolina-plaskaty.png
Binary files differ
diff --git a/doc/development/ux_guide/img/matthieu-poirier.png b/doc/development/ux_guide/img/matthieu-poirier.png
index dd21948ebe2..0ecc2d670d6 100644
--- a/doc/development/ux_guide/img/matthieu-poirier.png
+++ b/doc/development/ux_guide/img/matthieu-poirier.png
Binary files differ
diff --git a/doc/development/ux_guide/img/modals-general-confimation-dialog.png b/doc/development/ux_guide/img/modals-general-confimation-dialog.png
index 00a17374a0b..4ea0ea10ca7 100644
--- a/doc/development/ux_guide/img/modals-general-confimation-dialog.png
+++ b/doc/development/ux_guide/img/modals-general-confimation-dialog.png
Binary files differ
diff --git a/doc/development/ux_guide/img/modals-layout-for-modals.png b/doc/development/ux_guide/img/modals-layout-for-modals.png
index 6c7bc09e750..c481edd8250 100644
--- a/doc/development/ux_guide/img/modals-layout-for-modals.png
+++ b/doc/development/ux_guide/img/modals-layout-for-modals.png
Binary files differ
diff --git a/doc/development/ux_guide/img/modals-special-confimation-dialog.png b/doc/development/ux_guide/img/modals-special-confimation-dialog.png
index bf1e56326c5..d966010158b 100644
--- a/doc/development/ux_guide/img/modals-special-confimation-dialog.png
+++ b/doc/development/ux_guide/img/modals-special-confimation-dialog.png
Binary files differ
diff --git a/doc/development/ux_guide/img/modals-three-buttons.png b/doc/development/ux_guide/img/modals-three-buttons.png
index 519439e64e4..157d1b650bf 100644
--- a/doc/development/ux_guide/img/modals-three-buttons.png
+++ b/doc/development/ux_guide/img/modals-three-buttons.png
Binary files differ
diff --git a/doc/development/ux_guide/img/nazim-ramesh.png b/doc/development/ux_guide/img/nazim-ramesh.png
index cc3e197679d..dad2b37010b 100644
--- a/doc/development/ux_guide/img/nazim-ramesh.png
+++ b/doc/development/ux_guide/img/nazim-ramesh.png
Binary files differ
diff --git a/doc/development/ux_guide/img/popover-placement-above.png b/doc/development/ux_guide/img/popover-placement-above.png
index 1aa044bfc9c..84c9c878ec2 100644
--- a/doc/development/ux_guide/img/popover-placement-above.png
+++ b/doc/development/ux_guide/img/popover-placement-above.png
Binary files differ
diff --git a/doc/development/ux_guide/img/popover-placement-below.png b/doc/development/ux_guide/img/popover-placement-below.png
index 2d6ab8a1618..f6f18199ab6 100644
--- a/doc/development/ux_guide/img/popover-placement-below.png
+++ b/doc/development/ux_guide/img/popover-placement-below.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 3af0b56c8fb..f6cd212ecfd 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-systeminformationblock.png b/doc/development/ux_guide/img/surfaces-systeminformationblock.png
index 9f42f1d4dd0..f3313add2b8 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 53208727c64..eaa7f70c0c7 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 061f82e4df0..da49c192878 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 40c4f051cd0..4f5884c4b48 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_project_info.png b/doc/gitlab-basics/img/create_new_project_info.png
index b4119dc046a..2693a7f9a6d 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_new.png b/doc/gitlab-basics/img/fork_new.png
index fa185fdaca1..7bbc3d8fbae 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_select_branch.png b/doc/gitlab-basics/img/merge_request_select_branch.png
index 57ea0e65f34..b1dec975f9b 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/profile_settings.png b/doc/gitlab-basics/img/profile_settings.png
index aaa1a39313d..b91b698fb18 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_paste_pub.png b/doc/gitlab-basics/img/profile_settings_ssh_keys_paste_pub.png
index 5e501ec86ef..0b1c64a72f3 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 7ebb8973ef0..8014f1d5301 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 89a04c17fed..02ca0bf7478 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/img/devops_lifecycle.png b/doc/img/devops_lifecycle.png
index 0616be46df8..0b15e9619a5 100644
--- a/doc/img/devops_lifecycle.png
+++ b/doc/img/devops_lifecycle.png
Binary files differ
diff --git a/doc/install/google_cloud_platform/img/boot_disk.png b/doc/install/google_cloud_platform/img/boot_disk.png
index 37b2d9eaae7..b9f7eed6601 100644
--- a/doc/install/google_cloud_platform/img/boot_disk.png
+++ b/doc/install/google_cloud_platform/img/boot_disk.png
Binary files differ
diff --git a/doc/install/google_cloud_platform/img/first_signin.png b/doc/install/google_cloud_platform/img/first_signin.png
index 6eb3392d674..1e218abf63d 100644
--- a/doc/install/google_cloud_platform/img/first_signin.png
+++ b/doc/install/google_cloud_platform/img/first_signin.png
Binary files differ
diff --git a/doc/install/google_cloud_platform/img/gcp_landing.png b/doc/install/google_cloud_platform/img/gcp_landing.png
index d6390c4dd4f..92a9873728c 100644
--- a/doc/install/google_cloud_platform/img/gcp_landing.png
+++ b/doc/install/google_cloud_platform/img/gcp_landing.png
Binary files differ
diff --git a/doc/install/google_cloud_platform/img/launch_vm.png b/doc/install/google_cloud_platform/img/launch_vm.png
index 3fd13f232bb..53cb23277fd 100644
--- a/doc/install/google_cloud_platform/img/launch_vm.png
+++ b/doc/install/google_cloud_platform/img/launch_vm.png
Binary files differ
diff --git a/doc/install/google_cloud_platform/img/ssh_terminal.png b/doc/install/google_cloud_platform/img/ssh_terminal.png
index 6a1a418d8e9..171cb572074 100644
--- a/doc/install/google_cloud_platform/img/ssh_terminal.png
+++ b/doc/install/google_cloud_platform/img/ssh_terminal.png
Binary files differ
diff --git a/doc/install/google_cloud_platform/img/vm_created.png b/doc/install/google_cloud_platform/img/vm_created.png
index fb467f40838..0ba422af60c 100644
--- a/doc/install/google_cloud_platform/img/vm_created.png
+++ b/doc/install/google_cloud_platform/img/vm_created.png
Binary files differ
diff --git a/doc/install/google_cloud_platform/img/vm_details.png b/doc/install/google_cloud_platform/img/vm_details.png
index 2d230416a4b..85b9ca066c8 100644
--- a/doc/install/google_cloud_platform/img/vm_details.png
+++ b/doc/install/google_cloud_platform/img/vm_details.png
Binary files differ
diff --git a/doc/install/installation.md b/doc/install/installation.md
index a310f12b29e..2d657163721 100644
--- a/doc/install/installation.md
+++ b/doc/install/installation.md
@@ -457,11 +457,35 @@ GitLab-Pages uses [GNU Make](https://www.gnu.org/software/make/). This step is o
sudo -u git -H git checkout v$(</home/git/gitlab/GITLAB_PAGES_VERSION)
sudo -u git -H make
+### Install Gitaly
+
+ # Fetch Gitaly source with Git and compile with Go
+ sudo -u git -H bundle exec rake "gitlab:gitaly:install[/home/git/gitaly]" RAILS_ENV=production
+
+You can specify a different Git repository by providing it as an extra parameter:
+
+ sudo -u git -H bundle exec rake "gitlab:gitaly:install[/home/git/gitaly,https://example.com/gitaly.git]" RAILS_ENV=production
+
+Next, make sure gitaly configured:
+
+ # Restrict Gitaly socket access
+ sudo chmod 0700 /home/git/gitlab/tmp/sockets/private
+ sudo chown git /home/git/gitlab/tmp/sockets/private
+
+ # If you are using non-default settings you need to update config.toml
+ cd /home/git/gitaly
+ sudo -u git -H editor config.toml
+
+For more information about configuring Gitaly see
+[doc/administration/gitaly](../administration/gitaly).
+
### Initialize Database and Activate Advanced Features
sudo -u git -H bundle exec rake gitlab:setup RAILS_ENV=production
-
# Type 'yes' to create the database tables.
+
+ # or you can skip the question by adding force=yes
+ sudo -u git -H bundle exec rake gitlab:setup RAILS_ENV=production force=yes
# When done you see 'Administrator account created:'
@@ -491,28 +515,6 @@ Make GitLab start on boot:
sudo update-rc.d gitlab defaults 21
-### Install Gitaly
-
- # Fetch Gitaly source with Git and compile with Go
- sudo -u git -H bundle exec rake "gitlab:gitaly:install[/home/git/gitaly,/home/git/repositories]" RAILS_ENV=production
-
-You can specify a different Git repository by providing it as an extra parameter:
-
- sudo -u git -H bundle exec rake "gitlab:gitaly:install[/home/git/gitaly,/home/git/repositories,https://example.com/gitaly.git]" RAILS_ENV=production
-
-Next, make sure gitaly configured:
-
- # Restrict Gitaly socket access
- sudo chmod 0700 /home/git/gitlab/tmp/sockets/private
- sudo chown git /home/git/gitlab/tmp/sockets/private
-
- # If you are using non-default settings you need to update config.toml
- cd /home/git/gitaly
- sudo -u git -H editor config.toml
-
-For more information about configuring Gitaly see
-[doc/administration/gitaly](../administration/gitaly).
-
### Setup Logrotate
sudo cp lib/support/logrotate/gitlab /etc/logrotate.d/gitlab
diff --git a/doc/install/kubernetes/gitlab_chart.md b/doc/install/kubernetes/gitlab_chart.md
index 692f81dd7cd..5a6f26319c7 100644
--- a/doc/install/kubernetes/gitlab_chart.md
+++ b/doc/install/kubernetes/gitlab_chart.md
@@ -1,11 +1,12 @@
# GitLab Helm Chart
-> **Note:** The chart is currently **beta**, if you encounter any problems please [open an issue](https://gitlab.com/charts/gitlab/issues/new).
-For more information on available GitLab Helm Charts, please see our [overview](index.md#chart-overview).
+This is the official and recommended way to install GitLab on a cloud native environment.
+For more information on other available GitLab Helm Charts, see the [charts overview](index.md#chart-overview).
## Introduction
-The `gitlab` chart is the best way to operate GitLab on Kubernetes. This chart contains all the required components to get started, and can scale to large deployments.
+The `gitlab` chart is the best way to operate GitLab on Kubernetes. This chart
+contains all the required components to get started, and can scale to large deployments.
The default deployment includes:
@@ -14,78 +15,94 @@ The default deployment includes:
- An auto-scaling, unprivileged [GitLab Runner](https://docs.gitlab.com/runner/) using the Kubernetes executor
- Automatically provisioned SSL via [Let's Encrypt](https://letsencrypt.org/).
-### Limitations
+## Limitations
-Some features and functions are not currently available in the beta release.
-For details, see [known issues and limitations](https://gitlab.com/charts/gitlab/blob/master/doc/architecture/beta.md#known-issues-and-limitations) in the charts repository.
+Some features of GitLab are not currently available:
-## Prerequisites
+- [GitLab Pages](https://gitlab.com/charts/gitlab/issues/37)
+- [GitLab Geo](https://gitlab.com/charts/gitlab/issues/8)
+- [No in-cluster HA database](https://gitlab.com/charts/gitlab/issues/48)
+- MySQL will not be supported, as support is [deprecated within GitLab](https://docs.gitlab.com/omnibus/settings/database.html#using-a-mysql-database-management-server-enterprise-edition-only)
-In order to deploy GitLab on Kubernetes, a few prerequisites are required.
+## Installing GitLab using the Helm Chart
+
+The `gitlab` chart includes all required dependencies, and takes a few minutes
+to deploy.
+
+TIP: **Tip:**
+For production deployments, we strongly recommend using the
+[detailed installation instructions](https://gitlab.com/charts/gitlab/blob/master/doc/installation/README.md)
+utilizing [external Postgres, Redis, and object storage](https://gitlab.com/charts/gitlab/tree/master/doc/advanced) services.
+
+### Requirements
+
+In order to deploy GitLab on Kubernetes, the following are required:
1. `helm` and `kubectl` [installed on your computer](preparation/tools_installation.md).
1. A Kubernetes cluster, version 1.8 or higher. 6vCPU and 16GB of RAM is recommended.
- * [Google GKE](https://cloud.google.com/kubernetes-engine/docs/how-to/creating-a-container-cluster)
- * [Amazon EKS](https://docs.aws.amazon.com/eks/latest/userguide/getting-started.html)
- * [Microsoft AKS](https://docs.microsoft.com/en-us/azure/aks/kubernetes-walkthrough-portal)
+ - [Google GKE](https://cloud.google.com/kubernetes-engine/docs/how-to/creating-a-container-cluster)
+ - [Amazon EKS](https://docs.aws.amazon.com/eks/latest/userguide/getting-started.html)
+ - [Microsoft AKS](https://docs.microsoft.com/en-us/azure/aks/kubernetes-walkthrough-portal)
1. A [wildcard DNS entry and external IP address](preparation/networking.md)
1. [Authenticate and connect](preparation/connect.md) to the cluster
1. Configure and initialize [Helm Tiller](preparation/tiller.md).
-## Configuring and Installing GitLab
+### Deployment of GitLab to Kubernetes
-> **Note**: For deployments to Amazon EKS, there are [additional configuration requirements](preparation/eks.md).
+To deploy GitLab, the following three parameters are required:
-For simple deployments, running all services within Kubernetes, only three parameters are required:
-- `global.hosts.domain`: the [base domain](preparation/networking.md) of the wildcard host entry. For example, `mycompany.io` if the wild card entry is `*.mycompany.io`.
-- `global.hosts.externalIP`: the [external IP](preparation/networking.md) which the wildcard DNS resolves to.
-- `certmanager-issuer.email`: Email address to use when requesting new SSL certificates from Let's Encrypt.
+- `global.hosts.domain`: the [base domain](preparation/networking.md) of the
+ wildcard host entry. For example, `exampe.com` if the wild card entry is
+ `*.example.com`.
+- `global.hosts.externalIP`: the [external IP](preparation/networking.md) which
+ the wildcard DNS resolves to.
+- `certmanager-issuer.email`: the email address to use when requesting new SSL
+ certificates from Let's Encrypt.
-For enterprise deployments, or to utilize advanced settings, please use the instructions in the [`gitlab` chart project](https://gitlab.com/charts/gitlab) for the most up to date directions.
-- [External Postgres, Redis, and other dependencies](https://gitlab.com/charts/gitlab/tree/master/doc/advanced)
-- [Persistence settings](https://gitlab.com/charts/gitlab/blob/master/doc/installation/storage.md)
-- [Manual TLS certificates](https://gitlab.com/charts/gitlab/blob/master/doc/installation/tls.md)
-- [Manual secret creation](https://gitlab.com/charts/gitlab/blob/master/doc/installation/secrets.md)
+NOTE: **Note:**
+For deployments to Amazon EKS, there are
+[additional configuration requirements](preparation/eks.md). A full list of
+configuration options is [also available](https://gitlab.com/charts/gitlab/blob/master/doc/installation/command-line-options.md).
-For additional configuration options, consult the [full list of settings](https://gitlab.com/charts/gitlab/blob/master/doc/installation/command-line-options.md).
+Once you have all of your configuration options collected, you can get any
+dependencies and run helm. In this example, the helm release is named "gitlab":
-## Installing GitLab using the Helm Chart
-
-Once you have all of your configuration options collected, we can get any dependencies and
-run helm. In this example, we've named our helm release "gitlab".
-
-```
+```sh
helm repo add gitlab https://charts.gitlab.io/
-helm update
+helm repo update
helm upgrade --install gitlab gitlab/gitlab \
--timeout 600 \
- --set global.hosts.domain=example.local \
+ --set global.hosts.domain=example.com \
--set global.hosts.externalIP=10.10.10.10 \
- --set certmanager-issuer.email=me@example.local
+ --set certmanager-issuer.email=email@example.com
```
### Monitoring the Deployment
-This will output the list of resources installed once the deployment finishes which may take 5-10 minutes.
+This will output the list of resources installed once the deployment finishes,
+which may take 5-10 minutes.
-The status of the deployment can be checked by running `helm status gitlab` which can also be done while
-the deployment is taking place if you run the command in another terminal.
+The status of the deployment can be checked by running `helm status gitlab`
+which can also be done while the deployment is taking place if you run the
+command in another terminal.
### Initial login
-You can access the GitLab instance by visiting the domain name beginning with `gitlab.` followed by the domain specified during installation. From the example above, the URL would be `https://gitlab.example.local`.
+You can access the GitLab instance by visiting the domain name beginning with
+`gitlab.` followed by the domain specified during installation. From the example
+above, the URL would be `https://gitlab.example.com`.
If you manually created the secret for initial root password, you
can use that to sign in as `root` user. If not, Gitlab automatically
created a random password for `root` user. This can be extracted by the
following command (replace `<name>` by name of the release - which is `gitlab`
-if you used the command above).
+if you used the command above):
-```
-kubectl get secret <name>-gitlab-initial-root-password -ojsonpath={.data.password} | base64 --decode
+```sh
+kubectl get secret <name>-gitlab-initial-root-password -ojsonpath={.data.password} | base64 --decode ; echo
```
-## Outgoing email
+### Outgoing email
By default outgoing email is disabled. To enable it, provide details for your SMTP server
using the `global.smtp` and `global.email` settings. You can find details for these settings in the
@@ -95,14 +112,14 @@ If your SMTP server requires authentication make sure to read the section on pro
your password in the [secrets documentation](https://gitlab.com/charts/gitlab/blob/master/doc/installation/secrets.md#smtp-password).
You can disable authentication settings with `--set global.smtp.authentication=""`.
-If your Kubernetes cluster is on GKE, be aware that smtp [ports 25, 465, and 587
+If your Kubernetes cluster is on GKE, be aware that SMTP ports [25, 465, and 587
are blocked](https://cloud.google.com/compute/docs/tutorials/sending-mail/#using_standard_email_ports).
-## Deploying the Community Edition
+### Deploying the Community Edition
To deploy the Community Edition, include these options in your `helm install` command:
-```shell
+```sh
--set gitlab.migrations.image.repository=registry.gitlab.com/gitlab-org/build/cng/gitlab-rails-ce
--set gitlab.sidekiq.image.repository=registry.gitlab.com/gitlab-org/build/cng/gitlab-sidekiq-ce
--set gitlab.unicorn.image.repository=registry.gitlab.com/gitlab-org/build/cng/gitlab-unicorn-ce
@@ -113,15 +130,15 @@ To deploy the Community Edition, include these options in your `helm install` co
Once your GitLab Chart is installed, configuration changes and chart updates
should be done using `helm upgrade`:
-```bash
-helm upgrade -f values.yaml gitlab gitlab/gitlab
+```sh
+helm upgrade --reuse-values gitlab gitlab/gitlab
```
## Uninstalling GitLab using the Helm Chart
To uninstall the GitLab Chart, run the following:
-```bash
+```sh
helm delete gitlab
```
diff --git a/doc/install/kubernetes/gitlab_omnibus.md b/doc/install/kubernetes/gitlab_omnibus.md
index c2c8a7a92fd..d80cb6ad374 100644
--- a/doc/install/kubernetes/gitlab_omnibus.md
+++ b/doc/install/kubernetes/gitlab_omnibus.md
@@ -1,18 +1,24 @@
# GitLab-Omnibus Helm Chart
-> **Note:**.
-* This chart has been tested on Google Kubernetes Engine and Azure Container Service.
-**[This chart is beta](#limitations), and is the best way to install GitLab on Kubernetes today.** A new [cloud native GitLab chart](index.md#cloud-native-gitlab-chart) is in development with increased scalability and resilience, among other benefits. Once available, the cloud native chart will be the recommended installation method for Kubernetes, and this chart will be deprecated.
+CAUTION: **Caution:**
+This chart is **deprecated**. We recommend using the [`gitlab` chart](gitlab_chart.md)
+instead. A comparison of the two charts is available in [this video](https://youtu.be/Z6jWR8Z8dv8).
-For more information on available GitLab Helm Charts, please see our [overview](index.md#chart-overview).
+For more information on available GitLab Helm Charts, see the [charts overview](index.md#chart-overview).
-This work is based partially on: https://github.com/lwolf/kubernetes-gitlab/. GitLab would like to thank Sergey Nuzhdin for his work.
+- This GitLab-Omnibus chart has been tested on Google Kubernetes Engine and Azure Container Service.
+- This work is based partially on: https://github.com/lwolf/kubernetes-gitlab/. GitLab would like to thank Sergey Nuzhdin for his work.
## Introduction
-This chart provides an easy way to get started with GitLab, provisioning an installation with nearly all functionality enabled. SSL is automatically provisioned via [Let's Encrypt](https://letsencrypt.org/).
+This chart provides an easy way to get started with GitLab, provisioning an
+installation with nearly all functionality enabled. SSL is automatically
+provisioned via [Let's Encrypt](https://letsencrypt.org/).
-This Helm chart is in beta, and is suited for small to medium deployments. It will be deprecated by the [cloud native GitLab chart](https://gitlab.com/charts/helm.gitlab.io/blob/master/README.md) once available. Due to the significant architectural changes, migrating will require backing up data out of this instance and importing it into the new deployment.
+This Helm chart is suited for small to medium deployments and is **deprecated**
+and replaced by the [cloud native GitLab chart](https://gitlab.com/charts/helm.gitlab.io/blob/master/README.md).
+Due to the significant architectural changes, migrating will require backing up
+data out of this instance and importing it into the new deployment.
The deployment includes:
@@ -23,14 +29,12 @@ The deployment includes:
- [NGINX Ingress](https://github.com/kubernetes/charts/tree/master/stable/nginx-ingress)
- Persistent Volume Claims for Data, Registry, Postgres, and Redis
-### Limitations
+## Limitations
-* This chart is in beta, and suited for small to medium size deployments. [High Availability](https://docs.gitlab.com/ee/administration/high_availability/) and [Geo](https://docs.gitlab.com/ee/gitlab-geo/README.html) are not supported.
-* A new generation [cloud native GitLab chart](index.md#cloud-native-gitlab-chart) is in development, and will deprecate this chart. Due to the difficulty in supporting upgrades to the new architecture, migrating will require exporting data out of this instance and importing it into the new deployment. We plan to release the new chart in beta by the end of 2017.
+[High Availability](../../administration/high_availability/README.md) and
+[Geo](https://docs.gitlab.com/ee/gitlab-geo/README.html) are not supported.
-For more information on available GitLab Helm Charts, please see our [overview](index.md#chart-overview).
-
-## Prerequisites
+## Requirements
- _At least_ 4 GB of RAM available on your cluster. 41GB of storage and 2 CPU are also required.
- Kubernetes 1.4+ with Beta APIs enabled
@@ -39,43 +43,65 @@ For more information on available GitLab Helm Charts, please see our [overview](
- The `kubectl` CLI installed locally and authenticated for the cluster
- The [Helm client](https://github.com/kubernetes/helm/blob/master/docs/quickstart.md) installed locally on your machine
-### Networking Prerequisites
+### Networking requirements
-This chart configures a GitLab server and Kubernetes cluster which can support dynamic [Review Apps](https://docs.gitlab.com/ee/ci/review_apps/index.html), as well as services like the integrated [Container Registry](https://docs.gitlab.com/ee/user/project/container_registry.html) and [Mattermost](https://docs.gitlab.com/omnibus/gitlab-mattermost/).
+This chart configures a GitLab server and Kubernetes cluster which can support
+dynamic [Review Apps](../../ci/review_apps/index.md), as well as services like
+the integrated [Container Registry](../../user/project/container_registry.md)
+and [Mattermost](https://docs.gitlab.com/omnibus/gitlab-mattermost/).
-To support the GitLab services and dynamic environments, a wildcard DNS entry is required which resolves to the [Load Balancer](#load-balancer-ip) or [External IP](#external-ip). Configuration of the DNS entry will depend upon the DNS service being used.
+To support the GitLab services and dynamic environments, a wildcard DNS entry
+is required which resolves to the [load balancer](#load-balancer-ip) or
+[external IP](#external-ip). Configuration of the DNS entry will depend upon
+the DNS service being used.
-#### External IP (Recommended)
+#### External IP (recommended)
-To provision an external IP on GCP and Azure, simply request a new address from the Networking section. Ensure that the region matches the region your container cluster is created in. Note, it is important that the IP is not assigned at this point in time. It will be automatically assigned once the Helm chart is installed, and assigned to the Load Balancer.
+To provision an external IP on GCP and Azure, simply request a new address from
+the Networking section. Ensure that the region matches the region your container
+cluster is created in. It is important that the IP is not assigned at this point
+in time. It will be automatically assigned once the Helm chart is installed,
+and assigned to the Load Balancer.
-Now that an external IP address has been allocated, ensure that the wildcard DNS entry you would like to use resolves to this IP. Please consult the documentation for your DNS service for more information on creating DNS records.
+Now that an external IP address has been allocated, ensure that the wildcard
+DNS entry you would like to use resolves to this IP. Please consult the
+documentation for your DNS service for more information on creating DNS records.
-Finally, set the `baseIP` setting to this IP address when [deploying GitLab](#configuring-and-installing-gitlab).
+Finally, set the `baseIP` setting to this IP address when
+[deploying GitLab](#configuring-and-installing-gitlab).
#### Load Balancer IP
-If you do not specify a `baseIP`, an IP will be assigned to the Load Balancer or Ingress. You can retrieve this IP by running the following command *after* deploying GitLab:
+If you do not specify a `baseIP`, an IP will be assigned to the Load Balancer or
+Ingress. You can retrieve this IP by running the following command *after* deploying GitLab:
-`kubectl get svc -w --namespace nginx-ingress nginx`
+```sh
+kubectl get svc -w --namespace nginx-ingress nginx
+```
-The IP address will be displayed in the `EXTERNAL-IP` field, and should be used to configure the Wildcard DNS entry. For more information on creating a wildcard DNS entry, consult the documentation for the DNS server you are using.
+The IP address will be displayed in the `EXTERNAL-IP` field, and should be used
+to configure the Wildcard DNS entry. For more information on creating a wildcard
+DNS entry, consult the documentation for the DNS server you are using.
-For production deployments of GitLab, we strongly recommend using an [External IP](#external-ip).
+For production deployments of GitLab, we strongly recommend using a
+[external IP](#external-ip).
## Configuring and Installing GitLab
-For most installations, only two parameters are required:
+For most installations, two parameters are required:
+
- `baseDomain`: the [base domain](#networking-prerequisites) of the wildcard host entry. For example, `mycompany.io` if the wild card entry is `*.mycompany.io`.
- `legoEmail`: Email address to use when requesting new SSL certificates from Let's Encrypt.
Other common configuration options:
+
- `baseIP`: the desired [external IP address](#external-ip-recommended)
- `gitlab`: Choose the [desired edition](https://about.gitlab.com/pricing), either `ee` or `ce`. `ce` is the default.
- `gitlabEELicense`: For Enterprise Edition, the [license](https://docs.gitlab.com/ee/user/admin_area/license.html) can be installed directly via the Chart
- `provider`: Optimizes the deployment for a cloud provider. The default is `gke` for [Google Kubernetes Engine](https://cloud.google.com/kubernetes-engine/), with `acs` also supported for the [Azure Container Service](https://azure.microsoft.com/en-us/services/container-service/).
-For additional configuration options, consult the [values.yaml](https://gitlab.com/charts/charts.gitlab.io/blob/master/charts/gitlab-omnibus/values.yaml).
+For additional configuration options, consult the
+[`values.yaml`](https://gitlab.com/charts/charts.gitlab.io/blob/master/charts/gitlab-omnibus/values.yaml).
### Choosing a different GitLab release version
@@ -92,13 +118,14 @@ The different images can be found in the [gitlab-ce](https://hub.docker.com/r/gi
repositories on Docker Hub.
### Persistent storage
-> **Note:**
-If you are using a machine type with support for less than 4 attached disks, like an Azure trial, you should disable dedicated storage for Postgres and Redis.
-By default, persistent storage is enabled for GitLab and the charts it depends
-on (Redis and PostgreSQL).
+NOTE: **Note:**
+If you are using a machine type with support for less than 4 attached disks,
+like an Azure trial, you should disable dedicated storage for Postgres and Redis.
-Components can have their claim size set from your `values.yaml`, along with whether to provision separate storage for Postgres and Redis.
+By default, persistent storage is enabled for GitLab and the charts it depends
+on (Redis and PostgreSQL). Components can have their claim size set from your
+`values.yaml`, along with whether to provision separate storage for Postgres and Redis.
Basic configuration:
@@ -117,14 +144,23 @@ gitlabConfigStorageSize: 1Gi
### Routing and SSL
-Ingress routing and SSL are automatically configured within this Chart. An NGINX ingress is provisioned and configured, and will route traffic to any service. SSL certificates are automatically created and configured by [kube-lego](https://github.com/kubernetes/charts/tree/master/stable/kube-lego).
+Ingress routing and SSL are automatically configured within this Chart. An NGINX
+ingress is provisioned and configured, and will route traffic to any service.
+SSL certificates are automatically created and configured by
+[kube-lego](https://github.com/kubernetes/charts/tree/master/stable/kube-lego).
-> **Note:**
-Let's Encrypt limits a single TLD to five certificate requests within a single week. This means that common DNS wildcard services like [nip.io](http://nip.io) are unlikely to work.
+NOTE: **Note:**
+Let's Encrypt limits a single TLD to five certificate requests within a single
+week. This means that common DNS wildcard services like [nip.io](http://nip.io)
+and [xip.io](http://xip.io) are unlikely to work.
## Installing GitLab using the Helm Chart
-> **Note:**
-You may see a temporary error message `SchedulerPredicates failed due to PersistentVolumeClaim is not bound` while storage provisions. Once the storage provisions, the pods will automatically start. This may take a couple minutes depending on your cloud provider. If the error persists, please review the [prerequisites](#prerequisites) to ensure you have enough RAM, CPU, and storage.
+
+NOTE: **Note:**
+You may see a temporary error message `SchedulerPredicates failed due to PersistentVolumeClaim is not bound`
+while storage provisions. Once the storage provisions, the pods will automatically start.
+This may take a couple minutes depending on your cloud provider. If the error persists,
+please review the [requirements sections](#requirements) to ensure you have enough RAM, CPU, and storage.
Add the GitLab Helm repository and initialize Helm:
@@ -133,15 +169,15 @@ helm init
helm repo add gitlab https://charts.gitlab.io
```
-Once you have reviewed the [configuration settings](#configuring-and-installing-gitlab) you can install the chart. We recommending saving your configuration options in a `values.yaml` file for easier upgrades in the future.
-
-For example:
+Once you have reviewed the [configuration settings](#configuring-and-installing-gitlab),
+you can install the chart. We recommending saving your configuration options in a
+`values.yaml` file for easier upgrades in the future:
```bash
helm install --name gitlab -f values.yaml gitlab/gitlab-omnibus
```
-or passing them on the command line:
+Or you can pass them on the command line:
```bash
helm install --name gitlab --set baseDomain=gitlab.io,baseIP=192.0.2.1,gitlab=ee,gitlabEELicense=$LICENSE,legoEmail=email@gitlab.com gitlab/gitlab-omnibus
@@ -149,8 +185,11 @@ helm install --name gitlab --set baseDomain=gitlab.io,baseIP=192.0.2.1,gitlab=ee
## Updating GitLab using the Helm Chart
->**Note**: If you are upgrading from a previous version to 0.1.35 or above, you will need to change the access mode values for GitLab's storage. To do this, set the following in `values.yaml` or on the CLI:
-```
+If you are upgrading from a previous version to 0.1.35 or above, you will need to
+change the access mode values for GitLab's storage. To do this, set the following
+in `values.yaml` or on the CLI:
+
+```sh
gitlabDataAccessMode=ReadWriteMany
gitlabRegistryAccessMode=ReadWriteMany
gitlabConfigAccessMode=ReadWriteMany
@@ -159,15 +198,20 @@ gitlabConfigAccessMode=ReadWriteMany
Once your GitLab Chart is installed, configuration changes and chart updates
should be done using `helm upgrade`:
-```bash
+```sh
helm upgrade -f values.yaml gitlab gitlab/gitlab-omnibus
```
## Upgrading from CE to EE using the Helm Chart
-If you have installed the Community Edition using this chart, upgrading to Enterprise Edition is easy.
+If you have installed the Community Edition using this chart, upgrading to
+Enterprise Edition is easy.
-If you are using a `values.yaml` file to specify the configuration options, edit the file and set `gitlab=ee`. If you would like to run a specific version of GitLab EE, set `gitlabEEImage` to be the desired GitLab [docker image](https://hub.docker.com/r/gitlab/gitlab-ee/tags/). Then you can use `helm upgrade` to update your GitLab instance to EE:
+If you are using a `values.yaml` file to specify the configuration options, edit
+the file and set `gitlab=ee`. If you would like to run a specific version of
+GitLab EE, set `gitlabEEImage` to be the desired GitLab
+[docker image](https://hub.docker.com/r/gitlab/gitlab-ee/tags/). Then you can
+use `helm upgrade` to update your GitLab instance to EE:
```bash
helm upgrade -f values.yaml gitlab gitlab/gitlab-omnibus
@@ -191,9 +235,12 @@ helm delete gitlab
### Storage errors when updating `gitlab-omnibus` versions prior to 0.1.35
-Users upgrading `gitlab-omnibus` from a version prior to 0.1.35, may see an error like: `Error: UPGRADE FAILED: PersistentVolumeClaim "gitlab-gitlab-config-storage" is invalid: spec: Forbidden: field is immutable after creation`.
+Users upgrading `gitlab-omnibus` from a version prior to 0.1.35, may see an error
+like: `Error: UPGRADE FAILED: PersistentVolumeClaim "gitlab-gitlab-config-storage" is invalid: spec: Forbidden: field is immutable after creation`.
-This is due to a change in the access mode for GitLab storage in version 0.1.35. To successfully upgrade, the access mode flags must be set to `ReadWriteMany` as detailed in the [update section](#updating-gitlab-using-the-helm-chart).
+This is due to a change in the access mode for GitLab storage in version 0.1.35.
+To successfully upgrade, the access mode flags must be set to `ReadWriteMany`
+as detailed in the [update section](#updating-gitlab-using-the-helm-chart).
[kube-srv]: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services---service-types
[storageclass]: https://kubernetes.io/docs/concepts/storage/persistent-volumes/#storageclasses
diff --git a/doc/install/kubernetes/index.md b/doc/install/kubernetes/index.md
index 6419a9dcb69..e67d5ba4d4c 100644
--- a/doc/install/kubernetes/index.md
+++ b/doc/install/kubernetes/index.md
@@ -4,7 +4,8 @@ description: 'Read through the different methods to deploy GitLab on Kubernetes.
# Installing GitLab on Kubernetes
-> **Note**: These charts have been tested on Google Kubernetes Engine. Other Kubernetes installations may work as well, if not please [open an issue](https://gitlab.com/charts/issues).
+NOTE: **Note**: These charts have been tested on Google Kubernetes Engine. Other
+Kubernetes installations may work as well, if not please [open an issue](https://gitlab.com/charts/issues).
The easiest method to deploy GitLab on [Kubernetes](https://kubernetes.io/) is
to take advantage of GitLab's Helm charts. [Helm] is a package
@@ -14,30 +15,31 @@ should be deployed, upgraded, and configured.
## Chart Overview
-* **[GitLab Chart](gitlab_chart.html)**: The recommended GitLab chart, currently in beta. Supports large deployments with horizontal scaling of individual GitLab components, and does not require NFS.
-* **[GitLab Runner Chart](gitlab_runner_chart.md)**: For deploying just the GitLab Runner.
-* Other Charts
- * [GitLab-Omnibus](gitlab_omnibus.md): Chart based on the Omnibus GitLab linux package, only suitable for small deployments. The chart will be deprecated by the [GitLab chart](#gitlab-chart) when it is GA.
- * [Community Contributed Charts](#community-contributed-charts): Community contributed charts, deprecated by the official GitLab chart.
+- **[GitLab Chart](gitlab_chart.html)**: Deploys GitLab on Kubernetes. Includes all the required components to get started, and can scale to large deployments.
+- **[GitLab Runner Chart](gitlab_runner_chart.md)**: For deploying just the GitLab Runner.
+- Other Charts
+ - [GitLab-Omnibus](gitlab_omnibus.md): Chart based on the Omnibus GitLab package, only suitable for small deployments. Deprecated, we strongly recommend using the [gitlab](#gitlab-chart) chart.
+ - [Community contributed charts](#community-contributed-charts): Community contributed charts.
## GitLab Chart
-> **Note**: This chart is **beta**, while we work on the [remaining items for GA](https://gitlab.com/groups/charts/-/epics/15).
+This chart contains all the required components to get started, and can scale to
+large deployments. It offers a number of benefits:
-The best way to operate GitLab on Kubernetes. This chart contains all the required components to get started, and can scale to large deployments.
+- Horizontal scaling of individual components
+- No requirement for shared storage to scale
+- Containers do not need `root` permissions
+- Automatic SSL with Let's Encrypt
+- and plenty more.
-This chart offers a number of benefits:
-* Horizontal scaling of individual components
-* No requirement for shared storage to scale
-* Containers do not need `root` permissions
-* Automatic SSL with Let's Encrypt
-* and plenty more.
-
-Learn more about the [GitLab chart here](gitlab_chart.md) and [here [Video]](https://youtu.be/Z6jWR8Z8dv8).
+Learn more about the [GitLab chart](gitlab_chart.md).
## GitLab Runner Chart
-If you already have a GitLab instance running, inside or outside of Kubernetes, and you'd like to leverage the Runner's [Kubernetes capabilities](https://docs.gitlab.com/runner/executors/kubernetes.html), it can be deployed with the GitLab Runner chart.
+If you already have a GitLab instance running, inside or outside of Kubernetes,
+and you'd like to leverage the Runner's
+[Kubernetes capabilities](https://docs.gitlab.com/runner/executors/kubernetes.html),
+it can be deployed with the GitLab Runner chart.
Learn more about [gitlab-runner chart](gitlab_runner_chart.md).
@@ -45,11 +47,18 @@ Learn more about [gitlab-runner chart](gitlab_runner_chart.md).
### GitLab-Omnibus Chart
-> **Note**: This chart is beta, and **will be deprecated** when the [`gitlab`](#gitlab-chart) chart is GA.
+CAUTION: **Deprecated:**
+This chart is **deprecated**. We recommend using the [GitLab Chart](gitlab_chart.md)
+instead. A comparison of the two charts is available in [this video](https://youtu.be/Z6jWR8Z8dv8).
-It deploys and configures nearly all features of GitLab, including: a [Runner](https://docs.gitlab.com/runner/), [Container Registry](../../user/project/container_registry.html#gitlab-container-registry), [Mattermost](https://docs.gitlab.com/omnibus/gitlab-mattermost/), [automatic SSL](https://github.com/kubernetes/charts/tree/master/stable/kube-lego), and a [load balancer](https://github.com/kubernetes/ingress/tree/master/controllers/nginx). It is based on our [GitLab Omnibus Docker Images](https://docs.gitlab.com/omnibus/docker/README.html).
+This chart is based on the [GitLab Omnibus Docker images](https://docs.gitlab.com/omnibus/docker/).
+It deploys and configures nearly all features of GitLab, including:
-Once the [GitLab chart](#gitlab-chart) is GA, this chart will be deprecated. Migrating to the `gitlab` chart will require exporting data out of this instance and importing it into a new deployment.
+- a [GitLab Runner](https://docs.gitlab.com/runner/)
+- [Container Registry](../../user/project/container_registry.html#gitlab-container-registry)
+- [Mattermost](https://docs.gitlab.com/omnibus/gitlab-mattermost/)
+- [automatic SSL](https://github.com/kubernetes/charts/tree/master/stable/kube-lego)
+- and an [NGINX load balancer](https://github.com/kubernetes/ingress/tree/master/controllers/nginx).
Learn more about the [gitlab-omnibus chart](gitlab_omnibus.md).
diff --git a/doc/install/kubernetes/preparation/connect.md b/doc/install/kubernetes/preparation/connect.md
index fb633c456f5..a3a0cba4bf2 100644
--- a/doc/install/kubernetes/preparation/connect.md
+++ b/doc/install/kubernetes/preparation/connect.md
@@ -2,19 +2,14 @@
In order to deploy software and settings to a cluster, you must connect and authenticate to it.
-* [GKE cluster](#connect-to-gke-cluster)
-* [EKS cluster](#connect-to-eks-cluster)
-* [Local minikube cluster](#connect-to-local-minikube-cluster)
-
## Connect to GKE cluster
-The command for connection to the cluster can be obtained from the [Google Cloud Platform Console](https://console.cloud.google.com/kubernetes/list) by the individual cluster.
-
-Look for the **Connect** button in the clusters list page.
-
-**Or**
+The command for connection to the cluster can be obtained from the
+[Google Cloud Platform Console](https://console.cloud.google.com/kubernetes/list)
+by the individual cluster.
-Use the command below, filling in your cluster's informtion:
+Look for the **Connect** button in the clusters list page or use the command below,
+filling in your cluster's information:
```
gcloud container clusters get-credentials <cluster-name> --zone <zone> --project <project-id>
@@ -22,7 +17,8 @@ gcloud container clusters get-credentials <cluster-name> --zone <zone> --project
## Connect to EKS cluster
-For the most up to date instructions, follow the Amazon EKS documentation on [connecting to a cluster](https://docs.aws.amazon.com/eks/latest/userguide/getting-started.html#eks-configure-kubectl).
+For the most up to date instructions, follow the Amazon EKS documentation on
+[connecting to a cluster](https://docs.aws.amazon.com/eks/latest/userguide/getting-started.html#eks-configure-kubectl).
## Connect to local minikube cluster
diff --git a/doc/install/kubernetes/preparation/networking.md b/doc/install/kubernetes/preparation/networking.md
index b157cf31aa9..34a6130de27 100644
--- a/doc/install/kubernetes/preparation/networking.md
+++ b/doc/install/kubernetes/preparation/networking.md
@@ -1,6 +1,8 @@
# Networking Prerequisites
-> **Note**: Amazon EKS utilizes Elastic Load Balancers, which are addressed by DNS name and cannot be known ahead of time. Skip this section.
+NOTE: **Note:**
+Amazon EKS utilizes Elastic Load Balancers, which are addressed by DNS name and
+cannot be known ahead of time. If you're using EKS, you can skip this section.
The `gitlab` chart configures a GitLab server and Kubernetes cluster which can support dynamic [Review Apps](https://docs.gitlab.com/ee/ci/review_apps/index.html), as well as services like the integrated [Container Registry](https://docs.gitlab.com/ee/user/project/container_registry.html).
@@ -30,7 +32,7 @@ Now that an external IP address has been allocated, ensure that the wildcard DNS
Please consult the documentation for your DNS service for more information on creating DNS records:
-* [Google Domains](https://support.google.com/domains/answer/3290350?hl=en)
-* [GoDaddy](https://www.godaddy.com/help/add-an-a-record-19238)
+- [Google Domains](https://support.google.com/domains/answer/3290350?hl=en)
+- [GoDaddy](https://www.godaddy.com/help/add-an-a-record-19238)
Set `global.hosts.domain` to this DNS name when [deploying GitLab](../gitlab_chart.md#configuring-and-installing-gitlab).
diff --git a/doc/install/kubernetes/preparation/rbac.md b/doc/install/kubernetes/preparation/rbac.md
index 240893526d3..c5f8d7a7e9e 100644
--- a/doc/install/kubernetes/preparation/rbac.md
+++ b/doc/install/kubernetes/preparation/rbac.md
@@ -1,16 +1,20 @@
# Role Based Access Control
-Until Kubernetes 1.7, there were no permissions within a cluster. With the launch of 1.7, there is now a role based access control system ([RBAC](https://kubernetes.io/docs/admin/authorization/rbac/)) which determines what services can perform actions within a cluster.
+Until Kubernetes 1.7, there were no permissions within a cluster. With the launch
+of 1.7, there is now a [role based access control system (RBAC)](https://kubernetes.io/docs/admin/authorization/rbac/)
+which determines what services can perform actions within a cluster.
RBAC affects a few different aspects of GitLab:
-* [Installation of GitLab using Helm](tiller.md#preparing-for-helm-with-rbac)
-* Prometheus monitoring
-* GitLab Runner
-## Checking that RBAC is enabled
+- [Installation of GitLab using Helm](tiller.md#preparing-for-helm-with-rbac)
+- Prometheus monitoring
+- GitLab Runner
-Try listing the current cluster roles, if it fails then `RBAC` is disabled
+## Checking that RBAC is enabled
-This command will output `false` if `RBAC` is disabled and `true` otherwise
+Try listing the current cluster roles, if it fails then `RBAC` is disabled.
+The following command will output `false` if `RBAC` is disabled and `true` otherwise:
-`kubectl get clusterroles > /dev/null 2>&1 && echo true || echo false`
+```sh
+kubectl get clusterroles > /dev/null 2>&1 && echo true || echo false
+```
diff --git a/doc/install/kubernetes/preparation/tiller.md b/doc/install/kubernetes/preparation/tiller.md
index 016aac2abeb..107df074b3b 100644
--- a/doc/install/kubernetes/preparation/tiller.md
+++ b/doc/install/kubernetes/preparation/tiller.md
@@ -1,10 +1,15 @@
# Configuring and initializing Helm Tiller
-To make use of Helm, you must have a [Kubernetes][k8s-io] cluster. Ensure you can access your cluster using `kubectl`.
+To make use of Helm, you must have a [Kubernetes][k8s-io] cluster. Ensure you can
+access your cluster using `kubectl`.
Helm consists of two parts, the `helm` client and a `tiller` server inside Kubernetes.
-> **Note**: If you are not able to run Tiller in your cluster, for example on OpenShift, it is possible to use [Tiller locally](https://gitlab.com/charts/gitlab/tree/master/doc/helm#local-tiller) and avoid deploying it into the cluster. This should only be used when Tiller cannot be normally deployed.
+NOTE: **Note:**
+If you are not able to run Tiller in your cluster, for example on OpenShift, it
+is possible to use [Tiller locally](https://gitlab.com/charts/gitlab/tree/master/doc/helm#local-tiller)
+and avoid deploying it into the cluster. This should only be used when Tiller
+cannot be normally deployed.
## Initialize Helm and Tiller
diff --git a/doc/install/openshift_and_gitlab/img/add-gitlab-to-project.png b/doc/install/openshift_and_gitlab/img/add-gitlab-to-project.png
index fcad4e59ae3..5b6059dd022 100644
--- a/doc/install/openshift_and_gitlab/img/add-gitlab-to-project.png
+++ b/doc/install/openshift_and_gitlab/img/add-gitlab-to-project.png
Binary files differ
diff --git a/doc/install/openshift_and_gitlab/img/add-to-project.png b/doc/install/openshift_and_gitlab/img/add-to-project.png
index bd915a229f6..f9b00431d00 100644
--- a/doc/install/openshift_and_gitlab/img/add-to-project.png
+++ b/doc/install/openshift_and_gitlab/img/add-to-project.png
Binary files differ
diff --git a/doc/install/openshift_and_gitlab/img/create-project-ui.png b/doc/install/openshift_and_gitlab/img/create-project-ui.png
index e72866f252a..43b151264c5 100644
--- a/doc/install/openshift_and_gitlab/img/create-project-ui.png
+++ b/doc/install/openshift_and_gitlab/img/create-project-ui.png
Binary files differ
diff --git a/doc/install/openshift_and_gitlab/img/gitlab-logs.png b/doc/install/openshift_and_gitlab/img/gitlab-logs.png
index 1e24080c7df..8b90b2f74ac 100644
--- a/doc/install/openshift_and_gitlab/img/gitlab-logs.png
+++ b/doc/install/openshift_and_gitlab/img/gitlab-logs.png
Binary files differ
diff --git a/doc/install/openshift_and_gitlab/img/gitlab-overview.png b/doc/install/openshift_and_gitlab/img/gitlab-overview.png
index 3c5df0ea101..3a7bec7c2bc 100644
--- a/doc/install/openshift_and_gitlab/img/gitlab-overview.png
+++ b/doc/install/openshift_and_gitlab/img/gitlab-overview.png
Binary files differ
diff --git a/doc/install/openshift_and_gitlab/img/gitlab-running.png b/doc/install/openshift_and_gitlab/img/gitlab-running.png
index c7db691cb30..0fcd9f00d08 100644
--- a/doc/install/openshift_and_gitlab/img/gitlab-running.png
+++ b/doc/install/openshift_and_gitlab/img/gitlab-running.png
Binary files differ
diff --git a/doc/install/openshift_and_gitlab/img/gitlab-scale.png b/doc/install/openshift_and_gitlab/img/gitlab-scale.png
index 4903c7d7498..ebae8b588b1 100644
--- a/doc/install/openshift_and_gitlab/img/gitlab-scale.png
+++ b/doc/install/openshift_and_gitlab/img/gitlab-scale.png
Binary files differ
diff --git a/doc/install/openshift_and_gitlab/img/gitlab-settings.png b/doc/install/openshift_and_gitlab/img/gitlab-settings.png
index db4360ffef0..0dd1e1f5b8e 100644
--- a/doc/install/openshift_and_gitlab/img/gitlab-settings.png
+++ b/doc/install/openshift_and_gitlab/img/gitlab-settings.png
Binary files differ
diff --git a/doc/install/openshift_and_gitlab/img/no-resources.png b/doc/install/openshift_and_gitlab/img/no-resources.png
index 480fb766468..1ef0a0b31e5 100644
--- a/doc/install/openshift_and_gitlab/img/no-resources.png
+++ b/doc/install/openshift_and_gitlab/img/no-resources.png
Binary files differ
diff --git a/doc/install/openshift_and_gitlab/img/openshift-infra-project.png b/doc/install/openshift_and_gitlab/img/openshift-infra-project.png
index 8b9f85aa341..e31dda1461c 100644
--- a/doc/install/openshift_and_gitlab/img/openshift-infra-project.png
+++ b/doc/install/openshift_and_gitlab/img/openshift-infra-project.png
Binary files differ
diff --git a/doc/install/openshift_and_gitlab/img/pods-overview.png b/doc/install/openshift_and_gitlab/img/pods-overview.png
index e1cf08bd217..65927f65f4f 100644
--- a/doc/install/openshift_and_gitlab/img/pods-overview.png
+++ b/doc/install/openshift_and_gitlab/img/pods-overview.png
Binary files differ
diff --git a/doc/install/openshift_and_gitlab/img/rc-name.png b/doc/install/openshift_and_gitlab/img/rc-name.png
index 889e34adbec..16d967b8460 100644
--- a/doc/install/openshift_and_gitlab/img/rc-name.png
+++ b/doc/install/openshift_and_gitlab/img/rc-name.png
Binary files differ
diff --git a/doc/install/openshift_and_gitlab/img/running-pods.png b/doc/install/openshift_and_gitlab/img/running-pods.png
index 3fd4e56662f..e08487c881c 100644
--- a/doc/install/openshift_and_gitlab/img/running-pods.png
+++ b/doc/install/openshift_and_gitlab/img/running-pods.png
Binary files differ
diff --git a/doc/install/openshift_and_gitlab/img/storage-volumes.png b/doc/install/openshift_and_gitlab/img/storage-volumes.png
index ae1e5381faa..3fd092919bb 100644
--- a/doc/install/openshift_and_gitlab/img/storage-volumes.png
+++ b/doc/install/openshift_and_gitlab/img/storage-volumes.png
Binary files differ
diff --git a/doc/install/openshift_and_gitlab/img/web-console.png b/doc/install/openshift_and_gitlab/img/web-console.png
index aa1425d4f94..012d7703c73 100644
--- a/doc/install/openshift_and_gitlab/img/web-console.png
+++ b/doc/install/openshift_and_gitlab/img/web-console.png
Binary files differ
diff --git a/doc/integration/img/bitbucket_oauth_keys.png b/doc/integration/img/bitbucket_oauth_keys.png
index 6dd2c7d744e..2f0c0eff784 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/enable_trello_powerup.png b/doc/integration/img/enable_trello_powerup.png
index 65d01f1c38c..f80d0eadc0b 100644
--- a/doc/integration/img/enable_trello_powerup.png
+++ b/doc/integration/img/enable_trello_powerup.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 f145aeae75c..e83f9d5cfdf 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 9463ec1e7a3..7480b144091 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_website_url.png b/doc/integration/img/facebook_website_url.png
index 67d78d13951..7873c9905f1 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/gitlab_app.png b/doc/integration/img/gitlab_app.png
index 8d6a4456fc4..228e8a01305 100644
--- a/doc/integration/img/gitlab_app.png
+++ b/doc/integration/img/gitlab_app.png
Binary files differ
diff --git a/doc/integration/img/google_app.png b/doc/integration/img/google_app.png
index 9fda06dabb1..08f230452b4 100644
--- a/doc/integration/img/google_app.png
+++ b/doc/integration/img/google_app.png
Binary files differ
diff --git a/doc/integration/img/oauth_provider_admin_application.png b/doc/integration/img/oauth_provider_admin_application.png
index c8ecce129c8..353114fea30 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 954681e054e..c4546d8b3f5 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 65cca5f1e1b..21e442b5d04 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 ed99db3476d..ebff8529b4e 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/submit_issue.png b/doc/integration/img/submit_issue.png
index 8accb78faf3..e794eac189e 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 34e3c3ba001..c6a3245b1b1 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/monitoring/performance/img/grafana_dashboard_import.png b/doc/monitoring/performance/img/grafana_dashboard_import.png
index 7761ea00522..fd639ee0eb8 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 3e749eb8f9d..a98e0ed1e7d 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 33fcaaaef64..549ada8343e 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 c18f2147e9d..68a071f5ae2 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 d96a18ebc04..b9563a00e97 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/public_access/img/restrict_visibility_levels.png b/doc/public_access/img/restrict_visibility_levels.png
index c7d4d87981f..e9315cfb701 100644
--- a/doc/public_access/img/restrict_visibility_levels.png
+++ b/doc/public_access/img/restrict_visibility_levels.png
Binary files differ
diff --git a/doc/raketasks/backup_hrz.png b/doc/raketasks/backup_hrz.png
index c9595b236ee..32690b2904c 100644
--- a/doc/raketasks/backup_hrz.png
+++ b/doc/raketasks/backup_hrz.png
Binary files differ
diff --git a/doc/security/img/outbound_requests_section.png b/doc/security/img/outbound_requests_section.png
index 95c9c6ee771..f7783f34cdd 100644
--- a/doc/security/img/outbound_requests_section.png
+++ b/doc/security/img/outbound_requests_section.png
Binary files differ
diff --git a/doc/security/img/ssh_keys_restrictions_settings.png b/doc/security/img/ssh_keys_restrictions_settings.png
index 2e918fd4b3f..94258af3bf9 100644
--- a/doc/security/img/ssh_keys_restrictions_settings.png
+++ b/doc/security/img/ssh_keys_restrictions_settings.png
Binary files differ
diff --git a/doc/security/img/two_factor_authentication_group_settings.png b/doc/security/img/two_factor_authentication_group_settings.png
index a1b3c58bfdc..05d95554fd9 100644
--- a/doc/security/img/two_factor_authentication_group_settings.png
+++ b/doc/security/img/two_factor_authentication_group_settings.png
Binary files differ
diff --git a/doc/security/img/two_factor_authentication_settings.png b/doc/security/img/two_factor_authentication_settings.png
index 6d89be1eb04..2a2208f98bd 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/topics/autodevops/img/guide_environments.png b/doc/topics/autodevops/img/guide_environments.png
index 1d8d5614e64..404db17c57a 100644
--- a/doc/topics/autodevops/img/guide_environments.png
+++ b/doc/topics/autodevops/img/guide_environments.png
Binary files differ
diff --git a/doc/topics/autodevops/img/guide_ide_commit.png b/doc/topics/autodevops/img/guide_ide_commit.png
index 188f60f2a4b..d7be66f4049 100644
--- a/doc/topics/autodevops/img/guide_ide_commit.png
+++ b/doc/topics/autodevops/img/guide_ide_commit.png
Binary files differ
diff --git a/doc/topics/git/numerous_undo_possibilities_in_git/img/branching.png b/doc/topics/git/numerous_undo_possibilities_in_git/img/branching.png
index 9a80c211c99..d8dc9fc8097 100644
--- a/doc/topics/git/numerous_undo_possibilities_in_git/img/branching.png
+++ b/doc/topics/git/numerous_undo_possibilities_in_git/img/branching.png
Binary files differ
diff --git a/doc/topics/git/numerous_undo_possibilities_in_git/img/rebase_reset.png b/doc/topics/git/numerous_undo_possibilities_in_git/img/rebase_reset.png
index ac7ea9ecddc..6506de209f4 100644
--- a/doc/topics/git/numerous_undo_possibilities_in_git/img/rebase_reset.png
+++ b/doc/topics/git/numerous_undo_possibilities_in_git/img/rebase_reset.png
Binary files differ
diff --git a/doc/topics/git/numerous_undo_possibilities_in_git/img/revert.png b/doc/topics/git/numerous_undo_possibilities_in_git/img/revert.png
index 13b3a35ca45..040f8118d72 100644
--- a/doc/topics/git/numerous_undo_possibilities_in_git/img/revert.png
+++ b/doc/topics/git/numerous_undo_possibilities_in_git/img/revert.png
Binary files differ
diff --git a/doc/university/high-availability/aws/README.md b/doc/university/high-availability/aws/README.md
index 8f7bb8636c5..4e7eae19844 100644
--- a/doc/university/high-availability/aws/README.md
+++ b/doc/university/high-availability/aws/README.md
@@ -30,7 +30,7 @@ we'll be using to configure our cloud infrastructure.
### Reference Architecture
-![Reference Architecture](img/reference-arch.png)
+![Reference Architecture](img/reference-arch2.png)
***
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 1e125f301bc..cf32c024bf8 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 590a02b8dbe..875184af310 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/ig.png b/doc/university/high-availability/aws/img/ig.png
index d4fc2d12de8..2798d4beac3 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 650f375ab3c..2a2b80103fb 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 e51c066cee2..d872554fab7 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 afcd9e4af9b..e99497a52a2 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 651cc23b1ab..13130ac96b8 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 c6d1bc350e4..a88caba62c2 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/reference-arch.png b/doc/university/high-availability/aws/img/reference-arch.png
deleted file mode 100644
index 271ee5bc614..00000000000
--- a/doc/university/high-availability/aws/img/reference-arch.png
+++ /dev/null
Binary files differ
diff --git a/doc/university/high-availability/aws/img/reference-arch2.png b/doc/university/high-availability/aws/img/reference-arch2.png
new file mode 100644
index 00000000000..9f50b2f5171
--- /dev/null
+++ b/doc/university/high-availability/aws/img/reference-arch2.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 de910edc948..681c29bf07a 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/production_branch.png b/doc/university/training/gitlab_flow/production_branch.png
index 66456cc51af..956761d7eb8 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 5661e36c4e2..dcb5f97dff0 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/update/10.7-to-10.8.md b/doc/update/10.7-to-10.8.md
index 13101a987f4..7bb628f9740 100644
--- a/doc/update/10.7-to-10.8.md
+++ b/doc/update/10.7-to-10.8.md
@@ -38,16 +38,16 @@ You can check which version you are running with `ruby -v`.
Download Ruby and compile it:
- ```bash
- mkdir /tmp/ruby && cd /tmp/ruby
- curl --remote-name --progress https://cache.ruby-lang.org/pub/ruby/2.3/ruby-2.3.7.tar.gz
- echo '540996fec64984ab6099e34d2f5820b14904f15a ruby-2.3.7.tar.gz' | shasum -c - && tar xzf ruby-2.3.7.tar.gz
- cd ruby-2.3.7
-
- ./configure --disable-install-rdoc
- make
- sudo make install
- ```
+```bash
+mkdir /tmp/ruby && cd /tmp/ruby
+curl --remote-name --progress https://cache.ruby-lang.org/pub/ruby/2.3/ruby-2.3.7.tar.gz
+echo '540996fec64984ab6099e34d2f5820b14904f15a ruby-2.3.7.tar.gz' | shasum -c - && tar xzf ruby-2.3.7.tar.gz
+cd ruby-2.3.7
+
+./configure --disable-install-rdoc
+make
+sudo make install
+```
Install Bundler:
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 182549fc484..8d4cf710176 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/admin_area_default_artifacts_expiration.png b/doc/user/admin_area/settings/img/admin_area_default_artifacts_expiration.png
index 50a86ede56b..723be23e77b 100644
--- a/doc/user/admin_area/settings/img/admin_area_default_artifacts_expiration.png
+++ b/doc/user/admin_area/settings/img/admin_area_default_artifacts_expiration.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 33fd29e2039..3f827f1f7a3 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/domain_blacklist.png b/doc/user/admin_area/settings/img/domain_blacklist.png
index dedd3be1e8f..a7e972b7c0a 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 67abd13f741..c71abf0a226 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/admin_area/settings/img/update-available.png b/doc/user/admin_area/settings/img/update-available.png
index 0dafdad618e..9887e06c7dc 100644
--- a/doc/user/admin_area/settings/img/update-available.png
+++ b/doc/user/admin_area/settings/img/update-available.png
Binary files differ
diff --git a/doc/user/discussions/img/automatically_resolve_outdated_discussions.png b/doc/user/discussions/img/automatically_resolve_outdated_discussions.png
index 9a798ddd178..ba129e7a618 100644
--- a/doc/user/discussions/img/automatically_resolve_outdated_discussions.png
+++ b/doc/user/discussions/img/automatically_resolve_outdated_discussions.png
Binary files differ
diff --git a/doc/user/discussions/img/btn_new_issue_for_all_discussions.png b/doc/user/discussions/img/btn_new_issue_for_all_discussions.png
index b15447ec290..3306bf2e60e 100644
--- a/doc/user/discussions/img/btn_new_issue_for_all_discussions.png
+++ b/doc/user/discussions/img/btn_new_issue_for_all_discussions.png
Binary files differ
diff --git a/doc/user/discussions/img/discussion_comment.png b/doc/user/discussions/img/discussion_comment.png
index 8f66d138922..206ddebf54b 100644
--- a/doc/user/discussions/img/discussion_comment.png
+++ b/doc/user/discussions/img/discussion_comment.png
Binary files differ
diff --git a/doc/user/discussions/img/discussion_lock_system_notes.png b/doc/user/discussions/img/discussion_lock_system_notes.png
index 8e8e8e0bc3d..44a47e3f097 100644
--- a/doc/user/discussions/img/discussion_lock_system_notes.png
+++ b/doc/user/discussions/img/discussion_lock_system_notes.png
Binary files differ
diff --git a/doc/user/discussions/img/discussion_view.png b/doc/user/discussions/img/discussion_view.png
index 2ee1db2eab3..3a2b766ed7e 100644
--- a/doc/user/discussions/img/discussion_view.png
+++ b/doc/user/discussions/img/discussion_view.png
Binary files differ
diff --git a/doc/user/discussions/img/lock_form_member.png b/doc/user/discussions/img/lock_form_member.png
index 01c6308d24c..7bfcb4faae6 100644
--- a/doc/user/discussions/img/lock_form_member.png
+++ b/doc/user/discussions/img/lock_form_member.png
Binary files differ
diff --git a/doc/user/discussions/img/lock_form_non_member.png b/doc/user/discussions/img/lock_form_non_member.png
index 3bb70b69580..59e5fd89499 100644
--- a/doc/user/discussions/img/lock_form_non_member.png
+++ b/doc/user/discussions/img/lock_form_non_member.png
Binary files differ
diff --git a/doc/user/discussions/img/new_issue_for_discussion.png b/doc/user/discussions/img/new_issue_for_discussion.png
index 93c9dad8921..819d872a9a2 100644
--- a/doc/user/discussions/img/new_issue_for_discussion.png
+++ b/doc/user/discussions/img/new_issue_for_discussion.png
Binary files differ
diff --git a/doc/user/discussions/img/only_allow_merge_if_all_discussions_are_resolved_msg.png b/doc/user/discussions/img/only_allow_merge_if_all_discussions_are_resolved_msg.png
index bcdc0250d7c..9044926b0eb 100644
--- a/doc/user/discussions/img/only_allow_merge_if_all_discussions_are_resolved_msg.png
+++ b/doc/user/discussions/img/only_allow_merge_if_all_discussions_are_resolved_msg.png
Binary files differ
diff --git a/doc/user/discussions/img/preview_issue_for_discussion.png b/doc/user/discussions/img/preview_issue_for_discussion.png
index 2ee0653b2ba..30c273ca4c5 100644
--- a/doc/user/discussions/img/preview_issue_for_discussion.png
+++ b/doc/user/discussions/img/preview_issue_for_discussion.png
Binary files differ
diff --git a/doc/user/discussions/img/preview_issue_for_discussions.png b/doc/user/discussions/img/preview_issue_for_discussions.png
index 3fe0a666678..3d906e1b0b0 100644
--- a/doc/user/discussions/img/preview_issue_for_discussions.png
+++ b/doc/user/discussions/img/preview_issue_for_discussions.png
Binary files differ
diff --git a/doc/user/discussions/img/resolve_comment_button.png b/doc/user/discussions/img/resolve_comment_button.png
index 70340108874..7c19fac31a2 100644
--- a/doc/user/discussions/img/resolve_comment_button.png
+++ b/doc/user/discussions/img/resolve_comment_button.png
Binary files differ
diff --git a/doc/user/discussions/img/resolve_discussion_issue_notice.png b/doc/user/discussions/img/resolve_discussion_issue_notice.png
index e0ee6a39ffd..ed50dc1de91 100644
--- a/doc/user/discussions/img/resolve_discussion_issue_notice.png
+++ b/doc/user/discussions/img/resolve_discussion_issue_notice.png
Binary files differ
diff --git a/doc/user/discussions/img/resolve_discussion_open_issue.png b/doc/user/discussions/img/resolve_discussion_open_issue.png
index 98d63278326..9d0a14671d6 100644
--- a/doc/user/discussions/img/resolve_discussion_open_issue.png
+++ b/doc/user/discussions/img/resolve_discussion_open_issue.png
Binary files differ
diff --git a/doc/user/discussions/img/turn_off_lock.png b/doc/user/discussions/img/turn_off_lock.png
index dd05b398a8b..aae1def6f72 100644
--- a/doc/user/discussions/img/turn_off_lock.png
+++ b/doc/user/discussions/img/turn_off_lock.png
Binary files differ
diff --git a/doc/user/discussions/img/turn_on_lock.png b/doc/user/discussions/img/turn_on_lock.png
index 9597da4e14d..f36ffc8831b 100644
--- a/doc/user/discussions/img/turn_on_lock.png
+++ b/doc/user/discussions/img/turn_on_lock.png
Binary files differ
diff --git a/doc/user/group/img/add_new_members.png b/doc/user/group/img/add_new_members.png
index 53f5596de23..99b8e52ea13 100644
--- a/doc/user/group/img/add_new_members.png
+++ b/doc/user/group/img/add_new_members.png
Binary files differ
diff --git a/doc/user/group/img/create_new_group_info.png b/doc/user/group/img/create_new_group_info.png
index 8d2501d9f7a..1ac26fb08d9 100644
--- a/doc/user/group/img/create_new_group_info.png
+++ b/doc/user/group/img/create_new_group_info.png
Binary files differ
diff --git a/doc/user/group/img/create_new_project_from_group.png b/doc/user/group/img/create_new_project_from_group.png
index c35234660db..553cd0759aa 100644
--- a/doc/user/group/img/create_new_project_from_group.png
+++ b/doc/user/group/img/create_new_project_from_group.png
Binary files differ
diff --git a/doc/user/group/img/group_settings.png b/doc/user/group/img/group_settings.png
index 629cd0729aa..1705bf4ce8e 100644
--- a/doc/user/group/img/group_settings.png
+++ b/doc/user/group/img/group_settings.png
Binary files differ
diff --git a/doc/user/group/img/groups.png b/doc/user/group/img/groups.png
index 3173ddce7ff..efdfd5f82cd 100644
--- a/doc/user/group/img/groups.png
+++ b/doc/user/group/img/groups.png
Binary files differ
diff --git a/doc/user/group/img/membership_lock.png b/doc/user/group/img/membership_lock.png
index d31fbb43375..c9ad82c90f2 100644
--- a/doc/user/group/img/membership_lock.png
+++ b/doc/user/group/img/membership_lock.png
Binary files differ
diff --git a/doc/user/group/img/new_group_form.png b/doc/user/group/img/new_group_form.png
index 91727ab5336..1c4d3ec6ceb 100644
--- a/doc/user/group/img/new_group_form.png
+++ b/doc/user/group/img/new_group_form.png
Binary files differ
diff --git a/doc/user/group/img/new_group_from_groups.png b/doc/user/group/img/new_group_from_groups.png
index 9c5dd7ebd8b..ffafac1b1cd 100644
--- a/doc/user/group/img/new_group_from_groups.png
+++ b/doc/user/group/img/new_group_from_groups.png
Binary files differ
diff --git a/doc/user/group/img/new_group_from_other_pages.png b/doc/user/group/img/new_group_from_other_pages.png
index 77427224447..f84501d1ff2 100644
--- a/doc/user/group/img/new_group_from_other_pages.png
+++ b/doc/user/group/img/new_group_from_other_pages.png
Binary files differ
diff --git a/doc/user/group/img/request_access_button.png b/doc/user/group/img/request_access_button.png
index f1aae6afed7..54b490a3bb2 100644
--- a/doc/user/group/img/request_access_button.png
+++ b/doc/user/group/img/request_access_button.png
Binary files differ
diff --git a/doc/user/group/img/select_group_dropdown.png b/doc/user/group/img/select_group_dropdown.png
index 68fc950304c..79eca5d94d5 100644
--- a/doc/user/group/img/select_group_dropdown.png
+++ b/doc/user/group/img/select_group_dropdown.png
Binary files differ
diff --git a/doc/user/group/img/share_with_group_lock.png b/doc/user/group/img/share_with_group_lock.png
index c0f25389eaf..77b00d8a248 100644
--- a/doc/user/group/img/share_with_group_lock.png
+++ b/doc/user/group/img/share_with_group_lock.png
Binary files differ
diff --git a/doc/user/group/img/withdraw_access_request_button.png b/doc/user/group/img/withdraw_access_request_button.png
index c5d8ef6c04f..4365f7fa788 100644
--- a/doc/user/group/img/withdraw_access_request_button.png
+++ b/doc/user/group/img/withdraw_access_request_button.png
Binary files differ
diff --git a/doc/user/group/subgroups/img/group_members.png b/doc/user/group/subgroups/img/group_members.png
index b95fe6263bf..830ccafa794 100644
--- a/doc/user/group/subgroups/img/group_members.png
+++ b/doc/user/group/subgroups/img/group_members.png
Binary files differ
diff --git a/doc/user/group/subgroups/img/mention_subgroups.png b/doc/user/group/subgroups/img/mention_subgroups.png
index 8e6bed0111b..ec370add4f9 100644
--- a/doc/user/group/subgroups/img/mention_subgroups.png
+++ b/doc/user/group/subgroups/img/mention_subgroups.png
Binary files differ
diff --git a/doc/user/img/award_emoji_comment_picker.png b/doc/user/img/award_emoji_comment_picker.png
index 3ad1bab3119..07f90c898ed 100644
--- a/doc/user/img/award_emoji_comment_picker.png
+++ b/doc/user/img/award_emoji_comment_picker.png
Binary files differ
diff --git a/doc/user/img/award_emoji_select.png b/doc/user/img/award_emoji_select.png
index 496acb29eec..269282b94b0 100644
--- a/doc/user/img/award_emoji_select.png
+++ b/doc/user/img/award_emoji_select.png
Binary files differ
diff --git a/doc/user/img/award_emoji_votes_sort_options.png b/doc/user/img/award_emoji_votes_sort_options.png
index dd84b7f4f64..dc02d5169e0 100644
--- a/doc/user/img/award_emoji_votes_sort_options.png
+++ b/doc/user/img/award_emoji_votes_sort_options.png
Binary files differ
diff --git a/doc/user/img/markdown_logo.png b/doc/user/img/markdown_logo.png
index bb3faaaec76..5184851b6cf 100644
--- a/doc/user/img/markdown_logo.png
+++ b/doc/user/img/markdown_logo.png
Binary files differ
diff --git a/doc/user/instance_statistics/img/convdev_index.png b/doc/user/instance_statistics/img/convdev_index.png
index 191295c918b..bee1317438d 100644
--- a/doc/user/instance_statistics/img/convdev_index.png
+++ b/doc/user/instance_statistics/img/convdev_index.png
Binary files differ
diff --git a/doc/user/profile/img/active_sessions_list.png b/doc/user/profile/img/active_sessions_list.png
index 76a52220bcd..5d94dca69cc 100644
--- a/doc/user/profile/img/active_sessions_list.png
+++ b/doc/user/profile/img/active_sessions_list.png
Binary files differ
diff --git a/doc/user/profile/img/personal_access_tokens.png b/doc/user/profile/img/personal_access_tokens.png
index 6aa63dbe342..d29f4cb0a20 100644
--- a/doc/user/profile/img/personal_access_tokens.png
+++ b/doc/user/profile/img/personal_access_tokens.png
Binary files differ
diff --git a/doc/user/profile/img/profil-preferences-navigation-theme.png b/doc/user/profile/img/profil-preferences-navigation-theme.png
index 7adaec33b60..335a19ac290 100644
--- a/doc/user/profile/img/profil-preferences-navigation-theme.png
+++ b/doc/user/profile/img/profil-preferences-navigation-theme.png
Binary files differ
diff --git a/doc/user/project/clusters/eks_and_gitlab/img/add_cluster.png b/doc/user/project/clusters/eks_and_gitlab/img/add_cluster.png
index 9a0559a19d4..94ec83f1514 100644
--- a/doc/user/project/clusters/eks_and_gitlab/img/add_cluster.png
+++ b/doc/user/project/clusters/eks_and_gitlab/img/add_cluster.png
Binary files differ
diff --git a/doc/user/project/clusters/eks_and_gitlab/img/create_dns.png b/doc/user/project/clusters/eks_and_gitlab/img/create_dns.png
index 657ab0d9fa9..61ed85e5cd9 100644
--- a/doc/user/project/clusters/eks_and_gitlab/img/create_dns.png
+++ b/doc/user/project/clusters/eks_and_gitlab/img/create_dns.png
Binary files differ
diff --git a/doc/user/project/clusters/eks_and_gitlab/img/create_project.png b/doc/user/project/clusters/eks_and_gitlab/img/create_project.png
index f3446131419..b02ab4b9064 100644
--- a/doc/user/project/clusters/eks_and_gitlab/img/create_project.png
+++ b/doc/user/project/clusters/eks_and_gitlab/img/create_project.png
Binary files differ
diff --git a/doc/user/project/clusters/eks_and_gitlab/img/deploy_apps.png b/doc/user/project/clusters/eks_and_gitlab/img/deploy_apps.png
index d6c3b1b3a94..0d9fcc838d9 100644
--- a/doc/user/project/clusters/eks_and_gitlab/img/deploy_apps.png
+++ b/doc/user/project/clusters/eks_and_gitlab/img/deploy_apps.png
Binary files differ
diff --git a/doc/user/project/clusters/eks_and_gitlab/img/environment.png b/doc/user/project/clusters/eks_and_gitlab/img/environment.png
index 77d711ba8f6..4714c447026 100644
--- a/doc/user/project/clusters/eks_and_gitlab/img/environment.png
+++ b/doc/user/project/clusters/eks_and_gitlab/img/environment.png
Binary files differ
diff --git a/doc/user/project/clusters/eks_and_gitlab/img/new_project.png b/doc/user/project/clusters/eks_and_gitlab/img/new_project.png
index d401c4ac2bf..02afc099f10 100644
--- a/doc/user/project/clusters/eks_and_gitlab/img/new_project.png
+++ b/doc/user/project/clusters/eks_and_gitlab/img/new_project.png
Binary files differ
diff --git a/doc/user/project/clusters/eks_and_gitlab/img/pipeline.png b/doc/user/project/clusters/eks_and_gitlab/img/pipeline.png
index 5f9c9815c24..0eb00d0faa7 100644
--- a/doc/user/project/clusters/eks_and_gitlab/img/pipeline.png
+++ b/doc/user/project/clusters/eks_and_gitlab/img/pipeline.png
Binary files differ
diff --git a/doc/user/project/deploy_tokens/img/deploy_tokens.png b/doc/user/project/deploy_tokens/img/deploy_tokens.png
index 7e2d67a3120..55c537fd1d3 100644
--- a/doc/user/project/deploy_tokens/img/deploy_tokens.png
+++ b/doc/user/project/deploy_tokens/img/deploy_tokens.png
Binary files differ
diff --git a/doc/user/project/img/bulk-editing.png b/doc/user/project/img/bulk-editing.png
index f6b163f55d9..8ae649e5020 100644
--- a/doc/user/project/img/bulk-editing.png
+++ b/doc/user/project/img/bulk-editing.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 316612c0da0..8b17fae5e05 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/issue_board_assignee_lists.png b/doc/user/project/img/issue_board_assignee_lists.png
index 1ec94d22e33..f2660cd8f80 100644
--- a/doc/user/project/img/issue_board_assignee_lists.png
+++ b/doc/user/project/img/issue_board_assignee_lists.png
Binary files differ
diff --git a/doc/user/project/img/issue_board_creation.png b/doc/user/project/img/issue_board_creation.png
index 9dc4925b0a5..099fe6eee21 100644
--- a/doc/user/project/img/issue_board_creation.png
+++ b/doc/user/project/img/issue_board_creation.png
Binary files differ
diff --git a/doc/user/project/img/issue_board_edit_button.png b/doc/user/project/img/issue_board_edit_button.png
index 23883175344..a0dc6f41592 100644
--- a/doc/user/project/img/issue_board_edit_button.png
+++ b/doc/user/project/img/issue_board_edit_button.png
Binary files differ
diff --git a/doc/user/project/img/issue_board_move_issue_card_list.png b/doc/user/project/img/issue_board_move_issue_card_list.png
index cce252234c1..13750a63766 100644
--- a/doc/user/project/img/issue_board_move_issue_card_list.png
+++ b/doc/user/project/img/issue_board_move_issue_card_list.png
Binary files differ
diff --git a/doc/user/project/img/issue_board_view_scope.png b/doc/user/project/img/issue_board_view_scope.png
index 4e03cecbc2d..d173679a0e7 100644
--- a/doc/user/project/img/issue_board_view_scope.png
+++ b/doc/user/project/img/issue_board_view_scope.png
Binary files differ
diff --git a/doc/user/project/img/issue_boards_add_issues_modal.png b/doc/user/project/img/issue_boards_add_issues_modal.png
index 625a4304eaf..ecddf6709d0 100644
--- a/doc/user/project/img/issue_boards_add_issues_modal.png
+++ b/doc/user/project/img/issue_boards_add_issues_modal.png
Binary files differ
diff --git a/doc/user/project/img/issue_boards_multiple.png b/doc/user/project/img/issue_boards_multiple.png
index 4b2b8d457f1..7bb088aad0b 100644
--- a/doc/user/project/img/issue_boards_multiple.png
+++ b/doc/user/project/img/issue_boards_multiple.png
Binary files differ
diff --git a/doc/user/project/img/issue_boards_remove_issue.png b/doc/user/project/img/issue_boards_remove_issue.png
index 9a2fad2cc7f..7050e6c3ede 100644
--- a/doc/user/project/img/issue_boards_remove_issue.png
+++ b/doc/user/project/img/issue_boards_remove_issue.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 79b7b2f10a2..118b97c07e1 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-success.png b/doc/user/project/img/koding_build-success.png
index a2342cfd324..0f3b954abf5 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 16842410ae2..d921c73dc73 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_edit-on-ide.png b/doc/user/project/img/koding_edit-on-ide.png
index ab861281d3e..25ca7694fe0 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 0b6fcfadcc5..7e6c1735df2 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 1eeddcd3813..ac880376e09 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_run-in-ide.png b/doc/user/project/img/koding_run-in-ide.png
index d22e5023c59..fb5825a4010 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_stack-import.png b/doc/user/project/img/koding_stack-import.png
index 245ccb07ba3..483bfad7d6a 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 3f5c16d5d2f..c09a6d669f0 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_generate_default.png b/doc/user/project/img/labels_generate_default.png
index fca2a06e04f..982a4df999c 100644
--- a/doc/user/project/img/labels_generate_default.png
+++ b/doc/user/project/img/labels_generate_default.png
Binary files differ
diff --git a/doc/user/project/img/labels_group_issues.png b/doc/user/project/img/labels_group_issues.png
index 29dcf7ff45e..cea1d304d31 100644
--- a/doc/user/project/img/labels_group_issues.png
+++ b/doc/user/project/img/labels_group_issues.png
Binary files differ
diff --git a/doc/user/project/img/labels_list.png b/doc/user/project/img/labels_list.png
index 12c47ea9766..6878349fc0c 100644
--- a/doc/user/project/img/labels_list.png
+++ b/doc/user/project/img/labels_list.png
Binary files differ
diff --git a/doc/user/project/img/labels_prioritized.png b/doc/user/project/img/labels_prioritized.png
index 57dcfe89b3d..7ce2d08b38c 100644
--- a/doc/user/project/img/labels_prioritized.png
+++ b/doc/user/project/img/labels_prioritized.png
Binary files differ
diff --git a/doc/user/project/img/labels_project_list_search.png b/doc/user/project/img/labels_project_list_search.png
index ff9bf92e1c3..512d7767e6e 100644
--- a/doc/user/project/img/labels_project_list_search.png
+++ b/doc/user/project/img/labels_project_list_search.png
Binary files differ
diff --git a/doc/user/project/img/labels_promotion.png b/doc/user/project/img/labels_promotion.png
index 8a5efd210a2..762a3773692 100644
--- a/doc/user/project/img/labels_promotion.png
+++ b/doc/user/project/img/labels_promotion.png
Binary files differ
diff --git a/doc/user/project/img/labels_sidebar.png b/doc/user/project/img/labels_sidebar.png
index 7349c6d4f0c..454a0ca3f07 100644
--- a/doc/user/project/img/labels_sidebar.png
+++ b/doc/user/project/img/labels_sidebar.png
Binary files differ
diff --git a/doc/user/project/img/labels_sidebar_assign.png b/doc/user/project/img/labels_sidebar_assign.png
index 61e8d04fc85..5b7fb78b032 100644
--- a/doc/user/project/img/labels_sidebar_assign.png
+++ b/doc/user/project/img/labels_sidebar_assign.png
Binary files differ
diff --git a/doc/user/project/img/labels_sidebar_inline.png b/doc/user/project/img/labels_sidebar_inline.png
index 31fa397761d..2186f14ea92 100644
--- a/doc/user/project/img/labels_sidebar_inline.png
+++ b/doc/user/project/img/labels_sidebar_inline.png
Binary files differ
diff --git a/doc/user/project/img/labels_sort_label_priority.png b/doc/user/project/img/labels_sort_label_priority.png
index c8b97639121..faf629ac61d 100644
--- a/doc/user/project/img/labels_sort_label_priority.png
+++ b/doc/user/project/img/labels_sort_label_priority.png
Binary files differ
diff --git a/doc/user/project/img/labels_sort_priority.png b/doc/user/project/img/labels_sort_priority.png
index a95198e7f72..a6b5fca26f4 100644
--- a/doc/user/project/img/labels_sort_priority.png
+++ b/doc/user/project/img/labels_sort_priority.png
Binary files differ
diff --git a/doc/user/project/img/labels_subscriptions.png b/doc/user/project/img/labels_subscriptions.png
index 8bcb3b57f6c..f3c4235d051 100644
--- a/doc/user/project/img/labels_subscriptions.png
+++ b/doc/user/project/img/labels_subscriptions.png
Binary files differ
diff --git a/doc/user/project/img/priority_sort_order.png b/doc/user/project/img/priority_sort_order.png
index c558ec23b0e..cd1dd8237c0 100644
--- a/doc/user/project/img/priority_sort_order.png
+++ b/doc/user/project/img/priority_sort_order.png
Binary files differ
diff --git a/doc/user/project/img/project_overview_badges.png b/doc/user/project/img/project_overview_badges.png
index 3067a7dfa13..83b9766828a 100644
--- a/doc/user/project/img/project_overview_badges.png
+++ b/doc/user/project/img/project_overview_badges.png
Binary files differ
diff --git a/doc/user/project/img/project_repository_settings.png b/doc/user/project/img/project_repository_settings.png
index aa4d4452c87..69d36753a58 100644
--- a/doc/user/project/img/project_repository_settings.png
+++ b/doc/user/project/img/project_repository_settings.png
Binary files differ
diff --git a/doc/user/project/img/protected_branches_delete.png b/doc/user/project/img/protected_branches_delete.png
index cfdfe6c6c29..8910ae9e39d 100644
--- a/doc/user/project/img/protected_branches_delete.png
+++ b/doc/user/project/img/protected_branches_delete.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 320e6eb7fee..b537839c00b 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 3f8e462d3ad..62839e49d89 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 1b2936cb711..495ce4d7b6f 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_page.png b/doc/user/project/img/protected_branches_page.png
index 4e5afff3bae..9b10991f62e 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/img/protected_tag_matches.png b/doc/user/project/img/protected_tag_matches.png
index a36a11a1271..e89d0a47073 100644
--- a/doc/user/project/img/protected_tag_matches.png
+++ b/doc/user/project/img/protected_tag_matches.png
Binary files differ
diff --git a/doc/user/project/img/protected_tags_list.png b/doc/user/project/img/protected_tags_list.png
index c5e42dc0705..6c5295e0f4b 100644
--- a/doc/user/project/img/protected_tags_list.png
+++ b/doc/user/project/img/protected_tags_list.png
Binary files differ
diff --git a/doc/user/project/img/protected_tags_page.png b/doc/user/project/img/protected_tags_page.png
index 3848d91ebd6..5f8a2106cd1 100644
--- a/doc/user/project/img/protected_tags_page.png
+++ b/doc/user/project/img/protected_tags_page.png
Binary files differ
diff --git a/doc/user/project/img/protected_tags_permissions_dropdown.png b/doc/user/project/img/protected_tags_permissions_dropdown.png
index 9e0fc4e2a43..77098eeb591 100644
--- a/doc/user/project/img/protected_tags_permissions_dropdown.png
+++ b/doc/user/project/img/protected_tags_permissions_dropdown.png
Binary files differ
diff --git a/doc/user/project/import/img/bitbucket_server_import_credentials.png b/doc/user/project/import/img/bitbucket_server_import_credentials.png
index 70b26e89d49..25bcc3ab6e6 100644
--- a/doc/user/project/import/img/bitbucket_server_import_credentials.png
+++ b/doc/user/project/import/img/bitbucket_server_import_credentials.png
Binary files differ
diff --git a/doc/user/project/import/img/bitbucket_server_import_select_project.png b/doc/user/project/import/img/bitbucket_server_import_select_project.png
index e5b1b89e6a3..e7fddef9955 100644
--- a/doc/user/project/import/img/bitbucket_server_import_select_project.png
+++ b/doc/user/project/import/img/bitbucket_server_import_select_project.png
Binary files differ
diff --git a/doc/user/project/import/img/fogbugz_import_login.png b/doc/user/project/import/img/fogbugz_import_login.png
index 96bce70b74d..6ba4d443f1a 100644
--- a/doc/user/project/import/img/fogbugz_import_login.png
+++ b/doc/user/project/import/img/fogbugz_import_login.png
Binary files differ
diff --git a/doc/user/project/import/img/fogbugz_import_select_fogbogz.png b/doc/user/project/import/img/fogbugz_import_select_fogbogz.png
index b26c652e382..d207646a6f2 100644
--- a/doc/user/project/import/img/fogbugz_import_select_fogbogz.png
+++ b/doc/user/project/import/img/fogbugz_import_select_fogbogz.png
Binary files differ
diff --git a/doc/user/project/import/img/fogbugz_import_select_project.png b/doc/user/project/import/img/fogbugz_import_select_project.png
index ccc82f9d4cd..b5e6f497f9b 100644
--- a/doc/user/project/import/img/fogbugz_import_select_project.png
+++ b/doc/user/project/import/img/fogbugz_import_select_project.png
Binary files differ
diff --git a/doc/user/project/import/img/import_projects_from_gitea_new_import.png b/doc/user/project/import/img/import_projects_from_gitea_new_import.png
index a3f603cbd0a..41eb4b2bd00 100644
--- a/doc/user/project/import/img/import_projects_from_gitea_new_import.png
+++ b/doc/user/project/import/img/import_projects_from_gitea_new_import.png
Binary files differ
diff --git a/doc/user/project/import/img/import_projects_from_github_select_auth_method.png b/doc/user/project/import/img/import_projects_from_github_select_auth_method.png
index 1ccb38a815e..90e6243aec0 100644
--- a/doc/user/project/import/img/import_projects_from_github_select_auth_method.png
+++ b/doc/user/project/import/img/import_projects_from_github_select_auth_method.png
Binary files differ
diff --git a/doc/user/project/import/img/import_projects_from_new_project_page.png b/doc/user/project/import/img/import_projects_from_new_project_page.png
index 40402eae226..7c32d3555d1 100644
--- a/doc/user/project/import/img/import_projects_from_new_project_page.png
+++ b/doc/user/project/import/img/import_projects_from_new_project_page.png
Binary files differ
diff --git a/doc/user/project/integrations/img/hangouts_chat_configuration.png b/doc/user/project/integrations/img/hangouts_chat_configuration.png
index 33fadbe6547..54aaef6632d 100644
--- a/doc/user/project/integrations/img/hangouts_chat_configuration.png
+++ b/doc/user/project/integrations/img/hangouts_chat_configuration.png
Binary files differ
diff --git a/doc/user/project/integrations/img/issue_configuration.png b/doc/user/project/integrations/img/issue_configuration.png
index 2049d60fdd2..5dfd85974d8 100644
--- a/doc/user/project/integrations/img/issue_configuration.png
+++ b/doc/user/project/integrations/img/issue_configuration.png
Binary files differ
diff --git a/doc/user/project/integrations/img/jira_group_access.png b/doc/user/project/integrations/img/jira_group_access.png
index 9d64cc57269..448cc55504d 100644
--- a/doc/user/project/integrations/img/jira_group_access.png
+++ b/doc/user/project/integrations/img/jira_group_access.png
Binary files differ
diff --git a/doc/user/project/integrations/img/jira_project_name.png b/doc/user/project/integrations/img/jira_project_name.png
index 8540a427461..981c7f7ca18 100644
--- a/doc/user/project/integrations/img/jira_project_name.png
+++ b/doc/user/project/integrations/img/jira_project_name.png
Binary files differ
diff --git a/doc/user/project/integrations/img/jira_project_settings.png b/doc/user/project/integrations/img/jira_project_settings.png
index cb6a6ba14ce..d96002b7db8 100644
--- a/doc/user/project/integrations/img/jira_project_settings.png
+++ b/doc/user/project/integrations/img/jira_project_settings.png
Binary files differ
diff --git a/doc/user/project/integrations/img/jira_service.png b/doc/user/project/integrations/img/jira_service.png
index 8e073b84ff9..0ae2fa28756 100644
--- a/doc/user/project/integrations/img/jira_service.png
+++ b/doc/user/project/integrations/img/jira_service.png
Binary files differ
diff --git a/doc/user/project/integrations/img/jira_service_close_comment.png b/doc/user/project/integrations/img/jira_service_close_comment.png
index bb9cd7e3d13..9af0d38f098 100644
--- a/doc/user/project/integrations/img/jira_service_close_comment.png
+++ b/doc/user/project/integrations/img/jira_service_close_comment.png
Binary files differ
diff --git a/doc/user/project/integrations/img/jira_service_page.png b/doc/user/project/integrations/img/jira_service_page.png
index 63aa0e99a50..c75c11888a8 100644
--- a/doc/user/project/integrations/img/jira_service_page.png
+++ b/doc/user/project/integrations/img/jira_service_page.png
Binary files differ
diff --git a/doc/user/project/integrations/img/jira_user_management_link.png b/doc/user/project/integrations/img/jira_user_management_link.png
index f81c5b5fc87..5eb9d031c3e 100644
--- a/doc/user/project/integrations/img/jira_user_management_link.png
+++ b/doc/user/project/integrations/img/jira_user_management_link.png
Binary files differ
diff --git a/doc/user/project/integrations/img/mattermost_bot_auth.png b/doc/user/project/integrations/img/mattermost_bot_auth.png
index 830b7849f3d..a05d8da1237 100644
--- a/doc/user/project/integrations/img/mattermost_bot_auth.png
+++ b/doc/user/project/integrations/img/mattermost_bot_auth.png
Binary files differ
diff --git a/doc/user/project/integrations/img/mattermost_bot_available_commands.png b/doc/user/project/integrations/img/mattermost_bot_available_commands.png
index b51798cf10d..3232ccc3451 100644
--- a/doc/user/project/integrations/img/mattermost_bot_available_commands.png
+++ b/doc/user/project/integrations/img/mattermost_bot_available_commands.png
Binary files differ
diff --git a/doc/user/project/integrations/img/mattermost_configuration.png b/doc/user/project/integrations/img/mattermost_configuration.png
index f52acf4ef3b..e0b55b23520 100644
--- a/doc/user/project/integrations/img/mattermost_configuration.png
+++ b/doc/user/project/integrations/img/mattermost_configuration.png
Binary files differ
diff --git a/doc/user/project/integrations/img/mattermost_console_integrations.png b/doc/user/project/integrations/img/mattermost_console_integrations.png
index 92a30da5be0..625b57d4dc9 100644
--- a/doc/user/project/integrations/img/mattermost_console_integrations.png
+++ b/doc/user/project/integrations/img/mattermost_console_integrations.png
Binary files differ
diff --git a/doc/user/project/integrations/img/mattermost_gitlab_token.png b/doc/user/project/integrations/img/mattermost_gitlab_token.png
index 257018914d2..63140503824 100644
--- a/doc/user/project/integrations/img/mattermost_gitlab_token.png
+++ b/doc/user/project/integrations/img/mattermost_gitlab_token.png
Binary files differ
diff --git a/doc/user/project/integrations/img/mattermost_goto_console.png b/doc/user/project/integrations/img/mattermost_goto_console.png
index 3354c2a24b4..8bacbe485f4 100644
--- a/doc/user/project/integrations/img/mattermost_goto_console.png
+++ b/doc/user/project/integrations/img/mattermost_goto_console.png
Binary files differ
diff --git a/doc/user/project/integrations/img/mattermost_slash_command_configuration.png b/doc/user/project/integrations/img/mattermost_slash_command_configuration.png
index 12766ab2b34..f9e9de439ca 100644
--- a/doc/user/project/integrations/img/mattermost_slash_command_configuration.png
+++ b/doc/user/project/integrations/img/mattermost_slash_command_configuration.png
Binary files differ
diff --git a/doc/user/project/integrations/img/mattermost_team_integrations.png b/doc/user/project/integrations/img/mattermost_team_integrations.png
index 69d4a231e5a..c2b68256e11 100644
--- a/doc/user/project/integrations/img/mattermost_team_integrations.png
+++ b/doc/user/project/integrations/img/mattermost_team_integrations.png
Binary files differ
diff --git a/doc/user/project/integrations/img/merge_request_performance.png b/doc/user/project/integrations/img/merge_request_performance.png
index eba6515a6ae..a9cd761cdcb 100644
--- a/doc/user/project/integrations/img/merge_request_performance.png
+++ b/doc/user/project/integrations/img/merge_request_performance.png
Binary files differ
diff --git a/doc/user/project/integrations/img/microsoft_teams_configuration.png b/doc/user/project/integrations/img/microsoft_teams_configuration.png
index b5c9efc3dd9..627715d5c18 100644
--- a/doc/user/project/integrations/img/microsoft_teams_configuration.png
+++ b/doc/user/project/integrations/img/microsoft_teams_configuration.png
Binary files differ
diff --git a/doc/user/project/integrations/img/project_services.png b/doc/user/project/integrations/img/project_services.png
index 25b6cd5690b..5fed38a349c 100644
--- a/doc/user/project/integrations/img/project_services.png
+++ b/doc/user/project/integrations/img/project_services.png
Binary files differ
diff --git a/doc/user/project/integrations/img/prometheus_dashboard.png b/doc/user/project/integrations/img/prometheus_dashboard.png
index bd19f1b44cc..1fa36ca2675 100644
--- a/doc/user/project/integrations/img/prometheus_dashboard.png
+++ b/doc/user/project/integrations/img/prometheus_dashboard.png
Binary files differ
diff --git a/doc/user/project/integrations/img/prometheus_deploy.png b/doc/user/project/integrations/img/prometheus_deploy.png
index d39081bcc7b..3f19f23b0cc 100644
--- a/doc/user/project/integrations/img/prometheus_deploy.png
+++ b/doc/user/project/integrations/img/prometheus_deploy.png
Binary files differ
diff --git a/doc/user/project/integrations/img/prometheus_yaml_deploy.png b/doc/user/project/integrations/img/prometheus_yaml_deploy.png
index 978cd7eaa50..78dd178a077 100644
--- a/doc/user/project/integrations/img/prometheus_yaml_deploy.png
+++ b/doc/user/project/integrations/img/prometheus_yaml_deploy.png
Binary files differ
diff --git a/doc/user/project/integrations/img/redmine_configuration.png b/doc/user/project/integrations/img/redmine_configuration.png
index 7b6dd271401..eb392b848b5 100644
--- a/doc/user/project/integrations/img/redmine_configuration.png
+++ b/doc/user/project/integrations/img/redmine_configuration.png
Binary files differ
diff --git a/doc/user/project/integrations/img/services_templates_redmine_example.png b/doc/user/project/integrations/img/services_templates_redmine_example.png
index 379cef9888d..34594dfdd55 100644
--- a/doc/user/project/integrations/img/services_templates_redmine_example.png
+++ b/doc/user/project/integrations/img/services_templates_redmine_example.png
Binary files differ
diff --git a/doc/user/project/integrations/img/slack_configuration.png b/doc/user/project/integrations/img/slack_configuration.png
index 527824fc3eb..53b30e0e8cd 100644
--- a/doc/user/project/integrations/img/slack_configuration.png
+++ b/doc/user/project/integrations/img/slack_configuration.png
Binary files differ
diff --git a/doc/user/project/integrations/img/webhook_logs.png b/doc/user/project/integrations/img/webhook_logs.png
index 803678db6b6..24bb593c7d0 100644
--- a/doc/user/project/integrations/img/webhook_logs.png
+++ b/doc/user/project/integrations/img/webhook_logs.png
Binary files differ
diff --git a/doc/user/project/integrations/img/webhook_testing.png b/doc/user/project/integrations/img/webhook_testing.png
index 176dcec9d8a..acfebf473b9 100644
--- a/doc/user/project/integrations/img/webhook_testing.png
+++ b/doc/user/project/integrations/img/webhook_testing.png
Binary files differ
diff --git a/doc/user/project/integrations/img/webhooks_ssl.png b/doc/user/project/integrations/img/webhooks_ssl.png
index 21ddec4ebdf..f023e9665f2 100644
--- a/doc/user/project/integrations/img/webhooks_ssl.png
+++ b/doc/user/project/integrations/img/webhooks_ssl.png
Binary files differ
diff --git a/doc/user/project/issues/img/confidential_issues_index_page.png b/doc/user/project/issues/img/confidential_issues_index_page.png
index f3efe0ce04e..16979bf9ac2 100644
--- a/doc/user/project/issues/img/confidential_issues_index_page.png
+++ b/doc/user/project/issues/img/confidential_issues_index_page.png
Binary files differ
diff --git a/doc/user/project/issues/img/delete_issue.png b/doc/user/project/issues/img/delete_issue.png
index a356f52044e..87ea65956fc 100644
--- a/doc/user/project/issues/img/delete_issue.png
+++ b/doc/user/project/issues/img/delete_issue.png
Binary files differ
diff --git a/doc/user/project/issues/img/due_dates_create.png b/doc/user/project/issues/img/due_dates_create.png
index ece35d44213..392fb3553cb 100644
--- a/doc/user/project/issues/img/due_dates_create.png
+++ b/doc/user/project/issues/img/due_dates_create.png
Binary files differ
diff --git a/doc/user/project/issues/img/group_issues_list_view.png b/doc/user/project/issues/img/group_issues_list_view.png
index bba964076d0..c951a9e2dcd 100644
--- a/doc/user/project/issues/img/group_issues_list_view.png
+++ b/doc/user/project/issues/img/group_issues_list_view.png
Binary files differ
diff --git a/doc/user/project/issues/img/issue_board.png b/doc/user/project/issues/img/issue_board.png
index 87b1016cc76..df9d6f64985 100644
--- a/doc/user/project/issues/img/issue_board.png
+++ b/doc/user/project/issues/img/issue_board.png
Binary files differ
diff --git a/doc/user/project/issues/img/issue_template.png b/doc/user/project/issues/img/issue_template.png
index 0e4c8df897b..6cb2c07d27e 100644
--- a/doc/user/project/issues/img/issue_template.png
+++ b/doc/user/project/issues/img/issue_template.png
Binary files differ
diff --git a/doc/user/project/issues/img/new_issue_from_email.png b/doc/user/project/issues/img/new_issue_from_email.png
index 775ea0cdffb..6da899ea37c 100644
--- a/doc/user/project/issues/img/new_issue_from_email.png
+++ b/doc/user/project/issues/img/new_issue_from_email.png
Binary files differ
diff --git a/doc/user/project/issues/img/new_issue_from_issue_board.png b/doc/user/project/issues/img/new_issue_from_issue_board.png
index da892eff0a6..30a1ffb9011 100644
--- a/doc/user/project/issues/img/new_issue_from_issue_board.png
+++ b/doc/user/project/issues/img/new_issue_from_issue_board.png
Binary files differ
diff --git a/doc/user/project/issues/img/new_issue_from_projects_dashboard.png b/doc/user/project/issues/img/new_issue_from_projects_dashboard.png
index 4b9535f6b15..474ca2b45c0 100644
--- a/doc/user/project/issues/img/new_issue_from_projects_dashboard.png
+++ b/doc/user/project/issues/img/new_issue_from_projects_dashboard.png
Binary files differ
diff --git a/doc/user/project/issues/img/project_issues_list_view.png b/doc/user/project/issues/img/project_issues_list_view.png
index 584a81aab8a..c80bd58f5c9 100644
--- a/doc/user/project/issues/img/project_issues_list_view.png
+++ b/doc/user/project/issues/img/project_issues_list_view.png
Binary files differ
diff --git a/doc/user/project/issues/img/sidebar_confidential_issue.png b/doc/user/project/issues/img/sidebar_confidential_issue.png
index d99a1ca756e..a320f4dcfe5 100644
--- a/doc/user/project/issues/img/sidebar_confidential_issue.png
+++ b/doc/user/project/issues/img/sidebar_confidential_issue.png
Binary files differ
diff --git a/doc/user/project/issues/img/sidebar_move_issue.png b/doc/user/project/issues/img/sidebar_move_issue.png
index 1e688cec894..031284a24b2 100644
--- a/doc/user/project/issues/img/sidebar_move_issue.png
+++ b/doc/user/project/issues/img/sidebar_move_issue.png
Binary files differ
diff --git a/doc/user/project/issues/img/sidebar_not_confidential_issue.png b/doc/user/project/issues/img/sidebar_not_confidential_issue.png
index 2e6cbbc5b3a..c09f8204b37 100644
--- a/doc/user/project/issues/img/sidebar_not_confidential_issue.png
+++ b/doc/user/project/issues/img/sidebar_not_confidential_issue.png
Binary files differ
diff --git a/doc/user/project/issues/img/turn_off_confidentiality.png b/doc/user/project/issues/img/turn_off_confidentiality.png
index 248ae6522d6..04a85933071 100644
--- a/doc/user/project/issues/img/turn_off_confidentiality.png
+++ b/doc/user/project/issues/img/turn_off_confidentiality.png
Binary files differ
diff --git a/doc/user/project/issues/img/turn_on_confidentiality.png b/doc/user/project/issues/img/turn_on_confidentiality.png
index fac4c833699..fac360ca6dc 100644
--- a/doc/user/project/issues/img/turn_on_confidentiality.png
+++ b/doc/user/project/issues/img/turn_on_confidentiality.png
Binary files differ
diff --git a/doc/user/project/members/img/access_requests_management.png b/doc/user/project/members/img/access_requests_management.png
index 3693bed869b..8996d9564d7 100644
--- a/doc/user/project/members/img/access_requests_management.png
+++ b/doc/user/project/members/img/access_requests_management.png
Binary files differ
diff --git a/doc/user/project/members/img/add_new_user_to_project_settings.png b/doc/user/project/members/img/add_new_user_to_project_settings.png
index 40db600455f..e49ea1a3e3d 100644
--- a/doc/user/project/members/img/add_new_user_to_project_settings.png
+++ b/doc/user/project/members/img/add_new_user_to_project_settings.png
Binary files differ
diff --git a/doc/user/project/members/img/add_user_email_accept.png b/doc/user/project/members/img/add_user_email_accept.png
index 763b3ff463d..cbee9e08c70 100644
--- a/doc/user/project/members/img/add_user_email_accept.png
+++ b/doc/user/project/members/img/add_user_email_accept.png
Binary files differ
diff --git a/doc/user/project/members/img/add_user_import_members_from_another_project.png b/doc/user/project/members/img/add_user_import_members_from_another_project.png
index 0c32001098e..cb3b70bd4b5 100644
--- a/doc/user/project/members/img/add_user_import_members_from_another_project.png
+++ b/doc/user/project/members/img/add_user_import_members_from_another_project.png
Binary files differ
diff --git a/doc/user/project/members/img/add_user_members_menu.png b/doc/user/project/members/img/add_user_members_menu.png
index 8e61d15fe65..6f08088b52f 100644
--- a/doc/user/project/members/img/add_user_members_menu.png
+++ b/doc/user/project/members/img/add_user_members_menu.png
Binary files differ
diff --git a/doc/user/project/members/img/max_access_level.png b/doc/user/project/members/img/max_access_level.png
index 63f33f9d91d..42a0416ffbb 100644
--- a/doc/user/project/members/img/max_access_level.png
+++ b/doc/user/project/members/img/max_access_level.png
Binary files differ
diff --git a/doc/user/project/members/img/request_access_button.png b/doc/user/project/members/img/request_access_button.png
index 608baccb0ca..e8b490b91b8 100644
--- a/doc/user/project/members/img/request_access_button.png
+++ b/doc/user/project/members/img/request_access_button.png
Binary files differ
diff --git a/doc/user/project/members/img/withdraw_access_request_button.png b/doc/user/project/members/img/withdraw_access_request_button.png
index 6edd786b151..6a3172dfcdb 100644
--- a/doc/user/project/members/img/withdraw_access_request_button.png
+++ b/doc/user/project/members/img/withdraw_access_request_button.png
Binary files differ
diff --git a/doc/user/project/merge_requests/img/allow_collaboration.png b/doc/user/project/merge_requests/img/allow_collaboration.png
index 75596e7d9ad..3c81e4c27b8 100644
--- a/doc/user/project/merge_requests/img/allow_collaboration.png
+++ b/doc/user/project/merge_requests/img/allow_collaboration.png
Binary files differ
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 7dc344f8cf6..c98821548f8 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_mr.png b/doc/user/project/merge_requests/img/cherry_pick_changes_mr.png
index 811b0998f85..8b51503419b 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/create_from_email.png b/doc/user/project/merge_requests/img/create_from_email.png
index 71eb4bf267d..610f0b3d0c1 100644
--- a/doc/user/project/merge_requests/img/create_from_email.png
+++ b/doc/user/project/merge_requests/img/create_from_email.png
Binary files differ
diff --git a/doc/user/project/merge_requests/img/merge_conflict_editor.png b/doc/user/project/merge_requests/img/merge_conflict_editor.png
index 6660920c191..f10efbce5f5 100644
--- a/doc/user/project/merge_requests/img/merge_conflict_editor.png
+++ b/doc/user/project/merge_requests/img/merge_conflict_editor.png
Binary files differ
diff --git a/doc/user/project/merge_requests/img/merge_request.png b/doc/user/project/merge_requests/img/merge_request.png
index 61b61122b11..c0a62bbaba0 100644
--- a/doc/user/project/merge_requests/img/merge_request.png
+++ b/doc/user/project/merge_requests/img/merge_request.png
Binary files differ
diff --git a/doc/user/project/merge_requests/img/merge_request_diff_file_navigation.png b/doc/user/project/merge_requests/img/merge_request_diff_file_navigation.png
index 4eee734ff8d..ac766c99935 100644
--- a/doc/user/project/merge_requests/img/merge_request_diff_file_navigation.png
+++ b/doc/user/project/merge_requests/img/merge_request_diff_file_navigation.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 43a945c74d9..6c2317b29b5 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_pipeline_succeeds_enable.png b/doc/user/project/merge_requests/img/merge_when_pipeline_succeeds_enable.png
index d7f0535d3c5..9487264b41a 100644
--- a/doc/user/project/merge_requests/img/merge_when_pipeline_succeeds_enable.png
+++ b/doc/user/project/merge_requests/img/merge_when_pipeline_succeeds_enable.png
Binary files differ
diff --git a/doc/user/project/merge_requests/img/merge_when_pipeline_succeeds_only_if_succeeds_msg.png b/doc/user/project/merge_requests/img/merge_when_pipeline_succeeds_only_if_succeeds_msg.png
index c43f76b058c..761690d1e0c 100644
--- a/doc/user/project/merge_requests/img/merge_when_pipeline_succeeds_only_if_succeeds_msg.png
+++ b/doc/user/project/merge_requests/img/merge_when_pipeline_succeeds_only_if_succeeds_msg.png
Binary files differ
diff --git a/doc/user/project/merge_requests/img/merge_when_pipeline_succeeds_only_if_succeeds_settings.png b/doc/user/project/merge_requests/img/merge_when_pipeline_succeeds_only_if_succeeds_settings.png
index 9629ed99838..2a2101719ba 100644
--- a/doc/user/project/merge_requests/img/merge_when_pipeline_succeeds_only_if_succeeds_settings.png
+++ b/doc/user/project/merge_requests/img/merge_when_pipeline_succeeds_only_if_succeeds_settings.png
Binary files differ
diff --git a/doc/user/project/merge_requests/img/merge_when_pipeline_succeeds_status.png b/doc/user/project/merge_requests/img/merge_when_pipeline_succeeds_status.png
index d0691437c65..70fa2efc855 100644
--- a/doc/user/project/merge_requests/img/merge_when_pipeline_succeeds_status.png
+++ b/doc/user/project/merge_requests/img/merge_when_pipeline_succeeds_status.png
Binary files differ
diff --git a/doc/user/project/merge_requests/img/project_merge_requests_list_view.png b/doc/user/project/merge_requests/img/project_merge_requests_list_view.png
index 702ec1a2949..457716d811c 100644
--- a/doc/user/project/merge_requests/img/project_merge_requests_list_view.png
+++ b/doc/user/project/merge_requests/img/project_merge_requests_list_view.png
Binary files differ
diff --git a/doc/user/project/merge_requests/img/remove_source_branch_status.png b/doc/user/project/merge_requests/img/remove_source_branch_status.png
index 1377fab54ec..afd93207e02 100644
--- a/doc/user/project/merge_requests/img/remove_source_branch_status.png
+++ b/doc/user/project/merge_requests/img/remove_source_branch_status.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 a0663e130e9..c9dd0019024 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_mr.png b/doc/user/project/merge_requests/img/revert_changes_mr.png
index 8792018ee53..06b841b3002 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/squash_edit_form.png b/doc/user/project/merge_requests/img/squash_edit_form.png
index 496c6f44ea7..326d74b68cb 100644
--- a/doc/user/project/merge_requests/img/squash_edit_form.png
+++ b/doc/user/project/merge_requests/img/squash_edit_form.png
Binary files differ
diff --git a/doc/user/project/merge_requests/img/squash_mr_commits.png b/doc/user/project/merge_requests/img/squash_mr_commits.png
index 5fc6a8c48bb..dfc1ee38435 100644
--- a/doc/user/project/merge_requests/img/squash_mr_commits.png
+++ b/doc/user/project/merge_requests/img/squash_mr_commits.png
Binary files differ
diff --git a/doc/user/project/merge_requests/img/squash_mr_widget.png b/doc/user/project/merge_requests/img/squash_mr_widget.png
index 9cb458b2a35..81334ca9758 100644
--- a/doc/user/project/merge_requests/img/squash_mr_widget.png
+++ b/doc/user/project/merge_requests/img/squash_mr_widget.png
Binary files differ
diff --git a/doc/user/project/merge_requests/img/squash_squashed_commit.png b/doc/user/project/merge_requests/img/squash_squashed_commit.png
index 0cf5875f82c..458361c5490 100644
--- a/doc/user/project/merge_requests/img/squash_squashed_commit.png
+++ b/doc/user/project/merge_requests/img/squash_squashed_commit.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 3883fb4bc1c..8355fd62dcb 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 f5bd85dc7c1..0957a0310ac 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 cc70a5bf14b..831c92db2c0 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 90be6298d15..97d552692c9 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 0c492aca363..31f23be4d3d 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 e405879b28a..2c2a263b316 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 d7f8c419945..327ad9a8448 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/milestones/img/milestones_new_group_milestone.png b/doc/user/project/milestones/img/milestones_new_group_milestone.png
index b6defab101d..a517f0f7537 100644
--- a/doc/user/project/milestones/img/milestones_new_group_milestone.png
+++ b/doc/user/project/milestones/img/milestones_new_group_milestone.png
Binary files differ
diff --git a/doc/user/project/milestones/img/milestones_new_project_milestone.png b/doc/user/project/milestones/img/milestones_new_project_milestone.png
index 9aaff7dfef1..482c73f6568 100644
--- a/doc/user/project/milestones/img/milestones_new_project_milestone.png
+++ b/doc/user/project/milestones/img/milestones_new_project_milestone.png
Binary files differ
diff --git a/doc/user/project/milestones/img/milestones_project_milestone_page.png b/doc/user/project/milestones/img/milestones_project_milestone_page.png
index 9717075b8d0..c17bf350aeb 100644
--- a/doc/user/project/milestones/img/milestones_project_milestone_page.png
+++ b/doc/user/project/milestones/img/milestones_project_milestone_page.png
Binary files differ
diff --git a/doc/user/project/milestones/img/milestones_promote_milestone.png b/doc/user/project/milestones/img/milestones_promote_milestone.png
index 5e7f94c316f..2ef85c5951d 100644
--- a/doc/user/project/milestones/img/milestones_promote_milestone.png
+++ b/doc/user/project/milestones/img/milestones_promote_milestone.png
Binary files differ
diff --git a/doc/user/project/pages/img/dns_add_new_a_record_example_updated_2018.png b/doc/user/project/pages/img/dns_add_new_a_record_example_updated_2018.png
index fa72df66587..0150329d4b2 100644
--- a/doc/user/project/pages/img/dns_add_new_a_record_example_updated_2018.png
+++ b/doc/user/project/pages/img/dns_add_new_a_record_example_updated_2018.png
Binary files differ
diff --git a/doc/user/project/pages/img/pages_create_project.png b/doc/user/project/pages/img/pages_create_project.png
index be47f9d2a44..69e84b84984 100644
--- a/doc/user/project/pages/img/pages_create_project.png
+++ b/doc/user/project/pages/img/pages_create_project.png
Binary files differ
diff --git a/doc/user/project/pages/img/pages_dns_details.png b/doc/user/project/pages/img/pages_dns_details.png
index 274e98fde4d..3e57f43f7ba 100644
--- a/doc/user/project/pages/img/pages_dns_details.png
+++ b/doc/user/project/pages/img/pages_dns_details.png
Binary files differ
diff --git a/doc/user/project/pages/img/pages_multiple_domains.png b/doc/user/project/pages/img/pages_multiple_domains.png
index 6bc92db6b41..76c39101439 100644
--- a/doc/user/project/pages/img/pages_multiple_domains.png
+++ b/doc/user/project/pages/img/pages_multiple_domains.png
Binary files differ
diff --git a/doc/user/project/pages/img/pages_remove.png b/doc/user/project/pages/img/pages_remove.png
index b064310380e..10299880247 100644
--- a/doc/user/project/pages/img/pages_remove.png
+++ b/doc/user/project/pages/img/pages_remove.png
Binary files differ
diff --git a/doc/user/project/pages/img/pages_upload_cert.png b/doc/user/project/pages/img/pages_upload_cert.png
index dc431ea3fef..64e5f8eced1 100644
--- a/doc/user/project/pages/img/pages_upload_cert.png
+++ b/doc/user/project/pages/img/pages_upload_cert.png
Binary files differ
diff --git a/doc/user/project/pages/img/verify_your_domain.png b/doc/user/project/pages/img/verify_your_domain.png
index 89c69cac9a5..d870f9e6505 100644
--- a/doc/user/project/pages/img/verify_your_domain.png
+++ b/doc/user/project/pages/img/verify_your_domain.png
Binary files differ
diff --git a/doc/user/project/pipelines/img/job_artifacts_pipelines_page.png b/doc/user/project/pipelines/img/job_artifacts_pipelines_page.png
index 3ccce4f9bb4..983f903ca72 100644
--- a/doc/user/project/pipelines/img/job_artifacts_pipelines_page.png
+++ b/doc/user/project/pipelines/img/job_artifacts_pipelines_page.png
Binary files differ
diff --git a/doc/user/project/pipelines/img/pipeline_schedule_play.png b/doc/user/project/pipelines/img/pipeline_schedule_play.png
index f594ceee19d..ec6eb0d156b 100644
--- a/doc/user/project/pipelines/img/pipeline_schedule_play.png
+++ b/doc/user/project/pipelines/img/pipeline_schedule_play.png
Binary files differ
diff --git a/doc/user/project/pipelines/img/pipeline_schedule_variables.png b/doc/user/project/pipelines/img/pipeline_schedule_variables.png
index 47a0c6f3697..74692add93a 100644
--- a/doc/user/project/pipelines/img/pipeline_schedule_variables.png
+++ b/doc/user/project/pipelines/img/pipeline_schedule_variables.png
Binary files differ
diff --git a/doc/user/project/pipelines/img/pipeline_schedules_list.png b/doc/user/project/pipelines/img/pipeline_schedules_list.png
index 2ab2061db94..541fe4f9b1d 100644
--- a/doc/user/project/pipelines/img/pipeline_schedules_list.png
+++ b/doc/user/project/pipelines/img/pipeline_schedules_list.png
Binary files differ
diff --git a/doc/user/project/pipelines/img/pipeline_schedules_new_form.png b/doc/user/project/pipelines/img/pipeline_schedules_new_form.png
index 5a0e5965992..95203ec861b 100644
--- a/doc/user/project/pipelines/img/pipeline_schedules_new_form.png
+++ b/doc/user/project/pipelines/img/pipeline_schedules_new_form.png
Binary files differ
diff --git a/doc/user/project/pipelines/img/pipeline_schedules_ownership.png b/doc/user/project/pipelines/img/pipeline_schedules_ownership.png
index 31ed83abb4d..8fc5c5fbc82 100644
--- a/doc/user/project/pipelines/img/pipeline_schedules_ownership.png
+++ b/doc/user/project/pipelines/img/pipeline_schedules_ownership.png
Binary files differ
diff --git a/doc/user/project/repository/branches/img/delete_merged_branches.png b/doc/user/project/repository/branches/img/delete_merged_branches.png
index 1856a624f74..649a758b95f 100644
--- a/doc/user/project/repository/branches/img/delete_merged_branches.png
+++ b/doc/user/project/repository/branches/img/delete_merged_branches.png
Binary files differ
diff --git a/doc/user/project/repository/gpg_signed_commits/img/profile_settings_gpg_keys_paste_pub.png b/doc/user/project/repository/gpg_signed_commits/img/profile_settings_gpg_keys_paste_pub.png
index 8e26d98f1b0..6e2ff33eebb 100644
--- a/doc/user/project/repository/gpg_signed_commits/img/profile_settings_gpg_keys_paste_pub.png
+++ b/doc/user/project/repository/gpg_signed_commits/img/profile_settings_gpg_keys_paste_pub.png
Binary files differ
diff --git a/doc/user/project/repository/gpg_signed_commits/img/profile_settings_gpg_keys_single_key.png b/doc/user/project/repository/gpg_signed_commits/img/profile_settings_gpg_keys_single_key.png
index 5c14df36d73..ae0a8696c6c 100644
--- a/doc/user/project/repository/gpg_signed_commits/img/profile_settings_gpg_keys_single_key.png
+++ b/doc/user/project/repository/gpg_signed_commits/img/profile_settings_gpg_keys_single_key.png
Binary files differ
diff --git a/doc/user/project/repository/gpg_signed_commits/img/project_signed_and_unsigned_commits.png b/doc/user/project/repository/gpg_signed_commits/img/project_signed_and_unsigned_commits.png
index 088ecfa6d89..e1d44f15f3f 100644
--- a/doc/user/project/repository/gpg_signed_commits/img/project_signed_and_unsigned_commits.png
+++ b/doc/user/project/repository/gpg_signed_commits/img/project_signed_and_unsigned_commits.png
Binary files differ
diff --git a/doc/user/project/repository/gpg_signed_commits/img/project_signed_commit_unverified_signature.png b/doc/user/project/repository/gpg_signed_commits/img/project_signed_commit_unverified_signature.png
index 4e3392406b1..763a677f94a 100644
--- a/doc/user/project/repository/gpg_signed_commits/img/project_signed_commit_unverified_signature.png
+++ b/doc/user/project/repository/gpg_signed_commits/img/project_signed_commit_unverified_signature.png
Binary files differ
diff --git a/doc/user/project/repository/gpg_signed_commits/img/project_signed_commit_verified_signature.png b/doc/user/project/repository/gpg_signed_commits/img/project_signed_commit_verified_signature.png
index 766970dee81..1b6fa3fc2e2 100644
--- a/doc/user/project/repository/gpg_signed_commits/img/project_signed_commit_verified_signature.png
+++ b/doc/user/project/repository/gpg_signed_commits/img/project_signed_commit_verified_signature.png
Binary files differ
diff --git a/doc/user/project/repository/img/compare_branches.png b/doc/user/project/repository/img/compare_branches.png
index d7ab587f030..52d5c518c45 100644
--- a/doc/user/project/repository/img/compare_branches.png
+++ b/doc/user/project/repository/img/compare_branches.png
Binary files differ
diff --git a/doc/user/project/repository/img/repository_languages.png b/doc/user/project/repository/img/repository_languages.png
index d9fb1278e06..5977ad7faae 100644
--- a/doc/user/project/repository/img/repository_languages.png
+++ b/doc/user/project/repository/img/repository_languages.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 31edb6bde3a..a6edea1fcce 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 4729f5383c0..4e156b8adc8 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 8d82f981527..7bb8b9e29e3 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 1c9beff8849..590989c360e 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 ede691f6f74..efa3087fc0c 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 13a4d721039..b40fb1ce58d 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_push_widget.png b/doc/user/project/repository/img/web_editor_new_push_widget.png
index 77756876d4f..8957b5d6a6b 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 b52d5cabdf2..33e8ed891b5 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_start_new_merge_request.png b/doc/user/project/repository/img/web_editor_start_new_merge_request.png
index 384e8320f15..85f4769661a 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 f21183125f6..4608843b1f4 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 7f31c2a8887..a4440ec3cc9 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_upload_file_dialog.png b/doc/user/project/repository/img/web_editor_upload_file_dialog.png
index 04e951406ad..c0e9a99aa61 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 b8c766d4b99..c80a9ae4b3d 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 4945590e3e8..668254073e8 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 eef79821f8b..7f21bb2335b 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_new_project.png b/doc/user/project/settings/img/import_export_new_project.png
index 9dd509dc4a0..b335700c5be 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 fb831dca32b..e1e5e031d81 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 9f3a8330e3a..32bcda03c7e 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/user/project/settings/img/sharing_and_permissions_settings.png b/doc/user/project/settings/img/sharing_and_permissions_settings.png
index 0f9cf9512af..f5e3e32f95c 100644
--- a/doc/user/project/settings/img/sharing_and_permissions_settings.png
+++ b/doc/user/project/settings/img/sharing_and_permissions_settings.png
Binary files differ
diff --git a/doc/user/project/web_ide/img/open_web_ide.png b/doc/user/project/web_ide/img/open_web_ide.png
index d1192daf506..02a5a564472 100644
--- a/doc/user/project/web_ide/img/open_web_ide.png
+++ b/doc/user/project/web_ide/img/open_web_ide.png
Binary files differ
diff --git a/doc/user/project/wiki/img/wiki_create_home_page.png b/doc/user/project/wiki/img/wiki_create_home_page.png
index f50f564034c..658af33d76e 100644
--- a/doc/user/project/wiki/img/wiki_create_home_page.png
+++ b/doc/user/project/wiki/img/wiki_create_home_page.png
Binary files differ
diff --git a/doc/user/project/wiki/img/wiki_create_new_page.png b/doc/user/project/wiki/img/wiki_create_new_page.png
index c19124a8923..8954ec0d3a8 100644
--- a/doc/user/project/wiki/img/wiki_create_new_page.png
+++ b/doc/user/project/wiki/img/wiki_create_new_page.png
Binary files differ
diff --git a/doc/user/project/wiki/img/wiki_create_new_page_modal.png b/doc/user/project/wiki/img/wiki_create_new_page_modal.png
index ece437967dc..b800508901b 100644
--- a/doc/user/project/wiki/img/wiki_create_new_page_modal.png
+++ b/doc/user/project/wiki/img/wiki_create_new_page_modal.png
Binary files differ
diff --git a/doc/user/project/wiki/img/wiki_move_page_1.png b/doc/user/project/wiki/img/wiki_move_page_1.png
index 0331c9d3a5c..189fcc9a845 100644
--- a/doc/user/project/wiki/img/wiki_move_page_1.png
+++ b/doc/user/project/wiki/img/wiki_move_page_1.png
Binary files differ
diff --git a/doc/user/project/wiki/img/wiki_move_page_2.png b/doc/user/project/wiki/img/wiki_move_page_2.png
index a8e0c055051..63e6ddb29c1 100644
--- a/doc/user/project/wiki/img/wiki_move_page_2.png
+++ b/doc/user/project/wiki/img/wiki_move_page_2.png
Binary files differ
diff --git a/doc/user/project/wiki/img/wiki_page_history.png b/doc/user/project/wiki/img/wiki_page_history.png
index 0e6af1b468d..5a1ae295ed2 100644
--- a/doc/user/project/wiki/img/wiki_page_history.png
+++ b/doc/user/project/wiki/img/wiki_page_history.png
Binary files differ
diff --git a/doc/user/project/wiki/img/wiki_sidebar.png b/doc/user/project/wiki/img/wiki_sidebar.png
index 59814e2a06e..ff39c861a73 100644
--- a/doc/user/project/wiki/img/wiki_sidebar.png
+++ b/doc/user/project/wiki/img/wiki_sidebar.png
Binary files differ
diff --git a/doc/user/search/img/issue_search_by_term.png b/doc/user/search/img/issue_search_by_term.png
index 3cefa3adb8b..64450c6a891 100644
--- a/doc/user/search/img/issue_search_by_term.png
+++ b/doc/user/search/img/issue_search_by_term.png
Binary files differ
diff --git a/doc/user/search/img/issue_search_filter.png b/doc/user/search/img/issue_search_filter.png
index f357abd6bac..d4de3ff7656 100644
--- a/doc/user/search/img/issue_search_filter.png
+++ b/doc/user/search/img/issue_search_filter.png
Binary files differ
diff --git a/doc/user/search/img/issues_mrs_shortcut.png b/doc/user/search/img/issues_mrs_shortcut.png
index cf43df98aa0..2fe1350c806 100644
--- a/doc/user/search/img/issues_mrs_shortcut.png
+++ b/doc/user/search/img/issues_mrs_shortcut.png
Binary files differ
diff --git a/doc/user/search/img/project_search.png b/doc/user/search/img/project_search.png
index 0b76d7d6038..b2525b2c771 100644
--- a/doc/user/search/img/project_search.png
+++ b/doc/user/search/img/project_search.png
Binary files differ
diff --git a/doc/workflow/ci_mr.png b/doc/workflow/ci_mr.png
index 77423c68190..85a609cb814 100644
--- a/doc/workflow/ci_mr.png
+++ b/doc/workflow/ci_mr.png
Binary files differ
diff --git a/doc/workflow/environment_branches.png b/doc/workflow/environment_branches.png
index 0941a4cad9c..0aff33c6bb8 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 3e82afca75b..77236137190 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 294775e1fdd..407ddfb4799 100644
--- a/doc/workflow/forking/merge_request.png
+++ b/doc/workflow/forking/merge_request.png
Binary files differ
diff --git a/doc/workflow/git_pull.png b/doc/workflow/git_pull.png
index 2dd06b56c56..0e56e59471c 100644
--- a/doc/workflow/git_pull.png
+++ b/doc/workflow/git_pull.png
Binary files differ
diff --git a/doc/workflow/gitlab_flow.png b/doc/workflow/gitlab_flow.png
index c3562cc69a8..a6f3c947843 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 c3664aa97f2..ceb0d4b1691 100644
--- a/doc/workflow/good_commit.png
+++ b/doc/workflow/good_commit.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 23139cc00c5..0c2d7d7bc73 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/forking_workflow_fork_button.png b/doc/workflow/img/forking_workflow_fork_button.png
index 29854e6c516..941d5363c35 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 9365fd13200..df938da5677 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/notification_group_settings.png b/doc/workflow/img/notification_group_settings.png
index fc096f46901..ed5e9459216 100644
--- a/doc/workflow/img/notification_group_settings.png
+++ b/doc/workflow/img/notification_group_settings.png
Binary files differ
diff --git a/doc/workflow/img/notification_project_settings.png b/doc/workflow/img/notification_project_settings.png
index 006432f65c9..e2db2037d94 100644
--- a/doc/workflow/img/notification_project_settings.png
+++ b/doc/workflow/img/notification_project_settings.png
Binary files differ
diff --git a/doc/workflow/img/todo_list_item.png b/doc/workflow/img/todo_list_item.png
index 076069b651e..91bbf9e5373 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 3fa37067d1e..aefec7a2d9c 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_mark_done_sidebar.png b/doc/workflow/img/todos_mark_done_sidebar.png
index a8e756a71db..2badd880b40 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/merge_request.png b/doc/workflow/merge_request.png
index 08dfc7f2468..010e95983fc 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 7e72e2a3be6..4fa22d2bb5d 100644
--- a/doc/workflow/messy_flow.png
+++ b/doc/workflow/messy_flow.png
Binary files differ
diff --git a/doc/workflow/mr_inline_comments.png b/doc/workflow/mr_inline_comments.png
index 6a2e66a01ba..a18801f56e4 100644
--- a/doc/workflow/mr_inline_comments.png
+++ b/doc/workflow/mr_inline_comments.png
Binary files differ
diff --git a/doc/workflow/production_branch.png b/doc/workflow/production_branch.png
index 648d5d5c92e..c132d51bfb6 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 8b9bb61a5cc..fe865177ba8 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 5194d75a667..0a7f61d0248 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 97519e5808f..6137ad2ee56 100644
--- a/doc/workflow/releases/new_tag.png
+++ b/doc/workflow/releases/new_tag.png
Binary files differ
diff --git a/doc/workflow/repository_mirroring/repository_mirroring_detect_host_keys.png b/doc/workflow/repository_mirroring/repository_mirroring_detect_host_keys.png
index 333648942f8..2377a4a6516 100644
--- a/doc/workflow/repository_mirroring/repository_mirroring_detect_host_keys.png
+++ b/doc/workflow/repository_mirroring/repository_mirroring_detect_host_keys.png
Binary files differ
diff --git a/doc/workflow/repository_mirroring/repository_mirroring_diverged_branch_push.png b/doc/workflow/repository_mirroring/repository_mirroring_diverged_branch_push.png
index 038b05cb31d..786bd23eee6 100644
--- a/doc/workflow/repository_mirroring/repository_mirroring_diverged_branch_push.png
+++ b/doc/workflow/repository_mirroring/repository_mirroring_diverged_branch_push.png
Binary files differ
diff --git a/doc/workflow/repository_mirroring/repository_mirroring_hard_failed_main.png b/doc/workflow/repository_mirroring/repository_mirroring_hard_failed_main.png
index 99d429a1802..d8af5ce129e 100644
--- a/doc/workflow/repository_mirroring/repository_mirroring_hard_failed_main.png
+++ b/doc/workflow/repository_mirroring/repository_mirroring_hard_failed_main.png
Binary files differ
diff --git a/doc/workflow/repository_mirroring/repository_mirroring_hard_failed_settings.png b/doc/workflow/repository_mirroring/repository_mirroring_hard_failed_settings.png
index 0ab07afa3cc..a10102e97ac 100644
--- a/doc/workflow/repository_mirroring/repository_mirroring_hard_failed_settings.png
+++ b/doc/workflow/repository_mirroring/repository_mirroring_hard_failed_settings.png
Binary files differ
diff --git a/doc/workflow/repository_mirroring/repository_mirroring_pull_advanced_host_keys.png b/doc/workflow/repository_mirroring/repository_mirroring_pull_advanced_host_keys.png
index 5da5a7436bb..1f1b3e1d5fb 100644
--- a/doc/workflow/repository_mirroring/repository_mirroring_pull_advanced_host_keys.png
+++ b/doc/workflow/repository_mirroring/repository_mirroring_pull_advanced_host_keys.png
Binary files differ
diff --git a/doc/workflow/repository_mirroring/repository_mirroring_pull_settings.png b/doc/workflow/repository_mirroring/repository_mirroring_pull_settings.png
index 4b9085302a1..b8dfddb3d02 100644
--- a/doc/workflow/repository_mirroring/repository_mirroring_pull_settings.png
+++ b/doc/workflow/repository_mirroring/repository_mirroring_pull_settings.png
Binary files differ
diff --git a/doc/workflow/repository_mirroring/repository_mirroring_pull_settings_for_ssh.png b/doc/workflow/repository_mirroring/repository_mirroring_pull_settings_for_ssh.png
index 8c2efdafa43..8f1de1d3003 100644
--- a/doc/workflow/repository_mirroring/repository_mirroring_pull_settings_for_ssh.png
+++ b/doc/workflow/repository_mirroring/repository_mirroring_pull_settings_for_ssh.png
Binary files differ
diff --git a/doc/workflow/repository_mirroring/repository_mirroring_ssh_host_keys_verified.png b/doc/workflow/repository_mirroring/repository_mirroring_ssh_host_keys_verified.png
index 93f3a532a0e..930d10a0822 100644
--- a/doc/workflow/repository_mirroring/repository_mirroring_ssh_host_keys_verified.png
+++ b/doc/workflow/repository_mirroring/repository_mirroring_ssh_host_keys_verified.png
Binary files differ
diff --git a/doc/workflow/repository_mirroring/repository_mirroring_ssh_public_key_authentication.png b/doc/workflow/repository_mirroring/repository_mirroring_ssh_public_key_authentication.png
index 6997ad511d9..adc1eedac44 100644
--- a/doc/workflow/repository_mirroring/repository_mirroring_ssh_public_key_authentication.png
+++ b/doc/workflow/repository_mirroring/repository_mirroring_ssh_public_key_authentication.png
Binary files differ
diff --git a/doc/workflow/time-tracking/time-tracking-example.png b/doc/workflow/time-tracking/time-tracking-example.png
index bbcabb602d6..a96e4da7f74 100644
--- a/doc/workflow/time-tracking/time-tracking-example.png
+++ b/doc/workflow/time-tracking/time-tracking-example.png
Binary files differ
diff --git a/doc/workflow/time-tracking/time-tracking-sidebar.png b/doc/workflow/time-tracking/time-tracking-sidebar.png
index d1ff5571f95..22124afed6f 100644
--- a/doc/workflow/time-tracking/time-tracking-sidebar.png
+++ b/doc/workflow/time-tracking/time-tracking-sidebar.png
Binary files differ
diff --git a/lib/api/api.rb b/lib/api/api.rb
index e2ad3c5f4e3..c000666d992 100644
--- a/lib/api/api.rb
+++ b/lib/api/api.rb
@@ -99,12 +99,13 @@ module API
mount ::API::Features
mount ::API::Files
mount ::API::GroupBoards
- mount ::API::Groups
mount ::API::GroupMilestones
+ mount ::API::Groups
+ mount ::API::GroupVariables
mount ::API::Internal
mount ::API::Issues
- mount ::API::Jobs
mount ::API::JobArtifacts
+ mount ::API::Jobs
mount ::API::Keys
mount ::API::Labels
mount ::API::Lint
@@ -122,11 +123,12 @@ module API
mount ::API::ProjectExport
mount ::API::ProjectImport
mount ::API::ProjectHooks
- mount ::API::Projects
mount ::API::ProjectMilestones
+ mount ::API::Projects
mount ::API::ProjectSnapshots
mount ::API::ProjectSnippets
mount ::API::ProtectedBranches
+ mount ::API::ProtectedTags
mount ::API::Repositories
mount ::API::Runner
mount ::API::Runners
@@ -143,7 +145,6 @@ module API
mount ::API::Triggers
mount ::API::Users
mount ::API::Variables
- mount ::API::GroupVariables
mount ::API::Version
mount ::API::Wikis
diff --git a/lib/api/award_emoji.rb b/lib/api/award_emoji.rb
index c3d93996816..bde4b3ff4f6 100644
--- a/lib/api/award_emoji.rb
+++ b/lib/api/award_emoji.rb
@@ -100,7 +100,7 @@ module API
end
def can_award_awardable?
- awardable.user_can_award?(current_user, params[:name])
+ awardable.user_can_award?(current_user)
end
def awardable
diff --git a/lib/api/entities.rb b/lib/api/entities.rb
index b6393fdef19..95b25d7351a 100644
--- a/lib/api/entities.rb
+++ b/lib/api/entities.rb
@@ -91,6 +91,7 @@ module API
group_link.group.name
end
expose :group_access, as: :group_access_level
+ expose :expires_at
end
class ProjectIdentity < Grape::Entity
@@ -428,6 +429,11 @@ module API
expose :merge_access_levels, using: Entities::ProtectedRefAccess
end
+ class ProtectedTag < Grape::Entity
+ expose :name
+ expose :create_access_levels, using: Entities::ProtectedRefAccess
+ end
+
class Milestone < Grape::Entity
expose :id, :iid
expose :project_id, if: -> (entity, options) { entity&.project_id }
diff --git a/lib/api/files.rb b/lib/api/files.rb
index 29d7489bd7c..ff4f75c12df 100644
--- a/lib/api/files.rb
+++ b/lib/api/files.rb
@@ -59,7 +59,7 @@ module API
params :simple_file_params do
requires :file_path, type: String, desc: 'The url encoded path to the file. Ex. lib%2Fclass%2Erb'
requires :branch, type: String, desc: 'Name of the branch to commit into. To create a new branch, also provide `start_branch`.'
- requires :commit_message, type: String, desc: 'Commit message'
+ requires :commit_message, type: String, allow_blank: false, desc: 'Commit message'
optional :start_branch, type: String, desc: 'Name of the branch to start the new commit from'
optional :author_email, type: String, desc: 'The email of the author'
optional :author_name, type: String, desc: 'The name of the author'
diff --git a/lib/api/group_milestones.rb b/lib/api/group_milestones.rb
index 93fa0b95857..4b4352c2b27 100644
--- a/lib/api/group_milestones.rb
+++ b/lib/api/group_milestones.rb
@@ -41,7 +41,7 @@ module API
use :optional_params
end
post ":id/milestones" do
- authorize! :admin_milestones, user_group
+ authorize! :admin_milestone, user_group
create_milestone_for(user_group)
end
@@ -53,11 +53,21 @@ module API
use :update_params
end
put ":id/milestones/:milestone_id" do
- authorize! :admin_milestones, user_group
+ authorize! :admin_milestone, user_group
update_milestone_for(user_group)
end
+ desc 'Remove a project milestone'
+ delete ":id/milestones/:milestone_id" do
+ authorize! :admin_milestone, user_group
+
+ milestone = user_group.milestones.find(params[:milestone_id])
+ Milestones::DestroyService.new(user_group, current_user).execute(milestone)
+
+ status(204)
+ end
+
desc 'Get all issues for a single group milestone' do
success Entities::IssueBasic
end
diff --git a/lib/api/helpers/notes_helpers.rb b/lib/api/helpers/notes_helpers.rb
index e2984b08eca..7b1f5c2584b 100644
--- a/lib/api/helpers/notes_helpers.rb
+++ b/lib/api/helpers/notes_helpers.rb
@@ -92,10 +92,7 @@ module API
parent = noteable_parent(noteable)
- if opts[:created_at]
- opts.delete(:created_at) unless
- current_user.admin? || parent.owned_by?(current_user)
- end
+ opts.delete(:created_at) unless current_user.can?(:set_note_created_at, policy_object)
opts[:updated_at] = opts[:created_at] if opts[:created_at]
diff --git a/lib/api/issues.rb b/lib/api/issues.rb
index bda05d1795b..cedfd2fbaa0 100644
--- a/lib/api/issues.rb
+++ b/lib/api/issues.rb
@@ -172,11 +172,8 @@ module API
authorize! :create_issue, user_project
- # Setting created_at time or iid only allowed for admins and project owners
- unless current_user.admin? || user_project.owner == current_user
- params.delete(:created_at)
- params.delete(:iid)
- end
+ params.delete(:created_at) unless current_user.can?(:set_issue_created_at, user_project)
+ params.delete(:iid) unless current_user.can?(:set_issue_iid, user_project)
issue_params = declared_params(include_missing: false)
@@ -216,8 +213,8 @@ module API
issue = user_project.issues.find_by!(iid: params.delete(:issue_iid))
authorize! :update_issue, issue
- # Setting created_at time only allowed for admins and project owners
- unless current_user.admin? || user_project.owner == current_user
+ # Setting created_at time only allowed for admins and project/group owners
+ unless current_user.admin? || user_project.owner == current_user || current_user.owned_groups.include?(user_project.owner)
params.delete(:updated_at)
end
diff --git a/lib/api/project_milestones.rb b/lib/api/project_milestones.rb
index 306dc0e63d7..72cf32d7717 100644
--- a/lib/api/project_milestones.rb
+++ b/lib/api/project_milestones.rb
@@ -64,7 +64,8 @@ module API
delete ":id/milestones/:milestone_id" do
authorize! :admin_milestone, user_project
- user_project.milestones.find(params[:milestone_id]).destroy
+ milestone = user_project.milestones.find(params[:milestone_id])
+ Milestones::DestroyService.new(user_project, current_user).execute(milestone)
status(204)
end
diff --git a/lib/api/project_snippets.rb b/lib/api/project_snippets.rb
index 1de5551fee9..0ada0ef4708 100644
--- a/lib/api/project_snippets.rb
+++ b/lib/api/project_snippets.rb
@@ -49,7 +49,7 @@ module API
params do
requires :title, type: String, desc: 'The title of the snippet'
requires :file_name, type: String, desc: 'The file name of the snippet'
- requires :code, type: String, desc: 'The content of the snippet'
+ requires :code, type: String, allow_blank: false, desc: 'The content of the snippet'
optional :description, type: String, desc: 'The description of a snippet'
requires :visibility, type: String,
values: Gitlab::VisibilityLevel.string_values,
@@ -78,7 +78,7 @@ module API
requires :snippet_id, type: Integer, desc: 'The ID of a project snippet'
optional :title, type: String, desc: 'The title of the snippet'
optional :file_name, type: String, desc: 'The file name of the snippet'
- optional :code, type: String, desc: 'The content of the snippet'
+ optional :code, type: String, allow_blank: false, desc: 'The content of the snippet'
optional :description, type: String, desc: 'The description of a snippet'
optional :visibility, type: String,
values: Gitlab::VisibilityLevel.string_values,
diff --git a/lib/api/projects.rb b/lib/api/projects.rb
index 5738bf220c6..2801ae918c6 100644
--- a/lib/api/projects.rb
+++ b/lib/api/projects.rb
@@ -386,7 +386,7 @@ module API
requires :forked_from_id, type: String, desc: 'The ID of the project it was forked from'
end
post ":id/fork/:forked_from_id" do
- authenticated_as_admin!
+ authorize! :admin_project, user_project
fork_from_project = find_project!(params[:forked_from_id])
diff --git a/lib/api/protected_tags.rb b/lib/api/protected_tags.rb
new file mode 100644
index 00000000000..bf0a7184e1c
--- /dev/null
+++ b/lib/api/protected_tags.rb
@@ -0,0 +1,79 @@
+module API
+ class ProtectedTags < Grape::API
+ include PaginationParams
+
+ TAG_ENDPOINT_REQUIREMENTS = API::PROJECT_ENDPOINT_REQUIREMENTS.merge(name: API::NO_SLASH_URL_PART_REGEX)
+
+ before { authorize_admin_project }
+
+ params do
+ requires :id, type: String, desc: 'The ID of a project'
+ end
+ resource :projects, requirements: API::PROJECT_ENDPOINT_REQUIREMENTS do
+ desc "Get a project's protected tags" do
+ detail 'This feature was introduced in GitLab 11.3.'
+ success Entities::ProtectedTag
+ end
+ params do
+ use :pagination
+ end
+ get ':id/protected_tags' do
+ protected_tags = user_project.protected_tags.preload(:create_access_levels)
+
+ present paginate(protected_tags), with: Entities::ProtectedTag, project: user_project
+ end
+
+ desc 'Get a single protected tag' do
+ detail 'This feature was introduced in GitLab 11.3.'
+ success Entities::ProtectedTag
+ end
+ params do
+ requires :name, type: String, desc: 'The name of the tag or wildcard'
+ end
+ get ':id/protected_tags/:name', requirements: TAG_ENDPOINT_REQUIREMENTS do
+ protected_tag = user_project.protected_tags.find_by!(name: params[:name])
+
+ present protected_tag, with: Entities::ProtectedTag, project: user_project
+ end
+
+ desc 'Protect a single tag or wildcard' do
+ detail 'This feature was introduced in GitLab 11.3.'
+ success Entities::ProtectedTag
+ end
+ params do
+ requires :name, type: String, desc: 'The name of the protected tag'
+ optional :create_access_level, type: Integer, default: Gitlab::Access::MAINTAINER,
+ values: ProtectedRefAccess::ALLOWED_ACCESS_LEVELS,
+ desc: 'Access levels allowed to create (defaults: `40`, maintainer access level)'
+ end
+ post ':id/protected_tags' do
+ protected_tags_params = {
+ name: params[:name],
+ create_access_levels_attributes: [{ access_level: params[:create_access_level] }]
+ }
+
+ protected_tag = ::ProtectedTags::CreateService.new(user_project,
+ current_user,
+ protected_tags_params).execute
+
+ if protected_tag.persisted?
+ present protected_tag, with: Entities::ProtectedTag, project: user_project
+ else
+ render_api_error!(protected_tag.errors.full_messages, 422)
+ end
+ end
+
+ desc 'Unprotect a single tag' do
+ detail 'This feature was introduced in GitLab 11.3.'
+ end
+ params do
+ requires :name, type: String, desc: 'The name of the protected tag'
+ end
+ delete ':id/protected_tags/:name', requirements: TAG_ENDPOINT_REQUIREMENTS do
+ protected_tag = user_project.protected_tags.find_by!(name: params[:name])
+
+ destroy_conditionally!(protected_tag)
+ end
+ end
+ end
+end
diff --git a/lib/banzai/reference_parser/merge_request_parser.rb b/lib/banzai/reference_parser/merge_request_parser.rb
index a370ff5b5b3..9e5d55f72bc 100644
--- a/lib/banzai/reference_parser/merge_request_parser.rb
+++ b/lib/banzai/reference_parser/merge_request_parser.rb
@@ -14,11 +14,12 @@ module Banzai
# Eager loading these ensures we don't end up running dozens of
# queries in this process.
target_project: [
- { namespace: :owner },
+ { namespace: [:owner, :route] },
{ group: [:owners, :group_members] },
:invited_groups,
:project_members,
- :project_feature
+ :project_feature,
+ :route
]
}),
self.class.data_attribute
diff --git a/lib/feature.rb b/lib/feature.rb
index 09c5ef3ad94..24dbcb32fc0 100644
--- a/lib/feature.rb
+++ b/lib/feature.rb
@@ -47,7 +47,8 @@ class Feature
end
def disabled?(key, thing = nil)
- !enabled?(key, thing)
+ # we need to make different method calls to make it easy to mock / define expectations in test mode
+ thing.nil? ? !enabled?(key) : !enabled?(key, thing)
end
def enable(key, thing = true)
diff --git a/lib/gitlab/auth/ldap/access.rb b/lib/gitlab/auth/ldap/access.rb
index 865185eb5db..eeab7791643 100644
--- a/lib/gitlab/auth/ldap/access.rb
+++ b/lib/gitlab/auth/ldap/access.rb
@@ -19,8 +19,10 @@ module Gitlab
# Whether user is allowed, or not, we should update
# permissions to keep things clean
if access.allowed?
- access.update_user
- Users::UpdateService.new(user, user: user, last_credential_check_at: Time.now).execute
+ unless Gitlab::Database.read_only?
+ access.update_user
+ Users::UpdateService.new(user, user: user, last_credential_check_at: Time.now).execute
+ end
true
else
@@ -60,6 +62,12 @@ module Gitlab
false
end
+ def update_user
+ # no-op in CE
+ end
+
+ private
+
def adapter
@adapter ||= Gitlab::Auth::LDAP::Adapter.new(provider)
end
@@ -68,16 +76,16 @@ module Gitlab
Gitlab::Auth::LDAP::Config.new(provider)
end
- def find_ldap_user
- Gitlab::Auth::LDAP::Person.find_by_dn(ldap_identity.extern_uid, adapter)
- end
-
def ldap_user
return unless provider
@ldap_user ||= find_ldap_user
end
+ def find_ldap_user
+ Gitlab::Auth::LDAP::Person.find_by_dn(ldap_identity.extern_uid, adapter)
+ end
+
def block_user(user, reason)
user.ldap_block
@@ -102,10 +110,6 @@ module Gitlab
"unblocking Gitlab user \"#{user.name}\" (#{user.email})"
)
end
-
- def update_user
- # no-op in CE
- end
end
end
end
diff --git a/lib/gitlab/auth/o_auth/provider.rb b/lib/gitlab/auth/o_auth/provider.rb
index e73743944a9..26da9d09ccc 100644
--- a/lib/gitlab/auth/o_auth/provider.rb
+++ b/lib/gitlab/auth/o_auth/provider.rb
@@ -29,6 +29,7 @@ module Gitlab
def self.enabled?(name)
return true if name == 'database'
+ return true if self.ldap_provider?(name) && providers.include?(name.to_sym)
Gitlab::Auth.omniauth_enabled? && providers.include?(name.to_sym)
end
diff --git a/lib/gitlab/bitbucket_server_import/importer.rb b/lib/gitlab/bitbucket_server_import/importer.rb
index 268d21a77d1..b591d94668f 100644
--- a/lib/gitlab/bitbucket_server_import/importer.rb
+++ b/lib/gitlab/bitbucket_server_import/importer.rb
@@ -1,7 +1,10 @@
+# frozen_string_literal: true
+
module Gitlab
module BitbucketServerImport
class Importer
include Gitlab::ShellAdapter
+
attr_reader :recover_missing_commits
attr_reader :project, :project_key, :repository_slug, :client, :errors, :users
@@ -175,21 +178,18 @@ module Gitlab
description = ''
description += @formatter.author_line(pull_request.author) unless find_user_id(pull_request.author_email)
description += pull_request.description if pull_request.description
-
- source_branch_sha = pull_request.source_branch_sha
- target_branch_sha = pull_request.target_branch_sha
author_id = gitlab_user_id(pull_request.author_email)
attributes = {
iid: pull_request.iid,
title: pull_request.title,
description: description,
- source_project: project,
+ source_project_id: project.id,
source_branch: Gitlab::Git.ref_name(pull_request.source_branch_name),
- source_branch_sha: source_branch_sha,
- target_project: project,
+ source_branch_sha: pull_request.source_branch_sha,
+ target_project_id: project.id,
target_branch: Gitlab::Git.ref_name(pull_request.target_branch_name),
- target_branch_sha: target_branch_sha,
+ target_branch_sha: pull_request.target_branch_sha,
state: pull_request.state,
author_id: author_id,
assignee_id: nil,
@@ -197,7 +197,9 @@ module Gitlab
updated_at: pull_request.updated_at
}
- merge_request = project.merge_requests.create!(attributes)
+ creator = Gitlab::Import::MergeRequestCreator.new(project)
+ merge_request = creator.execute(attributes)
+
import_pull_request_comments(pull_request, merge_request) if merge_request.persisted?
end
diff --git a/lib/gitlab/ci/status/build/failed.rb b/lib/gitlab/ci/status/build/failed.rb
index 703f0b9217b..508b4814631 100644
--- a/lib/gitlab/ci/status/build/failed.rb
+++ b/lib/gitlab/ci/status/build/failed.rb
@@ -32,7 +32,7 @@ module Gitlab
end
def description
- "<br> (#{failure_reason_message})"
+ "- (#{failure_reason_message})"
end
def failure_reason_message
diff --git a/lib/gitlab/diff/highlight.rb b/lib/gitlab/diff/highlight.rb
index 5c1baa19b66..1f012043e56 100644
--- a/lib/gitlab/diff/highlight.rb
+++ b/lib/gitlab/diff/highlight.rb
@@ -37,7 +37,7 @@ module Gitlab
end
end
- diff_line.text = rich_line
+ diff_line.rich_text = rich_line
diff_line
end
diff --git a/lib/gitlab/diff/line.rb b/lib/gitlab/diff/line.rb
index 1faf7770634..1ab6df0b6ae 100644
--- a/lib/gitlab/diff/line.rb
+++ b/lib/gitlab/diff/line.rb
@@ -1,16 +1,17 @@
module Gitlab
module Diff
class Line
- SERIALIZE_KEYS = %i(line_code text type index old_pos new_pos).freeze
+ SERIALIZE_KEYS = %i(line_code rich_text text type index old_pos new_pos).freeze
attr_reader :line_code, :type, :index, :old_pos, :new_pos
attr_writer :rich_text
attr_accessor :text
- def initialize(text, type, index, old_pos, new_pos, parent_file: nil, line_code: nil)
+ def initialize(text, type, index, old_pos, new_pos, parent_file: nil, line_code: nil, rich_text: nil)
@text, @type, @index = text, type, index
@old_pos, @new_pos = old_pos, new_pos
@parent_file = parent_file
+ @rich_text = rich_text
# When line code is not provided from cache store we build it
# using the parent_file(Diff::File or Conflict::File).
@@ -18,7 +19,7 @@ module Gitlab
end
def self.init_from_hash(hash)
- new(hash[:text], hash[:type], hash[:index], hash[:old_pos], hash[:new_pos], line_code: hash[:line_code])
+ new(hash[:text], hash[:type], hash[:index], hash[:old_pos], hash[:new_pos], line_code: hash[:line_code], rich_text: hash[:rich_text])
end
def to_hash
@@ -85,7 +86,7 @@ module Gitlab
old_line: old_line,
new_line: new_line,
text: text,
- rich_text: rich_text || text,
+ rich_text: rich_text || CGI.escapeHTML(text),
meta_data: meta_positions
}
end
diff --git a/lib/gitlab/github_import.rb b/lib/gitlab/github_import.rb
index 65b5e30c70f..d40b06f969f 100644
--- a/lib/gitlab/github_import.rb
+++ b/lib/gitlab/github_import.rb
@@ -10,24 +10,6 @@ module Gitlab
Client.new(token_to_use, parallel: parallel)
end
- # Inserts a raw row and returns the ID of the inserted row.
- #
- # attributes - The attributes/columns to set.
- # relation - An ActiveRecord::Relation to use for finding the ID of the row
- # when using MySQL.
- def self.insert_and_return_id(attributes, relation)
- # We use bulk_insert here so we can bypass any queries executed by
- # callbacks or validation rules, as doing this wouldn't scale when
- # importing very large projects.
- result = Gitlab::Database
- .bulk_insert(relation.table_name, [attributes], return_ids: true)
-
- # MySQL doesn't support returning the IDs of a bulk insert in a way that
- # is not a pain, so in this case we'll issue an extra query instead.
- result.first ||
- relation.where(iid: attributes[:iid]).limit(1).pluck(:id).first
- end
-
# Returns the ID of the ghost user.
def self.ghost_user_id
key = 'github-import/ghost-user-id'
diff --git a/lib/gitlab/github_import/importer/issue_importer.rb b/lib/gitlab/github_import/importer/issue_importer.rb
index cb4d7a6a0b6..4226eee85cc 100644
--- a/lib/gitlab/github_import/importer/issue_importer.rb
+++ b/lib/gitlab/github_import/importer/issue_importer.rb
@@ -4,6 +4,8 @@ module Gitlab
module GithubImport
module Importer
class IssueImporter
+ include Gitlab::Import::DatabaseHelpers
+
attr_reader :project, :issue, :client, :user_finder, :milestone_finder,
:issuable_finder
@@ -55,7 +57,7 @@ module Gitlab
updated_at: issue.updated_at
}
- GithubImport.insert_and_return_id(attributes, project.issues).tap do |id|
+ insert_and_return_id(attributes, project.issues).tap do |id|
# We use .insert_and_return_id which effectively disables all callbacks.
# Trigger iid logic here to make sure we track internal id values consistently.
project.issues.find(id).ensure_project_iid!
diff --git a/lib/gitlab/github_import/importer/pull_request_importer.rb b/lib/gitlab/github_import/importer/pull_request_importer.rb
index ed17aa54373..ae7c4cf1b38 100644
--- a/lib/gitlab/github_import/importer/pull_request_importer.rb
+++ b/lib/gitlab/github_import/importer/pull_request_importer.rb
@@ -4,6 +4,8 @@ module Gitlab
module GithubImport
module Importer
class PullRequestImporter
+ include Gitlab::Import::MergeRequestHelpers
+
attr_reader :pull_request, :project, :client, :user_finder,
:milestone_finder, :issuable_finder
@@ -44,81 +46,27 @@ module Gitlab
description = MarkdownText
.format(pull_request.description, pull_request.author, author_found)
- # This work must be wrapped in a transaction as otherwise we can leave
- # behind incomplete data in the event of an error. This can then lead
- # to duplicate key errors when jobs are retried.
- MergeRequest.transaction do
- attributes = {
- iid: pull_request.iid,
- title: pull_request.truncated_title,
- description: description,
- source_project_id: project.id,
- target_project_id: project.id,
- source_branch: pull_request.formatted_source_branch,
- target_branch: pull_request.target_branch,
- state: pull_request.state,
- milestone_id: milestone_finder.id_for(pull_request),
- author_id: author_id,
- assignee_id: user_finder.assignee_id_for(pull_request),
- created_at: pull_request.created_at,
- updated_at: pull_request.updated_at
- }
-
- # When creating merge requests there are a lot of hooks that may
- # run, for many different reasons. Many of these hooks (e.g. the
- # ones used for rendering Markdown) are completely unnecessary and
- # may even lead to transaction timeouts.
- #
- # To ensure importing pull requests has a minimal impact and can
- # complete in a reasonable time we bypass all the hooks by inserting
- # the row and then retrieving it. We then only perform the
- # additional work that is strictly necessary.
- merge_request_id = GithubImport
- .insert_and_return_id(attributes, project.merge_requests)
-
- merge_request = project.merge_requests.find(merge_request_id)
-
- # We use .insert_and_return_id which effectively disables all callbacks.
- # Trigger iid logic here to make sure we track internal id values consistently.
- merge_request.ensure_target_project_iid!
+ attributes = {
+ iid: pull_request.iid,
+ title: pull_request.truncated_title,
+ description: description,
+ source_project_id: project.id,
+ target_project_id: project.id,
+ source_branch: pull_request.formatted_source_branch,
+ target_branch: pull_request.target_branch,
+ state: pull_request.state,
+ milestone_id: milestone_finder.id_for(pull_request),
+ author_id: author_id,
+ assignee_id: user_finder.assignee_id_for(pull_request),
+ created_at: pull_request.created_at,
+ updated_at: pull_request.updated_at
+ }
- [merge_request, false]
- end
- rescue ActiveRecord::InvalidForeignKey
- # It's possible the project has been deleted since scheduling this
- # job. In this case we'll just skip creating the merge request.
- []
- rescue ActiveRecord::RecordNotUnique
- # It's possible we previously created the MR, but failed when updating
- # the Git data. In this case we'll just continue working on the
- # existing row.
- [project.merge_requests.find_by(iid: pull_request.iid), true]
+ create_merge_request_without_hooks(project, attributes, pull_request.iid)
end
- def insert_git_data(merge_request, already_exists = false)
- # These fields are set so we can create the correct merge request
- # diffs.
- merge_request.source_branch_sha = pull_request.source_branch_sha
- merge_request.target_branch_sha = pull_request.target_branch_sha
-
- merge_request.keep_around_commit
-
- # MR diffs normally use an "after_save" hook to pull data from Git.
- # All of this happens in the transaction started by calling
- # create/save/etc. This in turn can lead to these transactions being
- # held open for much longer than necessary. To work around this we
- # first save the diff, then populate it.
- diff =
- if already_exists
- merge_request.merge_request_diffs.take ||
- merge_request.merge_request_diffs.build
- else
- merge_request.merge_request_diffs.build
- end
-
- diff.importing = true
- diff.save
- diff.save_git_content
+ def insert_git_data(merge_request, already_exists)
+ insert_or_replace_git_data(merge_request, pull_request.source_branch_sha, pull_request.target_branch_sha, already_exists)
end
end
end
diff --git a/lib/gitlab/i18n.rb b/lib/gitlab/i18n.rb
index b8213929c6a..7346eab9e76 100644
--- a/lib/gitlab/i18n.rb
+++ b/lib/gitlab/i18n.rb
@@ -5,6 +5,7 @@ module Gitlab
AVAILABLE_LANGUAGES = {
'en' => 'English',
'es' => 'Español',
+ 'gl_ES' => 'Galego',
'de' => 'Deutsch',
'fr' => 'Français',
'pt_BR' => 'Português (Brasil)',
diff --git a/lib/gitlab/import/database_helpers.rb b/lib/gitlab/import/database_helpers.rb
new file mode 100644
index 00000000000..80857061933
--- /dev/null
+++ b/lib/gitlab/import/database_helpers.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Import
+ module DatabaseHelpers
+ # Inserts a raw row and returns the ID of the inserted row.
+ #
+ # attributes - The attributes/columns to set.
+ # relation - An ActiveRecord::Relation to use for finding the ID of the row
+ # when using MySQL.
+ def insert_and_return_id(attributes, relation)
+ # We use bulk_insert here so we can bypass any queries executed by
+ # callbacks or validation rules, as doing this wouldn't scale when
+ # importing very large projects.
+ result = Gitlab::Database
+ .bulk_insert(relation.table_name, [attributes], return_ids: true)
+
+ # MySQL doesn't support returning the IDs of a bulk insert in a way that
+ # is not a pain, so in this case we'll issue an extra query instead.
+ result.first ||
+ relation.where(iid: attributes[:iid]).limit(1).pluck(:id).first
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/import/merge_request_creator.rb b/lib/gitlab/import/merge_request_creator.rb
new file mode 100644
index 00000000000..a01951b0762
--- /dev/null
+++ b/lib/gitlab/import/merge_request_creator.rb
@@ -0,0 +1,40 @@
+# frozen_string_literal: true
+
+# This module is designed for importers that need to create many merge
+# requests quickly. When creating merge requests there are a lot of hooks
+# that may run, for many different reasons. Many of these hooks (e.g. the ones
+# used for rendering Markdown) are completely unnecessary and may even lead to
+# transaction timeouts.
+#
+# To ensure importing merge requests requests has a minimal impact and can
+# complete in a reasonable time we bypass all the hooks by inserting the row
+# and then retrieving it. We then only perform the additional work that is
+# strictly necessary.
+module Gitlab
+ module Import
+ class MergeRequestCreator
+ include ::Gitlab::Import::DatabaseHelpers
+ include ::Gitlab::Import::MergeRequestHelpers
+
+ attr_accessor :project
+
+ def initialize(project)
+ @project = project
+ end
+
+ def execute(attributes)
+ source_branch_sha = attributes.delete(:source_branch_sha)
+ target_branch_sha = attributes.delete(:target_branch_sha)
+ iid = attributes[:iid]
+
+ merge_request, already_exists = create_merge_request_without_hooks(project, attributes, iid)
+
+ if merge_request
+ insert_or_replace_git_data(merge_request, source_branch_sha, target_branch_sha, already_exists)
+ end
+
+ merge_request
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/import/merge_request_helpers.rb b/lib/gitlab/import/merge_request_helpers.rb
new file mode 100644
index 00000000000..8ba70700dc1
--- /dev/null
+++ b/lib/gitlab/import/merge_request_helpers.rb
@@ -0,0 +1,70 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Import
+ module MergeRequestHelpers
+ include DatabaseHelpers
+
+ def create_merge_request_without_hooks(project, attributes, iid)
+ # This work must be wrapped in a transaction as otherwise we can leave
+ # behind incomplete data in the event of an error. This can then lead
+ # to duplicate key errors when jobs are retried.
+ MergeRequest.transaction do
+ # When creating merge requests there are a lot of hooks that may
+ # run, for many different reasons. Many of these hooks (e.g. the
+ # ones used for rendering Markdown) are completely unnecessary and
+ # may even lead to transaction timeouts.
+ #
+ # To ensure importing pull requests has a minimal impact and can
+ # complete in a reasonable time we bypass all the hooks by inserting
+ # the row and then retrieving it. We then only perform the
+ # additional work that is strictly necessary.
+ merge_request_id = insert_and_return_id(attributes, project.merge_requests)
+
+ merge_request = project.merge_requests.find(merge_request_id)
+
+ # We use .insert_and_return_id which effectively disables all callbacks.
+ # Trigger iid logic here to make sure we track internal id values consistently.
+ merge_request.ensure_target_project_iid!
+
+ [merge_request, false]
+ end
+ rescue ActiveRecord::InvalidForeignKey
+ # It's possible the project has been deleted since scheduling this
+ # job. In this case we'll just skip creating the merge request.
+ []
+ rescue ActiveRecord::RecordNotUnique
+ # It's possible we previously created the MR, but failed when updating
+ # the Git data. In this case we'll just continue working on the
+ # existing row.
+ [project.merge_requests.find_by(iid: iid), true]
+ end
+
+ def insert_or_replace_git_data(merge_request, source_branch_sha, target_branch_sha, already_exists = false)
+ # These fields are set so we can create the correct merge request
+ # diffs.
+ merge_request.source_branch_sha = source_branch_sha
+ merge_request.target_branch_sha = target_branch_sha
+
+ merge_request.keep_around_commit
+
+ # MR diffs normally use an "after_save" hook to pull data from Git.
+ # All of this happens in the transaction started by calling
+ # create/save/etc. This in turn can lead to these transactions being
+ # held open for much longer than necessary. To work around this we
+ # first save the diff, then populate it.
+ diff =
+ if already_exists
+ merge_request.merge_request_diffs.take ||
+ merge_request.merge_request_diffs.build
+ else
+ merge_request.merge_request_diffs.build
+ end
+
+ diff.importing = true
+ diff.save
+ diff.save_git_content
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/import_export/uploads_manager.rb b/lib/gitlab/import_export/uploads_manager.rb
index 07875ebb56a..e0d4235e65b 100644
--- a/lib/gitlab/import_export/uploads_manager.rb
+++ b/lib/gitlab/import_export/uploads_manager.rb
@@ -13,13 +13,11 @@ module Gitlab
end
def save
- copy_files(@from, uploads_export_path) if File.directory?(@from)
-
if File.file?(@from) && @relative_export_path == 'avatar'
copy_files(@from, File.join(uploads_export_path, @project.avatar.filename))
end
- copy_from_object_storage
+ copy_project_uploads
true
rescue => e
@@ -48,14 +46,19 @@ module Gitlab
UploadService.new(@project, File.open(upload, 'r'), FileUploader, uploader_context).execute
end
- def copy_from_object_storage
- return unless Gitlab::ImportExport.object_storage?
-
+ def copy_project_uploads
each_uploader do |uploader|
next unless uploader.file
- next if uploader.upload.local? # Already copied, using the old method
- download_and_copy(uploader)
+ if uploader.upload.local?
+ next unless uploader.upload.exist?
+
+ copy_files(uploader.absolute_path, File.join(uploads_export_path, uploader.upload.path))
+ else
+ next unless Gitlab::ImportExport.object_storage?
+
+ download_and_copy(uploader)
+ end
end
end
diff --git a/lib/gitlab/middleware/multipart.rb b/lib/gitlab/middleware/multipart.rb
index 18f91db98fc..3d588918adf 100644
--- a/lib/gitlab/middleware/multipart.rb
+++ b/lib/gitlab/middleware/multipart.rb
@@ -82,9 +82,13 @@ module Gitlab
end
def open_file(params, key)
- ::UploadedFile.from_params(
- params, key,
- [FileUploader.root, Gitlab.config.uploads.storage_path])
+ allowed_paths = [
+ FileUploader.root,
+ Gitlab.config.uploads.storage_path,
+ File.join(Rails.root, 'public/uploads/tmp')
+ ]
+
+ ::UploadedFile.from_params(params, key, allowed_paths)
end
end
diff --git a/lib/gitlab/path_regex.rb b/lib/gitlab/path_regex.rb
index 61653044433..359dd2bcbc7 100644
--- a/lib/gitlab/path_regex.rb
+++ b/lib/gitlab/path_regex.rb
@@ -40,6 +40,7 @@ module Gitlab
invites
jwt
koding
+ login
notification_settings
oauth
profile
diff --git a/lib/gitlab/url_blocker.rb b/lib/gitlab/url_blocker.rb
index 38be75b7482..3b483f27e70 100644
--- a/lib/gitlab/url_blocker.rb
+++ b/lib/gitlab/url_blocker.rb
@@ -31,6 +31,7 @@ module Gitlab
validate_localhost!(addrs_info) unless allow_localhost
validate_local_network!(addrs_info) unless allow_local_network
+ validate_link_local!(addrs_info) unless allow_local_network
true
end
@@ -89,6 +90,13 @@ module Gitlab
raise BlockedUrlError, "Requests to the local network are not allowed"
end
+ def validate_link_local!(addrs_info)
+ netmask = IPAddr.new('169.254.0.0/16')
+ return unless addrs_info.any? { |addr| addr.ipv6_linklocal? || netmask.include?(addr.ip_address) }
+
+ raise BlockedUrlError, "Requests to the link local network are not allowed"
+ end
+
def internal?(uri)
internal_web?(uri) || internal_shell?(uri)
end
diff --git a/lib/gitlab/usage_data.rb b/lib/gitlab/usage_data.rb
index 22c9638ecc0..7797bd5fab2 100644
--- a/lib/gitlab/usage_data.rb
+++ b/lib/gitlab/usage_data.rb
@@ -34,6 +34,7 @@ module Gitlab
def system_usage_data
{
counts: {
+ assignee_lists: List.assignee.count,
boards: Board.count,
ci_builds: ::Ci::Build.count,
ci_internal_pipelines: ::Ci::Pipeline.internal.count,
@@ -61,9 +62,11 @@ module Gitlab
groups: Group.count,
issues: Issue.count,
keys: Key.count,
+ label_lists: List.label.count,
labels: Label.count,
lfs_objects: LfsObject.count,
merge_requests: MergeRequest.count,
+ milestone_lists: List.milestone.count,
milestones: Milestone.count,
notes: Note.count,
pages_domains: PagesDomain.count,
diff --git a/lib/tasks/gettext.rake b/lib/tasks/gettext.rake
index f431352b61e..a497d26312e 100644
--- a/lib/tasks/gettext.rake
+++ b/lib/tasks/gettext.rake
@@ -82,7 +82,7 @@ namespace :gettext do
# `gettext:find` writes touches to temp files to `stderr` which would cause
# `static-analysis` to report failures. We can ignore these.
- silence_stream($stderr) do
+ silence_sdterr do
Rake::Task['gettext:find'].invoke
end
@@ -118,4 +118,15 @@ namespace :gettext do
end
end
end
+
+ def silence_sdterr(&block)
+ old_stderr = $stderr.dup
+ $stderr.reopen(File::NULL)
+ $stderr.sync = true
+
+ yield
+ ensure
+ $stderr.reopen(old_stderr)
+ old_stderr.close
+ end
end
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 73bff79aabe..ce5d82d479b 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -2391,6 +2391,18 @@ msgstr ""
msgid "Enter in your Bitbucket Server URL and personal access token below"
msgstr ""
+msgid "Enter the issue description"
+msgstr ""
+
+msgid "Enter the issue title"
+msgstr ""
+
+msgid "Enter the merge request description"
+msgstr ""
+
+msgid "Enter the merge request title"
+msgstr ""
+
msgid "Environments"
msgstr ""
@@ -2508,6 +2520,12 @@ msgstr ""
msgid "Error loading project data. Please try again."
msgstr ""
+msgid "Error loading template types."
+msgstr ""
+
+msgid "Error loading template."
+msgstr ""
+
msgid "Error occurred when toggling the notification subscription"
msgstr ""
@@ -3614,10 +3632,10 @@ msgstr ""
msgid "Milestones"
msgstr ""
-msgid "Milestones| You’re about to permanently delete the milestone %{milestoneTitle} from this project and remove it from %{issuesWithCount} and %{mergeRequestsWithCount}. Once deleted, it cannot be undone or recovered."
+msgid "Milestones| You’re about to permanently delete the milestone %{milestoneTitle} and remove it from %{issuesWithCount} and %{mergeRequestsWithCount}. Once deleted, it cannot be undone or recovered."
msgstr ""
-msgid "Milestones| You’re about to permanently delete the milestone %{milestoneTitle} from this project. %{milestoneTitle} is not currently used in any issues or merge requests."
+msgid "Milestones| You’re about to permanently delete the milestone %{milestoneTitle}. This milestone is not currently used in any issues or merge requests."
msgstr ""
msgid "Milestones|Delete milestone"
@@ -5044,6 +5062,9 @@ msgstr ""
msgid "Settings"
msgstr ""
+msgid "Setup a %{type} Runner manually"
+msgstr ""
+
msgid "Setup a specific Runner automatically"
msgstr ""
@@ -5471,6 +5492,9 @@ msgstr ""
msgid "The collection of events added to the data gathered for that stage."
msgstr ""
+msgid "The deployment of this job to %{environmentLink} did not succeed."
+msgstr ""
+
msgid "The fork relationship has been removed."
msgstr ""
@@ -5546,6 +5570,9 @@ msgstr ""
msgid "The time taken by each data entry gathered by that stage."
msgstr ""
+msgid "The update action will time out after %{number_of_minutes} minutes. For big repositories, use a clone/push combination."
+msgstr ""
+
msgid "The user map is a JSON document mapping the Google Code users that participated on your projects to the way their email addresses and usernames will be imported into GitLab. You can change this by changing the value on the right hand side of <code>:</code>. Be sure to preserve the surrounding double quotes, other punctuation and the email address or username on the left hand side."
msgstr ""
@@ -5651,6 +5678,18 @@ msgstr ""
msgid "This job has not started yet"
msgstr ""
+msgid "This job is an out-of-date deployment to %{environmentLink}."
+msgstr ""
+
+msgid "This job is an out-of-date deployment to %{environmentLink}. View the most recent deployment %{deploymentLink}."
+msgstr ""
+
+msgid "This job is creating a deployment to %{environmentLink} and will overwrite the last %{deploymentLink}."
+msgstr ""
+
+msgid "This job is creating a deployment to %{environmentLink}."
+msgstr ""
+
msgid "This job is in pending state and is waiting to be picked by a runner"
msgstr ""
@@ -5660,6 +5699,9 @@ msgstr ""
msgid "This job is stuck, because you don't have any active runners that can run this job."
msgstr ""
+msgid "This job is the most recent deployment to %{link}."
+msgstr ""
+
msgid "This job requires a manual action"
msgstr ""
@@ -6700,6 +6742,9 @@ msgstr ""
msgid "mrWidget|The source branch has been removed"
msgstr ""
+msgid "mrWidget|The source branch is %{commitsBehindLinkStart}%{commitsBehind}%{commitsBehindLinkEnd} the target branch"
+msgstr ""
+
msgid "mrWidget|The source branch is being removed"
msgstr ""
diff --git a/package.json b/package.json
index f5fc759f76e..17ff85c9cd0 100644
--- a/package.json
+++ b/package.json
@@ -18,7 +18,7 @@
"webpack-prod": "NODE_ENV=production webpack --config config/webpack.config.js"
},
"dependencies": {
- "@gitlab-org/gitlab-svgs": "^1.27.0",
+ "@gitlab-org/gitlab-svgs": "^1.28.0",
"@gitlab-org/gitlab-ui": "1.0.5",
"autosize": "^4.0.0",
"axios": "^0.17.1",
diff --git a/qa/qa.rb b/qa/qa.rb
index 90461b16dd4..8e23b444f3b 100644
--- a/qa/qa.rb
+++ b/qa/qa.rb
@@ -83,6 +83,7 @@ module QA
# Test scenario entrypoints.
#
module Test
+ autoload :Instance, 'qa/scenario/test/instance'
module Instance
autoload :All, 'qa/scenario/test/instance/all'
autoload :Smoke, 'qa/scenario/test/instance/smoke'
diff --git a/qa/qa/page/project/import/github.rb b/qa/qa/page/project/import/github.rb
index 36567927194..1a410a0f8a5 100644
--- a/qa/qa/page/project/import/github.rb
+++ b/qa/qa/page/project/import/github.rb
@@ -14,7 +14,7 @@ module QA
element :project_import_row, 'data: { qa: { repo_path: repo.full_name } }'
element :project_namespace_select
element :project_namespace_field, 'select_tag :namespace_id'
- element :project_path_field, 'text_field_tag :path, repo.name'
+ element :project_path_field, 'text_field_tag :path, sanitize_project_name(repo.name)'
element :import_button, "_('Import')"
end
diff --git a/qa/qa/scenario/template.rb b/qa/qa/scenario/template.rb
index 66eb86f25c8..a87d925ce32 100644
--- a/qa/qa/scenario/template.rb
+++ b/qa/qa/scenario/template.rb
@@ -21,14 +21,18 @@ module QA
def perform(address, *rspec_options)
Runtime::Scenario.define(:gitlab_address, address)
+ ##
+ # Perform before hooks, which are different for CE and EE
+ #
+ Runtime::Release.perform_before_hooks
+
Specs::Runner.perform do |specs|
specs.tty = true
- specs.tags = self.class.focus
specs.options =
if rspec_options.any?
rspec_options
else
- ::File.expand_path('../specs/features', __dir__)
+ ['--tag', self.class.focus.join(','), '--', ::File.expand_path('../specs/features', __dir__)]
end
end
end
diff --git a/qa/qa/scenario/test/instance.rb b/qa/qa/scenario/test/instance.rb
new file mode 100644
index 00000000000..a2d503cc015
--- /dev/null
+++ b/qa/qa/scenario/test/instance.rb
@@ -0,0 +1,41 @@
+# frozen_string_literal: true
+
+module QA
+ module Scenario
+ module Test
+ # This class exists for back-compatibility so that gitlab-qa can continue
+ # to call Test::Instance instead of Test::Instance::All until at least
+ # the current latest GitLab version has the Test::Instance::All class.
+ # As of Aug, 22nd 2018. Only GitLab >= 11.3 has this class.
+ module Instance
+ include Bootable
+
+ def self.perform(*args)
+ self.tap do |scenario|
+ yield scenario if block_given?
+ break scenario.do_perform(*args)
+ end
+ end
+
+ def self.do_perform(address, *rspec_options)
+ Runtime::Scenario.define(:gitlab_address, address)
+
+ ##
+ # Perform before hooks, which are different for CE and EE
+ #
+ Runtime::Release.perform_before_hooks
+
+ Specs::Runner.perform do |specs|
+ specs.tty = true
+ specs.options =
+ if rspec_options.any?
+ rspec_options
+ else
+ ['--', ::File.expand_path('../../specs/features', __dir__)]
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/scenario/test/integration/github.rb b/qa/qa/scenario/test/integration/github.rb
index 1d22b532aa5..76c3923d68a 100644
--- a/qa/qa/scenario/test/integration/github.rb
+++ b/qa/qa/scenario/test/integration/github.rb
@@ -2,7 +2,7 @@ module QA
module Scenario
module Test
module Integration
- class Github < Test::Instance
+ class Github < Test::Instance::All
tags :github
def perform(address, *rspec_options)
diff --git a/qa/qa/scenario/test/integration/kubernetes.rb b/qa/qa/scenario/test/integration/kubernetes.rb
index 7479073e979..405962caeed 100644
--- a/qa/qa/scenario/test/integration/kubernetes.rb
+++ b/qa/qa/scenario/test/integration/kubernetes.rb
@@ -2,7 +2,7 @@ module QA
module Scenario
module Test
module Integration
- class Kubernetes < Test::Instance
+ class Kubernetes < Test::Instance::All
tags :kubernetes
end
end
diff --git a/qa/qa/scenario/test/integration/ldap.rb b/qa/qa/scenario/test/integration/ldap.rb
index 257ed81d9e1..769fa389785 100644
--- a/qa/qa/scenario/test/integration/ldap.rb
+++ b/qa/qa/scenario/test/integration/ldap.rb
@@ -2,7 +2,7 @@ module QA
module Scenario
module Test
module Integration
- class LDAP < Test::Instance
+ class LDAP < Test::Instance::All
tags :ldap
end
end
diff --git a/qa/qa/scenario/test/integration/mattermost.rb b/qa/qa/scenario/test/integration/mattermost.rb
index 13bfad28b0b..831c6a9fcff 100644
--- a/qa/qa/scenario/test/integration/mattermost.rb
+++ b/qa/qa/scenario/test/integration/mattermost.rb
@@ -6,7 +6,7 @@ module QA
# Run test suite against any GitLab instance where mattermost is enabled,
# including staging and on-premises installation.
#
- class Mattermost < Test::Instance
+ class Mattermost < Test::Instance::All
tags :core, :mattermost
def perform(address, mattermost, *rspec_options)
diff --git a/qa/qa/specs/features/api/1_manage/.gitkeep b/qa/qa/specs/features/api/1_manage/.gitkeep
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/qa/qa/specs/features/api/1_manage/.gitkeep
diff --git a/qa/qa/specs/features/api/users_spec.rb b/qa/qa/specs/features/api/1_manage/users_spec.rb
index 3d25cca1e59..3e3c9e859aa 100644
--- a/qa/qa/specs/features/api/users_spec.rb
+++ b/qa/qa/specs/features/api/1_manage/users_spec.rb
@@ -1,19 +1,21 @@
+# frozen_string_literal: true
+
module QA
- describe 'API users' do
- before(:context) do
- @api_client = Runtime::API::Client.new(:gitlab)
- end
+ context :manage do
+ describe 'Users API' do
+ before(:context) do
+ @api_client = Runtime::API::Client.new(:gitlab)
+ end
- context 'when authenticated' do
let(:request) { Runtime::API::Request.new(@api_client, '/users') }
- it 'get list of users' do
+ it 'GET /users' do
get request.url
expect_status(200)
end
- it 'submit request with a valid user name' do
+ it 'GET /users/:username with a valid username' do
get request.url, { params: { username: Runtime::User.username } }
expect_status(200)
@@ -22,20 +24,12 @@ module QA
)
end
- it 'submit request with an invalid user name' do
+ it 'GET /users/:username with an invalid username' do
get request.url, { params: { username: SecureRandom.hex(10) } }
expect_status(200)
expect(json_body).to eq([])
end
end
-
- it 'submit request with an invalid token' do
- request = Runtime::API::Request.new(@api_client, '/users', private_token: 'invalid')
-
- get request.url
-
- expect_status(401)
- end
end
end
diff --git a/qa/qa/specs/features/api/2_plan/.gitkeep b/qa/qa/specs/features/api/2_plan/.gitkeep
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/qa/qa/specs/features/api/2_plan/.gitkeep
diff --git a/qa/qa/specs/features/api/basics_spec.rb b/qa/qa/specs/features/api/3_create/repository/files_spec.rb
index bc0b5ebfe10..bc0b5ebfe10 100644
--- a/qa/qa/specs/features/api/basics_spec.rb
+++ b/qa/qa/specs/features/api/3_create/repository/files_spec.rb
diff --git a/qa/qa/specs/features/api/4_verify/.gitkeep b/qa/qa/specs/features/api/4_verify/.gitkeep
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/qa/qa/specs/features/api/4_verify/.gitkeep
diff --git a/qa/qa/specs/features/api/5_package/.gitkeep b/qa/qa/specs/features/api/5_package/.gitkeep
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/qa/qa/specs/features/api/5_package/.gitkeep
diff --git a/qa/qa/specs/features/api/6_release/.gitkeep b/qa/qa/specs/features/api/6_release/.gitkeep
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/qa/qa/specs/features/api/6_release/.gitkeep
diff --git a/qa/qa/specs/features/api/7_configure/.gitkeep b/qa/qa/specs/features/api/7_configure/.gitkeep
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/qa/qa/specs/features/api/7_configure/.gitkeep
diff --git a/qa/qa/specs/features/browser_ui/1_manage/login/log_in_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/login/log_in_spec.rb
new file mode 100644
index 00000000000..1c7da930567
--- /dev/null
+++ b/qa/qa/specs/features/browser_ui/1_manage/login/log_in_spec.rb
@@ -0,0 +1,17 @@
+module QA
+ context :manage, :smoke do
+ describe 'basic user login' do
+ it 'user logs in using basic credentials' do
+ Runtime::Browser.visit(:gitlab, Page::Main::Login)
+ Page::Main::Login.act { sign_in_using_credentials }
+
+ # TODO, since `Signed in successfully` message was removed
+ # this is the only way to tell if user is signed in correctly.
+ #
+ Page::Menu::Main.perform do |menu|
+ expect(menu).to have_personal_area
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/specs/features/browser_ui/1_manage/login/log_into_gitlab_via_ldap_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/login/log_into_gitlab_via_ldap_spec.rb
new file mode 100644
index 00000000000..c9958917be9
--- /dev/null
+++ b/qa/qa/specs/features/browser_ui/1_manage/login/log_into_gitlab_via_ldap_spec.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+module QA
+ context :manage, :orchestrated, :ldap do
+ describe 'LDAP login' do
+ before do
+ Runtime::Env.user_type = 'ldap'
+ end
+
+ it 'user logs into GitLab using LDAP credentials' do
+ Runtime::Browser.visit(:gitlab, Page::Main::Login)
+ Page::Main::Login.act { sign_in_using_credentials }
+
+ # TODO, since `Signed in successfully` message was removed
+ # this is the only way to tell if user is signed in correctly.
+ #
+ Page::Menu::Main.perform do |menu|
+ expect(menu).to have_personal_area
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/specs/features/browser_ui/1_manage/login/log_into_mattermost_via_gitlab_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/login/log_into_mattermost_via_gitlab_spec.rb
new file mode 100644
index 00000000000..6eda2c750d4
--- /dev/null
+++ b/qa/qa/specs/features/browser_ui/1_manage/login/log_into_mattermost_via_gitlab_spec.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+module QA
+ context :manage, :orchestrated, :mattermost do
+ describe 'Mattermost login' do
+ it 'user logs into Mattermost using GitLab OAuth' do
+ Runtime::Browser.visit(:gitlab, Page::Main::Login) do
+ Page::Main::Login.act { sign_in_using_credentials }
+
+ Runtime::Browser.visit(:mattermost, Page::Mattermost::Login) do
+ Page::Mattermost::Login.act { sign_in_using_oauth }
+
+ Page::Mattermost::Main.perform do |page|
+ expect(page).to have_content(/(Welcome to: Mattermost|Logout GitLab Mattermost)/)
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/specs/features/browser_ui/1_manage/project/create_project_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/project/create_project_spec.rb
new file mode 100644
index 00000000000..bb1f3ab26d1
--- /dev/null
+++ b/qa/qa/specs/features/browser_ui/1_manage/project/create_project_spec.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+module QA
+ context :manage, :smoke do
+ describe 'Project creation' do
+ it 'user creates a new project' do
+ Runtime::Browser.visit(:gitlab, Page::Main::Login)
+ Page::Main::Login.act { sign_in_using_credentials }
+
+ created_project = Factory::Resource::Project.fabricate! do |project|
+ project.name = 'awesome-project'
+ project.description = 'create awesome project test'
+ end
+
+ expect(created_project.name).to match /^awesome-project-\h{16}$/
+
+ expect(page).to have_content(
+ /Project \S?awesome-project\S+ was successfully created/
+ )
+
+ expect(page).to have_content('create awesome project test')
+ expect(page).to have_content('The repository for this project is empty')
+ end
+ end
+ end
+end
diff --git a/qa/qa/specs/features/browser_ui/1_manage/project/import_github_repo_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/project/import_github_repo_spec.rb
new file mode 100644
index 00000000000..2ef8de61441
--- /dev/null
+++ b/qa/qa/specs/features/browser_ui/1_manage/project/import_github_repo_spec.rb
@@ -0,0 +1,110 @@
+# frozen_string_literal: true
+
+module QA
+ context :manage, :orchestrated, :github do
+ describe 'Project import from GitHub' do
+ let(:imported_project) do
+ Factory::Resource::ProjectImportedFromGithub.fabricate! do |project|
+ project.name = 'imported-project'
+ project.personal_access_token = Runtime::Env.github_access_token
+ project.github_repository_path = 'gitlab-qa/test-project'
+ end
+ end
+
+ after do
+ # We need to delete the imported project because it's impossible to import
+ # the same GitHub project twice for a given user.
+ api_client = Runtime::API::Client.new(:gitlab)
+ delete_project_request = Runtime::API::Request.new(api_client, "/projects/#{CGI.escape("#{Runtime::Namespace.path}/#{imported_project.name}")}")
+ delete delete_project_request.url
+
+ expect_status(202)
+ end
+
+ it 'user imports a GitHub repo' do
+ Runtime::Browser.visit(:gitlab, Page::Main::Login)
+ Page::Main::Login.act { sign_in_using_credentials }
+
+ imported_project # import the project
+
+ Page::Menu::Main.act { go_to_projects }
+ Page::Dashboard::Projects.perform do |dashboard|
+ dashboard.go_to_project(imported_project.name)
+ end
+
+ Page::Project::Show.act { wait_for_import }
+
+ verify_repository_import
+ verify_issues_import
+ verify_merge_requests_import
+ verify_labels_import
+ verify_milestones_import
+ verify_wiki_import
+ end
+
+ def verify_repository_import
+ expect(page).to have_content('This test project is used for automated GitHub import by GitLab QA.')
+ expect(page).to have_content(imported_project.name)
+ end
+
+ def verify_issues_import
+ Page::Menu::Side.act { click_issues }
+ expect(page).to have_content('This is a sample issue')
+
+ click_link 'This is a sample issue'
+
+ expect(page).to have_content('We should populate this project with issues, pull requests and wiki pages.')
+
+ # Comments
+ expect(page).to have_content('This is a comment from @rymai.')
+
+ Page::Issuable::Sidebar.perform do |issuable|
+ expect(issuable).to have_label('enhancement')
+ expect(issuable).to have_label('help wanted')
+ expect(issuable).to have_label('good first issue')
+ end
+ end
+
+ def verify_merge_requests_import
+ Page::Menu::Side.act { click_merge_requests }
+ expect(page).to have_content('Improve README.md')
+
+ click_link 'Improve README.md'
+
+ expect(page).to have_content('This improves the README file a bit.')
+
+ # Review comment are not supported yet
+ expect(page).not_to have_content('Really nice change.')
+
+ # Comments
+ expect(page).to have_content('Nice work! This is a comment from @rymai.')
+
+ # Diff comments
+ expect(page).to have_content('[Review comment] I like that!')
+ expect(page).to have_content('[Review comment] Nice blank line.')
+ expect(page).to have_content('[Single diff comment] Much better without this line!')
+
+ Page::Issuable::Sidebar.perform do |issuable|
+ expect(issuable).to have_label('bug')
+ expect(issuable).to have_label('enhancement')
+ end
+ end
+
+ def verify_labels_import
+ # TODO: Waiting on https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/19228
+ # to build upon it.
+ end
+
+ def verify_milestones_import
+ # TODO: Waiting on https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/18727
+ # to build upon it.
+ end
+
+ def verify_wiki_import
+ Page::Menu::Side.act { click_wiki }
+
+ expect(page).to have_content('Welcome to the test-project wiki!')
+ end
+ end
+ end
+end
diff --git a/qa/qa/specs/features/browser_ui/1_manage/project/view_project_activity_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/project/view_project_activity_spec.rb
new file mode 100644
index 00000000000..34bb6f1c197
--- /dev/null
+++ b/qa/qa/specs/features/browser_ui/1_manage/project/view_project_activity_spec.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+module QA
+ context :manage do
+ describe 'Project activity' do
+ it 'user creates an event in the activity page upon Git push' do
+ Runtime::Browser.visit(:gitlab, Page::Main::Login)
+ Page::Main::Login.act { sign_in_using_credentials }
+
+ Factory::Repository::ProjectPush.fabricate! do |push|
+ push.file_name = 'README.md'
+ push.file_content = '# This is a test project'
+ push.commit_message = 'Add README.md'
+ end
+
+ Page::Menu::Side.act { go_to_activity }
+
+ Page::Project::Activity.act { go_to_push_events }
+
+ expect(page).to have_content('pushed new branch master')
+ end
+ end
+ end
+end
diff --git a/qa/qa/specs/features/browser_ui/2_plan/issue/create_issue_spec.rb b/qa/qa/specs/features/browser_ui/2_plan/issue/create_issue_spec.rb
new file mode 100644
index 00000000000..1e110c331f7
--- /dev/null
+++ b/qa/qa/specs/features/browser_ui/2_plan/issue/create_issue_spec.rb
@@ -0,0 +1,50 @@
+# frozen_string_literal: true
+
+module QA
+ context :plan, :smoke do
+ describe 'Issue creation' do
+ let(:issue_title) { 'issue title' }
+
+ def create_issue
+ Runtime::Browser.visit(:gitlab, Page::Main::Login)
+ Page::Main::Login.act { sign_in_using_credentials }
+
+ Factory::Resource::Issue.fabricate! do |issue|
+ issue.title = issue_title
+ end
+ end
+
+ it 'user creates an issue' do
+ create_issue
+
+ Page::Menu::Side.act { click_issues }
+
+ expect(page).to have_content(issue_title)
+ end
+
+ context 'when using attachements in comments', :object_storage do
+ let(:file_to_attach) do
+ File.absolute_path(File.join('spec', 'fixtures', 'banana_sample.gif'))
+ end
+
+ it 'user comments on an issue with an attachment' do
+ create_issue
+
+ Page::Project::Issue::Show.perform do |show|
+ show.comment('See attached banana for scale', attachment: file_to_attach)
+
+ show.refresh
+
+ image_url = find('a[href$="banana_sample.gif"]')[:href]
+
+ found = show.wait(reload: false) do
+ show.asset_exists?(image_url)
+ end
+
+ expect(found).to be_truthy
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/specs/features/browser_ui/3_create/merge_request/create_merge_request_spec.rb b/qa/qa/specs/features/browser_ui/3_create/merge_request/create_merge_request_spec.rb
new file mode 100644
index 00000000000..bcf55a02a61
--- /dev/null
+++ b/qa/qa/specs/features/browser_ui/3_create/merge_request/create_merge_request_spec.rb
@@ -0,0 +1,57 @@
+# frozen_string_literal: true
+
+module QA
+ context :create do
+ describe 'Merge request creation' do
+ it 'user creates a new merge request' do
+ Runtime::Browser.visit(:gitlab, Page::Main::Login)
+ Page::Main::Login.act { sign_in_using_credentials }
+
+ current_project = Factory::Resource::Project.fabricate! do |project|
+ project.name = 'project-with-merge-request-and-milestone'
+ end
+
+ current_milestone = Factory::Resource::ProjectMilestone.fabricate! do |milestone|
+ milestone.title = 'unique-milestone'
+ milestone.project = current_project
+ end
+
+ Factory::Resource::MergeRequest.fabricate! do |merge_request|
+ merge_request.title = 'This is a merge request with a milestone'
+ merge_request.description = 'Great feature with milestone'
+ merge_request.project = current_project
+ merge_request.milestone = current_milestone
+ end
+
+ expect(page).to have_content('This is a merge request with a milestone')
+ expect(page).to have_content('Great feature with milestone')
+ expect(page).to have_content(/Opened [\w\s]+ ago/)
+
+ Page::Issuable::Sidebar.perform do |sidebar|
+ expect(sidebar).to have_milestone(current_milestone.title)
+ end
+ end
+ end
+ end
+
+ describe 'creates a merge request', :smoke do
+ it 'user creates a new merge request' do
+ Runtime::Browser.visit(:gitlab, Page::Main::Login)
+ Page::Main::Login.act { sign_in_using_credentials }
+
+ current_project = Factory::Resource::Project.fabricate! do |project|
+ project.name = 'project-with-merge-request'
+ end
+
+ Factory::Resource::MergeRequest.fabricate! do |merge_request|
+ merge_request.title = 'This is a merge request'
+ merge_request.description = 'Great feature'
+ merge_request.project = current_project
+ end
+
+ expect(page).to have_content('This is a merge request')
+ expect(page).to have_content('Great feature')
+ expect(page).to have_content(/Opened [\w\s]+ ago/)
+ end
+ end
+end
diff --git a/qa/qa/specs/features/browser_ui/3_create/merge_request/merge_merge_request_from_fork_spec.rb b/qa/qa/specs/features/browser_ui/3_create/merge_request/merge_merge_request_from_fork_spec.rb
new file mode 100644
index 00000000000..407a15800ab
--- /dev/null
+++ b/qa/qa/specs/features/browser_ui/3_create/merge_request/merge_merge_request_from_fork_spec.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+module QA
+ context :create do
+ describe 'Merge request creation from fork' do
+ it 'user forks a project, submits a merge request and maintainer merges it' do
+ Runtime::Browser.visit(:gitlab, Page::Main::Login)
+ Page::Main::Login.act { sign_in_using_credentials }
+
+ merge_request = Factory::Resource::MergeRequestFromFork.fabricate! do |merge_request|
+ merge_request.fork_branch = 'feature-branch'
+ end
+
+ Page::Menu::Main.perform { |main| main.sign_out }
+ Page::Main::Login.perform { |login| login.sign_in_using_credentials }
+
+ merge_request.visit!
+
+ Page::MergeRequest::Show.perform { |show| show.merge! }
+
+ expect(page).to have_content('The changes were merged')
+ end
+ end
+ end
+end
diff --git a/qa/qa/specs/features/browser_ui/3_create/merge_request/rebase_merge_request_spec.rb b/qa/qa/specs/features/browser_ui/3_create/merge_request/rebase_merge_request_spec.rb
new file mode 100644
index 00000000000..ddcbc94b1b1
--- /dev/null
+++ b/qa/qa/specs/features/browser_ui/3_create/merge_request/rebase_merge_request_spec.rb
@@ -0,0 +1,45 @@
+# frozen_string_literal: true
+
+module QA
+ context :create do
+ describe 'Merge request rebasing' do
+ it 'user rebases source branch of merge request' do
+ Runtime::Browser.visit(:gitlab, Page::Main::Login)
+ Page::Main::Login.act { sign_in_using_credentials }
+
+ project = Factory::Resource::Project.fabricate! do |project|
+ project.name = "only-fast-forward"
+ end
+
+ Page::Menu::Side.act { go_to_settings }
+ Page::Project::Settings::MergeRequest.act { enable_ff_only }
+
+ merge_request = Factory::Resource::MergeRequest.fabricate! do |merge_request|
+ merge_request.project = project
+ merge_request.title = 'Needs rebasing'
+ end
+
+ Factory::Repository::ProjectPush.fabricate! do |push|
+ push.project = project
+ push.file_name = "other.txt"
+ push.file_content = "New file added!"
+ push.branch_name = "master"
+ push.new_branch = false
+ end
+
+ merge_request.visit!
+
+ Page::MergeRequest::Show.perform do |merge_request|
+ expect(merge_request).to have_content('Needs rebasing')
+ expect(merge_request).not_to be_fast_forward_possible
+ expect(merge_request).not_to have_merge_button
+
+ merge_request.rebase!
+
+ expect(merge_request).to have_merge_button
+ expect(merge_request.fast_forward_possible?).to be_truthy
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/specs/features/browser_ui/3_create/merge_request/squash_merge_request_spec.rb b/qa/qa/specs/features/browser_ui/3_create/merge_request/squash_merge_request_spec.rb
new file mode 100644
index 00000000000..b5b8855a35d
--- /dev/null
+++ b/qa/qa/specs/features/browser_ui/3_create/merge_request/squash_merge_request_spec.rb
@@ -0,0 +1,54 @@
+# frozen_string_literal: true
+
+module QA
+ context :create do
+ describe 'Merge request squashing' do
+ it 'user squashes commits while merging' do
+ Runtime::Browser.visit(:gitlab, Page::Main::Login)
+ Page::Main::Login.act { sign_in_using_credentials }
+
+ project = Factory::Resource::Project.fabricate! do |project|
+ project.name = "squash-before-merge"
+ end
+
+ merge_request = Factory::Resource::MergeRequest.fabricate! do |merge_request|
+ merge_request.project = project
+ merge_request.title = 'Squashing commits'
+ end
+
+ Factory::Repository::ProjectPush.fabricate! do |push|
+ push.project = project
+ push.commit_message = 'to be squashed'
+ push.branch_name = merge_request.source_branch
+ push.new_branch = false
+ push.file_name = 'other.txt'
+ push.file_content = "Test with unicode characters ❤✓€❄"
+ end
+
+ merge_request.visit!
+
+ expect(page).to have_text('to be squashed')
+
+ Page::MergeRequest::Show.perform do |merge_request_page|
+ merge_request_page.mark_to_squash
+ merge_request_page.merge!
+
+ merge_request.project.visit!
+
+ Git::Repository.perform do |repository|
+ repository.uri = Page::Project::Show.act do
+ choose_repository_clone_http
+ repository_location.uri
+ end
+
+ repository.use_default_credentials
+
+ repository.act { clone }
+
+ expect(repository.commits.size).to eq 3
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/specs/features/repository/clone_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/clone_spec.rb
index 8b0613c5f78..b19bdd950fa 100644
--- a/qa/qa/specs/features/repository/clone_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/repository/clone_spec.rb
@@ -1,6 +1,8 @@
+# frozen_string_literal: true
+
module QA
- describe 'clone code from the repository' do
- context 'with regular account over http' do
+ context :create do
+ describe 'Git clone over HTTP' do
let(:location) do
Page::Project::Show.act do
choose_repository_clone_http
diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/create_edit_delete_file_via_web_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/create_edit_delete_file_via_web_spec.rb
new file mode 100644
index 00000000000..f18655442c1
--- /dev/null
+++ b/qa/qa/specs/features/browser_ui/3_create/repository/create_edit_delete_file_via_web_spec.rb
@@ -0,0 +1,58 @@
+# frozen_string_literal: true
+
+module QA
+ context :create, :core do
+ describe 'Files management' do
+ it 'user creates, edits and deletes a file via the Web' do
+ Runtime::Browser.visit(:gitlab, Page::Main::Login)
+ Page::Main::Login.act { sign_in_using_credentials }
+
+ # Create
+ file_name = 'QA Test - File name'
+ file_content = 'QA Test - File content'
+ commit_message_for_create = 'QA Test - Create new file'
+
+ Factory::Resource::File.fabricate! do |file|
+ file.name = file_name
+ file.content = file_content
+ file.commit_message = commit_message_for_create
+ end
+
+ expect(page).to have_content('The file has been successfully created.')
+ expect(page).to have_content(file_name)
+ expect(page).to have_content(file_content)
+ expect(page).to have_content(commit_message_for_create)
+
+ # Edit
+ updated_file_content = 'QA Test - Updated file content'
+ commit_message_for_update = 'QA Test - Update file'
+
+ Page::File::Show.act { click_edit }
+
+ Page::File::Form.act do
+ remove_content
+ add_content(updated_file_content)
+ add_commit_message(commit_message_for_update)
+ commit_changes
+ end
+
+ expect(page).to have_content('Your changes have been successfully committed.')
+ expect(page).to have_content(updated_file_content)
+ expect(page).to have_content(commit_message_for_update)
+
+ # Delete
+ commit_message_for_delete = 'QA Test - Delete file'
+
+ Page::File::Show.act do
+ click_delete
+ add_commit_message(commit_message_for_delete)
+ click_delete_file
+ end
+
+ expect(page).to have_content('The file has been successfully deleted.')
+ expect(page).to have_content(commit_message_for_delete)
+ expect(page).to have_no_content(file_name)
+ end
+ end
+ end
+end
diff --git a/qa/qa/specs/features/repository/push_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/push_over_http_spec.rb
index 1e89942e932..40dfd138a1b 100644
--- a/qa/qa/specs/features/repository/push_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/repository/push_over_http_spec.rb
@@ -1,6 +1,8 @@
+# frozen_string_literal: true
+
module QA
- describe 'push code to repository' do
- context 'with regular account over http' do
+ context :create do
+ describe 'Git push over HTTP' do
it 'user pushes code to the repository' do
Runtime::Browser.visit(:gitlab, Page::Main::Login)
Page::Main::Login.act { sign_in_using_credentials }
diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/push_protected_branch_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/push_protected_branch_spec.rb
new file mode 100644
index 00000000000..1d9cc33080d
--- /dev/null
+++ b/qa/qa/specs/features/browser_ui/3_create/repository/push_protected_branch_spec.rb
@@ -0,0 +1,70 @@
+# frozen_string_literal: true
+
+module QA
+ context :create do
+ describe 'Protected branch support' do
+ let(:branch_name) { 'protected-branch' }
+ let(:commit_message) { 'Protected push commit message' }
+ let(:project) do
+ Factory::Resource::Project.fabricate! do |resource|
+ resource.name = 'protected-branch-project'
+ end
+ end
+
+ before do
+ Runtime::Browser.visit(:gitlab, Page::Main::Login)
+ Page::Main::Login.act { sign_in_using_credentials }
+ end
+
+ after do
+ # We need to clear localStorage because we're using it for the dropdown,
+ # and capybara doesn't do this for us.
+ # https://github.com/teamcapybara/capybara/issues/1702
+ Capybara.execute_script 'localStorage.clear()'
+ end
+
+ context 'when developers and maintainers are allowed to push to a protected branch' do
+ it 'user with push rights successfully pushes to the protected branch' do
+ create_protected_branch(allow_to_push: true)
+
+ push = push_new_file(branch_name)
+
+ expect(push.output).to match(/remote: To create a merge request for protected-branch, visit/)
+ end
+ end
+
+ context 'when developers and maintainers are not allowed to push to a protected branch' do
+ it 'user without push rights fails to push to the protected branch' do
+ create_protected_branch(allow_to_push: false)
+
+ push = push_new_file(branch_name)
+
+ expect(push.output)
+ .to match(/remote\: GitLab\: You are not allowed to push code to protected branches on this project/)
+ expect(push.output)
+ .to match(/\[remote rejected\] #{branch_name} -> #{branch_name} \(pre-receive hook declined\)/)
+ end
+ end
+
+ def create_protected_branch(allow_to_push:)
+ Factory::Resource::Branch.fabricate! do |resource|
+ resource.branch_name = branch_name
+ resource.project = project
+ resource.allow_to_push = allow_to_push
+ resource.protected = true
+ end
+ end
+
+ def push_new_file(branch)
+ Factory::Repository::ProjectPush.fabricate! do |resource|
+ resource.project = project
+ resource.file_name = 'new_file.md'
+ resource.file_content = '# This is a new file'
+ resource.commit_message = 'Add new_file.md'
+ resource.branch_name = branch_name
+ resource.new_branch = false
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/specs/features/browser_ui/3_create/wiki/create_edit_clone_push_wiki_spec.rb b/qa/qa/specs/features/browser_ui/3_create/wiki/create_edit_clone_push_wiki_spec.rb
new file mode 100644
index 00000000000..8009b9e8609
--- /dev/null
+++ b/qa/qa/specs/features/browser_ui/3_create/wiki/create_edit_clone_push_wiki_spec.rb
@@ -0,0 +1,49 @@
+# frozen_string_literal: true
+
+module QA
+ context :create do
+ describe 'Wiki management' do
+ def login
+ Runtime::Browser.visit(:gitlab, Page::Main::Login)
+ Page::Main::Login.act { sign_in_using_credentials }
+ end
+
+ def validate_content(content)
+ expect(page).to have_content('Wiki was successfully updated')
+ expect(page).to have_content(/#{content}/)
+ end
+
+ before do
+ login
+ end
+
+ it 'user creates, edits, clones, and pushes to the wiki' do
+ wiki = Factory::Resource::Wiki.fabricate! do |resource|
+ resource.title = 'Home'
+ resource.content = '# My First Wiki Content'
+ resource.message = 'Update home'
+ end
+
+ validate_content('My First Wiki Content')
+
+ Page::Project::Wiki::Edit.act { go_to_edit_page }
+ Page::Project::Wiki::New.perform do |page|
+ page.set_content("My Second Wiki Content")
+ page.save_changes
+ end
+
+ validate_content('My Second Wiki Content')
+
+ Factory::Repository::WikiPush.fabricate! do |push|
+ push.wiki = wiki
+ push.file_name = 'Home.md'
+ push.file_content = '# My Third Wiki Content'
+ push.commit_message = 'Update Home.md'
+ end
+ Page::Menu::Side.act { click_wiki }
+
+ expect(page).to have_content('My Third Wiki Content')
+ end
+ end
+ end
+end
diff --git a/qa/qa/specs/features/browser_ui/4_verify/pipeline/create_and_process_pipeline_spec.rb b/qa/qa/specs/features/browser_ui/4_verify/pipeline/create_and_process_pipeline_spec.rb
new file mode 100644
index 00000000000..cdfe9b90e15
--- /dev/null
+++ b/qa/qa/specs/features/browser_ui/4_verify/pipeline/create_and_process_pipeline_spec.rb
@@ -0,0 +1,87 @@
+# frozen_string_literal: true
+
+module QA
+ context :verify, :orchestrated, :docker do
+ describe 'Pipeline creation and processing' do
+ let(:executor) { "qa-runner-#{Time.now.to_i}" }
+
+ after do
+ Service::Runner.new(executor).remove!
+ end
+
+ it 'users creates a pipeline which gets processed' do
+ Runtime::Browser.visit(:gitlab, Page::Main::Login)
+ Page::Main::Login.act { sign_in_using_credentials }
+
+ project = Factory::Resource::Project.fabricate! do |project|
+ project.name = 'project-with-pipelines'
+ project.description = 'Project with CI/CD Pipelines.'
+ end
+
+ Factory::Resource::Runner.fabricate! do |runner|
+ runner.project = project
+ runner.name = executor
+ runner.tags = %w[qa test]
+ end
+
+ Factory::Repository::ProjectPush.fabricate! do |push|
+ push.project = project
+ push.file_name = '.gitlab-ci.yml'
+ push.commit_message = 'Add .gitlab-ci.yml'
+ push.file_content = <<~EOF
+ test-success:
+ tags:
+ - qa
+ - test
+ script: echo 'OK'
+
+ test-failure:
+ tags:
+ - qa
+ - test
+ script:
+ - echo 'FAILURE'
+ - exit 1
+
+ test-tags:
+ tags:
+ - qa
+ - docker
+ script: echo 'NOOP'
+
+ test-artifacts:
+ tags:
+ - qa
+ - test
+ script: mkdir my-artifacts; echo "CONTENTS" > my-artifacts/artifact.txt
+ artifacts:
+ paths:
+ - my-artifacts/
+ EOF
+ end
+
+ Page::Project::Show.act { wait_for_push }
+
+ expect(page).to have_content('Add .gitlab-ci.yml')
+
+ Page::Menu::Side.act { click_ci_cd_pipelines }
+
+ expect(page).to have_content('All 1')
+ expect(page).to have_content('Add .gitlab-ci.yml')
+
+ puts 'Waiting for the runner to process the pipeline'
+ sleep 15 # Runner should process all jobs within 15 seconds.
+
+ Page::Project::Pipeline::Index.act { go_to_latest_pipeline }
+
+ Page::Project::Pipeline::Show.perform do |pipeline|
+ expect(pipeline).to be_running
+ expect(pipeline).to have_build('test-success', status: :success)
+ expect(pipeline).to have_build('test-failure', status: :failed)
+ expect(pipeline).to have_build('test-tags', status: :pending)
+ expect(pipeline).to have_build('test-artifacts', status: :success)
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/specs/features/browser_ui/4_verify/runner/register_runner_spec.rb b/qa/qa/specs/features/browser_ui/4_verify/runner/register_runner_spec.rb
new file mode 100644
index 00000000000..8d83a20f5bf
--- /dev/null
+++ b/qa/qa/specs/features/browser_ui/4_verify/runner/register_runner_spec.rb
@@ -0,0 +1,32 @@
+# frozen_string_literal: true
+
+module QA
+ context :verify, :docker do
+ describe 'Runner registration' do
+ let(:executor) { "qa-runner-#{Time.now.to_i}" }
+
+ after do
+ Service::Runner.new(executor).remove!
+ end
+
+ it 'user registers a new specific runner' do
+ Runtime::Browser.visit(:gitlab, Page::Main::Login)
+ Page::Main::Login.act { sign_in_using_credentials }
+
+ Factory::Resource::Runner.fabricate! do |runner|
+ runner.name = executor
+ end
+
+ Page::Project::Settings::CICD.perform do |settings|
+ sleep 5 # Runner should register within 5 seconds
+ settings.refresh
+
+ settings.expand_runners_settings do |page|
+ expect(page).to have_content(executor)
+ expect(page).to have_online_runner
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/specs/features/browser_ui/4_verify/secret_variable/add_secret_variable_spec.rb b/qa/qa/specs/features/browser_ui/4_verify/secret_variable/add_secret_variable_spec.rb
new file mode 100644
index 00000000000..08a87df5837
--- /dev/null
+++ b/qa/qa/specs/features/browser_ui/4_verify/secret_variable/add_secret_variable_spec.rb
@@ -0,0 +1,28 @@
+# frozen_string_literal: true
+
+module QA
+ context :verify do
+ describe 'Secret variable support' do
+ it 'user adds a secret variable' do
+ Runtime::Browser.visit(:gitlab, Page::Main::Login)
+ Page::Main::Login.act { sign_in_using_credentials }
+
+ Factory::Resource::SecretVariable.fabricate! do |resource|
+ resource.key = 'VARIABLE_KEY'
+ resource.value = 'some secret variable'
+ end
+
+ Page::Project::Settings::CICD.perform do |settings|
+ settings.expand_secret_variables do |page|
+ expect(page).to have_field(with: 'VARIABLE_KEY')
+ expect(page).not_to have_field(with: 'some secret variable')
+
+ page.reveal_variables
+
+ expect(page).to have_field(with: 'some secret variable')
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/specs/features/browser_ui/5_package/.gitkeep b/qa/qa/specs/features/browser_ui/5_package/.gitkeep
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/qa/qa/specs/features/browser_ui/5_package/.gitkeep
diff --git a/qa/qa/specs/features/browser_ui/6_release/deploy_key/add_deploy_key_spec.rb b/qa/qa/specs/features/browser_ui/6_release/deploy_key/add_deploy_key_spec.rb
new file mode 100644
index 00000000000..17dfa887434
--- /dev/null
+++ b/qa/qa/specs/features/browser_ui/6_release/deploy_key/add_deploy_key_spec.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+module QA
+ context :release do
+ describe 'Deploy key creation' do
+ it 'user adds a deploy key' do
+ Runtime::Browser.visit(:gitlab, Page::Main::Login)
+ Page::Main::Login.act { sign_in_using_credentials }
+
+ key = Runtime::Key::RSA.new
+ deploy_key_title = 'deploy key title'
+ deploy_key_value = key.public_key
+
+ deploy_key = Factory::Resource::DeployKey.fabricate! do |resource|
+ resource.title = deploy_key_title
+ resource.key = deploy_key_value
+ end
+
+ expect(deploy_key.fingerprint).to eq(key.fingerprint)
+ end
+ end
+ end
+end
diff --git a/qa/qa/specs/features/browser_ui/6_release/deploy_key/clone_using_deploy_key_spec.rb b/qa/qa/specs/features/browser_ui/6_release/deploy_key/clone_using_deploy_key_spec.rb
new file mode 100644
index 00000000000..8352d13b06d
--- /dev/null
+++ b/qa/qa/specs/features/browser_ui/6_release/deploy_key/clone_using_deploy_key_spec.rb
@@ -0,0 +1,109 @@
+# frozen_string_literal: true
+
+require 'digest/sha1'
+
+module QA
+ context :release, :docker do
+ describe 'Git clone using a deploy key' do
+ def login
+ Runtime::Browser.visit(:gitlab, Page::Main::Login)
+ Page::Main::Login.act { sign_in_using_credentials }
+ end
+
+ before(:all) do
+ login
+
+ @runner_name = "qa-runner-#{Time.now.to_i}"
+
+ @project = Factory::Resource::Project.fabricate! do |resource|
+ resource.name = 'deploy-key-clone-project'
+ end
+
+ @repository_location = @project.repository_ssh_location
+
+ Factory::Resource::Runner.fabricate! do |resource|
+ resource.project = @project
+ resource.name = @runner_name
+ resource.tags = %w[qa docker]
+ resource.image = 'gitlab/gitlab-runner:ubuntu'
+ end
+
+ Page::Menu::Main.act { sign_out }
+ end
+
+ after(:all) do
+ Service::Runner.new(@runner_name).remove!
+ end
+
+ keys = [
+ [Runtime::Key::RSA, 8192],
+ [Runtime::Key::ECDSA, 521],
+ [Runtime::Key::ED25519]
+ ]
+
+ keys.each do |(key_class, bits)|
+ it "user sets up a deploy key with #{key_class}(#{bits}) to clone code using pipelines" do
+ key = key_class.new(*bits)
+
+ login
+
+ Factory::Resource::DeployKey.fabricate! do |resource|
+ resource.project = @project
+ resource.title = "deploy key #{key.name}(#{key.bits})"
+ resource.key = key.public_key
+ end
+
+ deploy_key_name = "DEPLOY_KEY_#{key.name}_#{key.bits}"
+
+ Factory::Resource::SecretVariable.fabricate! do |resource|
+ resource.project = @project
+ resource.key = deploy_key_name
+ resource.value = key.private_key
+ end
+
+ gitlab_ci = <<~YAML
+ cat-config:
+ script:
+ - mkdir -p ~/.ssh
+ - ssh-keyscan -p #{@repository_location.port} #{@repository_location.host} >> ~/.ssh/known_hosts
+ - eval $(ssh-agent -s)
+ - ssh-add -D
+ - echo "$#{deploy_key_name}" | ssh-add -
+ - git clone #{@repository_location.git_uri}
+ - cd #{@project.name}
+ - git checkout #{deploy_key_name}
+ - sha1sum .gitlab-ci.yml
+ tags:
+ - qa
+ - docker
+ YAML
+
+ Factory::Repository::ProjectPush.fabricate! do |resource|
+ resource.project = @project
+ resource.file_name = '.gitlab-ci.yml'
+ resource.commit_message = 'Add .gitlab-ci.yml'
+ resource.file_content = gitlab_ci
+ resource.branch_name = deploy_key_name
+ resource.new_branch = true
+ end
+
+ sha1sum = Digest::SHA1.hexdigest(gitlab_ci)
+
+ Page::Project::Show.act { wait_for_push }
+ Page::Menu::Side.act { click_ci_cd_pipelines }
+ Page::Project::Pipeline::Index.act { go_to_latest_pipeline }
+ Page::Project::Pipeline::Show.act { go_to_first_job }
+
+ Page::Project::Job::Show.perform do |job|
+ job.wait(reload: false) do
+ job.completed? && !job.trace_loading?
+ end
+
+ expect(job.passed?).to be_truthy, "Job status did not become \"passed\"."
+ expect(job.output).to include(sha1sum)
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/specs/features/browser_ui/7_configure/auto_devops/create_project_with_auto_devops_spec.rb b/qa/qa/specs/features/browser_ui/7_configure/auto_devops/create_project_with_auto_devops_spec.rb
new file mode 100644
index 00000000000..dd24e8ffba5
--- /dev/null
+++ b/qa/qa/specs/features/browser_ui/7_configure/auto_devops/create_project_with_auto_devops_spec.rb
@@ -0,0 +1,68 @@
+# frozen_string_literal: true
+
+require 'pathname'
+
+module QA
+ context :configure, :orchestrated, :kubernetes do
+ describe 'Auto DevOps support' do
+ after do
+ @cluster&.remove!
+ end
+
+ it 'user creates a new project and runs auto devops' do
+ Runtime::Browser.visit(:gitlab, Page::Main::Login)
+ Page::Main::Login.act { sign_in_using_credentials }
+
+ project = Factory::Resource::Project.fabricate! do |p|
+ p.name = 'project-with-autodevops'
+ p.description = 'Project with Auto Devops'
+ end
+
+ # Disable code_quality check in Auto DevOps pipeline as it takes
+ # too long and times out the test
+ Factory::Resource::SecretVariable.fabricate! do |resource|
+ resource.key = 'CODE_QUALITY_DISABLED'
+ resource.value = '1'
+ end
+
+ # Create Auto Devops compatible repo
+ Factory::Repository::ProjectPush.fabricate! do |push|
+ push.project = project
+ push.directory = Pathname
+ .new(__dir__)
+ .join('../../../fixtures/auto_devops_rack')
+ push.commit_message = 'Create Auto DevOps compatible rack application'
+ end
+
+ Page::Project::Show.act { wait_for_push }
+
+ # Create and connect K8s cluster
+ @cluster = Service::KubernetesCluster.new.create!
+ kubernetes_cluster = Factory::Resource::KubernetesCluster.fabricate! do |cluster|
+ cluster.project = project
+ cluster.cluster = @cluster
+ cluster.install_helm_tiller = true
+ cluster.install_ingress = true
+ cluster.install_prometheus = true
+ cluster.install_runner = true
+ end
+
+ project.visit!
+ Page::Menu::Side.act { click_ci_cd_settings }
+ Page::Project::Settings::CICD.perform do |p|
+ p.enable_auto_devops_with_domain("#{kubernetes_cluster.ingress_ip}.nip.io")
+ end
+
+ project.visit!
+ Page::Menu::Side.act { click_ci_cd_pipelines }
+ Page::Project::Pipeline::Index.act { go_to_latest_pipeline }
+
+ Page::Project::Pipeline::Show.perform do |pipeline|
+ expect(pipeline).to have_build('build', status: :success, wait: 600)
+ expect(pipeline).to have_build('test', status: :success, wait: 600)
+ expect(pipeline).to have_build('production', status: :success, wait: 1200)
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/specs/features/browser_ui/7_configure/mattermost/create_group_with_mattermost_team_spec.rb b/qa/qa/specs/features/browser_ui/7_configure/mattermost/create_group_with_mattermost_team_spec.rb
new file mode 100644
index 00000000000..6ffdc55538a
--- /dev/null
+++ b/qa/qa/specs/features/browser_ui/7_configure/mattermost/create_group_with_mattermost_team_spec.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+module QA
+ context :configure, :orchestrated, :mattermost do
+ describe 'Mattermost support' do
+ it 'user creates a group with a mattermost team' do
+ Runtime::Browser.visit(:gitlab, Page::Main::Login)
+ Page::Main::Login.act { sign_in_using_credentials }
+ Page::Menu::Main.act { go_to_groups }
+
+ Page::Dashboard::Groups.perform do |page|
+ page.go_to_new_group
+
+ expect(page).to have_content(
+ /Create a Mattermost team for this group/
+ )
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/specs/features/login/basic_spec.rb b/qa/qa/specs/features/login/basic_spec.rb
deleted file mode 100644
index f866466c7bf..00000000000
--- a/qa/qa/specs/features/login/basic_spec.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-module QA
- describe 'basic user login', :smoke do
- it 'user logs in using basic credentials' do
- Runtime::Browser.visit(:gitlab, Page::Main::Login)
- Page::Main::Login.act { sign_in_using_credentials }
-
- # TODO, since `Signed in successfully` message was removed
- # this is the only way to tell if user is signed in correctly.
- #
- Page::Menu::Main.perform do |menu|
- expect(menu).to have_personal_area
- end
- end
- end
-end
diff --git a/qa/qa/specs/features/login/ldap_spec.rb b/qa/qa/specs/features/login/ldap_spec.rb
deleted file mode 100644
index de6111eea64..00000000000
--- a/qa/qa/specs/features/login/ldap_spec.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-module QA
- describe 'LDAP user login', :orchestrated, :ldap do
- before do
- Runtime::Env.user_type = 'ldap'
- end
-
- it 'user logs in using LDAP credentials' do
- Runtime::Browser.visit(:gitlab, Page::Main::Login)
- Page::Main::Login.act { sign_in_using_credentials }
-
- # TODO, since `Signed in successfully` message was removed
- # this is the only way to tell if user is signed in correctly.
- #
- Page::Menu::Main.perform do |menu|
- expect(menu).to have_personal_area
- end
- end
- end
-end
diff --git a/qa/qa/specs/features/mattermost/group_create_spec.rb b/qa/qa/specs/features/mattermost/group_create_spec.rb
deleted file mode 100644
index 097e1713aef..00000000000
--- a/qa/qa/specs/features/mattermost/group_create_spec.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-module QA
- describe 'create a new group', :orchestrated, :mattermost do
- it 'creating a group with a mattermost team' do
- Runtime::Browser.visit(:gitlab, Page::Main::Login)
- Page::Main::Login.act { sign_in_using_credentials }
- Page::Menu::Main.act { go_to_groups }
-
- Page::Dashboard::Groups.perform do |page|
- page.go_to_new_group
-
- expect(page).to have_content(
- /Create a Mattermost team for this group/
- )
- end
- end
- end
-end
diff --git a/qa/qa/specs/features/mattermost/login_spec.rb b/qa/qa/specs/features/mattermost/login_spec.rb
deleted file mode 100644
index 27f7d4c245f..00000000000
--- a/qa/qa/specs/features/mattermost/login_spec.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-module QA
- describe 'logging in to Mattermost', :orchestrated, :mattermost do
- it 'can use gitlab oauth' do
- Runtime::Browser.visit(:gitlab, Page::Main::Login) do
- Page::Main::Login.act { sign_in_using_credentials }
-
- Runtime::Browser.visit(:mattermost, Page::Mattermost::Login) do
- Page::Mattermost::Login.act { sign_in_using_oauth }
-
- Page::Mattermost::Main.perform do |page|
- expect(page).to have_content(/(Welcome to: Mattermost|Logout GitLab Mattermost)/)
- end
- end
- end
- end
- end
-end
diff --git a/qa/qa/specs/features/merge_request/create_spec.rb b/qa/qa/specs/features/merge_request/create_spec.rb
deleted file mode 100644
index 71e79956b85..00000000000
--- a/qa/qa/specs/features/merge_request/create_spec.rb
+++ /dev/null
@@ -1,53 +0,0 @@
-module QA
- describe 'creates a merge request with milestone' do
- it 'user creates a new merge request' do
- Runtime::Browser.visit(:gitlab, Page::Main::Login)
- Page::Main::Login.act { sign_in_using_credentials }
-
- current_project = Factory::Resource::Project.fabricate! do |project|
- project.name = 'project-with-merge-request-and-milestone'
- end
-
- current_milestone = Factory::Resource::ProjectMilestone.fabricate! do |milestone|
- milestone.title = 'unique-milestone'
- milestone.project = current_project
- end
-
- Factory::Resource::MergeRequest.fabricate! do |merge_request|
- merge_request.title = 'This is a merge request with a milestone'
- merge_request.description = 'Great feature with milestone'
- merge_request.project = current_project
- merge_request.milestone = current_milestone
- end
-
- expect(page).to have_content('This is a merge request with a milestone')
- expect(page).to have_content('Great feature with milestone')
- expect(page).to have_content(/Opened [\w\s]+ ago/)
-
- Page::Issuable::Sidebar.perform do |sidebar|
- expect(sidebar).to have_milestone(current_milestone.title)
- end
- end
- end
-
- describe 'creates a merge request', :smoke do
- it 'user creates a new merge request' do
- Runtime::Browser.visit(:gitlab, Page::Main::Login)
- Page::Main::Login.act { sign_in_using_credentials }
-
- current_project = Factory::Resource::Project.fabricate! do |project|
- project.name = 'project-with-merge-request'
- end
-
- Factory::Resource::MergeRequest.fabricate! do |merge_request|
- merge_request.title = 'This is a merge request'
- merge_request.description = 'Great feature'
- merge_request.project = current_project
- end
-
- expect(page).to have_content('This is a merge request')
- expect(page).to have_content('Great feature')
- expect(page).to have_content(/Opened [\w\s]+ ago/)
- end
- end
-end
diff --git a/qa/qa/specs/features/merge_request/rebase_spec.rb b/qa/qa/specs/features/merge_request/rebase_spec.rb
deleted file mode 100644
index c36d28e4237..00000000000
--- a/qa/qa/specs/features/merge_request/rebase_spec.rb
+++ /dev/null
@@ -1,39 +0,0 @@
-module QA
- describe 'merge request rebase' do
- it 'rebases source branch of merge request' do
- Runtime::Browser.visit(:gitlab, Page::Main::Login)
- Page::Main::Login.act { sign_in_using_credentials }
-
- project = Factory::Resource::Project.fabricate! do |project|
- project.name = "only-fast-forward"
- end
-
- Page::Menu::Side.act { go_to_settings }
- Page::Project::Settings::MergeRequest.act { enable_ff_only }
-
- merge_request = Factory::Resource::MergeRequest.fabricate! do |merge_request|
- merge_request.project = project
- merge_request.title = 'Needs rebasing'
- end
-
- Factory::Repository::ProjectPush.fabricate! do |push|
- push.project = project
- push.file_name = "other.txt"
- push.file_content = "New file added!"
- end
-
- merge_request.visit!
-
- Page::MergeRequest::Show.perform do |merge_request|
- expect(merge_request).to have_content('Needs rebasing')
- expect(merge_request).not_to be_fast_forward_possible
- expect(merge_request).not_to have_merge_button
-
- merge_request.rebase!
-
- expect(merge_request).to have_merge_button
- expect(merge_request.fast_forward_possible?).to be_truthy
- end
- end
- end
-end
diff --git a/qa/qa/specs/features/merge_request/squash_spec.rb b/qa/qa/specs/features/merge_request/squash_spec.rb
deleted file mode 100644
index 3ecc36a5ae1..00000000000
--- a/qa/qa/specs/features/merge_request/squash_spec.rb
+++ /dev/null
@@ -1,50 +0,0 @@
-module QA
- describe 'merge request squash commits' do
- it 'when squash commits is marked before merge' do
- Runtime::Browser.visit(:gitlab, Page::Main::Login)
- Page::Main::Login.act { sign_in_using_credentials }
-
- project = Factory::Resource::Project.fabricate! do |project|
- project.name = "squash-before-merge"
- end
-
- merge_request = Factory::Resource::MergeRequest.fabricate! do |merge_request|
- merge_request.project = project
- merge_request.title = 'Squashing commits'
- end
-
- Factory::Repository::ProjectPush.fabricate! do |push|
- push.project = project
- push.commit_message = 'to be squashed'
- push.branch_name = merge_request.source_branch
- push.new_branch = false
- push.file_name = 'other.txt'
- push.file_content = "Test with unicode characters ❤✓€❄"
- end
-
- merge_request.visit!
-
- expect(page).to have_text('to be squashed')
-
- Page::MergeRequest::Show.perform do |merge_request_page|
- merge_request_page.mark_to_squash
- merge_request_page.merge!
-
- merge_request.project.visit!
-
- Git::Repository.perform do |repository|
- repository.uri = Page::Project::Show.act do
- choose_repository_clone_http
- repository_location.uri
- end
-
- repository.use_default_credentials
-
- repository.act { clone }
-
- expect(repository.commits.size).to eq 3
- end
- end
- end
- end
-end
diff --git a/qa/qa/specs/features/project/activity_spec.rb b/qa/qa/specs/features/project/activity_spec.rb
deleted file mode 100644
index c7ce8dfdcc6..00000000000
--- a/qa/qa/specs/features/project/activity_spec.rb
+++ /dev/null
@@ -1,20 +0,0 @@
-module QA
- describe 'activity page' do
- it 'push creates an event in the activity page' do
- Runtime::Browser.visit(:gitlab, Page::Main::Login)
- Page::Main::Login.act { sign_in_using_credentials }
-
- Factory::Repository::ProjectPush.fabricate! do |push|
- push.file_name = 'README.md'
- push.file_content = '# This is a test project'
- push.commit_message = 'Add README.md'
- end
-
- Page::Menu::Side.act { go_to_activity }
-
- Page::Project::Activity.act { go_to_push_events }
-
- expect(page).to have_content('pushed new branch master')
- end
- end
-end
diff --git a/qa/qa/specs/features/project/add_deploy_key_spec.rb b/qa/qa/specs/features/project/add_deploy_key_spec.rb
deleted file mode 100644
index 24f9f4c77f8..00000000000
--- a/qa/qa/specs/features/project/add_deploy_key_spec.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-module QA
- describe 'deploy keys support' do
- it 'user adds a deploy key' do
- Runtime::Browser.visit(:gitlab, Page::Main::Login)
- Page::Main::Login.act { sign_in_using_credentials }
-
- key = Runtime::Key::RSA.new
- deploy_key_title = 'deploy key title'
- deploy_key_value = key.public_key
-
- deploy_key = Factory::Resource::DeployKey.fabricate! do |resource|
- resource.title = deploy_key_title
- resource.key = deploy_key_value
- end
-
- expect(deploy_key.fingerprint).to eq(key.fingerprint)
- end
- end
-end
diff --git a/qa/qa/specs/features/project/add_secret_variable_spec.rb b/qa/qa/specs/features/project/add_secret_variable_spec.rb
deleted file mode 100644
index 04d9fe488e2..00000000000
--- a/qa/qa/specs/features/project/add_secret_variable_spec.rb
+++ /dev/null
@@ -1,24 +0,0 @@
-module QA
- describe 'secret variables support' do
- it 'user adds a secret variable' do
- Runtime::Browser.visit(:gitlab, Page::Main::Login)
- Page::Main::Login.act { sign_in_using_credentials }
-
- Factory::Resource::SecretVariable.fabricate! do |resource|
- resource.key = 'VARIABLE_KEY'
- resource.value = 'some secret variable'
- end
-
- Page::Project::Settings::CICD.perform do |settings|
- settings.expand_secret_variables do |page|
- expect(page).to have_field(with: 'VARIABLE_KEY')
- expect(page).not_to have_field(with: 'some secret variable')
-
- page.reveal_variables
-
- expect(page).to have_field(with: 'some secret variable')
- end
- end
- end
- end
-end
diff --git a/qa/qa/specs/features/project/auto_devops_spec.rb b/qa/qa/specs/features/project/auto_devops_spec.rb
deleted file mode 100644
index 248669b6046..00000000000
--- a/qa/qa/specs/features/project/auto_devops_spec.rb
+++ /dev/null
@@ -1,64 +0,0 @@
-require 'pathname'
-
-module QA
- describe 'Auto Devops', :orchestrated, :kubernetes do
- after do
- @cluster&.remove!
- end
-
- it 'user creates a new project and runs auto devops' do
- Runtime::Browser.visit(:gitlab, Page::Main::Login)
- Page::Main::Login.act { sign_in_using_credentials }
-
- project = Factory::Resource::Project.fabricate! do |p|
- p.name = 'project-with-autodevops'
- p.description = 'Project with Auto Devops'
- end
-
- # Disable code_quality check in Auto DevOps pipeline as it takes
- # too long and times out the test
- Factory::Resource::SecretVariable.fabricate! do |resource|
- resource.key = 'CODE_QUALITY_DISABLED'
- resource.value = '1'
- end
-
- # Create Auto Devops compatible repo
- Factory::Repository::ProjectPush.fabricate! do |push|
- push.project = project
- push.directory = Pathname
- .new(__dir__)
- .join('../../../fixtures/auto_devops_rack')
- push.commit_message = 'Create Auto DevOps compatible rack application'
- end
-
- Page::Project::Show.act { wait_for_push }
-
- # Create and connect K8s cluster
- @cluster = Service::KubernetesCluster.new.create!
- kubernetes_cluster = Factory::Resource::KubernetesCluster.fabricate! do |cluster|
- cluster.project = project
- cluster.cluster = @cluster
- cluster.install_helm_tiller = true
- cluster.install_ingress = true
- cluster.install_prometheus = true
- cluster.install_runner = true
- end
-
- project.visit!
- Page::Menu::Side.act { click_ci_cd_settings }
- Page::Project::Settings::CICD.perform do |p|
- p.enable_auto_devops_with_domain("#{kubernetes_cluster.ingress_ip}.nip.io")
- end
-
- project.visit!
- Page::Menu::Side.act { click_ci_cd_pipelines }
- Page::Project::Pipeline::Index.act { go_to_latest_pipeline }
-
- Page::Project::Pipeline::Show.perform do |pipeline|
- expect(pipeline).to have_build('build', status: :success, wait: 600)
- expect(pipeline).to have_build('test', status: :success, wait: 600)
- expect(pipeline).to have_build('production', status: :success, wait: 1200)
- end
- end
- end
-end
diff --git a/qa/qa/specs/features/project/create_issue_spec.rb b/qa/qa/specs/features/project/create_issue_spec.rb
deleted file mode 100644
index bd3e8d2c666..00000000000
--- a/qa/qa/specs/features/project/create_issue_spec.rb
+++ /dev/null
@@ -1,46 +0,0 @@
-module QA
- describe 'creates issue', :smoke do
- let(:issue_title) { 'issue title' }
-
- def create_issue
- Runtime::Browser.visit(:gitlab, Page::Main::Login)
- Page::Main::Login.act { sign_in_using_credentials }
-
- Factory::Resource::Issue.fabricate! do |issue|
- issue.title = issue_title
- end
- end
-
- it 'user creates issue' do
- create_issue
-
- Page::Menu::Side.act { click_issues }
-
- expect(page).to have_content(issue_title)
- end
-
- context 'when using attachements in comments', :object_storage do
- let(:file_to_attach) do
- File.absolute_path(File.join('spec', 'fixtures', 'banana_sample.gif'))
- end
-
- it 'user comments on an issue with an attachment' do
- create_issue
-
- Page::Project::Issue::Show.perform do |show|
- show.comment('See attached banana for scale', attachment: file_to_attach)
-
- show.refresh
-
- image_url = find('a[href$="banana_sample.gif"]')[:href]
-
- found = show.wait(reload: false) do
- show.asset_exists?(image_url)
- end
-
- expect(found).to be_truthy
- end
- end
- end
- end
-end
diff --git a/qa/qa/specs/features/project/create_spec.rb b/qa/qa/specs/features/project/create_spec.rb
deleted file mode 100644
index 5e19e490778..00000000000
--- a/qa/qa/specs/features/project/create_spec.rb
+++ /dev/null
@@ -1,22 +0,0 @@
-module QA
- describe 'create a new project', :smoke do
- it 'user creates a new project' do
- Runtime::Browser.visit(:gitlab, Page::Main::Login)
- Page::Main::Login.act { sign_in_using_credentials }
-
- created_project = Factory::Resource::Project.fabricate! do |project|
- project.name = 'awesome-project'
- project.description = 'create awesome project test'
- end
-
- expect(created_project.name).to match /^awesome-project-\h{16}$/
-
- expect(page).to have_content(
- /Project \S?awesome-project\S+ was successfully created/
- )
-
- expect(page).to have_content('create awesome project test')
- expect(page).to have_content('The repository for this project is empty')
- end
- end
-end
diff --git a/qa/qa/specs/features/project/deploy_key_clone_spec.rb b/qa/qa/specs/features/project/deploy_key_clone_spec.rb
deleted file mode 100644
index 1d099508c24..00000000000
--- a/qa/qa/specs/features/project/deploy_key_clone_spec.rb
+++ /dev/null
@@ -1,105 +0,0 @@
-require 'digest/sha1'
-
-module QA
- describe 'cloning code using a deploy key', :docker do
- def login
- Runtime::Browser.visit(:gitlab, Page::Main::Login)
- Page::Main::Login.act { sign_in_using_credentials }
- end
-
- before(:all) do
- login
-
- @runner_name = "qa-runner-#{Time.now.to_i}"
-
- @project = Factory::Resource::Project.fabricate! do |resource|
- resource.name = 'deploy-key-clone-project'
- end
-
- @repository_location = @project.repository_ssh_location
-
- Factory::Resource::Runner.fabricate! do |resource|
- resource.project = @project
- resource.name = @runner_name
- resource.tags = %w[qa docker]
- resource.image = 'gitlab/gitlab-runner:ubuntu'
- end
-
- Page::Menu::Main.act { sign_out }
- end
-
- after(:all) do
- Service::Runner.new(@runner_name).remove!
- end
-
- keys = [
- [Runtime::Key::RSA, 8192],
- [Runtime::Key::ECDSA, 521],
- [Runtime::Key::ED25519]
- ]
-
- keys.each do |(key_class, bits)|
- it "user sets up a deploy key with #{key_class}(#{bits}) to clone code using pipelines" do
- key = key_class.new(*bits)
-
- login
-
- Factory::Resource::DeployKey.fabricate! do |resource|
- resource.project = @project
- resource.title = "deploy key #{key.name}(#{key.bits})"
- resource.key = key.public_key
- end
-
- deploy_key_name = "DEPLOY_KEY_#{key.name}_#{key.bits}"
-
- Factory::Resource::SecretVariable.fabricate! do |resource|
- resource.project = @project
- resource.key = deploy_key_name
- resource.value = key.private_key
- end
-
- gitlab_ci = <<~YAML
- cat-config:
- script:
- - mkdir -p ~/.ssh
- - ssh-keyscan -p #{@repository_location.port} #{@repository_location.host} >> ~/.ssh/known_hosts
- - eval $(ssh-agent -s)
- - ssh-add -D
- - echo "$#{deploy_key_name}" | ssh-add -
- - git clone #{@repository_location.git_uri}
- - cd #{@project.name}
- - git checkout #{deploy_key_name}
- - sha1sum .gitlab-ci.yml
- tags:
- - qa
- - docker
- YAML
-
- Factory::Repository::ProjectPush.fabricate! do |resource|
- resource.project = @project
- resource.file_name = '.gitlab-ci.yml'
- resource.commit_message = 'Add .gitlab-ci.yml'
- resource.file_content = gitlab_ci
- resource.branch_name = deploy_key_name
- resource.new_branch = true
- end
-
- sha1sum = Digest::SHA1.hexdigest(gitlab_ci)
-
- Page::Project::Show.act { wait_for_push }
- Page::Menu::Side.act { click_ci_cd_pipelines }
- Page::Project::Pipeline::Index.act { go_to_latest_pipeline }
- Page::Project::Pipeline::Show.act { go_to_first_job }
-
- Page::Project::Job::Show.perform do |job|
- job.wait(reload: false) do
- job.completed? && !job.trace_loading?
- end
-
- expect(job.passed?).to be_truthy, "Job status did not become \"passed\"."
- expect(job.output).to include(sha1sum)
- end
- end
- end
- end
-end
diff --git a/qa/qa/specs/features/project/file_spec.rb b/qa/qa/specs/features/project/file_spec.rb
deleted file mode 100644
index 5659784cd5c..00000000000
--- a/qa/qa/specs/features/project/file_spec.rb
+++ /dev/null
@@ -1,54 +0,0 @@
-module QA
- describe 'File Functionality', :core do
- it 'lets a user create, edit and delete a file via WebUI' do
- Runtime::Browser.visit(:gitlab, Page::Main::Login)
- Page::Main::Login.act { sign_in_using_credentials }
-
- # Create
- file_name = 'QA Test - File name'
- file_content = 'QA Test - File content'
- commit_message_for_create = 'QA Test - Create new file'
-
- Factory::Resource::File.fabricate! do |file|
- file.name = file_name
- file.content = file_content
- file.commit_message = commit_message_for_create
- end
-
- expect(page).to have_content('The file has been successfully created.')
- expect(page).to have_content(file_name)
- expect(page).to have_content(file_content)
- expect(page).to have_content(commit_message_for_create)
-
- # Edit
- updated_file_content = 'QA Test - Updated file content'
- commit_message_for_update = 'QA Test - Update file'
-
- Page::File::Show.act { click_edit }
-
- Page::File::Form.act do
- remove_content
- add_content(updated_file_content)
- add_commit_message(commit_message_for_update)
- commit_changes
- end
-
- expect(page).to have_content('Your changes have been successfully committed.')
- expect(page).to have_content(updated_file_content)
- expect(page).to have_content(commit_message_for_update)
-
- # Delete
- commit_message_for_delete = 'QA Test - Delete file'
-
- Page::File::Show.act do
- click_delete
- add_commit_message(commit_message_for_delete)
- click_delete_file
- end
-
- expect(page).to have_content('The file has been successfully deleted.')
- expect(page).to have_content(commit_message_for_delete)
- expect(page).to have_no_content(file_name)
- end
- end
-end
diff --git a/qa/qa/specs/features/project/fork_project_spec.rb b/qa/qa/specs/features/project/fork_project_spec.rb
deleted file mode 100644
index 280978bb950..00000000000
--- a/qa/qa/specs/features/project/fork_project_spec.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-module QA
- describe 'Project fork' do
- it 'can submit merge requests to upstream master' do
- Runtime::Browser.visit(:gitlab, Page::Main::Login)
- Page::Main::Login.act { sign_in_using_credentials }
-
- merge_request = Factory::Resource::MergeRequestFromFork.fabricate! do |merge_request|
- merge_request.fork_branch = 'feature-branch'
- end
-
- Page::Menu::Main.perform { |main| main.sign_out }
- Page::Main::Login.perform { |login| login.sign_in_using_credentials }
-
- merge_request.visit!
-
- Page::MergeRequest::Show.perform { |show| show.merge! }
-
- expect(page).to have_content('The changes were merged')
- end
- end
-end
diff --git a/qa/qa/specs/features/project/import_from_github_spec.rb b/qa/qa/specs/features/project/import_from_github_spec.rb
deleted file mode 100644
index 57695d2c726..00000000000
--- a/qa/qa/specs/features/project/import_from_github_spec.rb
+++ /dev/null
@@ -1,106 +0,0 @@
-module QA
- describe 'user imports a GitHub repo', :orchestrated, :github do
- let(:imported_project) do
- Factory::Resource::ProjectImportedFromGithub.fabricate! do |project|
- project.name = 'imported-project'
- project.personal_access_token = Runtime::Env.github_access_token
- project.github_repository_path = 'gitlab-qa/test-project'
- end
- end
-
- after do
- # We need to delete the imported project because it's impossible to import
- # the same GitHub project twice for a given user.
- api_client = Runtime::API::Client.new(:gitlab)
- delete_project_request = Runtime::API::Request.new(api_client, "/projects/#{CGI.escape("#{Runtime::Namespace.path}/#{imported_project.name}")}")
- delete delete_project_request.url
-
- expect_status(202)
- end
-
- it 'user imports a GitHub repo' do
- Runtime::Browser.visit(:gitlab, Page::Main::Login)
- Page::Main::Login.act { sign_in_using_credentials }
-
- imported_project # import the project
-
- Page::Menu::Main.act { go_to_projects }
- Page::Dashboard::Projects.perform do |dashboard|
- dashboard.go_to_project(imported_project.name)
- end
-
- Page::Project::Show.act { wait_for_import }
-
- verify_repository_import
- verify_issues_import
- verify_merge_requests_import
- verify_labels_import
- verify_milestones_import
- verify_wiki_import
- end
-
- def verify_repository_import
- expect(page).to have_content('This test project is used for automated GitHub import by GitLab QA.')
- expect(page).to have_content(imported_project.name)
- end
-
- def verify_issues_import
- Page::Menu::Side.act { click_issues }
- expect(page).to have_content('This is a sample issue')
-
- click_link 'This is a sample issue'
-
- expect(page).to have_content('We should populate this project with issues, pull requests and wiki pages.')
-
- # Comments
- expect(page).to have_content('This is a comment from @rymai.')
-
- Page::Issuable::Sidebar.perform do |issuable|
- expect(issuable).to have_label('enhancement')
- expect(issuable).to have_label('help wanted')
- expect(issuable).to have_label('good first issue')
- end
- end
-
- def verify_merge_requests_import
- Page::Menu::Side.act { click_merge_requests }
- expect(page).to have_content('Improve README.md')
-
- click_link 'Improve README.md'
-
- expect(page).to have_content('This improves the README file a bit.')
-
- # Review comment are not supported yet
- expect(page).not_to have_content('Really nice change.')
-
- # Comments
- expect(page).to have_content('Nice work! This is a comment from @rymai.')
-
- # Diff comments
- expect(page).to have_content('[Review comment] I like that!')
- expect(page).to have_content('[Review comment] Nice blank line.')
- expect(page).to have_content('[Single diff comment] Much better without this line!')
-
- Page::Issuable::Sidebar.perform do |issuable|
- expect(issuable).to have_label('bug')
- expect(issuable).to have_label('enhancement')
- end
- end
-
- def verify_labels_import
- # TODO: Waiting on https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/19228
- # to build upon it.
- end
-
- def verify_milestones_import
- # TODO: Waiting on https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/18727
- # to build upon it.
- end
-
- def verify_wiki_import
- Page::Menu::Side.act { click_wiki }
-
- expect(page).to have_content('Welcome to the test-project wiki!')
- end
- end
-end
diff --git a/qa/qa/specs/features/project/pipelines_spec.rb b/qa/qa/specs/features/project/pipelines_spec.rb
deleted file mode 100644
index 6c6b4e80626..00000000000
--- a/qa/qa/specs/features/project/pipelines_spec.rb
+++ /dev/null
@@ -1,102 +0,0 @@
-module QA
- describe 'CI/CD Pipelines', :orchestrated, :docker do
- let(:executor) { "qa-runner-#{Time.now.to_i}" }
-
- after do
- Service::Runner.new(executor).remove!
- end
-
- it 'user registers a new specific runner' do
- Runtime::Browser.visit(:gitlab, Page::Main::Login)
- Page::Main::Login.act { sign_in_using_credentials }
-
- Factory::Resource::Runner.fabricate! do |runner|
- runner.name = executor
- end
-
- Page::Project::Settings::CICD.perform do |settings|
- sleep 5 # Runner should register within 5 seconds
- settings.refresh
-
- settings.expand_runners_settings do |page|
- expect(page).to have_content(executor)
- expect(page).to have_online_runner
- end
- end
- end
-
- it 'users creates a new pipeline' do
- Runtime::Browser.visit(:gitlab, Page::Main::Login)
- Page::Main::Login.act { sign_in_using_credentials }
-
- project = Factory::Resource::Project.fabricate! do |project|
- project.name = 'project-with-pipelines'
- project.description = 'Project with CI/CD Pipelines.'
- end
-
- Factory::Resource::Runner.fabricate! do |runner|
- runner.project = project
- runner.name = executor
- runner.tags = %w[qa test]
- end
-
- Factory::Repository::ProjectPush.fabricate! do |push|
- push.project = project
- push.file_name = '.gitlab-ci.yml'
- push.commit_message = 'Add .gitlab-ci.yml'
- push.file_content = <<~EOF
- test-success:
- tags:
- - qa
- - test
- script: echo 'OK'
-
- test-failure:
- tags:
- - qa
- - test
- script:
- - echo 'FAILURE'
- - exit 1
-
- test-tags:
- tags:
- - qa
- - docker
- script: echo 'NOOP'
-
- test-artifacts:
- tags:
- - qa
- - test
- script: mkdir my-artifacts; echo "CONTENTS" > my-artifacts/artifact.txt
- artifacts:
- paths:
- - my-artifacts/
- EOF
- end
-
- Page::Project::Show.act { wait_for_push }
-
- expect(page).to have_content('Add .gitlab-ci.yml')
-
- Page::Menu::Side.act { click_ci_cd_pipelines }
-
- expect(page).to have_content('All 1')
- expect(page).to have_content('Add .gitlab-ci.yml')
-
- puts 'Waiting for the runner to process the pipeline'
- sleep 15 # Runner should process all jobs within 15 seconds.
-
- Page::Project::Pipeline::Index.act { go_to_latest_pipeline }
-
- Page::Project::Pipeline::Show.perform do |pipeline|
- expect(pipeline).to be_running
- expect(pipeline).to have_build('test-success', status: :success)
- expect(pipeline).to have_build('test-failure', status: :failed)
- expect(pipeline).to have_build('test-tags', status: :pending)
- expect(pipeline).to have_build('test-artifacts', status: :success)
- end
- end
- end
-end
diff --git a/qa/qa/specs/features/project/wikis_spec.rb b/qa/qa/specs/features/project/wikis_spec.rb
deleted file mode 100644
index 9af2dbd1264..00000000000
--- a/qa/qa/specs/features/project/wikis_spec.rb
+++ /dev/null
@@ -1,45 +0,0 @@
-module QA
- describe 'Wiki Functionality' do
- def login
- Runtime::Browser.visit(:gitlab, Page::Main::Login)
- Page::Main::Login.act { sign_in_using_credentials }
- end
-
- def validate_content(content)
- expect(page).to have_content('Wiki was successfully updated')
- expect(page).to have_content(/#{content}/)
- end
-
- before do
- login
- end
-
- it 'User creates, edits, clones, and pushes to the wiki' do
- wiki = Factory::Resource::Wiki.fabricate! do |resource|
- resource.title = 'Home'
- resource.content = '# My First Wiki Content'
- resource.message = 'Update home'
- end
-
- validate_content('My First Wiki Content')
-
- Page::Project::Wiki::Edit.act { go_to_edit_page }
- Page::Project::Wiki::New.perform do |page|
- page.set_content("My Second Wiki Content")
- page.save_changes
- end
-
- validate_content('My Second Wiki Content')
-
- Factory::Repository::WikiPush.fabricate! do |push|
- push.wiki = wiki
- push.file_name = 'Home.md'
- push.file_content = '# My Third Wiki Content'
- push.commit_message = 'Update Home.md'
- end
- Page::Menu::Side.act { click_wiki }
-
- expect(page).to have_content('My Third Wiki Content')
- end
- end
-end
diff --git a/qa/qa/specs/features/repository/protected_branches_spec.rb b/qa/qa/specs/features/repository/protected_branches_spec.rb
deleted file mode 100644
index aa23145478d..00000000000
--- a/qa/qa/specs/features/repository/protected_branches_spec.rb
+++ /dev/null
@@ -1,66 +0,0 @@
-module QA
- describe 'branch protection support' do
- let(:branch_name) { 'protected-branch' }
- let(:commit_message) { 'Protected push commit message' }
- let(:project) do
- Factory::Resource::Project.fabricate! do |resource|
- resource.name = 'protected-branch-project'
- end
- end
-
- before do
- Runtime::Browser.visit(:gitlab, Page::Main::Login)
- Page::Main::Login.act { sign_in_using_credentials }
- end
-
- after do
- # We need to clear localStorage because we're using it for the dropdown,
- # and capybara doesn't do this for us.
- # https://github.com/teamcapybara/capybara/issues/1702
- Capybara.execute_script 'localStorage.clear()'
- end
-
- context 'when developers and maintainers are allowed to push to a protected branch' do
- it 'user with push rights successfully pushes to the protected branch' do
- create_protected_branch(allow_to_push: true)
-
- push = push_new_file(branch_name)
-
- expect(push.output).to match(/remote: To create a merge request for protected-branch, visit/)
- end
- end
-
- context 'when developers and maintainers are not allowed to push to a protected branch' do
- it 'user without push rights fails to push to the protected branch' do
- create_protected_branch(allow_to_push: false)
-
- push = push_new_file(branch_name)
-
- expect(push.output)
- .to match(/remote\: GitLab\: You are not allowed to push code to protected branches on this project/)
- expect(push.output)
- .to match(/\[remote rejected\] #{branch_name} -> #{branch_name} \(pre-receive hook declined\)/)
- end
- end
-
- def create_protected_branch(allow_to_push:)
- Factory::Resource::Branch.fabricate! do |resource|
- resource.branch_name = branch_name
- resource.project = project
- resource.allow_to_push = allow_to_push
- resource.protected = true
- end
- end
-
- def push_new_file(branch)
- Factory::Repository::ProjectPush.fabricate! do |resource|
- resource.project = project
- resource.file_name = 'new_file.md'
- resource.file_content = '# This is a new file'
- resource.commit_message = 'Add new_file.md'
- resource.branch_name = branch_name
- resource.new_branch = false
- end
- end
- end
-end
diff --git a/qa/spec/runtime/env_spec.rb b/qa/spec/runtime/env_spec.rb
index ccc0b906845..5493a33cd2a 100644
--- a/qa/spec/runtime/env_spec.rb
+++ b/qa/spec/runtime/env_spec.rb
@@ -104,6 +104,8 @@ describe QA::Runtime::Env do
describe '.github_access_token' do
it 'returns "" if GITHUB_ACCESS_TOKEN is not defined' do
+ stub_env('GITHUB_ACCESS_TOKEN', nil)
+
expect(described_class.github_access_token).to eq('')
end
@@ -115,6 +117,8 @@ describe QA::Runtime::Env do
describe '.require_github_access_token!' do
it 'raises ArgumentError if GITHUB_ACCESS_TOKEN is not defined' do
+ stub_env('GITHUB_ACCESS_TOKEN', nil)
+
expect { described_class.require_github_access_token! }.to raise_error(ArgumentError)
end
diff --git a/qa/spec/scenario/test/instance/all_spec.rb b/qa/spec/scenario/test/instance/all_spec.rb
index 423527e938e..1d96352550b 100644
--- a/qa/spec/scenario/test/instance/all_spec.rb
+++ b/qa/spec/scenario/test/instance/all_spec.rb
@@ -1,4 +1,10 @@
describe QA::Scenario::Test::Instance::All do
+ subject do
+ Class.new(described_class) do
+ tags :rspec, :foo
+ end
+ end
+
context '#perform' do
let(:arguments) { spy('Runtime::Scenario') }
let(:release) { spy('Runtime::Release') }
@@ -24,7 +30,7 @@ describe QA::Scenario::Test::Instance::All do
subject.perform("test")
expect(runner).to have_received(:options=)
- .with(::File.expand_path('../../../../qa/specs/features', __dir__))
+ .with(['--tag', 'rspec,foo', '--', ::File.expand_path('../../../../qa/specs/features', __dir__)])
end
end
diff --git a/qa/spec/scenario/test/instance/smoke_spec.rb b/qa/spec/scenario/test/instance/smoke_spec.rb
index e79d19e8212..386eefae930 100644
--- a/qa/spec/scenario/test/instance/smoke_spec.rb
+++ b/qa/spec/scenario/test/instance/smoke_spec.rb
@@ -30,7 +30,7 @@ describe QA::Scenario::Test::Instance::Smoke do
subject.perform("test")
expect(runner).to have_received(:options=)
- .with(::File.expand_path('../../../../qa/specs/features', __dir__))
+ .with(['--tag', 'smoke', '--', ::File.expand_path('../../../../qa/specs/features', __dir__)])
end
end
diff --git a/rubocop/cop/line_break_around_conditional_block.rb b/rubocop/cop/line_break_around_conditional_block.rb
index 011f2bcf8bf..59fe6e5d98c 100644
--- a/rubocop/cop/line_break_around_conditional_block.rb
+++ b/rubocop/cop/line_break_around_conditional_block.rb
@@ -48,6 +48,8 @@ module RuboCop
MSG = 'Add a line break around conditional blocks'
def on_if(node)
+ # This cop causes errors in haml files, so let's skip those
+ return if in_haml?(node)
return if node.single_line?
return unless node.if? || node.unless?
@@ -116,6 +118,10 @@ module RuboCop
def end_line?(line)
line =~ /^\s*(end|})/
end
+
+ def in_haml?(node)
+ node.location.expression.source_buffer.name.end_with?('.haml.rb')
+ end
end
end
end
diff --git a/rubocop/cop/ruby_interpolation_in_translation.rb b/rubocop/cop/ruby_interpolation_in_translation.rb
new file mode 100644
index 00000000000..b9411fcfd6c
--- /dev/null
+++ b/rubocop/cop/ruby_interpolation_in_translation.rb
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+module RuboCop
+ module Cop
+ class RubyInterpolationInTranslation < RuboCop::Cop::Cop
+ MSG = "Don't use ruby interpolation \#{} inside translated strings, instead use \%{}"
+
+ TRANSLATION_METHODS = ':_ :s_ :N_ :n_'
+ RUBY_INTERPOLATION_REGEX = /.*\#\{.*\}/
+
+ def_node_matcher :translation_method?, <<~PATTERN
+ (send nil? {#{TRANSLATION_METHODS}} $dstr ...)
+ PATTERN
+
+ def_node_matcher :plural_translation_method?, <<~PATTERN
+ (send nil? :n_ str $dstr ...)
+ PATTERN
+
+ def on_send(node)
+ interpolation = translation_method?(node) || plural_translation_method?(node)
+ return unless interpolation
+
+ interpolation.descendants.each do |possible_violation|
+ add_offense(possible_violation, message: MSG) if possible_violation.type != :str
+ end
+ end
+ end
+ end
+end
diff --git a/rubocop/rubocop.rb b/rubocop/rubocop.rb
index 88c9bbf24f4..eaf421a7235 100644
--- a/rubocop/rubocop.rb
+++ b/rubocop/rubocop.rb
@@ -28,3 +28,4 @@ require_relative 'cop/rspec/env_assignment'
require_relative 'cop/rspec/factories_in_migration_specs'
require_relative 'cop/sidekiq_options_queue'
require_relative 'cop/destroy_all'
+require_relative 'cop/ruby_interpolation_in_translation'
diff --git a/scripts/frontend/extract_gettext_all.js b/scripts/frontend/extract_gettext_all.js
index af8cc4c3341..725522a3540 100644
--- a/scripts/frontend/extract_gettext_all.js
+++ b/scripts/frontend/extract_gettext_all.js
@@ -7,7 +7,7 @@ const {
} = require('gettext-extractor-vue');
const ensureSingleLine = require('../../app/assets/javascripts/locale/ensure_single_line.js');
-const arguments = argumentsParser
+const args = argumentsParser
.option('-f, --file <file>', 'Extract message from one single file')
.option('-a, --all', 'Extract message from all js/vue files')
.parse(process.argv);
@@ -61,12 +61,12 @@ function printJson() {
console.log(JSON.stringify(messages));
}
-if (arguments.file) {
- vueParser.parseFile(arguments.file).then(() => printJson());
-} else if (arguments.all) {
+if (args.file) {
+ vueParser.parseFile(args.file).then(() => printJson());
+} else if (args.all) {
vueParser.parseFilesGlob('{ee/app,app}/assets/javascripts/**/*.{js,vue}').then(() => printJson());
} else {
console.warn('ERROR: Please use the script correctly:');
- arguments.outputHelp();
+ args.outputHelp();
process.exit(1);
}
diff --git a/spec/controllers/groups/milestones_controller_spec.rb b/spec/controllers/groups/milestones_controller_spec.rb
index f7068546093..465f3499703 100644
--- a/spec/controllers/groups/milestones_controller_spec.rb
+++ b/spec/controllers/groups/milestones_controller_spec.rb
@@ -141,6 +141,17 @@ describe Groups::MilestonesController do
end
end
+ describe "#destroy" do
+ let(:milestone) { create(:milestone, group: group) }
+
+ it "removes milestone" do
+ delete :destroy, group_id: group.to_param, id: milestone.iid, format: :js
+
+ expect(response).to be_success
+ expect { Milestone.find(milestone.id) }.to raise_exception(ActiveRecord::RecordNotFound)
+ end
+ end
+
describe '#ensure_canonical_path' do
before do
sign_in(user)
diff --git a/spec/controllers/projects/commit_controller_spec.rb b/spec/controllers/projects/commit_controller_spec.rb
index 916a4be2567..9e149bc4c3c 100644
--- a/spec/controllers/projects/commit_controller_spec.rb
+++ b/spec/controllers/projects/commit_controller_spec.rb
@@ -230,7 +230,7 @@ describe Projects::CommitController do
id: master_pickable_commit.id)
expect(response).to redirect_to project_commits_path(project, 'master')
- expect(flash[:notice]).to eq('The commit has been successfully cherry-picked.')
+ expect(flash[:notice]).to eq('The commit has been successfully cherry-picked into master.')
end
end
diff --git a/spec/controllers/projects/merge_requests/creations_controller_spec.rb b/spec/controllers/projects/merge_requests/creations_controller_spec.rb
index d8995f98575..f8c37c0a676 100644
--- a/spec/controllers/projects/merge_requests/creations_controller_spec.rb
+++ b/spec/controllers/projects/merge_requests/creations_controller_spec.rb
@@ -29,6 +29,55 @@ describe Projects::MergeRequests::CreationsController do
expect(response).to be_success
end
end
+
+ context 'merge request with some commits' do
+ render_views
+
+ let(:large_diff_params) do
+ {
+ namespace_id: fork_project.namespace.to_param,
+ project_id: fork_project,
+ merge_request: {
+ source_branch: 'master',
+ target_branch: 'fix'
+ }
+ }
+ end
+
+ describe 'with artificial limits' do
+ before do
+ # Load MergeRequestdiff so stub_const won't override it with its own definition
+ # See https://github.com/rspec/rspec-mocks/issues/1079
+ stub_const("#{MergeRequestDiff}::COMMITS_SAFE_SIZE", 2)
+ end
+
+ it 'limits total commits' do
+ get :new, large_diff_params
+
+ expect(response).to be_success
+
+ total = assigns(:total_commit_count)
+ expect(assigns(:commits)).to be_an Array
+ expect(total).to be > 0
+ expect(assigns(:hidden_commit_count)).to be > 0
+ expect(response).to have_gitlab_http_status(200)
+ expect(response.body).to match %r(<span class="commits-count">2 commits</span>)
+ end
+ end
+
+ it 'shows total commits' do
+ get :new, large_diff_params
+
+ expect(response).to be_success
+
+ total = assigns(:total_commit_count)
+ expect(assigns(:commits)).to be_an Array
+ expect(total).to be > 0
+ expect(assigns(:hidden_commit_count)).to eq(0)
+ expect(response).to have_gitlab_http_status(200)
+ expect(response.body).to match %r(<span class="commits-count">#{total} commits</span>)
+ end
+ end
end
describe 'GET diffs' do
diff --git a/spec/factories/milestones.rb b/spec/factories/milestones.rb
index 019e4420212..027349b2f8e 100644
--- a/spec/factories/milestones.rb
+++ b/spec/factories/milestones.rb
@@ -34,7 +34,7 @@ FactoryBot.define do
milestone.project_id = evaluator.project_id
elsif evaluator.parent
id = evaluator.parent.id
- evaluator.parent.is_a?(Group) ? board.group_id = id : evaluator.project_id = id
+ evaluator.parent.is_a?(Group) ? evaluator.group_id = id : evaluator.project_id = id
else
milestone.project = create(:project)
end
diff --git a/spec/factories/project_group_links.rb b/spec/factories/project_group_links.rb
index d5ace9425a0..59c77627ee5 100644
--- a/spec/factories/project_group_links.rb
+++ b/spec/factories/project_group_links.rb
@@ -2,5 +2,6 @@ FactoryBot.define do
factory :project_group_link do
project
group
+ expires_at nil
end
end
diff --git a/spec/features/admin/admin_users_spec.rb b/spec/features/admin/admin_users_spec.rb
index 1db6c75b85b..b2eaeb1c487 100644
--- a/spec/features/admin/admin_users_spec.rb
+++ b/spec/features/admin/admin_users_spec.rb
@@ -134,6 +134,7 @@ describe "Admin::Users" do
expect(page).to have_content(user.email)
expect(page).to have_content(user.name)
+ expect(page).to have_content(user.id)
expect(page).to have_link('Block user', href: block_admin_user_path(user))
expect(page).to have_button('Delete user')
expect(page).to have_button('Delete user and contributions')
diff --git a/spec/features/dashboard/milestones_spec.rb b/spec/features/dashboard/milestones_spec.rb
index 0db69432702..d9d67788b38 100644
--- a/spec/features/dashboard/milestones_spec.rb
+++ b/spec/features/dashboard/milestones_spec.rb
@@ -13,8 +13,10 @@ describe 'Dashboard > Milestones' do
describe 'as logged-in user' do
let(:user) { create(:user) }
+ let(:group) { create(:group) }
let(:project) { create(:project, namespace: user.namespace) }
let!(:milestone) { create(:milestone, project: project) }
+ let!(:milestone2) { create(:milestone, group: group) }
before do
project.add_maintainer(user)
sign_in(user)
@@ -24,6 +26,7 @@ describe 'Dashboard > Milestones' do
it 'sees milestones' do
expect(current_path).to eq dashboard_milestones_path
expect(page).to have_content(milestone.title)
+ expect(page).to have_content(group.name)
end
end
end
diff --git a/spec/features/merge_request/user_sees_diff_spec.rb b/spec/features/merge_request/user_sees_diff_spec.rb
index d6e7ff33d5d..0c15febe8df 100644
--- a/spec/features/merge_request/user_sees_diff_spec.rb
+++ b/spec/features/merge_request/user_sees_diff_spec.rb
@@ -2,6 +2,7 @@ require 'rails_helper'
describe 'Merge request > User sees diff', :js do
include ProjectForksHelper
+ include RepoHelpers
let(:project) { create(:project, :public, :repository) }
let(:merge_request) { create(:merge_request, source_project: project) }
@@ -81,5 +82,58 @@ describe 'Merge request > User sees diff', :js do
expect(page).to have_selector('.js-cancel-fork-suggestion-button', count: 1)
end
end
+
+ context 'when file contains html' do
+ let(:current_user) { project.owner }
+ let(:branch_name) {"test_branch"}
+
+ def create_file(branch_name, file_name, content)
+ Files::CreateService.new(
+ project,
+ current_user,
+ start_branch: branch_name,
+ branch_name: branch_name,
+ commit_message: "Create file",
+ file_path: file_name,
+ file_content: content
+ ).execute
+
+ project.commit(branch_name)
+ end
+
+ it 'escapes any HTML special characters in the diff chunk header' do
+ file_content =
+ <<~CONTENT
+ function foo<input> {
+ let a = 1;
+ let b = 2;
+ let c = 3;
+ let d = 3;
+ }
+ CONTENT
+
+ new_file_content =
+ <<~CONTENT
+ function foo<input> {
+ let a = 1;
+ let b = 2;
+ let c = 3;
+ let x = 3;
+ }
+ CONTENT
+
+ file_name = 'xss_file.txt'
+
+ create_file('master', file_name, file_content)
+ merge_request = create(:merge_request, source_project: project)
+ create_file(merge_request.source_branch, file_name, new_file_content)
+
+ project.commit(merge_request.source_branch)
+
+ visit diffs_project_merge_request_path(project, merge_request)
+
+ expect(page).to have_text("function foo<input> {")
+ end
+ end
end
end
diff --git a/spec/features/milestones/user_deletes_milestone_spec.rb b/spec/features/milestones/user_deletes_milestone_spec.rb
index 9d4a68239d3..a8c296b4cd2 100644
--- a/spec/features/milestones/user_deletes_milestone_spec.rb
+++ b/spec/features/milestones/user_deletes_milestone_spec.rb
@@ -1,26 +1,46 @@
require "rails_helper"
describe "User deletes milestone", :js do
- set(:user) { create(:user) }
- set(:project) { create(:project) }
- set(:milestone) { create(:milestone, project: project) }
+ let(:user) { create(:user) }
+ let(:group) { create(:group) }
+ let(:project) { create(:project, namespace: group) }
before do
- project.add_developer(user)
sign_in(user)
+ end
+
+ context "when milestone belongs to project" do
+ let!(:milestone) { create(:milestone, parent: project, title: "project milestone") }
+
+ it "deletes milestone" do
+ project.add_developer(user)
+ visit(project_milestones_path(project))
+ click_link(milestone.title)
+ click_button("Delete")
+ click_button("Delete milestone")
+
+ expect(page).to have_content("No milestones to show")
+
+ visit(activity_project_path(project))
- visit(project_milestones_path(project))
+ expect(page).to have_content("#{user.name} destroyed milestone")
+ end
end
- it "deletes milestone" do
- click_link(milestone.title)
- click_button("Delete")
- click_button("Delete milestone")
+ context "when milestone belongs to group" do
+ let!(:milestone_to_be_deleted) { create(:milestone, parent: group, title: "group milestone 1") }
+ let!(:milestone) { create(:milestone, parent: group, title: "group milestone 2") }
- expect(page).to have_content("No milestones to show")
+ it "deletes milestone" do
+ group.add_developer(user)
+ visit(group_milestones_path(group))
- visit(activity_project_path(project))
+ click_link(milestone_to_be_deleted.title)
+ click_button("Delete")
+ click_button("Delete milestone")
- expect(page).to have_content("#{user.name} destroyed milestone")
+ expect(page).to have_content(milestone.title)
+ expect(page).not_to have_content(milestone_to_be_deleted)
+ end
end
end
diff --git a/spec/features/profiles/user_edit_profile_spec.rb b/spec/features/profiles/user_edit_profile_spec.rb
index 9e60b4995bd..206a3a4fe9a 100644
--- a/spec/features/profiles/user_edit_profile_spec.rb
+++ b/spec/features/profiles/user_edit_profile_spec.rb
@@ -130,5 +130,15 @@ describe 'User edit profile' do
visit user_path(user)
expect(page).not_to have_selector '.cover-status'
end
+
+ it 'displays a default emoji if only message is entered' do
+ message = 'a status without emoji'
+ visit(profile_path)
+ fill_in 'js-status-message-field', with: message
+
+ within('.js-toggle-emoji-menu') do
+ expect(page).to have_emoji('speech_balloon')
+ end
+ end
end
end
diff --git a/spec/features/projects/commit/cherry_pick_spec.rb b/spec/features/projects/commit/cherry_pick_spec.rb
index bc3c00dafe2..a61b614dbc8 100644
--- a/spec/features/projects/commit/cherry_pick_spec.rb
+++ b/spec/features/projects/commit/cherry_pick_spec.rb
@@ -21,7 +21,7 @@ describe 'Cherry-pick Commits' do
uncheck 'create_merge_request'
click_button 'Cherry-pick'
end
- expect(page).to have_content('The commit has been successfully cherry-picked.')
+ expect(page).to have_content('The commit has been successfully cherry-picked into master.')
end
end
@@ -32,7 +32,7 @@ describe 'Cherry-pick Commits' do
uncheck 'create_merge_request'
click_button 'Cherry-pick'
end
- expect(page).to have_content('The commit has been successfully cherry-picked.')
+ expect(page).to have_content('The commit has been successfully cherry-picked into master.')
end
end
@@ -59,7 +59,7 @@ describe 'Cherry-pick Commits' do
page.within('#modal-cherry-pick-commit') do
click_button 'Cherry-pick'
end
- expect(page).to have_content('The commit has been successfully cherry-picked. You can now submit a merge request to get this change into the original branch.')
+ expect(page).to have_content("The commit has been successfully cherry-picked into cherry-pick-#{master_pickable_commit.short_id}. You can now submit a merge request to get this change into the original branch.")
expect(page).to have_content("From cherry-pick-#{master_pickable_commit.short_id} into master")
end
end
@@ -86,7 +86,7 @@ describe 'Cherry-pick Commits' do
click_button 'Cherry-pick'
end
- expect(page).to have_content('The commit has been successfully cherry-picked.')
+ expect(page).to have_content('The commit has been successfully cherry-picked into feature.')
end
end
diff --git a/spec/features/projects/issues/user_sorts_issues_spec.rb b/spec/features/projects/issues/user_sorts_issues_spec.rb
index db5936a30cb..7d261ec7dae 100644
--- a/spec/features/projects/issues/user_sorts_issues_spec.rb
+++ b/spec/features/projects/issues/user_sorts_issues_spec.rb
@@ -1,7 +1,9 @@
require "spec_helper"
describe "User sorts issues" do
- set(:project) { create(:project_empty_repo, :public) }
+ set(:user) { create(:user) }
+ set(:group) { create(:group) }
+ set(:project) { create(:project_empty_repo, :public, group: group) }
set(:issue1) { create(:issue, project: project) }
set(:issue2) { create(:issue, project: project) }
set(:issue3) { create(:issue, project: project) }
@@ -12,7 +14,29 @@ describe "User sorts issues" do
create(:award_emoji, :downvote, awardable: issue1)
create(:award_emoji, :upvote, awardable: issue2)
+ sign_in(user)
+
+ visit(project_issues_path(project))
+ end
+
+ it 'keeps the sort option' do
+ find('button.dropdown-toggle').click
+
+ page.within('.content ul.dropdown-menu.dropdown-menu-right li') do
+ click_link('Milestone')
+ end
+
+ visit(issues_dashboard_path(assignee_id: user.id))
+
+ expect(find('.issues-filters a.is-active')).to have_content('Milestone')
+
visit(project_issues_path(project))
+
+ expect(find('.issues-filters a.is-active')).to have_content('Milestone')
+
+ visit(issues_group_path(group))
+
+ expect(find('.issues-filters a.is-active')).to have_content('Milestone')
end
it "sorts by popularity" do
diff --git a/spec/features/projects/jobs/user_browses_job_spec.rb b/spec/features/projects/jobs/user_browses_job_spec.rb
index 50e957bf12b..2d791947ee9 100644
--- a/spec/features/projects/jobs/user_browses_job_spec.rb
+++ b/spec/features/projects/jobs/user_browses_job_spec.rb
@@ -40,7 +40,7 @@ describe 'User browses a job', :js do
it 'displays the failure reason' do
within('.builds-container') do
build_link = first('.build-job > a')
- expect(build_link['data-title']).to eq('test - failed <br> (unknown failure)')
+ expect(build_link['data-title']).to eq('test - failed - (unknown failure)')
end
end
end
@@ -51,7 +51,7 @@ describe 'User browses a job', :js do
it 'displays the failure reason and retried label' do
within('.builds-container') do
build_link = first('.build-job > a')
- expect(build_link['data-title']).to eq('test - failed <br> (unknown failure) (retried)')
+ expect(build_link['data-title']).to eq('test - failed - (unknown failure) (retried)')
end
end
end
diff --git a/spec/features/projects/jobs/user_browses_jobs_spec.rb b/spec/features/projects/jobs/user_browses_jobs_spec.rb
index 08786fe1630..ebc20d15d67 100644
--- a/spec/features/projects/jobs/user_browses_jobs_spec.rb
+++ b/spec/features/projects/jobs/user_browses_jobs_spec.rb
@@ -36,7 +36,7 @@ describe 'User browses jobs' do
it 'displays a tooltip with the failure reason' do
page.within('.ci-table') do
failed_job_link = page.find('.ci-failed')
- expect(failed_job_link[:title]).to eq('Failed <br> (unknown failure)')
+ expect(failed_job_link[:title]).to eq('Failed - (unknown failure)')
end
end
end
diff --git a/spec/features/projects/merge_requests/user_sorts_merge_requests_spec.rb b/spec/features/projects/merge_requests/user_sorts_merge_requests_spec.rb
index e401933aed2..82cfe600d52 100644
--- a/spec/features/projects/merge_requests/user_sorts_merge_requests_spec.rb
+++ b/spec/features/projects/merge_requests/user_sorts_merge_requests_spec.rb
@@ -1,15 +1,18 @@
require 'spec_helper'
describe 'User sorts merge requests' do
+ include CookieHelper
+
let!(:merge_request) { create(:merge_request, source_project: project, target_project: project) }
let!(:merge_request2) do
create(:merge_request_with_diffs, source_project: project, target_project: project, source_branch: 'merge-test')
end
- let(:project) { create(:project, :public, :repository) }
- let(:user) { create(:user) }
+ set(:user) { create(:user) }
+ set(:group) { create(:group) }
+ set(:group_member) { create(:group_member, :maintainer, user: user, group: group) }
+ set(:project) { create(:project, :public, group: group) }
before do
- project.add_maintainer(user)
sign_in(user)
visit(project_merge_requests_path(project))
@@ -19,16 +22,42 @@ describe 'User sorts merge requests' do
find('button.dropdown-toggle').click
page.within('.content ul.dropdown-menu.dropdown-menu-right li') do
- click_link('Last updated')
+ click_link('Milestone')
end
visit(merge_requests_dashboard_path(assignee_id: user.id))
- expect(find('.issues-filters')).to have_content('Last updated')
+ expect(find('.issues-filters a.is-active')).to have_content('Milestone')
visit(project_merge_requests_path(project))
- expect(find('.issues-filters')).to have_content('Last updated')
+ expect(find('.issues-filters a.is-active')).to have_content('Milestone')
+
+ visit(merge_requests_group_path(group))
+
+ expect(find('.issues-filters a.is-active')).to have_content('Milestone')
+ end
+
+ it 'fallbacks to issuable_sort cookie key when remembering the sorting option' do
+ set_cookie('issuable_sort', 'milestone')
+
+ visit(merge_requests_dashboard_path(assignee_id: user.id))
+
+ expect(find('.issues-filters a.is-active')).to have_content('Milestone')
+ end
+
+ it 'separates remember sorting with issues' do
+ create(:issue, project: project)
+
+ find('button.dropdown-toggle').click
+
+ page.within('.content ul.dropdown-menu.dropdown-menu-right li') do
+ click_link('Milestone')
+ end
+
+ visit(project_issues_path(project))
+
+ expect(find('.issues-filters a.is-active')).not_to have_content('Milestone')
end
context 'when merge requests have awards' do
diff --git a/spec/features/projects/pipelines/pipeline_spec.rb b/spec/features/projects/pipelines/pipeline_spec.rb
index a84492ea5f1..603503a531c 100644
--- a/spec/features/projects/pipelines/pipeline_spec.rb
+++ b/spec/features/projects/pipelines/pipeline_spec.rb
@@ -126,7 +126,7 @@ describe 'Pipeline', :js do
it 'should include the failure reason' do
page.within('#ci-badge-test') do
build_link = page.find('.js-pipeline-graph-job-link')
- expect(build_link['data-original-title']).to eq('test - failed <br> (unknown failure)')
+ expect(build_link['data-original-title']).to eq('test - failed - (unknown failure)')
end
end
end
@@ -319,7 +319,7 @@ describe 'Pipeline', :js do
it 'displays a tooltip with the failure reason' do
page.within('.ci-table') do
failed_job_link = page.find('.ci-failed')
- expect(failed_job_link[:title]).to eq('Failed <br> (unknown failure)')
+ expect(failed_job_link[:title]).to eq('Failed - (unknown failure)')
end
end
end
diff --git a/spec/features/projects/pipelines/pipelines_spec.rb b/spec/features/projects/pipelines/pipelines_spec.rb
index 4a83bcc3efb..26a92f14787 100644
--- a/spec/features/projects/pipelines/pipelines_spec.rb
+++ b/spec/features/projects/pipelines/pipelines_spec.rb
@@ -406,7 +406,7 @@ describe 'Pipelines', :js do
within('.js-builds-dropdown-list') do
build_element = page.find('.mini-pipeline-graph-dropdown-item')
- expect(build_element['data-original-title']).to eq('build - failed <br> (unknown failure)')
+ expect(build_element['data-original-title']).to eq('build - failed - (unknown failure)')
end
end
end
diff --git a/spec/helpers/import_helper_spec.rb b/spec/helpers/import_helper_spec.rb
index 033155617c6..cb0ea4e26ba 100644
--- a/spec/helpers/import_helper_spec.rb
+++ b/spec/helpers/import_helper_spec.rb
@@ -1,6 +1,16 @@
require 'rails_helper'
describe ImportHelper do
+ describe '#sanitize_project_name' do
+ it 'removes whitespace' do
+ expect(helper.sanitize_project_name('my test repo')).to eq('my-test-repo')
+ end
+
+ it 'removes disallowed characters' do
+ expect(helper.sanitize_project_name('Test&me$over*h_ere')).to eq('Test-me-over-h_ere')
+ end
+ end
+
describe '#import_project_target' do
let(:user) { create(:user) }
diff --git a/spec/javascripts/badges/dummy_badge.js b/spec/javascripts/badges/dummy_badge.js
index 6aaff21c503..f0cdaddbd33 100644
--- a/spec/javascripts/badges/dummy_badge.js
+++ b/spec/javascripts/badges/dummy_badge.js
@@ -1,8 +1,9 @@
+import _ from 'underscore';
import { PROJECT_BADGE } from '~/badges/constants';
import { DUMMY_IMAGE_URL, TEST_HOST } from 'spec/test_constants';
export const createDummyBadge = () => {
- const id = Math.floor(1000 * Math.random());
+ const id = _.uniqueId();
return {
id,
imageUrl: `${TEST_HOST}/badges/${id}/image/url`,
diff --git a/spec/javascripts/flash_spec.js b/spec/javascripts/flash_spec.js
index 7198dbd4cf2..0a8e5a628c0 100644
--- a/spec/javascripts/flash_spec.js
+++ b/spec/javascripts/flash_spec.js
@@ -57,8 +57,11 @@ describe('Flash', () => {
hideFlash(el);
expect(
- el.style.transition,
- ).toBe('opacity 0.3s');
+ el.style['transition-property'],
+ ).toBe('opacity');
+ expect(
+ el.style['transition-duration'],
+ ).toBe('0.3s');
});
it('sets opacity style', () => {
diff --git a/spec/javascripts/helpers/vue_mount_component_helper.js b/spec/javascripts/helpers/vue_mount_component_helper.js
index 1057f0aca3e..6848c95d95d 100644
--- a/spec/javascripts/helpers/vue_mount_component_helper.js
+++ b/spec/javascripts/helpers/vue_mount_component_helper.js
@@ -1,3 +1,5 @@
+import Vue from 'vue';
+
const mountComponent = (Component, props = {}, el = null) =>
new Component({
propsData: props,
@@ -25,4 +27,12 @@ export const mountComponentWithSlots = (Component, { props, slots }) => {
return component.$mount();
};
+/**
+ * Mount a component with the given render method.
+ *
+ * This helps with inserting slots that need to be compiled.
+ */
+export const mountComponentWithRender = (render, el = null) =>
+ mountComponent(Vue.extend({ render }), {}, el);
+
export default mountComponent;
diff --git a/spec/javascripts/ide/stores/modules/commit/actions_spec.js b/spec/javascripts/ide/stores/modules/commit/actions_spec.js
index 24a7d76f30b..06b8b452319 100644
--- a/spec/javascripts/ide/stores/modules/commit/actions_spec.js
+++ b/spec/javascripts/ide/stores/modules/commit/actions_spec.js
@@ -184,7 +184,7 @@ describe('IDE commit module actions', () => {
branch,
})
.then(() => {
- expect(f.lastCommit.message).toBe(data.message);
+ expect(f.lastCommitSha).toBe(data.id);
})
.then(done)
.catch(done.fail);
@@ -266,19 +266,21 @@ describe('IDE commit module actions', () => {
});
describe('success', () => {
+ const COMMIT_RESPONSE = {
+ id: '123456',
+ short_id: '123',
+ message: 'test message',
+ committed_date: 'date',
+ stats: {
+ additions: '1',
+ deletions: '2',
+ },
+ };
+
beforeEach(() => {
spyOn(service, 'commit').and.returnValue(
Promise.resolve({
- data: {
- id: '123456',
- short_id: '123',
- message: 'test message',
- committed_date: 'date',
- stats: {
- additions: '1',
- deletions: '2',
- },
- },
+ data: COMMIT_RESPONSE,
}),
);
});
@@ -352,8 +354,8 @@ describe('IDE commit module actions', () => {
store
.dispatch('commit/commitChanges')
.then(() => {
- expect(store.state.entries[store.state.openFiles[0].path].lastCommit.message).toBe(
- 'test message',
+ expect(store.state.entries[store.state.openFiles[0].path].lastCommitSha).toBe(
+ COMMIT_RESPONSE.id,
);
done();
diff --git a/spec/javascripts/ide/stores/modules/file_templates/actions_spec.js b/spec/javascripts/ide/stores/modules/file_templates/actions_spec.js
new file mode 100644
index 00000000000..f831a9f0a5d
--- /dev/null
+++ b/spec/javascripts/ide/stores/modules/file_templates/actions_spec.js
@@ -0,0 +1,336 @@
+import MockAdapter from 'axios-mock-adapter';
+import axios from '~/lib/utils/axios_utils';
+import createState from '~/ide/stores/modules/file_templates/state';
+import * as actions from '~/ide/stores/modules/file_templates/actions';
+import * as types from '~/ide/stores/modules/file_templates/mutation_types';
+import testAction from 'spec/helpers/vuex_action_helper';
+
+describe('IDE file templates actions', () => {
+ let state;
+ let mock;
+
+ beforeEach(() => {
+ state = createState();
+
+ mock = new MockAdapter(axios);
+ });
+
+ afterEach(() => {
+ mock.restore();
+ });
+
+ describe('requestTemplateTypes', () => {
+ it('commits REQUEST_TEMPLATE_TYPES', done => {
+ testAction(
+ actions.requestTemplateTypes,
+ null,
+ state,
+ [{ type: types.REQUEST_TEMPLATE_TYPES }],
+ [],
+ done,
+ );
+ });
+ });
+
+ describe('receiveTemplateTypesError', () => {
+ it('commits RECEIVE_TEMPLATE_TYPES_ERROR and dispatches setErrorMessage', done => {
+ testAction(
+ actions.receiveTemplateTypesError,
+ null,
+ state,
+ [{ type: types.RECEIVE_TEMPLATE_TYPES_ERROR }],
+ [
+ {
+ type: 'setErrorMessage',
+ payload: {
+ action: jasmine.any(Function),
+ actionText: 'Please try again',
+ text: 'Error loading template types.',
+ },
+ },
+ ],
+ done,
+ );
+ });
+ });
+
+ describe('receiveTemplateTypesSuccess', () => {
+ it('commits RECEIVE_TEMPLATE_TYPES_SUCCESS', done => {
+ testAction(
+ actions.receiveTemplateTypesSuccess,
+ 'test',
+ state,
+ [{ type: types.RECEIVE_TEMPLATE_TYPES_SUCCESS, payload: 'test' }],
+ [],
+ done,
+ );
+ });
+ });
+
+ describe('fetchTemplateTypes', () => {
+ describe('success', () => {
+ beforeEach(() => {
+ mock.onGet(/api\/(.*)\/templates\/licenses/).replyOnce(200, [
+ {
+ name: 'MIT',
+ },
+ ]);
+ });
+
+ it('rejects if selectedTemplateType is empty', done => {
+ const dispatch = jasmine.createSpy('dispatch');
+
+ actions
+ .fetchTemplateTypes({ dispatch, state })
+ .then(done.fail)
+ .catch(() => {
+ expect(dispatch).not.toHaveBeenCalled();
+
+ done();
+ });
+ });
+
+ it('dispatches actions', done => {
+ state.selectedTemplateType = {
+ key: 'licenses',
+ };
+
+ testAction(
+ actions.fetchTemplateTypes,
+ null,
+ state,
+ [],
+ [
+ {
+ type: 'requestTemplateTypes',
+ },
+ {
+ type: 'receiveTemplateTypesSuccess',
+ payload: [
+ {
+ name: 'MIT',
+ },
+ ],
+ },
+ ],
+ done,
+ );
+ });
+ });
+
+ describe('error', () => {
+ beforeEach(() => {
+ mock.onGet(/api\/(.*)\/templates\/licenses/).replyOnce(500);
+ });
+
+ it('dispatches actions', done => {
+ state.selectedTemplateType = {
+ key: 'licenses',
+ };
+
+ testAction(
+ actions.fetchTemplateTypes,
+ null,
+ state,
+ [],
+ [
+ {
+ type: 'requestTemplateTypes',
+ },
+ {
+ type: 'receiveTemplateTypesError',
+ },
+ ],
+ done,
+ );
+ });
+ });
+ });
+
+ describe('setSelectedTemplateType', () => {
+ it('commits SET_SELECTED_TEMPLATE_TYPE', done => {
+ testAction(
+ actions.setSelectedTemplateType,
+ 'test',
+ state,
+ [{ type: types.SET_SELECTED_TEMPLATE_TYPE, payload: 'test' }],
+ [],
+ done,
+ );
+ });
+ });
+
+ describe('receiveTemplateError', () => {
+ it('dispatches setErrorMessage', done => {
+ testAction(
+ actions.receiveTemplateError,
+ 'test',
+ state,
+ [],
+ [
+ {
+ type: 'setErrorMessage',
+ payload: {
+ action: jasmine.any(Function),
+ actionText: 'Please try again',
+ text: 'Error loading template.',
+ actionPayload: 'test',
+ },
+ },
+ ],
+ done,
+ );
+ });
+ });
+
+ describe('fetchTemplate', () => {
+ describe('success', () => {
+ beforeEach(() => {
+ mock.onGet(/api\/(.*)\/templates\/licenses\/mit/).replyOnce(200, {
+ content: 'MIT content',
+ });
+ mock.onGet(/api\/(.*)\/templates\/licenses\/testing/).replyOnce(200, {
+ content: 'testing content',
+ });
+ });
+
+ it('dispatches setFileTemplate if template already has content', done => {
+ const template = {
+ content: 'already has content',
+ };
+
+ testAction(
+ actions.fetchTemplate,
+ template,
+ state,
+ [],
+ [{ type: 'setFileTemplate', payload: template }],
+ done,
+ );
+ });
+
+ it('dispatches success', done => {
+ const template = {
+ key: 'mit',
+ };
+
+ state.selectedTemplateType = {
+ key: 'licenses',
+ };
+
+ testAction(
+ actions.fetchTemplate,
+ template,
+ state,
+ [],
+ [{ type: 'setFileTemplate', payload: { content: 'MIT content' } }],
+ done,
+ );
+ });
+
+ it('dispatches success and uses name key for API call', done => {
+ const template = {
+ name: 'testing',
+ };
+
+ state.selectedTemplateType = {
+ key: 'licenses',
+ };
+
+ testAction(
+ actions.fetchTemplate,
+ template,
+ state,
+ [],
+ [{ type: 'setFileTemplate', payload: { content: 'testing content' } }],
+ done,
+ );
+ });
+ });
+
+ describe('error', () => {
+ beforeEach(() => {
+ mock.onGet(/api\/(.*)\/templates\/licenses\/mit/).replyOnce(500);
+ });
+
+ it('dispatches error', done => {
+ const template = {
+ name: 'testing',
+ };
+
+ state.selectedTemplateType = {
+ key: 'licenses',
+ };
+
+ testAction(
+ actions.fetchTemplate,
+ template,
+ state,
+ [],
+ [{ type: 'receiveTemplateError', payload: template }],
+ done,
+ );
+ });
+ });
+ });
+
+ describe('setFileTemplate', () => {
+ it('dispatches changeFileContent', () => {
+ const dispatch = jasmine.createSpy('dispatch');
+ const commit = jasmine.createSpy('commit');
+ const rootGetters = {
+ activeFile: { path: 'test' },
+ };
+
+ actions.setFileTemplate({ dispatch, commit, rootGetters }, { content: 'content' });
+
+ expect(dispatch).toHaveBeenCalledWith(
+ 'changeFileContent',
+ { path: 'test', content: 'content' },
+ { root: true },
+ );
+ });
+
+ it('commits SET_UPDATE_SUCCESS', () => {
+ const dispatch = jasmine.createSpy('dispatch');
+ const commit = jasmine.createSpy('commit');
+ const rootGetters = {
+ activeFile: { path: 'test' },
+ };
+
+ actions.setFileTemplate({ dispatch, commit, rootGetters }, { content: 'content' });
+
+ expect(commit).toHaveBeenCalledWith('SET_UPDATE_SUCCESS', true);
+ });
+ });
+
+ describe('undoFileTemplate', () => {
+ it('dispatches changeFileContent', () => {
+ const dispatch = jasmine.createSpy('dispatch');
+ const commit = jasmine.createSpy('commit');
+ const rootGetters = {
+ activeFile: { path: 'test', raw: 'raw content' },
+ };
+
+ actions.undoFileTemplate({ dispatch, commit, rootGetters });
+
+ expect(dispatch).toHaveBeenCalledWith(
+ 'changeFileContent',
+ { path: 'test', content: 'raw content' },
+ { root: true },
+ );
+ });
+
+ it('commits SET_UPDATE_SUCCESS', () => {
+ const dispatch = jasmine.createSpy('dispatch');
+ const commit = jasmine.createSpy('commit');
+ const rootGetters = {
+ activeFile: { path: 'test', raw: 'raw content' },
+ };
+
+ actions.undoFileTemplate({ dispatch, commit, rootGetters });
+
+ expect(commit).toHaveBeenCalledWith('SET_UPDATE_SUCCESS', false);
+ });
+ });
+});
diff --git a/spec/javascripts/ide/stores/modules/file_templates/getters_spec.js b/spec/javascripts/ide/stores/modules/file_templates/getters_spec.js
new file mode 100644
index 00000000000..e337c3f331b
--- /dev/null
+++ b/spec/javascripts/ide/stores/modules/file_templates/getters_spec.js
@@ -0,0 +1,30 @@
+import * as getters from '~/ide/stores/modules/file_templates/getters';
+
+describe('IDE file templates getters', () => {
+ describe('templateTypes', () => {
+ it('returns list of template types', () => {
+ expect(getters.templateTypes().length).toBe(4);
+ });
+ });
+
+ describe('showFileTemplatesBar', () => {
+ it('finds template type by name', () => {
+ expect(
+ getters.showFileTemplatesBar(null, {
+ templateTypes: getters.templateTypes(),
+ })('LICENSE'),
+ ).toEqual({
+ name: 'LICENSE',
+ key: 'licenses',
+ });
+ });
+
+ it('returns undefined if not found', () => {
+ expect(
+ getters.showFileTemplatesBar(null, {
+ templateTypes: getters.templateTypes(),
+ })('test'),
+ ).toBe(undefined);
+ });
+ });
+});
diff --git a/spec/javascripts/ide/stores/modules/file_templates/mutations_spec.js b/spec/javascripts/ide/stores/modules/file_templates/mutations_spec.js
new file mode 100644
index 00000000000..a51527d699f
--- /dev/null
+++ b/spec/javascripts/ide/stores/modules/file_templates/mutations_spec.js
@@ -0,0 +1,61 @@
+import createState from '~/ide/stores/modules/file_templates/state';
+import * as types from '~/ide/stores/modules/file_templates/mutation_types';
+import mutations from '~/ide/stores/modules/file_templates/mutations';
+
+describe('IDE file templates mutations', () => {
+ let state;
+
+ beforeEach(() => {
+ state = createState();
+ });
+
+ describe(types.REQUEST_TEMPLATE_TYPES, () => {
+ it('sets isLoading', () => {
+ mutations[types.REQUEST_TEMPLATE_TYPES](state);
+
+ expect(state.isLoading).toBe(true);
+ });
+ });
+
+ describe(types.RECEIVE_TEMPLATE_TYPES_ERROR, () => {
+ it('sets isLoading', () => {
+ state.isLoading = true;
+
+ mutations[types.RECEIVE_TEMPLATE_TYPES_ERROR](state);
+
+ expect(state.isLoading).toBe(false);
+ });
+ });
+
+ describe(types.RECEIVE_TEMPLATE_TYPES_SUCCESS, () => {
+ it('sets isLoading to false', () => {
+ state.isLoading = true;
+
+ mutations[types.RECEIVE_TEMPLATE_TYPES_SUCCESS](state, []);
+
+ expect(state.isLoading).toBe(false);
+ });
+
+ it('sets templates', () => {
+ mutations[types.RECEIVE_TEMPLATE_TYPES_SUCCESS](state, ['test']);
+
+ expect(state.templates).toEqual(['test']);
+ });
+ });
+
+ describe(types.SET_SELECTED_TEMPLATE_TYPE, () => {
+ it('sets selectedTemplateType', () => {
+ mutations[types.SET_SELECTED_TEMPLATE_TYPE](state, 'type');
+
+ expect(state.selectedTemplateType).toBe('type');
+ });
+ });
+
+ describe(types.SET_UPDATE_SUCCESS, () => {
+ it('sets updateSuccess', () => {
+ mutations[types.SET_UPDATE_SUCCESS](state, true);
+
+ expect(state.updateSuccess).toBe(true);
+ });
+ });
+});
diff --git a/spec/javascripts/jobs/artifacts_block_spec.js b/spec/javascripts/jobs/components/artifacts_block_spec.js
index c544c6f3e89..a06d287b3fa 100644
--- a/spec/javascripts/jobs/artifacts_block_spec.js
+++ b/spec/javascripts/jobs/components/artifacts_block_spec.js
@@ -1,7 +1,7 @@
import Vue from 'vue';
import { getTimeago } from '~/lib/utils/datetime_utility';
import component from '~/jobs/components/artifacts_block.vue';
-import mountComponent from '../helpers/vue_mount_component_helper';
+import mountComponent from '../../helpers/vue_mount_component_helper';
describe('Artifacts block', () => {
const Component = Vue.extend(component);
diff --git a/spec/javascripts/jobs/commit_block_spec.js b/spec/javascripts/jobs/components/commit_block_spec.js
index f755a5042b5..e21fa9c2874 100644
--- a/spec/javascripts/jobs/commit_block_spec.js
+++ b/spec/javascripts/jobs/components/commit_block_spec.js
@@ -1,6 +1,6 @@
import Vue from 'vue';
import component from '~/jobs/components/commit_block.vue';
-import mountComponent from '../helpers/vue_mount_component_helper';
+import mountComponent from '../../helpers/vue_mount_component_helper';
describe('Commit block', () => {
const Component = Vue.extend(component);
diff --git a/spec/javascripts/jobs/empty_state_spec.js b/spec/javascripts/jobs/components/empty_state_spec.js
index f8feb069fe0..dcc2b3d8a20 100644
--- a/spec/javascripts/jobs/empty_state_spec.js
+++ b/spec/javascripts/jobs/components/empty_state_spec.js
@@ -1,6 +1,6 @@
import Vue from 'vue';
import component from '~/jobs/components/empty_state.vue';
-import mountComponent from '../helpers/vue_mount_component_helper';
+import mountComponent from '../../helpers/vue_mount_component_helper';
describe('Empty State', () => {
const Component = Vue.extend(component);
diff --git a/spec/javascripts/jobs/components/environments_block_spec.js b/spec/javascripts/jobs/components/environments_block_spec.js
new file mode 100644
index 00000000000..015c26be9fc
--- /dev/null
+++ b/spec/javascripts/jobs/components/environments_block_spec.js
@@ -0,0 +1,137 @@
+import Vue from 'vue';
+import component from '~/jobs/components/environments_block.vue';
+import mountComponent from '../../helpers/vue_mount_component_helper';
+
+describe('Environments block', () => {
+ const Component = Vue.extend(component);
+ let vm;
+ const icon = {
+ group: 'success',
+ icon: 'status_success',
+ label: 'passed',
+ text: 'passed',
+ tooltip: 'passed',
+ };
+ const deployment = {
+ path: 'deployment',
+ name: 'deployment name',
+ };
+ const environment = {
+ path: '/environment',
+ name: 'environment',
+ };
+
+ afterEach(() => {
+ vm.$destroy();
+ });
+
+ describe('with latest deployment', () => {
+ it('renders info for most recent deployment', () => {
+ vm = mountComponent(Component, {
+ deploymentStatus: {
+ status: 'latest',
+ icon,
+ deployment,
+ environment,
+ },
+ });
+
+ expect(vm.$el.textContent.trim()).toEqual(
+ 'This job is the most recent deployment to environment.',
+ );
+ });
+ });
+
+ describe('with out of date deployment', () => {
+ describe('with last deployment', () => {
+ it('renders info for out date and most recent', () => {
+ vm = mountComponent(Component, {
+ deploymentStatus: {
+ status: 'out_of_date',
+ icon,
+ deployment,
+ environment: Object.assign({}, environment, {
+ last_deployment: { name: 'deployment', path: 'last_deployment' },
+ }),
+ },
+ });
+
+ expect(vm.$el.textContent.trim()).toEqual(
+ 'This job is an out-of-date deployment to environment. View the most recent deployment deployment.',
+ );
+ });
+ });
+
+ describe('without last deployment', () => {
+ it('renders info about out of date deployment', () => {
+ vm = mountComponent(Component, {
+ deploymentStatus: {
+ status: 'out_of_date',
+ icon,
+ deployment: null,
+ environment,
+ },
+ });
+
+ expect(vm.$el.textContent.trim()).toEqual(
+ 'This job is an out-of-date deployment to environment.',
+ );
+ });
+ });
+ });
+
+ describe('with failed deployment', () => {
+ it('renders info about failed deployment', () => {
+ vm = mountComponent(Component, {
+ deploymentStatus: {
+ status: 'failed',
+ icon,
+ deployment: null,
+ environment,
+ },
+ });
+
+ expect(vm.$el.textContent.trim()).toEqual(
+ 'The deployment of this job to environment did not succeed.',
+ );
+ });
+ });
+
+ describe('creating deployment', () => {
+ describe('with last deployment', () => {
+ it('renders info about creating deployment and overriding lastest deployment', () => {
+ vm = mountComponent(Component, {
+ deploymentStatus: {
+ status: 'creating',
+ icon,
+ deployment,
+ environment: Object.assign({}, environment, {
+ last_deployment: { name: 'deployment', path: 'last_deployment' },
+ }),
+ },
+ });
+
+ expect(vm.$el.textContent.trim()).toEqual(
+ 'This job is creating a deployment to environment and will overwrite the last deployment.',
+ );
+ });
+ });
+
+ describe('without last deployment', () => {
+ it('renders info about failed deployment', () => {
+ vm = mountComponent(Component, {
+ deploymentStatus: {
+ status: 'creating',
+ icon,
+ deployment: null,
+ environment,
+ },
+ });
+
+ expect(vm.$el.textContent.trim()).toEqual(
+ 'This job is creating a deployment to environment.',
+ );
+ });
+ });
+ });
+});
diff --git a/spec/javascripts/jobs/erased_block_spec.js b/spec/javascripts/jobs/components/erased_block_spec.js
index 7cf32e984a2..a4ae0c7c81e 100644
--- a/spec/javascripts/jobs/erased_block_spec.js
+++ b/spec/javascripts/jobs/components/erased_block_spec.js
@@ -1,7 +1,7 @@
import Vue from 'vue';
import { getTimeago } from '~/lib/utils/datetime_utility';
import component from '~/jobs/components/erased_block.vue';
-import mountComponent from '../helpers/vue_mount_component_helper';
+import mountComponent from '../../helpers/vue_mount_component_helper';
describe('Erased block', () => {
const Component = Vue.extend(component);
diff --git a/spec/javascripts/jobs/header_spec.js b/spec/javascripts/jobs/components/header_spec.js
index e21e2c6d6e3..e21e2c6d6e3 100644
--- a/spec/javascripts/jobs/header_spec.js
+++ b/spec/javascripts/jobs/components/header_spec.js
diff --git a/spec/javascripts/jobs/job_details_mediator_spec.js b/spec/javascripts/jobs/components/job_details_mediator_spec.js
index ca5c9cf87e4..3e2fb7bfbbb 100644
--- a/spec/javascripts/jobs/job_details_mediator_spec.js
+++ b/spec/javascripts/jobs/components/job_details_mediator_spec.js
@@ -1,7 +1,7 @@
import MockAdapter from 'axios-mock-adapter';
import axios from '~/lib/utils/axios_utils';
import JobMediator from '~/jobs/job_details_mediator';
-import job from './mock_data';
+import job from '../mock_data';
describe('JobMediator', () => {
let mediator;
diff --git a/spec/javascripts/jobs/job_log_spec.js b/spec/javascripts/jobs/components/job_log_spec.js
index 406f1c4ccc5..6a5b375a26c 100644
--- a/spec/javascripts/jobs/job_log_spec.js
+++ b/spec/javascripts/jobs/components/job_log_spec.js
@@ -1,6 +1,6 @@
import Vue from 'vue';
import component from '~/jobs/components/job_log.vue';
-import mountComponent from '../helpers/vue_mount_component_helper';
+import mountComponent from '../../helpers/vue_mount_component_helper';
describe('Job Log', () => {
const Component = Vue.extend(component);
diff --git a/spec/javascripts/jobs/job_store_spec.js b/spec/javascripts/jobs/components/job_store_spec.js
index d00faf29d1e..0dad5111b32 100644
--- a/spec/javascripts/jobs/job_store_spec.js
+++ b/spec/javascripts/jobs/components/job_store_spec.js
@@ -1,5 +1,5 @@
import JobStore from '~/jobs/stores/job_store';
-import job from './mock_data';
+import job from '../mock_data';
describe('Job Store', () => {
let store;
diff --git a/spec/javascripts/jobs/jobs_container_spec.js b/spec/javascripts/jobs/components/jobs_container_spec.js
index bf52e65cbc8..f3f8ff0d031 100644
--- a/spec/javascripts/jobs/jobs_container_spec.js
+++ b/spec/javascripts/jobs/components/jobs_container_spec.js
@@ -1,6 +1,6 @@
import Vue from 'vue';
import component from '~/jobs/components/jobs_container.vue';
-import mountComponent from '../helpers/vue_mount_component_helper';
+import mountComponent from '../../helpers/vue_mount_component_helper';
describe('Artifacts block', () => {
const Component = Vue.extend(component);
diff --git a/spec/javascripts/jobs/sidebar_detail_row_spec.js b/spec/javascripts/jobs/components/sidebar_detail_row_spec.js
index e6bfb0c4adc..e6bfb0c4adc 100644
--- a/spec/javascripts/jobs/sidebar_detail_row_spec.js
+++ b/spec/javascripts/jobs/components/sidebar_detail_row_spec.js
diff --git a/spec/javascripts/jobs/sidebar_details_block_spec.js b/spec/javascripts/jobs/components/sidebar_details_block_spec.js
index 21ef5650b80..ba19534dac2 100644
--- a/spec/javascripts/jobs/sidebar_details_block_spec.js
+++ b/spec/javascripts/jobs/components/sidebar_details_block_spec.js
@@ -1,7 +1,7 @@
import Vue from 'vue';
import sidebarDetailsBlock from '~/jobs/components/sidebar_details_block.vue';
-import job from './mock_data';
-import mountComponent from '../helpers/vue_mount_component_helper';
+import job from '../mock_data';
+import mountComponent from '../../helpers/vue_mount_component_helper';
describe('Sidebar details block', () => {
let SidebarComponent;
diff --git a/spec/javascripts/jobs/stages_dropdown_spec.js b/spec/javascripts/jobs/components/stages_dropdown_spec.js
index d3a5d48f56c..402289345aa 100644
--- a/spec/javascripts/jobs/stages_dropdown_spec.js
+++ b/spec/javascripts/jobs/components/stages_dropdown_spec.js
@@ -1,6 +1,6 @@
import Vue from 'vue';
import component from '~/jobs/components/stages_dropdown.vue';
-import mountComponent from '../helpers/vue_mount_component_helper';
+import mountComponent from '../../helpers/vue_mount_component_helper';
describe('Artifacts block', () => {
const Component = Vue.extend(component);
diff --git a/spec/javascripts/jobs/stuck_block_spec.js b/spec/javascripts/jobs/components/stuck_block_spec.js
index 4e2108dfdfb..c320793b2be 100644
--- a/spec/javascripts/jobs/stuck_block_spec.js
+++ b/spec/javascripts/jobs/components/stuck_block_spec.js
@@ -1,6 +1,6 @@
import Vue from 'vue';
import component from '~/jobs/components/stuck_block.vue';
-import mountComponent from '../helpers/vue_mount_component_helper';
+import mountComponent from '../../helpers/vue_mount_component_helper';
describe('Stuck Block Job component', () => {
const Component = Vue.extend(component);
diff --git a/spec/javascripts/jobs/trigger_value_spec.js b/spec/javascripts/jobs/components/trigger_value_spec.js
index acf91510ed2..3d41a3cfac1 100644
--- a/spec/javascripts/jobs/trigger_value_spec.js
+++ b/spec/javascripts/jobs/components/trigger_value_spec.js
@@ -1,6 +1,6 @@
import Vue from 'vue';
import component from '~/jobs/components/trigger_block.vue';
-import mountComponent from '../helpers/vue_mount_component_helper';
+import mountComponent from '../../helpers/vue_mount_component_helper';
describe('Trigger block', () => {
const Component = Vue.extend(component);
diff --git a/spec/javascripts/performance_bar/services/performance_bar_service_spec.js b/spec/javascripts/performance_bar/services/performance_bar_service_spec.js
new file mode 100644
index 00000000000..bc6947dbe81
--- /dev/null
+++ b/spec/javascripts/performance_bar/services/performance_bar_service_spec.js
@@ -0,0 +1,63 @@
+import PerformanceBarService from '~/performance_bar/services/performance_bar_service';
+
+describe('PerformanceBarService', () => {
+ describe('callbackParams', () => {
+ describe('fireCallback', () => {
+ function fireCallback(response, peekUrl) {
+ return PerformanceBarService.callbackParams(response, peekUrl)[0];
+ }
+
+ it('returns false when the request URL is the peek URL', () => {
+ expect(fireCallback({ headers: { 'x-request-id': '123' }, url: '/peek' }, '/peek'))
+ .toBeFalsy();
+ });
+
+ it('returns false when there is no request ID', () => {
+ expect(fireCallback({ headers: {}, url: '/request' }, '/peek'))
+ .toBeFalsy();
+ });
+
+ it('returns false when the request is an API request', () => {
+ expect(fireCallback({ headers: { 'x-request-id': '123' }, url: '/api/' }, '/peek'))
+ .toBeFalsy();
+ });
+
+ it('returns false when the response is from the cache', () => {
+ expect(fireCallback({ headers: { 'x-request-id': '123', 'x-gitlab-from-cache': 'true' }, url: '/request' }, '/peek'))
+ .toBeFalsy();
+ });
+
+ it('returns true when all conditions are met', () => {
+ expect(fireCallback({ headers: { 'x-request-id': '123' }, url: '/request' }, '/peek'))
+ .toBeTruthy();
+ });
+ });
+
+ describe('requestId', () => {
+ function requestId(response, peekUrl) {
+ return PerformanceBarService.callbackParams(response, peekUrl)[1];
+ }
+
+ it('gets the request ID from the headers', () => {
+ expect(requestId({ headers: { 'x-request-id': '123' } }, '/peek'))
+ .toEqual('123');
+ });
+ });
+
+ describe('requestUrl', () => {
+ function requestUrl(response, peekUrl) {
+ return PerformanceBarService.callbackParams(response, peekUrl)[2];
+ }
+
+ it('gets the request URL from the response object', () => {
+ expect(requestUrl({ headers: {}, url: '/request' }, '/peek'))
+ .toEqual('/request');
+ });
+
+ it('gets the request URL from response.config if present', () => {
+ expect(requestUrl({ headers: {}, config: { url: '/config-url' }, url: '/request' }, '/peek'))
+ .toEqual('/config-url');
+ });
+ });
+ });
+});
diff --git a/spec/javascripts/pipelines/graph/dropdown_job_component_spec.js b/spec/javascripts/pipelines/graph/dropdown_job_component_spec.js
index ff584396d61..2b47ca236b2 100644
--- a/spec/javascripts/pipelines/graph/dropdown_job_component_spec.js
+++ b/spec/javascripts/pipelines/graph/dropdown_job_component_spec.js
@@ -82,12 +82,4 @@ describe('dropdown job component', () => {
it('renders dropdown with jobs', () => {
expect(vm.$el.querySelectorAll('.scrollable-menu>ul>li').length).toEqual(mock.jobs.length);
});
-
- it('escapes tooltip title', () => {
- expect(
- vm.$el.querySelector('.js-pipeline-graph-job-link').getAttribute('data-original-title'),
- ).toEqual(
- '&lt;img src=x onerror=alert(document.domain)&gt; - passed',
- );
- });
});
diff --git a/spec/javascripts/pipelines/graph/job_component_spec.js b/spec/javascripts/pipelines/graph/job_component_spec.js
index 215ce1e81b5..0ae448f2ea8 100644
--- a/spec/javascripts/pipelines/graph/job_component_spec.js
+++ b/spec/javascripts/pipelines/graph/job_component_spec.js
@@ -161,24 +161,4 @@ describe('pipeline graph job component', () => {
expect(component.$el.querySelector(tooltipBoundary)).toBeNull();
});
});
-
- describe('tooltipText', () => {
- it('escapes job name', () => {
- component = mountComponent(JobComponent, {
- job: {
- id: 4259,
- name: '<img src=x onerror=alert(document.domain)>',
- status: {
- icon: 'status_success',
- label: 'success',
- tooltip: 'failed',
- },
- },
- });
-
- expect(
- component.$el.querySelector('.js-job-component-tooltip').getAttribute('data-original-title'),
- ).toEqual('&lt;img src=x onerror=alert(document.domain)&gt; - failed');
- });
- });
});
diff --git a/spec/javascripts/vue_mr_widget/components/mr_widget_header_spec.js b/spec/javascripts/vue_mr_widget/components/mr_widget_header_spec.js
index 8ac2f26979b..0e42537faed 100644
--- a/spec/javascripts/vue_mr_widget/components/mr_widget_header_spec.js
+++ b/spec/javascripts/vue_mr_widget/components/mr_widget_header_spec.js
@@ -45,7 +45,7 @@ describe('MRWidgetHeader', () => {
});
});
- describe('commitsText', () => {
+ describe('commitsBehindText', () => {
it('returns singular when there is one commit', () => {
vm = mountComponent(Component, {
mr: {
@@ -53,11 +53,12 @@ describe('MRWidgetHeader', () => {
sourceBranch: 'mr-widget-refactor',
sourceBranchLink: '<a href="/foo/bar/mr-widget-refactor">Link</a>',
targetBranch: 'master',
+ targetBranchPath: '/foo/bar/master',
statusPath: 'abc',
},
});
- expect(vm.commitsText).toEqual('1 commit behind');
+ expect(vm.commitsBehindText).toEqual('The source branch is <a href="/foo/bar/master">1 commit behind</a> the target branch');
});
it('returns plural when there is more than one commit', () => {
@@ -67,11 +68,12 @@ describe('MRWidgetHeader', () => {
sourceBranch: 'mr-widget-refactor',
sourceBranchLink: '<a href="/foo/bar/mr-widget-refactor">Link</a>',
targetBranch: 'master',
+ targetBranchPath: '/foo/bar/master',
statusPath: 'abc',
},
});
- expect(vm.commitsText).toEqual('2 commits behind');
+ expect(vm.commitsBehindText).toEqual('The source branch is <a href="/foo/bar/master">2 commits behind</a> the target branch');
});
});
});
@@ -280,9 +282,9 @@ describe('MRWidgetHeader', () => {
});
it('renders diverged commits info', () => {
- expect(vm.$el.querySelector('.diverged-commits-count').textContent).toMatch(
- /(mr-widget-refactor[\s\S]+?is 12 commits behind[\s\S]+?master)/,
- );
+ expect(vm.$el.querySelector('.diverged-commits-count').textContent).toEqual('The source branch is 12 commits behind the target branch');
+ expect(vm.$el.querySelector('.diverged-commits-count a').textContent).toEqual('12 commits behind');
+ expect(vm.$el.querySelector('.diverged-commits-count a')).toHaveAttr('href', vm.mr.targetBranchPath);
});
});
});
diff --git a/spec/javascripts/vue_shared/components/stacked_progress_bar_spec.js b/spec/javascripts/vue_shared/components/stacked_progress_bar_spec.js
index 076d940961d..f1fe2e996fc 100644
--- a/spec/javascripts/vue_shared/components/stacked_progress_bar_spec.js
+++ b/spec/javascripts/vue_shared/components/stacked_progress_bar_spec.js
@@ -44,7 +44,11 @@ describe('StackedProgressBarComponent', () => {
});
it('returns percentage with decimal place from provided count based on `totalCount`', () => {
- expect(vm.getPercent(10)).toBe(0.2);
+ expect(vm.getPercent(67)).toBe(1.3);
+ });
+
+ it('returns percentage as `< 1` from provided count based on `totalCount` when evaluated value is less than 1', () => {
+ expect(vm.getPercent(10)).toBe('< 1');
});
});
diff --git a/spec/javascripts/vue_shared/components/tooltip_on_truncate_spec.js b/spec/javascripts/vue_shared/components/tooltip_on_truncate_spec.js
new file mode 100644
index 00000000000..8465757deb6
--- /dev/null
+++ b/spec/javascripts/vue_shared/components/tooltip_on_truncate_spec.js
@@ -0,0 +1,162 @@
+import { mountComponentWithRender } from 'spec/helpers/vue_mount_component_helper';
+import TooltipOnTruncate from '~/vue_shared/components/tooltip_on_truncate.vue';
+
+const TEST_TITLE = 'lorem-ipsum-dolar-sit-amit-consectur-adipiscing-elit-sed-do';
+const CLASS_SHOW_TOOLTIP = 'js-show-tooltip';
+const STYLE_TRUNCATED = {
+ display: 'inline-block',
+ 'max-width': '20px',
+};
+const STYLE_NORMAL = {
+ display: 'inline-block',
+ 'max-width': '1000px',
+};
+
+function mountTooltipOnTruncate(options, createChildren) {
+ return mountComponentWithRender(h => h(TooltipOnTruncate, options, createChildren(h)), '#app');
+}
+
+describe('TooltipOnTruncate component', () => {
+ let vm;
+
+ beforeEach(() => {
+ const el = document.createElement('div');
+ el.id = 'app';
+ document.body.appendChild(el);
+ });
+
+ afterEach(() => {
+ vm.$destroy();
+ });
+
+ describe('with default target', () => {
+ it('renders tooltip if truncated', done => {
+ const options = {
+ style: STYLE_TRUNCATED,
+ props: {
+ title: TEST_TITLE,
+ },
+ };
+
+ vm = mountTooltipOnTruncate(options, () => [TEST_TITLE]);
+
+ vm.$nextTick()
+ .then(() => {
+ expect(vm.$el).toHaveClass(CLASS_SHOW_TOOLTIP);
+ expect(vm.$el).toHaveData('original-title', TEST_TITLE);
+ expect(vm.$el).toHaveData('placement', 'top');
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+
+ it('does not render tooltip if normal', done => {
+ const options = {
+ style: STYLE_NORMAL,
+ props: {
+ title: TEST_TITLE,
+ },
+ };
+
+ vm = mountTooltipOnTruncate(options, () => [TEST_TITLE]);
+
+ vm.$nextTick()
+ .then(() => {
+ expect(vm.$el).not.toHaveClass(CLASS_SHOW_TOOLTIP);
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+ });
+
+ describe('with child target', () => {
+ it('renders tooltip if truncated', done => {
+ const options = {
+ style: STYLE_NORMAL,
+ props: {
+ title: TEST_TITLE,
+ truncateTarget: 'child',
+ },
+ };
+
+ vm = mountTooltipOnTruncate(options, (h) => [
+ h('a', { style: STYLE_TRUNCATED }, TEST_TITLE),
+ ]);
+
+ vm.$nextTick()
+ .then(() => {
+ expect(vm.$el).toHaveClass(CLASS_SHOW_TOOLTIP);
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+
+ it('does not render tooltip if normal', done => {
+ const options = {
+ props: {
+ title: TEST_TITLE,
+ truncateTarget: 'child',
+ },
+ };
+
+ vm = mountTooltipOnTruncate(options, (h) => [
+ h('a', { style: STYLE_NORMAL }, TEST_TITLE),
+ ]);
+
+ vm.$nextTick()
+ .then(() => {
+ expect(vm.$el).not.toHaveClass(CLASS_SHOW_TOOLTIP);
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+ });
+
+ describe('with fn target', () => {
+ it('renders tooltip if truncated', done => {
+ const options = {
+ style: STYLE_NORMAL,
+ props: {
+ title: TEST_TITLE,
+ truncateTarget: (el) => el.childNodes[1],
+ },
+ };
+
+ vm = mountTooltipOnTruncate(options, (h) => [
+ h('a', { style: STYLE_NORMAL }, TEST_TITLE),
+ h('span', { style: STYLE_TRUNCATED }, TEST_TITLE),
+ ]);
+
+ vm.$nextTick()
+ .then(() => {
+ expect(vm.$el).toHaveClass(CLASS_SHOW_TOOLTIP);
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+ });
+
+ describe('placement', () => {
+ it('sets data-placement when tooltip is rendered', done => {
+ const options = {
+ props: {
+ title: TEST_TITLE,
+ truncateTarget: 'child',
+ placement: 'bottom',
+ },
+ };
+
+ vm = mountTooltipOnTruncate(options, (h) => [
+ h('a', { style: STYLE_TRUNCATED }, TEST_TITLE),
+ ]);
+
+ vm.$nextTick()
+ .then(() => {
+ expect(vm.$el).toHaveClass(CLASS_SHOW_TOOLTIP);
+ expect(vm.$el).toHaveData('placement', options.props.placement);
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+ });
+});
diff --git a/spec/lib/feature_spec.rb b/spec/lib/feature_spec.rb
index f313e675654..8bb5a843484 100644
--- a/spec/lib/feature_spec.rb
+++ b/spec/lib/feature_spec.rb
@@ -1,6 +1,13 @@
require 'spec_helper'
describe Feature do
+ before do
+ # We mock all calls to .enabled? to return true in order to force all
+ # specs to run the feature flag gated behavior, but here we need a clean
+ # behavior from the class
+ allow(described_class).to receive(:enabled?).and_call_original
+ end
+
describe '.get' do
let(:feature) { double(:feature) }
let(:key) { 'my_feature' }
@@ -106,4 +113,63 @@ describe Feature do
it_behaves_like 'a memoized Flipper instance'
end
end
+
+ describe '.enabled?' do
+ it 'returns false for undefined feature' do
+ expect(described_class.enabled?(:some_random_feature_flag)).to be_falsey
+ end
+
+ it 'returns false for existing disabled feature in the database' do
+ described_class.disable(:disabled_feature_flag)
+
+ expect(described_class.enabled?(:disabled_feature_flag)).to be_falsey
+ end
+
+ it 'returns true for existing enabled feature in the database' do
+ described_class.enable(:enabled_feature_flag)
+
+ expect(described_class.enabled?(:enabled_feature_flag)).to be_truthy
+ end
+
+ context 'with an individual actor' do
+ CustomActor = Struct.new(:flipper_id)
+
+ let(:actor) { CustomActor.new(flipper_id: 'CustomActor:5') }
+ let(:another_actor) { CustomActor.new(flipper_id: 'CustomActor:10') }
+
+ before do
+ described_class.enable(:enabled_feature_flag, actor)
+ end
+
+ it 'returns true when same actor is informed' do
+ expect(described_class.enabled?(:enabled_feature_flag, actor)).to be_truthy
+ end
+
+ it 'returns false when different actor is informed' do
+ expect(described_class.enabled?(:enabled_feature_flag, another_actor)).to be_falsey
+ end
+
+ it 'returns false when no actor is informed' do
+ expect(described_class.enabled?(:enabled_feature_flag)).to be_falsey
+ end
+ end
+ end
+
+ describe '.disable?' do
+ it 'returns true for undefined feature' do
+ expect(described_class.disabled?(:some_random_feature_flag)).to be_truthy
+ end
+
+ it 'returns true for existing disabled feature in the database' do
+ described_class.disable(:disabled_feature_flag)
+
+ expect(described_class.disabled?(:disabled_feature_flag)).to be_truthy
+ end
+
+ it 'returns false for existing enabled feature in the database' do
+ described_class.enable(:enabled_feature_flag)
+
+ expect(described_class.disabled?(:enabled_feature_flag)).to be_falsey
+ end
+ end
end
diff --git a/spec/lib/gitlab/auth/ldap/access_spec.rb b/spec/lib/gitlab/auth/ldap/access_spec.rb
index eff21985108..7800c543cdb 100644
--- a/spec/lib/gitlab/auth/ldap/access_spec.rb
+++ b/spec/lib/gitlab/auth/ldap/access_spec.rb
@@ -3,51 +3,61 @@ require 'spec_helper'
describe Gitlab::Auth::LDAP::Access do
include LdapHelpers
- let(:access) { described_class.new user }
let(:user) { create(:omniauth_user) }
+ subject(:access) { described_class.new(user) }
+
describe '.allowed?' do
- it 'updates the users `last_credential_check_at' do
+ before do
allow(access).to receive(:update_user)
- expect(access).to receive(:allowed?) { true }
- expect(described_class).to receive(:open).and_yield(access)
+ allow(access).to receive(:allowed?).and_return(true)
+ allow(described_class).to receive(:open).and_yield(access)
+ end
+ it "updates the user's `last_credential_check_at`" do
expect { described_class.allowed?(user) }
.to change { user.last_credential_check_at }
end
- end
- describe '#find_ldap_user' do
- it 'finds a user by dn first' do
- expect(Gitlab::Auth::LDAP::Person).to receive(:find_by_dn).and_return(:ldap_user)
+ it "does not update user's `last_credential_check_at` when in a read-only GitLab instance" do
+ allow(Gitlab::Database).to receive(:read_only?).and_return(true)
- access.find_ldap_user
+ expect { described_class.allowed?(user) }
+ .not_to change { user.last_credential_check_at }
end
end
describe '#allowed?' do
- subject { access.allowed? }
-
context 'when the user cannot be found' do
before do
- allow(Gitlab::Auth::LDAP::Person).to receive(:find_by_dn).and_return(nil)
- allow(Gitlab::Auth::LDAP::Person).to receive(:find_by_email).and_return(nil)
+ stub_ldap_person_find_by_dn(nil)
+ stub_ldap_person_find_by_email(user.email, nil)
end
- it { is_expected.to be_falsey }
+ it 'returns false' do
+ expect(access.allowed?).to be_falsey
+ end
it 'blocks user in GitLab' do
- expect(access).to receive(:block_user).with(user, 'does not exist anymore')
+ access.allowed?
+
+ expect(user).to be_blocked
+ expect(user).to be_ldap_blocked
+ end
+
+ it 'logs the reason' do
+ expect(Gitlab::AppLogger).to receive(:info).with(
+ "LDAP account \"123456\" does not exist anymore, " \
+ "blocking Gitlab user \"#{user.name}\" (#{user.email})"
+ )
access.allowed?
end
end
context 'when the user is found' do
- let(:ldap_user) { Gitlab::Auth::LDAP::Person.new(Net::LDAP::Entry.new, 'ldapmain') }
-
before do
- allow(Gitlab::Auth::LDAP::Person).to receive(:find_by_dn).and_return(ldap_user)
+ stub_ldap_person_find_by_dn(Net::LDAP::Entry.new)
end
context 'and the user is disabled via active directory' do
@@ -55,10 +65,22 @@ describe Gitlab::Auth::LDAP::Access do
allow(Gitlab::Auth::LDAP::Person).to receive(:disabled_via_active_directory?).and_return(true)
end
- it { is_expected.to be_falsey }
+ it 'returns false' do
+ expect(access.allowed?).to be_falsey
+ end
it 'blocks user in GitLab' do
- expect(access).to receive(:block_user).with(user, 'is disabled in Active Directory')
+ access.allowed?
+
+ expect(user).to be_blocked
+ expect(user).to be_ldap_blocked
+ end
+
+ it 'logs the reason' do
+ expect(Gitlab::AppLogger).to receive(:info).with(
+ "LDAP account \"123456\" is disabled in Active Directory, " \
+ "blocking Gitlab user \"#{user.name}\" (#{user.email})"
+ )
access.allowed?
end
@@ -92,7 +114,17 @@ describe Gitlab::Auth::LDAP::Access do
end
it 'unblocks user in GitLab' do
- expect(access).to receive(:unblock_user).with(user, 'is not disabled anymore')
+ access.allowed?
+
+ expect(user).not_to be_blocked
+ expect(user).not_to be_ldap_blocked
+ end
+
+ it 'logs the reason' do
+ expect(Gitlab::AppLogger).to receive(:info).with(
+ "LDAP account \"123456\" is not disabled anymore, " \
+ "unblocking Gitlab user \"#{user.name}\" (#{user.email})"
+ )
access.allowed?
end
@@ -105,18 +137,32 @@ describe Gitlab::Auth::LDAP::Access do
allow_any_instance_of(Gitlab::Auth::LDAP::Config).to receive(:active_directory).and_return(false)
end
- it { is_expected.to be_truthy }
+ it 'returns true' do
+ expect(access.allowed?).to be_truthy
+ end
context 'when user cannot be found' do
before do
- allow(Gitlab::Auth::LDAP::Person).to receive(:find_by_dn).and_return(nil)
- allow(Gitlab::Auth::LDAP::Person).to receive(:find_by_email).and_return(nil)
+ stub_ldap_person_find_by_dn(nil)
+ stub_ldap_person_find_by_email(user.email, nil)
end
- it { is_expected.to be_falsey }
+ it 'returns false' do
+ expect(access.allowed?).to be_falsey
+ end
it 'blocks user in GitLab' do
- expect(access).to receive(:block_user).with(user, 'does not exist anymore')
+ access.allowed?
+
+ expect(user).to be_blocked
+ expect(user).to be_ldap_blocked
+ end
+
+ it 'logs the reason' do
+ expect(Gitlab::AppLogger).to receive(:info).with(
+ "LDAP account \"123456\" does not exist anymore, " \
+ "blocking Gitlab user \"#{user.name}\" (#{user.email})"
+ )
access.allowed?
end
@@ -128,7 +174,17 @@ describe Gitlab::Auth::LDAP::Access do
end
it 'unblocks the user if it exists' do
- expect(access).to receive(:unblock_user).with(user, 'is available again')
+ access.allowed?
+
+ expect(user).not_to be_blocked
+ expect(user).not_to be_ldap_blocked
+ end
+
+ it 'logs the reason' do
+ expect(Gitlab::AppLogger).to receive(:info).with(
+ "LDAP account \"123456\" is available again, " \
+ "unblocking Gitlab user \"#{user.name}\" (#{user.email})"
+ )
access.allowed?
end
@@ -152,46 +208,4 @@ describe Gitlab::Auth::LDAP::Access do
end
end
end
-
- describe '#block_user' do
- before do
- user.activate
- allow(Gitlab::AppLogger).to receive(:info)
-
- access.block_user user, 'reason'
- end
-
- it 'blocks the user' do
- expect(user).to be_blocked
- expect(user).to be_ldap_blocked
- end
-
- it 'logs the reason' do
- expect(Gitlab::AppLogger).to have_received(:info).with(
- "LDAP account \"123456\" reason, " \
- "blocking Gitlab user \"#{user.name}\" (#{user.email})"
- )
- end
- end
-
- describe '#unblock_user' do
- before do
- user.ldap_block
- allow(Gitlab::AppLogger).to receive(:info)
-
- access.unblock_user user, 'reason'
- end
-
- it 'activates the user' do
- expect(user).not_to be_blocked
- expect(user).not_to be_ldap_blocked
- end
-
- it 'logs the reason' do
- Gitlab::AppLogger.info(
- "LDAP account \"123456\" reason, " \
- "unblocking Gitlab user \"#{user.name}\" (#{user.email})"
- )
- end
- end
end
diff --git a/spec/lib/gitlab/auth/o_auth/provider_spec.rb b/spec/lib/gitlab/auth/o_auth/provider_spec.rb
index fc35d430917..80d702cf9dc 100644
--- a/spec/lib/gitlab/auth/o_auth/provider_spec.rb
+++ b/spec/lib/gitlab/auth/o_auth/provider_spec.rb
@@ -1,6 +1,48 @@
require 'spec_helper'
describe Gitlab::Auth::OAuth::Provider do
+ describe '.enabled?' do
+ before do
+ allow(described_class).to receive(:providers).and_return([:ldapmain, :google_oauth2])
+ end
+
+ context 'when OmniAuth is disabled' do
+ before do
+ allow(Gitlab::Auth).to receive(:omniauth_enabled?).and_return(false)
+ end
+
+ it 'allows database auth' do
+ expect(described_class.enabled?('database')).to be_truthy
+ end
+
+ it 'allows LDAP auth' do
+ expect(described_class.enabled?('ldapmain')).to be_truthy
+ end
+
+ it 'does not allow other OmniAuth providers' do
+ expect(described_class.enabled?('google_oauth2')).to be_falsey
+ end
+ end
+
+ context 'when OmniAuth is enabled' do
+ before do
+ allow(Gitlab::Auth).to receive(:omniauth_enabled?).and_return(true)
+ end
+
+ it 'allows database auth' do
+ expect(described_class.enabled?('database')).to be_truthy
+ end
+
+ it 'allows LDAP auth' do
+ expect(described_class.enabled?('ldapmain')).to be_truthy
+ end
+
+ it 'allows other OmniAuth providers' do
+ expect(described_class.enabled?('google_oauth2')).to be_truthy
+ end
+ end
+ end
+
describe '#config_for' do
context 'for an LDAP provider' do
context 'when the provider exists' do
diff --git a/spec/lib/gitlab/ci/status/build/factory_spec.rb b/spec/lib/gitlab/ci/status/build/factory_spec.rb
index d53a7d468e3..8b92088902b 100644
--- a/spec/lib/gitlab/ci/status/build/factory_spec.rb
+++ b/spec/lib/gitlab/ci/status/build/factory_spec.rb
@@ -88,7 +88,7 @@ describe Gitlab::Ci::Status::Build::Factory do
expect(status.icon).to eq 'status_failed'
expect(status.favicon).to eq 'favicon_status_failed'
expect(status.label).to eq 'failed'
- expect(status.status_tooltip).to eq 'failed <br> (unknown failure)'
+ expect(status.status_tooltip).to eq 'failed - (unknown failure)'
expect(status).to have_details
expect(status).to have_action
end
diff --git a/spec/lib/gitlab/ci/status/build/failed_allowed_spec.rb b/spec/lib/gitlab/ci/status/build/failed_allowed_spec.rb
index bfaa508785e..af03d5a1308 100644
--- a/spec/lib/gitlab/ci/status/build/failed_allowed_spec.rb
+++ b/spec/lib/gitlab/ci/status/build/failed_allowed_spec.rb
@@ -76,7 +76,7 @@ describe Gitlab::Ci::Status::Build::FailedAllowed do
let(:status) { described_class.new(build_status) }
it 'does override badge_tooltip' do
- expect(status.badge_tooltip).to eq('failed <br> (unknown failure)')
+ expect(status.badge_tooltip).to eq('failed - (unknown failure)')
end
end
@@ -87,7 +87,7 @@ describe Gitlab::Ci::Status::Build::FailedAllowed do
let(:status) { described_class.new(build_status) }
it 'does override status_tooltip' do
- expect(status.status_tooltip).to eq 'failed <br> (unknown failure) (allowed to fail)'
+ expect(status.status_tooltip).to eq 'failed - (unknown failure) (allowed to fail)'
end
end
diff --git a/spec/lib/gitlab/ci/status/build/failed_spec.rb b/spec/lib/gitlab/ci/status/build/failed_spec.rb
index b6676b40fd3..e424270f7c5 100644
--- a/spec/lib/gitlab/ci/status/build/failed_spec.rb
+++ b/spec/lib/gitlab/ci/status/build/failed_spec.rb
@@ -52,7 +52,7 @@ describe Gitlab::Ci::Status::Build::Failed do
let(:status) { Gitlab::Ci::Status::Failed.new(build, user) }
it 'does override badge_tooltip' do
- expect(subject.badge_tooltip).to eq 'failed <br> (script failure)'
+ expect(subject.badge_tooltip).to eq 'failed - (script failure)'
end
end
@@ -61,7 +61,7 @@ describe Gitlab::Ci::Status::Build::Failed do
let(:status) { Gitlab::Ci::Status::Failed.new(build, user) }
it 'does override status_tooltip' do
- expect(subject.status_tooltip).to eq 'failed <br> (script failure)'
+ expect(subject.status_tooltip).to eq 'failed - (script failure)'
end
end
diff --git a/spec/lib/gitlab/ci/status/build/retried_spec.rb b/spec/lib/gitlab/ci/status/build/retried_spec.rb
index ee9acaf1c21..76c2fb01e3f 100644
--- a/spec/lib/gitlab/ci/status/build/retried_spec.rb
+++ b/spec/lib/gitlab/ci/status/build/retried_spec.rb
@@ -66,7 +66,7 @@ describe Gitlab::Ci::Status::Build::Retried do
let(:status) { Gitlab::Ci::Status::Build::Failed.new(failed_status) }
it 'does override status_tooltip' do
- expect(subject.status_tooltip).to eq 'failed <br> (unknown failure) (retried)'
+ expect(subject.status_tooltip).to eq 'failed - (unknown failure) (retried)'
end
end
diff --git a/spec/lib/gitlab/conflict/file_spec.rb b/spec/lib/gitlab/conflict/file_spec.rb
index 5b343920429..9095ffbfd52 100644
--- a/spec/lib/gitlab/conflict/file_spec.rb
+++ b/spec/lib/gitlab/conflict/file_spec.rb
@@ -69,10 +69,6 @@ describe Gitlab::Conflict::File do
CGI.unescapeHTML(ActionView::Base.full_sanitizer.sanitize(html)).delete("\n")
end
- it 'modifies the existing lines' do
- expect { conflict_file.highlight_lines! }.to change { conflict_file.lines.map(&:instance_variables) }
- end
-
it 'is called implicitly when rich_text is accessed on a line' do
expect(conflict_file).to receive(:highlight_lines!).once.and_call_original
diff --git a/spec/lib/gitlab/diff/highlight_spec.rb b/spec/lib/gitlab/diff/highlight_spec.rb
index 7c9e8c8d04e..3c8cf9c56cc 100644
--- a/spec/lib/gitlab/diff/highlight_spec.rb
+++ b/spec/lib/gitlab/diff/highlight_spec.rb
@@ -24,19 +24,19 @@ describe Gitlab::Diff::Highlight do
it 'highlights and marks unchanged lines' do
code = %Q{ <span id="LC7" class="line" lang="ruby"> <span class="k">def</span> <span class="nf">popen</span><span class="p">(</span><span class="n">cmd</span><span class="p">,</span> <span class="n">path</span><span class="o">=</span><span class="kp">nil</span><span class="p">)</span></span>\n}
- expect(subject[2].text).to eq(code)
+ expect(subject[2].rich_text).to eq(code)
end
it 'highlights and marks removed lines' do
code = %Q{-<span id="LC9" class="line" lang="ruby"> <span class="k">raise</span> <span class="s2">"System commands must be given as an array of strings"</span></span>\n}
- expect(subject[4].text).to eq(code)
+ expect(subject[4].rich_text).to eq(code)
end
it 'highlights and marks added lines' do
code = %Q{+<span id="LC9" class="line" lang="ruby"> <span class="k">raise</span> <span class="no"><span class="idiff left">RuntimeError</span></span><span class="p"><span class="idiff">,</span></span><span class="idiff right"> </span><span class="s2">"System commands must be given as an array of strings"</span></span>\n}
- expect(subject[5].text).to eq(code)
+ expect(subject[5].rich_text).to eq(code)
end
end
@@ -69,8 +69,8 @@ describe Gitlab::Diff::Highlight do
it 'marks added lines' do
code = %q{+ raise <span class="idiff left right">RuntimeError, </span>&quot;System commands must be given as an array of strings&quot;}
- expect(subject[5].text).to eq(code)
- expect(subject[5].text).to be_html_safe
+ expect(subject[5].rich_text).to eq(code)
+ expect(subject[5].rich_text).to be_html_safe
end
context 'when the inline diff marker has an invalid range' do
diff --git a/spec/lib/gitlab/diff/line_spec.rb b/spec/lib/gitlab/diff/line_spec.rb
new file mode 100644
index 00000000000..76d411973c7
--- /dev/null
+++ b/spec/lib/gitlab/diff/line_spec.rb
@@ -0,0 +1,22 @@
+describe Gitlab::Diff::Line do
+ describe '.init_from_hash' do
+ it 'round-trips correctly with to_hash' do
+ line = described_class.new('<input>', 'match', 0, 0, 1,
+ parent_file: double(:file),
+ line_code: double(:line_code),
+ rich_text: '&lt;input&gt;')
+
+ expect(described_class.init_from_hash(line.to_hash).to_hash)
+ .to eq(line.to_hash)
+ end
+ end
+
+ context "when setting rich text" do
+ it 'escapes any HTML special characters in the diff chunk header' do
+ subject = described_class.new("<input>", "", 0, 0, 0)
+ line = subject.as_json
+
+ expect(line[:rich_text]).to eq("&lt;input&gt;")
+ end
+ end
+end
diff --git a/spec/lib/gitlab/github_import/importer/issue_importer_spec.rb b/spec/lib/gitlab/github_import/importer/issue_importer_spec.rb
index 3f7a12144d5..65a2e1cb5cb 100644
--- a/spec/lib/gitlab/github_import/importer/issue_importer_spec.rb
+++ b/spec/lib/gitlab/github_import/importer/issue_importer_spec.rb
@@ -92,7 +92,7 @@ describe Gitlab::GithubImport::Importer::IssueImporter, :clean_gitlab_redis_cach
.with(issue)
.and_return([user.id, true])
- expect(Gitlab::GithubImport)
+ expect(importer)
.to receive(:insert_and_return_id)
.with(
{
@@ -121,7 +121,7 @@ describe Gitlab::GithubImport::Importer::IssueImporter, :clean_gitlab_redis_cach
.with(issue)
.and_return([project.creator_id, false])
- expect(Gitlab::GithubImport)
+ expect(importer)
.to receive(:insert_and_return_id)
.with(
{
@@ -150,7 +150,7 @@ describe Gitlab::GithubImport::Importer::IssueImporter, :clean_gitlab_redis_cach
.with(issue)
.and_return([user.id, true])
- expect(Gitlab::GithubImport)
+ expect(importer)
.to receive(:insert_and_return_id)
.and_raise(ActiveRecord::InvalidForeignKey, 'invalid foreign key')
@@ -185,7 +185,7 @@ describe Gitlab::GithubImport::Importer::IssueImporter, :clean_gitlab_redis_cach
.and_return([user.id, true])
issue = build_stubbed(:issue, project: project)
- allow(Gitlab::GithubImport)
+ allow(importer)
.to receive(:insert_and_return_id)
.and_return(issue.id)
allow(project.issues).to receive(:find).with(issue.id).and_return(issue)
diff --git a/spec/lib/gitlab/github_import/importer/pull_request_importer_spec.rb b/spec/lib/gitlab/github_import/importer/pull_request_importer_spec.rb
index 44c920043b4..25684ea9e2c 100644
--- a/spec/lib/gitlab/github_import/importer/pull_request_importer_spec.rb
+++ b/spec/lib/gitlab/github_import/importer/pull_request_importer_spec.rb
@@ -80,7 +80,7 @@ describe Gitlab::GithubImport::Importer::PullRequestImporter, :clean_gitlab_redi
end
it 'imports the pull request with the pull request author as the merge request author' do
- expect(Gitlab::GithubImport)
+ expect(importer)
.to receive(:insert_and_return_id)
.with(
{
@@ -114,7 +114,7 @@ describe Gitlab::GithubImport::Importer::PullRequestImporter, :clean_gitlab_redi
it 'triggers internal_id functionality to track greatest iids' do
mr = build_stubbed(:merge_request, source_project: project, target_project: project)
- allow(Gitlab::GithubImport).to receive(:insert_and_return_id).and_return(mr.id)
+ allow(importer).to receive(:insert_and_return_id).and_return(mr.id)
allow(project.merge_requests).to receive(:find).with(mr.id).and_return(mr)
expect(mr).to receive(:ensure_target_project_iid!)
@@ -135,7 +135,7 @@ describe Gitlab::GithubImport::Importer::PullRequestImporter, :clean_gitlab_redi
.with(pull_request)
.and_return(user.id)
- expect(Gitlab::GithubImport)
+ expect(importer)
.to receive(:insert_and_return_id)
.with(
{
@@ -181,7 +181,7 @@ describe Gitlab::GithubImport::Importer::PullRequestImporter, :clean_gitlab_redi
.to receive(:source_branch)
.and_return('master')
- expect(Gitlab::GithubImport)
+ expect(importer)
.to receive(:insert_and_return_id)
.with(
{
@@ -219,7 +219,7 @@ describe Gitlab::GithubImport::Importer::PullRequestImporter, :clean_gitlab_redi
.with(pull_request)
.and_return(user.id)
- expect(Gitlab::GithubImport)
+ expect(importer)
.to receive(:insert_and_return_id)
.and_raise(ActiveRecord::InvalidForeignKey, 'invalid foreign key')
diff --git a/spec/lib/gitlab/github_import_spec.rb b/spec/lib/gitlab/github_import_spec.rb
index 51414800e8c..496244c91bf 100644
--- a/spec/lib/gitlab/github_import_spec.rb
+++ b/spec/lib/gitlab/github_import_spec.rb
@@ -27,39 +27,6 @@ describe Gitlab::GithubImport do
end
end
- describe '.insert_and_return_id' do
- let(:attributes) { { iid: 1, title: 'foo' } }
- let(:project) { create(:project) }
-
- context 'on PostgreSQL' do
- it 'returns the ID returned by the query' do
- expect(Gitlab::Database)
- .to receive(:bulk_insert)
- .with(Issue.table_name, [attributes], return_ids: true)
- .and_return([10])
-
- id = described_class.insert_and_return_id(attributes, project.issues)
-
- expect(id).to eq(10)
- end
- end
-
- context 'on MySQL' do
- it 'uses a separate query to retrieve the ID' do
- issue = create(:issue, project: project, iid: attributes[:iid])
-
- expect(Gitlab::Database)
- .to receive(:bulk_insert)
- .with(Issue.table_name, [attributes], return_ids: true)
- .and_return([])
-
- id = described_class.insert_and_return_id(attributes, project.issues)
-
- expect(id).to eq(issue.id)
- end
- end
- end
-
describe '.ghost_user_id', :clean_gitlab_redis_cache do
it 'returns the ID of the ghost user' do
expect(described_class.ghost_user_id).to eq(User.ghost.id)
diff --git a/spec/lib/gitlab/import/database_helpers_spec.rb b/spec/lib/gitlab/import/database_helpers_spec.rb
new file mode 100644
index 00000000000..e716155b7d5
--- /dev/null
+++ b/spec/lib/gitlab/import/database_helpers_spec.rb
@@ -0,0 +1,46 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::Import::DatabaseHelpers do
+ let(:database_helper) do
+ Class.new do
+ include Gitlab::Import::DatabaseHelpers
+ end
+ end
+
+ subject { database_helper.new }
+
+ describe '.insert_and_return_id' do
+ let(:attributes) { { iid: 1, title: 'foo' } }
+ let(:project) { create(:project) }
+
+ context 'on PostgreSQL' do
+ it 'returns the ID returned by the query' do
+ expect(Gitlab::Database)
+ .to receive(:bulk_insert)
+ .with(Issue.table_name, [attributes], return_ids: true)
+ .and_return([10])
+
+ id = subject.insert_and_return_id(attributes, project.issues)
+
+ expect(id).to eq(10)
+ end
+ end
+
+ context 'on MySQL' do
+ it 'uses a separate query to retrieve the ID' do
+ issue = create(:issue, project: project, iid: attributes[:iid])
+
+ expect(Gitlab::Database)
+ .to receive(:bulk_insert)
+ .with(Issue.table_name, [attributes], return_ids: true)
+ .and_return([])
+
+ id = subject.insert_and_return_id(attributes, project.issues)
+
+ expect(id).to eq(issue.id)
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/import/merge_request_creator_spec.rb b/spec/lib/gitlab/import/merge_request_creator_spec.rb
new file mode 100644
index 00000000000..7c73e9b39f7
--- /dev/null
+++ b/spec/lib/gitlab/import/merge_request_creator_spec.rb
@@ -0,0 +1,43 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::Import::MergeRequestCreator do
+ let(:project) { create(:project, :repository) }
+
+ subject { described_class.new(project) }
+
+ describe '#execute' do
+ context 'merge request already exists' do
+ let(:merge_request) { create(:merge_request, target_project: project, source_project: project) }
+ let(:commits) { merge_request.merge_request_diffs.first.commits }
+ let(:attributes) { HashWithIndifferentAccess.new(merge_request.attributes.except("merge_params")) }
+
+ it 'updates the data' do
+ commits_count = commits.count
+ merge_request.merge_request_diffs.destroy_all # rubocop: disable DestroyAll
+
+ expect(merge_request.merge_request_diffs.count).to eq(0)
+
+ subject.execute(attributes)
+
+ expect(merge_request.reload.merge_request_diffs.count).to eq(1)
+ expect(merge_request.reload.merge_request_diffs.first.commits.count).to eq(commits_count)
+ end
+ end
+
+ context 'new merge request' do
+ let(:merge_request) { build(:merge_request, target_project: project, source_project: project) }
+ let(:attributes) { HashWithIndifferentAccess.new(merge_request.attributes.except("merge_params")) }
+
+ it 'creates a new merge request' do
+ attributes.delete(:id)
+
+ expect { subject.execute(attributes) }.to change { MergeRequest.count }.by(1)
+
+ new_mr = MergeRequest.last
+ expect(new_mr.merge_request_diffs.count).to eq(1)
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/import_export/uploads_manager_spec.rb b/spec/lib/gitlab/import_export/uploads_manager_spec.rb
index 9c3870a0af8..f799de18cd0 100644
--- a/spec/lib/gitlab/import_export/uploads_manager_spec.rb
+++ b/spec/lib/gitlab/import_export/uploads_manager_spec.rb
@@ -36,6 +36,38 @@ describe Gitlab::ImportExport::UploadsManager do
expect(File).to exist(exported_file_path)
end
+
+ context 'with orphaned project upload files' do
+ let(:orphan_path) { File.join(FileUploader.absolute_base_dir(project), 'f93f088ddf492ffd950cf059002cbbb6', 'orphan.jpg') }
+ let(:exported_orphan_path) { "#{shared.export_path}/uploads/f93f088ddf492ffd950cf059002cbbb6/orphan.jpg" }
+
+ before do
+ FileUtils.mkdir_p(File.dirname(orphan_path))
+ FileUtils.touch(orphan_path)
+ end
+
+ after do
+ File.delete(orphan_path) if File.exist?(orphan_path)
+ end
+
+ it 'excludes orphaned upload files' do
+ manager.save
+
+ expect(File).not_to exist(exported_orphan_path)
+ end
+ end
+
+ context 'with an upload missing its file' do
+ before do
+ File.delete(upload.absolute_path)
+ end
+
+ it 'does not cause errors' do
+ manager.save
+
+ expect(shared.errors).to be_empty
+ end
+ end
end
context 'using object storage' do
diff --git a/spec/lib/gitlab/middleware/multipart_spec.rb b/spec/lib/gitlab/middleware/multipart_spec.rb
index f788f8ee276..daf454665b0 100644
--- a/spec/lib/gitlab/middleware/multipart_spec.rb
+++ b/spec/lib/gitlab/middleware/multipart_spec.rb
@@ -75,6 +75,26 @@ describe Gitlab::Middleware::Multipart do
it_behaves_like 'multipart upload files'
end
+ it 'allows files in uploads/tmp directory' do
+ Dir.mktmpdir do |dir|
+ uploads_dir = File.join(dir, 'public/uploads/tmp')
+ FileUtils.mkdir_p(uploads_dir)
+
+ allow(Rails).to receive(:root).and_return(dir)
+ allow(Dir).to receive(:tmpdir).and_return(File.join(Dir.tmpdir, 'tmpsubdir'))
+
+ Tempfile.open('top-level', uploads_dir) do |tempfile|
+ env = post_env({ 'file' => tempfile.path }, { 'file.name' => original_filename, 'file.path' => tempfile.path }, Gitlab::Workhorse.secret, 'gitlab-workhorse')
+
+ expect(app).to receive(:call) do |env|
+ expect(Rack::Request.new(env).params['file']).to be_a(::UploadedFile)
+ end
+
+ middleware.call(env)
+ end
+ end
+ end
+
it 'allows symlinks for uploads dir' do
Tempfile.open('two-levels') do |tempfile|
symlinked_dir = '/some/dir/uploads'
diff --git a/spec/lib/gitlab/url_blocker_spec.rb b/spec/lib/gitlab/url_blocker_spec.rb
index 6f5f9938eca..624e2add860 100644
--- a/spec/lib/gitlab/url_blocker_spec.rb
+++ b/spec/lib/gitlab/url_blocker_spec.rb
@@ -1,3 +1,4 @@
+# coding: utf-8
require 'spec_helper'
describe Gitlab::UrlBlocker do
@@ -82,6 +83,17 @@ describe Gitlab::UrlBlocker do
expect(described_class).not_to be_blocked_url("http://#{ip}")
end
end
+
+ it 'allows IPv4 link-local endpoints' do
+ expect(described_class).not_to be_blocked_url('http://169.254.169.254')
+ expect(described_class).not_to be_blocked_url('http://169.254.168.100')
+ end
+
+ # This is blocked due to the hostname check: https://gitlab.com/gitlab-org/gitlab-ce/issues/50227
+ it 'blocks IPv6 link-local endpoints' do
+ expect(described_class).to be_blocked_url('http://[::ffff:169.254.169.254]')
+ expect(described_class).to be_blocked_url('http://[::ffff:169.254.168.100]')
+ end
end
context 'false' do
@@ -96,10 +108,21 @@ describe Gitlab::UrlBlocker do
expect(described_class).to be_blocked_url("http://#{ip}", allow_local_network: false)
end
end
+
+ it 'blocks IPv4 link-local endpoints' do
+ expect(described_class).to be_blocked_url('http://169.254.169.254', allow_local_network: false)
+ expect(described_class).to be_blocked_url('http://169.254.168.100', allow_local_network: false)
+ end
+
+ it 'blocks IPv6 link-local endpoints' do
+ expect(described_class).to be_blocked_url('http://[::ffff:169.254.169.254]', allow_local_network: false)
+ expect(described_class).to be_blocked_url('http://[::ffff:169.254.168.100]', allow_local_network: false)
+ expect(described_class).to be_blocked_url('http://[FE80::C800:EFF:FE74:8]', allow_local_network: false)
+ end
end
def stub_domain_resolv(domain, ip)
- allow(Addrinfo).to receive(:getaddrinfo).with(domain, any_args).and_return([double(ip_address: ip, ipv4_private?: true)])
+ allow(Addrinfo).to receive(:getaddrinfo).with(domain, any_args).and_return([double(ip_address: ip, ipv4_private?: true, ipv6_link_local?: false)])
end
def unstub_domain_resolv
diff --git a/spec/lib/gitlab/usage_data_spec.rb b/spec/lib/gitlab/usage_data_spec.rb
index a19b3c0ba66..de6dd2a9fea 100644
--- a/spec/lib/gitlab/usage_data_spec.rb
+++ b/spec/lib/gitlab/usage_data_spec.rb
@@ -56,6 +56,7 @@ describe Gitlab::UsageData do
expect(count_data[:projects]).to eq(3)
expect(count_data.keys).to match_array(%i(
+ assignee_lists
boards
ci_builds
ci_internal_pipelines
@@ -83,9 +84,11 @@ describe Gitlab::UsageData do
groups
issues
keys
+ label_lists
labels
lfs_objects
merge_requests
+ milestone_lists
milestones
notes
projects
diff --git a/spec/migrations/drop_duplicate_protected_tags_spec.rb b/spec/migrations/drop_duplicate_protected_tags_spec.rb
new file mode 100644
index 00000000000..acfb6850722
--- /dev/null
+++ b/spec/migrations/drop_duplicate_protected_tags_spec.rb
@@ -0,0 +1,40 @@
+require 'spec_helper'
+require Rails.root.join('db', 'migrate', '20180711103851_drop_duplicate_protected_tags.rb')
+
+describe DropDuplicateProtectedTags, :migration do
+ let(:namespaces) { table(:namespaces) }
+ let(:projects) { table(:projects) }
+ let(:protected_tags) { table(:protected_tags) }
+
+ before do
+ stub_const("#{described_class}::BATCH_SIZE", 2)
+
+ namespaces.create(id: 1, name: 'gitlab-org', path: 'gitlab-org')
+ projects.create!(id: 1, namespace_id: 1, name: 'gitlab1', path: 'gitlab1')
+ projects.create!(id: 2, namespace_id: 1, name: 'gitlab2', path: 'gitlab2')
+ end
+
+ it 'removes duplicated protected tags' do
+ protected_tags.create!(id: 1, project_id: 1, name: 'foo')
+ tag2 = protected_tags.create!(id: 2, project_id: 1, name: 'foo1')
+ protected_tags.create!(id: 3, project_id: 1, name: 'foo')
+ tag4 = protected_tags.create!(id: 4, project_id: 1, name: 'foo')
+ tag5 = protected_tags.create!(id: 5, project_id: 2, name: 'foo')
+
+ migrate!
+
+ expect(protected_tags.all.count).to eq 3
+ expect(protected_tags.all.pluck(:id)).to contain_exactly(tag2.id, tag4.id, tag5.id)
+ end
+
+ it 'does not remove unique protected tags' do
+ tag1 = protected_tags.create!(id: 1, project_id: 1, name: 'foo1')
+ tag2 = protected_tags.create!(id: 2, project_id: 1, name: 'foo2')
+ tag3 = protected_tags.create!(id: 3, project_id: 1, name: 'foo3')
+
+ migrate!
+
+ expect(protected_tags.all.count).to eq 3
+ expect(protected_tags.all.pluck(:id)).to contain_exactly(tag1.id, tag2.id, tag3.id)
+ end
+end
diff --git a/spec/models/commit_spec.rb b/spec/models/commit_spec.rb
index 5157d8fc645..d5f88e930d4 100644
--- a/spec/models/commit_spec.rb
+++ b/spec/models/commit_spec.rb
@@ -225,6 +225,12 @@ eos
end
describe 'description' do
+ it 'returns no_commit_message when safe_message is blank' do
+ allow(commit).to receive(:safe_message).and_return(nil)
+
+ expect(commit.description).to eq('--no commit message')
+ end
+
it 'returns description of commit message if title less than 100 characters' do
message = <<eos
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec sodales id felis id blandit.
diff --git a/spec/models/concerns/awardable_spec.rb b/spec/models/concerns/awardable_spec.rb
index a980cff28fb..69083bdc125 100644
--- a/spec/models/concerns/awardable_spec.rb
+++ b/spec/models/concerns/awardable_spec.rb
@@ -53,21 +53,14 @@ describe Awardable do
issue.project.add_guest(user)
end
- it 'does not allow upvoting or downvoting your own issue' do
- issue.update!(author: user)
-
- expect(issue.user_can_award?(user, AwardEmoji::DOWNVOTE_NAME)).to be_falsy
- expect(issue.user_can_award?(user, AwardEmoji::UPVOTE_NAME)).to be_falsy
- end
-
it 'is truthy when the user is allowed to award emoji' do
- expect(issue.user_can_award?(user, AwardEmoji::UPVOTE_NAME)).to be_truthy
+ expect(issue.user_can_award?(user)).to be_truthy
end
it 'is falsy when the project is archived' do
issue.project.update!(archived: true)
- expect(issue.user_can_award?(user, AwardEmoji::UPVOTE_NAME)).to be_falsy
+ expect(issue.user_can_award?(user)).to be_falsy
end
end
diff --git a/spec/models/issue_spec.rb b/spec/models/issue_spec.rb
index 84edfc3ff00..c21d85fb2a4 100644
--- a/spec/models/issue_spec.rb
+++ b/spec/models/issue_spec.rb
@@ -188,98 +188,6 @@ describe Issue do
end
end
- describe '#closed_by_merge_requests' do
- let(:project) { create(:project, :repository) }
- let(:issue) { create(:issue, project: project)}
- let(:closed_issue) { build(:issue, :closed, project: project)}
-
- let(:mr) do
- opts = {
- title: 'Awesome merge_request',
- description: "Fixes #{issue.to_reference}",
- source_branch: 'feature',
- target_branch: 'master'
- }
- MergeRequests::CreateService.new(project, project.owner, opts).execute
- end
-
- let(:closed_mr) do
- opts = {
- title: 'Awesome merge_request 2',
- description: "Fixes #{issue.to_reference}",
- source_branch: 'feature',
- target_branch: 'master',
- state: 'closed'
- }
- MergeRequests::CreateService.new(project, project.owner, opts).execute
- end
-
- it 'returns the merge request to close this issue' do
- expect(issue.closed_by_merge_requests(mr.author)).to eq([mr])
- end
-
- it "returns an empty array when the merge request is closed already" do
- expect(issue.closed_by_merge_requests(closed_mr.author)).to eq([])
- end
-
- it "returns an empty array when the current issue is closed already" do
- expect(closed_issue.closed_by_merge_requests(closed_issue.author)).to eq([])
- end
- end
-
- describe '#referenced_merge_requests' do
- let(:project) { create(:project, :public) }
- let(:issue) do
- create(:issue, description: merge_request.to_reference, project: project)
- end
- let!(:merge_request) do
- create(:merge_request,
- source_project: project,
- source_branch: 'master',
- target_branch: 'feature')
- end
-
- it 'returns the referenced merge requests' do
- mr2 = create(:merge_request,
- source_project: project,
- source_branch: 'feature',
- target_branch: 'master')
-
- create(:note_on_issue,
- noteable: issue,
- note: mr2.to_reference,
- project_id: project.id)
-
- expect(issue.referenced_merge_requests).to eq([merge_request, mr2])
- end
-
- it 'returns cross project referenced merge requests' do
- other_project = create(:project, :public)
- cross_project_merge_request = create(:merge_request, source_project: other_project)
- create(:note_on_issue,
- noteable: issue,
- note: cross_project_merge_request.to_reference(issue.project),
- project_id: issue.project.id)
-
- expect(issue.referenced_merge_requests).to eq([merge_request, cross_project_merge_request])
- end
-
- it 'excludes cross project references if the user cannot read cross project' do
- user = create(:user)
- allow(Ability).to receive(:allowed?).and_call_original
- expect(Ability).to receive(:allowed?).with(user, :read_cross_project) { false }
-
- other_project = create(:project, :public)
- cross_project_merge_request = create(:merge_request, source_project: other_project)
- create(:note_on_issue,
- noteable: issue,
- note: cross_project_merge_request.to_reference(issue.project),
- project_id: issue.project.id)
-
- expect(issue.referenced_merge_requests(user)).to eq([merge_request])
- end
- end
-
describe '#can_move?' do
let(:user) { create(:user) }
let(:issue) { create(:issue) }
@@ -365,7 +273,12 @@ describe Issue do
source_project: subject.project,
source_branch: "#{subject.iid}-branch" })
merge_request.create_cross_references!(user)
- expect(subject.referenced_merge_requests(user)).not_to be_empty
+
+ referenced_merge_requests = Issues::ReferencedMergeRequestsService
+ .new(subject.project, user)
+ .referenced_merge_requests(subject)
+
+ expect(referenced_merge_requests).not_to be_empty
expect(subject.related_branches(user)).to eq([subject.to_branch_name])
end
diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb
index 8cb706b54b0..7cfffbde42f 100644
--- a/spec/models/project_spec.rb
+++ b/spec/models/project_spec.rb
@@ -2989,6 +2989,7 @@ describe Project do
# call. This makes testing a bit easier.
allow(project).to receive(:gitlab_shell).and_return(gitlab_shell)
allow(project).to receive(:previous_changes).and_return('path' => ['foo'])
+ stub_feature_flags(skip_hashed_storage_upgrade: false)
end
it 'renames a repository' do
@@ -3160,6 +3161,7 @@ describe Project do
# call. This makes testing a bit easier.
allow(project).to receive(:gitlab_shell).and_return(gitlab_shell)
allow(project).to receive(:previous_changes).and_return('path' => ['foo'])
+ stub_feature_flags(skip_hashed_storage_upgrade: false)
end
context 'migration to hashed storage' do
diff --git a/spec/models/remote_mirror_spec.rb b/spec/models/remote_mirror_spec.rb
index c2ef0435c8e..269d5deca20 100644
--- a/spec/models/remote_mirror_spec.rb
+++ b/spec/models/remote_mirror_spec.rb
@@ -220,6 +220,18 @@ describe RemoteMirror do
end
end
+ context '#ensure_remote!' do
+ let(:remote_mirror) { create(:project, :repository, :remote_mirror).remote_mirrors.first }
+
+ it 'adds a remote multiple times with no errors' do
+ expect(remote_mirror.project.repository).to receive(:add_remote).with(remote_mirror.remote_name, remote_mirror.url).twice.and_call_original
+
+ 2.times do
+ remote_mirror.ensure_remote!
+ end
+ end
+ end
+
context '#updated_since?' do
let(:remote_mirror) { create(:project, :repository, :remote_mirror).remote_mirrors.first }
let(:timestamp) { Time.now - 5.minutes }
diff --git a/spec/models/repository_spec.rb b/spec/models/repository_spec.rb
index 2859d5149ec..93898012d34 100644
--- a/spec/models/repository_spec.rb
+++ b/spec/models/repository_spec.rb
@@ -2005,6 +2005,24 @@ describe Repository do
File.delete(path)
end
+
+ context 'for multiple SHAs' do
+ it 'skips non-existent SHAs' do
+ repository.keep_around('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', sample_commit.id)
+
+ expect(repository.kept_around?(sample_commit.id)).to be_truthy
+ end
+
+ it 'skips already-kept-around SHAs' do
+ repository.keep_around(sample_commit.id)
+
+ expect(repository.raw_repository).to receive(:write_ref).exactly(1).and_call_original
+
+ repository.keep_around(sample_commit.id, another_sample_commit.id)
+
+ expect(repository.kept_around?(another_sample_commit.id)).to be_truthy
+ end
+ end
end
describe '#update_ref' do
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index 9763477a711..fd99acb3bb2 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -315,6 +315,14 @@ describe User do
expect(users_with_two_factor).to eq([user_with_2fa.id])
expect(users_with_two_factor).not_to include(user_without_2fa.id)
end
+
+ it 'works with ORDER BY' do
+ user_with_2fa = create(:user, :two_factor_via_otp, :two_factor_via_u2f)
+
+ expect(described_class
+ .with_two_factor
+ .reorder_by_name).to eq([user_with_2fa])
+ end
end
describe ".without_two_factor" do
diff --git a/spec/policies/group_policy_spec.rb b/spec/policies/group_policy_spec.rb
index 615fea11f26..5e583be457e 100644
--- a/spec/policies/group_policy_spec.rb
+++ b/spec/policies/group_policy_spec.rb
@@ -17,7 +17,7 @@ describe GroupPolicy do
let(:reporter_permissions) { [:admin_label] }
- let(:developer_permissions) { [:admin_milestones] }
+ let(:developer_permissions) { [:admin_milestone] }
let(:maintainer_permissions) do
[
@@ -31,6 +31,7 @@ describe GroupPolicy do
:admin_namespace,
:admin_group_member,
:change_visibility_level,
+ :set_note_created_at,
(Gitlab::Database.postgresql? ? :create_subgroup : nil)
].compact
end
diff --git a/spec/policies/project_policy_spec.rb b/spec/policies/project_policy_spec.rb
index dd3fa4e6a51..b7ec35d6ec5 100644
--- a/spec/policies/project_policy_spec.rb
+++ b/spec/policies/project_policy_spec.rb
@@ -64,6 +64,7 @@ describe ProjectPolicy do
%i[
change_namespace change_visibility_level rename_project remove_project
archive_project remove_fork_project destroy_merge_request destroy_issue
+ set_issue_iid set_issue_created_at set_note_created_at
]
end
diff --git a/spec/presenters/ci/build_presenter_spec.rb b/spec/presenters/ci/build_presenter_spec.rb
index 6dfaa3b72f7..547d95e0908 100644
--- a/spec/presenters/ci/build_presenter_spec.rb
+++ b/spec/presenters/ci/build_presenter_spec.rb
@@ -78,7 +78,7 @@ describe Ci::BuildPresenter do
it 'returns the reason of failure' do
status_title = presenter.status_title
- expect(status_title).to eq('Failed <br> (unknown failure)')
+ expect(status_title).to eq('Failed - (unknown failure)')
end
end
@@ -89,7 +89,7 @@ describe Ci::BuildPresenter do
status_title = presenter.status_title
expect(status_title).not_to include('(retried)')
- expect(status_title).to eq('Failed <br> (unknown failure)')
+ expect(status_title).to eq('Failed - (unknown failure)')
end
end
@@ -99,7 +99,7 @@ describe Ci::BuildPresenter do
it 'returns the reason of failure' do
status_title = presenter.status_title
- expect(status_title).to eq('Failed <br> (unknown failure)')
+ expect(status_title).to eq('Failed - (unknown failure)')
end
end
@@ -173,7 +173,7 @@ describe Ci::BuildPresenter do
it 'returns the reason of failure' do
tooltip = subject.tooltip_message
- expect(tooltip).to eq("#{build.name} - failed <br> (script failure)")
+ expect(tooltip).to eq("#{build.name} - failed - (script failure)")
end
end
@@ -183,7 +183,7 @@ describe Ci::BuildPresenter do
it 'should include the reason of failure and the retried title' do
tooltip = subject.tooltip_message
- expect(tooltip).to eq("#{build.name} - failed <br> (script failure) (retried)")
+ expect(tooltip).to eq("#{build.name} - failed - (script failure) (retried)")
end
end
@@ -193,7 +193,7 @@ describe Ci::BuildPresenter do
it 'should include the reason of failure' do
tooltip = subject.tooltip_message
- expect(tooltip).to eq("#{build.name} - failed <br> (script failure) (allowed to fail)")
+ expect(tooltip).to eq("#{build.name} - failed - (script failure) (allowed to fail)")
end
end
diff --git a/spec/requests/api/award_emoji_spec.rb b/spec/requests/api/award_emoji_spec.rb
index 0921fecb933..7f3f3ab0977 100644
--- a/spec/requests/api/award_emoji_spec.rb
+++ b/spec/requests/api/award_emoji_spec.rb
@@ -167,12 +167,6 @@ describe API::AwardEmoji do
expect(response).to have_gitlab_http_status(401)
end
- it "returns a 404 error if the user authored issue" do
- post api("/projects/#{project.id}/issues/#{issue2.id}/award_emoji", user), name: 'thumbsup'
-
- expect(response).to have_gitlab_http_status(404)
- end
-
it "normalizes +1 as thumbsup award" do
post api("/projects/#{project.id}/issues/#{issue.iid}/award_emoji", user), name: '+1'
@@ -215,12 +209,6 @@ describe API::AwardEmoji do
expect(json_response['user']['username']).to eq(user.username)
end
- it "it returns 404 error when user authored note" do
- post api("/projects/#{project.id}/issues/#{issue.iid}/notes/#{note2.id}/award_emoji", user), name: 'thumbsup'
-
- expect(response).to have_gitlab_http_status(404)
- end
-
it "normalizes +1 as thumbsup award" do
post api("/projects/#{project.id}/issues/#{issue.iid}/notes/#{note.id}/award_emoji", user), name: '+1'
diff --git a/spec/requests/api/files_spec.rb b/spec/requests/api/files_spec.rb
index 0aec186f738..a2b41d56b8b 100644
--- a/spec/requests/api/files_spec.rb
+++ b/spec/requests/api/files_spec.rb
@@ -313,7 +313,7 @@ describe API::Files do
describe "POST /projects/:id/repository/files/:file_path" do
let!(:file_path) { "new_subfolder%2Fnewfile%2Erb" }
- let(:valid_params) do
+ let(:params) do
{
branch: "master",
content: "puts 8",
@@ -322,7 +322,7 @@ describe API::Files do
end
it "creates a new file in project repo" do
- post api(route(file_path), user), valid_params
+ post api(route(file_path), user), params
expect(response).to have_gitlab_http_status(201)
expect(json_response["file_path"]).to eq(CGI.unescape(file_path))
@@ -337,20 +337,28 @@ describe API::Files do
expect(response).to have_gitlab_http_status(400)
end
+ it 'returns a 400 bad request if the commit message is empty' do
+ params[:commit_message] = ''
+
+ post api(route(file_path), user), params
+
+ expect(response).to have_gitlab_http_status(400)
+ end
+
it "returns a 400 if editor fails to create file" do
allow_any_instance_of(Repository).to receive(:create_file)
.and_raise(Gitlab::Git::CommitError, 'Cannot create file')
- post api(route("any%2Etxt"), user), valid_params
+ post api(route("any%2Etxt"), user), params
expect(response).to have_gitlab_http_status(400)
end
context "when specifying an author" do
it "creates a new file with the specified author" do
- valid_params.merge!(author_email: author_email, author_name: author_name)
+ params.merge!(author_email: author_email, author_name: author_name)
- post api(route("new_file_with_author%2Etxt"), user), valid_params
+ post api(route("new_file_with_author%2Etxt"), user), params
expect(response).to have_gitlab_http_status(201)
expect(response.content_type).to eq('application/json')
@@ -364,7 +372,7 @@ describe API::Files do
let!(:project) { create(:project_empty_repo, namespace: user.namespace ) }
it "creates a new file in project repo" do
- post api(route("newfile%2Erb"), user), valid_params
+ post api(route("newfile%2Erb"), user), params
expect(response).to have_gitlab_http_status(201)
expect(json_response['file_path']).to eq('newfile.rb')
@@ -376,7 +384,7 @@ describe API::Files do
end
describe "PUT /projects/:id/repository/files" do
- let(:valid_params) do
+ let(:params) do
{
branch: 'master',
content: 'puts 8',
@@ -385,7 +393,7 @@ describe API::Files do
end
it "updates existing file in project repo" do
- put api(route(file_path), user), valid_params
+ put api(route(file_path), user), params
expect(response).to have_gitlab_http_status(200)
expect(json_response['file_path']).to eq(CGI.unescape(file_path))
@@ -394,8 +402,16 @@ describe API::Files do
expect(last_commit.author_name).to eq(user.name)
end
+ it 'returns a 400 bad request if the commit message is empty' do
+ params[:commit_message] = ''
+
+ put api(route(file_path), user), params
+
+ expect(response).to have_gitlab_http_status(400)
+ end
+
it "returns a 400 bad request if update existing file with stale last commit id" do
- params_with_stale_id = valid_params.merge(last_commit_id: 'stale')
+ params_with_stale_id = params.merge(last_commit_id: 'stale')
put api(route(file_path), user), params_with_stale_id
@@ -406,7 +422,7 @@ describe API::Files do
it "updates existing file in project repo with accepts correct last commit id" do
last_commit = Gitlab::Git::Commit
.last_for_path(project.repository, 'master', URI.unescape(file_path))
- params_with_correct_id = valid_params.merge(last_commit_id: last_commit.id)
+ params_with_correct_id = params.merge(last_commit_id: last_commit.id)
put api(route(file_path), user), params_with_correct_id
@@ -421,9 +437,9 @@ describe API::Files do
context "when specifying an author" do
it "updates a file with the specified author" do
- valid_params.merge!(author_email: author_email, author_name: author_name, content: "New content")
+ params.merge!(author_email: author_email, author_name: author_name, content: "New content")
- put api(route(file_path), user), valid_params
+ put api(route(file_path), user), params
expect(response).to have_gitlab_http_status(200)
last_commit = project.repository.commit.raw
@@ -434,7 +450,7 @@ describe API::Files do
end
describe "DELETE /projects/:id/repository/files" do
- let(:valid_params) do
+ let(:params) do
{
branch: 'master',
commit_message: 'Changed file'
@@ -442,7 +458,7 @@ describe API::Files do
end
it "deletes existing file in project repo" do
- delete api(route(file_path), user), valid_params
+ delete api(route(file_path), user), params
expect(response).to have_gitlab_http_status(204)
end
@@ -453,19 +469,27 @@ describe API::Files do
expect(response).to have_gitlab_http_status(400)
end
+ it 'returns a 400 bad request if the commit message is empty' do
+ params[:commit_message] = ''
+
+ delete api(route(file_path), user), params
+
+ expect(response).to have_gitlab_http_status(400)
+ end
+
it "returns a 400 if fails to delete file" do
allow_any_instance_of(Repository).to receive(:delete_file).and_raise(Gitlab::Git::CommitError, 'Cannot delete file')
- delete api(route(file_path), user), valid_params
+ delete api(route(file_path), user), params
expect(response).to have_gitlab_http_status(400)
end
context "when specifying an author" do
it "removes a file with the specified author" do
- valid_params.merge!(author_email: author_email, author_name: author_name)
+ params.merge!(author_email: author_email, author_name: author_name)
- delete api(route(file_path), user), valid_params
+ delete api(route(file_path), user), params
expect(response).to have_gitlab_http_status(204)
end
diff --git a/spec/requests/api/issues_spec.rb b/spec/requests/api/issues_spec.rb
index 28ba00c7293..f64815feffa 100644
--- a/spec/requests/api/issues_spec.rb
+++ b/spec/requests/api/issues_spec.rb
@@ -1023,6 +1023,20 @@ describe API::Issues do
end
end
+ context 'by a group owner' do
+ let(:group) { create(:group) }
+ let(:group_project) { create(:project, :public, namespace: group) }
+
+ it 'sets the internal ID on the new issue' do
+ group.add_owner(user2)
+ post api("/projects/#{group_project.id}/issues", user2),
+ title: 'new issue', iid: 9001
+
+ expect(response).to have_gitlab_http_status(201)
+ expect(json_response['iid']).to eq 9001
+ end
+ end
+
context 'by another user' do
it 'ignores the given internal ID' do
post api("/projects/#{project.id}/issues", user2),
@@ -1154,14 +1168,47 @@ describe API::Issues do
end
end
- context 'when an admin or owner makes the request' do
- it 'accepts the creation date to be set' do
- creation_time = 2.weeks.ago
- post api("/projects/#{project.id}/issues", user),
- title: 'new issue', labels: 'label, label2', created_at: creation_time
+ context 'setting created_at' do
+ let(:creation_time) { 2.weeks.ago }
+ let(:params) { { title: 'new issue', labels: 'label, label2', created_at: creation_time } }
- expect(response).to have_gitlab_http_status(201)
- expect(Time.parse(json_response['created_at'])).to be_like_time(creation_time)
+ context 'by an admin' do
+ it 'sets the creation time on the new issue' do
+ post api("/projects/#{project.id}/issues", admin), params
+
+ expect(response).to have_gitlab_http_status(201)
+ expect(Time.parse(json_response['created_at'])).to be_like_time(creation_time)
+ end
+ end
+
+ context 'by a project owner' do
+ it 'sets the creation time on the new issue' do
+ post api("/projects/#{project.id}/issues", user), params
+
+ expect(response).to have_gitlab_http_status(201)
+ expect(Time.parse(json_response['created_at'])).to be_like_time(creation_time)
+ end
+ end
+
+ context 'by a group owner' do
+ it 'sets the creation time on the new issue' do
+ group = create(:group)
+ group_project = create(:project, :public, namespace: group)
+ group.add_owner(user2)
+ post api("/projects/#{group_project.id}/issues", user2), params
+
+ expect(response).to have_gitlab_http_status(201)
+ expect(Time.parse(json_response['created_at'])).to be_like_time(creation_time)
+ end
+ end
+
+ context 'by another user' do
+ it 'ignores the given creation time' do
+ post api("/projects/#{project.id}/issues", user2), params
+
+ expect(response).to have_gitlab_http_status(201)
+ expect(Time.parse(json_response['created_at'])).not_to be_like_time(creation_time)
+ end
end
end
diff --git a/spec/requests/api/labels_spec.rb b/spec/requests/api/labels_spec.rb
index a4220f5b2be..b8a4a04a7e4 100644
--- a/spec/requests/api/labels_spec.rb
+++ b/spec/requests/api/labels_spec.rb
@@ -306,16 +306,16 @@ describe API::Labels do
end
it 'returns 400 for too long color code' do
- post api("/projects/#{project.id}/labels", user),
- name: 'Foo',
+ put api("/projects/#{project.id}/labels", user),
+ name: 'label1',
color: '#FFAAFFFF'
expect(response).to have_gitlab_http_status(400)
expect(json_response['message']['color']).to eq(['must be a valid color code'])
end
it 'returns 400 for invalid priority' do
- post api("/projects/#{project.id}/labels", user),
- name: 'Foo',
+ put api("/projects/#{project.id}/labels", user),
+ name: 'label1',
priority: 'foo'
expect(response).to have_gitlab_http_status(400)
diff --git a/spec/requests/api/project_milestones_spec.rb b/spec/requests/api/project_milestones_spec.rb
index 6c05c166bd6..62613aa5938 100644
--- a/spec/requests/api/project_milestones_spec.rb
+++ b/spec/requests/api/project_milestones_spec.rb
@@ -39,19 +39,6 @@ describe API::ProjectMilestones do
expect(response).to have_gitlab_http_status(404)
end
-
- it "rejects a member with reporter access from deleting a milestone" do
- delete api("/projects/#{project.id}/milestones/#{milestone.id}", reporter)
-
- expect(response).to have_gitlab_http_status(403)
- end
-
- it 'deletes the milestone when the user has developer access to the project' do
- delete api("/projects/#{project.id}/milestones/#{milestone.id}", user)
-
- expect(project.milestones.find_by_id(milestone.id)).to be_nil
- expect(response).to have_gitlab_http_status(204)
- end
end
describe 'PUT /projects/:id/milestones/:milestone_id to test observer on close' do
diff --git a/spec/requests/api/project_snippets_spec.rb b/spec/requests/api/project_snippets_spec.rb
index a3b5e8c6223..5dec0bc778c 100644
--- a/spec/requests/api/project_snippets_spec.rb
+++ b/spec/requests/api/project_snippets_spec.rb
@@ -116,6 +116,14 @@ describe API::ProjectSnippets do
expect(response).to have_gitlab_http_status(400)
end
+ it 'returns 400 for empty code field' do
+ params[:code] = ''
+
+ post api("/projects/#{project.id}/snippets/", admin), params
+
+ expect(response).to have_gitlab_http_status(400)
+ end
+
context 'when the snippet is spam' do
def create_snippet(project, snippet_params = {})
project.add_developer(user)
@@ -180,6 +188,14 @@ describe API::ProjectSnippets do
expect(response).to have_gitlab_http_status(400)
end
+ it 'returns 400 for empty code field' do
+ new_content = ''
+
+ put api("/projects/#{snippet.project.id}/snippets/#{snippet.id}/", admin), code: new_content
+
+ expect(response).to have_gitlab_http_status(400)
+ end
+
context 'when the snippet is spam' do
def update_snippet(snippet_params = {})
put api("/projects/#{snippet.project.id}/snippets/#{snippet.id}", admin), snippet_params
diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb
index c249c881db5..b6f92042ecc 100644
--- a/spec/requests/api/projects_spec.rb
+++ b/spec/requests/api/projects_spec.rb
@@ -402,7 +402,7 @@ describe API::Projects do
context 'and with min_access_level' do
before do
- project2.add_master(user2)
+ project2.add_maintainer(user2)
project3.add_developer(user2)
project4.add_reporter(user2)
end
@@ -913,12 +913,28 @@ describe API::Projects do
expect(json_response['shared_with_groups'][0]['group_id']).to eq(group.id)
expect(json_response['shared_with_groups'][0]['group_name']).to eq(group.name)
expect(json_response['shared_with_groups'][0]['group_access_level']).to eq(link.group_access)
+ expect(json_response['shared_with_groups'][0]['expires_at']).to be_nil
expect(json_response['only_allow_merge_if_pipeline_succeeds']).to eq(project.only_allow_merge_if_pipeline_succeeds)
expect(json_response['only_allow_merge_if_all_discussions_are_resolved']).to eq(project.only_allow_merge_if_all_discussions_are_resolved)
expect(json_response['merge_method']).to eq(project.merge_method.to_s)
expect(json_response['readme_url']).to eq(project.readme_url)
end
+ it 'returns a group link with expiration date' do
+ group = create(:group)
+ expires_at = 5.days.from_now.to_date
+ link = create(:project_group_link, project: project, group: group, expires_at: expires_at)
+
+ get api("/projects/#{project.id}", user)
+
+ expect(json_response['shared_with_groups']).to be_an Array
+ expect(json_response['shared_with_groups'].length).to eq(1)
+ expect(json_response['shared_with_groups'][0]['group_id']).to eq(group.id)
+ expect(json_response['shared_with_groups'][0]['group_name']).to eq(group.name)
+ expect(json_response['shared_with_groups'][0]['group_access_level']).to eq(link.group_access)
+ expect(json_response['shared_with_groups'][0]['expires_at']).to eq(expires_at.to_s)
+ end
+
it 'returns a project by path name' do
get api("/projects/#{project.id}", user)
expect(response).to have_gitlab_http_status(200)
@@ -1121,47 +1137,87 @@ describe API::Projects do
describe 'fork management' do
let(:project_fork_target) { create(:project) }
let(:project_fork_source) { create(:project, :public) }
+ let(:private_project_fork_source) { create(:project, :private) }
describe 'POST /projects/:id/fork/:forked_from_id' do
- let(:new_project_fork_source) { create(:project, :public) }
+ context 'user is a developer' do
+ before do
+ project_fork_target.add_developer(user)
+ end
- it "is not available for non admin users" do
- post api("/projects/#{project_fork_target.id}/fork/#{project_fork_source.id}", user)
- expect(response).to have_gitlab_http_status(403)
- end
+ it 'denies project to be forked from an existing project' do
+ post api("/projects/#{project_fork_target.id}/fork/#{project_fork_source.id}", user)
- it 'allows project to be forked from an existing project' do
- expect(project_fork_target.forked?).not_to be_truthy
- post api("/projects/#{project_fork_target.id}/fork/#{project_fork_source.id}", admin)
- expect(response).to have_gitlab_http_status(201)
- project_fork_target.reload
- expect(project_fork_target.forked_from_project.id).to eq(project_fork_source.id)
- expect(project_fork_target.forked_project_link).not_to be_nil
- expect(project_fork_target.forked?).to be_truthy
+ expect(response).to have_gitlab_http_status(403)
+ end
end
it 'refreshes the forks count cache' do
expect(project_fork_source.forks_count).to be_zero
+ end
- post api("/projects/#{project_fork_target.id}/fork/#{project_fork_source.id}", admin)
+ context 'user is maintainer' do
+ before do
+ project_fork_target.add_maintainer(user)
+ end
- expect(project_fork_source.forks_count).to eq(1)
- end
+ it 'allows project to be forked from an existing project' do
+ expect(project_fork_target).not_to be_forked
- it 'fails if forked_from project which does not exist' do
- post api("/projects/#{project_fork_target.id}/fork/9999", admin)
- expect(response).to have_gitlab_http_status(404)
+ post api("/projects/#{project_fork_target.id}/fork/#{project_fork_source.id}", user)
+ project_fork_target.reload
+
+ expect(response).to have_gitlab_http_status(201)
+ expect(project_fork_target.forked_from_project.id).to eq(project_fork_source.id)
+ expect(project_fork_target.forked_project_link).to be_present
+ expect(project_fork_target).to be_forked
+ end
+
+ it 'denies project to be forked from a private project' do
+ post api("/projects/#{project_fork_target.id}/fork/#{private_project_fork_source.id}", user)
+
+ expect(response).to have_gitlab_http_status(404)
+ end
end
- it 'fails with 409 if already forked' do
- post api("/projects/#{project_fork_target.id}/fork/#{project_fork_source.id}", admin)
- project_fork_target.reload
- expect(project_fork_target.forked_from_project.id).to eq(project_fork_source.id)
- post api("/projects/#{project_fork_target.id}/fork/#{new_project_fork_source.id}", admin)
- expect(response).to have_gitlab_http_status(409)
- project_fork_target.reload
- expect(project_fork_target.forked_from_project.id).to eq(project_fork_source.id)
- expect(project_fork_target.forked?).to be_truthy
+ context 'user is admin' do
+ it 'allows project to be forked from an existing project' do
+ expect(project_fork_target).not_to be_forked
+
+ post api("/projects/#{project_fork_target.id}/fork/#{project_fork_source.id}", admin)
+
+ expect(response).to have_gitlab_http_status(201)
+ end
+
+ it 'allows project to be forked from a private project' do
+ post api("/projects/#{project_fork_target.id}/fork/#{private_project_fork_source.id}", admin)
+
+ expect(response).to have_gitlab_http_status(201)
+ end
+
+ it 'refreshes the forks count cachce' do
+ expect do
+ post api("/projects/#{project_fork_target.id}/fork/#{project_fork_source.id}", admin)
+ end.to change(project_fork_source, :forks_count).by(1)
+ end
+
+ it 'fails if forked_from project which does not exist' do
+ post api("/projects/#{project_fork_target.id}/fork/9999", admin)
+ expect(response).to have_gitlab_http_status(404)
+ end
+
+ it 'fails with 409 if already forked' do
+ other_project_fork_source = create(:project, :public)
+
+ Projects::ForkService.new(project_fork_source, admin).execute(project_fork_target)
+
+ post api("/projects/#{project_fork_target.id}/fork/#{other_project_fork_source.id}", admin)
+ project_fork_target.reload
+
+ expect(response).to have_gitlab_http_status(409)
+ expect(project_fork_target.forked_from_project.id).to eq(project_fork_source.id)
+ expect(project_fork_target).to be_forked
+ end
end
end
@@ -1183,8 +1239,8 @@ describe API::Projects do
before do
post api("/projects/#{project_fork_target.id}/fork/#{project_fork_source.id}", admin)
project_fork_target.reload
- expect(project_fork_target.forked_from_project).not_to be_nil
- expect(project_fork_target.forked?).to be_truthy
+ expect(project_fork_target.forked_from_project).to be_present
+ expect(project_fork_target).to be_forked
end
it 'makes forked project unforked' do
@@ -1193,7 +1249,7 @@ describe API::Projects do
expect(response).to have_gitlab_http_status(204)
project_fork_target.reload
expect(project_fork_target.forked_from_project).to be_nil
- expect(project_fork_target.forked?).not_to be_truthy
+ expect(project_fork_target).not_to be_forked
end
it_behaves_like '412 response' do
@@ -1228,8 +1284,8 @@ describe API::Projects do
before do
post api("/projects/#{private_fork.id}/fork/#{project_fork_source.id}", admin)
private_fork.reload
- expect(private_fork.forked_from_project).not_to be_nil
- expect(private_fork.forked?).to be_truthy
+ expect(private_fork.forked_from_project).to be_present
+ expect(private_fork).to be_forked
project_fork_source.reload
expect(project_fork_source.forks.length).to eq(1)
expect(project_fork_source.forks).to include(private_fork)
diff --git a/spec/requests/api/protected_tags_spec.rb b/spec/requests/api/protected_tags_spec.rb
new file mode 100644
index 00000000000..f4f3ef31bc3
--- /dev/null
+++ b/spec/requests/api/protected_tags_spec.rb
@@ -0,0 +1,202 @@
+require 'spec_helper'
+
+describe API::ProtectedTags do
+ let(:user) { create(:user) }
+ let!(:project) { create(:project, :repository) }
+ let(:project2) { create(:project, path: 'project2', namespace: user.namespace) }
+ let(:protected_name) { 'feature' }
+ let(:tag_name) { protected_name }
+ let!(:protected_tag) do
+ create(:protected_tag, project: project, name: protected_name)
+ end
+
+ describe 'GET /projects/:id/protected_tags' do
+ let(:route) { "/projects/#{project.id}/protected_tags" }
+
+ shared_examples_for 'protected tags' do
+ it 'returns the protected tags' do
+ get api(route, user), per_page: 100
+
+ expect(response).to have_gitlab_http_status(200)
+ expect(response).to include_pagination_headers
+ expect(json_response).to be_an Array
+
+ protected_tag_names = json_response.map { |x| x['name'] }
+ expected_tags_names = project.protected_tags.map { |x| x['name'] }
+ expect(protected_tag_names).to match_array(expected_tags_names)
+ end
+ end
+
+ context 'when authenticated as a maintainer' do
+ before do
+ project.add_maintainer(user)
+ end
+
+ it_behaves_like 'protected tags'
+ end
+
+ context 'when authenticated as a guest' do
+ before do
+ project.add_guest(user)
+ end
+
+ it_behaves_like '403 response' do
+ let(:request) { get api(route, user) }
+ end
+ end
+ end
+
+ describe 'GET /projects/:id/protected_tags/:tag' do
+ let(:route) { "/projects/#{project.id}/protected_tags/#{tag_name}" }
+
+ shared_examples_for 'protected tag' do
+ it 'returns the protected tag' do
+ get api(route, user)
+
+ expect(response).to have_gitlab_http_status(200)
+ expect(json_response['name']).to eq(tag_name)
+ expect(json_response['create_access_levels'][0]['access_level']).to eq(::Gitlab::Access::MAINTAINER)
+ end
+
+ context 'when protected tag does not exist' do
+ let(:tag_name) { 'unknown' }
+
+ it_behaves_like '404 response' do
+ let(:request) { get api(route, user) }
+ let(:message) { '404 Not found' }
+ end
+ end
+ end
+
+ context 'when authenticated as a maintainer' do
+ before do
+ project.add_maintainer(user)
+ end
+
+ it_behaves_like 'protected tag'
+
+ context 'when protected tag contains a wildcard' do
+ let(:protected_name) { 'feature*' }
+
+ it_behaves_like 'protected tag'
+ end
+ end
+
+ context 'when authenticated as a guest' do
+ before do
+ project.add_guest(user)
+ end
+
+ it_behaves_like '403 response' do
+ let(:request) { get api(route, user) }
+ end
+ end
+ end
+
+ describe 'POST /projects/:id/protected_tags' do
+ let(:tag_name) { 'new_tag' }
+
+ context 'when authenticated as a maintainer' do
+ before do
+ project.add_maintainer(user)
+ end
+
+ it 'protects a single tag with maintainers can create tags' do
+ post api("/projects/#{project.id}/protected_tags", user), name: tag_name
+
+ expect(response).to have_gitlab_http_status(201)
+ expect(json_response['name']).to eq(tag_name)
+ expect(json_response['create_access_levels'][0]['access_level']).to eq(Gitlab::Access::MAINTAINER)
+ end
+
+ it 'protects a single tag with developers can create tags' do
+ post api("/projects/#{project.id}/protected_tags", user),
+ name: tag_name, create_access_level: 30
+
+ expect(response).to have_gitlab_http_status(201)
+ expect(json_response['name']).to eq(tag_name)
+ expect(json_response['create_access_levels'][0]['access_level']).to eq(Gitlab::Access::DEVELOPER)
+ end
+
+ it 'protects a single tag with no one can create tags' do
+ post api("/projects/#{project.id}/protected_tags", user),
+ name: tag_name, create_access_level: 0
+
+ expect(response).to have_gitlab_http_status(201)
+ expect(json_response['name']).to eq(tag_name)
+ expect(json_response['create_access_levels'][0]['access_level']).to eq(Gitlab::Access::NO_ACCESS)
+ end
+
+ it 'returns a 422 error if the same tag is protected twice' do
+ post api("/projects/#{project.id}/protected_tags", user), name: protected_name
+
+ expect(response).to have_gitlab_http_status(422)
+ expect(json_response['message'][0]).to eq('Name has already been taken')
+ end
+
+ it 'returns 201 if the same tag is proteted on different projects' do
+ post api("/projects/#{project.id}/protected_tags", user), name: protected_name
+ post api("/projects/#{project2.id}/protected_tags", user), name: protected_name
+
+ expect(response).to have_gitlab_http_status(201)
+ expect(json_response['name']).to eq(protected_name)
+ end
+
+ context 'when tag has a wildcard in its name' do
+ let(:tag_name) { 'feature/*' }
+
+ it 'protects multiple tags with a wildcard in the name' do
+ post api("/projects/#{project.id}/protected_tags", user), name: tag_name
+
+ expect(response).to have_gitlab_http_status(201)
+ expect(json_response['name']).to eq(tag_name)
+ expect(json_response['create_access_levels'][0]['access_level']).to eq(Gitlab::Access::MAINTAINER)
+ end
+ end
+ end
+
+ context 'when authenticated as a guest' do
+ before do
+ project.add_guest(user)
+ end
+
+ it 'returns a 403 error if guest' do
+ post api("/projects/#{project.id}/protected_tags/", user), name: tag_name
+
+ expect(response).to have_gitlab_http_status(403)
+ end
+ end
+ end
+
+ describe 'DELETE /projects/:id/protected_tags/unprotect/:tag' do
+ before do
+ project.add_maintainer(user)
+ end
+
+ it 'unprotects a single tag' do
+ delete api("/projects/#{project.id}/protected_tags/#{tag_name}", user)
+
+ expect(response).to have_gitlab_http_status(204)
+ end
+
+ it_behaves_like '412 response' do
+ let(:request) { api("/projects/#{project.id}/protected_tags/#{tag_name}", user) }
+ end
+
+ it "returns 404 if tag does not exist" do
+ delete api("/projects/#{project.id}/protected_tags/barfoo", user)
+
+ expect(response).to have_gitlab_http_status(404)
+ end
+
+ context 'when tag has a wildcard in its name' do
+ let(:protected_name) { 'feature*' }
+
+ it 'unprotects a wildcard tag' do
+ delete api("/projects/#{project.id}/protected_tags/#{tag_name}", user)
+
+ expect(response).to have_gitlab_http_status(204)
+ end
+ end
+ end
+end
diff --git a/spec/routing/admin_routing_spec.rb b/spec/routing/admin_routing_spec.rb
index 98df5f787f7..77baaef7afd 100644
--- a/spec/routing/admin_routing_spec.rb
+++ b/spec/routing/admin_routing_spec.rb
@@ -103,11 +103,11 @@ describe Admin::HooksController, "routing" do
end
end
-# admin_hook_hook_log_retry GET /admin/hooks/:hook_id/hook_logs/:id/retry(.:format) admin/hook_logs#retry
+# admin_hook_hook_log_retry POST /admin/hooks/:hook_id/hook_logs/:id/retry(.:format) admin/hook_logs#retry
# admin_hook_hook_log GET /admin/hooks/:hook_id/hook_logs/:id(.:format) admin/hook_logs#show
describe Admin::HookLogsController, 'routing' do
it 'to #retry' do
- expect(get('/admin/hooks/1/hook_logs/1/retry')).to route_to('admin/hook_logs#retry', hook_id: '1', id: '1')
+ expect(post('/admin/hooks/1/hook_logs/1/retry')).to route_to('admin/hook_logs#retry', hook_id: '1', id: '1')
end
it 'to #show' do
diff --git a/spec/routing/project_routing_spec.rb b/spec/routing/project_routing_spec.rb
index 70a7707826e..5abc6d81958 100644
--- a/spec/routing/project_routing_spec.rb
+++ b/spec/routing/project_routing_spec.rb
@@ -381,7 +381,7 @@ describe 'project routing' do
end
end
- # test_project_hook GET /:project_id/hooks/:id/test(.:format) hooks#test
+ # test_project_hook POST /:project_id/hooks/:id/test(.:format) hooks#test
# project_hooks GET /:project_id/hooks(.:format) hooks#index
# POST /:project_id/hooks(.:format) hooks#create
# edit_project_hook GET /:project_id/hooks/:id/edit(.:format) hooks#edit
@@ -398,11 +398,11 @@ describe 'project routing' do
end
end
- # retry_namespace_project_hook_hook_log GET /:project_id/hooks/:hook_id/hook_logs/:id/retry(.:format) projects/hook_logs#retry
+ # retry_namespace_project_hook_hook_log POST /:project_id/hooks/:hook_id/hook_logs/:id/retry(.:format) projects/hook_logs#retry
# namespace_project_hook_hook_log GET /:project_id/hooks/:hook_id/hook_logs/:id(.:format) projects/hook_logs#show
describe Projects::HookLogsController, 'routing' do
it 'to #retry' do
- expect(get('/gitlab/gitlabhq/hooks/1/hook_logs/1/retry')).to route_to('projects/hook_logs#retry', namespace_id: 'gitlab', project_id: 'gitlabhq', hook_id: '1', id: '1')
+ expect(post('/gitlab/gitlabhq/hooks/1/hook_logs/1/retry')).to route_to('projects/hook_logs#retry', namespace_id: 'gitlab', project_id: 'gitlabhq', hook_id: '1', id: '1')
end
it 'to #show' do
diff --git a/spec/rubocop/cop/ruby_interpolation_in_translation_spec.rb b/spec/rubocop/cop/ruby_interpolation_in_translation_spec.rb
new file mode 100644
index 00000000000..7bd50866577
--- /dev/null
+++ b/spec/rubocop/cop/ruby_interpolation_in_translation_spec.rb
@@ -0,0 +1,68 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+require 'rubocop'
+require 'rubocop/rspec/support'
+
+require_relative '../../../rubocop/cop/ruby_interpolation_in_translation'
+
+# Disabling interpolation check as we deliberately want to have #{} in strings.
+# rubocop:disable Lint/InterpolationCheck
+describe RuboCop::Cop::RubyInterpolationInTranslation do
+ subject(:cop) { described_class.new }
+
+ it 'does not add an offence for a regular messages' do
+ inspect_source('_("Hello world")')
+
+ expect(cop.offenses).to be_empty
+ end
+
+ it 'adds the correct offence when using interpolation in a string' do
+ inspect_source('_("Hello #{world}")')
+
+ offense = cop.offenses.first
+
+ expect(offense.location.source).to eq('#{world}')
+ expect(offense.message).to eq('Don\'t use ruby interpolation #{} inside translated strings, instead use %{}')
+ end
+
+ it 'detects when using a ruby interpolation in the first argument of a pluralized string' do
+ inspect_source('n_("Hello #{world}", "Hello world")')
+
+ expect(cop.offenses).not_to be_empty
+ end
+
+ it 'detects when using a ruby interpolation in the second argument of a pluralized string' do
+ inspect_source('n_("Hello world", "Hello #{world}")')
+
+ expect(cop.offenses).not_to be_empty
+ end
+
+ it 'detects when using interpolation in a namespaced translation' do
+ inspect_source('s_("Hello|#{world}")')
+
+ expect(cop.offenses).not_to be_empty
+ end
+
+ it 'does not add an offence for messages defined over multiple lines' do
+ source = <<~SRC
+ _("Hello "\
+ "world ")
+ SRC
+
+ inspect_source(source)
+ expect(cop.offenses).to be_empty
+ end
+
+ it 'adds an offence for violations in a message defined over multiple lines' do
+ source = <<~SRC
+ _("Hello "\
+ "\#{world} ")
+ SRC
+
+ inspect_source(source)
+ expect(cop.offenses).not_to be_empty
+ end
+end
+# rubocop:enable Lint/InterpolationCheck
diff --git a/spec/serializers/build_serializer_spec.rb b/spec/serializers/build_serializer_spec.rb
index 52459cd369d..302ef147eb2 100644
--- a/spec/serializers/build_serializer_spec.rb
+++ b/spec/serializers/build_serializer_spec.rb
@@ -37,7 +37,7 @@ describe BuildSerializer do
it 'serializes only status' do
expect(subject[:text]).to eq(status.text)
expect(subject[:label]).to eq('failed')
- expect(subject[:tooltip]).to eq('failed <br> (unknown failure)')
+ expect(subject[:tooltip]).to eq('failed - (unknown failure)')
expect(subject[:icon]).to eq(status.icon)
expect(subject[:favicon]).to match_asset_path("/assets/ci_favicons/#{status.favicon}.png")
end
diff --git a/spec/serializers/job_entity_spec.rb b/spec/serializers/job_entity_spec.rb
index a5581a34517..8e1ca3f308d 100644
--- a/spec/serializers/job_entity_spec.rb
+++ b/spec/serializers/job_entity_spec.rb
@@ -142,7 +142,7 @@ describe JobEntity do
end
it 'should indicate the failure reason on tooltip' do
- expect(subject[:status][:tooltip]).to eq('failed <br> (API failure)')
+ expect(subject[:status][:tooltip]).to eq('failed - (API failure)')
end
it 'should include a callout message with a verbose output' do
@@ -166,7 +166,7 @@ describe JobEntity do
end
it 'should indicate the failure reason on tooltip' do
- expect(subject[:status][:tooltip]).to eq('failed <br> (API failure) (allowed to fail)')
+ expect(subject[:status][:tooltip]).to eq('failed - (API failure) (allowed to fail)')
end
it 'should include a callout message with a verbose output' do
diff --git a/spec/services/git_push_service_spec.rb b/spec/services/git_push_service_spec.rb
index a3c9a660c2f..d4528256640 100644
--- a/spec/services/git_push_service_spec.rb
+++ b/spec/services/git_push_service_spec.rb
@@ -204,16 +204,37 @@ describe GitPushService, services: true do
end
describe "Push Event" do
- let!(:push_data) { push_data_from_service(project, user, oldrev, newrev, ref) }
- let(:event) { Event.find_by_action(Event::PUSHED) }
+ context "with an existing branch" do
+ let!(:push_data) { push_data_from_service(project, user, oldrev, newrev, ref) }
+ let(:event) { Event.find_by_action(Event::PUSHED) }
- it { expect(event).to be_an_instance_of(PushEvent) }
- it { expect(event.project).to eq(project) }
- it { expect(event.action).to eq(Event::PUSHED) }
- it { expect(event.push_event_payload).to be_an_instance_of(PushEventPayload) }
- it { expect(event.push_event_payload.commit_from).to eq(oldrev) }
- it { expect(event.push_event_payload.commit_to).to eq(newrev) }
- it { expect(event.push_event_payload.ref).to eq('master') }
+ it 'generates a push event with one commit' do
+ expect(event).to be_an_instance_of(PushEvent)
+ expect(event.project).to eq(project)
+ expect(event.action).to eq(Event::PUSHED)
+ expect(event.push_event_payload).to be_an_instance_of(PushEventPayload)
+ expect(event.push_event_payload.commit_from).to eq(oldrev)
+ expect(event.push_event_payload.commit_to).to eq(newrev)
+ expect(event.push_event_payload.ref).to eq('master')
+ expect(event.push_event_payload.commit_count).to eq(1)
+ end
+ end
+
+ context "with a new branch" do
+ let!(:new_branch_data) { push_data_from_service(project, user, Gitlab::Git::BLANK_SHA, newrev, ref) }
+ let(:event) { Event.find_by_action(Event::PUSHED) }
+
+ it 'generates a push event with more than one commit' do
+ expect(event).to be_an_instance_of(PushEvent)
+ expect(event.project).to eq(project)
+ expect(event.action).to eq(Event::PUSHED)
+ expect(event.push_event_payload).to be_an_instance_of(PushEventPayload)
+ expect(event.push_event_payload.commit_from).to be_nil
+ expect(event.push_event_payload.commit_to).to eq(newrev)
+ expect(event.push_event_payload.ref).to eq('master')
+ expect(event.push_event_payload.commit_count).to be > 1
+ end
+ end
context "Updates merge requests" do
it "when pushing a new branch for the first time" do
@@ -223,9 +244,14 @@ describe GitPushService, services: true do
end
end
- context "Sends System Push data" do
- it "when pushing on a branch" do
- expect(SystemHookPushWorker).to receive(:perform_async).with(push_data, :push_hooks)
+ describe 'system hooks' do
+ let!(:push_data) { push_data_from_service(project, user, oldrev, newrev, ref) }
+ let(:system_hooks_service) { SystemHooksService.new }
+
+ it "sends a system hook after pushing a branch" do
+ expect(SystemHooksService).to receive(:new).and_return(system_hooks_service)
+ expect(system_hooks_service).to receive(:execute_hooks).with(push_data, :push_hooks)
+
execute_service(project, user, oldrev, newrev, ref)
end
end
diff --git a/spec/services/groups/destroy_service_spec.rb b/spec/services/groups/destroy_service_spec.rb
index d80d0f5a8a8..97a88b5d697 100644
--- a/spec/services/groups/destroy_service_spec.rb
+++ b/spec/services/groups/destroy_service_spec.rb
@@ -35,6 +35,14 @@ describe Groups::DestroyService do
it { expect(NotificationSetting.unscoped.all).not_to include(notification_setting) }
end
+ context 'site statistics' do
+ it 'doesnt trigger project deletion hooks twice' do
+ expect_any_instance_of(Project).to receive(:untrack_site_statistics).once
+
+ destroy_group(group, user, async)
+ end
+ end
+
context 'mattermost team' do
let!(:chat_team) { create(:chat_team, namespace: group) }
diff --git a/spec/services/issues/fetch_referenced_merge_requests_service_spec.rb b/spec/services/issues/fetch_referenced_merge_requests_service_spec.rb
deleted file mode 100644
index 4e58179f45f..00000000000
--- a/spec/services/issues/fetch_referenced_merge_requests_service_spec.rb
+++ /dev/null
@@ -1,35 +0,0 @@
-require 'spec_helper.rb'
-
-describe Issues::FetchReferencedMergeRequestsService do
- let(:project) { create(:project) }
- let(:issue) { create(:issue, project: project) }
- let(:other_project) { create(:project) }
-
- let(:mr) { create(:merge_request, source_project: project, target_project: project, id: 2)}
- let(:other_mr) { create(:merge_request, source_project: other_project, target_project: other_project, id: 1)}
-
- let(:user) { create(:user) }
- let(:service) { described_class.new(project, user) }
-
- context 'with mentioned merge requests' do
- it 'returns a list of sorted merge requests' do
- allow(issue).to receive(:referenced_merge_requests).with(user).and_return([other_mr, mr])
-
- mrs, closed_by_mrs = service.execute(issue)
-
- expect(mrs).to match_array([mr, other_mr])
- expect(closed_by_mrs).to match_array([])
- end
- end
-
- context 'with closed-by merge requests' do
- it 'returns a list of sorted merge requests' do
- allow(issue).to receive(:closed_by_merge_requests).with(user).and_return([other_mr, mr])
-
- mrs, closed_by_mrs = service.execute(issue)
-
- expect(mrs).to match_array([])
- expect(closed_by_mrs).to match_array([mr, other_mr])
- end
- end
-end
diff --git a/spec/services/issues/referenced_merge_requests_service_spec.rb b/spec/services/issues/referenced_merge_requests_service_spec.rb
new file mode 100644
index 00000000000..61d1612829f
--- /dev/null
+++ b/spec/services/issues/referenced_merge_requests_service_spec.rb
@@ -0,0 +1,133 @@
+# frozen_string_literal: true
+
+require 'spec_helper.rb'
+
+describe Issues::ReferencedMergeRequestsService do
+ def create_referencing_mr(attributes = {})
+ create(:merge_request, attributes).tap do |merge_request|
+ create(:note, :system, project: project, noteable: issue, author: user, note: merge_request.to_reference(full: true))
+ end
+ end
+
+ def create_closing_mr(attributes = {})
+ create_referencing_mr(attributes).tap do |merge_request|
+ create(:merge_requests_closing_issues, issue: issue, merge_request: merge_request)
+ end
+ end
+
+ set(:user) { create(:user) }
+ set(:project) { create(:project, :public, :repository) }
+ set(:other_project) { create(:project, :public, :repository) }
+ set(:issue) { create(:issue, author: user, project: project) }
+
+ set(:closing_mr) { create_closing_mr(source_project: project) }
+ set(:closing_mr_other_project) { create_closing_mr(source_project: other_project) }
+
+ set(:referencing_mr) { create_referencing_mr(source_project: project, source_branch: 'csv') }
+ set(:referencing_mr_other_project) { create_referencing_mr(source_project: other_project, source_branch: 'csv') }
+
+ let(:service) { described_class.new(project, user) }
+
+ describe '#execute' do
+ it 'returns a list of sorted merge requests' do
+ mrs, closed_by_mrs = service.execute(issue)
+
+ expect(mrs).to eq([closing_mr, referencing_mr, closing_mr_other_project, referencing_mr_other_project])
+ expect(closed_by_mrs).to eq([closing_mr, closing_mr_other_project])
+ end
+
+ context 'performance' do
+ it 'does not run extra queries when extra namespaces are included', :use_clean_rails_memory_store_caching do
+ service.execute(issue) # warm cache
+ control_count = ActiveRecord::QueryRecorder.new { service.execute(issue) }.count
+
+ third_project = create(:project, :public)
+ create_closing_mr(source_project: third_project)
+ service.execute(issue) # warm cache
+
+ expect { service.execute(issue) }.not_to exceed_query_limit(control_count)
+ end
+
+ it 'preloads the head pipeline for each merge request, and its routes' do
+ # Hack to ensure no data is preserved on issue before starting the spec,
+ # to avoid false negatives
+ reloaded_issue = Issue.find(issue.id)
+
+ pipeline_routes = lambda do |merge_requests|
+ merge_requests.map { |mr| mr.head_pipeline&.project&.full_path }
+ end
+
+ closing_mr_other_project.update!(head_pipeline: create(:ci_pipeline))
+ control_count = ActiveRecord::QueryRecorder.new { service.execute(reloaded_issue).each(&pipeline_routes) }
+
+ closing_mr.update!(head_pipeline: create(:ci_pipeline))
+
+ expect { service.execute(issue).each(&pipeline_routes) }
+ .not_to exceed_query_limit(control_count)
+ end
+
+ it 'only loads issue notes once' do
+ expect(issue).to receive(:notes).once.and_call_original
+
+ service.execute(issue)
+ end
+ end
+ end
+
+ describe '#referenced_merge_requests' do
+ it 'returns the referenced merge requests' do
+ expect(service.referenced_merge_requests(issue)).to match_array([
+ closing_mr,
+ closing_mr_other_project,
+ referencing_mr,
+ referencing_mr_other_project
+ ])
+ end
+
+ it 'excludes cross project references if the user cannot read cross project' do
+ allow(Ability).to receive(:allowed?).and_call_original
+ expect(Ability).to receive(:allowed?).with(user, :read_cross_project).at_least(:once).and_return(false)
+
+ expect(service.referenced_merge_requests(issue)).not_to include(closing_mr_other_project)
+ expect(service.referenced_merge_requests(issue)).not_to include(referencing_mr_other_project)
+ end
+
+ context 'performance' do
+ it 'does not run a query for each note author', :use_clean_rails_memory_store_caching do
+ service.referenced_merge_requests(issue) # warm cache
+ control_count = ActiveRecord::QueryRecorder.new { service.referenced_merge_requests(issue) }.count
+
+ create(:note, project: project, noteable: issue, author: create(:user))
+ service.referenced_merge_requests(issue) # warm cache
+
+ expect { service.referenced_merge_requests(issue) }.not_to exceed_query_limit(control_count)
+ end
+ end
+ end
+
+ describe '#closed_by_merge_requests' do
+ let(:closed_issue) { build(:issue, :closed, project: project)}
+
+ it 'returns the open merge requests that close this issue' do
+ create_closing_mr(source_project: project, state: 'closed')
+
+ expect(service.closed_by_merge_requests(issue)).to match_array([closing_mr, closing_mr_other_project])
+ end
+
+ it 'returns an empty array when the current issue is closed already' do
+ expect(service.closed_by_merge_requests(closed_issue)).to eq([])
+ end
+
+ context 'performance' do
+ it 'does not run a query for each note author', :use_clean_rails_memory_store_caching do
+ service.closed_by_merge_requests(issue) # warm cache
+ control_count = ActiveRecord::QueryRecorder.new { service.closed_by_merge_requests(issue) }.count
+
+ create(:note, :system, project: project, noteable: issue, author: create(:user))
+ service.closed_by_merge_requests(issue) # warm cache
+
+ expect { service.closed_by_merge_requests(issue) }.not_to exceed_query_limit(control_count)
+ end
+ end
+ end
+end
diff --git a/spec/services/merge_requests/build_service_spec.rb b/spec/services/merge_requests/build_service_spec.rb
index 6aed481939e..0ced5d1b6d6 100644
--- a/spec/services/merge_requests/build_service_spec.rb
+++ b/spec/services/merge_requests/build_service_spec.rb
@@ -169,6 +169,10 @@ describe MergeRequests::BuildService do
end
end
+ it 'uses the title of the commit as the title of the merge request' do
+ expect(merge_request.title).to eq('Initial commit')
+ end
+
it 'appends the closing description' do
expected_description = [commit_description, closing_message].compact.join("\n\n")
diff --git a/spec/services/milestones/destroy_service_spec.rb b/spec/services/milestones/destroy_service_spec.rb
index 6f3612501f4..8680e428517 100644
--- a/spec/services/milestones/destroy_service_spec.rb
+++ b/spec/services/milestones/destroy_service_spec.rb
@@ -4,8 +4,6 @@ describe Milestones::DestroyService do
let(:user) { create(:user) }
let(:project) { create(:project) }
let(:milestone) { create(:milestone, title: 'Milestone v1.0', project: project) }
- let!(:issue) { create(:issue, project: project, milestone: milestone) }
- let!(:merge_request) { create(:merge_request, source_project: project, milestone: milestone) }
before do
project.add_maintainer(user)
@@ -23,12 +21,23 @@ describe Milestones::DestroyService do
end
it 'deletes milestone id from issuables' do
+ issue = create(:issue, project: project, milestone: milestone)
+ merge_request = create(:merge_request, source_project: project, milestone: milestone)
+
service.execute(milestone)
expect(issue.reload.milestone).to be_nil
expect(merge_request.reload.milestone).to be_nil
end
+ it 'logs destroy event' do
+ service.execute(milestone)
+
+ event = Event.where(project_id: milestone.project_id, target_type: 'Milestone')
+
+ expect(event.count).to eq(1)
+ end
+
context 'group milestones' do
let(:group) { create(:group) }
let(:group_milestone) { create(:milestone, group: group) }
@@ -38,13 +47,20 @@ describe Milestones::DestroyService do
group.add_developer(user)
end
- it { expect(service.execute(group_milestone)).to be_nil }
+ it { expect(service.execute(group_milestone)).to eq(group_milestone) }
- it 'does not update milestone issuables' do
- expect(MergeRequests::UpdateService).not_to receive(:new)
- expect(Issues::UpdateService).not_to receive(:new)
+ it 'deletes milestone id from issuables' do
+ issue = create(:issue, project: project, milestone: group_milestone)
+ merge_request = create(:merge_request, source_project: project, milestone: group_milestone)
service.execute(group_milestone)
+
+ expect(issue.reload.milestone).to be_nil
+ expect(merge_request.reload.milestone).to be_nil
+ end
+
+ it 'does not log destroy event' do
+ expect { service.execute(group_milestone) }.not_to change { Event.count }
end
end
end
diff --git a/spec/services/projects/fork_service_spec.rb b/spec/services/projects/fork_service_spec.rb
index f89f9b54f53..947cb61038d 100644
--- a/spec/services/projects/fork_service_spec.rb
+++ b/spec/services/projects/fork_service_spec.rb
@@ -264,6 +264,14 @@ describe Projects::ForkService do
expect(fork_from_project.forks_count).to eq(1)
end
+
+ it 'leaves no LFS objects dangling' do
+ create(:lfs_objects_project, project: fork_to_project)
+
+ expect { subject.execute(fork_to_project) }
+ .to change { fork_to_project.lfs_objects_projects.count }
+ .to(0)
+ end
end
end
end
diff --git a/spec/services/projects/update_remote_mirror_service_spec.rb b/spec/services/projects/update_remote_mirror_service_spec.rb
index 5c2e79ff9af..96e8a80b334 100644
--- a/spec/services/projects/update_remote_mirror_service_spec.rb
+++ b/spec/services/projects/update_remote_mirror_service_spec.rb
@@ -18,6 +18,7 @@ describe Projects::UpdateRemoteMirrorService do
end
it "fetches the remote repository" do
+ expect(remote_mirror).to receive(:ensure_remote!).and_call_original
expect(repository).to receive(:fetch_remote).with(remote_mirror.remote_name, no_tags: true) do
sync_remote(repository, remote_mirror.remote_name, local_branch_names)
end
diff --git a/spec/services/projects/update_service_spec.rb b/spec/services/projects/update_service_spec.rb
index 9572b4110d5..695b9980548 100644
--- a/spec/services/projects/update_service_spec.rb
+++ b/spec/services/projects/update_service_spec.rb
@@ -249,9 +249,20 @@ describe Projects::UpdateService do
expect(project.errors.messages[:base]).to include('There is already a repository with that name on disk')
end
- context 'when hashed storage enabled' do
+ it 'renames the project without upgrading it' do
+ result = update_project(project, admin, path: 'new-path')
+
+ expect(result).not_to include(status: :error)
+ expect(project).to be_valid
+ expect(project.errors).to be_empty
+ expect(project.disk_path).to include('new-path')
+ expect(project.reload.hashed_storage?(:repository)).to be_falsey
+ end
+
+ context 'when hashed storage is enabled' do
before do
stub_application_setting(hashed_storage_enabled: true)
+ stub_feature_flags(skip_hashed_storage_upgrade: false)
end
it 'migrates project to a hashed storage instead of renaming the repo to another legacy name' do
@@ -262,6 +273,22 @@ describe Projects::UpdateService do
expect(project.errors).to be_empty
expect(project.reload.hashed_storage?(:repository)).to be_truthy
end
+
+ context 'when skip_hashed_storage_upgrade feature flag is enabled' do
+ before do
+ stub_feature_flags(skip_hashed_storage_upgrade: true)
+ end
+
+ it 'renames the project without upgrading it' do
+ result = update_project(project, admin, path: 'new-path')
+
+ expect(result).not_to include(status: :error)
+ expect(project).to be_valid
+ expect(project.errors).to be_empty
+ expect(project.disk_path).to include('new-path')
+ expect(project.reload.hashed_storage?(:repository)).to be_falsey
+ end
+ end
end
end
diff --git a/spec/support/api/milestones_shared_examples.rb b/spec/support/api/milestones_shared_examples.rb
index afd6448aa26..3bebb7aae90 100644
--- a/spec/support/api/milestones_shared_examples.rb
+++ b/spec/support/api/milestones_shared_examples.rb
@@ -196,6 +196,24 @@ shared_examples_for 'group and project milestones' do |route_definition|
end
end
+ describe "DELETE #{route_definition}/:milestone_id" do
+ it "rejects a member with reporter access from deleting a milestone" do
+ reporter = create(:user)
+ milestone.parent.add_reporter(reporter)
+
+ delete api(resource_route, reporter)
+
+ expect(response).to have_gitlab_http_status(403)
+ end
+
+ it 'deletes the milestone when the user has developer access to the project' do
+ delete api(resource_route, user)
+
+ expect(project.milestones.find_by_id(milestone.id)).to be_nil
+ expect(response).to have_gitlab_http_status(204)
+ end
+ end
+
describe "GET #{route_definition}/:milestone_id/issues" do
let(:issues_route) { "#{route}/#{milestone.id}/issues" }
diff --git a/spec/support/helpers/cycle_analytics_helpers.rb b/spec/support/helpers/cycle_analytics_helpers.rb
index c228bd2393b..e0fceae88de 100644
--- a/spec/support/helpers/cycle_analytics_helpers.rb
+++ b/spec/support/helpers/cycle_analytics_helpers.rb
@@ -65,7 +65,9 @@ module CycleAnalyticsHelpers
end
def merge_merge_requests_closing_issue(user, project, issue)
- merge_requests = issue.closed_by_merge_requests(user)
+ merge_requests = Issues::ReferencedMergeRequestsService
+ .new(project, user)
+ .closed_by_merge_requests(issue)
merge_requests.each { |merge_request| MergeRequests::MergeService.new(project, user).execute(merge_request) }
end
diff --git a/spec/support/helpers/ldap_helpers.rb b/spec/support/helpers/ldap_helpers.rb
index b90bbc4b106..66ca5d7f0a3 100644
--- a/spec/support/helpers/ldap_helpers.rb
+++ b/spec/support/helpers/ldap_helpers.rb
@@ -37,6 +37,23 @@ module LdapHelpers
.to receive(:find_by_uid).with(uid, any_args).and_return(return_value)
end
+ def stub_ldap_person_find_by_dn(entry, provider = 'ldapmain')
+ person = ::Gitlab::Auth::LDAP::Person.new(entry, provider) if entry.present?
+
+ allow(::Gitlab::Auth::LDAP::Person)
+ .to receive(:find_by_dn)
+ .and_return(person)
+ end
+
+ def stub_ldap_person_find_by_email(email, entry, provider = 'ldapmain')
+ person = ::Gitlab::Auth::LDAP::Person.new(entry, provider) if entry.present?
+
+ allow(::Gitlab::Auth::LDAP::Person)
+ .to receive(:find_by_email)
+ .with(email, anything)
+ .and_return(person)
+ end
+
# Create a simple LDAP user entry.
def ldap_user_entry(uid)
entry = Net::LDAP::Entry.new
diff --git a/spec/support/helpers/stub_configuration.rb b/spec/support/helpers/stub_configuration.rb
index 1823099dd9c..8475f91799b 100644
--- a/spec/support/helpers/stub_configuration.rb
+++ b/spec/support/helpers/stub_configuration.rb
@@ -68,6 +68,10 @@ module StubConfiguration
allow(Gitlab.config.repositories).to receive(:storages).and_return(Settingslogic.new(messages))
end
+ def stub_kerberos_setting(messages)
+ allow(Gitlab.config.kerberos).to receive_messages(to_settings(messages))
+ end
+
private
# Modifies stubbed messages to also stub possible predicate versions
diff --git a/spec/support/helpers/stub_feature_flags.rb b/spec/support/helpers/stub_feature_flags.rb
index b96338bf548..c54a871b157 100644
--- a/spec/support/helpers/stub_feature_flags.rb
+++ b/spec/support/helpers/stub_feature_flags.rb
@@ -1,4 +1,7 @@
module StubFeatureFlags
+ # Stub Feature flags with `flag_name: true/false`
+ #
+ # @param [Hash] features where key is feature name and value is boolean whether enabled or not
def stub_feature_flags(features)
features.each do |feature_name, enabled|
allow(Feature).to receive(:enabled?).with(feature_name) { enabled }
diff --git a/spec/support/shared_examples/requests/api/notes.rb b/spec/support/shared_examples/requests/api/notes.rb
index 1b563021244..0e20dfe0725 100644
--- a/spec/support/shared_examples/requests/api/notes.rb
+++ b/spec/support/shared_examples/requests/api/notes.rb
@@ -111,17 +111,79 @@ shared_examples 'noteable API' do |parent_type, noteable_type, id_name|
post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", user), body: 'hi!'
end
- context 'when an admin or owner makes the request' do
- it 'accepts the creation date to be set' do
- creation_time = 2.weeks.ago
- post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", user),
- body: 'hi!', created_at: creation_time
+ context 'setting created_at' do
+ let(:creation_time) { 2.weeks.ago }
+ let(:params) { { body: 'hi!', created_at: creation_time } }
+
+ context 'by an admin' do
+ it 'sets the creation time on the new note' do
+ admin = create(:admin)
+ post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", admin), params
+
+ expect(response).to have_gitlab_http_status(201)
+ expect(json_response['body']).to eq('hi!')
+ expect(json_response['author']['username']).to eq(admin.username)
+ expect(Time.parse(json_response['created_at'])).to be_like_time(creation_time)
+ expect(Time.parse(json_response['updated_at'])).to be_like_time(creation_time)
+ end
+ end
- expect(response).to have_gitlab_http_status(201)
- expect(json_response['body']).to eq('hi!')
- expect(json_response['author']['username']).to eq(user.username)
- expect(Time.parse(json_response['created_at'])).to be_like_time(creation_time)
- expect(Time.parse(json_response['updated_at'])).to be_like_time(creation_time)
+ if parent_type == 'projects'
+ context 'by a project owner' do
+ it 'sets the creation time on the new note' do
+ post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", user), params
+
+ expect(response).to have_gitlab_http_status(201)
+ expect(json_response['body']).to eq('hi!')
+ expect(json_response['author']['username']).to eq(user.username)
+ expect(Time.parse(json_response['created_at'])).to be_like_time(creation_time)
+ expect(Time.parse(json_response['updated_at'])).to be_like_time(creation_time)
+ end
+ end
+
+ context 'by a group owner' do
+ it 'sets the creation time on the new note' do
+ user2 = create(:user)
+ group = create(:group)
+ group.add_owner(user2)
+ parent.update!(namespace: group)
+ user2.refresh_authorized_projects
+
+ post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", user2), params
+
+ expect(response).to have_gitlab_http_status(201)
+ expect(json_response['body']).to eq('hi!')
+ expect(json_response['author']['username']).to eq(user2.username)
+ expect(Time.parse(json_response['created_at'])).to be_like_time(creation_time)
+ expect(Time.parse(json_response['updated_at'])).to be_like_time(creation_time)
+ end
+ end
+ elsif parent_type == 'groups'
+ context 'by a group owner' do
+ it 'sets the creation time on the new note' do
+ post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", user), params
+
+ expect(response).to have_gitlab_http_status(201)
+ expect(json_response['body']).to eq('hi!')
+ expect(json_response['author']['username']).to eq(user.username)
+ expect(Time.parse(json_response['created_at'])).to be_like_time(creation_time)
+ expect(Time.parse(json_response['updated_at'])).to be_like_time(creation_time)
+ end
+ end
+ end
+
+ context 'by another user' do
+ it 'ignores the given creation time' do
+ user2 = create(:user)
+ parent.add_developer(user2)
+ post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", user2), params
+
+ expect(response).to have_gitlab_http_status(201)
+ expect(json_response['body']).to eq('hi!')
+ expect(json_response['author']['username']).to eq(user2.username)
+ expect(Time.parse(json_response['created_at'])).not_to be_like_time(creation_time)
+ expect(Time.parse(json_response['updated_at'])).not_to be_like_time(creation_time)
+ end
end
end
diff --git a/spec/views/projects/merge_requests/_commits.html.haml_spec.rb b/spec/views/projects/merge_requests/_commits.html.haml_spec.rb
index b1c6565c08a..a7628548de6 100644
--- a/spec/views/projects/merge_requests/_commits.html.haml_spec.rb
+++ b/spec/views/projects/merge_requests/_commits.html.haml_spec.rb
@@ -20,6 +20,7 @@ describe 'projects/merge_requests/_commits.html.haml' do
assign(:merge_request, merge_request)
assign(:commits, merge_request.commits)
+ assign(:hidden_commit_count, 0)
end
it 'shows commits from source project' do
@@ -30,4 +31,16 @@ describe 'projects/merge_requests/_commits.html.haml' do
expect(rendered).to have_link(href: href)
end
+
+ context 'when there are hidden commits' do
+ before do
+ assign(:hidden_commit_count, 1)
+ end
+
+ it 'shows notice about omitted commits' do
+ render
+
+ expect(rendered).to match(/1 additional commit has been omitted to prevent performance issues/)
+ end
+ end
end
diff --git a/spec/views/projects/merge_requests/creations/_new_submit.html.haml_spec.rb b/spec/views/projects/merge_requests/creations/_new_submit.html.haml_spec.rb
index 9ab105c3238..8befae39d3a 100644
--- a/spec/views/projects/merge_requests/creations/_new_submit.html.haml_spec.rb
+++ b/spec/views/projects/merge_requests/creations/_new_submit.html.haml_spec.rb
@@ -9,6 +9,8 @@ describe 'projects/merge_requests/creations/_new_submit.html.haml' do
assign(:merge_request, merge_request)
assign(:commits, merge_request.commits)
+ assign(:hidden_commit_count, 0)
+ assign(:total_commit_count, merge_request.commits.count)
assign(:project, merge_request.target_project)
allow(view).to receive(:can?).and_return(true)
@@ -29,4 +31,17 @@ describe 'projects/merge_requests/creations/_new_submit.html.haml' do
expect(rendered).not_to have_text('Builds')
end
end
+
+ context 'when there are hidden commits' do
+ before do
+ assign(:pipelines, Ci::Pipeline.none)
+ assign(:hidden_commit_count, 2)
+ end
+
+ it 'shows notice about omitted commits' do
+ render
+
+ expect(rendered).to match(/2 additional commits have been omitted to prevent performance issues/)
+ end
+ end
end
diff --git a/yarn.lock b/yarn.lock
index 4326245d2ac..db3b0bbe573 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -78,10 +78,14 @@
lodash "^4.2.0"
to-fast-properties "^2.0.0"
-"@gitlab-org/gitlab-svgs@^1.23.0", "@gitlab-org/gitlab-svgs@^1.27.0":
+"@gitlab-org/gitlab-svgs@^1.23.0":
version "1.27.0"
resolved "https://registry.yarnpkg.com/@gitlab-org/gitlab-svgs/-/gitlab-svgs-1.27.0.tgz#638e70399ebd59e503732177316bb9a18bf7a13f"
+"@gitlab-org/gitlab-svgs@^1.28.0":
+ version "1.28.0"
+ resolved "https://registry.yarnpkg.com/@gitlab-org/gitlab-svgs/-/gitlab-svgs-1.28.0.tgz#f689dfd46504df0a75027d6dd4ea01a71cd46f88"
+
"@gitlab-org/gitlab-ui@1.0.5":
version "1.0.5"
resolved "https://registry.yarnpkg.com/@gitlab-org/gitlab-ui/-/gitlab-ui-1.0.5.tgz#a64b402650494115c8b494a44b72c2d6fbf33fff"